diff options
22 files changed, 399 insertions, 361 deletions
diff --git a/.travis.yml b/.travis.yml index 76decf62..8ad514fd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -120,7 +120,7 @@ script: - ./.travis/run.sh after_success: - - source ~/.venv/bin/activate && coveralls + - source ~/.venv/bin/activate && bash <(curl -s https://codecov.io/bash) -e TRAVIS_OS_NAME,TOXENV,OPENSSL notifications: irc: diff --git a/.travis/install.sh b/.travis/install.sh index a046a5d8..17aee435 100755 --- a/.travis/install.sh +++ b/.travis/install.sh @@ -65,4 +65,4 @@ fi python -m virtualenv ~/.venv source ~/.venv/bin/activate -pip install tox coveralls +pip install tox codecov diff --git a/AUTHORS.rst b/AUTHORS.rst index 5f5e1a47..6f862b96 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -12,6 +12,7 @@ PGP key fingerprints are enclosed in parentheses. * Jarret Raim <jarito@gmail.com> * Alex Stapleton <alexs@prol.etari.at> (A1C7 E50B 66DE 39ED C847 9665 8E3C 20D1 9BD9 5C4C) * David Reid <dreid@dreid.org> (0F83 CC87 B32F 482B C726 B58A 9FBF D8F4 DA89 6D74) +* Matthew Lefkowitz <glyph@twistedmatrix.com> (06AB F638 E878 CD29 1264 18AB 7EC2 8125 0FBC 4A07) * Konstantinos Koukopoulos <koukopoulos@gmail.com> (D6BD 52B6 8C99 A91C E2C8 934D 3300 566B 3A46 726E) * Stephen Holsapple <sholsapp@gmail.com> * Terry Chia <terrycwk1994@gmail.com> @@ -12,8 +12,8 @@ Cryptography .. image:: https://travis-ci.org/pyca/cryptography.svg?branch=master :target: https://travis-ci.org/pyca/cryptography -.. image:: https://img.shields.io/coveralls/pyca/cryptography/master.svg - :target: https://coveralls.io/r/pyca/cryptography?branch=master +.. image:: https://codecov.io/github/pyca/cryptography/coverage.svg?branch=master + :target: https://codecov.io/github/pyca/cryptography?branch=master ``cryptography`` is a package which provides cryptographic recipes and diff --git a/docs/development/test-vectors.rst b/docs/development/test-vectors.rst index bc171b21..ca07547c 100644 --- a/docs/development/test-vectors.rst +++ b/docs/development/test-vectors.rst @@ -199,11 +199,22 @@ Custom X.509 Vectors set. * ``nc_permitted_excluded.pem`` - An RSA 2048 bit self-signed certificate containing a name constraints extension with both permitted and excluded - elements. + elements. Contains ``IPv4`` and ``IPv6`` addresses with network mask as well + as ``dNSName`` with a leading period. +* ``nc_permitted_excluded_2.pem`` - An RSA 2048 bit self-signed certificate + containing a name constraints extension with both permitted and excluded + elements. Unlike ``nc_permitted_excluded.pem``, the general names do not + contain any name constraints specific values. * ``nc_permitted.pem`` - An RSA 2048 bit self-signed certificate containing a name constraints extension with permitted elements. +* ``nc_permitted_2.pem`` - An RSA 2048 bit self-signed certificate containing a + name constraints extension with permitted elements that do not contain any + name constraints specific values. * ``nc_excluded.pem`` - An RSA 2048 bit self-signed certificate containing a name constraints extension with excluded elements. +* ``nc_invalid_ip_netmask.pem`` - An RSA 2048 bit self-signed certificate + containing a name constraints extension with a permitted element that has an + ``IPv6`` IP and an invalid network mask. * ``cp_user_notice_with_notice_reference.pem`` - An RSA 2048 bit self-signed certificate containing a certificate policies extension with a notice reference in the user notice. diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 85f65972..91bc304f 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -119,6 +119,9 @@ def _encode_basic_constraints(backend, basic_constraints, critical): obj = _txt2obj(backend, x509.OID_BASIC_CONSTRAINTS.dotted_string) assert obj is not None constraints = backend._lib.BASIC_CONSTRAINTS_new() + constraints = backend._ffi.gc( + constraints, backend._lib.BASIC_CONSTRAINTS_free + ) constraints.ca = 255 if basic_constraints.ca else 0 if basic_constraints.ca: constraints.pathlen = _encode_asn1_int( @@ -685,8 +688,7 @@ class Backend(object): def generate_dsa_parameters(self, key_size): if key_size not in (1024, 2048, 3072): - raise ValueError( - "Key size must be 1024 or 2048 or 3072 bits.") + raise ValueError("Key size must be 1024 or 2048 or 3072 bits.") if (self._lib.OPENSSL_VERSION_NUMBER < 0x1000000f and key_size > 1024): @@ -833,7 +835,7 @@ class Backend(object): # Set subject name. res = self._lib.X509_REQ_set_subject_name( - x509_req, _encode_name(self, list(builder._subject_name)) + x509_req, _encode_name(self, builder._subject_name) ) assert res == 1 @@ -1351,9 +1353,6 @@ class Backend(object): def _private_key_bytes(self, encoding, format, encryption_algorithm, evp_pkey, cdata): - if not isinstance(encoding, serialization.Encoding): - raise TypeError("encoding must be an item from the Encoding enum") - if not isinstance(format, serialization.PrivateFormat): raise TypeError( "format must be an item from the PrivateFormat enum" @@ -1416,6 +1415,8 @@ class Backend(object): elif format is serialization.PrivateFormat.PKCS8: write_bio = self._lib.i2d_PKCS8PrivateKey_bio key = evp_pkey + else: + raise TypeError("encoding must be an item from the Encoding enum") bio = self._create_mem_bio() res = write_bio( @@ -1448,11 +1449,6 @@ class Backend(object): if not isinstance(encoding, serialization.Encoding): raise TypeError("encoding must be an item from the Encoding enum") - if not isinstance(format, serialization.PublicFormat): - raise TypeError( - "format must be an item from the PublicFormat enum" - ) - if format is serialization.PublicFormat.SubjectPublicKeyInfo: if encoding is serialization.Encoding.PEM: write_bio = self._lib.PEM_write_bio_PUBKEY @@ -1469,6 +1465,10 @@ class Backend(object): write_bio = self._lib.i2d_RSAPublicKey_bio key = cdata + else: + raise TypeError( + "format must be an item from the PublicFormat enum" + ) bio = self._create_mem_bio() res = write_bio(bio, key) diff --git a/src/cryptography/hazmat/backends/openssl/x509.py b/src/cryptography/hazmat/backends/openssl/x509.py index a03414c8..cc805755 100644 --- a/src/cryptography/hazmat/backends/openssl/x509.py +++ b/src/cryptography/hazmat/backends/openssl/x509.py @@ -82,7 +82,17 @@ def _decode_general_names(backend, gns): def _decode_general_name(backend, gn): if gn.type == backend._lib.GEN_DNS: data = backend._ffi.buffer(gn.d.dNSName.data, gn.d.dNSName.length)[:] - return x509.DNSName(idna.decode(data)) + if data.startswith(b"*."): + # This is a wildcard name. We need to remove the leading wildcard, + # IDNA decode, then re-add the wildcard. Wildcard characters should + # always be left-most (RFC 2595 section 2.4). + data = u"*." + idna.decode(data[2:]) + else: + # Not a wildcard, decode away. If the string has a * in it anywhere + # invalid this will raise an InvalidCodePoint + data = idna.decode(data) + + return x509.DNSName(data) elif gn.type == backend._lib.GEN_URI: data = backend._ffi.buffer( gn.d.uniformResourceIdentifier.data, @@ -153,6 +163,45 @@ def _decode_general_name(backend, gn): ) +def _decode_ocsp_no_check(backend, ext): + return x509.OCSPNoCheck() + + +class _X509ExtensionParser(object): + def __init__(self, ext_count, get_ext, handlers): + self.ext_count = ext_count + self.get_ext = get_ext + self.handlers = handlers + + def parse(self, backend, x509_obj): + extensions = [] + seen_oids = set() + for i in range(self.ext_count(backend, x509_obj)): + ext = self.get_ext(backend, x509_obj, i) + assert ext != backend._ffi.NULL + crit = backend._lib.X509_EXTENSION_get_critical(ext) + critical = crit == 1 + oid = x509.ObjectIdentifier(_obj2txt(backend, ext.object)) + if oid in seen_oids: + raise x509.DuplicateExtension( + "Duplicate {0} extension found".format(oid), oid + ) + try: + handler = self.handlers[oid] + except KeyError: + if critical: + raise x509.UnsupportedExtension( + "{0} is not currently supported".format(oid), oid + ) + else: + value = handler(backend, ext) + extensions.append(x509.Extension(oid, critical, value)) + + seen_oids.add(oid) + + return x509.Extensions(extensions) + + @utils.register_interface(x509.Certificate) class _Certificate(object): def __init__(self, backend, x509): @@ -258,68 +307,17 @@ class _Certificate(object): @property def extensions(self): - extensions = [] - seen_oids = set() - extcount = self._backend._lib.X509_get_ext_count(self._x509) - for i in range(0, extcount): - ext = self._backend._lib.X509_get_ext(self._x509, i) - assert ext != self._backend._ffi.NULL - crit = self._backend._lib.X509_EXTENSION_get_critical(ext) - critical = crit == 1 - oid = x509.ObjectIdentifier(_obj2txt(self._backend, ext.object)) - if oid in seen_oids: - raise x509.DuplicateExtension( - "Duplicate {0} extension found".format(oid), oid - ) - elif oid == x509.OID_BASIC_CONSTRAINTS: - value = _decode_basic_constraints(self._backend, ext) - elif oid == x509.OID_SUBJECT_KEY_IDENTIFIER: - value = _decode_subject_key_identifier(self._backend, ext) - elif oid == x509.OID_KEY_USAGE: - value = _decode_key_usage(self._backend, ext) - elif oid == x509.OID_SUBJECT_ALTERNATIVE_NAME: - value = _decode_subject_alt_name(self._backend, ext) - elif oid == x509.OID_EXTENDED_KEY_USAGE: - value = _decode_extended_key_usage(self._backend, ext) - elif oid == x509.OID_AUTHORITY_KEY_IDENTIFIER: - value = _decode_authority_key_identifier(self._backend, ext) - elif oid == x509.OID_AUTHORITY_INFORMATION_ACCESS: - value = _decode_authority_information_access( - self._backend, ext - ) - elif oid == x509.OID_CERTIFICATE_POLICIES: - value = _decode_certificate_policies(self._backend, ext) - elif oid == x509.OID_CRL_DISTRIBUTION_POINTS: - value = _decode_crl_distribution_points(self._backend, ext) - elif oid == x509.OID_OCSP_NO_CHECK: - value = x509.OCSPNoCheck() - elif oid == x509.OID_INHIBIT_ANY_POLICY: - value = _decode_inhibit_any_policy(self._backend, ext) - elif oid == x509.OID_ISSUER_ALTERNATIVE_NAME: - value = _decode_issuer_alt_name(self._backend, ext) - elif critical: - raise x509.UnsupportedExtension( - "{0} is not currently supported".format(oid), oid - ) - else: - # Unsupported non-critical extension, silently skipping for now - seen_oids.add(oid) - continue - - seen_oids.add(oid) - extensions.append(x509.Extension(oid, critical, value)) - - return x509.Extensions(extensions) + return _CERTIFICATE_EXTENSION_PARSER.parse(self._backend, self._x509) def public_bytes(self, encoding): - if not isinstance(encoding, serialization.Encoding): - raise TypeError("encoding must be an item from the Encoding enum") - bio = self._backend._create_mem_bio() if encoding is serialization.Encoding.PEM: res = self._backend._lib.PEM_write_bio_X509(bio, self._x509) elif encoding is serialization.Encoding.DER: res = self._backend._lib.i2d_X509_bio(bio, self._x509) + else: + raise TypeError("encoding must be an item from the Encoding enum") + assert res == 1 return self._backend._read_mem_bio(bio) @@ -694,40 +692,10 @@ class _CertificateSigningRequest(object): @property def extensions(self): - extensions = [] - seen_oids = set() x509_exts = self._backend._lib.X509_REQ_get_extensions(self._x509_req) - extcount = self._backend._lib.sk_X509_EXTENSION_num(x509_exts) - for i in range(0, extcount): - ext = self._backend._lib.sk_X509_EXTENSION_value(x509_exts, i) - assert ext != self._backend._ffi.NULL - crit = self._backend._lib.X509_EXTENSION_get_critical(ext) - critical = crit == 1 - oid = x509.ObjectIdentifier(_obj2txt(self._backend, ext.object)) - if oid in seen_oids: - raise x509.DuplicateExtension( - "Duplicate {0} extension found".format(oid), oid - ) - elif oid == x509.OID_BASIC_CONSTRAINTS: - value = _decode_basic_constraints(self._backend, ext) - elif critical: - raise x509.UnsupportedExtension( - "{0} is not currently supported".format(oid), oid - ) - else: - # Unsupported non-critical extension, silently skipping for now - seen_oids.add(oid) - continue - - seen_oids.add(oid) - extensions.append(x509.Extension(oid, critical, value)) - - return x509.Extensions(extensions) + return _CSR_EXTENSION_PARSER.parse(self._backend, x509_exts) def public_bytes(self, encoding): - if not isinstance(encoding, serialization.Encoding): - raise TypeError("encoding must be an item from the Encoding enum") - bio = self._backend._create_mem_bio() if encoding is serialization.Encoding.PEM: res = self._backend._lib.PEM_write_bio_X509_REQ( @@ -735,5 +703,38 @@ class _CertificateSigningRequest(object): ) elif encoding is serialization.Encoding.DER: res = self._backend._lib.i2d_X509_REQ_bio(bio, self._x509_req) + else: + raise TypeError("encoding must be an item from the Encoding enum") + assert res == 1 return self._backend._read_mem_bio(bio) + + +_CERTIFICATE_EXTENSION_PARSER = _X509ExtensionParser( + ext_count=lambda backend, x: backend._lib.X509_get_ext_count(x), + get_ext=lambda backend, x, i: backend._lib.X509_get_ext(x, i), + handlers={ + x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints, + x509.OID_SUBJECT_KEY_IDENTIFIER: _decode_subject_key_identifier, + x509.OID_KEY_USAGE: _decode_key_usage, + x509.OID_SUBJECT_ALTERNATIVE_NAME: _decode_subject_alt_name, + x509.OID_EXTENDED_KEY_USAGE: _decode_extended_key_usage, + x509.OID_AUTHORITY_KEY_IDENTIFIER: _decode_authority_key_identifier, + x509.OID_AUTHORITY_INFORMATION_ACCESS: ( + _decode_authority_information_access + ), + x509.OID_CERTIFICATE_POLICIES: _decode_certificate_policies, + x509.OID_CRL_DISTRIBUTION_POINTS: _decode_crl_distribution_points, + x509.OID_OCSP_NO_CHECK: _decode_ocsp_no_check, + x509.OID_INHIBIT_ANY_POLICY: _decode_inhibit_any_policy, + x509.OID_ISSUER_ALTERNATIVE_NAME: _decode_issuer_alt_name, + } +) + +_CSR_EXTENSION_PARSER = _X509ExtensionParser( + ext_count=lambda backend, x: backend._lib.sk_X509_EXTENSION_num(x), + get_ext=lambda backend, x, i: backend._lib.sk_X509_EXTENSION_value(x, i), + handlers={ + x509.OID_BASIC_CONSTRAINTS: _decode_basic_constraints, + } +) diff --git a/src/cryptography/hazmat/primitives/serialization.py b/src/cryptography/hazmat/primitives/serialization.py index 8699fa91..098b31dc 100644 --- a/src/cryptography/hazmat/primitives/serialization.py +++ b/src/cryptography/hazmat/primitives/serialization.py @@ -106,12 +106,11 @@ def _load_ssh_ecdsa_public_key(expected_key_type, decoded_data, backend): if rest: raise ValueError('Key body contains extra bytes.') - if curve_name == b"nistp256": - curve = ec.SECP256R1() - elif curve_name == b"nistp384": - curve = ec.SECP384R1() - elif curve_name == b"nistp521": - curve = ec.SECP521R1() + curve = { + b"nistp256": ec.SECP256R1, + b"nistp384": ec.SECP384R1, + b"nistp521": ec.SECP521R1, + }[curve_name]() if six.indexbytes(data, 0) != 4: raise NotImplementedError( @@ -123,8 +122,12 @@ def _load_ssh_ecdsa_public_key(expected_key_type, decoded_data, backend): if len(data) != 1 + 2 * ((curve.key_size + 7) // 8): raise ValueError("Malformed key bytes") - x = _int_from_bytes(data[1:1 + (curve.key_size + 7) // 8], byteorder='big') - y = _int_from_bytes(data[1 + (curve.key_size + 7) // 8:], byteorder='big') + x = utils.int_from_bytes( + data[1:1 + (curve.key_size + 7) // 8], byteorder='big' + ) + y = utils.int_from_bytes( + data[1 + (curve.key_size + 7) // 8:], byteorder='big' + ) return ec.EllipticCurvePublicNumbers(x, y, curve).public_key(backend) @@ -146,27 +149,9 @@ def _read_next_mpint(data): """ mpint_data, rest = _read_next_string(data) - return _int_from_bytes(mpint_data, byteorder='big', signed=False), rest - - -if hasattr(int, "from_bytes"): - _int_from_bytes = int.from_bytes -else: - def _int_from_bytes(data, byteorder, signed=False): - assert byteorder == 'big' - assert not signed - - if len(data) % 4 != 0: - data = (b'\x00' * (4 - (len(data) % 4))) + data - - result = 0 - - while len(data) > 0: - digit, = struct.unpack('>I', data[:4]) - result = (result << 32) + digit - data = data[4:] - - return result + return ( + utils.int_from_bytes(mpint_data, byteorder='big', signed=False), rest + ) class Encoding(Enum): diff --git a/src/cryptography/utils.py b/src/cryptography/utils.py index 0bf8c0ea..24afe612 100644 --- a/src/cryptography/utils.py +++ b/src/cryptography/utils.py @@ -6,6 +6,7 @@ from __future__ import absolute_import, division, print_function import abc import inspect +import struct import sys import warnings @@ -25,6 +26,26 @@ def register_interface(iface): return register_decorator +if hasattr(int, "from_bytes"): + int_from_bytes = int.from_bytes +else: + def int_from_bytes(data, byteorder, signed=False): + assert byteorder == 'big' + assert not signed + + if len(data) % 4 != 0: + data = (b'\x00' * (4 - (len(data) % 4))) + data + + result = 0 + + while len(data) > 0: + digit, = struct.unpack('>I', data[:4]) + result = (result << 32) + digit + data = data[4:] + + return result + + class InterfaceNotImplemented(Exception): pass diff --git a/src/cryptography/x509.py b/src/cryptography/x509.py index 0f72abb3..668bc2ef 100644 --- a/src/cryptography/x509.py +++ b/src/cryptography/x509.py @@ -1486,4 +1486,6 @@ class CertificateSigningRequestBuilder(object): """ Signs the request using the requestor's private key. """ + if self._subject_name is None: + raise ValueError("A CertificateSigningRequest must have a subject") return backend.create_x509_csr(self, private_key, algorithm) diff --git a/tests/hazmat/primitives/test_concatkdf.py b/tests/hazmat/primitives/test_concatkdf.py index 27e5460e..aa568c1f 100644 --- a/tests/hazmat/primitives/test_concatkdf.py +++ b/tests/hazmat/primitives/test_concatkdf.py @@ -158,6 +158,27 @@ class TestConcatKDFHMAC(object): assert ckdf.derive(prk) == okm + def test_derive_explicit_salt(self, backend): + prk = binascii.unhexlify( + b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4" + b"b831cde499dff1ce45f6179f741c728aa733583b02409208" + b"8f0af7fce1d045edbc5790931e8d5ca79c73" + ) + + okm = binascii.unhexlify(b"64ce901db10d558661f10b6836a122a7" + b"605323ce2f39bf27eaaac8b34cf89f2f") + + oinfo = binascii.unhexlify( + b"a1b2c3d4e55e600be5f367e0e8a465f4bf2704db00c9325c" + b"9fbd216d12b49160b2ae5157650f43415653696421e68e" + ) + + ckdf = ConcatKDFHMAC( + hashes.SHA512(), 32, b"\x00" * 128, oinfo, backend + ) + + assert ckdf.derive(prk) == okm + def test_verify(self, backend): prk = binascii.unhexlify( b"013951627c1dea63ea2d7702dd24e963eef5faac6b4af7e4" diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py index 5c83d5c7..b6b0de94 100644 --- a/tests/hazmat/primitives/test_dsa.py +++ b/tests/hazmat/primitives/test_dsa.py @@ -30,21 +30,6 @@ from ...utils import ( ) -def _skip_if_no_serialization(key, backend): - if not isinstance( - key, - (dsa.DSAPrivateKeyWithSerialization, dsa.DSAPublicKeyWithSerialization) - ): - pytest.skip( - "{0} does not support DSA key serialization".format(backend) - ) - - -def test_skip_if_no_serialization(): - with pytest.raises(pytest.skip.Exception): - _skip_if_no_serialization("notakeywithserialization", "backend") - - @utils.register_interface(serialization.KeySerializationEncryption) class DummyKeyEncryption(object): pass @@ -75,35 +60,33 @@ class TestDSA(object): g=vector['g'] ).parameters(backend) skey = parameters.generate_private_key() - if isinstance(skey, dsa.DSAPrivateKeyWithSerialization): - numbers = skey.private_numbers() - skey_parameters = numbers.public_numbers.parameter_numbers - pkey = skey.public_key() - parameters = pkey.parameters() - parameter_numbers = parameters.parameter_numbers() - assert parameter_numbers.p == skey_parameters.p - assert parameter_numbers.q == skey_parameters.q - assert parameter_numbers.g == skey_parameters.g - assert skey_parameters.p == vector['p'] - assert skey_parameters.q == vector['q'] - assert skey_parameters.g == vector['g'] - assert skey.key_size == bit_length(vector['p']) - assert pkey.key_size == skey.key_size - public_numbers = pkey.public_numbers() - assert numbers.public_numbers.y == public_numbers.y - assert numbers.public_numbers.y == pow( - skey_parameters.g, numbers.x, skey_parameters.p - ) + numbers = skey.private_numbers() + skey_parameters = numbers.public_numbers.parameter_numbers + pkey = skey.public_key() + parameters = pkey.parameters() + parameter_numbers = parameters.parameter_numbers() + assert parameter_numbers.p == skey_parameters.p + assert parameter_numbers.q == skey_parameters.q + assert parameter_numbers.g == skey_parameters.g + assert skey_parameters.p == vector['p'] + assert skey_parameters.q == vector['q'] + assert skey_parameters.g == vector['g'] + assert skey.key_size == bit_length(vector['p']) + assert pkey.key_size == skey.key_size + public_numbers = pkey.public_numbers() + assert numbers.public_numbers.y == public_numbers.y + assert numbers.public_numbers.y == pow( + skey_parameters.g, numbers.x, skey_parameters.p + ) def test_generate_dsa_private_key_and_parameters(self, backend): skey = dsa.generate_private_key(1024, backend) assert skey - if isinstance(skey, dsa.DSAPrivateKeyWithSerialization): - numbers = skey.private_numbers() - skey_parameters = numbers.public_numbers.parameter_numbers - assert numbers.public_numbers.y == pow( - skey_parameters.g, numbers.x, skey_parameters.p - ) + numbers = skey.private_numbers() + skey_parameters = numbers.public_numbers.parameter_numbers + assert numbers.public_numbers.y == pow( + skey_parameters.g, numbers.x, skey_parameters.p + ) def test_invalid_parameters_values(self, backend): # Test a p < 1024 bits in length @@ -819,7 +802,6 @@ class TestDSASerialization(object): lambda pemfile: pemfile.read().encode() ) key = serialization.load_pem_private_key(key_bytes, None, backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( serialization.Encoding.PEM, fmt, @@ -847,7 +829,6 @@ class TestDSASerialization(object): lambda pemfile: pemfile.read().encode() ) key = serialization.load_pem_private_key(key_bytes, None, backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( serialization.Encoding.DER, fmt, @@ -888,7 +869,6 @@ class TestDSASerialization(object): def test_private_bytes_unencrypted(self, backend, encoding, fmt, loader_func): key = DSA_KEY_1024.private_key(backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( encoding, fmt, serialization.NoEncryption() ) @@ -934,7 +914,6 @@ class TestDSASerialization(object): def test_private_bytes_traditional_der_encrypted_invalid(self, backend): key = DSA_KEY_1024.private_key(backend) - _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.DER, @@ -949,7 +928,6 @@ class TestDSASerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( "notencoding", @@ -964,7 +942,6 @@ class TestDSASerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, @@ -979,7 +956,6 @@ class TestDSASerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, @@ -994,7 +970,6 @@ class TestDSASerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.PEM, @@ -1030,7 +1005,6 @@ class TestDSAPEMPublicKeySerialization(object): key_path, lambda pemfile: pemfile.read(), mode="rb" ) key = loader_func(key_bytes, backend) - _skip_if_no_serialization(key, backend) serialized = key.public_bytes( encoding, serialization.PublicFormat.SubjectPublicKeyInfo, ) @@ -1038,7 +1012,6 @@ class TestDSAPEMPublicKeySerialization(object): def test_public_bytes_invalid_encoding(self, backend): key = DSA_KEY_2048.private_key(backend).public_key() - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.public_bytes( "notencoding", @@ -1047,13 +1020,11 @@ class TestDSAPEMPublicKeySerialization(object): def test_public_bytes_invalid_format(self, backend): key = DSA_KEY_2048.private_key(backend).public_key() - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.public_bytes(serialization.Encoding.PEM, "invalidformat") def test_public_bytes_pkcs1_unsupported(self, backend): key = DSA_KEY_2048.private_key(backend).public_key() - _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.public_bytes( serialization.Encoding.PEM, serialization.PublicFormat.PKCS1 diff --git a/tests/hazmat/primitives/test_ec.py b/tests/hazmat/primitives/test_ec.py index cc185145..20465a2d 100644 --- a/tests/hazmat/primitives/test_ec.py +++ b/tests/hazmat/primitives/test_ec.py @@ -33,18 +33,6 @@ _HASH_TYPES = { } -def _skip_if_no_serialization(key, backend): - if not isinstance( - key, ( - ec.EllipticCurvePrivateKeyWithSerialization, - ec.EllipticCurvePublicKeyWithSerialization - ) - ): - pytest.skip( - "{0} does not support EC key serialization".format(backend) - ) - - def _skip_ecdsa_vector(backend, curve_type, hash_type): if not backend.elliptic_curve_signature_algorithm_supported( ec.ECDSA(hash_type()), @@ -88,11 +76,6 @@ def test_skip_curve_unsupported(backend): _skip_curve_unsupported(backend, DummyCurve()) -def test_skip_no_serialization(): - with pytest.raises(pytest.skip.Exception): - _skip_if_no_serialization("fakebackend", "fakekey") - - def test_ec_numbers(): numbers = ec.EllipticCurvePrivateNumbers( 1, @@ -173,12 +156,11 @@ class TestECWithNumbers(object): ).private_key(backend) assert key - if isinstance(key, ec.EllipticCurvePrivateKeyWithSerialization): - priv_num = key.private_numbers() - assert priv_num.private_value == vector['d'] - assert priv_num.public_numbers.x == vector['x'] - assert priv_num.public_numbers.y == vector['y'] - assert curve_type().name == priv_num.public_numbers.curve.name + priv_num = key.private_numbers() + assert priv_num.private_value == vector['d'] + assert priv_num.public_numbers.x == vector['x'] + assert priv_num.public_numbers.y == vector['y'] + assert curve_type().name == priv_num.public_numbers.curve.name @pytest.mark.requires_backend_interface(interface=EllipticCurveBackend) @@ -437,7 +419,6 @@ class TestECSerialization(object): lambda pemfile: pemfile.read().encode() ) key = serialization.load_pem_private_key(key_bytes, None, backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( serialization.Encoding.PEM, fmt, @@ -467,7 +448,6 @@ class TestECSerialization(object): lambda pemfile: pemfile.read().encode() ) key = serialization.load_pem_private_key(key_bytes, None, backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( serialization.Encoding.DER, fmt, @@ -514,7 +494,6 @@ class TestECSerialization(object): lambda pemfile: pemfile.read().encode() ) key = serialization.load_pem_private_key(key_bytes, None, backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( encoding, fmt, serialization.NoEncryption() ) @@ -566,7 +545,6 @@ class TestECSerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.DER, @@ -583,7 +561,6 @@ class TestECSerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( "notencoding", @@ -600,7 +577,6 @@ class TestECSerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, @@ -617,7 +593,6 @@ class TestECSerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, @@ -634,7 +609,6 @@ class TestECSerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.PEM, @@ -651,7 +625,6 @@ class TestECSerialization(object): pemfile.read().encode(), None, backend ) ) - _skip_if_no_serialization(key, backend) public = key.public_key() pem = public.public_bytes( serialization.Encoding.PEM, @@ -689,7 +662,6 @@ class TestEllipticCurvePEMPublicKeySerialization(object): key_path, lambda pemfile: pemfile.read(), mode="rb" ) key = loader_func(key_bytes, backend) - _skip_if_no_serialization(key, backend) serialized = key.public_bytes( encoding, serialization.PublicFormat.SubjectPublicKeyInfo, ) @@ -705,7 +677,6 @@ class TestEllipticCurvePEMPublicKeySerialization(object): pemfile.read().encode(), backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.public_bytes( "notencoding", @@ -722,7 +693,6 @@ class TestEllipticCurvePEMPublicKeySerialization(object): pemfile.read().encode(), backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.public_bytes(serialization.Encoding.PEM, "invalidformat") @@ -736,7 +706,6 @@ class TestEllipticCurvePEMPublicKeySerialization(object): pemfile.read().encode(), backend ) ) - _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.public_bytes( serialization.Encoding.PEM, serialization.PublicFormat.PKCS1 diff --git a/tests/hazmat/primitives/test_rsa.py b/tests/hazmat/primitives/test_rsa.py index eb12df8d..bfeab8dd 100644 --- a/tests/hazmat/primitives/test_rsa.py +++ b/tests/hazmat/primitives/test_rsa.py @@ -85,21 +85,6 @@ def test_modular_inverse(): ) -def _skip_if_no_serialization(key, backend): - if not isinstance( - key, - (rsa.RSAPrivateKeyWithSerialization, rsa.RSAPublicKeyWithSerialization) - ): - pytest.skip( - "{0} does not support RSA key serialization".format(backend) - ) - - -def test_skip_if_no_serialization(): - with pytest.raises(pytest.skip.Exception): - _skip_if_no_serialization("notakeywithserialization", "backend") - - @pytest.mark.requires_backend_interface(interface=RSABackend) class TestRSA(object): @pytest.mark.parametrize( @@ -113,10 +98,9 @@ class TestRSA(object): skey = rsa.generate_private_key(public_exponent, key_size, backend) assert skey.key_size == key_size - if isinstance(skey, rsa.RSAPrivateKeyWithSerialization): - _check_rsa_private_numbers(skey.private_numbers()) - pkey = skey.public_key() - assert isinstance(pkey.public_numbers(), rsa.RSAPublicNumbers) + _check_rsa_private_numbers(skey.private_numbers()) + pkey = skey.public_key() + assert isinstance(pkey.public_numbers(), rsa.RSAPublicNumbers) def test_generate_bad_public_exponent(self, backend): with pytest.raises(ValueError): @@ -1769,7 +1753,6 @@ class TestRSAPrivateKeySerialization(object): ) def test_private_bytes_encrypted_pem(self, backend, fmt, password): key = RSA_KEY_2048.private_key(backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( serialization.Encoding.PEM, fmt, @@ -1793,7 +1776,6 @@ class TestRSAPrivateKeySerialization(object): ) def test_private_bytes_encrypted_der(self, backend, fmt, password): key = RSA_KEY_2048.private_key(backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( serialization.Encoding.DER, fmt, @@ -1834,7 +1816,6 @@ class TestRSAPrivateKeySerialization(object): def test_private_bytes_unencrypted(self, backend, encoding, fmt, loader_func): key = RSA_KEY_2048.private_key(backend) - _skip_if_no_serialization(key, backend) serialized = key.private_bytes( encoding, fmt, serialization.NoEncryption() ) @@ -1878,7 +1859,6 @@ class TestRSAPrivateKeySerialization(object): def test_private_bytes_traditional_der_encrypted_invalid(self, backend): key = RSA_KEY_2048.private_key(backend) - _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.DER, @@ -1888,7 +1868,6 @@ class TestRSAPrivateKeySerialization(object): def test_private_bytes_invalid_encoding(self, backend): key = RSA_KEY_2048.private_key(backend) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( "notencoding", @@ -1898,7 +1877,6 @@ class TestRSAPrivateKeySerialization(object): def test_private_bytes_invalid_format(self, backend): key = RSA_KEY_2048.private_key(backend) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, @@ -1908,7 +1886,6 @@ class TestRSAPrivateKeySerialization(object): def test_private_bytes_invalid_encryption_algorithm(self, backend): key = RSA_KEY_2048.private_key(backend) - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.private_bytes( serialization.Encoding.PEM, @@ -1918,7 +1895,6 @@ class TestRSAPrivateKeySerialization(object): def test_private_bytes_unsupported_encryption_type(self, backend): key = RSA_KEY_2048.private_key(backend) - _skip_if_no_serialization(key, backend) with pytest.raises(ValueError): key.private_bytes( serialization.Encoding.PEM, @@ -1966,18 +1942,15 @@ class TestRSAPEMPublicKeySerialization(object): key_path, lambda pemfile: pemfile.read(), mode="rb" ) key = loader_func(key_bytes, backend) - _skip_if_no_serialization(key, backend) serialized = key.public_bytes(encoding, format) assert serialized == key_bytes def test_public_bytes_invalid_encoding(self, backend): key = RSA_KEY_2048.private_key(backend).public_key() - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.public_bytes("notencoding", serialization.PublicFormat.PKCS1) def test_public_bytes_invalid_format(self, backend): key = RSA_KEY_2048.private_key(backend).public_key() - _skip_if_no_serialization(key, backend) with pytest.raises(TypeError): key.public_bytes(serialization.Encoding.PEM, "invalidformat") diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 22c2145c..af605830 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -53,8 +53,7 @@ class TestDERSerialization(object): ) assert key assert isinstance(key, rsa.RSAPrivateKey) - if isinstance(key, rsa.RSAPrivateKeyWithSerialization): - _check_rsa_private_numbers(key.private_numbers()) + _check_rsa_private_numbers(key.private_numbers()) @pytest.mark.requires_backend_interface(interface=DSABackend) @pytest.mark.parametrize( @@ -76,8 +75,7 @@ class TestDERSerialization(object): ) assert key assert isinstance(key, dsa.DSAPrivateKey) - if isinstance(key, dsa.DSAPrivateKeyWithSerialization): - _check_dsa_private_numbers(key.private_numbers()) + _check_dsa_private_numbers(key.private_numbers()) @pytest.mark.parametrize( ("key_path", "password"), @@ -247,9 +245,8 @@ class TestDERSerialization(object): ) assert key assert isinstance(key, rsa.RSAPublicKey) - if isinstance(key, rsa.RSAPublicKeyWithSerialization): - numbers = key.public_numbers() - assert numbers.e == 65537 + numbers = key.public_numbers() + assert numbers.e == 65537 def test_load_der_invalid_public_key(self, backend): with pytest.raises(ValueError): @@ -330,8 +327,7 @@ class TestPEMSerialization(object): assert key assert isinstance(key, rsa.RSAPrivateKey) - if isinstance(key, rsa.RSAPrivateKeyWithSerialization): - _check_rsa_private_numbers(key.private_numbers()) + _check_rsa_private_numbers(key.private_numbers()) @pytest.mark.parametrize( ("key_path", "password"), @@ -352,8 +348,7 @@ class TestPEMSerialization(object): ) assert key assert isinstance(key, dsa.DSAPrivateKey) - if isinstance(key, dsa.DSAPrivateKeyWithSerialization): - _check_dsa_private_numbers(key.private_numbers()) + _check_dsa_private_numbers(key.private_numbers()) @pytest.mark.parametrize( ("key_path", "password"), @@ -397,9 +392,8 @@ class TestPEMSerialization(object): ) assert key assert isinstance(key, rsa.RSAPublicKey) - if isinstance(key, rsa.RSAPublicKeyWithSerialization): - numbers = key.public_numbers() - assert numbers.e == 65537 + numbers = key.public_numbers() + assert numbers.e == 65537 @pytest.mark.parametrize( ("key_file"), @@ -770,41 +764,40 @@ class TestPEMSerialization(object): params = key.parameters() assert isinstance(params, dsa.DSAParameters) - if isinstance(params, dsa.DSAParametersWithNumbers): - num = key.private_numbers() - pub = num.public_numbers - parameter_numbers = pub.parameter_numbers - assert num.x == int("00a535a8e1d0d91beafc8bee1d9b2a3a8de3311203", - 16) - assert pub.y == int( - "2b260ea97dc6a12ae932c640e7df3d8ff04a8a05a0324f8d5f1b23f15fa1" - "70ff3f42061124eff2586cb11b49a82dcdc1b90fc6a84fb10109cb67db5d" - "2da971aeaf17be5e37284563e4c64d9e5fc8480258b319f0de29d54d8350" - "70d9e287914d77df81491f4423b62da984eb3f45eb2a29fcea5dae525ac6" - "ab6bcce04bfdf5b6", - 16 - ) + num = key.private_numbers() + pub = num.public_numbers + parameter_numbers = pub.parameter_numbers + assert num.x == int("00a535a8e1d0d91beafc8bee1d9b2a3a8de3311203", + 16) + assert pub.y == int( + "2b260ea97dc6a12ae932c640e7df3d8ff04a8a05a0324f8d5f1b23f15fa1" + "70ff3f42061124eff2586cb11b49a82dcdc1b90fc6a84fb10109cb67db5d" + "2da971aeaf17be5e37284563e4c64d9e5fc8480258b319f0de29d54d8350" + "70d9e287914d77df81491f4423b62da984eb3f45eb2a29fcea5dae525ac6" + "ab6bcce04bfdf5b6", + 16 + ) - assert parameter_numbers.p == int( - "00aa0930cc145825221caffa28ac2894196a27833de5ec21270791689420" - "7774a2e7b238b0d36f1b2499a2c2585083eb01432924418d867faa212dd1" - "071d4dceb2782794ad393cc08a4d4ada7f68d6e839a5fcd34b4e402d82cb" - "8a8cb40fec31911bf9bd360b034caacb4c5e947992573c9e90099c1b0f05" - "940cabe5d2de49a167", - 16 - ) + assert parameter_numbers.p == int( + "00aa0930cc145825221caffa28ac2894196a27833de5ec21270791689420" + "7774a2e7b238b0d36f1b2499a2c2585083eb01432924418d867faa212dd1" + "071d4dceb2782794ad393cc08a4d4ada7f68d6e839a5fcd34b4e402d82cb" + "8a8cb40fec31911bf9bd360b034caacb4c5e947992573c9e90099c1b0f05" + "940cabe5d2de49a167", + 16 + ) - assert parameter_numbers.q == int( - "00adc0e869b36f0ac013a681fdf4d4899d69820451", 16) + assert parameter_numbers.q == int( + "00adc0e869b36f0ac013a681fdf4d4899d69820451", 16) - assert parameter_numbers.g == int( - "008c6b4589afa53a4d1048bfc346d1f386ca75521ccf72ddaa251286880e" - "e13201ff48890bbfc33d79bacaec71e7a778507bd5f1a66422e39415be03" - "e71141ba324f5b93131929182c88a9fa4062836066cebe74b5c6690c7d10" - "1106c240ab7ebd54e4e3301fd086ce6adac922fb2713a2b0887cba13b9bc" - "68ce5cfff241cd3246", - 16 - ) + assert parameter_numbers.g == int( + "008c6b4589afa53a4d1048bfc346d1f386ca75521ccf72ddaa251286880e" + "e13201ff48890bbfc33d79bacaec71e7a778507bd5f1a66422e39415be03" + "e71141ba324f5b93131929182c88a9fa4062836066cebe74b5c6690c7d10" + "1106c240ab7ebd54e4e3301fd086ce6adac922fb2713a2b0887cba13b9bc" + "68ce5cfff241cd3246", + 16 + ) @pytest.mark.parametrize( ("key_file", "password"), diff --git a/tests/test_x509.py b/tests/test_x509.py index 08dae0ce..df315cc3 100644 --- a/tests/test_x509.py +++ b/tests/test_x509.py @@ -687,11 +687,21 @@ class TestCertificateSigningRequestBuilder(object): def test_sign_invalid_hash_algorithm(self, backend): private_key = RSA_KEY_2048.private_key(backend) - builder = x509.CertificateSigningRequestBuilder() + builder = x509.CertificateSigningRequestBuilder().subject_name( + x509.Name([]) + ) with pytest.raises(TypeError): builder.sign(private_key, 'NotAHash', backend) @pytest.mark.requires_backend_interface(interface=RSABackend) + def test_no_subject_name(self, backend): + private_key = RSA_KEY_2048.private_key(backend) + + builder = x509.CertificateSigningRequestBuilder() + with pytest.raises(ValueError): + builder.sign(private_key, hashes.SHA256(), backend) + + @pytest.mark.requires_backend_interface(interface=RSABackend) def test_build_ca_request_with_rsa(self, backend): private_key = RSA_KEY_2048.private_key(backend) @@ -887,44 +897,43 @@ class TestDSACertificate(object): assert isinstance(cert.signature_hash_algorithm, hashes.SHA1) public_key = cert.public_key() assert isinstance(public_key, dsa.DSAPublicKey) - if isinstance(public_key, dsa.DSAPublicKeyWithSerialization): - num = public_key.public_numbers() - assert num.y == int( - "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94" - "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2" - "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2" - "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b" - "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6" - "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386" - "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2" - "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632" - "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16 - ) - assert num.parameter_numbers.g == int( - "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67" - "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b" - "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2" - "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa" - "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f" - "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a" - "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0" - "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76" - "fa6247676a6d3ac945844a083509c6a1b436baca", 16 - ) - assert num.parameter_numbers.p == int( - "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3" - "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330" - "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e" - "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a" - "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4" - "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2" - "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93" - "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d" - "833e36468f3907cfca788a3cb790f0341c8a31bf", 16 - ) - assert num.parameter_numbers.q == int( - "822ff5d234e073b901cf5941f58e1f538e71d40d", 16 - ) + num = public_key.public_numbers() + assert num.y == int( + "4c08bfe5f2d76649c80acf7d431f6ae2124b217abc8c9f6aca776ddfa94" + "53b6656f13e543684cd5f6431a314377d2abfa068b7080cb8ddc065afc2" + "dea559f0b584c97a2b235b9b69b46bc6de1aed422a6f341832618bcaae2" + "198aba388099dafb05ff0b5efecb3b0ae169a62e1c72022af50ae68af3b" + "033c18e6eec1f7df4692c456ccafb79cc7e08da0a5786e9816ceda651d6" + "1b4bb7b81c2783da97cea62df67af5e85991fdc13aff10fc60e06586386" + "b96bb78d65750f542f86951e05a6d81baadbcd35a2e5cad4119923ae6a2" + "002091a3d17017f93c52970113cdc119970b9074ca506eac91c3dd37632" + "5df4af6b3911ef267d26623a5a1c5df4a6d13f1c", 16 + ) + assert num.parameter_numbers.g == int( + "4b7ced71dc353965ecc10d441a9a06fc24943a32d66429dd5ef44d43e67" + "d789d99770aec32c0415dc92970880872da45fef8dd1e115a3e4801387b" + "a6d755861f062fd3b6e9ea8e2641152339b828315b1528ee6c7b79458d2" + "1f3db973f6fc303f9397174c2799dd2351282aa2d8842c357a73495bbaa" + "c4932786414c55e60d73169f5761036fba29e9eebfb049f8a3b1b7cee6f" + "3fbfa136205f130bee2cf5b9c38dc1095d4006f2e73335c07352c64130a" + "1ab2b89f13b48f628d3cc3868beece9bb7beade9f830eacc6fa241425c0" + "b3fcc0df416a0c89f7bf35668d765ec95cdcfbe9caff49cfc156c668c76" + "fa6247676a6d3ac945844a083509c6a1b436baca", 16 + ) + assert num.parameter_numbers.p == int( + "bfade6048e373cd4e48b677e878c8e5b08c02102ae04eb2cb5c46a523a3" + "af1c73d16b24f34a4964781ae7e50500e21777754a670bd19a7420d6330" + "84e5556e33ca2c0e7d547ea5f46a07a01bf8669ae3bdec042d9b2ae5e6e" + "cf49f00ba9dac99ab6eff140d2cedf722ee62c2f9736857971444c25d0a" + "33d2017dc36d682a1054fe2a9428dda355a851ce6e6d61e03e419fd4ca4" + "e703313743d86caa885930f62ed5bf342d8165627681e9cc3244ba72aa2" + "2148400a6bbe80154e855d042c9dc2a3405f1e517be9dea50562f56da93" + "f6085f844a7e705c1f043e65751c583b80d29103e590ccb26efdaa0893d" + "833e36468f3907cfca788a3cb790f0341c8a31bf", 16 + ) + assert num.parameter_numbers.q == int( + "822ff5d234e073b901cf5941f58e1f538e71d40d", 16 + ) @pytest.mark.parametrize( ("path", "loader_func"), @@ -968,17 +977,16 @@ class TestECDSACertificate(object): assert isinstance(cert.signature_hash_algorithm, hashes.SHA384) public_key = cert.public_key() assert isinstance(public_key, ec.EllipticCurvePublicKey) - if isinstance(public_key, ec.EllipticCurvePublicKeyWithSerialization): - num = public_key.public_numbers() - assert num.x == int( - "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f" - "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16 - ) - assert num.y == int( - "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7" - "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16 - ) - assert isinstance(num.curve, ec.SECP384R1) + num = public_key.public_numbers() + assert num.x == int( + "dda7d9bb8ab80bfb0b7f21d2f0bebe73f3335d1abc34eadec69bbcd095f" + "6f0ccd00bba615b51467e9e2d9fee8e630c17", 16 + ) + assert num.y == int( + "ec0770f5cf842e40839ce83f416d3badd3a4145936789d0343ee10136c7" + "2deae88a7a16bb543ce67dc23ff031ca3e23e", 16 + ) + assert isinstance(num.curve, ec.SECP384R1) def test_load_ecdsa_no_named_curve(self, backend): _skip_curve_unsupported(backend, ec.SECP256R1()) diff --git a/tests/test_x509_ext.py b/tests/test_x509_ext.py index cacc0573..6d91ba41 100644 --- a/tests/test_x509_ext.py +++ b/tests/test_x509_ext.py @@ -1351,6 +1351,37 @@ class TestRSASubjectAlternativeNameExtension(object): dns = san.get_values_for_type(x509.DNSName) assert dns == [u"www.cryptography.io", u"cryptography.io"] + def test_wildcard_dns_name(self, backend): + cert = _load_cert( + os.path.join("x509", "wildcard_san.pem"), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_SUBJECT_ALTERNATIVE_NAME + ) + + dns = ext.value.get_values_for_type(x509.DNSName) + assert dns == [ + u'*.langui.sh', + u'langui.sh', + u'*.saseliminator.com', + u'saseliminator.com' + ] + + def test_san_wildcard_idna_dns_name(self, backend): + cert = _load_cert( + os.path.join("x509", "custom", "san_wildcard_idna.pem"), + x509.load_pem_x509_certificate, + backend + ) + ext = cert.extensions.get_extension_for_oid( + x509.OID_SUBJECT_ALTERNATIVE_NAME + ) + + dns = ext.value.get_values_for_type(x509.DNSName) + assert dns == [u'*.\u043f\u044b\u043a\u0430.cryptography'] + def test_unsupported_other_name(self, backend): cert = _load_cert( os.path.join( diff --git a/tests/utils.py b/tests/utils.py index 46d93646..8be5c1fa 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -397,10 +397,7 @@ def load_fips_dsa_key_pair_vectors(vector_data): elif line.startswith("[mod = L=3072"): continue - if not reading_key_data: - continue - - elif reading_key_data: + if reading_key_data: if line.startswith("P"): vectors.append({'p': int(line.split("=")[1], 16)}) elif line.startswith("Q"): diff --git a/vectors/cryptography_vectors/x509/custom/nc_invalid_ip_netmask.pem b/vectors/cryptography_vectors/x509/custom/nc_invalid_ip_netmask.pem new file mode 100644 index 00000000..42f7fd37 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/nc_invalid_ip_netmask.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgITBm/Wnt8Tt9uB01YkE0oW0WAn8DANBgkqhkiG9w0BAQsF +ADAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUwNjI3MjMzNDI1WhcNMTYw +NjI2MjMzNDI1WjAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCylTa0WkLvIXB4sWoPdv5iL3idlVHKR+ncODKL +nwQ2Jtd990MfakOFRLrJFF1tfPL4qyRbbyMyrgCOoKBCAuIdBZfBDH3JWFjxGy8J +Yls8yVeAVKreV18HmLvAsBL3bnr7Gk3vpznrfoG5rn5T/fL0cqqTXFV8zQhjHiEo +zftSaoq0LOxsSgFdxXS8e8K6RMvLCZPcMpI4fo1Kq2QBT2J1x1/Hq/VnK132cs0g +TOyiTyyJfvRmlqdXowh7Jf8LQB4mM6gc023fEdQ+HH6JYX1vDQVxaiTM6KMYJNv/ +l4gchP3jknOfZffwGGdXQrtUMhQmltnSqV5nY/G2OGm/Z0pdAgMBAAGjNjA0MDIG +A1UdHgEB/wQoMCagJDAihyAA/wAAAAAAAAAAAAAAAAAA/////wAA/////wD/AAAA +ADANBgkqhkiG9w0BAQsFAAOCAQEALGCUUKrfrDkuezZmG5ibkAYOMl2jwc6qmyRO +GzAeh1xgJpyG4Cz6E57PZwFJiU7WsagW75xiuhyt3BvjEob9TaHmkPka16SdJBP2 +6fkzUHu9HKJbJ5GNzPrcJJG0IQB9Vdqs2D3qrpNC6IQ80PLPaT8Lq3L6Na8c2VrQ +Y80eHVxiTllDFy8NGIu5nvuKinLSW/O/WNH7M0pkQ9clFR7R+bGNwGrTJ9pKhgGK +fNJU7CT5HTViMQmN49c3B6JrdBblBI/q3SLTqxqa0Qwp2ZH2fYjCszO3QdpPlbQD +N8kfs6qmNhkvfIDWMNdQBqhnhuOJ8FJLo1/xYP1ziigg+ajN8g== +-----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/custom/nc_permitted_2.pem b/vectors/cryptography_vectors/x509/custom/nc_permitted_2.pem new file mode 100644 index 00000000..05a904f5 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/nc_permitted_2.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3DCCAcSgAwIBAgITBm/6kAXHpw8f3guDBcRXNLfl5DANBgkqhkiG9w0BAQsF +ADAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUwNjI5MDkzMjQ5WhcNMTYw +NjI4MDkzMjQ5WjAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCylTa0WkLvIXB4sWoPdv5iL3idlVHKR+ncODKL +nwQ2Jtd990MfakOFRLrJFF1tfPL4qyRbbyMyrgCOoKBCAuIdBZfBDH3JWFjxGy8J +Yls8yVeAVKreV18HmLvAsBL3bnr7Gk3vpznrfoG5rn5T/fL0cqqTXFV8zQhjHiEo +zftSaoq0LOxsSgFdxXS8e8K6RMvLCZPcMpI4fo1Kq2QBT2J1x1/Hq/VnK132cs0g +TOyiTyyJfvRmlqdXowh7Jf8LQB4mM6gc023fEdQ+HH6JYX1vDQVxaiTM6KMYJNv/ +l4gchP3jknOfZffwGGdXQrtUMhQmltnSqV5nY/G2OGm/Z0pdAgMBAAGjITAfMB0G +A1UdHgEB/wQTMBGgDzANggt6b21iby5sb2NhbDANBgkqhkiG9w0BAQsFAAOCAQEA +WcDkqLUsvIBfTzKncOSiy08lcwu+kq/8rybh4HoHEimcy47M+XLPnXqwA7jedz8M +Znog64O9wZ1olWs+GGrGcJAth2BqdNtRvb6/o2Hq29vNbCQeYRlOTdNzGnb5v6fB +HEPvuB7UNKyaJ2tF50oxqhg8ojgauX3fuanCtR9Obx/2U8e8zfBIauX13XfpoCyt +efeL97kYz+XIQwG8TvXpNdHO0QjmA/ToR7E5BbSo2e4cicKEomtLhKI7EXa+Ofwg +HoyVC8wl97nm7mwI7iFYK5f8YoqwILxKEP6O9+pZEOveqdKfx4+WAgeGyDvBwAjf +Ej8vkawtdgV/96ajsIqzDQ== +-----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded.pem b/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded.pem index 13f26ca6..7c92eaf1 100644 --- a/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded.pem +++ b/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded.pem @@ -1,19 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDIzCCAgugAwIBAgITBm9f6VBd37JBCGQYKoXvtJ0PbDANBgkqhkiG9w0BAQsF -ADAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUwNjIzMDcyMTU4WhcNMTYw -NjIyMDcyMTU4WjAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwggEiMA0GCSqGSIb3 +MIIDIzCCAgugAwIBAgITBm/Wc4kdp3PUxItnkeVsX2BhETANBgkqhkiG9w0BAQsF +ADAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUwNjI3MjMyNDQ5WhcNMTYw +NjI2MjMyNDQ5WjAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwggEiMA0GCSqGSIb3 DQEBAQUAA4IBDwAwggEKAoIBAQCylTa0WkLvIXB4sWoPdv5iL3idlVHKR+ncODKL nwQ2Jtd990MfakOFRLrJFF1tfPL4qyRbbyMyrgCOoKBCAuIdBZfBDH3JWFjxGy8J Yls8yVeAVKreV18HmLvAsBL3bnr7Gk3vpznrfoG5rn5T/fL0cqqTXFV8zQhjHiEo zftSaoq0LOxsSgFdxXS8e8K6RMvLCZPcMpI4fo1Kq2QBT2J1x1/Hq/VnK132cs0g TOyiTyyJfvRmlqdXowh7Jf8LQB4mM6gc023fEdQ+HH6JYX1vDQVxaiTM6KMYJNv/ l4gchP3jknOfZffwGGdXQrtUMhQmltnSqV5nY/G2OGm/Z0pdAgMBAAGjaDBmMGQG -A1UdHgEB/wRaMFigMDAKhwjAqAAA////ADAihyAA/wAAAAAAAAAAAAAAAAAAAP8A -AAAAAAAAAAAAAAAA/6EkMA2CCy5kb21haW4uY29tMBOGEWh0dHA6Ly90ZXN0Lmxv -Y2FsMA0GCSqGSIb3DQEBCwUAA4IBAQAKS62+aFz7T7Vt2K5/dHWE8sqh9g86veQL -wBQPG+6ysG4QkQQOiS4CUwOCf4S3quS0pXn+UeJsQKistjFWxoVIrLhEaCPMjpwX -2LSnQQVBF4YCOnnGyGD1m4hCH1j3hWkHKwPLCcQ7LQ6a1a7CKHLitVxWGWUW+CM+ -NYxt/mon5rYZTomI6p1eVsdrq7Ma942HbgvvQBT8EJjrNGRbH9RV7mGj1ZxBdyyX -Li7iLk670nIzTG/DfA+yckU5vZkrhicezhsLqXYwhzWUpmWp68vehj0zd25qHP2k -lCXgYIHtlc9m8p/Io4eRM/Kx8qMsMGe8l7FI8j9uNNZGHt0ecdbX +A1UdHgEB/wRaMFigMDAKhwjAqAAA////ADAihyAA/wAAAAAAAAAAAAAAAAAA//// +////////////AAAAAKEkMA2CCy5kb21haW4uY29tMBOGEWh0dHA6Ly90ZXN0Lmxv +Y2FsMA0GCSqGSIb3DQEBCwUAA4IBAQCA+WJUYgrKl4XG/zNL9EcxMexWrJAfpGf8 +wcBpvG7Xko0OBdLhspylDL2wDGh1tqAwBCqxJHoDwxuYLJdN7uc4Zq75RCa6aP8C +Lq8gcSlO4TNrFB2GCnHaFNkDpvSBIDkWdqHZr9IykNZ2KhPB+/rKxZGlaupATUSO +aYKJ/8Vl62IpNLx1KqVtNM8pCyiWO8Eru2NVWoqwmTRKnyWhFLi/kWNn7A76EsQF +9skfHoZGlGY69pklyY92y6c7eLma4l6DzRwxut3dNCM1AFtdFoN+RRyYduwTN9qo +dMmAD6sb6wn0a+Ss6K20lJv/DQc4A3nFPKzKFmZh5RwO4f+hUSAe -----END CERTIFICATE----- diff --git a/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded_2.pem b/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded_2.pem new file mode 100644 index 00000000..2cdf1d68 --- /dev/null +++ b/vectors/cryptography_vectors/x509/custom/nc_permitted_excluded_2.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9DCCAdygAwIBAgITBm/3q66sET2C+Ko/TLr1EHnvdTANBgkqhkiG9w0BAQsF +ADAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwHhcNMTUwNjI5MDY0ODQ4WhcNMTYw +NjI4MDY0ODQ4WjAXMRUwEwYDVQQDDAxjcnlwdG9ncmFwaHkwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQCylTa0WkLvIXB4sWoPdv5iL3idlVHKR+ncODKL +nwQ2Jtd990MfakOFRLrJFF1tfPL4qyRbbyMyrgCOoKBCAuIdBZfBDH3JWFjxGy8J +Yls8yVeAVKreV18HmLvAsBL3bnr7Gk3vpznrfoG5rn5T/fL0cqqTXFV8zQhjHiEo +zftSaoq0LOxsSgFdxXS8e8K6RMvLCZPcMpI4fo1Kq2QBT2J1x1/Hq/VnK132cs0g +TOyiTyyJfvRmlqdXowh7Jf8LQB4mM6gc023fEdQ+HH6JYX1vDQVxaiTM6KMYJNv/ +l4gchP3jknOfZffwGGdXQrtUMhQmltnSqV5nY/G2OGm/Z0pdAgMBAAGjOTA3MDUG +A1UdHgEB/wQrMCmgDzANggt6b21iby5sb2NhbKEWMBSkEjAQMQ4wDAYDVQQDDAV6 +b21ibzANBgkqhkiG9w0BAQsFAAOCAQEAaSyuJlNVZkkwHn4V9EglOTm6DC/lzrLm +1y/qcXsY2NXgCRfpZal0lx25M7Dl2G1IOBG+Ub1/ua0NASlpd6BeZ4prmcD4OBib +oAhMJxt8QNNwkcMG5PnI6reQz5MiRwGOCEAZeX1opIijn/tO49RliEnEQCKbsvdr +d+0ieNhLdoxazW/k3UCu+Vdd1b3TOLERrhm/xGj2W9AhWAv7GIovhBGGfuD6BFmC +uHjxoG0So//NiHTfZ9eukgW3rNSbjQjtnC8BsRzUdhX/YBvw+SKkeVL2oz7+lRgD +fhba3FtwUfCIX3y/UAc0E0+x9bLFDyQXYNHAXq+q72sOkLXgAH8bfQ== +-----END CERTIFICATE----- |