summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2020-08-15 18:05:46 -0500
committerGitHub <noreply@github.com>2020-08-15 19:05:46 -0400
commit9a55f775e5faa58e260451725d8d5bd3b41ce379 (patch)
tree32669fb280712477f373c8e385346924bf1da59b /src
parent679a1c7b93cb9d48f4813e7fdffd51c427667841 (diff)
downloadcryptography-9a55f775e5faa58e260451725d8d5bd3b41ce379.tar.gz
move the x509 parsers into the backend object (#5405)
* move the parser into the backend object This allows us to generate the list of supported extensions when instantiating the backend object rather than building multiple parsers and picking the right one at runtime when parsing the extensions themselves. * sigh
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py62
-rw-r--r--src/cryptography/hazmat/backends/openssl/decode_asn1.py120
-rw-r--r--src/cryptography/hazmat/backends/openssl/ocsp.py17
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py22
4 files changed, 103 insertions, 118 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index afe57a537..3d1079ad9 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -42,6 +42,14 @@ from cryptography.hazmat.backends.openssl.ciphers import _CipherContext
from cryptography.hazmat.backends.openssl.cmac import _CMACContext
from cryptography.hazmat.backends.openssl.decode_asn1 import (
_CRL_ENTRY_REASON_ENUM_TO_CODE,
+ _CRL_EXTENSION_HANDLERS,
+ _EXTENSION_HANDLERS_BASE,
+ _EXTENSION_HANDLERS_SCT,
+ _OCSP_BASICRESP_EXTENSION_HANDLERS,
+ _OCSP_REQ_EXTENSION_HANDLERS,
+ _OCSP_SINGLERESP_EXTENSION_HANDLERS_SCT,
+ _REVOKED_EXTENSION_HANDLERS,
+ _X509ExtensionParser,
)
from cryptography.hazmat.backends.openssl.dh import (
_DHParameters,
@@ -219,6 +227,7 @@ class Backend(object):
self._cipher_registry = {}
self._register_default_ciphers()
+ self._register_x509_ext_parsers()
if self._fips_enabled and self._lib.CRYPTOGRAPHY_NEEDS_OSRANDOM_ENGINE:
warnings.warn(
"OpenSSL FIPS mode is enabled. Can't enable DRBG fork safety.",
@@ -404,6 +413,59 @@ class Backend(object):
)
self.register_cipher_adapter(AES, XTS, _get_xts_cipher)
+ def _register_x509_ext_parsers(self):
+ ext_handlers = _EXTENSION_HANDLERS_BASE.copy()
+ # All revoked extensions are valid single response extensions, see:
+ # https://tools.ietf.org/html/rfc6960#section-4.4.5
+ singleresp_handlers = _REVOKED_EXTENSION_HANDLERS.copy()
+
+ if self._lib.Cryptography_HAS_SCT:
+ ext_handlers.update(_EXTENSION_HANDLERS_SCT)
+ singleresp_handlers.update(_OCSP_SINGLERESP_EXTENSION_HANDLERS_SCT)
+
+ self._certificate_extension_parser = _X509ExtensionParser(
+ self,
+ ext_count=self._lib.X509_get_ext_count,
+ get_ext=self._lib.X509_get_ext,
+ handlers=ext_handlers,
+ )
+ self._csr_extension_parser = _X509ExtensionParser(
+ self,
+ ext_count=self._lib.sk_X509_EXTENSION_num,
+ get_ext=self._lib.sk_X509_EXTENSION_value,
+ handlers=ext_handlers,
+ )
+ self._revoked_cert_extension_parser = _X509ExtensionParser(
+ self,
+ ext_count=self._lib.X509_REVOKED_get_ext_count,
+ get_ext=self._lib.X509_REVOKED_get_ext,
+ handlers=_REVOKED_EXTENSION_HANDLERS,
+ )
+ self._crl_extension_parser = _X509ExtensionParser(
+ self,
+ ext_count=self._lib.X509_CRL_get_ext_count,
+ get_ext=self._lib.X509_CRL_get_ext,
+ handlers=_CRL_EXTENSION_HANDLERS,
+ )
+ self._ocsp_req_ext_parser = _X509ExtensionParser(
+ self,
+ ext_count=self._lib.OCSP_REQUEST_get_ext_count,
+ get_ext=self._lib.OCSP_REQUEST_get_ext,
+ handlers=_OCSP_REQ_EXTENSION_HANDLERS,
+ )
+ self._ocsp_basicresp_ext_parser = _X509ExtensionParser(
+ self,
+ ext_count=self._lib.OCSP_BASICRESP_get_ext_count,
+ get_ext=self._lib.OCSP_BASICRESP_get_ext,
+ handlers=_OCSP_BASICRESP_EXTENSION_HANDLERS,
+ )
+ self._ocsp_singleresp_ext_parser = _X509ExtensionParser(
+ self,
+ ext_count=self._lib.OCSP_SINGLERESP_get_ext_count,
+ get_ext=self._lib.OCSP_SINGLERESP_get_ext,
+ handlers=singleresp_handlers,
+ )
+
def create_symmetric_encryption_ctx(self, cipher, mode):
return _CipherContext(self, cipher, mode, _CipherContext._ENCRYPT)
diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
index 56dcf26c1..279b00ca5 100644
--- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py
+++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py
@@ -181,21 +181,25 @@ def _decode_delta_crl_indicator(backend, ext):
class _X509ExtensionParser(object):
- def __init__(self, ext_count, get_ext, handlers):
+ def __init__(self, backend, ext_count, get_ext, handlers):
self.ext_count = ext_count
self.get_ext = get_ext
self.handlers = handlers
+ self._backend = backend
- def parse(self, backend, x509_obj):
+ def parse(self, x509_obj):
extensions = []
seen_oids = set()
- for i in range(self.ext_count(backend, x509_obj)):
- ext = self.get_ext(backend, x509_obj, i)
- backend.openssl_assert(ext != backend._ffi.NULL)
- crit = backend._lib.X509_EXTENSION_get_critical(ext)
+ for i in range(self.ext_count(x509_obj)):
+ ext = self.get_ext(x509_obj, i)
+ self._backend.openssl_assert(ext != self._backend._ffi.NULL)
+ crit = self._backend._lib.X509_EXTENSION_get_critical(ext)
critical = crit == 1
oid = x509.ObjectIdentifier(
- _obj2txt(backend, backend._lib.X509_EXTENSION_get_object(ext))
+ _obj2txt(
+ self._backend,
+ self._backend._lib.X509_EXTENSION_get_object(ext),
+ )
)
if oid in seen_oids:
raise x509.DuplicateExtension(
@@ -207,8 +211,8 @@ class _X509ExtensionParser(object):
# ourselves.
if oid == ExtensionOID.TLS_FEATURE:
# The extension contents are a SEQUENCE OF INTEGERs.
- data = backend._lib.X509_EXTENSION_get_data(ext)
- data_bytes = _asn1_string_to_bytes(backend, data)
+ data = self._backend._lib.X509_EXTENSION_get_data(ext)
+ data_bytes = _asn1_string_to_bytes(self._backend, data)
features = DERReader(data_bytes).read_single_element(SEQUENCE)
parsed = []
while not features.is_empty():
@@ -221,9 +225,9 @@ class _X509ExtensionParser(object):
seen_oids.add(oid)
continue
elif oid == ExtensionOID.PRECERT_POISON:
- data = backend._lib.X509_EXTENSION_get_data(ext)
+ data = self._backend._lib.X509_EXTENSION_get_data(ext)
# The contents of the extension must be an ASN.1 NULL.
- reader = DERReader(_asn1_string_to_bytes(backend, data))
+ reader = DERReader(_asn1_string_to_bytes(self._backend, data))
reader.read_single_element(NULL).check_empty()
extensions.append(
x509.Extension(oid, critical, x509.PrecertPoison())
@@ -235,21 +239,21 @@ class _X509ExtensionParser(object):
handler = self.handlers[oid]
except KeyError:
# Dump the DER payload into an UnrecognizedExtension object
- data = backend._lib.X509_EXTENSION_get_data(ext)
- backend.openssl_assert(data != backend._ffi.NULL)
- der = backend._ffi.buffer(data.data, data.length)[:]
+ data = self._backend._lib.X509_EXTENSION_get_data(ext)
+ self._backend.openssl_assert(data != self._backend._ffi.NULL)
+ der = self._backend._ffi.buffer(data.data, data.length)[:]
unrecognized = x509.UnrecognizedExtension(oid, der)
extensions.append(x509.Extension(oid, critical, unrecognized))
else:
- ext_data = backend._lib.X509V3_EXT_d2i(ext)
- if ext_data == backend._ffi.NULL:
- backend._consume_errors()
+ ext_data = self._backend._lib.X509V3_EXT_d2i(ext)
+ if ext_data == self._backend._ffi.NULL:
+ self._backend._consume_errors()
raise ValueError(
"The {} extension is invalid and can't be "
"parsed".format(oid)
)
- value = handler(backend, ext_data)
+ value = handler(self._backend, ext_data)
extensions.append(x509.Extension(oid, critical, value))
seen_oids.add(oid)
@@ -813,7 +817,7 @@ def _decode_nonce(backend, nonce):
return x509.OCSPNonce(_asn1_string_to_bytes(backend, nonce))
-_EXTENSION_HANDLERS_NO_SCT = {
+_EXTENSION_HANDLERS_BASE = {
ExtensionOID.BASIC_CONSTRAINTS: _decode_basic_constraints,
ExtensionOID.SUBJECT_KEY_IDENTIFIER: _decode_subject_key_identifier,
ExtensionOID.KEY_USAGE: _decode_key_usage,
@@ -835,11 +839,11 @@ _EXTENSION_HANDLERS_NO_SCT = {
ExtensionOID.NAME_CONSTRAINTS: _decode_name_constraints,
ExtensionOID.POLICY_CONSTRAINTS: _decode_policy_constraints,
}
-_EXTENSION_HANDLERS = _EXTENSION_HANDLERS_NO_SCT.copy()
-_EXTENSION_HANDLERS[
- ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS
-] = _decode_precert_signed_certificate_timestamps
-
+_EXTENSION_HANDLERS_SCT = {
+ ExtensionOID.PRECERT_SIGNED_CERTIFICATE_TIMESTAMPS: (
+ _decode_precert_signed_certificate_timestamps
+ )
+}
_REVOKED_EXTENSION_HANDLERS = {
CRLEntryExtensionOID.CRL_REASON: _decode_crl_reason,
@@ -867,66 +871,8 @@ _OCSP_BASICRESP_EXTENSION_HANDLERS = {
OCSPExtensionOID.NONCE: _decode_nonce,
}
-# All revoked extensions are valid single response extensions, see:
-# https://tools.ietf.org/html/rfc6960#section-4.4.5
-_OCSP_SINGLERESP_EXTENSION_HANDLERS_NO_SCT = _REVOKED_EXTENSION_HANDLERS.copy()
-_OCSP_SINGLERESP_EXTENSION_HANDLERS = (
- _OCSP_SINGLERESP_EXTENSION_HANDLERS_NO_SCT.copy()
-)
-_OCSP_SINGLERESP_EXTENSION_HANDLERS[
- ExtensionOID.SIGNED_CERTIFICATE_TIMESTAMPS
-] = _decode_signed_certificate_timestamps
-
-_CERTIFICATE_EXTENSION_PARSER_NO_SCT = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.X509_get_ext_count(x),
- get_ext=lambda backend, x, i: backend._lib.X509_get_ext(x, i),
- handlers=_EXTENSION_HANDLERS_NO_SCT,
-)
-
-_CERTIFICATE_EXTENSION_PARSER = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.X509_get_ext_count(x),
- get_ext=lambda backend, x, i: backend._lib.X509_get_ext(x, i),
- handlers=_EXTENSION_HANDLERS,
-)
-
-_CSR_EXTENSION_PARSER = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.sk_X509_EXTENSION_num(x),
- get_ext=lambda backend, x, i: backend._lib.sk_X509_EXTENSION_value(x, i),
- handlers=_EXTENSION_HANDLERS,
-)
-
-_REVOKED_CERTIFICATE_EXTENSION_PARSER = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.X509_REVOKED_get_ext_count(x),
- get_ext=lambda backend, x, i: backend._lib.X509_REVOKED_get_ext(x, i),
- handlers=_REVOKED_EXTENSION_HANDLERS,
-)
-
-_CRL_EXTENSION_PARSER = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.X509_CRL_get_ext_count(x),
- get_ext=lambda backend, x, i: backend._lib.X509_CRL_get_ext(x, i),
- handlers=_CRL_EXTENSION_HANDLERS,
-)
-
-_OCSP_REQ_EXT_PARSER = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.OCSP_REQUEST_get_ext_count(x),
- get_ext=lambda backend, x, i: backend._lib.OCSP_REQUEST_get_ext(x, i),
- handlers=_OCSP_REQ_EXTENSION_HANDLERS,
-)
-
-_OCSP_BASICRESP_EXT_PARSER = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.OCSP_BASICRESP_get_ext_count(x),
- get_ext=lambda backend, x, i: backend._lib.OCSP_BASICRESP_get_ext(x, i),
- handlers=_OCSP_BASICRESP_EXTENSION_HANDLERS,
-)
-
-_OCSP_SINGLERESP_EXT_PARSER = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.OCSP_SINGLERESP_get_ext_count(x),
- get_ext=lambda backend, x, i: backend._lib.OCSP_SINGLERESP_get_ext(x, i),
- handlers=_OCSP_SINGLERESP_EXTENSION_HANDLERS,
-)
-
-_OCSP_SINGLERESP_EXT_PARSER_NO_SCT = _X509ExtensionParser(
- ext_count=lambda backend, x: backend._lib.OCSP_SINGLERESP_get_ext_count(x),
- get_ext=lambda backend, x, i: backend._lib.OCSP_SINGLERESP_get_ext(x, i),
- handlers=_OCSP_SINGLERESP_EXTENSION_HANDLERS_NO_SCT,
-)
+_OCSP_SINGLERESP_EXTENSION_HANDLERS_SCT = {
+ ExtensionOID.SIGNED_CERTIFICATE_TIMESTAMPS: (
+ _decode_signed_certificate_timestamps
+ )
+}
diff --git a/src/cryptography/hazmat/backends/openssl/ocsp.py b/src/cryptography/hazmat/backends/openssl/ocsp.py
index c432e222c..50c02e7a8 100644
--- a/src/cryptography/hazmat/backends/openssl/ocsp.py
+++ b/src/cryptography/hazmat/backends/openssl/ocsp.py
@@ -10,10 +10,6 @@ from cryptography import utils, x509
from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.backends.openssl.decode_asn1 import (
_CRL_ENTRY_REASON_CODE_TO_ENUM,
- _OCSP_BASICRESP_EXT_PARSER,
- _OCSP_REQ_EXT_PARSER,
- _OCSP_SINGLERESP_EXT_PARSER,
- _OCSP_SINGLERESP_EXT_PARSER_NO_SCT,
_asn1_integer_to_int,
_asn1_string_to_bytes,
_decode_x509_name,
@@ -340,19 +336,12 @@ class _OCSPResponse(object):
@utils.cached_property
@_requires_successful_response
def extensions(self):
- return _OCSP_BASICRESP_EXT_PARSER.parse(self._backend, self._basic)
+ return self._backend._ocsp_basicresp_ext_parser.parse(self._basic)
@utils.cached_property
@_requires_successful_response
def single_extensions(self):
- if self._backend._lib.Cryptography_HAS_SCT:
- return _OCSP_SINGLERESP_EXT_PARSER.parse(
- self._backend, self._single
- )
- else:
- return _OCSP_SINGLERESP_EXT_PARSER_NO_SCT.parse(
- self._backend, self._single
- )
+ return self._backend._ocsp_singleresp_ext_parser.parse(self._single)
def public_bytes(self, encoding):
if encoding is not serialization.Encoding.DER:
@@ -400,7 +389,7 @@ class _OCSPRequest(object):
@utils.cached_property
def extensions(self):
- return _OCSP_REQ_EXT_PARSER.parse(self._backend, self._ocsp_request)
+ return self._backend._ocsp_req_ext_parser.parse(self._ocsp_request)
def public_bytes(self, encoding):
if encoding is not serialization.Encoding.DER:
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 1ebb69468..4d0dac764 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -10,11 +10,6 @@ import operator
from cryptography import utils, x509
from cryptography.exceptions import UnsupportedAlgorithm
from cryptography.hazmat.backends.openssl.decode_asn1 import (
- _CERTIFICATE_EXTENSION_PARSER,
- _CERTIFICATE_EXTENSION_PARSER_NO_SCT,
- _CRL_EXTENSION_PARSER,
- _CSR_EXTENSION_PARSER,
- _REVOKED_CERTIFICATE_EXTENSION_PARSER,
_asn1_integer_to_int,
_asn1_string_to_bytes,
_decode_x509_name,
@@ -133,14 +128,7 @@ class _Certificate(object):
@utils.cached_property
def extensions(self):
- if self._backend._lib.Cryptography_HAS_SCT:
- return _CERTIFICATE_EXTENSION_PARSER.parse(
- self._backend, self._x509
- )
- else:
- return _CERTIFICATE_EXTENSION_PARSER_NO_SCT.parse(
- self._backend, self._x509
- )
+ return self._backend._certificate_extension_parser.parse(self._x509)
@property
def signature(self):
@@ -207,8 +195,8 @@ class _RevokedCertificate(object):
@utils.cached_property
def extensions(self):
- return _REVOKED_CERTIFICATE_EXTENSION_PARSER.parse(
- self._backend, self._x509_revoked
+ return self._backend._revoked_cert_extension_parser.parse(
+ self._x509_revoked
)
@@ -363,7 +351,7 @@ class _CertificateRevocationList(object):
@utils.cached_property
def extensions(self):
- return _CRL_EXTENSION_PARSER.parse(self._backend, self._x509_crl)
+ return self._backend._crl_extension_parser.parse(self._x509_crl)
def is_signature_valid(self, public_key):
if not isinstance(
@@ -449,7 +437,7 @@ class _CertificateSigningRequest(object):
),
),
)
- return _CSR_EXTENSION_PARSER.parse(self._backend, x509_exts)
+ return self._backend._csr_extension_parser.parse(x509_exts)
def public_bytes(self, encoding):
bio = self._backend._create_mem_bio_gc()