diff options
-rw-r--r-- | src/cryptography/hazmat/backends/openssl/backend.py | 4 | ||||
-rw-r--r-- | src/cryptography/hazmat/primitives/serialization.py | 4 | ||||
-rw-r--r-- | src/cryptography/x509.py | 4 | ||||
-rw-r--r-- | tests/hazmat/primitives/test_serialization.py | 10 | ||||
-rw-r--r-- | tests/test_x509.py | 89 |
5 files changed, 103 insertions, 8 deletions
diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 570782a2..f9da9ea7 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1163,6 +1163,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) elif isinstance(extension.value, x509.AuthorityInformationAccess): diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py index 098b31dc..fc50456e 100644 --- a/src/cryptography/hazmat/primitives/serialization.py +++ b/src/cryptography/hazmat/primitives/serialization.py @@ -33,9 +33,9 @@ def load_der_public_key(data, backend): def load_ssh_public_key(data, backend): - key_parts = data.split(b' ') + key_parts = data.split(b' ', 2) - if len(key_parts) != 2 and len(key_parts) != 3: + if len(key_parts) < 2: raise ValueError( 'Key is not in the proper format or contains extra data.') diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 6e27cdb7..978eb560 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/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index af605830..f82e7354 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -854,7 +854,7 @@ class TestRSASSHSerialization(object): with pytest.raises(ValueError): load_ssh_public_key(ssh_key, backend) - def test_load_ssh_public_key_rsa_extra_string_after_comment(self, backend): + def test_load_ssh_public_key_rsa_comment_with_spaces(self, backend): ssh_key = ( b"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDDu/XRP1kyK6Cgt36gts9XAk" b"FiiuJLW6RU0j3KKVZSs1I7Z3UmU9/9aVh/rZV43WQG8jaR6kkcP4stOR0DEtll" @@ -866,8 +866,7 @@ class TestRSASSHSerialization(object): b"2MzHvnbv testkey@localhost extra" ) - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) + load_ssh_public_key(ssh_key, backend) def test_load_ssh_public_key_rsa_extra_data_after_modulo(self, backend): ssh_key = ( @@ -943,7 +942,7 @@ class TestDSSSSHSerialization(object): with pytest.raises(ValueError): load_ssh_public_key(ssh_key, backend) - def test_load_ssh_public_key_dss_extra_string_after_comment(self, backend): + def test_load_ssh_public_key_dss_comment_with_spaces(self, backend): ssh_key = ( b"ssh-dss AAAAB3NzaC1kc3MAAACBALmwUtfwdjAUjU2Dixd5DvT0NDcjjr69UD" b"LqSD/Xt5Al7D3GXr1WOrWGpjO0NE9qzRCvMTU7zykRH6XjuNXB6Hvv48Zfm4vm" @@ -957,8 +956,7 @@ class TestDSSSSHSerialization(object): b"z53N7tPF/IhHTjBHb1Ol7IFu9p9A== testkey@localhost extra" ) - with pytest.raises(ValueError): - load_ssh_public_key(ssh_key, backend) + load_ssh_public_key(ssh_key, backend) def test_load_ssh_public_key_dss_extra_data_after_modulo(self, backend): ssh_key = ( diff --git a/tests/test_x509.py b/tests/test_x509.py index 0c63670d..e31b57f4 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): |