mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-24 01:17:34 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
246
security/manager/ssl/tests/unit/test_pinning_dynamic.js
Normal file
246
security/manager/ssl/tests/unit/test_pinning_dynamic.js
Normal file
|
|
@ -0,0 +1,246 @@
|
|||
/* 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";
|
||||
|
||||
// The purpose of this test is to create a site security service state file
|
||||
// and see that the site security service reads it properly.
|
||||
|
||||
function writeLine(aLine, aOutputStream) {
|
||||
aOutputStream.write(aLine, aLine.length);
|
||||
}
|
||||
|
||||
var gSSService = null;
|
||||
var gSSSStateSeen = false;
|
||||
var gPreloadStateSeen = false;
|
||||
|
||||
var profileDir = do_get_profile();
|
||||
var certdb;
|
||||
|
||||
function certFromFile(cert_name) {
|
||||
return constructCertFromFile("test_pinning_dynamic/" + cert_name + ".pem");
|
||||
}
|
||||
|
||||
function loadCert(cert_name, trust_string) {
|
||||
let cert_filename = "test_pinning_dynamic/" + cert_name + ".pem";
|
||||
addCertFromFile(certdb, cert_filename, trust_string);
|
||||
return constructCertFromFile(cert_filename);
|
||||
}
|
||||
|
||||
function checkOK(cert, hostname) {
|
||||
return checkCertErrorGeneric(certdb, cert, PRErrorCodeSuccess,
|
||||
certificateUsageSSLServer, {}, hostname);
|
||||
}
|
||||
|
||||
function checkFail(cert, hostname) {
|
||||
return checkCertErrorGeneric(certdb, cert, MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE,
|
||||
certificateUsageSSLServer, {}, hostname);
|
||||
}
|
||||
|
||||
const NON_ISSUED_KEY_HASH = "KHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAN=";
|
||||
const PINNING_ROOT_KEY_HASH = "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=";
|
||||
|
||||
function run_test() {
|
||||
Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2);
|
||||
|
||||
let stateFile = profileDir.clone();
|
||||
stateFile.append(SSS_STATE_FILE_NAME);
|
||||
// Assuming we're working with a clean slate, the SSS_STATE file shouldn't
|
||||
// exist until we create it.
|
||||
ok(!stateFile.exists(),
|
||||
"State file should not exist when working with a clean slate");
|
||||
let outputStream = FileUtils.openFileOutputStream(stateFile);
|
||||
let now = (new Date()).getTime();
|
||||
writeLine(`a.pinning2.example.com:HPKP\t0\t0\t${now + 100000},1,0,${PINNING_ROOT_KEY_HASH}\n`, outputStream);
|
||||
writeLine(`b.pinning2.example.com:HPKP\t0\t0\t${now + 100000},1,1,${PINNING_ROOT_KEY_HASH}\n`, outputStream);
|
||||
|
||||
outputStream.close();
|
||||
|
||||
let preloadFile = profileDir.clone();
|
||||
preloadFile.append(PRELOAD_STATE_FILE_NAME);
|
||||
ok(!preloadFile.exists(),
|
||||
"Preload file should not exist when working with a clean slate");
|
||||
|
||||
outputStream = FileUtils.openFileOutputStream(preloadFile);
|
||||
writeLine(`a.preload.example.com:HPKP\t0\t0\t${now + 100000},1,1,${PINNING_ROOT_KEY_HASH}\n`, outputStream);
|
||||
outputStream.close();
|
||||
|
||||
Services.obs.addObserver(checkStateRead, "data-storage-ready", false);
|
||||
do_test_pending();
|
||||
gSSService = Cc["@mozilla.org/ssservice;1"]
|
||||
.getService(Ci.nsISiteSecurityService);
|
||||
notEqual(gSSService, null,
|
||||
"SiteSecurityService should have initialized successfully using" +
|
||||
" the generated state file");
|
||||
}
|
||||
|
||||
function checkDefaultSiteHPKPStatus() {
|
||||
ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
||||
"a.pinning2.example.com", 0),
|
||||
"a.pinning2.example.com should have HPKP status");
|
||||
ok(!gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
||||
"x.a.pinning2.example.com", 0),
|
||||
"x.a.pinning2.example.com should not have HPKP status");
|
||||
ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
||||
"b.pinning2.example.com", 0),
|
||||
"b.pinning2.example.com should have HPKP status");
|
||||
ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
||||
"x.b.pinning2.example.com", 0),
|
||||
"x.b.pinning2.example.com should have HPKP status");
|
||||
}
|
||||
|
||||
function checkStateRead(aSubject, aTopic, aData) {
|
||||
if (aData == SSS_STATE_FILE_NAME) {
|
||||
gSSSStateSeen = true;
|
||||
} else if (aData == PRELOAD_STATE_FILE_NAME) {
|
||||
gPreloadStateSeen = true;
|
||||
} else {
|
||||
throw new Error("Observed data should either be the Site Security " +
|
||||
"Service state file name or the preload file name");
|
||||
}
|
||||
|
||||
if (!gSSSStateSeen || !gPreloadStateSeen) {
|
||||
return;
|
||||
}
|
||||
|
||||
notEqual(gSSService, null, "SiteSecurityService should be initialized");
|
||||
|
||||
// Initializing the certificate DB will cause NSS-initialization, which in
|
||||
// turn initializes the site security service. Since we're in part testing
|
||||
// that the site security service correctly reads its state file, we have to
|
||||
// make sure it doesn't start up before we've populated the file
|
||||
certdb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
|
||||
loadCert("pinningroot", "CTu,CTu,CTu");
|
||||
loadCert("badca", "CTu,CTu,CTu");
|
||||
|
||||
// the written entry is for a.pinning2.example.com without subdomains
|
||||
// and b.pinning2.example.com with subdomains
|
||||
checkFail(certFromFile('a.pinning2.example.com-badca'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('a.pinning2.example.com-pinningroot'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-badca'), "x.a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-pinningroot'), "x.a.pinning2.example.com");
|
||||
|
||||
checkFail(certFromFile('b.pinning2.example.com-badca'), "b.pinning2.example.com");
|
||||
checkOK(certFromFile('b.pinning2.example.com-pinningroot'), "b.pinning2.example.com");
|
||||
checkFail(certFromFile('x.b.pinning2.example.com-badca'), "x.b.pinning2.example.com");
|
||||
checkOK(certFromFile('x.b.pinning2.example.com-pinningroot'), "x.b.pinning2.example.com");
|
||||
|
||||
checkDefaultSiteHPKPStatus();
|
||||
|
||||
|
||||
// add includeSubdomains to a.pinning2.example.com
|
||||
gSSService.setKeyPins("a.pinning2.example.com", true,
|
||||
new Date().getTime() + 1000000, 2,
|
||||
[NON_ISSUED_KEY_HASH, PINNING_ROOT_KEY_HASH]);
|
||||
checkFail(certFromFile('a.pinning2.example.com-badca'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('a.pinning2.example.com-pinningroot'), "a.pinning2.example.com");
|
||||
checkFail(certFromFile('x.a.pinning2.example.com-badca'), "x.a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-pinningroot'), "x.a.pinning2.example.com");
|
||||
checkFail(certFromFile('b.pinning2.example.com-badca'), "b.pinning2.example.com");
|
||||
checkOK(certFromFile('b.pinning2.example.com-pinningroot'), "b.pinning2.example.com");
|
||||
checkFail(certFromFile('x.b.pinning2.example.com-badca'), "x.b.pinning2.example.com");
|
||||
checkOK(certFromFile('x.b.pinning2.example.com-pinningroot'), "x.b.pinning2.example.com");
|
||||
|
||||
ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
||||
"a.pinning2.example.com", 0),
|
||||
"a.pinning2.example.com should still have HPKP status after adding" +
|
||||
" includeSubdomains to a.pinning2.example.com");
|
||||
ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
||||
"x.a.pinning2.example.com", 0),
|
||||
"x.a.pinning2.example.com should now have HPKP status after adding" +
|
||||
" includeSubdomains to a.pinning2.example.com");
|
||||
|
||||
// Now setpins without subdomains
|
||||
gSSService.setKeyPins("a.pinning2.example.com", false,
|
||||
new Date().getTime() + 1000000, 2,
|
||||
[NON_ISSUED_KEY_HASH, PINNING_ROOT_KEY_HASH]);
|
||||
checkFail(certFromFile('a.pinning2.example.com-badca'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('a.pinning2.example.com-pinningroot'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-badca'), "x.a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-pinningroot'), "x.a.pinning2.example.com");
|
||||
|
||||
checkFail(certFromFile('b.pinning2.example.com-badca'), "b.pinning2.example.com");
|
||||
checkOK(certFromFile('b.pinning2.example.com-pinningroot'), "b.pinning2.example.com");
|
||||
checkFail(certFromFile('x.b.pinning2.example.com-badca'), "x.b.pinning2.example.com");
|
||||
checkOK(certFromFile('x.b.pinning2.example.com-pinningroot'), "x.b.pinning2.example.com");
|
||||
|
||||
checkDefaultSiteHPKPStatus();
|
||||
|
||||
// failure to insert new pin entry leaves previous pin behavior
|
||||
throws(() => {
|
||||
gSSService.setKeyPins("a.pinning2.example.com", true,
|
||||
new Date().getTime() + 1000000, 1, ["not a hash"]);
|
||||
}, /NS_ERROR_ILLEGAL_VALUE/, "Attempting to set an invalid pin should fail");
|
||||
checkFail(certFromFile('a.pinning2.example.com-badca'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('a.pinning2.example.com-pinningroot'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-badca'), "x.a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-pinningroot'), "x.a.pinning2.example.com");
|
||||
|
||||
checkFail(certFromFile('b.pinning2.example.com-badca'), "b.pinning2.example.com");
|
||||
checkOK(certFromFile('b.pinning2.example.com-pinningroot'), "b.pinning2.example.com");
|
||||
checkFail(certFromFile('x.b.pinning2.example.com-badca'), "x.b.pinning2.example.com");
|
||||
checkOK(certFromFile('x.b.pinning2.example.com-pinningroot'), "x.b.pinning2.example.com");
|
||||
|
||||
checkDefaultSiteHPKPStatus();
|
||||
|
||||
// Incorrect size results in failure
|
||||
throws(() => {
|
||||
gSSService.setKeyPins("a.pinning2.example.com", true,
|
||||
new Date().getTime() + 1000000, 2, ["not a hash"]);
|
||||
}, /NS_ERROR_XPC_NOT_ENOUGH_ELEMENTS_IN_ARRAY/,
|
||||
"Attempting to set a pin with an incorrect size should fail");
|
||||
|
||||
// Ensure built-in pins work as expected
|
||||
ok(!gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
||||
"nonexistent.example.com", 0),
|
||||
"Not built-in nonexistent.example.com should not have HPKP status");
|
||||
ok(gSSService.isSecureHost(Ci.nsISiteSecurityService.HEADER_HPKP,
|
||||
"include-subdomains.pinning.example.com", 0),
|
||||
"Built-in include-subdomains.pinning.example.com should have HPKP status");
|
||||
|
||||
gSSService.setKeyPins("a.pinning2.example.com", false, new Date().getTime(),
|
||||
1, [NON_ISSUED_KEY_HASH]);
|
||||
|
||||
// Check that a preload pin loaded from file works as expected
|
||||
checkFail(certFromFile("a.preload.example.com-badca"), "a.preload.example.com");
|
||||
checkOK(certFromFile("a.preload.example.com-pinningroot"), "a.preload.example.com");
|
||||
|
||||
// Check a dynamic addition works as expected
|
||||
// first, it should succeed with the badCA - because there's no pin
|
||||
checkOK(certFromFile('b.preload.example.com-badca'), "b.preload.example.com");
|
||||
// then we add a pin, and we should get a failure (ensuring the expiry is
|
||||
// after the test timeout)
|
||||
gSSService.setKeyPins("b.preload.example.com", false,
|
||||
new Date().getTime() + 1000000, 2,
|
||||
[NON_ISSUED_KEY_HASH, PINNING_ROOT_KEY_HASH], true);
|
||||
checkFail(certFromFile('b.preload.example.com-badca'), "b.preload.example.com");
|
||||
|
||||
do_timeout(1250, checkExpiredState);
|
||||
}
|
||||
|
||||
function checkExpiredState() {
|
||||
checkOK(certFromFile('a.pinning2.example.com-badca'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('a.pinning2.example.com-pinningroot'), "a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-badca'), "x.a.pinning2.example.com");
|
||||
checkOK(certFromFile('x.a.pinning2.example.com-pinningroot'), "x.a.pinning2.example.com");
|
||||
|
||||
checkFail(certFromFile('b.pinning2.example.com-badca'), "b.pinning2.example.com");
|
||||
checkOK(certFromFile('b.pinning2.example.com-pinningroot'), "b.pinning2.example.com");
|
||||
checkFail(certFromFile('x.b.pinning2.example.com-badca'), "x.b.pinning2.example.com");
|
||||
checkOK(certFromFile('x.b.pinning2.example.com-pinningroot'), "x.b.pinning2.example.com");
|
||||
checkPreloadClear();
|
||||
}
|
||||
|
||||
function checkPreloadClear() {
|
||||
// Check that the preloaded pins still work after private data is cleared
|
||||
gSSService.clearAll();
|
||||
checkFail(certFromFile('b.preload.example.com-badca'), "b.preload.example.com");
|
||||
|
||||
// Check that the preloaded pins are cleared when we clear preloads
|
||||
gSSService.clearPreloads();
|
||||
checkOK(certFromFile('b.preload.example.com-badca'), "b.preload.example.com");
|
||||
|
||||
do_test_finished();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue