Repository URL to install this package:
|
Version:
1.7.1 ▾
|
# This file is dual licensed under the terms of the Apache License, Version
# 2.0, and the BSD License. See the LICENSE file in the root of this repository
# for complete details.
from __future__ import absolute_import, division, print_function
import os
import pytest
from cryptography.hazmat.backends.interfaces import DHBackend
from cryptography.hazmat.primitives.asymmetric import dh
from cryptography.utils import bit_length, int_from_bytes
from ...utils import load_nist_vectors, load_vectors_from_file
def test_dh_parameternumbers():
params = dh.DHParameterNumbers(
65537, 2
)
assert params.p == 65537
assert params.g == 2
with pytest.raises(TypeError):
dh.DHParameterNumbers(
None, 2
)
with pytest.raises(TypeError):
dh.DHParameterNumbers(
65537, None
)
with pytest.raises(TypeError):
dh.DHParameterNumbers(
None, None
)
with pytest.raises(ValueError):
dh.DHParameterNumbers(
65537, 7
)
def test_dh_numbers():
params = dh.DHParameterNumbers(
65537, 2
)
public = dh.DHPublicNumbers(
1, params
)
assert public.parameter_numbers is params
assert public.y == 1
with pytest.raises(TypeError):
dh.DHPublicNumbers(
1, None
)
with pytest.raises(TypeError):
dh.DHPublicNumbers(
None, params
)
private = dh.DHPrivateNumbers(
1, public
)
assert private.public_numbers is public
assert private.x == 1
with pytest.raises(TypeError):
dh.DHPrivateNumbers(
1, None
)
with pytest.raises(TypeError):
dh.DHPrivateNumbers(
None, public
)
def test_dh_parameter_numbers_equality():
assert dh.DHParameterNumbers(65537, 2) == dh.DHParameterNumbers(65537, 2)
assert dh.DHParameterNumbers(6, 2) != dh.DHParameterNumbers(65537, 2)
assert dh.DHParameterNumbers(65537, 5) != dh.DHParameterNumbers(65537, 2)
assert dh.DHParameterNumbers(65537, 2) != object()
def test_dh_private_numbers_equality():
params = dh.DHParameterNumbers(65537, 2)
public = dh.DHPublicNumbers(1, params)
private = dh.DHPrivateNumbers(2, public)
assert private == dh.DHPrivateNumbers(2, public)
assert private != dh.DHPrivateNumbers(0, public)
assert private != dh.DHPrivateNumbers(2, dh.DHPublicNumbers(0, params))
assert private != dh.DHPrivateNumbers(
2, dh.DHPublicNumbers(1, dh.DHParameterNumbers(65537, 5))
)
assert private != object()
def test_dh_public_numbers_equality():
params = dh.DHParameterNumbers(65537, 2)
public = dh.DHPublicNumbers(1, params)
assert public == dh.DHPublicNumbers(1, params)
assert public != dh.DHPublicNumbers(0, params)
assert public != dh.DHPublicNumbers(1, dh.DHParameterNumbers(65537, 5))
assert public != object()
@pytest.mark.requires_backend_interface(interface=DHBackend)
class TestDH(object):
def test_small_key_generate_dh(self, backend):
with pytest.raises(ValueError):
dh.generate_parameters(2, 511, backend)
def test_unsupported_generator_generate_dh(self, backend):
with pytest.raises(ValueError):
dh.generate_parameters(7, 512, backend)
def test_dh_parameters_supported(self, backend):
assert backend.dh_parameters_supported(23, 5)
assert not backend.dh_parameters_supported(23, 18)
def test_convert_to_numbers(self, backend):
parameters = backend.generate_dh_private_key_and_parameters(2, 512)
private = parameters.private_numbers()
p = private.public_numbers.parameter_numbers.p
g = private.public_numbers.parameter_numbers.g
params = dh.DHParameterNumbers(p, g)
public = dh.DHPublicNumbers(1, params)
private = dh.DHPrivateNumbers(2, public)
deserialized_params = params.parameters(backend)
deserialized_public = public.public_key(backend)
deserialized_private = private.private_key(backend)
assert isinstance(deserialized_params,
dh.DHParametersWithSerialization)
assert isinstance(deserialized_public,
dh.DHPublicKeyWithSerialization)
assert isinstance(deserialized_private,
dh.DHPrivateKeyWithSerialization)
def test_numbers_unsupported_parameters(self, backend):
params = dh.DHParameterNumbers(23, 2)
public = dh.DHPublicNumbers(1, params)
private = dh.DHPrivateNumbers(2, public)
with pytest.raises(ValueError):
private.private_key(backend)
def test_generate_dh(self, backend):
generator = 2
key_size = 512
parameters = dh.generate_parameters(generator, key_size, backend)
assert isinstance(parameters, dh.DHParameters)
key = parameters.generate_private_key()
assert isinstance(key, dh.DHPrivateKey)
assert key.key_size == key_size
public = key.public_key()
assert isinstance(public, dh.DHPublicKey)
assert public.key_size == key_size
assert isinstance(parameters, dh.DHParametersWithSerialization)
parameter_numbers = parameters.parameter_numbers()
assert isinstance(parameter_numbers, dh.DHParameterNumbers)
assert bit_length(parameter_numbers.p) == key_size
assert isinstance(public, dh.DHPublicKeyWithSerialization)
assert isinstance(public.public_numbers(), dh.DHPublicNumbers)
assert isinstance(public.parameters(), dh.DHParameters)
assert isinstance(key, dh.DHPrivateKeyWithSerialization)
assert isinstance(key.private_numbers(), dh.DHPrivateNumbers)
assert isinstance(key.parameters(), dh.DHParameters)
def test_exchange(self, backend):
parameters = dh.generate_parameters(2, 512, backend)
assert isinstance(parameters, dh.DHParameters)
key1 = parameters.generate_private_key()
key2 = parameters.generate_private_key()
symkey1 = key1.exchange(key2.public_key())
assert symkey1
assert len(symkey1) == 512 // 8
symkey2 = key2.exchange(key1.public_key())
assert symkey1 == symkey2
def test_exchange_algorithm(self, backend):
parameters = dh.generate_parameters(2, 512, backend)
key1 = parameters.generate_private_key()
key2 = parameters.generate_private_key()
shared_key_bytes = key2.exchange(key1.public_key())
symkey = int_from_bytes(shared_key_bytes, 'big')
symkey_manual = pow(key1.public_key().public_numbers().y,
key2.private_numbers().x,
parameters.parameter_numbers().p)
assert symkey == symkey_manual
def test_symmetric_key_padding(self, backend):
"""
This test has specific parameters that produce a symmetric key
In length 63 bytes instead 64. We make sure here that we add
padding to the key.
"""
p = int("11859949538425015739337467917303613431031019140213666"
"129025407300654026585086345323066284800963463204246390"
"256567934582260424238844463330887962689642467123")
g = 2
y = int("32155788395534640648739966373159697798396966919821525"
"72238852825117261342483718574508213761865276905503199"
"969908098203345481366464874759377454476688391248")
x = int("409364065449673443397833358558926598469347813468816037"
"268451847116982490733450463194921405069999008617231539"
"7147035896687401350877308899732826446337707128")
parameters = dh.DHParameterNumbers(p, g)
public = dh.DHPublicNumbers(y, parameters)
private = dh.DHPrivateNumbers(x, public)
key = private.private_key(backend)
symkey = key.exchange(public.public_key(backend))
assert len(symkey) == 512 // 8
assert symkey[:1] == b'\x00'
@pytest.mark.parametrize(
"vector",
load_vectors_from_file(
os.path.join("asymmetric", "DH", "bad_exchange.txt"),
load_nist_vectors))
def test_bad_exchange(self, backend, vector):
parameters1 = dh.DHParameterNumbers(int(vector["p1"]),
int(vector["g"]))
public1 = dh.DHPublicNumbers(int(vector["y1"]), parameters1)
private1 = dh.DHPrivateNumbers(int(vector["x1"]), public1)
key1 = private1.private_key(backend)
pub_key1 = key1.public_key()
parameters2 = dh.DHParameterNumbers(int(vector["p2"]),
int(vector["g"]))
public2 = dh.DHPublicNumbers(int(vector["y2"]), parameters2)
private2 = dh.DHPrivateNumbers(int(vector["x2"]), public2)
key2 = private2.private_key(backend)
pub_key2 = key2.public_key()
if pub_key2.public_numbers().y >= parameters1.p:
with pytest.raises(ValueError):
key1.exchange(pub_key2)
else:
symkey1 = key1.exchange(pub_key2)
assert symkey1
symkey2 = key2.exchange(pub_key1)
assert symkey1 != symkey2
@pytest.mark.parametrize(
"vector",
load_vectors_from_file(
os.path.join("asymmetric", "DH", "vec.txt"),
load_nist_vectors))
def test_dh_vectors(self, backend, vector):
parameters = dh.DHParameterNumbers(int(vector["p"]),
int(vector["g"]))
public = dh.DHPublicNumbers(int(vector["y"]), parameters)
private = dh.DHPrivateNumbers(int(vector["x"]), public)
key = private.private_key(backend)
symkey = key.exchange(public.public_key(backend))
assert int_from_bytes(symkey, 'big') == int(vector["k"], 16)