diff options
author | Vincent Pelletier <plr.vincent@gmail.com> | 2017-08-12 22:05:00 +0900 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2017-08-12 08:05:00 -0500 |
commit | 6c02ee85bcd68e1e4fc6770421699fbd07c9b3e9 (patch) | |
tree | 5bfb5a0966cd3e00810b0161276e26aac8fdf3bb | |
parent | ca941bd00baa598cb83d91a4e88b4bbcec0fc265 (diff) | |
download | cryptography-6c02ee85bcd68e1e4fc6770421699fbd07c9b3e9.tar.gz cryptography-6c02ee85bcd68e1e4fc6770421699fbd07c9b3e9.tar.bz2 cryptography-6c02ee85bcd68e1e4fc6770421699fbd07c9b3e9.zip |
Add is_signature_valid method on CertificateRevocationList (#3849)
-rw-r--r-- | docs/development/test-vectors.rst | 5 | ||||
-rw-r--r-- | docs/x509/reference.rst | 6 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/x509.py | 16 | ||||
-rw-r--r-- | src/cryptography/x509/base.py | 6 | ||||
-rw-r--r-- | tests/test_x509.py | 41 | ||||
-rw-r--r-- | vectors/cryptography_vectors/x509/custom/invalid_signature.pem | 28 | ||||
-rw-r--r-- | vectors/cryptography_vectors/x509/custom/valid_signature.pem | 28 |
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----- |