deprecate make_self_signed_cert (#10466)

with https://github.com/certbot/certbot/pull/10465,
make_self_signed_cert is no longer used outside of our tests so let's
move it there and remove it from our public API
This commit is contained in:
Brad Warren
2025-09-30 07:16:03 -07:00
committed by GitHub
parent 513190afe0
commit 33890ab7f3
5 changed files with 70 additions and 15 deletions
@@ -112,21 +112,24 @@ class GenMakeSelfSignedCertTest(unittest.TestCase):
self.serial_num: list[int] = []
self.privkey = rsa.generate_private_key(public_exponent=65537, key_size=2048)
def test_sn_collisions(self):
@classmethod
def _call(cls, *args, **kwargs):
from acme.crypto_util import make_self_signed_cert
with pytest.warns(DeprecationWarning, match='make_self_signed_cert is deprecated'):
return make_self_signed_cert(*args, **kwargs)
def test_sn_collisions(self):
for _ in range(self.cert_count):
cert = make_self_signed_cert(self.privkey, ['dummy'], force_san=True,
ips=[ipaddress.ip_address("10.10.10.10")])
cert = self._call(self.privkey, ['dummy'], force_san=True,
ips=[ipaddress.ip_address("10.10.10.10")])
self.serial_num.append(cert.serial_number)
assert len(set(self.serial_num)) >= self.cert_count
def test_no_ips(self):
from acme.crypto_util import make_self_signed_cert
make_self_signed_cert(self.privkey, ['dummy'])
self._call(self.privkey, ['dummy'])
@mock.patch("acme.crypto_util._now")
def test_expiry_times(self, mock_now):
from acme.crypto_util import make_self_signed_cert
from datetime import datetime, timedelta, timezone
not_before = 1736200830
validity = 100
@@ -134,7 +137,7 @@ class GenMakeSelfSignedCertTest(unittest.TestCase):
not_before_dt = datetime.fromtimestamp(not_before)
validity_td = timedelta(validity)
not_after_dt = not_before_dt + validity_td
cert = make_self_signed_cert(
cert = self._call(
self.privkey,
['dummy'],
not_before=not_before_dt,
@@ -155,7 +158,7 @@ class GenMakeSelfSignedCertTest(unittest.TestCase):
now_dt = datetime.fromtimestamp(now)
mock_now.return_value = now_dt.replace(tzinfo=timezone.utc)
valid_after_now_dt = now_dt + validity_td
cert = make_self_signed_cert(
cert = self._call(
self.privkey,
['dummy'],
validity=validity_td,
@@ -169,20 +172,18 @@ class GenMakeSelfSignedCertTest(unittest.TestCase):
self.assertEqual(cert.not_valid_after, valid_after_now_dt)
def test_no_name(self):
from acme.crypto_util import make_self_signed_cert
with pytest.raises(AssertionError):
make_self_signed_cert(self.privkey, ips=[ipaddress.ip_address("1.1.1.1")])
make_self_signed_cert(self.privkey)
self._call(self.privkey, ips=[ipaddress.ip_address("1.1.1.1")])
self._call(self.privkey)
def test_extensions(self):
from acme.crypto_util import make_self_signed_cert
extension_type = x509.TLSFeature([x509.TLSFeatureType.status_request])
extension = x509.Extension(
x509.TLSFeature.oid,
False,
extension_type
)
cert = make_self_signed_cert(
cert = self._call(
self.privkey,
ips=[ipaddress.ip_address("1.1.1.1")],
extensions=[extension]
+3
View File
@@ -7,6 +7,7 @@ import typing
from typing import Literal
from typing import Optional
from typing import Union
import warnings
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
@@ -202,6 +203,8 @@ def make_self_signed_cert(private_key: types.CertificateIssuerPrivateKeyTypes,
subject CN. If only one domain is provided no ``subjectAltName``
extension is used, unless `force_san` is ``True``.
"""
warnings.warn("make_self_signed_cert is deprecated and will be removed in "
"an upcoming release", DeprecationWarning)
assert domains or ips, "Must provide one or more hostnames or IPs for the cert."
builder = x509.CertificateBuilder()
@@ -18,7 +18,6 @@ from cryptography.hazmat.primitives import serialization
from urllib3.util import connection
from acme import challenges
from acme import crypto_util
from acme import messages
from certbot import achallenges
from certbot import errors as le_errors
@@ -143,7 +142,7 @@ def test_installer(args: argparse.Namespace, plugin: common.Proxy, config: str,
def test_deploy_cert(plugin: common.Proxy, temp_dir: str, domains: list[str]) -> bool:
"""Tests deploy_cert returning True if the tests are successful"""
cert = crypto_util.make_self_signed_cert(util.KEY, domains)
cert = util.make_self_signed_cert(util.KEY, domains)
cert_path = os.path.join(temp_dir, "cert.pem")
with open(cert_path, "wb") as f:
f.write(cert.public_bytes(serialization.Encoding.PEM))
@@ -1,11 +1,15 @@
"""Utility functions for Certbot plugin tests."""
import argparse
import copy
from datetime import datetime, timedelta, timezone
import os
import re
import shutil
import tarfile
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import types
import josepy as jose
from certbot._internal import constants
@@ -49,3 +53,50 @@ def extract_configs(configs: str, parent_dir: str) -> str:
raise errors.Error("Unknown configurations file type")
return config_dir
def make_self_signed_cert(private_key: types.CertificateIssuerPrivateKeyTypes,
domains: list[str],
) -> x509.Certificate:
"""Generate new self-signed certificate.
:param buffer private_key_pem: Private key, in PEM PKCS#8 format.
:type domains: `list` of `str`
:param buffer private_key_pem: One of
`cryptography.hazmat.primitives.asymmetric.types.CertificateIssuerPrivateKeyTypes`
If more than one domain is provided, all of the domains are put into
``subjectAltName`` X.509 extension and first domain is set as the
subject CN. If only one domain is provided no ``subjectAltName``
extension is used.
"""
assert domains, "Must provide one or more hostnames for the cert."
builder = x509.CertificateBuilder()
builder = builder.serial_number(x509.random_serial_number())
builder = builder.add_extension(x509.BasicConstraints(ca=True, path_length=0), critical=True)
name_attrs = [x509.NameAttribute(x509.OID_COMMON_NAME, domains[0])]
builder = builder.subject_name(x509.Name(name_attrs))
builder = builder.issuer_name(x509.Name(name_attrs))
sanlist: list[x509.GeneralName] = []
for address in domains:
sanlist.append(x509.DNSName(address))
if len(domains) > 1:
builder = builder.add_extension(
x509.SubjectAlternativeName(sanlist),
critical=False
)
not_before = datetime.now(tz=timezone.utc)
validity = timedelta(seconds=7 * 24 * 60 * 60)
builder = builder.not_valid_before(not_before)
builder = builder.not_valid_after(not_before + validity)
public_key = private_key.public_key()
builder = builder.public_key(public_key)
return builder.sign(private_key, hashes.SHA256())
+1
View File
@@ -0,0 +1 @@
The function `acme.crypto_util.make_self_signed_cert` was deprecated and will be removed in a future release.