Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ The third digit is only for regressions.
Backward-incompatible changes:
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

- Removed deprecated ``OpenSSL.crypto.X509Req``, ``OpenSSL.crypto.dump_certificate_request``, and ``OpenSSL.crypto.load_certificate_request``. ``cryptography.x509`` should be used instead.
- ``OpenSSL.SSL.Connection.set_session`` now raises ``ValueError`` if the ``Session`` was obtained from a ``Connection`` that was using a different ``Context`` than this one. OpenSSL requires (but does not verify) that sessions only be re-used with a compatible ``SSL_CTX``, so this contract is now enforced.

Deprecations:
Expand Down
19 changes: 1 addition & 18 deletions doc/api/crypto.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

`pyca/cryptography`_ is likely a better choice than using this module.
It contains a complete set of cryptographic primitives as well as a significantly better and more powerful X509 API.
If necessary you can convert to and from cryptography objects using the ``to_cryptography`` and ``from_cryptography`` methods on ``X509``, ``X509Req``, ``CRL``, and ``PKey``.
If necessary you can convert to and from cryptography objects using the ``to_cryptography`` and ``from_cryptography`` methods on ``X509``, ``CRL``, and ``PKey``.


Elliptic curves
Expand Down Expand Up @@ -42,13 +42,6 @@ Certificates

.. autofunction:: load_certificate

Certificate signing requests
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. autofunction:: dump_certificate_request

.. autofunction:: load_certificate_request

Private keys
~~~~~~~~~~~~

Expand Down Expand Up @@ -82,16 +75,6 @@ X509Name objects
:special-members:
:exclude-members: __repr__, __getattr__, __weakref__

.. _openssl-x509req:

X509Req objects
---------------

.. autoclass:: X509Req
:members:
:special-members:
:exclude-members: __weakref__

.. _openssl-x509store:

X509Store objects
Expand Down
270 changes: 0 additions & 270 deletions src/OpenSSL/crypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,16 @@ def deprecated(msg: str, **kwargs: object) -> Callable[[_T], _T]:
"Error",
"PKey",
"X509Name",
"X509Req",
"X509Store",
"X509StoreContext",
"X509StoreContextError",
"X509StoreFlags",
"dump_certificate",
"dump_certificate_request",
"dump_privatekey",
"dump_publickey",
"get_elliptic_curve",
"get_elliptic_curves",
"load_certificate",
"load_certificate_request",
"load_privatekey",
"load_publickey",
]
Expand Down Expand Up @@ -782,181 +779,6 @@ def get_components(self) -> list[tuple[bytes, bytes]]:
return result


@deprecated(
"CSR support in pyOpenSSL is deprecated. You should use the APIs "
"in cryptography."
)
class X509Req:
"""
An X.509 certificate signing requests.

.. deprecated:: 24.2.0
Use `cryptography.x509.CertificateSigningRequest` instead.
"""

def __init__(self) -> None:
req = _lib.X509_REQ_new()
self._req = _ffi.gc(req, _lib.X509_REQ_free)
# Default to version 0.
self.set_version(0)

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

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

.. versionadded:: 17.1.0
"""
from cryptography.x509 import load_der_x509_csr

der = _dump_certificate_request_internal(FILETYPE_ASN1, self)

return load_der_x509_csr(der)

@classmethod
def from_cryptography(
cls, crypto_req: x509.CertificateSigningRequest
) -> X509Req:
"""
Construct based on a ``cryptography`` *crypto_req*.

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

:rtype: X509Req

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

from cryptography.hazmat.primitives.serialization import Encoding

der = crypto_req.public_bytes(Encoding.DER)
return _load_certificate_request_internal(FILETYPE_ASN1, der)

def set_pubkey(self, pkey: PKey) -> None:
"""
Set the public key of the certificate signing request.

:param pkey: The public key to use.
:type pkey: :py:class:`PKey`

:return: ``None``
"""
set_result = _lib.X509_REQ_set_pubkey(self._req, pkey._pkey)
_openssl_assert(set_result == 1)

def get_pubkey(self) -> PKey:
"""
Get the public key of the certificate signing request.

:return: The public key.
:rtype: :py:class:`PKey`
"""
pkey = PKey.__new__(PKey)
pkey._pkey = _lib.X509_REQ_get_pubkey(self._req)
_openssl_assert(pkey._pkey != _ffi.NULL)
pkey._pkey = _ffi.gc(pkey._pkey, _lib.EVP_PKEY_free)
pkey._only_public = True
return pkey

def set_version(self, version: int) -> None:
"""
Set the version subfield (RFC 2986, section 4.1) of the certificate
request.

:param int version: The version number.
:return: ``None``
"""
if not isinstance(version, int):
raise TypeError("version must be an int")
if version != 0:
raise ValueError(
"Invalid version. The only valid version for X509Req is 0."
)
set_result = _lib.X509_REQ_set_version(self._req, version)
_openssl_assert(set_result == 1)

def get_version(self) -> int:
"""
Get the version subfield (RFC 2459, section 4.1.2.1) of the certificate
request.

:return: The value of the version subfield.
:rtype: :py:class:`int`
"""
return _lib.X509_REQ_get_version(self._req)

def get_subject(self) -> X509Name:
"""
Return the subject of this certificate signing request.

This creates a new :class:`X509Name` that wraps the underlying subject
name field on the certificate signing request. Modifying it will modify
the underlying signing request, and will have the effect of modifying
any other :class:`X509Name` that refers to this subject.

:return: The subject of this certificate signing request.
:rtype: :class:`X509Name`
"""
name = X509Name.__new__(X509Name)
name._name = _lib.X509_REQ_get_subject_name(self._req)
_openssl_assert(name._name != _ffi.NULL)

# The name is owned by the X509Req structure. As long as the X509Name
# Python object is alive, keep the X509Req Python object alive.
name._owner = self

return name

def sign(self, pkey: PKey, digest: str) -> None:
"""
Sign the certificate signing request with this key and digest type.

:param pkey: The key pair to sign with.
:type pkey: :py:class:`PKey`
:param digest: The name of the message digest to use for the signature,
e.g. :py:data:`"sha256"`.
:type digest: :py:class:`str`
:return: ``None``
"""
if pkey._only_public:
raise ValueError("Key has only public part")

if not pkey._initialized:
raise ValueError("Key is uninitialized")

digest_obj = _lib.EVP_get_digestbyname(_byte_string(digest))
if digest_obj == _ffi.NULL:
raise ValueError("No such digest method")

sign_result = _lib.X509_REQ_sign(self._req, pkey._pkey, digest_obj)
_openssl_assert(sign_result > 0)

def verify(self, pkey: PKey) -> bool:
"""
Verifies the signature on this certificate signing request.

:param PKey key: A public key.

:return: ``True`` if the signature is correct.
:rtype: bool

:raises OpenSSL.crypto.Error: If the signature is invalid or there is a
problem verifying the signature.
"""
if not isinstance(pkey, PKey):
raise TypeError("pkey must be a PKey instance")

result = _lib.X509_REQ_verify(self._req, pkey._pkey)
if result <= 0:
_raise_current_error()

return result


class X509:
"""
An X.509 certificate.
Expand Down Expand Up @@ -2117,95 +1939,3 @@ def load_privatekey(
pkey = PKey.__new__(PKey)
pkey._pkey = _ffi.gc(evp_pkey, _lib.EVP_PKEY_free)
return pkey


def dump_certificate_request(type: int, req: X509Req) -> bytes:
"""
Dump the certificate request *req* into a buffer string encoded with the
type *type*.

:param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)
:param req: The certificate request to dump
:return: The buffer with the dumped certificate request in


.. deprecated:: 24.2.0
Use `cryptography.x509.CertificateSigningRequest` instead.
"""
bio = _new_mem_buf()

if type == FILETYPE_PEM:
result_code = _lib.PEM_write_bio_X509_REQ(bio, req._req)
elif type == FILETYPE_ASN1:
result_code = _lib.i2d_X509_REQ_bio(bio, req._req)
elif type == FILETYPE_TEXT:
result_code = _lib.X509_REQ_print_ex(bio, req._req, 0, 0)
else:
raise ValueError(
"type argument must be FILETYPE_PEM, FILETYPE_ASN1, or "
"FILETYPE_TEXT"
)

_openssl_assert(result_code != 0)

return _bio_to_string(bio)


_dump_certificate_request_internal = dump_certificate_request

utils.deprecated(
dump_certificate_request,
__name__,
(
"CSR support in pyOpenSSL is deprecated. You should use the APIs "
"in cryptography."
),
DeprecationWarning,
name="dump_certificate_request",
)


def load_certificate_request(type: int, buffer: bytes) -> X509Req:
"""
Load a certificate request (X509Req) from the string *buffer* encoded with
the type *type*.

:param type: The file type (one of FILETYPE_PEM, FILETYPE_ASN1)
:param buffer: The buffer the certificate request is stored in
:return: The X509Req object

.. deprecated:: 24.2.0
Use `cryptography.x509.load_der_x509_csr` or
`cryptography.x509.load_pem_x509_csr` instead.
"""
if isinstance(buffer, str):
buffer = buffer.encode("ascii")

bio = _new_mem_buf(buffer)

if type == FILETYPE_PEM:
req = _lib.PEM_read_bio_X509_REQ(bio, _ffi.NULL, _ffi.NULL, _ffi.NULL)
elif type == FILETYPE_ASN1:
req = _lib.d2i_X509_REQ_bio(bio, _ffi.NULL)
else:
raise ValueError("type argument must be FILETYPE_PEM or FILETYPE_ASN1")

_openssl_assert(req != _ffi.NULL)

x509req = X509Req.__new__(X509Req)
x509req._req = _ffi.gc(req, _lib.X509_REQ_free)
return x509req


_load_certificate_request_internal = load_certificate_request

utils.deprecated(
load_certificate_request,
__name__,
(
"CSR support in pyOpenSSL is deprecated. You should use the APIs "
"in cryptography."
),
DeprecationWarning,
name="load_certificate_request",
)
Loading
Loading