Skip to content

Commit 243cac3

Browse files
committed
remove python deprecation warnings from pyopenssl
Create certificates using the pyhttpd credentials instead.
1 parent cf08920 commit 243cac3

File tree

9 files changed

+167
-127
lines changed

9 files changed

+167
-127
lines changed

test/modules/md/md_cert_util.py

Lines changed: 20 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import logging
22
import re
3-
import os
43
import socket
54
import OpenSSL
65
import time
@@ -12,6 +11,7 @@
1211
from http.client import HTTPConnection
1312
from urllib.parse import urlparse
1413

14+
from cryptography import x509
1515

1616
SEC_PER_DAY = 24 * 60 * 60
1717

@@ -23,45 +23,6 @@ class MDCertUtil(object):
2323
# Utility class for inspecting certificates in test cases
2424
# Uses PyOpenSSL: https://pyopenssl.org/en/stable/index.html
2525

26-
@classmethod
27-
def create_self_signed_cert(cls, path, name_list, valid_days, serial=1000):
28-
domain = name_list[0]
29-
if not os.path.exists(path):
30-
os.makedirs(path)
31-
32-
cert_file = os.path.join(path, 'pubcert.pem')
33-
pkey_file = os.path.join(path, 'privkey.pem')
34-
# create a key pair
35-
if os.path.exists(pkey_file):
36-
key_buffer = open(pkey_file, 'rt').read()
37-
k = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, key_buffer)
38-
else:
39-
k = OpenSSL.crypto.PKey()
40-
k.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)
41-
42-
# create a self-signed cert
43-
cert = OpenSSL.crypto.X509()
44-
cert.get_subject().C = "DE"
45-
cert.get_subject().ST = "NRW"
46-
cert.get_subject().L = "Muenster"
47-
cert.get_subject().O = "greenbytes GmbH"
48-
cert.get_subject().CN = domain
49-
cert.set_serial_number(serial)
50-
cert.gmtime_adj_notBefore(valid_days["notBefore"] * SEC_PER_DAY)
51-
cert.gmtime_adj_notAfter(valid_days["notAfter"] * SEC_PER_DAY)
52-
cert.set_issuer(cert.get_subject())
53-
54-
cert.add_extensions([OpenSSL.crypto.X509Extension(
55-
b"subjectAltName", False, b", ".join(map(lambda n: b"DNS:" + n.encode(), name_list))
56-
)])
57-
cert.set_pubkey(k)
58-
cert.sign(k, 'sha1')
59-
60-
open(cert_file, "wt").write(
61-
OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert).decode('utf-8'))
62-
open(pkey_file, "wt").write(
63-
OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, k).decode('utf-8'))
64-
6526
@classmethod
6627
def load_server_cert(cls, host_ip, host_port, host_name, tls=None, ciphers=None):
6728
ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
@@ -138,17 +99,26 @@ def get_serial(self):
13899
# add leading 0s to align with word boundaries.
139100
return ("%lx" % (self.cert.get_serial_number())).upper()
140101

141-
def same_serial_as(self, other):
142-
if isinstance(other, MDCertUtil):
143-
return self.cert.get_serial_number() == other.cert.get_serial_number()
144-
elif isinstance(other, OpenSSL.crypto.X509):
145-
return self.cert.get_serial_number() == other.get_serial_number()
146-
elif isinstance(other, str):
102+
@staticmethod
103+
def _get_serial(cert) -> int:
104+
if isinstance(cert, x509.Certificate):
105+
return cert.serial_number
106+
if isinstance(cert, MDCertUtil):
107+
return cert.get_serial_number()
108+
elif isinstance(cert, OpenSSL.crypto.X509):
109+
return cert.get_serial_number()
110+
elif isinstance(cert, str):
147111
# assume a hex number
148-
return self.cert.get_serial_number() == int(other, 16)
149-
elif isinstance(other, int):
150-
return self.cert.get_serial_number() == other
151-
return False
112+
return int(cert, 16)
113+
elif isinstance(cert, int):
114+
return cert
115+
return 0
116+
117+
def get_serial_number(self):
118+
return self._get_serial(self.cert)
119+
120+
def same_serial_as(self, other):
121+
return self._get_serial(self.cert) == self._get_serial(other)
152122

153123
def get_not_before(self):
154124
tsp = self.cert.get_notBefore()

test/modules/md/md_env.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
import time
1313

1414
from datetime import datetime, timedelta
15-
from typing import Dict, Optional
15+
from typing import Dict, Optional, Any
1616

17-
from pyhttpd.certs import CertificateSpec
17+
from pyhttpd.certs import CertificateSpec, Credentials, HttpdTestCA
1818
from .md_cert_util import MDCertUtil
1919
from pyhttpd.env import HttpdTestSetup, HttpdTestEnv
2020
from pyhttpd.result import ExecResult
@@ -611,8 +611,13 @@ def await_ocsp_status(self, domain, timeout=10, ca_file=None):
611611
time.sleep(0.1)
612612
raise TimeoutError(f"ocsp respopnse not available: {domain}")
613613

614-
def create_self_signed_cert(self, name_list, valid_days, serial=1000, path=None):
615-
dirpath = path
616-
if not path:
617-
dirpath = os.path.join(self.store_domains(), name_list[0])
618-
return MDCertUtil.create_self_signed_cert(dirpath, name_list, valid_days, serial)
614+
def create_self_signed_cert(self, spec: CertificateSpec,
615+
valid_from: timedelta = timedelta(days=-1),
616+
valid_to: timedelta = timedelta(days=89),
617+
serial: Optional[int] = None) -> Credentials:
618+
key_type = spec.key_type if spec.key_type else 'rsa4096'
619+
return HttpdTestCA.create_credentials(spec=spec, issuer=None,
620+
key_type=key_type,
621+
valid_from=valid_from,
622+
valid_to=valid_to,
623+
serial=serial)

test/modules/md/test_502_acmev2_drive.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
import json
55
import os.path
66
import re
7-
import time
7+
from datetime import timedelta
88

99
import pytest
10+
from pyhttpd.certs import CertificateSpec
1011

11-
from .md_conf import MDConf, MDConf
12+
from .md_conf import MDConf
1213
from .md_cert_util import MDCertUtil
1314
from .md_env import MDTestEnv
1415

@@ -430,9 +431,12 @@ def test_md_502_201(self, env, renew_window, test_data_list):
430431
print("TRACE: start testing renew window: %s" % renew_window)
431432
for tc in test_data_list:
432433
print("TRACE: create self-signed cert: %s" % tc["valid"])
433-
env.create_self_signed_cert([name], tc["valid"])
434-
cert2 = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
435-
assert not cert2.same_serial_as(cert1)
434+
creds = env.create_self_signed_cert(CertificateSpec(domains=[name]),
435+
valid_from=timedelta(days=tc["valid"]["notBefore"]),
436+
valid_to=timedelta(days=tc["valid"]["notAfter"]))
437+
assert creds.certificate.serial_number != cert1.get_serial_number()
438+
# copy it over, assess status again
439+
creds.save_cert_pem(env.store_domain_file(name, 'pubcert.pem'))
436440
md = env.a2md(["list", name]).json['output'][0]
437441
assert md["renew"] == tc["renew"], \
438442
"Expected renew == {} indicator in {}, test case {}".format(tc["renew"], md, tc)

test/modules/md/test_702_auto.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import os
2-
import time
2+
from datetime import timedelta
33

44
import pytest
5+
from pyhttpd.certs import CertificateSpec
56

6-
from pyhttpd.conf import HttpdConf
77
from pyhttpd.env import HttpdTestEnv
88
from .md_cert_util import MDCertUtil
99
from .md_env import MDTestEnv
@@ -320,18 +320,22 @@ def test_md_702_009(self, env):
320320
assert cert1.same_serial_as(stat['rsa']['serial'])
321321
#
322322
# create self-signed cert, with critical remaining valid duration -> drive again
323-
env.create_self_signed_cert([domain], {"notBefore": -120, "notAfter": 2}, serial=7029)
324-
cert3 = MDCertUtil(env.store_domain_file(domain, 'pubcert.pem'))
325-
assert cert3.same_serial_as('1B75')
323+
creds = env.create_self_signed_cert(CertificateSpec(domains=[domain]),
324+
valid_from=timedelta(days=-120),
325+
valid_to=timedelta(days=2),
326+
serial=7029)
327+
creds.save_cert_pem(env.store_domain_file(domain, 'pubcert.pem'))
328+
creds.save_pkey_pem(env.store_domain_file(domain, 'privkey.pem'))
329+
assert creds.certificate.serial_number == 7029
326330
assert env.apache_restart() == 0
327331
stat = env.get_certificate_status(domain)
328-
assert cert3.same_serial_as(stat['rsa']['serial'])
332+
assert creds.certificate.serial_number == int(stat['rsa']['serial'], 16)
329333
#
330334
# cert should renew and be different afterwards
331335
assert env.await_completion([domain], must_renew=True)
332336
stat = env.get_certificate_status(domain)
333-
assert not cert3.same_serial_as(stat['rsa']['serial'])
334-
337+
creds.certificate.serial_number != int(stat['rsa']['serial'], 16)
338+
335339
# test case: drive with an unsupported challenge due to port availability
336340
def test_md_702_010(self, env):
337341
domain = self.test_domain

test/modules/md/test_730_static.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import os
2+
from datetime import timedelta
23

34
import pytest
5+
from pyhttpd.certs import CertificateSpec
46

57
from .md_conf import MDConf
68
from .md_env import MDTestEnv
@@ -30,12 +32,14 @@ def test_md_730_001(self, env):
3032
domains = [domain, 'www.%s' % domain]
3133
testpath = os.path.join(env.gen_dir, 'test_920_001')
3234
# cert that is only 10 more days valid
33-
env.create_self_signed_cert(domains, {"notBefore": -80, "notAfter": 10},
34-
serial=730001, path=testpath)
35+
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
36+
valid_from=timedelta(days=-80),
37+
valid_to=timedelta(days=10),
38+
serial=730001)
3539
cert_file = os.path.join(testpath, 'pubcert.pem')
3640
pkey_file = os.path.join(testpath, 'privkey.pem')
37-
assert os.path.exists(cert_file)
38-
assert os.path.exists(pkey_file)
41+
creds.save_cert_pem(cert_file)
42+
creds.save_pkey_pem(pkey_file)
3943
conf = MDConf(env)
4044
conf.start_md(domains)
4145
conf.add(f"MDCertificateFile {cert_file}")
@@ -60,12 +64,14 @@ def test_md_730_002(self, env):
6064
domains = [domain, 'www.%s' % domain]
6165
testpath = os.path.join(env.gen_dir, 'test_920_001')
6266
# cert that is only 10 more days valid
63-
env.create_self_signed_cert(domains, {"notBefore": -80, "notAfter": 10},
64-
serial=730001, path=testpath)
67+
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
68+
valid_from=timedelta(days=-80),
69+
valid_to=timedelta(days=10),
70+
serial=730001)
6571
cert_file = os.path.join(testpath, 'pubcert.pem')
6672
pkey_file = os.path.join(testpath, 'privkey.pem')
67-
assert os.path.exists(cert_file)
68-
assert os.path.exists(pkey_file)
73+
creds.save_cert_pem(cert_file)
74+
creds.save_pkey_pem(pkey_file)
6975
conf = MDConf(env)
7076
conf.start_md(domains)
7177
conf.add(f"MDPrivateKeys secp384r1 rsa3072")
@@ -93,13 +99,14 @@ def test_md_730_003(self, env):
9399
domains = [domain, 'www.%s' % domain]
94100
testpath = os.path.join(env.gen_dir, 'test_920_001')
95101
# cert that is only 10 more days valid
96-
env.create_self_signed_cert(domains, {"notBefore": -80, "notAfter": 10},
97-
serial=730001, path=testpath)
102+
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
103+
valid_from=timedelta(days=-80),
104+
valid_to=timedelta(days=10),
105+
serial=730001)
98106
cert_file = os.path.join(testpath, 'pubcert.pem')
99107
pkey_file = os.path.join(testpath, 'privkey.pem')
100-
assert os.path.exists(cert_file)
101-
assert os.path.exists(pkey_file)
102-
108+
creds.save_cert_pem(cert_file)
109+
creds.save_pkey_pem(pkey_file)
103110
conf = MDConf(env)
104111
conf.start_md(domains)
105112
conf.add(f"MDCertificateFile {cert_file}")

test/modules/md/test_801_stapling.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import os
44
import time
5+
from datetime import timedelta
56
import pytest
7+
from pyhttpd.certs import CertificateSpec
68

79
from .md_conf import MDConf
810
from .md_env import MDTestEnv
@@ -334,12 +336,14 @@ def test_md_801_009(self, env):
334336
domains = [md]
335337
testpath = os.path.join(env.gen_dir, 'test_801_009')
336338
# cert that is 30 more days valid
337-
env.create_self_signed_cert(domains, {"notBefore": -60, "notAfter": 30},
338-
serial=801009, path=testpath)
339+
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
340+
valid_from=timedelta(days=-60),
341+
valid_to=timedelta(days=30),
342+
serial=801009)
339343
cert_file = os.path.join(testpath, 'pubcert.pem')
340344
pkey_file = os.path.join(testpath, 'privkey.pem')
341-
assert os.path.exists(cert_file)
342-
assert os.path.exists(pkey_file)
345+
creds.save_cert_pem(cert_file)
346+
creds.save_pkey_pem(pkey_file)
343347
conf = MDConf(env)
344348
conf.start_md(domains)
345349
conf.add("MDCertificateFile %s" % cert_file)

test/modules/md/test_901_message.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
import json
44
import os
55
import time
6+
from datetime import timedelta
67
import pytest
8+
from pyhttpd.certs import CertificateSpec
79

8-
from .md_conf import MDConf, MDConf
10+
from .md_conf import MDConf
911
from .md_env import MDTestEnv
1012

1113

@@ -155,13 +157,15 @@ def test_md_901_010(self, env):
155157
domain = self.test_domain
156158
domains = [domain, 'www.%s' % domain]
157159
testpath = os.path.join(env.gen_dir, 'test_901_010')
158-
# cert that is only 10 more days valid
159-
env.create_self_signed_cert(domains, {"notBefore": -70, "notAfter": 20},
160-
serial=901010, path=testpath)
160+
# cert that is only 20 more days valid
161+
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
162+
valid_from=timedelta(days=-70),
163+
valid_to=timedelta(days=20),
164+
serial=901010)
161165
cert_file = os.path.join(testpath, 'pubcert.pem')
162166
pkey_file = os.path.join(testpath, 'privkey.pem')
163-
assert os.path.exists(cert_file)
164-
assert os.path.exists(pkey_file)
167+
creds.save_cert_pem(cert_file)
168+
creds.save_pkey_pem(pkey_file)
165169
conf = MDConf(env)
166170
conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
167171
conf.start_md(domains)
@@ -178,13 +182,15 @@ def test_md_901_011(self, env):
178182
domain = self.test_domain
179183
domains = [domain, f'www.{domain}']
180184
testpath = os.path.join(env.gen_dir, 'test_901_011')
181-
# cert that is only 10 more days valid
182-
env.create_self_signed_cert(domains, {"notBefore": -85, "notAfter": 5},
183-
serial=901011, path=testpath)
185+
# cert that is only 5 more days valid
186+
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
187+
valid_from=timedelta(days=-85),
188+
valid_to=timedelta(days=5),
189+
serial=901010)
184190
cert_file = os.path.join(testpath, 'pubcert.pem')
185191
pkey_file = os.path.join(testpath, 'privkey.pem')
186-
assert os.path.exists(cert_file)
187-
assert os.path.exists(pkey_file)
192+
creds.save_cert_pem(cert_file)
193+
creds.save_pkey_pem(pkey_file)
188194
conf = MDConf(env)
189195
conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
190196
conf.start_md(domains)

test/modules/md/test_920_status.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
import os
44
import re
5-
import time
5+
from datetime import timedelta
66

77
import pytest
8+
from pyhttpd.certs import CertificateSpec
89

910
from .md_conf import MDConf
1011
from shutil import copyfile
@@ -165,13 +166,15 @@ def test_md_920_011(self, env):
165166
domain = self.test_domain
166167
domains = [domain, 'www.%s' % domain]
167168
testpath = os.path.join(env.gen_dir, 'test_920_011')
168-
# cert that is only 10 more days valid
169-
env.create_self_signed_cert(domains, {"notBefore": -70, "notAfter": 20},
170-
serial=920011, path=testpath)
169+
# cert that is only 20 more days valid
170+
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
171+
valid_from=timedelta(days=-70),
172+
valid_to=timedelta(days=20),
173+
serial=920011)
171174
cert_file = os.path.join(testpath, 'pubcert.pem')
172175
pkey_file = os.path.join(testpath, 'privkey.pem')
173-
assert os.path.exists(cert_file)
174-
assert os.path.exists(pkey_file)
176+
creds.save_cert_pem(cert_file)
177+
creds.save_pkey_pem(pkey_file)
175178
conf = MDConf(env, std_vhosts=False, std_ports=False, text=f"""
176179
MDBaseServer on
177180
MDPortMap http:- https:{env.https_port}

0 commit comments

Comments
 (0)