aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2015-03-29 09:32:13 -0400
committerAlex Gaynor <alex.gaynor@gmail.com>2015-03-29 09:32:13 -0400
commit43f49de4fb7e878e8ff7bb5c49cef8bbddb65e3f (patch)
tree7e9a78b048ff33ff1712be9aec198da8955eb99a
parent554104d69e00d7afbea3c69f8e956e84bda5f1af (diff)
parentb759e29dfeb889015039041e3d1b74939ab3a53c (diff)
downloadcryptography-43f49de4fb7e878e8ff7bb5c49cef8bbddb65e3f.tar.gz
cryptography-43f49de4fb7e878e8ff7bb5c49cef8bbddb65e3f.tar.bz2
cryptography-43f49de4fb7e878e8ff7bb5c49cef8bbddb65e3f.zip
Merge pull request #1702 from reaperhulk/parse-x509-request
Parse X509 Requests
-rw-r--r--CHANGELOG.rst2
-rw-r--r--docs/hazmat/backends/interfaces.rst9
-rw-r--r--docs/x509.rst147
-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.py16
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py29
-rw-r--r--src/cryptography/hazmat/bindings/openssl/x509.py5
-rw-r--r--src/cryptography/x509.py26
-rw-r--r--tests/hazmat/backends/test_multibackend.py6
-rw-r--r--tests/test_x509.py71
11 files changed, 297 insertions, 29 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index b35dc144..6f02f951 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -18,6 +18,8 @@ Changelog
:class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPrivateKeyWithSerialization`,
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`.
0.8.1 - 2015-03-20
~~~~~~~~~~~~~~~~~~
diff --git a/docs/hazmat/backends/interfaces.rst b/docs/hazmat/backends/interfaces.rst
index 1af8d8f2..8866cf71 100644
--- a/docs/hazmat/backends/interfaces.rst
+++ b/docs/hazmat/backends/interfaces.rst
@@ -509,3 +509,12 @@ A specific ``backend`` may provide one or more of these interfaces.
:param bytes data: DER formatted certificate data.
:returns: An instance of :class:`~cryptography.x509.Certificate`.
+
+ .. method:: load_pem_x509_csr(data)
+
+ .. versionadded:: 0.9
+
+ :param bytes data: PEM formatted certificate signing request data.
+
+ :returns: An instance of
+ :class:`~cryptography.x509.CertificateSigningRequest`.
diff --git a/docs/x509.rst b/docs/x509.rst
index f17c3dae..22b282ce 100644
--- a/docs/x509.rst
+++ b/docs/x509.rst
@@ -3,11 +3,57 @@ X.509
.. currentmodule:: cryptography.x509
+.. testsetup::
+
+ pem_req_data = b"""
+ -----BEGIN CERTIFICATE REQUEST-----
+ MIIC0zCCAbsCAQAwWTELMAkGA1UEBhMCVVMxETAPBgNVBAgMCElsbGlub2lzMRAw
+ DgYDVQQHDAdDaGljYWdvMREwDwYDVQQKDAhyNTA5IExMQzESMBAGA1UEAwwJaGVs
+ bG8uY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqhZx+Mo9VRd9
+ vsnWWa6NBCws21rZ0+1B/JGgB4hDsZS7iDE4Bj5z4idheFRtl8bBbdjPknq7BfoF
+ 8v15Zq/Zv7i2xMSDL+LUrTBZezRd4bRTGqCm6YJ5EYkhqdcqeZleHCFImguHoq1J
+ Fh0+kObQrTHXw3ZP57a3o1IvyIUA3nNoCBL0QQhwBXaDXOojMKNR+bqB5ve8GS1y
+ Elr0AM/+cJsfaIahNQUgFKx3Eu3GeEOMKYOAG1lycgdQdmTUybLrT3U7vkClTseM
+ xHg1r5En7ALjONIhqRuq3rddYahrP8HXozb3zUy3cJ7P6IeaosuvNzvMXOX9P6HD
+ Ha9urDAJ1wIDAQABoDUwMwYJKoZIhvcNAQkOMSYwJDAiBgNVHREEGzAZggl3b3Js
+ ZC5jb22CDHdoYXRldmVyLmNvbTANBgkqhkiG9w0BAQUFAAOCAQEAS4Ro6h+z52SK
+ YSLCYARpnEu/rmh4jdqndt8naqcNb6uLx9mlKZ2W9on9XDjnSdQD9q+ZP5aZfESw
+ R0+rJhW9ZrNa/g1pt6M24ihclHYDAxYMWxT1z/TXXGM3TmZZ6gfYlNE1kkBuODHa
+ UYsR/1Ht1E1EsmmUimt2n+zQR2K8T9Coa+boaUW/GsTEuz1aaJAkj5ZvTDiIhRG4
+ AOCqFZOLAQmCCNgJnnspD9hDz/Ons085LF5wnYjN4/Nsk5tS6AGs3xjZ3jPoOGGn
+ 82WQ9m4dBGoVDZXsobVTaN592JEYwN5iu72zRn7Einb4V4H5y3yD2dD4yWPlt4pk
+ 5wFkeYsZEA==
+ -----END CERTIFICATE REQUEST-----
+ """.strip()
+
+ pem_data = b"""
+ -----BEGIN CERTIFICATE-----
+ MIIDfDCCAmSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEf
+ MB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMVHJ1c3Qg
+ QW5jaG9yMB4XDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFowQDELMAkGA1UE
+ BhMCVVMxHzAdBgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExEDAOBgNVBAMT
+ B0dvb2QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQWJpHYo37
+ Xfb7oJSPe+WvfTlzIG21WQ7MyMbGtK/m8mejCzR6c+f/pJhEH/OcDSMsXq8h5kXa
+ BGqWK+vSwD/Pzp5OYGptXmGPcthDtAwlrafkGOS4GqIJ8+k9XGKs+vQUXJKsOk47
+ RuzD6PZupq4s16xaLVqYbUC26UcY08GpnoLNHJZS/EmXw1ZZ3d4YZjNlpIpWFNHn
+ UGmdiGKXUPX/9H0fVjIAaQwjnGAbpgyCumWgzIwPpX+ElFOUr3z7BoVnFKhIXze+
+ VmQGSWxZxvWDUN90Ul0tLEpLgk3OVxUB4VUGuf15OJOpgo1xibINPmWt14Vda2N9
+ yrNKloJGZNqLAgMBAAGjfDB6MB8GA1UdIwQYMBaAFOR9X9FclYYILAWuvnW2ZafZ
+ XahmMB0GA1UdDgQWBBRYAYQkG7wrUpRKPaUQchRR9a86yTAOBgNVHQ8BAf8EBAMC
+ AQYwFwYDVR0gBBAwDjAMBgpghkgBZQMCATABMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
+ KoZIhvcNAQELBQADggEBADWHlxbmdTXNwBL/llwhQqwnazK7CC2WsXBBqgNPWj7m
+ tvQ+aLG8/50Qc2Sun7o2VnwF9D18UUe8Gj3uPUYH+oSI1vDdyKcjmMbKRU4rk0eo
+ 3UHNDXwqIVc9CQS9smyV+x1HCwL4TTrq+LXLKx/qVij0Yqk+UJfAtrg2jnYKXsCu
+ FMBQQnWCGrwa1g1TphRp/RmYHnMynYFmZrXtzFz+U9XEA7C+gPq4kqDI/iVfIT1s
+ 6lBtdB50lrDVwl2oYfAvW/6sC2se2QleZidUmrziVNP4oEeXINokU6T6p//HM1FG
+ QYw2jOvpKcKtWCSAnegEbgsGYzATKjmPJPJ0npHFqzM=
+ -----END CERTIFICATE-----
+ """.strip()
+
X.509 is an ITU-T standard for a `public key infrastructure`_. X.509v3 is
defined in :rfc:`5280` (which obsoletes :rfc:`2459` and :rfc:`3280`). X.509
certificates are commonly used in protocols like `TLS`_.
-
Loading Certificates
~~~~~~~~~~~~~~~~~~~~
@@ -43,32 +89,6 @@ Loading Certificates
:returns: An instance of :class:`~cryptography.x509.Certificate`.
-.. testsetup::
-
- pem_data = b"""
- -----BEGIN CERTIFICATE-----
- MIIDfDCCAmSgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJVUzEf
- MB0GA1UEChMWVGVzdCBDZXJ0aWZpY2F0ZXMgMjAxMTEVMBMGA1UEAxMMVHJ1c3Qg
- QW5jaG9yMB4XDTEwMDEwMTA4MzAwMFoXDTMwMTIzMTA4MzAwMFowQDELMAkGA1UE
- BhMCVVMxHzAdBgNVBAoTFlRlc3QgQ2VydGlmaWNhdGVzIDIwMTExEDAOBgNVBAMT
- B0dvb2QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCQWJpHYo37
- Xfb7oJSPe+WvfTlzIG21WQ7MyMbGtK/m8mejCzR6c+f/pJhEH/OcDSMsXq8h5kXa
- BGqWK+vSwD/Pzp5OYGptXmGPcthDtAwlrafkGOS4GqIJ8+k9XGKs+vQUXJKsOk47
- RuzD6PZupq4s16xaLVqYbUC26UcY08GpnoLNHJZS/EmXw1ZZ3d4YZjNlpIpWFNHn
- UGmdiGKXUPX/9H0fVjIAaQwjnGAbpgyCumWgzIwPpX+ElFOUr3z7BoVnFKhIXze+
- VmQGSWxZxvWDUN90Ul0tLEpLgk3OVxUB4VUGuf15OJOpgo1xibINPmWt14Vda2N9
- yrNKloJGZNqLAgMBAAGjfDB6MB8GA1UdIwQYMBaAFOR9X9FclYYILAWuvnW2ZafZ
- XahmMB0GA1UdDgQWBBRYAYQkG7wrUpRKPaUQchRR9a86yTAOBgNVHQ8BAf8EBAMC
- AQYwFwYDVR0gBBAwDjAMBgpghkgBZQMCATABMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
- KoZIhvcNAQELBQADggEBADWHlxbmdTXNwBL/llwhQqwnazK7CC2WsXBBqgNPWj7m
- tvQ+aLG8/50Qc2Sun7o2VnwF9D18UUe8Gj3uPUYH+oSI1vDdyKcjmMbKRU4rk0eo
- 3UHNDXwqIVc9CQS9smyV+x1HCwL4TTrq+LXLKx/qVij0Yqk+UJfAtrg2jnYKXsCu
- FMBQQnWCGrwa1g1TphRp/RmYHnMynYFmZrXtzFz+U9XEA7C+gPq4kqDI/iVfIT1s
- 6lBtdB50lrDVwl2oYfAvW/6sC2se2QleZidUmrziVNP4oEeXINokU6T6p//HM1FG
- QYw2jOvpKcKtWCSAnegEbgsGYzATKjmPJPJ0npHFqzM=
- -----END CERTIFICATE-----
- """.strip()
-
.. doctest::
>>> from cryptography import x509
@@ -77,6 +97,36 @@ Loading Certificates
>>> cert.serial
2
+Loading Certificate Signing Requests
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. function:: load_pem_x509_csr(data, backend)
+
+ .. versionadded:: 0.9
+
+ Deserialize a certificate signing request (CSR) from PEM encoded data. PEM
+ requests are base64 decoded and have delimiters that look like
+ ``-----BEGIN CERTIFICATE REQUEST-----``. This format is also known as
+ PKCS#10.
+
+ :param bytes data: The PEM 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
+ >>> from cryptography.hazmat.backends import default_backend
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> csr = x509.load_pem_x509_csr(pem_req_data, default_backend())
+ >>> isinstance(csr.signature_hash_algorithm, hashes.SHA1)
+ True
+
X.509 Certificate Object
~~~~~~~~~~~~~~~~~~~~~~~~
@@ -211,6 +261,49 @@ X.509 Certificate Object
... print(ext)
<Extension(oid=<ObjectIdentifier(oid=2.5.29.19, name=basicConstraints)>, critical=True, value=<BasicConstraints(ca=True, path_length=None)>)>
+X.509 CSR (Certificate Signing Request) Object
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. class:: CertificateSigningRequest
+
+ .. versionadded:: 0.9
+
+ .. method:: public_key()
+
+ :type:
+ :class:`~cryptography.hazmat.primitives.asymmetric.rsa.RSAPublicKey` or
+ :class:`~cryptography.hazmat.primitives.asymmetric.dsa.DSAPublicKey` or
+ :class:`~cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey`
+
+ The public key associated with the request.
+
+ .. doctest::
+
+ >>> from cryptography.hazmat.primitives.asymmetric import rsa
+ >>> public_key = csr.public_key()
+ >>> isinstance(public_key, rsa.RSAPublicKey)
+ True
+
+ .. attribute:: subject
+
+ :type: :class:`Name`
+
+ The :class:`Name` of the subject.
+
+ .. attribute:: signature_hash_algorithm
+
+ :type: :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm`
+
+ Returns the
+ :class:`~cryptography.hazmat.primitives.hashes.HashAlgorithm` which
+ was used in signing this request.
+
+ .. doctest::
+
+ >>> from cryptography.hazmat.primitives import hashes
+ >>> isinstance(csr.signature_hash_algorithm, hashes.SHA1)
+ True
+
.. class:: Name
.. versionadded:: 0.8
diff --git a/src/cryptography/hazmat/backends/interfaces.py b/src/cryptography/hazmat/backends/interfaces.py
index 79808909..354b5141 100644
--- a/src/cryptography/hazmat/backends/interfaces.py
+++ b/src/cryptography/hazmat/backends/interfaces.py
@@ -261,3 +261,9 @@ class X509Backend(object):
"""
Load an X.509 certificate 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 6e378c19..54b044f0 100644
--- a/src/cryptography/hazmat/backends/multibackend.py
+++ b/src/cryptography/hazmat/backends/multibackend.py
@@ -324,3 +324,12 @@ class MultiBackend(object):
"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)
+
+ raise UnsupportedAlgorithm(
+ "This backend does not support X.509.",
+ _Reasons.UNSUPPORTED_X509
+ )
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 60aa4531..6cc3fd91 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -34,7 +34,9 @@ from cryptography.hazmat.backends.openssl.hmac import _HMACContext
from cryptography.hazmat.backends.openssl.rsa import (
_RSAPrivateKey, _RSAPublicKey
)
-from cryptography.hazmat.backends.openssl.x509 import _Certificate
+from cryptography.hazmat.backends.openssl.x509 import (
+ _Certificate, _CertificateSigningRequest
+)
from cryptography.hazmat.bindings.openssl.binding import Binding
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import dsa, ec, rsa
@@ -820,6 +822,18 @@ class Backend(object):
x509 = self._ffi.gc(x509, self._lib.X509_free)
return _Certificate(self, x509)
+ def load_pem_x509_csr(self, data):
+ mem_bio = self._bytes_to_bio(data)
+ x509_req = self._lib.PEM_read_bio_X509_REQ(
+ mem_bio.bio, self._ffi.NULL, self._ffi.NULL, 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/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 1c9cf5cf..2b66c21e 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -216,3 +216,32 @@ class _Certificate(object):
path_length = self._backend._bn_to_int(bn)
return x509.BasicConstraints(ca, path_length)
+
+
+@utils.register_interface(x509.CertificateSigningRequest)
+class _CertificateSigningRequest(object):
+ def __init__(self, backend, x509_req):
+ self._backend = backend
+ self._x509_req = x509_req
+
+ def public_key(self):
+ pkey = self._backend._lib.X509_REQ_get_pubkey(self._x509_req)
+ assert pkey != self._backend._ffi.NULL
+ pkey = self._backend._ffi.gc(pkey, self._backend._lib.EVP_PKEY_free)
+ return self._backend._evp_pkey_to_public_key(pkey)
+
+ @property
+ def subject(self):
+ subject = self._backend._lib.X509_REQ_get_subject_name(self._x509_req)
+ assert subject != self._backend._ffi.NULL
+ return _build_x509_name(self._backend, subject)
+
+ @property
+ def signature_hash_algorithm(self):
+ oid = _obj2txt(self._backend, self._x509_req.sig_alg.algorithm)
+ try:
+ return x509._SIG_OIDS_TO_HASH[oid]
+ except KeyError:
+ raise UnsupportedAlgorithm(
+ "Signature algorithm OID:{0} not recognized".format(oid)
+ )
diff --git a/src/cryptography/hazmat/bindings/openssl/x509.py b/src/cryptography/hazmat/bindings/openssl/x509.py
index 949a936e..e867450b 100644
--- a/src/cryptography/hazmat/bindings/openssl/x509.py
+++ b/src/cryptography/hazmat/bindings/openssl/x509.py
@@ -44,7 +44,10 @@ typedef struct {
typedef ... X509_EXTENSIONS;
-typedef ... X509_REQ;
+typedef struct {
+ X509_ALGOR *sig_alg;
+ ...;
+} X509_REQ;
typedef struct {
ASN1_INTEGER *serialNumber;
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 864736e8..25bbe9ca 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -60,6 +60,10 @@ def load_der_x509_certificate(data, backend):
return backend.load_der_x509_certificate(data)
+def load_pem_x509_csr(data, backend):
+ return backend.load_pem_x509_csr(data)
+
+
class InvalidVersion(Exception):
def __init__(self, msg, parsed_version):
super(InvalidVersion, self).__init__(msg)
@@ -336,3 +340,25 @@ class Certificate(object):
Returns a HashAlgorithm corresponding to the type of the digest signed
in the certificate.
"""
+
+
+@six.add_metaclass(abc.ABCMeta)
+class CertificateSigningRequest(object):
+ @abc.abstractmethod
+ def public_key(self):
+ """
+ Returns the public key
+ """
+
+ @abc.abstractproperty
+ def subject(self):
+ """
+ Returns the subject name object.
+ """
+
+ @abc.abstractproperty
+ def signature_hash_algorithm(self):
+ """
+ Returns a HashAlgorithm corresponding to the type of the digest signed
+ in the certificate.
+ """
diff --git a/tests/hazmat/backends/test_multibackend.py b/tests/hazmat/backends/test_multibackend.py
index 5a8891c4..40305387 100644
--- a/tests/hazmat/backends/test_multibackend.py
+++ b/tests/hazmat/backends/test_multibackend.py
@@ -197,6 +197,9 @@ class DummyX509Backend(object):
def load_der_x509_certificate(self, data):
pass
+ def load_pem_x509_csr(self, data):
+ pass
+
class TestMultiBackend(object):
def test_ciphers(self):
@@ -472,9 +475,12 @@ 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 = MultiBackend([])
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
backend.load_pem_x509_certificate(b"certdata")
with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
backend.load_der_x509_certificate(b"certdata")
+ with raises_unsupported_algorithm(_Reasons.UNSUPPORTED_X509):
+ backend.load_pem_x509_csr(b"reqdata")
diff --git a/tests/test_x509.py b/tests/test_x509.py
index 2a472686..22b93f61 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -340,6 +340,38 @@ 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
+ )
+ assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
+ public_key = request.public_key()
+ assert isinstance(public_key, rsa.RSAPublicKey)
+ subject = request.subject
+ assert isinstance(subject, x509.Name)
+ assert list(subject) == [
+ x509.NameAttribute(x509.OID_COUNTRY_NAME, 'US'),
+ x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, 'Texas'),
+ x509.NameAttribute(x509.OID_LOCALITY_NAME, 'Austin'),
+ x509.NameAttribute(x509.OID_ORGANIZATION_NAME, 'PyCA'),
+ x509.NameAttribute(x509.OID_COMMON_NAME, 'cryptography.io'),
+ ]
+
+ def test_invalid_certificate_request_pem(self, backend):
+ with pytest.raises(ValueError):
+ x509.load_pem_x509_csr(b"notacsr", backend)
+
+ def test_unsupported_signature_hash_algorithm_request(self, backend):
+ request = _load_cert(
+ os.path.join("x509", "requests", "rsa_md4.pem"),
+ x509.load_pem_x509_csr,
+ backend
+ )
+ with pytest.raises(UnsupportedAlgorithm):
+ request.signature_hash_algorithm
+
@pytest.mark.requires_backend_interface(interface=DSABackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)
@@ -392,6 +424,25 @@ 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
+ )
+ assert isinstance(request.signature_hash_algorithm, hashes.SHA1)
+ public_key = request.public_key()
+ assert isinstance(public_key, dsa.DSAPublicKey)
+ subject = request.subject
+ assert isinstance(subject, x509.Name)
+ assert list(subject) == [
+ x509.NameAttribute(x509.OID_COMMON_NAME, 'cryptography.io'),
+ x509.NameAttribute(x509.OID_ORGANIZATION_NAME, 'PyCA'),
+ x509.NameAttribute(x509.OID_COUNTRY_NAME, 'US'),
+ x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, 'Texas'),
+ x509.NameAttribute(x509.OID_LOCALITY_NAME, 'Austin'),
+ ]
+
@pytest.mark.requires_backend_interface(interface=EllipticCurveBackend)
@pytest.mark.requires_backend_interface(interface=X509Backend)
@@ -428,6 +479,26 @@ class TestECDSACertificate(object):
with pytest.raises(NotImplementedError):
cert.public_key()
+ def test_load_ecdsa_certificate_request(self, backend):
+ _skip_curve_unsupported(backend, ec.SECP384R1())
+ request = _load_cert(
+ os.path.join("x509", "requests", "ec_sha256.pem"),
+ x509.load_pem_x509_csr,
+ backend
+ )
+ assert isinstance(request.signature_hash_algorithm, hashes.SHA256)
+ public_key = request.public_key()
+ assert isinstance(public_key, ec.EllipticCurvePublicKey)
+ subject = request.subject
+ assert isinstance(subject, x509.Name)
+ assert list(subject) == [
+ x509.NameAttribute(x509.OID_COMMON_NAME, 'cryptography.io'),
+ x509.NameAttribute(x509.OID_ORGANIZATION_NAME, 'PyCA'),
+ x509.NameAttribute(x509.OID_COUNTRY_NAME, 'US'),
+ x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, 'Texas'),
+ x509.NameAttribute(x509.OID_LOCALITY_NAME, 'Austin'),
+ ]
+
class TestNameAttribute(object):
def test_init_bad_oid(self):