From ceb3076785ff22ac5a8139b94b80780dbd0125d0 Mon Sep 17 00:00:00 2001 From: Joey den Broeder Date: Mon, 25 Mar 2024 20:14:16 +0100 Subject: [PATCH] Remove pyOpenSSL Since we are only using pyOpenSSL to generate certificates, and this functionality is now deprecated... Move functionality to cryptography instead --- requirements-dev.in | 1 - .../test_certificate_authorities.py | 60 +++++++++------ tests/unit/test_runtime_configuration.py | 75 ++++++++++++------- 3 files changed, 86 insertions(+), 50 deletions(-) diff --git a/requirements-dev.in b/requirements-dev.in index 0610bed2c..a13e5eb5b 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -4,7 +4,6 @@ pytest==8.2.2 pytest-timer==1.0.0 pytest-timeout==2.3.1 pylint==3.2.5 -pyopenssl==24.0.0 randomname==0.2.1 requests-mock==1.12.1 ruff==0.5.1 diff --git a/tests/integration/test_certificate_authorities.py b/tests/integration/test_certificate_authorities.py index 379e75a1a..543ee96aa 100644 --- a/tests/integration/test_certificate_authorities.py +++ b/tests/integration/test_certificate_authorities.py @@ -1,7 +1,11 @@ import base64 +from datetime import datetime, timedelta from socket import gethostname -from OpenSSL import crypto +from cryptography import x509 +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.x509.oid import NameOID from tests.integration import basetest @@ -15,28 +19,40 @@ def setUp(self): self.certificate = self._create_self_signed_cert() def _create_self_signed_cert(self): + # Generate a private key + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048, + ) + + # Create a self-signed certificate + subject = issuer = x509.Name([ + x509.NameAttribute(NameOID.COUNTRY_NAME, "NL"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Rotterdam"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "Rotterdam"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mendix"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Mendix"), + x509.NameAttribute(NameOID.COMMON_NAME, gethostname()), + ]) + cert = x509.CertificateBuilder().subject_name( + subject + ).issuer_name( + issuer + ).public_key( + private_key.public_key() + ).serial_number( + 1000 + ).not_valid_before( + datetime.utcnow() + ).not_valid_after( + datetime.utcnow() + timedelta(days=365*10) + ).add_extension( + x509.BasicConstraints(ca=True, path_length=None), critical=True, + ).sign(private_key, hashes.SHA256()) + + cert_pem = cert.public_bytes(serialization.Encoding.PEM) - # Create a key pair - k = crypto.PKey() - k.generate_key(crypto.TYPE_RSA, 1024) - - # Create a self-signed cert - cert = crypto.X509() - cert.get_subject().C = "NL" - cert.get_subject().ST = "Rotterdam" - cert.get_subject().L = "Rotterdam" - cert.get_subject().O = "Mendix" # noqa: E741 - cert.get_subject().OU = "Mendix" - cert.get_subject().CN = gethostname() - cert.set_serial_number(1000) - cert.gmtime_adj_notBefore(0) - cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60) - cert.set_issuer(cert.get_subject()) - cert.set_pubkey(k) - cert.sign(k, "sha1") - - # Return a .PEM certificate - return crypto.dump_certificate(crypto.FILETYPE_PEM, cert) + return cert_pem def test_certificate_authorities(self): self.stage_container( diff --git a/tests/unit/test_runtime_configuration.py b/tests/unit/test_runtime_configuration.py index 5288b4a60..bf8cacd31 100644 --- a/tests/unit/test_runtime_configuration.py +++ b/tests/unit/test_runtime_configuration.py @@ -1,13 +1,19 @@ import base64 import json import os +from datetime import datetime, timedelta from socket import gethostname from unittest import TestCase, mock +from cryptography import x509 +from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives.asymmetric import rsa +from cryptography.hazmat.primitives.serialization import pkcs12 +from cryptography.x509.oid import NameOID + from buildpack import util from buildpack.core import runtime, security from lib.m2ee.version import MXVersion -from OpenSSL import crypto class M2EEMock: @@ -87,34 +93,49 @@ def test_custom_runtime_setting_is_set(self): ) -def _create_self_signed_cert(): - # Create a key pair - k = crypto.PKey() - k.generate_key(crypto.TYPE_RSA, 1024) - - # Create a self-signed cert - cert = crypto.X509() - cert.get_subject().C = "NL" - cert.get_subject().ST = "Rotterdam" - cert.get_subject().L = "Rotterdam" - cert.get_subject().O = "Mendix" # noqa: E741 - cert.get_subject().OU = "Mendix" - cert.get_subject().CN = gethostname() - cert.set_serial_number(1000) - cert.gmtime_adj_notBefore(0) - cert.gmtime_adj_notAfter(10 * 365 * 24 * 60 * 60) - cert.set_issuer(cert.get_subject()) - cert.set_pubkey(k) - cert.sign(k, "sha1") - - # Create a P12 container - p12 = crypto.PKCS12() - p12.set_certificate(cert) - - return p12.export() +class TestClientCertificateConfiguration(TestCase): + def _create_self_signed_cert(): # pylint: disable=no-method-argument + # Generate a private key + private_key = rsa.generate_private_key( + public_exponent=65537, + key_size=2048, + ) + # Create a self-signed certificate + subject = issuer = x509.Name([ + x509.NameAttribute(NameOID.COUNTRY_NAME, "NL"), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, "Rotterdam"), + x509.NameAttribute(NameOID.LOCALITY_NAME, "Rotterdam"), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, "Mendix"), + x509.NameAttribute(NameOID.ORGANIZATIONAL_UNIT_NAME, "Mendix"), + x509.NameAttribute(NameOID.COMMON_NAME, gethostname()), + ]) + cert = x509.CertificateBuilder().subject_name( + subject + ).issuer_name( + issuer + ).public_key( + private_key.public_key() + ).serial_number( + 1000 + ).not_valid_before( + datetime.utcnow() + ).not_valid_after( + datetime.utcnow() + timedelta(days=365*10) + ).add_extension( + x509.BasicConstraints(ca=True, path_length=None), critical=True, + ).sign(private_key, hashes.SHA256()) + + # Serialize private key and certificate to a PKCS12 container + p12 = pkcs12.serialize_key_and_certificates( + name=b"selfsigned", + key=private_key, + cert=cert, + cas=None, + encryption_algorithm=serialization.NoEncryption() + ) -class TestClientCertificateConfiguration(TestCase): + return p12 CERTIFICATE_ENV = { "CLIENT_CERTIFICATES": json.dumps(