17db96d56Sopenharmony_ci"""Make the custom certificate and private key files used by test_ssl 27db96d56Sopenharmony_ciand friends.""" 37db96d56Sopenharmony_ci 47db96d56Sopenharmony_ciimport os 57db96d56Sopenharmony_ciimport pprint 67db96d56Sopenharmony_ciimport shutil 77db96d56Sopenharmony_ciimport tempfile 87db96d56Sopenharmony_cifrom subprocess import * 97db96d56Sopenharmony_ci 107db96d56Sopenharmony_cistartdate = "20180829142316Z" 117db96d56Sopenharmony_cienddate = "20371028142316Z" 127db96d56Sopenharmony_ci 137db96d56Sopenharmony_cireq_template = """ 147db96d56Sopenharmony_ci [ default ] 157db96d56Sopenharmony_ci base_url = http://testca.pythontest.net/testca 167db96d56Sopenharmony_ci 177db96d56Sopenharmony_ci [req] 187db96d56Sopenharmony_ci distinguished_name = req_distinguished_name 197db96d56Sopenharmony_ci prompt = no 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci [req_distinguished_name] 227db96d56Sopenharmony_ci C = XY 237db96d56Sopenharmony_ci L = Castle Anthrax 247db96d56Sopenharmony_ci O = Python Software Foundation 257db96d56Sopenharmony_ci CN = {hostname} 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci [req_x509_extensions_nosan] 287db96d56Sopenharmony_ci 297db96d56Sopenharmony_ci [req_x509_extensions_simple] 307db96d56Sopenharmony_ci subjectAltName = @san 317db96d56Sopenharmony_ci 327db96d56Sopenharmony_ci [req_x509_extensions_full] 337db96d56Sopenharmony_ci subjectAltName = @san 347db96d56Sopenharmony_ci keyUsage = critical,keyEncipherment,digitalSignature 357db96d56Sopenharmony_ci extendedKeyUsage = serverAuth,clientAuth 367db96d56Sopenharmony_ci basicConstraints = critical,CA:false 377db96d56Sopenharmony_ci subjectKeyIdentifier = hash 387db96d56Sopenharmony_ci authorityKeyIdentifier = keyid:always,issuer:always 397db96d56Sopenharmony_ci authorityInfoAccess = @issuer_ocsp_info 407db96d56Sopenharmony_ci crlDistributionPoints = @crl_info 417db96d56Sopenharmony_ci 427db96d56Sopenharmony_ci [ issuer_ocsp_info ] 437db96d56Sopenharmony_ci caIssuers;URI.0 = $base_url/pycacert.cer 447db96d56Sopenharmony_ci OCSP;URI.0 = $base_url/ocsp/ 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci [ crl_info ] 477db96d56Sopenharmony_ci URI.0 = $base_url/revocation.crl 487db96d56Sopenharmony_ci 497db96d56Sopenharmony_ci [san] 507db96d56Sopenharmony_ci DNS.1 = {hostname} 517db96d56Sopenharmony_ci {extra_san} 527db96d56Sopenharmony_ci 537db96d56Sopenharmony_ci [dir_sect] 547db96d56Sopenharmony_ci C = XY 557db96d56Sopenharmony_ci L = Castle Anthrax 567db96d56Sopenharmony_ci O = Python Software Foundation 577db96d56Sopenharmony_ci CN = dirname example 587db96d56Sopenharmony_ci 597db96d56Sopenharmony_ci [princ_name] 607db96d56Sopenharmony_ci realm = EXP:0, GeneralString:KERBEROS.REALM 617db96d56Sopenharmony_ci principal_name = EXP:1, SEQUENCE:principal_seq 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci [principal_seq] 647db96d56Sopenharmony_ci name_type = EXP:0, INTEGER:1 657db96d56Sopenharmony_ci name_string = EXP:1, SEQUENCE:principals 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci [principals] 687db96d56Sopenharmony_ci princ1 = GeneralString:username 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci [ ca ] 717db96d56Sopenharmony_ci default_ca = CA_default 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci [ CA_default ] 747db96d56Sopenharmony_ci dir = cadir 757db96d56Sopenharmony_ci database = $dir/index.txt 767db96d56Sopenharmony_ci crlnumber = $dir/crl.txt 777db96d56Sopenharmony_ci default_md = sha256 787db96d56Sopenharmony_ci startdate = {startdate} 797db96d56Sopenharmony_ci default_startdate = {startdate} 807db96d56Sopenharmony_ci enddate = {enddate} 817db96d56Sopenharmony_ci default_enddate = {enddate} 827db96d56Sopenharmony_ci default_days = 7000 837db96d56Sopenharmony_ci default_crl_days = 7000 847db96d56Sopenharmony_ci certificate = pycacert.pem 857db96d56Sopenharmony_ci private_key = pycakey.pem 867db96d56Sopenharmony_ci serial = $dir/serial 877db96d56Sopenharmony_ci RANDFILE = $dir/.rand 887db96d56Sopenharmony_ci policy = policy_match 897db96d56Sopenharmony_ci 907db96d56Sopenharmony_ci [ policy_match ] 917db96d56Sopenharmony_ci countryName = match 927db96d56Sopenharmony_ci stateOrProvinceName = optional 937db96d56Sopenharmony_ci organizationName = match 947db96d56Sopenharmony_ci organizationalUnitName = optional 957db96d56Sopenharmony_ci commonName = supplied 967db96d56Sopenharmony_ci emailAddress = optional 977db96d56Sopenharmony_ci 987db96d56Sopenharmony_ci [ policy_anything ] 997db96d56Sopenharmony_ci countryName = optional 1007db96d56Sopenharmony_ci stateOrProvinceName = optional 1017db96d56Sopenharmony_ci localityName = optional 1027db96d56Sopenharmony_ci organizationName = optional 1037db96d56Sopenharmony_ci organizationalUnitName = optional 1047db96d56Sopenharmony_ci commonName = supplied 1057db96d56Sopenharmony_ci emailAddress = optional 1067db96d56Sopenharmony_ci 1077db96d56Sopenharmony_ci 1087db96d56Sopenharmony_ci [ v3_ca ] 1097db96d56Sopenharmony_ci 1107db96d56Sopenharmony_ci subjectKeyIdentifier=hash 1117db96d56Sopenharmony_ci authorityKeyIdentifier=keyid:always,issuer 1127db96d56Sopenharmony_ci basicConstraints = CA:true 1137db96d56Sopenharmony_ci 1147db96d56Sopenharmony_ci """ 1157db96d56Sopenharmony_ci 1167db96d56Sopenharmony_cihere = os.path.abspath(os.path.dirname(__file__)) 1177db96d56Sopenharmony_ci 1187db96d56Sopenharmony_ci 1197db96d56Sopenharmony_cidef make_cert_key(hostname, sign=False, extra_san='', 1207db96d56Sopenharmony_ci ext='req_x509_extensions_full', key='rsa:3072'): 1217db96d56Sopenharmony_ci print("creating cert for " + hostname) 1227db96d56Sopenharmony_ci tempnames = [] 1237db96d56Sopenharmony_ci for i in range(3): 1247db96d56Sopenharmony_ci with tempfile.NamedTemporaryFile(delete=False) as f: 1257db96d56Sopenharmony_ci tempnames.append(f.name) 1267db96d56Sopenharmony_ci req_file, cert_file, key_file = tempnames 1277db96d56Sopenharmony_ci try: 1287db96d56Sopenharmony_ci req = req_template.format( 1297db96d56Sopenharmony_ci hostname=hostname, 1307db96d56Sopenharmony_ci extra_san=extra_san, 1317db96d56Sopenharmony_ci startdate=startdate, 1327db96d56Sopenharmony_ci enddate=enddate 1337db96d56Sopenharmony_ci ) 1347db96d56Sopenharmony_ci with open(req_file, 'w') as f: 1357db96d56Sopenharmony_ci f.write(req) 1367db96d56Sopenharmony_ci args = ['req', '-new', '-nodes', '-days', '7000', 1377db96d56Sopenharmony_ci '-newkey', key, '-keyout', key_file, 1387db96d56Sopenharmony_ci '-extensions', ext, 1397db96d56Sopenharmony_ci '-config', req_file] 1407db96d56Sopenharmony_ci if sign: 1417db96d56Sopenharmony_ci with tempfile.NamedTemporaryFile(delete=False) as f: 1427db96d56Sopenharmony_ci tempnames.append(f.name) 1437db96d56Sopenharmony_ci reqfile = f.name 1447db96d56Sopenharmony_ci args += ['-out', reqfile ] 1457db96d56Sopenharmony_ci 1467db96d56Sopenharmony_ci else: 1477db96d56Sopenharmony_ci args += ['-x509', '-out', cert_file ] 1487db96d56Sopenharmony_ci check_call(['openssl'] + args) 1497db96d56Sopenharmony_ci 1507db96d56Sopenharmony_ci if sign: 1517db96d56Sopenharmony_ci args = [ 1527db96d56Sopenharmony_ci 'ca', 1537db96d56Sopenharmony_ci '-config', req_file, 1547db96d56Sopenharmony_ci '-extensions', ext, 1557db96d56Sopenharmony_ci '-out', cert_file, 1567db96d56Sopenharmony_ci '-outdir', 'cadir', 1577db96d56Sopenharmony_ci '-policy', 'policy_anything', 1587db96d56Sopenharmony_ci '-batch', '-infiles', reqfile 1597db96d56Sopenharmony_ci ] 1607db96d56Sopenharmony_ci check_call(['openssl'] + args) 1617db96d56Sopenharmony_ci 1627db96d56Sopenharmony_ci 1637db96d56Sopenharmony_ci with open(cert_file, 'r') as f: 1647db96d56Sopenharmony_ci cert = f.read() 1657db96d56Sopenharmony_ci with open(key_file, 'r') as f: 1667db96d56Sopenharmony_ci key = f.read() 1677db96d56Sopenharmony_ci return cert, key 1687db96d56Sopenharmony_ci finally: 1697db96d56Sopenharmony_ci for name in tempnames: 1707db96d56Sopenharmony_ci os.remove(name) 1717db96d56Sopenharmony_ci 1727db96d56Sopenharmony_ciTMP_CADIR = 'cadir' 1737db96d56Sopenharmony_ci 1747db96d56Sopenharmony_cidef unmake_ca(): 1757db96d56Sopenharmony_ci shutil.rmtree(TMP_CADIR) 1767db96d56Sopenharmony_ci 1777db96d56Sopenharmony_cidef make_ca(): 1787db96d56Sopenharmony_ci os.mkdir(TMP_CADIR) 1797db96d56Sopenharmony_ci with open(os.path.join('cadir','index.txt'),'a+') as f: 1807db96d56Sopenharmony_ci pass # empty file 1817db96d56Sopenharmony_ci with open(os.path.join('cadir','crl.txt'),'a+') as f: 1827db96d56Sopenharmony_ci f.write("00") 1837db96d56Sopenharmony_ci with open(os.path.join('cadir','index.txt.attr'),'w+') as f: 1847db96d56Sopenharmony_ci f.write('unique_subject = no') 1857db96d56Sopenharmony_ci # random start value for serial numbers 1867db96d56Sopenharmony_ci with open(os.path.join('cadir','serial'), 'w') as f: 1877db96d56Sopenharmony_ci f.write('CB2D80995A69525B\n') 1887db96d56Sopenharmony_ci 1897db96d56Sopenharmony_ci with tempfile.NamedTemporaryFile("w") as t: 1907db96d56Sopenharmony_ci req = req_template.format( 1917db96d56Sopenharmony_ci hostname='our-ca-server', 1927db96d56Sopenharmony_ci extra_san='', 1937db96d56Sopenharmony_ci startdate=startdate, 1947db96d56Sopenharmony_ci enddate=enddate 1957db96d56Sopenharmony_ci ) 1967db96d56Sopenharmony_ci t.write(req) 1977db96d56Sopenharmony_ci t.flush() 1987db96d56Sopenharmony_ci with tempfile.NamedTemporaryFile() as f: 1997db96d56Sopenharmony_ci args = ['req', '-config', t.name, '-new', 2007db96d56Sopenharmony_ci '-nodes', 2017db96d56Sopenharmony_ci '-newkey', 'rsa:3072', 2027db96d56Sopenharmony_ci '-keyout', 'pycakey.pem', 2037db96d56Sopenharmony_ci '-out', f.name, 2047db96d56Sopenharmony_ci '-subj', '/C=XY/L=Castle Anthrax/O=Python Software Foundation CA/CN=our-ca-server'] 2057db96d56Sopenharmony_ci check_call(['openssl'] + args) 2067db96d56Sopenharmony_ci args = ['ca', '-config', t.name, 2077db96d56Sopenharmony_ci '-out', 'pycacert.pem', '-batch', '-outdir', TMP_CADIR, 2087db96d56Sopenharmony_ci '-keyfile', 'pycakey.pem', 2097db96d56Sopenharmony_ci '-selfsign', '-extensions', 'v3_ca', '-infiles', f.name ] 2107db96d56Sopenharmony_ci check_call(['openssl'] + args) 2117db96d56Sopenharmony_ci args = ['ca', '-config', t.name, '-gencrl', '-out', 'revocation.crl'] 2127db96d56Sopenharmony_ci check_call(['openssl'] + args) 2137db96d56Sopenharmony_ci 2147db96d56Sopenharmony_ci # capath hashes depend on subject! 2157db96d56Sopenharmony_ci check_call([ 2167db96d56Sopenharmony_ci 'openssl', 'x509', '-in', 'pycacert.pem', '-out', 'capath/ceff1710.0' 2177db96d56Sopenharmony_ci ]) 2187db96d56Sopenharmony_ci shutil.copy('capath/ceff1710.0', 'capath/b1930218.0') 2197db96d56Sopenharmony_ci 2207db96d56Sopenharmony_ci 2217db96d56Sopenharmony_cidef print_cert(path): 2227db96d56Sopenharmony_ci import _ssl 2237db96d56Sopenharmony_ci pprint.pprint(_ssl._test_decode_cert(path)) 2247db96d56Sopenharmony_ci 2257db96d56Sopenharmony_ci 2267db96d56Sopenharmony_ciif __name__ == '__main__': 2277db96d56Sopenharmony_ci os.chdir(here) 2287db96d56Sopenharmony_ci cert, key = make_cert_key('localhost', ext='req_x509_extensions_simple') 2297db96d56Sopenharmony_ci with open('ssl_cert.pem', 'w') as f: 2307db96d56Sopenharmony_ci f.write(cert) 2317db96d56Sopenharmony_ci with open('ssl_key.pem', 'w') as f: 2327db96d56Sopenharmony_ci f.write(key) 2337db96d56Sopenharmony_ci print("password protecting ssl_key.pem in ssl_key.passwd.pem") 2347db96d56Sopenharmony_ci check_call(['openssl','pkey','-in','ssl_key.pem','-out','ssl_key.passwd.pem','-aes256','-passout','pass:somepass']) 2357db96d56Sopenharmony_ci check_call(['openssl','pkey','-in','ssl_key.pem','-out','keycert.passwd.pem','-aes256','-passout','pass:somepass']) 2367db96d56Sopenharmony_ci 2377db96d56Sopenharmony_ci with open('keycert.pem', 'w') as f: 2387db96d56Sopenharmony_ci f.write(key) 2397db96d56Sopenharmony_ci f.write(cert) 2407db96d56Sopenharmony_ci 2417db96d56Sopenharmony_ci with open('keycert.passwd.pem', 'a+') as f: 2427db96d56Sopenharmony_ci f.write(cert) 2437db96d56Sopenharmony_ci 2447db96d56Sopenharmony_ci # For certificate matching tests 2457db96d56Sopenharmony_ci make_ca() 2467db96d56Sopenharmony_ci cert, key = make_cert_key('fakehostname', ext='req_x509_extensions_simple') 2477db96d56Sopenharmony_ci with open('keycert2.pem', 'w') as f: 2487db96d56Sopenharmony_ci f.write(key) 2497db96d56Sopenharmony_ci f.write(cert) 2507db96d56Sopenharmony_ci 2517db96d56Sopenharmony_ci cert, key = make_cert_key('localhost', sign=True) 2527db96d56Sopenharmony_ci with open('keycert3.pem', 'w') as f: 2537db96d56Sopenharmony_ci f.write(key) 2547db96d56Sopenharmony_ci f.write(cert) 2557db96d56Sopenharmony_ci 2567db96d56Sopenharmony_ci cert, key = make_cert_key('fakehostname', sign=True) 2577db96d56Sopenharmony_ci with open('keycert4.pem', 'w') as f: 2587db96d56Sopenharmony_ci f.write(key) 2597db96d56Sopenharmony_ci f.write(cert) 2607db96d56Sopenharmony_ci 2617db96d56Sopenharmony_ci cert, key = make_cert_key( 2627db96d56Sopenharmony_ci 'localhost-ecc', sign=True, key='param:secp384r1.pem' 2637db96d56Sopenharmony_ci ) 2647db96d56Sopenharmony_ci with open('keycertecc.pem', 'w') as f: 2657db96d56Sopenharmony_ci f.write(key) 2667db96d56Sopenharmony_ci f.write(cert) 2677db96d56Sopenharmony_ci 2687db96d56Sopenharmony_ci extra_san = [ 2697db96d56Sopenharmony_ci 'otherName.1 = 1.2.3.4;UTF8:some other identifier', 2707db96d56Sopenharmony_ci 'otherName.2 = 1.3.6.1.5.2.2;SEQUENCE:princ_name', 2717db96d56Sopenharmony_ci 'email.1 = user@example.org', 2727db96d56Sopenharmony_ci 'DNS.2 = www.example.org', 2737db96d56Sopenharmony_ci # GEN_X400 2747db96d56Sopenharmony_ci 'dirName.1 = dir_sect', 2757db96d56Sopenharmony_ci # GEN_EDIPARTY 2767db96d56Sopenharmony_ci 'URI.1 = https://www.python.org/', 2777db96d56Sopenharmony_ci 'IP.1 = 127.0.0.1', 2787db96d56Sopenharmony_ci 'IP.2 = ::1', 2797db96d56Sopenharmony_ci 'RID.1 = 1.2.3.4.5', 2807db96d56Sopenharmony_ci ] 2817db96d56Sopenharmony_ci 2827db96d56Sopenharmony_ci cert, key = make_cert_key('allsans', sign=True, extra_san='\n'.join(extra_san)) 2837db96d56Sopenharmony_ci with open('allsans.pem', 'w') as f: 2847db96d56Sopenharmony_ci f.write(key) 2857db96d56Sopenharmony_ci f.write(cert) 2867db96d56Sopenharmony_ci 2877db96d56Sopenharmony_ci extra_san = [ 2887db96d56Sopenharmony_ci # könig (king) 2897db96d56Sopenharmony_ci 'DNS.2 = xn--knig-5qa.idn.pythontest.net', 2907db96d56Sopenharmony_ci # königsgäßchen (king's alleyway) 2917db96d56Sopenharmony_ci 'DNS.3 = xn--knigsgsschen-lcb0w.idna2003.pythontest.net', 2927db96d56Sopenharmony_ci 'DNS.4 = xn--knigsgchen-b4a3dun.idna2008.pythontest.net', 2937db96d56Sopenharmony_ci # βόλοσ (marble) 2947db96d56Sopenharmony_ci 'DNS.5 = xn--nxasmq6b.idna2003.pythontest.net', 2957db96d56Sopenharmony_ci 'DNS.6 = xn--nxasmm1c.idna2008.pythontest.net', 2967db96d56Sopenharmony_ci ] 2977db96d56Sopenharmony_ci 2987db96d56Sopenharmony_ci # IDN SANS, signed 2997db96d56Sopenharmony_ci cert, key = make_cert_key('idnsans', sign=True, extra_san='\n'.join(extra_san)) 3007db96d56Sopenharmony_ci with open('idnsans.pem', 'w') as f: 3017db96d56Sopenharmony_ci f.write(key) 3027db96d56Sopenharmony_ci f.write(cert) 3037db96d56Sopenharmony_ci 3047db96d56Sopenharmony_ci cert, key = make_cert_key('nosan', sign=True, ext='req_x509_extensions_nosan') 3057db96d56Sopenharmony_ci with open('nosan.pem', 'w') as f: 3067db96d56Sopenharmony_ci f.write(key) 3077db96d56Sopenharmony_ci f.write(cert) 3087db96d56Sopenharmony_ci 3097db96d56Sopenharmony_ci unmake_ca() 3107db96d56Sopenharmony_ci print("update Lib/test/test_ssl.py and Lib/test/test_asyncio/utils.py") 3117db96d56Sopenharmony_ci print_cert('keycert.pem') 3127db96d56Sopenharmony_ci print_cert('keycert3.pem') 313