diff options
author | Andre Caron <andre.l.caron@gmail.com> | 2015-05-17 15:08:48 -0400 |
---|---|---|
committer | Andre Caron <andre.l.caron@gmail.com> | 2015-05-17 15:08:48 -0400 |
commit | 6e721a939f6fff70940ff4272e288f17b193e138 (patch) | |
tree | e10d369eabda5e2f737ea6eed9fc7b2bc1c3f728 | |
parent | b0391810fb74bd098592b03ffbb937daeed4561f (diff) | |
download | cryptography-6e721a939f6fff70940ff4272e288f17b193e138.tar.gz cryptography-6e721a939f6fff70940ff4272e288f17b193e138.tar.bz2 cryptography-6e721a939f6fff70940ff4272e288f17b193e138.zip |
Adds support for CSR extensions.
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/x509.py | 32 | ||||
-rw-r--r-- | src/cryptography/x509.py | 6 | ||||
-rw-r--r-- | tests/test_x509.py | 58 |
3 files changed, 96 insertions, 0 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index b36694dd..6db6fc9c 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -657,3 +657,35 @@ class _CertificateSigningRequest(object): raise UnsupportedAlgorithm( "Signature algorithm OID:{0} not recognized".format(oid) ) + + @property + def extensions(self): + extensions = [] + seen_oids = set() + x509_exts = self._backend._lib.X509_REQ_get_extensions(self._x509_req) + extcount = self._backend._lib.sk_X509_EXTENSION_num(x509_exts) + for i in range(0, extcount): + ext = self._backend._lib.sk_X509_EXTENSION_value(x509_exts, i) + assert ext != self._backend._ffi.NULL + crit = self._backend._lib.X509_EXTENSION_get_critical(ext) + critical = crit == 1 + oid = x509.ObjectIdentifier(_obj2txt(self._backend, ext.object)) + if oid in seen_oids: + raise x509.DuplicateExtension( + "Duplicate {0} extension found".format(oid), oid + ) + elif oid == x509.OID_BASIC_CONSTRAINTS: + value = _decode_basic_constraints(self._backend, ext) + elif critical: + raise x509.UnsupportedExtension( + "{0} is not currently supported".format(oid), oid + ) + else: + # Unsupported non-critical extension, silently skipping for now + seen_oids.add(oid) + continue + + seen_oids.add(oid) + extensions.append(x509.Extension(oid, critical, value)) + + return x509.Extensions(extensions) diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 325d6d62..49cc8493 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -1177,3 +1177,9 @@ class CertificateSigningRequest(object): Returns a HashAlgorithm corresponding to the type of the digest signed in the certificate. """ + + @abc.abstractproperty + def extensions(self): + """ + Returns the extensions in the signing request. + """ diff --git a/tests/test_x509.py b/tests/test_x509.py index 8561f1f4..47c1c647 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -395,6 +395,9 @@ class TestRSACertificate(object): x509.NameAttribute(x509.OID_ORGANIZATION_NAME, 'PyCA'), x509.NameAttribute(x509.OID_COMMON_NAME, 'cryptography.io'), ] + extensions = request.extensions + assert isinstance(extensions, x509.Extensions) + assert list(extensions) == [] @pytest.mark.parametrize( "loader_func", @@ -413,6 +416,61 @@ class TestRSACertificate(object): with pytest.raises(UnsupportedAlgorithm): request.signature_hash_algorithm + def test_duplicate_extension(self, backend): + request = _load_cert( + os.path.join( + "x509", "requests", "two_basic_constraints.pem" + ), + x509.load_pem_x509_csr, + backend + ) + with pytest.raises(x509.DuplicateExtension) as exc: + request.extensions + + assert exc.value.oid == x509.OID_BASIC_CONSTRAINTS + + def test_unsupported_critical_extension(self, backend): + request = _load_cert( + os.path.join( + "x509", "requests", "unsupported_extension_critical.pem" + ), + x509.load_pem_x509_csr, + backend + ) + with pytest.raises(x509.UnsupportedExtension) as exc: + request.extensions + + assert exc.value.oid == x509.ObjectIdentifier('1.2.3.4') + + def test_unsupported_extension(self, backend): + request = _load_cert( + os.path.join( + "x509", "requests", "unsupported_extension.pem" + ), + x509.load_pem_x509_csr, + backend + ) + extensions = request.extensions + assert len(extensions) == 0 + + def test_request_basic_constraints(self, backend): + request = _load_cert( + os.path.join( + "x509", "requests", "basic_constraints.pem" + ), + x509.load_pem_x509_csr, + backend + ) + extensions = request.extensions + assert isinstance(extensions, x509.Extensions) + assert list(extensions) == [ + x509.Extension( + x509.OID_BASIC_CONSTRAINTS, + True, + x509.BasicConstraints(True, 1), + ), + ] + @pytest.mark.requires_backend_interface(interface=DSABackend) @pytest.mark.requires_backend_interface(interface=X509Backend) |