diff options
author | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-29 19:19:00 +0000 |
---|---|---|
committer | thakis@chromium.org <thakis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-29 19:19:00 +0000 |
commit | 3b5648911bcde7d6dddc0fbef236257ea14b58af (patch) | |
tree | ea4b51adfef0a94c446fbdc38408a7344408d528 /third_party | |
parent | 840321b9afc8d9d26234969ff0f6ba26b360933c (diff) | |
download | chromium_src-3b5648911bcde7d6dddc0fbef236257ea14b58af.zip chromium_src-3b5648911bcde7d6dddc0fbef236257ea14b58af.tar.gz chromium_src-3b5648911bcde7d6dddc0fbef236257ea14b58af.tar.bz2 |
Move chrome/third_party/mozilla_security_manager to third_party.
All third_party libraries should be directly in third_party, not scattered throughout the tree.
Note that net/third_party contains a folder of the same name, I will
move files in there into third_party/mozilla_security_manager later.
BUG=80916
TEST=none
Review URL: http://codereview.chromium.org/6902141
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83569 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'third_party')
8 files changed, 1457 insertions, 0 deletions
diff --git a/third_party/mozilla_security_manager/LICENSE b/third_party/mozilla_security_manager/LICENSE new file mode 100644 index 0000000..cbb1827 --- /dev/null +++ b/third_party/mozilla_security_manager/LICENSE @@ -0,0 +1,35 @@ +/* ***** 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): + * + * 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 ***** */ diff --git a/third_party/mozilla_security_manager/README.chromium b/third_party/mozilla_security_manager/README.chromium new file mode 100644 index 0000000..558bd22 --- /dev/null +++ b/third_party/mozilla_security_manager/README.chromium @@ -0,0 +1,13 @@ +Name: Mozilla Personal Security Manager +URL: http://mxr.mozilla.org/mozilla-central/source/security/manager/ +InfoURL: http://www.mozilla.org/ +Version: 36838:a59a5f030021 +Security Critical: Yes + +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/third_party/mozilla_security_manager/nsNSSCertHelper.cpp b/third_party/mozilla_security_manager/nsNSSCertHelper.cpp new file mode 100644 index 0000000..b778482 --- /dev/null +++ b/third_party/mozilla_security_manager/nsNSSCertHelper.cpp @@ -0,0 +1,1051 @@ +/* ***** 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 "third_party/mozilla_security_manager/nsNSSCertHelper.h" + +#include <keyhi.h> +#include <prprf.h> +#include <unicode/uidna.h> + +#include "base/i18n/number_formatting.h" +#include "base/string_number_conversions.h" +#include "base/stringprintf.h" +#include "base/utf_string_conversions.h" +#include "chrome/common/net/x509_certificate_model.h" +#include "grit/generated_resources.h" +#include "net/base/net_util.h" +#include "net/third_party/mozilla_security_manager/nsNSSCertTrust.h" +#include "ui/base/l10n/l10n_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); +} + +SECOidTag RegisterDynamicOid(const char* oid_string) { + SECOidTag rv = SEC_OID_UNKNOWN; + unsigned char buffer[1024]; + SECOidData od; + od.oid.type = siDEROID; + od.oid.data = buffer; + od.oid.len = sizeof(buffer); + + if (SEC_StringToOID(NULL, &od.oid, oid_string, 0) == SECSuccess) { + od.offset = SEC_OID_UNKNOWN; + od.mechanism = CKM_INVALID_MECHANISM; + od.supportedExtension = INVALID_CERT_EXTENSION; + od.desc = oid_string; + + rv = SECOID_AddEntry(&od); + } + DCHECK_NE(rv, SEC_OID_UNKNOWN) << oid_string; + return rv; +} + +// Format a SECItem as a space separated string, with 16 bytes on each line. +std::string ProcessRawBytes(SECItem* data) { + return x509_certificate_model::ProcessRawBytes(data->data, data->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; +SECOidTag eku_ms_individual_code_signing = SEC_OID_UNKNOWN; +SECOidTag eku_ms_commercial_code_signing = SEC_OID_UNKNOWN; +SECOidTag eku_ms_trust_list_signing = SEC_OID_UNKNOWN; +SECOidTag eku_ms_time_stamping = SEC_OID_UNKNOWN; +SECOidTag eku_ms_server_gated_crypto = SEC_OID_UNKNOWN; +SECOidTag eku_ms_encrypting_file_system = SEC_OID_UNKNOWN; +SECOidTag eku_ms_file_recovery = SEC_OID_UNKNOWN; +SECOidTag eku_ms_windows_hardware_driver_verification = SEC_OID_UNKNOWN; +SECOidTag eku_ms_qualified_subordination = SEC_OID_UNKNOWN; +SECOidTag eku_ms_key_recovery = SEC_OID_UNKNOWN; +SECOidTag eku_ms_document_signing = SEC_OID_UNKNOWN; +SECOidTag eku_ms_lifetime_signing = SEC_OID_UNKNOWN; +SECOidTag eku_ms_smart_card_logon = SEC_OID_UNKNOWN; +SECOidTag eku_ms_key_recovery_agent = SEC_OID_UNKNOWN; +SECOidTag eku_netscape_international_step_up = SEC_OID_UNKNOWN; + +void RegisterDynamicOids() { + if (ms_cert_ext_certtype != SEC_OID_UNKNOWN) + return; + + ms_cert_ext_certtype = RegisterDynamicOid("1.3.6.1.4.1.311.20.2"); + ms_certsrv_ca_version = RegisterDynamicOid("1.3.6.1.4.1.311.21.1"); + ms_nt_principal_name = RegisterDynamicOid("1.3.6.1.4.1.311.20.2.3"); + ms_nt_principal_name = RegisterDynamicOid("1.3.6.1.4.1.311.25.1"); + + eku_ms_individual_code_signing = RegisterDynamicOid("1.3.6.1.4.1.311.2.1.21"); + eku_ms_commercial_code_signing = RegisterDynamicOid("1.3.6.1.4.1.311.2.1.22"); + eku_ms_trust_list_signing = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.1"); + eku_ms_time_stamping = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.2"); + eku_ms_server_gated_crypto = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.3"); + eku_ms_encrypting_file_system = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.4"); + eku_ms_file_recovery = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.4.1"); + eku_ms_windows_hardware_driver_verification = RegisterDynamicOid( + "1.3.6.1.4.1.311.10.3.5"); + eku_ms_qualified_subordination = RegisterDynamicOid( + "1.3.6.1.4.1.311.10.3.10"); + eku_ms_key_recovery = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.11"); + eku_ms_document_signing = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.12"); + eku_ms_lifetime_signing = RegisterDynamicOid("1.3.6.1.4.1.311.10.3.13"); + eku_ms_smart_card_logon = RegisterDynamicOid("1.3.6.1.4.1.311.20.2.2"); + eku_ms_key_recovery_agent = RegisterDynamicOid("1.3.6.1.4.1.311.21.6"); + eku_netscape_international_step_up = RegisterDynamicOid( + "2.16.840.1.113730.4.1"); +} + +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; + case SEC_OID_EXT_KEY_USAGE_SERVER_AUTH: + string_id = IDS_CERT_EKU_TLS_WEB_SERVER_AUTHENTICATION; + break; + case SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH: + string_id = IDS_CERT_EKU_TLS_WEB_CLIENT_AUTHENTICATION; + break; + case SEC_OID_EXT_KEY_USAGE_CODE_SIGN: + string_id = IDS_CERT_EKU_CODE_SIGNING; + break; + case SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT: + string_id = IDS_CERT_EKU_EMAIL_PROTECTION; + break; + case SEC_OID_EXT_KEY_USAGE_TIME_STAMP: + string_id = IDS_CERT_EKU_TIME_STAMPING; + break; + case SEC_OID_OCSP_RESPONDER: + string_id = IDS_CERT_EKU_OCSP_SIGNING; + break; + case SEC_OID_PKIX_CPS_POINTER_QUALIFIER: + string_id = IDS_CERT_PKIX_CPS_POINTER_QUALIFIER; + break; + case SEC_OID_PKIX_USER_NOTICE_QUALIFIER: + string_id = IDS_CERT_PKIX_USER_NOTICE_QUALIFIER; + 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 if (oid_tag == eku_ms_individual_code_signing) + string_id = IDS_CERT_EKU_MS_INDIVIDUAL_CODE_SIGNING; + else if (oid_tag == eku_ms_commercial_code_signing) + string_id = IDS_CERT_EKU_MS_COMMERCIAL_CODE_SIGNING; + else if (oid_tag == eku_ms_trust_list_signing) + string_id = IDS_CERT_EKU_MS_TRUST_LIST_SIGNING; + else if (oid_tag == eku_ms_time_stamping) + string_id = IDS_CERT_EKU_MS_TIME_STAMPING; + else if (oid_tag == eku_ms_server_gated_crypto) + string_id = IDS_CERT_EKU_MS_SERVER_GATED_CRYPTO; + else if (oid_tag == eku_ms_encrypting_file_system) + string_id = IDS_CERT_EKU_MS_ENCRYPTING_FILE_SYSTEM; + else if (oid_tag == eku_ms_file_recovery) + string_id = IDS_CERT_EKU_MS_FILE_RECOVERY; + else if (oid_tag == eku_ms_windows_hardware_driver_verification) + string_id = IDS_CERT_EKU_MS_WINDOWS_HARDWARE_DRIVER_VERIFICATION; + else if (oid_tag == eku_ms_qualified_subordination) + string_id = IDS_CERT_EKU_MS_QUALIFIED_SUBORDINATION; + else if (oid_tag == eku_ms_key_recovery) + string_id = IDS_CERT_EKU_MS_KEY_RECOVERY; + else if (oid_tag == eku_ms_document_signing) + string_id = IDS_CERT_EKU_MS_DOCUMENT_SIGNING; + else if (oid_tag == eku_ms_lifetime_signing) + string_id = IDS_CERT_EKU_MS_LIFETIME_SIGNING; + else if (oid_tag == eku_ms_smart_card_logon) + string_id = IDS_CERT_EKU_MS_SMART_CARD_LOGON; + else if (oid_tag == eku_ms_key_recovery_agent) + string_id = IDS_CERT_EKU_MS_KEY_RECOVERY_AGENT; + else if (oid_tag == eku_netscape_international_step_up) + string_id = IDS_CERT_EKU_NETSCAPE_INTERNATIONAL_STEP_UP; + 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); + if (SECOID_FindOIDTag(&avas[i]->type) == SEC_OID_AVA_COMMON_NAME) + value = x509_certificate_model::ProcessIDN(value); + 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; + base::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); + value = x509_certificate_model::ProcessIDN(value); + 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; + 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 ProcessUserNotice(SECItem* der_notice) { + CERTUserNotice* notice = CERT_DecodeUserNotice(der_notice); + if (!notice) + return ProcessRawBytes(der_notice); + + std::string rv; + if (notice->noticeReference.organization.len != 0) { + switch (notice->noticeReference.organization.type) { + case siAsciiString: + case siVisibleString: + case siUTF8String: + rv += std::string( + reinterpret_cast<char*>(notice->noticeReference.organization.data), + notice->noticeReference.organization.len); + break; + case siBMPString: + rv += ProcessBMPString(¬ice->noticeReference.organization); + break; + default: + break; + } + rv += " - "; + SECItem** itemList = notice->noticeReference.noticeNumbers; + while (*itemList) { + unsigned long number; + if (SEC_ASN1DecodeInteger(*itemList, &number) == SECSuccess) { + if (itemList != notice->noticeReference.noticeNumbers) + rv += ", "; + rv += '#'; + rv += UTF16ToUTF8(base::UintToString16(number)); + } + itemList++; + } + } + if (notice->displayText.len != 0) { + rv += "\n "; + switch (notice->displayText.type) { + case siAsciiString: + case siVisibleString: + case siUTF8String: + rv += std::string(reinterpret_cast<char*>(notice->displayText.data), + notice->displayText.len); + break; + case siBMPString: + rv += ProcessBMPString(¬ice->displayText); + break; + default: + break; + } + } + + CERT_DestroyUserNotice(notice); + return rv; +} + +std::string ProcessCertificatePolicies(SECItem* extension_data) { + std::string rv; + + CERTCertificatePolicies* policies = CERT_DecodeCertificatePoliciesExtension( + extension_data); + if (!policies) + return l10n_util::GetStringUTF8(IDS_CERT_EXTENSION_DUMP_ERROR); + + CERTPolicyInfo** policyInfos = policies->policyInfos; + while (*policyInfos) { + CERTPolicyInfo* policyInfo = *policyInfos++; + std::string key = GetOIDText(&policyInfo->policyID); + + // If we have policy qualifiers, display the oid text + // with a ':', otherwise just put the oid text and a newline. + // TODO(mattm): Add extra note if this is the ev oid? (It's a bit + // complicated, since we don't want to do the EV check synchronously.) + if (policyInfo->policyQualifiers) { + rv += l10n_util::GetStringFUTF8(IDS_CERT_MULTILINE_INFO_START_FORMAT, + UTF8ToUTF16(key)); + } else { + rv += key; + } + rv += '\n'; + + if (policyInfo->policyQualifiers) { + // Add all qualifiers on separate lines, indented. + CERTPolicyQualifier** policyQualifiers = policyInfo->policyQualifiers; + while (*policyQualifiers != NULL) { + rv += " "; + + CERTPolicyQualifier* policyQualifier = *policyQualifiers++; + rv += l10n_util::GetStringFUTF8( + IDS_CERT_MULTILINE_INFO_START_FORMAT, + UTF8ToUTF16(GetOIDText(&policyQualifier->qualifierID))); + switch(policyQualifier->oid) { + case SEC_OID_PKIX_CPS_POINTER_QUALIFIER: + rv += " "; + /* The CPS pointer ought to be the cPSuri alternative + of the Qualifier choice. */ + rv += ProcessIA5String(&policyQualifier->qualifierValue); + break; + case SEC_OID_PKIX_USER_NOTICE_QUALIFIER: + rv += ProcessUserNotice(&policyQualifier->qualifierValue); + break; + default: + rv += ProcessRawBytes(&policyQualifier->qualifierValue); + break; + } + rv += '\n'; + } + } + } + + CERT_DestroyCertificatePoliciesExtension(policies); + 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: + // generalName is a typo in upstream NSS; fullName is actually a + // GeneralNames (SEQUENCE OF GeneralName). See Mozilla Bug #615100. + rv += ProcessGeneralNames(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); + comma = true; + } + } + 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 int mask; + int string_id; +}; + +static std::string ProcessBitField(SECItem* bitfield, + const MaskIdPair* string_map, + size_t len, + char separator) { + unsigned int bits = 0; + std::string rv; + for (size_t i = 0; i * 8 < bitfield->len && i < sizeof(bits); ++i) + bits |= bitfield->data[i] << (i * 8); + for (size_t i = 0; i < len; ++i) { + if (bits & string_map[i].mask) { + if (!rv.empty()) + rv += separator; + rv += l10n_util::GetStringUTF8(string_map[i].string_id); + } + } + return rv; +} + +static std::string ProcessBitStringExtension(SECItem* extension_data, + const MaskIdPair* string_map, + size_t len, + char separator) { + 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 = ProcessBitField(&decoded, string_map, len, separator); + PORT_Free(decoded.data); + return rv; +} + +std::string ProcessNSCertTypeExtension(SECItem* extension_data) { + static const 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), '\n'); +} + +static const MaskIdPair key_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}, + {KU_ENCIPHER_ONLY, IDS_CERT_X509_KEY_USAGE_ENCIPHER_ONLY}, + // NSS is missing a flag for dechiperOnly, see: + // https://bugzilla.mozilla.org/show_bug.cgi?id=549952 +}; + +std::string ProcessKeyUsageBitString(SECItem* bitstring, char sep) { + return ProcessBitField(bitstring, key_usage_string_map, + arraysize(key_usage_string_map), sep); +} + +std::string ProcessKeyUsageExtension(SECItem* extension_data) { + return ProcessBitStringExtension(extension_data, key_usage_string_map, + arraysize(key_usage_string_map), '\n'); +} + +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) { + oid = *oids; + std::string oid_dump = DumpOidString(oid); + std::string oid_text = GetOIDText(oid); + + // If oid is one we recognize, oid_text will have a text description of the OID, + // which we display along with the oid_dump. If we don't recognize the OID, + // GetOIDText will return the same value as DumpOidString, so just display + // the OID alone. + if (oid_dump == oid_text) + rv += oid_dump; + else + rv += l10n_util::GetStringFUTF8(IDS_CERT_EXT_KEY_USAGE_FORMAT, + UTF8ToUTF16(oid_text), + UTF8ToUTF16(oid_dump)); + 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); + case SEC_OID_X509_CERTIFICATE_POLICIES: + return ProcessCertificatePolicies(extension_data); + 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); + } +} + +std::string ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo* spki) { + std::string rv; + SECKEYPublicKey* key = SECKEY_ExtractPublicKey(spki); + if (key) { + switch (key->keyType) { + case rsaKey: { + rv = l10n_util::GetStringFUTF8( + IDS_CERT_RSA_PUBLIC_KEY_DUMP_FORMAT, + base::UintToString16(key->u.rsa.modulus.len * 8), + UTF8ToUTF16(ProcessRawBytes(&key->u.rsa.modulus)), + base::UintToString16(key->u.rsa.publicExponent.len * 8), + UTF8ToUTF16(ProcessRawBytes(&key->u.rsa.publicExponent))); + break; + } + default: + rv = x509_certificate_model::ProcessRawBits( + spki->subjectPublicKey.data, spki->subjectPublicKey.len); + break; + } + SECKEY_DestroyPublicKey(key); + } + return rv; +} + +net::CertType GetCertType(CERTCertificate *cert) { + nsNSSCertTrust trust(cert->trust); + if (cert->nickname && trust.HasAnyUser()) + return net::USER_CERT; + if (trust.HasAnyCA()) + return net::CA_CERT; + if (trust.HasPeer(PR_TRUE, PR_FALSE, PR_FALSE)) + return net::SERVER_CERT; + if (CERT_IsCACert(cert, NULL)) + return net::CA_CERT; + return net::UNKNOWN_CERT; +} + +} // namespace mozilla_security_manager diff --git a/third_party/mozilla_security_manager/nsNSSCertHelper.h b/third_party/mozilla_security_manager/nsNSSCertHelper.h new file mode 100644 index 0000000..8160c7a --- /dev/null +++ b/third_party/mozilla_security_manager/nsNSSCertHelper.h @@ -0,0 +1,96 @@ +/* ***** 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/memory/scoped_ptr.h" +#include "net/base/cert_database.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(); + +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 ProcessKeyUsageBitString(SECItem* bitstring, char sep); +std::string ProcessKeyUsageExtension(SECItem* extension_data); +std::string ProcessExtKeyUsage(SECItem* extension_data); +std::string ProcessExtensionData(SECOidTag oid_tag, SECItem* extension_data); +std::string ProcessSubjectPublicKeyInfo(CERTSubjectPublicKeyInfo* spki); + +net::CertType GetCertType(CERTCertificate *cert); + +} // namespace mozilla_security_manager + +#endif // CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTHELPER_H_ diff --git a/third_party/mozilla_security_manager/nsNSSCertificate.cpp b/third_party/mozilla_security_manager/nsNSSCertificate.cpp new file mode 100644 index 0000000..a04821d --- /dev/null +++ b/third_party/mozilla_security_manager/nsNSSCertificate.cpp @@ -0,0 +1,78 @@ +/* ***** 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 "third_party/mozilla_security_manager/nsNSSCertificate.h" + +#include <pk11func.h> + +#include "grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.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; +} + +std::string GetCertTokenName(CERTCertificate* cert) { + std::string token; + if (cert->slot) { + token = PK11_GetTokenName(cert->slot); + } + return token; +} + +} // namespace mozilla_security_manager diff --git a/third_party/mozilla_security_manager/nsNSSCertificate.h b/third_party/mozilla_security_manager/nsNSSCertificate.h new file mode 100644 index 0000000..b436601 --- /dev/null +++ b/third_party/mozilla_security_manager/nsNSSCertificate.h @@ -0,0 +1,58 @@ +/* ***** 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); + +// Based on nsNSSCertificate::GetTokenName. +std::string GetCertTokenName(CERTCertificate* cert); + +} // namespace mozilla_security_manager + +#endif // CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSNSSCERTIFICATE_H_ diff --git a/third_party/mozilla_security_manager/nsUsageArrayHelper.cpp b/third_party/mozilla_security_manager/nsUsageArrayHelper.cpp new file mode 100644 index 0000000..bab85f5 --- /dev/null +++ b/third_party/mozilla_security_manager/nsUsageArrayHelper.cpp @@ -0,0 +1,73 @@ +/* ***** 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): + * John Gardiner Myers <jgmyers@speakeasy.net> + * + * 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 "third_party/mozilla_security_manager/nsUsageArrayHelper.h" + +#include "grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" + +namespace mozilla_security_manager { + +void GetCertUsageStrings(CERTCertificate* cert, std::vector<std::string>* out) { + SECCertificateUsage usages = 0; + // TODO(wtc): See if we should use X509Certificate::Verify instead. + if (CERT_VerifyCertificateNow(CERT_GetDefaultCertDB(), cert, PR_TRUE, + certificateUsageCheckAllUsages, + NULL, &usages) == SECSuccess) { + static const struct { + SECCertificateUsage usage; + int string_id; + } usage_string_map[] = { + {certificateUsageSSLClient, IDS_CERT_USAGE_SSL_CLIENT}, + {certificateUsageSSLServer, IDS_CERT_USAGE_SSL_SERVER}, + {certificateUsageSSLServerWithStepUp, + IDS_CERT_USAGE_SSL_SERVER_WITH_STEPUP}, + {certificateUsageEmailSigner, IDS_CERT_USAGE_EMAIL_SIGNER}, + {certificateUsageEmailRecipient, IDS_CERT_USAGE_EMAIL_RECEIVER}, + {certificateUsageObjectSigner, IDS_CERT_USAGE_OBJECT_SIGNER}, + {certificateUsageSSLCA, IDS_CERT_USAGE_SSL_CA}, + {certificateUsageStatusResponder, IDS_CERT_USAGE_STATUS_RESPONDER}, + }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(usage_string_map); ++i) { + if (usages & usage_string_map[i].usage) + out->push_back(l10n_util::GetStringUTF8( + usage_string_map[i].string_id)); + } + } +} + +} // namespace mozilla_security_manager diff --git a/third_party/mozilla_security_manager/nsUsageArrayHelper.h b/third_party/mozilla_security_manager/nsUsageArrayHelper.h new file mode 100644 index 0000000..31ba550 --- /dev/null +++ b/third_party/mozilla_security_manager/nsUsageArrayHelper.h @@ -0,0 +1,53 @@ +/* ***** 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): + * John Gardiner Myers <jgmyers@speakeasy.net> + * + * 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_NSUSAGEARRAYHELPER_H_ +#define CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSUSAGEARRAYHELPER_H_ + +#include <cert.h> + +#include <string> +#include <vector> + +namespace mozilla_security_manager { + +// Based on nsUsageArrayHelper::GetUsagesArray. +void GetCertUsageStrings(CERTCertificate* cert, std::vector<std::string>* out); + +} // namespace mozilla_security_manager + +#endif // CHROME_THIRD_PARTY_MOZILLA_SECURITY_MANAGER_NSUSAGEARRAYHELPER_H_ |