mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 04:45:45 +00:00
Bug 998057: Add tests for certificate pinning (r=cviecco,dkeeler)
This commit is contained in:
parent
cf6decae49
commit
68b3043845
@ -82,13 +82,15 @@
|
||||
"Baltimore CyberTrust Root"
|
||||
]
|
||||
},
|
||||
// For pinning tests on pinning.example.com, the issuer must be testCA.
|
||||
// For pinning tests on pinning.example.com, the certificate must be 'End
|
||||
// Entity Test Cert'
|
||||
{
|
||||
"name": "mozilla_test",
|
||||
"static_spki_hashes": [
|
||||
"End Entity Test Cert"
|
||||
]
|
||||
} ],
|
||||
}
|
||||
],
|
||||
|
||||
"entries": [
|
||||
{ "name": "addons.mozilla.org", "include_subdomains": true, "pins": "mozilla" },
|
||||
@ -96,7 +98,7 @@
|
||||
{ "name": "cdn.mozilla.net", "include_subdomains": true, "pins": "mozilla_cdn" },
|
||||
{ "name": "cdn.mozilla.org", "include_subdomains": true, "pins": "mozilla_cdn" },
|
||||
{ "name": "media.mozilla.com", "include_subdomains": true, "pins": "mozilla_cdn" },
|
||||
{ "name": "include-subdomain.pinning.example.com", "include_subdomains": true, "pins": "mozilla_test" },
|
||||
{ "name": "include-subdomains.pinning.example.com", "include_subdomains": true, "pins": "mozilla_test" },
|
||||
{ "name": "exclude-subdomains.pinning.example.com", "include_subdomains": false, "pins": "mozilla_test" }
|
||||
]
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ static const char kDigiCert_High_Assurance_EV_Root_CAFingerprint[]=
|
||||
|
||||
/* End Entity Test Cert */
|
||||
static const char kEnd_Entity_Test_CertFingerprint[]=
|
||||
"97H5CNFJ2u3u1NvH3ru67t5OiCO8KydOyNh9GCEyAeM=";
|
||||
"sEIYDccDj1ULE64YxhvqV7ASqc2qfIofVyArzg+62hU=";
|
||||
|
||||
/* Equifax Secure CA */
|
||||
static const char kEquifax_Secure_CAFingerprint[]=
|
||||
@ -196,10 +196,10 @@ static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = {
|
||||
{ "cdn.mozilla.net", true, &kPinSet_mozilla_cdn },
|
||||
{ "cdn.mozilla.org", true, &kPinSet_mozilla_cdn },
|
||||
{ "exclude-subdomains.pinning.example.com", false, &kPinSet_mozilla_test },
|
||||
{ "include-subdomain.pinning.example.com", true, &kPinSet_mozilla_test },
|
||||
{ "include-subdomains.pinning.example.com", true, &kPinSet_mozilla_test },
|
||||
{ "media.mozilla.com", true, &kPinSet_mozilla_cdn },
|
||||
};
|
||||
|
||||
static const int kPublicKeyPinningPreloadListLength = 7;
|
||||
|
||||
const PRTime kPreloadPKPinsExpirationTime = INT64_C(1409763023059000);
|
||||
const PRTime kPreloadPKPinsExpirationTime = INT64_C(1409782406553000);
|
||||
|
Binary file not shown.
@ -51,6 +51,7 @@ const SEC_ERROR_OCSP_INVALID_SIGNING_CERT = SEC_ERROR_BASE + 144;
|
||||
const SEC_ERROR_POLICY_VALIDATION_FAILED = SEC_ERROR_BASE + 160; // -8032
|
||||
const SEC_ERROR_OCSP_BAD_SIGNATURE = SEC_ERROR_BASE + 157;
|
||||
const SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = SEC_ERROR_BASE + 176;
|
||||
const SEC_ERROR_APPLICATION_CALLBACK_ERROR = SEC_ERROR_BASE + 178;
|
||||
|
||||
const SSL_ERROR_BAD_CERT_DOMAIN = SSL_ERROR_BASE + 12;
|
||||
|
||||
|
@ -230,7 +230,7 @@ function add_distrust_override_test(certFileName, hostName,
|
||||
let certToDistrust = constructCertFromFile(certFileName);
|
||||
|
||||
add_test(function () {
|
||||
// "pu" means the cert is actively distrusted.
|
||||
// Add an entry to the NSS certDB that says to distrust the cert
|
||||
setCertTrust(certToDistrust, "pu,,");
|
||||
clearSessionCache();
|
||||
run_next_test();
|
||||
|
96
security/manager/ssl/tests/unit/test_pinning.js
Normal file
96
security/manager/ssl/tests/unit/test_pinning.js
Normal file
@ -0,0 +1,96 @@
|
||||
// -*- 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/.
|
||||
//
|
||||
// For all cases, the acceptable pinset includes only certificates pinned to
|
||||
// Test End Entity Cert (signed by issuer testCA). Other certificates
|
||||
// are issued by otherCA, which is never in the pinset but is a user-specified
|
||||
// trust anchor. This test covers multiple cases:
|
||||
//
|
||||
// Pinned domain include-subdomains.pinning.example.com includes subdomains
|
||||
// - PASS: include-subdomains.pinning.example.com serves a correct cert
|
||||
// - PASS: good.include-subdomains.pinning.example.com serves a correct cert
|
||||
// - FAIL (strict): bad.include-subdomains.pinning.example.com serves a cert
|
||||
// not in the pinset
|
||||
// - PASS (mitm): bad.include-subdomains.pinning.example.com serves a cert not
|
||||
// in the pinset, but issued by a user-specified trust domain
|
||||
//
|
||||
// Pinned domain exclude-subdomains.pinning.example.com excludes subdomains
|
||||
// - PASS: exclude-subdomains.pinning.example.com serves a correct cert
|
||||
// - FAIL: exclude-subdomains.pinning.example.com services an incorrect cert
|
||||
// (TODO: test using verifyCertnow)
|
||||
// - PASS: sub.exclude-subdomains.pinning.example.com serves an incorrect cert
|
||||
|
||||
"use strict";
|
||||
|
||||
do_get_profile(); // must be called before getting nsIX509CertDB
|
||||
const certdb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
|
||||
function test_strict() {
|
||||
// In strict mode, we always evaluate pinning data, regardless of whether the
|
||||
// issuer is a built-in trust anchor.
|
||||
add_test(function() {
|
||||
Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
// Issued by otherCA, which is not in the pinset for pinning.example.com.
|
||||
add_connection_test("bad.include-subdomains.pinning.example.com",
|
||||
getXPCOMStatusFromNSS(SEC_ERROR_APPLICATION_CALLBACK_ERROR));
|
||||
|
||||
// These domains serve certs that match the pinset.
|
||||
add_connection_test("include-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
add_connection_test("good.include-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
add_connection_test("exclude-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
|
||||
// This domain serves a cert that doesn't match the pinset, but subdomains
|
||||
// are excluded.
|
||||
add_connection_test("sub.exclude-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
};
|
||||
|
||||
function test_mitm() {
|
||||
// In MITM mode, we allow pinning to pass if the chain resolves to any
|
||||
// user-specified trust anchor, even if it is not in the pinset.
|
||||
add_test(function() {
|
||||
Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 1);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_connection_test("include-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
add_connection_test("good.include-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
|
||||
// In this case, even though otherCA is not in the pinset, it is a
|
||||
// user-specified trust anchor and the pinning check succeeds.
|
||||
add_connection_test("bad.include-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
|
||||
add_connection_test("exclude-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
add_connection_test("sub.exclude-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
};
|
||||
|
||||
function test_disabled() {
|
||||
// Disable pinning.
|
||||
add_test(function() {
|
||||
Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 0);
|
||||
run_next_test();
|
||||
});
|
||||
|
||||
add_connection_test("include-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
add_connection_test("good.include-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
add_connection_test("bad.include-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
add_connection_test("exclude-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
add_connection_test("sub.exclude-subdomains.pinning.example.com", Cr.NS_OK);
|
||||
};
|
||||
|
||||
function run_test() {
|
||||
add_tls_server_setup("BadCertServer");
|
||||
|
||||
// Add a user-specified trust anchor.
|
||||
addCertFromFile(certdb, "tlsserver/other-test-ca.der", "CTu,u,u");
|
||||
|
||||
test_strict();
|
||||
test_mitm();
|
||||
test_disabled();
|
||||
run_next_test();
|
||||
}
|
Binary file not shown.
@ -24,6 +24,7 @@ struct BadCertHost
|
||||
const char *mCertName;
|
||||
};
|
||||
|
||||
// Hostname, cert nickname pairs.
|
||||
const BadCertHost sBadCertHosts[] =
|
||||
{
|
||||
{ "expired.example.com", "expired" },
|
||||
@ -42,6 +43,15 @@ const BadCertHost sBadCertHosts[] =
|
||||
{ "inadequatekeyusage.example.com", "inadequatekeyusage" },
|
||||
{ "selfsigned-inadequateEKU.example.com", "selfsigned-inadequateEKU" },
|
||||
{ "self-signed-end-entity-with-cA-true.example.com", "self-signed-EE-with-cA-true" },
|
||||
// All of include-subdomains.pinning.example.com is pinned to End Entity Test
|
||||
// Cert with nick localhostAndExampleCom. Any other nick will only pass
|
||||
// pinning when security.cert_pinning.enforcement.level != strict and otherCA
|
||||
// is added as a user-specified trust anchor. See StaticHPKPins.h.
|
||||
{ "include-subdomains.pinning.example.com", "localhostAndExampleCom" },
|
||||
{ "good.include-subdomains.pinning.example.com", "localhostAndExampleCom" },
|
||||
{ "bad.include-subdomains.pinning.example.com", "otherIssuerEE" },
|
||||
{ "exclude-subdomains.pinning.example.com", "localhostAndExampleCom" },
|
||||
{ "sub.exclude-subdomains.pinning.example.com", "otherIssuerEE" },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
||||
|
Binary file not shown.
@ -139,7 +139,10 @@ function make_delegated {
|
||||
|
||||
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,*.pinning.example.com"
|
||||
|
||||
make_EE localhostAndExampleCom 'CN=Test End-entity' testCA "localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com"
|
||||
# Make an EE cert issued by otherCA
|
||||
make_EE otherIssuerEE 'CN=Wrong CA Pin Test End-Entity' otherCA "*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com"
|
||||
|
||||
$RUN_MOZILLA $CERTUTIL -d $OUTPUT_DIR -L -n localhostAndExampleCom -r > $OUTPUT_DIR/default-ee.der
|
||||
# A cert that is like localhostAndExampleCom, but with a different serial number for
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -66,3 +66,7 @@ fail-if = os == "android" || buildapp == "b2g"
|
||||
# Bug 989485 : this test this fails on slow devices
|
||||
skip-if = os == "android" || (buildapp == "b2g" && processor == "arm")
|
||||
requesttimeoutfactor = 4
|
||||
[test_pinning.js]
|
||||
run-sequentially = hardcoded ports
|
||||
# Bug 676972: test fails consistently on Android and B2G
|
||||
fail-if = os == "android" || buildapp == "b2g"
|
||||
|
Loading…
Reference in New Issue
Block a user