aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2015-10-27 07:31:25 -0400
committerAlex Gaynor <alex.gaynor@gmail.com>2015-10-27 07:31:25 -0400
commitd9849599346dd245c175221114b8d559d9d2124f (patch)
tree5dcdc3a3c1c5544f6aeae054eb2a07d73b96a6ce
parent9c72a6bb3868979cf9416cfa526ea2fc066f854d (diff)
parent8fdd1d3a00ea2c1de04a214314e20a39009c7c29 (diff)
downloadcryptography-d9849599346dd245c175221114b8d559d9d2124f.tar.gz
cryptography-d9849599346dd245c175221114b8d559d9d2124f.tar.bz2
cryptography-d9849599346dd245c175221114b8d559d9d2124f.zip
Merge pull request #2435 from reaperhulk/fix-2407
encode countryName with PrintableString
-rw-r--r--dev-requirements.txt1
-rw-r--r--setup.py1
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py14
-rw-r--r--tests/test_x509.py41
-rw-r--r--tox.ini1
5 files changed, 52 insertions, 6 deletions
diff --git a/dev-requirements.txt b/dev-requirements.txt
index d82c13b6..f6eec132 100644
--- a/dev-requirements.txt
+++ b/dev-requirements.txt
@@ -5,6 +5,7 @@ invoke
iso8601
pep8-naming
pretend
+pyasn1_modules
pytest
requests
sphinx
diff --git a/setup.py b/setup.py
index 9c97e1dd..19f1e663 100644
--- a/setup.py
+++ b/setup.py
@@ -63,6 +63,7 @@ test_requirements = [
"pretend",
"iso8601",
"hypothesis",
+ "pyasn1_modules",
]
# If there's no vectors locally that probably means we are in a tarball and
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 6471da6e..8e302a99 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -52,7 +52,7 @@ from cryptography.hazmat.primitives.ciphers.algorithms import (
from cryptography.hazmat.primitives.ciphers.modes import (
CBC, CFB, CFB8, CTR, ECB, GCM, OFB
)
-from cryptography.x509.oid import ExtensionOID
+from cryptography.x509.oid import ExtensionOID, NameOID
_MemoryBIO = collections.namedtuple("_MemoryBIO", ["bio", "char_ptr"])
@@ -133,12 +133,14 @@ def _encode_name(backend, attributes):
for attribute in attributes:
value = attribute.value.encode('utf8')
obj = _txt2obj_gc(backend, attribute.oid.dotted_string)
+ if attribute.oid == NameOID.COUNTRY_NAME:
+ # Per RFC5280 Appendix A.1 countryName should be encoded as
+ # PrintableString, not UTF8String
+ type = backend._lib.MBSTRING_ASC
+ else:
+ type = backend._lib.MBSTRING_UTF8
res = backend._lib.X509_NAME_add_entry_by_OBJ(
- subject,
- obj,
- backend._lib.MBSTRING_UTF8,
- value,
- -1, -1, 0,
+ subject, obj, type, value, -1, -1, 0,
)
backend.openssl_assert(res == 1)
return subject
diff --git a/tests/test_x509.py b/tests/test_x509.py
index a54cdc56..4072ef15 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -9,6 +9,10 @@ import datetime
import ipaddress
import os
+from pyasn1.codec.der import decoder
+
+from pyasn1_modules import rfc2459
+
import pytest
import six
@@ -1083,6 +1087,43 @@ class TestRSACertificateRequest(object):
x509.DNSName(u"cryptography.io"),
]
+ def test_build_cert_printable_string_country_name(self, backend):
+ issuer_private_key = RSA_KEY_2048.private_key(backend)
+ subject_private_key = RSA_KEY_2048.private_key(backend)
+
+ not_valid_before = datetime.datetime(2002, 1, 1, 12, 1)
+ not_valid_after = datetime.datetime(2030, 12, 31, 8, 30)
+
+ builder = x509.CertificateBuilder().serial_number(
+ 777
+ ).issuer_name(x509.Name([
+ x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
+ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
+ ])).subject_name(x509.Name([
+ x509.NameAttribute(NameOID.COUNTRY_NAME, u'US'),
+ x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u'Texas'),
+ ])).public_key(
+ subject_private_key.public_key()
+ ).not_valid_before(
+ not_valid_before
+ ).not_valid_after(
+ not_valid_after
+ )
+
+ cert = builder.sign(issuer_private_key, hashes.SHA256(), backend)
+
+ parsed, _ = decoder.decode(
+ cert.public_bytes(serialization.Encoding.DER),
+ asn1Spec=rfc2459.Certificate()
+ )
+ tbs_cert = parsed.getComponentByName('tbsCertificate')
+ subject = tbs_cert.getComponentByName('subject')
+ issuer = tbs_cert.getComponentByName('issuer')
+ # \x13 is printable string. The first byte of the value of the
+ # node corresponds to the ASN.1 string type.
+ assert subject[0][0][0][1][0] == b"\x13"[0]
+ assert issuer[0][0][0][1][0] == b"\x13"[0]
+
class TestCertificateBuilder(object):
@pytest.mark.requires_backend_interface(interface=RSABackend)
diff --git a/tox.ini b/tox.ini
index 1ed03a5e..35dc5671 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,6 +9,7 @@ deps =
pretend
pytest
hypothesis>=1.11.4
+ pyasn1_modules
./vectors
passenv = ARCHFLAGS LDFLAGS CFLAGS INCLUDE LIB LD_LIBRARY_PATH USERNAME
commands =