diff options
author | Andrea De Pasquale <447065+adepasquale@users.noreply.github.com> | 2020-03-19 20:23:35 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-19 15:23:35 -0400 |
commit | 87b2749c52e688c809f1861e55d958c64147493c (patch) | |
tree | acb7980da6a59fb88961dc1c6b670064a5102d85 | |
parent | 416d6856f19121c0102575a50bba6360c4708bb0 (diff) | |
download | cryptography-87b2749c52e688c809f1861e55d958c64147493c.tar.gz cryptography-87b2749c52e688c809f1861e55d958c64147493c.tar.bz2 cryptography-87b2749c52e688c809f1861e55d958c64147493c.zip |
Allow NameAttribute.value to be an empty string (#5109)
* Allow NameAttribute.value to be an empty string
RFC 4514 https://tools.ietf.org/html/rfc4514 does not mention that
"AttributeValue" can not be an empty (zero-length) string.
Fixes #5106
* reverse order to match fix from another PR
Co-authored-by: Paul Kehrer <paul.l.kehrer@gmail.com>
-rw-r--r-- | src/cryptography/x509/name.py | 6 | ||||
-rw-r--r-- | tests/x509/test_x509.py | 22 |
2 files changed, 21 insertions, 7 deletions
diff --git a/src/cryptography/x509/name.py b/src/cryptography/x509/name.py index 922cab5a..6816e063 100644 --- a/src/cryptography/x509/name.py +++ b/src/cryptography/x509/name.py @@ -54,6 +54,9 @@ _NAMEOID_TO_NAME = { def _escape_dn_value(val): """Escape special characters in RFC4514 Distinguished Name value.""" + if not val: + return '' + # See https://tools.ietf.org/html/rfc4514#section-2.4 val = val.replace('\\', '\\\\') val = val.replace('"', '\\"') @@ -93,9 +96,6 @@ class NameAttribute(object): "Country name must be a 2 character country code" ) - if len(value) == 0: - raise ValueError("Value cannot be an empty string") - # 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 diff --git a/tests/x509/test_x509.py b/tests/x509/test_x509.py index fb0c96ab..7c45660f 100644 --- a/tests/x509/test_x509.py +++ b/tests/x509/test_x509.py @@ -4281,6 +4281,10 @@ class TestNameAttribute(object): b'bytes' ) + def test_init_none_value(self): + with pytest.raises(TypeError): + x509.NameAttribute(NameOID.ORGANIZATION_NAME, None) + def test_init_bad_country_code_value(self): with pytest.raises(ValueError): x509.NameAttribute( @@ -4295,10 +4299,6 @@ class TestNameAttribute(object): u'\U0001F37A\U0001F37A' ) - def test_init_empty_value(self): - with pytest.raises(ValueError): - x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'') - def test_invalid_type(self): with pytest.raises(TypeError): x509.NameAttribute(NameOID.COMMON_NAME, u"common", "notanenum") @@ -4350,6 +4350,10 @@ class TestNameAttribute(object): assert (na.rfc4514_string() == '1.2.840.113549.1.9.1=somebody@example.com') + def test_empty_value(self): + na = x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'') + assert na.rfc4514_string() == r'ST=' + class TestRelativeDistinguishedName(object): def test_init_empty(self): @@ -4569,6 +4573,16 @@ class TestName(object): assert (n.rfc4514_string() == 'OU=Sales+CN=J. Smith,DC=example,DC=net') + def test_rfc4514_string_empty_values(self): + n = x509.Name([ + x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'), + x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u''), + x509.NameAttribute(NameOID.LOCALITY_NAME, u''), + x509.NameAttribute(NameOID.ORGANIZATION_NAME, u'PyCA'), + x509.NameAttribute(NameOID.COMMON_NAME, u'cryptography.io'), + ]) + assert (n.rfc4514_string() == 'CN=cryptography.io,O=PyCA,L=,ST=,C=US') + def test_not_nameattribute(self): with pytest.raises(TypeError): x509.Name(["not-a-NameAttribute"]) |