bpo-32602: Test ECDSA certs (#5247)

Add test certs and test for ECDSA cert and EC/RSA dual mode.

I'm also adding certs for IDNA 2003/2008 tests and simplify some test
data handling.

Signed-off-by: Christian Heimes <christian@python.org>
This commit is contained in:
Christian Heimes 2018-01-20 15:16:30 +01:00 committed by GitHub
parent ff5be6e810
commit bd5c7d238c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 1049 additions and 440 deletions

View file

@ -2,14 +2,17 @@
and friends."""
import os
import pprint
import shutil
import tempfile
from subprocess import *
req_template = """
[ default ]
base_url = http://testca.pythontest.net/testca
[req]
distinguished_name = req_distinguished_name
x509_extensions = req_x509_extensions
prompt = no
[req_distinguished_name]
@ -18,9 +21,26 @@ req_template = """
O = Python Software Foundation
CN = {hostname}
[req_x509_extensions]
[req_x509_extensions_simple]
subjectAltName = @san
[req_x509_extensions_full]
subjectAltName = @san
keyUsage = critical,keyEncipherment,digitalSignature
extendedKeyUsage = serverAuth,clientAuth
basicConstraints = critical,CA:false
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
authorityInfoAccess = @issuer_ocsp_info
crlDistributionPoints = @crl_info
[ issuer_ocsp_info ]
caIssuers;URI.0 = $base_url/pycacert.cer
OCSP;URI.0 = $base_url/ocsp/
[ crl_info ]
URI.0 = $base_url/revocation.crl
[san]
DNS.1 = {hostname}
{extra_san}
@ -56,7 +76,6 @@ req_template = """
private_key = pycakey.pem
serial = $dir/serial
RANDFILE = $dir/.rand
policy = policy_match
[ policy_match ]
@ -87,7 +106,9 @@ req_template = """
here = os.path.abspath(os.path.dirname(__file__))
def make_cert_key(hostname, sign=False, extra_san=''):
def make_cert_key(hostname, sign=False, extra_san='',
ext='req_x509_extensions_full', key='rsa:2048'):
print("creating cert for " + hostname)
tempnames = []
for i in range(3):
@ -99,7 +120,8 @@ def make_cert_key(hostname, sign=False, extra_san=''):
with open(req_file, 'w') as f:
f.write(req)
args = ['req', '-new', '-days', '3650', '-nodes',
'-newkey', 'rsa:1024', '-keyout', key_file,
'-newkey', key, '-keyout', key_file,
'-extensions', ext,
'-config', req_file]
if sign:
with tempfile.NamedTemporaryFile(delete=False) as f:
@ -112,8 +134,15 @@ def make_cert_key(hostname, sign=False, extra_san=''):
check_call(['openssl'] + args)
if sign:
args = ['ca', '-config', req_file, '-out', cert_file, '-outdir', 'cadir',
'-policy', 'policy_anything', '-batch', '-infiles', reqfile ]
args = [
'ca',
'-config', req_file,
'-extensions', ext,
'-out', cert_file,
'-outdir', 'cadir',
'-policy', 'policy_anything',
'-batch', '-infiles', reqfile
]
check_call(['openssl'] + args)
@ -157,9 +186,21 @@ def make_ca():
args = ['ca', '-config', t.name, '-gencrl', '-out', 'revocation.crl']
check_call(['openssl'] + args)
# capath hashes depend on subject!
check_call([
'openssl', 'x509', '-in', 'pycacert.pem', '-out', 'capath/ceff1710.0'
])
shutil.copy('capath/ceff1710.0', 'capath/b1930218.0')
def print_cert(path):
import _ssl
pprint.pprint(_ssl._test_decode_cert(path))
if __name__ == '__main__':
os.chdir(here)
cert, key = make_cert_key('localhost')
cert, key = make_cert_key('localhost', ext='req_x509_extensions_simple')
with open('ssl_cert.pem', 'w') as f:
f.write(cert)
with open('ssl_key.pem', 'w') as f:
@ -177,7 +218,7 @@ if __name__ == '__main__':
# For certificate matching tests
make_ca()
cert, key = make_cert_key('fakehostname')
cert, key = make_cert_key('fakehostname', ext='req_x509_extensions_simple')
with open('keycert2.pem', 'w') as f:
f.write(key)
f.write(cert)
@ -192,6 +233,13 @@ if __name__ == '__main__':
f.write(key)
f.write(cert)
cert, key = make_cert_key(
'localhost-ecc', True, key='param:secp384r1.pem'
)
with open('keycertecc.pem', 'w') as f:
f.write(key)
f.write(cert)
extra_san = [
'otherName.1 = 1.2.3.4;UTF8:some other identifier',
'otherName.2 = 1.3.6.1.5.2.2;SEQUENCE:princ_name',
@ -211,6 +259,24 @@ if __name__ == '__main__':
f.write(key)
f.write(cert)
extra_san = [
# könig (king)
'DNS.2 = xn--knig-5qa.idn.pythontest.net',
# königsgäßchen (king's alleyway)
'DNS.3 = xn--knigsgsschen-lcb0w.idna2003.pythontest.net',
'DNS.4 = xn--knigsgchen-b4a3dun.idna2008.pythontest.net',
# βόλοσ (marble)
'DNS.5 = xn--nxasmq6b.idna2003.pythontest.net',
'DNS.6 = xn--nxasmm1c.idna2008.pythontest.net',
]
# IDN SANS, signed
cert, key = make_cert_key('idnsans', True, extra_san='\n'.join(extra_san))
with open('idnsans.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'])
print("update Lib/test/test_ssl.py and Lib/test/test_asyncio/util.py")
print_cert('keycert.pem')
print_cert('keycert3.pem')