blob: f630813b2c23573b25211297b06abf70f930c436 [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
31 default_md = sha1
32 default_days = 3600
33 certificate = pycacert.pem
34 private_key = pycakey.pem
35 serial = $dir/serial
36 RANDFILE = $dir/.rand
37
38 policy = policy_match
39
40 [ policy_match ]
41 countryName = match
42 stateOrProvinceName = optional
43 organizationName = match
44 organizationalUnitName = optional
45 commonName = supplied
46 emailAddress = optional
47
48 [ policy_anything ]
49 countryName = optional
50 stateOrProvinceName = optional
51 localityName = optional
52 organizationName = optional
53 organizationalUnitName = optional
54 commonName = supplied
55 emailAddress = optional
56
57
58 [ v3_ca ]
59
60 subjectKeyIdentifier=hash
61 authorityKeyIdentifier=keyid:always,issuer
62 basicConstraints = CA:true
63
Antoine Pitrou81564092010-10-08 23:06:24 +000064 """
65
66here = os.path.abspath(os.path.dirname(__file__))
67
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010068def make_cert_key(hostname, sign=False):
69 print("creating cert for " + hostname)
Antoine Pitrou81564092010-10-08 23:06:24 +000070 tempnames = []
71 for i in range(3):
72 with tempfile.NamedTemporaryFile(delete=False) as f:
73 tempnames.append(f.name)
74 req_file, cert_file, key_file = tempnames
75 try:
76 with open(req_file, 'w') as f:
77 f.write(req_template.format(hostname=hostname))
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010078 args = ['req', '-new', '-days', '3650', '-nodes',
Antoine Pitrou81564092010-10-08 23:06:24 +000079 '-newkey', 'rsa:1024', '-keyout', key_file,
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010080 '-config', req_file]
81 if sign:
82 with tempfile.NamedTemporaryFile(delete=False) as f:
83 tempnames.append(f.name)
84 reqfile = f.name
85 args += ['-out', reqfile ]
86
87 else:
88 args += ['-x509', '-out', cert_file ]
Antoine Pitrou81564092010-10-08 23:06:24 +000089 check_call(['openssl'] + args)
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +010090
91 if sign:
92 args = ['ca', '-config', req_file, '-out', cert_file, '-outdir', 'cadir',
93 '-policy', 'policy_anything', '-batch', '-infiles', reqfile ]
94 check_call(['openssl'] + args)
95
96
Antoine Pitrou81564092010-10-08 23:06:24 +000097 with open(cert_file, 'r') as f:
98 cert = f.read()
99 with open(key_file, 'r') as f:
100 key = f.read()
101 return cert, key
102 finally:
103 for name in tempnames:
104 os.remove(name)
105
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100106TMP_CADIR = 'cadir'
107
108def unmake_ca():
109 shutil.rmtree(TMP_CADIR)
110
111def make_ca():
112 os.mkdir(TMP_CADIR)
113 with open(os.path.join('cadir','index.txt'),'a+') as f:
114 pass # empty file
115 with open(os.path.join('cadir','index.txt.attr'),'w+') as f:
116 f.write('unique_subject = no')
117
118 with tempfile.NamedTemporaryFile("w") as t:
119 t.write(req_template.format(hostname='our-ca-server'))
120 t.flush()
121 with tempfile.NamedTemporaryFile() as f:
122 args = ['req', '-new', '-days', '3650', '-extensions', 'v3_ca', '-nodes',
123 '-newkey', 'rsa:2048', '-keyout', 'pycakey.pem',
124 '-out', f.name,
125 '-subj', '/C=XY/L=Castle Anthrax/O=Python Software Foundation CA/CN=our-ca-server']
126 check_call(['openssl'] + args)
127 args = ['ca', '-config', t.name, '-create_serial',
128 '-out', 'pycacert.pem', '-batch', '-outdir', TMP_CADIR,
129 '-keyfile', 'pycakey.pem', '-days', '3650',
130 '-selfsign', '-extensions', 'v3_ca', '-infiles', f.name ]
131 check_call(['openssl'] + args)
Antoine Pitrou81564092010-10-08 23:06:24 +0000132
133if __name__ == '__main__':
134 os.chdir(here)
135 cert, key = make_cert_key('localhost')
136 with open('ssl_cert.pem', 'w') as f:
137 f.write(cert)
138 with open('ssl_key.pem', 'w') as f:
139 f.write(key)
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100140 print("password protecting ssl_key.pem in ssl_key.passwd.pem")
141 check_call(['openssl','rsa','-in','ssl_key.pem','-out','ssl_key.passwd.pem','-des3','-passout','pass:somepass'])
142 check_call(['openssl','rsa','-in','ssl_key.pem','-out','keycert.passwd.pem','-des3','-passout','pass:somepass'])
143
Antoine Pitrou81564092010-10-08 23:06:24 +0000144 with open('keycert.pem', 'w') as f:
145 f.write(key)
146 f.write(cert)
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100147
148 with open('keycert.passwd.pem', 'a+') as f:
149 f.write(cert)
150
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000151 # For certificate matching tests
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100152 make_ca()
Antoine Pitrou803e6d62010-10-13 10:36:15 +0000153 cert, key = make_cert_key('fakehostname')
154 with open('keycert2.pem', 'w') as f:
155 f.write(key)
156 f.write(cert)
Antoine Pitrou58ddc9d2013-01-05 21:20:29 +0100157
158 cert, key = make_cert_key('localhost', True)
159 with open('keycert3.pem', 'w') as f:
160 f.write(key)
161 f.write(cert)
162
163 cert, key = make_cert_key('fakehostname', True)
164 with open('keycert4.pem', 'w') as f:
165 f.write(key)
166 f.write(cert)
167
168 unmake_ca()
169 print("\n\nPlease change the values in test_ssl.py, test_parse_cert function related to notAfter,notBefore and serialNumber")
170 check_call(['openssl','x509','-in','keycert.pem','-dates','-serial','-noout'])