Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py: 74%
216 statements
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +0000
« prev ^ index » next coverage.py v7.2.2, created at 2023-03-26 06:36 +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 import utils
10from cryptography.hazmat._oid import ObjectIdentifier
11from cryptography.hazmat.primitives import _serialization, hashes
12from cryptography.hazmat.primitives.asymmetric import utils as asym_utils
15class EllipticCurveOID:
16 SECP192R1 = ObjectIdentifier("1.2.840.10045.3.1.1")
17 SECP224R1 = ObjectIdentifier("1.3.132.0.33")
18 SECP256K1 = ObjectIdentifier("1.3.132.0.10")
19 SECP256R1 = ObjectIdentifier("1.2.840.10045.3.1.7")
20 SECP384R1 = ObjectIdentifier("1.3.132.0.34")
21 SECP521R1 = ObjectIdentifier("1.3.132.0.35")
22 BRAINPOOLP256R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.7")
23 BRAINPOOLP384R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.11")
24 BRAINPOOLP512R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.13")
25 SECT163K1 = ObjectIdentifier("1.3.132.0.1")
26 SECT163R2 = ObjectIdentifier("1.3.132.0.15")
27 SECT233K1 = ObjectIdentifier("1.3.132.0.26")
28 SECT233R1 = ObjectIdentifier("1.3.132.0.27")
29 SECT283K1 = ObjectIdentifier("1.3.132.0.16")
30 SECT283R1 = ObjectIdentifier("1.3.132.0.17")
31 SECT409K1 = ObjectIdentifier("1.3.132.0.36")
32 SECT409R1 = ObjectIdentifier("1.3.132.0.37")
33 SECT571K1 = ObjectIdentifier("1.3.132.0.38")
34 SECT571R1 = ObjectIdentifier("1.3.132.0.39")
37class EllipticCurve(metaclass=abc.ABCMeta):
38 @property
39 @abc.abstractmethod
40 def name(self) -> str:
41 """
42 The name of the curve. e.g. secp256r1.
43 """
45 @property
46 @abc.abstractmethod
47 def key_size(self) -> int:
48 """
49 Bit size of a secret scalar for the curve.
50 """
53class EllipticCurveSignatureAlgorithm(metaclass=abc.ABCMeta):
54 @property
55 @abc.abstractmethod
56 def algorithm(
57 self,
58 ) -> typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm]:
59 """
60 The digest algorithm used with this signature.
61 """
64class EllipticCurvePrivateKey(metaclass=abc.ABCMeta):
65 @abc.abstractmethod
66 def exchange(
67 self, algorithm: "ECDH", peer_public_key: "EllipticCurvePublicKey"
68 ) -> bytes:
69 """
70 Performs a key exchange operation using the provided algorithm with the
71 provided peer's public key.
72 """
74 @abc.abstractmethod
75 def public_key(self) -> "EllipticCurvePublicKey":
76 """
77 The EllipticCurvePublicKey for this private key.
78 """
80 @property
81 @abc.abstractmethod
82 def curve(self) -> EllipticCurve:
83 """
84 The EllipticCurve that this key is on.
85 """
87 @property
88 @abc.abstractmethod
89 def key_size(self) -> int:
90 """
91 Bit size of a secret scalar for the curve.
92 """
94 @abc.abstractmethod
95 def sign(
96 self,
97 data: bytes,
98 signature_algorithm: EllipticCurveSignatureAlgorithm,
99 ) -> bytes:
100 """
101 Signs the data
102 """
104 @abc.abstractmethod
105 def private_numbers(self) -> "EllipticCurvePrivateNumbers":
106 """
107 Returns an EllipticCurvePrivateNumbers.
108 """
110 @abc.abstractmethod
111 def private_bytes(
112 self,
113 encoding: _serialization.Encoding,
114 format: _serialization.PrivateFormat,
115 encryption_algorithm: _serialization.KeySerializationEncryption,
116 ) -> bytes:
117 """
118 Returns the key serialized as bytes.
119 """
122EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey
125class EllipticCurvePublicKey(metaclass=abc.ABCMeta):
126 @property
127 @abc.abstractmethod
128 def curve(self) -> EllipticCurve:
129 """
130 The EllipticCurve that this key is on.
131 """
133 @property
134 @abc.abstractmethod
135 def key_size(self) -> int:
136 """
137 Bit size of a secret scalar for the curve.
138 """
140 @abc.abstractmethod
141 def public_numbers(self) -> "EllipticCurvePublicNumbers":
142 """
143 Returns an EllipticCurvePublicNumbers.
144 """
146 @abc.abstractmethod
147 def public_bytes(
148 self,
149 encoding: _serialization.Encoding,
150 format: _serialization.PublicFormat,
151 ) -> bytes:
152 """
153 Returns the key serialized as bytes.
154 """
156 @abc.abstractmethod
157 def verify(
158 self,
159 signature: bytes,
160 data: bytes,
161 signature_algorithm: EllipticCurveSignatureAlgorithm,
162 ) -> None:
163 """
164 Verifies the signature of the data.
165 """
167 @classmethod
168 def from_encoded_point(
169 cls, curve: EllipticCurve, data: bytes
170 ) -> "EllipticCurvePublicKey":
171 utils._check_bytes("data", data)
173 if not isinstance(curve, EllipticCurve):
174 raise TypeError("curve must be an EllipticCurve instance")
176 if len(data) == 0:
177 raise ValueError("data must not be an empty byte string")
179 if data[0] not in [0x02, 0x03, 0x04]:
180 raise ValueError("Unsupported elliptic curve point type")
182 from cryptography.hazmat.backends.openssl.backend import backend
184 return backend.load_elliptic_curve_public_bytes(curve, data)
187EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey
190class SECT571R1(EllipticCurve):
191 name = "sect571r1"
192 key_size = 570
195class SECT409R1(EllipticCurve):
196 name = "sect409r1"
197 key_size = 409
200class SECT283R1(EllipticCurve):
201 name = "sect283r1"
202 key_size = 283
205class SECT233R1(EllipticCurve):
206 name = "sect233r1"
207 key_size = 233
210class SECT163R2(EllipticCurve):
211 name = "sect163r2"
212 key_size = 163
215class SECT571K1(EllipticCurve):
216 name = "sect571k1"
217 key_size = 571
220class SECT409K1(EllipticCurve):
221 name = "sect409k1"
222 key_size = 409
225class SECT283K1(EllipticCurve):
226 name = "sect283k1"
227 key_size = 283
230class SECT233K1(EllipticCurve):
231 name = "sect233k1"
232 key_size = 233
235class SECT163K1(EllipticCurve):
236 name = "sect163k1"
237 key_size = 163
240class SECP521R1(EllipticCurve):
241 name = "secp521r1"
242 key_size = 521
245class SECP384R1(EllipticCurve):
246 name = "secp384r1"
247 key_size = 384
250class SECP256R1(EllipticCurve):
251 name = "secp256r1"
252 key_size = 256
255class SECP256K1(EllipticCurve):
256 name = "secp256k1"
257 key_size = 256
260class SECP224R1(EllipticCurve):
261 name = "secp224r1"
262 key_size = 224
265class SECP192R1(EllipticCurve):
266 name = "secp192r1"
267 key_size = 192
270class BrainpoolP256R1(EllipticCurve):
271 name = "brainpoolP256r1"
272 key_size = 256
275class BrainpoolP384R1(EllipticCurve):
276 name = "brainpoolP384r1"
277 key_size = 384
280class BrainpoolP512R1(EllipticCurve):
281 name = "brainpoolP512r1"
282 key_size = 512
285_CURVE_TYPES: typing.Dict[str, typing.Type[EllipticCurve]] = {
286 "prime192v1": SECP192R1,
287 "prime256v1": SECP256R1,
288 "secp192r1": SECP192R1,
289 "secp224r1": SECP224R1,
290 "secp256r1": SECP256R1,
291 "secp384r1": SECP384R1,
292 "secp521r1": SECP521R1,
293 "secp256k1": SECP256K1,
294 "sect163k1": SECT163K1,
295 "sect233k1": SECT233K1,
296 "sect283k1": SECT283K1,
297 "sect409k1": SECT409K1,
298 "sect571k1": SECT571K1,
299 "sect163r2": SECT163R2,
300 "sect233r1": SECT233R1,
301 "sect283r1": SECT283R1,
302 "sect409r1": SECT409R1,
303 "sect571r1": SECT571R1,
304 "brainpoolP256r1": BrainpoolP256R1,
305 "brainpoolP384r1": BrainpoolP384R1,
306 "brainpoolP512r1": BrainpoolP512R1,
307}
310class ECDSA(EllipticCurveSignatureAlgorithm):
311 def __init__(
312 self,
313 algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
314 ):
315 self._algorithm = algorithm
317 @property
318 def algorithm(
319 self,
320 ) -> typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm]:
321 return self._algorithm
324def generate_private_key(
325 curve: EllipticCurve, backend: typing.Any = None
326) -> EllipticCurvePrivateKey:
327 from cryptography.hazmat.backends.openssl.backend import backend as ossl
329 return ossl.generate_elliptic_curve_private_key(curve)
332def derive_private_key(
333 private_value: int,
334 curve: EllipticCurve,
335 backend: typing.Any = None,
336) -> EllipticCurvePrivateKey:
337 from cryptography.hazmat.backends.openssl.backend import backend as ossl
339 if not isinstance(private_value, int):
340 raise TypeError("private_value must be an integer type.")
342 if private_value <= 0:
343 raise ValueError("private_value must be a positive integer.")
345 if not isinstance(curve, EllipticCurve):
346 raise TypeError("curve must provide the EllipticCurve interface.")
348 return ossl.derive_elliptic_curve_private_key(private_value, curve)
351class EllipticCurvePublicNumbers:
352 def __init__(self, x: int, y: int, curve: EllipticCurve):
353 if not isinstance(x, int) or not isinstance(y, int):
354 raise TypeError("x and y must be integers.")
356 if not isinstance(curve, EllipticCurve):
357 raise TypeError("curve must provide the EllipticCurve interface.")
359 self._y = y
360 self._x = x
361 self._curve = curve
363 def public_key(self, backend: typing.Any = None) -> EllipticCurvePublicKey:
364 from cryptography.hazmat.backends.openssl.backend import (
365 backend as ossl,
366 )
368 return ossl.load_elliptic_curve_public_numbers(self)
370 @property
371 def curve(self) -> EllipticCurve:
372 return self._curve
374 @property
375 def x(self) -> int:
376 return self._x
378 @property
379 def y(self) -> int:
380 return self._y
382 def __eq__(self, other: object) -> bool:
383 if not isinstance(other, EllipticCurvePublicNumbers):
384 return NotImplemented
386 return (
387 self.x == other.x
388 and self.y == other.y
389 and self.curve.name == other.curve.name
390 and self.curve.key_size == other.curve.key_size
391 )
393 def __hash__(self) -> int:
394 return hash((self.x, self.y, self.curve.name, self.curve.key_size))
396 def __repr__(self) -> str:
397 return (
398 "<EllipticCurvePublicNumbers(curve={0.curve.name}, x={0.x}, "
399 "y={0.y}>".format(self)
400 )
403class EllipticCurvePrivateNumbers:
404 def __init__(
405 self, private_value: int, public_numbers: EllipticCurvePublicNumbers
406 ):
407 if not isinstance(private_value, int):
408 raise TypeError("private_value must be an integer.")
410 if not isinstance(public_numbers, EllipticCurvePublicNumbers):
411 raise TypeError(
412 "public_numbers must be an EllipticCurvePublicNumbers "
413 "instance."
414 )
416 self._private_value = private_value
417 self._public_numbers = public_numbers
419 def private_key(
420 self, backend: typing.Any = None
421 ) -> EllipticCurvePrivateKey:
422 from cryptography.hazmat.backends.openssl.backend import (
423 backend as ossl,
424 )
426 return ossl.load_elliptic_curve_private_numbers(self)
428 @property
429 def private_value(self) -> int:
430 return self._private_value
432 @property
433 def public_numbers(self) -> EllipticCurvePublicNumbers:
434 return self._public_numbers
436 def __eq__(self, other: object) -> bool:
437 if not isinstance(other, EllipticCurvePrivateNumbers):
438 return NotImplemented
440 return (
441 self.private_value == other.private_value
442 and self.public_numbers == other.public_numbers
443 )
445 def __hash__(self) -> int:
446 return hash((self.private_value, self.public_numbers))
449class ECDH:
450 pass
453_OID_TO_CURVE = {
454 EllipticCurveOID.SECP192R1: SECP192R1,
455 EllipticCurveOID.SECP224R1: SECP224R1,
456 EllipticCurveOID.SECP256K1: SECP256K1,
457 EllipticCurveOID.SECP256R1: SECP256R1,
458 EllipticCurveOID.SECP384R1: SECP384R1,
459 EllipticCurveOID.SECP521R1: SECP521R1,
460 EllipticCurveOID.BRAINPOOLP256R1: BrainpoolP256R1,
461 EllipticCurveOID.BRAINPOOLP384R1: BrainpoolP384R1,
462 EllipticCurveOID.BRAINPOOLP512R1: BrainpoolP512R1,
463 EllipticCurveOID.SECT163K1: SECT163K1,
464 EllipticCurveOID.SECT163R2: SECT163R2,
465 EllipticCurveOID.SECT233K1: SECT233K1,
466 EllipticCurveOID.SECT233R1: SECT233R1,
467 EllipticCurveOID.SECT283K1: SECT283K1,
468 EllipticCurveOID.SECT283R1: SECT283R1,
469 EllipticCurveOID.SECT409K1: SECT409K1,
470 EllipticCurveOID.SECT409R1: SECT409R1,
471 EllipticCurveOID.SECT571K1: SECT571K1,
472 EllipticCurveOID.SECT571R1: SECT571R1,
473}
476def get_curve_for_oid(oid: ObjectIdentifier) -> typing.Type[EllipticCurve]:
477 try:
478 return _OID_TO_CURVE[oid]
479 except KeyError:
480 raise LookupError(
481 "The provided object identifier has no matching elliptic "
482 "curve class"
483 )