aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py15
-rw-r--r--src/cryptography/hazmat/backends/openssl/x509.py45
-rw-r--r--src/cryptography/x509.py35
3 files changed, 88 insertions, 7 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 75d7e32f..8441e891 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -225,8 +225,8 @@ class Backend(object):
)
def create_symmetric_encryption_ctx(self, cipher, mode):
- if (isinstance(mode, CTR) and isinstance(cipher, AES)
- and not self._evp_cipher_supported(cipher, mode)):
+ if (isinstance(mode, CTR) and isinstance(cipher, AES) and
+ not self._evp_cipher_supported(cipher, mode)):
# This is needed to provide support for AES CTR mode in OpenSSL
# 0.9.8. It can be removed when we drop 0.9.8 support (RHEL 5
# extended life ends 2020).
@@ -235,8 +235,8 @@ class Backend(object):
return _CipherContext(self, cipher, mode, _CipherContext._ENCRYPT)
def create_symmetric_decryption_ctx(self, cipher, mode):
- if (isinstance(mode, CTR) and isinstance(cipher, AES)
- and not self._evp_cipher_supported(cipher, mode)):
+ if (isinstance(mode, CTR) and isinstance(cipher, AES) and
+ not self._evp_cipher_supported(cipher, mode)):
# This is needed to provide support for AES CTR mode in OpenSSL
# 0.9.8. It can be removed when we drop 0.9.8 support (RHEL 5
# extended life ends 2020).
@@ -671,9 +671,10 @@ class Backend(object):
def cmac_algorithm_supported(self, algorithm):
return (
- self._lib.Cryptography_HAS_CMAC == 1
- and self.cipher_supported(algorithm, CBC(
- b"\x00" * algorithm.block_size))
+ self._lib.Cryptography_HAS_CMAC == 1 and
+ self.cipher_supported(
+ algorithm, CBC(b"\x00" * algorithm.block_size)
+ )
)
def create_cmac_ctx(self, algorithm):
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py
index 66c99c9f..76dcf32f 100644
--- a/src/cryptography/hazmat/backends/openssl/x509.py
+++ b/src/cryptography/hazmat/backends/openssl/x509.py
@@ -91,3 +91,48 @@ class _Certificate(object):
)
).decode("ascii")
return datetime.datetime.strptime(time, "%Y%m%d%H%M%SZ")
+
+ @property
+ def issuer(self):
+ issuer = self._backend._lib.X509_get_issuer_name(self._x509)
+ assert issuer != self._backend._ffi.NULL
+ return self._build_x509_name(issuer)
+
+ @property
+ def subject(self):
+ subject = self._backend._lib.X509_get_subject_name(self._x509)
+ assert subject != self._backend._ffi.NULL
+ return self._build_x509_name(subject)
+
+ def _build_x509_name(self, x509_name):
+ count = self._backend._lib.X509_NAME_entry_count(x509_name)
+ attributes = []
+ for x in range(count):
+ entry = self._backend._lib.X509_NAME_get_entry(x509_name, x)
+ obj = self._backend._lib.X509_NAME_ENTRY_get_object(entry)
+ assert obj != self._backend._ffi.NULL
+ data = self._backend._lib.X509_NAME_ENTRY_get_data(entry)
+ assert data != self._backend._ffi.NULL
+ buf = self._backend._ffi.new("unsigned char **")
+ res = self._backend._lib.ASN1_STRING_to_UTF8(buf, data)
+ assert res >= 0
+ assert buf[0] != self._backend._ffi.NULL
+ buf = self._backend._ffi.gc(
+ buf, lambda buf: self._backend._lib.OPENSSL_free(buf[0])
+ )
+ value = self._backend._ffi.buffer(buf[0], res)[:].decode('utf8')
+ # Set to 80 on the recommendation of
+ # https://www.openssl.org/docs/crypto/OBJ_nid2ln.html
+ buf_len = 80
+ buf = self._backend._ffi.new("char[]", buf_len)
+ res = self._backend._lib.OBJ_obj2txt(buf, buf_len, obj, 1)
+ assert res > 0
+ oid = self._backend._ffi.buffer(buf, res)[:].decode()
+
+ attributes.append(
+ x509.NameAttribute(
+ x509.ObjectIdentifier(oid), value
+ )
+ )
+
+ return x509.Name(attributes)
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 71062588..8a888d2a 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -104,6 +104,29 @@ class ObjectIdentifier(object):
dotted_string = utils.read_only_property("_dotted_string")
+class Name(object):
+ def __init__(self, attributes):
+ self._attributes = attributes
+
+ def get_attributes_for_oid(self, oid):
+ return [i for i in self._attributes if i.oid == oid]
+
+ def __eq__(self, other):
+ if not isinstance(other, Name):
+ return NotImplemented
+
+ return self._attributes == other._attributes
+
+ def __ne__(self, other):
+ return not self == other
+
+ def __iter__(self):
+ return iter(self._attributes)
+
+ def __len__(self):
+ return len(self._attributes)
+
+
OID_COMMON_NAME = ObjectIdentifier("2.5.4.3")
OID_COUNTRY_NAME = ObjectIdentifier("2.5.4.6")
OID_LOCALITY_NAME = ObjectIdentifier("2.5.4.7")
@@ -158,3 +181,15 @@ class Certificate(object):
"""
Not after time (represented as UTC datetime)
"""
+
+ @abc.abstractproperty
+ def issuer(self):
+ """
+ Returns the issuer name object.
+ """
+
+ @abc.abstractproperty
+ def subject(self):
+ """
+ Returns the subject name object.
+ """