Skip to content
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
49 changes: 27 additions & 22 deletions tests/certs/client.cert.pem
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
-----BEGIN CERTIFICATE-----
MIIEAzCCAuugAwIBAgIUPfej8IQ/5bCrihqWImrq2vKPOq0wDQYJKoZIhvcNAQEL
BQAwgaMxCzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQHDAdU
b3JvbnRvMRgwFgYDVQQKDA9NYWdpY1N0YWNrIEluYy4xFjAUBgNVBAsMDWFzeW5j
cGcgdGVzdHMxHzAdBgNVBAMMFmFzeW5jcGcgdGVzdCBjbGllbnQgQ0ExHTAbBgkq
hkiG9w0BCQEWDmhlbGxvQG1hZ2ljLmlvMB4XDTIxMDgwOTIxNTA1MloXDTMyMDEw
NDIxNTA1MlowgZUxCzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYD
VQQHDAdUb3JvbnRvMRgwFgYDVQQKDA9NYWdpY1N0YWNrIEluYy4xFjAUBgNVBAsM
DWFzeW5jcGcgdGVzdHMxETAPBgNVBAMMCHNzbF91c2VyMR0wGwYJKoZIhvcNAQkB
Fg5oZWxsb0BtYWdpYy5pbzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
AJjiP9Ik/KRRLK9GMvoH8m1LO+Gyrr8Gz36LpmKJMR/PpwTL+1pOkYSGhOyT3Cw9
/kWWLJRCvYqKgFtYtbr4S6ReGm3GdSVW+sfVRYDrRQZLPgQSPeq25g2v8UZ63Ota
lPAyUPUZKpxyWz8PL77lV8psb9yv14yBH2kv9BbxKPksWOU8p8OCn1Z3WFFl0ItO
nzMvCp5os+xFrt4SpoRGTx9x4QleY+zrEsYZtmnV4wC+JuJkNw4fuCdrX5k7dghs
uZkcsAZof1nMdYsYiazeDfQKZtJqh5kO7mpwvCudKUWaLJJUwiQA87BwSlnCd/Hh
TZDbC+zeFNjTS49/4Q72xVECAwEAAaM7MDkwHwYDVR0jBBgwFoAUi1jMmAisuOib
mHIE2n0W2WnnaL0wCQYDVR0TBAIwADALBgNVHQ8EBAMCBPAwDQYJKoZIhvcNAQEL
BQADggEBACbnp5oOp639ko4jn8axF+so91k0vIcgwDg+NqgtSRsuAENGumHAa8ec
YOks0TCTvNN5E6AfNSxRat5CyguIlJ/Vy3KbkkFNXcCIcI/duAJvNphg7JeqYlQM
VIJhrO/5oNQMzzTw8XzTHnciGbrbiZ04hjwrruEkvmIAwgQPhIgq4H6umTZauTvk
DEo7uLm7RuG9hnDyWCdJxLLljefNL/EAuDYpPzgTeEN6JAnOu0ULIbpxpJKiYEId
8I0U2n0I2NTDOHmsAJiXf8BiHHmpK5SXFyY9s2ZuGkCzvmeZlR81tTXmHZ3v1X2z
8NajoAZfJ+QD50DrbF5E00yovZbyIB4=
MIIE7DCCA9SgAwIBAgIJAMXPbgYRbS6PMA0GCSqGSIb3DQEBCwUAMIGjMQswCQYD
VQQGEwJDQTEQMA4GA1UECAwHT250YXJpbzEQMA4GA1UEBwwHVG9yb250bzEYMBYG
A1UECgwPTWFnaWNTdGFjayBJbmMuMRYwFAYDVQQLDA1hc3luY3BnIHRlc3RzMR8w
HQYDVQQDDBZhc3luY3BnIHRlc3QgY2xpZW50IENBMR0wGwYJKoZIhvcNAQkBFg5o
ZWxsb0BtYWdpYy5pbzAeFw0yNjA5MjAxNTQ2MTNaFw00NTExMjAxNTQ2MTNaMIGV
MQswCQYDVQQGEwJDQTEQMA4GA1UECAwHT250YXJpbzEQMA4GA1UEBwwHVG9yb250
bzEYMBYGA1UECgwPTWFnaWNTdGFjayBJbmMuMRYwFAYDVQQLDA1hc3luY3BnIHRl
c3RzMREwDwYDVQQDDAhzc2xfdXNlcjEdMBsGCSqGSIb3DQEJARYOaGVsbG9AbWFn
aWMuaW8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCY4j/SJPykUSyv
RjL6B/JtSzvhsq6/Bs9+i6ZiiTEfz6cEy/taTpGEhoTsk9wsPf5FliyUQr2KioBb
WLW6+EukXhptxnUlVvrH1UWA60UGSz4EEj3qtuYNr/FGetzrWpTwMlD1GSqccls/
Dy++5VfKbG/cr9eMgR9pL/QW8Sj5LFjlPKfDgp9Wd1hRZdCLTp8zLwqeaLPsRa7e
EqaERk8fceEJXmPs6xLGGbZp1eMAvibiZDcOH7gna1+ZO3YIbLmZHLAGaH9ZzHWL
GIms3g30CmbSaoeZDu5qcLwrnSlFmiySVMIkAPOwcEpZwnfx4U2Q2wvs3hTY00uP
f+EO9sVRAgMBAAGjggEtMIIBKTALBgNVHQ8EBAMCBaAwDAYDVR0TAQH/BAIwADAT
BgNVHSUEDDAKBggrBgEFBQcDAjAdBgNVHQ4EFgQUrN4T5/0XSalNz7t/TFsyKBDp
Z/0wgdcGA1UdIwSBzzCBzIAUi1jMmAisuOibmHIE2n0W2WnnaL2hgamkgaYwgaMx
CzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQHDAdUb3JvbnRv
MRgwFgYDVQQKDA9NYWdpY1N0YWNrIEluYy4xFjAUBgNVBAsMDWFzeW5jcGcgdGVz
dHMxHzAdBgNVBAMMFmFzeW5jcGcgdGVzdCBjbGllbnQgQ0ExHTAbBgkqhkiG9w0B
CQEWDmhlbGxvQG1hZ2ljLmlvgghiZ4DNR5q6XDANBgkqhkiG9w0BAQsFAAOCAQEA
V2yzmJzxZUVYDOLkWdMI7w+easy8387xNDqVMoSMagnyoeJ1Qgwh1F7W8xYJ+XEz
mfI2FJVWOQtOfp0Uib1l0M5ysZr9iKiJ+z0daiw8l/9ru3U0D+UiGUqQcR9v8wpo
1o9gg+sDuMASd+3TwQHw61N6cs5J0hp8w2lJa8QmPWcnfEDwRWlaIbIPY9dRtSZ5
geUEk7sj9XIN2gGeCQ4z1wUv/ZPJ8pCsHlam4KUt39Kx8FTUIKKlJrxQjrEW6yeY
DlbEdrGL1JpE80zBXGyGUQYXC76MMr0yDb70BFiGCNQrKdJeFe9zCl8N8Uq8IImg
URBnwi1RJjdumfMw1gC1Ow==
-----END CERTIFICATE-----
46 changes: 23 additions & 23 deletions tests/certs/client_ca.cert.pem
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
-----BEGIN CERTIFICATE-----
MIIEKTCCAxGgAwIBAgIUKmL8tfNS9LIB6GLB9RpZpTyk3uIwDQYJKoZIhvcNAQEL
BQAwgaMxCzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQHDAdU
b3JvbnRvMRgwFgYDVQQKDA9NYWdpY1N0YWNrIEluYy4xFjAUBgNVBAsMDWFzeW5j
cGcgdGVzdHMxHzAdBgNVBAMMFmFzeW5jcGcgdGVzdCBjbGllbnQgQ0ExHTAbBgkq
hkiG9w0BCQEWDmhlbGxvQG1hZ2ljLmlvMB4XDTIxMDgwOTIxNDQxM1oXDTQxMDgw
NDIxNDQxM1owgaMxCzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYD
VQQHDAdUb3JvbnRvMRgwFgYDVQQKDA9NYWdpY1N0YWNrIEluYy4xFjAUBgNVBAsM
DWFzeW5jcGcgdGVzdHMxHzAdBgNVBAMMFmFzeW5jcGcgdGVzdCBjbGllbnQgQ0Ex
HTAbBgkqhkiG9w0BCQEWDmhlbGxvQG1hZ2ljLmlvMIIBIjANBgkqhkiG9w0BAQEF
AAOCAQ8AMIIBCgKCAQEAptRYfxKiWExfZguQDva53bIqYa4lJwZA86Qu0peBUcsd
E6zyHNgVv4XSMim1FH12KQ4KPKuQAcVqRMCRAHqB96kUfWQqF//fLajr0umdzcbx
+UTgNux8TkScTl9KNAxhiR/oOGbKFcNSs4raaG8puwwEN66uMhoKk2pN2NwDVfHa
bTekJ3jouTcTCnqCynx4qwI4WStJkuW4IPCmDRVXxOOauT7YalElYLWYtAOqGEvf
noDK2Imhc0h6B5XW8nI54rVCXWwhW1v3RLAJGP+LwSy++bf08xmpHXdKkAj5BmUO
QwJRiJ33Xa17rmi385egx8KpqV04YEAPdV1Z4QM6PQIDAQABo1MwUTAdBgNVHQ4E
FgQUi1jMmAisuOibmHIE2n0W2WnnaL0wHwYDVR0jBBgwFoAUi1jMmAisuOibmHIE
2n0W2WnnaL0wDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAifNE
ZLZXxECp2Sl6jCViZxgFf2+OHDvRORgI6J0heckYyYF/JHvLaDphh6TkSJAdT6Y3
hAb7jueTMI+6RIdRzIjTKCGdJqUetiSfAbnQyIp2qmVqdjeFoXTvQL7BdkIE+kOW
0iomMqDB3czTl//LrgVQCYqKM0D/Ytecpg2mbshLfpPxdHyliCJcb4SqfdrDnKoV
HUduBjOVot+6bkB5SEGCrrB4KMFTzbAu+zriKWWz+uycIyeVMLEyhDs59vptOK6e
gWkraG43LZY3cHPiVeN3tA/dWdyJf9rgK21zQDSMB8OSH4yQjdQmkkvRQBjp3Fcy
w2SZIP4o9l1Y7+hMMw==
MIIEKjCCAxKgAwIBAgIIYmeAzUeaulwwDQYJKoZIhvcNAQELBQAwgaMxCzAJBgNV
BAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQHDAdUb3JvbnRvMRgwFgYD
VQQKDA9NYWdpY1N0YWNrIEluYy4xFjAUBgNVBAsMDWFzeW5jcGcgdGVzdHMxHzAd
BgNVBAMMFmFzeW5jcGcgdGVzdCBjbGllbnQgQ0ExHTAbBgkqhkiG9w0BCQEWDmhl
bGxvQG1hZ2ljLmlvMB4XDTI2MDkyMDE1NDYxM1oXDTQ1MTEyMDE1NDYxM1owgaMx
CzAJBgNVBAYTAkNBMRAwDgYDVQQIDAdPbnRhcmlvMRAwDgYDVQQHDAdUb3JvbnRv
MRgwFgYDVQQKDA9NYWdpY1N0YWNrIEluYy4xFjAUBgNVBAsMDWFzeW5jcGcgdGVz
dHMxHzAdBgNVBAMMFmFzeW5jcGcgdGVzdCBjbGllbnQgQ0ExHTAbBgkqhkiG9w0B
CQEWDmhlbGxvQG1hZ2ljLmlvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAptRYfxKiWExfZguQDva53bIqYa4lJwZA86Qu0peBUcsdE6zyHNgVv4XSMim1
FH12KQ4KPKuQAcVqRMCRAHqB96kUfWQqF//fLajr0umdzcbx+UTgNux8TkScTl9K
NAxhiR/oOGbKFcNSs4raaG8puwwEN66uMhoKk2pN2NwDVfHabTekJ3jouTcTCnqC
ynx4qwI4WStJkuW4IPCmDRVXxOOauT7YalElYLWYtAOqGEvfnoDK2Imhc0h6B5XW
8nI54rVCXWwhW1v3RLAJGP+LwSy++bf08xmpHXdKkAj5BmUOQwJRiJ33Xa17rmi3
85egx8KpqV04YEAPdV1Z4QM6PQIDAQABo2AwXjAPBgNVHRMBAf8EBTADAQH/MAsG
A1UdDwQEAwIBBjAdBgNVHQ4EFgQUi1jMmAisuOibmHIE2n0W2WnnaL0wHwYDVR0j
BBgwFoAUi1jMmAisuOibmHIE2n0W2WnnaL0wDQYJKoZIhvcNAQELBQADggEBAEI4
hrs6eAd+AD1GwU1GQpuwOGYPlwKHAIYgpDkNi9UTF3munLnVIZffxeq8z9e31kxo
/1CJYanG3ajupBxj/+wRWKQkf9mWLo8N9fmEWC1k9Xp8r9WyupnfSRILZh/aEvSW
pkbJAwI9xB+fD8L225+wQKwR0XT//uqtlzIyxLSMMwZXAfr9p3LlMvPG/xwfywg+
SiFIIBIUM64f4sH6wDZWpGeORdI3BlPo/fiZgvZiI6VJv16Kq4eU0KwMsGeFE5ON
99vSDNKqrLqahEv9vigDnCAWus9IN5Cap3xA7Q2C4naDB87y6JSIv+kuVreiuf5x
qzhNr5p37kx+78yclOQ=
-----END CERTIFICATE-----
149 changes: 128 additions & 21 deletions tests/certs/gen.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import argparse
import datetime
import os

Expand All @@ -9,18 +10,30 @@
from cryptography.x509 import oid


def _new_cert(issuer=None, is_issuer=False, serial_number=None, **subject):
backend = backends.default_backend()
private_key = rsa.generate_private_key(
public_exponent=65537, key_size=4096, backend=backend
)
public_key = private_key.public_key()
subject = x509.Name(
def _new_subject(**subject):
return x509.Name(
[
x509.NameAttribute(getattr(oid.NameOID, key.upper()), value)
for key, value in subject.items()
]
)


def _new_cert(
issuer=None,
is_issuer=False,
is_client=False,
private_key=None,
serial_number=None,
**subject,
):
backend = backends.default_backend()
if private_key is None:
private_key = rsa.generate_private_key(
public_exponent=65537, key_size=4096, backend=backend
)
public_key = private_key.public_key()
subject = _new_subject(**subject)
builder = (
x509.CertificateBuilder()
.subject_name(subject)
Expand Down Expand Up @@ -85,6 +98,11 @@ def _new_cert(issuer=None, is_issuer=False, serial_number=None, **subject):
)
)
else:
extended_key_usage = (
oid.ExtendedKeyUsageOID.CLIENT_AUTH
if is_client
else oid.ExtendedKeyUsageOID.SERVER_AUTH
)
Comment on lines +101 to +105
builder = (
builder.add_extension(
x509.KeyUsage(
Expand All @@ -105,11 +123,7 @@ def _new_cert(issuer=None, is_issuer=False, serial_number=None, **subject):
critical=True,
)
.add_extension(
x509.ExtendedKeyUsage([oid.ExtendedKeyUsageOID.SERVER_AUTH]),
critical=False,
)
.add_extension(
x509.SubjectAlternativeName([x509.DNSName("localhost")]),
x509.ExtendedKeyUsage([extended_key_usage]),
critical=False,
)
.add_extension(
Expand All @@ -121,6 +135,11 @@ def _new_cert(issuer=None, is_issuer=False, serial_number=None, **subject):
critical=False,
)
)
if not is_client:
builder = builder.add_extension(
x509.SubjectAlternativeName([x509.DNSName("localhost")]),
critical=False,
)
certificate = builder.sign(
private_key=signing_key,
algorithm=hashes.SHA256(),
Expand All @@ -129,20 +148,36 @@ def _new_cert(issuer=None, is_issuer=False, serial_number=None, **subject):
return certificate, private_key


def _write_cert(path, cert_key_pair, password=None):
certificate, private_key = cert_key_pair
def _write_key(path, private_key, password=None):
if password:
encryption = serialization.BestAvailableEncryption(password)
else:
encryption = serialization.NoEncryption()
with open(path + ".key.pem", "wb") as f:
with open(path, "wb") as f:
f.write(
private_key.private_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PrivateFormat.TraditionalOpenSSL,
encryption_algorithm=encryption,
)
)


def _load_key(path, password=None):
try:
with open(path, "rb") as f:
return serialization.load_pem_private_key(
f.read(),
password=password,
backend=backends.default_backend(),
)
except FileNotFoundError:
return None


def _write_cert(path, cert_key_pair, password=None):
certificate, private_key = cert_key_pair
_write_key(path + ".key.pem", private_key, password)
with open(path + ".cert.pem", "wb") as f:
f.write(
certificate.public_bytes(
Expand All @@ -151,22 +186,50 @@ def _write_cert(path, cert_key_pair, password=None):
)


def new_ca(path, **subject):
cert_key_pair = _new_cert(is_issuer=True, **subject)
def new_ca(path, private_key=None, **subject):
cert_key_pair = _new_cert(
is_issuer=True,
private_key=private_key,
**subject,
)
_write_cert(path, cert_key_pair)
return cert_key_pair


def new_cert(
path, ca_cert_key_pair, password=None, is_issuer=False, **subject
path,
ca_cert_key_pair,
password=None,
is_issuer=False,
is_client=False,
private_key=None,
**subject,
):
cert_key_pair = _new_cert(
issuer=ca_cert_key_pair, is_issuer=is_issuer, **subject
issuer=ca_cert_key_pair,
is_issuer=is_issuer,
is_client=is_client,
private_key=private_key,
**subject,
)
_write_cert(path, cert_key_pair, password)
return cert_key_pair


def new_csr(path, private_key, **subject):
request = (
x509.CertificateSigningRequestBuilder()
.subject_name(_new_subject(**subject))
.sign(
private_key,
hashes.SHA256(),
backends.default_backend(),
)
)
with open(path + ".csr.pem", "wb") as f:
f.write(request.public_bytes(serialization.Encoding.PEM))


def new_crl(path, issuer, cert):
issuer_cert, signing_key = issuer
revoked_cert = (
Expand All @@ -187,9 +250,15 @@ def new_crl(path, issuer, cert):
f.write(crl.public_bytes(encoding=serialization.Encoding.PEM))


def main():
def main(*, rotate_keys=False):
def existing_key(path):
if rotate_keys:
return None
return _load_key(path)

ca = new_ca(
"ca",
private_key=existing_key("ca.key.pem"),
country_name="CA",
state_or_province_name="Ontario",
locality_name="Toronto",
Expand All @@ -201,6 +270,7 @@ def main():
server = new_cert(
"server",
ca,
private_key=existing_key("server.key.pem"),
country_name="CA",
state_or_province_name="Ontario",
organization_name="MagicStack Inc.",
Expand All @@ -211,6 +281,43 @@ def main():
)
new_crl('server', ca, server)

client_ca = new_ca(
"client_ca",
private_key=existing_key("client_ca.key.pem"),
country_name="CA",
state_or_province_name="Ontario",
locality_name="Toronto",
organization_name="MagicStack Inc.",
organizational_unit_name="asyncpg tests",
common_name="asyncpg test client CA",
email_address="hello@magic.io",
)
client_subject = dict(
country_name="CA",
state_or_province_name="Ontario",
locality_name="Toronto",
organization_name="MagicStack Inc.",
organizational_unit_name="asyncpg tests",
common_name="ssl_user",
email_address="hello@magic.io",
)
client = new_cert(
"client",
client_ca,
is_client=True,
private_key=existing_key("client.key.pem"),
**client_subject,
)
new_csr("client", client[1], **client_subject)
_write_key("client.key.protected.pem", client[1], b"secRet")


if __name__ == "__main__":
main()
parser = argparse.ArgumentParser()
parser.add_argument(
"--rotate-keys",
action="store_true",
help="generate new private keys instead of reusing existing key files",
)
args = parser.parse_args()
main(rotate_keys=args.rotate_keys)
Loading