☠☠ backed out by 99b36484d3bc ☠ ☠ | |
author | Mark Goodwin <mgoodwin@mozilla.com> |
Fri, 17 Jul 2015 10:03:56 +0100 | |
changeset 253457 | fb6cbb4ada544b1d4e690b8dad1e067c2e3e609b |
parent 253456 | ec1b5a7d05e941f4b4bb4ef38d949011f877124f |
child 253458 | f324dcfaab40316a32888591053bd27b4c353658 |
push id | 29065 |
push user | ryanvm@gmail.com |
push date | Fri, 17 Jul 2015 14:26:32 +0000 |
treeherder | mozilla-central@911935404233 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | keeler |
bugs | 1183822 |
milestone | 42.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/security/certverifier/NSSCertDBTrustDomain.cpp +++ b/security/certverifier/NSSCertDBTrustDomain.cpp @@ -5,16 +5,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "NSSCertDBTrustDomain.h" #include <stdint.h> #include "ExtendedValidation.h" #include "OCSPRequestor.h" +#include "OCSPVerificationTrustDomain.h" #include "certdb.h" #include "cert.h" #include "mozilla/UniquePtr.h" #include "nsNSSCertificate.h" #include "nss.h" #include "NSSErrorsService.h" #include "nsServiceManagerUtils.h" #include "pk11pub.h" @@ -633,17 +634,27 @@ NSSCertDBTrustDomain::CheckRevocation(En Result NSSCertDBTrustDomain::VerifyAndMaybeCacheEncodedOCSPResponse( const CertID& certID, Time time, uint16_t maxLifetimeInDays, Input encodedResponse, EncodedResponseSource responseSource, /*out*/ bool& expired) { Time thisUpdate(Time::uninitialized); Time validThrough(Time::uninitialized); - Result rv = VerifyEncodedOCSPResponse(*this, certID, time, + + // We use a try and fallback approach which first mandates good signature + // digest algorithms, then falls back to SHA-1 if this fails. If a delegated + // OCSP response signing certificate was issued with a SHA-1 signature, + // verification initially fails. We cache the failure and then re-use that + // result even when doing fallback (i.e. when weak signature digest algorithms + // should succeed). To address this we use an OCSPVerificationTrustDomain + // here, rather than using *this, to ensure verification succeeds for all + // allowed signature digest algorithms. + OCSPVerificationTrustDomain trustDomain(*this); + Result rv = VerifyEncodedOCSPResponse(trustDomain, certID, time, maxLifetimeInDays, encodedResponse, expired, &thisUpdate, &validThrough); // If a response was stapled and expired, we don't want to cache it. Return // early to simplify the logic here. if (responseSource == ResponseWasStapled && expired) { PR_ASSERT(rv != Success); return rv; }
new file mode 100644 --- /dev/null +++ b/security/certverifier/OCSPVerificationTrustDomain.cpp @@ -0,0 +1,110 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "OCSPVerificationTrustDomain.h" + +using namespace mozilla; +using namespace mozilla::pkix; + +OCSPVerificationTrustDomain::OCSPVerificationTrustDomain( + NSSCertDBTrustDomain& certDBTrustDomain) + : mCertDBTrustDomain(certDBTrustDomain) +{ +} + +Result +OCSPVerificationTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA, + const CertPolicyId& policy, + Input candidateCertDER, + /*out*/ TrustLevel& trustLevel) +{ + return mCertDBTrustDomain.GetCertTrust(endEntityOrCA, policy, + candidateCertDER, trustLevel); +} + + +Result +OCSPVerificationTrustDomain::FindIssuer(Input, IssuerChecker&, Time) +{ + // We do not expect this to be called for OCSP signers + return Result::FATAL_ERROR_LIBRARY_FAILURE; +} + +Result +OCSPVerificationTrustDomain::IsChainValid(const DERArray&, Time) +{ + // We do not expect this to be called for OCSP signers + return Result::FATAL_ERROR_LIBRARY_FAILURE; +} + +Result +OCSPVerificationTrustDomain::CheckRevocation(EndEntityOrCA, const CertID&, + Time, Duration, const Input*, + const Input*) +{ + // We do not expect this to be called for OCSP signers + return Result::FATAL_ERROR_LIBRARY_FAILURE; +} + +Result +OCSPVerificationTrustDomain::CheckSignatureDigestAlgorithm( + DigestAlgorithm aAlg, EndEntityOrCA aEEOrCA) +{ + // The reason for wrapping the NSSCertDBTrustDomain in an + // OCSPVerificationTrustDomain is to allow us to bypass the weaker signature + // algorithm check - thus all allowable signature digest algorithms should + // always be accepted. This is only needed while we gather telemetry on SHA-1. + return Success; +} + +Result +OCSPVerificationTrustDomain::CheckRSAPublicKeyModulusSizeInBits( + EndEntityOrCA aEEOrCA, unsigned int aModulusSizeInBits) +{ + return mCertDBTrustDomain. + CheckRSAPublicKeyModulusSizeInBits(aEEOrCA, aModulusSizeInBits); +} + +Result +OCSPVerificationTrustDomain::VerifyRSAPKCS1SignedDigest( + const SignedDigest& aSignedDigest, Input aSubjectPublicKeyInfo) +{ + return mCertDBTrustDomain.VerifyRSAPKCS1SignedDigest(aSignedDigest, + aSubjectPublicKeyInfo); +} + +Result +OCSPVerificationTrustDomain::CheckECDSACurveIsAcceptable( + EndEntityOrCA aEEOrCA, NamedCurve aCurve) +{ + return mCertDBTrustDomain.CheckECDSACurveIsAcceptable(aEEOrCA, aCurve); +} + +Result +OCSPVerificationTrustDomain::VerifyECDSASignedDigest( + const SignedDigest& aSignedDigest, Input aSubjectPublicKeyInfo) +{ + return mCertDBTrustDomain.VerifyECDSASignedDigest(aSignedDigest, + aSubjectPublicKeyInfo); +} + +Result +OCSPVerificationTrustDomain::CheckValidityIsAcceptable( + Time notBefore, Time notAfter, EndEntityOrCA endEntityOrCA, + KeyPurposeId keyPurpose) +{ + return mCertDBTrustDomain.CheckValidityIsAcceptable(notBefore, notAfter, + endEntityOrCA, + keyPurpose); +} + +Result +OCSPVerificationTrustDomain::DigestBuf( + Input item, DigestAlgorithm digestAlg, + /*out*/ uint8_t* digestBuf, size_t digestBufLen) +{ + return mCertDBTrustDomain.DigestBuf(item, digestAlg, digestBuf, digestBufLen); +}
new file mode 100644 --- /dev/null +++ b/security/certverifier/OCSPVerificationTrustDomain.h @@ -0,0 +1,79 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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__OCSPVerificationTrustDomain_h +#define mozilla_psm__OCSPVerificationTrustDomain_h + +#include "pkix/pkixtypes.h" +#include "NSSCertDBTrustDomain.h" + +namespace mozilla { namespace psm { + +class OCSPVerificationTrustDomain : public mozilla::pkix::TrustDomain +{ +public: + OCSPVerificationTrustDomain(NSSCertDBTrustDomain& certDBTrustDomain); + + virtual Result FindIssuer(mozilla::pkix::Input encodedIssuerName, + IssuerChecker& checker, + mozilla::pkix::Time time) override; + + virtual Result GetCertTrust(mozilla::pkix::EndEntityOrCA endEntityOrCA, + const mozilla::pkix::CertPolicyId& policy, + mozilla::pkix::Input candidateCertDER, + /*out*/ mozilla::pkix::TrustLevel& trustLevel) + override; + + virtual Result CheckSignatureDigestAlgorithm( + mozilla::pkix::DigestAlgorithm digestAlg, + mozilla::pkix::EndEntityOrCA endEntityOrCA) override; + + virtual Result CheckRSAPublicKeyModulusSizeInBits( + mozilla::pkix::EndEntityOrCA endEntityOrCA, + unsigned int modulusSizeInBits) override; + + virtual Result VerifyRSAPKCS1SignedDigest( + const mozilla::pkix::SignedDigest& signedDigest, + mozilla::pkix::Input subjectPublicKeyInfo) override; + + virtual Result CheckECDSACurveIsAcceptable( + mozilla::pkix::EndEntityOrCA endEntityOrCA, + mozilla::pkix::NamedCurve curve) override; + + virtual Result VerifyECDSASignedDigest( + const mozilla::pkix::SignedDigest& signedDigest, + mozilla::pkix::Input subjectPublicKeyInfo) override; + + virtual Result DigestBuf(mozilla::pkix::Input item, + mozilla::pkix::DigestAlgorithm digestAlg, + /*out*/ uint8_t* digestBuf, + size_t digestBufLen) override; + + virtual Result CheckValidityIsAcceptable( + mozilla::pkix::Time notBefore, mozilla::pkix::Time notAfter, + mozilla::pkix::EndEntityOrCA endEntityOrCA, + mozilla::pkix::KeyPurposeId keyPurpose) override; + + virtual Result CheckRevocation( + mozilla::pkix::EndEntityOrCA endEntityOrCA, + const mozilla::pkix::CertID& certID, + mozilla::pkix::Time time, + mozilla::pkix::Duration validityDuration, + /*optional*/ const mozilla::pkix::Input* stapledOCSPResponse, + /*optional*/ const mozilla::pkix::Input* aiaExtension) + override; + + virtual Result IsChainValid(const mozilla::pkix::DERArray& certChain, + mozilla::pkix::Time time) override; + +private: + NSSCertDBTrustDomain& mCertDBTrustDomain; +}; + + +} } // namespace mozilla::psm + +#endif // mozilla_psm__OCSPVerificationTrustDomain_h
--- a/security/certverifier/moz.build +++ b/security/certverifier/moz.build @@ -9,16 +9,17 @@ EXPORTS += [ 'OCSPCache.h', ] UNIFIED_SOURCES += [ 'CertVerifier.cpp', 'NSSCertDBTrustDomain.cpp', 'OCSPCache.cpp', 'OCSPRequestor.cpp', + 'OCSPVerificationTrustDomain.cpp', ] if not CONFIG['NSS_NO_EV_CERTS']: UNIFIED_SOURCES += [ 'ExtendedValidation.cpp', ] LOCAL_INCLUDES += [