From 1bd77e2f4ee2fcdd9233ea36ed74edeee02817c5 Mon Sep 17 00:00:00 2001 From: Joern Heissler Date: Wed, 13 Jan 2016 22:51:37 +0100 Subject: Add verify method on CertificateSigningRequest --- docs/development/test-vectors.rst | 6 ++++-- docs/x509/reference.rst | 9 +++++++++ src/cryptography/hazmat/backends/openssl/x509.py | 12 +++++++++++- src/cryptography/x509/base.py | 6 ++++++ tests/test_x509.py | 20 +++++++++++++++++++- .../x509/requests/invalid_signature.pem | 10 ++++++++++ 6 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 vectors/cryptography_vectors/x509/requests/invalid_signature.pem diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index ad945f2f..4abf9f63 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -278,7 +278,7 @@ Custom X.509 Request Vectors request using RSA and SHA1 with a subject alternative name extension generated using OpenSSL. * ``two_basic_constraints.pem`` - A certificate signing request - for a RSA 2048 bit key containing two basic constraints extensions. + for an RSA 2048 bit key containing two basic constraints extensions. * ``unsupported_extension.pem`` - A certificate signing request for an RSA 2048 bit key containing containing an unsupported extension type. The OID was encoded as "1.2.3.4" with an @@ -287,9 +287,11 @@ Custom X.509 Request Vectors request for an RSA 2048 bit key containing containing an unsupported extension type marked critical. The OID was encoded as "1.2.3.4" with an ``extnValue`` of "value". -* ``basic_constraints.pem`` - A certificate signing request for a RSA +* ``basic_constraints.pem`` - A certificate signing request for an RSA 2048 bit key containing a basic constraints extension marked as critical. +* ``invalid_signature.pem`` - A certificate signing request for an RSA + 1024 bit key containing an invalid signature with correct padding. Custom X.509 Certificate Revocation List Vectors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 8bb3f40d..568eb405 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -761,6 +761,15 @@ X.509 CSR (Certificate Signing Request) Object key embedded in the CSR). This data may be used to validate the CSR signature. + .. method:: verify() + + .. versionadded:: 1.3 + + :raises cryptography.exceptions.InvalidSignature: If the signature does + not validate. + + Verifies the CSR signature. + X.509 Certificate Revocation List Builder ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index a6f7d69e..18274aa1 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -7,7 +7,7 @@ from __future__ import absolute_import, division, print_function import operator from cryptography import utils, x509 -from cryptography.exceptions import UnsupportedAlgorithm +from cryptography.exceptions import UnsupportedAlgorithm, InvalidSignature from cryptography.hazmat.backends.openssl.decode_asn1 import ( _CERTIFICATE_EXTENSION_PARSER, _CRL_EXTENSION_PARSER, _CSR_EXTENSION_PARSER, _REVOKED_CERTIFICATE_EXTENSION_PARSER, @@ -362,3 +362,13 @@ class _CertificateSigningRequest(object): @property def signature(self): return _asn1_string_to_bytes(self._backend, self._x509_req.signature) + + def verify(self): + pkey = self._backend._lib.X509_REQ_get_pubkey(self._x509_req) + self._backend.openssl_assert(pkey != self._backend._ffi.NULL) + pkey = self._backend._ffi.gc(pkey, self._backend._lib.EVP_PKEY_free) + res = self._backend._lib.X509_REQ_verify(self._x509_req, pkey) + + if res != 1: + self._backend._consume_errors() + raise InvalidSignature diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index 55e965f7..d24070d5 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -288,6 +288,12 @@ class CertificateSigningRequest(object): 2986. """ + @abc.abstractmethod + def verify(self): + """ + Verifies signature of signing request. + """ + @six.add_metaclass(abc.ABCMeta) class RevokedCertificate(object): diff --git a/tests/test_x509.py b/tests/test_x509.py index 6145edb1..fde0755e 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -18,7 +18,7 @@ import pytest import six from cryptography import utils, x509 -from cryptography.exceptions import UnsupportedAlgorithm +from cryptography.exceptions import UnsupportedAlgorithm, InvalidSignature from cryptography.hazmat.backends.interfaces import ( DSABackend, EllipticCurveBackend, RSABackend, X509Backend ) @@ -1241,6 +1241,24 @@ class TestRSACertificateRequest(object): with pytest.raises(TypeError): request.public_bytes('NotAnEncoding') + def test_verify_bad(self, backend): + request = _load_cert( + os.path.join("x509", "requests", "invalid_signature.pem"), + x509.load_pem_x509_csr, + backend + ) + + with pytest.raises(InvalidSignature): + request.verify() + + def test_verify_good(self, backend): + request = _load_cert( + os.path.join("x509", "requests", "rsa_sha256.pem"), + x509.load_pem_x509_csr, + backend + ) + request.verify() + @pytest.mark.parametrize( ("request_path", "loader_func", "encoding"), [ diff --git a/vectors/cryptography_vectors/x509/requests/invalid_signature.pem b/vectors/cryptography_vectors/x509/requests/invalid_signature.pem new file mode 100644 index 00000000..f95bd17a --- /dev/null +++ b/vectors/cryptography_vectors/x509/requests/invalid_signature.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBTjCBuAIBADAPMQ0wCwYDVQQDDAR0ZXN0MIGfMA0GCSqGSIb3DQEBAQUAA4GN +ADCBiQKBgQDOdf0xwr1fUP0+wtYfwi1sqAe78WNSONLjtGYSpEFBNS9T6dW+m3vj +EaEZ0dI7B+Y5jC53JG8vSoBN/xLzw/CCDgLq8OvftOeS4+FZqznRDucgzbqctVzs +PshGcfZ3n8DIiEBbSqeMvs02spKXvYxi3M2S5aJ2GVl2wNlzRLcTuwIDAQABoAAw +DQYJKoZIhvcNAQELBQADgYEAZ7Jbqn9hhMYJ+y4ikTNG6GNu48GINyzXXX3bzv3O ++xGnKbjp99FbJKDOalnG492kZKyg2cCC5UQW8SNZOQpfnjsguB3HZoOrRlExkavY +IapdMZiK5g6ocViceV4gRybkW/Yh3p7cFzOmaABAWzeyJm3/TcTWBLvx/M7Mj1pE +8f8= +-----END CERTIFICATE REQUEST----- -- cgit v1.2.3 From fbda8ce83d8aa774bbd5438dfd98def87585df3b Mon Sep 17 00:00:00 2001 From: Joern Heissler Date: Mon, 18 Jan 2016 00:24:44 +0100 Subject: Change method to property --- docs/x509/reference.rst | 7 ++----- src/cryptography/hazmat/backends/openssl/x509.py | 9 ++++++--- src/cryptography/x509/base.py | 4 ++-- tests/test_x509.py | 12 +++++------- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/docs/x509/reference.rst b/docs/x509/reference.rst index 568eb405..3b14567e 100644 --- a/docs/x509/reference.rst +++ b/docs/x509/reference.rst @@ -761,14 +761,11 @@ X.509 CSR (Certificate Signing Request) Object key embedded in the CSR). This data may be used to validate the CSR signature. - .. method:: verify() + .. attribute:: is_signature_valid .. versionadded:: 1.3 - :raises cryptography.exceptions.InvalidSignature: If the signature does - not validate. - - Verifies the CSR signature. + Returns True if the CSR signature is correct, False otherwise. X.509 Certificate Revocation List Builder ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 18274aa1..c71f8d92 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -7,7 +7,7 @@ from __future__ import absolute_import, division, print_function import operator from cryptography import utils, x509 -from cryptography.exceptions import UnsupportedAlgorithm, InvalidSignature +from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.backends.openssl.decode_asn1 import ( _CERTIFICATE_EXTENSION_PARSER, _CRL_EXTENSION_PARSER, _CSR_EXTENSION_PARSER, _REVOKED_CERTIFICATE_EXTENSION_PARSER, @@ -363,7 +363,8 @@ class _CertificateSigningRequest(object): def signature(self): return _asn1_string_to_bytes(self._backend, self._x509_req.signature) - def verify(self): + @property + def is_signature_valid(self): pkey = self._backend._lib.X509_REQ_get_pubkey(self._x509_req) self._backend.openssl_assert(pkey != self._backend._ffi.NULL) pkey = self._backend._ffi.gc(pkey, self._backend._lib.EVP_PKEY_free) @@ -371,4 +372,6 @@ class _CertificateSigningRequest(object): if res != 1: self._backend._consume_errors() - raise InvalidSignature + return False + + return True diff --git a/src/cryptography/x509/base.py b/src/cryptography/x509/base.py index d24070d5..4a22ed02 100644 --- a/src/cryptography/x509/base.py +++ b/src/cryptography/x509/base.py @@ -288,8 +288,8 @@ class CertificateSigningRequest(object): 2986. """ - @abc.abstractmethod - def verify(self): + @abc.abstractproperty + def is_signature_valid(self): """ Verifies signature of signing request. """ diff --git a/tests/test_x509.py b/tests/test_x509.py index fde0755e..0eef0bc3 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -18,7 +18,7 @@ import pytest import six from cryptography import utils, x509 -from cryptography.exceptions import UnsupportedAlgorithm, InvalidSignature +from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.backends.interfaces import ( DSABackend, EllipticCurveBackend, RSABackend, X509Backend ) @@ -1241,23 +1241,21 @@ class TestRSACertificateRequest(object): with pytest.raises(TypeError): request.public_bytes('NotAnEncoding') - def test_verify_bad(self, backend): + def test_signature_invalid(self, backend): request = _load_cert( os.path.join("x509", "requests", "invalid_signature.pem"), x509.load_pem_x509_csr, backend ) + assert not request.is_signature_valid - with pytest.raises(InvalidSignature): - request.verify() - - def test_verify_good(self, backend): + def test_signature_valid(self, backend): request = _load_cert( os.path.join("x509", "requests", "rsa_sha256.pem"), x509.load_pem_x509_csr, backend ) - request.verify() + assert request.is_signature_valid @pytest.mark.parametrize( ("request_path", "loader_func", "encoding"), -- cgit v1.2.3