зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1228794 - Convert test_getchain.js to generate certificates at build time. r=keeler
With this change, CertUtils.py is no longer needed. --HG-- extra : rebase_source : 2e7c7f82c17fd44d97fc68f657f3c313f4b4d125
This commit is contained in:
Родитель
d61cdc0082
Коммит
ee7d82a508
|
@ -16,6 +16,7 @@ TEST_DIRS += [
|
|||
'test_cert_trust',
|
||||
'test_cert_version',
|
||||
'test_ev_certs',
|
||||
'test_getchain',
|
||||
'test_intermediate_basic_usage_constraints',
|
||||
'test_keysize',
|
||||
'test_keysize_ev',
|
||||
|
|
|
@ -1,344 +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/.
|
||||
|
||||
# This file requires openssl 1.0.0 at least
|
||||
|
||||
import os
|
||||
import random
|
||||
import pexpect
|
||||
import time
|
||||
import sys
|
||||
|
||||
default_validity_in_days = 10 * 365
|
||||
|
||||
def generate_cert_generic(db_dir, dest_dir, serial_num, key_type, name,
|
||||
ext_text, signer_key_filename = "",
|
||||
signer_cert_filename = "",
|
||||
subject_string = "",
|
||||
key_size = '2048',
|
||||
validity_in_days = default_validity_in_days):
|
||||
"""
|
||||
Generate an x509 certificate with a sha256 signature
|
||||
|
||||
Arguments:
|
||||
db_dir -- location of the temporary params for the certificate
|
||||
dest_dir -- location of the x509 cert
|
||||
serial_num -- serial number for the cert (must be unique for each signer
|
||||
key)
|
||||
key_type -- the type of key generated: potential values: 'rsa' or any
|
||||
of the curves found by 'openssl ecparam -list_curves'
|
||||
name -- the common name for the cert, will match the prefix of the
|
||||
output cert
|
||||
ext_text -- the text for the x509 extensions to be added to the
|
||||
certificate
|
||||
signer_key_filename -- the filename of the key from which the cert will
|
||||
be signed if null the cert will be self signed (think CA
|
||||
roots).
|
||||
signer_cert_filename -- the certificate that will sign the certificate
|
||||
(used to extract signer info) it must be in DER format.
|
||||
key_size -- public key size for RSA certs
|
||||
validity_in_days -- the number of days the cert will be valid for
|
||||
|
||||
output:
|
||||
key_name -- the filename of the key file (PEM format)
|
||||
cert_name -- the filename of the output certificate (DER format)
|
||||
"""
|
||||
key_name = db_dir + "/"+ name + ".key"
|
||||
if key_type == 'rsa':
|
||||
os.system ("openssl genpkey -algorithm RSA -out " + key_name +
|
||||
" -pkeyopt rsa_keygen_bits:" + key_size)
|
||||
else:
|
||||
#assume is ec
|
||||
os.system("openssl ecparam -out " + key_name + " -name "+ key_type +
|
||||
" -genkey");
|
||||
csr_name = db_dir + "/"+ name + ".csr"
|
||||
if not subject_string:
|
||||
subject_string = '/CN=' + name
|
||||
os.system ("openssl req -new -key " + key_name + " -days 3650" +
|
||||
" -extensions v3_ca -batch -out " + csr_name +
|
||||
" -utf8 -subj '" + subject_string + "'")
|
||||
|
||||
extensions_filename = db_dir + "/openssl-exts"
|
||||
f = open(extensions_filename,'w')
|
||||
f.write(ext_text)
|
||||
f.close()
|
||||
|
||||
cert_name = dest_dir + "/"+ name + ".der"
|
||||
if not signer_key_filename:
|
||||
signer_key_filename = key_name;
|
||||
os.system ("openssl x509 -req -sha256 -in " + csr_name +
|
||||
" -days " + str(validity_in_days) +
|
||||
" -signkey " + signer_key_filename +
|
||||
" -set_serial " + str(serial_num) +
|
||||
" -extfile " + extensions_filename +
|
||||
" -outform DER -out "+ cert_name)
|
||||
else:
|
||||
os.system ("openssl x509 -req -sha256 -in " + csr_name +
|
||||
" -CAkey " + signer_key_filename +
|
||||
" -CA " + signer_cert_filename + " -CAform DER " +
|
||||
" -days " + str(validity_in_days) +
|
||||
" -set_serial " + str(serial_num) + " -out " + cert_name +
|
||||
" -outform DER -extfile " + extensions_filename)
|
||||
return key_name, cert_name
|
||||
|
||||
|
||||
|
||||
def generate_int_and_ee(db_dir, dest_dir, ca_key, ca_cert, name, int_ext_text,
|
||||
ee_ext_text, key_type = 'rsa',
|
||||
ee_validity_in_days = default_validity_in_days):
|
||||
"""
|
||||
Generate an intermediate and ee signed by the generated intermediate. The
|
||||
name of the intermediate files will be the name '.der' or '.key'. The name
|
||||
of the end entity files with be "ee-"+ name plus the appropiate prefixes.
|
||||
The serial number will be generated radomly so it is potentially possible
|
||||
to have problem (but very unlikely).
|
||||
|
||||
Arguments:
|
||||
db_dir -- location of the temporary params for the certificate
|
||||
dest_dir -- location of the x509 cert
|
||||
ca_key -- The filename of the key that will be used to sign the
|
||||
intermediate (PEM FORMAT)
|
||||
ca_cert -- The filename of the cert that will be used to sign the
|
||||
intermediate, it MUST be the private key for the ca_key.
|
||||
The file must be in DER format.
|
||||
name -- the common name for the intermediate, will match the prefix
|
||||
of the output intermediate. The ee will have the name
|
||||
prefixed with "ee-"
|
||||
int_ext_text -- the text for the x509 extensions to be added to the
|
||||
intermediate certificate
|
||||
ee_ext_text -- the text for the x509 extensions to be added to the
|
||||
end entity certificate
|
||||
key_type -- the type of key generated: potential values: 'rsa' or any
|
||||
of the curves found by 'openssl ecparam -list_curves'
|
||||
ee_validity_in_days -- the number of days the end-entity cert will be
|
||||
valid for
|
||||
|
||||
output:
|
||||
int_key -- the filename of the intermeidate key file (PEM format)
|
||||
int_cert -- the filename of the intermediate certificate (DER format)
|
||||
ee_key -- the filename of the end entity key file (PEM format)
|
||||
ee_cert -- the filename of the end entity certficate (DER format)
|
||||
|
||||
"""
|
||||
[int_key, int_cert] = generate_cert_generic(db_dir, dest_dir,
|
||||
random.randint(100,40000000),
|
||||
key_type, "int-" + name,
|
||||
int_ext_text,
|
||||
ca_key, ca_cert)
|
||||
[ee_key, ee_cert] = generate_cert_generic(
|
||||
db_dir,
|
||||
dest_dir,
|
||||
random.randint(100,40000000),
|
||||
key_type,
|
||||
name,
|
||||
ee_ext_text,
|
||||
int_key,
|
||||
int_cert,
|
||||
validity_in_days = ee_validity_in_days)
|
||||
|
||||
return int_key, int_cert, ee_key, ee_cert
|
||||
|
||||
def generate_pkcs12(db_dir, dest_dir, der_cert_filename, key_pem_filename,
|
||||
prefix):
|
||||
"""
|
||||
Generate a pkcs12 file for a given certificate name (in der format) and
|
||||
a key filename (key in pem format). The output file will have an empty
|
||||
password.
|
||||
|
||||
Arguments:
|
||||
input:
|
||||
db_dir -- location of the temporary params for the certificate
|
||||
dest_dir -- location of the x509 cert
|
||||
der_cert_filename -- the filename of the certificate to be included in the
|
||||
output file (DER format)
|
||||
key_pem_filename -- the filename of the private key of the certificate to
|
||||
(PEM format)
|
||||
prefix -- the name to be prepended to the output pkcs12 file.
|
||||
output:
|
||||
pk12_filename -- the filename of the outgoing pkcs12 output file
|
||||
"""
|
||||
#make pem cert file from der filename
|
||||
pem_cert_filename = db_dir + "/" + prefix + ".pem"
|
||||
pk12_filename = dest_dir + "/" + prefix + ".p12"
|
||||
os.system("openssl x509 -inform der -in " + der_cert_filename + " -out " +
|
||||
pem_cert_filename )
|
||||
#now make pkcs12 file
|
||||
child = pexpect.spawn("openssl pkcs12 -export -in " + pem_cert_filename +
|
||||
" -inkey " + key_pem_filename + " -out " +
|
||||
pk12_filename)
|
||||
child.expect('Enter Export Password:')
|
||||
child.sendline('')
|
||||
child.expect('Verifying - Enter Export Password:')
|
||||
child.sendline('')
|
||||
child.expect(pexpect.EOF)
|
||||
return pk12_filename
|
||||
|
||||
def print_cert_info(cert_filename):
|
||||
"""
|
||||
Prints out information (such as fingerprints) for the given cert.
|
||||
The information printed is sufficient for enabling EV for the given cert
|
||||
if necessary.
|
||||
|
||||
Note: The utility 'pp' is available as part of NSS.
|
||||
|
||||
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
|
||||
nss database with the sql format.
|
||||
Arguments
|
||||
db_dir -- the desired location of the new database
|
||||
output
|
||||
noise_file -- the path to a noise file suitable to generate TEST
|
||||
certificates. This does not have enough entropy for a real
|
||||
secret
|
||||
pwd_file -- the patch to the secret file used for the database.
|
||||
this file should be empty.
|
||||
"""
|
||||
nss_db_files = ["cert9.db", "key4.db", "pkcs11.txt"]
|
||||
for file in nss_db_files:
|
||||
if os.path.isfile(file):
|
||||
os.remove(file)
|
||||
# create noise file
|
||||
noise_file = db_dir + "/noise"
|
||||
nf = open(noise_file, 'w')
|
||||
nf.write(str(time.time()))
|
||||
nf.close()
|
||||
# create pwd file
|
||||
pwd_file = db_dir + "/pwfile"
|
||||
pf = open(pwd_file, 'w')
|
||||
pf.write("\n")
|
||||
pf.close()
|
||||
# create nss db
|
||||
os.system("certutil -d sql:" + db_dir + " -N -f " + pwd_file);
|
||||
return [noise_file, pwd_file]
|
||||
|
||||
def generate_self_signed_cert(db_dir, dest_dir, noise_file, name, version, do_bc, is_ca):
|
||||
"""
|
||||
Creates a new self-signed certificate in an sql NSS database and as a der file
|
||||
Arguments:
|
||||
db_dir -- the location of the nss database (in sql format)
|
||||
dest_dir -- the location of for the output file
|
||||
noise_file -- the location of a noise file.
|
||||
name -- the nickname of the new certificate in the database and the
|
||||
common name of the certificate
|
||||
version -- the version number of the certificate (valid certs must use
|
||||
3)
|
||||
do_bc -- if the certificate should include the basic constraints
|
||||
(valid ca's should be true)
|
||||
is_ca -- mark the extenstion true or false
|
||||
output:
|
||||
outname -- the location of the der file.
|
||||
"""
|
||||
out_name = dest_dir + "/" + name + ".der"
|
||||
base_exec_string = ("certutil -S -z " + noise_file + " -g 2048 -d sql:" +
|
||||
db_dir + "/ -n " + name + " -v 120 -s 'CN=" + name +
|
||||
",O=PSM Testing,L=Mountain View,ST=California,C=US'" +
|
||||
" -t C,C,C -x --certVersion=" + str(int(version)))
|
||||
if (do_bc):
|
||||
child = pexpect.spawn(base_exec_string + " -2")
|
||||
child.logfile = sys.stdout
|
||||
child.expect('Is this a CA certificate \[y/N\]?')
|
||||
if (is_ca):
|
||||
child.sendline('y')
|
||||
else:
|
||||
child.sendline('N')
|
||||
child.expect('Enter the path length constraint, enter to skip \[<0 for unlimited path\]: >')
|
||||
child.sendline('')
|
||||
child.expect('Is this a critical extension \[y/N\]?')
|
||||
child.sendline('')
|
||||
child.expect(pexpect.EOF)
|
||||
else:
|
||||
os.system(base_exec_string)
|
||||
os.system("certutil -d sql:" + db_dir + "/ -L -n " + name + " -r > " +
|
||||
out_name)
|
||||
return out_name
|
||||
|
||||
def generate_ca_cert(db_dir, dest_dir, noise_file, name, version, do_bc):
|
||||
"""
|
||||
Creates a new CA certificate in an sql NSS database and as a der file
|
||||
Arguments:
|
||||
db_dir -- the location of the nss database (in sql format)
|
||||
dest_dir -- the location of for the output file
|
||||
noise_file -- the location of a noise file.
|
||||
name -- the nickname of the new certificate in the database and the
|
||||
common name of the certificate
|
||||
version -- the version number of the certificate (valid certs must use
|
||||
3)
|
||||
do_bc -- if the certificate should include the basic constraints
|
||||
(valid ca's should be true)
|
||||
output:
|
||||
outname -- the location of the der file.
|
||||
"""
|
||||
return generate_self_signed_cert(db_dir, dest_dir, noise_file, name, version, do_bc, True)
|
||||
|
||||
|
||||
def generate_child_cert(db_dir, dest_dir, noise_file, name, ca_nick, version,
|
||||
do_bc, is_ee, ocsp_url):
|
||||
"""
|
||||
Creates a new child certificate in an sql NSS database and as a der file
|
||||
Arguments:
|
||||
db_dir -- the location of the nss database (in sql format)
|
||||
dest_dir -- the location of for the output file
|
||||
noise_file -- the location of a noise file.
|
||||
name -- the nickname of the new certificate in the database and the
|
||||
common name of the certificate
|
||||
ca_nick -- the nickname of the isser of the new certificate
|
||||
version -- the version number of the certificate (valid certs must use
|
||||
3)
|
||||
do_bc -- if the certificate should include the basic constraints
|
||||
(valid ca's should be true)
|
||||
is_ee -- is this and End Entity cert? false means intermediate
|
||||
ocsp_url -- optional location of the ocsp responder for this certificate
|
||||
this is included only if do_bc is set to True
|
||||
output:
|
||||
outname -- the location of the der file.
|
||||
"""
|
||||
|
||||
out_name = dest_dir + "/" + name + ".der"
|
||||
base_exec_string = ("certutil -S -z " + noise_file + " -g 2048 -d sql:" +
|
||||
db_dir + "/ -n " + name + " -v 120 -m " +
|
||||
str(random.randint(100, 40000000)) + " -s 'CN=" + name +
|
||||
",O=PSM Testing,L=Mountain View,ST=California,C=US'" +
|
||||
" -t C,C,C -c " + ca_nick + " --certVersion=" +
|
||||
str(int(version)))
|
||||
if (do_bc):
|
||||
extra_arguments = " -2"
|
||||
if (ocsp_url):
|
||||
extra_arguments += " --extAIA"
|
||||
child = pexpect.spawn(base_exec_string + extra_arguments)
|
||||
child.logfile = sys.stdout
|
||||
child.expect('Is this a CA certificate \[y/N\]?')
|
||||
if (is_ee):
|
||||
child.sendline('N')
|
||||
else:
|
||||
child.sendline('y')
|
||||
child.expect('Enter the path length constraint, enter to skip \[<0 for unlimited path\]: >')
|
||||
child.sendline('')
|
||||
child.expect('Is this a critical extension \[y/N\]?')
|
||||
child.sendline('')
|
||||
if (ocsp_url):
|
||||
child.expect('\s+Choice >')
|
||||
child.sendline('2')
|
||||
child.expect('\s+Choice: >')
|
||||
child.sendline('7')
|
||||
child.expect('Enter data:')
|
||||
child.sendline(ocsp_url)
|
||||
child.expect('\s+Choice: >')
|
||||
child.sendline('0')
|
||||
child.expect('Add another location to the Authority Information Access extension \[y/N\]')
|
||||
child.sendline('')
|
||||
child.expect('Is this a critical extension \[y/N\]?')
|
||||
child.sendline('')
|
||||
child.expect(pexpect.EOF)
|
||||
else:
|
||||
os.system(base_exec_string)
|
||||
os.system("certutil -d sql:" + db_dir + "/ -L -n " + name + " -r > " +
|
||||
out_name)
|
||||
return out_name
|
||||
|
|
@ -18,6 +18,7 @@ subject:<subject distinguished name specification>
|
|||
[subjectKey:<key specification>]
|
||||
[signature:{sha256WithRSAEncryption,sha1WithRSAEncryption,
|
||||
md5WithRSAEncryption,ecdsaWithSHA256}]
|
||||
[serialNumber:<integer in the interval [1, 127]>]
|
||||
[extension:<extension name:<extension-specific data>>]
|
||||
[...]
|
||||
|
||||
|
@ -72,8 +73,11 @@ If an extension name has '[critical]' after it, it will be marked as
|
|||
critical. Otherwise (by default), it will not be marked as critical.
|
||||
|
||||
TLSFeature values can either consist of a named value (currently only
|
||||
'OCSPMustStaple' which corresponds to status_request) or a numeric tls feature
|
||||
value (see rfc7633 for more information).
|
||||
'OCSPMustStaple' which corresponds to status_request) or a numeric TLS
|
||||
feature value (see rfc7633 for more information).
|
||||
|
||||
If a serial number is not explicitly specified, it is automatically
|
||||
generated based on the contents of the certificate.
|
||||
"""
|
||||
|
||||
from pyasn1.codec.der import decoder
|
||||
|
@ -113,7 +117,12 @@ class NameConstraints(univ.Sequence):
|
|||
)
|
||||
|
||||
|
||||
class UnknownBaseError(Exception):
|
||||
class Error(Exception):
|
||||
"""Base class for exceptions in this module."""
|
||||
pass
|
||||
|
||||
|
||||
class UnknownBaseError(Error):
|
||||
"""Base class for handling unexpected input in this module."""
|
||||
def __init__(self, value):
|
||||
super(UnknownBaseError, self).__init__()
|
||||
|
@ -196,6 +205,7 @@ class UnknownNSCertTypeError(UnknownBaseError):
|
|||
UnknownBaseError.__init__(self, value)
|
||||
self.category = 'nsCertType'
|
||||
|
||||
|
||||
class UnknownTLSFeature(UnknownBaseError):
|
||||
"""Helper exception type to handle unknown TLS Features."""
|
||||
|
||||
|
@ -204,6 +214,17 @@ class UnknownTLSFeature(UnknownBaseError):
|
|||
self.category = 'TLSFeature'
|
||||
|
||||
|
||||
class InvalidSerialNumber(Error):
|
||||
"""Exception type to handle invalid serial numbers."""
|
||||
|
||||
def __init__(self, value):
|
||||
super(InvalidSerialNumber, self).__init__()
|
||||
self.value = value
|
||||
|
||||
def __str__(self):
|
||||
return repr(self.value)
|
||||
|
||||
|
||||
def getASN1Tag(asn1Type):
|
||||
"""Helper function for returning the base tag value of a given
|
||||
type from the pyasn1 package"""
|
||||
|
@ -309,6 +330,16 @@ def datetimeToTime(dt):
|
|||
time.setComponentByName('generalTime', useful.GeneralizedTime(dt.strftime('%Y%m%d%H%M%SZ')))
|
||||
return time
|
||||
|
||||
def serialBytesToString(serialBytes):
|
||||
"""Takes a list of integers in the interval [0, 255] and returns
|
||||
the corresponding serial number string."""
|
||||
serialBytesLen = len(serialBytes)
|
||||
if serialBytesLen > 127:
|
||||
raise InvalidSerialNumber("{} bytes is too long".format(serialBytesLen))
|
||||
# Prepend the ASN.1 INTEGER tag and length bytes.
|
||||
stringBytes = [getASN1Tag(univ.Integer), serialBytesLen] + serialBytes
|
||||
return ''.join(chr(b) for b in stringBytes)
|
||||
|
||||
class Certificate(object):
|
||||
"""Utility class for reading a certificate specification and
|
||||
generating a signed x509 certificate"""
|
||||
|
@ -326,8 +357,12 @@ class Certificate(object):
|
|||
self.extensions = None
|
||||
self.subjectKey = pykey.keyFromSpecification('default')
|
||||
self.issuerKey = pykey.keyFromSpecification('default')
|
||||
self.serialNumber = None
|
||||
self.decodeParams(paramStream)
|
||||
self.serialNumber = self.generateSerialNumber()
|
||||
# If a serial number wasn't specified, generate one based on
|
||||
# the certificate contents.
|
||||
if not self.serialNumber:
|
||||
self.serialNumber = self.generateSerialNumber()
|
||||
|
||||
def generateSerialNumber(self):
|
||||
"""Generates a serial number for this certificate based on its
|
||||
|
@ -353,10 +388,7 @@ class Certificate(object):
|
|||
# significant byte is set (to prevent a leading zero byte,
|
||||
# which also wouldn't be valid).
|
||||
serialBytes[0] |= 0x01
|
||||
# Now prepend the ASN.1 INTEGER tag and length bytes.
|
||||
serialBytes.insert(0, len(serialBytes))
|
||||
serialBytes.insert(0, getASN1Tag(univ.Integer))
|
||||
return ''.join(chr(b) for b in serialBytes)
|
||||
return serialBytesToString(serialBytes)
|
||||
|
||||
def decodeParams(self, paramStream):
|
||||
for line in paramStream.readlines():
|
||||
|
@ -381,6 +413,13 @@ class Certificate(object):
|
|||
self.setupKey('subject', value)
|
||||
elif param == 'signature':
|
||||
self.signature = value
|
||||
elif param == 'serialNumber':
|
||||
serialNumber = int(value)
|
||||
# Ensure only serial numbers that conform to the rules listed in
|
||||
# generateSerialNumber() are permitted.
|
||||
if serialNumber < 1 or serialNumber > 127:
|
||||
raise InvalidSerialNumber(value)
|
||||
self.serialNumber = serialBytesToString([serialNumber])
|
||||
else:
|
||||
raise UnknownParameterTypeError(param)
|
||||
|
||||
|
@ -553,13 +592,12 @@ class Certificate(object):
|
|||
def addTLSFeature(self, features, critical):
|
||||
namedFeatures = {'OCSPMustStaple': 5}
|
||||
featureList = [f.strip() for f in features.split(',')]
|
||||
print "FeatureList is",featureList
|
||||
sequence = univ.Sequence()
|
||||
for feature in featureList:
|
||||
featureValue = 0
|
||||
try:
|
||||
featureValue = int(feature)
|
||||
except:
|
||||
except ValueError:
|
||||
try:
|
||||
featureValue = namedFeatures[feature]
|
||||
except:
|
||||
|
|
|
@ -8,19 +8,13 @@
|
|||
do_get_profile(); // must be called before getting nsIX509CertDB
|
||||
const certdb = Cc["@mozilla.org/security/x509certdb;1"]
|
||||
.getService(Ci.nsIX509CertDB);
|
||||
// This is the list of certificates needed for the test
|
||||
// The certificates prefixed by 'int-' are intermediates
|
||||
// This is the list of certificates needed for the test.
|
||||
var certList = [
|
||||
'ee',
|
||||
'ca-1',
|
||||
'ca-2',
|
||||
];
|
||||
|
||||
function load_cert(cert_name, trust_string) {
|
||||
var cert_filename = cert_name + ".der";
|
||||
addCertFromFile(certdb, "test_getchain/" + cert_filename, trust_string);
|
||||
}
|
||||
|
||||
// Since all the ca's are identical expect for the serial number
|
||||
// I have to grab them by enumerating all the certs and then finding
|
||||
// the ones that I am interested in.
|
||||
|
@ -31,7 +25,7 @@ function get_ca_array() {
|
|||
while (enumerator.hasMoreElements()) {
|
||||
let cert = enumerator.getNext().QueryInterface(Ci.nsIX509Cert);
|
||||
if (cert.commonName == 'ca') {
|
||||
ret_array[parseInt(cert.serialNumber)] = cert;
|
||||
ret_array[parseInt(cert.serialNumber, 16)] = cert;
|
||||
}
|
||||
}
|
||||
return ret_array;
|
||||
|
@ -53,7 +47,7 @@ function check_matching_issuer_and_getchain(expected_issuer_serial, cert) {
|
|||
function check_getchain(ee_cert, ssl_ca, email_ca){
|
||||
// A certificate should first build a chain/issuer to
|
||||
// a SSL trust domain, then an EMAIL trust domain and then
|
||||
// and object signer trust domain
|
||||
// an object signer trust domain.
|
||||
|
||||
const nsIX509Cert = Components.interfaces.nsIX509Cert;
|
||||
certdb.setCertTrust(ssl_ca, nsIX509Cert.CA_CERT,
|
||||
|
@ -73,8 +67,8 @@ function run_test() {
|
|||
clearOCSPCache();
|
||||
clearSessionCache();
|
||||
|
||||
for (let i = 0 ; i < certList.length; i++) {
|
||||
load_cert(certList[i], ',,');
|
||||
for (let cert of certList) {
|
||||
addCertFromFile(certdb, `test_getchain/${cert}.pem`, ",,");
|
||||
}
|
||||
|
||||
let ee_cert = certdb.findCertByNickname(null, 'ee');
|
||||
|
|
Двоичные данные
security/manager/ssl/tests/unit/test_getchain/ca-1.der
Двоичные данные
security/manager/ssl/tests/unit/test_getchain/ca-1.der
Двоичный файл не отображается.
|
@ -0,0 +1,5 @@
|
|||
issuer:ca
|
||||
subject:ca
|
||||
extension:basicConstraints:cA,
|
||||
extension:keyUsage:cRLSign,keyCertSign
|
||||
serialNumber:1
|
Двоичные данные
security/manager/ssl/tests/unit/test_getchain/ca-2.der
Двоичные данные
security/manager/ssl/tests/unit/test_getchain/ca-2.der
Двоичный файл не отображается.
|
@ -0,0 +1,5 @@
|
|||
issuer:ca
|
||||
subject:ca
|
||||
extension:basicConstraints:cA,
|
||||
extension:keyUsage:cRLSign,keyCertSign
|
||||
serialNumber:2
|
Двоичные данные
security/manager/ssl/tests/unit/test_getchain/ee.der
Двоичные данные
security/manager/ssl/tests/unit/test_getchain/ee.der
Двоичный файл не отображается.
|
@ -0,0 +1,2 @@
|
|||
issuer:ca
|
||||
subject:ee
|
|
@ -1,73 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
# 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/.
|
||||
|
||||
import tempfile, os, sys
|
||||
import random
|
||||
import pexpect
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
libpath = os.path.abspath('../psm_common_py')
|
||||
|
||||
sys.path.append(libpath)
|
||||
|
||||
import CertUtils
|
||||
|
||||
srcdir = os.getcwd()
|
||||
db = tempfile.mkdtemp()
|
||||
|
||||
CA_basic_constraints = "basicConstraints = critical, CA:TRUE\n"
|
||||
EE_basic_constraints = "basicConstraints = CA:FALSE\n"
|
||||
|
||||
CA_full_ku = ("keyUsage = digitalSignature, nonRepudiation, keyEncipherment, " +
|
||||
"dataEncipherment, keyAgreement, keyCertSign, cRLSign\n")
|
||||
|
||||
CA_eku = ("extendedKeyUsage = critical, serverAuth, clientAuth, " +
|
||||
"emailProtection, codeSigning\n")
|
||||
|
||||
authority_key_ident = "authorityKeyIdentifier = keyid, issuer\n"
|
||||
subject_key_ident = "subjectKeyIdentifier = hash\n"
|
||||
|
||||
|
||||
def self_sign_csr(db_dir, dst_dir, csr_name, key_file, serial_num, ext_text,
|
||||
out_prefix):
|
||||
extensions_filename = db_dir + "/openssl-exts"
|
||||
f = open(extensions_filename, 'w')
|
||||
f.write(ext_text)
|
||||
f.close()
|
||||
cert_name = dst_dir + "/" + out_prefix + ".der"
|
||||
os.system ("openssl x509 -req -sha256 -days 3650 -in " + csr_name +
|
||||
" -signkey " + key_file +
|
||||
" -set_serial " + str(serial_num) +
|
||||
" -extfile " + extensions_filename +
|
||||
" -outform DER -out " + cert_name)
|
||||
|
||||
|
||||
|
||||
def generate_certs():
|
||||
key_type = 'rsa'
|
||||
ca_ext = CA_basic_constraints + CA_full_ku + subject_key_ident + CA_eku;
|
||||
ee_ext_text = (EE_basic_constraints + authority_key_ident)
|
||||
[ca_key, ca_cert] = CertUtils.generate_cert_generic(db,
|
||||
srcdir,
|
||||
1,
|
||||
key_type,
|
||||
'ca',
|
||||
ca_ext)
|
||||
CertUtils.generate_cert_generic(db,
|
||||
srcdir,
|
||||
100,
|
||||
key_type,
|
||||
'ee',
|
||||
ee_ext_text,
|
||||
ca_key,
|
||||
ca_cert)
|
||||
|
||||
shutil.copy(ca_cert, srcdir + "/" + "ca-1.der")
|
||||
self_sign_csr(db, srcdir, db + "/ca.csr", ca_key, 2, ca_ext, "ca-2")
|
||||
os.remove(ca_cert);
|
||||
|
||||
generate_certs()
|
|
@ -0,0 +1,19 @@
|
|||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# 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/.
|
||||
|
||||
test_certificates = (
|
||||
'ca-1.pem',
|
||||
'ca-2.pem',
|
||||
'ee.pem',
|
||||
)
|
||||
|
||||
for test_certificate in test_certificates:
|
||||
input_file = test_certificate + '.certspec'
|
||||
GENERATED_FILES += [test_certificate]
|
||||
props = GENERATED_FILES[test_certificate]
|
||||
props.script = '../pycert.py'
|
||||
props.inputs = [input_file]
|
||||
TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_getchain += ['!%s' % test_certificate]
|
Загрузка…
Ссылка в новой задаче