Bug 915931, Part 4: Expand OCSP xpcshell tests to test insanity::pkix, r=keeler

--HG--
extra : rebase_source : e645de251c459d6fa38996bb7bfd35e21eaf3b72
This commit is contained in:
Brian Smith 2014-02-17 13:19:54 -08:00
parent 141e0cb2aa
commit 2e66c4833d
6 changed files with 256 additions and 170 deletions

View File

@ -114,64 +114,119 @@ function run_test() {
// setup and start ocsp responder
Services.prefs.setCharPref("network.dns.localDomains",
'www.example.com, crl.example.com');
add_tests_in_mode(true);
add_tests_in_mode(false);
run_next_test();
}
add_test(function() {
clearOCSPCache();
let ocspResponder = start_ocsp_responder(
isDebugBuild ? ["int-ev-valid", "ev-valid"]
: ["ev-valid"]);
check_ee_for_ev("ev-valid", isDebugBuild);
ocspResponder.stop(run_next_test);
});
function add_tests_in_mode(useInsanity)
{
add_test(function () {
Services.prefs.setBoolPref("security.use_insanity_verification",
useInsanity);
run_next_test();
});
add_test(function() {
clearOCSPCache();
let ocspResponder = start_ocsp_responder(["non-ev-root"]);
check_ee_for_ev("non-ev-root", false);
ocspResponder.stop(run_next_test);
});
add_test(function () {
clearOCSPCache();
let ocspResponder = start_ocsp_responder(
isDebugBuild ? ["int-ev-valid", "ev-valid"]
: ["ev-valid"]);
check_ee_for_ev("ev-valid", isDebugBuild);
ocspResponder.stop(run_next_test);
});
add_test(function() {
clearOCSPCache();
// libpkix will attempt to validate the intermediate, which does have an
// OCSP URL.
let ocspResponder = isDebugBuild ? start_ocsp_responder(["int-ev-valid"])
: failingOCSPResponder();
check_ee_for_ev("no-ocsp-url-cert", false);
ocspResponder.stop(run_next_test);
});
add_test(function() {
clearOCSPCache();
let ocspResponder = start_ocsp_responder(["non-ev-root"]);
check_ee_for_ev("non-ev-root", false);
ocspResponder.stop(run_next_test);
});
// bug 917380: Chcek that an untrusted EV root is untrusted.
const nsIX509Cert = Ci.nsIX509Cert;
add_test(function() {
let evRootCA = certdb.findCertByNickname(null, evrootnick);
certdb.setCertTrust(evRootCA, nsIX509Cert.CA_CERT, 0);
add_test(function() {
clearOCSPCache();
// libpkix will attempt to validate the intermediate, which does have an
// OCSP URL.
let ocspResponder = isDebugBuild ? start_ocsp_responder(["int-ev-valid"])
: failingOCSPResponder();
check_ee_for_ev("no-ocsp-url-cert", false);
ocspResponder.stop(run_next_test);
});
clearOCSPCache();
let ocspResponder = failingOCSPResponder();
check_cert_err("ev-valid", SEC_ERROR_UNTRUSTED_ISSUER);
ocspResponder.stop(run_next_test);
});
// bug 917380: Chcek that an untrusted EV root is untrusted.
const nsIX509Cert = Ci.nsIX509Cert;
add_test(function() {
let evRootCA = certdb.findCertByNickname(null, evrootnick);
certdb.setCertTrust(evRootCA, nsIX509Cert.CA_CERT, 0);
// bug 917380: Chcek that a trusted EV root is trusted after disabling and
// re-enabling trust.
add_test(function() {
let evRootCA = certdb.findCertByNickname(null, evrootnick);
certdb.setCertTrust(evRootCA, nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_SSL |
Ci.nsIX509CertDB.TRUSTED_EMAIL |
Ci.nsIX509CertDB.TRUSTED_OBJSIGN);
clearOCSPCache();
let ocspResponder = failingOCSPResponder();
check_cert_err("ev-valid",
useInsanity ? SEC_ERROR_UNKNOWN_ISSUER
: SEC_ERROR_UNTRUSTED_ISSUER);
ocspResponder.stop(run_next_test);
});
clearOCSPCache();
let ocspResponder = start_ocsp_responder(
isDebugBuild ? ["int-ev-valid", "ev-valid"]
: ["ev-valid"]);
check_ee_for_ev("ev-valid", isDebugBuild);
ocspResponder.stop(run_next_test);
});
// bug 917380: Chcek that a trusted EV root is trusted after disabling and
// re-enabling trust.
add_test(function() {
let evRootCA = certdb.findCertByNickname(null, evrootnick);
certdb.setCertTrust(evRootCA, nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_SSL |
Ci.nsIX509CertDB.TRUSTED_EMAIL |
Ci.nsIX509CertDB.TRUSTED_OBJSIGN);
clearOCSPCache();
let ocspResponder = start_ocsp_responder(
isDebugBuild ? ["int-ev-valid", "ev-valid"]
: ["ev-valid"]);
check_ee_for_ev("ev-valid", isDebugBuild);
ocspResponder.stop(run_next_test);
});
add_test(function () {
check_no_ocsp_requests("ev-valid",
isDebugBuild ? SEC_ERROR_REVOKED_CERTIFICATE
: SEC_ERROR_EXTENSION_NOT_FOUND);
});
add_test(function () {
check_no_ocsp_requests("non-ev-root",
isDebugBuild ? SEC_ERROR_UNTRUSTED_ISSUER
: SEC_ERROR_EXTENSION_NOT_FOUND);
});
add_test(function () {
check_no_ocsp_requests("no-ocsp-url-cert",
isDebugBuild ? SEC_ERROR_REVOKED_CERTIFICATE
: SEC_ERROR_EXTENSION_NOT_FOUND);
});
// Test the EV continues to work with flags after successful EV verification
add_test(function () {
clearOCSPCache();
let ocspResponder = start_ocsp_responder(
isDebugBuild ? ["int-ev-valid", "ev-valid"]
: ["ev-valid"]);
check_ee_for_ev("ev-valid", isDebugBuild);
ocspResponder.stop(function () {
// without net it must be able to EV verify
let failingOcspResponder = failingOCSPResponder();
let cert = certdb.findCertByNickname(null, "ev-valid");
let hasEVPolicy = {};
let verifiedChain = {};
let flags = Ci.nsIX509CertDB.FLAG_LOCAL_ONLY |
Ci.nsIX509CertDB.FLAG_MUST_BE_EV;
let error = certdb.verifyCertNow(cert, certificateUsageSSLServer,
flags, verifiedChain, hasEVPolicy);
do_check_eq(hasEVPolicy.value, isDebugBuild);
do_check_eq(error, isDebugBuild ? 0 : SEC_ERROR_EXTENSION_NOT_FOUND);
failingOcspResponder.stop(run_next_test);
});
});
}
// bug 950240: add FLAG_MUST_BE_EV to CertVerifier::VerifyCert
// to prevent spurious OCSP requests that race with OCSP stapling.
@ -198,49 +253,3 @@ function check_no_ocsp_requests(cert_name, expected_error) {
do_check_eq(identityInfo.isExtendedValidation, false);
ocspResponder.stop(run_next_test);
}
add_test(function() {
check_no_ocsp_requests("ev-valid", isDebugBuild ?
SEC_ERROR_REVOKED_CERTIFICATE:
SEC_ERROR_EXTENSION_NOT_FOUND);
});
add_test(function() {
check_no_ocsp_requests("non-ev-root", isDebugBuild ?
SEC_ERROR_UNTRUSTED_ISSUER:
SEC_ERROR_EXTENSION_NOT_FOUND);
});
add_test(function() {
check_no_ocsp_requests("no-ocsp-url-cert", isDebugBuild?
SEC_ERROR_REVOKED_CERTIFICATE:
SEC_ERROR_EXTENSION_NOT_FOUND);
});
// Test the EV continues to work with flags after successful EV verification
add_test(function() {
clearOCSPCache();
let ocspResponder = start_ocsp_responder(
isDebugBuild ? ["int-ev-valid", "ev-valid"]
: ["ev-valid"]);
check_ee_for_ev("ev-valid", isDebugBuild);
ocspResponder.stop(function () {
// without net it must be able to EV verify
let failingOcspResponder = failingOCSPResponder();
let cert = certdb.findCertByNickname(null, "ev-valid");
let hasEVPolicy = {};
let verifiedChain = {};
let flags = Ci.nsIX509CertDB.FLAG_LOCAL_ONLY |
Ci.nsIX509CertDB.FLAG_MUST_BE_EV;
let error = certdb.verifyCertNow(cert, certificateUsageSSLServer,
flags, verifiedChain, hasEVPolicy);
do_check_eq(hasEVPolicy.value, isDebugBuild);
do_check_eq(error, isDebugBuild ? 0 : SEC_ERROR_EXTENSION_NOT_FOUND);
failingOcspResponder.stop(run_next_test);
});
});

View File

@ -107,7 +107,7 @@ function run_test() {
//---------------------------------------------------------------------------
add_test(function() { ocspResponder.stop(run_next_test); run_next_test(); });
add_test(function() { ocspResponder.stop(run_next_test); });
run_next_test();
}

View File

@ -9,27 +9,45 @@
// response with a bad signature. With security.OCSP.require set to true,
// this should fail (but it also shouldn't cause assertion failures).
let gOCSPRequestCount = 0;
function run_test() {
do_get_profile();
Services.prefs.setBoolPref("security.OCSP.require", true);
let args = [ ["bad-signature", "localhostAndExampleCom", "unused" ] ];
let ocspResponses = generateOCSPResponses(args, "tlsserver");
let ocspResponseBadSignature = ocspResponses[0];
let ocspRequestCount = 0;
let ocspResponder = new HttpServer();
ocspResponder.registerPrefixHandler("/", function(request, response) {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "application/ocsp-response");
response.write(ocspResponseBadSignature);
ocspRequestCount++;
});
ocspResponder.start(8080);
// We don't actually make use of stapling in this test. This is just how we
// get a TLS connection.
add_tls_server_setup("OCSPStaplingServer");
let args = [["bad-signature", "localhostAndExampleCom", "unused"]];
let ocspResponses = generateOCSPResponses(args, "tlsserver");
let ocspResponseBadSignature = ocspResponses[0];
let ocspResponder = new HttpServer();
ocspResponder.registerPrefixHandler("/", function (request, response) {
response.setStatusLine(request.httpVersion, 200, "OK");
response.setHeader("Content-Type", "application/ocsp-response");
response.write(ocspResponseBadSignature);
gOCSPRequestCount++;
});
ocspResponder.start(8080);
add_tests_in_mode(true);
add_tests_in_mode(false);
add_test(function () { ocspResponder.stop(run_next_test); });
run_next_test();
}
function add_tests_in_mode(useInsanity)
{
add_test(function () {
Services.prefs.setBoolPref("security.use_insanity_verification",
useInsanity);
run_next_test();
});
add_connection_test("ocsp-stapling-none.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT));
// bug 964493 - using a cached OCSP response with a bad signature would cause
@ -38,7 +56,11 @@ function run_test() {
// of the error handling code.
add_connection_test("ocsp-stapling-none.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT));
add_test(function() { ocspResponder.stop(run_next_test); });
add_test(function() { do_check_eq(ocspRequestCount, 1); run_next_test(); });
run_next_test();
add_test(function () {
// XXX(bug 915932): special case for insanity::pkix due to the temporary
// lack of an OCSP cache.
do_check_eq(gOCSPRequestCount, useInsanity ? 2 : 1);
gOCSPRequestCount = 0;
run_next_test();
});
}

View File

@ -21,17 +21,12 @@ function add_ocsp_test(aHost, aExpectedResult, aStaplingEnabled) {
});
}
function run_test() {
do_get_profile();
let fakeOCSPResponder = new HttpServer();
fakeOCSPResponder.registerPrefixHandler("/", function(request, response) {
response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
do_check_true(gExpectOCSPRequest);
function add_tests_in_mode(useInsanity, certDB, otherTestCA) {
add_test(function () {
Services.prefs.setBoolPref("security.use_insanity_verification",
useInsanity);
run_next_test();
});
fakeOCSPResponder.start(8080);
add_tls_server_setup("OCSPStaplingServer");
// In the absence of OCSP stapling, these should actually all work.
add_ocsp_test("ocsp-stapling-good.example.com", Cr.NS_OK, false);
@ -56,25 +51,33 @@ function run_test() {
add_ocsp_test("ocsp-stapling-revoked.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE), true);
// SEC_ERROR_OCSP_INVALID_SIGNING_CERT vs SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE
// depends on whether the CA that signed the response is a trusted CA.
// This stapled response is from a CA that is untrusted and did not issue
// the server's certificate.
add_ocsp_test("ocsp-stapling-good-other-ca.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_BAD_DATABASE), true);
// SEC_ERROR_BAD_DATABASE vs SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE depends on
// whether the CA that signed the response is a trusted CA.
add_test(function() {
let certdb = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
// Another trusted CA that shouldn't be trusted for OCSP responses, etc.
// for the "good" CA.
addCertFromFile(certdb, "tlsserver/other-test-ca.der", "CTu,u,u");
certDB.setCertTrust(otherTestCA, Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.UNTRUSTED);
run_next_test();
});
add_ocsp_test("ocsp-stapling-good-other-ca.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_OCSP_INVALID_SIGNING_CERT), true);
// The stapled response is from a CA that is trusted but did not issue the
// server's certificate.
add_test(function() {
certDB.setCertTrust(otherTestCA, Ci.nsIX509Cert.CA_CERT,
Ci.nsIX509CertDB.TRUSTED_SSL);
run_next_test();
});
add_ocsp_test("ocsp-stapling-good-other-ca.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE),
true);
// TODO: Test the case where the signing cert can't be found at all, which
// will result in SEC_ERROR_BAD_DATABASE in the NSS classic case.
add_ocsp_test("ocsp-stapling-malformed.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_OCSP_MALFORMED_REQUEST), true);
add_ocsp_test("ocsp-stapling-srverr.example.com",
@ -106,11 +109,6 @@ function run_test() {
// ocsp-stapling-expired.example.com and
// ocsp-stapling-expired-fresh-ca.example.com are handled in
// test_ocsp_stapling_expired.js
add_test(function() { fakeOCSPResponder.stop(run_next_test); });
add_test(check_ocsp_stapling_telemetry);
run_next_test();
}
function check_ocsp_stapling_telemetry() {
@ -118,10 +116,38 @@ function check_ocsp_stapling_telemetry() {
.getService(Ci.nsITelemetry)
.getHistogramById("SSL_OCSP_STAPLING")
.snapshot();
do_check_eq(histogram.counts[0], 0); // histogram bucket 0 is unused
do_check_eq(histogram.counts[1], 1); // 1 connection with a good response
do_check_eq(histogram.counts[2], 14); // 14 connections with no stapled resp.
do_check_eq(histogram.counts[3], 0); // 0 connections with an expired response
do_check_eq(histogram.counts[4], 11); // 11 connections with bad responses
do_check_eq(histogram.counts[0], 2 * 0); // histogram bucket 0 is unused
do_check_eq(histogram.counts[1], 2 * 1); // 1 connection with a good response
do_check_eq(histogram.counts[2], 2 * 14); // 14 connections with no stapled resp.
do_check_eq(histogram.counts[3], 2 * 0); // 0 connections with an expired response
do_check_eq(histogram.counts[4], 2 * 11); // 11 connections with bad responses
run_next_test();
}
function run_test() {
do_get_profile();
let certDB = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
let otherTestCAFile = do_get_file("tlsserver/other-test-ca.der", false);
let otherTestCADER = readFile(otherTestCAFile);
let otherTestCA = certDB.constructX509(otherTestCADER, otherTestCADER.length);
let fakeOCSPResponder = new HttpServer();
fakeOCSPResponder.registerPrefixHandler("/", function (request, response) {
response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
do_check_true(gExpectOCSPRequest);
});
fakeOCSPResponder.start(8080);
add_tls_server_setup("OCSPStaplingServer");
add_tests_in_mode(true, certDB, otherTestCA);
add_tests_in_mode(false, certDB, otherTestCA);
add_test(function () {
fakeOCSPResponder.stop(check_ocsp_stapling_telemetry);
});
run_next_test();
}

View File

@ -25,23 +25,27 @@ function add_ocsp_test(aHost, aExpectedResult, aOCSPResponseToServe) {
});
}
function run_test() {
do_get_profile();
Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
let args = [ ["good", "localhostAndExampleCom", "unused" ],
["expiredresponse", "localhostAndExampleCom", "unused"],
["oldvalidperiod", "localhostAndExampleCom", "unused"],
["revoked", "localhostAndExampleCom", "unused"] ];
let ocspResponses = generateOCSPResponses(args, "tlsserver");
// Fresh response, certificate is good.
let ocspResponseGood = ocspResponses[0];
// Expired response, certificate is good.
let expiredOCSPResponseGood = ocspResponses[1];
// Fresh signature, old validity period, certificate is good.
let oldValidityPeriodOCSPResponseGood = ocspResponses[2];
// Fresh signature, certificate is revoked.
let ocspResponseRevoked = ocspResponses[3];
do_get_profile();
Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
let args = [["good", "localhostAndExampleCom", "unused"],
["expiredresponse", "localhostAndExampleCom", "unused"],
["oldvalidperiod", "localhostAndExampleCom", "unused"],
["revoked", "localhostAndExampleCom", "unused"],
["unknown", "localhostAndExampleCom", "unused"],
];
let ocspResponses = generateOCSPResponses(args, "tlsserver");
// Fresh response, certificate is good.
let ocspResponseGood = ocspResponses[0];
// Expired response, certificate is good.
let expiredOCSPResponseGood = ocspResponses[1];
// Fresh signature, old validity period, certificate is good.
let oldValidityPeriodOCSPResponseGood = ocspResponses[2];
// Fresh signature, certificate is revoked.
let ocspResponseRevoked = ocspResponses[3];
// Fresh signature, certificate is unknown.
let ocspResponseUnknown = ocspResponses[4];
function run_test() {
let ocspResponder = new HttpServer();
ocspResponder.registerPrefixHandler("/", function(request, response) {
response.setStatusLine(request.httpVersion, 200, "OK");
@ -50,8 +54,21 @@ function run_test() {
gOCSPRequestCount++;
});
ocspResponder.start(8080);
add_tls_server_setup("OCSPStaplingServer");
add_tests_in_mode(true);
add_tests_in_mode(false);
add_test(function () { ocspResponder.stop(run_next_test); });
add_test(check_ocsp_stapling_telemetry);
run_next_test();
}
function add_tests_in_mode(useInsanity)
{
add_test(function () {
Services.prefs.setBoolPref("security.use_insanity_verification",
useInsanity);
run_next_test();
});
// In these tests, the OCSP stapling server gives us a stapled
// response based on the host name ("ocsp-stapling-expired" or
@ -80,9 +97,9 @@ function run_test() {
add_ocsp_test("ocsp-stapling-expired-fresh-ca.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_REVOKED_CERTIFICATE),
ocspResponseRevoked);
add_test(function() { ocspResponder.stop(run_next_test); });
add_test(check_ocsp_stapling_telemetry);
run_next_test();
add_ocsp_test("ocsp-stapling-expired.example.com",
getXPCOMStatusFromNSS(SEC_ERROR_OCSP_UNKNOWN_CERT),
ocspResponseUnknown);
}
function check_ocsp_stapling_telemetry() {
@ -90,10 +107,10 @@ function check_ocsp_stapling_telemetry() {
.getService(Ci.nsITelemetry)
.getHistogramById("SSL_OCSP_STAPLING")
.snapshot();
do_check_eq(histogram.counts[0], 0); // histogram bucket 0 is unused
do_check_eq(histogram.counts[1], 0); // 0 connections with a good response
do_check_eq(histogram.counts[2], 0); // 0 connections with no stapled resp.
do_check_eq(histogram.counts[3], 8); // 8 connections with an expired response
do_check_eq(histogram.counts[4], 0); // 0 connections with bad responses
do_check_eq(histogram.counts[0], 2 * 0); // histogram bucket 0 is unused
do_check_eq(histogram.counts[1], 2 * 0); // 0 connections with a good response
do_check_eq(histogram.counts[2], 2 * 0); // 0 connections with no stapled resp.
do_check_eq(histogram.counts[3], 2 * 9); // 8 connections with an expired response
do_check_eq(histogram.counts[4], 2 * 0); // 0 connections with bad responses
run_next_test();
}

View File

@ -33,11 +33,23 @@ function run_test() {
add_tls_server_setup("OCSPStaplingServer");
add_ocsp_test("ocsp-stapling-with-intermediate.example.com", Cr.NS_OK);
add_test(function() { ocspResponder.stop(run_next_test); });
add_tests_in_mode(true);
add_tests_in_mode(false);
add_test(function () { ocspResponder.stop(run_next_test); });
add_test(function() {
do_check_eq(gOCSPRequestCount, 0);
run_next_test();
});
run_next_test();
}
function add_tests_in_mode(useInsanity) {
add_test(function () {
Services.prefs.setBoolPref("security.use_insanity_verification",
useInsanity);
run_next_test();
});
add_ocsp_test("ocsp-stapling-with-intermediate.example.com", Cr.NS_OK);
}