Merge m-c to inbound.

This commit is contained in:
Ryan VanderMeulen 2014-01-13 18:01:29 -05:00
commit e970aa37d9
16 changed files with 47 additions and 381 deletions

View File

@ -31,28 +31,16 @@ function load_ca(ca_name) {
addCertFromFile(certdb, "test_ev_certs/" + ca_filename, 'CTu,CTu,CTu');
}
const SERVER_PORT = 8888;
var gHttpServer;
var gOCSPResponseCounter = 0;
function failingOCSPResponder() {
let httpServer = new HttpServer();
httpServer.registerPrefixHandler("/", function(request, response) {
do_check_true(false);
});
httpServer.start(SERVER_PORT);
return httpServer;
}
function start_ocsp_responder(expectedCertNames) {
let httpServer = new HttpServer();
httpServer.registerPrefixHandler("/",
function start_ocsp_responder() {
const SERVER_PORT = 8888;
gHttpServer = new HttpServer();
gHttpServer.registerPrefixHandler("/",
function handleServerCallback(aRequest, aResponse) {
do_check_neq(aRequest.host, "crl.example.com"); // No CRL checks
let cert_nick = aRequest.path.slice(1, aRequest.path.length - 1);
do_check_true(expectedCertNames.length >= 1);
let expected_nick = expectedCertNames.shift();
do_check_eq(cert_nick, expected_nick);
do_print("Generating ocsp response for '" + cert_nick + "'");
aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
aResponse.setHeader("Content-Type", "application/ocsp-response");
@ -66,16 +54,11 @@ function start_ocsp_responder(expectedCertNames) {
let retArray = generateOCSPResponses(arg_array, "test_ev_certs");
let responseBody = retArray[0];
aResponse.bodyOutputStream.write(responseBody, responseBody.length);
gOCSPResponseCounter++;
});
httpServer.identity.setPrimary("http", "www.example.com", SERVER_PORT);
httpServer.identity.add("http", "crl.example.com", SERVER_PORT);
httpServer.start(SERVER_PORT);
return {
stop: function(callback) {
do_check_eq(expectedCertNames.length, 0);
httpServer.stop(callback);
}
};
gHttpServer.identity.setPrimary("http", "www.example.com", SERVER_PORT);
gHttpServer.identity.add("http", "crl.example.com", SERVER_PORT);
gHttpServer.start(SERVER_PORT);
}
function check_cert_err(cert_name, expected_error) {
@ -114,53 +97,44 @@ function run_test() {
Services.prefs.setCharPref("network.dns.localDomains",
'www.example.com, crl.example.com');
start_ocsp_responder();
run_next_test();
}
add_test(function() {
clearOCSPCache();
let ocspResponder = start_ocsp_responder(["int-ev-valid", "ev-valid"]);
check_ee_for_ev("ev-valid", true);
ocspResponder.stop(run_next_test);
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);
run_next_test();
});
add_test(function() {
clearOCSPCache();
let ocspResponder = failingOCSPResponder();
check_ee_for_ev("no-ocsp-url-cert", false);
ocspResponder.stop(run_next_test);
run_next_test();
});
// bug 917380: Chcek that an untrusted EV root is untrusted.
const nsIX509Cert = Ci.nsIX509Cert;
add_test(function() {
// Test for bug 917380
add_test(function () {
const nsIX509Cert = Ci.nsIX509Cert;
let evRootCA = certdb.findCertByNickname(null, evrootnick);
certdb.setCertTrust(evRootCA, nsIX509Cert.CA_CERT, 0);
clearOCSPCache();
let ocspResponder = failingOCSPResponder();
check_cert_err("ev-valid", SEC_ERROR_UNTRUSTED_ISSUER);
ocspResponder.stop(run_next_test);
});
// bug 917380: Chcek that a trusted EV root is trusted.
// TODO: isn't this a duplicate of the above test?
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(["int-ev-valid", "ev-valid"]);
check_ee_for_ev("ev-valid", true);
ocspResponder.stop(run_next_test);
run_next_test();
});
// The following test should be the last as it performs cleanups
add_test(function() {
do_check_eq(4, gOCSPResponseCounter);
gHttpServer.stop(run_next_test);
});

View File

@ -1,43 +0,0 @@
// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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/.
"use strict";
// In which we connect to a server that staples an OCSP response for a
// certificate signed by an intermediate that has an OCSP AIA to ensure
// that an OCSP request is not made for the intermediate.
let gOCSPRequestCount = 0;
function add_ocsp_test(aHost, aExpectedResult) {
add_connection_test(aHost, aExpectedResult,
function() {
clearOCSPCache();
clearSessionCache();
});
}
function run_test() {
do_get_profile();
Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true);
let ocspResponder = new HttpServer();
ocspResponder.registerPrefixHandler("/", function(request, response) {
gOCSPRequestCount++;
response.setStatusLine(request.httpVersion, 500, "Internal Server Error");
let body = "Refusing to return a response";
response.bodyOutputStream.write(body, body.length);
});
ocspResponder.start(8080);
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_test(function() {
do_check_eq(gOCSPRequestCount, 0);
run_next_test();
});
run_next_test();
}

View File

@ -35,7 +35,6 @@ const OCSPHost sOCSPHosts[] =
{ "ocsp-stapling-trylater.example.com", ORTTryLater, nullptr },
{ "ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr },
{ "ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr },
{ "ocsp-stapling-with-intermediate.example.com", ORTGood, "ocspEEWithIntermediate" },
{ nullptr, ORTNull, nullptr }
};
@ -53,17 +52,9 @@ DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr,
fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName);
}
const char *certNickname;
if (strcmp(host->mHostName,
"ocsp-stapling-with-intermediate.example.com") == 0) {
certNickname = host->mAdditionalCertName;
} else {
certNickname = DEFAULT_CERT_NICKNAME;
}
ScopedCERTCertificate cert;
SSLKEAType certKEA;
if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname,
if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, DEFAULT_CERT_NICKNAME,
&cert, &certKEA)) {
return SSL_SNI_SEND_ALERT;
}

View File

@ -59,7 +59,7 @@ $RUN_MOZILLA $CERTUTIL -d $OUTPUT_DIR -N -f $PASSWORD_FILE
COMMON_ARGS="-v 360 -w -1 -2 -z $NOISE_FILE"
function make_CA {
CA_RESPONSES="y\n1\ny"
CA_RESPONSES="y\n0\ny"
NICKNAME="${1}"
SUBJECT="${2}"
DERFILE="${3}"
@ -74,24 +74,7 @@ function make_CA {
SERIALNO=1
function make_INT {
INT_RESPONSES="y\n0\ny\n2\n7\nhttp://localhost:8080/\n\nn\nn\n"
NICKNAME="${1}"
SUBJECT="${2}"
CA="${3}"
echo -e "$INT_RESPONSES" | $RUN_MOZILLA $CERTUTIL -d $OUTPUT_DIR -S \
-n $NICKNAME \
-s "$SUBJECT" \
-c $CA \
-t ",," \
-m $SERIALNO \
--extAIA \
$COMMON_ARGS
SERIALNO=$(($SERIALNO + 1))
}
function make_EE {
function make_cert {
CERT_RESPONSES="n\n\ny\n2\n7\nhttp://localhost:8080/\n\nn\nn\n"
NICKNAME="${1}"
SUBJECT="${2}"
@ -115,13 +98,10 @@ function make_EE {
make_CA testCA 'CN=Test CA' test-ca.der
make_CA otherCA 'CN=Other test CA' other-test-ca.der
make_EE localhostAndExampleCom 'CN=Test End-entity' testCA "localhost,*.example.com"
make_cert localhostAndExampleCom 'CN=Test End-entity' testCA "localhost,*.example.com"
# A cert that is like localhostAndExampleCom, but with a different serial number for
# testing the "OCSP response is from the right issuer, but it is for the wrong cert"
# case.
make_EE ocspOtherEndEntity 'CN=Other Cert' testCA "localhost,*.example.com"
make_INT testINT 'CN=Test Intermediate' testCA
make_EE ocspEEWithIntermediate 'CN=Test End-entity with Intermediate' testINT "localhost,*.example.com"
make_cert ocspOtherEndEntity 'CN=Other Cert' testCA "localhost,*.example.com"
cleanup

View File

@ -37,10 +37,6 @@ fail-if = os == "android"
run-sequentially = hardcoded ports
# Bug 676972: test fails consistently on Android
fail-if = os == "android"
[test_ocsp_stapling_with_intermediate.js]
run-sequentially = hardcoded ports
# Bug 676972: test fails consistently on Android
fail-if = os == "android"
[test_ocsp_caching.js]
run-sequentially = hardcoded ports
# Bug 676972: test fails consistently on Android

View File

@ -10,3 +10,4 @@
*/
#error "Do not include this header file."

View File

@ -261,28 +261,6 @@ void ReleaseDPCache(CRLDPCache* dpcache, PRBool writeLocked);
*/
void CERT_MapStanError();
/* Like CERT_VerifyCert, except with an additional argument, flags. The
* flags are defined immediately below.
*
* OCSP checking is always skipped when certUsage is certUsageStatusResponder.
*/
SECStatus
cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
PRBool checkSig, SECCertUsage certUsage, PRTime t,
PRUint32 flags, void *wincx, CERTVerifyLog *log);
/* Use the default settings.
* cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS) is equivalent
* to CERT_VerifyCert(...);
*/
#define CERT_VERIFYCERT_USE_DEFAULTS 0
/* Skip all the OCSP checks during certificate verification, regardless of
* the global OCSP settings. By default, certificate |cert| will have its
* revocation status checked via OCSP according to the global OCSP settings.
*/
#define CERT_VERIFYCERT_SKIP_OCSP 1
/* Interface function for libpkix cert validation engine:
* cert_verify wrapper. */
SECStatus

View File

@ -1200,7 +1200,7 @@ CERT_VerifyCertificate(CERTCertDBHandle *handle, CERTCertificate *cert,
/*
* Check OCSP revocation status, but only if the cert we are checking
* is not a status responder itself. We only do this in the case
* is not a status reponder itself. We only do this in the case
* where we checked the cert chain (above); explicit trust "wins"
* (avoids status checking, just as it avoids CRL checking) by
* bypassing this code.
@ -1234,20 +1234,11 @@ SECStatus
CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
PRBool checkSig, SECCertUsage certUsage, PRTime t,
void *wincx, CERTVerifyLog *log)
{
return cert_VerifyCertWithFlags(handle, cert, checkSig, certUsage, t,
CERT_VERIFYCERT_USE_DEFAULTS, wincx, log);
}
SECStatus
cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
PRBool checkSig, SECCertUsage certUsage, PRTime t,
PRUint32 flags, void *wincx, CERTVerifyLog *log)
{
SECStatus rv;
unsigned int requiredKeyUsage;
unsigned int requiredCertType;
unsigned int failedFlags;
unsigned int flags;
unsigned int certType;
PRBool trusted;
PRBool allowOverride;
@ -1316,10 +1307,10 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
LOG_ERROR_OR_EXIT(log,cert,0,requiredCertType);
}
rv = cert_CheckLeafTrust(cert, certUsage, &failedFlags, &trusted);
rv = cert_CheckLeafTrust(cert,certUsage, &flags, &trusted);
if (rv == SECFailure) {
PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags);
LOG_ERROR_OR_EXIT(log,cert,0,flags);
} else if (trusted) {
goto done;
}
@ -1332,17 +1323,15 @@ cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
}
/*
* Check revocation status, but only if the cert we are checking is not a
* status responder itself and the caller did not ask us to skip the check.
* We only do this in the case where we checked the cert chain (above);
* explicit trust "wins" (avoids status checking, just as it avoids CRL
* checking, which is all done inside VerifyCertChain) by bypassing this
* code.
* Check revocation status, but only if the cert we are checking
* is not a status reponder itself. We only do this in the case
* where we checked the cert chain (above); explicit trust "wins"
* (avoids status checking, just as it avoids CRL checking, which
* is all done inside VerifyCertChain) by bypassing this code.
*/
if (!(flags & CERT_VERIFYCERT_SKIP_OCSP) &&
certUsage != certUsageStatusResponder) {
statusConfig = CERT_GetStatusConfig(handle);
if (statusConfig && statusConfig->statusChecker) {
statusConfig = CERT_GetStatusConfig(handle);
if (certUsage != certUsageStatusResponder && statusConfig != NULL) {
if (statusConfig->statusChecker != NULL) {
rv = (* statusConfig->statusChecker)(handle, cert,
t, wincx);
if (rv != SECSuccess) {

View File

@ -18,7 +18,6 @@
#include "secasn1.h"
#include "secder.h"
#include "cert.h"
#include "certi.h"
#include "xconst.h"
#include "secerr.h"
#include "secoid.h"
@ -4185,9 +4184,8 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
} else {
certUsage = certUsageStatusResponder;
}
rv = cert_VerifyCertWithFlags(handle, signerCert, PR_TRUE, certUsage,
producedAt, CERT_VERIFYCERT_SKIP_OCSP,
pwArg, NULL);
rv = CERT_VerifyCert(handle, signerCert, PR_TRUE,
certUsage, producedAt, pwArg, NULL);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
goto finish;

View File

@ -1,5 +1,2 @@
This directory contains patches that were added locally
on top of the NSS release.
bug-950129.patch Make OCSP fetching policy for OCSP response signing
certificates consistent.

View File

@ -1,195 +0,0 @@
# HG changeset patch
# Parent 352d188c67d9fefd82524c4439a5d04679687945
# User Brian Smith <brian@briansmith.org>
diff --git a/security/nss/lib/certdb/certi.h b/security/nss/lib/certdb/certi.h
--- a/security/nss/lib/certdb/certi.h
+++ b/security/nss/lib/certdb/certi.h
@@ -256,16 +256,38 @@ void ReleaseDPCache(CRLDPCache* dpcache,
/*
* map Stan errors into NSS errors
* This function examines the stan error stack and automatically sets
* PORT_SetError(); to the appropriate SEC_ERROR value.
*/
void CERT_MapStanError();
+/* Like CERT_VerifyCert, except with an additional argument, flags. The
+ * flags are defined immediately below.
+ *
+ * OCSP checking is always skipped when certUsage is certUsageStatusResponder.
+ */
+SECStatus
+cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
+ PRBool checkSig, SECCertUsage certUsage, PRTime t,
+ PRUint32 flags, void *wincx, CERTVerifyLog *log);
+
+/* Use the default settings.
+ * cert_VerifyCertWithFlags(..., CERT_VERIFYCERT_USE_DEFAULTS) is equivalent
+ * to CERT_VerifyCert(...);
+ */
+#define CERT_VERIFYCERT_USE_DEFAULTS 0
+
+/* Skip all the OCSP checks during certificate verification, regardless of
+ * the global OCSP settings. By default, certificate |cert| will have its
+ * revocation status checked via OCSP according to the global OCSP settings.
+ */
+#define CERT_VERIFYCERT_SKIP_OCSP 1
+
/* Interface function for libpkix cert validation engine:
* cert_verify wrapper. */
SECStatus
cert_VerifyCertChainPkix(CERTCertificate *cert,
PRBool checkSig,
SECCertUsage requiredUsage,
PRTime time,
void *wincx,
diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c
--- a/security/nss/lib/certhigh/certvfy.c
+++ b/security/nss/lib/certhigh/certvfy.c
@@ -1195,17 +1195,17 @@ CERT_VerifyCertificate(CERTCertDBHandle
if (rv != SECSuccess) {
/* EXIT_IF_NOT_LOGGING(log); XXX ???? */
INVALID_USAGE();
}
/*
* Check OCSP revocation status, but only if the cert we are checking
- * is not a status reponder itself. We only do this in the case
+ * is not a status responder itself. We only do this in the case
* where we checked the cert chain (above); explicit trust "wins"
* (avoids status checking, just as it avoids CRL checking) by
* bypassing this code.
*/
if (PR_FALSE == checkedOCSP) {
checkedOCSP = PR_TRUE; /* only check OCSP once */
statusConfig = CERT_GetStatusConfig(handle);
@@ -1230,20 +1230,29 @@ loser:
return(valid);
}
SECStatus
CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
PRBool checkSig, SECCertUsage certUsage, PRTime t,
void *wincx, CERTVerifyLog *log)
{
+ return cert_VerifyCertWithFlags(handle, cert, checkSig, certUsage, t,
+ CERT_VERIFYCERT_USE_DEFAULTS, wincx, log);
+}
+
+SECStatus
+cert_VerifyCertWithFlags(CERTCertDBHandle *handle, CERTCertificate *cert,
+ PRBool checkSig, SECCertUsage certUsage, PRTime t,
+ PRUint32 flags, void *wincx, CERTVerifyLog *log)
+{
SECStatus rv;
unsigned int requiredKeyUsage;
unsigned int requiredCertType;
- unsigned int flags;
+ unsigned int failedFlags;
unsigned int certType;
PRBool trusted;
PRBool allowOverride;
SECCertTimeValidity validity;
CERTStatusConfig *statusConfig;
#ifdef notdef
/* check if this cert is in the Evil list */
@@ -1302,41 +1311,43 @@ CERT_VerifyCert(CERTCertDBHandle *handle
PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
LOG_ERROR_OR_EXIT(log,cert,0,requiredKeyUsage);
}
if ( !( certType & requiredCertType ) ) {
PORT_SetError(SEC_ERROR_INADEQUATE_CERT_TYPE);
LOG_ERROR_OR_EXIT(log,cert,0,requiredCertType);
}
- rv = cert_CheckLeafTrust(cert,certUsage, &flags, &trusted);
+ rv = cert_CheckLeafTrust(cert, certUsage, &failedFlags, &trusted);
if (rv == SECFailure) {
PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
- LOG_ERROR_OR_EXIT(log,cert,0,flags);
+ LOG_ERROR_OR_EXIT(log, cert, 0, failedFlags);
} else if (trusted) {
goto done;
}
rv = CERT_VerifyCertChain(handle, cert, checkSig, certUsage,
t, wincx, log);
if (rv != SECSuccess) {
EXIT_IF_NOT_LOGGING(log);
}
/*
- * Check revocation status, but only if the cert we are checking
- * is not a status reponder itself. We only do this in the case
- * where we checked the cert chain (above); explicit trust "wins"
- * (avoids status checking, just as it avoids CRL checking, which
- * is all done inside VerifyCertChain) by bypassing this code.
+ * Check revocation status, but only if the cert we are checking is not a
+ * status responder itself and the caller did not ask us to skip the check.
+ * We only do this in the case where we checked the cert chain (above);
+ * explicit trust "wins" (avoids status checking, just as it avoids CRL
+ * checking, which is all done inside VerifyCertChain) by bypassing this
+ * code.
*/
- statusConfig = CERT_GetStatusConfig(handle);
- if (certUsage != certUsageStatusResponder && statusConfig != NULL) {
- if (statusConfig->statusChecker != NULL) {
+ if (!(flags & CERT_VERIFYCERT_SKIP_OCSP) &&
+ certUsage != certUsageStatusResponder) {
+ statusConfig = CERT_GetStatusConfig(handle);
+ if (statusConfig && statusConfig->statusChecker) {
rv = (* statusConfig->statusChecker)(handle, cert,
t, wincx);
if (rv != SECSuccess) {
LOG_ERROR_OR_EXIT(log,cert,0,0);
}
}
}
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -13,16 +13,17 @@
#include "prnetdb.h"
#include "seccomon.h"
#include "secitem.h"
#include "secoidt.h"
#include "secasn1.h"
#include "secder.h"
#include "cert.h"
+#include "certi.h"
#include "xconst.h"
#include "secerr.h"
#include "secoid.h"
#include "hasht.h"
#include "sechash.h"
#include "secasn1.h"
#include "plbase64.h"
#include "keyhi.h"
@@ -4179,18 +4180,19 @@ CERT_VerifyOCSPResponseSignature(CERTOCS
rv = SECSuccess;
} else {
SECCertUsage certUsage;
if (CERT_IsCACert(signerCert, NULL)) {
certUsage = certUsageAnyCA;
} else {
certUsage = certUsageStatusResponder;
}
- rv = CERT_VerifyCert(handle, signerCert, PR_TRUE,
- certUsage, producedAt, pwArg, NULL);
+ rv = cert_VerifyCertWithFlags(handle, signerCert, PR_TRUE, certUsage,
+ producedAt, CERT_VERIFYCERT_SKIP_OCSP,
+ pwArg, NULL);
if (rv != SECSuccess) {
PORT_SetError(SEC_ERROR_OCSP_INVALID_SIGNING_CERT);
goto finish;
}
}
rv = ocsp_VerifyResponseSignature(signerCert, signature,
tbsResponseDataDER,