aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Gaynor <alex.gaynor@gmail.com>2015-08-03 16:58:09 -0400
committerAlex Gaynor <alex.gaynor@gmail.com>2015-08-03 16:58:09 -0400
commite0277f7e4598db6628cb378ba40bec8edb6f8672 (patch)
tree15b64b0bd6bf8fa8694dd1d0eb13d157269ac4c9
parentb45c79b69d75c0e1dc69e941f67c3eaa4326a443 (diff)
parent2748d8aefb765f7549869c619c9d2136c2aa2318 (diff)
downloadcryptography-e0277f7e4598db6628cb378ba40bec8edb6f8672.tar.gz
cryptography-e0277f7e4598db6628cb378ba40bec8edb6f8672.tar.bz2
cryptography-e0277f7e4598db6628cb378ba40bec8edb6f8672.zip
Merge pull request #2197 from reaperhulk/cert-ku-eku
support keyusage and extendedkeyusage in certificatebuilder
-rw-r--r--src/cryptography/hazmat/backends/openssl/backend.py4
-rw-r--r--src/cryptography/x509.py4
-rw-r--r--tests/test_x509.py89
3 files changed, 97 insertions, 0 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
index 0176de21..5bb91a9b 100644
--- a/src/cryptography/hazmat/backends/openssl/backend.py
+++ b/src/cryptography/hazmat/backends/openssl/backend.py
@@ -1137,6 +1137,10 @@ class Backend(object):
for i, extension in enumerate(builder._extensions):
if isinstance(extension.value, x509.BasicConstraints):
pp, r = _encode_basic_constraints(self, extension.value)
+ elif isinstance(extension.value, x509.KeyUsage):
+ pp, r = _encode_key_usage(self, extension.value)
+ elif isinstance(extension.value, x509.ExtendedKeyUsage):
+ pp, r = _encode_extended_key_usage(self, extension.value)
elif isinstance(extension.value, x509.SubjectAlternativeName):
pp, r = _encode_subject_alt_name(self, extension.value)
else:
diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py
index f35582b0..defac248 100644
--- a/src/cryptography/x509.py
+++ b/src/cryptography/x509.py
@@ -1720,6 +1720,10 @@ class CertificateBuilder(object):
"""
if isinstance(extension, BasicConstraints):
extension = Extension(OID_BASIC_CONSTRAINTS, critical, extension)
+ elif isinstance(extension, KeyUsage):
+ extension = Extension(OID_KEY_USAGE, critical, extension)
+ elif isinstance(extension, ExtendedKeyUsage):
+ extension = Extension(OID_EXTENDED_KEY_USAGE, critical, extension)
elif isinstance(extension, SubjectAlternativeName):
extension = Extension(
OID_SUBJECT_ALTERNATIVE_NAME, critical, extension
diff --git a/tests/test_x509.py b/tests/test_x509.py
index ba35f64d..668a3bad 100644
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -1119,6 +1119,95 @@ class TestCertificateBuilder(object):
with pytest.raises(ValueError):
builder.sign(issuer_private_key, hashes.SHA512(), backend)
+ @pytest.mark.requires_backend_interface(interface=RSABackend)
+ @pytest.mark.requires_backend_interface(interface=X509Backend)
+ def test_extended_key_usage(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)
+
+ cert = x509.CertificateBuilder().subject_name(
+ x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
+ ).issuer_name(
+ x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
+ ).not_valid_before(
+ not_valid_before
+ ).not_valid_after(
+ not_valid_after
+ ).public_key(
+ subject_private_key.public_key()
+ ).serial_number(
+ 123
+ ).add_extension(
+ x509.ExtendedKeyUsage([
+ x509.OID_CLIENT_AUTH,
+ x509.OID_SERVER_AUTH,
+ x509.OID_CODE_SIGNING,
+ ]), critical=False
+ ).sign(issuer_private_key, hashes.SHA256(), backend)
+
+ eku = cert.extensions.get_extension_for_oid(
+ x509.OID_EXTENDED_KEY_USAGE
+ )
+ assert eku.critical is False
+ assert eku.value == x509.ExtendedKeyUsage([
+ x509.OID_CLIENT_AUTH,
+ x509.OID_SERVER_AUTH,
+ x509.OID_CODE_SIGNING,
+ ])
+
+ @pytest.mark.requires_backend_interface(interface=RSABackend)
+ @pytest.mark.requires_backend_interface(interface=X509Backend)
+ def test_key_usage(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)
+
+ cert = x509.CertificateBuilder().subject_name(
+ x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
+ ).issuer_name(
+ x509.Name([x509.NameAttribute(x509.OID_COUNTRY_NAME, u'US')])
+ ).not_valid_before(
+ not_valid_before
+ ).not_valid_after(
+ not_valid_after
+ ).public_key(
+ subject_private_key.public_key()
+ ).serial_number(
+ 123
+ ).add_extension(
+ x509.KeyUsage(
+ digital_signature=True,
+ content_commitment=True,
+ key_encipherment=False,
+ data_encipherment=False,
+ key_agreement=False,
+ key_cert_sign=True,
+ crl_sign=False,
+ encipher_only=False,
+ decipher_only=False
+ ),
+ critical=False
+ ).sign(issuer_private_key, hashes.SHA256(), backend)
+
+ ext = cert.extensions.get_extension_for_oid(x509.OID_KEY_USAGE)
+ assert ext.critical is False
+ assert ext.value == x509.KeyUsage(
+ digital_signature=True,
+ content_commitment=True,
+ key_encipherment=False,
+ data_encipherment=False,
+ key_agreement=False,
+ key_cert_sign=True,
+ crl_sign=False,
+ encipher_only=False,
+ decipher_only=False
+ )
+
@pytest.mark.requires_backend_interface(interface=X509Backend)
class TestCertificateSigningRequestBuilder(object):