diff options
author | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-26 22:38:20 +0000 |
---|---|---|
committer | mattm@chromium.org <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-26 22:38:20 +0000 |
commit | e505a900d371c2012fd32a6d763ae283a98f72a1 (patch) | |
tree | fef99fd74e520c2e10d7a7fe88174c93b349b237 /chrome | |
parent | da65cbb338400a9b29857d8e0e818e4bed3c9318 (diff) | |
download | chromium_src-e505a900d371c2012fd32a6d763ae283a98f72a1.zip chromium_src-e505a900d371c2012fd32a6d763ae283a98f72a1.tar.gz chromium_src-e505a900d371c2012fd32a6d763ae283a98f72a1.tar.bz2 |
Linux: Add decoding for a bunch of certificate extensions.
BUG=18119
TEST=open https site in firefox and chrome, compare certificate extension details
Review URL: http://codereview.chromium.org/557046
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@40172 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/app/generated_resources.grd | 189 | ||||
-rw-r--r-- | chrome/browser/DEPS | 1 | ||||
-rw-r--r-- | chrome/browser/gtk/certificate_viewer.cc | 222 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 4 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/README.chromium | 12 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp | 811 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h | 97 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/nsNSSCertificate.cpp | 65 | ||||
-rw-r--r-- | chrome/third_party/mozilla_security_manager/nsNSSCertificate.h | 55 |
9 files changed, 1261 insertions, 195 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 2a9b3be..9c1b927 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -2692,12 +2692,201 @@ each locale. --> PKCS #1 SHA-512 With RSA Encryption </message> + <message name="IDS_CERT_EXT_NS_CERT_TYPE" desc="description of extension Netscape Certificate Type"> + Netscape Certificate Type + </message> + <message name="IDS_CERT_EXT_NS_CERT_TYPE_EMAIL" desc="description of a certificate type for email"> + Email Certificate + </message> + <message name="IDS_CERT_EXT_NS_CERT_TYPE_EMAIL_CA" desc="description of a certificate type for email certificate authority"> + Email Certificate Authority + </message> + <message name="IDS_CERT_EXT_NS_CERT_BASE_URL" desc="description of extension Netscape Certificate Base URL"> + Netscape Certificate Base URL + </message> + <message name="IDS_CERT_EXT_NS_CERT_REVOCATION_URL" desc="description of extension Netscape Certificate Revocation URL"> + Netscape Certificate Revocation URL + </message> + <message name="IDS_CERT_EXT_NS_CA_REVOCATION_URL" desc="description of extension Netscape Certificate Authority Revocation URL"> + Netscape Certificate Authority Revocation URL + </message> + <message name="IDS_CERT_EXT_NS_CERT_RENEWAL_URL" desc="description of extension Netscape Certificate Renewal URL"> + Netscape Certificate Renewal URL + </message> + <message name="IDS_CERT_EXT_NS_CA_POLICY_URL" desc="description of extension Netscape Certificate Authority Policy URL"> + Netscape Certificate Authority Policy URL + </message> + <message name="IDS_CERT_EXT_NS_SSL_SERVER_NAME" desc="description of extension Netscape Certificate SSL Server Name"> + Netscape Certificate SSL Server Name + </message> + <message name="IDS_CERT_EXT_NS_COMMENT" desc="description of extension Netscape Certificate Comment"> + Netscape Certificate Comment + </message> + <message name="IDS_CERT_EXT_NS_LOST_PASSWORD_URL" desc="description of extension Netscape Lost Password URL"> + Netscape Lost Password URL + </message> + <message name="IDS_CERT_EXT_NS_CERT_RENEWAL_TIME" desc="description of extension Netscape Certificate Renewal Time"> + Netscape Certificate Renewal Time + </message> + <message name="IDS_CERT_X509_SUBJECT_DIRECTORY_ATTR" desc="description of extension Certificate Subject Directory Attributes"> + Certificate Subject Directory Attributes + </message> + <message name="IDS_CERT_X509_SUBJECT_KEYID" desc="description of extension Certificate Subject Key ID"> + Certificate Subject Key ID + </message> + <message name="IDS_CERT_KEYID_FORMAT" desc="format for key id in certificate extensions details"> + Key ID: <ph name="KEY_ID">$1<ex>19 EB 8E 93</ex></ph> + </message> + <message name="IDS_CERT_ISSUER_FORMAT" desc="format for issuer in certificate extensions details"> + Issuer: <ph name="CERTIFICATE_AUTHORITY">$1<ex>VeriSign</ex></ph> + </message> + <message name="IDS_CERT_SERIAL_NUMBER_FORMAT" desc="format for serial number in certificate extensions details"> + Serial Number: <ph name="Serail Number">$1<ex>19 EB 8E 93</ex></ph> + </message> + <message name="IDS_CERT_X509_KEY_USAGE" desc="description of extension Certificate Key Usage"> + Certificate Key Usage + </message> + <message name="IDS_CERT_X509_SUBJECT_ALT_NAME" desc="description of extension Certificate Subject Alternative Name"> + Certificate Subject Alternative Name + </message> + <message name="IDS_CERT_X509_ISSUER_ALT_NAME" desc="description of extension Certificate Issuer Alternative Name"> + Certificate Issuer Alternative Name + </message> + <message name="IDS_CERT_X509_BASIC_CONSTRAINTS" desc="description of extension Certificate Basic Constraints"> + Certificate Basic Constraints + </message> + <message name="IDS_CERT_X509_NAME_CONSTRAINTS" desc="description of extension Certificate Name Constraints"> + Certificate Name Constraints + </message> + <message name="IDS_CERT_X509_CRL_DIST_POINTS" desc="description of extension CRL Distribution Points"> + CRL Distribution Points + </message> + <message name="IDS_CERT_X509_CERT_POLICIES" desc="description of extension Certificate Policies"> + Certificate Policies + </message> + <message name="IDS_CERT_X509_POLICY_MAPPINGS" desc="description of extension Certificate Policy Mappings"> + Certificate Policy Mappings + </message> + <message name="IDS_CERT_X509_POLICY_CONSTRAINTS" desc="description of extension Certificate Policy Constraints"> + Certificate Policy Constraints + </message> + <message name="IDS_CERT_X509_AUTH_KEYID" desc="description of extension Certificate Authority Key Identifier"> + Certificate Authority Key ID + </message> + <message name="IDS_CERT_X509_EXT_KEY_USAGE" desc="description of extension Extended Key Usage"> + Extended Key Usage + </message> + <message name="IDS_CERT_X509_AUTH_INFO_ACCESS" desc="description of extension Authority Information Access"> + Authority Information Access + </message> + <message name="IDS_CERT_X509_KEY_USAGE_SIGNING" desc="description of certificate usage Signing"> + Signing + </message> + <message name="IDS_CERT_X509_KEY_USAGE_NONREP" desc="description of certificate usage Non-repudiation"> + Non-repudiation + </message> + <message name="IDS_CERT_X509_KEY_USAGE_ENCIPHERMENT" desc="description of certificate usage Key Encipherment"> + Key Encipherment + </message> + <message name="IDS_CERT_X509_KEY_USAGE_DATA_ENCIPHERMENT" desc="description of certificate usage Data Encipherment"> + Data Encipherment + </message> + <message name="IDS_CERT_X509_KEY_USAGE_KEY_AGREEMENT" desc="description of certificate usage Key Agreement"> + Key Agreement + </message> + <message name="IDS_CERT_X509_KEY_USAGE_CERT_SIGNER" desc="description of certificate usage Certificate Signer"> + Certificate Signer + </message> + <message name="IDS_CERT_X509_KEY_USAGE_CRL_SIGNER" desc="description of certificate usage CRL Signer"> + CRL Signer + </message> + <message name="IDS_CERT_X509_BASIC_CONSTRAINT_IS_CA" desc="description of certificate constraint Is a Certificate Authority"> + Is a Certificate Authority + </message> + <message name="IDS_CERT_X509_BASIC_CONSTRAINT_IS_NOT_CA" desc="description of certificate constraint Is not a Certificate Authority"> + Is not a Certificate Authority + </message> + <message name="IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN" desc="description of certificate constraint Maximum number of intermediate CAs: %S"> + Maximum number of intermediate CAs: <ph name="NUM_INTERMEDIATE_CA">$1<ex>5</ex></ph> + </message> + <message name="IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN_UNLIMITED" desc="value NUM_INTERMEDIATE_CA when there is no limit"> + unlimited + </message> + <message name="IDS_CERT_REVOCATION_REASON_UNUSED" desc="description of certificate revocation for reason Unused"> + Unused + </message> + <message name="IDS_CERT_REVOCATION_REASON_KEY_COMPROMISE" desc="description of certificate revocation for reason Key Compromise"> + Key Compromise + </message> + <message name="IDS_CERT_REVOCATION_REASON_CA_COMPROMISE" desc="description of certificate revocation for reason CA Compromise"> + CA Compromise + </message> + <message name="IDS_CERT_REVOCATION_REASON_AFFILIATION_CHANGED" desc="description of certificate revocation for reason Affiliation Changed"> + Affiliation Changed + </message> + <message name="IDS_CERT_REVOCATION_REASON_SUPERSEDED" desc="description of certificate revocation for reason Superseded"> + Superseded + </message> + <message name="IDS_CERT_REVOCATION_REASON_CESSATION_OF_OPERATION" desc="description of certificate revocation for reason Cessation of Operation"> + Cessation of Operation + </message> + <message name="IDS_CERT_REVOCATION_REASON_CERTIFICATE_HOLD" desc="description of certificate revocation for reason Certificate Hold"> + Certificate on Hold + </message> + <message name="IDS_CERT_OCSP_RESPONDER_FORMAT" desc="format for info about OCSP responder"> + OCSP Responder: <ph name="LOCATION">$1<ex>Foo</ex></ph> + </message> + <message name="IDS_CERT_CA_ISSUERS_FORMAT" desc="format for info about CA Issuers"> + CA Issuers: <ph name="LOCATION">$1<ex>Foo</ex></ph> + </message> + <message name="IDS_CERT_UNKNOWN_OID_INFO_FORMAT" desc="format for info about an OID we don't have a specific format for"> + <ph name="OID">$1<ex>OID.1.23.45.6</ex></ph>: <ph name="INFO">$2<ex>Foo</ex></ph> + </message> + <message name="IDS_CERT_GENERAL_NAME_RFC822_NAME" desc="label for the certRFC822Name general name type"> + Email Address + </message> + <message name="IDS_CERT_GENERAL_NAME_DNS_NAME" desc="label for the certDNSName general name type"> + DNS Name + </message> + <message name="IDS_CERT_GENERAL_NAME_X400_ADDRESS" desc="label for the certX400Address general name type"> + X.400 Address + </message> + <message name="IDS_CERT_GENERAL_NAME_DIRECTORY_NAME" desc="label for the certDirectoryName general name type"> + X.500 Name + </message> + <message name="IDS_CERT_GENERAL_NAME_EDI_PARTY_NAME" desc="label for the certEDIPartyName general name type"> + EDI Party Name + </message> + <message name="IDS_CERT_GENERAL_NAME_URI" desc="label for the certURI general name type"> + URI + </message> + <message name="IDS_CERT_GENERAL_NAME_IP_ADDRESS" desc="label for the certIPAddress general name type"> + IP Address + </message> + <message name="IDS_CERT_GENERAL_NAME_REGISTERED_ID" desc="label for the certRegisteredID general name type"> + Registered OID + </message> + <message name="IDS_CERT_EXT_MS_CERT_TYPE" desc="description of extension Microsoft Certificate Template Name"> + Microsoft Certificate Template Name + </message> + <message name="IDS_CERT_EXT_MS_CA_VERSION" desc="description of extension Microsoft CA Version"> + Microsoft CA Version + </message> + <message name="IDS_CERT_EXT_MS_NT_PRINCIPAL_NAME" desc="description of extension Microsoft Principal Name"> + Microsoft Principal Name + </message> + <message name="IDS_CERT_EXT_MS_NTDS_REPLICATION" desc="description of extension Microsoft Domain GUID"> + Microsoft Domain GUID + </message> <message name="IDS_CERT_EXTENSION_CRITICAL" desc="The text displayed in the certificate details dialog for a given extension which is critical"> Critical </message> <message name="IDS_CERT_EXTENSION_NON_CRITICAL" desc="The text displayed in the certificate details dialog for a given extension which is not critical"> Not Critical </message> + <message name="IDS_CERT_EXTENSION_DUMP_ERROR" desc="The text displayed in the certificate details dialog for a given extension which could not be decoded"> + Error: Unable to decode extension + </message> <!-- Certificate manager dialog strings. These are only used on platforms that don't have a native certificate manager dialog, such as Linux. --> <message name="IDS_CERTIFICATE_MANAGER_TITLE" desc="String to be displayed in the title bar of the certificate manager dialog"> diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 855116c..f128afb 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -16,6 +16,7 @@ include_rules = [ # Other libraries. "+chrome/third_party/hunspell", + "+chrome/third_party/mozilla_security_manager", "+libxml", # For search engine definition parsing. "+media/audio", # Chrome's lightweight audio library. "+media/base", diff --git a/chrome/browser/gtk/certificate_viewer.cc b/chrome/browser/gtk/certificate_viewer.cc index 5f539fb..836921a 100644 --- a/chrome/browser/gtk/certificate_viewer.cc +++ b/chrome/browser/gtk/certificate_viewer.cc @@ -7,7 +7,6 @@ #include <cert.h> #include <gtk/gtk.h> #include <hasht.h> -#include <prprf.h> #include <sechash.h> #include <algorithm> @@ -20,8 +19,13 @@ #include "base/utf_string_conversions.h" #include "chrome/browser/cert_store.h" #include "chrome/common/gtk_util.h" +#include "chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h" +#include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h" #include "grit/generated_resources.h" +// PSM = Mozilla's Personal Security Manager. +namespace psm = mozilla_security_manager; + namespace { const char kDetailsFontFamily[] = "monospace"; @@ -64,182 +68,8 @@ std::string HashCert(CERTCertificate* cert, HASH_HashType algorithm, int len) { return Stringize(CERT_Hexify(&fingerprint_item, TRUE)); } -// Format a SECItem as a space separated string, with 16 bytes on each line. -std::string ProcessRawBytes(SECItem* data) { - static const char kHexChars[] = "0123456789ABCDEF"; - - // Each input byte creates two output hex characters + a space or newline, - // except for the last byte. - std::string ret(std::max(0u, data->len * 3 - 1), '\0'); - - for (size_t i = 0; i < data->len; ++i) { - unsigned char b = data->data[i]; - ret[i * 3] = kHexChars[(b >> 4) & 0xf]; - ret[i * 3 + 1] = kHexChars[b & 0xf]; - if (i + 1 < data->len) { - if ((i + 1) % 16 == 0) - ret[i * 3 + 2] = '\n'; - else - ret[i * 3 + 2] = ' '; - } - } - return ret; -} - -// For fields which have the length specified in bits, rather than bytes. -std::string ProcessRawBits(SECItem* data) { - SECItem bytedata; - bytedata.data = data->data; - bytedata.len = data->len / 8; - return ProcessRawBytes(&bytedata); -} - -// Based on mozilla/source/security/manager/ssl/src/nsNSSCertificate.cpp: -// nsNSSCertificate::GetWindowTitle. -std::string GetCertTitle(CERTCertificate* cert) { - std::string rv; - if (cert->nickname) { - rv = cert->nickname; - } else { - char* cn = CERT_GetCommonName(&cert->subject); - if (cn) { - rv = Stringize(cn); - } else if (cert->subjectName) { - rv = cert->subjectName; - } else if (cert->emailAddr) { - rv = cert->emailAddr; - } - } - // TODO(mattm): Should we return something other than an empty string when all - // the checks fail? - return rv; -} - -std::string GetOIDText(SECItem* oid) { - int string_id; - switch (SECOID_FindOIDTag(oid)) { - case SEC_OID_AVA_COMMON_NAME: - string_id = IDS_CERT_OID_AVA_COMMON_NAME; - break; - case SEC_OID_AVA_STATE_OR_PROVINCE: - string_id = IDS_CERT_OID_AVA_STATE_OR_PROVINCE; - break; - case SEC_OID_AVA_ORGANIZATION_NAME: - string_id = IDS_CERT_OID_AVA_ORGANIZATION_NAME; - break; - case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: - string_id = IDS_CERT_OID_AVA_ORGANIZATIONAL_UNIT_NAME; - break; - case SEC_OID_AVA_DN_QUALIFIER: - string_id = IDS_CERT_OID_AVA_DN_QUALIFIER; - break; - case SEC_OID_AVA_COUNTRY_NAME: - string_id = IDS_CERT_OID_AVA_COUNTRY_NAME; - break; - case SEC_OID_AVA_SERIAL_NUMBER: - string_id = IDS_CERT_OID_AVA_SERIAL_NUMBER; - break; - case SEC_OID_AVA_LOCALITY: - string_id = IDS_CERT_OID_AVA_LOCALITY; - break; - case SEC_OID_AVA_DC: - string_id = IDS_CERT_OID_AVA_DC; - break; - case SEC_OID_RFC1274_MAIL: - string_id = IDS_CERT_OID_RFC1274_MAIL; - break; - case SEC_OID_RFC1274_UID: - string_id = IDS_CERT_OID_RFC1274_UID; - break; - case SEC_OID_PKCS9_EMAIL_ADDRESS: - string_id = IDS_CERT_OID_PKCS9_EMAIL_ADDRESS; - break; - case SEC_OID_PKCS1_RSA_ENCRYPTION: - string_id = IDS_CERT_OID_PKCS1_RSA_ENCRYPTION; - break; - case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: - string_id = IDS_CERT_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; - break; - case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: - string_id = IDS_CERT_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION; - break; - case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: - string_id = IDS_CERT_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; - break; - case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: - string_id = IDS_CERT_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; - break; - case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: - string_id = IDS_CERT_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; - break; - case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: - string_id = IDS_CERT_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; - break; - case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: - string_id = IDS_CERT_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; - break; - // There are a billionty other OIDs we could add here. I tried to get the - // important ones... - default: - string_id = -1; - break; - } - if (string_id >= 0) - return l10n_util::GetStringUTF8(string_id); - - char* pr_string = CERT_GetOidString(oid); - if (pr_string) { - std::string rv = pr_string; - PR_smprintf_free(pr_string); - return rv; - } - - return ProcessRawBytes(oid); -} - -// Get a display string from a Relative Distinguished Name. -std::string ProcessRDN(CERTRDN* rdn) { - std::string rv; - - CERTAVA** avas = rdn->avas; - for (size_t i = 0; avas[i] != NULL; ++i) { - rv += GetOIDText(&avas[i]->type); - SECItem* decode_item = CERT_DecodeAVAValue(&avas[i]->value); - if (decode_item) { - // TODO(mattm): Pass decode_item to CERT_RFC1485_EscapeAndQuote. - rv += " = "; - std::string value(reinterpret_cast<char*>(decode_item->data), - decode_item->len); - rv += value; - SECITEM_FreeItem(decode_item, PR_TRUE); - } - rv += '\n'; - } - - return rv; -} - -std::string ProcessName(CERTName* name) { - std::string rv; - CERTRDN** last_rdn; - - // Find last non-NULL rdn. - for (last_rdn = name->rdns; last_rdn[0]; last_rdn++) {} - last_rdn--; - - for (CERTRDN** rdn = last_rdn; rdn >= name->rdns; rdn--) - rv += ProcessRDN(*rdn); - return rv; -} - std::string ProcessSecAlgorithm(SECAlgorithmID* algorithm_id) { - return GetOIDText(&algorithm_id->algorithm); -} - -std::string ProcessExtensionData(SECItem* extension_data) { - // TODO(mattm): should display extension-specific info here (see - // ProcessExtensionData in nsNSSCertHelper.cpp) - return ProcessRawBytes(extension_data); + return psm::GetOIDText(&algorithm_id->algorithm); } std::string ProcessExtension(CERTCertExtension* extension) { @@ -248,13 +78,14 @@ std::string ProcessExtension(CERTCertExtension* extension) { if (extension->critical.data && extension->critical.data[0]) criticality = IDS_CERT_EXTENSION_CRITICAL; rv = l10n_util::GetStringUTF8(criticality) + "\n" + - ProcessExtensionData(&extension->value); + psm::ProcessExtensionData(SECOID_FindOIDTag(&extension->id), + &extension->value); return rv; } std::string ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo* spki) { // TODO(mattm): firefox decodes the key and displays modulus and exponent. - return ProcessRawBits(&spki->subjectPublicKey); + return psm::ProcessRawBits(&spki->subjectPublicKey); } //////////////////////////////////////////////////////////////////////////////// @@ -321,9 +152,9 @@ class CertificateViewer { static GtkTreeStore* CreateFieldsTreeStore(CERTCertificate* cert); // Callbacks for user selecting elements in the trees. - static void OnHierarchySelectionChanged(GtkTreeSelection *selection, + static void OnHierarchySelectionChanged(GtkTreeSelection* selection, CertificateViewer* viewer); - static void OnFieldsSelectionChanged(GtkTreeSelection *selection, + static void OnFieldsSelectionChanged(GtkTreeSelection* selection, CertificateViewer* viewer); // The certificate hierarchy (leaf cert first). @@ -359,7 +190,7 @@ void OnDestroy(GtkDialog* dialog, CertificateViewer* cert_viewer) { CertificateViewer::CertificateViewer(gfx::NativeWindow parent, CERTCertList* cert_chain_list) : cert_chain_list_(cert_chain_list) { - CERTCertListNode *node; + CERTCertListNode* node; for (node = CERT_LIST_HEAD(cert_chain_list_); !CERT_LIST_END(node, cert_chain_list_); node = CERT_LIST_NEXT(node)) { @@ -369,7 +200,7 @@ CertificateViewer::CertificateViewer(gfx::NativeWindow parent, dialog_ = gtk_dialog_new_with_buttons( l10n_util::GetStringFUTF8( IDS_CERT_INFO_DIALOG_TITLE, - UTF8ToUTF16(GetCertTitle(cert_chain_.front()))).c_str(), + UTF8ToUTF16(psm::GetCertTitle(cert_chain_.front()))).c_str(), parent, // Non-modal. GTK_DIALOG_NO_SEPARATOR, @@ -379,6 +210,7 @@ CertificateViewer::CertificateViewer(gfx::NativeWindow parent, gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(dialog_)->vbox), gtk_util::kContentAreaSpacing); + psm::RegisterDynamicOids(); InitGeneralPage(); InitDetailsPage(); @@ -430,10 +262,10 @@ void CertificateViewer::InitGeneralPage() { NULL, &usages) == SECSuccess) { // List of usages to display is borrowed from // mozilla/source/security/manager/ssl/src/nsUsageArrayHelper.cpp - struct { + static const struct { SECCertificateUsage usage; int string_id; - } usageStringMap[] = { + } usage_string_map[] = { {certificateUsageSSLClient, IDS_CERT_USAGE_SSL_CLIENT}, {certificateUsageSSLServer, IDS_CERT_USAGE_SSL_SERVER}, {certificateUsageSSLServerWithStepUp, @@ -444,13 +276,13 @@ void CertificateViewer::InitGeneralPage() { {certificateUsageSSLCA, IDS_CERT_USAGE_SSL_CA}, {certificateUsageStatusResponder, IDS_CERT_USAGE_STATUS_RESPONDER}, }; - for (size_t i = 0; i < ARRAYSIZE_UNSAFE(usageStringMap); ++i) { - if (usages & usageStringMap[i].usage) + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(usage_string_map); ++i) { + if (usages & usage_string_map[i].usage) gtk_box_pack_start( GTK_BOX(uses_vbox), gtk_util::IndentWidget(gtk_util::LeftAlignMisc(gtk_label_new( l10n_util::GetStringUTF8( - usageStringMap[i].string_id).c_str()))), + usage_string_map[i].string_id).c_str()))), FALSE, FALSE, 0); } } @@ -542,7 +374,7 @@ void CertificateViewer::FillHierarchyStore(GtkTreeStore* hierarchy_store, GtkTreeStore* fields_store = CreateFieldsTreeStore(*i); gtk_tree_store_set( hierarchy_store, &iter, - HIERARCHY_NAME, GetCertTitle(*i).c_str(), + HIERARCHY_NAME, psm::GetCertTitle(*i).c_str(), HIERARCHY_OBJECT, fields_store, -1); g_object_unref(fields_store); @@ -559,7 +391,7 @@ void CertificateViewer::FillTreeStoreWithCertFields(GtkTreeStore* store, gtk_tree_store_append(store, &top, NULL); gtk_tree_store_set( store, &top, - FIELDS_NAME, GetCertTitle(cert).c_str(), + FIELDS_NAME, psm::GetCertTitle(cert).c_str(), FIELDS_VALUE, "", -1); @@ -608,7 +440,7 @@ void CertificateViewer::FillTreeStoreWithCertFields(GtkTreeStore* store, store, &iter, FIELDS_NAME, l10n_util::GetStringUTF8(IDS_CERT_DETAILS_ISSUER).c_str(), - FIELDS_VALUE, ProcessName(&cert->issuer).c_str(), + FIELDS_VALUE, psm::ProcessName(&cert->issuer).c_str(), -1); GtkTreeIter validity_iter; @@ -648,7 +480,7 @@ void CertificateViewer::FillTreeStoreWithCertFields(GtkTreeStore* store, store, &iter, FIELDS_NAME, l10n_util::GetStringUTF8(IDS_CERT_DETAILS_SUBJECT).c_str(), - FIELDS_VALUE, ProcessName(&cert->subject).c_str(), + FIELDS_VALUE, psm::ProcessName(&cert->subject).c_str(), -1); GtkTreeIter subject_public_key_iter; @@ -692,7 +524,7 @@ void CertificateViewer::FillTreeStoreWithCertFields(GtkTreeStore* store, gtk_tree_store_append(store, &iter, &extensions_iter); gtk_tree_store_set( store, &iter, - FIELDS_NAME, GetOIDText(&cert->extensions[i]->id).c_str(), + FIELDS_NAME, psm::GetOIDText(&cert->extensions[i]->id).c_str(), FIELDS_VALUE, ProcessExtension(cert->extensions[i]).c_str(), -1); } @@ -712,7 +544,7 @@ void CertificateViewer::FillTreeStoreWithCertFields(GtkTreeStore* store, store, &iter, FIELDS_NAME, l10n_util::GetStringUTF8(IDS_CERT_DETAILS_CERTIFICATE_SIG_VALUE).c_str(), - FIELDS_VALUE, ProcessRawBits(&cert->signatureWrap.signature).c_str(), + FIELDS_VALUE, psm::ProcessRawBits(&cert->signatureWrap.signature).c_str(), -1); } @@ -836,7 +668,7 @@ void CertificateViewer::InitDetailsPage() { // static void CertificateViewer::OnHierarchySelectionChanged( - GtkTreeSelection *selection, CertificateViewer* viewer) { + GtkTreeSelection* selection, CertificateViewer* viewer) { GtkTreeIter iter; GtkTreeModel* model; if (gtk_tree_selection_get_selected(selection, &model, &iter)) { @@ -851,7 +683,7 @@ void CertificateViewer::OnHierarchySelectionChanged( } // static -void CertificateViewer::OnFieldsSelectionChanged(GtkTreeSelection *selection, +void CertificateViewer::OnFieldsSelectionChanged(GtkTreeSelection* selection, CertificateViewer* viewer) { GtkTreeIter iter; GtkTreeModel* model; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 2acdcda..ffdac13 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2255,6 +2255,10 @@ 'sources': [ 'browser/crash_handler_host_linux.h', 'browser/net/ssl_config_service_manager_pref.cc', + 'third_party/mozilla_security_manager/nsNSSCertHelper.cpp', + 'third_party/mozilla_security_manager/nsNSSCertHelper.h', + 'third_party/mozilla_security_manager/nsNSSCertificate.cpp', + 'third_party/mozilla_security_manager/nsNSSCertificate.h', ], 'conditions': [ ['linux_breakpad==1', { diff --git a/chrome/third_party/mozilla_security_manager/README.chromium b/chrome/third_party/mozilla_security_manager/README.chromium new file mode 100644 index 0000000..18bb62b --- /dev/null +++ b/chrome/third_party/mozilla_security_manager/README.chromium @@ -0,0 +1,12 @@ +URL: http://mxr.mozilla.org/mozilla-central/source/security/manager/ +InfoURL: http://www.mozilla.org/ +Version: 36838:a59a5f030021 +License: MPL 1.1/GPL 2.0/LGPL 2.1 + +Description: +This is selected code bits from Mozilla's Personal Security Manager. + +Local Modifications: +Files are forked from Mozilla's because of the heavy adaptations necessary. +Differences are using Chromium localization and other libraries instead of +Mozilla's, matching the Chromium style, etc. diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp new file mode 100644 index 0000000..6f6d9f2 --- /dev/null +++ b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.cpp @@ -0,0 +1,811 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Ian McGreer <mcgreer@netscape.com> + * Javier Delgadillo <javi@netscape.com> + * John Gardiner Myers <jgmyers@speakeasy.net> + * Martin v. Loewis <martin@v.loewis.de> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h" + +#include <prprf.h> + +#include "app/l10n_util.h" +#include "base/i18n/number_formatting.h" +#include "grit/generated_resources.h" +#include "net/base/net_util.h" + +namespace { + +std::string BMPtoUTF8(PRArenaPool* arena, unsigned char* data, + unsigned int len) { + if (len % 2 != 0) + return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + + unsigned int utf8_val_len = len * 3 + 1; + std::vector<unsigned char> utf8_val(utf8_val_len); + if (!PORT_UCS2_UTF8Conversion(PR_FALSE, data, len, + &utf8_val.front(), utf8_val_len, &utf8_val_len)) + return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + return std::string(reinterpret_cast<char*>(&utf8_val.front()), utf8_val_len); +} + +} // namespace + +namespace mozilla_security_manager { + +SECOidTag ms_cert_ext_certtype = SEC_OID_UNKNOWN; +SECOidTag ms_certsrv_ca_version = SEC_OID_UNKNOWN; +SECOidTag ms_nt_principal_name = SEC_OID_UNKNOWN; +SECOidTag ms_ntds_replication = SEC_OID_UNKNOWN; +#define MICROSOFT_OID 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0x37 +static const unsigned char kMsCertExtCerttype[] = {MICROSOFT_OID, 20, 2}; +static const unsigned char kMsCertSrvCAVersion[] = {MICROSOFT_OID, 21, 1}; +static const unsigned char kMsNTPrincipalName[] = {MICROSOFT_OID, 20, 2, 3}; +static const unsigned char kMsNTDSReplication[] = {MICROSOFT_OID, 25, 1}; + +void RegisterDynamicOids() { + if (ms_cert_ext_certtype != SEC_OID_UNKNOWN) + return; + + SECOidData od; + od.oid.data = const_cast<unsigned char*>(kMsCertExtCerttype); + od.oid.len = sizeof(kMsCertExtCerttype); + od.offset = SEC_OID_UNKNOWN; + od.mechanism = CKM_INVALID_MECHANISM; + od.supportedExtension = INVALID_CERT_EXTENSION; + od.desc = "ms_cert_ext_certtype"; + ms_cert_ext_certtype = SECOID_AddEntry(&od); + DCHECK_NE(ms_cert_ext_certtype, SEC_OID_UNKNOWN); + + od.oid.data = const_cast<unsigned char*>(kMsCertSrvCAVersion); + od.oid.len = sizeof(kMsCertSrvCAVersion); + od.offset = SEC_OID_UNKNOWN; + od.mechanism = CKM_INVALID_MECHANISM; + od.supportedExtension = INVALID_CERT_EXTENSION; + od.desc = "ms_certsrv_ca_version"; + ms_certsrv_ca_version = SECOID_AddEntry(&od); + DCHECK_NE(ms_certsrv_ca_version, SEC_OID_UNKNOWN); + + od.oid.data = const_cast<unsigned char*>(kMsNTPrincipalName); + od.oid.len = sizeof(kMsNTPrincipalName); + od.offset = SEC_OID_UNKNOWN; + od.mechanism = CKM_INVALID_MECHANISM; + od.supportedExtension = INVALID_CERT_EXTENSION; + od.desc = "ms_nt_principal_name"; + ms_nt_principal_name = SECOID_AddEntry(&od); + DCHECK_NE(ms_nt_principal_name, SEC_OID_UNKNOWN); + + od.oid.data = const_cast<unsigned char*>(kMsNTDSReplication); + od.oid.len = sizeof(kMsNTDSReplication); + od.offset = SEC_OID_UNKNOWN; + od.mechanism = CKM_INVALID_MECHANISM; + od.supportedExtension = INVALID_CERT_EXTENSION; + od.desc = "ms_ntds_replication"; + ms_ntds_replication = SECOID_AddEntry(&od); + DCHECK_NE(ms_ntds_replication, SEC_OID_UNKNOWN); +} + +std::string ProcessRawBytes(SECItem* data) { + static const char kHexChars[] = "0123456789ABCDEF"; + + // Each input byte creates two output hex characters + a space or newline, + // except for the last byte. + std::string ret(std::max(0u, data->len * 3 - 1), '\0'); + + for (size_t i = 0; i < data->len; ++i) { + unsigned char b = data->data[i]; + ret[i * 3] = kHexChars[(b >> 4) & 0xf]; + ret[i * 3 + 1] = kHexChars[b & 0xf]; + if (i + 1 < data->len) { + if ((i + 1) % 16 == 0) + ret[i * 3 + 2] = '\n'; + else + ret[i * 3 + 2] = ' '; + } + } + return ret; +} + +std::string ProcessRawBits(SECItem* data) { + SECItem bytedata; + bytedata.data = data->data; + bytedata.len = data->len / 8; + return ProcessRawBytes(&bytedata); +} + +std::string DumpOidString(SECItem* oid) { + char* pr_string = CERT_GetOidString(oid); + if (pr_string) { + std::string rv = pr_string; + PR_smprintf_free(pr_string); + return rv; + } + + return ProcessRawBytes(oid); +} + +std::string GetOIDText(SECItem* oid) { + int string_id; + SECOidTag oid_tag = SECOID_FindOIDTag(oid); + switch (oid_tag) { + case SEC_OID_AVA_COMMON_NAME: + string_id = IDS_CERT_OID_AVA_COMMON_NAME; + break; + case SEC_OID_AVA_STATE_OR_PROVINCE: + string_id = IDS_CERT_OID_AVA_STATE_OR_PROVINCE; + break; + case SEC_OID_AVA_ORGANIZATION_NAME: + string_id = IDS_CERT_OID_AVA_ORGANIZATION_NAME; + break; + case SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME: + string_id = IDS_CERT_OID_AVA_ORGANIZATIONAL_UNIT_NAME; + break; + case SEC_OID_AVA_DN_QUALIFIER: + string_id = IDS_CERT_OID_AVA_DN_QUALIFIER; + break; + case SEC_OID_AVA_COUNTRY_NAME: + string_id = IDS_CERT_OID_AVA_COUNTRY_NAME; + break; + case SEC_OID_AVA_SERIAL_NUMBER: + string_id = IDS_CERT_OID_AVA_SERIAL_NUMBER; + break; + case SEC_OID_AVA_LOCALITY: + string_id = IDS_CERT_OID_AVA_LOCALITY; + break; + case SEC_OID_AVA_DC: + string_id = IDS_CERT_OID_AVA_DC; + break; + case SEC_OID_RFC1274_MAIL: + string_id = IDS_CERT_OID_RFC1274_MAIL; + break; + case SEC_OID_RFC1274_UID: + string_id = IDS_CERT_OID_RFC1274_UID; + break; + case SEC_OID_PKCS9_EMAIL_ADDRESS: + string_id = IDS_CERT_OID_PKCS9_EMAIL_ADDRESS; + break; + case SEC_OID_PKCS1_RSA_ENCRYPTION: + string_id = IDS_CERT_OID_PKCS1_RSA_ENCRYPTION; + break; + case SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION: + string_id = IDS_CERT_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; + break; + case SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION: + string_id = IDS_CERT_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION; + break; + case SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION: + string_id = IDS_CERT_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; + break; + case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION: + string_id = IDS_CERT_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; + break; + case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION: + string_id = IDS_CERT_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; + break; + case SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION: + string_id = IDS_CERT_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; + break; + case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION: + string_id = IDS_CERT_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; + break; + case SEC_OID_NS_CERT_EXT_CERT_TYPE: + string_id = IDS_CERT_EXT_NS_CERT_TYPE; + break; + case SEC_OID_NS_CERT_EXT_BASE_URL: + string_id = IDS_CERT_EXT_NS_CERT_BASE_URL; + break; + case SEC_OID_NS_CERT_EXT_REVOCATION_URL: + string_id = IDS_CERT_EXT_NS_CERT_REVOCATION_URL; + break; + case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL: + string_id = IDS_CERT_EXT_NS_CA_REVOCATION_URL; + break; + case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL: + string_id = IDS_CERT_EXT_NS_CERT_RENEWAL_URL; + break; + case SEC_OID_NS_CERT_EXT_CA_POLICY_URL: + string_id = IDS_CERT_EXT_NS_CA_POLICY_URL; + break; + case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME: + string_id = IDS_CERT_EXT_NS_SSL_SERVER_NAME; + break; + case SEC_OID_NS_CERT_EXT_COMMENT: + string_id = IDS_CERT_EXT_NS_COMMENT; + break; + case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL: + string_id = IDS_CERT_EXT_NS_LOST_PASSWORD_URL; + break; + case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME: + string_id = IDS_CERT_EXT_NS_CERT_RENEWAL_TIME; + break; + case SEC_OID_X509_SUBJECT_DIRECTORY_ATTR: + string_id = IDS_CERT_X509_SUBJECT_DIRECTORY_ATTR; + break; + case SEC_OID_X509_SUBJECT_KEY_ID: + string_id = IDS_CERT_X509_SUBJECT_KEYID; + break; + case SEC_OID_X509_KEY_USAGE: + string_id = IDS_CERT_X509_KEY_USAGE; + break; + case SEC_OID_X509_SUBJECT_ALT_NAME: + string_id = IDS_CERT_X509_SUBJECT_ALT_NAME; + break; + case SEC_OID_X509_ISSUER_ALT_NAME: + string_id = IDS_CERT_X509_ISSUER_ALT_NAME; + break; + case SEC_OID_X509_BASIC_CONSTRAINTS: + string_id = IDS_CERT_X509_BASIC_CONSTRAINTS; + break; + case SEC_OID_X509_NAME_CONSTRAINTS: + string_id = IDS_CERT_X509_NAME_CONSTRAINTS; + break; + case SEC_OID_X509_CRL_DIST_POINTS: + string_id = IDS_CERT_X509_CRL_DIST_POINTS; + break; + case SEC_OID_X509_CERTIFICATE_POLICIES: + string_id = IDS_CERT_X509_CERT_POLICIES; + break; + case SEC_OID_X509_POLICY_MAPPINGS: + string_id = IDS_CERT_X509_POLICY_MAPPINGS; + break; + case SEC_OID_X509_POLICY_CONSTRAINTS: + string_id = IDS_CERT_X509_POLICY_CONSTRAINTS; + break; + case SEC_OID_X509_AUTH_KEY_ID: + string_id = IDS_CERT_X509_AUTH_KEYID; + break; + case SEC_OID_X509_EXT_KEY_USAGE: + string_id = IDS_CERT_X509_EXT_KEY_USAGE; + break; + case SEC_OID_X509_AUTH_INFO_ACCESS: + string_id = IDS_CERT_X509_AUTH_INFO_ACCESS; + break; + + // There are a billionty other OIDs we could add here. I tried to get the + // important ones... + default: + if (oid_tag == ms_cert_ext_certtype) + string_id = IDS_CERT_EXT_MS_CERT_TYPE; + else if (oid_tag == ms_certsrv_ca_version) + string_id = IDS_CERT_EXT_MS_CA_VERSION; + else if (oid_tag == ms_nt_principal_name) + string_id = IDS_CERT_EXT_MS_NT_PRINCIPAL_NAME; + else if (oid_tag == ms_ntds_replication) + string_id = IDS_CERT_EXT_MS_NTDS_REPLICATION; + else + string_id = -1; + break; + } + if (string_id >= 0) + return l10n_util::GetStringUTF8(string_id); + + return DumpOidString(oid); +} + + +// Get a display string from a Relative Distinguished Name. +std::string ProcessRDN(CERTRDN* rdn) { + std::string rv; + + CERTAVA** avas = rdn->avas; + for (size_t i = 0; avas[i] != NULL; ++i) { + rv += GetOIDText(&avas[i]->type); + SECItem* decode_item = CERT_DecodeAVAValue(&avas[i]->value); + if (decode_item) { + // TODO(mattm): Pass decode_item to CERT_RFC1485_EscapeAndQuote. + rv += " = "; + std::string value(reinterpret_cast<char*>(decode_item->data), + decode_item->len); + rv += value; + SECITEM_FreeItem(decode_item, PR_TRUE); + } + rv += '\n'; + } + + return rv; +} + +std::string ProcessName(CERTName* name) { + std::string rv; + CERTRDN** last_rdn; + + // Find last non-NULL rdn. + for (last_rdn = name->rdns; last_rdn[0]; last_rdn++) {} + last_rdn--; + + for (CERTRDN** rdn = last_rdn; rdn >= name->rdns; rdn--) + rv += ProcessRDN(*rdn); + return rv; +} + +std::string ProcessBasicConstraints(SECItem* extension_data) { + CERTBasicConstraints value; + value.pathLenConstraint = -1; + if (CERT_DecodeBasicConstraintValue(&value, extension_data) != SECSuccess) + return ProcessRawBytes(extension_data); + + std::string rv; + if (value.isCA) + rv = l10n_util::GetStringUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_IS_CA); + else + rv = l10n_util::GetStringUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_IS_NOT_CA); + rv += '\n'; + if (value.pathLenConstraint != -1) { + string16 depth; + if (value.pathLenConstraint == CERT_UNLIMITED_PATH_CONSTRAINT) { + depth = l10n_util::GetStringUTF16( + IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN_UNLIMITED); + } else { + depth = base::FormatNumber(value.pathLenConstraint); + } + rv += l10n_util::GetStringFUTF8(IDS_CERT_X509_BASIC_CONSTRAINT_PATH_LEN, + depth); + } + return rv; +} + +std::string ProcessGeneralName(PRArenaPool* arena, + CERTGeneralName* current) { + DCHECK(current); + + std::string key; + std::string value; + + switch (current->type) { + case certOtherName: { + key = GetOIDText(¤t->name.OthName.oid); + SECOidTag oid_tag = SECOID_FindOIDTag(¤t->name.OthName.oid); + if (oid_tag == ms_nt_principal_name) { + // The type of this name is apparently nowhere explicitly + // documented. However, in the generated templates, it is always + // UTF-8. So try to decode this as UTF-8; if that fails, dump the + // raw data. + SECItem decoded; + if (SEC_ASN1DecodeItem(arena, &decoded, + SEC_ASN1_GET(SEC_UTF8StringTemplate), + ¤t->name.OthName.name) == SECSuccess) { + value = std::string(reinterpret_cast<char*>(decoded.data), + decoded.len); + } else { + value = ProcessRawBytes(¤t->name.OthName.name); + } + break; + } else if (oid_tag == ms_ntds_replication) { + // This should be a 16-byte GUID. + SECItem guid; + if (SEC_ASN1DecodeItem(arena, &guid, + SEC_ASN1_GET(SEC_OctetStringTemplate), + ¤t->name.OthName.name) == SECSuccess && + guid.len == 16) { + unsigned char* d = guid.data; + SStringPrintf(&value, + "{%.2x%.2x%.2x%.2x-%.2x%.2x-%.2x%.2x-" + "%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x}", + d[3], d[2], d[1], d[0], d[5], d[4], d[7], d[6], + d[8], d[9], d[10], d[11], d[12], d[13], d[14], d[15]); + } else { + value = ProcessRawBytes(¤t->name.OthName.name); + } + } else { + value = ProcessRawBytes(¤t->name.OthName.name); + } + break; + } + case certRFC822Name: + key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_RFC822_NAME); + value = std::string(reinterpret_cast<char*>(current->name.other.data), + current->name.other.len); + break; + case certDNSName: + key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_DNS_NAME); + value = std::string(reinterpret_cast<char*>(current->name.other.data), + current->name.other.len); + break; + case certX400Address: + key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_X400_ADDRESS); + value = ProcessRawBytes(¤t->name.other); + break; + case certDirectoryName: + key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_DIRECTORY_NAME); + value = ProcessName(¤t->name.directoryName); + break; + case certEDIPartyName: + key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_EDI_PARTY_NAME); + value = ProcessRawBytes(¤t->name.other); + break; + case certURI: + key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_URI); + value = std::string(reinterpret_cast<char*>(current->name.other.data), + current->name.other.len); + break; + case certIPAddress: { + key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_IP_ADDRESS); + struct addrinfo addr = {0}; + if (current->name.other.len == 4) { + struct sockaddr_in addr4 = {0}; + addr.ai_addr = reinterpret_cast<sockaddr*>(&addr4); + addr.ai_addrlen = sizeof(addr4); + addr.ai_family = AF_INET; + addr4.sin_family = addr.ai_family; + memcpy(&addr4.sin_addr, current->name.other.data, + current->name.other.len); + value = net::NetAddressToString(&addr); + } else if (current->name.other.len == 16) { + struct sockaddr_in6 addr6 = {0}; + addr.ai_addr = reinterpret_cast<sockaddr*>(&addr6); + addr.ai_addrlen = sizeof(addr6); + addr.ai_family = AF_INET6; + addr6.sin6_family = addr.ai_family; + memcpy(&addr6.sin6_addr, current->name.other.data, + current->name.other.len); + value = net::NetAddressToString(&addr); + } + if (value.empty()) { + // Invalid IP address. + value = ProcessRawBytes(¤t->name.other); + } + break; + } + case certRegisterID: + key = l10n_util::GetStringUTF8(IDS_CERT_GENERAL_NAME_REGISTERED_ID); + value = DumpOidString(¤t->name.other); + break; + } + std::string rv(l10n_util::GetStringFUTF8(IDS_CERT_UNKNOWN_OID_INFO_FORMAT, + UTF8ToUTF16(key), + UTF8ToUTF16(value))); + rv += '\n'; + return rv; +} + +std::string ProcessGeneralNames(PRArenaPool* arena, + CERTGeneralName* name_list) { + std::string rv; + CERTGeneralName* current = name_list; + + do { + std::string text = ProcessGeneralName(arena, current); + if (text.empty()) + break; + rv += text + '\n'; + current = CERT_GetNextGeneralName(current); + } while (current != name_list); + return rv; +} + +std::string ProcessAltName(SECItem* extension_data) { + CERTGeneralName* name_list; + + ScopedPRArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + CHECK(arena.get()); + + name_list = CERT_DecodeAltNameExtension(arena.get(), extension_data); + if (!name_list) + return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + + return ProcessGeneralNames(arena.get(), name_list); +} + +std::string ProcessSubjectKeyId(SECItem* extension_data) { + SECItem decoded; + ScopedPRArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + CHECK(arena.get()); + + std::string rv; + if (SEC_QuickDERDecodeItem(arena.get(), &decoded, + SEC_ASN1_GET(SEC_OctetStringTemplate), + extension_data) != SECSuccess) { + rv = l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + return rv; + } + + rv = l10n_util::GetStringFUTF8(IDS_CERT_KEYID_FORMAT, + ASCIIToUTF16(ProcessRawBytes(&decoded))); + return rv; +} + +std::string ProcessAuthKeyId(SECItem* extension_data) { + CERTAuthKeyID* ret; + ScopedPRArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + std::string rv; + + CHECK(arena.get()); + + ret = CERT_DecodeAuthKeyID(arena.get(), extension_data); + + if (ret->keyID.len > 0) { + rv += l10n_util::GetStringFUTF8(IDS_CERT_KEYID_FORMAT, + ASCIIToUTF16(ProcessRawBytes(&ret->keyID))); + rv += '\n'; + } + + if (ret->authCertIssuer) { + rv += l10n_util::GetStringFUTF8( + IDS_CERT_ISSUER_FORMAT, + UTF8ToUTF16(ProcessGeneralNames(arena.get(), ret->authCertIssuer))); + rv += '\n'; + } + + if (ret->authCertSerialNumber.len > 0) { + rv += l10n_util::GetStringFUTF8( + IDS_CERT_SERIAL_NUMBER_FORMAT, + ASCIIToUTF16(ProcessRawBytes(&ret->authCertSerialNumber))); + rv += '\n'; + } + + return rv; +} + +std::string ProcessCrlDistPoints(SECItem* extension_data) { + std::string rv; + CERTCrlDistributionPoints* crldp; + CRLDistributionPoint** points; + CRLDistributionPoint* point; + bool comma; + + static const struct { + int reason; + int string_id; + } reason_string_map[] = { + {RF_UNUSED, IDS_CERT_REVOCATION_REASON_UNUSED}, + {RF_KEY_COMPROMISE, IDS_CERT_REVOCATION_REASON_KEY_COMPROMISE}, + {RF_CA_COMPROMISE, IDS_CERT_REVOCATION_REASON_CA_COMPROMISE}, + {RF_AFFILIATION_CHANGED, IDS_CERT_REVOCATION_REASON_AFFILIATION_CHANGED}, + {RF_SUPERSEDED, IDS_CERT_REVOCATION_REASON_SUPERSEDED}, + {RF_CESSATION_OF_OPERATION, + IDS_CERT_REVOCATION_REASON_CESSATION_OF_OPERATION}, + {RF_CERTIFICATE_HOLD, IDS_CERT_REVOCATION_REASON_CERTIFICATE_HOLD}, + }; + + ScopedPRArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + CHECK(arena.get()); + + crldp = CERT_DecodeCRLDistributionPoints(arena.get(), extension_data); + if (!crldp || !crldp->distPoints) { + rv = l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + return rv; + } + + for (points = crldp->distPoints; *points; ++points) { + point = *points; + switch (point->distPointType) { + case generalName: + rv += ProcessGeneralName(arena.get(), point->distPoint.fullName); + break; + case relativeDistinguishedName: + rv += ProcessRDN(&point->distPoint.relativeName); + break; + } + if (point->reasons.len) { + rv += ' '; + comma = false; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(reason_string_map); ++i) { + if (point->reasons.data[0] & reason_string_map[i].reason) { + if (comma) + rv += ','; + rv += l10n_util::GetStringUTF8(reason_string_map[i].string_id); + } + } + rv += '\n'; + } + if (point->crlIssuer) { + rv += l10n_util::GetStringFUTF8( + IDS_CERT_ISSUER_FORMAT, + UTF8ToUTF16(ProcessGeneralNames(arena.get(), point->crlIssuer))); + } + } + return rv; +} + +std::string ProcessAuthInfoAccess(SECItem* extension_data) { + std::string rv; + CERTAuthInfoAccess** aia; + CERTAuthInfoAccess* desc; + ScopedPRArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + CHECK(arena.get()); + + aia = CERT_DecodeAuthInfoAccessExtension(arena.get(), extension_data); + if (aia == NULL) + return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + + while (*aia != NULL) { + desc = *aia++; + string16 location_str = UTF8ToUTF16(ProcessGeneralName(arena.get(), + desc->location)); + switch (SECOID_FindOIDTag(&desc->method)) { + case SEC_OID_PKIX_OCSP: + rv += l10n_util::GetStringFUTF8(IDS_CERT_OCSP_RESPONDER_FORMAT, + location_str); + break; + case SEC_OID_PKIX_CA_ISSUERS: + rv += l10n_util::GetStringFUTF8(IDS_CERT_CA_ISSUERS_FORMAT, + location_str); + break; + default: + rv += l10n_util::GetStringFUTF8(IDS_CERT_UNKNOWN_OID_INFO_FORMAT, + UTF8ToUTF16(GetOIDText(&desc->method)), + location_str); + break; + } + } + return rv; +} + +std::string ProcessIA5String(SECItem* extension_data) { + SECItem item; + if (SEC_ASN1DecodeItem(NULL, &item, SEC_ASN1_GET(SEC_IA5StringTemplate), + extension_data) != SECSuccess) + return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + std::string rv((char*)item.data, item.len); // ASCII data. + PORT_Free(item.data); + return rv; +} + +std::string ProcessBMPString(SECItem* extension_data) { + std::string rv; + SECItem item; + ScopedPRArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + CHECK(arena.get()); + + if (SEC_ASN1DecodeItem(arena.get(), &item, + SEC_ASN1_GET(SEC_BMPStringTemplate), extension_data) == + SECSuccess) + rv = BMPtoUTF8(arena.get(), item.data, item.len); + return rv; +} + +struct MaskIdPair { + unsigned char mask; + int string_id; +}; + +static std::string ProcessBitStringExtension(SECItem* extension_data, + const MaskIdPair* string_map, + size_t len) { + SECItem decoded; + decoded.type = siBuffer; + decoded.data = NULL; + decoded.len = 0; + if (SEC_ASN1DecodeItem(NULL, &decoded, SEC_ASN1_GET(SEC_BitStringTemplate), + extension_data) != SECSuccess) + return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + + std::string rv; + for (size_t i = 0; i < len; ++i) { + if (decoded.data[0] & string_map[i].mask) { + rv += l10n_util::GetStringUTF8(string_map[i].string_id) + '\n'; + } + } + PORT_Free(decoded.data); + return rv; +} + +std::string ProcessNSCertTypeExtension(SECItem* extension_data) { + MaskIdPair usage_string_map[] = { + {NS_CERT_TYPE_SSL_CLIENT, IDS_CERT_USAGE_SSL_CLIENT}, + {NS_CERT_TYPE_SSL_SERVER, IDS_CERT_USAGE_SSL_SERVER}, + {NS_CERT_TYPE_EMAIL, IDS_CERT_EXT_NS_CERT_TYPE_EMAIL}, + {NS_CERT_TYPE_OBJECT_SIGNING, IDS_CERT_USAGE_OBJECT_SIGNER}, + {NS_CERT_TYPE_SSL_CA, IDS_CERT_USAGE_SSL_CA}, + {NS_CERT_TYPE_EMAIL_CA, IDS_CERT_EXT_NS_CERT_TYPE_EMAIL_CA}, + {NS_CERT_TYPE_OBJECT_SIGNING_CA, IDS_CERT_USAGE_OBJECT_SIGNER}, + }; + return ProcessBitStringExtension(extension_data, usage_string_map, + ARRAYSIZE_UNSAFE(usage_string_map)); +} + +std::string ProcessKeyUsageExtension(SECItem* extension_data) { + MaskIdPair usage_string_map[] = { + {KU_DIGITAL_SIGNATURE, IDS_CERT_X509_KEY_USAGE_SIGNING}, + {KU_NON_REPUDIATION, IDS_CERT_X509_KEY_USAGE_NONREP}, + {KU_KEY_ENCIPHERMENT, IDS_CERT_X509_KEY_USAGE_ENCIPHERMENT}, + {KU_DATA_ENCIPHERMENT, IDS_CERT_X509_KEY_USAGE_DATA_ENCIPHERMENT}, + {KU_KEY_AGREEMENT, IDS_CERT_X509_KEY_USAGE_KEY_AGREEMENT}, + {KU_KEY_CERT_SIGN, IDS_CERT_X509_KEY_USAGE_CERT_SIGNER}, + {KU_CRL_SIGN, IDS_CERT_X509_KEY_USAGE_CRL_SIGNER}, + }; + return ProcessBitStringExtension(extension_data, usage_string_map, + ARRAYSIZE_UNSAFE(usage_string_map)); +} + +std::string ProcessExtKeyUsage(SECItem* extension_data) { + std::string rv; + CERTOidSequence* extension_key_usage = NULL; + extension_key_usage = CERT_DecodeOidSequence(extension_data); + if (extension_key_usage == NULL) + return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + + SECItem** oids; + SECItem* oid; + for (oids = extension_key_usage->oids; oids != NULL && *oids != NULL; + ++oids) { + // TODO(mattm): Need to either lookup strings here based on the OIDs or add + // more OIDS to GetOIDText. (See the strings of the form + // CertDumpEKU_<underlined-OID> in Mozilla.) + + oid = *oids; + rv += GetOIDText(oid); + rv += '\n'; + } + CERT_DestroyOidSequence(extension_key_usage); + return rv; +} + +std::string ProcessExtensionData(SECOidTag oid_tag, SECItem* extension_data) { + // This (and its sub-functions) are based on the same-named functions in + // security/manager/ssl/src/nsNSSCertHelper.cpp. + switch (oid_tag) { + case SEC_OID_NS_CERT_EXT_CERT_TYPE: + return ProcessNSCertTypeExtension(extension_data); + case SEC_OID_X509_KEY_USAGE: + return ProcessKeyUsageExtension(extension_data); + case SEC_OID_X509_BASIC_CONSTRAINTS: + return ProcessBasicConstraints(extension_data); + case SEC_OID_X509_EXT_KEY_USAGE: + return ProcessExtKeyUsage(extension_data); + case SEC_OID_X509_ISSUER_ALT_NAME: + case SEC_OID_X509_SUBJECT_ALT_NAME: + return ProcessAltName(extension_data); + case SEC_OID_X509_SUBJECT_KEY_ID: + return ProcessSubjectKeyId(extension_data); + case SEC_OID_X509_AUTH_KEY_ID: + return ProcessAuthKeyId(extension_data); + // TODO(mattm): + // case SEC_OID_X509_CERTIFICATE_POLICIES: + // return ProcessCertificatePolicies(extension_data, ev_oid_tag); + case SEC_OID_X509_CRL_DIST_POINTS: + return ProcessCrlDistPoints(extension_data); + case SEC_OID_X509_AUTH_INFO_ACCESS: + return ProcessAuthInfoAccess(extension_data); + case SEC_OID_NS_CERT_EXT_BASE_URL: + case SEC_OID_NS_CERT_EXT_REVOCATION_URL: + case SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL: + case SEC_OID_NS_CERT_EXT_CA_CERT_URL: + case SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL: + case SEC_OID_NS_CERT_EXT_CA_POLICY_URL: + case SEC_OID_NS_CERT_EXT_HOMEPAGE_URL: + case SEC_OID_NS_CERT_EXT_COMMENT: + case SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME: + case SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL: + return ProcessIA5String(extension_data); + default: + if (oid_tag == ms_cert_ext_certtype) + return ProcessBMPString(extension_data); + return ProcessRawBytes(extension_data); + } +} + +} // namespace mozilla_security_manager diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h new file mode 100644 index 0000000..ba0a445 --- /dev/null +++ b/chrome/third_party/mozilla_security_manager/nsNSSCertHelper.h @@ -0,0 +1,97 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Ian McGreer <mcgreer@netscape.com> + * Javier Delgadillo <javi@netscape.com> + * John Gardiner Myers <jgmyers@speakeasy.net> + * Martin v. Loewis <martin@v.loewis.de> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTHELPER_H_ +#define CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTHELPER_H_ + +#include <cert.h> + +#include <string> + +#include "base/scoped_ptr.h" + +class FreePRArenaPool { + public: + inline void operator()(PRArenaPool* x) const { + PORT_FreeArena(x, PR_FALSE); + } +}; +typedef scoped_ptr_malloc<PRArenaPool, FreePRArenaPool> ScopedPRArenaPool; + +namespace mozilla_security_manager { + +extern SECOidTag ms_cert_ext_certtype; +extern SECOidTag ms_certsrv_ca_version; +extern SECOidTag ms_nt_principal_name; +extern SECOidTag ms_ntds_replication; + +void RegisterDynamicOids(); + +// Format a SECItem as a space separated string, with 16 bytes on each line. +std::string ProcessRawBytes(SECItem* data); + +// For fields which have the length specified in bits, rather than bytes. +std::string ProcessRawBits(SECItem* data); + +std::string DumpOidString(SECItem* oid); +std::string GetOIDText(SECItem* oid); + +std::string ProcessRDN(CERTRDN* rdn); +std::string ProcessName(CERTName* name); +std::string ProcessBasicConstraints(SECItem* extension_data); +std::string ProcessGeneralName(PRArenaPool* arena, + CERTGeneralName* current); +std::string ProcessGeneralNames(PRArenaPool* arena, + CERTGeneralName* name_list); +std::string ProcessAltName(SECItem* extension_data); +std::string ProcessSubjectKeyId(SECItem* extension_data); +std::string ProcessAuthKeyId(SECItem* extension_data); +std::string ProcessCrlDistPoints(SECItem* extension_data); +std::string ProcessAuthInfoAccess(SECItem* extension_data); +std::string ProcessIA5String(SECItem* extension_data); +std::string ProcessBMPString(SECItem* extension_data); +std::string ProcessNSCertTypeExtension(SECItem* extension_data); +std::string ProcessKeyUsageExtension(SECItem* extension_data); +std::string ProcessExtKeyUsage(SECItem* extension_data); +std::string ProcessExtensionData(SECOidTag oid_tag, SECItem* extension_data); + +} // namespace mozilla_security_manager + +#endif // CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTHELPER_H_ diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertificate.cpp b/chrome/third_party/mozilla_security_manager/nsNSSCertificate.cpp new file mode 100644 index 0000000..9d1abe8 --- /dev/null +++ b/chrome/third_party/mozilla_security_manager/nsNSSCertificate.cpp @@ -0,0 +1,65 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Ian McGreer <mcgreer@netscape.com> + * Javier Delgadillo <javi@netscape.com> + * Kai Engert <kengert@redhat.com> + * Jesper Kristensen <mail@jesperkristensen.dk> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "chrome/third_party/mozilla_security_manager/nsNSSCertificate.h" + +namespace mozilla_security_manager { + +std::string GetCertTitle(CERTCertificate* cert) { + std::string rv; + if (cert->nickname) { + rv = cert->nickname; + } else { + char* cn = CERT_GetCommonName(&cert->subject); + if (cn) { + rv = cn; + PORT_Free(cn); + } else if (cert->subjectName) { + rv = cert->subjectName; + } else if (cert->emailAddr) { + rv = cert->emailAddr; + } + } + // TODO(mattm): Should we return something other than an empty string when all + // the checks fail? + return rv; +} + +} // namespace mozilla_security_manager diff --git a/chrome/third_party/mozilla_security_manager/nsNSSCertificate.h b/chrome/third_party/mozilla_security_manager/nsNSSCertificate.h new file mode 100644 index 0000000..8ac10e6 --- /dev/null +++ b/chrome/third_party/mozilla_security_manager/nsNSSCertificate.h @@ -0,0 +1,55 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 2000 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Ian McGreer <mcgreer@netscape.com> + * Javier Delgadillo <javi@netscape.com> + * Kai Engert <kengert@redhat.com> + * Jesper Kristensen <mail@jesperkristensen.dk> + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTIFICATE_H_ +#define CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTIFICATE_H_ + +#include <cert.h> + +#include <string> + +namespace mozilla_security_manager { + +// Based on nsNSSCertificate::GetWindowTitle. +std::string GetCertTitle(CERTCertificate* cert); + +} // namespace mozilla_security_manager + +#endif // CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTIFICATE_H_ |