diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 6 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/decode_asn1.py | 4 | ||||
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/encode_asn1.py | 14 | ||||
-rw-r--r-- | src/cryptography/x509/name.py | 46 |
4 files changed, 47 insertions, 23 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 3a889344..ede35ec0 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -95,12 +95,6 @@ class Backend(object): self._ffi = self._binding.ffi self._lib = self._binding.lib - # Set the default string mask for encoding ASN1 strings to UTF8. This - # is the default for newer OpenSSLs for several years (1.0.1h+) and is - # recommended in RFC 2459. - res = self._lib.ASN1_STRING_set_default_mask_asc(b"utf8only") - self.openssl_assert(res == 1) - self._cipher_registry = {} self._register_default_ciphers() self.activate_osrandom_engine() diff --git a/src/cryptography/hazmat/backends/openssl/decode_asn1.py b/src/cryptography/hazmat/backends/openssl/decode_asn1.py index ec55a9e8..2665fb22 100644 --- a/src/cryptography/hazmat/backends/openssl/decode_asn1.py +++ b/src/cryptography/hazmat/backends/openssl/decode_asn1.py @@ -11,6 +11,7 @@ from asn1crypto.core import Integer, SequenceOf from cryptography import x509 from cryptography.x509.extensions import _TLS_FEATURE_TYPE_TO_ENUM +from cryptography.x509.name import _ASN1_TYPE_TO_ENUM from cryptography.x509.oid import ( CRLEntryExtensionOID, CertificatePoliciesOID, ExtensionOID ) @@ -51,8 +52,9 @@ def _decode_x509_name_entry(backend, x509_name_entry): backend.openssl_assert(data != backend._ffi.NULL) value = _asn1_string_to_utf8(backend, data) oid = _obj2txt(backend, obj) + type = _ASN1_TYPE_TO_ENUM[data.type] - return x509.NameAttribute(x509.ObjectIdentifier(oid), value) + return x509.NameAttribute(x509.ObjectIdentifier(oid), value, type) def _decode_x509_name(backend, x509_name): diff --git a/src/cryptography/hazmat/backends/openssl/encode_asn1.py b/src/cryptography/hazmat/backends/openssl/encode_asn1.py index 6b867683..e45e1050 100644 --- a/src/cryptography/hazmat/backends/openssl/encode_asn1.py +++ b/src/cryptography/hazmat/backends/openssl/encode_asn1.py @@ -14,7 +14,7 @@ from cryptography.hazmat.backends.openssl.decode_asn1 import ( _CRL_ENTRY_REASON_ENUM_TO_CODE, _DISTPOINT_TYPE_FULLNAME, _DISTPOINT_TYPE_RELATIVENAME ) -from cryptography.x509.oid import CRLEntryExtensionOID, ExtensionOID, NameOID +from cryptography.x509.oid import CRLEntryExtensionOID, ExtensionOID def _encode_asn1_int(backend, x): @@ -118,17 +118,9 @@ def _encode_sk_name_entry(backend, attributes): def _encode_name_entry(backend, attribute): value = attribute.value.encode('utf8') obj = _txt2obj_gc(backend, attribute.oid.dotted_string) - if attribute.oid in [ - NameOID.COUNTRY_NAME, NameOID.JURISDICTION_COUNTRY_NAME - ]: - # Per RFC5280 Appendix A.1 countryName should be encoded as - # PrintableString, not UTF8String. EV Guidelines section 9.2.5 says - # jurisdictionCountryName follows the same rules as countryName. - type = backend._lib.MBSTRING_ASC - else: - type = backend._lib.MBSTRING_UTF8 + name_entry = backend._lib.X509_NAME_ENTRY_create_by_OBJ( - backend._ffi.NULL, obj, type, value, -1 + backend._ffi.NULL, obj, attribute._type.value, value, -1 ) return name_entry diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py index 108b60cc..2fbaee91 100644 --- a/src/cryptography/x509/name.py +++ b/src/cryptography/x509/name.py @@ -4,14 +4,33 @@ from __future__ import absolute_import, division, print_function +from enum import Enum + import six from cryptography import utils from cryptography.x509.oid import NameOID, ObjectIdentifier +class _ASN1Type(Enum): + UTF8String = 12 + NumericString = 18 + PrintableString = 19 + T61String = 20 + IA5String = 22 + UTCTime = 23 + GeneralizedTime = 24 + VisibleString = 26 + UniversalString = 28 + BMPString = 30 + + +_ASN1_TYPE_TO_ENUM = dict((i.value, i) for i in _ASN1Type) +_SENTINEL = object() + + class NameAttribute(object): - def __init__(self, oid, value): + def __init__(self, oid, value, _type=_SENTINEL): if not isinstance(oid, ObjectIdentifier): raise TypeError( "oid argument must be an ObjectIdentifier instance." @@ -22,16 +41,33 @@ class NameAttribute(object): "value argument must be a text type." ) - if oid == NameOID.COUNTRY_NAME and len(value.encode("utf8")) != 2: - raise ValueError( - "Country name must be a 2 character country code" - ) + if ( + oid == NameOID.COUNTRY_NAME or + oid == NameOID.JURISDICTION_COUNTRY_NAME + ): + if len(value.encode("utf8")) != 2: + raise ValueError( + "Country name must be a 2 character country code" + ) + + if _type == _SENTINEL: + _type = _ASN1Type.PrintableString if len(value) == 0: raise ValueError("Value cannot be an empty string") + # Set the default string type for encoding ASN1 strings to UTF8. This + # is the default for newer OpenSSLs for several years (1.0.1h+) and is + # recommended in RFC 2459. + if _type == _SENTINEL: + _type = _ASN1Type.UTF8String + + if not isinstance(_type, _ASN1Type): + raise TypeError("_type must be from the _ASN1Type enum") + self._oid = oid self._value = value + self._type = _type oid = utils.read_only_property("_oid") value = utils.read_only_property("_value") |