Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py: 57%
134 statements
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:05 +0000
« prev ^ index » next coverage.py v7.3.2, created at 2023-12-08 06:05 +0000
1# This file is dual licensed under the terms of the Apache License, Version
2# 2.0, and the BSD License. See the LICENSE file in the root of this repository
3# for complete details.
5from __future__ import annotations
7import abc
8import typing
10from cryptography.hazmat.bindings._rust import openssl as rust_openssl
11from cryptography.hazmat.primitives import _serialization, hashes
12from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
15class DSAParameters(metaclass=abc.ABCMeta):
16 @abc.abstractmethod
17 def generate_private_key(self) -> DSAPrivateKey:
18 """
19 Generates and returns a DSAPrivateKey.
20 """
22 @abc.abstractmethod
23 def parameter_numbers(self) -> DSAParameterNumbers:
24 """
25 Returns a DSAParameterNumbers.
26 """
29DSAParametersWithNumbers = DSAParameters
30DSAParameters.register(rust_openssl.dsa.DSAParameters)
33class DSAPrivateKey(metaclass=abc.ABCMeta):
34 @property
35 @abc.abstractmethod
36 def key_size(self) -> int:
37 """
38 The bit length of the prime modulus.
39 """
41 @abc.abstractmethod
42 def public_key(self) -> DSAPublicKey:
43 """
44 The DSAPublicKey associated with this private key.
45 """
47 @abc.abstractmethod
48 def parameters(self) -> DSAParameters:
49 """
50 The DSAParameters object associated with this private key.
51 """
53 @abc.abstractmethod
54 def sign(
55 self,
56 data: bytes,
57 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
58 ) -> bytes:
59 """
60 Signs the data
61 """
63 @abc.abstractmethod
64 def private_numbers(self) -> DSAPrivateNumbers:
65 """
66 Returns a DSAPrivateNumbers.
67 """
69 @abc.abstractmethod
70 def private_bytes(
71 self,
72 encoding: _serialization.Encoding,
73 format: _serialization.PrivateFormat,
74 encryption_algorithm: _serialization.KeySerializationEncryption,
75 ) -> bytes:
76 """
77 Returns the key serialized as bytes.
78 """
81DSAPrivateKeyWithSerialization = DSAPrivateKey
82DSAPrivateKey.register(rust_openssl.dsa.DSAPrivateKey)
85class DSAPublicKey(metaclass=abc.ABCMeta):
86 @property
87 @abc.abstractmethod
88 def key_size(self) -> int:
89 """
90 The bit length of the prime modulus.
91 """
93 @abc.abstractmethod
94 def parameters(self) -> DSAParameters:
95 """
96 The DSAParameters object associated with this public key.
97 """
99 @abc.abstractmethod
100 def public_numbers(self) -> DSAPublicNumbers:
101 """
102 Returns a DSAPublicNumbers.
103 """
105 @abc.abstractmethod
106 def public_bytes(
107 self,
108 encoding: _serialization.Encoding,
109 format: _serialization.PublicFormat,
110 ) -> bytes:
111 """
112 Returns the key serialized as bytes.
113 """
115 @abc.abstractmethod
116 def verify(
117 self,
118 signature: bytes,
119 data: bytes,
120 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
121 ) -> None:
122 """
123 Verifies the signature of the data.
124 """
126 @abc.abstractmethod
127 def __eq__(self, other: object) -> bool:
128 """
129 Checks equality.
130 """
133DSAPublicKeyWithSerialization = DSAPublicKey
134DSAPublicKey.register(rust_openssl.dsa.DSAPublicKey)
137class DSAParameterNumbers:
138 def __init__(self, p: int, q: int, g: int):
139 if (
140 not isinstance(p, int)
141 or not isinstance(q, int)
142 or not isinstance(g, int)
143 ):
144 raise TypeError(
145 "DSAParameterNumbers p, q, and g arguments must be integers."
146 )
148 self._p = p
149 self._q = q
150 self._g = g
152 @property
153 def p(self) -> int:
154 return self._p
156 @property
157 def q(self) -> int:
158 return self._q
160 @property
161 def g(self) -> int:
162 return self._g
164 def parameters(self, backend: typing.Any = None) -> DSAParameters:
165 from cryptography.hazmat.backends.openssl.backend import (
166 backend as ossl,
167 )
169 return ossl.load_dsa_parameter_numbers(self)
171 def __eq__(self, other: object) -> bool:
172 if not isinstance(other, DSAParameterNumbers):
173 return NotImplemented
175 return self.p == other.p and self.q == other.q and self.g == other.g
177 def __repr__(self) -> str:
178 return (
179 "<DSAParameterNumbers(p={self.p}, q={self.q}, "
180 "g={self.g})>".format(self=self)
181 )
184class DSAPublicNumbers:
185 def __init__(self, y: int, parameter_numbers: DSAParameterNumbers):
186 if not isinstance(y, int):
187 raise TypeError("DSAPublicNumbers y argument must be an integer.")
189 if not isinstance(parameter_numbers, DSAParameterNumbers):
190 raise TypeError(
191 "parameter_numbers must be a DSAParameterNumbers instance."
192 )
194 self._y = y
195 self._parameter_numbers = parameter_numbers
197 @property
198 def y(self) -> int:
199 return self._y
201 @property
202 def parameter_numbers(self) -> DSAParameterNumbers:
203 return self._parameter_numbers
205 def public_key(self, backend: typing.Any = None) -> DSAPublicKey:
206 from cryptography.hazmat.backends.openssl.backend import (
207 backend as ossl,
208 )
210 return ossl.load_dsa_public_numbers(self)
212 def __eq__(self, other: object) -> bool:
213 if not isinstance(other, DSAPublicNumbers):
214 return NotImplemented
216 return (
217 self.y == other.y
218 and self.parameter_numbers == other.parameter_numbers
219 )
221 def __repr__(self) -> str:
222 return (
223 "<DSAPublicNumbers(y={self.y}, "
224 "parameter_numbers={self.parameter_numbers})>".format(self=self)
225 )
228class DSAPrivateNumbers:
229 def __init__(self, x: int, public_numbers: DSAPublicNumbers):
230 if not isinstance(x, int):
231 raise TypeError("DSAPrivateNumbers x argument must be an integer.")
233 if not isinstance(public_numbers, DSAPublicNumbers):
234 raise TypeError(
235 "public_numbers must be a DSAPublicNumbers instance."
236 )
237 self._public_numbers = public_numbers
238 self._x = x
240 @property
241 def x(self) -> int:
242 return self._x
244 @property
245 def public_numbers(self) -> DSAPublicNumbers:
246 return self._public_numbers
248 def private_key(self, backend: typing.Any = None) -> DSAPrivateKey:
249 from cryptography.hazmat.backends.openssl.backend import (
250 backend as ossl,
251 )
253 return ossl.load_dsa_private_numbers(self)
255 def __eq__(self, other: object) -> bool:
256 if not isinstance(other, DSAPrivateNumbers):
257 return NotImplemented
259 return (
260 self.x == other.x and self.public_numbers == other.public_numbers
261 )
264def generate_parameters(
265 key_size: int, backend: typing.Any = None
266) -> DSAParameters:
267 from cryptography.hazmat.backends.openssl.backend import backend as ossl
269 return ossl.generate_dsa_parameters(key_size)
272def generate_private_key(
273 key_size: int, backend: typing.Any = None
274) -> DSAPrivateKey:
275 from cryptography.hazmat.backends.openssl.backend import backend as ossl
277 return ossl.generate_dsa_private_key_and_parameters(key_size)
280def _check_dsa_parameters(parameters: DSAParameterNumbers) -> None:
281 if parameters.p.bit_length() not in [1024, 2048, 3072, 4096]:
282 raise ValueError(
283 "p must be exactly 1024, 2048, 3072, or 4096 bits long"
284 )
285 if parameters.q.bit_length() not in [160, 224, 256]:
286 raise ValueError("q must be exactly 160, 224, or 256 bits long")
288 if not (1 < parameters.g < parameters.p):
289 raise ValueError("g, p don't satisfy 1 < g < p.")
292def _check_dsa_private_numbers(numbers: DSAPrivateNumbers) -> None:
293 parameters = numbers.public_numbers.parameter_numbers
294 _check_dsa_parameters(parameters)
295 if numbers.x <= 0 or numbers.x >= parameters.q:
296 raise ValueError("x must be > 0 and < q.")
298 if numbers.public_numbers.y != pow(parameters.g, numbers.x, parameters.p):
299 raise ValueError("y must be equal to (g ** x % p).")