--- a/netwerk/base/security-prefs.js
+++ b/netwerk/base/security-prefs.js
@@ -63,15 +63,27 @@ pref("security.pki.sha1_enforcement_leve
// August 2015 if necessary
// 3: only use name information from the subject alternative name extension
#ifdef RELEASE_BUILD
pref("security.pki.name_matching_mode", 1);
#else
pref("security.pki.name_matching_mode", 2);
#endif
+// security.pki.netscape_step_up_policy controls how the platform handles the
+// id-Netscape-stepUp OID in extended key usage extensions of CA certificates.
+// 0: id-Netscape-stepUp is always considered equivalent to id-kp-serverAuth
+// 1: it is considered equivalent when the notBefore is before 23 August 2016
+// 2: similarly, but for 23 August 2015
+// 3: it is never considered equivalent
+#ifdef RELEASE_BUILD
+pref("security.pki.netscape_step_up_policy", 1);
+#else
+pref("security.pki.netscape_step_up_policy", 2);
+#endif
+
pref("security.webauth.u2f", false);
pref("security.webauth.u2f_enable_softtoken", false);
pref("security.webauth.u2f_enable_usbtoken", false);
pref("security.ssl.errorReporting.enabled", true);
pref("security.ssl.errorReporting.url", "https://data.mozilla.com/submit/sslreports");
pref("security.ssl.errorReporting.automatic", false);
--- a/security/apps/AppTrustDomain.cpp
+++ b/security/apps/AppTrustDomain.cpp
@@ -363,9 +363,17 @@ AppTrustDomain::VerifyECDSASignedDigest(
Result
AppTrustDomain::CheckValidityIsAcceptable(Time /*notBefore*/, Time /*notAfter*/,
EndEntityOrCA /*endEntityOrCA*/,
KeyPurposeId /*keyPurpose*/)
{
return Success;
}
+Result
+AppTrustDomain::NetscapeStepUpMatchesServerAuth(Time /*notBefore*/,
+ /*out*/ bool& matches)
+{
+ matches = false;
+ return Success;
+}
+
} } // namespace mozilla::psm
--- a/security/apps/AppTrustDomain.h
+++ b/security/apps/AppTrustDomain.h
@@ -56,16 +56,19 @@ public:
mozilla::pkix::NamedCurve curve) override;
virtual Result VerifyECDSASignedDigest(
const mozilla::pkix::SignedDigest& signedDigest,
mozilla::pkix::Input subjectPublicKeyInfo) override;
virtual Result CheckValidityIsAcceptable(
mozilla::pkix::Time notBefore, mozilla::pkix::Time notAfter,
mozilla::pkix::EndEntityOrCA endEntityOrCA,
mozilla::pkix::KeyPurposeId keyPurpose) override;
+ virtual Result NetscapeStepUpMatchesServerAuth(
+ mozilla::pkix::Time notBefore,
+ /*out*/ bool& matches) override;
virtual Result DigestBuf(mozilla::pkix::Input item,
mozilla::pkix::DigestAlgorithm digestAlg,
/*out*/ uint8_t* digestBuf,
size_t digestBufLen) override;
private:
/*out*/ UniqueCERTCertList& mCertChain;
void* mPinArg; // non-owning!
--- a/security/certverifier/CertVerifier.cpp
+++ b/security/certverifier/CertVerifier.cpp
@@ -35,24 +35,26 @@ const CertVerifier::Flags CertVerifier::
const CertVerifier::Flags CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST = 4;
CertVerifier::CertVerifier(OcspDownloadConfig odc,
OcspStrictConfig osc,
OcspGetConfig ogc,
uint32_t certShortLifetimeInDays,
PinningMode pinningMode,
SHA1Mode sha1Mode,
- BRNameMatchingPolicy::Mode nameMatchingMode)
+ BRNameMatchingPolicy::Mode nameMatchingMode,
+ NetscapeStepUpPolicy netscapeStepUpPolicy)
: mOCSPDownloadConfig(odc)
, mOCSPStrict(osc == ocspStrict)
, mOCSPGETEnabled(ogc == ocspGetEnabled)
, mCertShortLifetimeInDays(certShortLifetimeInDays)
, mPinningMode(pinningMode)
, mSHA1Mode(sha1Mode)
, mNameMatchingMode(nameMatchingMode)
+ , mNetscapeStepUpPolicy(netscapeStepUpPolicy)
{
}
CertVerifier::~CertVerifier()
{
}
void
@@ -268,18 +270,19 @@ CertVerifier::VerifyCert(CERTCertificate
case certificateUsageSSLClient: {
// XXX: We don't really have a trust bit for SSL client authentication so
// just use trustEmail as it is the closest alternative.
NSSCertDBTrustDomain trustDomain(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
- SHA1Mode::Allowed, builtChain, nullptr,
- nullptr);
+ SHA1Mode::Allowed,
+ NetscapeStepUpPolicy::NeverMatch,
+ builtChain, nullptr, nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity,
KeyUsage::digitalSignature,
KeyPurposeId::id_kp_clientAuth,
CertPolicyId::anyPolicy, stapledOCSPResponse);
break;
}
@@ -342,18 +345,18 @@ CertVerifier::VerifyCert(CERTCertificate
pinningTelemetryInfo->Reset();
}
NSSCertDBTrustDomain
trustDomain(trustSSL, evOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays, mPinningMode, MIN_RSA_BITS,
ValidityCheckingMode::CheckForEV,
- sha1ModeConfigurations[i], builtChain,
- pinningTelemetryInfo, hostname);
+ sha1ModeConfigurations[i], mNetscapeStepUpPolicy,
+ builtChain, pinningTelemetryInfo, hostname);
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
KeyUsage::digitalSignature,// (EC)DHE
KeyUsage::keyEncipherment, // RSA
KeyUsage::keyAgreement, // (EC)DH
KeyPurposeId::id_kp_serverAuth,
evPolicy, stapledOCSPResponse,
ocspStaplingStatus);
// If we succeeded with the SHA1Mode of only allowing imported roots to
@@ -433,18 +436,18 @@ CertVerifier::VerifyCert(CERTCertificate
}
NSSCertDBTrustDomain trustDomain(trustSSL, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
mPinningMode, keySizeOptions[i],
ValidityCheckingMode::CheckingOff,
sha1ModeConfigurations[j],
- builtChain, pinningTelemetryInfo,
- hostname);
+ mNetscapeStepUpPolicy, builtChain,
+ pinningTelemetryInfo, hostname);
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
KeyUsage::digitalSignature,//(EC)DHE
KeyUsage::keyEncipherment,//RSA
KeyUsage::keyAgreement,//(EC)DH
KeyPurposeId::id_kp_serverAuth,
CertPolicyId::anyPolicy,
stapledOCSPResponse,
ocspStaplingStatus);
@@ -497,32 +500,34 @@ CertVerifier::VerifyCert(CERTCertificate
}
case certificateUsageSSLCA: {
NSSCertDBTrustDomain trustDomain(trustSSL, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
- mSHA1Mode, builtChain, nullptr, nullptr);
+ mSHA1Mode, mNetscapeStepUpPolicy,
+ builtChain, nullptr, nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeCA, KeyUsage::keyCertSign,
KeyPurposeId::id_kp_serverAuth,
CertPolicyId::anyPolicy, stapledOCSPResponse);
break;
}
case certificateUsageEmailSigner: {
NSSCertDBTrustDomain trustDomain(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
- SHA1Mode::Allowed, builtChain, nullptr,
- nullptr);
+ SHA1Mode::Allowed,
+ NetscapeStepUpPolicy::NeverMatch,
+ builtChain, nullptr, nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity,
KeyUsage::digitalSignature,
KeyPurposeId::id_kp_emailProtection,
CertPolicyId::anyPolicy, stapledOCSPResponse);
if (rv == Result::ERROR_INADEQUATE_KEY_USAGE) {
rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity,
@@ -537,18 +542,19 @@ CertVerifier::VerifyCert(CERTCertificate
// TODO: The higher level S/MIME processing should pass in which key
// usage it is trying to verify for, and base its algorithm choices
// based on the result of the verification(s).
NSSCertDBTrustDomain trustDomain(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
- SHA1Mode::Allowed, builtChain, nullptr,
- nullptr);
+ SHA1Mode::Allowed,
+ NetscapeStepUpPolicy::NeverMatch,
+ builtChain, nullptr, nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity,
KeyUsage::keyEncipherment, // RSA
KeyPurposeId::id_kp_emailProtection,
CertPolicyId::anyPolicy, stapledOCSPResponse);
if (rv == Result::ERROR_INADEQUATE_KEY_USAGE) {
rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity,
@@ -560,18 +566,19 @@ CertVerifier::VerifyCert(CERTCertificate
}
case certificateUsageObjectSigner: {
NSSCertDBTrustDomain trustDomain(trustObjectSigning, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
- SHA1Mode::Allowed, builtChain, nullptr,
- nullptr);
+ SHA1Mode::Allowed,
+ NetscapeStepUpPolicy::NeverMatch,
+ builtChain, nullptr, nullptr);
rv = BuildCertChain(trustDomain, certDER, time,
EndEntityOrCA::MustBeEndEntity,
KeyUsage::digitalSignature,
KeyPurposeId::id_kp_codeSigning,
CertPolicyId::anyPolicy, stapledOCSPResponse);
break;
}
@@ -592,42 +599,45 @@ CertVerifier::VerifyCert(CERTCertificate
keyUsage = KeyUsage::digitalSignature;
eku = KeyPurposeId::id_kp_OCSPSigning;
}
NSSCertDBTrustDomain sslTrust(trustSSL, defaultOCSPFetching, mOCSPCache,
pinArg, ocspGETConfig, mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
- SHA1Mode::Allowed, builtChain, nullptr,
- nullptr);
+ SHA1Mode::Allowed,
+ NetscapeStepUpPolicy::NeverMatch,
+ builtChain, nullptr, nullptr);
rv = BuildCertChain(sslTrust, certDER, time, endEntityOrCA,
keyUsage, eku, CertPolicyId::anyPolicy,
stapledOCSPResponse);
if (rv == Result::ERROR_UNKNOWN_ISSUER) {
NSSCertDBTrustDomain emailTrust(trustEmail, defaultOCSPFetching,
mOCSPCache, pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled, MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
- SHA1Mode::Allowed, builtChain, nullptr,
- nullptr);
+ SHA1Mode::Allowed,
+ NetscapeStepUpPolicy::NeverMatch,
+ builtChain, nullptr, nullptr);
rv = BuildCertChain(emailTrust, certDER, time, endEntityOrCA,
keyUsage, eku, CertPolicyId::anyPolicy,
stapledOCSPResponse);
if (rv == Result::ERROR_UNKNOWN_ISSUER) {
NSSCertDBTrustDomain objectSigningTrust(trustObjectSigning,
defaultOCSPFetching, mOCSPCache,
pinArg, ocspGETConfig,
mCertShortLifetimeInDays,
pinningDisabled,
MIN_RSA_BITS_WEAK,
ValidityCheckingMode::CheckingOff,
- SHA1Mode::Allowed, builtChain,
- nullptr, nullptr);
+ SHA1Mode::Allowed,
+ NetscapeStepUpPolicy::NeverMatch,
+ builtChain, nullptr, nullptr);
rv = BuildCertChain(objectSigningTrust, certDER, time,
endEntityOrCA, keyUsage, eku,
CertPolicyId::anyPolicy, stapledOCSPResponse);
}
}
break;
}
--- a/security/certverifier/CertVerifier.h
+++ b/security/certverifier/CertVerifier.h
@@ -28,16 +28,18 @@ enum class SHA1ModeResult {
NeverChecked = 0,
SucceededWithoutSHA1 = 1,
SucceededWithSHA1Before2016 = 2,
SucceededWithImportedRoot = 3,
SucceededWithSHA1 = 4,
Failed = 5,
};
+enum class NetscapeStepUpPolicy : uint32_t;
+
class PinningTelemetryInfo
{
public:
// Should we accumulate pinning telemetry for the result?
bool accumulateResult;
Telemetry::ID certPinningResultHistogram;
int32_t certPinningResultBucket;
// Should we accumulate telemetry for the root?
@@ -118,28 +120,30 @@ public:
ocspEVOnly = 2
};
enum OcspStrictConfig { ocspRelaxed = 0, ocspStrict };
enum OcspGetConfig { ocspGetDisabled = 0, ocspGetEnabled = 1 };
CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
PinningMode pinningMode, SHA1Mode sha1Mode,
- BRNameMatchingPolicy::Mode nameMatchingMode);
+ BRNameMatchingPolicy::Mode nameMatchingMode,
+ NetscapeStepUpPolicy netscapeStepUpPolicy);
~CertVerifier();
void ClearOCSPCache() { mOCSPCache.Clear(); }
const OcspDownloadConfig mOCSPDownloadConfig;
const bool mOCSPStrict;
const bool mOCSPGETEnabled;
const uint32_t mCertShortLifetimeInDays;
const PinningMode mPinningMode;
const SHA1Mode mSHA1Mode;
const BRNameMatchingPolicy::Mode mNameMatchingMode;
+ const NetscapeStepUpPolicy mNetscapeStepUpPolicy;
private:
OCSPCache mOCSPCache;
// Returns true if the configured SHA1 mode is more restrictive than the given
// mode. SHA1Mode::Forbidden is more restrictive than any other mode except
// Forbidden. Next is Before2016, then ImportedRoot, then Allowed.
// (A mode is never more restrictive than itself.)
--- a/security/certverifier/NSSCertDBTrustDomain.cpp
+++ b/security/certverifier/NSSCertDBTrustDomain.cpp
@@ -47,29 +47,31 @@ NSSCertDBTrustDomain::NSSCertDBTrustDoma
OCSPCache& ocspCache,
/*optional but shouldn't be*/ void* pinArg,
CertVerifier::OcspGetConfig ocspGETConfig,
uint32_t certShortLifetimeInDays,
CertVerifier::PinningMode pinningMode,
unsigned int minRSABits,
ValidityCheckingMode validityCheckingMode,
CertVerifier::SHA1Mode sha1Mode,
+ NetscapeStepUpPolicy netscapeStepUpPolicy,
UniqueCERTCertList& builtChain,
/*optional*/ PinningTelemetryInfo* pinningTelemetryInfo,
/*optional*/ const char* hostname)
: mCertDBTrustType(certDBTrustType)
, mOCSPFetching(ocspFetching)
, mOCSPCache(ocspCache)
, mPinArg(pinArg)
, mOCSPGetConfig(ocspGETConfig)
, mCertShortLifetimeInDays(certShortLifetimeInDays)
, mPinningMode(pinningMode)
, mMinRSABits(minRSABits)
, mValidityCheckingMode(validityCheckingMode)
, mSHA1Mode(sha1Mode)
+ , mNetscapeStepUpPolicy(netscapeStepUpPolicy)
, mBuiltChain(builtChain)
, mPinningTelemetryInfo(pinningTelemetryInfo)
, mHostname(hostname)
, mCertBlocklist(do_GetService(NS_CERTBLOCKLIST_CONTRACTID))
, mOCSPStaplingStatus(CertVerifier::OCSP_STAPLING_NEVER_CHECKED)
{
}
@@ -923,16 +925,44 @@ NSSCertDBTrustDomain::CheckValidityIsAcc
if (validityDuration > maxValidityDuration) {
return Result::ERROR_VALIDITY_TOO_LONG;
}
return Success;
}
+Result
+NSSCertDBTrustDomain::NetscapeStepUpMatchesServerAuth(Time notBefore,
+ /*out*/ bool& matches)
+{
+ // (new Date("2015-08-23T00:00:00Z")).getTime() / 1000
+ static const Time AUGUST_23_2015 = TimeFromEpochInSeconds(1440288000);
+ // (new Date("2016-08-23T00:00:00Z")).getTime() / 1000
+ static const Time AUGUST_23_2016 = TimeFromEpochInSeconds(1471910400);
+
+ switch (mNetscapeStepUpPolicy) {
+ case NetscapeStepUpPolicy::AlwaysMatch:
+ matches = true;
+ return Success;
+ case NetscapeStepUpPolicy::MatchBefore23August2016:
+ matches = notBefore < AUGUST_23_2016;
+ return Success;
+ case NetscapeStepUpPolicy::MatchBefore23August2015:
+ matches = notBefore < AUGUST_23_2015;
+ return Success;
+ case NetscapeStepUpPolicy::NeverMatch:
+ matches = false;
+ return Success;
+ default:
+ MOZ_ASSERT_UNREACHABLE("unhandled NetscapeStepUpPolicy type");
+ }
+ return Result::FATAL_ERROR_LIBRARY_FAILURE;
+}
+
namespace {
static char*
nss_addEscape(const char* string, char quote)
{
char* newString = 0;
size_t escapes = 0, size = 0;
const char* src;
--- a/security/certverifier/NSSCertDBTrustDomain.h
+++ b/security/certverifier/NSSCertDBTrustDomain.h
@@ -16,16 +16,30 @@
namespace mozilla { namespace psm {
enum class ValidityCheckingMode {
CheckingOff = 0,
CheckForEV = 1,
};
+// Policy options for matching id-Netscape-stepUp with id-kp-serverAuth (for CA
+// certificates only):
+// * Always match: the step-up OID is considered equivalent to serverAuth
+// * Match before 23 August 2016: the OID is considered equivalent if the
+// certificate's notBefore is before 23 August 2016
+// * Match before 23 August 2015: similarly, but for 23 August 2015
+// * Never match: the OID is never considered equivalent to serverAuth
+enum class NetscapeStepUpPolicy : uint32_t {
+ AlwaysMatch = 0,
+ MatchBefore23August2016 = 1,
+ MatchBefore23August2015 = 2,
+ NeverMatch = 3,
+};
+
SECStatus InitializeNSS(const char* dir, bool readOnly, bool loadPKCS11Modules);
void DisableMD5();
extern const char BUILTIN_ROOTS_MODULE_DEFAULT_NAME[];
// The dir parameter is the path to the directory containing the NSS builtin
// roots module. Usually this is the same as the path to the other NSS shared
@@ -60,16 +74,17 @@ public:
NSSCertDBTrustDomain(SECTrustType certDBTrustType, OCSPFetching ocspFetching,
OCSPCache& ocspCache, void* pinArg,
CertVerifier::OcspGetConfig ocspGETConfig,
uint32_t certShortLifetimeInDays,
CertVerifier::PinningMode pinningMode,
unsigned int minRSABits,
ValidityCheckingMode validityCheckingMode,
CertVerifier::SHA1Mode sha1Mode,
+ NetscapeStepUpPolicy netscapeStepUpPolicy,
UniqueCERTCertList& builtChain,
/*optional*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
/*optional*/ const char* hostname = nullptr);
virtual Result FindIssuer(mozilla::pkix::Input encodedIssuerName,
IssuerChecker& checker,
mozilla::pkix::Time time) override;
@@ -105,16 +120,20 @@ public:
/*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 NetscapeStepUpMatchesServerAuth(
+ mozilla::pkix::Time notBefore,
+ /*out*/ bool& matches) 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;
@@ -146,16 +165,17 @@ private:
OCSPCache& mOCSPCache; // non-owning!
void* mPinArg; // non-owning!
const CertVerifier::OcspGetConfig mOCSPGetConfig;
const uint32_t mCertShortLifetimeInDays;
CertVerifier::PinningMode mPinningMode;
const unsigned int mMinRSABits;
ValidityCheckingMode mValidityCheckingMode;
CertVerifier::SHA1Mode mSHA1Mode;
+ NetscapeStepUpPolicy mNetscapeStepUpPolicy;
UniqueCERTCertList& mBuiltChain; // non-owning
PinningTelemetryInfo* mPinningTelemetryInfo;
const char* mHostname; // non-owning - only used for pinning checks
nsCOMPtr<nsICertBlocklist> mCertBlocklist;
CertVerifier::OCSPStaplingStatus mOCSPStaplingStatus;
};
} } // namespace mozilla::psm
--- a/security/certverifier/OCSPVerificationTrustDomain.cpp
+++ b/security/certverifier/OCSPVerificationTrustDomain.cpp
@@ -97,14 +97,21 @@ OCSPVerificationTrustDomain::CheckValidi
KeyPurposeId keyPurpose)
{
return mCertDBTrustDomain.CheckValidityIsAcceptable(notBefore, notAfter,
endEntityOrCA,
keyPurpose);
}
Result
+OCSPVerificationTrustDomain::NetscapeStepUpMatchesServerAuth(Time notBefore,
+ /*out*/ bool& matches)
+{
+ return mCertDBTrustDomain.NetscapeStepUpMatchesServerAuth(notBefore, matches);
+}
+
+Result
OCSPVerificationTrustDomain::DigestBuf(
Input item, DigestAlgorithm digestAlg,
/*out*/ uint8_t* digestBuf, size_t digestBufLen)
{
return mCertDBTrustDomain.DigestBuf(item, digestAlg, digestBuf, digestBufLen);
}
--- a/security/certverifier/OCSPVerificationTrustDomain.h
+++ b/security/certverifier/OCSPVerificationTrustDomain.h
@@ -53,16 +53,19 @@ public:
/*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 NetscapeStepUpMatchesServerAuth(mozilla::pkix::Time notBefore,
+ /*out*/ bool& matches) 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;
--- a/security/manager/ssl/CSTrustDomain.cpp
+++ b/security/manager/ssl/CSTrustDomain.cpp
@@ -203,15 +203,23 @@ Result
CSTrustDomain::CheckValidityIsAcceptable(Time notBefore, Time notAfter,
EndEntityOrCA endEntityOrCA,
KeyPurposeId keyPurpose)
{
return Success;
}
Result
+CSTrustDomain::NetscapeStepUpMatchesServerAuth(Time notBefore,
+ /*out*/ bool& matches)
+{
+ matches = false;
+ return Success;
+}
+
+Result
CSTrustDomain::DigestBuf(Input item, DigestAlgorithm digestAlg,
/*out*/ uint8_t* digestBuf, size_t digestBufLen)
{
return DigestBufNSS(item, digestAlg, digestBuf, digestBufLen);
}
} } // end namespace mozilla::psm
--- a/security/manager/ssl/CSTrustDomain.h
+++ b/security/manager/ssl/CSTrustDomain.h
@@ -55,16 +55,18 @@ public:
mozilla::pkix::NamedCurve curve) override;
virtual Result VerifyECDSASignedDigest(
const mozilla::pkix::SignedDigest& signedDigest,
mozilla::pkix::Input subjectPublicKeyInfo) override;
virtual Result CheckValidityIsAcceptable(
mozilla::pkix::Time notBefore, mozilla::pkix::Time notAfter,
mozilla::pkix::EndEntityOrCA endEntityOrCA,
mozilla::pkix::KeyPurposeId keyPurpose) override;
+ virtual Result NetscapeStepUpMatchesServerAuth(
+ mozilla::pkix::Time notBefore, /*out*/ bool& matches) override;
virtual Result DigestBuf(mozilla::pkix::Input item,
mozilla::pkix::DigestAlgorithm digestAlg,
/*out*/ uint8_t* digestBuf,
size_t digestBufLen) override;
private:
/*out*/ UniqueCERTCertList& mCertChain;
nsCOMPtr<nsICertBlocklist> mCertBlocklist;
--- a/security/manager/ssl/SharedCertVerifier.h
+++ b/security/manager/ssl/SharedCertVerifier.h
@@ -1,34 +1,35 @@
/* 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__SharedCertVerifier_h
-#define mozilla_psm__SharedCertVerifier_h
+#ifndef SharedCertVerifier_h
+#define SharedCertVerifier_h
-#include "certt.h"
#include "CertVerifier.h"
#include "mozilla/RefPtr.h"
namespace mozilla { namespace psm {
class SharedCertVerifier : public mozilla::psm::CertVerifier
{
protected:
~SharedCertVerifier();
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedCertVerifier)
SharedCertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
PinningMode pinningMode, SHA1Mode sha1Mode,
- BRNameMatchingPolicy::Mode nameMatchingMode)
+ BRNameMatchingPolicy::Mode nameMatchingMode,
+ NetscapeStepUpPolicy netscapeStepUpPolicy)
: mozilla::psm::CertVerifier(odc, osc, ogc, certShortLifetimeInDays,
- pinningMode, sha1Mode, nameMatchingMode)
+ pinningMode, sha1Mode, nameMatchingMode,
+ netscapeStepUpPolicy)
{
}
};
} } // namespace mozilla::psm
-#endif // mozilla_psm__SharedCertVerifier_h
+#endif // SharedCertVerifier_h
--- a/security/manager/ssl/nsNSSComponent.cpp
+++ b/security/manager/ssl/nsNSSComponent.cpp
@@ -1343,27 +1343,43 @@ void nsNSSComponent::setValidationOption
case BRNameMatchingPolicy::Mode::EnforceAfter23August2016:
case BRNameMatchingPolicy::Mode::DoNotEnforce:
break;
default:
nameMatchingMode = BRNameMatchingPolicy::Mode::DoNotEnforce;
break;
}
+ NetscapeStepUpPolicy netscapeStepUpPolicy =
+ static_cast<NetscapeStepUpPolicy>
+ (Preferences::GetUint("security.pki.netscape_step_up_policy",
+ static_cast<uint32_t>(NetscapeStepUpPolicy::AlwaysMatch)));
+ switch (netscapeStepUpPolicy) {
+ case NetscapeStepUpPolicy::AlwaysMatch:
+ case NetscapeStepUpPolicy::MatchBefore23August2016:
+ case NetscapeStepUpPolicy::MatchBefore23August2015:
+ case NetscapeStepUpPolicy::NeverMatch:
+ break;
+ default:
+ netscapeStepUpPolicy = NetscapeStepUpPolicy::AlwaysMatch;
+ break;
+ }
+
CertVerifier::OcspDownloadConfig odc;
CertVerifier::OcspStrictConfig osc;
CertVerifier::OcspGetConfig ogc;
uint32_t certShortLifetimeInDays;
GetRevocationBehaviorFromPrefs(&odc, &osc, &ogc, &certShortLifetimeInDays,
lock);
mDefaultCertVerifier = new SharedCertVerifier(odc, osc, ogc,
certShortLifetimeInDays,
pinningMode, sha1Mode,
- nameMatchingMode);
+ nameMatchingMode,
+ netscapeStepUpPolicy);
}
// Enable the TLS versions given in the prefs, defaulting to TLS 1.0 (min) and
// TLS 1.2 (max) when the prefs aren't set or set to invalid values.
nsresult
nsNSSComponent::setEnabledTLSVersions()
{
// keep these values in sync with security-prefs.js
@@ -1746,17 +1762,18 @@ nsNSSComponent::Observe(nsISupports* aSu
} else if (prefName.EqualsLiteral("security.OCSP.enabled") ||
prefName.EqualsLiteral("security.OCSP.require") ||
prefName.EqualsLiteral("security.OCSP.GET.enabled") ||
prefName.EqualsLiteral("security.pki.cert_short_lifetime_in_days") ||
prefName.EqualsLiteral("security.ssl.enable_ocsp_stapling") ||
prefName.EqualsLiteral("security.ssl.enable_ocsp_must_staple") ||
prefName.EqualsLiteral("security.cert_pinning.enforcement_level") ||
prefName.EqualsLiteral("security.pki.sha1_enforcement_level") ||
- prefName.EqualsLiteral("security.pki.name_matching_mode")) {
+ prefName.EqualsLiteral("security.pki.name_matching_mode") ||
+ prefName.EqualsLiteral("security.pki.netscape_step_up_policy")) {
MutexAutoLock lock(mutex);
setValidationOptions(false, lock);
#ifdef DEBUG
} else if (prefName.EqualsLiteral("security.test.built_in_root_hash")) {
MutexAutoLock lock(mutex);
mTestBuiltInRootHash = Preferences::GetString("security.test.built_in_root_hash");
#endif // DEBUG
} else if (prefName.Equals(kFamilySafetyModePref)) {
--- a/security/manager/ssl/tests/unit/test_cert_eku.js
+++ b/security/manager/ssl/tests/unit/test_cert_eku.js
@@ -21,31 +21,53 @@ function certFromFile(certName) {
function loadCertWithTrust(certName, trustString) {
addCertFromFile(certdb, `test_cert_eku/${certName}.pem`, trustString);
}
function checkEndEntity(cert, expectedResult) {
checkCertErrorGeneric(certdb, cert, expectedResult, certificateUsageSSLServer);
}
+function checkCertOn25August2016(cert, expectedResult) {
+ // (new Date("2016-08-25T00:00:00Z")).getTime() / 1000
+ const VALIDATION_TIME = 1472083200;
+ checkCertErrorGenericAtTime(certdb, cert, expectedResult,
+ certificateUsageSSLServer, VALIDATION_TIME);
+}
+
function run_test() {
loadCertWithTrust("ca", "CTu,,");
// end-entity has id-kp-serverAuth => success
checkEndEntity(certFromFile("ee-SA"), PRErrorCodeSuccess);
// end-entity has id-kp-serverAuth => success
checkEndEntity(certFromFile("ee-SA-CA"), PRErrorCodeSuccess);
// end-entity has extended key usage, but id-kp-serverAuth is not present =>
// failure
checkEndEntity(certFromFile("ee-CA"), SEC_ERROR_INADEQUATE_CERT_TYPE);
// end-entity has id-kp-serverAuth => success
checkEndEntity(certFromFile("ee-SA-nsSGC"), PRErrorCodeSuccess);
+
// end-entity has extended key usage, but id-kp-serverAuth is not present =>
- // failure (in particular, Netscape Server Gated Crypto is not an acceptable
- // substitute for end-entity certificates).
+ // failure (in particular, Netscape Server Gated Crypto (also known as
+ // Netscape Step Up) is not an acceptable substitute for end-entity
+ // certificates).
+ // Verify this for all Netscape Step Up policy configurations.
+ // 0 = "always accept nsSGC in place of serverAuth for CA certificates"
+ Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 0);
checkEndEntity(certFromFile("ee-nsSGC"), SEC_ERROR_INADEQUATE_CERT_TYPE);
+ // 1 = "accept nsSGC before 23 August 2016"
+ Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 1);
+ checkEndEntity(certFromFile("ee-nsSGC"), SEC_ERROR_INADEQUATE_CERT_TYPE);
+ // 2 = "accept nsSGC before 23 August 2015"
+ Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 2);
+ checkEndEntity(certFromFile("ee-nsSGC"), SEC_ERROR_INADEQUATE_CERT_TYPE);
+ // 3 = "never accept nsSGC"
+ Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 3);
+ checkEndEntity(certFromFile("ee-nsSGC"), SEC_ERROR_INADEQUATE_CERT_TYPE);
+
// end-entity has id-kp-OCSPSigning, which is not acceptable for end-entity
// certificates being verified as TLS server certificates => failure
checkEndEntity(certFromFile("ee-SA-OCSP"), SEC_ERROR_INADEQUATE_CERT_TYPE);
// intermediate has id-kp-serverAuth => success
loadCertWithTrust("int-SA", ",,");
checkEndEntity(certFromFile("ee-int-SA"), PRErrorCodeSuccess);
// intermediate has id-kp-serverAuth => success
@@ -53,17 +75,57 @@ function run_test() {
checkEndEntity(certFromFile("ee-int-SA-CA"), PRErrorCodeSuccess);
// intermediate has extended key usage, but id-kp-serverAuth is not present
// => failure
loadCertWithTrust("int-CA", ",,");
checkEndEntity(certFromFile("ee-int-CA"), SEC_ERROR_INADEQUATE_CERT_TYPE);
// intermediate has id-kp-serverAuth => success
loadCertWithTrust("int-SA-nsSGC", ",,");
checkEndEntity(certFromFile("ee-int-SA-nsSGC"), PRErrorCodeSuccess);
- // intermediate has Netscape Server Gated Crypto, which is acceptable for CA
- // certificates only => success
- loadCertWithTrust("int-nsSGC", ",,");
- checkEndEntity(certFromFile("ee-int-nsSGC"), PRErrorCodeSuccess);
+
+ // Intermediate has Netscape Server Gated Crypto. Success will depend on the
+ // Netscape Step Up policy configuration and the notBefore property of the
+ // intermediate.
+ loadCertWithTrust("int-nsSGC-recent", ",,");
+ loadCertWithTrust("int-nsSGC-old", ",,");
+ loadCertWithTrust("int-nsSGC-older", ",,");
+ // 0 = "always accept nsSGC in place of serverAuth for CA certificates"
+ Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 0);
+ do_print("Netscape Step Up policy: always accept");
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-recent"),
+ PRErrorCodeSuccess);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-old"),
+ PRErrorCodeSuccess);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-older"),
+ PRErrorCodeSuccess);
+ // 1 = "accept nsSGC before 23 August 2016"
+ do_print("Netscape Step Up policy: accept before 23 August 2016");
+ Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 1);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-recent"),
+ SEC_ERROR_INADEQUATE_CERT_TYPE);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-old"),
+ PRErrorCodeSuccess);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-older"),
+ PRErrorCodeSuccess);
+ // 2 = "accept nsSGC before 23 August 2015"
+ do_print("Netscape Step Up policy: accept before 23 August 2015");
+ Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 2);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-recent"),
+ SEC_ERROR_INADEQUATE_CERT_TYPE);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-old"),
+ SEC_ERROR_INADEQUATE_CERT_TYPE);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-older"),
+ PRErrorCodeSuccess);
+ // 3 = "never accept nsSGC"
+ do_print("Netscape Step Up policy: never accept");
+ Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 3);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-recent"),
+ SEC_ERROR_INADEQUATE_CERT_TYPE);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-old"),
+ SEC_ERROR_INADEQUATE_CERT_TYPE);
+ checkCertOn25August2016(certFromFile("ee-int-nsSGC-older"),
+ SEC_ERROR_INADEQUATE_CERT_TYPE);
+
// intermediate has id-kp-OCSPSigning, which is acceptable for CA
// certificates => success
loadCertWithTrust("int-SA-OCSP", ",,");
checkEndEntity(certFromFile("ee-int-SA-OCSP"), PRErrorCodeSuccess);
}
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICvzCCAamgAwIBAgIUac/Ua4oKf1WNLQyhgz1UXGbHa8IwCwYJKoZIhvcNAQEL
+MBgxFjAUBgNVBAMMDWludC1uc1NHQy1vbGQwIhgPMjAxNDExMjcwMDAwMDBaGA8y
+MDE3MDIwNDAwMDAwMFowGzEZMBcGA1UEAwwQZWUtaW50LW5zU0dDLW9sZDCCASIw
+DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ
+6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk
+nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N
+/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG
+JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd
+7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA
+ATALBgkqhkiG9w0BAQsDggEBAKUQOZ3Kc6I/onqOl+LcxdQzdYUmncwKAO5+5ESX
+3B+ppoY58JKYbri9iHKQUB5Ou1+XAdtgzF9RtDpFxDbo96FdVSrsNr9lQ5zEKYuk
+INz1z/ht6sJAJSNxXY4uaUjWy5F+ac3JTbO9RDYLyRfUG30yWMisF2Uuw64hHt34
+3lQ070k6wcRLZZR45hb0u+rTR9QZRCWPCAhdSkce/H2OgJGxMa8vDjy9UTtt1UeA
+6H2tb1qB3w39rJdIChFrYt6BjBxcY44eS6kvI6DyexyxSnvQUs/+sDbhijhiE0l3
+NhYCQL8o2VgO34Kl/y+Q36RCALuFmwvgu7iAY1zAQpBIeq4=
+-----END CERTIFICATE-----
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem.certspec
@@ -0,0 +1,2 @@
+issuer:int-nsSGC-old
+subject:ee-int-nsSGC-old
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICwzCCAa2gAwIBAgIUF8YmhmRRcG/xp85wOFjmF8sAV/8wCwYJKoZIhvcNAQEL
+MBoxGDAWBgNVBAMMD2ludC1uc1NHQy1vbGRlcjAiGA8yMDE0MTEyNzAwMDAwMFoY
+DzIwMTcwMjA0MDAwMDAwWjAdMRswGQYDVQQDDBJlZS1pbnQtbnNTR0Mtb2xkZXIw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ
+PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH
+9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw
+4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86
+exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0
+ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N
+AgMBAAEwCwYJKoZIhvcNAQELA4IBAQCt4yp7EPeeT34sLPjLZnJK7fUKHlPFElkH
+0TaJC/nxjN26SZp/Q2g6cNahIC2QWYCfP+OCvtoWM3KIcEWgm1Yg6Oth9KH0A67P
+UUx6D/okrPnJ1UjIVGQk2X0hAwE6cfmmlhdFtdQKhD15QVFFFtoUSufEciA75KDq
+r/8dNTdVIg7pCXSwGalHb7ApiB/W+n32kZKTqflCphbOVadxm/h0DlZeAAInsD73
+r9++L1BL6zY65NAR6XJNnAO2Pkx4+9UylA3gVhgjt9QEX0dSuUp85zxtFNFF8Wsi
+3nUoHbpurXDTz82bqfpgbaoGK69P9LEmrjCLyPXuEeWEWaE1yQbz
+-----END CERTIFICATE-----
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem.certspec
@@ -0,0 +1,2 @@
+issuer:int-nsSGC-older
+subject:ee-int-nsSGC-older
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem
@@ -0,0 +1,17 @@
+-----BEGIN CERTIFICATE-----
+MIICxTCCAa+gAwIBAgIUXQEyALiaoIkVgJ2nLszSUNw6GuMwCwYJKoZIhvcNAQEL
+MBsxGTAXBgNVBAMMEGludC1uc1NHQy1yZWNlbnQwIhgPMjAxNDExMjcwMDAwMDBa
+GA8yMDE3MDIwNDAwMDAwMFowHjEcMBoGA1UEAwwTZWUtaW50LW5zU0dDLXJlY2Vu
+dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG
+NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn
+RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu
+p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ
+Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p
+47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1
+7Y0CAwEAATALBgkqhkiG9w0BAQsDggEBALYD7rGM1eSO04/CJTcwTl2Vz+L73pz3
+i3BAi6omaNEISdPpjOT9qypXHRYCkK1vAmUJu9th40xsM2cuLqwmFKO+tEgPIWjm
++ml6wBlB45YCXYpZ98UyVugB8t03EFGmSZREMSpIBWUxLPFv62N5tutWGGZkCpwZ
+ArYWqC+Dar0mFyoLZyKU+gfmZvZOsEwqDbrLVPbPcsav7uHEx8Usko0eJ8A9BT1Y
+YAGplSUCxVBoq38UwvARjhsKZ5zVjA4A9J1K8ZLQB7ZvGJ9sQHuyXTu4CJscSzfo
+l2NyrTCct8PUtzHsQp4bYCLNo2q32zuK9wdHUBgsXVeYCzOzyrNgkwc=
+-----END CERTIFICATE-----
\ No newline at end of file
rename from security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC.pem.certspec
rename to security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec
--- a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC.pem.certspec
+++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec
@@ -1,2 +1,2 @@
-issuer:int-nsSGC
-subject:ee-int-nsSGC
+issuer:int-nsSGC-recent
+subject:ee-int-nsSGC-recent
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC.pem
+++ /dev/null
@@ -1,17 +0,0 @@
------BEGIN CERTIFICATE-----
-MIICtzCCAaGgAwIBAgIUIcmIZ2fArJABRWRbZL/VVaA2ZDkwCwYJKoZIhvcNAQEL
-MBQxEjAQBgNVBAMMCWludC1uc1NHQzAiGA8yMDE0MTEyNzAwMDAwMFoYDzIwMTcw
-MjA0MDAwMDAwWjAXMRUwEwYDVQQDDAxlZS1pbnQtbnNTR0MwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo
-V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p
-0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk
-fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh
-W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI
-TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJKoZI
-hvcNAQELA4IBAQABjnFHTkFppJyVXDcImH6EaE+PNkFKXp2uIXjiV4xJP2JjYqal
-2J3AAKxRSPtSCSVtkKUSkm4hNX2Jo7Kqdw+EFkOOhqWLltk1m2DpXOLzrfJ3SArm
-ZrS+8EH133SPDSZ5zXXN8NBu1F5acY41Da3LmMvhBrEaCiDW0/nJsrh/t+H6Bf6I
-ZGIEs55jH2yOzyM+uKtyNNTA5xrH+K+wIQNLeX/6ML8HAlpwLHmuuQEdZ7Ti+Idu
-5uIFbQBUypsinwiCaYnGIaEQOrXCMhOGiZxaLFzq/kqKkfS4c627d3gV8PxIYouY
-zypSx75mGbN+pUtC1a5hGFfGofTkK+I19EPs
------END CERTIFICATE-----
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC2TCCAcOgAwIBAgIUbcXBg0y82WEm7Yor5jl0vYp6sLQwCwYJKoZIhvcNAQEL
+MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTYwNzI0MDAwMDAwWhgPMjAxNjA5MjQwMDAw
+MDBaMBgxFjAUBgNVBAMMDWludC1uc1NHQy1vbGQwggEiMA0GCSqGSIb3DQEBAQUA
+A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH
+Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr
+IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ
+sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA
+dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE
+LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjJjAkMAwGA1UdEwQF
+MAMBAf8wFAYDVR0lBA0wCwYJYIZIAYb4QgQBMAsGCSqGSIb3DQEBCwOCAQEAM+vf
+k8pAexjnMg1N5zp/X53Q6CaDseUj3FWnO/prJiMSWa2pcE+09naIc2gR7YsuapRr
++7Z1cOrF7uKVRnSKHmmZHGr+/EtoUuhwtkMpcbaCL5061Of6Un8UnK5sAQTECUip
+CMChu0kX/qVlBiE/eJG2lrq8lycCdhjjjQjS0Fk1Jikh33/JeJCCay/pWOoiagv2
+ansOq+gUWiG55jTGT4b+0TdY70rLX7WDpliqieTfd7xVB0Zv4U41ydI/tcP5lo3g
+/X4szNbZNyu9dRmLjVqDS3lhGGnRPiDblxlKm6vafrsd3zk4vg+UJlrHPP1q94Bh
+Fbax9mimAkqXvI/F+A==
+-----END CERTIFICATE-----
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem.certspec
@@ -0,0 +1,5 @@
+issuer:ca
+subject:int-nsSGC-old
+extension:basicConstraints:cA,
+extension:extKeyUsage:nsSGC
+validity:20160724-20160924
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC2zCCAcWgAwIBAgIUDUfr/LSKxxp6n1UoiDvmm9b4cCswCwYJKoZIhvcNAQEL
+MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTUwNzI0MDAwMDAwWhgPMjAxNjA5MjQwMDAw
+MDBaMBoxGDAWBgNVBAMMD2ludC1uc1NHQy1vbGRlcjCCASIwDQYJKoZIhvcNAQEB
+BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7
+wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp
+k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh
+eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW
+EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc
+JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMmMCQwDAYDVR0T
+BAUwAwEB/zAUBgNVHSUEDTALBglghkgBhvhCBAEwCwYJKoZIhvcNAQELA4IBAQAY
+46wuAov03l8b+soIfL0TR+7LMwHnekiaa6M52nToHE8oDyH0NgFx4mMbdQYxKHvi
+xn9Lgp650JN0ofkJ2Z5lduakAW8n316+bfimkJVCHst7jhSEc7qWAb96kLabZD7U
+N+8cpelepAbfe8vpH043qon8tg9fYABZ4RrXCEQvhb+nHbNnW+GgnnnrtD7GM165
+krU12IDIOO/rQ04/vrKOa0p+Zv+oaLJMLhPPeXlQTno/bRY9VRq0oQej3iOyd6vH
+wfq2PUCmTeOziI8YO6V9Ddtc/TYPwh3yF0AtKFXsl9MZ3xrlD17pl1BsVdIGANQf
+qus1PdEkVZc8fRGBCJKv
+-----END CERTIFICATE-----
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem.certspec
@@ -0,0 +1,5 @@
+issuer:ca
+subject:int-nsSGC-older
+extension:basicConstraints:cA,
+extension:extKeyUsage:nsSGC
+validity:20150724-20160924
new file mode 100644
--- /dev/null
+++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC3DCCAcagAwIBAgIUE3ByAD3ROipiblgZuY8BtAMhi6swCwYJKoZIhvcNAQEL
+MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTYwODI0MDAwMDAwWhgPMjAxNzA4MjQwMDAw
+MDBaMBsxGTAXBgNVBAMMEGludC1uc1NHQy1yZWNlbnQwggEiMA0GCSqGSIb3DQEB
+AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk
+e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg
+KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI
+YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi
+lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL
+HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjJjAkMAwGA1Ud
+EwQFMAMBAf8wFAYDVR0lBA0wCwYJYIZIAYb4QgQBMAsGCSqGSIb3DQEBCwOCAQEA
+VPtQzyrS2EDjCT6V7b8KKEXAyl70GZe1rD2s/xS+Uj43la5vVQyB0PtabDTh4lVy
+hut0M0o3E9hQ39qswMOcmNQdTnXTrhUzJPuGUnXxb8Jxjv+FR6+M8cmcdIlnFfXF
+HQXwVn9LzvxwlbMatY3xQXrKQz6RzrMQ0V6tYKZZSHZvecy1iCbr2CIpU7I3D2aR
+NatT1GYjaU+8u2afAoYKd+euB7pVMew7JuAxJ13iM1IMWyMil+/36ZOv5MBSSWRU
+7ts0vZeH5Ne0kEYf5uOY7LWaw7fCo7HKiyOcB0xSvQL1BvjTf6NqbCO4a29BYQF6
+Ieyp6ItfrpIuwcpfyq1d7A==
+-----END CERTIFICATE-----
\ No newline at end of file
rename from security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC.pem.certspec
rename to security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec
--- a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC.pem.certspec
+++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec
@@ -1,4 +1,5 @@
issuer:ca
-subject:int-nsSGC
+subject:int-nsSGC-recent
extension:basicConstraints:cA,
extension:extKeyUsage:nsSGC
+validity:20160824-20170824
deleted file mode 100644
--- a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC.pem
+++ /dev/null
@@ -1,18 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIC1TCCAb+gAwIBAgIUOxLAJlXzecoaBnkH1SBlJk1SarIwCwYJKoZIhvcNAQEL
-MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
-MDBaMBQxEjAQBgNVBAMMCWludC1uc1NHQzCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY
-H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk
-27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9
-0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM
-kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL
-L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMmMCQwDAYDVR0TBAUwAwEB
-/zAUBgNVHSUEDTALBglghkgBhvhCBAEwCwYJKoZIhvcNAQELA4IBAQAYW/xGaRLN
-PnvYj8xP9847hfXB9ncxyv1OKZWBYgPwehFoaUQXTfSxap0I97r27rF7LjzOH6uZ
-hatV9JNoHfSW6LGKCo6Rb4O+6tBS/zbf5xDFre5NWmmVogOcPmXD6RpktE0UCMUv
-6meJNgDld7/3lsrNjqHwOOdQAOpPJKa7Qraboc27Je3FTRc4uSSuXgqHOwt8Z1oq
-ux4WMzboAlXP4/hACbwJQxNoAA/dCaf93T2gxXWRIh9c07YPQXHNRgdYmDTwU/cJ
-L/WrKfeFspUQodIjPhNXuyZa1LtGFG2vk95jx6UbqRSP+vlxAg/jwQgN1V9arNX/
-UFht9sxFaE75
------END CERTIFICATE-----
\ No newline at end of file
--- a/security/manager/ssl/tests/unit/test_cert_eku/moz.build
+++ b/security/manager/ssl/tests/unit/test_cert_eku/moz.build
@@ -12,20 +12,24 @@
# 'ee-SA-OCSP.pem',
# 'ee-SA-nsSGC.pem',
# 'ee-SA.pem',
# 'ee-int-CA.pem',
# 'ee-int-SA-CA.pem',
# 'ee-int-SA-OCSP.pem',
# 'ee-int-SA-nsSGC.pem',
# 'ee-int-SA.pem',
-# 'ee-int-nsSGC.pem',
+# 'ee-int-nsSGC-old.pem',
+# 'ee-int-nsSGC-older.pem',
+# 'ee-int-nsSGC-recent.pem',
# 'ee-nsSGC.pem',
# 'int-CA.pem',
# 'int-SA-CA.pem',
# 'int-SA-OCSP.pem',
# 'int-SA-nsSGC.pem',
# 'int-SA.pem',
-# 'int-nsSGC.pem',
+# 'int-nsSGC-old.pem',
+# 'int-nsSGC-older.pem',
+# 'int-nsSGC-recent.pem',
#)
#
#for test_certificate in test_certificates:
# GeneratedTestCertificate(test_certificate)
--- a/security/pkix/include/pkix/pkixtypes.h
+++ b/security/pkix/include/pkix/pkixtypes.h
@@ -323,16 +323,25 @@ public:
//
// Return Success if the validity duration is acceptable,
// Result::ERROR_VALIDITY_TOO_LONG if the validity duration is not acceptable,
// or another error code if another error occurred.
virtual Result CheckValidityIsAcceptable(Time notBefore, Time notAfter,
EndEntityOrCA endEntityOrCA,
KeyPurposeId keyPurpose) = 0;
+ // For compatibility, a CA certificate with an extended key usage that
+ // contains the id-Netscape-stepUp OID but does not contain the
+ // id-kp-serverAuth OID may be considered valid for issuing server auth
+ // certificates. This function allows TrustDomain implementations to control
+ // this setting based on the start of the validity period of the certificate
+ // in question.
+ virtual Result NetscapeStepUpMatchesServerAuth(Time notBefore,
+ /*out*/ bool& matches) = 0;
+
// Compute a digest of the data in item using the given digest algorithm.
//
// item contains the data to hash.
// digestBuf points to a buffer to where the digest will be written.
// digestBufLen will be the size of the digest output (20 for SHA-1,
// 32 for SHA-256, etc.).
//
// TODO: Taking the output buffer as (uint8_t*, size_t) is counter to our
--- a/security/pkix/lib/pkixcheck.cpp
+++ b/security/pkix/lib/pkixcheck.cpp
@@ -679,17 +679,18 @@ CheckBasicConstraints(EndEntityOrCA endE
return Success;
}
// 4.2.1.12. Extended Key Usage (id-ce-extKeyUsage)
static Result
MatchEKU(Reader& value, KeyPurposeId requiredEKU,
- EndEntityOrCA endEntityOrCA, /*in/out*/ bool& found,
+ EndEntityOrCA endEntityOrCA, TrustDomain& trustDomain,
+ Time notBefore, /*in/out*/ bool& found,
/*in/out*/ bool& foundOCSPSigning)
{
// See Section 5.9 of "A Layman's Guide to a Subset of ASN.1, BER, and DER"
// for a description of ASN.1 DER encoding of OIDs.
// id-pkix OBJECT IDENTIFIER ::=
// { iso(1) identified-organization(3) dod(6) internet(1)
// security(5) mechanisms(5) pkix(7) }
@@ -710,25 +711,34 @@ MatchEKU(Reader& value, KeyPurposeId req
// id-Netscape-stepUp OBJECT IDENTIFIER ::= { id-Netscape-policy 1 }
static const uint8_t serverStepUp[] =
{ (40*2)+16, 128+6,72, 1, 128+6,128+120,66, 4, 1 };
bool match = false;
if (!found) {
switch (requiredEKU) {
- case KeyPurposeId::id_kp_serverAuth:
- // Treat CA certs with step-up OID as also having SSL server type.
- // Comodo has issued certificates that require this behavior that don't
- // expire until June 2020! TODO(bug 982932): Limit this exception to
- // old certificates.
- match = value.MatchRest(server) ||
- (endEntityOrCA == EndEntityOrCA::MustBeCA &&
- value.MatchRest(serverStepUp));
+ case KeyPurposeId::id_kp_serverAuth: {
+ if (value.MatchRest(server)) {
+ match = true;
+ break;
+ }
+ // Potentially treat CA certs with step-up OID as also having SSL server
+ // type. Comodo has issued certificates that require this behavior that
+ // don't expire until June 2020!
+ if (endEntityOrCA == EndEntityOrCA::MustBeCA &&
+ value.MatchRest(serverStepUp)) {
+ Result rv = trustDomain.NetscapeStepUpMatchesServerAuth(notBefore,
+ match);
+ if (rv != Success) {
+ return rv;
+ }
+ }
break;
+ }
case KeyPurposeId::id_kp_clientAuth:
match = value.MatchRest(client);
break;
case KeyPurposeId::id_kp_codeSigning:
match = value.MatchRest(code);
break;
@@ -759,32 +769,34 @@ MatchEKU(Reader& value, KeyPurposeId req
value.SkipToEnd(); // ignore unmatched OIDs.
return Success;
}
Result
CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA,
const Input* encodedExtendedKeyUsage,
- KeyPurposeId requiredEKU)
+ KeyPurposeId requiredEKU, TrustDomain& trustDomain,
+ Time notBefore)
{
// XXX: We're using Result::ERROR_INADEQUATE_CERT_TYPE here so that callers
// can distinguish EKU mismatch from KU mismatch from basic constraints
// mismatch. We should probably add a new error code that is more clear for
// this type of problem.
bool foundOCSPSigning = false;
if (encodedExtendedKeyUsage) {
bool found = requiredEKU == KeyPurposeId::anyExtendedKeyUsage;
Reader input(*encodedExtendedKeyUsage);
Result rv = der::NestedOf(input, der::SEQUENCE, der::OIDTag,
der::EmptyAllowed::No, [&](Reader& r) {
- return MatchEKU(r, requiredEKU, endEntityOrCA, found, foundOCSPSigning);
+ return MatchEKU(r, requiredEKU, endEntityOrCA, trustDomain, notBefore,
+ found, foundOCSPSigning);
});
if (rv != Success) {
return Result::ERROR_INADEQUATE_CERT_TYPE;
}
if (der::End(input) != Success) {
return Result::ERROR_INADEQUATE_CERT_TYPE;
}
@@ -1007,17 +1019,17 @@ CheckIssuerIndependentProperties(TrustDo
// 4.2.1.10. Name Constraints is dealt with in during path building.
// 4.2.1.11. Policy Constraints are implicitly supported; see the
// documentation about policy enforcement in pkix.h.
// 4.2.1.12. Extended Key Usage
rv = CheckExtendedKeyUsage(endEntityOrCA, cert.GetExtKeyUsage(),
- requiredEKUIfPresent);
+ requiredEKUIfPresent, trustDomain, notBefore);
if (rv != Success) {
return rv;
}
// 4.2.1.13. CRL Distribution Points is not supported, though the
// TrustDomain's CheckRevocation method may parse it and process it
// on its own.
--- a/security/pkix/test/gtest/pkixcheck_CheckExtendedKeyUsage_tests.cpp
+++ b/security/pkix/test/gtest/pkixcheck_CheckExtendedKeyUsage_tests.cpp
@@ -28,21 +28,26 @@
using namespace mozilla::pkix;
using namespace mozilla::pkix::test;
namespace mozilla { namespace pkix {
extern Result CheckExtendedKeyUsage(EndEntityOrCA endEntityOrCA,
const Input* encodedExtendedKeyUsage,
- KeyPurposeId requiredEKU);
+ KeyPurposeId requiredEKU,
+ TrustDomain& trustDomain, Time notBefore);
} } // namespace mozilla::pkix
-class pkixcheck_CheckExtendedKeyUsage : public ::testing::Test { };
+class pkixcheck_CheckExtendedKeyUsage : public ::testing::Test
+{
+protected:
+ DefaultCryptoTrustDomain mTrustDomain;
+};
#define ASSERT_BAD(x) ASSERT_EQ(Result::ERROR_INADEQUATE_CERT_TYPE, x)
// tlv_id_kp_OCSPSigning and tlv_id_kp_serverAuth are defined in pkixtestutil.h
// python DottedOIDToCode.py --tlv id-kp-clientAuth 1.3.6.1.5.5.7.3.2
static const uint8_t tlv_id_kp_clientAuth[] = {
0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02
@@ -77,91 +82,111 @@ static const uint8_t tlv_anyExtendedKeyU
TEST_F(pkixcheck_CheckExtendedKeyUsage, none)
{
// The input Input is nullptr. This means the cert had no extended key usage
// extension. This is always valid except for when the certificate is an
// end-entity and the required usage is id-kp-OCSPSigning.
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity,
nullptr,
- KeyPurposeId::anyExtendedKeyUsage));
+ KeyPurposeId::anyExtendedKeyUsage,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, nullptr,
- KeyPurposeId::anyExtendedKeyUsage));
+ KeyPurposeId::anyExtendedKeyUsage,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity,
nullptr,
- KeyPurposeId::id_kp_serverAuth));
+ KeyPurposeId::id_kp_serverAuth,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, nullptr,
- KeyPurposeId::id_kp_serverAuth));
+ KeyPurposeId::id_kp_serverAuth,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity,
nullptr,
- KeyPurposeId::id_kp_clientAuth));
+ KeyPurposeId::id_kp_clientAuth,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, nullptr,
- KeyPurposeId::id_kp_clientAuth));
+ KeyPurposeId::id_kp_clientAuth,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity,
nullptr,
- KeyPurposeId::id_kp_codeSigning));
+ KeyPurposeId::id_kp_codeSigning,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, nullptr,
- KeyPurposeId::id_kp_codeSigning));
+ KeyPurposeId::id_kp_codeSigning,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity,
nullptr,
- KeyPurposeId::id_kp_emailProtection));
+ KeyPurposeId::id_kp_emailProtection,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, nullptr,
- KeyPurposeId::id_kp_emailProtection));
+ KeyPurposeId::id_kp_emailProtection,
+ mTrustDomain, Now()));
ASSERT_BAD(CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity, nullptr,
- KeyPurposeId::id_kp_OCSPSigning));
+ KeyPurposeId::id_kp_OCSPSigning,
+ mTrustDomain, Now()));
ASSERT_EQ(Success, CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, nullptr,
- KeyPurposeId::id_kp_OCSPSigning));
+ KeyPurposeId::id_kp_OCSPSigning,
+ mTrustDomain, Now()));
}
static const Input empty_null;
TEST_F(pkixcheck_CheckExtendedKeyUsage, empty)
{
// The input Input is empty. The cert has an empty extended key usage
// extension, which is syntactically invalid.
ASSERT_BAD(CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity, &empty_null,
- KeyPurposeId::id_kp_serverAuth));
+ KeyPurposeId::id_kp_serverAuth,
+ mTrustDomain, Now()));
ASSERT_BAD(CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, &empty_null,
- KeyPurposeId::id_kp_serverAuth));
+ KeyPurposeId::id_kp_serverAuth,
+ mTrustDomain, Now()));
static const uint8_t dummy = 0x00;
Input empty_nonnull;
ASSERT_EQ(Success, empty_nonnull.Init(&dummy, 0));
ASSERT_BAD(CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity, &empty_nonnull,
- KeyPurposeId::id_kp_serverAuth));
+ KeyPurposeId::id_kp_serverAuth,
+ mTrustDomain, Now()));
ASSERT_BAD(CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, &empty_nonnull,
- KeyPurposeId::id_kp_serverAuth));
+ KeyPurposeId::id_kp_serverAuth,
+ mTrustDomain, Now()));
}
struct EKUTestcase
{
ByteString ekuSEQUENCE;
KeyPurposeId keyPurposeId;
Result expectedResultEndEntity;
Result expectedResultCA;
};
class CheckExtendedKeyUsageTest
: public ::testing::Test
, public ::testing::WithParamInterface<EKUTestcase>
{
+protected:
+ DefaultCryptoTrustDomain mTrustDomain;
};
TEST_P(CheckExtendedKeyUsageTest, EKUTestcase)
{
const EKUTestcase& param(GetParam());
Input encodedEKU;
ASSERT_EQ(Success, encodedEKU.Init(param.ekuSEQUENCE.data(),
param.ekuSEQUENCE.length()));
ASSERT_EQ(param.expectedResultEndEntity,
CheckExtendedKeyUsage(EndEntityOrCA::MustBeEndEntity, &encodedEKU,
- param.keyPurposeId));
+ param.keyPurposeId,
+ mTrustDomain, Now()));
ASSERT_EQ(param.expectedResultCA,
CheckExtendedKeyUsage(EndEntityOrCA::MustBeCA, &encodedEKU,
- param.keyPurposeId));
+ param.keyPurposeId,
+ mTrustDomain, Now()));
}
#define SINGLE_EKU_SUCCESS(oidBytes, keyPurposeId) \
{ TLV(der::SEQUENCE, BytesToByteString(oidBytes)), keyPurposeId, \
Success, Success }
#define SINGLE_EKU_SUCCESS_CA(oidBytes, keyPurposeId) \
{ TLV(der::SEQUENCE, BytesToByteString(oidBytes)), keyPurposeId, \
Result::ERROR_INADEQUATE_CERT_TYPE, Success }
--- a/security/pkix/test/gtest/pkixgtest.h
+++ b/security/pkix/test/gtest/pkixgtest.h
@@ -166,16 +166,23 @@ public:
Result CheckValidityIsAcceptable(Time, Time, EndEntityOrCA, KeyPurposeId)
override
{
ADD_FAILURE();
return NotReached("CheckValidityIsAcceptable should not be called",
Result::FATAL_ERROR_LIBRARY_FAILURE);
}
+
+ Result NetscapeStepUpMatchesServerAuth(Time, bool&) override
+ {
+ ADD_FAILURE();
+ return NotReached("NetscapeStepUpMatchesServerAuth should not be called",
+ Result::FATAL_ERROR_LIBRARY_FAILURE);
+ }
};
class DefaultCryptoTrustDomain : public EverythingFailsByDefaultTrustDomain
{
Result DigestBuf(Input item, DigestAlgorithm digestAlg,
/*out*/ uint8_t* digestBuf, size_t digestBufLen) override
{
return TestDigestBuf(item, digestAlg, digestBuf, digestBufLen);
@@ -210,16 +217,22 @@ class DefaultCryptoTrustDomain : public
return TestVerifyRSAPKCS1SignedDigest(signedDigest, subjectPublicKeyInfo);
}
Result CheckValidityIsAcceptable(Time, Time, EndEntityOrCA, KeyPurposeId)
override
{
return Success;
}
+
+ Result NetscapeStepUpMatchesServerAuth(Time, /*out*/ bool& matches) override
+ {
+ matches = true;
+ return Success;
+ }
};
class DefaultNameMatchingPolicy : public NameMatchingPolicy
{
public:
virtual Result FallBackToCommonName(
Time, /*out*/ FallBackToSearchWithinSubject& fallBackToCommonName) override
{