mirror of
https://github.com/python/cpython.git
synced 2025-08-04 00:48:58 +00:00
Issue #8109: The ssl module now has support for server-side SNI, thanks to a :meth:SSLContext.set_servername_callback
method.
Patch by Daniel Black.
This commit is contained in:
parent
3c9850aad7
commit
58ddc9d743
11 changed files with 881 additions and 42 deletions
|
@ -2,6 +2,7 @@
|
|||
and friends."""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
from subprocess import *
|
||||
|
@ -20,11 +21,52 @@ req_template = """
|
|||
|
||||
[req_x509_extensions]
|
||||
subjectAltName = DNS:{hostname}
|
||||
|
||||
[ ca ]
|
||||
default_ca = CA_default
|
||||
|
||||
[ CA_default ]
|
||||
dir = cadir
|
||||
database = $dir/index.txt
|
||||
default_md = sha1
|
||||
default_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):
|
||||
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:
|
||||
|
@ -33,10 +75,25 @@ def make_cert_key(hostname):
|
|||
try:
|
||||
with open(req_file, 'w') as f:
|
||||
f.write(req_template.format(hostname=hostname))
|
||||
args = ['req', '-new', '-days', '3650', '-nodes', '-x509',
|
||||
args = ['req', '-new', '-days', '3650', '-nodes',
|
||||
'-newkey', 'rsa:1024', '-keyout', key_file,
|
||||
'-out', cert_file, '-config', req_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:
|
||||
|
@ -46,6 +103,32 @@ def make_cert_key(hostname):
|
|||
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','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)
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.chdir(here)
|
||||
|
@ -54,11 +137,34 @@ if __name__ == '__main__':
|
|||
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'])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue