aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2015-12-27 15:00:59 -0500
committerAlex Gaynor <alex.gaynor@gmail.com>2015-12-27 15:00:59 -0500
commitb04b67e06ea638e23e06f3fde151a6912c184025 (patch)
treec09c007cd5ae3bb50f58255fc1d15c645b7860df
parentd5d0a3102b609907f2dfadad8e0da10374475697 (diff)
parent9d345312d5ff22cd40d2359dc1765170badf42ea (diff)
downloadcryptography-b04b67e06ea638e23e06f3fde151a6912c184025.tar.gz
cryptography-b04b67e06ea638e23e06f3fde151a6912c184025.tar.bz2
cryptography-b04b67e06ea638e23e06f3fde151a6912c184025.zip
Merge pull request #2593 from reaperhulk/crl-support-ec-dsa
Support EC and DSA signing of CRLs in the OpenSSL backend
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py21
-rw-r--r--tests/hazmat/backends/test_openssl.py37
-rw-r--r--tests/test_x509_crlbuilder.py64
3 files changed, 107 insertions, 15 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 38fe0772..e8b0322e 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -1453,16 +1453,17 @@ class Backend(object):
if not isinstance(algorithm, hashes.HashAlgorithm):
raise TypeError('Algorithm must be a registered hash algorithm.')
- if isinstance(private_key, _DSAPrivateKey):
- raise NotImplementedError(
- "CRL signatures aren't implemented for DSA"
- " keys at this time."
- )
- if isinstance(private_key, _EllipticCurvePrivateKey):
- raise NotImplementedError(
- "CRL signatures aren't implemented for EC"
- " keys at this time."
- )
+ if self._lib.OPENSSL_VERSION_NUMBER <= 0x10001000:
+ if isinstance(private_key, _DSAPrivateKey):
+ raise NotImplementedError(
+ "CRL signatures aren't implemented for DSA"
+ " keys on OpenSSL versions less than 1.0.1."
+ )
+ if isinstance(private_key, _EllipticCurvePrivateKey):
+ raise NotImplementedError(
+ "CRL signatures aren't implemented for EC"
+ " keys on OpenSSL versions less than 1.0.1."
+ )
evp_md = self._lib.EVP_get_digestbyname(
algorithm.name.encode('ascii')
diff --git a/tests/hazmat/backends/test_openssl.py b/tests/hazmat/backends/test_openssl.py
index c0e9d28f..ad2daf7d 100644
--- a/tests/hazmat/backends/test_openssl.py
+++ b/tests/hazmat/backends/test_openssl.py
@@ -558,6 +558,43 @@ class TestOpenSSLSignX509CertificateRevocationList(object):
with pytest.raises(TypeError):
backend.create_x509_crl(object(), private_key, hashes.SHA256())
+ @pytest.mark.skipif(
+ backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000,
+ reason="Requires an older OpenSSL. Must be < 1.0.1"
+ )
+ def test_sign_with_dsa_private_key_is_unsupported(self):
+ private_key = DSA_KEY_2048.private_key(backend)
+ builder = x509.CertificateRevocationListBuilder()
+ builder = builder.issuer_name(
+ x509.Name([x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US')])
+ ).last_update(
+ datetime.datetime(2002, 1, 1, 12, 1)
+ ).next_update(
+ datetime.datetime(2032, 1, 1, 12, 1)
+ )
+
+ with pytest.raises(NotImplementedError):
+ builder.sign(private_key, hashes.SHA1(), backend)
+
+ @pytest.mark.skipif(
+ backend._lib.OPENSSL_VERSION_NUMBER >= 0x10001000,
+ reason="Requires an older OpenSSL. Must be < 1.0.1"
+ )
+ def test_sign_with_ec_private_key_is_unsupported(self):
+ _skip_curve_unsupported(backend, ec.SECP256R1())
+ private_key = ec.generate_private_key(ec.SECP256R1(), backend)
+ builder = x509.CertificateRevocationListBuilder()
+ builder = builder.issuer_name(
+ x509.Name([x509.NameAttribute(x509.NameOID.COUNTRY_NAME, u'US')])
+ ).last_update(
+ datetime.datetime(2002, 1, 1, 12, 1)
+ ).next_update(
+ datetime.datetime(2032, 1, 1, 12, 1)
+ )
+
+ with pytest.raises(NotImplementedError):
+ builder.sign(private_key, hashes.SHA512(), backend)
+
class TestOpenSSLCreateRevokedCertificate(object):
def test_invalid_builder(self):
diff --git a/tests/test_x509_crlbuilder.py b/tests/test_x509_crlbuilder.py
index 763a6472..32a07487 100644
--- a/tests/test_x509_crlbuilder.py
+++ b/tests/test_x509_crlbuilder.py
@@ -308,8 +308,23 @@ class TestCertificateRevocationListBuilder(object):
@pytest.mark.requires_backend_interface(interface=DSABackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)
- def test_sign_dsa_key_unsupported(self, backend):
+ def test_sign_dsa_key(self, backend):
+ if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
+ pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
private_key = DSA_KEY_2048.private_key(backend)
+ invalidity_date = x509.InvalidityDate(
+ datetime.datetime(2002, 1, 1, 0, 0)
+ )
+ ian = x509.IssuerAlternativeName([
+ x509.UniformResourceIdentifier(u"https://cryptography.io"),
+ ])
+ revoked_cert0 = x509.RevokedCertificateBuilder().serial_number(
+ 2
+ ).revocation_date(
+ datetime.datetime(2012, 1, 1, 1, 1)
+ ).add_extension(
+ invalidity_date, False
+ ).build(backend)
last_update = datetime.datetime(2002, 1, 1, 12, 1)
next_update = datetime.datetime(2030, 1, 1, 12, 1)
builder = x509.CertificateRevocationListBuilder().issuer_name(
@@ -320,16 +335,43 @@ class TestCertificateRevocationListBuilder(object):
last_update
).next_update(
next_update
+ ).add_revoked_certificate(
+ revoked_cert0
+ ).add_extension(
+ ian, False
)
- with pytest.raises(NotImplementedError):
- builder.sign(private_key, hashes.SHA256(), backend)
+ crl = builder.sign(private_key, hashes.SHA256(), backend)
+ assert crl.extensions.get_extension_for_class(
+ x509.IssuerAlternativeName
+ ).value == ian
+ assert crl[0].serial_number == revoked_cert0.serial_number
+ assert crl[0].revocation_date == revoked_cert0.revocation_date
+ assert len(crl[0].extensions) == 1
+ ext = crl[0].extensions.get_extension_for_class(x509.InvalidityDate)
+ assert ext.critical is False
+ assert ext.value == invalidity_date
@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)
def test_sign_ec_key_unsupported(self, backend):
+ if backend._lib.OPENSSL_VERSION_NUMBER < 0x10001000:
+ pytest.skip("Requires a newer OpenSSL. Must be >= 1.0.1")
_skip_curve_unsupported(backend, ec.SECP256R1())
private_key = ec.generate_private_key(ec.SECP256R1(), backend)
+ invalidity_date = x509.InvalidityDate(
+ datetime.datetime(2002, 1, 1, 0, 0)
+ )
+ ian = x509.IssuerAlternativeName([
+ x509.UniformResourceIdentifier(u"https://cryptography.io"),
+ ])
+ revoked_cert0 = x509.RevokedCertificateBuilder().serial_number(
+ 2
+ ).revocation_date(
+ datetime.datetime(2012, 1, 1, 1, 1)
+ ).add_extension(
+ invalidity_date, False
+ ).build(backend)
last_update = datetime.datetime(2002, 1, 1, 12, 1)
next_update = datetime.datetime(2030, 1, 1, 12, 1)
builder = x509.CertificateRevocationListBuilder().issuer_name(
@@ -340,10 +382,22 @@ class TestCertificateRevocationListBuilder(object):
last_update
).next_update(
next_update
+ ).add_revoked_certificate(
+ revoked_cert0
+ ).add_extension(
+ ian, False
)
- with pytest.raises(NotImplementedError):
- builder.sign(private_key, hashes.SHA256(), backend)
+ crl = builder.sign(private_key, hashes.SHA256(), backend)
+ assert crl.extensions.get_extension_for_class(
+ x509.IssuerAlternativeName
+ ).value == ian
+ assert crl[0].serial_number == revoked_cert0.serial_number
+ assert crl[0].revocation_date == revoked_cert0.revocation_date
+ assert len(crl[0].extensions) == 1
+ ext = crl[0].extensions.get_extension_for_class(x509.InvalidityDate)
+ assert ext.critical is False
+ assert ext.value == invalidity_date
@pytest.mark.requires_backend_interface(interface=RSABackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)