author | David Keeler <dkeeler@mozilla.com> |
Fri, 30 Sep 2016 18:08:08 -0700 | |
changeset 319272 | 6810346363585085e260d47a58cf5b7d58542d44 |
parent 319271 | c7ad8590b1e78f9bad9dccd8dc64fc34717819db |
child 319273 | e45221018bdd6365ce904ade9ad0698420e67f42 |
push id | 83120 |
push user | cbook@mozilla.com |
push date | Tue, 25 Oct 2016 08:47:23 +0000 |
treeherder | mozilla-inbound@4ee669700dc8 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | Cykesiopka, mgoodwin |
bugs | 1227638 |
milestone | 52.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/b2g/confvars.sh +++ b/b2g/confvars.sh @@ -14,17 +14,16 @@ MOZ_B2G_VERSION=2.6.0.0-prerelease MOZ_B2G_OS_NAME=Boot2Gecko MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official # MOZ_APP_DISPLAYNAME is set by branding/configure.sh MOZ_NO_SMART_CARDS=1 MOZ_APP_STATIC_INI=1 -MOZ_NO_EV_CERTS=1 if test "$OS_TARGET" = "Android"; then MOZ_CAPTURE=1 MOZ_RAW=1 MOZ_AUDIO_CHANNEL_MANAGER=1 fi # use custom widget for html:select
--- a/old-configure.in +++ b/old-configure.in @@ -3953,24 +3953,16 @@ dnl ==================================== dnl = Disable smartcard support dnl ======================================================== if test -n "$MOZ_NO_SMART_CARDS"; then AC_DEFINE(MOZ_NO_SMART_CARDS) fi AC_SUBST(MOZ_NO_SMART_CARDS) dnl ======================================================== -dnl = Disable EV certificate verification -dnl ======================================================== -if test -n "$MOZ_NO_EV_CERTS"; then - AC_DEFINE(MOZ_NO_EV_CERTS) -fi -AC_SUBST(MOZ_NO_EV_CERTS) - -dnl ======================================================== dnl = Sandboxing support dnl ======================================================== if test -n "$MOZ_TSAN" -o -n "$MOZ_ASAN"; then # Bug 1182565: TSan conflicts with sandboxing on Linux. # Bug 1287971: LSan also conflicts with sandboxing on Linux. case $OS_TARGET in Linux|Android) MOZ_SANDBOX=
--- a/security/certverifier/CertVerifier.cpp +++ b/security/certverifier/CertVerifier.cpp @@ -457,17 +457,16 @@ CertVerifier::VerifyCert(CERTCertificate size_t sha1ModeConfigurationsCount = MOZ_ARRAY_LENGTH(sha1ModeConfigurations); static_assert(MOZ_ARRAY_LENGTH(sha1ModeConfigurations) == MOZ_ARRAY_LENGTH(sha1ModeResults), "digestAlgorithm array lengths differ"); rv = Result::ERROR_UNKNOWN_ERROR; -#ifndef MOZ_NO_EV_CERTS // Try to validate for EV first. NSSCertDBTrustDomain::OCSPFetching evOCSPFetching = (mOCSPDownloadConfig == ocspOff) || (flags & FLAG_LOCAL_ONLY) ? NSSCertDBTrustDomain::LocalOnlyOCSPForEV : NSSCertDBTrustDomain::FetchOCSPForEV; CertPolicyId evPolicy; SECOidTag evPolicyOidTag; @@ -532,17 +531,16 @@ CertVerifier::VerifyCert(CERTCertificate if (rv != Success) { break; } } } if (rv == Success) { break; } -#endif if (flags & FLAG_MUST_BE_EV) { rv = Result::ERROR_POLICY_VALIDATION_FAILED; break; } // Now try non-EV. unsigned int keySizeOptions[] = {
--- a/security/certverifier/ExtendedValidation.cpp +++ b/security/certverifier/ExtendedValidation.cpp @@ -6,16 +6,17 @@ #include "ExtendedValidation.h" #include "base64.h" #include "cert.h" #include "certdb.h" #include "hasht.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/Assertions.h" #include "mozilla/Casting.h" #include "mozilla/PodOperations.h" #include "pk11pub.h" #include "pkix/pkixtypes.h" #include "prerror.h" #include "prinit.h" #include "secerr.h" @@ -1244,120 +1245,102 @@ CertIsAuthoritativeForEVPolicy(const Uni PodEqual(oidData->oid.data, policy.bytes, policy.numBytes)) { return true; } } return false; } -static PRStatus -IdentityInfoInit() +nsresult +LoadExtendedValidationInfo() { static const char* sCABForumOIDString = "2.23.140.1.1"; static const char* sCABForumOIDDescription = "CA/Browser Forum EV OID"; mozilla::ScopedAutoSECItem cabforumOIDItem; if (SEC_StringToOID(nullptr, &cabforumOIDItem, sCABForumOIDString, 0) != SECSuccess) { - return PR_FAILURE; + return NS_ERROR_FAILURE; } sCABForumEVOIDTag = RegisterOID(cabforumOIDItem, sCABForumOIDDescription); if (sCABForumEVOIDTag == SEC_OID_UNKNOWN) { - return PR_FAILURE; + return NS_ERROR_FAILURE; } for (size_t iEV = 0; iEV < mozilla::ArrayLength(myTrustedEVInfos); ++iEV) { nsMyTrustedEVInfo& entry = myTrustedEVInfos[iEV]; + SECStatus srv; +#ifdef DEBUG + // This section of code double-checks that we calculated the correct + // certificate hash given the issuer and serial number and that it is + // actually present in our loaded root certificates module. It is + // unnecessary to check this in non-debug builds since we will safely fall + // back to DV if the EV information is incorrect. mozilla::ScopedAutoSECItem derIssuer; - SECStatus rv = ATOB_ConvertAsciiToItem(&derIssuer, entry.issuer_base64); - PR_ASSERT(rv == SECSuccess); - if (rv != SECSuccess) { - return PR_FAILURE; + srv = ATOB_ConvertAsciiToItem(&derIssuer, entry.issuer_base64); + MOZ_ASSERT(srv == SECSuccess, "Could not base64-decode built-in EV issuer"); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; } mozilla::ScopedAutoSECItem serialNumber; - rv = ATOB_ConvertAsciiToItem(&serialNumber, entry.serial_base64); - PR_ASSERT(rv == SECSuccess); - if (rv != SECSuccess) { - return PR_FAILURE; + srv = ATOB_ConvertAsciiToItem(&serialNumber, entry.serial_base64); + MOZ_ASSERT(srv == SECSuccess, "Could not base64-decode built-in EV serial"); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; } CERTIssuerAndSN ias; ias.derIssuer.data = derIssuer.data; ias.derIssuer.len = derIssuer.len; ias.serialNumber.data = serialNumber.data; ias.serialNumber.len = serialNumber.len; ias.serialNumber.type = siUnsignedInteger; UniqueCERTCertificate cert(CERT_FindCertByIssuerAndSN(nullptr, &ias)); // 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 assert on debug builds, but - // silently continue on release builds. In both cases, the root cert does - // not get EV treatment. + // version of system NSS is installed). if (!cert) { -#ifdef DEBUG - // The debug CA structs are at positions 0 to NUM_TEST_EV_ROOTS - 1, and - // are NOT in the NSS root DB. - if (iEV < NUM_TEST_EV_ROOTS) { - continue; + // The entries for the debug EV roots are at indices 0 through + // NUM_TEST_EV_ROOTS - 1. Since they're not built-in, they probably + // haven't been loaded yet. + MOZ_ASSERT(iEV < NUM_TEST_EV_ROOTS, "Could not find built-in EV root"); + } else { + unsigned char certFingerprint[SHA256_LENGTH]; + srv = PK11_HashBuf(SEC_OID_SHA256, certFingerprint, cert->derCert.data, + AssertedCast<int32_t>(cert->derCert.len)); + MOZ_ASSERT(srv == SECSuccess, "Could not hash EV root"); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; } -#endif - PR_NOT_REACHED("Could not find EV root in NSS storage"); - continue; - } - - unsigned char certFingerprint[SHA256_LENGTH]; - rv = PK11_HashBuf(SEC_OID_SHA256, certFingerprint, cert->derCert.data, - AssertedCast<int32_t>(cert->derCert.len)); - PR_ASSERT(rv == SECSuccess); - if (rv == SECSuccess) { - bool same = !memcmp(certFingerprint, entry.ev_root_sha256_fingerprint, - sizeof(certFingerprint)); - PR_ASSERT(same); - if (same) { - mozilla::ScopedAutoSECItem evOIDItem; - rv = SEC_StringToOID(nullptr, &evOIDItem, entry.dotted_oid, 0); - PR_ASSERT(rv == SECSuccess); - if (rv == SECSuccess) { - entry.oid_tag = RegisterOID(evOIDItem, entry.oid_name); - if (entry.oid_tag == SEC_OID_UNKNOWN) { - rv = SECFailure; - } - } - } else { - PR_SetError(SEC_ERROR_BAD_DATA, 0); - rv = SECFailure; + bool same = PodEqual(certFingerprint, entry.ev_root_sha256_fingerprint); + MOZ_ASSERT(same, "EV root fingerprint mismatch"); + if (!same) { + return NS_ERROR_FAILURE; } } - - if (rv != SECSuccess) { - entry.oid_tag = SEC_OID_UNKNOWN; - return PR_FAILURE; +#endif + // This is the code that actually enables these roots for EV. + mozilla::ScopedAutoSECItem evOIDItem; + srv = SEC_StringToOID(nullptr, &evOIDItem, entry.dotted_oid, 0); + MOZ_ASSERT(srv == SECSuccess, "SEC_StringToOID failed"); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + entry.oid_tag = RegisterOID(evOIDItem, entry.oid_name); + if (entry.oid_tag == SEC_OID_UNKNOWN) { + return NS_ERROR_FAILURE; } } - return PR_SUCCESS; -} - -static PRCallOnceType sIdentityInfoCallOnce; - -void -EnsureIdentityInfoLoaded() -{ - (void) PR_CallOnce(&sIdentityInfoCallOnce, IdentityInfoInit); -} - -void -CleanupIdentityInfo() -{ - memset(&sIdentityInfoCallOnce, 0, sizeof(PRCallOnceType)); + return NS_OK; } // Find the first policy OID that is known to be an EV policy OID. SECStatus GetFirstEVPolicy(CERTCertificate* cert, /*out*/ mozilla::pkix::CertPolicyId& policy, /*out*/ SECOidTag& policyOidTag) {
--- a/security/certverifier/ExtendedValidation.h +++ b/security/certverifier/ExtendedValidation.h @@ -9,24 +9,21 @@ #include "ScopedNSSTypes.h" #include "certt.h" #include "prtypes.h" namespace mozilla { namespace pkix { struct CertPolicyId; } } namespace mozilla { namespace psm { -#ifndef MOZ_NO_EV_CERTS -void EnsureIdentityInfoLoaded(); -void CleanupIdentityInfo(); +nsresult LoadExtendedValidationInfo(); SECStatus GetFirstEVPolicy(CERTCertificate* cert, /*out*/ mozilla::pkix::CertPolicyId& policy, /*out*/ SECOidTag& policyOidTag); // CertIsAuthoritativeForEVPolicy does NOT evaluate whether the cert is trusted // or distrusted. bool CertIsAuthoritativeForEVPolicy(const UniqueCERTCertificate& cert, const mozilla::pkix::CertPolicyId& policy); -#endif } } // namespace mozilla::psm #endif // ExtendedValidation_h
--- a/security/certverifier/NSSCertDBTrustDomain.cpp +++ b/security/certverifier/NSSCertDBTrustDomain.cpp @@ -168,22 +168,16 @@ NSSCertDBTrustDomain::FindIssuer(Input e } Result NSSCertDBTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA, const CertPolicyId& policy, Input candidateCertDER, /*out*/ TrustLevel& trustLevel) { -#ifdef MOZ_NO_EV_CERTS - if (!policy.IsAnyPolicy()) { - return Result::ERROR_POLICY_VALIDATION_FAILED; - } -#endif - // XXX: This would be cleaner and more efficient if we could get the trust // information without constructing a CERTCertificate here, but NSS doesn't // expose it in any other easy-to-use fashion. The use of // CERT_NewTempCertificate to get a CERTCertificate shouldn't be a // performance problem because NSS will just find the existing // CERTCertificate in its in-memory cache and return it. SECItem candidateCertDERSECItem = UnsafeMapInputToSECItem(candidateCertDER); UniqueCERTCertificate candidateCert( @@ -245,22 +239,20 @@ NSSCertDBTrustDomain::GetCertTrust(EndEn // For TRUST, we only use the CERTDB_TRUSTED_CA bit, because Gecko hasn't // needed to consider end-entity certs to be their own trust anchors since // Gecko implemented nsICertOverrideService. if (flags & CERTDB_TRUSTED_CA) { if (policy.IsAnyPolicy()) { trustLevel = TrustLevel::TrustAnchor; return Success; } -#ifndef MOZ_NO_EV_CERTS if (CertIsAuthoritativeForEVPolicy(candidateCert, policy)) { trustLevel = TrustLevel::TrustAnchor; return Success; } -#endif } } trustLevel = TrustLevel::InheritsTrust; return Success; } Result
--- a/security/manager/ssl/SSLServerCertVerification.cpp +++ b/security/manager/ssl/SSLServerCertVerification.cpp @@ -1753,47 +1753,16 @@ AuthCertificateHook(void* arg, PRFileDes NS_ERROR("error code not set"); error = PR_UNKNOWN_ERROR; } PR_SetError(error, 0); return SECFailure; } -#ifndef MOZ_NO_EV_CERTS -class InitializeIdentityInfo : public CryptoTask -{ - virtual nsresult CalculateResult() override - { - EnsureIdentityInfoLoaded(); - return NS_OK; - } - - virtual void ReleaseNSSResources() override { } // no-op - virtual void CallCallback(nsresult rv) override { } // no-op -}; -#endif - -void EnsureServerVerificationInitialized() -{ -#ifndef MOZ_NO_EV_CERTS - // Should only be called from socket transport thread due to the static - // variable and the reference to gCertVerificationThreadPool - - static bool triggeredCertVerifierInit = false; - if (triggeredCertVerifierInit) - return; - triggeredCertVerifierInit = true; - - RefPtr<InitializeIdentityInfo> initJob = new InitializeIdentityInfo(); - if (gCertVerificationThreadPool) - gCertVerificationThreadPool->Dispatch(initJob, NS_DISPATCH_NORMAL); -#endif -} - SSLServerCertVerificationResult::SSLServerCertVerificationResult( nsNSSSocketInfo* infoObject, PRErrorCode errorCode, Telemetry::ID telemetryID, uint32_t telemetryValue, SSLErrorMessageType errorMessageType) : mInfoObject(infoObject) , mErrorCode(errorCode) , mErrorMessageType(errorMessageType) , mTelemetryID(telemetryID)
--- a/security/manager/ssl/SSLServerCertVerification.h +++ b/security/manager/ssl/SSLServerCertVerification.h @@ -9,16 +9,11 @@ #include "seccomon.h" #include "prio.h" namespace mozilla { namespace psm { SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, PRBool isServer); -// EnsureServerVerificationInitialized() posts an event to a cert -// verification thread to run nsINSSComponent::EnsureIdentityInfoLoaded() -// exactly once. It must be called from socket thread. -void EnsureServerVerificationInitialized(); - } } // namespace mozilla::psm #endif
--- a/security/manager/ssl/nsNSSCertHelper.cpp +++ b/security/manager/ssl/nsNSSCertHelper.cpp @@ -1963,25 +1963,25 @@ nsNSSCertificate::CreateTBSCertificateAS nssComponent->GetPIPNSSBundleString("CertDumpSubjectUniqueID", text); printableItem->SetDisplayName(text); asn1Objects->AppendElement(printableItem, false); } if (mCert->extensions) { SECOidTag ev_oid_tag = SEC_OID_UNKNOWN; -#ifndef MOZ_NO_EV_CERTS bool validEV; rv = hasValidEVOidTag(ev_oid_tag, validEV); - if (NS_FAILED(rv)) + if (NS_FAILED(rv)) { return rv; + } - if (!validEV) + if (!validEV) { ev_oid_tag = SEC_OID_UNKNOWN; -#endif + } rv = ProcessExtensions(mCert->extensions, sequence, ev_oid_tag, nssComponent); if (NS_FAILED(rv)) return rv; } sequence.forget(retSequence); return NS_OK; }
--- a/security/manager/ssl/nsNSSCertificate.cpp +++ b/security/manager/ssl/nsNSSCertificate.cpp @@ -1129,26 +1129,23 @@ nsNSSCertificate::Equals(nsIX509Cert* ot NS_ENSURE_ARG(other); NS_ENSURE_ARG(result); UniqueCERTCertificate cert(other->GetCert()); *result = (mCert.get() == cert.get()); return NS_OK; } -#ifndef MOZ_NO_EV_CERTS - nsresult nsNSSCertificate::hasValidEVOidTag(SECOidTag& resultOidTag, bool& validEV) { nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) + 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; @@ -1191,41 +1188,34 @@ nsNSSCertificate::getValidEVOidTag(SECOi if (validEV) { mCachedEVOidTag = resultOidTag; } mCachedEVStatus = validEV ? ev_status_valid : ev_status_invalid; } return rv; } -#endif // MOZ_NO_EV_CERTS - nsresult nsNSSCertificate::GetIsExtendedValidation(bool* aIsEV) { -#ifdef MOZ_NO_EV_CERTS - *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 } namespace mozilla { // TODO(bug 1036065): It seems like we only construct CERTCertLists for the // purpose of constructing nsNSSCertLists, so maybe we should change this // function to output an nsNSSCertList instead. SECStatus
--- a/security/manager/ssl/nsNSSCertificateDB.cpp +++ b/security/manager/ssl/nsNSSCertificateDB.cpp @@ -1470,20 +1470,16 @@ VerifyCertAtTime(nsIX509Cert* aCert, NS_ENSURE_ARG_POINTER(aHasEVPolicy); NS_ENSURE_ARG_POINTER(aVerifiedChain); NS_ENSURE_ARG_POINTER(_retval); *aVerifiedChain = nullptr; *aHasEVPolicy = false; *_retval = PR_UNKNOWN_ERROR; -#ifndef MOZ_NO_EV_CERTS - EnsureIdentityInfoLoaded(); -#endif - UniqueCERTCertificate nssCert(aCert->GetCert()); if (!nssCert) { return NS_ERROR_INVALID_ARG; } RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier()); NS_ENSURE_TRUE(certVerifier, NS_ERROR_FAILURE);
--- a/security/manager/ssl/nsNSSComponent.cpp +++ b/security/manager/ssl/nsNSSComponent.cpp @@ -1819,16 +1819,22 @@ nsNSSComponent::InitializeNSS() rv = setEnabledTLSVersions(); if (NS_FAILED(rv)) { return NS_ERROR_UNEXPECTED; } DisableMD5(); LoadLoadableRoots(); + rv = LoadExtendedValidationInfo(); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("failed to load EV info")); + return rv; + } + MaybeEnableFamilySafetyCompatibility(); MaybeImportEnterpriseRoots(); ConfigureTLSSessionIdentifiers(); bool requireSafeNegotiation = Preferences::GetBool("security.ssl.require_safe_negotiation", REQUIRE_SAFE_NEGOTIATION_DEFAULT); @@ -1936,19 +1942,17 @@ nsNSSComponent::ShutdownNSS() #ifndef MOZ_NO_SMART_CARDS ShutdownSmartCardThreads(); #endif SSL_ClearSessionCache(); // TLSServerSocket may be run with the session cache enabled. This ensures // those resources are cleaned up. Unused << SSL_ShutdownServerSessionIDCache(); -#ifndef MOZ_NO_EV_CERTS - CleanupIdentityInfo(); -#endif + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("evaporating psm resources")); if (NS_FAILED(nsNSSShutDownList::evaporateAllNSSResources())) { MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("failed to evaporate resources")); return; } UnloadLoadableRoots(); EnsureNSSInitialized(nssShutdown); if (SECSuccess != ::NSS_Shutdown()) {
--- a/security/manager/ssl/nsNSSIOLayer.cpp +++ b/security/manager/ssl/nsNSSIOLayer.cpp @@ -2434,20 +2434,16 @@ nsSSLIOLayerImportFD(PRFileDesc* fd, goto loser; } if (SECSuccess != SSL_SetURL(sslSock, host)) { NS_NOTREACHED("SSL_SetURL failed"); goto loser; } - // This is an optimization to make sure the identity info dataset is parsed - // and loaded on a separate thread and can be overlapped with network latency. - EnsureServerVerificationInitialized(); - return sslSock; loser: if (sslSock) { PR_Close(sslSock); } return nullptr; }
--- a/security/manager/ssl/nsSSLStatus.cpp +++ b/security/manager/ssl/nsSSLStatus.cpp @@ -124,21 +124,17 @@ nsSSLStatus::GetIsExtendedValidation(boo return NS_OK; } if (mHasIsEVStatus) { *aIsEV = mIsEV; return NS_OK; } -#ifdef MOZ_NO_EV_CERTS - return NS_OK; -#else return NS_ERROR_NOT_AVAILABLE; -#endif } NS_IMETHODIMP nsSSLStatus::Read(nsIObjectInputStream* aStream) { nsCOMPtr<nsISupports> cert; nsresult rv = aStream->ReadObject(true, getter_AddRefs(cert)); NS_ENSURE_SUCCESS(rv, rv); @@ -285,18 +281,16 @@ nsSSLStatus::SetServerCert(nsNSSCertific mServerCert = aServerCert; if (aEVStatus != nsNSSCertificate::ev_status_unknown) { mIsEV = (aEVStatus == nsNSSCertificate::ev_status_valid); mHasIsEVStatus = true; return; } -#ifndef MOZ_NO_EV_CERTS if (aServerCert) { nsresult rv = aServerCert->GetIsExtendedValidation(&mIsEV); if (NS_FAILED(rv)) { return; } mHasIsEVStatus = true; } -#endif }