mirror of
https://github.com/python/cpython.git
synced 2024-12-17 22:05:04 +08:00
225877917e
of the context in order to enable certification revocation list (CRL) checks or strict X509 rules.
177 lines
5.5 KiB
Python
177 lines
5.5 KiB
Python
"""Make the custom certificate and private key files used by test_ssl
|
|
and friends."""
|
|
|
|
import os
|
|
import shutil
|
|
import sys
|
|
import tempfile
|
|
from subprocess import *
|
|
|
|
req_template = """
|
|
[req]
|
|
distinguished_name = req_distinguished_name
|
|
x509_extensions = req_x509_extensions
|
|
prompt = no
|
|
|
|
[req_distinguished_name]
|
|
C = XY
|
|
L = Castle Anthrax
|
|
O = Python Software Foundation
|
|
CN = {hostname}
|
|
|
|
[req_x509_extensions]
|
|
subjectAltName = DNS:{hostname}
|
|
|
|
[ ca ]
|
|
default_ca = CA_default
|
|
|
|
[ CA_default ]
|
|
dir = cadir
|
|
database = $dir/index.txt
|
|
crlnumber = $dir/crl.txt
|
|
default_md = sha1
|
|
default_days = 3600
|
|
default_crl_days = 3600
|
|
certificate = pycacert.pem
|
|
private_key = pycakey.pem
|
|
serial = $dir/serial
|
|
RANDFILE = $dir/.rand
|
|
|
|
policy = policy_match
|
|
|
|
[ policy_match ]
|
|
countryName = match
|
|
stateOrProvinceName = optional
|
|
organizationName = match
|
|
organizationalUnitName = optional
|
|
commonName = supplied
|
|
emailAddress = optional
|
|
|
|
[ policy_anything ]
|
|
countryName = optional
|
|
stateOrProvinceName = optional
|
|
localityName = optional
|
|
organizationName = optional
|
|
organizationalUnitName = optional
|
|
commonName = supplied
|
|
emailAddress = optional
|
|
|
|
|
|
[ v3_ca ]
|
|
|
|
subjectKeyIdentifier=hash
|
|
authorityKeyIdentifier=keyid:always,issuer
|
|
basicConstraints = CA:true
|
|
|
|
"""
|
|
|
|
here = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
def make_cert_key(hostname, sign=False):
|
|
print("creating cert for " + hostname)
|
|
tempnames = []
|
|
for i in range(3):
|
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
|
tempnames.append(f.name)
|
|
req_file, cert_file, key_file = tempnames
|
|
try:
|
|
with open(req_file, 'w') as f:
|
|
f.write(req_template.format(hostname=hostname))
|
|
args = ['req', '-new', '-days', '3650', '-nodes',
|
|
'-newkey', 'rsa:1024', '-keyout', key_file,
|
|
'-config', req_file]
|
|
if sign:
|
|
with tempfile.NamedTemporaryFile(delete=False) as f:
|
|
tempnames.append(f.name)
|
|
reqfile = f.name
|
|
args += ['-out', reqfile ]
|
|
|
|
else:
|
|
args += ['-x509', '-out', cert_file ]
|
|
check_call(['openssl'] + args)
|
|
|
|
if sign:
|
|
args = ['ca', '-config', req_file, '-out', cert_file, '-outdir', 'cadir',
|
|
'-policy', 'policy_anything', '-batch', '-infiles', reqfile ]
|
|
check_call(['openssl'] + args)
|
|
|
|
|
|
with open(cert_file, 'r') as f:
|
|
cert = f.read()
|
|
with open(key_file, 'r') as f:
|
|
key = f.read()
|
|
return cert, key
|
|
finally:
|
|
for name in tempnames:
|
|
os.remove(name)
|
|
|
|
TMP_CADIR = 'cadir'
|
|
|
|
def unmake_ca():
|
|
shutil.rmtree(TMP_CADIR)
|
|
|
|
def make_ca():
|
|
os.mkdir(TMP_CADIR)
|
|
with open(os.path.join('cadir','index.txt'),'a+') as f:
|
|
pass # empty file
|
|
with open(os.path.join('cadir','crl.txt'),'a+') as f:
|
|
r.write("00")
|
|
with open(os.path.join('cadir','index.txt.attr'),'w+') as f:
|
|
f.write('unique_subject = no')
|
|
|
|
with tempfile.NamedTemporaryFile("w") as t:
|
|
t.write(req_template.format(hostname='our-ca-server'))
|
|
t.flush()
|
|
with tempfile.NamedTemporaryFile() as f:
|
|
args = ['req', '-new', '-days', '3650', '-extensions', 'v3_ca', '-nodes',
|
|
'-newkey', 'rsa:2048', '-keyout', 'pycakey.pem',
|
|
'-out', f.name,
|
|
'-subj', '/C=XY/L=Castle Anthrax/O=Python Software Foundation CA/CN=our-ca-server']
|
|
check_call(['openssl'] + args)
|
|
args = ['ca', '-config', t.name, '-create_serial',
|
|
'-out', 'pycacert.pem', '-batch', '-outdir', TMP_CADIR,
|
|
'-keyfile', 'pycakey.pem', '-days', '3650',
|
|
'-selfsign', '-extensions', 'v3_ca', '-infiles', f.name ]
|
|
check_call(['openssl'] + args)
|
|
args = ['ca', '-config', t.name, '-gencrl', '-out', 'revocation.crl']
|
|
check_call(['openssl'] + args)
|
|
|
|
if __name__ == '__main__':
|
|
os.chdir(here)
|
|
cert, key = make_cert_key('localhost')
|
|
with open('ssl_cert.pem', 'w') as f:
|
|
f.write(cert)
|
|
with open('ssl_key.pem', 'w') as f:
|
|
f.write(key)
|
|
print("password protecting ssl_key.pem in ssl_key.passwd.pem")
|
|
check_call(['openssl','rsa','-in','ssl_key.pem','-out','ssl_key.passwd.pem','-des3','-passout','pass:somepass'])
|
|
check_call(['openssl','rsa','-in','ssl_key.pem','-out','keycert.passwd.pem','-des3','-passout','pass:somepass'])
|
|
|
|
with open('keycert.pem', 'w') as f:
|
|
f.write(key)
|
|
f.write(cert)
|
|
|
|
with open('keycert.passwd.pem', 'a+') as f:
|
|
f.write(cert)
|
|
|
|
# For certificate matching tests
|
|
make_ca()
|
|
cert, key = make_cert_key('fakehostname')
|
|
with open('keycert2.pem', 'w') as f:
|
|
f.write(key)
|
|
f.write(cert)
|
|
|
|
cert, key = make_cert_key('localhost', True)
|
|
with open('keycert3.pem', 'w') as f:
|
|
f.write(key)
|
|
f.write(cert)
|
|
|
|
cert, key = make_cert_key('fakehostname', True)
|
|
with open('keycert4.pem', 'w') as f:
|
|
f.write(key)
|
|
f.write(cert)
|
|
|
|
unmake_ca()
|
|
print("\n\nPlease change the values in test_ssl.py, test_parse_cert function related to notAfter,notBefore and serialNumber")
|
|
check_call(['openssl','x509','-in','keycert.pem','-dates','-serial','-noout'])
|