aboutsummaryrefslogtreecommitdiffstats
path: root/tests/hazmat
diff options
context:
space:
mode:
authorPaul Kehrer <paul.l.kehrer@gmail.com>2019-01-14 21:50:17 -0600
committerAlex Gaynor <alex.gaynor@gmail.com>2019-01-14 22:50:17 -0500
commitc6c25c21496858271fbc4c89fb102074fd3d5f60 (patch)
tree009896d2b53e2d45f050b35320609bf348f0e31c /tests/hazmat
parentaeb3acbe9abffba68da3cc8b6bc0f3c2acb9bd9d (diff)
downloadcryptography-c6c25c21496858271fbc4c89fb102074fd3d5f60.tar.gz
cryptography-c6c25c21496858271fbc4c89fb102074fd3d5f60.tar.bz2
cryptography-c6c25c21496858271fbc4c89fb102074fd3d5f60.zip
Serialization x25519 (#4688)
* modify x25519 serialization to match x448 supports raw and pkcs8 encoding on private_bytes supports raw and subjectpublickeyinfo on public_bytes deprecates zero argument call to public_bytes * add docs * this is public now * don't need that * review feedback
Diffstat (limited to 'tests/hazmat')
-rw-r--r--tests/hazmat/primitives/test_serialization.py64
-rw-r--r--tests/hazmat/primitives/test_x25519.py122
2 files changed, 178 insertions, 8 deletions
diff --git a/tests/hazmat/primitives/test_serialization.py b/tests/hazmat/primitives/test_serialization.py
index 81d372fc..2bc49078 100644
--- a/tests/hazmat/primitives/test_serialization.py
+++ b/tests/hazmat/primitives/test_serialization.py
@@ -1297,3 +1297,67 @@ class TestX448Serialization(object):
assert public_key.public_bytes(
encoding, PublicFormat.SubjectPublicKeyInfo
) == data
+
+
+@pytest.mark.supported(
+ only_if=lambda backend: backend.x25519_supported(),
+ skip_message="Requires OpenSSL with X25519 support"
+)
+class TestX25519Serialization(object):
+ def test_load_der_private_key(self, backend):
+ data = load_vectors_from_file(
+ os.path.join("asymmetric", "X25519", "x25519-pkcs8-enc.der"),
+ lambda derfile: derfile.read(),
+ mode="rb"
+ )
+ unencrypted = load_vectors_from_file(
+ os.path.join("asymmetric", "X25519", "x25519-pkcs8.der"),
+ lambda derfile: derfile.read(),
+ mode="rb"
+ )
+ key = load_der_private_key(data, b"password", backend)
+ assert key.private_bytes(
+ Encoding.DER, PrivateFormat.PKCS8, NoEncryption()
+ ) == unencrypted
+
+ def test_load_pem_private_key(self, backend):
+ data = load_vectors_from_file(
+ os.path.join("asymmetric", "X25519", "x25519-pkcs8-enc.pem"),
+ lambda pemfile: pemfile.read(),
+ mode="rb"
+ )
+ unencrypted = load_vectors_from_file(
+ os.path.join("asymmetric", "X25519", "x25519-pkcs8.pem"),
+ lambda pemfile: pemfile.read(),
+ mode="rb"
+ )
+ key = load_pem_private_key(data, b"password", backend)
+ assert key.private_bytes(
+ Encoding.PEM, PrivateFormat.PKCS8, NoEncryption()
+ ) == unencrypted
+
+ @pytest.mark.parametrize(
+ ("key_path", "encoding", "loader"),
+ [
+ (
+ ["X25519", "x25519-pub.pem"],
+ Encoding.PEM,
+ load_pem_public_key
+ ),
+ (
+ ["X25519", "x25519-pub.der"],
+ Encoding.DER,
+ load_der_public_key
+ ),
+ ]
+ )
+ def test_load_public_key(self, key_path, encoding, loader, backend):
+ data = load_vectors_from_file(
+ os.path.join("asymmetric", *key_path),
+ lambda pemfile: pemfile.read(),
+ mode="rb"
+ )
+ public_key = loader(data, backend)
+ assert public_key.public_bytes(
+ encoding, PublicFormat.SubjectPublicKeyInfo
+ ) == data
diff --git a/tests/hazmat/primitives/test_x25519.py b/tests/hazmat/primitives/test_x25519.py
index 0f83eb6e..682c3125 100644
--- a/tests/hazmat/primitives/test_x25519.py
+++ b/tests/hazmat/primitives/test_x25519.py
@@ -9,8 +9,10 @@ import os
import pytest
+from cryptography import utils
from cryptography.exceptions import _Reasons
from cryptography.hazmat.backends.interfaces import DHBackend
+from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric.x25519 import (
X25519PrivateKey, X25519PublicKey
)
@@ -50,7 +52,7 @@ class TestX25519Exchange(object):
private = binascii.unhexlify(vector["input_scalar"])
public = binascii.unhexlify(vector["input_u"])
shared_key = binascii.unhexlify(vector["output_u"])
- private_key = X25519PrivateKey._from_private_bytes(private)
+ private_key = X25519PrivateKey.from_private_bytes(private)
public_key = X25519PublicKey.from_public_bytes(public)
computed_shared_key = private_key.exchange(public_key)
assert computed_shared_key == shared_key
@@ -64,11 +66,11 @@ class TestX25519Exchange(object):
b"684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d9953"
b"2c51"
)
- private_key = X25519PrivateKey._from_private_bytes(private)
+ private_key = X25519PrivateKey.from_private_bytes(private)
public_key = X25519PublicKey.from_public_bytes(public)
for _ in range(1000):
computed_shared_key = private_key.exchange(public_key)
- private_key = X25519PrivateKey._from_private_bytes(
+ private_key = X25519PrivateKey.from_private_bytes(
computed_shared_key
)
public_key = X25519PublicKey.from_public_bytes(old_private)
@@ -86,13 +88,25 @@ class TestX25519Exchange(object):
private = binascii.unhexlify(
"78f1e8edf14481b389448dac8f59c70b038e7cf92ef2c7eff57a72466e115296"
)
- private_key = X25519PrivateKey._from_private_bytes(
+ private_key = X25519PrivateKey.from_private_bytes(
private
)
public_key = X25519PublicKey.from_public_bytes(public)
with pytest.raises(ValueError):
private_key.exchange(public_key)
+ def test_deprecated_public_bytes(self, backend):
+ key = X25519PrivateKey.generate().public_key()
+ with pytest.warns(utils.DeprecatedIn25):
+ key.public_bytes()
+
+ def test_public_bytes_bad_args(self, backend):
+ key = X25519PrivateKey.generate().public_key()
+ with pytest.raises(ValueError):
+ key.public_bytes(None, serialization.PublicFormat.Raw)
+ with pytest.raises(ValueError):
+ key.public_bytes(serialization.Encoding.Raw)
+
# These vectors are also from RFC 7748
# https://tools.ietf.org/html/rfc7748#section-6.1
@pytest.mark.parametrize(
@@ -120,11 +134,20 @@ class TestX25519Exchange(object):
)
]
)
- def test_public_bytes(self, private_bytes, public_bytes, backend):
- private_key = X25519PrivateKey._from_private_bytes(private_bytes)
- assert private_key.public_key().public_bytes() == public_bytes
+ def test_pub_priv_bytes_raw(self, private_bytes, public_bytes, backend):
+ private_key = X25519PrivateKey.from_private_bytes(private_bytes)
+ assert private_key.private_bytes(
+ serialization.Encoding.Raw,
+ serialization.PrivateFormat.Raw,
+ serialization.NoEncryption()
+ ) == private_bytes
+ assert private_key.public_key().public_bytes(
+ serialization.Encoding.Raw, serialization.PublicFormat.Raw
+ ) == public_bytes
public_key = X25519PublicKey.from_public_bytes(public_bytes)
- assert public_key.public_bytes() == public_bytes
+ assert public_key.public_bytes(
+ serialization.Encoding.Raw, serialization.PublicFormat.Raw
+ ) == public_bytes
def test_generate(self, backend):
key = X25519PrivateKey.generate()
@@ -142,3 +165,86 @@ class TestX25519Exchange(object):
with pytest.raises(ValueError):
X25519PublicKey.from_public_bytes(b"a" * 33)
+
+ def test_invalid_private_bytes(self, backend):
+ key = X25519PrivateKey.generate()
+ with pytest.raises(ValueError):
+ key.private_bytes(
+ serialization.Encoding.Raw,
+ serialization.PrivateFormat.Raw,
+ None
+ )
+
+ with pytest.raises(ValueError):
+ key.private_bytes(
+ serialization.Encoding.Raw,
+ serialization.PrivateFormat.PKCS8,
+ None
+ )
+
+ with pytest.raises(ValueError):
+ key.private_bytes(
+ serialization.Encoding.PEM,
+ serialization.PrivateFormat.Raw,
+ serialization.NoEncryption()
+ )
+
+ def test_invalid_public_bytes(self, backend):
+ key = X25519PrivateKey.generate().public_key()
+ with pytest.raises(ValueError):
+ key.public_bytes(
+ serialization.Encoding.Raw,
+ serialization.PublicFormat.SubjectPublicKeyInfo
+ )
+
+ with pytest.raises(ValueError):
+ key.public_bytes(
+ serialization.Encoding.PEM,
+ serialization.PublicFormat.PKCS1
+ )
+
+ with pytest.raises(ValueError):
+ key.public_bytes(
+ serialization.Encoding.PEM,
+ serialization.PublicFormat.Raw
+ )
+
+ @pytest.mark.parametrize(
+ ("encoding", "fmt", "encryption", "passwd", "load_func"),
+ [
+ (
+ serialization.Encoding.PEM,
+ serialization.PrivateFormat.PKCS8,
+ serialization.BestAvailableEncryption(b"password"),
+ b"password",
+ serialization.load_pem_private_key
+ ),
+ (
+ serialization.Encoding.DER,
+ serialization.PrivateFormat.PKCS8,
+ serialization.BestAvailableEncryption(b"password"),
+ b"password",
+ serialization.load_der_private_key
+ ),
+ (
+ serialization.Encoding.PEM,
+ serialization.PrivateFormat.PKCS8,
+ serialization.NoEncryption(),
+ None,
+ serialization.load_pem_private_key
+ ),
+ (
+ serialization.Encoding.DER,
+ serialization.PrivateFormat.PKCS8,
+ serialization.NoEncryption(),
+ None,
+ serialization.load_der_private_key
+ ),
+ ]
+ )
+ def test_round_trip_private_serialization(self, encoding, fmt, encryption,
+ passwd, load_func, backend):
+ key = X25519PrivateKey.generate()
+ serialized = key.private_bytes(encoding, fmt, encryption)
+ loaded_key = load_func(serialized, passwd, backend)
+ assert isinstance(loaded_key, X25519PrivateKey)