From 9470f67a3086e4c003ab27ca6a2209dae9b1a9e6 Mon Sep 17 00:00:00 2001 From: Marko Kreen Date: Mon, 25 May 2020 21:17:25 +0300 Subject: Cleanup serialize (#5149) * Additional tests for public/private_bytes They expose few places that raise TypeError and AssertionError! before, and ValueError later. * Cleanup of private_bytes() backend Also pass key itself down to backend. * Cleanup of public_bytes() backend * Test handling of unsupported key type --- .../hazmat/backends/openssl/backend.py | 200 ++++++++++----------- src/cryptography/hazmat/backends/openssl/dh.py | 1 + src/cryptography/hazmat/backends/openssl/dsa.py | 8 +- src/cryptography/hazmat/backends/openssl/ec.py | 5 +- .../hazmat/backends/openssl/ed25519.py | 19 +- src/cryptography/hazmat/backends/openssl/ed448.py | 19 +- src/cryptography/hazmat/backends/openssl/rsa.py | 1 + src/cryptography/hazmat/backends/openssl/x25519.py | 19 +- src/cryptography/hazmat/backends/openssl/x448.py | 19 +- .../hazmat/primitives/serialization/__init__.py | 2 - tests/hazmat/primitives/test_serialization.py | 123 ++++++++++++- 11 files changed, 223 insertions(+), 193 deletions(-) diff --git a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py index 6fd191f0..e5b64e3d 100644 --- a/src/cryptography/hazmat/backends/openssl/backend.py +++ b/src/cryptography/hazmat/backends/openssl/backend.py @@ -1746,26 +1746,14 @@ class Backend(object): return ctx def _private_key_bytes(self, encoding, format, encryption_algorithm, - evp_pkey, cdata): + key, evp_pkey, cdata): + # validate argument types + 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" ) - - # X9.62 encoding is only valid for EC public keys - if encoding is serialization.Encoding.X962: - raise ValueError("X9.62 format is only valid for EC public keys") - - # Raw format and encoding are only valid for X25519, Ed25519, X448, and - # Ed448 keys. We capture those cases before this method is called so if - # we see those enum values here it means the caller has passed them to - # a key that doesn't support raw type - if format is serialization.PrivateFormat.Raw: - raise ValueError("raw format is invalid with this key or encoding") - - if encoding is serialization.Encoding.Raw: - raise ValueError("raw encoding is invalid with this key or format") - if not isinstance(encryption_algorithm, serialization.KeySerializationEncryption): raise TypeError( @@ -1773,19 +1761,13 @@ class Backend(object): "instance" ) + # validate password if isinstance(encryption_algorithm, serialization.NoEncryption): password = b"" - passlen = 0 - evp_cipher = self._ffi.NULL elif isinstance(encryption_algorithm, serialization.BestAvailableEncryption): - # This is a curated value that we will update over time. - evp_cipher = self._lib.EVP_get_cipherbyname( - b"aes-256-cbc" - ) password = encryption_algorithm.password - passlen = len(password) - if passlen > 1023: + if len(password) > 1023: raise ValueError( "Passwords longer than 1023 bytes are not supported by " "this backend" @@ -1793,127 +1775,135 @@ class Backend(object): else: raise ValueError("Unsupported encryption type") - key_type = self._lib.EVP_PKEY_id(evp_pkey) - if encoding is serialization.Encoding.PEM: - if format is serialization.PrivateFormat.PKCS8: + # PKCS8 + PEM/DER + if format is serialization.PrivateFormat.PKCS8: + if encoding is serialization.Encoding.PEM: write_bio = self._lib.PEM_write_bio_PKCS8PrivateKey - key = evp_pkey + elif encoding is serialization.Encoding.DER: + write_bio = self._lib.i2d_PKCS8PrivateKey_bio else: - assert format is serialization.PrivateFormat.TraditionalOpenSSL + raise ValueError("Unsupported encoding for PKCS8") + return self._private_key_bytes_via_bio( + write_bio, evp_pkey, password + ) + + # TraditionalOpenSSL + PEM/DER + if format is serialization.PrivateFormat.TraditionalOpenSSL: + key_type = self._lib.EVP_PKEY_id(evp_pkey) + + if encoding is serialization.Encoding.PEM: if key_type == self._lib.EVP_PKEY_RSA: write_bio = self._lib.PEM_write_bio_RSAPrivateKey elif key_type == self._lib.EVP_PKEY_DSA: write_bio = self._lib.PEM_write_bio_DSAPrivateKey - else: - assert key_type == self._lib.EVP_PKEY_EC + elif key_type == self._lib.EVP_PKEY_EC: write_bio = self._lib.PEM_write_bio_ECPrivateKey + else: + raise ValueError( + "Unsupported key type for TraditionalOpenSSL" + ) + return self._private_key_bytes_via_bio( + write_bio, cdata, password + ) - key = cdata - elif encoding is serialization.Encoding.DER: - if format is serialization.PrivateFormat.TraditionalOpenSSL: - if not isinstance( - encryption_algorithm, serialization.NoEncryption - ): + if encoding is serialization.Encoding.DER: + if password: raise ValueError( "Encryption is not supported for DER encoded " "traditional OpenSSL keys" ) + if key_type == self._lib.EVP_PKEY_RSA: + write_bio = self._lib.i2d_RSAPrivateKey_bio + elif key_type == self._lib.EVP_PKEY_EC: + write_bio = self._lib.i2d_ECPrivateKey_bio + elif key_type == self._lib.EVP_PKEY_DSA: + write_bio = self._lib.i2d_DSAPrivateKey_bio + else: + raise ValueError( + "Unsupported key type for TraditionalOpenSSL" + ) + return self._bio_func_output(write_bio, cdata) - return self._private_key_bytes_traditional_der(key_type, cdata) - else: - assert format is serialization.PrivateFormat.PKCS8 - write_bio = self._lib.i2d_PKCS8PrivateKey_bio - key = evp_pkey + raise ValueError( + "Unsupported encoding for TraditionalOpenSSL" + ) + + # Anything that key-specific code was supposed to handle earlier, + # like Raw. + raise ValueError("format is invalid with this key") + + def _private_key_bytes_via_bio(self, write_bio, evp_pkey, password): + if not password: + evp_cipher = self._ffi.NULL else: - raise TypeError("encoding must be Encoding.PEM or Encoding.DER") + # This is a curated value that we will update over time. + evp_cipher = self._lib.EVP_get_cipherbyname(b"aes-256-cbc") - bio = self._create_mem_bio_gc() - res = write_bio( - bio, - key, + return self._bio_func_output( + write_bio, + evp_pkey, evp_cipher, password, - passlen, + len(password), self._ffi.NULL, self._ffi.NULL ) - self.openssl_assert(res == 1) - return self._read_mem_bio(bio) - - def _private_key_bytes_traditional_der(self, key_type, cdata): - if key_type == self._lib.EVP_PKEY_RSA: - write_bio = self._lib.i2d_RSAPrivateKey_bio - elif key_type == self._lib.EVP_PKEY_EC: - write_bio = self._lib.i2d_ECPrivateKey_bio - else: - self.openssl_assert(key_type == self._lib.EVP_PKEY_DSA) - write_bio = self._lib.i2d_DSAPrivateKey_bio + def _bio_func_output(self, write_bio, *args): bio = self._create_mem_bio_gc() - res = write_bio(bio, cdata) + res = write_bio(bio, *args) self.openssl_assert(res == 1) return self._read_mem_bio(bio) def _public_key_bytes(self, encoding, format, key, 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.PublicFormat): + raise TypeError( + "format must be an item from the PublicFormat enum" + ) - # Compressed/UncompressedPoint are only valid for EC keys and those - # cases are handled by the ECPublicKey public_bytes method before this - # method is called - if format in (serialization.PublicFormat.UncompressedPoint, - serialization.PublicFormat.CompressedPoint): - raise ValueError("Point formats are not valid for this key type") - - # Raw format and encoding are only valid for X25519, Ed25519, X448, and - # Ed448 keys. We capture those cases before this method is called so if - # we see those enum values here it means the caller has passed them to - # a key that doesn't support raw type - if format is serialization.PublicFormat.Raw: - raise ValueError("raw format is invalid with this key or encoding") - - if encoding is serialization.Encoding.Raw: - raise ValueError("raw encoding is invalid with this key or format") - - if ( - format is serialization.PublicFormat.OpenSSH or - encoding is serialization.Encoding.OpenSSH - ): - if ( - format is not serialization.PublicFormat.OpenSSH or - encoding is not serialization.Encoding.OpenSSH - ): - raise ValueError( - "OpenSSH format must be used with OpenSSH encoding" - ) - return self._openssh_public_key_bytes(key) - elif format is serialization.PublicFormat.SubjectPublicKeyInfo: + # SubjectPublicKeyInfo + PEM/DER + if format is serialization.PublicFormat.SubjectPublicKeyInfo: if encoding is serialization.Encoding.PEM: write_bio = self._lib.PEM_write_bio_PUBKEY - else: - assert encoding is serialization.Encoding.DER + elif encoding is serialization.Encoding.DER: write_bio = self._lib.i2d_PUBKEY_bio + else: + raise ValueError( + "SubjectPublicKeyInfo works only with PEM or DER encoding" + ) + return self._bio_func_output(write_bio, evp_pkey) - key = evp_pkey - elif format is serialization.PublicFormat.PKCS1: + # PKCS1 + PEM/DER + if format is serialization.PublicFormat.PKCS1: # Only RSA is supported here. - assert self._lib.EVP_PKEY_id(evp_pkey) == self._lib.EVP_PKEY_RSA + key_type = self._lib.EVP_PKEY_id(evp_pkey) + if key_type != self._lib.EVP_PKEY_RSA: + raise ValueError("PKCS1 format is supported only for RSA keys") + if encoding is serialization.Encoding.PEM: write_bio = self._lib.PEM_write_bio_RSAPublicKey - else: - assert encoding is serialization.Encoding.DER + elif encoding is serialization.Encoding.DER: write_bio = self._lib.i2d_RSAPublicKey_bio + else: + raise ValueError( + "PKCS1 works only with PEM or DER encoding" + ) + return self._bio_func_output(write_bio, cdata) - key = cdata - else: - raise TypeError( - "format must be an item from the PublicFormat enum" + # OpenSSH + OpenSSH + if format is serialization.PublicFormat.OpenSSH: + if encoding is serialization.Encoding.OpenSSH: + return self._openssh_public_key_bytes(key) + + raise ValueError( + "OpenSSH format must be used with OpenSSH encoding" ) - bio = self._create_mem_bio_gc() - res = write_bio(bio, key) - self.openssl_assert(res == 1) - return self._read_mem_bio(bio) + # Anything that key-specific code was supposed to handle earlier, + # like Raw, CompressedPoint, UncompressedPoint + raise ValueError("format is invalid with this key") def _openssh_public_key_bytes(self, key): if isinstance(key, rsa.RSAPublicKey): diff --git a/src/cryptography/hazmat/backends/openssl/dh.py b/src/cryptography/hazmat/backends/openssl/dh.py index 961f1769..1d5065c2 100644 --- a/src/cryptography/hazmat/backends/openssl/dh.py +++ b/src/cryptography/hazmat/backends/openssl/dh.py @@ -209,6 +209,7 @@ class _DHPrivateKey(object): encoding, format, encryption_algorithm, + self, self._evp_pkey, self._dh_cdata ) diff --git a/src/cryptography/hazmat/backends/openssl/dsa.py b/src/cryptography/hazmat/backends/openssl/dsa.py index de61f089..79142bf6 100644 --- a/src/cryptography/hazmat/backends/openssl/dsa.py +++ b/src/cryptography/hazmat/backends/openssl/dsa.py @@ -10,7 +10,7 @@ from cryptography.hazmat.backends.openssl.utils import ( _calculate_digest_and_algorithm, _check_not_prehashed, _warn_sign_verify_deprecated ) -from cryptography.hazmat.primitives import hashes, serialization +from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import ( AsymmetricSignatureContext, AsymmetricVerificationContext, dsa ) @@ -183,6 +183,7 @@ class _DSAPrivateKey(object): encoding, format, encryption_algorithm, + self, self._evp_pkey, self._dsa_cdata ) @@ -248,11 +249,6 @@ class _DSAPublicKey(object): return _DSAParameters(self._backend, dsa_cdata) def public_bytes(self, encoding, format): - if format is serialization.PublicFormat.PKCS1: - raise ValueError( - "DSA public keys do not support PKCS1 serialization" - ) - return self._backend._public_key_bytes( encoding, format, diff --git a/src/cryptography/hazmat/backends/openssl/ec.py b/src/cryptography/hazmat/backends/openssl/ec.py index 3d8681b4..e70a3410 100644 --- a/src/cryptography/hazmat/backends/openssl/ec.py +++ b/src/cryptography/hazmat/backends/openssl/ec.py @@ -225,6 +225,7 @@ class _EllipticCurvePrivateKey(object): encoding, format, encryption_algorithm, + self, self._evp_pkey, self._ec_key ) @@ -312,10 +313,6 @@ class _EllipticCurvePublicKey(object): return self._backend._ffi.buffer(buf)[:] def public_bytes(self, encoding, format): - if format is serialization.PublicFormat.PKCS1: - raise ValueError( - "EC public keys do not support PKCS1 serialization" - ) if ( encoding is serialization.Encoding.X962 or diff --git a/src/cryptography/hazmat/backends/openssl/ed25519.py b/src/cryptography/hazmat/backends/openssl/ed25519.py index f38f11d1..1632ec37 100644 --- a/src/cryptography/hazmat/backends/openssl/ed25519.py +++ b/src/cryptography/hazmat/backends/openssl/ed25519.py @@ -32,15 +32,6 @@ class _Ed25519PublicKey(object): return self._raw_public_bytes() - if ( - encoding in serialization._PEM_DER and - format is not serialization.PublicFormat.SubjectPublicKeyInfo - ): - raise ValueError( - "format must be SubjectPublicKeyInfo when encoding is PEM or " - "DER" - ) - return self._backend._public_key_bytes( encoding, format, self, self._evp_pkey, None ) @@ -128,16 +119,8 @@ class _Ed25519PrivateKey(object): return self._raw_private_bytes() - if ( - encoding in serialization._PEM_DER and - format is not serialization.PrivateFormat.PKCS8 - ): - raise ValueError( - "format must be PKCS8 when encoding is PEM or DER" - ) - return self._backend._private_key_bytes( - encoding, format, encryption_algorithm, self._evp_pkey, None + encoding, format, encryption_algorithm, self, self._evp_pkey, None ) def _raw_private_bytes(self): diff --git a/src/cryptography/hazmat/backends/openssl/ed448.py b/src/cryptography/hazmat/backends/openssl/ed448.py index f541f05d..4845a1f2 100644 --- a/src/cryptography/hazmat/backends/openssl/ed448.py +++ b/src/cryptography/hazmat/backends/openssl/ed448.py @@ -35,15 +35,6 @@ class _Ed448PublicKey(object): return self._raw_public_bytes() - if ( - encoding in serialization._PEM_DER and - format is not serialization.PublicFormat.SubjectPublicKeyInfo - ): - raise ValueError( - "format must be SubjectPublicKeyInfo when encoding is PEM or " - "DER" - ) - return self._backend._public_key_bytes( encoding, format, self, self._evp_pkey, None ) @@ -131,16 +122,8 @@ class _Ed448PrivateKey(object): return self._raw_private_bytes() - if ( - encoding in serialization._PEM_DER and - format is not serialization.PrivateFormat.PKCS8 - ): - raise ValueError( - "format must be PKCS8 when encoding is PEM or DER" - ) - return self._backend._private_key_bytes( - encoding, format, encryption_algorithm, self._evp_pkey, None + encoding, format, encryption_algorithm, self, self._evp_pkey, None ) def _raw_private_bytes(self): diff --git a/src/cryptography/hazmat/backends/openssl/rsa.py b/src/cryptography/hazmat/backends/openssl/rsa.py index bd4a1bea..a9e07b52 100644 --- a/src/cryptography/hazmat/backends/openssl/rsa.py +++ b/src/cryptography/hazmat/backends/openssl/rsa.py @@ -406,6 +406,7 @@ class _RSAPrivateKey(object): encoding, format, encryption_algorithm, + self, self._evp_pkey, self._rsa_cdata ) diff --git a/src/cryptography/hazmat/backends/openssl/x25519.py b/src/cryptography/hazmat/backends/openssl/x25519.py index 8708834e..665acf2f 100644 --- a/src/cryptography/hazmat/backends/openssl/x25519.py +++ b/src/cryptography/hazmat/backends/openssl/x25519.py @@ -36,15 +36,6 @@ class _X25519PublicKey(object): return self._raw_public_bytes() - if ( - encoding in serialization._PEM_DER and - format is not serialization.PublicFormat.SubjectPublicKeyInfo - ): - raise ValueError( - "format must be SubjectPublicKeyInfo when encoding is PEM or " - "DER" - ) - return self._backend._public_key_bytes( encoding, format, self, self._evp_pkey, None ) @@ -106,16 +97,8 @@ class _X25519PrivateKey(object): return self._raw_private_bytes() - if ( - encoding in serialization._PEM_DER and - format is not serialization.PrivateFormat.PKCS8 - ): - raise ValueError( - "format must be PKCS8 when encoding is PEM or DER" - ) - return self._backend._private_key_bytes( - encoding, format, encryption_algorithm, self._evp_pkey, None + encoding, format, encryption_algorithm, self, self._evp_pkey, None ) def _raw_private_bytes(self): diff --git a/src/cryptography/hazmat/backends/openssl/x448.py b/src/cryptography/hazmat/backends/openssl/x448.py index fe0dcd9c..3de35b43 100644 --- a/src/cryptography/hazmat/backends/openssl/x448.py +++ b/src/cryptography/hazmat/backends/openssl/x448.py @@ -35,15 +35,6 @@ class _X448PublicKey(object): return self._raw_public_bytes() - if ( - encoding in serialization._PEM_DER and - format is not serialization.PublicFormat.SubjectPublicKeyInfo - ): - raise ValueError( - "format must be SubjectPublicKeyInfo when encoding is PEM or " - "DER" - ) - return self._backend._public_key_bytes( encoding, format, self, self._evp_pkey, None ) @@ -100,16 +91,8 @@ class _X448PrivateKey(object): return self._raw_private_bytes() - if ( - encoding in serialization._PEM_DER and - format is not serialization.PrivateFormat.PKCS8 - ): - raise ValueError( - "format must be PKCS8 when encoding is PEM or DER" - ) - return self._backend._private_key_bytes( - encoding, format, encryption_algorithm, self._evp_pkey, None + encoding, format, encryption_algorithm, self, self._evp_pkey, None ) def _raw_private_bytes(self): diff --git a/src/cryptography/hazmat/primitives/serialization/__init__.py b/src/cryptography/hazmat/primitives/serialization/__init__.py index f6d4ce99..b910751b 100644 --- a/src/cryptography/hazmat/primitives/serialization/__init__.py +++ b/src/cryptography/hazmat/primitives/serialization/__init__.py @@ -15,8 +15,6 @@ from cryptography.hazmat.primitives.serialization.ssh import ( ) -_PEM_DER = (Encoding.PEM, Encoding.DER) - __all__ = [ "load_der_parameters", "load_der_private_key", "load_der_public_key", "load_pem_parameters", "load_pem_private_key", "load_pem_public_key", diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py index 6c86927a..8e8e15af 100644 --- a/tests/hazmat/primitives/test_serialization.py +++ b/tests/hazmat/primitives/test_serialization.py @@ -17,7 +17,7 @@ from cryptography.hazmat.backends.interfaces import ( PEMSerializationBackend, RSABackend ) from cryptography.hazmat.primitives.asymmetric import ( - dsa, ec, ed25519, ed448, rsa + dsa, ec, ed25519, ed448, rsa, x25519, x448 ) from cryptography.hazmat.primitives.serialization import ( BestAvailableEncryption, Encoding, NoEncryption, @@ -574,6 +574,24 @@ class TestPEMSerialization(object): ) ) + def test_invalid_encoding_with_traditional(self, backend): + key_file = os.path.join( + "asymmetric", "Traditional_OpenSSL_Serialization", "testrsa.pem" + ) + key = load_vectors_from_file( + key_file, + lambda pemfile: load_pem_private_key( + pemfile.read(), None, backend + ), + mode="rb" + ) + + for enc in (Encoding.OpenSSH, Encoding.Raw, Encoding.X962): + with pytest.raises(ValueError): + key.private_bytes( + enc, PrivateFormat.TraditionalOpenSSL, NoEncryption() + ) + @pytest.mark.parametrize( "key_path", [ @@ -1396,6 +1414,17 @@ class TestEd25519Serialization(object): encoding, PublicFormat.SubjectPublicKeyInfo ) == data + def test_openssl_serialization_unsupported(self, backend): + key = ed25519.Ed25519PrivateKey.generate() + with pytest.raises(ValueError): + key.private_bytes( + Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption(), + ) + with pytest.raises(ValueError): + key.private_bytes( + Encoding.DER, PrivateFormat.TraditionalOpenSSL, NoEncryption(), + ) + @pytest.mark.supported( only_if=lambda backend: backend.x448_supported(), @@ -1460,6 +1489,17 @@ class TestX448Serialization(object): encoding, PublicFormat.SubjectPublicKeyInfo ) == data + def test_openssl_serialization_unsupported(self, backend): + key = x448.X448PrivateKey.generate() + with pytest.raises(ValueError): + key.private_bytes( + Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption(), + ) + with pytest.raises(ValueError): + key.private_bytes( + Encoding.DER, PrivateFormat.TraditionalOpenSSL, NoEncryption(), + ) + @pytest.mark.supported( only_if=lambda backend: backend.x25519_supported(), @@ -1524,6 +1564,17 @@ class TestX25519Serialization(object): encoding, PublicFormat.SubjectPublicKeyInfo ) == data + def test_openssl_serialization_unsupported(self, backend): + key = x25519.X25519PrivateKey.generate() + with pytest.raises(ValueError): + key.private_bytes( + Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption(), + ) + with pytest.raises(ValueError): + key.private_bytes( + Encoding.DER, PrivateFormat.TraditionalOpenSSL, NoEncryption(), + ) + @pytest.mark.supported( only_if=lambda backend: backend.ed448_supported(), @@ -1588,9 +1639,73 @@ class TestEd448Serialization(object): encoding, PublicFormat.SubjectPublicKeyInfo ) == data + def test_openssl_serialization_unsupported(self, backend): + key = ed448.Ed448PrivateKey.generate() + with pytest.raises(ValueError): + key.private_bytes( + Encoding.PEM, PrivateFormat.TraditionalOpenSSL, NoEncryption(), + ) + with pytest.raises(ValueError): + key.private_bytes( + Encoding.DER, PrivateFormat.TraditionalOpenSSL, NoEncryption(), + ) + def test_openssh_serialization_unsupported(self, backend): - key = ed448.Ed448PrivateKey.generate().public_key() + key = ed448.Ed448PrivateKey.generate() with pytest.raises(ValueError): - key.public_bytes( - Encoding.OpenSSH, PublicFormat.OpenSSH + key.public_key().public_bytes( + Encoding.OpenSSH, PublicFormat.OpenSSH, ) + + +class TestDHSerialization(object): + """Test all options with least-supported key type. + """ + def test_dh_public_key(self, backend): + data = load_vectors_from_file( + os.path.join("asymmetric", "DH", "dhkey.pem"), + lambda pemfile: pemfile.read(), + mode="rb" + ) + public_key = load_pem_private_key(data, None, backend).public_key() + for enc in ( + Encoding.PEM, Encoding.DER, Encoding.OpenSSH, + Encoding.Raw, Encoding.X962 + ): + for fmt in ( + PublicFormat.SubjectPublicKeyInfo, PublicFormat.PKCS1, + PublicFormat.OpenSSH, PublicFormat.Raw, + PublicFormat.CompressedPoint, PublicFormat.UncompressedPoint, + ): + if ( + enc in (Encoding.PEM, Encoding.DER) and + fmt == PublicFormat.SubjectPublicKeyInfo + ): + # tested elsewhere + continue + with pytest.raises(ValueError): + public_key.public_bytes(enc, fmt) + + def test_dh_private_key(self, backend): + data = load_vectors_from_file( + os.path.join("asymmetric", "DH", "dhkey.pem"), + lambda pemfile: pemfile.read(), + mode="rb" + ) + private_key = load_pem_private_key(data, None, backend) + for enc in ( + Encoding.PEM, Encoding.DER, Encoding.OpenSSH, + Encoding.Raw, Encoding.X962 + ): + for fmt in ( + PrivateFormat.PKCS8, PrivateFormat.TraditionalOpenSSL, + PrivateFormat.Raw + ): + if ( + enc in (Encoding.PEM, Encoding.DER) and + fmt is PrivateFormat.PKCS8 + ): + # tested elsewhere + continue + with pytest.raises(ValueError): + private_key.private_bytes(enc, fmt, NoEncryption()) -- cgit v1.2.3