aboutsummaryrefslogtreecommitdiffstats
path: root/tests/hazmat/primitives/test_dsa.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/hazmat/primitives/test_dsa.py')
-rw-r--r--tests/hazmat/primitives/test_dsa.py968
1 files changed, 451 insertions, 517 deletions
diff --git a/tests/hazmat/primitives/test_dsa.py b/tests/hazmat/primitives/test_dsa.py
index 5c83d5c7..9e1acf93 100644
--- a/tests/hazmat/primitives/test_dsa.py
+++ b/tests/hazmat/primitives/test_dsa.py
@@ -9,7 +9,6 @@ import os
import pytest
-from cryptography import utils
from cryptography.exceptions import AlreadyFinalized, InvalidSignature
from cryptography.hazmat.backends.interfaces import (
DSABackend, PEMSerializationBackend
@@ -17,37 +16,34 @@ from cryptography.hazmat.backends.interfaces import (
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import dsa
from cryptography.hazmat.primitives.asymmetric.utils import (
- encode_rfc6979_signature
+ Prehashed, encode_dss_signature
)
-from cryptography.utils import bit_length
+from cryptography.utils import CryptographyDeprecationWarning
from .fixtures_dsa import (
DSA_KEY_1024, DSA_KEY_2048, DSA_KEY_3072
)
+from ...doubles import DummyHashAlgorithm, DummyKeySerializationEncryption
from ...utils import (
load_fips_dsa_key_pair_vectors, load_fips_dsa_sig_vectors,
load_vectors_from_file,
)
-def _skip_if_no_serialization(key, backend):
- if not isinstance(
- key,
- (dsa.DSAPrivateKeyWithSerialization, dsa.DSAPublicKeyWithSerialization)
+def _skip_if_dsa_not_supported(backend, algorithm, p, q, g):
+ if (
+ not backend.dsa_parameters_supported(p, q, g) or
+ not backend.dsa_hash_supported(algorithm)
):
pytest.skip(
- "{0} does not support DSA key serialization".format(backend)
+ "{} does not support the provided parameters".format(backend)
)
-def test_skip_if_no_serialization():
+@pytest.mark.requires_backend_interface(interface=DSABackend)
+def test_skip_if_dsa_not_supported(backend):
with pytest.raises(pytest.skip.Exception):
- _skip_if_no_serialization("notakeywithserialization", "backend")
-
-
-@utils.register_interface(serialization.KeySerializationEncryption)
-class DummyKeyEncryption(object):
- pass
+ _skip_if_dsa_not_supported(backend, DummyHashAlgorithm(), 1, 1, 1)
@pytest.mark.requires_backend_interface(interface=DSABackend)
@@ -75,476 +71,282 @@ 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 == vector['p'].bit_length()
+ 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
- )
-
- def test_invalid_parameters_values(self, backend):
- # Test a p < 1024 bits in length
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=2 ** 1000,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ).parameters(backend)
-
- # Test a p < 2048 bits in length
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=2 ** 2000,
- q=DSA_KEY_2048.public_numbers.parameter_numbers.q,
- g=DSA_KEY_2048.public_numbers.parameter_numbers.g,
- ).parameters(backend)
-
- # Test a p < 3072 bits in length
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=2 ** 3000,
- q=DSA_KEY_3072.public_numbers.parameter_numbers.q,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ).parameters(backend)
-
- # Test a p > 3072 bits in length
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=2 ** 3100,
- q=DSA_KEY_3072.public_numbers.parameter_numbers.q,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ).parameters(backend)
-
- # Test a q < 160 bits in length
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=2 ** 150,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ).parameters(backend)
-
- # Test a q < 256 bits in length
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=DSA_KEY_2048.public_numbers.parameter_numbers.p,
- q=2 ** 250,
- g=DSA_KEY_2048.public_numbers.parameter_numbers.g
- ).parameters(backend)
-
- # Test a q > 256 bits in length
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=DSA_KEY_3072.public_numbers.parameter_numbers.p,
- q=2 ** 260,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ).parameters(backend)
-
- # Test a g < 1
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=0
- ).parameters(backend)
-
- # Test a g = 1
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=1
- ).parameters(backend)
-
- # Test a g > p
- with pytest.raises(ValueError):
- dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=2 ** 1200
- ).parameters(backend)
-
- def test_invalid_dsa_private_key_arguments(self, backend):
- # Test a p < 1024 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=2 ** 1000,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=DSA_KEY_1024.x
- ).private_key(backend)
-
- # Test a p < 2048 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=2 ** 2000,
- q=DSA_KEY_2048.public_numbers.parameter_numbers.q,
- g=DSA_KEY_2048.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_2048.public_numbers.y
- ),
- x=DSA_KEY_2048.x,
- ).private_key(backend)
-
- # Test a p < 3072 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=2 ** 3000,
- q=DSA_KEY_3072.public_numbers.parameter_numbers.q,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_3072.public_numbers.y
- ),
- x=DSA_KEY_3072.x,
- ).private_key(backend)
-
- # Test a p > 3072 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=2 ** 3100,
- q=DSA_KEY_3072.public_numbers.parameter_numbers.q,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_3072.public_numbers.y
- ),
- x=DSA_KEY_3072.x,
- ).private_key(backend)
-
- # Test a q < 160 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=2 ** 150,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=DSA_KEY_1024.x,
- ).private_key(backend)
-
- # Test a q < 256 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_2048.public_numbers.parameter_numbers.p,
- q=2 ** 250,
- g=DSA_KEY_2048.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_2048.public_numbers.y
- ),
- x=DSA_KEY_2048.x,
- ).private_key(backend)
-
- # Test a q > 256 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_3072.public_numbers.parameter_numbers.p,
- q=2 ** 260,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_3072.public_numbers.y
- ),
- x=DSA_KEY_3072.x,
- ).private_key(backend)
-
- # Test a g < 1
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=0,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=DSA_KEY_1024.x,
- ).private_key(backend)
-
- # Test a g = 1
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=1,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=DSA_KEY_1024.x,
- ).private_key(backend)
-
- # Test a g > p
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=2 ** 1200,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=DSA_KEY_1024.x,
- ).private_key(backend)
-
- # Test x = 0
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=0,
- ).private_key(backend)
-
- # Test x < 0
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=-2,
- ).private_key(backend)
-
- # Test x = q
- with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=2 ** 159,
- ).private_key(backend)
+ 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
+ )
- # Test x > q
+ @pytest.mark.parametrize(
+ ("p", "q", "g"),
+ [
+ (
+ 2 ** 1000,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ ),
+ (
+ 2 ** 2000,
+ DSA_KEY_2048.public_numbers.parameter_numbers.q,
+ DSA_KEY_2048.public_numbers.parameter_numbers.g,
+ ),
+ (
+ 2 ** 3000,
+ DSA_KEY_3072.public_numbers.parameter_numbers.q,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ ),
+ (
+ 2 ** 3100,
+ DSA_KEY_3072.public_numbers.parameter_numbers.q,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ 2 ** 150,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ ),
+ (
+ DSA_KEY_2048.public_numbers.parameter_numbers.p,
+ 2 ** 250,
+ DSA_KEY_2048.public_numbers.parameter_numbers.g
+ ),
+ (
+ DSA_KEY_3072.public_numbers.parameter_numbers.p,
+ 2 ** 260,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 0
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 1
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 2 ** 1200
+ ),
+ ]
+ )
+ def test_invalid_parameters_values(self, p, q, g, backend):
with pytest.raises(ValueError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=2 ** 200,
- ).private_key(backend)
+ dsa.DSAParameterNumbers(p, q, g).parameters(backend)
- # Test y != (g ** x) % p
+ @pytest.mark.parametrize(
+ ("p", "q", "g", "y", "x"),
+ [
+ (
+ 2 ** 1000,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ DSA_KEY_1024.public_numbers.y,
+ DSA_KEY_1024.x,
+ ),
+ (
+ 2 ** 2000,
+ DSA_KEY_2048.public_numbers.parameter_numbers.q,
+ DSA_KEY_2048.public_numbers.parameter_numbers.g,
+ DSA_KEY_2048.public_numbers.y,
+ DSA_KEY_2048.x,
+ ),
+ (
+ 2 ** 3000,
+ DSA_KEY_3072.public_numbers.parameter_numbers.q,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ DSA_KEY_3072.public_numbers.y,
+ DSA_KEY_3072.x,
+ ),
+ (
+ 2 ** 3100,
+ DSA_KEY_3072.public_numbers.parameter_numbers.q,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ DSA_KEY_3072.public_numbers.y,
+ DSA_KEY_3072.x,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ 2 ** 150,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ DSA_KEY_1024.public_numbers.y,
+ DSA_KEY_1024.x,
+ ),
+ (
+ DSA_KEY_2048.public_numbers.parameter_numbers.p,
+ 2 ** 250,
+ DSA_KEY_2048.public_numbers.parameter_numbers.g,
+ DSA_KEY_2048.public_numbers.y,
+ DSA_KEY_2048.x,
+ ),
+ (
+ DSA_KEY_3072.public_numbers.parameter_numbers.p,
+ 2 ** 260,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ DSA_KEY_3072.public_numbers.y,
+ DSA_KEY_3072.x,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 0,
+ DSA_KEY_1024.public_numbers.y,
+ DSA_KEY_1024.x,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 1,
+ DSA_KEY_1024.public_numbers.y,
+ DSA_KEY_1024.x,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 2 ** 1200,
+ DSA_KEY_1024.public_numbers.y,
+ DSA_KEY_1024.x,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ DSA_KEY_1024.public_numbers.y,
+ 0,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ DSA_KEY_1024.public_numbers.y,
+ -2,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ DSA_KEY_1024.public_numbers.y,
+ 2 ** 159,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ DSA_KEY_1024.public_numbers.y,
+ 2 ** 200,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ 2 ** 100,
+ DSA_KEY_1024.x
+ ),
+ ]
+ )
+ def test_invalid_dsa_private_key_arguments(self, p, q, g, y, x, backend):
with pytest.raises(ValueError):
dsa.DSAPrivateNumbers(
public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=2 ** 100
- ),
- x=DSA_KEY_1024.x,
+ parameter_numbers=dsa.DSAParameterNumbers(p=p, q=q, g=g),
+ y=y
+ ), x=x
).private_key(backend)
- # Test a non-integer y value
- with pytest.raises(TypeError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=None
- ),
- x=DSA_KEY_1024.x,
- ).private_key(backend)
-
- # Test a non-integer x value
- with pytest.raises(TypeError):
- dsa.DSAPrivateNumbers(
- public_numbers=dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ),
- x=None,
- ).private_key(backend)
-
- def test_invalid_dsa_public_key_arguments(self, backend):
- # Test a p < 1024 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=2 ** 1000,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ).public_key(backend)
-
- # Test a p < 2048 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=2 ** 2000,
- q=DSA_KEY_2048.public_numbers.parameter_numbers.q,
- g=DSA_KEY_2048.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_2048.public_numbers.y
- ).public_key(backend)
-
- # Test a p < 3072 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=2 ** 3000,
- q=DSA_KEY_3072.public_numbers.parameter_numbers.q,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_3072.public_numbers.y
- ).public_key(backend)
-
- # Test a p > 3072 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=2 ** 3100,
- q=DSA_KEY_3072.public_numbers.parameter_numbers.q,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_3072.public_numbers.y
- ).public_key(backend)
-
- # Test a q < 160 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=2 ** 150,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ).public_key(backend)
-
- # Test a q < 256 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_2048.public_numbers.parameter_numbers.p,
- q=2 ** 250,
- g=DSA_KEY_2048.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_2048.public_numbers.y
- ).public_key(backend)
-
- # Test a q > 256 bits in length
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_3072.public_numbers.parameter_numbers.p,
- q=2 ** 260,
- g=DSA_KEY_3072.public_numbers.parameter_numbers.g,
- ),
- y=DSA_KEY_3072.public_numbers.y
- ).public_key(backend)
-
- # Test a g < 1
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=0,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ).public_key(backend)
-
- # Test a g = 1
- with pytest.raises(ValueError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=1,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ).public_key(backend)
-
- # Test a g > p
+ @pytest.mark.parametrize(
+ ("p", "q", "g", "y"),
+ [
+ (
+ 2 ** 1000,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ DSA_KEY_1024.public_numbers.y,
+ ),
+ (
+ 2 ** 2000,
+ DSA_KEY_2048.public_numbers.parameter_numbers.q,
+ DSA_KEY_2048.public_numbers.parameter_numbers.g,
+ DSA_KEY_2048.public_numbers.y,
+ ),
+ (
+ 2 ** 3000,
+ DSA_KEY_3072.public_numbers.parameter_numbers.q,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ DSA_KEY_3072.public_numbers.y,
+ ),
+ (
+ 2 ** 3100,
+ DSA_KEY_3072.public_numbers.parameter_numbers.q,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ DSA_KEY_3072.public_numbers.y,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ 2 ** 150,
+ DSA_KEY_1024.public_numbers.parameter_numbers.g,
+ DSA_KEY_1024.public_numbers.y,
+ ),
+ (
+ DSA_KEY_2048.public_numbers.parameter_numbers.p,
+ 2 ** 250,
+ DSA_KEY_2048.public_numbers.parameter_numbers.g,
+ DSA_KEY_2048.public_numbers.y,
+ ),
+ (
+ DSA_KEY_3072.public_numbers.parameter_numbers.p,
+ 2 ** 260,
+ DSA_KEY_3072.public_numbers.parameter_numbers.g,
+ DSA_KEY_3072.public_numbers.y,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 0,
+ DSA_KEY_1024.public_numbers.y,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 1,
+ DSA_KEY_1024.public_numbers.y,
+ ),
+ (
+ DSA_KEY_1024.public_numbers.parameter_numbers.p,
+ DSA_KEY_1024.public_numbers.parameter_numbers.q,
+ 2 ** 1200,
+ DSA_KEY_1024.public_numbers.y,
+ ),
+ ]
+ )
+ def test_invalid_dsa_public_key_arguments(self, p, q, g, y, backend):
with pytest.raises(ValueError):
dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=2 ** 1200,
- ),
- y=DSA_KEY_1024.public_numbers.y
- ).public_key(backend)
-
- # Test a non-integer y value
- with pytest.raises(TypeError):
- dsa.DSAPublicNumbers(
- parameter_numbers=dsa.DSAParameterNumbers(
- p=DSA_KEY_1024.public_numbers.parameter_numbers.p,
- q=DSA_KEY_1024.public_numbers.parameter_numbers.q,
- g=DSA_KEY_1024.public_numbers.parameter_numbers.g,
- ),
- y=None
+ parameter_numbers=dsa.DSAParameterNumbers(p=p, q=q, g=g),
+ y=y
).public_key(backend)
@@ -569,14 +371,10 @@ class TestDSAVerification(object):
def test_dsa_verification(self, vector, backend):
digest_algorithm = vector['digest_algorithm'].replace("-", "")
algorithm = self._algorithms_dict[digest_algorithm]
- if (
- not backend.dsa_parameters_supported(
- vector['p'], vector['q'], vector['g']
- ) or not backend.dsa_hash_supported(algorithm)
- ):
- pytest.skip(
- "{0} does not support the provided parameters".format(backend)
- )
+
+ _skip_if_dsa_not_supported(
+ backend, algorithm, vector['p'], vector['q'], vector['g']
+ )
public_key = dsa.DSAPublicNumbers(
parameter_numbers=dsa.DSAParameterNumbers(
@@ -584,25 +382,29 @@ class TestDSAVerification(object):
),
y=vector['y']
).public_key(backend)
- sig = encode_rfc6979_signature(vector['r'], vector['s'])
- verifier = public_key.verifier(sig, algorithm())
- verifier.update(vector['msg'])
+ sig = encode_dss_signature(vector['r'], vector['s'])
+
if vector['result'] == "F":
with pytest.raises(InvalidSignature):
- verifier.verify()
+ public_key.verify(sig, vector['msg'], algorithm())
else:
- verifier.verify()
+ public_key.verify(sig, vector['msg'], algorithm())
def test_dsa_verify_invalid_asn1(self, backend):
public_key = DSA_KEY_1024.public_numbers.public_key(backend)
- verifier = public_key.verifier(b'fakesig', hashes.SHA1())
- verifier.update(b'fakesig')
with pytest.raises(InvalidSignature):
- verifier.verify()
+ public_key.verify(b'fakesig', b'fakemsg', hashes.SHA1())
+
+ def test_signature_not_bytes(self, backend):
+ public_key = DSA_KEY_1024.public_numbers.public_key(backend)
+ with pytest.raises(TypeError), \
+ pytest.warns(CryptographyDeprecationWarning):
+ public_key.verifier(1234, hashes.SHA1())
def test_use_after_finalize(self, backend):
public_key = DSA_KEY_1024.public_numbers.public_key(backend)
- verifier = public_key.verifier(b'fakesig', hashes.SHA1())
+ with pytest.warns(CryptographyDeprecationWarning):
+ verifier = public_key.verifier(b'fakesig', hashes.SHA1())
verifier.update(b'irrelevant')
with pytest.raises(InvalidSignature):
verifier.verify()
@@ -611,6 +413,50 @@ class TestDSAVerification(object):
with pytest.raises(AlreadyFinalized):
verifier.update(b"more data")
+ def test_verify(self, backend):
+ message = b"one little message"
+ algorithm = hashes.SHA1()
+ private_key = DSA_KEY_1024.private_key(backend)
+ signature = private_key.sign(message, algorithm)
+ public_key = private_key.public_key()
+ public_key.verify(signature, message, algorithm)
+
+ def test_prehashed_verify(self, backend):
+ private_key = DSA_KEY_1024.private_key(backend)
+ message = b"one little message"
+ h = hashes.Hash(hashes.SHA1(), backend)
+ h.update(message)
+ digest = h.finalize()
+ prehashed_alg = Prehashed(hashes.SHA1())
+ signature = private_key.sign(message, hashes.SHA1())
+ public_key = private_key.public_key()
+ public_key.verify(signature, digest, prehashed_alg)
+
+ def test_prehashed_digest_mismatch(self, backend):
+ private_key = DSA_KEY_1024.private_key(backend)
+ public_key = private_key.public_key()
+ message = b"one little message"
+ h = hashes.Hash(hashes.SHA1(), backend)
+ h.update(message)
+ digest = h.finalize()
+ prehashed_alg = Prehashed(hashes.SHA224())
+ with pytest.raises(ValueError):
+ public_key.verify(b"\x00" * 128, digest, prehashed_alg)
+
+ def test_prehashed_unsupported_in_signer_ctx(self, backend):
+ private_key = DSA_KEY_1024.private_key(backend)
+ with pytest.raises(TypeError), \
+ pytest.warns(CryptographyDeprecationWarning):
+ private_key.signer(Prehashed(hashes.SHA1()))
+
+ def test_prehashed_unsupported_in_verifier_ctx(self, backend):
+ public_key = DSA_KEY_1024.private_key(backend).public_key()
+ with pytest.raises(TypeError), \
+ pytest.warns(CryptographyDeprecationWarning):
+ public_key.verifier(
+ b"0" * 64, Prehashed(hashes.SHA1())
+ )
+
@pytest.mark.requires_backend_interface(interface=DSABackend)
class TestDSASignature(object):
@@ -632,14 +478,10 @@ class TestDSASignature(object):
def test_dsa_signing(self, vector, backend):
digest_algorithm = vector['digest_algorithm'].replace("-", "")
algorithm = self._algorithms_dict[digest_algorithm]
- if (
- not backend.dsa_parameters_supported(
- vector['p'], vector['q'], vector['g']
- ) or not backend.dsa_hash_supported(algorithm)
- ):
- pytest.skip(
- "{0} does not support the provided parameters".format(backend)
- )
+
+ _skip_if_dsa_not_supported(
+ backend, algorithm, vector['p'], vector['q'], vector['g']
+ )
private_key = dsa.DSAPrivateNumbers(
public_numbers=dsa.DSAPublicNumbers(
@@ -650,19 +492,15 @@ class TestDSASignature(object):
),
x=vector['x']
).private_key(backend)
- signer = private_key.signer(algorithm())
- signer.update(vector['msg'])
- signature = signer.finalize()
+ signature = private_key.sign(vector['msg'], algorithm())
assert signature
- public_key = private_key.public_key()
- verifier = public_key.verifier(signature, algorithm())
- verifier.update(vector['msg'])
- verifier.verify()
+ private_key.public_key().verify(signature, vector['msg'], algorithm())
def test_use_after_finalize(self, backend):
private_key = DSA_KEY_1024.private_key(backend)
- signer = private_key.signer(hashes.SHA1())
+ with pytest.warns(CryptographyDeprecationWarning):
+ signer = private_key.signer(hashes.SHA1())
signer.update(b"data")
signer.finalize()
with pytest.raises(AlreadyFinalized):
@@ -670,6 +508,35 @@ class TestDSASignature(object):
with pytest.raises(AlreadyFinalized):
signer.update(b"more data")
+ def test_sign(self, backend):
+ private_key = DSA_KEY_1024.private_key(backend)
+ message = b"one little message"
+ algorithm = hashes.SHA1()
+ signature = private_key.sign(message, algorithm)
+ public_key = private_key.public_key()
+ public_key.verify(signature, message, algorithm)
+
+ def test_prehashed_sign(self, backend):
+ private_key = DSA_KEY_1024.private_key(backend)
+ message = b"one little message"
+ h = hashes.Hash(hashes.SHA1(), backend)
+ h.update(message)
+ digest = h.finalize()
+ prehashed_alg = Prehashed(hashes.SHA1())
+ signature = private_key.sign(digest, prehashed_alg)
+ public_key = private_key.public_key()
+ public_key.verify(signature, message, hashes.SHA1())
+
+ def test_prehashed_digest_mismatch(self, backend):
+ private_key = DSA_KEY_1024.private_key(backend)
+ message = b"one little message"
+ h = hashes.Hash(hashes.SHA1(), backend)
+ h.update(message)
+ digest = h.finalize()
+ prehashed_alg = Prehashed(hashes.SHA224())
+ with pytest.raises(ValueError):
+ private_key.sign(digest, prehashed_alg)
+
class TestDSANumbers(object):
def test_dsa_parameter_numbers(self):
@@ -730,6 +597,21 @@ class TestDSANumbers(object):
with pytest.raises(TypeError):
dsa.DSAPrivateNumbers(x=None, public_numbers=public_numbers)
+ def test_repr(self):
+ parameter_numbers = dsa.DSAParameterNumbers(p=1, q=2, g=3)
+ assert (
+ repr(parameter_numbers) == "<DSAParameterNumbers(p=1, q=2, g=3)>"
+ )
+
+ public_numbers = dsa.DSAPublicNumbers(
+ y=4,
+ parameter_numbers=parameter_numbers
+ )
+ assert repr(public_numbers) == (
+ "<DSAPublicNumbers(y=4, parameter_numbers=<DSAParameterNumbers(p=1"
+ ", q=2, g=3)>)>"
+ )
+
class TestDSANumberEquality(object):
def test_parameter_numbers_eq(self):
@@ -819,7 +701,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,
@@ -833,6 +714,20 @@ class TestDSASerialization(object):
assert loaded_priv_num == priv_num
@pytest.mark.parametrize(
+ ("encoding", "fmt"),
+ [
+ (serialization.Encoding.Raw, serialization.PrivateFormat.PKCS8),
+ (serialization.Encoding.DER, serialization.PrivateFormat.Raw),
+ (serialization.Encoding.Raw, serialization.PrivateFormat.Raw),
+ (serialization.Encoding.X962, serialization.PrivateFormat.PKCS8),
+ ]
+ )
+ def test_private_bytes_rejects_invalid(self, encoding, fmt, backend):
+ key = DSA_KEY_1024.private_key(backend)
+ with pytest.raises(ValueError):
+ key.private_bytes(encoding, fmt, serialization.NoEncryption())
+
+ @pytest.mark.parametrize(
("fmt", "password"),
[
[serialization.PrivateFormat.PKCS8, b"s"],
@@ -847,7 +742,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 +782,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 +827,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 +841,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 +855,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 +869,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,12 +883,11 @@ class TestDSASerialization(object):
pemfile.read().encode(), None, backend
)
)
- _skip_if_no_serialization(key, backend)
with pytest.raises(ValueError):
key.private_bytes(
serialization.Encoding.PEM,
serialization.PrivateFormat.TraditionalOpenSSL,
- DummyKeyEncryption()
+ DummyKeySerializationEncryption()
)
@@ -1030,15 +918,36 @@ 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,
)
assert serialized == key_bytes
+ def test_public_bytes_openssh(self, backend):
+ key_bytes = load_vectors_from_file(
+ os.path.join("asymmetric", "PKCS8", "unenc-dsa-pkcs8.pub.pem"),
+ lambda pemfile: pemfile.read(), mode="rb"
+ )
+ key = serialization.load_pem_public_key(key_bytes, backend)
+
+ ssh_bytes = key.public_bytes(
+ serialization.Encoding.OpenSSH, serialization.PublicFormat.OpenSSH
+ )
+ assert ssh_bytes == (
+ b"ssh-dss AAAAB3NzaC1kc3MAAACBAKoJMMwUWCUiHK/6KKwolBlqJ4M95ewhJweR"
+ b"aJQgd3Si57I4sNNvGySZosJYUIPrAUMpJEGNhn+qIS3RBx1NzrJ4J5StOTzAik1K"
+ b"2n9o1ug5pfzTS05ALYLLioy0D+wxkRv5vTYLA0yqy0xelHmSVzyekAmcGw8FlAyr"
+ b"5dLeSaFnAAAAFQCtwOhps28KwBOmgf301ImdaYIEUQAAAIEAjGtFia+lOk0QSL/D"
+ b"RtHzhsp1UhzPct2qJRKGiA7hMgH/SIkLv8M9ebrK7HHnp3hQe9XxpmQi45QVvgPn"
+ b"EUG6Mk9bkxMZKRgsiKn6QGKDYGbOvnS1xmkMfRARBsJAq369VOTjMB/Qhs5q2ski"
+ b"+ycTorCIfLoTubxozlz/8kHNMkYAAACAKyYOqX3GoSrpMsZA5989j/BKigWgMk+N"
+ b"Xxsj8V+hcP8/QgYRJO/yWGyxG0moLc3BuQ/GqE+xAQnLZ9tdLalxrq8Xvl43KEVj"
+ b"5MZNnl/ISAJYsxnw3inVTYNQcNnih5FNd9+BSR9EI7YtqYTrP0XrKin86l2uUlrG"
+ b"q2vM4Ev99bY="
+ )
+
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,14 +956,39 @@ 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
)
+
+ @pytest.mark.parametrize(
+ ("encoding", "fmt"),
+ [
+ (
+ serialization.Encoding.Raw,
+ serialization.PublicFormat.SubjectPublicKeyInfo
+ ),
+ (serialization.Encoding.Raw, serialization.PublicFormat.PKCS1),
+ ] + list(itertools.product(
+ [
+ serialization.Encoding.Raw,
+ serialization.Encoding.X962,
+ serialization.Encoding.PEM,
+ serialization.Encoding.DER
+ ],
+ [
+ serialization.PublicFormat.Raw,
+ serialization.PublicFormat.UncompressedPoint,
+ serialization.PublicFormat.CompressedPoint
+ ]
+ ))
+ )
+ def test_public_bytes_rejects_invalid(self, encoding, fmt, backend):
+ key = DSA_KEY_2048.private_key(backend).public_key()
+ with pytest.raises(ValueError):
+ key.public_bytes(encoding, fmt)