Bug 975122: Allow cert error overrides when insanity::pkix is used, r?cviecco, r?keeler

--HG--
extra : rebase_source : 47f5e779a16c462e40baa2d9cec2e83946c9076c
This commit is contained in:
Brian Smith 2014-02-22 19:08:06 -08:00
Родитель 0a4df845e2
Коммит c3a50adf07
13 изменённых файлов: 402 добавлений и 122 удалений

Просмотреть файл

@ -746,6 +746,8 @@ CertVerifier::VerifySSLServerCert(CERTCertificate* peerCert,
return SECFailure;
}
// CreateCertErrorRunnable assumes that CERT_VerifyCertName is only called
// if VerifyCert succeeded.
ScopedCERTCertList validationChain;
SECStatus rv = VerifyCert(peerCert, stapledOCSPResponse,
certificateUsageSSLServer, time,

Просмотреть файл

@ -33,7 +33,7 @@ interface nsIOpenSignedAppFileCallback : nsISupports
* This represents a service to access and manipulate
* X.509 certificates stored in a database.
*/
[scriptable, uuid(398dfa21-f29d-4530-bb42-136c6e7d9486)]
[scriptable, uuid(7446a5b1-84ca-491f-a2fe-0bc60a71ffa5)]
interface nsIX509CertDB : nsISupports {
/**
@ -197,6 +197,14 @@ interface nsIX509CertDB : nsISupports {
in unsigned long type,
in unsigned long trust);
/**
* @param cert The certificate for which to modify trust.
* @param trustString decoded by CERT_DecodeTrustString. 3 comma separated
* characters, indicating SSL, Email, and Obj signing
* trust.
*/
void setCertTrustFromString(in nsIX509Cert3 cert, in string trustString);
/**
* Query whether a certificate is trusted for a particular use.
*

Просмотреть файл

@ -303,7 +303,6 @@ MapCertErrorToProbeValue(PRErrorCode errorCode)
case SEC_ERROR_UNTRUSTED_ISSUER: return 4;
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: return 5;
case SEC_ERROR_UNTRUSTED_CERT: return 6;
case SEC_ERROR_INADEQUATE_KEY_USAGE: return 7;
case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: return 8;
case SSL_ERROR_BAD_CERT_DOMAIN: return 9;
case SEC_ERROR_EXPIRED_CERTIFICATE: return 10;
@ -313,6 +312,79 @@ MapCertErrorToProbeValue(PRErrorCode errorCode)
return 0;
}
SECStatus
InsanityDetermineCertOverrideErrors(CERTCertificate* cert,
const char* hostName, PRTime now,
PRErrorCode defaultErrorCodeToReport,
/*out*/ uint32_t& collectedErrors,
/*out*/ PRErrorCode& errorCodeTrust,
/*out*/ PRErrorCode& errorCodeMismatch,
/*out*/ PRErrorCode& errorCodeExpired)
{
MOZ_ASSERT(cert);
MOZ_ASSERT(hostName);
MOZ_ASSERT(collectedErrors == 0);
MOZ_ASSERT(errorCodeTrust == 0);
MOZ_ASSERT(errorCodeMismatch == 0);
MOZ_ASSERT(errorCodeExpired == 0);
// Assumes the error prioritization described in insanity::pkix's
// BuildForward function. Also assumes that CERT_VerifyCertName was only
// called if CertVerifier::VerifyCert succeeded.
switch (defaultErrorCodeToReport) {
case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
case SEC_ERROR_UNKNOWN_ISSUER:
{
collectedErrors = nsICertOverrideService::ERROR_UNTRUSTED;
errorCodeTrust = defaultErrorCodeToReport;
SECCertTimeValidity validity = CERT_CheckCertValidTimes(cert, now, false);
if (validity == secCertTimeUndetermined) {
PR_SetError(defaultErrorCodeToReport, 0);
return SECFailure;
}
if (validity != secCertTimeValid) {
collectedErrors |= nsICertOverrideService::ERROR_TIME;
errorCodeExpired = SEC_ERROR_EXPIRED_CERTIFICATE;
}
break;
}
case SEC_ERROR_EXPIRED_CERTIFICATE:
collectedErrors = nsICertOverrideService::ERROR_TIME;
errorCodeExpired = SEC_ERROR_EXPIRED_CERTIFICATE;
break;
case SSL_ERROR_BAD_CERT_DOMAIN:
collectedErrors = nsICertOverrideService::ERROR_MISMATCH;
errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
break;
case 0:
NS_ERROR("No error code set during certificate validation failure.");
PR_SetError(PR_INVALID_STATE_ERROR, 0);
return SECFailure;
default:
PR_SetError(defaultErrorCodeToReport, 0);
return SECFailure;
}
if (defaultErrorCodeToReport != SSL_ERROR_BAD_CERT_DOMAIN) {
if (CERT_VerifyCertName(cert, hostName) != SECSuccess) {
if (PR_GetError() != SSL_ERROR_BAD_CERT_DOMAIN) {
PR_SetError(defaultErrorCodeToReport, 0);
return SECFailure;
}
collectedErrors |= nsICertOverrideService::ERROR_MISMATCH;
errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
}
}
return SECSuccess;
}
SSLServerCertVerificationResult*
CertErrorRunnable::CheckCertOverrides()
{
@ -494,7 +566,6 @@ PRErrorCodeToOverrideType(PRErrorCode errorCode)
case SEC_ERROR_UNTRUSTED_ISSUER:
case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE:
case SEC_ERROR_UNTRUSTED_CERT:
case SEC_ERROR_INADEQUATE_KEY_USAGE:
case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED:
// We group all these errors as "cert not trusted"
return nsICertOverrideService::ERROR_UNTRUSTED;
@ -507,6 +578,100 @@ PRErrorCodeToOverrideType(PRErrorCode errorCode)
}
}
SECStatus
NSSDetermineCertOverrideErrors(CertVerifier& certVerifier,
CERTCertificate* cert,
const SECItem* stapledOCSPResponse,
TransportSecurityInfo* infoObject,
PRTime now,
PRErrorCode defaultErrorCodeToReport,
/*out*/ uint32_t& collectedErrors,
/*out*/ PRErrorCode& errorCodeTrust,
/*out*/ PRErrorCode& errorCodeMismatch,
/*out*/ PRErrorCode& errorCodeExpired)
{
MOZ_ASSERT(cert);
MOZ_ASSERT(infoObject);
MOZ_ASSERT(defaultErrorCodeToReport != 0);
MOZ_ASSERT(collectedErrors == 0);
MOZ_ASSERT(errorCodeTrust == 0);
MOZ_ASSERT(errorCodeMismatch == 0);
MOZ_ASSERT(errorCodeExpired == 0);
if (defaultErrorCodeToReport == 0) {
NS_ERROR("No error code set during certificate validation failure.");
PR_SetError(PR_INVALID_STATE_ERROR, 0);
return SECFailure;
}
// We only allow overrides for certain errors. Return early if the error
// is not one of them. This is to avoid doing revocation fetching in the
// case of OCSP stapling and probably for other reasons.
if (PRErrorCodeToOverrideType(defaultErrorCodeToReport) == 0) {
PR_SetError(defaultErrorCodeToReport, 0);
return SECFailure;
}
PLArenaPool* log_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
PLArenaPoolCleanerFalseParam log_arena_cleaner(log_arena);
if (!log_arena) {
NS_ERROR("PORT_NewArena failed");
return SECFailure; // PORT_NewArena set error code
}
CERTVerifyLog* verify_log = PORT_ArenaZNew(log_arena, CERTVerifyLog);
if (!verify_log) {
NS_ERROR("PORT_ArenaZNew failed");
return SECFailure; // PORT_ArenaZNew set error code
}
CERTVerifyLogContentsCleaner verify_log_cleaner(verify_log);
verify_log->arena = log_arena;
// We ignore the result code of the cert verification (i.e. VerifyCert's rv)
// Either it is a failure, which is expected, and we'll process the
// verify log below.
// Or it is a success, then a domain mismatch is the only
// possible failure.
// XXX TODO: convert to VerifySSLServerCert
// XXX TODO: get rid of error log
certVerifier.VerifyCert(cert, stapledOCSPResponse, certificateUsageSSLServer,
now, infoObject, 0, nullptr, nullptr, verify_log);
// Check the name field against the desired hostname.
if (CERT_VerifyCertName(cert, infoObject->GetHostNameRaw()) != SECSuccess) {
collectedErrors |= nsICertOverrideService::ERROR_MISMATCH;
errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
}
CERTVerifyLogNode* i_node;
for (i_node = verify_log->head; i_node; i_node = i_node->next) {
uint32_t overrideType = PRErrorCodeToOverrideType(i_node->error);
// If this isn't an overridable error, set the error and return.
if (overrideType == 0) {
PR_SetError(i_node->error, 0);
return SECFailure;
}
collectedErrors |= overrideType;
if (overrideType == nsICertOverrideService::ERROR_UNTRUSTED) {
if (errorCodeTrust == 0) {
errorCodeTrust = i_node->error;
}
} else if (overrideType == nsICertOverrideService::ERROR_MISMATCH) {
if (errorCodeMismatch == 0) {
errorCodeMismatch = i_node->error;
}
} else if (overrideType == nsICertOverrideService::ERROR_TIME) {
if (errorCodeExpired == 0) {
errorCodeExpired = i_node->error;
}
} else {
MOZ_CRASH("unexpected return value from PRErrorCodeToOverrideType");
}
}
return SECSuccess;
}
// Returns null with the error code (PR_GetError()) set if it does not create
// the CertErrorRunnable.
CertErrorRunnable*
@ -522,17 +687,41 @@ CreateCertErrorRunnable(CertVerifier& certVerifier,
MOZ_ASSERT(infoObject);
MOZ_ASSERT(cert);
// We only allow overrides for certain errors. Return early if the error
// is not one of them. This is to avoid doing revocation fetching in the
// case of OCSP stapling and probably for other reasons.
if (PRErrorCodeToOverrideType(defaultErrorCodeToReport) == 0) {
PR_SetError(defaultErrorCodeToReport, 0);
return nullptr;
}
uint32_t collected_errors = 0;
PRErrorCode errorCodeTrust = 0;
PRErrorCode errorCodeMismatch = 0;
PRErrorCode errorCodeExpired = 0;
if (defaultErrorCodeToReport == 0) {
NS_ERROR("No error code set during certificate validation failure.");
PR_SetError(PR_INVALID_STATE_ERROR, 0);
SECStatus rv;
switch (certVerifier.mImplementation) {
case CertVerifier::classic:
#ifndef NSS_NO_LIBPKIX
case CertVerifier::libpkix:
#endif
rv = NSSDetermineCertOverrideErrors(certVerifier, cert, stapledOCSPResponse,
infoObject, now,
defaultErrorCodeToReport,
collected_errors, errorCodeTrust,
errorCodeMismatch, errorCodeExpired);
break;
case CertVerifier::insanity:
rv = InsanityDetermineCertOverrideErrors(cert,
infoObject->GetHostNameRaw(),
now, defaultErrorCodeToReport,
collected_errors,
errorCodeTrust,
errorCodeMismatch,
errorCodeExpired);
break;
default:
MOZ_CRASH("unexpected CertVerifier implementation");
PR_SetError(defaultErrorCodeToReport, 0);
return nullptr;
}
if (rv != SECSuccess) {
return nullptr;
}
@ -543,70 +732,7 @@ CreateCertErrorRunnable(CertVerifier& certVerifier,
return nullptr;
}
PLArenaPool* log_arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
PLArenaPoolCleanerFalseParam log_arena_cleaner(log_arena);
if (!log_arena) {
NS_ERROR("PORT_NewArena failed");
return nullptr; // PORT_NewArena set error code
}
CERTVerifyLog* verify_log = PORT_ArenaZNew(log_arena, CERTVerifyLog);
if (!verify_log) {
NS_ERROR("PORT_ArenaZNew failed");
return nullptr; // PORT_ArenaZNew set error code
}
CERTVerifyLogContentsCleaner verify_log_cleaner(verify_log);
verify_log->arena = log_arena;
// We ignore the result code of the cert verification (i.e. VerifyCert's rv)
// Either it is a failure, which is expected, and we'll process the
// verify log below.
// Or it is a success, then a domain mismatch is the only
// possible failure.
// XXX TODO: convert to VerifySSLServerCert
// XXX TODO: get rid of error log
certVerifier.VerifyCert(cert, stapledOCSPResponse,
certificateUsageSSLServer, now,
infoObject, 0, nullptr, nullptr, verify_log);
PRErrorCode errorCodeMismatch = 0;
PRErrorCode errorCodeTrust = 0;
PRErrorCode errorCodeExpired = 0;
uint32_t collected_errors = 0;
// Check the name field against the desired hostname.
if (CERT_VerifyCertName(cert, infoObject->GetHostNameRaw()) != SECSuccess) {
collected_errors |= nsICertOverrideService::ERROR_MISMATCH;
errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN;
}
CERTVerifyLogNode* i_node;
for (i_node = verify_log->head; i_node; i_node = i_node->next)
{
uint32_t overrideType = PRErrorCodeToOverrideType(i_node->error);
// If this isn't an overridable error, set the error and return.
if (overrideType == 0) {
PR_SetError(i_node->error, 0);
return nullptr;
}
collected_errors |= overrideType;
if (overrideType == nsICertOverrideService::ERROR_UNTRUSTED) {
errorCodeTrust = (errorCodeTrust == 0 ? i_node->error : errorCodeTrust);
} else if (overrideType == nsICertOverrideService::ERROR_MISMATCH) {
errorCodeMismatch = (errorCodeMismatch == 0 ? i_node->error
: errorCodeMismatch);
} else if (overrideType == nsICertOverrideService::ERROR_TIME) {
errorCodeExpired = (errorCodeExpired == 0 ? i_node->error
: errorCodeExpired);
} else {
MOZ_CRASH("unexpected return value from PRErrorCodeToOverrideType");
}
}
if (!collected_errors)
{
if (!collected_errors) {
// This will happen when CERT_*Verify* only returned error(s) that are
// not on our whitelist of overridable certificate errors.
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] !collected_errors: %d\n",

Просмотреть файл

@ -1630,15 +1630,30 @@ nsNSSCertificateDB::AddCert(const nsACString & aCertDER, const char *aTrust,
return AddCertFromBase64(base64.get(), aTrust, aName);
}
NS_IMETHODIMP
nsNSSCertificateDB::SetCertTrustFromString(nsIX509Cert3* cert,
const char* trustString)
{
CERTCertTrust trust;
// need to calculate the trust bits from the aTrust string.
SECStatus srv = CERT_DecodeTrustString(&trust,
const_cast<char *>(trustString));
if (srv != SECSuccess) {
return MapSECStatus(SECFailure);
}
insanity::pkix::ScopedCERTCertificate nssCert(cert->GetCert());
srv = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), nssCert.get(), &trust);
return MapSECStatus(srv);
}
NS_IMETHODIMP
nsNSSCertificateDB::GetCerts(nsIX509CertList **_retval)
{
nsNSSShutDownPreventionLock locker;
if (isAlreadyShutDown()) {
return NS_ERROR_NOT_AVAILABLE;
}
}
nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
nsCOMPtr<nsIX509CertList> nssCertList;

Просмотреть файл

@ -73,6 +73,20 @@ function addCertFromFile(certdb, filename, trustString) {
certdb.addCert(der, trustString, null);
}
function constructCertFromFile(filename) {
let certFile = do_get_file(filename, false);
let certDER = readFile(certFile);
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
return certdb.constructX509(certDER, certDER.length);
}
function setCertTrust(cert, trustString) {
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
certdb.setCertTrustFromString(cert, trustString);
}
function getXPCOMStatusFromNSS(statusNSS) {
let nssErrorsService = Cc["@mozilla.org/nss_errors_service;1"]
.getService(Ci.nsINSSErrorsService);

Просмотреть файл

@ -11,6 +11,10 @@
// 2. Add an override for that host/port/certificate/override bits.
// 3. Connect again. This should succeed.
do_get_profile();
let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
.getService(Ci.nsICertOverrideService);
function add_cert_override(aHost, aExpectedBits, aSecurityInfo) {
let sslstatus = aSecurityInfo.QueryInterface(Ci.nsISSLStatusProvider)
.SSLStatus;
@ -20,8 +24,6 @@ function add_cert_override(aHost, aExpectedBits, aSecurityInfo) {
(sslstatus.isNotValidAtThisTime ? Ci.nsICertOverrideService.ERROR_TIME : 0);
do_check_eq(bits, aExpectedBits);
let cert = sslstatus.serverCert;
let certOverrideService = Cc["@mozilla.org/security/certoverride;1"]
.getService(Ci.nsICertOverrideService);
certOverrideService.rememberValidityOverride(aHost, 8443, cert, aExpectedBits,
true);
}
@ -38,66 +40,170 @@ function check_telemetry() {
.getHistogramById("SSL_CERT_ERROR_OVERRIDES")
.snapshot();
do_check_eq(histogram.counts[ 0], 0);
do_check_eq(histogram.counts[ 1], 1);
do_check_eq(histogram.counts[ 2], 1);
do_check_eq(histogram.counts[ 3], 1);
do_check_eq(histogram.counts[ 4], 1);
do_check_eq(histogram.counts[ 5], 1);
do_check_eq(histogram.counts[ 6], 1);
do_check_eq(histogram.counts[ 7], 1);
do_check_eq(histogram.counts[ 8], 1);
do_check_eq(histogram.counts[ 9], 1);
do_check_eq(histogram.counts[10], 1);
do_check_eq(histogram.counts[ 2], 6 + 1); // SEC_ERROR_UNKNOWN_ISSUER
do_check_eq(histogram.counts[ 3], 0 + 1); // SEC_ERROR_CA_CERT_INVALID
do_check_eq(histogram.counts[ 4], 0 + 4); // SEC_ERROR_UNTRUSTED_ISSUER
do_check_eq(histogram.counts[ 5], 0 + 1); // SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE
do_check_eq(histogram.counts[ 6], 0 + 1); // SEC_ERROR_UNTRUSTED_CERT
do_check_eq(histogram.counts[ 7], 0); // SEC_ERROR_INADEQUATE_KEY_USAGE
do_check_eq(histogram.counts[ 8], 2 + 2); // SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED
do_check_eq(histogram.counts[ 9], 4 + 4); // SSL_ERROR_BAD_CERT_DOMAIN
do_check_eq(histogram.counts[10], 5 + 5); // SEC_ERROR_EXPIRED_CERTIFICATE
run_next_test();
}
function run_test() {
do_get_profile();
add_tls_server_setup("BadCertServer");
let fakeOCSPResponder = new HttpServer();
fakeOCSPResponder.registerPrefixHandler("/", function (request, response) {
response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
});
fakeOCSPResponder.start(8080);
add_tests_in_mode(true);
add_tests_in_mode(false);
add_test(function () {
fakeOCSPResponder.stop(check_telemetry);
});
run_next_test();
}
function add_tests_in_mode(useInsanity) {
add_test(function () {
Services.prefs.setBoolPref("security.use_insanity_verification",
useInsanity);
run_next_test();
});
add_simple_tests(useInsanity);
add_combo_tests(useInsanity);
add_distrust_tests(useInsanity);
add_test(function () {
certOverrideService.clearValidityOverride("all:temporary-certificates", 0);
run_next_test();
});
}
function add_simple_tests(useInsanity) {
add_cert_override_test("expired.example.com",
Ci.nsICertOverrideService.ERROR_TIME,
getXPCOMStatusFromNSS(SEC_ERROR_EXPIRED_CERTIFICATE));
add_cert_override_test("selfsigned.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED,
getXPCOMStatusFromNSS(SEC_ERROR_CA_CERT_INVALID));
getXPCOMStatusFromNSS(
useInsanity ? SEC_ERROR_UNKNOWN_ISSUER
: SEC_ERROR_CA_CERT_INVALID));
add_cert_override_test("unknownissuer.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED,
getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_ISSUER));
add_cert_override_test("expiredissuer.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED,
getXPCOMStatusFromNSS(SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE));
getXPCOMStatusFromNSS(
useInsanity ? SEC_ERROR_UNKNOWN_ISSUER
: SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE));
add_cert_override_test("md5signature.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED,
getXPCOMStatusFromNSS(SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED));
add_cert_override_test("inadequatekeyusage.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED,
getXPCOMStatusFromNSS(SEC_ERROR_INADEQUATE_KEY_USAGE));
getXPCOMStatusFromNSS(
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED));
add_cert_override_test("mismatch.example.com",
Ci.nsICertOverrideService.ERROR_MISMATCH,
getXPCOMStatusFromNSS(SSL_ERROR_BAD_CERT_DOMAIN));
}
function add_combo_tests(useInsanity) {
// Note that "untrusted" here really is "unknown issuer" in the
// insanity::pkix case.
add_cert_override_test("mismatch-expired.example.com",
Ci.nsICertOverrideService.ERROR_MISMATCH |
Ci.nsICertOverrideService.ERROR_TIME,
getXPCOMStatusFromNSS(SSL_ERROR_BAD_CERT_DOMAIN));
add_cert_override_test("mismatch-untrusted.example.com",
Ci.nsICertOverrideService.ERROR_MISMATCH |
Ci.nsICertOverrideService.ERROR_UNTRUSTED,
getXPCOMStatusFromNSS(
useInsanity ? SEC_ERROR_UNKNOWN_ISSUER
: SEC_ERROR_UNTRUSTED_ISSUER));
add_cert_override_test("untrusted-expired.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED |
Ci.nsICertOverrideService.ERROR_TIME,
getXPCOMStatusFromNSS(
useInsanity ? SEC_ERROR_UNKNOWN_ISSUER
: SEC_ERROR_UNTRUSTED_ISSUER));
add_cert_override_test("mismatch-untrusted-expired.example.com",
Ci.nsICertOverrideService.ERROR_MISMATCH |
Ci.nsICertOverrideService.ERROR_UNTRUSTED |
Ci.nsICertOverrideService.ERROR_TIME,
getXPCOMStatusFromNSS(
useInsanity ? SEC_ERROR_UNKNOWN_ISSUER
: SEC_ERROR_UNTRUSTED_ISSUER));
add_cert_override_test("md5signature-expired.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED |
Ci.nsICertOverrideService.ERROR_TIME,
getXPCOMStatusFromNSS(
SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED));
}
function add_distrust_tests(useInsanity) {
// Before we specifically distrust this certificate, it should be trusted.
add_connection_test("untrusted.example.com", Cr.NS_OK);
add_test(function() {
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
// A trust argument of "pu" means the cert is actively distrusted.
addCertFromFile(certdb, "tlsserver/default-ee.der", "pu,,");
// XXX(Bug 975777): Active distrust is an overridable error when NSS-based
// verification is used.
add_distrust_override_test("tlsserver/default-ee.der",
"untrusted.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_CERT),
useInsanity
? getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_CERT)
: Cr.NS_OK);
// XXX(Bug 975777): Active distrust is an overridable error when NSS-based
// verification is used.
add_distrust_override_test("tlsserver/other-test-ca.der",
"untrustedissuer.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER),
useInsanity
? getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER)
: Cr.NS_OK);
}
function add_distrust_override_test(certFileName, hostName,
expectedResultBefore, expectedResultAfter) {
let certToDistrust = constructCertFromFile(certFileName);
add_test(function () {
// "pu" means the cert is actively distrusted.
setCertTrust(certToDistrust, "pu,,");
clearSessionCache();
run_next_test();
});
add_cert_override_test("untrusted.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED,
getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_CERT));
add_test(function() {
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
// A trust argument of "pu" means the cert is actively distrusted.
addCertFromFile(certdb, "tlsserver/other-test-ca.der", "pu,,");
run_next_test();
});
add_cert_override_test("untrustedissuer.example.com",
Ci.nsICertOverrideService.ERROR_UNTRUSTED,
getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER));
add_test(check_telemetry);
run_next_test();
add_connection_test(hostName, expectedResultBefore, null,
function (securityInfo) {
securityInfo.QueryInterface(Ci.nsISSLStatusProvider);
// XXX(Bug 754369): SSLStatus isn't available for
// non-overridable errors.
if (securityInfo.SSLStatus) {
certOverrideService.rememberValidityOverride(
hostName, 8443, securityInfo.SSLStatus.serverCert,
Ci.nsICertOverrideService.ERROR_UNTRUSTED, true);
} else {
// A missing SSLStatus probably means (due to bug
// 754369) that the error was non-overridable, which
// is what we're trying to test, though we'd rather
// not test it this way.
do_check_neq(expectedResultAfter, Cr.NS_OK);
}
clearSessionCache();
});
add_connection_test(hostName, expectedResultAfter, null,
function () {
setCertTrust(certToDistrust, "u,,");
});
}

Двоичный файл не отображается.

Просмотреть файл

@ -33,8 +33,12 @@ const BadCertHost sBadCertHosts[] =
{ "expiredissuer.example.com", "expiredissuer" },
{ "md5signature.example.com", "md5signature" },
{ "untrusted.example.com", "localhostAndExampleCom" },
{ "inadequatekeyusage.example.com", "inadequatekeyusage" },
{ "untrustedissuer.example.com", "untrustedissuer" },
{ "mismatch-expired.example.com", "mismatch-expired" },
{ "mismatch-untrusted.example.com", "mismatch-untrusted" },
{ "untrusted-expired.example.com", "untrusted-expired" },
{ "md5signature-expired.example.com", "md5signature-expired" },
{ "mismatch-untrusted-expired.example.com", "mismatch-untrusted-expired" },
{ nullptr, nullptr }
};

Двоичный файл не отображается.

Просмотреть файл

@ -99,7 +99,7 @@ function make_EE {
SUBJECT="${2}"
CA="${3}"
SUBJECT_ALT_NAME="${4}"
EXTRA_ARGS="${5}"
EXTRA_ARGS="${5} ${6}"
echo -e "$CERT_RESPONSES" | $RUN_MOZILLA $CERTUTIL -d $OUTPUT_DIR -S \
-n $NICKNAME \
@ -136,7 +136,12 @@ $RUN_MOZILLA $CERTUTIL -d $OUTPUT_DIR -D -n deletedINT
make_INT expiredINT 'CN=Expired Test Intermediate' testCA "-w -400"
make_EE expiredissuer 'CN=Test End-entity with expired issuer' expiredINT "expiredissuer.example.com"
NSS_ALLOW_WEAK_SIGNATURE_ALG=1 make_EE md5signature 'CN=Test End-entity with MD5 signature' testCA "md5signature.example.com" "-Z MD5"
make_EE inadequatekeyusage 'CN=Test End-entity with inadequate key usage' testCA "inadequatekeyusage.example.com" "--keyUsage crlSigning"
make_EE untrustedissuer 'CN=Test End-entity with untrusted issuer' otherCA "untrustedissuer.example.com"
make_EE mismatch-expired 'CN=Mismatch-Expired Test End-entity' testCA "doesntmatch.example.com" "-w -400"
make_EE mismatch-untrusted 'CN=Mismatch-Untrusted Test End-entity' otherCA "doesntmatch.example.com"
make_EE untrusted-expired 'CN=Untrusted-Expired Test End-entity' otherCA "untrusted-expired.example.com" "-w -400"
make_EE mismatch-untrusted-expired 'CN=Mismatch-Untrusted-Expired Test End-entity' otherCA "doesntmatch.example.com" "-w -400"
NSS_ALLOW_WEAK_SIGNATURE_ALG=1 make_EE md5signature-expired 'CN=Test MD5Signature-Expired End-entity' testCA "md5signature-expired.example.com" "-Z MD5" "-w -400"
cleanup

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.