aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2015-05-17 13:35:52 -0600
committerPaul Kehrer <paul.l.kehrer@gmail.com>2015-05-17 13:35:52 -0600
commit509bacbd475fce046524015ebb5e400e278c73fb (patch)
treee10d369eabda5e2f737ea6eed9fc7b2bc1c3f728
parentb0391810fb74bd098592b03ffbb937daeed4561f (diff)
parent6e721a939f6fff70940ff4272e288f17b193e138 (diff)
downloadcryptography-509bacbd475fce046524015ebb5e400e278c73fb.tar.gz
cryptography-509bacbd475fce046524015ebb5e400e278c73fb.tar.bz2
cryptography-509bacbd475fce046524015ebb5e400e278c73fb.zip
Merge pull request #1966 from AndreLouisCaron/csr-extensions
Adds support for CSR extensions
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py32
-rw-r--r--src/cryptography/x509.py6
-rw-r--r--tests/test_x509.py58
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)