зеркало из https://github.com/mozilla/gecko-dev.git
bug 1239455 - rework telemetry for SHA-1 certificates to reflect possible policy states r=Cykesiopka,mgoodwin,rbarnes
Before this patch, we were measuring where SHA-1 was being used in TLS certificates: nowhere, in end-entities, in intermediates, or in both. However, the possible SHA-1 policies don't differentiate between end-entities and intermediates and instead depended on whether or not each certificate has a notBefore value after 2015 (i.e. >= 0:00:00 1 January 2016 UTC). We need to gather telemetry on the possible policy configurations. --HG-- extra : rebase_source : 301c821c8de16ffb924cd198dd0a4d3139536019
This commit is contained in:
Родитель
97affffb42
Коммит
113252b726
|
@ -1404,6 +1404,8 @@ pref("security.insecure_password.ui.enabled", false);
|
|||
// 1 = allow MITM for certificate pinning checks.
|
||||
pref("security.cert_pinning.enforcement_level", 1);
|
||||
|
||||
// NB: Changes to this pref affect CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
|
||||
// See the comment in CertVerifier.cpp.
|
||||
// 0 = allow SHA-1
|
||||
pref("security.pki.sha1_enforcement_level", 0);
|
||||
|
||||
|
|
|
@ -498,6 +498,8 @@ pref("security.mixed_content.block_active_content", true);
|
|||
// Enable pinning
|
||||
pref("security.cert_pinning.enforcement_level", 1);
|
||||
|
||||
// NB: Changes to this pref affect CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
|
||||
// See the comment in CertVerifier.cpp.
|
||||
// Allow SHA-1 certificates
|
||||
pref("security.pki.sha1_enforcement_level", 0);
|
||||
|
||||
|
|
|
@ -57,8 +57,30 @@ InitCertVerifierLog()
|
|||
}
|
||||
}
|
||||
|
||||
Result
|
||||
IsCertChainRootBuiltInRoot(CERTCertList* chain, bool& result)
|
||||
{
|
||||
if (!chain || CERT_LIST_EMPTY(chain)) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
CERTCertListNode* rootNode = CERT_LIST_TAIL(chain);
|
||||
if (!rootNode) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
CERTCertificate* root = rootNode->cert;
|
||||
if (!root) {
|
||||
return Result::FATAL_ERROR_LIBRARY_FAILURE;
|
||||
}
|
||||
SECStatus srv = IsCertBuiltInRoot(root, result);
|
||||
if (srv != SECSuccess) {
|
||||
return MapPRErrorCodeToResult(PR_GetError());
|
||||
}
|
||||
return Success;
|
||||
}
|
||||
|
||||
SECStatus
|
||||
IsCertBuiltInRoot(CERTCertificate* cert, bool& result) {
|
||||
IsCertBuiltInRoot(CERTCertificate* cert, bool& result)
|
||||
{
|
||||
result = false;
|
||||
ScopedPK11SlotList slots;
|
||||
slots = PK11_GetAllSlotsForCert(cert, nullptr);
|
||||
|
@ -115,19 +137,37 @@ BuildCertChainForOneKeyUsage(NSSCertDBTrustDomain& trustDomain, Input certDER,
|
|||
return rv;
|
||||
}
|
||||
|
||||
bool
|
||||
CertVerifier::SHA1ModeMoreRestrictiveThanGivenMode(SHA1Mode mode)
|
||||
{
|
||||
switch (mSHA1Mode) {
|
||||
case SHA1Mode::Forbidden:
|
||||
return mode != SHA1Mode::Forbidden;
|
||||
case SHA1Mode::Before2016:
|
||||
return mode != SHA1Mode::Forbidden && mode != SHA1Mode::Before2016;
|
||||
case SHA1Mode::ImportedRoot:
|
||||
return mode == SHA1Mode::Allowed;
|
||||
case SHA1Mode::Allowed:
|
||||
return false;
|
||||
default:
|
||||
MOZ_ASSERT(false, "unexpected SHA1Mode type");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static const unsigned int MIN_RSA_BITS = 2048;
|
||||
static const unsigned int MIN_RSA_BITS_WEAK = 1024;
|
||||
|
||||
SECStatus
|
||||
CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
||||
Time time, void* pinArg, const char* hostname,
|
||||
const Flags flags,
|
||||
/*out*/ ScopedCERTCertList& builtChain,
|
||||
/*optional*/ const Flags flags,
|
||||
/*optional*/ const SECItem* stapledOCSPResponseSECItem,
|
||||
/*optional out*/ ScopedCERTCertList* builtChain,
|
||||
/*optional out*/ SECOidTag* evOidPolicy,
|
||||
/*optional out*/ OCSPStaplingStatus* ocspStaplingStatus,
|
||||
/*optional out*/ KeySizeStatus* keySizeStatus,
|
||||
/*optional out*/ SignatureDigestStatus* sigDigestStatus,
|
||||
/*optional out*/ SHA1ModeResult* sha1ModeResult,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo)
|
||||
{
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, ("Top of VerifyCert\n"));
|
||||
|
@ -135,11 +175,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
PR_ASSERT(cert);
|
||||
PR_ASSERT(usage == certificateUsageSSLServer || !(flags & FLAG_MUST_BE_EV));
|
||||
PR_ASSERT(usage == certificateUsageSSLServer || !keySizeStatus);
|
||||
PR_ASSERT(usage == certificateUsageSSLServer || !sigDigestStatus);
|
||||
PR_ASSERT(usage == certificateUsageSSLServer || !sha1ModeResult);
|
||||
|
||||
if (builtChain) {
|
||||
*builtChain = nullptr;
|
||||
}
|
||||
if (evOidPolicy) {
|
||||
*evOidPolicy = SEC_OID_UNKNOWN;
|
||||
}
|
||||
|
@ -159,12 +196,12 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
*keySizeStatus = KeySizeStatus::NeverChecked;
|
||||
}
|
||||
|
||||
if (sigDigestStatus) {
|
||||
if (sha1ModeResult) {
|
||||
if (usage != certificateUsageSSLServer) {
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
*sigDigestStatus = SignatureDigestStatus::NeverChecked;
|
||||
*sha1ModeResult = SHA1ModeResult::NeverChecked;
|
||||
}
|
||||
|
||||
if (!cert ||
|
||||
|
@ -216,8 +253,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
mCertShortLifetimeInDays,
|
||||
pinningDisabled, MIN_RSA_BITS_WEAK,
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
AcceptAllAlgorithms, SHA1Mode::Allowed,
|
||||
nullptr, nullptr, builtChain);
|
||||
SHA1Mode::Allowed, builtChain, nullptr,
|
||||
nullptr);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::digitalSignature,
|
||||
|
@ -231,24 +268,27 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
// restrict the acceptable key usage based on the key exchange method
|
||||
// chosen by the server.
|
||||
|
||||
SignatureDigestOption digestAlgorithmOptions[] = {
|
||||
DisableSHA1Everywhere,
|
||||
DisableSHA1ForCA,
|
||||
DisableSHA1ForEE,
|
||||
AcceptAllAlgorithms
|
||||
// These configurations are in order of most restrictive to least
|
||||
// restrictive. This enables us to gather telemetry on the expected
|
||||
// results of setting the default policy to a particular configuration.
|
||||
SHA1Mode sha1ModeConfigurations[] = {
|
||||
SHA1Mode::Forbidden,
|
||||
SHA1Mode::Before2016,
|
||||
SHA1Mode::ImportedRoot,
|
||||
SHA1Mode::Allowed,
|
||||
};
|
||||
|
||||
SignatureDigestStatus digestAlgorithmStatuses[] = {
|
||||
SignatureDigestStatus::GoodAlgorithmsOnly,
|
||||
SignatureDigestStatus::WeakEECert,
|
||||
SignatureDigestStatus::WeakCACert,
|
||||
SignatureDigestStatus::WeakCAAndEE
|
||||
SHA1ModeResult sha1ModeResults[] = {
|
||||
SHA1ModeResult::SucceededWithoutSHA1,
|
||||
SHA1ModeResult::SucceededWithSHA1Before2016,
|
||||
SHA1ModeResult::SucceededWithImportedRoot,
|
||||
SHA1ModeResult::SucceededWithSHA1,
|
||||
};
|
||||
|
||||
size_t digestAlgorithmOptionsCount = MOZ_ARRAY_LENGTH(digestAlgorithmStatuses);
|
||||
size_t sha1ModeConfigurationsCount = MOZ_ARRAY_LENGTH(sha1ModeConfigurations);
|
||||
|
||||
static_assert(MOZ_ARRAY_LENGTH(digestAlgorithmOptions) ==
|
||||
MOZ_ARRAY_LENGTH(digestAlgorithmStatuses),
|
||||
static_assert(MOZ_ARRAY_LENGTH(sha1ModeConfigurations) ==
|
||||
MOZ_ARRAY_LENGTH(sha1ModeResults),
|
||||
"digestAlgorithm array lengths differ");
|
||||
|
||||
rv = Result::ERROR_UNKNOWN_ERROR;
|
||||
|
@ -263,21 +303,30 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
CertPolicyId evPolicy;
|
||||
SECOidTag evPolicyOidTag;
|
||||
SECStatus srv = GetFirstEVPolicy(cert, evPolicy, evPolicyOidTag);
|
||||
for (size_t i=0;
|
||||
i < digestAlgorithmOptionsCount && rv != Success && srv == SECSuccess;
|
||||
for (size_t i = 0;
|
||||
i < sha1ModeConfigurationsCount && rv != Success && srv == SECSuccess;
|
||||
i++) {
|
||||
// Because of the try-strict and fallback approach, we have to clear any
|
||||
// previously noted telemetry information
|
||||
if (pinningTelemetryInfo) {
|
||||
pinningTelemetryInfo->Reset();
|
||||
}
|
||||
// Don't attempt verification if the SHA1 mode set by preferences
|
||||
// (mSHA1Mode) is more restrictive than the SHA1 mode option we're on.
|
||||
// (To put it another way, only attempt verification if the SHA1 mode
|
||||
// option we're on is as restrictive or more restrictive than
|
||||
// mSHA1Mode.) This allows us to gather telemetry information while
|
||||
// still enforcing the mode set by preferences.
|
||||
if (SHA1ModeMoreRestrictiveThanGivenMode(sha1ModeConfigurations[i])) {
|
||||
continue;
|
||||
}
|
||||
NSSCertDBTrustDomain
|
||||
trustDomain(trustSSL, evOCSPFetching,
|
||||
mOCSPCache, pinArg, ocspGETConfig,
|
||||
mCertShortLifetimeInDays, mPinningMode, MIN_RSA_BITS,
|
||||
ValidityCheckingMode::CheckForEV,
|
||||
digestAlgorithmOptions[i], mSHA1Mode,
|
||||
pinningTelemetryInfo, hostname, builtChain);
|
||||
sha1ModeConfigurations[i], builtChain,
|
||||
pinningTelemetryInfo, hostname);
|
||||
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
|
||||
KeyUsage::digitalSignature,// (EC)DHE
|
||||
KeyUsage::keyEncipherment, // RSA
|
||||
|
@ -285,14 +334,34 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
KeyPurposeId::id_kp_serverAuth,
|
||||
evPolicy, stapledOCSPResponse,
|
||||
ocspStaplingStatus);
|
||||
// If we succeeded with the SHA1Mode of only allowing imported roots to
|
||||
// issue SHA1 certificates after 2015, if the chain we built doesn't
|
||||
// terminate with an imported root, we must reject it. (This only works
|
||||
// because we try SHA1 configurations in order of decreasing
|
||||
// strictness.)
|
||||
// Note that if there existed a certificate chain with a built-in root
|
||||
// that had SHA1 certificates issued before 2016, it would have already
|
||||
// been accepted. If such a chain had SHA1 certificates issued after
|
||||
// 2015, it will only be accepted in the SHA1Mode::Allowed case.
|
||||
if (rv == Success &&
|
||||
sha1ModeConfigurations[i] == SHA1Mode::ImportedRoot) {
|
||||
bool isBuiltInRoot = false;
|
||||
rv = IsCertChainRootBuiltInRoot(builtChain, isBuiltInRoot);
|
||||
if (rv != Success) {
|
||||
break;
|
||||
}
|
||||
if (isBuiltInRoot) {
|
||||
rv = Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
|
||||
}
|
||||
}
|
||||
if (rv == Success) {
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
|
||||
("cert is EV with status %i\n", digestAlgorithmStatuses[i]));
|
||||
("cert is EV with status %i\n", sha1ModeResults[i]));
|
||||
if (evOidPolicy) {
|
||||
*evOidPolicy = evPolicyOidTag;
|
||||
}
|
||||
if (sigDigestStatus) {
|
||||
*sigDigestStatus = digestAlgorithmStatuses[i];
|
||||
if (sha1ModeResult) {
|
||||
*sha1ModeResult = sha1ModeResults[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -323,17 +392,21 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
|
||||
size_t keySizeOptionsCount = MOZ_ARRAY_LENGTH(keySizeStatuses);
|
||||
|
||||
for (size_t i=0; i<keySizeOptionsCount && rv != Success; i++) {
|
||||
for (size_t j=0; j<digestAlgorithmOptionsCount && rv != Success; j++) {
|
||||
|
||||
for (size_t i = 0; i < keySizeOptionsCount && rv != Success; i++) {
|
||||
for (size_t j = 0; j < sha1ModeConfigurationsCount && rv != Success;
|
||||
j++) {
|
||||
// invalidate any telemetry info relating to failed chains
|
||||
if (pinningTelemetryInfo) {
|
||||
pinningTelemetryInfo->Reset();
|
||||
}
|
||||
|
||||
// If we're not going to do SHA-1 in any case, don't try
|
||||
if (mSHA1Mode == SHA1Mode::Forbidden &&
|
||||
digestAlgorithmOptions[i] != DisableSHA1Everywhere) {
|
||||
// Don't attempt verification if the SHA1 mode set by preferences
|
||||
// (mSHA1Mode) is more restrictive than the SHA1 mode option we're on.
|
||||
// (To put it another way, only attempt verification if the SHA1 mode
|
||||
// option we're on is as restrictive or more restrictive than
|
||||
// mSHA1Mode.) This allows us to gather telemetry information while
|
||||
// still enforcing the mode set by preferences.
|
||||
if (SHA1ModeMoreRestrictiveThanGivenMode(sha1ModeConfigurations[j])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -342,9 +415,9 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
mCertShortLifetimeInDays,
|
||||
mPinningMode, keySizeOptions[i],
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
digestAlgorithmOptions[j],
|
||||
mSHA1Mode, pinningTelemetryInfo,
|
||||
hostname, builtChain);
|
||||
sha1ModeConfigurations[j],
|
||||
builtChain, pinningTelemetryInfo,
|
||||
hostname);
|
||||
rv = BuildCertChainForOneKeyUsage(trustDomain, certDER, time,
|
||||
KeyUsage::digitalSignature,//(EC)DHE
|
||||
KeyUsage::keyEncipherment,//RSA
|
||||
|
@ -353,32 +426,49 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
CertPolicyId::anyPolicy,
|
||||
stapledOCSPResponse,
|
||||
ocspStaplingStatus);
|
||||
// If we succeeded with the SHA1Mode of only allowing imported roots
|
||||
// to issue SHA1 certificates after 2015, if the chain we built
|
||||
// doesn't terminate with an imported root, we must reject it. (This
|
||||
// only works because we try SHA1 configurations in order of
|
||||
// decreasing strictness.)
|
||||
// Note that if there existed a certificate chain with a built-in root
|
||||
// that had SHA1 certificates issued before 2016, it would have
|
||||
// already been accepted. If such a chain had SHA1 certificates issued
|
||||
// after 2015, it will only be accepted in the SHA1Mode::Allowed case.
|
||||
if (rv == Success &&
|
||||
sha1ModeConfigurations[j] == SHA1Mode::ImportedRoot) {
|
||||
bool isBuiltInRoot = false;
|
||||
rv = IsCertChainRootBuiltInRoot(builtChain, isBuiltInRoot);
|
||||
if (rv != Success) {
|
||||
break;
|
||||
}
|
||||
if (isBuiltInRoot) {
|
||||
rv = Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
|
||||
}
|
||||
}
|
||||
if (rv == Success) {
|
||||
if (keySizeStatus) {
|
||||
*keySizeStatus = keySizeStatuses[i];
|
||||
}
|
||||
if (sigDigestStatus) {
|
||||
*sigDigestStatus = digestAlgorithmStatuses[j];
|
||||
if (sha1ModeResult) {
|
||||
*sha1ModeResult = sha1ModeResults[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv == Success) {
|
||||
// If SHA-1 is forbidden by preference, don't accumulate SHA-1
|
||||
// telemetry, to avoid skewing the results.
|
||||
if (sigDigestStatus && mSHA1Mode == SHA1Mode::Forbidden) {
|
||||
*sigDigestStatus = SignatureDigestStatus::NeverChecked;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (keySizeStatus) {
|
||||
*keySizeStatus = KeySizeStatus::AlreadyBad;
|
||||
}
|
||||
if (sigDigestStatus && mSHA1Mode != SHA1Mode::Forbidden) {
|
||||
*sigDigestStatus = SignatureDigestStatus::AlreadyBad;
|
||||
// Only collect CERT_CHAIN_SHA1_POLICY_STATUS telemetry indicating a
|
||||
// failure when mSHA1Mode is the default.
|
||||
// NB: When we change the default, we have to change this.
|
||||
if (sha1ModeResult && mSHA1Mode == SHA1Mode::Allowed) {
|
||||
*sha1ModeResult = SHA1ModeResult::Failed;
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -390,8 +480,7 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
mCertShortLifetimeInDays,
|
||||
pinningDisabled, MIN_RSA_BITS_WEAK,
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
AcceptAllAlgorithms, mSHA1Mode,
|
||||
nullptr, nullptr, builtChain);
|
||||
mSHA1Mode, builtChain, nullptr, nullptr);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeCA, KeyUsage::keyCertSign,
|
||||
KeyPurposeId::id_kp_serverAuth,
|
||||
|
@ -405,8 +494,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
mCertShortLifetimeInDays,
|
||||
pinningDisabled, MIN_RSA_BITS_WEAK,
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
AcceptAllAlgorithms, SHA1Mode::Allowed,
|
||||
nullptr, nullptr, builtChain);
|
||||
SHA1Mode::Allowed, builtChain, nullptr,
|
||||
nullptr);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::digitalSignature,
|
||||
|
@ -431,8 +520,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
mCertShortLifetimeInDays,
|
||||
pinningDisabled, MIN_RSA_BITS_WEAK,
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
AcceptAllAlgorithms, SHA1Mode::Allowed,
|
||||
nullptr, nullptr, builtChain);
|
||||
SHA1Mode::Allowed, builtChain, nullptr,
|
||||
nullptr);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::keyEncipherment, // RSA
|
||||
|
@ -454,8 +543,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
mCertShortLifetimeInDays,
|
||||
pinningDisabled, MIN_RSA_BITS_WEAK,
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
AcceptAllAlgorithms, SHA1Mode::Allowed,
|
||||
nullptr, nullptr, builtChain);
|
||||
SHA1Mode::Allowed, builtChain, nullptr,
|
||||
nullptr);
|
||||
rv = BuildCertChain(trustDomain, certDER, time,
|
||||
EndEntityOrCA::MustBeEndEntity,
|
||||
KeyUsage::digitalSignature,
|
||||
|
@ -486,8 +575,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
pinArg, ocspGETConfig, mCertShortLifetimeInDays,
|
||||
pinningDisabled, MIN_RSA_BITS_WEAK,
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
AcceptAllAlgorithms, SHA1Mode::Allowed,
|
||||
nullptr, nullptr, builtChain);
|
||||
SHA1Mode::Allowed, builtChain, nullptr,
|
||||
nullptr);
|
||||
rv = BuildCertChain(sslTrust, certDER, time, endEntityOrCA,
|
||||
keyUsage, eku, CertPolicyId::anyPolicy,
|
||||
stapledOCSPResponse);
|
||||
|
@ -497,8 +586,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
mCertShortLifetimeInDays,
|
||||
pinningDisabled, MIN_RSA_BITS_WEAK,
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
AcceptAllAlgorithms, SHA1Mode::Allowed,
|
||||
nullptr, nullptr, builtChain);
|
||||
SHA1Mode::Allowed, builtChain, nullptr,
|
||||
nullptr);
|
||||
rv = BuildCertChain(emailTrust, certDER, time, endEntityOrCA,
|
||||
keyUsage, eku, CertPolicyId::anyPolicy,
|
||||
stapledOCSPResponse);
|
||||
|
@ -510,8 +599,8 @@ CertVerifier::VerifyCert(CERTCertificate* cert, SECCertificateUsage usage,
|
|||
pinningDisabled,
|
||||
MIN_RSA_BITS_WEAK,
|
||||
ValidityCheckingMode::CheckingOff,
|
||||
AcceptAllAlgorithms, SHA1Mode::Allowed,
|
||||
nullptr, nullptr, builtChain);
|
||||
SHA1Mode::Allowed, builtChain,
|
||||
nullptr, nullptr);
|
||||
rv = BuildCertChain(objectSigningTrust, certDER, time,
|
||||
endEntityOrCA, keyUsage, eku,
|
||||
CertPolicyId::anyPolicy, stapledOCSPResponse);
|
||||
|
@ -539,13 +628,13 @@ CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert,
|
|||
Time time,
|
||||
/*optional*/ void* pinarg,
|
||||
const char* hostname,
|
||||
bool saveIntermediatesInPermanentDatabase,
|
||||
Flags flags,
|
||||
/*optional out*/ ScopedCERTCertList* builtChain,
|
||||
/*out*/ ScopedCERTCertList& builtChain,
|
||||
/*optional*/ bool saveIntermediatesInPermanentDatabase,
|
||||
/*optional*/ Flags flags,
|
||||
/*optional out*/ SECOidTag* evOidPolicy,
|
||||
/*optional out*/ OCSPStaplingStatus* ocspStaplingStatus,
|
||||
/*optional out*/ KeySizeStatus* keySizeStatus,
|
||||
/*optional out*/ SignatureDigestStatus* sigDigestStatus,
|
||||
/*optional out*/ SHA1ModeResult* sha1ModeResult,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo)
|
||||
{
|
||||
PR_ASSERT(peerCert);
|
||||
|
@ -553,9 +642,6 @@ CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert,
|
|||
PR_ASSERT(hostname);
|
||||
PR_ASSERT(hostname[0]);
|
||||
|
||||
if (builtChain) {
|
||||
*builtChain = nullptr;
|
||||
}
|
||||
if (evOidPolicy) {
|
||||
*evOidPolicy = SEC_OID_UNKNOWN;
|
||||
}
|
||||
|
@ -565,14 +651,12 @@ CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert,
|
|||
return SECFailure;
|
||||
}
|
||||
|
||||
ScopedCERTCertList builtChainTemp;
|
||||
// CreateCertErrorRunnable assumes that CheckCertHostname is only called
|
||||
// if VerifyCert succeeded.
|
||||
SECStatus rv = VerifyCert(peerCert, certificateUsageSSLServer, time, pinarg,
|
||||
hostname, flags, stapledOCSPResponse,
|
||||
&builtChainTemp, evOidPolicy, ocspStaplingStatus,
|
||||
keySizeStatus, sigDigestStatus,
|
||||
pinningTelemetryInfo);
|
||||
hostname, builtChain, flags, stapledOCSPResponse,
|
||||
evOidPolicy, ocspStaplingStatus, keySizeStatus,
|
||||
sha1ModeResult, pinningTelemetryInfo);
|
||||
if (rv != SECSuccess) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -625,11 +709,7 @@ CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert,
|
|||
}
|
||||
|
||||
if (saveIntermediatesInPermanentDatabase) {
|
||||
SaveIntermediateCerts(builtChainTemp);
|
||||
}
|
||||
|
||||
if (builtChain) {
|
||||
*builtChain = builtChainTemp.forget();
|
||||
SaveIntermediateCerts(builtChain);
|
||||
}
|
||||
|
||||
return SECSuccess;
|
||||
|
|
|
@ -22,14 +22,14 @@ enum class KeySizeStatus {
|
|||
AlreadyBad = 3,
|
||||
};
|
||||
|
||||
// These values correspond to the CERT_CHAIN_SIGNATURE_DIGEST telemetry.
|
||||
enum class SignatureDigestStatus {
|
||||
// These values correspond to the CERT_CHAIN_SHA1_POLICY_STATUS telemetry.
|
||||
enum class SHA1ModeResult {
|
||||
NeverChecked = 0,
|
||||
GoodAlgorithmsOnly = 1,
|
||||
WeakEECert = 2,
|
||||
WeakCACert = 3,
|
||||
WeakCAAndEE = 4,
|
||||
AlreadyBad = 5,
|
||||
SucceededWithoutSHA1 = 1,
|
||||
SucceededWithSHA1Before2016 = 2,
|
||||
SucceededWithImportedRoot = 3,
|
||||
SucceededWithSHA1 = 4,
|
||||
Failed = 5,
|
||||
};
|
||||
|
||||
class PinningTelemetryInfo
|
||||
|
@ -73,13 +73,13 @@ public:
|
|||
mozilla::pkix::Time time,
|
||||
void* pinArg,
|
||||
const char* hostname,
|
||||
/*out*/ ScopedCERTCertList& builtChain,
|
||||
Flags flags = 0,
|
||||
/*optional in*/ const SECItem* stapledOCSPResponse = nullptr,
|
||||
/*optional out*/ ScopedCERTCertList* builtChain = nullptr,
|
||||
/*optional out*/ SECOidTag* evOidPolicy = nullptr,
|
||||
/*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
|
||||
/*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
|
||||
/*optional out*/ SignatureDigestStatus* sigDigestStatus = nullptr,
|
||||
/*optional out*/ SHA1ModeResult* sha1ModeResult = nullptr,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr);
|
||||
|
||||
SECStatus VerifySSLServerCert(
|
||||
|
@ -88,13 +88,13 @@ public:
|
|||
mozilla::pkix::Time time,
|
||||
/*optional*/ void* pinarg,
|
||||
const char* hostname,
|
||||
bool saveIntermediatesInPermanentDatabase = false,
|
||||
Flags flags = 0,
|
||||
/*optional out*/ ScopedCERTCertList* builtChain = nullptr,
|
||||
/*out*/ ScopedCERTCertList& builtChain,
|
||||
/*optional*/ bool saveIntermediatesInPermanentDatabase = false,
|
||||
/*optional*/ Flags flags = 0,
|
||||
/*optional out*/ SECOidTag* evOidPolicy = nullptr,
|
||||
/*optional out*/ OCSPStaplingStatus* ocspStaplingStatus = nullptr,
|
||||
/*optional out*/ KeySizeStatus* keySizeStatus = nullptr,
|
||||
/*optional out*/ SignatureDigestStatus* sigDigestStatus = nullptr,
|
||||
/*optional out*/ SHA1ModeResult* sha1ModeResult = nullptr,
|
||||
/*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr);
|
||||
|
||||
enum PinningMode {
|
||||
|
@ -107,7 +107,8 @@ public:
|
|||
enum class SHA1Mode {
|
||||
Allowed = 0,
|
||||
Forbidden = 1,
|
||||
OnlyBefore2016 = 2
|
||||
Before2016 = 2,
|
||||
ImportedRoot = 3,
|
||||
};
|
||||
|
||||
enum OcspDownloadConfig {
|
||||
|
@ -134,6 +135,12 @@ public:
|
|||
|
||||
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.)
|
||||
bool SHA1ModeMoreRestrictiveThanGivenMode(SHA1Mode mode);
|
||||
};
|
||||
|
||||
void InitCertVerifierLog();
|
||||
|
|
|
@ -50,11 +50,10 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
|
|||
CertVerifier::PinningMode pinningMode,
|
||||
unsigned int minRSABits,
|
||||
ValidityCheckingMode validityCheckingMode,
|
||||
SignatureDigestOption signatureDigestOption,
|
||||
CertVerifier::SHA1Mode sha1Mode,
|
||||
ScopedCERTCertList& builtChain,
|
||||
/*optional*/ PinningTelemetryInfo* pinningTelemetryInfo,
|
||||
/*optional*/ const char* hostname,
|
||||
/*optional*/ ScopedCERTCertList* builtChain)
|
||||
/*optional*/ const char* hostname)
|
||||
: mCertDBTrustType(certDBTrustType)
|
||||
, mOCSPFetching(ocspFetching)
|
||||
, mOCSPCache(ocspCache)
|
||||
|
@ -64,11 +63,10 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(SECTrustType certDBTrustType,
|
|||
, mPinningMode(pinningMode)
|
||||
, mMinRSABits(minRSABits)
|
||||
, mValidityCheckingMode(validityCheckingMode)
|
||||
, mSignatureDigestOption(signatureDigestOption)
|
||||
, mSHA1Mode(sha1Mode)
|
||||
, mBuiltChain(builtChain)
|
||||
, mPinningTelemetryInfo(pinningTelemetryInfo)
|
||||
, mHostname(hostname)
|
||||
, mBuiltChain(builtChain)
|
||||
, mCertBlocklist(do_GetService(NS_CERTBLOCKLIST_CONTRACTID))
|
||||
, mOCSPStaplingStatus(CertVerifier::OCSP_STAPLING_NEVER_CHECKED)
|
||||
{
|
||||
|
@ -806,9 +804,7 @@ NSSCertDBTrustDomain::IsChainValid(const DERArray& certArray, Time time)
|
|||
}
|
||||
}
|
||||
|
||||
if (mBuiltChain) {
|
||||
*mBuiltChain = certList.forget();
|
||||
}
|
||||
mBuiltChain = certList.forget();
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
@ -824,40 +820,25 @@ NSSCertDBTrustDomain::CheckSignatureDigestAlgorithm(DigestAlgorithm aAlg,
|
|||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug,
|
||||
("NSSCertDBTrustDomain: CheckSignatureDigestAlgorithm"));
|
||||
if (aAlg == DigestAlgorithm::sha1) {
|
||||
// First check based on SHA1Mode
|
||||
switch (mSHA1Mode) {
|
||||
case CertVerifier::SHA1Mode::Forbidden:
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, ("SHA-1 certificate rejected"));
|
||||
return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
|
||||
case CertVerifier::SHA1Mode::OnlyBefore2016:
|
||||
case CertVerifier::SHA1Mode::Before2016:
|
||||
if (JANUARY_FIRST_2016 <= notBefore) {
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, ("Post-2015 SHA-1 certificate rejected"));
|
||||
return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
|
||||
}
|
||||
break;
|
||||
case CertVerifier::SHA1Mode::Allowed:
|
||||
// Enforcing that the resulting chain uses an imported root is only
|
||||
// possible at a higher level. This is done in CertVerifier::VerifyCert.
|
||||
case CertVerifier::SHA1Mode::ImportedRoot:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Then check the signatureDigestOption values
|
||||
if (mSignatureDigestOption == DisableSHA1Everywhere) {
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, ("SHA-1 certificate rejected"));
|
||||
return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
|
||||
}
|
||||
|
||||
if (endEntityOrCA == EndEntityOrCA::MustBeCA) {
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, ("CA cert is SHA-1"));
|
||||
return mSignatureDigestOption == DisableSHA1ForCA
|
||||
? Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
||||
: Success;
|
||||
} else {
|
||||
MOZ_LOG(gCertVerifierLog, LogLevel::Debug, ("EE cert is SHA-1"));
|
||||
return mSignatureDigestOption == DisableSHA1ForEE
|
||||
? Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
|
||||
: Success;
|
||||
}
|
||||
}
|
||||
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,13 +41,6 @@ char* DefaultServerNicknameForCert(CERTCertificate* cert);
|
|||
|
||||
void SaveIntermediateCerts(const ScopedCERTCertList& certList);
|
||||
|
||||
enum SignatureDigestOption {
|
||||
AcceptAllAlgorithms,
|
||||
DisableSHA1ForEE,
|
||||
DisableSHA1ForCA,
|
||||
DisableSHA1Everywhere,
|
||||
};
|
||||
|
||||
class NSSCertDBTrustDomain : public mozilla::pkix::TrustDomain
|
||||
{
|
||||
|
||||
|
@ -69,11 +62,10 @@ public:
|
|||
CertVerifier::PinningMode pinningMode,
|
||||
unsigned int minRSABits,
|
||||
ValidityCheckingMode validityCheckingMode,
|
||||
SignatureDigestOption signatureDigestOption,
|
||||
CertVerifier::SHA1Mode sha1Mode,
|
||||
ScopedCERTCertList& builtChain,
|
||||
/*optional*/ PinningTelemetryInfo* pinningTelemetryInfo = nullptr,
|
||||
/*optional*/ const char* hostname = nullptr,
|
||||
/*optional out*/ ScopedCERTCertList* builtChain = nullptr);
|
||||
/*optional*/ const char* hostname = nullptr);
|
||||
|
||||
virtual Result FindIssuer(mozilla::pkix::Input encodedIssuerName,
|
||||
IssuerChecker& checker,
|
||||
|
@ -156,11 +148,10 @@ private:
|
|||
CertVerifier::PinningMode mPinningMode;
|
||||
const unsigned int mMinRSABits;
|
||||
ValidityCheckingMode mValidityCheckingMode;
|
||||
SignatureDigestOption mSignatureDigestOption;
|
||||
CertVerifier::SHA1Mode mSHA1Mode;
|
||||
ScopedCERTCertList& mBuiltChain; // non-owning
|
||||
PinningTelemetryInfo* mPinningTelemetryInfo;
|
||||
const char* mHostname; // non-owning - only used for pinning checks
|
||||
ScopedCERTCertList* mBuiltChain; // non-owning
|
||||
nsCOMPtr<nsICertBlocklist> mCertBlocklist;
|
||||
CertVerifier::OCSPStaplingStatus mOCSPStaplingStatus;
|
||||
};
|
||||
|
|
|
@ -1222,7 +1222,7 @@ AuthCertificate(CertVerifier& certVerifier,
|
|||
CertVerifier::OCSPStaplingStatus ocspStaplingStatus =
|
||||
CertVerifier::OCSP_STAPLING_NEVER_CHECKED;
|
||||
KeySizeStatus keySizeStatus = KeySizeStatus::NeverChecked;
|
||||
SignatureDigestStatus sigDigestStatus = SignatureDigestStatus::NeverChecked;
|
||||
SHA1ModeResult sha1ModeResult = SHA1ModeResult::NeverChecked;
|
||||
PinningTelemetryInfo pinningTelemetryInfo;
|
||||
|
||||
int flags = 0;
|
||||
|
@ -1234,9 +1234,9 @@ AuthCertificate(CertVerifier& certVerifier,
|
|||
rv = certVerifier.VerifySSLServerCert(cert, stapledOCSPResponse,
|
||||
time, infoObject,
|
||||
infoObject->GetHostNameRaw(),
|
||||
saveIntermediates, flags, &certList,
|
||||
certList, saveIntermediates, flags,
|
||||
&evOidPolicy, &ocspStaplingStatus,
|
||||
&keySizeStatus, &sigDigestStatus,
|
||||
&keySizeStatus, &sha1ModeResult,
|
||||
&pinningTelemetryInfo);
|
||||
PRErrorCode savedErrorCode;
|
||||
if (rv != SECSuccess) {
|
||||
|
@ -1250,9 +1250,9 @@ AuthCertificate(CertVerifier& certVerifier,
|
|||
Telemetry::Accumulate(Telemetry::CERT_CHAIN_KEY_SIZE_STATUS,
|
||||
static_cast<uint32_t>(keySizeStatus));
|
||||
}
|
||||
if (sigDigestStatus != SignatureDigestStatus::NeverChecked) {
|
||||
Telemetry::Accumulate(Telemetry::CERT_CHAIN_SIGNATURE_DIGEST_STATUS,
|
||||
static_cast<uint32_t>(sigDigestStatus));
|
||||
if (sha1ModeResult != SHA1ModeResult::NeverChecked) {
|
||||
Telemetry::Accumulate(Telemetry::CERT_CHAIN_SHA1_POLICY_STATUS,
|
||||
static_cast<uint32_t>(sha1ModeResult));
|
||||
}
|
||||
|
||||
if (pinningTelemetryInfo.accumulateForRoot) {
|
||||
|
|
|
@ -250,9 +250,7 @@ VerifyCertificate(CERTCertificate* cert, void* voidContext, void* pinArg)
|
|||
certificateUsageObjectSigner,
|
||||
Now(), pinArg,
|
||||
nullptr, // hostname
|
||||
0, // flags
|
||||
nullptr, // stapledOCSPResponse
|
||||
&context->builtChain));
|
||||
context->builtChain));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
|
|
@ -831,9 +831,8 @@ nsNSSCertificate::GetChain(nsIArray** _rvChain)
|
|||
if (certVerifier->VerifyCert(mCert.get(), certificateUsageSSLServer, now,
|
||||
nullptr, /*XXX fixme*/
|
||||
nullptr, /* hostname */
|
||||
CertVerifier::FLAG_LOCAL_ONLY,
|
||||
nullptr, /* stapledOCSPResponse */
|
||||
&nssChain) != SECSuccess) {
|
||||
nssChain,
|
||||
CertVerifier::FLAG_LOCAL_ONLY) != SECSuccess) {
|
||||
nssChain = nullptr;
|
||||
// keep going
|
||||
}
|
||||
|
@ -858,9 +857,8 @@ nsNSSCertificate::GetChain(nsIArray** _rvChain)
|
|||
if (certVerifier->VerifyCert(mCert.get(), usage, now,
|
||||
nullptr, /*XXX fixme*/
|
||||
nullptr, /*hostname*/
|
||||
CertVerifier::FLAG_LOCAL_ONLY,
|
||||
nullptr, /* stapledOCSPResponse */
|
||||
&nssChain) != SECSuccess) {
|
||||
nssChain,
|
||||
CertVerifier::FLAG_LOCAL_ONLY) != SECSuccess) {
|
||||
nssChain = nullptr;
|
||||
// keep going
|
||||
}
|
||||
|
@ -1393,11 +1391,13 @@ nsNSSCertificate::hasValidEVOidTag(SECOidTag& resultOidTag, bool& validEV)
|
|||
|
||||
uint32_t flags = mozilla::psm::CertVerifier::FLAG_LOCAL_ONLY |
|
||||
mozilla::psm::CertVerifier::FLAG_MUST_BE_EV;
|
||||
ScopedCERTCertList unusedBuiltChain;
|
||||
SECStatus rv = certVerifier->VerifyCert(mCert.get(),
|
||||
certificateUsageSSLServer, mozilla::pkix::Now(),
|
||||
nullptr /* XXX pinarg */,
|
||||
nullptr /* hostname */,
|
||||
flags, nullptr /* stapledOCSPResponse */ , nullptr, &resultOidTag);
|
||||
unusedBuiltChain,
|
||||
flags, nullptr /* stapledOCSPResponse */, &resultOidTag);
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
resultOidTag = SEC_OID_UNKNOWN;
|
||||
|
|
|
@ -615,7 +615,7 @@ nsNSSCertificateDB::ImportEmailCertificate(uint8_t * data, uint32_t length,
|
|||
SECStatus rv = certVerifier->VerifyCert(node->cert,
|
||||
certificateUsageEmailRecipient,
|
||||
mozilla::pkix::Now(), ctx,
|
||||
nullptr, 0, nullptr, &certChain);
|
||||
nullptr, certChain);
|
||||
|
||||
if (rv != SECSuccess) {
|
||||
nsCOMPtr<nsIX509Cert> certToShow = nsNSSCertificate::Create(node->cert);
|
||||
|
@ -783,7 +783,7 @@ nsNSSCertificateDB::ImportValidCACertsInList(CERTCertList *certList, nsIInterfac
|
|||
SECStatus rv = certVerifier->VerifyCert(node->cert,
|
||||
certificateUsageVerifyCA,
|
||||
mozilla::pkix::Now(), ctx,
|
||||
nullptr, 0, nullptr, &certChain);
|
||||
nullptr, certChain);
|
||||
if (rv != SECSuccess) {
|
||||
nsCOMPtr<nsIX509Cert> certToShow = nsNSSCertificate::Create(node->cert);
|
||||
DisplayCertificateAlert(ctx, "NotImportingUnverifiedCert", certToShow, proofOfLock);
|
||||
|
@ -1351,11 +1351,13 @@ nsNSSCertificateDB::FindCertByEmailAddress(nsISupports *aToken, const char *aEma
|
|||
!CERT_LIST_END(node, certlist);
|
||||
node = CERT_LIST_NEXT(node)) {
|
||||
|
||||
ScopedCERTCertList unusedCertChain;
|
||||
SECStatus srv = certVerifier->VerifyCert(node->cert,
|
||||
certificateUsageEmailRecipient,
|
||||
mozilla::pkix::Now(),
|
||||
nullptr /*XXX pinarg*/,
|
||||
nullptr /*hostname*/);
|
||||
nullptr /*hostname*/,
|
||||
unusedCertChain);
|
||||
if (srv == SECSuccess) {
|
||||
break;
|
||||
}
|
||||
|
@ -1722,17 +1724,17 @@ VerifyCertAtTime(nsIX509Cert* aCert,
|
|||
aTime,
|
||||
nullptr, // Assume no context
|
||||
aHostname,
|
||||
resultChain,
|
||||
false, // don't save intermediates
|
||||
aFlags,
|
||||
&resultChain,
|
||||
&evOidPolicy);
|
||||
} else {
|
||||
srv = certVerifier->VerifyCert(nssCert, aUsage, aTime,
|
||||
nullptr, // Assume no context
|
||||
aHostname,
|
||||
resultChain,
|
||||
aFlags,
|
||||
nullptr, // stapledOCSPResponse
|
||||
&resultChain,
|
||||
&evOidPolicy);
|
||||
}
|
||||
|
||||
|
|
|
@ -862,8 +862,14 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting,
|
|||
CertVerifier::SHA1Mode sha1Mode = static_cast<CertVerifier::SHA1Mode>
|
||||
(Preferences::GetInt("security.pki.sha1_enforcement_level",
|
||||
static_cast<int32_t>(CertVerifier::SHA1Mode::Allowed)));
|
||||
if (sha1Mode > CertVerifier::SHA1Mode::OnlyBefore2016) {
|
||||
sha1Mode = CertVerifier::SHA1Mode::Allowed;
|
||||
switch (sha1Mode) {
|
||||
case CertVerifier::SHA1Mode::Allowed:
|
||||
case CertVerifier::SHA1Mode::Forbidden:
|
||||
case CertVerifier::SHA1Mode::Before2016:
|
||||
case CertVerifier::SHA1Mode::ImportedRoot:
|
||||
break;
|
||||
default:
|
||||
sha1Mode = CertVerifier::SHA1Mode::Allowed;
|
||||
}
|
||||
|
||||
CertVerifier::OcspDownloadConfig odc;
|
||||
|
|
|
@ -380,11 +380,11 @@ nsNSSSocketInfo::IsAcceptableForHost(const nsACString& hostname, bool* _retval)
|
|||
}
|
||||
nsAutoCString hostnameFlat(PromiseFlatCString(hostname));
|
||||
CertVerifier::Flags flags = CertVerifier::FLAG_LOCAL_ONLY;
|
||||
ScopedCERTCertList unusedBuiltChain;
|
||||
SECStatus rv = certVerifier->VerifySSLServerCert(nssCert, nullptr,
|
||||
mozilla::pkix::Now(),
|
||||
nullptr, hostnameFlat.get(),
|
||||
false, flags, nullptr,
|
||||
nullptr);
|
||||
unusedBuiltChain, false, flags);
|
||||
if (rv != SECSuccess) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -712,9 +712,10 @@ nsSiteSecurityService::ProcessPKPHeader(nsIURI* aSourceURI,
|
|||
if (certVerifier->VerifySSLServerCert(nssCert, nullptr, // stapled ocsp
|
||||
now, nullptr, // pinarg
|
||||
host.get(), // hostname
|
||||
certList,
|
||||
false, // don't store intermediates
|
||||
CertVerifier::FLAG_LOCAL_ONLY,
|
||||
&certList) != SECSuccess) {
|
||||
CertVerifier::FLAG_LOCAL_ONLY)
|
||||
!= SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
|
|
@ -103,9 +103,11 @@ nsUsageArrayHelper::check(uint32_t previousCheckResult,
|
|||
MOZ_CRASH("unknown cert usage passed to check()");
|
||||
}
|
||||
|
||||
ScopedCERTCertList unusedBuiltChain;
|
||||
SECStatus rv = certVerifier->VerifyCert(mCert, aCertUsage, time,
|
||||
nullptr /*XXX:wincx*/,
|
||||
nullptr /*hostname*/, flags);
|
||||
nullptr /*hostname*/,
|
||||
unusedBuiltChain, flags);
|
||||
|
||||
if (rv == SECSuccess) {
|
||||
typestr.Append(suffix);
|
||||
|
|
|
@ -59,9 +59,12 @@ function run_test() {
|
|||
// Expected outcomes (accept / reject):
|
||||
//
|
||||
// a b c d e
|
||||
// allowed=0 Acc Acc Acc Acc Acc
|
||||
// forbidden=1 Rej Rej Rej Rej Rej
|
||||
// onlyBefore2016=2 Acc Acc Rej Rej Rej
|
||||
// Allowed=0 Acc Acc Acc Acc Acc
|
||||
// Forbidden=1 Rej Rej Rej Rej Rej
|
||||
// Before2016=2 Acc Acc Rej Rej Rej
|
||||
//
|
||||
// The pref setting of ImportedRoot (3) accepts everything because the
|
||||
// testing root is an imported one. This will be addressed in bug 1240118.
|
||||
|
||||
// SHA-1 allowed
|
||||
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 0);
|
||||
|
@ -86,4 +89,13 @@ function run_test() {
|
|||
checkEndEntity(certFromFile("ee-post_int-pre"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
|
||||
checkIntermediate(certFromFile("int-post"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
|
||||
checkEndEntity(certFromFile("ee-post_int-post"), SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED);
|
||||
|
||||
// SHA-1 allowed only before 2016 or when issued by an imported root (which
|
||||
// happens to be all of our test certificates).
|
||||
Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 3);
|
||||
checkIntermediate(certFromFile("int-pre"), PRErrorCodeSuccess);
|
||||
checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess);
|
||||
checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess);
|
||||
checkIntermediate(certFromFile("int-post"), PRErrorCodeSuccess);
|
||||
checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess);
|
||||
}
|
||||
|
|
|
@ -8016,11 +8016,11 @@
|
|||
"n_values": 4,
|
||||
"description": "Does enforcing a larger minimum RSA key size cause verification failures? 1 = no, 2 = yes, 3 = another error prevented finding a verified chain"
|
||||
},
|
||||
"CERT_CHAIN_SIGNATURE_DIGEST_STATUS": {
|
||||
"CERT_CHAIN_SHA1_POLICY_STATUS": {
|
||||
"expires_in_version": "default",
|
||||
"kind": "enumerated",
|
||||
"n_values": 6,
|
||||
"description": "Information on weak signature digest algorithms in the chain: 1 = Only good algorithms, 2 = a weak algorithm was present in an end entity, 3 = a weak algorithm was present in a CA cert, 4 = a weak algorithm was present in both EE and CA certs, 5 = another error prevented signature algorithm from being determined"
|
||||
"description": "1 = No SHA1 signatures, 2 = SHA1 certificates issued before 2016, 3 = SHA1 certificates issued by an imported root, 4 = SHA1 certificates issued after 2015, 5 = another error prevented successful verification"
|
||||
},
|
||||
"WEAVE_CONFIGURED": {
|
||||
"expires_in_version": "default",
|
||||
|
|
Загрузка…
Ссылка в новой задаче