Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add to_cryptography/from_cryptography on CRL and X509Req #645

Merged
merged 2 commits into from Jun 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Expand Up @@ -32,6 +32,7 @@ Changes:
^^^^^^^^

- Added ``OpenSSL.crypto.X509.from_cryptography`` and ``OpenSSL.crypto.X509.to_cryptography`` for converting X.509 certificate to and from pyca/cryptography objects. `#640 <https://github.com/pyca/pyopenssl/pull/640>`_
- Added ``OpenSSL.crypto.X509Req.from_cryptography``, ``OpenSSL.crypto.X509Req.to_cryptography``, ``OpenSSL.crypto.CRL.from_cryptography``, and ``OpenSSL.crypto.CRL.to_cryptography`` for converting X.509 CSRs and CRLs to and from pyca/cryptography objects. `#645 <https://github.com/pyca/pyopenssl/pull/645>`_
- Added ``OpenSSL.debug`` that allows to get an overview of used library versions (including linked OpenSSL) and other useful runtime information using ``python -m OpenSSL.debug``.
`#620 <https://github.com/pyca/pyopenssl/pull/620>`_

Expand Down
66 changes: 66 additions & 0 deletions src/OpenSSL/crypto.py
Expand Up @@ -830,6 +830,39 @@ def __init__(self):
# Default to version 0.
self.set_version(0)

def to_cryptography(self):
"""
Export as a ``cryptography`` certificate signing request.

:rtype: ``cryptography.x509.CertificateSigningRequest``

.. versionadded:: 17.1.0
"""
from cryptography.hazmat.backends.openssl.x509 import (
_CertificateSigningRequest
)
backend = _get_backend()
return _CertificateSigningRequest(backend, self._req)

@classmethod
def from_cryptography(cls, crypto_req):
"""
Construct based on a ``cryptography`` *crypto_req*.

:param crypto_req: A ``cryptography`` X.509 certificate signing request
:type crypto_req: ``cryptography.x509.CertificateSigningRequest``

:rtype: PKey

.. versionadded:: 17.1.0
"""
if not isinstance(crypto_req, x509.CertificateSigningRequest):
raise TypeError("Must be a certificate signing request")

req = cls()
req._req = crypto_req._x509_req
return req

def set_pubkey(self, pkey):
"""
Set the public key of the certificate signing request.
Expand Down Expand Up @@ -1993,6 +2026,39 @@ def __init__(self):
crl = _lib.X509_CRL_new()
self._crl = _ffi.gc(crl, _lib.X509_CRL_free)

def to_cryptography(self):
"""
Export as a ``cryptography`` CRL.

:rtype: ``cryptography.x509.CertificateRevocationList``

.. versionadded:: 17.1.0
"""
from cryptography.hazmat.backends.openssl.x509 import (
_CertificateRevocationList
)
backend = _get_backend()
return _CertificateRevocationList(backend, self._crl)

@classmethod
def from_cryptography(cls, crypto_crl):
"""
Construct based on a ``cryptography`` *crypto_crl*.

:param crypto_crl: A ``cryptography`` certificate revocation list
:type crypto_crl: ``cryptography.x509.CertificateRevocationList``

:rtype: CRL

.. versionadded:: 17.1.0
"""
if not isinstance(crypto_crl, x509.CertificateRevocationList):
raise TypeError("Must be a certificate revocation list")

crl = cls()
crl._crl = crypto_crl._x509_crl
return crl

def get_revoked(self):
"""
Return the revocations in this certificate revocation list.
Expand Down
32 changes: 32 additions & 0 deletions tests/test_crypto.py
Expand Up @@ -1420,6 +1420,24 @@ def test_verify_success(self):
request.sign(pkey, GOOD_DIGEST)
assert request.verify(pkey)

def test_convert_from_cryptography(self):
crypto_req = x509.load_pem_x509_csr(
cleartextCertificateRequestPEM, backend
)
req = X509Req.from_cryptography(crypto_req)
assert isinstance(req, X509Req)

def test_convert_from_cryptography_unsupported_type(self):
with pytest.raises(TypeError):
X509Req.from_cryptography(object())

def test_convert_to_cryptography_key(self):
req = load_certificate_request(
FILETYPE_PEM, cleartextCertificateRequestPEM
)
crypto_req = req.to_cryptography()
assert isinstance(crypto_req, x509.CertificateSigningRequest)


class TestX509(_PKeyInteractionTestsMixin):
"""
Expand Down Expand Up @@ -3437,6 +3455,20 @@ def test_verify_with_missing_crl(self):
assert err.value.args[0][2] == 'unable to get certificate CRL'
assert err.value.certificate.get_subject().CN == 'intermediate-service'

def test_convert_from_cryptography(self):
crypto_crl = x509.load_pem_x509_crl(crlData, backend)
crl = CRL.from_cryptography(crypto_crl)
assert isinstance(crl, CRL)

def test_convert_from_cryptography_unsupported_type(self):
with pytest.raises(TypeError):
CRL.from_cryptography(object())

def test_convert_to_cryptography_key(self):
crl = load_crl(FILETYPE_PEM, crlData)
crypto_crl = crl.to_cryptography()
assert isinstance(crypto_crl, x509.CertificateRevocationList)


class TestX509StoreContext(object):
"""
Expand Down