aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.rst3
-rw-r--r--docs/x509.rst16
-rw-r--r--src/cryptography/hazmat/backends/interfaces.py6
-rw-r--r--src/cryptography/hazmat/backends/multibackend.py9
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py10
-rw-r--r--src/cryptography/x509.py4
-rw-r--r--tests/hazmat/backends/test_multibackend.py6
-rw-r--r--tests/test_x509.py71
8 files changed, 104 insertions, 21 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 2d705b18..b520e48e 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -23,7 +23,8 @@ Changelog
and
:class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePrivateKeyWithSerialization`.
* Add support for parsing X.509 certificate signing requests (CSRs) with
- :func:`~cryptography.x509.load_pem_x509_csr`.
+ :func:`~cryptography.x509.load_pem_x509_csr` and
+ :func:`~cryptography.x509.load_der_x509_csr`.
0.8.1 - 2015-03-20
~~~~~~~~~~~~~~~~~~
diff --git a/docs/x509.rst b/docs/x509.rst
index 22b282ce..dbfb441b 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -118,6 +118,22 @@ Loading Certificate Signing Requests
:returns: An instance of
:class:`~cryptography.x509.CertificateSigningRequest`.
+.. function:: load_der_x509_csr(data, backend)
+
+ .. versionadded:: 0.9
+
+ Deserialize a certificate signing request (CSR) from DER encoded data. DER
+ is a binary format and is not commonly used with CSRs.
+
+ :param bytes data: The DER encoded request data.
+
+ :param backend: A backend supporting the
+ :class:`~cryptography.hazmat.backends.interfaces.X509Backend`
+ interface.
+
+ :returns: An instance of
+ :class:`~cryptography.x509.CertificateSigningRequest`.
+
.. doctest::
>>> from cryptography import x509
diff --git a/src/cryptography/hazmat/backends/interfaces.py b/src/cryptography/hazmat/backends/interfaces.py
index 354b5141..5224f5c7 100644
--- a/src/cryptography/hazmat/backends/interfaces.py
+++ b/src/cryptography/hazmat/backends/interfaces.py
@@ -263,6 +263,12 @@ class X509Backend(object):
"""
@abc.abstractmethod
+ def load_der_x509_csr(self, data):
+ """
+ Load an X.509 CSR from DER encoded data.
+ """
+
+ @abc.abstractmethod
def load_pem_x509_csr(self, data):
"""
Load an X.509 CSR from PEM encoded data.
diff --git a/src/cryptography/hazmat/backends/multibackend.py b/src/cryptography/hazmat/backends/multibackend.py
index 54b044f0..784ab84d 100644
--- a/src/cryptography/hazmat/backends/multibackend.py
+++ b/src/cryptography/hazmat/backends/multibackend.py
@@ -325,6 +325,15 @@ class MultiBackend(object):
_Reasons.UNSUPPORTED_X509
)
+ def load_der_x509_csr(self, data):
+ for b in self._filtered_backends(X509Backend):
+ return b.load_der_x509_csr(data)
+
+ raise UnsupportedAlgorithm(
+ "This backend does not support X.509.",
+ _Reasons.UNSUPPORTED_X509
+ )
+
def load_pem_x509_csr(self, data):
for b in self._filtered_backends(X509Backend):
return b.load_pem_x509_csr(data)
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 854219f7..665771a8 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -834,6 +834,16 @@ class Backend(object):
x509_req = self._ffi.gc(x509_req, self._lib.X509_REQ_free)
return _CertificateSigningRequest(self, x509_req)
+ def load_der_x509_csr(self, data):
+ mem_bio = self._bytes_to_bio(data)
+ x509_req = self._lib.d2i_X509_REQ_bio(mem_bio.bio, self._ffi.NULL)
+ if x509_req == self._ffi.NULL:
+ self._consume_errors()
+ raise ValueError("Unable to load request")
+
+ x509_req = self._ffi.gc(x509_req, self._lib.X509_REQ_free)
+ return _CertificateSigningRequest(self, x509_req)
+
def _load_key(self, openssl_read_func, convert_func, data, password):
mem_bio = self._bytes_to_bio(data)
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 25bbe9ca..113c35e0 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -64,6 +64,10 @@ def load_pem_x509_csr(data, backend):
return backend.load_pem_x509_csr(data)
+def load_der_x509_csr(data, backend):
+ return backend.load_der_x509_csr(data)
+
+
class InvalidVersion(Exception):
def __init__(self, msg, parsed_version):
super(InvalidVersion, self).__init__(msg)
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index 40305387..5871e6c8 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -200,6 +200,9 @@ class DummyX509Backend(object):
def load_pem_x509_csr(self, data):
pass
+ def load_der_x509_csr(self, data):
+ pass
+
class TestMultiBackend(object):
def test_ciphers(self):
@@ -476,6 +479,7 @@ class TestMultiBackend(object):
backend.load_pem_x509_certificate(b"certdata")
backend.load_der_x509_certificate(b"certdata")
backend.load_pem_x509_csr(b"reqdata")
+ backend.load_der_x509_csr(b"reqdata")
backend = MultiBackend([])
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
@@ -484,3 +488,5 @@ class TestMultiBackend(object):
backend.load_der_x509_certificate(b"certdata")
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
backend.load_pem_x509_csr(b"reqdata")
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
+ backend.load_der_x509_csr(b"reqdata")
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 22b93f61..dc148d9d 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -340,12 +340,21 @@ class TestRSACertificate(object):
with pytest.raises(UnsupportedAlgorithm):
cert.signature_hash_algorithm
- def test_load_rsa_certificate_request(self, backend):
- request = _load_cert(
- os.path.join("x509", "requests", "rsa_sha1.pem"),
- x509.load_pem_x509_csr,
- backend
- )
+ @pytest.mark.parametrize(
+ ("path", "loader_func"),
+ [
+ [
+ os.path.join("x509", "requests", "rsa_sha1.pem"),
+ x509.load_pem_x509_csr
+ ],
+ [
+ os.path.join("x509", "requests", "rsa_sha1.der"),
+ x509.load_der_x509_csr
+ ],
+ ]
+ )
+ def test_load_rsa_certificate_request(self, path, loader_func, backend):
+ request = _load_cert(path, loader_func, backend)
assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
public_key = request.public_key()
assert isinstance(public_key, rsa.RSAPublicKey)
@@ -359,9 +368,13 @@ class TestRSACertificate(object):
x509.NameAttribute(x509.OID_COMMON_NAME, 'cryptography.io'),
]
- def test_invalid_certificate_request_pem(self, backend):
+ @pytest.mark.parametrize(
+ "loader_func",
+ [x509.load_pem_x509_csr, x509.load_der_x509_csr]
+ )
+ def test_invalid_certificate_request(self, loader_func, backend):
with pytest.raises(ValueError):
- x509.load_pem_x509_csr(b"notacsr", backend)
+ loader_func(b"notacsr", backend)
def test_unsupported_signature_hash_algorithm_request(self, backend):
request = _load_cert(
@@ -424,12 +437,21 @@ class TestDSACertificate(object):
"822ff5d234e073b901cf5941f58e1f538e71d40d", 16
)
- def test_load_dsa_request(self, backend):
- request = _load_cert(
- os.path.join("x509", "requests", "dsa_sha1.pem"),
- x509.load_pem_x509_csr,
- backend
- )
+ @pytest.mark.parametrize(
+ ("path", "loader_func"),
+ [
+ [
+ os.path.join("x509", "requests", "dsa_sha1.pem"),
+ x509.load_pem_x509_csr
+ ],
+ [
+ os.path.join("x509", "requests", "dsa_sha1.der"),
+ x509.load_der_x509_csr
+ ],
+ ]
+ )
+ def test_load_dsa_request(self, path, loader_func, backend):
+ request = _load_cert(path, loader_func, backend)
assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
public_key = request.public_key()
assert isinstance(public_key, dsa.DSAPublicKey)
@@ -479,13 +501,22 @@ class TestECDSACertificate(object):
with pytest.raises(NotImplementedError):
cert.public_key()
- def test_load_ecdsa_certificate_request(self, backend):
+ @pytest.mark.parametrize(
+ ("path", "loader_func"),
+ [
+ [
+ os.path.join("x509", "requests", "ec_sha256.pem"),
+ x509.load_pem_x509_csr
+ ],
+ [
+ os.path.join("x509", "requests", "ec_sha256.der"),
+ x509.load_der_x509_csr
+ ],
+ ]
+ )
+ def test_load_ecdsa_certificate_request(self, path, loader_func, backend):
_skip_curve_unsupported(backend, ec.SECP384R1())
- request = _load_cert(
- os.path.join("x509", "requests", "ec_sha256.pem"),
- x509.load_pem_x509_csr,
- backend
- )
+ request = _load_cert(path, loader_func, backend)
assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
public_key = request.public_key()
assert isinstance(public_key, ec.EllipticCurvePublicKey)