From 12442a2aca8c4eaa2ebcaf42aef81f5f3b0935bf Mon Sep 17 00:00:00 2001 From: Mads Jensen Date: Fri, 21 Jan 2022 10:29:53 +0100 Subject: [PATCH] Test coverage dns ecdsa (#9174) * Added test coverage for ES256 signing keys in DNS challenges. * pass tests * Feedback --- acme/tests/challenges_test.py | 24 ++++++++++++++++-------- acme/tests/test_util.py | 9 +++++++++ acme/tests/testdata/README | 4 ++++ acme/tests/testdata/ec_secp384r1_key.pem | 6 ++++++ 4 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 acme/tests/testdata/ec_secp384r1_key.pem diff --git a/acme/tests/challenges_test.py b/acme/tests/challenges_test.py index ed8470fa6..d7815a6c3 100644 --- a/acme/tests/challenges_test.py +++ b/acme/tests/challenges_test.py @@ -6,6 +6,7 @@ from unittest import mock import josepy as jose import OpenSSL import requests +from josepy.jwk import JWKEC from acme import errors @@ -401,8 +402,11 @@ class DNSTest(unittest.TestCase): hash(DNS.from_json(self.jmsg)) def test_gen_check_validation(self): - self.assertTrue(self.msg.check_validation( - self.msg.gen_validation(KEY), KEY.public_key())) + ec_key_secp384r1 = JWKEC(key=test_util.load_ecdsa_private_key('ec_secp384r1_key.pem')) + for key, alg in [(KEY, jose.RS256), (ec_key_secp384r1, jose.ES384)]: + with self.subTest(key=key, alg=alg): + self.assertTrue(self.msg.check_validation( + self.msg.gen_validation(key, alg=alg), key.public_key())) def test_gen_check_validation_wrong_key(self): key2 = jose.JWKRSA.load(test_util.load_vector('rsa1024_key.pem')) @@ -423,8 +427,7 @@ class DNSTest(unittest.TestCase): payload=self.msg.update( token=b'x' * 20).json_dumps().encode('utf-8'), alg=jose.RS256, key=KEY) - self.assertFalse(self.msg.check_validation( - bad_validation, KEY.public_key())) + self.assertFalse(self.msg.check_validation(bad_validation, KEY.public_key())) def test_gen_response(self): with mock.patch('acme.challenges.DNS.gen_validation') as mock_gen: @@ -435,8 +438,14 @@ class DNSTest(unittest.TestCase): self.assertEqual(response.validation, mock.sentinel.validation) def test_validation_domain_name(self): - self.assertEqual( - '_acme-challenge.le.wtf', self.msg.validation_domain_name('le.wtf')) + self.assertEqual('_acme-challenge.le.wtf', self.msg.validation_domain_name('le.wtf')) + + def test_validation_domain_name_ecdsa(self): + ec_key_secp384r1 = JWKEC(key=test_util.load_ecdsa_private_key('ec_secp384r1_key.pem')) + self.assertIs(self.msg.check_validation( + self.msg.gen_validation(ec_key_secp384r1, alg=jose.ES384), + ec_key_secp384r1.public_key()), True + ) class DNSResponseTest(unittest.TestCase): @@ -474,8 +483,7 @@ class DNSResponseTest(unittest.TestCase): hash(DNSResponse.from_json(self.jmsg_from)) def test_check_validation(self): - self.assertTrue( - self.msg.check_validation(self.chall, KEY.public_key())) + self.assertTrue(self.msg.check_validation(self.chall, KEY.public_key())) class JWSPayloadRFC8555Compliant(unittest.TestCase): diff --git a/acme/tests/test_util.py b/acme/tests/test_util.py index d4a45272d..efa5a219c 100644 --- a/acme/tests/test_util.py +++ b/acme/tests/test_util.py @@ -10,6 +10,7 @@ from cryptography.hazmat.primitives import serialization import josepy as jose from OpenSSL import crypto import pkg_resources +from josepy.util import ComparableECKey def load_vector(*names): @@ -60,6 +61,14 @@ def load_rsa_private_key(*names): load_vector(*names), password=None, backend=default_backend())) +def load_ecdsa_private_key(*names): + """Load ECDSA private key.""" + loader = _guess_loader(names[-1], serialization.load_pem_private_key, + serialization.load_der_private_key) + return ComparableECKey(loader( + load_vector(*names), password=None, backend=default_backend())) + + def load_pyopenssl_private_key(*names): """Load pyOpenSSL private key.""" loader = _guess_loader( diff --git a/acme/tests/testdata/README b/acme/tests/testdata/README index 9c1a12d80..5a3ca4663 100644 --- a/acme/tests/testdata/README +++ b/acme/tests/testdata/README @@ -15,3 +15,7 @@ and for the certificates: 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 + +and for the elliptic key curves: + + openssl genpkey -algorithm EC -out ec_secp384r1.pem -pkeyopt ec_paramgen_curve:P-384 -pkeyopt ec_param_enc:named_curve diff --git a/acme/tests/testdata/ec_secp384r1_key.pem b/acme/tests/testdata/ec_secp384r1_key.pem new file mode 100644 index 000000000..4bc4e68e5 --- /dev/null +++ b/acme/tests/testdata/ec_secp384r1_key.pem @@ -0,0 +1,6 @@ +-----BEGIN PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDArTn0pbFk3xHfKeXte +xJgS4JVdJQ8mqvezhaNpULZPnwb+mcKLlrj6f5SRM52yREGhZANiAAQcrMoPMVqV +rHnDGGz5HUKLNmXfChlNgsrwsruawXF+M283CA6eckAjTXNyiC/ounWmvtoKsZG0 +2UQOfQUNSCANId/r986yRGc03W6RJSkcRp86qBYjNsLgbZpber/3+M4= +-----END PRIVATE KEY-----