Skip to content

Commit

Permalink
remove python deprecation warnings from pyopenssl
Browse files Browse the repository at this point in the history
Create certificates using the pyhttpd credentials instead.
  • Loading branch information
icing committed Sep 6, 2024
1 parent cf08920 commit 243cac3
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 127 deletions.
70 changes: 20 additions & 50 deletions test/modules/md/md_cert_util.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import logging
import re
import os
import socket
import OpenSSL
import time
Expand All @@ -12,6 +11,7 @@
from http.client import HTTPConnection
from urllib.parse import urlparse

from cryptography import x509

SEC_PER_DAY = 24 * 60 * 60

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

@classmethod
def create_self_signed_cert(cls, path, name_list, valid_days, serial=1000):
domain = name_list[0]
if not os.path.exists(path):
os.makedirs(path)

cert_file = os.path.join(path, 'pubcert.pem')
pkey_file = os.path.join(path, 'privkey.pem')
# create a key pair
if os.path.exists(pkey_file):
key_buffer = open(pkey_file, 'rt').read()
k = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, key_buffer)
else:
k = OpenSSL.crypto.PKey()
k.generate_key(OpenSSL.crypto.TYPE_RSA, 2048)

# create a self-signed cert
cert = OpenSSL.crypto.X509()
cert.get_subject().C = "DE"
cert.get_subject().ST = "NRW"
cert.get_subject().L = "Muenster"
cert.get_subject().O = "greenbytes GmbH"
cert.get_subject().CN = domain
cert.set_serial_number(serial)
cert.gmtime_adj_notBefore(valid_days["notBefore"] * SEC_PER_DAY)
cert.gmtime_adj_notAfter(valid_days["notAfter"] * SEC_PER_DAY)
cert.set_issuer(cert.get_subject())

cert.add_extensions([OpenSSL.crypto.X509Extension(
b"subjectAltName", False, b", ".join(map(lambda n: b"DNS:" + n.encode(), name_list))
)])
cert.set_pubkey(k)
cert.sign(k, 'sha1')

open(cert_file, "wt").write(
OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM, cert).decode('utf-8'))
open(pkey_file, "wt").write(
OpenSSL.crypto.dump_privatekey(OpenSSL.crypto.FILETYPE_PEM, k).decode('utf-8'))

@classmethod
def load_server_cert(cls, host_ip, host_port, host_name, tls=None, ciphers=None):
ctx = OpenSSL.SSL.Context(OpenSSL.SSL.SSLv23_METHOD)
Expand Down Expand Up @@ -138,17 +99,26 @@ def get_serial(self):
# add leading 0s to align with word boundaries.
return ("%lx" % (self.cert.get_serial_number())).upper()

def same_serial_as(self, other):
if isinstance(other, MDCertUtil):
return self.cert.get_serial_number() == other.cert.get_serial_number()
elif isinstance(other, OpenSSL.crypto.X509):
return self.cert.get_serial_number() == other.get_serial_number()
elif isinstance(other, str):
@staticmethod
def _get_serial(cert) -> int:
if isinstance(cert, x509.Certificate):
return cert.serial_number
if isinstance(cert, MDCertUtil):
return cert.get_serial_number()
elif isinstance(cert, OpenSSL.crypto.X509):
return cert.get_serial_number()
elif isinstance(cert, str):
# assume a hex number
return self.cert.get_serial_number() == int(other, 16)
elif isinstance(other, int):
return self.cert.get_serial_number() == other
return False
return int(cert, 16)
elif isinstance(cert, int):
return cert
return 0

def get_serial_number(self):
return self._get_serial(self.cert)

def same_serial_as(self, other):
return self._get_serial(self.cert) == self._get_serial(other)

def get_not_before(self):
tsp = self.cert.get_notBefore()
Expand Down
19 changes: 12 additions & 7 deletions test/modules/md/md_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import time

from datetime import datetime, timedelta
from typing import Dict, Optional
from typing import Dict, Optional, Any

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

def create_self_signed_cert(self, name_list, valid_days, serial=1000, path=None):
dirpath = path
if not path:
dirpath = os.path.join(self.store_domains(), name_list[0])
return MDCertUtil.create_self_signed_cert(dirpath, name_list, valid_days, serial)
def create_self_signed_cert(self, spec: CertificateSpec,
valid_from: timedelta = timedelta(days=-1),
valid_to: timedelta = timedelta(days=89),
serial: Optional[int] = None) -> Credentials:
key_type = spec.key_type if spec.key_type else 'rsa4096'
return HttpdTestCA.create_credentials(spec=spec, issuer=None,
key_type=key_type,
valid_from=valid_from,
valid_to=valid_to,
serial=serial)
14 changes: 9 additions & 5 deletions test/modules/md/test_502_acmev2_drive.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
import json
import os.path
import re
import time
from datetime import timedelta

import pytest
from pyhttpd.certs import CertificateSpec

from .md_conf import MDConf, MDConf
from .md_conf import MDConf
from .md_cert_util import MDCertUtil
from .md_env import MDTestEnv

Expand Down Expand Up @@ -430,9 +431,12 @@ def test_md_502_201(self, env, renew_window, test_data_list):
print("TRACE: start testing renew window: %s" % renew_window)
for tc in test_data_list:
print("TRACE: create self-signed cert: %s" % tc["valid"])
env.create_self_signed_cert([name], tc["valid"])
cert2 = MDCertUtil(env.store_domain_file(name, 'pubcert.pem'))
assert not cert2.same_serial_as(cert1)
creds = env.create_self_signed_cert(CertificateSpec(domains=[name]),
valid_from=timedelta(days=tc["valid"]["notBefore"]),
valid_to=timedelta(days=tc["valid"]["notAfter"]))
assert creds.certificate.serial_number != cert1.get_serial_number()
# copy it over, assess status again
creds.save_cert_pem(env.store_domain_file(name, 'pubcert.pem'))
md = env.a2md(["list", name]).json['output'][0]
assert md["renew"] == tc["renew"], \
"Expected renew == {} indicator in {}, test case {}".format(tc["renew"], md, tc)
Expand Down
20 changes: 12 additions & 8 deletions test/modules/md/test_702_auto.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import os
import time
from datetime import timedelta

import pytest
from pyhttpd.certs import CertificateSpec

from pyhttpd.conf import HttpdConf
from pyhttpd.env import HttpdTestEnv
from .md_cert_util import MDCertUtil
from .md_env import MDTestEnv
Expand Down Expand Up @@ -320,18 +320,22 @@ def test_md_702_009(self, env):
assert cert1.same_serial_as(stat['rsa']['serial'])
#
# create self-signed cert, with critical remaining valid duration -> drive again
env.create_self_signed_cert([domain], {"notBefore": -120, "notAfter": 2}, serial=7029)
cert3 = MDCertUtil(env.store_domain_file(domain, 'pubcert.pem'))
assert cert3.same_serial_as('1B75')
creds = env.create_self_signed_cert(CertificateSpec(domains=[domain]),
valid_from=timedelta(days=-120),
valid_to=timedelta(days=2),
serial=7029)
creds.save_cert_pem(env.store_domain_file(domain, 'pubcert.pem'))
creds.save_pkey_pem(env.store_domain_file(domain, 'privkey.pem'))
assert creds.certificate.serial_number == 7029
assert env.apache_restart() == 0
stat = env.get_certificate_status(domain)
assert cert3.same_serial_as(stat['rsa']['serial'])
assert creds.certificate.serial_number == int(stat['rsa']['serial'], 16)
#
# cert should renew and be different afterwards
assert env.await_completion([domain], must_renew=True)
stat = env.get_certificate_status(domain)
assert not cert3.same_serial_as(stat['rsa']['serial'])
creds.certificate.serial_number != int(stat['rsa']['serial'], 16)

# test case: drive with an unsupported challenge due to port availability
def test_md_702_010(self, env):
domain = self.test_domain
Expand Down
33 changes: 20 additions & 13 deletions test/modules/md/test_730_static.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os
from datetime import timedelta

import pytest
from pyhttpd.certs import CertificateSpec

from .md_conf import MDConf
from .md_env import MDTestEnv
Expand Down Expand Up @@ -30,12 +32,14 @@ def test_md_730_001(self, env):
domains = [domain, 'www.%s' % domain]
testpath = os.path.join(env.gen_dir, 'test_920_001')
# cert that is only 10 more days valid
env.create_self_signed_cert(domains, {"notBefore": -80, "notAfter": 10},
serial=730001, path=testpath)
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
valid_from=timedelta(days=-80),
valid_to=timedelta(days=10),
serial=730001)
cert_file = os.path.join(testpath, 'pubcert.pem')
pkey_file = os.path.join(testpath, 'privkey.pem')
assert os.path.exists(cert_file)
assert os.path.exists(pkey_file)
creds.save_cert_pem(cert_file)
creds.save_pkey_pem(pkey_file)
conf = MDConf(env)
conf.start_md(domains)
conf.add(f"MDCertificateFile {cert_file}")
Expand All @@ -60,12 +64,14 @@ def test_md_730_002(self, env):
domains = [domain, 'www.%s' % domain]
testpath = os.path.join(env.gen_dir, 'test_920_001')
# cert that is only 10 more days valid
env.create_self_signed_cert(domains, {"notBefore": -80, "notAfter": 10},
serial=730001, path=testpath)
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
valid_from=timedelta(days=-80),
valid_to=timedelta(days=10),
serial=730001)
cert_file = os.path.join(testpath, 'pubcert.pem')
pkey_file = os.path.join(testpath, 'privkey.pem')
assert os.path.exists(cert_file)
assert os.path.exists(pkey_file)
creds.save_cert_pem(cert_file)
creds.save_pkey_pem(pkey_file)
conf = MDConf(env)
conf.start_md(domains)
conf.add(f"MDPrivateKeys secp384r1 rsa3072")
Expand Down Expand Up @@ -93,13 +99,14 @@ def test_md_730_003(self, env):
domains = [domain, 'www.%s' % domain]
testpath = os.path.join(env.gen_dir, 'test_920_001')
# cert that is only 10 more days valid
env.create_self_signed_cert(domains, {"notBefore": -80, "notAfter": 10},
serial=730001, path=testpath)
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
valid_from=timedelta(days=-80),
valid_to=timedelta(days=10),
serial=730001)
cert_file = os.path.join(testpath, 'pubcert.pem')
pkey_file = os.path.join(testpath, 'privkey.pem')
assert os.path.exists(cert_file)
assert os.path.exists(pkey_file)

creds.save_cert_pem(cert_file)
creds.save_pkey_pem(pkey_file)
conf = MDConf(env)
conf.start_md(domains)
conf.add(f"MDCertificateFile {cert_file}")
Expand Down
12 changes: 8 additions & 4 deletions test/modules/md/test_801_stapling.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import os
import time
from datetime import timedelta
import pytest
from pyhttpd.certs import CertificateSpec

from .md_conf import MDConf
from .md_env import MDTestEnv
Expand Down Expand Up @@ -334,12 +336,14 @@ def test_md_801_009(self, env):
domains = [md]
testpath = os.path.join(env.gen_dir, 'test_801_009')
# cert that is 30 more days valid
env.create_self_signed_cert(domains, {"notBefore": -60, "notAfter": 30},
serial=801009, path=testpath)
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
valid_from=timedelta(days=-60),
valid_to=timedelta(days=30),
serial=801009)
cert_file = os.path.join(testpath, 'pubcert.pem')
pkey_file = os.path.join(testpath, 'privkey.pem')
assert os.path.exists(cert_file)
assert os.path.exists(pkey_file)
creds.save_cert_pem(cert_file)
creds.save_pkey_pem(pkey_file)
conf = MDConf(env)
conf.start_md(domains)
conf.add("MDCertificateFile %s" % cert_file)
Expand Down
28 changes: 17 additions & 11 deletions test/modules/md/test_901_message.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import json
import os
import time
from datetime import timedelta
import pytest
from pyhttpd.certs import CertificateSpec

from .md_conf import MDConf, MDConf
from .md_conf import MDConf
from .md_env import MDTestEnv


Expand Down Expand Up @@ -155,13 +157,15 @@ def test_md_901_010(self, env):
domain = self.test_domain
domains = [domain, 'www.%s' % domain]
testpath = os.path.join(env.gen_dir, 'test_901_010')
# cert that is only 10 more days valid
env.create_self_signed_cert(domains, {"notBefore": -70, "notAfter": 20},
serial=901010, path=testpath)
# cert that is only 20 more days valid
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
valid_from=timedelta(days=-70),
valid_to=timedelta(days=20),
serial=901010)
cert_file = os.path.join(testpath, 'pubcert.pem')
pkey_file = os.path.join(testpath, 'privkey.pem')
assert os.path.exists(cert_file)
assert os.path.exists(pkey_file)
creds.save_cert_pem(cert_file)
creds.save_pkey_pem(pkey_file)
conf = MDConf(env)
conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
conf.start_md(domains)
Expand All @@ -178,13 +182,15 @@ def test_md_901_011(self, env):
domain = self.test_domain
domains = [domain, f'www.{domain}']
testpath = os.path.join(env.gen_dir, 'test_901_011')
# cert that is only 10 more days valid
env.create_self_signed_cert(domains, {"notBefore": -85, "notAfter": 5},
serial=901011, path=testpath)
# cert that is only 5 more days valid
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
valid_from=timedelta(days=-85),
valid_to=timedelta(days=5),
serial=901010)
cert_file = os.path.join(testpath, 'pubcert.pem')
pkey_file = os.path.join(testpath, 'privkey.pem')
assert os.path.exists(cert_file)
assert os.path.exists(pkey_file)
creds.save_cert_pem(cert_file)
creds.save_pkey_pem(pkey_file)
conf = MDConf(env)
conf.add(f"MDMessageCmd {self.mcmd} {self.mlog}")
conf.start_md(domains)
Expand Down
15 changes: 9 additions & 6 deletions test/modules/md/test_920_status.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@

import os
import re
import time
from datetime import timedelta

import pytest
from pyhttpd.certs import CertificateSpec

from .md_conf import MDConf
from shutil import copyfile
Expand Down Expand Up @@ -165,13 +166,15 @@ def test_md_920_011(self, env):
domain = self.test_domain
domains = [domain, 'www.%s' % domain]
testpath = os.path.join(env.gen_dir, 'test_920_011')
# cert that is only 10 more days valid
env.create_self_signed_cert(domains, {"notBefore": -70, "notAfter": 20},
serial=920011, path=testpath)
# cert that is only 20 more days valid
creds = env.create_self_signed_cert(CertificateSpec(domains=domains),
valid_from=timedelta(days=-70),
valid_to=timedelta(days=20),
serial=920011)
cert_file = os.path.join(testpath, 'pubcert.pem')
pkey_file = os.path.join(testpath, 'privkey.pem')
assert os.path.exists(cert_file)
assert os.path.exists(pkey_file)
creds.save_cert_pem(cert_file)
creds.save_pkey_pem(pkey_file)
conf = MDConf(env, std_vhosts=False, std_ports=False, text=f"""
MDBaseServer on
MDPortMap http:- https:{env.https_port}
Expand Down
Loading

0 comments on commit 243cac3

Please sign in to comment.