Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/cryptography/hazmat/primitives/asymmetric/dsa.py : 57%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
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 import utils
10from cryptography.hazmat.backends import _get_backend
11from cryptography.hazmat.primitives import _serialization, hashes
12from cryptography.hazmat.primitives.asymmetric import (
13 AsymmetricSignatureContext,
14 AsymmetricVerificationContext,
15 utils as asym_utils,
16)
19class DSAParameters(metaclass=abc.ABCMeta):
20 @abc.abstractmethod
21 def generate_private_key(self) -> "DSAPrivateKey":
22 """
23 Generates and returns a DSAPrivateKey.
24 """
26 @abc.abstractmethod
27 def parameter_numbers(self) -> "DSAParameterNumbers":
28 """
29 Returns a DSAParameterNumbers.
30 """
33DSAParametersWithNumbers = DSAParameters
36class DSAPrivateKey(metaclass=abc.ABCMeta):
37 @abc.abstractproperty
38 def key_size(self) -> int:
39 """
40 The bit length of the prime modulus.
41 """
43 @abc.abstractmethod
44 def public_key(self) -> "DSAPublicKey":
45 """
46 The DSAPublicKey associated with this private key.
47 """
49 @abc.abstractmethod
50 def parameters(self) -> DSAParameters:
51 """
52 The DSAParameters object associated with this private key.
53 """
55 @abc.abstractmethod
56 def signer(
57 self,
58 signature_algorithm: hashes.HashAlgorithm,
59 ) -> AsymmetricSignatureContext:
60 """
61 Returns an AsymmetricSignatureContext used for signing data.
62 """
64 @abc.abstractmethod
65 def sign(
66 self,
67 data: bytes,
68 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
69 ) -> bytes:
70 """
71 Signs the data
72 """
74 @abc.abstractmethod
75 def private_numbers(self) -> "DSAPrivateNumbers":
76 """
77 Returns a DSAPrivateNumbers.
78 """
80 @abc.abstractmethod
81 def private_bytes(
82 self,
83 encoding: _serialization.Encoding,
84 format: _serialization.PrivateFormat,
85 encryption_algorithm: _serialization.KeySerializationEncryption,
86 ) -> bytes:
87 """
88 Returns the key serialized as bytes.
89 """
92DSAPrivateKeyWithSerialization = DSAPrivateKey
95class DSAPublicKey(metaclass=abc.ABCMeta):
96 @abc.abstractproperty
97 def key_size(self) -> int:
98 """
99 The bit length of the prime modulus.
100 """
102 @abc.abstractmethod
103 def parameters(self) -> DSAParameters:
104 """
105 The DSAParameters object associated with this public key.
106 """
108 @abc.abstractmethod
109 def verifier(
110 self,
111 signature: bytes,
112 signature_algorithm: hashes.HashAlgorithm,
113 ) -> AsymmetricVerificationContext:
114 """
115 Returns an AsymmetricVerificationContext used for signing data.
116 """
118 @abc.abstractmethod
119 def public_numbers(self) -> "DSAPublicNumbers":
120 """
121 Returns a DSAPublicNumbers.
122 """
124 @abc.abstractmethod
125 def public_bytes(
126 self,
127 encoding: _serialization.Encoding,
128 format: _serialization.PublicFormat,
129 ) -> bytes:
130 """
131 Returns the key serialized as bytes.
132 """
134 @abc.abstractmethod
135 def verify(
136 self,
137 signature: bytes,
138 data: bytes,
139 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
140 ):
141 """
142 Verifies the signature of the data.
143 """
146DSAPublicKeyWithSerialization = DSAPublicKey
149class DSAParameterNumbers(object):
150 def __init__(self, p: int, q: int, g: int):
151 if (
152 not isinstance(p, int)
153 or not isinstance(q, int)
154 or not isinstance(g, int)
155 ):
156 raise TypeError(
157 "DSAParameterNumbers p, q, and g arguments must be integers."
158 )
160 self._p = p
161 self._q = q
162 self._g = g
164 p = utils.read_only_property("_p")
165 q = utils.read_only_property("_q")
166 g = utils.read_only_property("_g")
168 def parameters(self, backend=None) -> DSAParameters:
169 backend = _get_backend(backend)
170 return backend.load_dsa_parameter_numbers(self)
172 def __eq__(self, other):
173 if not isinstance(other, DSAParameterNumbers):
174 return NotImplemented
176 return self.p == other.p and self.q == other.q and self.g == other.g
178 def __ne__(self, other):
179 return not self == other
181 def __repr__(self):
182 return (
183 "<DSAParameterNumbers(p={self.p}, q={self.q}, "
184 "g={self.g})>".format(self=self)
185 )
188class DSAPublicNumbers(object):
189 def __init__(self, y: int, parameter_numbers: DSAParameterNumbers):
190 if not isinstance(y, int):
191 raise TypeError("DSAPublicNumbers y argument must be an integer.")
193 if not isinstance(parameter_numbers, DSAParameterNumbers):
194 raise TypeError(
195 "parameter_numbers must be a DSAParameterNumbers instance."
196 )
198 self._y = y
199 self._parameter_numbers = parameter_numbers
201 y = utils.read_only_property("_y")
202 parameter_numbers = utils.read_only_property("_parameter_numbers")
204 def public_key(self, backend=None) -> DSAPublicKey:
205 backend = _get_backend(backend)
206 return backend.load_dsa_public_numbers(self)
208 def __eq__(self, other):
209 if not isinstance(other, DSAPublicNumbers):
210 return NotImplemented
212 return (
213 self.y == other.y
214 and self.parameter_numbers == other.parameter_numbers
215 )
217 def __ne__(self, other):
218 return not self == other
220 def __repr__(self):
221 return (
222 "<DSAPublicNumbers(y={self.y}, "
223 "parameter_numbers={self.parameter_numbers})>".format(self=self)
224 )
227class DSAPrivateNumbers(object):
228 def __init__(self, x: int, public_numbers: DSAPublicNumbers):
229 if not isinstance(x, int):
230 raise TypeError("DSAPrivateNumbers x argument must be an integer.")
232 if not isinstance(public_numbers, DSAPublicNumbers):
233 raise TypeError(
234 "public_numbers must be a DSAPublicNumbers instance."
235 )
236 self._public_numbers = public_numbers
237 self._x = x
239 x = utils.read_only_property("_x")
240 public_numbers = utils.read_only_property("_public_numbers")
242 def private_key(self, backend=None) -> DSAPrivateKey:
243 backend = _get_backend(backend)
244 return backend.load_dsa_private_numbers(self)
246 def __eq__(self, other):
247 if not isinstance(other, DSAPrivateNumbers):
248 return NotImplemented
250 return (
251 self.x == other.x and self.public_numbers == other.public_numbers
252 )
254 def __ne__(self, other):
255 return not self == other
258def generate_parameters(key_size: int, backend=None) -> DSAParameters:
259 backend = _get_backend(backend)
260 return backend.generate_dsa_parameters(key_size)
263def generate_private_key(key_size: int, backend=None) -> DSAPrivateKey:
264 backend = _get_backend(backend)
265 return backend.generate_dsa_private_key_and_parameters(key_size)
268def _check_dsa_parameters(parameters: DSAParameterNumbers):
269 if parameters.p.bit_length() not in [1024, 2048, 3072, 4096]:
270 raise ValueError(
271 "p must be exactly 1024, 2048, 3072, or 4096 bits long"
272 )
273 if parameters.q.bit_length() not in [160, 224, 256]:
274 raise ValueError("q must be exactly 160, 224, or 256 bits long")
276 if not (1 < parameters.g < parameters.p):
277 raise ValueError("g, p don't satisfy 1 < g < p.")
280def _check_dsa_private_numbers(numbers: DSAPrivateNumbers):
281 parameters = numbers.public_numbers.parameter_numbers
282 _check_dsa_parameters(parameters)
283 if numbers.x <= 0 or numbers.x >= parameters.q:
284 raise ValueError("x must be > 0 and < q.")
286 if numbers.public_numbers.y != pow(parameters.g, numbers.x, parameters.p):
287 raise ValueError("y must be equal to (g ** x % p).")