mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-17 07:15:46 +00:00
Bug 1434300 - Update Imminent Distrust status for future Symantec sanctions r=fkiefer,keeler
This patch does a few things: 1) It adds a permament test mechanism for the "imminent distrust" trust status in nsNSSCallbacks: a simple xpcshell test to exercise a clause in the imminent distrust logic in nsNSSCallbacks' IsCertificateDistrustImminent method. 2) This test removes test_symantec_apple_google_unaffected.js as its functionality is rolled into the new test_imminent_distrust.js. 3) It updates the Symantec imminent distrust warning algorithm to remove the validity date exception; this warns of the upcoming distrust for those affected certs in Firefox 63. This patch does not attempt to edit the browser chrome test that checks the console; that is a subsequent patch. MozReview-Commit-ID: 1HyVLfmEOP7 --HG-- extra : rebase_source : 48c9caae2d26a7e36102b4770c4044101acf0712
This commit is contained in:
parent
ad6889fdd2
commit
d1bff6c67a
@ -0,0 +1,22 @@
|
||||
// Script from security/manager/tools/crtshToDNStruct/crtshToDNStruct.py
|
||||
// Invocation: security/manager/tools/crtshToDNStruct/crtshToDNStruct.py security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem
|
||||
|
||||
// This file is used by test_imminent_distrust.js and by
|
||||
// browser_console_certificate_imminent_distrust.js to ensure that the UI for
|
||||
// alerting users to an upcoming CA distrust action continues to function.
|
||||
|
||||
// /C=US/CN=Imminently Distrusted End Entity
|
||||
// SHA256 Fingerprint: 63:3A:70:8A:67:42:91:95:98:E9:D1:CB:8B:5D:73:80
|
||||
// BA:6D:AD:25:82:62:52:AD:5E:5E:DC:06:BF:03:1F:D0
|
||||
static const uint8_t CAImminentlyDistrustedEndEntityDN[58] = {
|
||||
0x30, 0x38, 0x31, 0x0B, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02,
|
||||
0x55, 0x53, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x20,
|
||||
0x49, 0x6D, 0x6D, 0x69, 0x6E, 0x65, 0x6E, 0x74, 0x6C, 0x79, 0x20, 0x44, 0x69,
|
||||
0x73, 0x74, 0x72, 0x75, 0x73, 0x74, 0x65, 0x64, 0x20, 0x45, 0x6E, 0x64, 0x20,
|
||||
0x45, 0x6E, 0x74, 0x69, 0x74, 0x79,
|
||||
};
|
||||
|
||||
static const DataAndLength TestImminentDistrustEndEntityDNs[]= {
|
||||
{ CAImminentlyDistrustedEndEntityDN,
|
||||
sizeof(CAImminentlyDistrustedEndEntityDN) },
|
||||
};
|
@ -39,7 +39,7 @@
|
||||
#include "TrustOverrideUtils.h"
|
||||
#include "TrustOverride-SymantecData.inc"
|
||||
#include "TrustOverride-AppleGoogleData.inc"
|
||||
|
||||
#include "TrustOverride-TestImminentDistrustData.inc"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::pkix;
|
||||
@ -1255,30 +1255,25 @@ IsCertificateDistrustImminent(nsIX509CertList* aCertList,
|
||||
return rv;
|
||||
}
|
||||
|
||||
// We need to verify the age of the end entity
|
||||
nsCOMPtr<nsIX509CertValidity> validity;
|
||||
rv = eeCert->GetValidity(getter_AddRefs(validity));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
// Check the test certificate condition first; this is a special certificate
|
||||
// that gets the 'imminent distrust' treatment; this is so that the distrust
|
||||
// UX code does not become stale, as it will need regular use. See Bug 1409257
|
||||
// for context. Please do not remove this when adjusting the rest of the
|
||||
// method.
|
||||
UniqueCERTCertificate nssEECert(eeCert->GetCert());
|
||||
if (!nssEECert) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
PRTime notBefore;
|
||||
rv = validity->GetNotBefore(¬Before);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
// PRTime is microseconds since the epoch, whereas JS time is milliseconds.
|
||||
// (new Date("2016-06-01T00:00:00Z")).getTime() * 1000
|
||||
static const PRTime JUNE_1_2016 = 1464739200000000;
|
||||
|
||||
// If the end entity's notBefore date is after 2016-06-01, this algorithm
|
||||
// doesn't apply, so exit false before we do any iterating
|
||||
if (notBefore >= JUNE_1_2016) {
|
||||
aResult = false;
|
||||
aResult = CertDNIsInList(nssEECert.get(), TestImminentDistrustEndEntityDNs);
|
||||
if (aResult) {
|
||||
// Exit early
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Proceed with the Symantec imminent distrust algorithm. This algorithm is
|
||||
// to be removed in Firefox 63, when the validity period check will also be
|
||||
// removed from the code in NSSCertDBTrustDomain.
|
||||
|
||||
// We need an owning handle when calling nsIX509Cert::GetCert().
|
||||
UniqueCERTCertificate nssRootCert(rootCert->GetCert());
|
||||
// If the root is not one of the Symantec roots, exit false
|
||||
|
@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDSzCCAjOgAwIBAgIUa5hfI/44eCaBMFte+oFrCN4wsOAwDQYJKoZIhvcNAQEL
|
||||
BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE2MTEyNzAwMDAwMFoYDzIwMTkw
|
||||
MjA1MDAwMDAwWjA4MQswCQYDVQQGEwJVUzEpMCcGA1UEAxMgSW1taW5lbnRseSBE
|
||||
aXN0cnVzdGVkIEVuZCBFbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
|
||||
AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG
|
||||
m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr
|
||||
bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4
|
||||
SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3
|
||||
/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z
|
||||
FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjbzBtMDcGA1UdEQQwMC6CCWxvY2Fs
|
||||
aG9zdIIhaW1taW5lbnRseS1kaXN0cnVzdGVkLmV4YW1wbGUuY29tMDIGCCsGAQUF
|
||||
BwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkq
|
||||
hkiG9w0BAQsFAAOCAQEAZbcXYrr6V3GvIjGsHEvI7X5P5kwuu7XADxBZItcu9eLv
|
||||
s3Sa7U3tIlhZkLYzsLuPz2q3ZkG+baFayOJgXPPaleEDrxDpElyPYtD+oTvO5oVv
|
||||
2G8UlObIdzuym5FPDpvuiQIcDIZELUOQO9V+fjeK0CZ4luFnox+cIvnB39pLa5Xd
|
||||
hHUyWMgsf9cW/T1yjjRAS2YX/HUYGjSH9MNhSriiAABers1fyJkn7fdVTav2pQTp
|
||||
5yNdtwrFYkWjw1DG17uj/gtkll3ACw9oztjYTGj/okDI+ViLJqL4QeQb4G4Lpp77
|
||||
+A8JfHGf/yFprXMMExy8FNN8FLIxdN2lX4WwBS5WHQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
@ -0,0 +1,4 @@
|
||||
issuer:Test CA
|
||||
subject:printableString/C=US/CN=Imminently Distrusted End Entity
|
||||
extension:subjectAlternativeName:localhost,imminently-distrusted.example.com
|
||||
extension:authorityInformationAccess:http://localhost:8888/
|
@ -13,6 +13,7 @@
|
||||
# 'ca-used-as-end-entity.pem',
|
||||
# 'default-ee.pem',
|
||||
# 'ee-from-missing-intermediate.pem',
|
||||
# 'ee-imminently-distrusted.pem',
|
||||
# 'eeIssuedByNonCA.pem',
|
||||
# 'eeIssuedByV1Cert.pem',
|
||||
# 'emptyIssuerName.pem',
|
||||
|
29
security/manager/ssl/tests/unit/test_imminent_distrust.js
Normal file
29
security/manager/ssl/tests/unit/test_imminent_distrust.js
Normal file
@ -0,0 +1,29 @@
|
||||
/* 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";
|
||||
|
||||
// Tests handling of certificates that are selected to emit a distrust warning
|
||||
// to the console.
|
||||
|
||||
function shouldBeImminentlyDistrusted(aTransportSecurityInfo) {
|
||||
let isDistrust = aTransportSecurityInfo.securityState &
|
||||
Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT;
|
||||
Assert.ok(isDistrust, "This host should be imminently distrusted");
|
||||
}
|
||||
|
||||
function shouldNotBeImminentlyDistrusted(aTransportSecurityInfo) {
|
||||
let isDistrust = aTransportSecurityInfo.securityState &
|
||||
Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT;
|
||||
Assert.ok(!isDistrust, "This host should not be imminently distrusted");
|
||||
}
|
||||
|
||||
do_get_profile();
|
||||
|
||||
add_tls_server_setup("BadCertServer", "bad_certs");
|
||||
|
||||
add_connection_test("imminently-distrusted.example.com",
|
||||
PRErrorCodeSuccess, null, shouldBeImminentlyDistrusted);
|
||||
|
||||
add_connection_test("include-subdomains.pinning.example.com",
|
||||
PRErrorCodeSuccess, null, shouldNotBeImminentlyDistrusted);
|
@ -31,9 +31,9 @@ add_connection_test("symantec-whitelist-after-cutoff.example.com",
|
||||
add_connection_test("symantec-whitelist-before-cutoff.example.com",
|
||||
PRErrorCodeSuccess, null, shouldNotBeImminentlyDistrusted);
|
||||
|
||||
// Not-whitelisted certs after the cutoff aren't distrusted
|
||||
// Not-whitelisted certs after the cutoff are to be distrusted
|
||||
add_connection_test("symantec-not-whitelisted-after-cutoff.example.com",
|
||||
PRErrorCodeSuccess, null, shouldNotBeImminentlyDistrusted);
|
||||
PRErrorCodeSuccess, null, shouldBeImminentlyDistrusted);
|
||||
|
||||
// Not whitelisted certs before the cutoff are to be distrusted
|
||||
add_connection_test("symantec-not-whitelisted-before-cutoff.example.com",
|
||||
|
@ -1,22 +0,0 @@
|
||||
/* 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";
|
||||
|
||||
// Tests handling of certificates issued by Symantec. If such
|
||||
// certificates have a notBefore before 1 June 2016, and are not
|
||||
// issued by an Apple or Google intermediate, they should emit a
|
||||
// warning to the console.
|
||||
|
||||
function shouldNotBeImminentlyDistrusted(aTransportSecurityInfo) {
|
||||
let isDistrust = aTransportSecurityInfo.securityState &
|
||||
Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT;
|
||||
Assert.ok(!isDistrust, "This host should not be imminently distrusted");
|
||||
}
|
||||
|
||||
do_get_profile();
|
||||
|
||||
add_tls_server_setup("OCSPStaplingServer", "ocsp_certs");
|
||||
|
||||
add_connection_test("ocsp-stapling-good.example.com",
|
||||
PRErrorCodeSuccess, null, shouldNotBeImminentlyDistrusted);
|
@ -78,6 +78,7 @@ const BadCertHost sBadCertHosts[] =
|
||||
{ "emptyissuername.example.com", "emptyIssuerName" },
|
||||
{ "ev-test.example.com", "ev-test" },
|
||||
{ "ee-from-missing-intermediate.example.com", "ee-from-missing-intermediate" },
|
||||
{ "imminently-distrusted.example.com", "ee-imminently-distrusted" },
|
||||
{ "localhost", "unknownissuer" },
|
||||
{ nullptr, nullptr }
|
||||
};
|
||||
|
@ -97,6 +97,8 @@ skip-if = toolkit == 'android'
|
||||
skip-if = toolkit == 'android'
|
||||
[test_hmac.js]
|
||||
[test_intermediate_basic_usage_constraints.js]
|
||||
[test_imminent_distrust.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_js_cert_override_service.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_keysize.js]
|
||||
@ -179,8 +181,6 @@ skip-if = toolkit == 'android'
|
||||
[test_sts_preloadlist_selfdestruct.js]
|
||||
[test_symantec_apple_google.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_symantec_apple_google_unaffected.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_validity.js]
|
||||
run-sequentially = hardcoded ports
|
||||
[test_x509.js]
|
||||
|
@ -48,7 +48,7 @@ def nameOIDtoString(oid):
|
||||
return "OU"
|
||||
raise Exception("Unknown OID: {}".format(oid))
|
||||
|
||||
def print_block(pemData):
|
||||
def print_block(pemData, crtshId):
|
||||
substrate = pem.readPemFromFile(io.StringIO(pemData.decode("utf-8")))
|
||||
cert, rest = decoder.decode(substrate, asn1Spec=rfc5280.Certificate())
|
||||
der_subject = encoder.encode(cert['tbsCertificate']['subject'])
|
||||
@ -67,8 +67,9 @@ def print_block(pemData):
|
||||
print("// {dn}".format(dn=distinguished_name))
|
||||
print("// SHA256 Fingerprint: " + ":".join(fingerprint[:16]))
|
||||
print("// " + ":".join(fingerprint[16:]))
|
||||
print("// https://crt.sh/?id={crtsh} (crt.sh ID={crtsh})"
|
||||
.format(crtsh=crtshId))
|
||||
if crtshId:
|
||||
print("// https://crt.sh/?id={crtsh} (crt.sh ID={crtsh})"
|
||||
.format(crtsh=crtshId))
|
||||
print("static const uint8_t {}[{}] = ".format(block_name, len(octets)) + "{")
|
||||
|
||||
while len(octets) > 0:
|
||||
@ -89,11 +90,14 @@ if __name__ == "__main__":
|
||||
print("// Invocation: {} {}".format(sys.argv[0], " ".join(certshIds)))
|
||||
print()
|
||||
for crtshId in certshIds:
|
||||
r = requests.get('https://crt.sh/?d={}'.format(crtshId))
|
||||
r.raise_for_status()
|
||||
|
||||
pemData = r.content
|
||||
blocks.append(print_block(pemData))
|
||||
# Try a local file first, then crt.sh
|
||||
try:
|
||||
with open(crtshId, "rb") as pemFile:
|
||||
blocks.append(print_block(pemFile.read(), None))
|
||||
except FileNotFoundError:
|
||||
r = requests.get('https://crt.sh/?d={}'.format(crtshId))
|
||||
r.raise_for_status()
|
||||
blocks.append(print_block(r.content, crtshId))
|
||||
|
||||
print("static const DataAndLength RootDNs[]= {")
|
||||
for structName in blocks:
|
||||
|
Loading…
Reference in New Issue
Block a user