aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--docs/development/test-vectors.rst5
-rw-r--r--docs/x509/reference.rst6
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py16
-rw-r--r--src/cryptography/x509/base.py6
-rw-r--r--tests/test_x509.py41
-rw-r--r--vectors/cryptography_vectors/x509/custom/invalid_signature.pem28
-rw-r--r--vectors/cryptography_vectors/x509/custom/valid_signature.pem28
7 files changed, 130 insertions, 0 deletions
diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst
index eb95a62e..ec6a1d0c 100644
--- a/docs/development/test-vectors.rst
+++ b/docs/development/test-vectors.rst
@@ -369,6 +369,11 @@ Custom X.509 Certificate Revocation List Vectors
* ``crl_ian_aia_aki.pem`` - Contains a CRL with ``IssuerAlternativeName``,
``AuthorityInformationAccess``, ``AuthorityKeyIdentifier`` and ``CRLNumber``
extensions.
+* ``valid_signature.pem`` - Contains a CRL with the public key which was used
+ to generate it.
+* ``invalid_signature.pem`` - Contains a CRL with the last signature byte
+ incremented by 1 to produce an invalid signature, and the public key which
+ was used to generate it.
Hashes
~~~~~~
diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst
index 8b976119..47f76254 100644
--- a/docs/x509/reference.rst
+++ b/docs/x509/reference.rst
@@ -563,6 +563,12 @@ X.509 CRL (Certificate Revocation List) Object
over the network and used as part of a certificate verification
process.
+ .. method:: is_signature_valid(public_key)
+
+ .. versionadded:: 2.1
+
+ Returns True if the CRL signature is correct for given public key,
+ False otherwise.
X.509 Certificate Builder
~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 5bf0438e..9637fc0e 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -17,6 +17,7 @@ from cryptography.hazmat.backends.openssl.decode_asn1 import (
_asn1_string_to_bytes, _decode_x509_name, _obj2txt, _parse_asn1_time
)
from cryptography.hazmat.primitives import hashes, serialization
+from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
@utils.register_interface(x509.Certificate)
@@ -338,6 +339,21 @@ class _CertificateRevocationList(object):
def extensions(self):
return _CRL_EXTENSION_PARSER.parse(self._backend, self._x509_crl)
+ def is_signature_valid(self, public_key):
+ if not isinstance(public_key, (dsa.DSAPublicKey, rsa.RSAPublicKey,
+ ec.EllipticCurvePublicKey)):
+ raise TypeError('Expecting one of DSAPublicKey, RSAPublicKey,'
+ ' or EllipticCurvePublicKey.')
+ res = self._backend._lib.X509_CRL_verify(
+ self._x509_crl, public_key._evp_pkey
+ )
+
+ if res != 1:
+ self._backend._consume_errors()
+ return False
+
+ return True
+
@utils.register_interface(x509.CertificateSigningRequest)
class _CertificateSigningRequest(object):
diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py
index ffa71916..2c96c5bc 100644
--- a/src/cryptography/x509/base.py
+++ b/src/cryptography/x509/base.py
@@ -250,6 +250,12 @@ class CertificateRevocationList(object):
Checks not equal.
"""
+ @abc.abstractmethod
+ def is_signature_valid(self, public_key):
+ """
+ Verifies signature of revocation list against given public key.
+ """
+
@six.add_metaclass(abc.ABCMeta)
class CertificateSigningRequest(object):
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 58d3e546..52854363 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -336,6 +336,47 @@ class TestCertificateRevocationList(object):
with pytest.raises(TypeError):
crl.public_bytes('NotAnEncoding')
+ def test_verify_bad(self, backend):
+ crl = _load_cert(
+ os.path.join("x509", "custom", "invalid_signature.pem"),
+ x509.load_pem_x509_crl,
+ backend
+ )
+ crt = _load_cert(
+ os.path.join("x509", "custom", "invalid_signature.pem"),
+ x509.load_pem_x509_certificate,
+ backend
+ )
+
+ assert not crl.is_signature_valid(crt.public_key())
+
+ def test_verify_good(self, backend):
+ crl = _load_cert(
+ os.path.join("x509", "custom", "valid_signature.pem"),
+ x509.load_pem_x509_crl,
+ backend
+ )
+ crt = _load_cert(
+ os.path.join("x509", "custom", "valid_signature.pem"),
+ x509.load_pem_x509_certificate,
+ backend
+ )
+
+ assert crl.is_signature_valid(crt.public_key())
+
+ def test_verify_argument_must_be_a_public_key(self, backend):
+ crl = _load_cert(
+ os.path.join("x509", "custom", "valid_signature.pem"),
+ x509.load_pem_x509_crl,
+ backend
+ )
+
+ with pytest.raises(TypeError):
+ crl.is_signature_valid("not a public key")
+
+ with pytest.raises(TypeError):
+ crl.is_signature_valid(object)
+
@pytest.mark.requires_backend_interface(interface=X509Backend)
class TestRevokedCertificate(object):
diff --git a/vectors/cryptography_vectors/x509/custom/invalid_signature.pem b/vectors/cryptography_vectors/x509/custom/invalid_signature.pem
new file mode 100644
index 00000000..2fc483d9
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/invalid_signature.pem
@@ -0,0 +1,28 @@
+-----BEGIN X509 CRL-----
+MIIBfTBnAgEBMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNVBAMMGmludmFsaWRfc2ln
+bmF0dXJlIENSTCB0ZXN0Fw0xNzA4MDYwMTQ4MjVaFw0xNzA5MDUwMTQ4MjVaoA4w
+DDAKBgNVHRQEAwIBAzANBgkqhkiG9w0BAQsFAAOCAQEAFgGnFwwqviPvA0bfmnvI
+c6oGIlq9Bmx/vSH6gwLCuGWn2BrKCWCIJNEtK4hrTfQRASb/uywHvhnByAE2lQlY
+9FiefdvXgF5zEah/gV/2A0azvqfvOlPBLzreeoW3Q1fizmip3XN1fXiq8cXBpEYt
+SRTJPzgbHvIu50EB2J0hs+rGo1hPTDtZn/r63hcQzUhIWQVmwP+NOzhpUcdnQj3/
+pn6BAJcxyYO2xDoUIncq586k8XVqshEl9xVwJMKhDDk84m/WQZg8i8szgI/muFsm
+3vilMgIISrTMYeFIZWAy8rYfKLDMlmAtPRXYqyqOdTsLqz2X3RDMRHMXf1Vf8V31
+vA==
+-----END X509 CRL-----
+-----BEGIN CERTIFICATE-----
+MIICxjCCAa4CCQCETsDmKRzISDANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpp
+bnZhbGlkX3NpZ25hdHVyZSBDUkwgdGVzdDAeFw0xNzA4MDYwMTM5MzRaFw0xNzA5
+MDUwMTM5MzRaMCUxIzAhBgNVBAMMGmludmFsaWRfc2lnbmF0dXJlIENSTCB0ZXN0
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwUMEv2zCY/YMUrmuTqF0
+mWvRTB5aU9YQFOT882jTHeFvb4ZKIQDUBz+B6UObGPcdwJv/S1srhcLa4dWEEkVh
+GrFRXzPxZOXS/NbMgqnlxtkP3SjiINmYVSUY4+zXpneM32QXbEoQQoYkHHLiHg4l
+L2hQHGYE47cRFzJ9IqIIFGx5Sh+fAWm40CzCDTaVWd7C4IsamOdYhvflpXJZcKtQ
+ni1vQl5IEunsGP7nHdOcOBSi6LkNj2jGhflPwuOlWEXeqbHxAfd7We6fMPXDjZVR
+TRTa+MHpfA1yCZgpr9NOmu8h115zWx+/pDjsNf9PqNSGgfRTsayT8AYFi5SzfORm
+xQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA0xIWlIp0LmyqAEASHppuDFbKLVlRb
+H1oSQRbWiZpRpBHIdPEtEqp8+2KOQXyZEWzkGwuo46++Zt/aepGOBEbSAljvyJV9
+P4JqH/jJeHkZSC+/CYcegMh14xr6X3OYe+go+huwPSGULYbDguhgzAzpU+0LHWsF
+Q/JCKZOjDutLJekzbvNeUgxkNFtsL1OhWYvSzngAph0OJ0QsDTyUhHv2iigHHv/I
+Y83lNYi6AriqE2L42leHBcvG6Gnc8Ipx+su6r2a/KnHt8XeWXf/OK/HbqKiCG1AV
+Xzp8dgfQjXvDdTLl9yL+jjeOcMdOemY3x2EzQPX1God0rl1pvZFIRYih
+-----END CERTIFICATE-----
diff --git a/vectors/cryptography_vectors/x509/custom/valid_signature.pem b/vectors/cryptography_vectors/x509/custom/valid_signature.pem
new file mode 100644
index 00000000..9c218098
--- /dev/null
+++ b/vectors/cryptography_vectors/x509/custom/valid_signature.pem
@@ -0,0 +1,28 @@
+-----BEGIN X509 CRL-----
+MIIBfTBnAgEBMA0GCSqGSIb3DQEBCwUAMCUxIzAhBgNVBAMMGmludmFsaWRfc2ln
+bmF0dXJlIENSTCB0ZXN0Fw0xNzA4MDYwMTQ4MjVaFw0xNzA5MDUwMTQ4MjVaoA4w
+DDAKBgNVHRQEAwIBAzANBgkqhkiG9w0BAQsFAAOCAQEAFgGnFwwqviPvA0bfmnvI
+c6oGIlq9Bmx/vSH6gwLCuGWn2BrKCWCIJNEtK4hrTfQRASb/uywHvhnByAE2lQlY
+9FiefdvXgF5zEah/gV/2A0azvqfvOlPBLzreeoW3Q1fizmip3XN1fXiq8cXBpEYt
+SRTJPzgbHvIu50EB2J0hs+rGo1hPTDtZn/r63hcQzUhIWQVmwP+NOzhpUcdnQj3/
+pn6BAJcxyYO2xDoUIncq586k8XVqshEl9xVwJMKhDDk84m/WQZg8i8szgI/muFsm
+3vilMgIISrTMYeFIZWAy8rYfKLDMlmAtPRXYqyqOdTsLqz2X3RDMRHMXf1Vf8V31
+ug==
+-----END X509 CRL-----
+-----BEGIN CERTIFICATE-----
+MIICxjCCAa4CCQCETsDmKRzISDANBgkqhkiG9w0BAQsFADAlMSMwIQYDVQQDDBpp
+bnZhbGlkX3NpZ25hdHVyZSBDUkwgdGVzdDAeFw0xNzA4MDYwMTM5MzRaFw0xNzA5
+MDUwMTM5MzRaMCUxIzAhBgNVBAMMGmludmFsaWRfc2lnbmF0dXJlIENSTCB0ZXN0
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwUMEv2zCY/YMUrmuTqF0
+mWvRTB5aU9YQFOT882jTHeFvb4ZKIQDUBz+B6UObGPcdwJv/S1srhcLa4dWEEkVh
+GrFRXzPxZOXS/NbMgqnlxtkP3SjiINmYVSUY4+zXpneM32QXbEoQQoYkHHLiHg4l
+L2hQHGYE47cRFzJ9IqIIFGx5Sh+fAWm40CzCDTaVWd7C4IsamOdYhvflpXJZcKtQ
+ni1vQl5IEunsGP7nHdOcOBSi6LkNj2jGhflPwuOlWEXeqbHxAfd7We6fMPXDjZVR
+TRTa+MHpfA1yCZgpr9NOmu8h115zWx+/pDjsNf9PqNSGgfRTsayT8AYFi5SzfORm
+xQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQA0xIWlIp0LmyqAEASHppuDFbKLVlRb
+H1oSQRbWiZpRpBHIdPEtEqp8+2KOQXyZEWzkGwuo46++Zt/aepGOBEbSAljvyJV9
+P4JqH/jJeHkZSC+/CYcegMh14xr6X3OYe+go+huwPSGULYbDguhgzAzpU+0LHWsF
+Q/JCKZOjDutLJekzbvNeUgxkNFtsL1OhWYvSzngAph0OJ0QsDTyUhHv2iigHHv/I
+Y83lNYi6AriqE2L42leHBcvG6Gnc8Ipx+su6r2a/KnHt8XeWXf/OK/HbqKiCG1AV
+Xzp8dgfQjXvDdTLl9yL+jjeOcMdOemY3x2EzQPX1God0rl1pvZFIRYih
+-----END CERTIFICATE-----