author | Brian Smith <brian@briansmith.org> |
Sun, 26 Jan 2014 19:36:28 -0800 | |
changeset 165286 | 2dc56ee0e0e51a35ac0573b57451ad79361e6d0d |
parent 165285 | 99cf3634be5dadf488320b12e5c884e6d9363870 |
child 165287 | 95f848f55c90176dd061a54c6d8d9855dbfed258 |
push id | 38936 |
push user | brian@briansmith.org |
push date | Mon, 27 Jan 2014 06:36:40 +0000 |
treeherder | mozilla-inbound@e6c9677b89d2 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | keeler |
bugs | 891066 |
milestone | 29.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/build/dumbmake-dependencies +++ b/build/dumbmake-dependencies @@ -13,20 +13,19 @@ toolkit/library docshell/build docshell uriloader modules widget gfx toolkit/components/build toolkit/components - security/build security/manager - security/dbm - security/nss + security/certverifier + security/build accessible dom content layout editor parser js/src mfbt
new file mode 100644 --- /dev/null +++ b/security/certverifier/CertVerifier.cpp @@ -0,0 +1,439 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "CertVerifier.h" +#include "ExtendedValidation.h" +#include "ScopedNSSTypes.h" +#include "cert.h" +#include "secerr.h" +#include "prerror.h" + +#ifdef PR_LOGGING +extern PRLogModuleInfo* gPIPNSSLog; +#endif + +namespace mozilla { namespace psm { + +const CertVerifier::Flags CertVerifier::FLAG_LOCAL_ONLY = 1; +const CertVerifier::Flags CertVerifier::FLAG_NO_DV_FALLBACK_FOR_EV = 2; + +CertVerifier::CertVerifier(implementation_config ic, + missing_cert_download_config mcdc, + crl_download_config cdc, + ocsp_download_config odc, + ocsp_strict_config osc, + ocsp_get_config ogc) + : mImplementation(ic) + , mMissingCertDownloadEnabled(mcdc == missing_cert_download_on) + , mCRLDownloadEnabled(cdc == crl_download_allowed) + , mOCSPDownloadEnabled(odc == ocsp_on) + , mOCSPStrict(osc == ocsp_strict) + , mOCSPGETEnabled(ogc == ocsp_get_enabled) +{ +} + +CertVerifier::~CertVerifier() +{ +} + +static SECStatus +ClassicVerifyCert(CERTCertificate* cert, + const SECCertificateUsage usage, + const PRTime time, + void* pinArg, + /*optional out*/ CERTCertList** validationChain, + /*optional out*/ CERTVerifyLog* verifyLog) +{ + SECStatus rv; + SECCertUsage enumUsage; + if (validationChain) { + switch(usage){ + case certificateUsageSSLClient: + enumUsage = certUsageSSLClient; + break; + case certificateUsageSSLServer: + enumUsage = certUsageSSLServer; + break; + case certificateUsageSSLServerWithStepUp: + enumUsage = certUsageSSLServerWithStepUp; + break; + case certificateUsageSSLCA: + enumUsage = certUsageSSLCA; + break; + case certificateUsageEmailSigner: + enumUsage = certUsageEmailSigner; + break; + case certificateUsageEmailRecipient: + enumUsage = certUsageEmailRecipient; + break; + case certificateUsageObjectSigner: + enumUsage = certUsageObjectSigner; + break; + case certificateUsageUserCertImport: + enumUsage = certUsageUserCertImport; + break; + case certificateUsageVerifyCA: + enumUsage = certUsageVerifyCA; + break; + case certificateUsageProtectedObjectSigner: + enumUsage = certUsageProtectedObjectSigner; + break; + case certificateUsageStatusResponder: + enumUsage = certUsageStatusResponder; + break; + case certificateUsageAnyCA: + enumUsage = certUsageAnyCA; + break; + default: + return SECFailure; + } + } + if (usage == certificateUsageSSLServer) { + // SSL server cert verification has always used CERT_VerifyCert, so we + // continue to use it for SSL cert verification to minimize the risk of + // there being any differnce in results between CERT_VerifyCert and + // CERT_VerifyCertificate. + rv = CERT_VerifyCert(CERT_GetDefaultCertDB(), cert, true, + certUsageSSLServer, time, pinArg, verifyLog); + } else { + rv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), cert, true, + usage, time, pinArg, verifyLog, nullptr); + } + if (rv == SECSuccess && validationChain) { + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: getting chain in 'classic' \n")); + *validationChain = CERT_GetCertChainFromCert(cert, time, enumUsage); + if (!*validationChain) { + rv = SECFailure; + } + } + return rv; +} + +SECStatus +CertVerifier::VerifyCert(CERTCertificate* cert, + const SECCertificateUsage usage, + const PRTime time, + void* pinArg, + const Flags flags, + /*optional out*/ CERTCertList** validationChain, + /*optional out*/ SECOidTag* evOidPolicy, + /*optional out*/ CERTVerifyLog* verifyLog) +{ + if (!cert || + ((flags & FLAG_NO_DV_FALLBACK_FOR_EV) && + (usage != certificateUsageSSLServer || !evOidPolicy))) + { + PR_NOT_REACHED("Invalid arguments to CertVerifier::VerifyCert"); + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (validationChain) { + *validationChain = nullptr; + } + if (evOidPolicy) { + *evOidPolicy = SEC_OID_UNKNOWN; + } + + switch(usage){ + case certificateUsageSSLClient: + case certificateUsageSSLServer: + case certificateUsageSSLCA: + case certificateUsageEmailSigner: + case certificateUsageEmailRecipient: + case certificateUsageObjectSigner: + case certificateUsageStatusResponder: + break; + default: + NS_WARNING("Calling VerifyCert with invalid usage"); + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + +#ifndef NSS_NO_LIBPKIX + ScopedCERTCertList trustAnchors; + SECStatus rv; + SECOidTag evPolicy = SEC_OID_UNKNOWN; + + // Do EV checking only for sslserver usage + if (usage == certificateUsageSSLServer) { + SECStatus srv = GetFirstEVPolicy(cert, evPolicy); + if (srv == SECSuccess) { + if (evPolicy != SEC_OID_UNKNOWN) { + trustAnchors = GetRootsForOid(evPolicy); + } + if (!trustAnchors) { + return SECFailure; + } + // pkix ignores an empty trustanchors list and + // decides then to use the whole set of trust in the DB + // so we set the evPolicy to unkown in this case + if (CERT_LIST_EMPTY(trustAnchors)) { + evPolicy = SEC_OID_UNKNOWN; + } + } else { + // Do not setup EV verification params + evPolicy = SEC_OID_UNKNOWN; + } + } + + MOZ_ASSERT_IF(evPolicy != SEC_OID_UNKNOWN, trustAnchors); + + size_t i = 0; + size_t validationChainLocation = 0; + size_t validationTrustAnchorLocation = 0; + CERTValOutParam cvout[4]; + if (verifyLog) { + cvout[i].type = cert_po_errorLog; + cvout[i].value.pointer.log = verifyLog; + ++i; + } + if (validationChain) { + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: setting up validation chain outparam.\n")); + validationChainLocation = i; + cvout[i].type = cert_po_certList; + cvout[i].value.pointer.cert = nullptr; + ++i; + validationTrustAnchorLocation = i; + cvout[i].type = cert_po_trustAnchor; + cvout[i].value.pointer.chain = nullptr; + ++i; + } + cvout[i].type = cert_po_end; + + CERTRevocationFlags rev; + + CERTRevocationMethodIndex revPreferredMethods[2]; + rev.leafTests.preferred_methods = + rev.chainTests.preferred_methods = revPreferredMethods; + + uint64_t revFlagsPerMethod[2]; + rev.leafTests.cert_rev_flags_per_method = + rev.chainTests.cert_rev_flags_per_method = revFlagsPerMethod; + rev.leafTests.number_of_preferred_methods = + rev.chainTests.number_of_preferred_methods = 1; + + rev.leafTests.number_of_defined_methods = + rev.chainTests.number_of_defined_methods = cert_revocation_method_ocsp + 1; + + const bool localOnly = flags & FLAG_LOCAL_ONLY; + CERTValInParam cvin[6]; + + // Parameters for both EV and DV validation + cvin[0].type = cert_pi_useAIACertFetch; + cvin[0].value.scalar.b = mMissingCertDownloadEnabled && !localOnly; + cvin[1].type = cert_pi_revocationFlags; + cvin[1].value.pointer.revocation = &rev; + cvin[2].type = cert_pi_date; + cvin[2].value.scalar.time = time; + i = 3; + const size_t evParamLocation = i; + + if (evPolicy != SEC_OID_UNKNOWN) { + // EV setup! + // XXX 859872 The current flags are not quite correct. (use + // of ocsp flags for crl preferences). + uint64_t ocspRevMethodFlags = + CERT_REV_M_TEST_USING_THIS_METHOD + | ((mOCSPDownloadEnabled && !localOnly) ? + CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING) + | CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE + | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE + | CERT_REV_M_IGNORE_MISSING_FRESH_INFO + | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO + | (mOCSPGETEnabled ? 0 : CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP); + + rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] = + rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] + = CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD; + + rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = + rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] + = ocspRevMethodFlags; + + rev.leafTests.cert_rev_method_independent_flags = + rev.chainTests.cert_rev_method_independent_flags = + // avoiding the network is good, let's try local first + CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST + // is overall revocation requirement strict or relaxed? + | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE + ; + + rev.leafTests.preferred_methods[0] = + rev.chainTests.preferred_methods[0] = cert_revocation_method_ocsp; + + cvin[i].type = cert_pi_policyOID; + cvin[i].value.arraySize = 1; + cvin[i].value.array.oids = &evPolicy; + ++i; + MOZ_ASSERT(trustAnchors); + cvin[i].type = cert_pi_trustAnchors; + cvin[i].value.pointer.chain = trustAnchors; + ++i; + + cvin[i].type = cert_pi_end; + + rv = CERT_PKIXVerifyCert(cert, usage, cvin, cvout, pinArg); + if (rv == SECSuccess) { + if (evOidPolicy) { + *evOidPolicy = evPolicy; + } + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, + ("VerifyCert: successful CERT_PKIXVerifyCert(ev) \n")); + goto pkix_done; + } + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, + ("VerifyCert: failed CERT_PKIXVerifyCert(ev)\n")); + + if (validationChain && *validationChain) { + // There SHOULD not be a validation chain on failure, asserion here for + // the debug builds AND a fallback for production builds + MOZ_ASSERT(false, + "certPKIXVerifyCert returned failure AND a validationChain"); + CERT_DestroyCertList(*validationChain); + *validationChain = nullptr; + } + + if (verifyLog) { + // Cleanup the log so that it is ready the the next validation + CERTVerifyLogNode* i_node; + for (i_node = verifyLog->head; i_node; i_node = i_node->next) { + //destroy cert if any. + if (i_node->cert) { + CERT_DestroyCertificate(i_node->cert); + } + // No need to cleanup the actual nodes in the arena. + } + verifyLog->count = 0; + verifyLog->head = nullptr; + verifyLog->tail = nullptr; + } + + } +#endif + + // If we're here, PKIX EV verification failed. + // If requested, don't do DV fallback. + if (flags & FLAG_NO_DV_FALLBACK_FOR_EV) { + PR_ASSERT(*evOidPolicy == SEC_OID_UNKNOWN); + return SECSuccess; + } + + if (mImplementation == classic) { + // XXX: we do not care about the localOnly flag (currently) as the + // caller that wants localOnly should disable and reenable the fetching. + return ClassicVerifyCert(cert, usage, time, pinArg, validationChain, + verifyLog); + } + +#ifdef NSS_NO_LIBPKIX + PR_NOT_REACHED("libpkix implementation chosen but not even compiled in"); + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; +#else + PR_ASSERT(mImplementation == libpkix); + + // The current flags check the chain the same way as the leafs + rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] = + rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] = + // implicit default source - makes no sense for CRLs + CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE + + // let's not stop on fresh CRL. If OCSP is enabled, too, let's check it + | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO + + // no fresh CRL? well, let other flag decide whether to fail or not + | CERT_REV_M_IGNORE_MISSING_FRESH_INFO + + // testing using local CRLs is always allowed + | CERT_REV_M_TEST_USING_THIS_METHOD + + // no local crl and don't know where to get it from? ignore + | CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE + + // crl download based on parameter + | ((mCRLDownloadEnabled && !localOnly) ? + CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING) + ; + + rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = + rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = + // use OCSP + CERT_REV_M_TEST_USING_THIS_METHOD + + // if app has a default OCSP responder configured, let's use it + | CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE + + // of course OCSP doesn't work without a source. let's accept such certs + | CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE + + // if ocsp is required stop on lack of freshness + | (mOCSPStrict ? + CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO : CERT_REV_M_IGNORE_MISSING_FRESH_INFO) + + // ocsp success is sufficient + | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO + + // ocsp enabled controls network fetching, too + | ((mOCSPDownloadEnabled && !localOnly) ? + CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING) + + | (mOCSPGETEnabled ? 0 : CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP); + ; + + rev.leafTests.preferred_methods[0] = + rev.chainTests.preferred_methods[0] = cert_revocation_method_ocsp; + + rev.leafTests.cert_rev_method_independent_flags = + rev.chainTests.cert_rev_method_independent_flags = + // avoiding the network is good, let's try local first + CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST; + + // Skip EV parameters + cvin[evParamLocation].type = cert_pi_end; + + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: calling CERT_PKIXVerifyCert(dv) \n")); + rv = CERT_PKIXVerifyCert(cert, usage, cvin, cvout, pinArg); + +pkix_done: + if (validationChain) { + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: validation chain requested\n")); + ScopedCERTCertificate trustAnchor(cvout[validationTrustAnchorLocation].value.pointer.cert); + + if (rv == SECSuccess) { + if (! cvout[validationChainLocation].value.pointer.chain) { + PR_SetError(PR_UNKNOWN_ERROR, 0); + return SECFailure; + } + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: I have a chain\n")); + *validationChain = cvout[validationChainLocation].value.pointer.chain; + if (trustAnchor) { + // we should only add the issuer to the chain if it is not already + // present. On CA cert checking, the issuer is the same cert, so in + // that case we do not add the cert to the chain. + if (!CERT_CompareCerts(trustAnchor, cert)) { + PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: adding issuer to tail for display\n")); + // note: rv is reused to catch errors on cert creation! + ScopedCERTCertificate tempCert(CERT_DupCertificate(trustAnchor)); + rv = CERT_AddCertToListTail(*validationChain, tempCert); + if (rv == SECSuccess) { + tempCert.forget(); // ownership traferred to validationChain + } else { + CERT_DestroyCertList(*validationChain); + *validationChain = nullptr; + } + } + } + } else { + // Validation was a fail, clean up if needed + if (cvout[validationChainLocation].value.pointer.chain) { + CERT_DestroyCertList(cvout[validationChainLocation].value.pointer.chain); + } + } + } + + return rv; +#endif +} + +} } // namespace mozilla::psm
new file mode 100644 --- /dev/null +++ b/security/certverifier/CertVerifier.h @@ -0,0 +1,64 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_psm__CertVerifier_h +#define mozilla_psm__CertVerifier_h + +#include "certt.h" +#include "insanity/ScopedPtr.h" + +namespace mozilla { namespace psm { + +class CertVerifier +{ +public: + typedef unsigned int Flags; + // XXX: FLAG_LOCAL_ONLY is ignored in the classic verification case + static const Flags FLAG_LOCAL_ONLY; + // Don't perform fallback DV validation on EV validation failure. + static const Flags FLAG_NO_DV_FALLBACK_FOR_EV; + + // *evOidPolicy == SEC_OID_UNKNOWN means the cert is NOT EV + // Only one usage per verification is supported. + SECStatus VerifyCert(CERTCertificate* cert, + const SECCertificateUsage usage, + const PRTime time, + void* pinArg, + const Flags flags = 0, + /*optional out*/ CERTCertList** validationChain = nullptr, + /*optional out*/ SECOidTag* evOidPolicy = nullptr , + /*optional out*/ CERTVerifyLog* verifyLog = nullptr); + + enum implementation_config { + classic = 0, +#ifndef NSS_NO_LIBPKIX + libpkix = 1, +#endif + }; + + enum missing_cert_download_config { missing_cert_download_off = 0, missing_cert_download_on }; + enum crl_download_config { crl_local_only = 0, crl_download_allowed }; + enum ocsp_download_config { ocsp_off = 0, ocsp_on }; + enum ocsp_strict_config { ocsp_relaxed = 0, ocsp_strict }; + enum ocsp_get_config { ocsp_get_disabled = 0, ocsp_get_enabled = 1 }; + + bool IsOCSPDownloadEnabled() const { return mOCSPDownloadEnabled; } + + CertVerifier(implementation_config ic, missing_cert_download_config ac, + crl_download_config cdc, ocsp_download_config odc, + ocsp_strict_config osc, ocsp_get_config ogc); + ~CertVerifier(); + +public: + const implementation_config mImplementation; + const bool mMissingCertDownloadEnabled; + const bool mCRLDownloadEnabled; + const bool mOCSPDownloadEnabled; + const bool mOCSPStrict; + const bool mOCSPGETEnabled; +}; + +} } // namespace mozilla::psm + +#endif // mozilla_psm__CertVerifier_h
new file mode 100644 --- /dev/null +++ b/security/certverifier/ExtendedValidation.cpp @@ -0,0 +1,1017 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "ExtendedValidation.h" + +#include "cert.h" +#include "certdb.h" +#include "base64.h" +#include "pk11pub.h" +#include "secerr.h" +#include "prerror.h" +#include "prinit.h" + +#ifdef PR_LOGGING +extern PRLogModuleInfo* gPIPNSSLog; +#endif + +#define CONST_OID static const unsigned char +#define OI(x) { siDEROID, (unsigned char*) x, sizeof x } + +struct nsMyTrustedEVInfo +{ + const char* dotted_oid; + const char* oid_name; // Set this to null to signal an invalid structure, + // (We can't have an empty list, so we'll use a dummy entry) + SECOidTag oid_tag; + const unsigned char ev_root_sha1_fingerprint[20]; + const char* issuer_base64; + const char* serial_base64; + CERTCertificate* cert; +}; + +// HOWTO enable additional CA root certificates for EV: +// +// For each combination of "root certificate" and "policy OID", +// one entry must be added to the array named myTrustedEVInfos. +// +// We use the combination of "issuer name" and "serial number" to +// uniquely identify the certificate. In order to avoid problems +// because of encodings when comparing certificates, we don't +// use plain text representation, we rather use the original encoding +// as it can be found in the root certificate (in base64 format). +// +// We can use the NSS utility named "pp" to extract the encoding. +// +// Build standalone NSS including the NSS tools, then run +// pp -t certificate-identity -i the-cert-filename +// +// You will need the output from sections "Issuer", "Fingerprint (SHA1)", +// "Issuer DER Base64" and "Serial DER Base64". +// +// The new section consists of 8 lines: +// +// - a comment that should contain the human readable issuer name +// of the certificate, as printed by the pp tool +// - the EV policy OID that is associated to the EV grant +// - a text description of the EV policy OID. The array can contain +// multiple entries with the same OID. +// Please make sure to use the identical OID text description for +// all entries with the same policy OID (use the text search +// feature of your text editor to find duplicates). +// When adding a new policy OID that is not yet contained in the array, +// please make sure that your new description is different from +// all the other descriptions (again use the text search feature +// to be sure). +// - the constant SEC_OID_UNKNOWN +// (it will be replaced at runtime with another identifier) +// - the SHA1 fingerprint +// - the "Issuer DER Base64" as printed by the pp tool. +// Remove all whitespaces. If you use multiple lines, make sure that +// only the final line will be followed by a comma. +// - the "Serial DER Base64" (as printed by pp) +// - nullptr +// +// After adding an entry, test it locally against the test site that +// has been provided by the CA. Note that you must use a version of NSS +// where the root certificate has already been added and marked as trusted +// for issueing SSL server certificates (at least). +// +// If you are able to connect to the site without certificate errors, +// but you don't see the EV status indicator, then most likely the CA +// has a problem in their infrastructure. The most common problems are +// related to the CA's OCSP infrastructure, either they use an incorrect +// OCSP signing certificate, or OCSP for the intermediate certificates +// isn't working, or OCSP isn't working at all. + +static struct nsMyTrustedEVInfo myTrustedEVInfos[] = { + // IMPORTANT! When extending this list, + // pairs of dotted_oid and oid_name should always be unique pairs. + // In other words, if you add another list, that uses the same dotted_oid + // as an existing entry, then please use the same oid_name. +#ifdef DEBUG + // Debug EV certificates should all use the OID (repeating EV OID is OK): + // 1.3.6.1.4.1.13769.666.666.666.1.500.9.1. + // If you add or remove debug EV certs you must also modify IdentityInfoInit + // (there is another #ifdef DEBUG section there) so that the correct number of + // certs are skipped as these debug EV certs are NOT part of the default trust + // store. + { + // This is the testing EV signature (xpcshell) (RSA) + // CN=XPCShell EV Testing (untrustworthy) CA,OU=Security Engineering,O=Mozilla - EV debug test CA,L=Mountain View,ST=CA,C=US" + "1.3.6.1.4.1.13769.666.666.666.1.500.9.1", + "DEBUGtesting EV OID", + SEC_OID_UNKNOWN, + { 0x9C, 0x62, 0xEF, 0xDB, 0xAE, 0xF9, 0xEB, 0x36, 0x58, 0xFB, + 0x3B, 0xD3, 0x47, 0x64, 0x93, 0x9D, 0x86, 0x29, 0x6A, 0xE0 }, + "MIGnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWlu" + "IFZpZXcxIzAhBgNVBAoMGk1vemlsbGEgLSBFViBkZWJ1ZyB0ZXN0IENBMR0wGwYD" + "VQQLDBRTZWN1cml0eSBFbmdpbmVlcmluZzEvMC0GA1UEAwwmWFBDU2hlbGwgRVYg" + "VGVzdGluZyAodW50cnVzdHdvcnRoeSkgQ0E=", + "At+3zdo=", + nullptr + }, +#endif + { + // OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP + "1.2.392.200091.100.721.1", + "SECOM EV OID", + SEC_OID_UNKNOWN, + { 0xFE, 0xB8, 0xC4, 0x32, 0xDC, 0xF9, 0x76, 0x9A, 0xCE, 0xAE, + 0x3D, 0xD8, 0x90, 0x8F, 0xFD, 0x28, 0x86, 0x65, 0x64, 0x7D }, + "MGAxCzAJBgNVBAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENP" + "LixMVEQuMSowKAYDVQQLEyFTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVWIFJvb3RD" + "QTE=", + "AA==", + nullptr + }, + { + // CN=Cybertrust Global Root,O=Cybertrust, Inc + "1.3.6.1.4.1.6334.1.100.1", + "Cybertrust EV OID", + SEC_OID_UNKNOWN, + { 0x5F, 0x43, 0xE5, 0xB1, 0xBF, 0xF8, 0x78, 0x8C, 0xAC, 0x1C, + 0xC7, 0xCA, 0x4A, 0x9A, 0xC6, 0x22, 0x2B, 0xCC, 0x34, 0xC6 }, + "MDsxGDAWBgNVBAoTD0N5YmVydHJ1c3QsIEluYzEfMB0GA1UEAxMWQ3liZXJ0cnVz" + "dCBHbG9iYWwgUm9vdA==", + "BAAAAAABD4WqLUg=", + nullptr + }, + { + // CN=SwissSign Gold CA - G2,O=SwissSign AG,C=CH + "2.16.756.1.89.1.2.1.1", + "SwissSign EV OID", + SEC_OID_UNKNOWN, + { 0xD8, 0xC5, 0x38, 0x8A, 0xB7, 0x30, 0x1B, 0x1B, 0x6E, 0xD4, + 0x7A, 0xE6, 0x45, 0x25, 0x3A, 0x6F, 0x9F, 0x1A, 0x27, 0x61 }, + "MEUxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMT" + "FlN3aXNzU2lnbiBHb2xkIENBIC0gRzI=", + "ALtAHEP1Xk+w", + nullptr + }, + { + // CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL + "1.3.6.1.4.1.23223.1.1.1", + "StartCom EV OID", + SEC_OID_UNKNOWN, + { 0x3E, 0x2B, 0xF7, 0xF2, 0x03, 0x1B, 0x96, 0xF3, 0x8C, 0xE6, + 0xC4, 0xD8, 0xA8, 0x5D, 0x3E, 0x2D, 0x58, 0x47, 0x6A, 0x0F }, + "MH0xCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQL" + "EyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBT" + "dGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "AQ==", + nullptr + }, + { + // CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL + "1.3.6.1.4.1.23223.1.1.1", + "StartCom EV OID", + SEC_OID_UNKNOWN, + { 0xA3, 0xF1, 0x33, 0x3F, 0xE2, 0x42, 0xBF, 0xCF, 0xC5, 0xD1, + 0x4E, 0x8F, 0x39, 0x42, 0x98, 0x40, 0x68, 0x10, 0xD1, 0xA0 }, + "MH0xCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQL" + "EyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBT" + "dGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "LQ==", + nullptr + }, + { + // CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL + "1.3.6.1.4.1.23223.1.1.1", + "StartCom EV OID", + SEC_OID_UNKNOWN, + { 0x31, 0xF1, 0xFD, 0x68, 0x22, 0x63, 0x20, 0xEE, 0xC6, 0x3B, + 0x3F, 0x9D, 0xEA, 0x4A, 0x3E, 0x53, 0x7C, 0x7C, 0x39, 0x17 }, + "MFMxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSwwKgYDVQQD" + "EyNTdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBHMg==", + "Ow==", + nullptr + }, + { + // CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU="(c) 2006 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US + "2.16.840.1.113733.1.7.23.6", + "VeriSign EV OID", + SEC_OID_UNKNOWN, + { 0x4E, 0xB6, 0xD5, 0x78, 0x49, 0x9B, 0x1C, 0xCF, 0x5F, 0x58, + 0x1E, 0xAD, 0x56, 0xBE, 0x3D, 0x9B, 0x67, 0x44, 0xA5, 0xE5 }, + "MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV" + "BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA2IFZl" + "cmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMT" + "PFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB" + "dXRob3JpdHkgLSBHNQ==", + "GNrRniZ96LtKIVjNzGs7Sg==", + nullptr + }, + { + // CN=GeoTrust Primary Certification Authority,O=GeoTrust Inc.,C=US + "1.3.6.1.4.1.14370.1.6", + "GeoTrust EV OID", + SEC_OID_UNKNOWN, + { 0x32, 0x3C, 0x11, 0x8E, 0x1B, 0xF7, 0xB8, 0xB6, 0x52, 0x54, + 0xE2, 0xE2, 0x10, 0x0D, 0xD6, 0x02, 0x90, 0x37, 0xF0, 0x96 }, + "MFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQD" + "EyhHZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5", + "GKy1av1pthU6Y2yv2vrEoQ==", + nullptr + }, + { + // CN=thawte Primary Root CA,OU="(c) 2006 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US + "2.16.840.1.113733.1.7.48.1", + "Thawte EV OID", + SEC_OID_UNKNOWN, + { 0x91, 0xC6, 0xD6, 0xEE, 0x3E, 0x8A, 0xC8, 0x63, 0x84, 0xE5, + 0x48, 0xC2, 0x99, 0x29, 0x5C, 0x75, 0x6C, 0x81, 0x7B, 0x81 }, + "MIGpMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMSgwJgYDVQQL" + "Ex9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYDVQQLEy8oYykg" + "MjAwNiB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0G" + "A1UEAxMWdGhhd3RlIFByaW1hcnkgUm9vdCBDQQ==", + "NE7VVyDV7exJ9C/ON9srbQ==", + nullptr + }, + { + // CN=XRamp Global Certification Authority,O=XRamp Security Services Inc,OU=www.xrampsecurity.com,C=US + "2.16.840.1.114404.1.1.2.4.1", + "Trustwave EV OID", + SEC_OID_UNKNOWN, + { 0xB8, 0x01, 0x86, 0xD1, 0xEB, 0x9C, 0x86, 0xA5, 0x41, 0x04, + 0xCF, 0x30, 0x54, 0xF3, 0x4C, 0x52, 0xB7, 0xE5, 0x58, 0xC6 }, + "MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29t" + "MSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMT" + "JFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "UJRs7Bjq1ZxN1ZfvdY+grQ==", + nullptr + }, + { + // CN=SecureTrust CA,O=SecureTrust Corporation,C=US + "2.16.840.1.114404.1.1.2.4.1", + "Trustwave EV OID", + SEC_OID_UNKNOWN, + { 0x87, 0x82, 0xC6, 0xC3, 0x04, 0x35, 0x3B, 0xCF, 0xD2, 0x96, + 0x92, 0xD2, 0x59, 0x3E, 0x7D, 0x44, 0xD9, 0x34, 0xFF, 0x11 }, + "MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlv" + "bjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=", + "DPCOXAgWpa1Cf/DrJxhZ0A==", + nullptr + }, + { + // CN=Secure Global CA,O=SecureTrust Corporation,C=US + "2.16.840.1.114404.1.1.2.4.1", + "Trustwave EV OID", + SEC_OID_UNKNOWN, + { 0x3A, 0x44, 0x73, 0x5A, 0xE5, 0x81, 0x90, 0x1F, 0x24, 0x86, + 0x61, 0x46, 0x1E, 0x3B, 0x9C, 0xC4, 0x5F, 0xF5, 0x3A, 0x1B }, + "MEoxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlv" + "bjEZMBcGA1UEAxMQU2VjdXJlIEdsb2JhbCBDQQ==", + "B1YipOjUiolN9BPI8PjqpQ==", + nullptr + }, + { + // CN=COMODO ECC Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB + "1.3.6.1.4.1.6449.1.2.1.5.1", + "Comodo EV OID", + SEC_OID_UNKNOWN, + { 0x9F, 0x74, 0x4E, 0x9F, 0x2B, 0x4D, 0xBA, 0xEC, 0x0F, 0x31, + 0x2C, 0x50, 0xB6, 0x56, 0x3B, 0x8E, 0x2D, 0x93, 0xC3, 0x11 }, + "MIGFMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAw" + "DgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDErMCkG" + "A1UEAxMiQ09NT0RPIEVDQyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", + "H0evqmIAcFBUTAGem2OZKg==", + nullptr + }, + { + // CN=COMODO Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB + "1.3.6.1.4.1.6449.1.2.1.5.1", + "Comodo EV OID", + SEC_OID_UNKNOWN, + { 0x66, 0x31, 0xBF, 0x9E, 0xF7, 0x4F, 0x9E, 0xB6, 0xC9, 0xD5, + 0xA6, 0x0C, 0xBA, 0x6A, 0xBE, 0xD1, 0xF7, 0xBD, 0xEF, 0x7B }, + "MIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAw" + "DgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEnMCUG" + "A1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5", + "ToEtioJl4AsC7j41AkblPQ==", + nullptr + }, + { + // CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE + "1.3.6.1.4.1.6449.1.2.1.5.1", + "Comodo EV OID", + SEC_OID_UNKNOWN, + { 0x02, 0xFA, 0xF3, 0xE2, 0x91, 0x43, 0x54, 0x68, 0x60, 0x78, + 0x57, 0x69, 0x4D, 0xF5, 0xE4, 0x5B, 0x68, 0x85, 0x18, 0x68 }, + "MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMd" + "QWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0" + "IEV4dGVybmFsIENBIFJvb3Q=", + "AQ==", + nullptr + }, + { + // CN=UTN - DATACorp SGC,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US + "1.3.6.1.4.1.6449.1.2.1.5.1", + "Comodo EV OID", + SEC_OID_UNKNOWN, + { 0x58, 0x11, 0x9F, 0x0E, 0x12, 0x82, 0x87, 0xEA, 0x50, 0xFD, + 0xD9, 0x87, 0x45, 0x6F, 0x4F, 0x78, 0xDC, 0xFA, 0xD6, 0xD4 }, + "MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFr" + "ZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsT" + "GGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNv" + "cnAgU0dD", + "RL4Mi1AAIbQR0ypoBqmtaQ==", + nullptr + }, + { + // CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US + "1.3.6.1.4.1.6449.1.2.1.5.1", + "Comodo EV OID", + SEC_OID_UNKNOWN, + { 0x04, 0x83, 0xED, 0x33, 0x99, 0xAC, 0x36, 0x08, 0x05, 0x87, + 0x22, 0xED, 0xBC, 0x5E, 0x46, 0x00, 0xE3, 0xBE, 0xF9, 0xD7 }, + "MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFr" + "ZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsT" + "GGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEfMB0GA1UEAxMWVVROLVVTRVJGaXJz" + "dC1IYXJkd2FyZQ==", + "RL4Mi1AAJLQR0zYq/mUK/Q==", + nullptr + }, + { + // OU=Go Daddy Class 2 Certification Authority,O=\"The Go Daddy Group, Inc.\",C=US + "2.16.840.1.114413.1.7.23.3", + "Go Daddy EV OID a", + SEC_OID_UNKNOWN, + { 0x27, 0x96, 0xBA, 0xE6, 0x3F, 0x18, 0x01, 0xE2, 0x77, 0x26, + 0x1B, 0xA0, 0xD7, 0x77, 0x70, 0x02, 0x8F, 0x20, 0xEE, 0xE4 }, + "MGMxCzAJBgNVBAYTAlVTMSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIElu" + "Yy4xMTAvBgNVBAsTKEdvIERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRo" + "b3JpdHk=", + "AA==", + nullptr + }, + { + // CN=Go Daddy Root Certificate Authority - G2,O="GoDaddy.com, Inc.",L=Scottsdale,ST=Arizona,C=US + "2.16.840.1.114413.1.7.23.3", + "Go Daddy EV OID a", + SEC_OID_UNKNOWN, + { 0x47, 0xBE, 0xAB, 0xC9, 0x22, 0xEA, 0xE8, 0x0E, 0x78, 0x78, + 0x34, 0x62, 0xA7, 0x9F, 0x45, 0xC2, 0x54, 0xFD, 0xE6, 0x8B }, + "MIGDMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2Nv" + "dHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xMTAvBgNVBAMTKEdv" + "IERhZGR5IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzI=", + "AA==", + nullptr + }, + { + // E=info@valicert.com,CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=\"ValiCert, Inc.\",L=ValiCert Validation Network + "2.16.840.1.114413.1.7.23.3", + "Go Daddy EV OID a", + SEC_OID_UNKNOWN, + { 0x31, 0x7A, 0x2A, 0xD0, 0x7F, 0x2B, 0x33, 0x5E, 0xF5, 0xA1, + 0xC3, 0x4E, 0x4B, 0x57, 0xE8, 0xB7, 0xD8, 0xF1, 0xFC, 0xA6 }, + "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNV" + "BAoTDlZhbGlDZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBv" + "bGljeSBWYWxpZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52" + "YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbQ==", + "AQ==", + nullptr + }, + { + // E=info@valicert.com,CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=\"ValiCert, Inc.\",L=ValiCert Validation Network + "2.16.840.1.114414.1.7.23.3", + "Go Daddy EV OID b", + SEC_OID_UNKNOWN, + { 0x31, 0x7A, 0x2A, 0xD0, 0x7F, 0x2B, 0x33, 0x5E, 0xF5, 0xA1, + 0xC3, 0x4E, 0x4B, 0x57, 0xE8, 0xB7, 0xD8, 0xF1, 0xFC, 0xA6 }, + "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNV" + "BAoTDlZhbGlDZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBv" + "bGljeSBWYWxpZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52" + "YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbQ==", + "AQ==", + nullptr + }, + { + // OU=Starfield Class 2 Certification Authority,O=\"Starfield Technologies, Inc.\",C=US + "2.16.840.1.114414.1.7.23.3", + "Go Daddy EV OID b", + SEC_OID_UNKNOWN, + { 0xAD, 0x7E, 0x1C, 0x28, 0xB0, 0x64, 0xEF, 0x8F, 0x60, 0x03, + 0x40, 0x20, 0x14, 0xC3, 0xD0, 0xE3, 0x37, 0x0E, 0xB5, 0x8A }, + "MGgxCzAJBgNVBAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVz" + "LCBJbmMuMTIwMAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9u" + "IEF1dGhvcml0eQ==", + "AA==", + nullptr + }, + { + // CN=Starfield Root Certificate Authority - G2,O="Starfield Technologies, Inc.",L=Scottsdale,ST=Arizona,C=US + "2.16.840.1.114414.1.7.23.3", + "Go Daddy EV OID b", + SEC_OID_UNKNOWN, + { 0xB5, 0x1C, 0x06, 0x7C, 0xEE, 0x2B, 0x0C, 0x3D, 0xF8, 0x55, + 0xAB, 0x2D, 0x92, 0xF4, 0xFE, 0x39, 0xD4, 0xE7, 0x0F, 0x0E }, + "MIGPMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2Nv" + "dHRzZGFsZTElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEy" + "MDAGA1UEAxMpU3RhcmZpZWxkIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0g" + "RzI=", + "AA==", + nullptr + }, + { + // CN=DigiCert High Assurance EV Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US + "2.16.840.1.114412.2.1", + "DigiCert EV OID", + SEC_OID_UNKNOWN, + { 0x5F, 0xB7, 0xEE, 0x06, 0x33, 0xE2, 0x59, 0xDB, 0xAD, 0x0C, + 0x4C, 0x9A, 0xE6, 0xD3, 0X8F, 0x1A, 0x61, 0xC7, 0xDC, 0x25 }, + "MGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT" + "EHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJh" + "bmNlIEVWIFJvb3QgQ0E=", + "AqxcJmoLQJuPC3nyrkYldw==", + nullptr + }, + { + // CN=QuoVadis Root CA 2,O=QuoVadis Limited,C=BM + "1.3.6.1.4.1.8024.0.2.100.1.2", + "Quo Vadis EV OID", + SEC_OID_UNKNOWN, + { 0xCA, 0x3A, 0xFB, 0xCF, 0x12, 0x40, 0x36, 0x4B, 0x44, 0xB2, + 0x16, 0x20, 0x88, 0x80, 0x48, 0x39, 0x19, 0x93, 0x7C, 0xF7 }, + "MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYD" + "VQQDExJRdW9WYWRpcyBSb290IENBIDI=", + "BQk=", + nullptr + }, + { + // CN=Network Solutions Certificate Authority,O=Network Solutions L.L.C.,C=US + "1.3.6.1.4.1.782.1.2.1.8.1", + "Network Solutions EV OID", + SEC_OID_UNKNOWN, + { 0x74, 0xF8, 0xA3, 0xC3, 0xEF, 0xE7, 0xB3, 0x90, 0x06, 0x4B, + 0x83, 0x90, 0x3C, 0x21, 0x64, 0x60, 0x20, 0xE5, 0xDF, 0xCE }, + "MGIxCzAJBgNVBAYTAlVTMSEwHwYDVQQKExhOZXR3b3JrIFNvbHV0aW9ucyBMLkwu" + "Qy4xMDAuBgNVBAMTJ05ldHdvcmsgU29sdXRpb25zIENlcnRpZmljYXRlIEF1dGhv" + "cml0eQ==", + "V8szb8JcFuZHFhfjkDFo4A==", + nullptr + }, + { + // CN=Entrust Root Certification Authority,OU="(c) 2006 Entrust, Inc.",OU=www.entrust.net/CPS is incorporated by reference,O="Entrust, Inc.",C=US + "2.16.840.1.114028.10.1.2", + "Entrust EV OID", + SEC_OID_UNKNOWN, + { 0xB3, 0x1E, 0xB1, 0xB7, 0x40, 0xE3, 0x6C, 0x84, 0x02, 0xDA, + 0xDC, 0x37, 0xD4, 0x4D, 0xF5, 0xD4, 0x67, 0x49, 0x52, 0xF9 }, + "MIGwMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjE5MDcGA1UE" + "CxMwd3d3LmVudHJ1c3QubmV0L0NQUyBpcyBpbmNvcnBvcmF0ZWQgYnkgcmVmZXJl" + "bmNlMR8wHQYDVQQLExYoYykgMjAwNiBFbnRydXN0LCBJbmMuMS0wKwYDVQQDEyRF" + "bnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHk=", + "RWtQVA==", + nullptr + }, + { + // CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE + "1.3.6.1.4.1.4146.1.1", + "GlobalSign EV OID", + SEC_OID_UNKNOWN, + { 0xB1, 0xBC, 0x96, 0x8B, 0xD4, 0xF4, 0x9D, 0x62, 0x2A, 0xA8, + 0x9A, 0x81, 0xF2, 0x15, 0x01, 0x52, 0xA4, 0x1D, 0x82, 0x9C }, + "MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYD" + "VQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=", + "BAAAAAABFUtaw5Q=", + nullptr + }, + { + // CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R2 + "1.3.6.1.4.1.4146.1.1", + "GlobalSign EV OID", + SEC_OID_UNKNOWN, + { 0x75, 0xE0, 0xAB, 0xB6, 0x13, 0x85, 0x12, 0x27, 0x1C, 0x04, + 0xF8, 0x5F, 0xDD, 0xDE, 0x38, 0xE4, 0xB7, 0x24, 0x2E, 0xFE }, + "MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpH" + "bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu", + "BAAAAAABD4Ym5g0=", + nullptr + }, + { + // CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R3 + "1.3.6.1.4.1.4146.1.1", + "GlobalSign EV OID", + SEC_OID_UNKNOWN, + { 0xD6, 0x9B, 0x56, 0x11, 0x48, 0xF0, 0x1C, 0x77, 0xC5, 0x45, + 0x78, 0xC1, 0x09, 0x26, 0xDF, 0x5B, 0x85, 0x69, 0x76, 0xAD }, + "MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpH" + "bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu", + "BAAAAAABIVhTCKI=", + nullptr + }, + { + // CN=Buypass Class 3 CA 1,O=Buypass AS-983163327,C=NO + "2.16.578.1.26.1.3.3", + "Buypass EV OID", + SEC_OID_UNKNOWN, + { 0x61, 0x57, 0x3A, 0x11, 0xDF, 0x0E, 0xD8, 0x7E, 0xD5, 0x92, + 0x65, 0x22, 0xEA, 0xD0, 0x56, 0xD7, 0x44, 0xB3, 0x23, 0x71 }, + "MEsxCzAJBgNVBAYTAk5PMR0wGwYDVQQKDBRCdXlwYXNzIEFTLTk4MzE2MzMyNzEd" + "MBsGA1UEAwwUQnV5cGFzcyBDbGFzcyAzIENBIDE=", + "Ag==", + nullptr + }, + { + // CN=Buypass Class 3 Root CA,O=Buypass AS-983163327,C=NO + "2.16.578.1.26.1.3.3", + "Buypass EV OID", + SEC_OID_UNKNOWN, + { 0xDA, 0xFA, 0xF7, 0xFA, 0x66, 0x84, 0xEC, 0x06, 0x8F, 0x14, + 0x50, 0xBD, 0xC7, 0xC2, 0x81, 0xA5, 0xBC, 0xA9, 0x64, 0x57 }, + "ME4xCzAJBgNVBAYTAk5PMR0wGwYDVQQKDBRCdXlwYXNzIEFTLTk4MzE2MzMyNzEg" + "MB4GA1UEAwwXQnV5cGFzcyBDbGFzcyAzIFJvb3QgQ0E=", + "Ag==", + nullptr + }, + { + // CN=Class 2 Primary CA,O=Certplus,C=FR + "1.3.6.1.4.1.22234.2.5.2.3.1", + "Certplus EV OID", + SEC_OID_UNKNOWN, + { 0x74, 0x20, 0x74, 0x41, 0x72, 0x9C, 0xDD, 0x92, 0xEC, 0x79, + 0x31, 0xD8, 0x23, 0x10, 0x8D, 0xC2, 0x81, 0x92, 0xE2, 0xBB }, + "MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xh" + "c3MgMiBQcmltYXJ5IENB", + "AIW9S/PY2uNp9pTXX8OlRCM=", + nullptr + }, + { + // CN=Chambers of Commerce Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU + "1.3.6.1.4.1.17326.10.14.2.1.2", + "Camerfirma EV OID a", + SEC_OID_UNKNOWN, + { 0x78, 0x6A, 0x74, 0xAC, 0x76, 0xAB, 0x14, 0x7F, 0x9C, 0x6A, + 0x30, 0x50, 0xBA, 0x9E, 0xA8, 0x7E, 0xFE, 0x9A, 0xCE, 0x3C }, + "MIGuMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh" + "ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ" + "QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMT" + "IENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4", + "AKPaQn6ksa7a", + nullptr + }, + { + // CN=Global Chambersign Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU + "1.3.6.1.4.1.17326.10.8.12.1.2", + "Camerfirma EV OID b", + SEC_OID_UNKNOWN, + { 0x4A, 0xBD, 0xEE, 0xEC, 0x95, 0x0D, 0x35, 0x9C, 0x89, 0xAE, + 0xC7, 0x52, 0xA1, 0x2C, 0x5B, 0x29, 0xF6, 0xD6, 0xAA, 0x0C }, + "MIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh" + "ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ" + "QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMT" + "Hkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwOA==", + "AMnN0+nVfSPO", + nullptr + }, + { + // CN=TC TrustCenter Universal CA III,OU=TC TrustCenter Universal CA,O=TC TrustCenter GmbH,C=DE + "1.2.276.0.44.1.1.1.4", + "TC TrustCenter EV OID", + SEC_OID_UNKNOWN, + { 0x96, 0x56, 0xCD, 0x7B, 0x57, 0x96, 0x98, 0x95, 0xD0, 0xE1, + 0x41, 0x46, 0x68, 0x06, 0xFB, 0xB8, 0xC6, 0x11, 0x06, 0x87 }, + "MHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRlciBHbWJIMSQw" + "IgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAmBgNVBAMTH1RD" + "IFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUk=", + "YyUAAQACFI0zFQLkbPQ=", + nullptr + }, + { + // CN=AffirmTrust Commercial,O=AffirmTrust,C=US + "1.3.6.1.4.1.34697.2.1", + "AffirmTrust EV OID a", + SEC_OID_UNKNOWN, + { 0xF9, 0xB5, 0xB6, 0x32, 0x45, 0x5F, 0x9C, 0xBE, 0xEC, 0x57, + 0x5F, 0x80, 0xDC, 0xE9, 0x6E, 0x2C, 0xC7, 0xB2, 0x78, 0xB7 }, + "MEQxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEfMB0GA1UEAwwW" + "QWZmaXJtVHJ1c3QgQ29tbWVyY2lhbA==", + "d3cGJyapsXw=", + nullptr + }, + { + // CN=AffirmTrust Networking,O=AffirmTrust,C=US + "1.3.6.1.4.1.34697.2.2", + "AffirmTrust EV OID b", + SEC_OID_UNKNOWN, + { 0x29, 0x36, 0x21, 0x02, 0x8B, 0x20, 0xED, 0x02, 0xF5, 0x66, + 0xC5, 0x32, 0xD1, 0xD6, 0xED, 0x90, 0x9F, 0x45, 0x00, 0x2F }, + "MEQxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEfMB0GA1UEAwwW" + "QWZmaXJtVHJ1c3QgTmV0d29ya2luZw==", + "fE8EORzUmS0=", + nullptr + }, + { + // CN=AffirmTrust Premium,O=AffirmTrust,C=US + "1.3.6.1.4.1.34697.2.3", + "AffirmTrust EV OID c", + SEC_OID_UNKNOWN, + { 0xD8, 0xA6, 0x33, 0x2C, 0xE0, 0x03, 0x6F, 0xB1, 0x85, 0xF6, + 0x63, 0x4F, 0x7D, 0x6A, 0x06, 0x65, 0x26, 0x32, 0x28, 0x27 }, + "MEExCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEcMBoGA1UEAwwT" + "QWZmaXJtVHJ1c3QgUHJlbWl1bQ==", + "bYwURrGmCu4=", + nullptr + }, + { + // CN=AffirmTrust Premium ECC,O=AffirmTrust,C=US + "1.3.6.1.4.1.34697.2.4", + "AffirmTrust EV OID d", + SEC_OID_UNKNOWN, + { 0xB8, 0x23, 0x6B, 0x00, 0x2F, 0x1D, 0x16, 0x86, 0x53, 0x01, + 0x55, 0x6C, 0x11, 0xA4, 0x37, 0xCA, 0xEB, 0xFF, 0xC3, 0xBB }, + "MEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwX" + "QWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0M=", + "dJclisc/elQ=", + nullptr + }, + { + // CN=Certum Trusted Network CA,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL + "1.2.616.1.113527.2.5.1.1", + "Certum EV OID", + SEC_OID_UNKNOWN, + { 0x07, 0xE0, 0x32, 0xE0, 0x20, 0xB7, 0x2C, 0x3F, 0x19, 0x2F, + 0x06, 0x28, 0xA2, 0x59, 0x3A, 0x19, 0xA7, 0x0F, 0x06, 0x9E }, + "MH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBT" + "LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAg" + "BgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0E=", + "BETA", + nullptr + }, + { + // CN=Izenpe.com,O=IZENPE S.A.,C=ES + "1.3.6.1.4.1.14777.6.1.1", + "Izenpe EV OID 1", + SEC_OID_UNKNOWN, + { 0x2F, 0x78, 0x3D, 0x25, 0x52, 0x18, 0xA7, 0x4A, 0x65, 0x39, + 0x71, 0xB5, 0x2C, 0xA2, 0x9C, 0x45, 0x15, 0x6F, 0xE9, 0x19 }, + "MDgxCzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwK" + "SXplbnBlLmNvbQ==", + "ALC3WhZIX7/hy/WL1xnmfQ==", + nullptr + }, + { + // CN=Izenpe.com,O=IZENPE S.A.,C=ES + "1.3.6.1.4.1.14777.6.1.2", + "Izenpe EV OID 2", + SEC_OID_UNKNOWN, + { 0x2F, 0x78, 0x3D, 0x25, 0x52, 0x18, 0xA7, 0x4A, 0x65, 0x39, + 0x71, 0xB5, 0x2C, 0xA2, 0x9C, 0x45, 0x15, 0x6F, 0xE9, 0x19 }, + "MDgxCzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwK" + "SXplbnBlLmNvbQ==", + "ALC3WhZIX7/hy/WL1xnmfQ==", + nullptr + }, + { + // CN=A-Trust-nQual-03,OU=A-Trust-nQual-03,O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,C=AT + "1.2.40.0.17.1.22", + "A-Trust EV OID", + SEC_OID_UNKNOWN, + { 0xD3, 0xC0, 0x63, 0xF2, 0x19, 0xED, 0x07, 0x3E, 0x34, 0xAD, + 0x5D, 0x75, 0x0B, 0x32, 0x76, 0x29, 0xFF, 0xD5, 0x9A, 0xF2 }, + "MIGNMQswCQYDVQQGEwJBVDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hl" + "cmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYD" + "VQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAz", + "AWwe", + nullptr + }, + { + // CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE + "1.3.6.1.4.1.7879.13.24.1", + "T-Systems EV OID", + SEC_OID_UNKNOWN, + { 0x55, 0xA6, 0x72, 0x3E, 0xCB, 0xF2, 0xEC, 0xCD, 0xC3, 0x23, + 0x74, 0x70, 0x19, 0x9D, 0x2A, 0xBE, 0x11, 0xE3, 0x81, 0xD1 }, + "MIGCMQswCQYDVQQGEwJERTErMCkGA1UECgwiVC1TeXN0ZW1zIEVudGVycHJpc2Ug" + "U2VydmljZXMgR21iSDEfMB0GA1UECwwWVC1TeXN0ZW1zIFRydXN0IENlbnRlcjEl" + "MCMGA1UEAwwcVC1UZWxlU2VjIEdsb2JhbFJvb3QgQ2xhc3MgMw==", + "AQ==", + nullptr + }, + { + // CN=TURKTRUST Elektronik Sertifika Hizmet Saglayicisi,O=TURKTRUST Bilgi Illetisim ve Bilisim Guvenligi Hizmetleri A.S.,C=TR + "2.16.792.3.0.3.1.1.5", + "TurkTrust EV OID", + SEC_OID_UNKNOWN, + { 0xF1, 0x7F, 0x6F, 0xB6, 0x31, 0xDC, 0x99, 0xE3, 0xA3, 0xC8, + 0x7F, 0xFE, 0x1C, 0xF1, 0x81, 0x10, 0x88, 0xD9, 0x60, 0x33 }, + "MIG/MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlmaWthIEhp" + "em1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmth" + "cmExXjBcBgNVBAoMVVTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxp" + "xZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uIChjKSBBcmFsxLFrIDIw" + "MDc=", + "AQ==", + nullptr + }, + { + // CN=China Internet Network Information Center EV Certificates Root,O=China Internet Network Information Center,C=CN + "1.3.6.1.4.1.29836.1.10", + "CNNIC EV OID", + SEC_OID_UNKNOWN, + { 0x4F, 0x99, 0xAA, 0x93, 0xFB, 0x2B, 0xD1, 0x37, 0x26, 0xA1, + 0x99, 0x4A, 0xCE, 0x7F, 0xF0, 0x05, 0xF2, 0x93, 0x5D, 0x1E }, + "MIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29y" + "ayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNoaW5hIEludGVybmV0IE5l" + "dHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRlcyBSb290", + "SJ8AAQ==", + nullptr + }, + { + // CN=TWCA Root Certification Authority,OU=Root CA,O=TAIWAN-CA,C=TW + "1.3.6.1.4.1.40869.1.1.22.3", + "TWCA EV OID", + SEC_OID_UNKNOWN, + { 0xCF, 0x9E, 0x87, 0x6D, 0xD3, 0xEB, 0xFC, 0x42, 0x26, 0x97, + 0xA3, 0xB5, 0xA3, 0x7A, 0xA0, 0x76, 0xA9, 0x06, 0x23, 0x48 }, + "MF8xCzAJBgNVBAYTAlRXMRIwEAYDVQQKDAlUQUlXQU4tQ0ExEDAOBgNVBAsMB1Jv" + "b3QgQ0ExKjAoBgNVBAMMIVRXQ0EgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0" + "eQ==", + "AQ==", + nullptr + }, + { + // CN=D-TRUST Root Class 3 CA 2 EV 2009,O=D-Trust GmbH,C=DE + "1.3.6.1.4.1.4788.2.202.1", + "D-TRUST EV OID", + SEC_OID_UNKNOWN, + { 0x96, 0xC9, 0x1B, 0x0B, 0x95, 0xB4, 0x10, 0x98, 0x42, 0xFA, + 0xD0, 0xD8, 0x22, 0x79, 0xFE, 0x60, 0xFA, 0xB9, 0x16, 0x83 }, + "MFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMM" + "IUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOQ==", + "CYP0", + nullptr + }, + { + // CN=Swisscom Root EV CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch + "2.16.756.1.83.21.0", + "Swisscom EV OID", + SEC_OID_UNKNOWN, + { 0xE7, 0xA1, 0x90, 0x29, 0xD3, 0xD5, 0x52, 0xDC, 0x0D, 0x0F, + 0xC6, 0x92, 0xD3, 0xEA, 0x88, 0x0D, 0x15, 0x2E, 0x1A, 0x6B }, + "MGcxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln" + "aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEeMBwGA1UEAxMVU3dpc3Njb20gUm9v" + "dCBFViBDQSAy", + "APL6ZOJ0Y9ON/RAdBB92ylg=", + nullptr + }, + { + // CN=VeriSign Universal Root Certification Authority,OU="(c) 2008 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US + "2.16.840.1.113733.1.7.23.6", + "VeriSign EV OID", + SEC_OID_UNKNOWN, + { 0x36, 0x79, 0xCA, 0x35, 0x66, 0x87, 0x72, 0x30, 0x4D, 0x30, + 0xA5, 0xFB, 0x87, 0x3B, 0x0F, 0xA7, 0x7B, 0xB7, 0x0D, 0x54 }, + "MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV" + "BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZl" + "cmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMT" + "L1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5", + "QBrEZCGzEyEDDrvkEhrFHQ==", + nullptr + }, + { + // CN=GeoTrust Primary Certification Authority - G3,OU=(c) 2008 GeoTrust Inc. - For authorized use only,O=GeoTrust Inc.,C=US + "1.3.6.1.4.1.14370.1.6", + "GeoTrust EV OID", + SEC_OID_UNKNOWN, + { 0x03, 0x9E, 0xED, 0xB8, 0x0B, 0xE7, 0xA0, 0x3C, 0x69, 0x53, + 0x89, 0x3B, 0x20, 0xD2, 0xD9, 0x32, 0x3A, 0x4C, 0x2A, 0xFD }, + "MIGYMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjE5MDcGA1UE" + "CxMwKGMpIDIwMDggR2VvVHJ1c3QgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBv" + "bmx5MTYwNAYDVQQDEy1HZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0" + "aG9yaXR5IC0gRzM=", + "FaxulBmyeUtB9iepwxgPHw==", + nullptr + }, + { + // CN=thawte Primary Root CA - G3,OU="(c) 2008 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US + "2.16.840.1.113733.1.7.48.1", + "Thawte EV OID", + SEC_OID_UNKNOWN, + { 0xF1, 0x8B, 0x53, 0x8D, 0x1B, 0xE9, 0x03, 0xB6, 0xA6, 0xF0, + 0x56, 0x43, 0x5B, 0x17, 0x15, 0x89, 0xCA, 0xF3, 0x6B, 0xF2 }, + "MIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMSgwJgYDVQQL" + "Ex9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYDVQQLEy8oYykg" + "MjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG" + "A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz", + "YAGXt0an6rS0mtZLL/eQ+w==", + nullptr + } +}; + +static SECOidTag +register_oid(const SECItem* oid_item, const char* oid_name) +{ + if (!oid_item) + return SEC_OID_UNKNOWN; + + SECOidData od; + od.oid.len = oid_item->len; + od.oid.data = oid_item->data; + od.offset = SEC_OID_UNKNOWN; + od.desc = oid_name; + od.mechanism = CKM_INVALID_MECHANISM; + od.supportedExtension = INVALID_CERT_EXTENSION; + return SECOID_AddEntry(&od); +} + +static void +addToCertListIfTrusted(CERTCertList* certList, CERTCertificate* cert) { + CERTCertTrust nssTrust; + if (CERT_GetCertTrust(cert, &nssTrust) != SECSuccess) { + return; + } + unsigned int flags = SEC_GET_TRUST_FLAGS(&nssTrust, trustSSL); + + if (flags & CERTDB_TRUSTED_CA) { + CERT_AddCertToListTail(certList, CERT_DupCertificate(cert)); + } +} + +static bool +isEVPolicy(SECOidTag policyOIDTag) +{ + for (size_t iEV = 0; iEV < PR_ARRAY_SIZE(myTrustedEVInfos); ++iEV) { + nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV]; + if (policyOIDTag == entry.oid_tag) { + return true; + } + } + + return false; +} + +namespace mozilla { namespace psm { + +CERTCertList* +GetRootsForOid(SECOidTag oid_tag) +{ + CERTCertList* certList = CERT_NewCertList(); + if (!certList) + return nullptr; + + for (size_t iEV = 0; iEV < PR_ARRAY_SIZE(myTrustedEVInfos); ++iEV) { + nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV]; + if (entry.oid_tag == oid_tag) { + addToCertListIfTrusted(certList, entry.cert); + } + } + + return certList; +} + +static PRStatus +IdentityInfoInit() +{ + for (size_t iEV = 0; iEV < PR_ARRAY_SIZE(myTrustedEVInfos); ++iEV) { + nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV]; + + SECStatus rv; + CERTIssuerAndSN ias; + + rv = ATOB_ConvertAsciiToItem(&ias.derIssuer, const_cast<char*>(entry.issuer_base64)); + PR_ASSERT(rv == SECSuccess); + if (rv != SECSuccess) { + return PR_FAILURE; + } + rv = ATOB_ConvertAsciiToItem(&ias.serialNumber, + const_cast<char*>(entry.serial_base64)); + PR_ASSERT(rv == SECSuccess); + if (rv != SECSuccess) { + SECITEM_FreeItem(&ias.derIssuer, false); + return PR_FAILURE; + } + + ias.serialNumber.type = siUnsignedInteger; + + entry.cert = CERT_FindCertByIssuerAndSN(nullptr, &ias); + + SECITEM_FreeItem(&ias.derIssuer, false); + SECITEM_FreeItem(&ias.serialNumber, false); + + // If an entry is missing in the NSS root database, it may be because the + // root database is out of sync with what we expect (e.g. a different + // version of system NSS is installed). We will just silently avoid + // treating that root cert as EV. + if (!entry.cert) { +#ifdef DEBUG + // The debug CA info is at position 0, and is NOT on the NSS root db + if (iEV == 0) { + continue; + } +#endif + PR_NOT_REACHED("Could not find EV root in NSS storage"); + continue; + } + + unsigned char certFingerprint[20]; + rv = PK11_HashBuf(SEC_OID_SHA1, certFingerprint, + entry.cert->derCert.data, entry.cert->derCert.len); + MOZ_ASSERT(rv == SECSuccess); + if (rv == SECSuccess) { + bool same = !memcmp(certFingerprint, entry.ev_root_sha1_fingerprint, 20); + MOZ_ASSERT(same); + if (same) { + + SECItem ev_oid_item; + ev_oid_item.data = nullptr; + ev_oid_item.len = 0; + rv = SEC_StringToOID(nullptr, &ev_oid_item, entry.dotted_oid, 0); + MOZ_ASSERT(rv == SECSuccess); + if (rv == SECSuccess) { + entry.oid_tag = register_oid(&ev_oid_item, entry.oid_name); + if (entry.oid_tag == SEC_OID_UNKNOWN) { + rv = SECFailure; + } + SECITEM_FreeItem(&ev_oid_item, false); + } + } else { + PR_SetError(SEC_ERROR_BAD_DATA, 0); + rv = SECFailure; + } + } + + if (rv != SECSuccess) { + CERT_DestroyCertificate(entry.cert); + entry.cert = nullptr; + entry.oid_tag = SEC_OID_UNKNOWN; + return PR_FAILURE; + } + } + + return PR_SUCCESS; +} + +static PRCallOnceType sIdentityInfoCallOnce; + +void +EnsureIdentityInfoLoaded() +{ + (void) PR_CallOnce(&sIdentityInfoCallOnce, IdentityInfoInit); +} + +void +CleanupIdentityInfo() +{ + for (size_t iEV = 0; iEV < PR_ARRAY_SIZE(myTrustedEVInfos); ++iEV) { + nsMyTrustedEVInfo &entry = myTrustedEVInfos[iEV]; + if (entry.cert) { + CERT_DestroyCertificate(entry.cert); + entry.cert = nullptr; + } + } + + memset(&sIdentityInfoCallOnce, 0, sizeof(PRCallOnceType)); +} + +// Find the first policy OID that is known to be an EV policy OID. +SECStatus +GetFirstEVPolicy(CERTCertificate* cert, SECOidTag& outOidTag) +{ + if (!cert) + return SECFailure; + + if (cert->extensions) { + for (int i=0; cert->extensions[i]; i++) { + const SECItem* oid = &cert->extensions[i]->id; + + SECOidTag oidTag = SECOID_FindOIDTag(oid); + if (oidTag != SEC_OID_X509_CERTIFICATE_POLICIES) + continue; + + SECItem* value = &cert->extensions[i]->value; + + CERTCertificatePolicies* policies; + CERTPolicyInfo** policyInfos; + + policies = CERT_DecodeCertificatePoliciesExtension(value); + if (!policies) + continue; + + policyInfos = policies->policyInfos; + + bool found = false; + while (*policyInfos) { + const CERTPolicyInfo* policyInfo = *policyInfos++; + + SECOidTag oid_tag = policyInfo->oid; + if (oid_tag != SEC_OID_UNKNOWN && isEVPolicy(oid_tag)) { + // in our list of OIDs accepted for EV + outOidTag = oid_tag; + found = true; + break; + } + } + CERT_DestroyCertificatePoliciesExtension(policies); + if (found) + return SECSuccess; + } + } + + return SECFailure; +} + +} } // namespace mozilla::psm
new file mode 100644 --- /dev/null +++ b/security/certverifier/ExtendedValidation.h @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_psm_ExtendedValidation_h +#define mozilla_psm_ExtendedValidation_h + +#include "certt.h" +#include "prtypes.h" + +namespace mozilla { namespace psm { + +#ifndef NSS_NO_LIBPKIX +void EnsureIdentityInfoLoaded(); +SECStatus GetFirstEVPolicy(CERTCertificate *cert, SECOidTag &outOidTag); +CERTCertList* GetRootsForOid(SECOidTag oid_tag); +void CleanupIdentityInfo(); +#endif + +} } // namespace mozilla::psm + +#endif // mozilla_psm_ExtendedValidation_h
new file mode 100644 --- /dev/null +++ b/security/certverifier/moz.build @@ -0,0 +1,20 @@ +# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +UNIFIED_SOURCES += [ + 'CertVerifier.cpp', +] + +if not CONFIG['NSS_NO_LIBPKIX']: + UNIFIED_SOURCES += [ + 'ExtendedValidation.cpp', + ] + +LOCAL_INCLUDES += [ + '../insanity/include', +] + +FINAL_LIBRARY = 'xul'
deleted file mode 100644 --- a/security/manager/ssl/src/CertVerifier.cpp +++ /dev/null @@ -1,441 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CertVerifier.h" -#include "ScopedNSSTypes.h" -#include "cert.h" -#include "secerr.h" -#include "prerror.h" - -#ifdef PR_LOGGING -extern PRLogModuleInfo* gPIPNSSLog; -#endif - -namespace mozilla { namespace psm { - -extern SECStatus getFirstEVPolicy(CERTCertificate* cert, SECOidTag& outOidTag); -extern CERTCertList* getRootsForOid(SECOidTag oid_tag); - -const CertVerifier::Flags CertVerifier::FLAG_LOCAL_ONLY = 1; -const CertVerifier::Flags CertVerifier::FLAG_NO_DV_FALLBACK_FOR_EV = 2; - -CertVerifier::CertVerifier(implementation_config ic, - missing_cert_download_config mcdc, - crl_download_config cdc, - ocsp_download_config odc, - ocsp_strict_config osc, - ocsp_get_config ogc) - : mImplementation(ic) - , mMissingCertDownloadEnabled(mcdc == missing_cert_download_on) - , mCRLDownloadEnabled(cdc == crl_download_allowed) - , mOCSPDownloadEnabled(odc == ocsp_on) - , mOCSPStrict(osc == ocsp_strict) - , mOCSPGETEnabled(ogc == ocsp_get_enabled) -{ -} - -CertVerifier::~CertVerifier() -{ -} - -static SECStatus -ClassicVerifyCert(CERTCertificate* cert, - const SECCertificateUsage usage, - const PRTime time, - void* pinArg, - /*optional out*/ CERTCertList** validationChain, - /*optional out*/ CERTVerifyLog* verifyLog) -{ - SECStatus rv; - SECCertUsage enumUsage; - if (validationChain) { - switch(usage){ - case certificateUsageSSLClient: - enumUsage = certUsageSSLClient; - break; - case certificateUsageSSLServer: - enumUsage = certUsageSSLServer; - break; - case certificateUsageSSLServerWithStepUp: - enumUsage = certUsageSSLServerWithStepUp; - break; - case certificateUsageSSLCA: - enumUsage = certUsageSSLCA; - break; - case certificateUsageEmailSigner: - enumUsage = certUsageEmailSigner; - break; - case certificateUsageEmailRecipient: - enumUsage = certUsageEmailRecipient; - break; - case certificateUsageObjectSigner: - enumUsage = certUsageObjectSigner; - break; - case certificateUsageUserCertImport: - enumUsage = certUsageUserCertImport; - break; - case certificateUsageVerifyCA: - enumUsage = certUsageVerifyCA; - break; - case certificateUsageProtectedObjectSigner: - enumUsage = certUsageProtectedObjectSigner; - break; - case certificateUsageStatusResponder: - enumUsage = certUsageStatusResponder; - break; - case certificateUsageAnyCA: - enumUsage = certUsageAnyCA; - break; - default: - return SECFailure; - } - } - if (usage == certificateUsageSSLServer) { - // SSL server cert verification has always used CERT_VerifyCert, so we - // continue to use it for SSL cert verification to minimize the risk of - // there being any differnce in results between CERT_VerifyCert and - // CERT_VerifyCertificate. - rv = CERT_VerifyCert(CERT_GetDefaultCertDB(), cert, true, - certUsageSSLServer, time, pinArg, verifyLog); - } else { - rv = CERT_VerifyCertificate(CERT_GetDefaultCertDB(), cert, true, - usage, time, pinArg, verifyLog, nullptr); - } - if (rv == SECSuccess && validationChain) { - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: getting chain in 'classic' \n")); - *validationChain = CERT_GetCertChainFromCert(cert, time, enumUsage); - if (!*validationChain) { - rv = SECFailure; - } - } - return rv; -} - -SECStatus -CertVerifier::VerifyCert(CERTCertificate* cert, - const SECCertificateUsage usage, - const PRTime time, - void* pinArg, - const Flags flags, - /*optional out*/ CERTCertList** validationChain, - /*optional out*/ SECOidTag* evOidPolicy, - /*optional out*/ CERTVerifyLog* verifyLog) -{ - if (!cert || - ((flags & FLAG_NO_DV_FALLBACK_FOR_EV) && - (usage != certificateUsageSSLServer || !evOidPolicy))) - { - PR_NOT_REACHED("Invalid arguments to CertVerifier::VerifyCert"); - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - if (validationChain) { - *validationChain = nullptr; - } - if (evOidPolicy) { - *evOidPolicy = SEC_OID_UNKNOWN; - } - - switch(usage){ - case certificateUsageSSLClient: - case certificateUsageSSLServer: - case certificateUsageSSLCA: - case certificateUsageEmailSigner: - case certificateUsageEmailRecipient: - case certificateUsageObjectSigner: - case certificateUsageStatusResponder: - break; - default: - NS_WARNING("Calling VerifyCert with invalid usage"); - PORT_SetError(SEC_ERROR_INVALID_ARGS); - return SECFailure; - } - -#ifndef NSS_NO_LIBPKIX - ScopedCERTCertList trustAnchors; - SECStatus rv; - SECOidTag evPolicy = SEC_OID_UNKNOWN; - - // Do EV checking only for sslserver usage - if (usage == certificateUsageSSLServer) { - SECStatus srv = getFirstEVPolicy(cert, evPolicy); - if (srv == SECSuccess) { - if (evPolicy != SEC_OID_UNKNOWN) { - trustAnchors = getRootsForOid(evPolicy); - } - if (!trustAnchors) { - return SECFailure; - } - // pkix ignores an empty trustanchors list and - // decides then to use the whole set of trust in the DB - // so we set the evPolicy to unkown in this case - if (CERT_LIST_EMPTY(trustAnchors)) { - evPolicy = SEC_OID_UNKNOWN; - } - } else { - // Do not setup EV verification params - evPolicy = SEC_OID_UNKNOWN; - } - } - - MOZ_ASSERT_IF(evPolicy != SEC_OID_UNKNOWN, trustAnchors); - - size_t i = 0; - size_t validationChainLocation = 0; - size_t validationTrustAnchorLocation = 0; - CERTValOutParam cvout[4]; - if (verifyLog) { - cvout[i].type = cert_po_errorLog; - cvout[i].value.pointer.log = verifyLog; - ++i; - } - if (validationChain) { - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: setting up validation chain outparam.\n")); - validationChainLocation = i; - cvout[i].type = cert_po_certList; - cvout[i].value.pointer.cert = nullptr; - ++i; - validationTrustAnchorLocation = i; - cvout[i].type = cert_po_trustAnchor; - cvout[i].value.pointer.chain = nullptr; - ++i; - } - cvout[i].type = cert_po_end; - - CERTRevocationFlags rev; - - CERTRevocationMethodIndex revPreferredMethods[2]; - rev.leafTests.preferred_methods = - rev.chainTests.preferred_methods = revPreferredMethods; - - uint64_t revFlagsPerMethod[2]; - rev.leafTests.cert_rev_flags_per_method = - rev.chainTests.cert_rev_flags_per_method = revFlagsPerMethod; - rev.leafTests.number_of_preferred_methods = - rev.chainTests.number_of_preferred_methods = 1; - - rev.leafTests.number_of_defined_methods = - rev.chainTests.number_of_defined_methods = cert_revocation_method_ocsp + 1; - - const bool localOnly = flags & FLAG_LOCAL_ONLY; - CERTValInParam cvin[6]; - - // Parameters for both EV and DV validation - cvin[0].type = cert_pi_useAIACertFetch; - cvin[0].value.scalar.b = mMissingCertDownloadEnabled && !localOnly; - cvin[1].type = cert_pi_revocationFlags; - cvin[1].value.pointer.revocation = &rev; - cvin[2].type = cert_pi_date; - cvin[2].value.scalar.time = time; - i = 3; - const size_t evParamLocation = i; - - if (evPolicy != SEC_OID_UNKNOWN) { - // EV setup! - // XXX 859872 The current flags are not quite correct. (use - // of ocsp flags for crl preferences). - uint64_t ocspRevMethodFlags = - CERT_REV_M_TEST_USING_THIS_METHOD - | ((mOCSPDownloadEnabled && !localOnly) ? - CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING) - | CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE - | CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE - | CERT_REV_M_IGNORE_MISSING_FRESH_INFO - | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO - | (mOCSPGETEnabled ? 0 : CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP); - - rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] = - rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] - = CERT_REV_M_DO_NOT_TEST_USING_THIS_METHOD; - - rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = - rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] - = ocspRevMethodFlags; - - rev.leafTests.cert_rev_method_independent_flags = - rev.chainTests.cert_rev_method_independent_flags = - // avoiding the network is good, let's try local first - CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST - // is overall revocation requirement strict or relaxed? - | CERT_REV_MI_REQUIRE_SOME_FRESH_INFO_AVAILABLE - ; - - rev.leafTests.preferred_methods[0] = - rev.chainTests.preferred_methods[0] = cert_revocation_method_ocsp; - - cvin[i].type = cert_pi_policyOID; - cvin[i].value.arraySize = 1; - cvin[i].value.array.oids = &evPolicy; - ++i; - MOZ_ASSERT(trustAnchors); - cvin[i].type = cert_pi_trustAnchors; - cvin[i].value.pointer.chain = trustAnchors; - ++i; - - cvin[i].type = cert_pi_end; - - rv = CERT_PKIXVerifyCert(cert, usage, cvin, cvout, pinArg); - if (rv == SECSuccess) { - if (evOidPolicy) { - *evOidPolicy = evPolicy; - } - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, - ("VerifyCert: successful CERT_PKIXVerifyCert(ev) \n")); - goto pkix_done; - } - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, - ("VerifyCert: failed CERT_PKIXVerifyCert(ev)\n")); - - if (validationChain && *validationChain) { - // There SHOULD not be a validation chain on failure, asserion here for - // the debug builds AND a fallback for production builds - MOZ_ASSERT(false, - "certPKIXVerifyCert returned failure AND a validationChain"); - CERT_DestroyCertList(*validationChain); - *validationChain = nullptr; - } - - if (verifyLog) { - // Cleanup the log so that it is ready the the next validation - CERTVerifyLogNode* i_node; - for (i_node = verifyLog->head; i_node; i_node = i_node->next) { - //destroy cert if any. - if (i_node->cert) { - CERT_DestroyCertificate(i_node->cert); - } - // No need to cleanup the actual nodes in the arena. - } - verifyLog->count = 0; - verifyLog->head = nullptr; - verifyLog->tail = nullptr; - } - - } -#endif - - // If we're here, PKIX EV verification failed. - // If requested, don't do DV fallback. - if (flags & FLAG_NO_DV_FALLBACK_FOR_EV) { - PR_ASSERT(*evOidPolicy == SEC_OID_UNKNOWN); - return SECSuccess; - } - - if (mImplementation == classic) { - // XXX: we do not care about the localOnly flag (currently) as the - // caller that wants localOnly should disable and reenable the fetching. - return ClassicVerifyCert(cert, usage, time, pinArg, validationChain, - verifyLog); - } - -#ifdef NSS_NO_LIBPKIX - PR_NOT_REACHED("libpkix implementation chosen but not even compiled in"); - PR_SetError(PR_INVALID_STATE_ERROR, 0); - return SECFailure; -#else - PR_ASSERT(mImplementation == libpkix); - - // The current flags check the chain the same way as the leafs - rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_crl] = - rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_crl] = - // implicit default source - makes no sense for CRLs - CERT_REV_M_IGNORE_IMPLICIT_DEFAULT_SOURCE - - // let's not stop on fresh CRL. If OCSP is enabled, too, let's check it - | CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO - - // no fresh CRL? well, let other flag decide whether to fail or not - | CERT_REV_M_IGNORE_MISSING_FRESH_INFO - - // testing using local CRLs is always allowed - | CERT_REV_M_TEST_USING_THIS_METHOD - - // no local crl and don't know where to get it from? ignore - | CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE - - // crl download based on parameter - | ((mCRLDownloadEnabled && !localOnly) ? - CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING) - ; - - rev.leafTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = - rev.chainTests.cert_rev_flags_per_method[cert_revocation_method_ocsp] = - // use OCSP - CERT_REV_M_TEST_USING_THIS_METHOD - - // if app has a default OCSP responder configured, let's use it - | CERT_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE - - // of course OCSP doesn't work without a source. let's accept such certs - | CERT_REV_M_SKIP_TEST_ON_MISSING_SOURCE - - // if ocsp is required stop on lack of freshness - | (mOCSPStrict ? - CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO : CERT_REV_M_IGNORE_MISSING_FRESH_INFO) - - // ocsp success is sufficient - | CERT_REV_M_STOP_TESTING_ON_FRESH_INFO - - // ocsp enabled controls network fetching, too - | ((mOCSPDownloadEnabled && !localOnly) ? - CERT_REV_M_ALLOW_NETWORK_FETCHING : CERT_REV_M_FORBID_NETWORK_FETCHING) - - | (mOCSPGETEnabled ? 0 : CERT_REV_M_FORCE_POST_METHOD_FOR_OCSP); - ; - - rev.leafTests.preferred_methods[0] = - rev.chainTests.preferred_methods[0] = cert_revocation_method_ocsp; - - rev.leafTests.cert_rev_method_independent_flags = - rev.chainTests.cert_rev_method_independent_flags = - // avoiding the network is good, let's try local first - CERT_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST; - - // Skip EV parameters - cvin[evParamLocation].type = cert_pi_end; - - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: calling CERT_PKIXVerifyCert(dv) \n")); - rv = CERT_PKIXVerifyCert(cert, usage, cvin, cvout, pinArg); - -pkix_done: - if (validationChain) { - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: validation chain requested\n")); - ScopedCERTCertificate trustAnchor(cvout[validationTrustAnchorLocation].value.pointer.cert); - - if (rv == SECSuccess) { - if (! cvout[validationChainLocation].value.pointer.chain) { - PR_SetError(PR_UNKNOWN_ERROR, 0); - return SECFailure; - } - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: I have a chain\n")); - *validationChain = cvout[validationChainLocation].value.pointer.chain; - if (trustAnchor) { - // we should only add the issuer to the chain if it is not already - // present. On CA cert checking, the issuer is the same cert, so in - // that case we do not add the cert to the chain. - if (!CERT_CompareCerts(trustAnchor, cert)) { - PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("VerifyCert: adding issuer to tail for display\n")); - // note: rv is reused to catch errors on cert creation! - ScopedCERTCertificate tempCert(CERT_DupCertificate(trustAnchor)); - rv = CERT_AddCertToListTail(*validationChain, tempCert); - if (rv == SECSuccess) { - tempCert.forget(); // ownership traferred to validationChain - } else { - CERT_DestroyCertList(*validationChain); - *validationChain = nullptr; - } - } - } - } else { - // Validation was a fail, clean up if needed - if (cvout[validationChainLocation].value.pointer.chain) { - CERT_DestroyCertList(cvout[validationChainLocation].value.pointer.chain); - } - } - } - - return rv; -#endif -} - -} } // namespace mozilla::psm
deleted file mode 100644 --- a/security/manager/ssl/src/CertVerifier.h +++ /dev/null @@ -1,64 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla_psm__CertVerifier_h -#define mozilla_psm__CertVerifier_h - -#include "certt.h" -#include "insanity/ScopedPtr.h" - -namespace mozilla { namespace psm { - -class CertVerifier -{ -public: - typedef unsigned int Flags; - // XXX: FLAG_LOCAL_ONLY is ignored in the classic verification case - static const Flags FLAG_LOCAL_ONLY; - // Don't perform fallback DV validation on EV validation failure. - static const Flags FLAG_NO_DV_FALLBACK_FOR_EV; - - // *evOidPolicy == SEC_OID_UNKNOWN means the cert is NOT EV - // Only one usage per verification is supported. - SECStatus VerifyCert(CERTCertificate* cert, - const SECCertificateUsage usage, - const PRTime time, - void* pinArg, - const Flags flags = 0, - /*optional out*/ CERTCertList** validationChain = nullptr, - /*optional out*/ SECOidTag* evOidPolicy = nullptr , - /*optional out*/ CERTVerifyLog* verifyLog = nullptr); - - enum implementation_config { - classic = 0, -#ifndef NSS_NO_LIBPKIX - libpkix = 1, -#endif - }; - - enum missing_cert_download_config { missing_cert_download_off = 0, missing_cert_download_on }; - enum crl_download_config { crl_local_only = 0, crl_download_allowed }; - enum ocsp_download_config { ocsp_off = 0, ocsp_on }; - enum ocsp_strict_config { ocsp_relaxed = 0, ocsp_strict }; - enum ocsp_get_config { ocsp_get_disabled = 0, ocsp_get_enabled = 1 }; - - bool IsOCSPDownloadEnabled() const { return mOCSPDownloadEnabled; } - - CertVerifier(implementation_config ic, missing_cert_download_config ac, - crl_download_config cdc, ocsp_download_config odc, - ocsp_strict_config osc, ocsp_get_config ogc); - ~CertVerifier(); - -public: - const implementation_config mImplementation; - const bool mMissingCertDownloadEnabled; - const bool mCRLDownloadEnabled; - const bool mOCSPDownloadEnabled; - const bool mOCSPStrict; - const bool mOCSPGETEnabled; -}; - -} } // namespace mozilla::psm - -#endif // mozilla_psm__CertVerifier_h
--- a/security/manager/ssl/src/SSLServerCertVerification.cpp +++ b/security/manager/ssl/src/SSLServerCertVerification.cpp @@ -92,16 +92,18 @@ // we need the event to interrupt the PR_Poll that may waiting for I/O on the // socket for which we are validating the cert. #include "SSLServerCertVerification.h" #include <cstring> #include "CertVerifier.h" +#include "CryptoTask.h" +#include "ExtendedValidation.h" #include "nsIBadCertListener2.h" #include "nsICertOverrideService.h" #include "nsISiteSecurityService.h" #include "nsNSSComponent.h" #include "nsNSSCleaner.h" #include "nsRecentBadCerts.h" #include "nsNSSIOLayer.h" #include "nsNSSShutDown.h" @@ -1338,43 +1340,26 @@ AuthCertificateHook(void* arg, PRFileDes error = PR_UNKNOWN_ERROR; } PR_SetError(error, 0); return SECFailure; } #ifndef NSS_NO_LIBPKIX -class InitializeIdentityInfo : public nsRunnable - , public nsNSSShutDownObject +class InitializeIdentityInfo : public CryptoTask { -private: - NS_IMETHOD Run() + virtual nsresult CalculateResult() MOZ_OVERRIDE { - nsNSSShutDownPreventionLock nssShutdownPrevention; - if (isAlreadyShutDown()) - return NS_OK; - - nsresult rv; - nsCOMPtr<nsINSSComponent> inss = do_GetService(PSM_COMPONENT_CONTRACTID, &rv); - if (NS_SUCCEEDED(rv)) - inss->EnsureIdentityInfoLoaded(); + EnsureIdentityInfoLoaded(); return NS_OK; } - virtual void virtualDestroyNSSReference() - { - } - - ~InitializeIdentityInfo() - { - nsNSSShutDownPreventionLock nssShutdownPrevention; - if (!isAlreadyShutDown()) - shutdown(calledFromObject); - } + virtual void ReleaseNSSResources() MOZ_OVERRIDE { } // no-op + virtual void CallCallback(nsresult rv) MOZ_OVERRIDE { } // no-op }; #endif void EnsureServerVerificationInitialized() { #ifndef NSS_NO_LIBPKIX // Should only be called from socket transport thread due to the static // variable and the reference to gCertVerificationThreadPool
--- a/security/manager/ssl/src/moz.build +++ b/security/manager/ssl/src/moz.build @@ -11,28 +11,26 @@ EXPORTS += [ 'ScopedNSSTypes.h', ] EXPORTS.mozilla += [ 'PublicSSL.h', ] UNIFIED_SOURCES += [ - 'CertVerifier.cpp', 'CryptoTask.cpp', 'nsCertificatePrincipal.cpp', 'nsCertOverrideService.cpp', 'nsCertPicker.cpp', 'nsCertVerificationThread.cpp', 'nsClientAuthRemember.cpp', 'nsCMS.cpp', 'nsCMSSecureMessage.cpp', 'nsCrypto.cpp', 'nsDataSignatureVerifier.cpp', - 'nsIdentityChecking.cpp', 'nsKeygenHandler.cpp', 'nsKeygenThread.cpp', 'nsKeyModule.cpp', 'nsNSSASN1Object.cpp', 'nsNSSCallbacks.cpp', 'nsNSSCertCache.cpp', 'nsNSSCertHelper.cpp', 'nsNSSCertificate.cpp', @@ -89,15 +87,16 @@ if CONFIG['MOZ_XUL']: UNIFIED_SOURCES += [ 'md4.c', ] FINAL_LIBRARY = 'xul' LOCAL_INCLUDES += [ - '../../../insanity/include', + '../../../certverifier', + '../../../insanity/include', ] DEFINES['NSS_ENABLE_ECC'] = 'True' for var in ('DLL_PREFIX', 'DLL_SUFFIX'): DEFINES[var] = '"%s"' % CONFIG[var]
deleted file mode 100644 --- a/security/manager/ssl/src/nsIdentityChecking.cpp +++ /dev/null @@ -1,1423 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CertVerifier.h" -#include "nsNSSCertificate.h" -#include "nsNSSComponent.h" -#include "mozilla/RefPtr.h" -#include "nsAppDirectoryServiceDefs.h" -#include "nsStreamUtils.h" -#include "nsNetUtil.h" -#include "nsILineInputStream.h" -#include "nsPromiseFlatString.h" -#include "nsTArray.h" -#include "nsNSSCertTrust.h" - -#include "cert.h" -#include "base64.h" -#include "nsSSLStatus.h" -#include "ScopedNSSTypes.h" - -using namespace mozilla; - -#ifdef DEBUG -#ifndef PSM_ENABLE_TEST_EV_ROOTS -#define PSM_ENABLE_TEST_EV_ROOTS -#endif -#endif - -#ifdef PR_LOGGING -extern PRLogModuleInfo* gPIPNSSLog; -#endif - -#define CONST_OID static const unsigned char -#define OI(x) { siDEROID, (unsigned char*) x, sizeof x } - -struct nsMyTrustedEVInfo -{ - const char* dotted_oid; - const char* oid_name; // Set this to null to signal an invalid structure, - // (We can't have an empty list, so we'll use a dummy entry) - SECOidTag oid_tag; - const char* ev_root_sha1_fingerprint; - const char* issuer_base64; - const char* serial_base64; - CERTCertificate* cert; -}; - -// HOWTO enable additional CA root certificates for EV: -// -// For each combination of "root certificate" and "policy OID", -// one entry must be added to the array named myTrustedEVInfos. -// -// We use the combination of "issuer name" and "serial number" to -// uniquely identify the certificate. In order to avoid problems -// because of encodings when comparing certificates, we don't -// use plain text representation, we rather use the original encoding -// as it can be found in the root certificate (in base64 format). -// -// We can use the NSS utility named "pp" to extract the encoding. -// -// Build standalone NSS including the NSS tools, then run -// pp -t certificate-identity -i the-cert-filename -// -// You will need the output from sections "Issuer", "Fingerprint (SHA1)", -// "Issuer DER Base64" and "Serial DER Base64". -// -// The new section consists of 8 lines: -// -// - a comment that should contain the human readable issuer name -// of the certificate, as printed by the pp tool -// - the EV policy OID that is associated to the EV grant -// - a text description of the EV policy OID. The array can contain -// multiple entries with the same OID. -// Please make sure to use the identical OID text description for -// all entries with the same policy OID (use the text search -// feature of your text editor to find duplicates). -// When adding a new policy OID that is not yet contained in the array, -// please make sure that your new description is different from -// all the other descriptions (again use the text search feature -// to be sure). -// - the constant SEC_OID_UNKNOWN -// (it will be replaced at runtime with another identifier) -// - the UPPERCASE version of the SHA1 fingerprint, hexadecimal, -// bytes separated by colons (as printed by pp) -// - the "Issuer DER Base64" as printed by the pp tool. -// Remove all whitespaces. If you use multiple lines, make sure that -// only the final line will be followed by a comma. -// - the "Serial DER Base64" (as printed by pp) -// - a nullptr value -// -// After adding an entry, test it locally against the test site that -// has been provided by the CA. Note that you must use a version of NSS -// where the root certificate has already been added and marked as trusted -// for issueing SSL server certificates (at least). -// -// If you are able to connect to the site without certificate errors, -// but you don't see the EV status indicator, then most likely the CA -// has a problem in their infrastructure. The most common problems are -// related to the CA's OCSP infrastructure, either they use an incorrect -// OCSP signing certificate, or OCSP for the intermediate certificates -// isn't working, or OCSP isn't working at all. - -static struct nsMyTrustedEVInfo myTrustedEVInfos[] = { - // IMPORTANT! When extending this list, - // pairs of dotted_oid and oid_name should always be unique pairs. - // In other words, if you add another list, that uses the same dotted_oid - // as an existing entry, then please use the same oid_name. -#ifdef DEBUG - // Debug EV certificates should all use the OID (repeating EV OID is OK): - // 1.3.6.1.4.1.13769.666.666.666.1.500.9.1. - // If you add or remove debug EV certs you must also modify IdentityInfoInit - // (there is another #ifdef DEBUG section there) so that the correct number of - // certs are skipped as these debug EV certs are NOT part of the default trust - // store. - { - // This is the testing EV signature (xpcshell) (RSA) - // CN=XPCShell EV Testing (untrustworthy) CA,OU=Security Engineering,O=Mozilla - EV debug test CA,L=Mountain View,ST=CA,C=US" - "1.3.6.1.4.1.13769.666.666.666.1.500.9.1", - "DEBUGtesting EV OID", - SEC_OID_UNKNOWN, - "9C:62:EF:DB:AE:F9:EB:36:58:FB:3B:D3:47:64:93:9D:86:29:6A:E0", - "MIGnMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExFjAUBgNVBAcMDU1vdW50YWlu" - "IFZpZXcxIzAhBgNVBAoMGk1vemlsbGEgLSBFViBkZWJ1ZyB0ZXN0IENBMR0wGwYD" - "VQQLDBRTZWN1cml0eSBFbmdpbmVlcmluZzEvMC0GA1UEAwwmWFBDU2hlbGwgRVYg" - "VGVzdGluZyAodW50cnVzdHdvcnRoeSkgQ0E=", - "At+3zdo=", - nullptr - }, -#endif - { - // OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP - "1.2.392.200091.100.721.1", - "SECOM EV OID", - SEC_OID_UNKNOWN, - "FE:B8:C4:32:DC:F9:76:9A:CE:AE:3D:D8:90:8F:FD:28:86:65:64:7D", - "MGAxCzAJBgNVBAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENP" - "LixMVEQuMSowKAYDVQQLEyFTZWN1cml0eSBDb21tdW5pY2F0aW9uIEVWIFJvb3RD" - "QTE=", - "AA==", - nullptr - }, - { - // CN=Cybertrust Global Root,O=Cybertrust, Inc - "1.3.6.1.4.1.6334.1.100.1", - "Cybertrust EV OID", - SEC_OID_UNKNOWN, - "5F:43:E5:B1:BF:F8:78:8C:AC:1C:C7:CA:4A:9A:C6:22:2B:CC:34:C6", - "MDsxGDAWBgNVBAoTD0N5YmVydHJ1c3QsIEluYzEfMB0GA1UEAxMWQ3liZXJ0cnVz" - "dCBHbG9iYWwgUm9vdA==", - "BAAAAAABD4WqLUg=", - nullptr - }, - { - // CN=SwissSign Gold CA - G2,O=SwissSign AG,C=CH - "2.16.756.1.89.1.2.1.1", - "SwissSign EV OID", - SEC_OID_UNKNOWN, - "D8:C5:38:8A:B7:30:1B:1B:6E:D4:7A:E6:45:25:3A:6F:9F:1A:27:61", - "MEUxCzAJBgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMT" - "FlN3aXNzU2lnbiBHb2xkIENBIC0gRzI=", - "ALtAHEP1Xk+w", - nullptr - }, - { - // CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL - "1.3.6.1.4.1.23223.1.1.1", - "StartCom EV OID", - SEC_OID_UNKNOWN, - "3E:2B:F7:F2:03:1B:96:F3:8C:E6:C4:D8:A8:5D:3E:2D:58:47:6A:0F", - "MH0xCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQL" - "EyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBT" - "dGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", - "AQ==", - nullptr - }, - { - // CN=StartCom Certification Authority,OU=Secure Digital Certificate Signing,O=StartCom Ltd.,C=IL - "1.3.6.1.4.1.23223.1.1.1", - "StartCom EV OID", - SEC_OID_UNKNOWN, - "A3:F1:33:3F:E2:42:BF:CF:C5:D1:4E:8F:39:42:98:40:68:10:D1:A0", - "MH0xCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQL" - "EyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMSkwJwYDVQQDEyBT" - "dGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", - "LQ==", - nullptr - }, - { - // CN=StartCom Certification Authority G2,O=StartCom Ltd.,C=IL - "1.3.6.1.4.1.23223.1.1.1", - "StartCom EV OID", - SEC_OID_UNKNOWN, - "31:F1:FD:68:22:63:20:EE:C6:3B:3F:9D:EA:4A:3E:53:7C:7C:39:17", - "MFMxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSwwKgYDVQQD" - "EyNTdGFydENvbSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBHMg==", - "Ow==", - nullptr - }, - { - // CN=VeriSign Class 3 Public Primary Certification Authority - G5,OU="(c) 2006 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US - "2.16.840.1.113733.1.7.23.6", - "VeriSign EV OID", - SEC_OID_UNKNOWN, - "4E:B6:D5:78:49:9B:1C:CF:5F:58:1E:AD:56:BE:3D:9B:67:44:A5:E5", - "MIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV" - "BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA2IFZl" - "cmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMT" - "PFZlcmlTaWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB" - "dXRob3JpdHkgLSBHNQ==", - "GNrRniZ96LtKIVjNzGs7Sg==", - nullptr - }, - { - // CN=GeoTrust Primary Certification Authority,O=GeoTrust Inc.,C=US - "1.3.6.1.4.1.14370.1.6", - "GeoTrust EV OID", - SEC_OID_UNKNOWN, - "32:3C:11:8E:1B:F7:B8:B6:52:54:E2:E2:10:0D:D6:02:90:37:F0:96", - "MFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTEwLwYDVQQD" - "EyhHZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5", - "GKy1av1pthU6Y2yv2vrEoQ==", - nullptr - }, - { - // CN=thawte Primary Root CA,OU="(c) 2006 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US - "2.16.840.1.113733.1.7.48.1", - "Thawte EV OID", - SEC_OID_UNKNOWN, - "91:C6:D6:EE:3E:8A:C8:63:84:E5:48:C2:99:29:5C:75:6C:81:7B:81", - "MIGpMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMSgwJgYDVQQL" - "Ex9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYDVQQLEy8oYykg" - "MjAwNiB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEfMB0G" - "A1UEAxMWdGhhd3RlIFByaW1hcnkgUm9vdCBDQQ==", - "NE7VVyDV7exJ9C/ON9srbQ==", - nullptr - }, - { - // CN=XRamp Global Certification Authority,O=XRamp Security Services Inc,OU=www.xrampsecurity.com,C=US - "2.16.840.1.114404.1.1.2.4.1", - "Trustwave EV OID", - SEC_OID_UNKNOWN, - "B8:01:86:D1:EB:9C:86:A5:41:04:CF:30:54:F3:4C:52:B7:E5:58:C6", - "MIGCMQswCQYDVQQGEwJVUzEeMBwGA1UECxMVd3d3LnhyYW1wc2VjdXJpdHkuY29t" - "MSQwIgYDVQQKExtYUmFtcCBTZWN1cml0eSBTZXJ2aWNlcyBJbmMxLTArBgNVBAMT" - "JFhSYW1wIEdsb2JhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", - "UJRs7Bjq1ZxN1ZfvdY+grQ==", - nullptr - }, - { - // CN=SecureTrust CA,O=SecureTrust Corporation,C=US - "2.16.840.1.114404.1.1.2.4.1", - "Trustwave EV OID", - SEC_OID_UNKNOWN, - "87:82:C6:C3:04:35:3B:CF:D2:96:92:D2:59:3E:7D:44:D9:34:FF:11", - "MEgxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlv" - "bjEXMBUGA1UEAxMOU2VjdXJlVHJ1c3QgQ0E=", - "DPCOXAgWpa1Cf/DrJxhZ0A==", - nullptr - }, - { - // CN=Secure Global CA,O=SecureTrust Corporation,C=US - "2.16.840.1.114404.1.1.2.4.1", - "Trustwave EV OID", - SEC_OID_UNKNOWN, - "3A:44:73:5A:E5:81:90:1F:24:86:61:46:1E:3B:9C:C4:5F:F5:3A:1B", - "MEoxCzAJBgNVBAYTAlVTMSAwHgYDVQQKExdTZWN1cmVUcnVzdCBDb3Jwb3JhdGlv" - "bjEZMBcGA1UEAxMQU2VjdXJlIEdsb2JhbCBDQQ==", - "B1YipOjUiolN9BPI8PjqpQ==", - nullptr - }, - { - // CN=COMODO ECC Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - "1.3.6.1.4.1.6449.1.2.1.5.1", - "Comodo EV OID", - SEC_OID_UNKNOWN, - "9F:74:4E:9F:2B:4D:BA:EC:0F:31:2C:50:B6:56:3B:8E:2D:93:C3:11", - "MIGFMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAw" - "DgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDErMCkG" - "A1UEAxMiQ09NT0RPIEVDQyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQ==", - "H0evqmIAcFBUTAGem2OZKg==", - nullptr - }, - { - // CN=COMODO Certification Authority,O=COMODO CA Limited,L=Salford,ST=Greater Manchester,C=GB - "1.3.6.1.4.1.6449.1.2.1.5.1", - "Comodo EV OID", - SEC_OID_UNKNOWN, - "66:31:BF:9E:F7:4F:9E:B6:C9:D5:A6:0C:BA:6A:BE:D1:F7:BD:EF:7B", - "MIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAw" - "DgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEnMCUG" - "A1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5", - "ToEtioJl4AsC7j41AkblPQ==", - nullptr - }, - { - // CN=AddTrust External CA Root,OU=AddTrust External TTP Network,O=AddTrust AB,C=SE - "1.3.6.1.4.1.6449.1.2.1.5.1", - "Comodo EV OID", - SEC_OID_UNKNOWN, - "02:FA:F3:E2:91:43:54:68:60:78:57:69:4D:F5:E4:5B:68:85:18:68", - "MG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMd" - "QWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0" - "IEV4dGVybmFsIENBIFJvb3Q=", - "AQ==", - nullptr - }, - { - // CN=UTN - DATACorp SGC,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US - "1.3.6.1.4.1.6449.1.2.1.5.1", - "Comodo EV OID", - SEC_OID_UNKNOWN, - "58:11:9F:0E:12:82:87:EA:50:FD:D9:87:45:6F:4F:78:DC:FA:D6:D4", - "MIGTMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFr" - "ZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsT" - "GGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNv" - "cnAgU0dD", - "RL4Mi1AAIbQR0ypoBqmtaQ==", - nullptr - }, - { - // CN=UTN-USERFirst-Hardware,OU=http://www.usertrust.com,O=The USERTRUST Network,L=Salt Lake City,ST=UT,C=US - "1.3.6.1.4.1.6449.1.2.1.5.1", - "Comodo EV OID", - SEC_OID_UNKNOWN, - "04:83:ED:33:99:AC:36:08:05:87:22:ED:BC:5E:46:00:E3:BE:F9:D7", - "MIGXMQswCQYDVQQGEwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFr" - "ZSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsT" - "GGh0dHA6Ly93d3cudXNlcnRydXN0LmNvbTEfMB0GA1UEAxMWVVROLVVTRVJGaXJz" - "dC1IYXJkd2FyZQ==", - "RL4Mi1AAJLQR0zYq/mUK/Q==", - nullptr - }, - { - // OU=Go Daddy Class 2 Certification Authority,O=\"The Go Daddy Group, Inc.\",C=US - "2.16.840.1.114413.1.7.23.3", - "Go Daddy EV OID a", - SEC_OID_UNKNOWN, - "27:96:BA:E6:3F:18:01:E2:77:26:1B:A0:D7:77:70:02:8F:20:EE:E4", - "MGMxCzAJBgNVBAYTAlVTMSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIElu" - "Yy4xMTAvBgNVBAsTKEdvIERhZGR5IENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRo" - "b3JpdHk=", - "AA==", - nullptr - }, - { - // CN=Go Daddy Root Certificate Authority - G2,O="GoDaddy.com, Inc.",L=Scottsdale,ST=Arizona,C=US - "2.16.840.1.114413.1.7.23.3", - "Go Daddy EV OID a", - SEC_OID_UNKNOWN, - "47:BE:AB:C9:22:EA:E8:0E:78:78:34:62:A7:9F:45:C2:54:FD:E6:8B", - "MIGDMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2Nv" - "dHRzZGFsZTEaMBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xMTAvBgNVBAMTKEdv" - "IERhZGR5IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzI=", - "AA==", - nullptr - }, - { - // E=info@valicert.com,CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=\"ValiCert, Inc.\",L=ValiCert Validation Network - "2.16.840.1.114413.1.7.23.3", - "Go Daddy EV OID a", - SEC_OID_UNKNOWN, - "31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6", - "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNV" - "BAoTDlZhbGlDZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBv" - "bGljeSBWYWxpZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52" - "YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbQ==", - "AQ==", - nullptr - }, - { - // E=info@valicert.com,CN=http://www.valicert.com/,OU=ValiCert Class 2 Policy Validation Authority,O=\"ValiCert, Inc.\",L=ValiCert Validation Network - "2.16.840.1.114414.1.7.23.3", - "Go Daddy EV OID b", - SEC_OID_UNKNOWN, - "31:7A:2A:D0:7F:2B:33:5E:F5:A1:C3:4E:4B:57:E8:B7:D8:F1:FC:A6", - "MIG7MSQwIgYDVQQHExtWYWxpQ2VydCBWYWxpZGF0aW9uIE5ldHdvcmsxFzAVBgNV" - "BAoTDlZhbGlDZXJ0LCBJbmMuMTUwMwYDVQQLEyxWYWxpQ2VydCBDbGFzcyAyIFBv" - "bGljeSBWYWxpZGF0aW9uIEF1dGhvcml0eTEhMB8GA1UEAxMYaHR0cDovL3d3dy52" - "YWxpY2VydC5jb20vMSAwHgYJKoZIhvcNAQkBFhFpbmZvQHZhbGljZXJ0LmNvbQ==", - "AQ==", - nullptr - }, - { - // OU=Starfield Class 2 Certification Authority,O=\"Starfield Technologies, Inc.\",C=US - "2.16.840.1.114414.1.7.23.3", - "Go Daddy EV OID b", - SEC_OID_UNKNOWN, - "AD:7E:1C:28:B0:64:EF:8F:60:03:40:20:14:C3:D0:E3:37:0E:B5:8A", - "MGgxCzAJBgNVBAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVz" - "LCBJbmMuMTIwMAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9u" - "IEF1dGhvcml0eQ==", - "AA==", - nullptr - }, - { - // CN=Starfield Root Certificate Authority - G2,O="Starfield Technologies, Inc.",L=Scottsdale,ST=Arizona,C=US - "2.16.840.1.114414.1.7.23.3", - "Go Daddy EV OID b", - SEC_OID_UNKNOWN, - "B5:1C:06:7C:EE:2B:0C:3D:F8:55:AB:2D:92:F4:FE:39:D4:E7:0F:0E", - "MIGPMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2Nv" - "dHRzZGFsZTElMCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEy" - "MDAGA1UEAxMpU3RhcmZpZWxkIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0g" - "RzI=", - "AA==", - nullptr - }, - { - // CN=DigiCert High Assurance EV Root CA,OU=www.digicert.com,O=DigiCert Inc,C=US - "2.16.840.1.114412.2.1", - "DigiCert EV OID", - SEC_OID_UNKNOWN, - "5F:B7:EE:06:33:E2:59:DB:AD:0C:4C:9A:E6:D3:8F:1A:61:C7:DC:25", - "MGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT" - "EHd3dy5kaWdpY2VydC5jb20xKzApBgNVBAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJh" - "bmNlIEVWIFJvb3QgQ0E=", - "AqxcJmoLQJuPC3nyrkYldw==", - nullptr - }, - { - // CN=QuoVadis Root CA 2,O=QuoVadis Limited,C=BM - "1.3.6.1.4.1.8024.0.2.100.1.2", - "Quo Vadis EV OID", - SEC_OID_UNKNOWN, - "CA:3A:FB:CF:12:40:36:4B:44:B2:16:20:88:80:48:39:19:93:7C:F7", - "MEUxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYD" - "VQQDExJRdW9WYWRpcyBSb290IENBIDI=", - "BQk=", - nullptr - }, - { - // CN=Network Solutions Certificate Authority,O=Network Solutions L.L.C.,C=US - "1.3.6.1.4.1.782.1.2.1.8.1", - "Network Solutions EV OID", - SEC_OID_UNKNOWN, - "74:F8:A3:C3:EF:E7:B3:90:06:4B:83:90:3C:21:64:60:20:E5:DF:CE", - "MGIxCzAJBgNVBAYTAlVTMSEwHwYDVQQKExhOZXR3b3JrIFNvbHV0aW9ucyBMLkwu" - "Qy4xMDAuBgNVBAMTJ05ldHdvcmsgU29sdXRpb25zIENlcnRpZmljYXRlIEF1dGhv" - "cml0eQ==", - "V8szb8JcFuZHFhfjkDFo4A==", - nullptr - }, - { - // CN=Entrust Root Certification Authority,OU="(c) 2006 Entrust, Inc.",OU=www.entrust.net/CPS is incorporated by reference,O="Entrust, Inc.",C=US - "2.16.840.1.114028.10.1.2", - "Entrust EV OID", - SEC_OID_UNKNOWN, - "B3:1E:B1:B7:40:E3:6C:84:02:DA:DC:37:D4:4D:F5:D4:67:49:52:F9", - "MIGwMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNRW50cnVzdCwgSW5jLjE5MDcGA1UE" - "CxMwd3d3LmVudHJ1c3QubmV0L0NQUyBpcyBpbmNvcnBvcmF0ZWQgYnkgcmVmZXJl" - "bmNlMR8wHQYDVQQLExYoYykgMjAwNiBFbnRydXN0LCBJbmMuMS0wKwYDVQQDEyRF" - "bnRydXN0IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHk=", - "RWtQVA==", - nullptr - }, - { - // CN=GlobalSign Root CA,OU=Root CA,O=GlobalSign nv-sa,C=BE - "1.3.6.1.4.1.4146.1.1", - "GlobalSign EV OID", - SEC_OID_UNKNOWN, - "B1:BC:96:8B:D4:F4:9D:62:2A:A8:9A:81:F2:15:01:52:A4:1D:82:9C", - "MFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYD" - "VQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxTaWduIFJvb3QgQ0E=", - "BAAAAAABFUtaw5Q=", - nullptr - }, - { - // CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R2 - "1.3.6.1.4.1.4146.1.1", - "GlobalSign EV OID", - SEC_OID_UNKNOWN, - "75:E0:AB:B6:13:85:12:27:1C:04:F8:5F:DD:DE:38:E4:B7:24:2E:FE", - "MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIyMRMwEQYDVQQKEwpH" - "bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu", - "BAAAAAABD4Ym5g0=", - nullptr - }, - { - // CN=GlobalSign,O=GlobalSign,OU=GlobalSign Root CA - R3 - "1.3.6.1.4.1.4146.1.1", - "GlobalSign EV OID", - SEC_OID_UNKNOWN, - "D6:9B:56:11:48:F0:1C:77:C5:45:78:C1:09:26:DF:5B:85:69:76:AD", - "MEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFIzMRMwEQYDVQQKEwpH" - "bG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWdu", - "BAAAAAABIVhTCKI=", - nullptr - }, - { - // CN=Buypass Class 3 CA 1,O=Buypass AS-983163327,C=NO - "2.16.578.1.26.1.3.3", - "Buypass EV OID", - SEC_OID_UNKNOWN, - "61:57:3A:11:DF:0E:D8:7E:D5:92:65:22:EA:D0:56:D7:44:B3:23:71", - "MEsxCzAJBgNVBAYTAk5PMR0wGwYDVQQKDBRCdXlwYXNzIEFTLTk4MzE2MzMyNzEd" - "MBsGA1UEAwwUQnV5cGFzcyBDbGFzcyAzIENBIDE=", - "Ag==", - nullptr - }, - { - // CN=Buypass Class 3 Root CA,O=Buypass AS-983163327,C=NO - "2.16.578.1.26.1.3.3", - "Buypass EV OID", - SEC_OID_UNKNOWN, - "DA:FA:F7:FA:66:84:EC:06:8F:14:50:BD:C7:C2:81:A5:BC:A9:64:57", - "ME4xCzAJBgNVBAYTAk5PMR0wGwYDVQQKDBRCdXlwYXNzIEFTLTk4MzE2MzMyNzEg" - "MB4GA1UEAwwXQnV5cGFzcyBDbGFzcyAzIFJvb3QgQ0E=", - "Ag==", - nullptr - }, - { - // CN=Class 2 Primary CA,O=Certplus,C=FR - "1.3.6.1.4.1.22234.2.5.2.3.1", - "Certplus EV OID", - SEC_OID_UNKNOWN, - "74:20:74:41:72:9C:DD:92:EC:79:31:D8:23:10:8D:C2:81:92:E2:BB", - "MD0xCzAJBgNVBAYTAkZSMREwDwYDVQQKEwhDZXJ0cGx1czEbMBkGA1UEAxMSQ2xh" - "c3MgMiBQcmltYXJ5IENB", - "AIW9S/PY2uNp9pTXX8OlRCM=", - nullptr - }, - { - // CN=Chambers of Commerce Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU - "1.3.6.1.4.1.17326.10.14.2.1.2", - "Camerfirma EV OID a", - SEC_OID_UNKNOWN, - "78:6A:74:AC:76:AB:14:7F:9C:6A:30:50:BA:9E:A8:7E:FE:9A:CE:3C", - "MIGuMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh" - "ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ" - "QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMT" - "IENoYW1iZXJzIG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4", - "AKPaQn6ksa7a", - nullptr - }, - { - // CN=Global Chambersign Root - 2008,O=AC Camerfirma S.A.,serialNumber=A82743287,L=Madrid (see current address at www.camerfirma.com/address),C=EU - "1.3.6.1.4.1.17326.10.8.12.1.2", - "Camerfirma EV OID b", - SEC_OID_UNKNOWN, - "4A:BD:EE:EC:95:0D:35:9C:89:AE:C7:52:A1:2C:5B:29:F6:D6:AA:0C", - "MIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBh" - "ZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJ" - "QTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMT" - "Hkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwOA==", - "AMnN0+nVfSPO", - nullptr - }, - { - // CN=TC TrustCenter Universal CA III,OU=TC TrustCenter Universal CA,O=TC TrustCenter GmbH,C=DE - "1.2.276.0.44.1.1.1.4", - "TC TrustCenter EV OID", - SEC_OID_UNKNOWN, - "96:56:CD:7B:57:96:98:95:D0:E1:41:46:68:06:FB:B8:C6:11:06:87", - "MHsxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNUQyBUcnVzdENlbnRlciBHbWJIMSQw" - "IgYDVQQLExtUQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0ExKDAmBgNVBAMTH1RD" - "IFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQSBJSUk=", - "YyUAAQACFI0zFQLkbPQ=", - nullptr - }, - { - // CN=AffirmTrust Commercial,O=AffirmTrust,C=US - "1.3.6.1.4.1.34697.2.1", - "AffirmTrust EV OID a", - SEC_OID_UNKNOWN, - "F9:B5:B6:32:45:5F:9C:BE:EC:57:5F:80:DC:E9:6E:2C:C7:B2:78:B7", - "MEQxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEfMB0GA1UEAwwW" - "QWZmaXJtVHJ1c3QgQ29tbWVyY2lhbA==", - "d3cGJyapsXw=", - nullptr - }, - { - // CN=AffirmTrust Networking,O=AffirmTrust,C=US - "1.3.6.1.4.1.34697.2.2", - "AffirmTrust EV OID b", - SEC_OID_UNKNOWN, - "29:36:21:02:8B:20:ED:02:F5:66:C5:32:D1:D6:ED:90:9F:45:00:2F", - "MEQxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEfMB0GA1UEAwwW" - "QWZmaXJtVHJ1c3QgTmV0d29ya2luZw==", - "fE8EORzUmS0=", - nullptr - }, - { - // CN=AffirmTrust Premium,O=AffirmTrust,C=US - "1.3.6.1.4.1.34697.2.3", - "AffirmTrust EV OID c", - SEC_OID_UNKNOWN, - "D8:A6:33:2C:E0:03:6F:B1:85:F6:63:4F:7D:6A:06:65:26:32:28:27", - "MEExCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEcMBoGA1UEAwwT" - "QWZmaXJtVHJ1c3QgUHJlbWl1bQ==", - "bYwURrGmCu4=", - nullptr - }, - { - // CN=AffirmTrust Premium ECC,O=AffirmTrust,C=US - "1.3.6.1.4.1.34697.2.4", - "AffirmTrust EV OID d", - SEC_OID_UNKNOWN, - "B8:23:6B:00:2F:1D:16:86:53:01:55:6C:11:A4:37:CA:EB:FF:C3:BB", - "MEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwX" - "QWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0M=", - "dJclisc/elQ=", - nullptr - }, - { - // CN=Certum Trusted Network CA,OU=Certum Certification Authority,O=Unizeto Technologies S.A.,C=PL - "1.2.616.1.113527.2.5.1.1", - "Certum EV OID", - SEC_OID_UNKNOWN, - "07:E0:32:E0:20:B7:2C:3F:19:2F:06:28:A2:59:3A:19:A7:0F:06:9E", - "MH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBT" - "LkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAg" - "BgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0E=", - "BETA", - nullptr - }, - { - // CN=Izenpe.com,O=IZENPE S.A.,C=ES - "1.3.6.1.4.1.14777.6.1.1", - "Izenpe EV OID 1", - SEC_OID_UNKNOWN, - "2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19", - "MDgxCzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwK" - "SXplbnBlLmNvbQ==", - "ALC3WhZIX7/hy/WL1xnmfQ==", - nullptr - }, - { - // CN=Izenpe.com,O=IZENPE S.A.,C=ES - "1.3.6.1.4.1.14777.6.1.2", - "Izenpe EV OID 2", - SEC_OID_UNKNOWN, - "2F:78:3D:25:52:18:A7:4A:65:39:71:B5:2C:A2:9C:45:15:6F:E9:19", - "MDgxCzAJBgNVBAYTAkVTMRQwEgYDVQQKDAtJWkVOUEUgUy5BLjETMBEGA1UEAwwK" - "SXplbnBlLmNvbQ==", - "ALC3WhZIX7/hy/WL1xnmfQ==", - nullptr - }, - { - // CN=A-Trust-nQual-03,OU=A-Trust-nQual-03,O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH,C=AT - "1.2.40.0.17.1.22", - "A-Trust EV OID", - SEC_OID_UNKNOWN, - "D3:C0:63:F2:19:ED:07:3E:34:AD:5D:75:0B:32:76:29:FF:D5:9A:F2", - "MIGNMQswCQYDVQQGEwJBVDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hl" - "cmhlaXRzc3lzdGVtZSBpbSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYD" - "VQQLDBBBLVRydXN0LW5RdWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAz", - "AWwe", - nullptr - }, - { - // CN=T-TeleSec GlobalRoot Class 3,OU=T-Systems Trust Center,O=T-Systems Enterprise Services GmbH,C=DE - "1.3.6.1.4.1.7879.13.24.1", - "T-Systems EV OID", - SEC_OID_UNKNOWN, - "55:A6:72:3E:CB:F2:EC:CD:C3:23:74:70:19:9D:2A:BE:11:E3:81:D1", - "MIGCMQswCQYDVQQGEwJERTErMCkGA1UECgwiVC1TeXN0ZW1zIEVudGVycHJpc2Ug" - "U2VydmljZXMgR21iSDEfMB0GA1UECwwWVC1TeXN0ZW1zIFRydXN0IENlbnRlcjEl" - "MCMGA1UEAwwcVC1UZWxlU2VjIEdsb2JhbFJvb3QgQ2xhc3MgMw==", - "AQ==", - nullptr - }, - { - // CN=TURKTRUST Elektronik Sertifika Hizmet Saglayicisi,O=TURKTRUST Bilgi Illetisim ve Bilisim Guvenligi Hizmetleri A.S.,C=TR - "2.16.792.3.0.3.1.1.5", - "TurkTrust EV OID", - SEC_OID_UNKNOWN, - "F1:7F:6F:B6:31:DC:99:E3:A3:C8:7F:FE:1C:F1:81:10:88:D9:60:33", - "MIG/MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2VydGlmaWthIEhp" - "em1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYTAlRSMQ8wDQYDVQQHDAZBbmth" - "cmExXjBcBgNVBAoMVVTDnFJLVFJVU1QgQmlsZ2kgxLBsZXRpxZ9pbSB2ZSBCaWxp" - "xZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEuxZ4uIChjKSBBcmFsxLFrIDIw" - "MDc=", - "AQ==", - nullptr - }, - { - // CN=China Internet Network Information Center EV Certificates Root,O=China Internet Network Information Center,C=CN - "1.3.6.1.4.1.29836.1.10", - "CNNIC EV OID", - SEC_OID_UNKNOWN, - "4F:99:AA:93:FB:2B:D1:37:26:A1:99:4A:CE:7F:F0:05:F2:93:5D:1E", - "MIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEgSW50ZXJuZXQgTmV0d29y" - "ayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNoaW5hIEludGVybmV0IE5l" - "dHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRpZmljYXRlcyBSb290", - "SJ8AAQ==", - nullptr - }, - { - // CN=TWCA Root Certification Authority,OU=Root CA,O=TAIWAN-CA,C=TW - "1.3.6.1.4.1.40869.1.1.22.3", - "TWCA EV OID", - SEC_OID_UNKNOWN, - "CF:9E:87:6D:D3:EB:FC:42:26:97:A3:B5:A3:7A:A0:76:A9:06:23:48", - "MF8xCzAJBgNVBAYTAlRXMRIwEAYDVQQKDAlUQUlXQU4tQ0ExEDAOBgNVBAsMB1Jv" - "b3QgQ0ExKjAoBgNVBAMMIVRXQ0EgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0" - "eQ==", - "AQ==", - nullptr - }, - { - // CN=D-TRUST Root Class 3 CA 2 EV 2009,O=D-Trust GmbH,C=DE - "1.3.6.1.4.1.4788.2.202.1", - "D-TRUST EV OID", - SEC_OID_UNKNOWN, - "96:C9:1B:0B:95:B4:10:98:42:FA:D0:D8:22:79:FE:60:FA:B9:16:83", - "MFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMM" - "IUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOQ==", - "CYP0", - nullptr - }, - { - // CN=Swisscom Root EV CA 2,OU=Digital Certificate Services,O=Swisscom,C=ch - "2.16.756.1.83.21.0", - "Swisscom EV OID", - SEC_OID_UNKNOWN, - "E7:A1:90:29:D3:D5:52:DC:0D:0F:C6:92:D3:EA:88:0D:15:2E:1A:6B", - "MGcxCzAJBgNVBAYTAmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGln" - "aXRhbCBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczEeMBwGA1UEAxMVU3dpc3Njb20gUm9v" - "dCBFViBDQSAy", - "APL6ZOJ0Y9ON/RAdBB92ylg=", - nullptr - }, - { - // CN=VeriSign Universal Root Certification Authority,OU="(c) 2008 VeriSign, Inc. - For authorized use only",OU=VeriSign Trust Network,O="VeriSign, Inc.",C=US - "2.16.840.1.113733.1.7.23.6", - "VeriSign EV OID", - SEC_OID_UNKNOWN, - "36:79:CA:35:66:87:72:30:4D:30:A5:FB:87:3B:0F:A7:7B:B7:0D:54", - "MIG9MQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNV" - "BAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZl" - "cmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMT" - "L1ZlcmlTaWduIFVuaXZlcnNhbCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5", - "QBrEZCGzEyEDDrvkEhrFHQ==", - nullptr - }, - { - // CN=GeoTrust Primary Certification Authority - G3,OU=(c) 2008 GeoTrust Inc. - For authorized use only,O=GeoTrust Inc.,C=US - "1.3.6.1.4.1.14370.1.6", - "GeoTrust EV OID", - SEC_OID_UNKNOWN, - "03:9E:ED:B8:0B:E7:A0:3C:69:53:89:3B:20:D2:D9:32:3A:4C:2A:FD", - "MIGYMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjE5MDcGA1UE" - "CxMwKGMpIDIwMDggR2VvVHJ1c3QgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBv" - "bmx5MTYwNAYDVQQDEy1HZW9UcnVzdCBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0" - "aG9yaXR5IC0gRzM=", - "FaxulBmyeUtB9iepwxgPHw==", - nullptr - }, - { - // CN=thawte Primary Root CA - G3,OU="(c) 2008 thawte, Inc. - For authorized use only",OU=Certification Services Division,O="thawte, Inc.",C=US - "2.16.840.1.113733.1.7.48.1", - "Thawte EV OID", - SEC_OID_UNKNOWN, - "F1:8B:53:8D:1B:E9:03:B6:A6:F0:56:43:5B:17:15:89:CA:F3:6B:F2", - "MIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3RlLCBJbmMuMSgwJgYDVQQL" - "Ex9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9uMTgwNgYDVQQLEy8oYykg" - "MjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTEkMCIG" - "A1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz", - "YAGXt0an6rS0mtZLL/eQ+w==", - nullptr - }, - { - // OU=Sample Certification Authority,O=\"Sample, Inc.\",C=US - "0.0.0.0", - 0, // for real entries use a string like "Sample INVALID EV OID" - SEC_OID_UNKNOWN, - "00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33", //UPPERCASE! - "Cg==", - "Cg==", - nullptr - } -}; - -static SECOidTag -register_oid(const SECItem* oid_item, const char* oid_name) -{ - if (!oid_item) - return SEC_OID_UNKNOWN; - - SECOidData od; - od.oid.len = oid_item->len; - od.oid.data = oid_item->data; - od.offset = SEC_OID_UNKNOWN; - od.desc = oid_name; - od.mechanism = CKM_INVALID_MECHANISM; - od.supportedExtension = INVALID_CERT_EXTENSION; - return SECOID_AddEntry(&od); -} - -static void -addToCertListIfTrusted(CERTCertList* certList, CERTCertificate* cert) { - CERTCertTrust nssTrust; - if (CERT_GetCertTrust(cert, &nssTrust) != SECSuccess) { - return; - } - unsigned int flags = SEC_GET_TRUST_FLAGS(&nssTrust, trustSSL); - - if (flags & CERTDB_TRUSTED_CA) { - CERT_AddCertToListTail(certList, CERT_DupCertificate(cert)); - } -} - -#ifdef PSM_ENABLE_TEST_EV_ROOTS -class nsMyTrustedEVInfoClass : public nsMyTrustedEVInfo -{ -public: - nsMyTrustedEVInfoClass(); - ~nsMyTrustedEVInfoClass(); -}; - -nsMyTrustedEVInfoClass::nsMyTrustedEVInfoClass() -{ - dotted_oid = nullptr; - oid_name = nullptr; - oid_tag = SEC_OID_UNKNOWN; - ev_root_sha1_fingerprint = nullptr; - issuer_base64 = nullptr; - serial_base64 = nullptr; - cert = nullptr; -} - -nsMyTrustedEVInfoClass::~nsMyTrustedEVInfoClass() -{ - // Cast away const-ness in order to free these strings - free(const_cast<char*>(dotted_oid)); - free(const_cast<char*>(oid_name)); - free(const_cast<char*>(ev_root_sha1_fingerprint)); - free(const_cast<char*>(issuer_base64)); - free(const_cast<char*>(serial_base64)); - if (cert) - CERT_DestroyCertificate(cert); -} - -typedef nsTArray<nsMyTrustedEVInfoClass*> testEVArray; -static testEVArray* testEVInfos; -static bool testEVInfosLoaded = false; -#endif - -#ifdef PSM_ENABLE_TEST_EV_ROOTS -static const char kTestEVRootsFileName[] = "test_ev_roots.txt"; - -static void -loadTestEVInfos() -{ - if (!testEVInfos) - return; - - testEVInfos->Clear(); - - char* env_val = getenv("ENABLE_TEST_EV_ROOTS_FILE"); - if (!env_val) - return; - - int enabled_val = atoi(env_val); - if (!enabled_val) - return; - - nsCOMPtr<nsIFile> aFile; - NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(aFile)); - if (!aFile) - return; - - aFile->AppendNative(NS_LITERAL_CSTRING(kTestEVRootsFileName)); - - nsresult rv; - nsCOMPtr<nsIInputStream> fileInputStream; - rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), aFile); - if (NS_FAILED(rv)) - return; - - nsCOMPtr<nsILineInputStream> lineInputStream = - do_QueryInterface(fileInputStream, &rv); - if (NS_FAILED(rv)) - return; - - nsAutoCString buffer; - bool isMore = true; - - // file format - // - // file format must be strictly followed - // strings in file must be UTF-8 - // each record consists of multiple lines - // each line consists of a descriptor, a single space, and the data - // the descriptors are: - // 1_fingerprint (in format XX:XX:XX:...) - // 2_readable_oid (treated as a comment) - // the input file must strictly follow this order - // the input file may contain 0, 1 or many records - // completely empty lines are ignored - // lines that start with the # char are ignored - - int line_counter = 0; - bool found_error = false; - - enum { - pos_fingerprint, pos_readable_oid, pos_issuer, pos_serial - } reader_position = pos_fingerprint; - - nsCString fingerprint, readable_oid, issuer, serial; - - while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) { - ++line_counter; - if (buffer.IsEmpty() || buffer.First() == '#') { - continue; - } - - int32_t seperatorIndex = buffer.FindChar(' ', 0); - if (seperatorIndex == 0) { - found_error = true; - break; - } - - const nsASingleFragmentCString& descriptor = - Substring(buffer, 0, seperatorIndex); - const nsASingleFragmentCString& data = - Substring(buffer, seperatorIndex + 1, - buffer.Length() - seperatorIndex + 1); - - if (reader_position == pos_fingerprint && - descriptor.EqualsLiteral(("1_fingerprint"))) { - fingerprint = data; - reader_position = pos_readable_oid; - continue; - } - else if (reader_position == pos_readable_oid && - descriptor.EqualsLiteral(("2_readable_oid"))) { - readable_oid = data; - reader_position = pos_issuer; - continue; - } - else if (reader_position == pos_issuer && - descriptor.EqualsLiteral(("3_issuer"))) { - issuer = data; - reader_position = pos_serial; - continue; - } - else if (reader_position == pos_serial && - descriptor.EqualsLiteral(("4_serial"))) { - serial = data; - reader_position = pos_fingerprint; - } - else { - found_error = true; - break; - } - - nsMyTrustedEVInfoClass* temp_ev = new nsMyTrustedEVInfoClass; - if (!temp_ev) - return; - - temp_ev->ev_root_sha1_fingerprint = strdup(fingerprint.get()); - temp_ev->oid_name = strdup(readable_oid.get()); - temp_ev->dotted_oid = strdup(readable_oid.get()); - temp_ev->issuer_base64 = strdup(issuer.get()); - temp_ev->serial_base64 = strdup(serial.get()); - - SECStatus rv; - CERTIssuerAndSN ias; - - rv = ATOB_ConvertAsciiToItem(&ias.derIssuer, const_cast<char*>(temp_ev->issuer_base64)); - NS_ASSERTION(rv==SECSuccess, "error converting ascii to binary."); - rv = ATOB_ConvertAsciiToItem(&ias.serialNumber, const_cast<char*>(temp_ev->serial_base64)); - NS_ASSERTION(rv==SECSuccess, "error converting ascii to binary."); - - temp_ev->cert = CERT_FindCertByIssuerAndSN(nullptr, &ias); - NS_ASSERTION(temp_ev->cert, "Could not find EV root in NSS storage"); - - SECITEM_FreeItem(&ias.derIssuer, false); - SECITEM_FreeItem(&ias.serialNumber, false); - - if (!temp_ev->cert) - return; - - nsNSSCertificate c(temp_ev->cert); - nsAutoString fingerprint; - c.GetSha1Fingerprint(fingerprint); - - NS_ConvertASCIItoUTF16 sha1(temp_ev->ev_root_sha1_fingerprint); - - if (sha1 != fingerprint) { - NS_ASSERTION(sha1 == fingerprint, "found EV root with unexpected SHA1 mismatch"); - CERT_DestroyCertificate(temp_ev->cert); - temp_ev->cert = nullptr; - return; - } - - SECItem ev_oid_item; - ev_oid_item.data = nullptr; - ev_oid_item.len = 0; - SECStatus srv = SEC_StringToOID(nullptr, &ev_oid_item, - readable_oid.get(), readable_oid.Length()); - if (srv != SECSuccess) { - delete temp_ev; - found_error = true; - break; - } - - temp_ev->oid_tag = register_oid(&ev_oid_item, temp_ev->oid_name); - SECITEM_FreeItem(&ev_oid_item, false); - - testEVInfos->AppendElement(temp_ev); - } - - if (found_error) { - fprintf(stderr, "invalid line %d in test_ev_roots file\n", line_counter); - } -} - -static bool -isEVPolicyInExternalDebugRootsFile(SECOidTag policyOIDTag) -{ - if (!testEVInfos) - return false; - - char* env_val = getenv("ENABLE_TEST_EV_ROOTS_FILE"); - if (!env_val) - return false; - - int enabled_val = atoi(env_val); - if (!enabled_val) - return false; - - for (size_t i=0; i<testEVInfos->Length(); ++i) { - nsMyTrustedEVInfoClass* ev = testEVInfos->ElementAt(i); - if (!ev) - continue; - if (policyOIDTag == ev->oid_tag) - return true; - } - - return false; -} - -static bool -getRootsForOidFromExternalRootsFile(CERTCertList* certList, - SECOidTag policyOIDTag) -{ - if (!testEVInfos) - return false; - - char* env_val = getenv("ENABLE_TEST_EV_ROOTS_FILE"); - if (!env_val) - return false; - - int enabled_val = atoi(env_val); - if (!enabled_val) - return false; - - for (size_t i=0; i<testEVInfos->Length(); ++i) { - nsMyTrustedEVInfoClass* ev = testEVInfos->ElementAt(i); - if (!ev) - continue; - if (policyOIDTag == ev->oid_tag) { - addToCertListIfTrusted(certList, ev->cert); - } - } - - return false; -} -#endif - -static bool -isEVPolicy(SECOidTag policyOIDTag) -{ - for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) { - nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV]; - if (!entry.oid_name) // invalid or placeholder list entry - continue; - if (policyOIDTag == entry.oid_tag) { - return true; - } - } - -#ifdef PSM_ENABLE_TEST_EV_ROOTS - if (isEVPolicyInExternalDebugRootsFile(policyOIDTag)) { - return true; - } -#endif - - return false; -} - -namespace mozilla { namespace psm { - -CERTCertList* -getRootsForOid(SECOidTag oid_tag) -{ - CERTCertList* certList = CERT_NewCertList(); - if (!certList) - return nullptr; - - for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) { - nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV]; - if (!entry.oid_name) // invalid or placeholder list entry - continue; - if (entry.oid_tag == oid_tag) { - addToCertListIfTrusted(certList, entry.cert); - } - } - -#ifdef PSM_ENABLE_TEST_EV_ROOTS - getRootsForOidFromExternalRootsFile(certList, oid_tag); -#endif - return certList; -} - -} } // namespace mozilla::psm - -PRStatus -nsNSSComponent::IdentityInfoInit() -{ - for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) { - nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV]; - if (!entry.oid_name) // invalid or placeholder list entry - continue; - - SECStatus rv; - CERTIssuerAndSN ias; - - rv = ATOB_ConvertAsciiToItem(&ias.derIssuer, const_cast<char*>(entry.issuer_base64)); - NS_ASSERTION(rv==SECSuccess, "error converting ascii to binary."); - rv = ATOB_ConvertAsciiToItem(&ias.serialNumber, const_cast<char*>(entry.serial_base64)); - NS_ASSERTION(rv==SECSuccess, "error converting ascii to binary."); - ias.serialNumber.type = siUnsignedInteger; - - entry.cert = CERT_FindCertByIssuerAndSN(nullptr, &ias); - -#ifdef DEBUG - // The debug CA cert is at positions 0, and is NOT in the NSS root db. - if (iEV > 0) { - NS_ASSERTION(entry.cert, "Could not find EV root in NSS storage"); - } -#endif - - SECITEM_FreeItem(&ias.derIssuer, false); - SECITEM_FreeItem(&ias.serialNumber, false); - - if (!entry.cert) - continue; - - nsNSSCertificate c(entry.cert); - nsAutoString fingerprint; - c.GetSha1Fingerprint(fingerprint); - - NS_ConvertASCIItoUTF16 sha1(entry.ev_root_sha1_fingerprint); - - if (sha1 != fingerprint) { - NS_ASSERTION(sha1 == fingerprint, "found EV root with unexpected SHA1 mismatch"); - CERT_DestroyCertificate(entry.cert); - entry.cert = nullptr; - continue; - } - - SECItem ev_oid_item; - ev_oid_item.data = nullptr; - ev_oid_item.len = 0; - SECStatus srv = SEC_StringToOID(nullptr, &ev_oid_item, - entry.dotted_oid, 0); - if (srv != SECSuccess) - continue; - - entry.oid_tag = register_oid(&ev_oid_item, entry.oid_name); - - SECITEM_FreeItem(&ev_oid_item, false); - } - -#ifdef PSM_ENABLE_TEST_EV_ROOTS - if (!testEVInfosLoaded) { - testEVInfosLoaded = true; - testEVInfos = new testEVArray; - if (testEVInfos) { - loadTestEVInfos(); - } - } -#endif - - return PR_SUCCESS; -} - -namespace mozilla { namespace psm { - -// Find the first policy OID that is known to be an EV policy OID. -SECStatus -getFirstEVPolicy(CERTCertificate* cert, SECOidTag& outOidTag) -{ - if (!cert) - return SECFailure; - - if (cert->extensions) { - for (int i=0; cert->extensions[i]; i++) { - const SECItem* oid = &cert->extensions[i]->id; - - SECOidTag oidTag = SECOID_FindOIDTag(oid); - if (oidTag != SEC_OID_X509_CERTIFICATE_POLICIES) - continue; - - SECItem* value = &cert->extensions[i]->value; - - CERTCertificatePolicies* policies; - CERTPolicyInfo** policyInfos; - - policies = CERT_DecodeCertificatePoliciesExtension(value); - if (!policies) - continue; - - policyInfos = policies->policyInfos; - - bool found = false; - while (*policyInfos) { - const CERTPolicyInfo* policyInfo = *policyInfos++; - - SECOidTag oid_tag = policyInfo->oid; - if (oid_tag != SEC_OID_UNKNOWN && isEVPolicy(oid_tag)) { - // in our list of OIDs accepted for EV - outOidTag = oid_tag; - found = true; - break; - } - } - CERT_DestroyCertificatePoliciesExtension(policies); - if (found) - return SECSuccess; - } - } - - return SECFailure; -} - -} } // namespace mozilla::psm - -NS_IMETHODIMP -nsSSLStatus::GetIsExtendedValidation(bool* aIsEV) -{ - NS_ENSURE_ARG_POINTER(aIsEV); - *aIsEV = false; - -#ifdef NSS_NO_LIBPKIX - return NS_OK; -#else - nsCOMPtr<nsIX509Cert> cert = mServerCert; - nsresult rv; - nsCOMPtr<nsIIdentityInfo> idinfo = do_QueryInterface(cert, &rv); - - // mServerCert should never be null when this method is called because - // nsSSLStatus objects always have mServerCert set right after they are - // constructed and before they are returned. GetIsExtendedValidation should - // only be called in the chrome process (in e10s), and mServerCert will always - // implement nsIIdentityInfo in the chrome process. - if (!idinfo) { - NS_ERROR("nsSSLStatus has null mServerCert or was called in the content " - "process"); - return NS_ERROR_UNEXPECTED; - } - - // Never allow bad certs for EV, regardless of overrides. - if (mHaveCertErrorBits) - return NS_OK; - - return idinfo->GetIsExtendedValidation(aIsEV); -#endif -} - -#ifndef NSS_NO_LIBPKIX - -nsresult -nsNSSCertificate::hasValidEVOidTag(SECOidTag& resultOidTag, bool& validEV) -{ - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) - return NS_ERROR_NOT_AVAILABLE; - - nsresult nrv; - nsCOMPtr<nsINSSComponent> nssComponent = - do_GetService(PSM_COMPONENT_CONTRACTID, &nrv); - if (NS_FAILED(nrv)) - return nrv; - nssComponent->EnsureIdentityInfoLoaded(); - - RefPtr<mozilla::psm::SharedCertVerifier> - certVerifier(mozilla::psm::GetDefaultCertVerifier()); - NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED); - - validEV = false; - resultOidTag = SEC_OID_UNKNOWN; - - uint32_t flags = mozilla::psm::CertVerifier::FLAG_LOCAL_ONLY | - mozilla::psm::CertVerifier::FLAG_NO_DV_FALLBACK_FOR_EV; - SECStatus rv = certVerifier->VerifyCert(mCert, - certificateUsageSSLServer, PR_Now(), - nullptr /* XXX pinarg */, - flags, nullptr, &resultOidTag); - - if (rv != SECSuccess) { - resultOidTag = SEC_OID_UNKNOWN; - } - if (resultOidTag != SEC_OID_UNKNOWN) { - validEV = true; - } - return NS_OK; -} - -nsresult -nsNSSCertificate::getValidEVOidTag(SECOidTag& resultOidTag, bool& validEV) -{ - if (mCachedEVStatus != ev_status_unknown) { - validEV = (mCachedEVStatus == ev_status_valid); - if (validEV) - resultOidTag = mCachedEVOidTag; - return NS_OK; - } - - nsresult rv = hasValidEVOidTag(resultOidTag, validEV); - if (NS_SUCCEEDED(rv)) { - if (validEV) { - mCachedEVOidTag = resultOidTag; - } - mCachedEVStatus = validEV ? ev_status_valid : ev_status_invalid; - } - return rv; -} - -#endif // NSS_NO_LIBPKIX - -NS_IMETHODIMP -nsNSSCertificate::GetIsExtendedValidation(bool* aIsEV) -{ -#ifdef NSS_NO_LIBPKIX - *aIsEV = false; - return NS_OK; -#else - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) - return NS_ERROR_NOT_AVAILABLE; - - NS_ENSURE_ARG(aIsEV); - *aIsEV = false; - - if (mCachedEVStatus != ev_status_unknown) { - *aIsEV = (mCachedEVStatus == ev_status_valid); - return NS_OK; - } - - SECOidTag oid_tag; - return getValidEVOidTag(oid_tag, *aIsEV); -#endif -} - -NS_IMETHODIMP -nsNSSCertificate::GetValidEVPolicyOid(nsACString& outDottedOid) -{ - outDottedOid.Truncate(); - -#ifndef NSS_NO_LIBPKIX - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) - return NS_ERROR_NOT_AVAILABLE; - - SECOidTag oid_tag; - bool valid; - nsresult rv = getValidEVOidTag(oid_tag, valid); - if (NS_FAILED(rv)) - return rv; - - if (valid) { - SECOidData* oid_data = SECOID_FindOIDByTag(oid_tag); - if (!oid_data) - return NS_ERROR_FAILURE; - - char* oid_str = CERT_GetOidString(&oid_data->oid); - if (!oid_str) - return NS_ERROR_FAILURE; - - outDottedOid = oid_str; - PR_smprintf_free(oid_str); - } -#endif - - return NS_OK; -} - -#ifndef NSS_NO_LIBPKIX - -NS_IMETHODIMP -nsNSSComponent::EnsureIdentityInfoLoaded() -{ - PRStatus rv = PR_CallOnce(&mIdentityInfoCallOnce, IdentityInfoInit); - return (rv == PR_SUCCESS) ? NS_OK : NS_ERROR_FAILURE; -} - -// only called during shutdown -void -nsNSSComponent::CleanupIdentityInfo() -{ - nsNSSShutDownPreventionLock locker; - for (size_t iEV=0; iEV < (sizeof(myTrustedEVInfos)/sizeof(nsMyTrustedEVInfo)); ++iEV) { - nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV]; - if (entry.cert) { - CERT_DestroyCertificate(entry.cert); - entry.cert = nullptr; - } - } - -#ifdef PSM_ENABLE_TEST_EV_ROOTS - if (testEVInfosLoaded) { - testEVInfosLoaded = false; - if (testEVInfos) { - for (size_t i = 0; i<testEVInfos->Length(); ++i) { - delete testEVInfos->ElementAt(i); - } - testEVInfos->Clear(); - delete testEVInfos; - testEVInfos = nullptr; - } - } -#endif - memset(&mIdentityInfoCallOnce, 0, sizeof(PRCallOnceType)); -} - -#endif
--- a/security/manager/ssl/src/nsNSSCertificate.cpp +++ b/security/manager/ssl/src/nsNSSCertificate.cpp @@ -4,16 +4,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "prmem.h" #include "prerror.h" #include "prprf.h" #include "nsNSSCertificate.h" #include "CertVerifier.h" +#include "ExtendedValidation.h" #include "nsNSSComponent.h" // for PIPNSS string bundle calls. #include "nsNSSCleaner.h" #include "nsCOMPtr.h" #include "nsIMutableArray.h" #include "nsNSSCertValidity.h" #include "nsPKCS12Blob.h" #include "nsPK11TokenDB.h" #include "nsIX509Cert.h" @@ -1476,16 +1477,135 @@ char* nsNSSCertificate::defaultServerNic } PR_Free(nickname); count++; } PR_FREEIF(servername); return nickname; } +#ifndef NSS_NO_LIBPKIX + +nsresult +nsNSSCertificate::hasValidEVOidTag(SECOidTag& resultOidTag, bool& validEV) +{ + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) + return NS_ERROR_NOT_AVAILABLE; + + EnsureIdentityInfoLoaded(); + + RefPtr<mozilla::psm::SharedCertVerifier> + certVerifier(mozilla::psm::GetDefaultCertVerifier()); + NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED); + + validEV = false; + resultOidTag = SEC_OID_UNKNOWN; + + uint32_t flags = mozilla::psm::CertVerifier::FLAG_LOCAL_ONLY | + mozilla::psm::CertVerifier::FLAG_NO_DV_FALLBACK_FOR_EV; + SECStatus rv = certVerifier->VerifyCert(mCert, + certificateUsageSSLServer, PR_Now(), + nullptr /* XXX pinarg */, + flags, nullptr, &resultOidTag); + + if (rv != SECSuccess) { + resultOidTag = SEC_OID_UNKNOWN; + } + if (resultOidTag != SEC_OID_UNKNOWN) { + validEV = true; + } + return NS_OK; +} + +nsresult +nsNSSCertificate::getValidEVOidTag(SECOidTag& resultOidTag, bool& validEV) +{ + if (mCachedEVStatus != ev_status_unknown) { + validEV = (mCachedEVStatus == ev_status_valid); + if (validEV) { + resultOidTag = mCachedEVOidTag; + } + return NS_OK; + } + + nsresult rv = hasValidEVOidTag(resultOidTag, validEV); + if (NS_SUCCEEDED(rv)) { + if (validEV) { + mCachedEVOidTag = resultOidTag; + } + mCachedEVStatus = validEV ? ev_status_valid : ev_status_invalid; + } + return rv; +} + +#endif // NSS_NO_LIBPKIX + +NS_IMETHODIMP +nsNSSCertificate::GetIsExtendedValidation(bool* aIsEV) +{ +#ifdef NSS_NO_LIBPKIX + *aIsEV = false; + return NS_OK; +#else + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + + NS_ENSURE_ARG(aIsEV); + *aIsEV = false; + + if (mCachedEVStatus != ev_status_unknown) { + *aIsEV = (mCachedEVStatus == ev_status_valid); + return NS_OK; + } + + SECOidTag oid_tag; + return getValidEVOidTag(oid_tag, *aIsEV); +#endif +} + +NS_IMETHODIMP +nsNSSCertificate::GetValidEVPolicyOid(nsACString& outDottedOid) +{ + outDottedOid.Truncate(); + +#ifndef NSS_NO_LIBPKIX + nsNSSShutDownPreventionLock locker; + if (isAlreadyShutDown()) { + return NS_ERROR_NOT_AVAILABLE; + } + + SECOidTag oid_tag; + bool valid; + nsresult rv = getValidEVOidTag(oid_tag, valid); + if (NS_FAILED(rv)) { + return rv; + } + + if (valid) { + SECOidData* oid_data = SECOID_FindOIDByTag(oid_tag); + if (!oid_data) { + return NS_ERROR_FAILURE; + } + + char* oid_str = CERT_GetOidString(&oid_data->oid); + if (!oid_str) { + return NS_ERROR_FAILURE; + } + + outDottedOid.Assign(oid_str); + PR_smprintf_free(oid_str); + } +#endif + + return NS_OK; +} + NS_IMPL_ISUPPORTS1(nsNSSCertList, nsIX509CertList) nsNSSCertList::nsNSSCertList(CERTCertList* certList, const nsNSSShutDownPreventionLock& proofOfLock) { if (certList) { mCertList = certList; } else {
--- a/security/manager/ssl/src/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/src/nsNSSCertificateDB.cpp @@ -6,16 +6,17 @@ // CERT_AddTempCertToPerm is exposed as __CERT_AddTempCertToPerm, but it is // only exported so PSM can use it for this specific purpose. #define CERT_AddTempCertToPerm __CERT_AddTempCertToPerm #include "nsNSSComponent.h" #include "nsNSSCertificateDB.h" #include "CertVerifier.h" +#include "ExtendedValidation.h" #include "nsNSSComponent.h" #include "mozilla/Base64.h" #include "nsCOMPtr.h" #include "nsNSSCertificate.h" #include "nsNSSHelper.h" #include "nsNSSCertHelper.h" #include "nsNSSCertCache.h" #include "nsCRT.h" @@ -1693,23 +1694,18 @@ nsNSSCertificateDB::VerifyCertNow(nsIX50 *aHasEVPolicy = false; *_retval = PR_UNKNOWN_ERROR; nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) { return NS_ERROR_NOT_AVAILABLE; } - nsresult rv; #ifndef NSS_NO_LIBPKIX - nsCOMPtr<nsINSSComponent> inss = do_GetService(PSM_COMPONENT_CONTRACTID, &rv); - if (NS_FAILED(rv)) { - return NS_ERROR_NOT_AVAILABLE; - } - inss->EnsureIdentityInfoLoaded(); + EnsureIdentityInfoLoaded(); #endif nsCOMPtr<nsIX509Cert2> x509Cert = do_QueryInterface(aCert); if (!x509Cert) { return NS_ERROR_INVALID_ARG; } ScopedCERTCertificate nssCert(x509Cert->GetCert());
--- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -5,16 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifdef MOZ_LOGGING #define FORCE_PR_LOG 1 #endif #include "nsNSSComponent.h" +#include "ExtendedValidation.h" #include "mozilla/Telemetry.h" #include "nsCertVerificationThread.h" #include "nsAppDirectoryServiceDefs.h" #include "nsComponentManagerUtils.h" #include "nsDirectoryServiceDefs.h" #include "nsICertOverrideService.h" #include "mozilla/Preferences.h" #include "nsThreadUtils.h" @@ -215,22 +216,16 @@ nsNSSComponent::nsNSSComponent() { #ifdef PR_LOGGING if (!gPIPNSSLog) gPIPNSSLog = PR_NewLogModule("pipnss"); #endif PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSComponent::ctor\n")); mObserversRegistered = false; -#ifndef NSS_NO_LIBPKIX - // In order to keep startup time lower, we delay loading and - // registering all identity data until first needed. - memset(&mIdentityInfoCallOnce, 0, sizeof(PRCallOnceType)); -#endif - NS_ASSERTION( (0 == mInstanceCount), "nsNSSComponent is a singleton, but instantiated multiple times!"); ++mInstanceCount; mShutdownObjectList = nsNSSShutDownList::construct(); mIsNetworkDown = false; } void nsNSSComponent::deleteBackgroundThreads() @@ -899,22 +894,21 @@ static const CipherPref sCipherPrefs[] = { nullptr, 0 } // end marker }; static void setNonPkixOcspEnabled(int32_t ocspEnabled) { // Note: this preference is numeric vs boolean because previously we // supported more than two options. + CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB()); if (!ocspEnabled) { CERT_DisableOCSPChecking(CERT_GetDefaultCertDB()); - CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB()); } else { CERT_EnableOCSPChecking(CERT_GetDefaultCertDB()); - CERT_DisableOCSPDefaultResponder(CERT_GetDefaultCertDB()); } } static const int32_t OCSP_ENABLED_DEFAULT = 1; static const bool REQUIRE_SAFE_NEGOTIATION_DEFAULT = false; static const bool ALLOW_UNRESTRICTED_RENEGO_DEFAULT = false; static const bool FALSE_START_ENABLED_DEFAULT = true; static const bool NPN_ENABLED_DEFAULT = true;
--- a/security/manager/ssl/src/nsNSSComponent.h +++ b/security/manager/ssl/src/nsNSSComponent.h @@ -102,20 +102,16 @@ class NS_NO_VTABLE nsINSSComponent : pub NS_IMETHOD PostEvent(const nsAString& eventType, const nsAString& token) = 0; NS_IMETHOD DispatchEvent(const nsAString& eventType, const nsAString& token) = 0; #endif -#ifndef NSS_NO_LIBPKIX - NS_IMETHOD EnsureIdentityInfoLoaded() = 0; -#endif - NS_IMETHOD IsNSSInitialized(bool* initialized) = 0; virtual ::mozilla::TemporaryRef<mozilla::psm::SharedCertVerifier> GetDefaultCertVerifier() = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsINSSComponent, NS_INSSCOMPONENT_IID) @@ -170,31 +166,27 @@ public: NS_IMETHOD DispatchEvent(const nsAString& eventType, const nsAString& token); void LaunchSmartCardThreads(); void ShutdownSmartCardThreads(); nsresult DispatchEventToWindow(nsIDOMWindow* domWin, const nsAString& eventType, const nsAString& token); #endif -#ifndef NSS_NO_LIBPKIX - NS_IMETHOD EnsureIdentityInfoLoaded(); -#endif NS_IMETHOD IsNSSInitialized(bool* initialized); ::mozilla::TemporaryRef<mozilla::psm::SharedCertVerifier> GetDefaultCertVerifier() MOZ_OVERRIDE; private: nsresult InitializeNSS(); void ShutdownNSS(); void InstallLoadableRoots(); void UnloadLoadableRoots(); - void CleanupIdentityInfo(); void setValidationOptions(bool isInitialSetting); nsresult setEnabledTLSVersions(); nsresult InitializePIPNSSBundle(); nsresult ConfigureInternalPKCS11Token(); nsresult RegisterObservers(); nsresult DeregisterObservers(); // Methods that we use to handle the profile change notifications (and to @@ -221,17 +213,16 @@ private: void createBackgroundThreads(); nsCertVerificationThread* mCertVerificationThread; nsNSSHttpInterface mHttpForNSS; mozilla::RefPtr<mozilla::psm::SharedCertVerifier> mDefaultCertVerifier; static PRStatus IdentityInfoInit(void); - PRCallOnceType mIdentityInfoCallOnce; }; class nsNSSErrors { public: static const char* getDefaultErrorStringName(PRErrorCode err); static const char* getOverrideErrorStringName(PRErrorCode aErrorCode); static nsresult getErrorMessageFromCode(PRErrorCode err,
--- a/security/manager/ssl/src/nsSSLStatus.cpp +++ b/security/manager/ssl/src/nsSSLStatus.cpp @@ -2,16 +2,17 @@ * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsSSLStatus.h" #include "plstr.h" #include "nsIClassInfoImpl.h" +#include "nsIIdentityInfo.h" #include "nsIProgrammingLanguage.h" #include "nsIObjectOutputStream.h" #include "nsIObjectInputStream.h" NS_IMETHODIMP nsSSLStatus::GetServerCert(nsIX509Cert** _result) { NS_ASSERTION(_result, "non-NULL destination required"); @@ -84,16 +85,49 @@ nsSSLStatus::GetIsUntrusted(bool* _resul NS_ASSERTION(_result, "non-NULL destination required"); *_result = mHaveCertErrorBits && mIsUntrusted; return NS_OK; } NS_IMETHODIMP +nsSSLStatus::GetIsExtendedValidation(bool* aIsEV) +{ + NS_ENSURE_ARG_POINTER(aIsEV); + *aIsEV = false; + +#ifdef NSS_NO_LIBPKIX + return NS_OK; +#else + nsCOMPtr<nsIX509Cert> cert = mServerCert; + nsresult rv; + nsCOMPtr<nsIIdentityInfo> idinfo = do_QueryInterface(cert, &rv); + + // mServerCert should never be null when this method is called because + // nsSSLStatus objects always have mServerCert set right after they are + // constructed and before they are returned. GetIsExtendedValidation should + // only be called in the chrome process (in e10s), and mServerCert will always + // implement nsIIdentityInfo in the chrome process. + if (!idinfo) { + NS_ERROR("nsSSLStatus has null mServerCert or was called in the content " + "process"); + return NS_ERROR_UNEXPECTED; + } + + // Never allow bad certs for EV, regardless of overrides. + if (mHaveCertErrorBits) { + return NS_OK; + } + + return idinfo->GetIsExtendedValidation(aIsEV); +#endif +} + +NS_IMETHODIMP nsSSLStatus::Read(nsIObjectInputStream* stream) { nsCOMPtr<nsISupports> cert; nsresult rv = stream->ReadObject(true, getter_AddRefs(cert)); NS_ENSURE_SUCCESS(rv, rv); mServerCert = do_QueryInterface(cert); if (!mServerCert)
--- a/toolkit/toolkit.mozbuild +++ b/toolkit/toolkit.mozbuild @@ -15,16 +15,20 @@ if CONFIG['COMPILE_ENVIRONMENT']: if not CONFIG['MOZ_NATIVE_NSS']: add_tier_dir('nss', 'security/build') include('/config/js/js.mozbuild') if CONFIG['MOZ_CONTENT_SANDBOX']: add_tier_dir('sandbox', 'security/sandbox') +# Depends on NSS and NSPR, and must be built after sandbox or else B2G emulator +# builds fail. +add_tier_dir('platform', 'security/certverifier') + # the signing related bits of libmar depend on nss if CONFIG['MOZ_UPDATER']: add_tier_dir('platform', 'modules/libmar') if CONFIG['NS_TRACE_MALLOC']: add_tier_dir('platform', 'tools/trace-malloc/lib') if CONFIG['MOZ_DMD']: