summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMathias Ertl <mati@er.tl>2021-03-15 23:44:02 +0100
committerGitHub <noreply@github.com>2021-03-15 18:44:02 -0400
commit8d41a94bba7674cfcb120ce7a76b7c3df5c2bb73 (patch)
tree3ff165eb8711231b59f6e50ff5dda0c6c021a484 /src
parentcd2ab9ec6c14333e10fb161295d5ae355c4a8f96 (diff)
downloadcryptography-8d41a94bba7674cfcb120ce7a76b7c3df5c2bb73.tar.gz
typehint x509.base (#5899)
* start typing x509.base * statically type x509.base * typehint X509Backend interface * typehint at least the X509Backend interface * make _CertificateRevocationList/_CertificateSigningRequest actual subclasses of the interface (as done before for Certificate in f16bff2cb) * tell mypy to ignore lines with deliberately wrong types * signature_hash_algorithm always returns a hash algorithm (it's not optional) * Revert "signature_hash_algorithm always returns a hash algorithm (it's not optional)" This reverts commit f6a5b172b416f8ddea561203c0cf03b55e4ec50e. * hash algorithm is actually optional * fix import style * typehint parsed_version to int, which it de facto always is * minimize changes * break import cycle with conditional imports * ignore access to private members of openssl implementation * reformat code with Black * test check for missing public key
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/__init__.py2
-rw-r--r--src/cryptography/hazmat/backends/interfaces.py56
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py62
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py6
4 files changed, 95 insertions, 31 deletions
diff --git a/src/cryptography/hazmat/backends/__init__.py b/src/cryptography/hazmat/backends/__init__.py
index 7f74cba2c..64eedecb5 100644
--- a/src/cryptography/hazmat/backends/__init__.py
+++ b/src/cryptography/hazmat/backends/__init__.py
@@ -9,7 +9,7 @@ from cryptography.hazmat.backends.interfaces import Backend
_default_backend: typing.Optional[Backend] = None
-def default_backend():
+def default_backend() -> Backend:
global _default_backend
if _default_backend is None:
diff --git a/src/cryptography/hazmat/backends/interfaces.py b/src/cryptography/hazmat/backends/interfaces.py
index d57289bb1..bb5106080 100644
--- a/src/cryptography/hazmat/backends/interfaces.py
+++ b/src/cryptography/hazmat/backends/interfaces.py
@@ -4,6 +4,23 @@
import abc
+import typing
+
+
+if typing.TYPE_CHECKING:
+ from cryptography.hazmat._types import _PRIVATE_KEY_TYPES
+ from cryptography.hazmat.primitives import hashes
+ from cryptography.x509.base import (
+ Certificate,
+ CertificateBuilder,
+ CertificateRevocationList,
+ CertificateRevocationListBuilder,
+ CertificateSigningRequest,
+ CertificateSigningRequestBuilder,
+ RevokedCertificate,
+ RevokedCertificateBuilder,
+ )
+ from cryptography.x509.name import Name
class CipherBackend(metaclass=abc.ABCMeta):
@@ -262,69 +279,86 @@ class DERSerializationBackend(metaclass=abc.ABCMeta):
class X509Backend(metaclass=abc.ABCMeta):
@abc.abstractmethod
- def load_pem_x509_certificate(self, data):
+ def load_pem_x509_certificate(self, data: bytes) -> "Certificate":
"""
Load an X.509 certificate from PEM encoded data.
"""
@abc.abstractmethod
- def load_der_x509_certificate(self, data):
+ def load_der_x509_certificate(self, data: bytes) -> "Certificate":
"""
Load an X.509 certificate from DER encoded data.
"""
@abc.abstractmethod
- def load_der_x509_csr(self, data):
+ def load_der_x509_csr(self, data: bytes) -> "CertificateSigningRequest":
"""
Load an X.509 CSR from DER encoded data.
"""
@abc.abstractmethod
- def load_pem_x509_csr(self, data):
+ def load_pem_x509_csr(self, data: bytes) -> "CertificateSigningRequest":
"""
Load an X.509 CSR from PEM encoded data.
"""
@abc.abstractmethod
- def create_x509_csr(self, builder, private_key, algorithm):
+ def create_x509_csr(
+ self,
+ builder: "CertificateSigningRequestBuilder",
+ private_key: "_PRIVATE_KEY_TYPES",
+ algorithm: typing.Optional["hashes.HashAlgorithm"],
+ ) -> "CertificateSigningRequest":
"""
Create and sign an X.509 CSR from a CSR builder object.
"""
@abc.abstractmethod
- def create_x509_certificate(self, builder, private_key, algorithm):
+ def create_x509_certificate(
+ self,
+ builder: "CertificateBuilder",
+ private_key: "_PRIVATE_KEY_TYPES",
+ algorithm: typing.Optional["hashes.HashAlgorithm"],
+ ) -> "Certificate":
"""
Create and sign an X.509 certificate from a CertificateBuilder object.
"""
@abc.abstractmethod
- def create_x509_crl(self, builder, private_key, algorithm):
+ def create_x509_crl(
+ self,
+ builder: "CertificateRevocationListBuilder",
+ private_key: "_PRIVATE_KEY_TYPES",
+ algorithm: typing.Optional["hashes.HashAlgorithm"],
+ ) -> "CertificateRevocationList":
"""
Create and sign an X.509 CertificateRevocationList from a
CertificateRevocationListBuilder object.
"""
@abc.abstractmethod
- def create_x509_revoked_certificate(self, builder):
+ def create_x509_revoked_certificate(
+ self, builder: "RevokedCertificateBuilder"
+ ) -> "RevokedCertificate":
"""
Create a RevokedCertificate object from a RevokedCertificateBuilder
object.
"""
@abc.abstractmethod
- def x509_name_bytes(self, name):
+ def x509_name_bytes(self, name: "Name") -> bytes:
"""
Compute the DER encoded bytes of an X509 Name object.
"""
@abc.abstractmethod
- def load_pem_x509_crl(self, data):
+ def load_pem_x509_crl(self, data: bytes) -> "CertificateRevocationList":
"""
Load an X.509 CRL from PEM encoded data.
"""
@abc.abstractmethod
- def load_der_x509_crl(self, data):
+ def load_der_x509_crl(self, data: bytes) -> "CertificateRevocationList":
"""
Load an X.509 CRL from DER encoded data.
"""
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 605af068d..90957324c 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -6,6 +6,7 @@
import collections
import contextlib
import itertools
+import typing
import warnings
from contextlib import contextmanager
@@ -18,6 +19,7 @@ from cryptography.hazmat._der import (
encode_der,
encode_der_integer,
)
+from cryptography.hazmat._types import _PRIVATE_KEY_TYPES
from cryptography.hazmat.backends.interfaces import Backend as BackendInterface
from cryptography.hazmat.backends.openssl import aead
from cryptography.hazmat.backends.openssl.ciphers import _CipherContext
@@ -137,6 +139,7 @@ from cryptography.hazmat.primitives.ciphers.modes import (
from cryptography.hazmat.primitives.kdf import scrypt
from cryptography.hazmat.primitives.serialization import pkcs7, ssh
from cryptography.x509 import ocsp
+from cryptography.x509.name import Name
_MemoryBIO = collections.namedtuple("_MemoryBIO", ["bio", "char_ptr"])
@@ -895,7 +898,12 @@ class Backend(BackendInterface):
"MD5 hash algorithm is only supported with RSA keys"
)
- def create_x509_csr(self, builder, private_key, algorithm):
+ def create_x509_csr(
+ self,
+ builder: x509.CertificateSigningRequestBuilder,
+ private_key: _PRIVATE_KEY_TYPES,
+ algorithm: typing.Optional[hashes.HashAlgorithm],
+ ) -> _CertificateSigningRequest:
if not isinstance(builder, x509.CertificateSigningRequestBuilder):
raise TypeError("Builder type mismatch.")
self._x509_check_signature_params(private_key, algorithm)
@@ -920,7 +928,9 @@ class Backend(BackendInterface):
# Set subject public key.
public_key = private_key.public_key()
- res = self._lib.X509_REQ_set_pubkey(x509_req, public_key._evp_pkey)
+ res = self._lib.X509_REQ_set_pubkey(
+ x509_req, public_key._evp_pkey # type: ignore[union-attr]
+ )
self.openssl_assert(res == 1)
# Add extensions.
@@ -960,16 +970,25 @@ class Backend(BackendInterface):
self.openssl_assert(res == 1)
# Sign the request using the requester's private key.
- res = self._lib.X509_REQ_sign(x509_req, private_key._evp_pkey, evp_md)
+ res = self._lib.X509_REQ_sign(
+ x509_req, private_key._evp_pkey, evp_md # type: ignore[union-attr]
+ )
if res == 0:
errors = self._consume_errors_with_text()
raise ValueError("Signing failed", errors)
return _CertificateSigningRequest(self, x509_req)
- def create_x509_certificate(self, builder, private_key, algorithm):
+ def create_x509_certificate(
+ self,
+ builder: x509.CertificateBuilder,
+ private_key: _PRIVATE_KEY_TYPES,
+ algorithm: typing.Optional[hashes.HashAlgorithm],
+ ) -> _Certificate:
if not isinstance(builder, x509.CertificateBuilder):
raise TypeError("Builder type mismatch.")
+ if builder._public_key is None:
+ raise TypeError("Builder has no public key.")
self._x509_check_signature_params(private_key, algorithm)
# Resolve the signature algorithm.
@@ -1027,7 +1046,11 @@ class Backend(BackendInterface):
self.openssl_assert(res == 1)
# Sign the certificate with the issuer's private key.
- res = self._lib.X509_sign(x509_cert, private_key._evp_pkey, evp_md)
+ res = self._lib.X509_sign(
+ x509_cert,
+ private_key._evp_pkey, # type: ignore[union-attr]
+ evp_md,
+ )
if res == 0:
errors = self._consume_errors_with_text()
raise ValueError("Signing failed", errors)
@@ -1058,7 +1081,12 @@ class Backend(BackendInterface):
self._set_asn1_time(asn1_time, time)
return asn1_time
- def create_x509_crl(self, builder, private_key, algorithm):
+ def create_x509_crl(
+ self,
+ builder: x509.CertificateRevocationListBuilder,
+ private_key: _PRIVATE_KEY_TYPES,
+ algorithm: typing.Optional[hashes.HashAlgorithm],
+ ) -> _CertificateRevocationList:
if not isinstance(builder, x509.CertificateRevocationListBuilder):
raise TypeError("Builder type mismatch.")
self._x509_check_signature_params(private_key, algorithm)
@@ -1109,7 +1137,9 @@ class Backend(BackendInterface):
res = self._lib.X509_CRL_add0_revoked(x509_crl, revoked)
self.openssl_assert(res == 1)
- res = self._lib.X509_CRL_sign(x509_crl, private_key._evp_pkey, evp_md)
+ res = self._lib.X509_CRL_sign(
+ x509_crl, private_key._evp_pkey, evp_md # type: ignore[union-attr]
+ )
if res == 0:
errors = self._consume_errors_with_text()
raise ValueError("Signing failed", errors)
@@ -1170,7 +1200,9 @@ class Backend(BackendInterface):
nid, 1 if extension.critical else 0, ext_struct
)
- def create_x509_revoked_certificate(self, builder):
+ def create_x509_revoked_certificate(
+ self, builder: x509.RevokedCertificateBuilder
+ ) -> _RevokedCertificate:
if not isinstance(builder, x509.RevokedCertificateBuilder):
raise TypeError("Builder type mismatch.")
@@ -1316,7 +1348,7 @@ class Backend(BackendInterface):
self._handle_key_loading_error()
- def load_pem_x509_certificate(self, data):
+ def load_pem_x509_certificate(self, data: bytes) -> _Certificate:
mem_bio = self._bytes_to_bio(data)
x509 = self._lib.PEM_read_bio_X509(
mem_bio.bio, self._ffi.NULL, self._ffi.NULL, self._ffi.NULL
@@ -1332,7 +1364,7 @@ class Backend(BackendInterface):
x509 = self._ffi.gc(x509, self._lib.X509_free)
return _Certificate(self, x509)
- def load_der_x509_certificate(self, data):
+ def load_der_x509_certificate(self, data: bytes) -> _Certificate:
mem_bio = self._bytes_to_bio(data)
x509 = self._lib.d2i_X509_bio(mem_bio.bio, self._ffi.NULL)
if x509 == self._ffi.NULL:
@@ -1342,7 +1374,7 @@ class Backend(BackendInterface):
x509 = self._ffi.gc(x509, self._lib.X509_free)
return _Certificate(self, x509)
- def load_pem_x509_crl(self, data):
+ def load_pem_x509_crl(self, data: bytes) -> _CertificateRevocationList:
mem_bio = self._bytes_to_bio(data)
x509_crl = self._lib.PEM_read_bio_X509_CRL(
mem_bio.bio, self._ffi.NULL, self._ffi.NULL, self._ffi.NULL
@@ -1358,7 +1390,7 @@ class Backend(BackendInterface):
x509_crl = self._ffi.gc(x509_crl, self._lib.X509_CRL_free)
return _CertificateRevocationList(self, x509_crl)
- def load_der_x509_crl(self, data):
+ def load_der_x509_crl(self, data: bytes) -> _CertificateRevocationList:
mem_bio = self._bytes_to_bio(data)
x509_crl = self._lib.d2i_X509_CRL_bio(mem_bio.bio, self._ffi.NULL)
if x509_crl == self._ffi.NULL:
@@ -1368,7 +1400,7 @@ class Backend(BackendInterface):
x509_crl = self._ffi.gc(x509_crl, self._lib.X509_CRL_free)
return _CertificateRevocationList(self, x509_crl)
- def load_pem_x509_csr(self, data):
+ def load_pem_x509_csr(self, data: bytes) -> _CertificateSigningRequest:
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
@@ -1384,7 +1416,7 @@ class Backend(BackendInterface):
x509_req = self._ffi.gc(x509_req, self._lib.X509_REQ_free)
return _CertificateSigningRequest(self, x509_req)
- def load_der_x509_csr(self, data):
+ def load_der_x509_csr(self, data: bytes) -> _CertificateSigningRequest:
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:
@@ -2200,7 +2232,7 @@ class Backend(BackendInterface):
def dh_x942_serialization_supported(self):
return self._lib.Cryptography_HAS_EVP_PKEY_DHX == 1
- def x509_name_bytes(self, name):
+ def x509_name_bytes(self, name: Name) -> bytes:
x509_name = _encode_name_gc(self, name)
pp = self._ffi.new("unsigned char **")
res = self._lib.i2d_X509_NAME(x509_name, pp)
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 07a1dd8a4..ea938a272 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -204,8 +204,7 @@ class _RevokedCertificate(x509.RevokedCertificate):
)
-@utils.register_interface(x509.CertificateRevocationList)
-class _CertificateRevocationList(object):
+class _CertificateRevocationList(x509.CertificateRevocationList):
def __init__(self, backend, x509_crl):
self._backend = backend
self._x509_crl = x509_crl
@@ -385,8 +384,7 @@ class _CertificateRevocationList(object):
return True
-@utils.register_interface(x509.CertificateSigningRequest)
-class _CertificateSigningRequest(object):
+class _CertificateSigningRequest(x509.CertificateSigningRequest):
def __init__(self, backend, x509_req):
self._backend = backend
self._x509_req = x509_req