Bug 622859 - Tests for bug 622859. r=briansmith,keeler

This commit is contained in:
Cykesiopka 2014-10-16 05:22:00 +02:00
Родитель 01941f880c
Коммит ef48a9fa7c
34 изменённых файлов: 411 добавлений и 104 удалений

Просмотреть файл

@ -90,6 +90,7 @@ struct nsMyTrustedEVInfo
// OCSP signing certificate, or OCSP for the intermediate certificates
// isn't working, or OCSP isn't working at all.
static const size_t NUM_TEST_EV_ROOTS = 2;
static struct nsMyTrustedEVInfo myTrustedEVInfos[] = {
// IMPORTANT! When extending this list,
// pairs of dotted_oid and oid_name should always be unique pairs.
@ -98,10 +99,9 @@ static struct nsMyTrustedEVInfo myTrustedEVInfos[] = {
#ifdef DEBUG
// Debug EV certificates should all use the OID (repeating EV OID is OK):
// 1.3.6.1.4.1.13769.666.666.666.1.500.9.1.
// If you add or remove debug EV certs you must also modify IdentityInfoInit
// (there is another #ifdef DEBUG section there) so that the correct number of
// certs are skipped as these debug EV certs are NOT part of the default trust
// store.
// If you add or remove debug EV certs you must also modify NUM_TEST_EV_ROOTS
// so that the correct number of certs are skipped as these debug EV certs are
// NOT part of the default trust store.
{
// This is the testing EV signature (xpcshell) (RSA)
// CN=XPCShell EV Testing (untrustworthy) CA,OU=Security Engineering,O=Mozilla - EV debug test CA,L=Mountain View,ST=CA,C=US"
@ -118,6 +118,20 @@ static struct nsMyTrustedEVInfo myTrustedEVInfos[] = {
"At+3zdo=",
nullptr
},
{
// The RSA root with an inadequate key size used for EV key size checking
// O=ev-rsa-caBad,CN=XPCShell Key Size Testing rsa 2040-bit (EV)
"1.3.6.1.4.1.13769.666.666.666.1.500.9.1",
"DEBUGtesting EV OID",
SEC_OID_UNKNOWN,
{ 0x0E, 0xE2, 0x7A, 0x44, 0xD3, 0xAB, 0x66, 0x1A, 0x31, 0xBF, 0x0C,
0x1C, 0xFC, 0xAA, 0xD9, 0xD6, 0x27, 0x75, 0xC2, 0xDB, 0xC5, 0x69,
0xD7, 0x1C, 0xDE, 0x9C, 0x7E, 0xD5, 0x86, 0x88, 0x6C, 0xB7 },
"ME0xNDAyBgNVBAMMK1hQQ1NoZWxsIEtleSBTaXplIFRlc3RpbmcgcnNhIDIwNDAt"
"Yml0IChFVikxFTATBgNVBAoMDGV2LXJzYS1jYUJhZA==",
"PCQ3",
nullptr
},
#endif
{
// OU=Security Communication EV RootCA1,O="SECOM Trust Systems CO.,LTD.",C=JP
@ -1082,8 +1096,9 @@ IdentityInfoInit()
// treating that root cert as EV.
if (!entry.cert) {
#ifdef DEBUG
// The debug CA info is at position 0, and is NOT on the NSS root db
if (iEV == 0) {
// The debug CA structs are at positions 0 to NUM_TEST_EV_ROOTS - 1, and
// are NOT in the NSS root DB.
if (iEV < NUM_TEST_EV_ROOTS) {
continue;
}
#endif

Просмотреть файл

@ -183,6 +183,33 @@ def generate_pkcs12(db_dir, dest_dir, der_cert_filename, key_pem_filename,
child.expect(pexpect.EOF)
return pk12_filename
def import_cert_and_pkcs12(db_dir, cert_filename, pkcs12_filename, nickname,
trust_flags):
"""
Imports a given certificate file and PKCS12 file into the SQL NSS DB.
Arguments:
db_dir -- the location of the database and password file
cert_filename -- the filename of the cert in DER format
pkcs12_filename -- the filename of the private key of the cert in PEM
format
nickname -- the nickname to assign to the cert
trust_flags -- the trust flags the cert should have
"""
os.system('certutil -A -d sql:' + db_dir + ' -n ' + nickname + ' -i ' +
cert_filename + ' -t "' + trust_flags + '"')
os.system('pk12util -i ' + pkcs12_filename + ' -d sql:' + db_dir +
' -w ' + db_dir + '/pwfile')
def print_cert_info_for_ev(cert_filename):
"""
Prints out the information required to enable EV for the given cert.
Arguments:
cert_filename -- the filename of the cert in DER format
"""
os.system('pp -t certificate-identity -i ' + cert_filename)
def init_nss_db(db_dir):
"""
Remove the current nss database in the specified directory and create a new

Двоичные данные
security/manager/ssl/tests/unit/test_keysize/cert9.db Normal file

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
security/manager/ssl/tests/unit/test_keysize/ev-rsa-caBad.der Normal file

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичные данные
security/manager/ssl/tests/unit/test_keysize/ev-rsa-intOK-caOK.der Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -18,121 +18,222 @@ db_dir = tempfile.mkdtemp()
dsaBad_param_filename = 'dsaBad_param.pem'
dsaOK_param_filename = 'dsaOK_param.pem'
ca_ext_text = 'basicConstraints = critical, CA:TRUE\n'
ca_ext_text = ('basicConstraints = critical, CA:TRUE\n' +
'keyUsage = keyCertSign, cRLSign\n')
ee_ext_text = ''
def generate_certs(key_type, bad_key_size, ok_key_size):
aia_prefix = 'authorityInfoAccess = OCSP;URI:http://www.example.com:8888/'
aia_suffix = '/\n'
mozilla_testing_ev_policy = ('certificatePolicies = @v3_ca_ev_cp\n\n' +
'[ v3_ca_ev_cp ]\n' +
'policyIdentifier = ' +
'1.3.6.1.4.1.13769.666.666.666.1.500.9.1\n\n' +
'CPS.1 = "http://mytestdomain.local/cps"')
generated_ev_root_filenames = []
def generate_and_maybe_import_cert(key_type, cert_name_suffix, base_ext_text,
signer_key_filename, signer_cert_filename,
dsa_param_filename, key_size, generate_ev):
"""
Generates a certificate and imports it into the NSS DB if appropriate.
Arguments:
key_type -- the type of key generated: potential values: 'rsa', 'dsa',
or any of the curves found by 'openssl ecparam -list_curves'
cert_name_suffix -- suffix of the generated cert name
base_ext_text -- the base text for the x509 extensions to be added to the
certificate (extra extensions will be added if generating
an EV cert)
signer_key_filename -- the filename of the key from which the cert will
be signed. If an empty string is passed in the cert
will be self signed (think CA roots).
signer_cert_filename -- the filename of the signer cert that will sign the
certificate being generated. Ignored if an empty
string is passed in for signer_key_filename.
Must be in DER format.
dsa_param_filename -- the filename for the DSA param file
key_size -- public key size for RSA certs
generate_ev -- whether an EV cert should be generated
Output:
key_filename -- the filename of the key file (PEM format)
cert_filename -- the filename of the certificate (DER format)
"""
cert_name = key_type + cert_name_suffix
ev_ext_text = ''
subject_string = ('/CN=XPCShell Key Size Testing %s %s-bit' %
(key_type, key_size))
if generate_ev:
cert_name = 'ev-' + cert_name
ev_ext_text = (aia_prefix + cert_name + aia_suffix +
mozilla_testing_ev_policy)
subject_string += ' (EV)'
# Use the organization field to store the cert nickname for easier debugging
subject_string += '/O=' + cert_name
[key_filename, cert_filename] = CertUtils.generate_cert_generic(
db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
cert_name,
base_ext_text + ev_ext_text,
signer_key_filename,
signer_cert_filename,
subject_string,
dsa_param_filename,
key_size)
if generate_ev:
# The dest_dir argument of generate_pkcs12() is also set to db_dir as
# the .p12 files do not need to be kept once they have been imported.
pkcs12_filename = CertUtils.generate_pkcs12(db_dir, db_dir,
cert_filename, key_filename,
cert_name)
CertUtils.import_cert_and_pkcs12(srcdir, cert_filename, pkcs12_filename,
cert_name, ',,')
if not signer_key_filename:
generated_ev_root_filenames.append(cert_filename)
return [key_filename, cert_filename]
def generate_certs(key_type, bad_key_size, ok_key_size, generate_ev):
"""
Generates the various certificates used by the key size tests.
Arguments:
key_type -- the type of key generated: potential values: 'rsa', 'dsa',
or any of the curves found by 'openssl ecparam -list_curves'
bad_key_size -- the public key size bad certs should have
ok_key_size -- the public key size OK certs should have
generate_ev -- whether an EV cert should be generated
"""
if key_type == 'dsa':
CertUtils.init_dsa(db_dir, dsaBad_param_filename, bad_key_size)
CertUtils.init_dsa(db_dir, dsaOK_param_filename, ok_key_size)
# OK Chain
[caOK_key, caOK_cert] = CertUtils.generate_cert_generic(
db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-caOK',
ca_ext_text,
dsa_param_filename = dsaOK_param_filename,
key_size = ok_key_size)
if generate_ev and key_type == 'rsa':
# Reuse the existing RSA EV root
caOK_cert_name = 'evroot'
caOK_key = '../test_ev_certs/evroot.key'
caOK_cert = '../test_ev_certs/evroot.der'
caOK_pkcs12_filename = '../test_ev_certs/evroot.p12'
CertUtils.import_cert_and_pkcs12(srcdir, caOK_cert, caOK_pkcs12_filename,
caOK_cert_name, ',,')
else:
[caOK_key, caOK_cert] = generate_and_maybe_import_cert(
key_type,
'-caOK',
ca_ext_text,
'',
'',
dsaOK_param_filename,
ok_key_size,
generate_ev)
[intOK_key, intOK_cert] = CertUtils.generate_cert_generic(
db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-intOK-caOK',
ca_ext_text,
caOK_key,
caOK_cert,
dsa_param_filename = dsaOK_param_filename,
key_size = ok_key_size)
[intOK_key, intOK_cert] = generate_and_maybe_import_cert(
key_type,
'-intOK-caOK',
ca_ext_text,
caOK_key,
caOK_cert,
dsaOK_param_filename,
ok_key_size,
generate_ev)
CertUtils.generate_cert_generic(db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-eeOK-intOK-caOK',
ee_ext_text,
intOK_key,
intOK_cert,
dsa_param_filename = dsaOK_param_filename,
key_size = ok_key_size)
generate_and_maybe_import_cert(
key_type,
'-eeOK-intOK-caOK',
ee_ext_text,
intOK_key,
intOK_cert,
dsaOK_param_filename,
ok_key_size,
generate_ev)
# Bad CA
[caBad_key, caBad_cert] = CertUtils.generate_cert_generic(
db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-caBad',
ca_ext_text,
dsa_param_filename = dsaBad_param_filename,
key_size = bad_key_size)
[caBad_key, caBad_cert] = generate_and_maybe_import_cert(
key_type,
'-caBad',
ca_ext_text,
'',
'',
dsaBad_param_filename,
bad_key_size,
generate_ev)
[int_key, int_cert] = CertUtils.generate_cert_generic(
db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-intOK-caBad',
ca_ext_text,
caBad_key,
caBad_cert,
dsa_param_filename = dsaOK_param_filename,
key_size = ok_key_size)
[int_key, int_cert] = generate_and_maybe_import_cert(
key_type,
'-intOK-caBad',
ca_ext_text,
caBad_key,
caBad_cert,
dsaOK_param_filename,
ok_key_size,
generate_ev)
CertUtils.generate_cert_generic(db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-eeOK-intOK-caBad',
ee_ext_text,
int_key,
int_cert,
dsa_param_filename = dsaOK_param_filename,
key_size = ok_key_size)
generate_and_maybe_import_cert(
key_type,
'-eeOK-intOK-caBad',
ee_ext_text,
int_key,
int_cert,
dsaOK_param_filename,
ok_key_size,
generate_ev)
# Bad Intermediate
[intBad_key, intBad_cert] = CertUtils.generate_cert_generic(
db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-intBad-caOK',
ca_ext_text,
caOK_key,
caOK_cert,
dsa_param_filename = dsaBad_param_filename,
key_size = bad_key_size)
[intBad_key, intBad_cert] = generate_and_maybe_import_cert(
key_type,
'-intBad-caOK',
ca_ext_text,
caOK_key,
caOK_cert,
dsaBad_param_filename,
bad_key_size,
generate_ev)
CertUtils.generate_cert_generic(db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-eeOK-intBad-caOK',
ee_ext_text,
intBad_key,
intBad_cert,
dsa_param_filename = dsaOK_param_filename,
key_size = ok_key_size)
generate_and_maybe_import_cert(
key_type,
'-eeOK-intBad-caOK',
ee_ext_text,
intBad_key,
intBad_cert,
dsaOK_param_filename,
ok_key_size,
generate_ev)
# Bad End Entity
CertUtils.generate_cert_generic(db_dir,
srcdir,
random.randint(100, 40000000),
key_type,
key_type + '-eeBad-intOK-caOK',
ee_ext_text,
intOK_key,
intOK_cert,
dsa_param_filename = dsaBad_param_filename,
key_size = bad_key_size)
generate_and_maybe_import_cert(
key_type,
'-eeBad-intOK-caOK',
ee_ext_text,
intOK_key,
intOK_cert,
dsaBad_param_filename,
bad_key_size,
generate_ev)
# SECKEY_PublicKeyStrengthInBits() rounds up the number of bits to the next
# multiple of 8 - therefore the highest key size less than 1024 that can be
# tested at the moment is 1016
generate_certs('rsa', '1016', '1024')
# Create a NSS DB for use by the OCSP responder.
CertUtils.init_nss_db(srcdir)
generate_certs('dsa', '960', '1024')
# TODO(bug 636807): SECKEY_PublicKeyStrengthInBits() rounds up the number of
# bits to the next multiple of 8 - therefore the highest key size less than 1024
# that can be tested is 1016, less than 2048 is 2040 and so on.
generate_certs('rsa', '1016', '1024', False)
generate_certs('rsa', '2040', '2048', True)
generate_certs('dsa', '960', '1024', False)
# Print a blank line and the information needed to enable EV for any roots
# generated by this script.
print
for cert_filename in generated_ev_root_filenames:
CertUtils.print_cert_info_for_ev(cert_filename)
print ('You now MUST update the compiled test EV root information to match ' +
'the EV root information printed above.')

Двоичные данные
security/manager/ssl/tests/unit/test_keysize/key4.db Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,5 @@
library=
name=NSS Internal PKCS #11 Module
parameters=configdir='sql:/home/m-c_drive/mozilla-inbound/security/manager/ssl/tests/unit/test_keysize' certPrefix='' keyPrefix='' secmod='secmod.db' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription=''
NSS=Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES,Camellia,SEED,SHA256,SHA512] askpw=any timeout=30})

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,154 @@
// -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/publicdomain/zero/1.0/
"use strict";
// Checks that RSA certs with key sizes below 2048 bits when verifying for EV
// are rejected.
do_get_profile(); // Must be called before getting nsIX509CertDB
const certDB = Cc["@mozilla.org/security/x509certdb;1"]
.getService(Ci.nsIX509CertDB);
const SERVER_PORT = 8888;
function getOCSPResponder(expectedCertNames) {
let expectedPaths = expectedCertNames.slice();
return startOCSPResponder(SERVER_PORT, "www.example.com", [],
"test_keysize", expectedCertNames, expectedPaths);
}
function certFromFile(filename) {
let der = readFile(do_get_file("test_keysize/" + filename, false));
return certDB.constructX509(der, der.length);
}
function loadCert(certName, trustString) {
let certFilename = certName + ".der";
addCertFromFile(certDB, "test_keysize/" + certFilename, trustString);
return certFromFile(certFilename);
}
function checkEVStatus(cert, usage, isEVExpected) {
do_print("cert cn=" + cert.commonName);
do_print("cert o=" + cert.organization);
do_print("cert issuer cn=" + cert.issuerCommonName);
do_print("cert issuer o=" + cert.issuerOrganization);
let hasEVPolicy = {};
let verifiedChain = {};
let error = certDB.verifyCertNow(cert, usage, NO_FLAGS, verifiedChain,
hasEVPolicy);
equal(hasEVPolicy.value, isEVExpected);
equal(0, error);
}
/**
* Adds a single EV key size test.
*
* @param {Array} expectedNamesForOCSP
* An array of nicknames of the certs to be responded to. The cert name
* prefix is not added to the nicknames in this array.
* @param {String} certNamePrefix
* The prefix to prepend to the passed in cert names.
* @param {String} rootCACertFileName
* The file name of the root CA cert. Can begin with ".." to reference
* certs in folders other than "test_keysize/".
* @param {Array} subCACertFileNames
* An array of file names of any sub CA certificates.
* @param {String} endEntityCertFileName
* The file name of the end entity cert.
* @param {Boolean} expectedResult
* Whether the chain is expected to validate as EV.
*/
function addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
rootCACertFileName, subCACertFileNames,
endEntityCertFileName, expectedResult)
{
add_test(function() {
clearOCSPCache();
let ocspResponder = getOCSPResponder(expectedNamesForOCSP);
// Don't prepend the cert name prefix if rootCACertFileName starts with ".."
// to support reusing certs in other directories.
let rootCertNamePrefix = rootCACertFileName.startsWith("..")
? ""
: certNamePrefix;
loadCert(rootCertNamePrefix + rootCACertFileName, "CTu,CTu,CTu");
for (let subCACertFileName of subCACertFileNames) {
loadCert(certNamePrefix + subCACertFileName, ",,");
}
checkEVStatus(certFromFile(certNamePrefix + endEntityCertFileName + ".der"),
certificateUsageSSLServer, expectedResult);
ocspResponder.stop(run_next_test);
});
}
/**
* For debug builds which have the test EV roots compiled in, checks for the
* given key type that good chains validate as EV, while bad chains fail EV and
* validate as DV.
* For opt builds which don't have the test EV roots compiled in, checks that
* none of the chains validate as EV.
*
* Note: This function assumes that the key size requirements for EV are greater
* than or equal to the requirements for DV.
*
* @param {String} keyType
* The key type to check (e.g. "rsa").
*/
function checkForKeyType(keyType) {
let certNamePrefix = "ev-" + keyType;
// Reuse the existing test RSA EV root
let rootCAOKCertFileName = keyType == "rsa" ? "../test_ev_certs/evroot"
: "-caOK";
// OK CA -> OK INT -> OK EE
// In opt builds, this chain is only validated for DV. Hence, an OCSP fetch
// will not be done for the "-intOK-caOK" intermediate in such a build.
let expectedNamesForOCSP = isDebugBuild
? [ certNamePrefix + "-intOK-caOK",
certNamePrefix + "-eeOK-intOK-caOK" ]
: [ certNamePrefix + "-eeOK-intOK-caOK" ];
addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
rootCAOKCertFileName,
["-intOK-caOK"],
"-eeOK-intOK-caOK",
isDebugBuild);
// Bad CA -> OK INT -> OK EE
expectedNamesForOCSP = [ certNamePrefix + "-eeOK-intOK-caBad" ];
addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
"-caBad",
["-intOK-caBad"],
"-eeOK-intOK-caBad",
false);
// OK CA -> Bad INT -> OK EE
expectedNamesForOCSP = isDebugBuild
? [ certNamePrefix + "-intBad-caOK" ]
: [ certNamePrefix + "-eeOK-intBad-caOK" ];
addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
rootCAOKCertFileName,
["-intBad-caOK"],
"-eeOK-intBad-caOK",
false);
// OK CA -> OK INT -> Bad EE
expectedNamesForOCSP = [ certNamePrefix + "-eeBad-intOK-caOK" ];
addKeySizeTestForEV(expectedNamesForOCSP, certNamePrefix,
rootCAOKCertFileName,
["-intOK-caOK"],
"-eeBad-intOK-caOK",
false);
}
function run_test() {
// Setup OCSP responder
Services.prefs.setCharPref("network.dns.localDomains", "www.example.com");
checkForKeyType("rsa");
run_next_test();
}

Просмотреть файл

@ -106,6 +106,11 @@ run-sequentially = hardcoded ports
skip-if = os == "android"
[test_add_preexisting_cert.js]
[test_keysize.js]
[test_keysize_ev.js]
run-sequentially = hardcoded ports
# Bug 1009158: this test times out on Android
# Bug 1008316: B2G doesn't have EV enabled
skip-if = os == "android" || buildapp == "b2g"
[test_cert_chains.js]
run-sequentially = hardcoded ports
# Bug 1009158: this test times out on Android