aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/cryptography/x509.py19
-rw-r--r--tests/test_x509_ext.py18
2 files changed, 37 insertions, 0 deletions
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index 33c64168..8bed79e2 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,23 @@ 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 not address:
+ # parseaddr has found a name (e.g. Name <email>) 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 af0ffafb..84a40995 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):