Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py: 54%
125 statements
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +0000
« prev ^ index » next coverage.py v7.0.1, created at 2022-12-25 06:11 +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.
6import abc
7import typing
9from cryptography.hazmat.primitives import _serialization, hashes
10from cryptography.hazmat.primitives.asymmetric import (
11 utils as asym_utils,
12)
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
32class DSAPrivateKey(metaclass=abc.ABCMeta):
33 @abc.abstractproperty
34 def key_size(self) -> int:
35 """
36 The bit length of the prime modulus.
37 """
39 @abc.abstractmethod
40 def public_key(self) -> "DSAPublicKey":
41 """
42 The DSAPublicKey associated with this private key.
43 """
45 @abc.abstractmethod
46 def parameters(self) -> DSAParameters:
47 """
48 The DSAParameters object associated with this private key.
49 """
51 @abc.abstractmethod
52 def sign(
53 self,
54 data: bytes,
55 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
56 ) -> bytes:
57 """
58 Signs the data
59 """
61 @abc.abstractmethod
62 def private_numbers(self) -> "DSAPrivateNumbers":
63 """
64 Returns a DSAPrivateNumbers.
65 """
67 @abc.abstractmethod
68 def private_bytes(
69 self,
70 encoding: _serialization.Encoding,
71 format: _serialization.PrivateFormat,
72 encryption_algorithm: _serialization.KeySerializationEncryption,
73 ) -> bytes:
74 """
75 Returns the key serialized as bytes.
76 """
79DSAPrivateKeyWithSerialization = DSAPrivateKey
82class DSAPublicKey(metaclass=abc.ABCMeta):
83 @abc.abstractproperty
84 def key_size(self) -> int:
85 """
86 The bit length of the prime modulus.
87 """
89 @abc.abstractmethod
90 def parameters(self) -> DSAParameters:
91 """
92 The DSAParameters object associated with this public key.
93 """
95 @abc.abstractmethod
96 def public_numbers(self) -> "DSAPublicNumbers":
97 """
98 Returns a DSAPublicNumbers.
99 """
101 @abc.abstractmethod
102 def public_bytes(
103 self,
104 encoding: _serialization.Encoding,
105 format: _serialization.PublicFormat,
106 ) -> bytes:
107 """
108 Returns the key serialized as bytes.
109 """
111 @abc.abstractmethod
112 def verify(
113 self,
114 signature: bytes,
115 data: bytes,
116 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
117 ) -> None:
118 """
119 Verifies the signature of the data.
120 """
123DSAPublicKeyWithSerialization = DSAPublicKey
126class DSAParameterNumbers:
127 def __init__(self, p: int, q: int, g: int):
128 if (
129 not isinstance(p, int)
130 or not isinstance(q, int)
131 or not isinstance(g, int)
132 ):
133 raise TypeError(
134 "DSAParameterNumbers p, q, and g arguments must be integers."
135 )
137 self._p = p
138 self._q = q
139 self._g = g
141 @property
142 def p(self) -> int:
143 return self._p
145 @property
146 def q(self) -> int:
147 return self._q
149 @property
150 def g(self) -> int:
151 return self._g
153 def parameters(self, backend: typing.Any = None) -> DSAParameters:
154 from cryptography.hazmat.backends.openssl.backend import (
155 backend as ossl,
156 )
158 return ossl.load_dsa_parameter_numbers(self)
160 def __eq__(self, other: object) -> bool:
161 if not isinstance(other, DSAParameterNumbers):
162 return NotImplemented
164 return self.p == other.p and self.q == other.q and self.g == other.g
166 def __repr__(self) -> str:
167 return (
168 "<DSAParameterNumbers(p={self.p}, q={self.q}, "
169 "g={self.g})>".format(self=self)
170 )
173class DSAPublicNumbers:
174 def __init__(self, y: int, parameter_numbers: DSAParameterNumbers):
175 if not isinstance(y, int):
176 raise TypeError("DSAPublicNumbers y argument must be an integer.")
178 if not isinstance(parameter_numbers, DSAParameterNumbers):
179 raise TypeError(
180 "parameter_numbers must be a DSAParameterNumbers instance."
181 )
183 self._y = y
184 self._parameter_numbers = parameter_numbers
186 @property
187 def y(self) -> int:
188 return self._y
190 @property
191 def parameter_numbers(self) -> DSAParameterNumbers:
192 return self._parameter_numbers
194 def public_key(self, backend: typing.Any = None) -> DSAPublicKey:
195 from cryptography.hazmat.backends.openssl.backend import (
196 backend as ossl,
197 )
199 return ossl.load_dsa_public_numbers(self)
201 def __eq__(self, other: object) -> bool:
202 if not isinstance(other, DSAPublicNumbers):
203 return NotImplemented
205 return (
206 self.y == other.y
207 and self.parameter_numbers == other.parameter_numbers
208 )
210 def __repr__(self) -> str:
211 return (
212 "<DSAPublicNumbers(y={self.y}, "
213 "parameter_numbers={self.parameter_numbers})>".format(self=self)
214 )
217class DSAPrivateNumbers:
218 def __init__(self, x: int, public_numbers: DSAPublicNumbers):
219 if not isinstance(x, int):
220 raise TypeError("DSAPrivateNumbers x argument must be an integer.")
222 if not isinstance(public_numbers, DSAPublicNumbers):
223 raise TypeError(
224 "public_numbers must be a DSAPublicNumbers instance."
225 )
226 self._public_numbers = public_numbers
227 self._x = x
229 @property
230 def x(self) -> int:
231 return self._x
233 @property
234 def public_numbers(self) -> DSAPublicNumbers:
235 return self._public_numbers
237 def private_key(self, backend: typing.Any = None) -> DSAPrivateKey:
238 from cryptography.hazmat.backends.openssl.backend import (
239 backend as ossl,
240 )
242 return ossl.load_dsa_private_numbers(self)
244 def __eq__(self, other: object) -> bool:
245 if not isinstance(other, DSAPrivateNumbers):
246 return NotImplemented
248 return (
249 self.x == other.x and self.public_numbers == other.public_numbers
250 )
253def generate_parameters(
254 key_size: int, backend: typing.Any = None
255) -> DSAParameters:
256 from cryptography.hazmat.backends.openssl.backend import backend as ossl
258 return ossl.generate_dsa_parameters(key_size)
261def generate_private_key(
262 key_size: int, backend: typing.Any = None
263) -> DSAPrivateKey:
264 from cryptography.hazmat.backends.openssl.backend import backend as ossl
266 return ossl.generate_dsa_private_key_and_parameters(key_size)
269def _check_dsa_parameters(parameters: DSAParameterNumbers) -> None:
270 if parameters.p.bit_length() not in [1024, 2048, 3072, 4096]:
271 raise ValueError(
272 "p must be exactly 1024, 2048, 3072, or 4096 bits long"
273 )
274 if parameters.q.bit_length() not in [160, 224, 256]:
275 raise ValueError("q must be exactly 160, 224, or 256 bits long")
277 if not (1 < parameters.g < parameters.p):
278 raise ValueError("g, p don't satisfy 1 < g < p.")
281def _check_dsa_private_numbers(numbers: DSAPrivateNumbers) -> None:
282 parameters = numbers.public_numbers.parameter_numbers
283 _check_dsa_parameters(parameters)
284 if numbers.x <= 0 or numbers.x >= parameters.q:
285 raise ValueError("x must be > 0 and < q.")
287 if numbers.public_numbers.y != pow(parameters.g, numbers.x, parameters.p):
288 raise ValueError("y must be equal to (g ** x % p).")