aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py6
-rw-r--r--src/cryptography/hazmat/backends/openssl/decode_asn1.py4
-rw-r--r--src/cryptography/hazmat/backends/openssl/encode_asn1.py14
-rw-r--r--src/cryptography/x509/name.py46
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")