blob: 81d04f82dcfb082d89ee5f097c1dd8336994c7a2 [file] [log] [blame]
Antoine Pitrou81564092010-10-08 23:06:24 +00001"""Make the custom certificate and private key files used by test_ssl
2and friends."""
3
4import os
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +01005import shutil
Antoine Pitrou81564092010-10-08 23:06:24 +00006import sys
7import tempfile
8from subprocess import *
9
10req_template = """
11 [req]
12 distinguished_name = req_distinguished_name
13 x509_extensions = req_x509_extensions
14 prompt = no
15
16 [req_distinguished_name]
17 C = XY
18 L = Castle Anthrax
19 O = Python Software Foundation
20 CN = {hostname}
21
22 [req_x509_extensions]
23 subjectAltName = DNS:{hostname}
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010024
25 [ ca ]
26 default_ca = CA_default
27
28 [ CA_default ]
29 dir = cadir
30 database = $dir/index.txt
Christian Heimes22587792013-11-21 23:56:13 +010031 crlnumber = $dir/crl.txt
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010032 default_md = sha1
33 default_days = 3600
Christian Heimes22587792013-11-21 23:56:13 +010034 default_crl_days = 3600
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010035 certificate = pycacert.pem
36 private_key = pycakey.pem
37 serial = $dir/serial
38 RANDFILE = $dir/.rand
39
40 policy = policy_match
41
42 [ policy_match ]
43 countryName = match
44 stateOrProvinceName = optional
45 organizationName = match
46 organizationalUnitName = optional
47 commonName = supplied
48 emailAddress = optional
49
50 [ policy_anything ]
51 countryName = optional
52 stateOrProvinceName = optional
53 localityName = optional
54 organizationName = optional
55 organizationalUnitName = optional
56 commonName = supplied
57 emailAddress = optional
58
59
60 [ v3_ca ]
61
62 subjectKeyIdentifier=hash
63 authorityKeyIdentifier=keyid:always,issuer
64 basicConstraints = CA:true
65
Antoine Pitrou81564092010-10-08 23:06:24 +000066 """
67
68here = os.path.abspath(os.path.dirname(__file__))
69
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010070def make_cert_key(hostname, sign=False):
71 print("creating cert for " + hostname)
Antoine Pitrou81564092010-10-08 23:06:24 +000072 tempnames = []
73 for i in range(3):
74 with tempfile.NamedTemporaryFile(delete=False) as f:
75 tempnames.append(f.name)
76 req_file, cert_file, key_file = tempnames
77 try:
78 with open(req_file, 'w') as f:
79 f.write(req_template.format(hostname=hostname))
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010080 args = ['req', '-new', '-days', '3650', '-nodes',
Antoine Pitrou81564092010-10-08 23:06:24 +000081 '-newkey', 'rsa:1024', '-keyout', key_file,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010082 '-config', req_file]
83 if sign:
84 with tempfile.NamedTemporaryFile(delete=False) as f:
85 tempnames.append(f.name)
86 reqfile = f.name
87 args += ['-out', reqfile ]
88
89 else:
90 args += ['-x509', '-out', cert_file ]
Antoine Pitrou81564092010-10-08 23:06:24 +000091 check_call(['openssl'] + args)
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010092
93 if sign:
94 args = ['ca', '-config', req_file, '-out', cert_file, '-outdir', 'cadir',
95 '-policy', 'policy_anything', '-batch', '-infiles', reqfile ]
96 check_call(['openssl'] + args)
97
98
Antoine Pitrou81564092010-10-08 23:06:24 +000099 with open(cert_file, 'r') as f:
100 cert = f.read()
101 with open(key_file, 'r') as f:
102 key = f.read()
103 return cert, key
104 finally:
105 for name in tempnames:
106 os.remove(name)
107
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100108TMP_CADIR = 'cadir'
109
110def unmake_ca():
111 shutil.rmtree(TMP_CADIR)
112
113def make_ca():
114 os.mkdir(TMP_CADIR)
115 with open(os.path.join('cadir','index.txt'),'a+') as f:
116 pass # empty file
Christian Heimes22587792013-11-21 23:56:13 +0100117 with open(os.path.join('cadir','crl.txt'),'a+') as f:
Antoine Pitroud2e9fdf2014-07-26 11:15:52 -0400118 f.write("00")
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100119 with open(os.path.join('cadir','index.txt.attr'),'w+') as f:
120 f.write('unique_subject = no')
121
122 with tempfile.NamedTemporaryFile("w") as t:
123 t.write(req_template.format(hostname='our-ca-server'))
124 t.flush()
125 with tempfile.NamedTemporaryFile() as f:
126 args = ['req', '-new', '-days', '3650', '-extensions', 'v3_ca', '-nodes',
127 '-newkey', 'rsa:2048', '-keyout', 'pycakey.pem',
128 '-out', f.name,
129 '-subj', '/C=XY/L=Castle Anthrax/O=Python Software Foundation CA/CN=our-ca-server']
130 check_call(['openssl'] + args)
131 args = ['ca', '-config', t.name, '-create_serial',
132 '-out', 'pycacert.pem', '-batch', '-outdir', TMP_CADIR,
133 '-keyfile', 'pycakey.pem', '-days', '3650',
134 '-selfsign', '-extensions', 'v3_ca', '-infiles', f.name ]
135 check_call(['openssl'] + args)
Christian Heimes22587792013-11-21 23:56:13 +0100136 args = ['ca', '-config', t.name, '-gencrl', '-out', 'revocation.crl']
137 check_call(['openssl'] + args)
Antoine Pitrou81564092010-10-08 23:06:24 +0000138
139if __name__ == '__main__':
140 os.chdir(here)
141 cert, key = make_cert_key('localhost')
142 with open('ssl_cert.pem', 'w') as f:
143 f.write(cert)
144 with open('ssl_key.pem', 'w') as f:
145 f.write(key)
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100146 print("password protecting ssl_key.pem in ssl_key.passwd.pem")
147 check_call(['openssl','rsa','-in','ssl_key.pem','-out','ssl_key.passwd.pem','-des3','-passout','pass:somepass'])
148 check_call(['openssl','rsa','-in','ssl_key.pem','-out','keycert.passwd.pem','-des3','-passout','pass:somepass'])
149
Antoine Pitrou81564092010-10-08 23:06:24 +0000150 with open('keycert.pem', 'w') as f:
151 f.write(key)
152 f.write(cert)
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100153
154 with open('keycert.passwd.pem', 'a+') as f:
155 f.write(cert)
156
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000157 # For certificate matching tests
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100158 make_ca()
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000159 cert, key = make_cert_key('fakehostname')
160 with open('keycert2.pem', 'w') as f:
161 f.write(key)
162 f.write(cert)
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100163
164 cert, key = make_cert_key('localhost', True)
165 with open('keycert3.pem', 'w') as f:
166 f.write(key)
167 f.write(cert)
168
169 cert, key = make_cert_key('fakehostname', True)
170 with open('keycert4.pem', 'w') as f:
171 f.write(key)
172 f.write(cert)
173
174 unmake_ca()
175 print("\n\nPlease change the values in test_ssl.py, test_parse_cert function related to notAfter,notBefore and serialNumber")
176 check_call(['openssl','x509','-in','keycert.pem','-dates','-serial','-noout'])