mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
bug 1245280 - add policy mechanism to optionally enforce BRs for falling back to subject CN r=Cykesiopka,mgoodwin
MozReview-Commit-ID: 7xT6JGpOH1g --HG-- extra : rebase_source : 0def29e8be898a2d975ee4390b3bc6a193766b1b
This commit is contained in:
parent
5753e3da83
commit
6e4140d766
@ -49,6 +49,20 @@ pref("security.pki.cert_short_lifetime_in_days", 10);
|
||||
// 3 = allow SHA-1 for certificates issued before 2016 or by an imported root.
|
||||
pref("security.pki.sha1_enforcement_level", 3);
|
||||
|
||||
// security.pki.name_matching_mode controls how the platform matches hostnames
|
||||
// to name information in TLS certificates. The possible values are:
|
||||
// 0: always fall back to the subject common name if necessary (as in, if the
|
||||
// subject alternative name extension is either not present or does not
|
||||
// contain any DNS names or IP addresses)
|
||||
// 1: fall back to the subject common name for certificates valid before 23
|
||||
// August 2016 if necessary
|
||||
// 2: 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
|
||||
|
||||
pref("security.webauth.u2f", false);
|
||||
pref("security.webauth.u2f.softtoken", false);
|
||||
pref("security.webauth.u2f.usbtoken", false);
|
||||
|
38
security/certverifier/BRNameMatchingPolicy.cpp
Normal file
38
security/certverifier/BRNameMatchingPolicy.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "BRNameMatchingPolicy.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
using namespace mozilla::psm;
|
||||
using namespace mozilla::pkix;
|
||||
|
||||
Result
|
||||
BRNameMatchingPolicy::FallBackToCommonName(
|
||||
Time notBefore,
|
||||
/*out*/ FallBackToSearchWithinSubject& fallBackToCommonName)
|
||||
{
|
||||
// (new Date("2016-08-23T00:00:00Z")).getTime() / 1000
|
||||
static const Time AUGUST_23_2016 = TimeFromEpochInSeconds(1471910400);
|
||||
switch (mMode)
|
||||
{
|
||||
case Mode::Enforce:
|
||||
fallBackToCommonName = FallBackToSearchWithinSubject::No;
|
||||
break;
|
||||
case Mode::EnforceAfter23August2016:
|
||||
fallBackToCommonName = notBefore > AUGUST_23_2016
|
||||
? FallBackToSearchWithinSubject::No
|
||||
: FallBackToSearchWithinSubject::Yes;
|
||||
break;
|
||||
case Mode::DoNotEnforce:
|
||||
fallBackToCommonName = FallBackToSearchWithinSubject::Yes;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Unexpected Mode");
|
||||
}
|
||||
return Success;
|
||||
}
|
56
security/certverifier/BRNameMatchingPolicy.h
Normal file
56
security/certverifier/BRNameMatchingPolicy.h
Normal file
@ -0,0 +1,56 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRNameMatchingPolicy_h
|
||||
#define BRNameMatchingPolicy_h
|
||||
|
||||
#include "pkix/pkixtypes.h"
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
// According to the Baseline Requirements version 1.3.3 section 7.1.4.2.2.a,
|
||||
// the requirements of the subject common name field are as follows:
|
||||
// "If present, this field MUST contain a single IP address or Fully‐Qualified
|
||||
// Domain Name that is one of the values contained in the Certificate’s
|
||||
// subjectAltName extension". Consequently, since any name information present
|
||||
// in the common name must be present in the subject alternative name extension,
|
||||
// when performing name matching, it should not be necessary to fall back to the
|
||||
// common name. Because this consequence has not commonly been enforced, this
|
||||
// implementation provides a mechanism to start enforcing it gradually while
|
||||
// maintaining some backwards compatibility. If configured with the mode
|
||||
// "EnforceAfter23August2016", name matching will only fall back to using the
|
||||
// subject common name for certificates where the notBefore field is before 23
|
||||
// August 2016.
|
||||
// Note that this implementation does not actually directly enforce that if the
|
||||
// subject common name is present, its value corresponds to a dNSName or
|
||||
// iPAddress entry in the subject alternative name extension.
|
||||
|
||||
class BRNameMatchingPolicy : public mozilla::pkix::NameMatchingPolicy
|
||||
{
|
||||
public:
|
||||
enum class Mode {
|
||||
DoNotEnforce = 0,
|
||||
EnforceAfter23August2016 = 1,
|
||||
Enforce = 2,
|
||||
};
|
||||
|
||||
explicit BRNameMatchingPolicy(Mode mode)
|
||||
: mMode(mode)
|
||||
{
|
||||
}
|
||||
|
||||
virtual mozilla::pkix::Result FallBackToCommonName(
|
||||
mozilla::pkix::Time notBefore,
|
||||
/*out*/ mozilla::pkix::FallBackToSearchWithinSubject& fallBacktoCommonName)
|
||||
override;
|
||||
|
||||
private:
|
||||
Mode mMode;
|
||||
};
|
||||
|
||||
} } // namespace mozilla::psm
|
||||
|
||||
#endif // BRNameMatchingPolicy_h
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "BRNameMatchingPolicy.h"
|
||||
#include "ExtendedValidation.h"
|
||||
#include "NSSCertDBTrustDomain.h"
|
||||
#include "NSSErrorsService.h"
|
||||
@ -38,13 +39,15 @@ CertVerifier::CertVerifier(OcspDownloadConfig odc,
|
||||
OcspGetConfig ogc,
|
||||
uint32_t certShortLifetimeInDays,
|
||||
PinningMode pinningMode,
|
||||
SHA1Mode sha1Mode)
|
||||
SHA1Mode sha1Mode,
|
||||
BRNameMatchingPolicy::Mode nameMatchingMode)
|
||||
: mOCSPDownloadConfig(odc)
|
||||
, mOCSPStrict(osc == ocspStrict)
|
||||
, mOCSPGETEnabled(ogc == ocspGetEnabled)
|
||||
, mCertShortLifetimeInDays(certShortLifetimeInDays)
|
||||
, mPinningMode(pinningMode)
|
||||
, mSHA1Mode(sha1Mode)
|
||||
, mNameMatchingMode(nameMatchingMode)
|
||||
{
|
||||
}
|
||||
|
||||
@ -716,7 +719,16 @@ CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert,
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
result = CheckCertHostname(peerCertInput, hostnameInput);
|
||||
bool isBuiltInRoot;
|
||||
result = IsCertChainRootBuiltInRoot(builtChain, isBuiltInRoot);
|
||||
if (result != Success) {
|
||||
PR_SetError(MapResultToPRErrorCode(result), 0);
|
||||
return SECFailure;
|
||||
}
|
||||
BRNameMatchingPolicy nameMatchingPolicy(
|
||||
isBuiltInRoot ? mNameMatchingMode
|
||||
: BRNameMatchingPolicy::Mode::DoNotEnforce);
|
||||
result = CheckCertHostname(peerCertInput, hostnameInput, nameMatchingPolicy);
|
||||
if (result != Success) {
|
||||
// Treat malformed name information as a domain mismatch.
|
||||
if (result == Result::ERROR_BAD_DER) {
|
||||
|
@ -7,10 +7,11 @@
|
||||
#ifndef mozilla_psm__CertVerifier_h
|
||||
#define mozilla_psm__CertVerifier_h
|
||||
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "pkix/pkixtypes.h"
|
||||
#include "BRNameMatchingPolicy.h"
|
||||
#include "OCSPCache.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "pkix/pkixtypes.h"
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
@ -121,7 +122,8 @@ public:
|
||||
|
||||
CertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
|
||||
OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
|
||||
PinningMode pinningMode, SHA1Mode sha1Mode);
|
||||
PinningMode pinningMode, SHA1Mode sha1Mode,
|
||||
BRNameMatchingPolicy::Mode nameMatchingMode);
|
||||
~CertVerifier();
|
||||
|
||||
void ClearOCSPCache() { mOCSPCache.Clear(); }
|
||||
@ -132,6 +134,7 @@ public:
|
||||
const uint32_t mCertShortLifetimeInDays;
|
||||
const PinningMode mPinningMode;
|
||||
const SHA1Mode mSHA1Mode;
|
||||
const BRNameMatchingPolicy::Mode mNameMatchingMode;
|
||||
|
||||
private:
|
||||
OCSPCache mOCSPCache;
|
||||
|
@ -5,11 +5,13 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
EXPORTS += [
|
||||
'BRNameMatchingPolicy.h',
|
||||
'CertVerifier.h',
|
||||
'OCSPCache.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'BRNameMatchingPolicy.cpp',
|
||||
'CertVerifier.cpp',
|
||||
'NSSCertDBTrustDomain.cpp',
|
||||
'OCSPCache.cpp',
|
||||
|
@ -96,41 +96,40 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "pkix/pkix.h"
|
||||
#include "pkix/pkixnss.h"
|
||||
#include "BRNameMatchingPolicy.h"
|
||||
#include "CertVerifier.h"
|
||||
#include "CryptoTask.h"
|
||||
#include "ExtendedValidation.h"
|
||||
#include "NSSCertDBTrustDomain.h"
|
||||
#include "nsIBadCertListener2.h"
|
||||
#include "nsICertOverrideService.h"
|
||||
#include "nsISiteSecurityService.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsNSSIOLayer.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsIThreadPool.h"
|
||||
#include "nsISocketProvider.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "PSMRunnable.h"
|
||||
#include "RootCertificateTelemetryUtils.h"
|
||||
#include "SharedSSLState.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsURLHelper.h"
|
||||
|
||||
#include "ssl.h"
|
||||
#include "cert.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/net/DNS.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsIBadCertListener2.h"
|
||||
#include "nsICertOverrideService.h"
|
||||
#include "nsISiteSecurityService.h"
|
||||
#include "nsISocketProvider.h"
|
||||
#include "nsIThreadPool.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsNSSIOLayer.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "nsXPCOMCIDInternal.h"
|
||||
#include "pkix/pkix.h"
|
||||
#include "pkix/pkixnss.h"
|
||||
#include "secerr.h"
|
||||
#include "secoidt.h"
|
||||
#include "secport.h"
|
||||
#include "ssl.h"
|
||||
#include "sslerr.h"
|
||||
|
||||
extern mozilla::LazyLogModule gPIPNSSLog;
|
||||
@ -432,13 +431,28 @@ DetermineCertOverrideErrors(CERTCertificate* cert, const char* hostName,
|
||||
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
|
||||
return SECFailure;
|
||||
}
|
||||
result = CheckCertHostname(certInput, hostnameInput);
|
||||
// Use a lax policy so as to not generate potentially spurious name
|
||||
// mismatch "hints".
|
||||
BRNameMatchingPolicy nameMatchingPolicy(
|
||||
BRNameMatchingPolicy::Mode::DoNotEnforce);
|
||||
// CheckCertHostname expects that its input represents a certificate that
|
||||
// has already been successfully validated by BuildCertChain. This is
|
||||
// obviously not the case, however, because we're in the error path of
|
||||
// certificate verification. Thus, this is problematic. In the future, it
|
||||
// would be nice to remove this optimistic additional error checking and
|
||||
// simply punt to the front-end, which can more easily (and safely) perform
|
||||
// extra checks to give the user hints as to why verification failed.
|
||||
result = CheckCertHostname(certInput, hostnameInput, nameMatchingPolicy);
|
||||
// Treat malformed name information as a domain mismatch.
|
||||
if (result == Result::ERROR_BAD_DER ||
|
||||
result == Result::ERROR_BAD_CERT_DOMAIN) {
|
||||
collectedErrors |= nsICertOverrideService::ERROR_MISMATCH;
|
||||
errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
|
||||
} else if (result != Success) {
|
||||
} else if (IsFatalError(result)) {
|
||||
// Because its input has not been validated by BuildCertChain,
|
||||
// CheckCertHostname can return an error that is less important than the
|
||||
// original certificate verification error. Only return an error result
|
||||
// from this function if we've encountered a fatal error.
|
||||
PR_SetError(MapResultToPRErrorCode(result), 0);
|
||||
return SECFailure;
|
||||
}
|
||||
|
@ -21,9 +21,10 @@ public:
|
||||
|
||||
SharedCertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc,
|
||||
OcspGetConfig ogc, uint32_t certShortLifetimeInDays,
|
||||
PinningMode pinningMode, SHA1Mode sha1Mode)
|
||||
PinningMode pinningMode, SHA1Mode sha1Mode,
|
||||
BRNameMatchingPolicy::Mode nameMatchingMode)
|
||||
: mozilla::psm::CertVerifier(odc, osc, ogc, certShortLifetimeInDays,
|
||||
pinningMode, sha1Mode)
|
||||
pinningMode, sha1Mode, nameMatchingMode)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
@ -872,6 +872,21 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting,
|
||||
break;
|
||||
default:
|
||||
sha1Mode = CertVerifier::SHA1Mode::Allowed;
|
||||
break;
|
||||
}
|
||||
|
||||
BRNameMatchingPolicy::Mode nameMatchingMode =
|
||||
static_cast<BRNameMatchingPolicy::Mode>
|
||||
(Preferences::GetInt("security.pki.name_matching_mode",
|
||||
static_cast<int32_t>(BRNameMatchingPolicy::Mode::DoNotEnforce)));
|
||||
switch (nameMatchingMode) {
|
||||
case BRNameMatchingPolicy::Mode::Enforce:
|
||||
case BRNameMatchingPolicy::Mode::EnforceAfter23August2016:
|
||||
case BRNameMatchingPolicy::Mode::DoNotEnforce:
|
||||
break;
|
||||
default:
|
||||
nameMatchingMode = BRNameMatchingPolicy::Mode::DoNotEnforce;
|
||||
break;
|
||||
}
|
||||
|
||||
CertVerifier::OcspDownloadConfig odc;
|
||||
@ -883,7 +898,8 @@ void nsNSSComponent::setValidationOptions(bool isInitialSetting,
|
||||
lock);
|
||||
mDefaultCertVerifier = new SharedCertVerifier(odc, osc, ogc,
|
||||
certShortLifetimeInDays,
|
||||
pinningMode, sha1Mode);
|
||||
pinningMode, sha1Mode,
|
||||
nameMatchingMode);
|
||||
}
|
||||
|
||||
// Enable the TLS versions given in the prefs, defaulting to TLS 1.0 (min) and
|
||||
@ -1321,7 +1337,8 @@ nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
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.sha1_enforcement_level") ||
|
||||
prefName.EqualsLiteral("security.pki.name_matching_mode")) {
|
||||
MutexAutoLock lock(mutex);
|
||||
setValidationOptions(false, lock);
|
||||
#ifdef DEBUG
|
||||
|
@ -12,6 +12,7 @@ if not CONFIG['MOZ_NO_SMART_CARDS']:
|
||||
TEST_DIRS += [
|
||||
'bad_certs',
|
||||
'ocsp_certs',
|
||||
'test_baseline_requirements',
|
||||
'test_cert_eku',
|
||||
'test_cert_embedded_null',
|
||||
'test_cert_keyUsage',
|
||||
|
@ -29,7 +29,7 @@ keyUsage:[digitalSignature,nonRepudiation,keyEncipherment,
|
||||
extKeyUsage:[serverAuth,clientAuth,codeSigning,emailProtection
|
||||
nsSGC, # Netscape Server Gated Crypto
|
||||
OCSPSigning,timeStamping]
|
||||
subjectAlternativeName:[<dNSName>,...]
|
||||
subjectAlternativeName:[<dNSName|directoryName>,...]
|
||||
authorityInformationAccess:<OCSP URI>
|
||||
certificatePolicies:<policy OID>
|
||||
nameConstraints:{permitted,excluded}:[<dNSName|directoryName>,...]
|
||||
@ -531,14 +531,19 @@ class Certificate(object):
|
||||
extKeyUsageExtension.setComponentByPosition(count, self.keyPurposeToOID(keyPurpose))
|
||||
self.addExtension(rfc2459.id_ce_extKeyUsage, extKeyUsageExtension, critical)
|
||||
|
||||
def addSubjectAlternativeName(self, dNSNames, critical):
|
||||
def addSubjectAlternativeName(self, names, critical):
|
||||
subjectAlternativeName = rfc2459.SubjectAltName()
|
||||
for count, dNSName in enumerate(dNSNames.split(',')):
|
||||
for count, name in enumerate(names.split(',')):
|
||||
generalName = rfc2459.GeneralName()
|
||||
# The string may have things like '\0' (i.e. a slash
|
||||
# followed by the number zero) that have to be decoded into
|
||||
# the resulting '\x00' (i.e. a byte with value zero).
|
||||
generalName.setComponentByName('dNSName', dNSName.decode(encoding='string_escape'))
|
||||
if '/' in name:
|
||||
directoryName = stringToDN(name,
|
||||
tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))
|
||||
generalName.setComponentByName('directoryName', directoryName)
|
||||
else:
|
||||
# The string may have things like '\0' (i.e. a slash
|
||||
# followed by the number zero) that have to be decoded into
|
||||
# the resulting '\x00' (i.e. a byte with value zero).
|
||||
generalName.setComponentByName('dNSName', name.decode(encoding='string_escape'))
|
||||
subjectAlternativeName.setComponentByPosition(count, generalName)
|
||||
self.addExtension(rfc2459.id_ce_subjectAltName, subjectAlternativeName, critical)
|
||||
|
||||
|
@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICxTCCAa+gAwIBAgIUQy+m6w0ZtMTfbmtELQQz8zwqCAowCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTQxMTI3MDAwMDAwWhgPMjAxNzAyMDQwMDAw
|
||||
MDBaMA0xCzAJBgNVBAMMAmNhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
|
||||
AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu
|
||||
Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO
|
||||
7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf
|
||||
qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt
|
||||
HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx
|
||||
uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1Ud
|
||||
DwQEAwIBBjALBgkqhkiG9w0BAQsDggEBAJQcekrdR+S6U0I3owUQxVOoUJMzHdTj
|
||||
u562Ra7cOiJQwe1OQZbvo6rQkQWPrpuDOGpwwr1+HBMGb8mjUqeFo5wIinU003TC
|
||||
UYYEpDCbPwXOKDkDUukKd1aO4wpJc/v8YIiCz7aCRj9HQ3L5YO5JsgMNSCXKKoUm
|
||||
ILcz2V+IQZ6lePzFfd2aO3zLMDPwEOyujYYtQnBVZIT4F/x/6nU8E6bkbDSGPjQW
|
||||
CSVhwa0YQ9lCRSM6e//wGry4i8X8718t1V+Nqh7y6u7UlOrXbNEA4pR6mvJsqPhF
|
||||
Mj82We4OGNBxXbyuGJObQgLBfmRuwKQT9SNtKWEifiaTw8apT/fBagc=
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,4 @@
|
||||
issuer:ca
|
||||
subject:ca
|
||||
extension:basicConstraints:cA,
|
||||
extension:keyUsage:cRLSign,keyCertSign
|
@ -0,0 +1,17 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Temporarily disabled. See bug 1256495.
|
||||
#test_certificates = (
|
||||
# 'ca.pem',
|
||||
# 'no-san-old.pem',
|
||||
# 'no-san-recent.pem',
|
||||
# 'san-contains-no-hostnames-old.pem',
|
||||
# 'san-contains-no-hostnames-recent.pem',
|
||||
#)
|
||||
#
|
||||
#for test_certificate in test_certificates:
|
||||
# GeneratedTestCertificate(test_certificate)
|
@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICrzCCAZmgAwIBAgIUS00fexo4Y4FagP1oiKQiGCJKd/swCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTYwNzI0MDAwMDAwWhgPMjAxNjA5MjQwMDAw
|
||||
MDBaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo
|
||||
4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD
|
||||
SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX
|
||||
kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx
|
||||
owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/
|
||||
Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMAsGCSqGSIb3DQEBCwOC
|
||||
AQEAnooFCIG4D5EQxpe6EcB3gXE2Cj5kMBvO5H+OobaVRd4kIxET+MChwsN2nuwy
|
||||
xooA/P2M+9W/S3KP/K8L1tlyf/8J2xlr349MhULhCKG7XxpEQZl6sVjaeDLwWrEK
|
||||
2Ts1jPgCTufdfPYBcO3rb4HSdHNfFlhB98dfgSakXqXzUZ9sz2VxmAeL6tLvspG9
|
||||
tH5viWFc+lv1J3/Jtzk79hleDsiIdcjTjC/bM/Y49jkNOBxru4Qrw5AZuveoVy/G
|
||||
2axz89wBpjLYjI0KtVxCf8dutcVW7UwFKQywmo7QDqha61f0f8I6oCYXsDPK9FPf
|
||||
WLIrK1TT3YxdhN7QIRu6J8ttBQ==
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,3 @@
|
||||
issuer:ca
|
||||
subject:example.com
|
||||
validity:20160724-20160924
|
@ -0,0 +1,17 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICrzCCAZmgAwIBAgIUWxGwhSb8roUQoLNpJajl0X8jk10wCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTYwODI0MDAwMDAwWhgPMjAxNjA5MjQwMDAw
|
||||
MDBaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo
|
||||
4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD
|
||||
SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX
|
||||
kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx
|
||||
owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/
|
||||
Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMAsGCSqGSIb3DQEBCwOC
|
||||
AQEADs0POeb1wJthEcg1nRYRcPgcNHsV1yVCkHMyfmssA1rgWXsp93PRVaCyZYgI
|
||||
Dq+8QJtAYpdcChFcEYeGjcjLv49Dh+yiiZPPbRWKJB0y3v+13A74M1q+IQFoQWAh
|
||||
L5GzAEjApsB1j/csRfDNjIwcP1WApN1iZ2NPxFU+PAIFhcmm+uD2doDtQfpMN9vi
|
||||
HEg5H1x7JOufOZlN+zbnPK+Ob7N13pFd/P/IO8XhA/X8by4G45oh0deyELf9zVcW
|
||||
4flslHPYthp4LDEyPvTP52jHn/yTO/m8cxKmCZOuwiw4DWfSVUy6irUs8W5SlfS8
|
||||
gI2Ctb+G5YvSffsPYwkUg3Hg7g==
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,3 @@
|
||||
issuer:ca
|
||||
subject:example.com
|
||||
validity:20160824-20160924
|
@ -0,0 +1,18 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC4TCCAcugAwIBAgIUL/Gibj3iILbh9idTh3u9XTSwzqIwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTYwNzI0MDAwMDAwWhgPMjAxNjA5MjQwMDAw
|
||||
MDBaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo
|
||||
4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD
|
||||
SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX
|
||||
kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx
|
||||
owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/
|
||||
Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozAwLjAsBgNVHREEJTAj
|
||||
pCEwHzEdMBsGA1UECgwURXhhbXBsZSBPcmdhbml6YXRpb24wCwYJKoZIhvcNAQEL
|
||||
A4IBAQAtCjzHSdXdAyaC5Qyw77gFwQKECHDAimgze1Nvgkyiv4LJLSuFZ84jnLIL
|
||||
PM+iRxrxeBOdNy8PNIaDadFb5NoovmdLTG08ZjNjJoXOt5JufIHQrUzrcZy1aP7z
|
||||
rWXED1QcwyKkoOAOqr5hOZ3pmu67a1vJgjZ8H4dVhfFkmSVGPG/6mTvn9H4N/AEo
|
||||
K+M7BW1WMnNexsV5mMvlUUdfZP0J3o9oI9msH6uH92xU6jIHpgcm6plXfpOBGQfB
|
||||
g6EUGD4znDe24ljbaohFATWw5c09kkOQNg/H6DQpb1Vi6k+X62Zgj5UR79zx53e+
|
||||
3Wo3Iu+hJUfNwyNk7KVF+r1wsUdA
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,4 @@
|
||||
issuer:ca
|
||||
subject:example.com
|
||||
validity:20160724-20160924
|
||||
extension:subjectAlternativeName:/O=Example Organization
|
@ -0,0 +1,18 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIC4TCCAcugAwIBAgIUUwz+d++GVy8L6Lxi9GVnzG6yUCEwCwYJKoZIhvcNAQEL
|
||||
MA0xCzAJBgNVBAMMAmNhMCIYDzIwMTYwODI0MDAwMDAwWhgPMjAxNjA5MjQwMDAw
|
||||
MDBaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOC
|
||||
AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo
|
||||
4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD
|
||||
SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX
|
||||
kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx
|
||||
owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/
|
||||
Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozAwLjAsBgNVHREEJTAj
|
||||
pCEwHzEdMBsGA1UECgwURXhhbXBsZSBPcmdhbml6YXRpb24wCwYJKoZIhvcNAQEL
|
||||
A4IBAQCdKXA+1XhcpKdyjeJjEEUm9ptoS8tKJt/vdGUPCByzlD71OJGsiXorTcGY
|
||||
V2sgbGCmxA8dnxG8bPQMFdAZ2hRjWjZ/Hs18SDbMAONjzgiPlwUWRZldb2Th7WX3
|
||||
7a+1uMsT1rEsgmip7FuJjqW0qEyuHFRTt47aK0GJRX42VC5kJVMX8ujl8ucqSSNa
|
||||
PRh6IPQgIxSchu79weP+YIxMz3GDvNuu6z4QWdkzQrnYqSJpLgNGPAdAxFCgsok3
|
||||
5rFNhadGNv6RqrG00HmXPBTTq6T8rQEsbQZQZ4eensb0HxdiQyX4XGnMeEpElTwO
|
||||
LHziGIW2jBA9v5FJVBCC9QQysNby
|
||||
-----END CERTIFICATE-----
|
@ -0,0 +1,4 @@
|
||||
issuer:ca
|
||||
subject:example.com
|
||||
validity:20160824-20160924
|
||||
extension:subjectAlternativeName:/O=Example Organization
|
@ -0,0 +1,131 @@
|
||||
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// The preference security.pki.name_matching_mode controls whether or not
|
||||
// mozilla::pkix will fall back to using a certificate's subject common name
|
||||
// during name matching. If the Baseline Requirements are followed, fallback
|
||||
// should not be necessary (because any name information in the subject common
|
||||
// name should be present in the subject alternative name extension). Due to
|
||||
// compatibility concerns, the platform can be configured to fall back for
|
||||
// certificates that are valid before 23 August 2016. Note that for certificates
|
||||
// issued by an imported root, the platform will fall back if necessary,
|
||||
// regardless of the value of the preference.
|
||||
|
||||
"use strict";
|
||||
|
||||
do_get_profile(); // must be called before getting nsIX509CertDB
|
||||
const gCertDB = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
|
||||
function certFromFile(certName) {
|
||||
return constructCertFromFile(`test_baseline_requirements/${certName}.pem`);
|
||||
}
|
||||
|
||||
function loadCertWithTrust(certName, trustString) {
|
||||
addCertFromFile(gCertDB, `test_baseline_requirements/${certName}.pem`,
|
||||
trustString);
|
||||
}
|
||||
|
||||
function checkCertOn25August2016(cert, expectedResult) {
|
||||
// (new Date("2016-08-25T00:00:00Z")).getTime() / 1000
|
||||
const VALIDATION_TIME = 1472083200;
|
||||
checkCertErrorGenericAtTime(gCertDB, cert, expectedResult,
|
||||
certificateUsageSSLServer, VALIDATION_TIME, {},
|
||||
"example.com");
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
do_register_cleanup(() => {
|
||||
Services.prefs.clearUserPref("security.pki.name_matching_mode");
|
||||
Services.prefs.clearUserPref("security.test.built_in_root_hash");
|
||||
});
|
||||
|
||||
loadCertWithTrust("ca", "CTu,,");
|
||||
|
||||
// When verifying a certificate, if the trust anchor is not a built-in root,
|
||||
// name matching will fall back to using the subject common name if necessary
|
||||
// (i.e. if there is no subject alternative name extension or it does not
|
||||
// contain any dNSName or iPAddress entries). Thus, since imported roots are
|
||||
// not in general treated as built-ins, these should all successfully verify
|
||||
// regardless of the value of the pref.
|
||||
Services.prefs.setIntPref("security.pki.name_matching_mode", 0);
|
||||
do_print("current mode: always fall back, root not built-in");
|
||||
checkCertOn25August2016(certFromFile("no-san-recent"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("no-san-old"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-recent"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-old"),
|
||||
PRErrorCodeSuccess);
|
||||
|
||||
Services.prefs.setIntPref("security.pki.name_matching_mode", 1);
|
||||
do_print("current mode: fall back for notBefore < August 23, 2016, root " +
|
||||
"not built-in");
|
||||
checkCertOn25August2016(certFromFile("no-san-recent"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("no-san-old"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-recent"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-old"),
|
||||
PRErrorCodeSuccess);
|
||||
|
||||
Services.prefs.setIntPref("security.pki.name_matching_mode", 2);
|
||||
do_print("current mode: never fall back, root not built-in");
|
||||
checkCertOn25August2016(certFromFile("no-san-recent"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("no-san-old"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-recent"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-old"),
|
||||
PRErrorCodeSuccess);
|
||||
|
||||
// In debug builds, we can treat an imported root as a built-in, and thus we
|
||||
// can actually test the different values of the pref.
|
||||
if (isDebugBuild) {
|
||||
let root = certFromFile("ca");
|
||||
Services.prefs.setCharPref("security.test.built_in_root_hash",
|
||||
root.sha256Fingerprint);
|
||||
|
||||
// Always fall back if necessary.
|
||||
Services.prefs.setIntPref("security.pki.name_matching_mode", 0);
|
||||
do_print("current mode: always fall back, root built-in");
|
||||
checkCertOn25August2016(certFromFile("no-san-recent"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("no-san-old"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-recent"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-old"),
|
||||
PRErrorCodeSuccess);
|
||||
|
||||
// Only fall back if notBefore < 23 August 2016
|
||||
Services.prefs.setIntPref("security.pki.name_matching_mode", 1);
|
||||
do_print("current mode: fall back for notBefore < August 23, 2016, root " +
|
||||
"built-in");
|
||||
checkCertOn25August2016(certFromFile("no-san-recent"),
|
||||
SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
checkCertOn25August2016(certFromFile("no-san-old"),
|
||||
PRErrorCodeSuccess);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-recent"),
|
||||
SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-old"),
|
||||
PRErrorCodeSuccess);
|
||||
|
||||
// Never fall back.
|
||||
Services.prefs.setIntPref("security.pki.name_matching_mode", 2);
|
||||
do_print("current mode: never fall back, root built-in");
|
||||
checkCertOn25August2016(certFromFile("no-san-recent"),
|
||||
SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
checkCertOn25August2016(certFromFile("no-san-old"),
|
||||
SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-recent"),
|
||||
SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
checkCertOn25August2016(certFromFile("san-contains-no-hostnames-old"),
|
||||
SSL_ERROR_BAD_CERT_DOMAIN);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ tags = psm
|
||||
support-files =
|
||||
bad_certs/**
|
||||
ocsp_certs/**
|
||||
test_baseline_requirements/**
|
||||
test_cert_eku/**
|
||||
test_cert_embedded_null/**
|
||||
test_cert_keyUsage/**
|
||||
@ -29,6 +30,7 @@ support-files =
|
||||
tlsserver/**
|
||||
|
||||
[test_add_preexisting_cert.js]
|
||||
[test_baseline_requirements_subject_common_name.js]
|
||||
[test_cert_blocklist.js]
|
||||
skip-if = buildapp == "b2g"
|
||||
tags = addons psm
|
||||
|
@ -116,7 +116,8 @@ Result BuildCertChain(TrustDomain& trustDomain, Input cert,
|
||||
// - IP addresses are out of scope of RFC 6125, but this method accepts them for
|
||||
// backward compatibility (see SearchNames in pkixnames.cpp)
|
||||
// - A wildcard in a DNS-ID may only appear as the entirety of the first label.
|
||||
Result CheckCertHostname(Input cert, Input hostname);
|
||||
Result CheckCertHostname(Input cert, Input hostname,
|
||||
NameMatchingPolicy& nameMatchingPolicy);
|
||||
|
||||
// Construct an RFC-6960-encoded OCSP request, ready for submission to a
|
||||
// responder, for the provided CertID. The request has no extensions.
|
||||
|
@ -349,6 +349,30 @@ protected:
|
||||
void operator=(const TrustDomain&) = delete;
|
||||
};
|
||||
|
||||
enum class FallBackToSearchWithinSubject { No = 0, Yes = 1 };
|
||||
|
||||
// Applications control the behavior of matching presented name information from
|
||||
// a certificate against a reference hostname by implementing the
|
||||
// NameMatchingPolicy interface. Used in concert with CheckCertHostname.
|
||||
class NameMatchingPolicy
|
||||
{
|
||||
public:
|
||||
virtual ~NameMatchingPolicy() { }
|
||||
|
||||
// Given that the certificate in question has a notBefore field with the given
|
||||
// value, should name matching fall back to searching within the subject
|
||||
// common name field?
|
||||
virtual Result FallBackToCommonName(
|
||||
Time notBefore,
|
||||
/*out*/ FallBackToSearchWithinSubject& fallBackToCommonName) = 0;
|
||||
|
||||
protected:
|
||||
NameMatchingPolicy() { }
|
||||
|
||||
NameMatchingPolicy(const NameMatchingPolicy&) = delete;
|
||||
void operator=(const NameMatchingPolicy&) = delete;
|
||||
};
|
||||
|
||||
} } // namespace mozilla::pkix
|
||||
|
||||
#endif // mozilla_pkix_pkixtypes_h
|
||||
|
@ -114,8 +114,6 @@ ReadGeneralName(Reader& reader,
|
||||
return Success;
|
||||
}
|
||||
|
||||
enum class FallBackToSearchWithinSubject { No = 0, Yes = 1 };
|
||||
|
||||
enum class MatchResult
|
||||
{
|
||||
NoNamesOfGivenType = 0,
|
||||
@ -219,7 +217,8 @@ MatchPresentedDNSIDWithReferenceDNSID(Input presentedDNSID,
|
||||
// assumed to be a string representation of an IPv4 address, an IPv6 addresss,
|
||||
// or a normalized ASCII (possibly punycode) DNS name.
|
||||
Result
|
||||
CheckCertHostname(Input endEntityCertDER, Input hostname)
|
||||
CheckCertHostname(Input endEntityCertDER, Input hostname,
|
||||
NameMatchingPolicy& nameMatchingPolicy)
|
||||
{
|
||||
BackCert cert(endEntityCertDER, EndEntityOrCA::MustBeEndEntity, nullptr);
|
||||
Result rv = cert.Init();
|
||||
@ -227,10 +226,22 @@ CheckCertHostname(Input endEntityCertDER, Input hostname)
|
||||
return rv;
|
||||
}
|
||||
|
||||
Time notBefore(Time::uninitialized);
|
||||
rv = ParseValidity(cert.GetValidity(), ¬Before);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
FallBackToSearchWithinSubject fallBackToSearchWithinSubject;
|
||||
rv = nameMatchingPolicy.FallBackToCommonName(notBefore,
|
||||
fallBackToSearchWithinSubject);
|
||||
if (rv != Success) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
const Input* subjectAltName(cert.GetSubjectAltName());
|
||||
Input subject(cert.GetSubject());
|
||||
|
||||
// For backward compatibility with legacy certificates, we fall back to
|
||||
// For backward compatibility with legacy certificates, we may fall back to
|
||||
// searching for a name match in the subject common name for DNS names and
|
||||
// IPv4 addresses. We don't do so for IPv6 addresses because we do not think
|
||||
// there are many certificates that would need such fallback, and because
|
||||
@ -244,13 +255,13 @@ CheckCertHostname(Input endEntityCertDER, Input hostname)
|
||||
uint8_t ipv4[4];
|
||||
if (IsValidReferenceDNSID(hostname)) {
|
||||
rv = SearchNames(subjectAltName, subject, GeneralNameType::dNSName,
|
||||
hostname, FallBackToSearchWithinSubject::Yes, match);
|
||||
hostname, fallBackToSearchWithinSubject, match);
|
||||
} else if (ParseIPv6Address(hostname, ipv6)) {
|
||||
rv = SearchNames(subjectAltName, subject, GeneralNameType::iPAddress,
|
||||
Input(ipv6), FallBackToSearchWithinSubject::No, match);
|
||||
} else if (ParseIPv4Address(hostname, ipv4)) {
|
||||
rv = SearchNames(subjectAltName, subject, GeneralNameType::iPAddress,
|
||||
Input(ipv4), FallBackToSearchWithinSubject::Yes, match);
|
||||
Input(ipv4), fallBackToSearchWithinSubject, match);
|
||||
} else {
|
||||
return Result::ERROR_BAD_CERT_DOMAIN;
|
||||
}
|
||||
|
@ -217,6 +217,17 @@ class DefaultCryptoTrustDomain : public EverythingFailsByDefaultTrustDomain
|
||||
}
|
||||
};
|
||||
|
||||
class DefaultNameMatchingPolicy : public NameMatchingPolicy
|
||||
{
|
||||
public:
|
||||
virtual Result FallBackToCommonName(
|
||||
Time, /*out*/ FallBackToSearchWithinSubject& fallBackToCommonName) override
|
||||
{
|
||||
fallBackToCommonName = FallBackToSearchWithinSubject::Yes;
|
||||
return Success;
|
||||
}
|
||||
};
|
||||
|
||||
} } } // namespace mozilla::pkix::test
|
||||
|
||||
#endif // mozilla_pkix_pkixgtest_h
|
||||
|
@ -902,6 +902,8 @@ class pkixnames_MatchPresentedDNSIDWithReferenceDNSID
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<PresentedMatchesReference>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
TEST_P(pkixnames_MatchPresentedDNSIDWithReferenceDNSID,
|
||||
@ -937,6 +939,8 @@ class pkixnames_Turkish_I_Comparison
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<InputValidity>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
TEST_P(pkixnames_Turkish_I_Comparison, MatchPresentedDNSIDWithReferenceDNSID)
|
||||
@ -982,6 +986,8 @@ class pkixnames_IsValidReferenceDNSID
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<InputValidity>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
TEST_P(pkixnames_IsValidReferenceDNSID, IsValidReferenceDNSID)
|
||||
@ -1006,6 +1012,8 @@ class pkixnames_ParseIPv4Address
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<IPAddressParams<4>>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
TEST_P(pkixnames_ParseIPv4Address, ParseIPv4Address)
|
||||
@ -1032,6 +1040,8 @@ class pkixnames_ParseIPv6Address
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<IPAddressParams<16>>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
TEST_P(pkixnames_ParseIPv6Address, ParseIPv6Address)
|
||||
@ -1074,6 +1084,8 @@ class pkixnames_CheckCertHostname
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<CheckCertHostnameParams>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
#define WITH_SAN(r, ps, psan, result) \
|
||||
@ -1578,7 +1590,8 @@ TEST_P(pkixnames_CheckCertHostname, CheckCertHostname)
|
||||
ASSERT_EQ(Success, hostnameInput.Init(param.hostname.data(),
|
||||
param.hostname.length()));
|
||||
|
||||
ASSERT_EQ(param.result, CheckCertHostname(certInput, hostnameInput));
|
||||
ASSERT_EQ(param.result, CheckCertHostname(certInput, hostnameInput,
|
||||
mNameMatchingPolicy));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(pkixnames_CheckCertHostname,
|
||||
@ -1610,13 +1623,15 @@ TEST_F(pkixnames_CheckCertHostname, SANWithoutSequence)
|
||||
|
||||
static const uint8_t a[] = { 'a' };
|
||||
ASSERT_EQ(Result::ERROR_EXTENSION_VALUE_INVALID,
|
||||
CheckCertHostname(certInput, Input(a)));
|
||||
CheckCertHostname(certInput, Input(a), mNameMatchingPolicy));
|
||||
}
|
||||
|
||||
class pkixnames_CheckCertHostname_PresentedMatchesReference
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<PresentedMatchesReference>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
TEST_P(pkixnames_CheckCertHostname_PresentedMatchesReference, CN_NoSAN)
|
||||
@ -1636,7 +1651,7 @@ TEST_P(pkixnames_CheckCertHostname_PresentedMatchesReference, CN_NoSAN)
|
||||
param.referenceDNSID.length()));
|
||||
|
||||
ASSERT_EQ(param.expectedMatches ? Success : Result::ERROR_BAD_CERT_DOMAIN,
|
||||
CheckCertHostname(certInput, hostnameInput));
|
||||
CheckCertHostname(certInput, hostnameInput, mNameMatchingPolicy));
|
||||
}
|
||||
|
||||
TEST_P(pkixnames_CheckCertHostname_PresentedMatchesReference,
|
||||
@ -1660,7 +1675,8 @@ TEST_P(pkixnames_CheckCertHostname_PresentedMatchesReference,
|
||||
= param.expectedResult != Success ? param.expectedResult
|
||||
: param.expectedMatches ? Success
|
||||
: Result::ERROR_BAD_CERT_DOMAIN;
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, hostnameInput));
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, hostnameInput,
|
||||
mNameMatchingPolicy));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(pkixnames_CheckCertHostname_DNSID_MATCH_PARAMS,
|
||||
@ -1689,8 +1705,10 @@ TEST_P(pkixnames_Turkish_I_Comparison, CheckCertHostname_CN_NoSAN)
|
||||
? Success
|
||||
: Result::ERROR_BAD_CERT_DOMAIN;
|
||||
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, UPPERCASE_I));
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, LOWERCASE_I));
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, UPPERCASE_I,
|
||||
mNameMatchingPolicy));
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, LOWERCASE_I,
|
||||
mNameMatchingPolicy));
|
||||
}
|
||||
|
||||
TEST_P(pkixnames_Turkish_I_Comparison, CheckCertHostname_SAN)
|
||||
@ -1716,14 +1734,18 @@ TEST_P(pkixnames_Turkish_I_Comparison, CheckCertHostname_SAN)
|
||||
InputsAreEqual(UPPERCASE_I, input)) ? Success
|
||||
: Result::ERROR_BAD_CERT_DOMAIN;
|
||||
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, UPPERCASE_I));
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, LOWERCASE_I));
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, UPPERCASE_I,
|
||||
mNameMatchingPolicy));
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, LOWERCASE_I,
|
||||
mNameMatchingPolicy));
|
||||
}
|
||||
|
||||
class pkixnames_CheckCertHostname_IPV4_Addresses
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<IPAddressParams<4>>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
TEST_P(pkixnames_CheckCertHostname_IPV4_Addresses,
|
||||
@ -1745,7 +1767,7 @@ TEST_P(pkixnames_CheckCertHostname_IPV4_Addresses,
|
||||
param.input.length()));
|
||||
|
||||
ASSERT_EQ(param.isValid ? Success : Result::ERROR_BAD_CERT_DOMAIN,
|
||||
CheckCertHostname(certInput, hostnameInput));
|
||||
CheckCertHostname(certInput, hostnameInput, mNameMatchingPolicy));
|
||||
}
|
||||
|
||||
TEST_P(pkixnames_CheckCertHostname_IPV4_Addresses,
|
||||
@ -1772,7 +1794,8 @@ TEST_P(pkixnames_CheckCertHostname_IPV4_Addresses,
|
||||
? Success
|
||||
: Result::ERROR_BAD_CERT_DOMAIN;
|
||||
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, hostnameInput));
|
||||
ASSERT_EQ(expectedResult, CheckCertHostname(certInput, hostnameInput,
|
||||
mNameMatchingPolicy));
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(pkixnames_CheckCertHostname_IPV4_ADDRESSES,
|
||||
@ -2572,6 +2595,8 @@ class pkixnames_CheckNameConstraints
|
||||
: public ::testing::Test
|
||||
, public ::testing::WithParamInterface<NameConstraintParams>
|
||||
{
|
||||
public:
|
||||
DefaultNameMatchingPolicy mNameMatchingPolicy;
|
||||
};
|
||||
|
||||
TEST_P(pkixnames_CheckNameConstraints,
|
||||
|
Loading…
Reference in New Issue
Block a user