mirror of
https://github.com/certbot/certbot.git
synced 2026-07-27 08:09:10 +02:00
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:
@@ -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]
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
The function `acme.crypto_util.make_self_signed_cert` was deprecated and will be removed in a future release.
|
||||
Reference in New Issue
Block a user