Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update make_tls_certs.py, work with openssl 3 (#8701) #8707

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ repos:
- urllib3
- git+https://github.com/dask/dask
- git+https://github.com/dask/zict
# This script is heavily based on one from upstream cpython, applying
# our style to it makes it unnecessarily hard to diff it against
# the upstream version for future revisions
exclude: make_tls_certs\.py

# Increase this value to clear the cache on GitHub actions if nothing else in this file
# has changed. See also same variable in .github/workflows/test.yaml
Expand Down
257 changes: 147 additions & 110 deletions distributed/tests/make_tls_certs.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
"""Make the custom certificate and private key files used by TLS tests.

Code heavily borrowed from Lib/tests/make_ssl_certs.py in CPython.
Code heavily borrowed from Lib/test/certdata/make_ssl_certs.py in CPython.
Changes: filenames, dropped the SAN/ECC stuff, create a smaller set of
certs which is all we need for our tests. Is excluded from pre-commit so
we can keep the diff against upstream tight for ease of updating.
"""

from __future__ import annotations

import os
import pprint
import shutil
import subprocess
import tempfile
from subprocess import *

startdate = "20180829142316Z"
enddate = "20371028142316Z"

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]
Expand All @@ -22,38 +31,78 @@
O = Dask
CN = {hostname}

[req_x509_extensions]
[req_x509_extensions_nosan]

[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}

[ca]
[dir_sect]
C = XY
L = Castle Anthrax
O = Python Software Foundation
CN = dirname example

[princ_name]
realm = EXP:0, GeneralString:KERBEROS.REALM
principal_name = EXP:1, SEQUENCE:principal_seq

[principal_seq]
name_type = EXP:0, INTEGER:1
name_string = EXP:1, SEQUENCE:principals

[principals]
princ1 = GeneralString:username

[ ca ]
default_ca = CA_default

[CA_default]
[ CA_default ]
dir = cadir
database = $dir/index.txt
crlnumber = $dir/crl.txt
default_md = sha256
default_days = 360000
default_crl_days = 360000
startdate = {startdate}
default_startdate = {startdate}
enddate = {enddate}
default_enddate = {enddate}
default_days = 7000
default_crl_days = 7000
certificate = tls-ca-cert.pem
private_key = tls-ca-key.pem
serial = $dir/serial
RANDFILE = $dir/.rand

policy = policy_match

[policy_match]
[ policy_match ]
countryName = match
stateOrProvinceName = optional
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

[policy_anything]
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
Expand All @@ -62,162 +111,150 @@
commonName = supplied
emailAddress = optional

[v3_ca]

[ v3_ca ]

subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = CA:true
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, keyCertSign, cRLSign

"""

here = os.path.abspath(os.path.dirname(__file__))


def make_cert_key(hostname, sign=False):
def make_cert_key(hostname, sign=False, extra_san='',
ext='req_x509_extensions_full', key='rsa:3072'):
print("creating cert for " + hostname)
tempnames = []
for _ in range(3):
for i in range(3):
with tempfile.NamedTemporaryFile(delete=False) as f:
tempnames.append(f.name)
req_file, cert_file, key_file = tempnames
if sign:
reqext = 'req_x509_extensions_simple'
else:
reqext = ext
try:
req = req_template.format(hostname=hostname)
with open(req_file, "w") as f:
req = req_template.format(
hostname=hostname,
extra_san=extra_san,
startdate=startdate,
enddate=enddate
)
with open(req_file, 'w') as f:
f.write(req)
args = [
"req",
"-new",
"-days",
"365242",
"-nodes",
"-newkey",
"rsa:2048",
"-keyout",
key_file,
"-config",
req_file,
]
args = ['req', '-new', '-nodes', '-days', '7000',
'-newkey', key, '-keyout', key_file,
'-extensions', reqext,
'-config', req_file]
if sign:
with tempfile.NamedTemporaryFile(delete=False) as f:
tempnames.append(f.name)
reqfile = f.name
args += ["-out", reqfile]
args += ['-out', reqfile ]

else:
args += ["-x509", "-out", cert_file]
subprocess.check_call(["openssl"] + args)
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,
'ca',
'-config', req_file,
'-extensions', ext,
'-out', cert_file,
'-outdir', 'cadir',
'-policy', 'policy_anything',
'-batch', '-infiles', reqfile
]
subprocess.check_call(["openssl"] + args)
check_call(['openssl'] + args)


with open(cert_file) as f:
with open(cert_file, 'r') as f:
cert = f.read()
with open(key_file) as f:
with open(key_file, 'r') as f:
key = f.read()
return cert, key
finally:
for name in tempnames:
os.remove(name)


TMP_CADIR = "cadir"

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','crl.txt'),'a+') as f:
# f.write("00")
with open(os.path.join("cadir", "index.txt.attr"), "w+") as f:
f.write("unique_subject = no")
with open(os.path.join('cadir','index.txt'),'a+') as f:
pass # empty file
with open(os.path.join('cadir','crl.txt'),'a+') as f:
f.write("00")
with open(os.path.join('cadir','index.txt.attr'),'w+') as f:
f.write('unique_subject = no')
# random start value for serial numbers
with open(os.path.join('cadir','serial'), 'w') as f:
f.write('CB2D80995A69525B\n')

with tempfile.NamedTemporaryFile("w") as t:
t.write(req_template.format(hostname="our-ca-server"))
req = req_template.format(
hostname='our-ca-server',
extra_san='',
startdate=startdate,
enddate=enddate
)
t.write(req)
t.flush()
with tempfile.NamedTemporaryFile() as f:
args = [
"req",
"-new",
"-days",
"365242",
"-extensions",
"v3_ca",
"-nodes",
"-newkey",
"rsa:2048",
"-keyout",
"tls-ca-key.pem",
"-out",
f.name,
"-subj",
"/C=XY/L=Dask-distributed/O=Dask CA/CN=our-ca-server",
]
subprocess.check_call(["openssl"] + args)
args = [
"ca",
"-config",
t.name,
"-create_serial",
"-out",
"tls-ca-cert.pem",
"-batch",
"-outdir",
TMP_CADIR,
"-keyfile",
"tls-ca-key.pem",
"-days",
"365242",
"-selfsign",
"-extensions",
"v3_ca",
"-infiles",
f.name,
]
subprocess.check_call(["openssl"] + args)
# args = ['ca', '-config', t.name, '-gencrl', '-out', 'revocation.crl']
# subprocess.check_call(['openssl'] + args)
args = ['req', '-config', t.name, '-new',
'-nodes',
'-newkey', 'rsa:3072',
'-keyout', 'tls-ca-key.pem',
'-out', f.name,
'-subj', '/C=XY/L=Dask-distributed/O=Dask CA/CN=our-ca-server']
check_call(['openssl'] + args)
args = ['ca', '-config', t.name,
'-out', 'tls-ca-cert.pem', '-batch', '-outdir', TMP_CADIR,
'-keyfile', 'tls-ca-key.pem',
'-selfsign', '-extensions', 'v3_ca', '-infiles', f.name ]
check_call(['openssl'] + args)
args = ['ca', '-config', t.name, '-gencrl', '-out', 'revocation.crl']
check_call(['openssl'] + args)

def print_cert(path):
import _ssl
pprint.pprint(_ssl._test_decode_cert(path))


if __name__ == "__main__":
if __name__ == '__main__':
os.chdir(here)
cert, key = make_cert_key("localhost")
with open("tls-self-signed-cert.pem", "w") as f:
cert, key = make_cert_key('localhost', ext='req_x509_extensions_simple')
with open('tls-self-signed-cert.pem', 'w') as f:
f.write(cert)
with open("tls-self-signed-key.pem", "w") as f:
with open('tls-self-signed-key.pem', 'w') as f:
f.write(key)

# For certificate matching tests
make_ca()
with open("tls-ca-cert.pem") as f:
with open('tls-ca-cert.pem') as f:
ca_cert = f.read()

cert, key = make_cert_key("localhost", sign=True)
with open("tls-cert.pem", "w") as f:
cert, key = make_cert_key('localhost', sign=True)
with open('tls-cert.pem', 'w') as f:
f.write(cert)
with open("tls-cert-chain.pem", "w") as f:
with open('tls-cert-chain.pem', 'w') as f:
f.write(cert)
f.write(ca_cert)
with open("tls-key.pem", "w") as f:
with open('tls-key.pem', 'w') as f:
f.write(key)
with open("tls-key-cert.pem", "w") as f:
with open('tls-key-cert.pem', 'w') as f:
f.write(key)
f.write(cert)

unmake_ca()

print_cert('tls-self-signed-cert.pem')
print_cert('tls-key-cert.pem')
print_cert('tls-cert-chain.pem')
Loading
Loading