diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/x509.py | 42 | ||||
-rw-r--r-- | src/cryptography/x509.py | 93 |
2 files changed, 135 insertions, 0 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index 66c99c9f..e27d32f8 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -91,3 +91,45 @@ 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(0, 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 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') + buf_len = 50 + 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..2371b36c 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -104,6 +104,87 @@ class ObjectIdentifier(object): dotted_string = utils.read_only_property("_dotted_string") +class Name(object): + def __init__(self, attributes): + self._attributes = attributes + + def _filter_attr_list(self, oid): + return [i for i in self._attributes if i.oid == oid] + + @property + def common_name(self): + return self._filter_attr_list(OID_COMMON_NAME) + + @property + def country_name(self): + return self._filter_attr_list(OID_COUNTRY_NAME) + + @property + def locality_name(self): + return self._filter_attr_list(OID_LOCALITY_NAME) + + @property + def state_or_province_name(self): + return self._filter_attr_list(OID_STATE_OR_PROVINCE_NAME) + + @property + def organization_name(self): + return self._filter_attr_list(OID_ORGANIZATION_NAME) + + @property + def organizational_unit_name(self): + return self._filter_attr_list(OID_ORGANIZATIONAL_UNIT_NAME) + + @property + def serial_number(self): + return self._filter_attr_list(OID_SERIAL_NUMBER) + + @property + def surname(self): + return self._filter_attr_list(OID_SURNAME) + + @property + def given_name(self): + return self._filter_attr_list(OID_GIVEN_NAME) + + @property + def title(self): + return self._filter_attr_list(OID_TITLE) + + @property + def generation_qualifier(self): + return self._filter_attr_list(OID_GENERATION_QUALIFIER) + + @property + def dn_qualifier(self): + return self._filter_attr_list(OID_DN_QUALIFIER) + + @property + def pseudonym(self): + return self._filter_attr_list(OID_PSEUDONYM) + + @property + def domain_component(self): + return self._filter_attr_list(OID_DOMAIN_COMPONENT) + + @property + def email_address(self): + return self._filter_attr_list(OID_EMAIL_ADDRESS) + + @property + def attributes(self): + return self._attributes[:] + + def __eq__(self, other): + if not isinstance(other, Name): + return NotImplemented + + return self.attributes == other.attributes + + def __ne__(self, other): + return not self == other + + 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 +239,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. + """ |