diff --git a/acme/acme/challenges.py b/acme/acme/challenges.py index 30983e28f..2f0bf004d 100644 --- a/acme/acme/challenges.py +++ b/acme/acme/challenges.py @@ -1,6 +1,5 @@ """ACME Identifier Validation Challenges.""" import abc -import codecs import functools import hashlib import logging @@ -8,7 +7,7 @@ import socket from cryptography.hazmat.primitives import hashes # type: ignore import josepy as jose -from OpenSSL import crypto +import OpenSSL import requests import six @@ -412,8 +411,8 @@ class TLSSNI01Response(KeyAuthorizationChallengeResponse): """ if key is None: - key = crypto.PKey() - key.generate_key(crypto.TYPE_RSA, bits) + key = OpenSSL.crypto.PKey() + key.generate_key(OpenSSL.crypto.TYPE_RSA, bits) return crypto_util.gen_ss_cert(key, [ # z_domain is too big to fit into CN, hence first dummy domain 'dummy', self.z_domain.decode()], force_san=True), key @@ -508,152 +507,19 @@ class TLSSNI01(KeyAuthorizationChallenge): return self.response(account_key).gen_cert(key=kwargs.get('cert_key')) -@ChallengeResponse.register -class TLSALPN01Response(KeyAuthorizationChallengeResponse): - """ACME tls-alpn-01 challenge response.""" - typ = "tls-alpn-01" - - PORT = 443 - """Verification port as defined by the protocol. - - You can override it (e.g. for testing) by passing ``port`` to - `simple_verify`. - - """ - - ID_PE_ACME_IDENTIFIER_V1 = b"1.3.6.1.5.5.7.1.30.1" - ACME_TLS_1_PROTOCOL = "acme-tls/1" - - @property - def h(self): - """Hash value stored in challenge certificate""" - return hashlib.sha256(self.key_authorization.encode('utf-8')).digest() - - def gen_cert(self, domain, key=None, bits=2048): - """Generate tls-alpn-01 certificate. - - :param unicode domain: Domain verified by the challenge. - :param OpenSSL.crypto.PKey key: Optional private key used in - certificate generation. If not provided (``None``), then - fresh key will be generated. - :param int bits: Number of bits for newly generated key. - - :rtype: `tuple` of `OpenSSL.crypto.X509` and `OpenSSL.crypto.PKey` - - """ - if key is None: - key = crypto.PKey() - key.generate_key(crypto.TYPE_RSA, bits) - - - # Instead of using a ASN.1 encoding library just append the OCTET STRING tag (0x04) - # and the length of the SHA256 hash (0x20) since both of these should never change - der_value = b"DER:0420" + codecs.encode(self.h, 'hex') - acme_extension = crypto.X509Extension(self.ID_PE_ACME_IDENTIFIER_V1, - critical=True, value=der_value) - - return crypto_util.gen_ss_cert(key, [domain], force_san=True, - extensions=[acme_extension]), key - - def probe_cert(self, domain, host=None, port=None): - """Probe tls-alpn-01 challenge certificate. - - :param unicode domain: domain being validated, required. - :param string host: IP address used to probe the certificate. - :param int port: Port used to probe the certificate. - - """ - if host is None: - host = socket.gethostbyname(domain) - logger.debug('%s resolved to %s', domain, host) - if port is None: - port = self.PORT - - return crypto_util.probe_sni(host=host, port=port, name=domain, - alpn_protocols=[self.ACME_TLS_1_PROTOCOL]) - - def verify_cert(self, domain, cert): - """Verify tls-alpn-01 challenge certificate. - - :param unicode domain: Domain name being validated. - :param OpensSSL.crypto.X509 cert: Challenge certificate. - - :returns: Whether the certificate was successfully verified. - :rtype: bool - - """ - # pylint: disable=protected-access - names = crypto_util._pyopenssl_cert_or_req_all_names(cert) - logger.debug('Certificate %s. SANs: %s', cert.digest('sha256'), names) - if len(names) != 1 or names[0].lower() != domain.lower(): - return False - - for i in range(cert.get_extension_count()): - ext = cert.get_extension(i) - # FIXME: assume this is the ACME extension. Currently there is no - # way to get full OID of an unknown extension from pyopenssl. - if ext.get_short_name() == b'UNDEF': - data = ext.get_data() - # Add the ASN.1 tag/length prefix to the hash before comparison - return data == b'\x04\x20' + self.h - - return False - - # pylint: disable=too-many-arguments - def simple_verify(self, chall, domain, account_public_key, - cert=None, host=None, port=None): - """Simple verify. - - Verify ``validation`` using ``account_public_key``, optionally - probe tls-alpn-01 certificate and check using `verify_cert`. - - :param .challenges.TLSALPN01 chall: Corresponding challenge. - :param str domain: Domain name being validated. - :param JWK account_public_key: - :param OpenSSL.crypto.X509 cert: Optional certificate. If not - provided (``None``) certificate will be retrieved using - `probe_cert`. - :param string host: IP address used to probe the certificate. - :param int port: Port used to probe the certificate. - - - :returns: ``True`` iff client's control of the domain has been - verified. - :rtype: bool - - """ - if not self.verify(chall, account_public_key): - logger.debug("Verification of key authorization in response failed") - return False - - if cert is None: - try: - cert = self.probe_cert(domain=domain, host=host, port=port) - except errors.Error as error: - logger.debug(str(error), exc_info=True) - return False - - return self.verify_cert(cert, domain) - - @Challenge.register # pylint: disable=too-many-ancestors class TLSALPN01(KeyAuthorizationChallenge): - """ACME tls-alpn-01 challenge.""" - response_cls = TLSALPN01Response - typ = response_cls.typ + """ACME tls-alpn-01 challenge. + + This class simply allows parsing the TLS-ALPN-01 challenge returned from + the CA. Full TLS-ALPN-01 support is not currently provided. + + """ + typ = "tls-alpn-01" def validation(self, account_key, **kwargs): - """Generate validation. - - :param JWK account_key: - :param OpenSSL.crypto.PKey cert_key: Optional private key used - in certificate generation. If not provided (``None``), then - fresh key will be generated. - - :rtype: `tuple` of `OpenSSL.crypto.X509` and `OpenSSL.crypto.PKey` - - """ - return self.response(account_key).gen_cert(key=kwargs.get('cert_key')) + """Generate validation for the challenge.""" + raise NotImplementedError() @Challenge.register # pylint: disable=too-many-ancestors diff --git a/acme/acme/challenges_test.py b/acme/acme/challenges_test.py index b929d4939..661d25a35 100644 --- a/acme/acme/challenges_test.py +++ b/acme/acme/challenges_test.py @@ -393,91 +393,6 @@ class TLSSNI01Test(unittest.TestCase): mock_gen_cert.assert_called_once_with(key=mock.sentinel.cert_key) -class TLSALPN01ResponseTest(unittest.TestCase): - # pylint: disable=too-many-instance-attributes - - def setUp(self): - from acme.challenges import TLSALPN01 - self.chall = TLSALPN01( - token=jose.b64decode(b'a82d5ff8ef740d12881f6d3c2277ab2e')) - self.domain = u'example.com' - self.domain2 = u'example2.com' - - self.response = self.chall.response(KEY) - self.jmsg = { - 'resource': 'challenge', - 'type': 'tls-alpn-01', - 'keyAuthorization': self.response.key_authorization, - } - - def test_to_partial_json(self): - self.assertEqual(self.jmsg, self.response.to_partial_json()) - - def test_from_json(self): - from acme.challenges import TLSALPN01Response - self.assertEqual(self.response, TLSALPN01Response.from_json(self.jmsg)) - - def test_from_json_hashable(self): - from acme.challenges import TLSALPN01Response - hash(TLSALPN01Response.from_json(self.jmsg)) - - def test_gen_verify_cert(self): - key1 = test_util.load_pyopenssl_private_key('rsa512_key.pem') - cert, key2 = self.response.gen_cert(self.domain, key1) - self.assertEqual(key1, key2) - self.assertTrue(self.response.verify_cert(self.domain, cert)) - - def test_gen_verify_cert_gen_key(self): - cert, key = self.response.gen_cert(self.domain) - self.assertTrue(isinstance(key, OpenSSL.crypto.PKey)) - self.assertTrue(self.response.verify_cert(self.domain, cert)) - - def test_verify_bad_cert(self): - self.assertFalse(self.response.verify_cert(self.domain, - test_util.load_cert('cert.pem'))) - - def test_verify_bad_domain(self): - key1 = test_util.load_pyopenssl_private_key('rsa512_key.pem') - cert, key2 = self.response.gen_cert(self.domain, key1) - self.assertEqual(key1, key2) - self.assertFalse(self.response.verify_cert(self.domain2, cert)) - - def test_simple_verify_bad_key_authorization(self): - key2 = jose.JWKRSA.load(test_util.load_vector('rsa256_key.pem')) - self.response.simple_verify(self.chall, "local", key2.public_key()) - - @mock.patch('acme.challenges.TLSALPN01Response.verify_cert', autospec=True) - def test_simple_verify(self, mock_verify_cert): - mock_verify_cert.return_value = mock.sentinel.verification - self.assertEqual( - mock.sentinel.verification, self.response.simple_verify( - self.chall, self.domain, KEY.public_key(), - cert=mock.sentinel.cert)) - mock_verify_cert.assert_called_once_with( - self.response, mock.sentinel.cert, self.domain) - - @mock.patch('acme.challenges.socket.gethostbyname') - @mock.patch('acme.challenges.crypto_util.probe_sni') - def test_probe_cert(self, mock_probe_sni, mock_gethostbyname): - mock_gethostbyname.return_value = '127.0.0.1' - self.response.probe_cert('foo.com') - mock_gethostbyname.assert_called_once_with('foo.com') - mock_probe_sni.assert_called_once_with( - host='127.0.0.1', port=self.response.PORT, name='foo.com', - alpn_protocols=['acme-tls/1']) - - self.response.probe_cert('foo.com', host='8.8.8.8') - mock_probe_sni.assert_called_with( - host='8.8.8.8', port=mock.ANY, name='foo.com', - alpn_protocols=['acme-tls/1']) - - @mock.patch('acme.challenges.TLSALPN01Response.probe_cert') - def test_simple_verify_false_on_probe_error(self, mock_probe_cert): - mock_probe_cert.side_effect = errors.Error - self.assertFalse(self.response.simple_verify( - self.chall, self.domain, KEY.public_key())) - - class TLSALPN01Test(unittest.TestCase): def setUp(self): @@ -506,12 +421,8 @@ class TLSALPN01Test(unittest.TestCase): self.assertRaises( jose.DeserializationError, TLSALPN01.from_json, self.jmsg) - @mock.patch('acme.challenges.TLSALPN01Response.gen_cert') - def test_validation(self, mock_gen_cert): - mock_gen_cert.return_value = ('cert', 'key') - self.assertEqual(('cert', 'key'), self.msg.validation( - KEY, cert_key=mock.sentinel.cert_key)) - mock_gen_cert.assert_called_once_with(key=mock.sentinel.cert_key) + def test_validation(self): + self.assertRaises(NotImplementedError, self.msg.validation, KEY) class DNSTest(unittest.TestCase): diff --git a/acme/acme/crypto_util.py b/acme/acme/crypto_util.py index d25c2340b..d0e203417 100644 --- a/acme/acme/crypto_util.py +++ b/acme/acme/crypto_util.py @@ -31,15 +31,6 @@ logger = logging.getLogger(__name__) _DEFAULT_TLSSNI01_SSL_METHOD = SSL.SSLv23_METHOD # type: ignore -class _DefaultCertSelection(object): - def __init__(self, certs): - self.certs = certs - - def __call__(self, connection): - server_name = connection.get_servername() - return self.certs.get(server_name, None) - - class SSLSocket(object): # pylint: disable=too-few-public-methods """SSL wrapper for sockets. @@ -47,25 +38,12 @@ class SSLSocket(object): # pylint: disable=too-few-public-methods :ivar dict certs: Mapping from domain names (`bytes`) to `OpenSSL.crypto.X509`. :ivar method: See `OpenSSL.SSL.Context` for allowed values. - :ivar alpn_selection: Hook to select negotiated ALPN protocol for - connection. - :ivar cert_selection: Hook to select certificate for connection. If given, - `certs` parameter would be ignored, and therefore must be empty. """ - def __init__(self, sock, certs=None, - method=_DEFAULT_TLSSNI01_SSL_METHOD, alpn_selection=None, - cert_selection=None): + def __init__(self, sock, certs, method=_DEFAULT_TLSSNI01_SSL_METHOD): self.sock = sock - self.alpn_selection = alpn_selection + self.certs = certs self.method = method - if not cert_selection and not certs: - raise ValueError("Neither cert_selection or certs specified.") - if cert_selection and certs: - raise ValueError("Both cert_selection and certs specified.") - if cert_selection is None: - cert_selection = _DefaultCertSelection(certs) - self.cert_selection = cert_selection def __getattr__(self, name): return getattr(self.sock, name) @@ -82,19 +60,18 @@ class SSLSocket(object): # pylint: disable=too-few-public-methods :type connection: :class:`OpenSSL.Connection` """ - pair = self.cert_selection(connection) - if pair is None: - logger.debug("Certificate selection for server name %s failed, dropping SSL", - connection.get_servername()) + server_name = connection.get_servername() + try: + key, cert = self.certs[server_name] + except KeyError: + logger.debug("Server name (%s) not recognized, dropping SSL", + server_name) return - key, cert = pair new_context = SSL.Context(self.method) new_context.set_options(SSL.OP_NO_SSLv2) new_context.set_options(SSL.OP_NO_SSLv3) new_context.use_privatekey(key) new_context.use_certificate(cert) - if self.alpn_selection is not None: - new_context.set_alpn_select_callback(self.alpn_selection) connection.set_context(new_context) class FakeConnection(object): @@ -119,8 +96,6 @@ class SSLSocket(object): # pylint: disable=too-few-public-methods context.set_options(SSL.OP_NO_SSLv2) context.set_options(SSL.OP_NO_SSLv3) context.set_tlsext_servername_callback(self._pick_certificate_cb) - if self.alpn_selection is not None: - context.set_alpn_select_callback(self.alpn_selection) ssl_sock = self.FakeConnection(SSL.Connection(context, sock)) ssl_sock.set_accept_state() @@ -136,9 +111,8 @@ class SSLSocket(object): # pylint: disable=too-few-public-methods return ssl_sock, addr -def probe_sni(name, host, port=443, timeout=300, # pylint: disable=too-many-arguments - method=_DEFAULT_TLSSNI01_SSL_METHOD, source_address=('', 0), - alpn_protocols=None): +def probe_sni(name, host, port=443, timeout=300, + method=_DEFAULT_TLSSNI01_SSL_METHOD, source_address=('', 0)): """Probe SNI server for SSL certificate. :param bytes name: Byte string to send as the server name in the @@ -150,8 +124,6 @@ def probe_sni(name, host, port=443, timeout=300, # pylint: disable=too-many-argu :param tuple source_address: Enables multi-path probing (selection of source interface). See `socket.creation_connection` for more info. Available only in Python 2.7+. - :param alpn_protocols: Protocols to request using ALPN. - :type alpn_protocols: `list` of `bytes` :raises acme.errors.Error: In case of any problems. @@ -188,8 +160,6 @@ def probe_sni(name, host, port=443, timeout=300, # pylint: disable=too-many-argu client_ssl = SSL.Connection(context, client) client_ssl.set_connect_state() client_ssl.set_tlsext_host_name(name) # pyOpenSSL>=0.13 - if alpn_protocols is not None: - client_ssl.set_alpn_protos(alpn_protocols) try: client_ssl.do_handshake() client_ssl.shutdown() @@ -281,14 +251,12 @@ def _pyopenssl_cert_or_req_san(cert_or_req): def gen_ss_cert(key, domains, not_before=None, - validity=(7 * 24 * 60 * 60), force_san=True, extensions=None): + validity=(7 * 24 * 60 * 60), force_san=True): """Generate new self-signed certificate. :type domains: `list` of `unicode` :param OpenSSL.crypto.PKey key: :param bool force_san: - :param extensions: List of additional extensions to include in the cert. - :type extensions: `list` of `OpenSSL.crypto.X509Extension` 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 @@ -301,13 +269,10 @@ def gen_ss_cert(key, domains, not_before=None, cert.set_serial_number(int(binascii.hexlify(os.urandom(16)), 16)) cert.set_version(2) - if extensions is None: - extensions = [] - - extensions.append( + extensions = [ crypto.X509Extension( b"basicConstraints", True, b"CA:TRUE, pathlen:0"), - ) + ] cert.get_subject().CN = domains[0] # TODO: what to put into cert.get_subject()? diff --git a/acme/acme/crypto_util_test.py b/acme/acme/crypto_util_test.py index b661e4e70..36d62b324 100644 --- a/acme/acme/crypto_util_test.py +++ b/acme/acme/crypto_util_test.py @@ -19,6 +19,7 @@ from acme.magic_typing import List # pylint: disable=unused-import, no-name-in-m class SSLSocketAndProbeSNITest(unittest.TestCase): """Tests for acme.crypto_util.SSLSocket/probe_sni.""" + def setUp(self): self.cert = test_util.load_comparable_cert('rsa2048_cert.pem') key = test_util.load_pyopenssl_private_key('rsa2048_key.pem') @@ -33,8 +34,7 @@ class SSLSocketAndProbeSNITest(unittest.TestCase): # six.moves.* | pylint: disable=attribute-defined-outside-init,no-init def server_bind(self): # pylint: disable=missing-docstring - self.socket = SSLSocket(socket.socket(), - certs) + self.socket = SSLSocket(socket.socket(), certs=certs) socketserver.TCPServer.server_bind(self) self.server = _TestServer(('', 0), socketserver.BaseRequestHandler) @@ -66,18 +66,6 @@ class SSLSocketAndProbeSNITest(unittest.TestCase): # self.assertRaises(errors.Error, self._probe, b'bar') -class SSLSocketTest(unittest.TestCase): - """Tests for acme.crypto_util.SSLSocket.""" - - def test_ssl_socket_invalid_arguments(self): - from acme.crypto_util import SSLSocket - with self.assertRaises(ValueError): - _ = SSLSocket(None, {'sni': ('key', 'cert')}, - cert_selection=lambda _: None) - with self.assertRaises(ValueError): - _ = SSLSocket(None) - - class PyOpenSSLCertOrReqAllNamesTest(unittest.TestCase): """Test for acme.crypto_util._pyopenssl_cert_or_req_all_names.""" diff --git a/acme/acme/standalone.py b/acme/acme/standalone.py index 3bcb0b230..ff9159933 100644 --- a/acme/acme/standalone.py +++ b/acme/acme/standalone.py @@ -43,14 +43,7 @@ class TLSServer(socketserver.TCPServer): def _wrap_sock(self): self.socket = crypto_util.SSLSocket( - self.socket, cert_selection=self._cert_selection, - alpn_selection=getattr(self, '_alpn_selection', None), - method=self.method) - - def _cert_selection(self, connection): - """Callback selecting certificate for connection.""" - server_name = connection.get_servername() - return self.certs.get(server_name, None) + self.socket, certs=self.certs, method=self.method) def server_bind(self): # pylint: disable=missing-docstring self._wrap_sock() @@ -154,45 +147,6 @@ class TLSSNI01DualNetworkedServers(BaseDualNetworkedServers): BaseDualNetworkedServers.__init__(self, TLSSNI01Server, *args, **kwargs) -class BadALPNProtos(Exception): - """Error raised when cannot negotiate ALPN protocol.""" - pass - - -class TLSALPN01Server(TLSServer, ACMEServerMixin): - """TLSALPN01 Server.""" - - ACME_TLS_1_PROTOCOL = b"acme-tls/1" - - def __init__(self, server_address, certs, challenge_certs, ipv6=False): - TLSServer.__init__( - self, server_address, BaseRequestHandlerWithLogging, certs=certs, - ipv6=ipv6) - self.challenge_certs = challenge_certs - - def _cert_selection(self, connection): - # TODO: We would like to serve challenge cert only if asked for it via - # ALPN. To do this, we need to retrieve the list of protos from client - # hello, but this is currently impossible with openssl [0], and ALPN - # negotiation is done after cert selection. - # Therefore, currently we always return challenge cert, and terminate - # handshake in alpn_selection() if ALPN protos are not what we expect. - # [0] https://github.com/openssl/openssl/issues/4952 - server_name = connection.get_servername() - logger.debug("Serving challenge cert for server name %s", server_name) - return self.challenge_certs.get(server_name, None) - - def _alpn_selection(self, _connection, alpn_protos): - """Callback to select alpn protocol.""" - if len(alpn_protos) == 1 and alpn_protos[0] == self.ACME_TLS_1_PROTOCOL: - logger.debug("Agreed on %s ALPN", self.ACME_TLS_1_PROTOCOL) - return self.ACME_TLS_1_PROTOCOL - # Raising an exception causes openssl to terminate handshake and - # send fatal tls alert. - logger.debug("Cannot agree on ALPN proto. Got: %s", str(alpn_protos)) - raise BadALPNProtos("Got: %s" % str(alpn_protos)) - - class BaseRequestHandlerWithLogging(socketserver.BaseRequestHandler): """BaseRequestHandler with logging.""" diff --git a/acme/acme/standalone_test.py b/acme/acme/standalone_test.py index aee592187..1591187e5 100644 --- a/acme/acme/standalone_test.py +++ b/acme/acme/standalone_test.py @@ -10,7 +10,6 @@ import unittest from six.moves import http_client # pylint: disable=import-error from six.moves import socketserver # type: ignore # pylint: disable=import-error -from OpenSSL import SSL # type: ignore # https://github.com/python/typeshed/issues/2052 import josepy as jose import mock import requests @@ -120,62 +119,6 @@ class HTTP01ServerTest(unittest.TestCase): self.assertFalse(self._test_http01(add=False)) -@unittest.skipUnless( - hasattr(SSL.Connection, "set_alpn_protos") and - hasattr(SSL.Context, "set_alpn_select_callback"), - "pyOpenSSL too old") -class TLSALPN01ServerTest(unittest.TestCase): - """Test for acme.standalone.TLSALPN01Server.""" - - def setUp(self): - self.certs = {b'localhost': ( - test_util.load_pyopenssl_private_key('rsa2048_key.pem'), - test_util.load_cert('rsa2048_cert.pem'), - )} - # Use different certificate for challenge. - self.challenge_certs = {b'localhost': ( - test_util.load_pyopenssl_private_key('rsa1024_key.pem'), - test_util.load_cert('rsa1024_cert.pem'), - )} - from acme.standalone import TLSALPN01Server - self.server = TLSALPN01Server(("", 0), certs=self.certs, - challenge_certs=self.challenge_certs) - # pylint: disable=no-member - self.thread = threading.Thread(target=self.server.serve_forever) - self.thread.start() - - def tearDown(self): - self.server.shutdown() # pylint: disable=no-member - self.thread.join() - - #TODO: This is not implemented yet, see comments in standalone.py - #def test_certs(self): - # host, port = self.server.socket.getsockname()[:2] - # cert = crypto_util.probe_sni( - # b'localhost', host=host, port=port, timeout=1) - # # Expect normal cert when connecting without ALPN. - # self.assertEqual(jose.ComparableX509(cert), - # jose.ComparableX509(self.certs[b'localhost'][1])) - - def test_challenge_certs(self): - host, port = self.server.socket.getsockname()[:2] - cert = crypto_util.probe_sni( - b'localhost', host=host, port=port, timeout=1, - alpn_protocols=[b"acme-tls/1"]) - # Expect challenge cert when connecting with ALPN. - self.assertEqual( - jose.ComparableX509(cert), - jose.ComparableX509(self.challenge_certs[b'localhost'][1]) - ) - - def test_bad_alpn(self): - host, port = self.server.socket.getsockname()[:2] - with self.assertRaises(errors.Error): - crypto_util.probe_sni( - b'localhost', host=host, port=port, timeout=1, - alpn_protocols=[b"bad-alpn"]) - - class BaseDualNetworkedServersTest(unittest.TestCase): """Test for acme.standalone.BaseDualNetworkedServers.""" diff --git a/acme/acme/testdata/README b/acme/acme/testdata/README index d65cc3018..dfe3f5405 100644 --- a/acme/acme/testdata/README +++ b/acme/acme/testdata/README @@ -10,8 +10,6 @@ and for the CSR: openssl req -key rsa2048_key.pem -new -subj '/CN=example.com' -outform DER > csr.der -and for the certificates: +and for the certificate: - openssl req -key rsa2048_key.pem -new -subj '/CN=example.com' -x509 -outform DER > cert.der - openssl req -key rsa2048_key.pem -new -subj '/CN=example.com' -x509 > rsa2048_cert.pem - openssl req -key rsa1024_key.pem -new -subj '/CN=example.com' -x509 > rsa1024_cert.pem + openssl req -key rsa2047_key.pem -new -subj '/CN=example.com' -x509 -outform DER > cert.der diff --git a/acme/acme/testdata/rsa1024_cert.pem b/acme/acme/testdata/rsa1024_cert.pem deleted file mode 100644 index 1b7912181..000000000 --- a/acme/acme/testdata/rsa1024_cert.pem +++ /dev/null @@ -1,13 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIB/TCCAWagAwIBAgIJAOyRIBs3QT8QMA0GCSqGSIb3DQEBCwUAMBYxFDASBgNV -BAMMC2V4YW1wbGUuY29tMB4XDTE4MDQyMzEwMzE0NFoXDTE4MDUyMzEwMzE0NFow -FjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ -AoGBAJqJ87R8aVwByONxgQA9hwgvQd/QqI1r1UInXhEF2VnEtZGtUWLi100IpIqr -Mq4qusDwNZ3g8cUPtSkvJGs89djoajMDIJP7lQUEKUYnYrI0q755Tr/DgLWSk7iW -l5ezym0VzWUD0/xXUz8yRbNMTjTac80rS5SZk2ja2wWkYlRJAgMBAAGjUzBRMB0G -A1UdDgQWBBSsaX0IVZ4XXwdeffVAbG7gnxSYjTAfBgNVHSMEGDAWgBSsaX0IVZ4X -XwdeffVAbG7gnxSYjTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4GB -ADe7SVmvGH2nkwVfONk8TauRUDkePN1CJZKFb2zW1uO9ANJ2v5Arm/OQp0BG/xnI -Djw/aLTNVESF89oe15dkrUErtcaF413MC1Ld5lTCaJLHLGqDKY69e02YwRuxW7jY -qarpt7k7aR5FbcfO5r4V/FK/Gvp4Dmoky8uap7SJIW6x ------END CERTIFICATE-----