diff options
author | Paul Kehrer <paul.l.kehrer@gmail.com> | 2017-12-01 10:48:56 +0800 |
---|---|---|
committer | Alex Gaynor <alex.gaynor@gmail.com> | 2017-11-30 20:48:56 -0600 |
commit | 4662d44fd3db5078a1882100653a3dbab3e3c7a1 (patch) | |
tree | 8338b438c3a388fc3f5026e87b90cfe0a04ab462 /src/cryptography/x509 | |
parent | 66460d8f62b3f27a009bb61be6ce7675c8451b6e (diff) | |
download | cryptography-4662d44fd3db5078a1882100653a3dbab3e3c7a1.tar.gz cryptography-4662d44fd3db5078a1882100653a3dbab3e3c7a1.tar.bz2 cryptography-4662d44fd3db5078a1882100653a3dbab3e3c7a1.zip |
Fix ASN1 string type encoding for several Name OIDs (#4035)
* Fix ASN1 string type encoding for several Name OIDs
When we changed over to the new type encoding system we didn't verify
that the new code exactly matched the ASN1 string types that OpenSSL was
previously choosing. This caused serialNumber, dnQualifier,
emailAddress, and domainComponent to change from their proper encodings
to UTF8String as of version 2.1.
Now we check to see if there's a sentinel value (indicating no custom
type has been passed) and then check if the OID has a different default
than UTF8. If it does, we set it.
This PR also adds tests for the ASN1 string type of ever supported
NameOID.
* review feedback
Diffstat (limited to 'src/cryptography/x509')
-rw-r--r-- | src/cryptography/x509/name.py | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py index 2fbaee91..0daa8bbd 100644 --- a/src/cryptography/x509/name.py +++ b/src/cryptography/x509/name.py @@ -27,6 +27,14 @@ class _ASN1Type(Enum): _ASN1_TYPE_TO_ENUM = dict((i.value, i) for i in _ASN1Type) _SENTINEL = object() +_NAMEOID_DEFAULT_TYPE = { + NameOID.COUNTRY_NAME: _ASN1Type.PrintableString, + NameOID.JURISDICTION_COUNTRY_NAME: _ASN1Type.PrintableString, + NameOID.SERIAL_NUMBER: _ASN1Type.PrintableString, + NameOID.DN_QUALIFIER: _ASN1Type.PrintableString, + NameOID.EMAIL_ADDRESS: _ASN1Type.IA5String, + NameOID.DOMAIN_COMPONENT: _ASN1Type.IA5String, +} class NameAttribute(object): @@ -50,17 +58,17 @@ class NameAttribute(object): "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. + # The appropriate ASN1 string type varies by OID and is defined across + # multiple RFCs including 2459, 3280, and 5280. In general UTF8String + # is preferred (2459), but 3280 and 5280 specify several OIDs with + # alternate types. This means when we see the sentinel value we need + # to look up whether the OID has a non-UTF8 type. If it does, set it + # to that. Otherwise, UTF8! if _type == _SENTINEL: - _type = _ASN1Type.UTF8String + _type = _NAMEOID_DEFAULT_TYPE.get(oid, _ASN1Type.UTF8String) if not isinstance(_type, _ASN1Type): raise TypeError("_type must be from the _ASN1Type enum") |