diff options
author | Paul Kehrer <paul.l.kehrer@gmail.com> | 2015-07-12 09:41:21 -0500 |
---|---|---|
committer | Paul Kehrer <paul.l.kehrer@gmail.com> | 2015-07-12 09:41:21 -0500 |
commit | 01d5d0b44256bed5e49f37e2f92e1f4e4fc0154e (patch) | |
tree | f430f60fbbb9211ad527a444b8693ee68f9a75c6 | |
parent | 534846178021b1a2993730409e8a3937b589ea12 (diff) | |
download | cryptography-01d5d0b44256bed5e49f37e2f92e1f4e4fc0154e.tar.gz cryptography-01d5d0b44256bed5e49f37e2f92e1f4e4fc0154e.tar.bz2 cryptography-01d5d0b44256bed5e49f37e2f92e1f4e4fc0154e.zip |
expand RFC822Name to validate and (internally) IDNA encode
This will be used in the CSR builder
-rw-r--r-- | src/cryptography/x509.py | 20 | ||||
-rw-r--r-- | tests/test_x509_ext.py | 18 |
2 files changed, 38 insertions, 0 deletions
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 33c64168..ca91b07a 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -6,8 +6,11 @@ from __future__ import absolute_import, division, print_function import abc import ipaddress +from email.utils import parseaddr from enum import Enum +import idna + import six from cryptography import utils @@ -901,7 +904,24 @@ class RFC822Name(object): if not isinstance(value, six.text_type): raise TypeError("value must be a unicode string") + name, address = parseaddr(value) + parts = address.split(u"@") + if name or len(parts) > 2 or not address: + # parseaddr has found a name (e.g. Name <email>) or the split + # has found more than 2 parts (which means more than one @) + # or the entire value is an empty string. + raise ValueError("Invalid rfc822name value") + elif len(parts) == 1: + # Single label email name. This is valid for local delivery. + # No IDNA encoding needed since there is no domain component. + encoded = address.encode("ascii") + else: + # A normal email of the form user@domain.com. Let's attempt to + # encode the domain component and reconstruct the address. + encoded = parts[0].encode("ascii") + b"@" + idna.encode(parts[1]) + self._value = value + self._encoded = encoded value = utils.read_only_property("_value") diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py index 993802b8..e1569865 100644 --- a/tests/test_x509_ext.py +++ b/tests/test_x509_ext.py @@ -1087,6 +1087,24 @@ class TestDirectoryName(object): assert gn != object() +class TestRFC822Name(object): + def test_invalid_email(self): + with pytest.raises(ValueError): + x509.RFC822Name(u"Name <email>") + + with pytest.raises(ValueError): + x509.RFC822Name(u"") + + def test_single_label(self): + gn = x509.RFC822Name(u"administrator") + assert gn.value == u"administrator" + + def test_idna(self): + gn = x509.RFC822Name(u"email@em\xe5\xefl.com") + assert gn.value == u"email@em\xe5\xefl.com" + assert gn._encoded == b"email@xn--eml-vla4c.com" + + class TestRegisteredID(object): def test_not_oid(self): with pytest.raises(TypeError): |