codekingpro/portable-devtools
114k
1# This file is dual licensed under the terms of the Apache License, Version2# 2.0, and the BSD License. See the LICENSE file in the root of this repository3# for complete details.4 5from __future__ import annotations6 7import abc8import typing9 10from cryptography import utils11from cryptography.exceptions import UnsupportedAlgorithm, _Reasons12from cryptography.hazmat._oid import ObjectIdentifier13from cryptography.hazmat.bindings._rust import openssl as rust_openssl14from cryptography.hazmat.primitives import _serialization, hashes15from cryptography.hazmat.primitives.asymmetric import utils as asym_utils16 17 18class EllipticCurveOID:19 SECP192R1 = ObjectIdentifier("1.2.840.10045.3.1.1")20 SECP224R1 = ObjectIdentifier("1.3.132.0.33")21 SECP256K1 = ObjectIdentifier("1.3.132.0.10")22 SECP256R1 = ObjectIdentifier("1.2.840.10045.3.1.7")23 SECP384R1 = ObjectIdentifier("1.3.132.0.34")24 SECP521R1 = ObjectIdentifier("1.3.132.0.35")25 BRAINPOOLP256R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.7")26 BRAINPOOLP384R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.11")27 BRAINPOOLP512R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.13")28 29 30class EllipticCurve(metaclass=abc.ABCMeta):31 @property32 @abc.abstractmethod33 def name(self) -> str:34 """35 The name of the curve. e.g. secp256r1.36 """37 38 @property39 @abc.abstractmethod40 def key_size(self) -> int:41 """42 Bit size of a secret scalar for the curve.43 """44 45 @property46 @abc.abstractmethod47 def group_order(self) -> int:48 """49 The order of the curve's group.50 """51 52 53class EllipticCurveSignatureAlgorithm(metaclass=abc.ABCMeta):54 @property55 @abc.abstractmethod56 def algorithm(57 self,58 ) -> asym_utils.Prehashed | hashes.HashAlgorithm:59 """60 The digest algorithm used with this signature.61 """62 63 64class EllipticCurvePrivateKey(metaclass=abc.ABCMeta):65 @abc.abstractmethod66 def exchange(67 self, algorithm: ECDH, peer_public_key: EllipticCurvePublicKey68 ) -> bytes:69 """70 Performs a key exchange operation using the provided algorithm with the71 provided peer's public key.72 """73 74 @abc.abstractmethod75 def public_key(self) -> EllipticCurvePublicKey:76 """77 The EllipticCurvePublicKey for this private key.78 """79 80 @property81 @abc.abstractmethod82 def curve(self) -> EllipticCurve:83 """84 The EllipticCurve that this key is on.85 """86 87 @property88 @abc.abstractmethod89 def key_size(self) -> int:90 """91 Bit size of a secret scalar for the curve.92 """93 94 @abc.abstractmethod95 def sign(96 self,97 data: utils.Buffer,98 signature_algorithm: EllipticCurveSignatureAlgorithm,99 ) -> bytes:100 """101 Signs the data102 """103 104 @abc.abstractmethod105 def private_numbers(self) -> EllipticCurvePrivateNumbers:106 """107 Returns an EllipticCurvePrivateNumbers.108 """109 110 @abc.abstractmethod111 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 """120 121 @abc.abstractmethod122 def __copy__(self) -> EllipticCurvePrivateKey:123 """124 Returns a copy.125 """126 127 @abc.abstractmethod128 def __deepcopy__(self, memo: dict) -> EllipticCurvePrivateKey:129 """130 Returns a deep copy.131 """132 133 134EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey135EllipticCurvePrivateKey.register(rust_openssl.ec.ECPrivateKey)136 137 138class EllipticCurvePublicKey(metaclass=abc.ABCMeta):139 @property140 @abc.abstractmethod141 def curve(self) -> EllipticCurve:142 """143 The EllipticCurve that this key is on.144 """145 146 @property147 @abc.abstractmethod148 def key_size(self) -> int:149 """150 Bit size of a secret scalar for the curve.151 """152 153 @abc.abstractmethod154 def public_numbers(self) -> EllipticCurvePublicNumbers:155 """156 Returns an EllipticCurvePublicNumbers.157 """158 159 @abc.abstractmethod160 def public_bytes(161 self,162 encoding: _serialization.Encoding,163 format: _serialization.PublicFormat,164 ) -> bytes:165 """166 Returns the key serialized as bytes.167 """168 169 @abc.abstractmethod170 def verify(171 self,172 signature: utils.Buffer,173 data: utils.Buffer,174 signature_algorithm: EllipticCurveSignatureAlgorithm,175 ) -> None:176 """177 Verifies the signature of the data.178 """179 180 @classmethod181 def from_encoded_point(182 cls, curve: EllipticCurve, data: bytes183 ) -> EllipticCurvePublicKey:184 utils._check_bytes("data", data)185 186 if len(data) == 0:187 raise ValueError("data must not be an empty byte string")188 189 if data[0] not in [0x02, 0x03, 0x04]:190 raise ValueError("Unsupported elliptic curve point type")191 192 return rust_openssl.ec.from_public_bytes(curve, data)193 194 @abc.abstractmethod195 def __eq__(self, other: object) -> bool:196 """197 Checks equality.198 """199 200 @abc.abstractmethod201 def __copy__(self) -> EllipticCurvePublicKey:202 """203 Returns a copy.204 """205 206 @abc.abstractmethod207 def __deepcopy__(self, memo: dict) -> EllipticCurvePublicKey:208 """209 Returns a deep copy.210 """211 212 213EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey214EllipticCurvePublicKey.register(rust_openssl.ec.ECPublicKey)215 216EllipticCurvePrivateNumbers = rust_openssl.ec.EllipticCurvePrivateNumbers217EllipticCurvePublicNumbers = rust_openssl.ec.EllipticCurvePublicNumbers218 219 220class SECP521R1(EllipticCurve):221 name = "secp521r1"222 key_size = 521223 group_order = 0x1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409 # noqa: E501224 225 226class SECP384R1(EllipticCurve):227 name = "secp384r1"228 key_size = 384229 group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973 # noqa: E501230 231 232class SECP256R1(EllipticCurve):233 name = "secp256r1"234 key_size = 256235 group_order = (236 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551237 )238 239 240class SECP256K1(EllipticCurve):241 name = "secp256k1"242 key_size = 256243 group_order = (244 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141245 )246 247 248class SECP224R1(EllipticCurve):249 name = "secp224r1"250 key_size = 224251 group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D252 253 254class SECP192R1(EllipticCurve):255 name = "secp192r1"256 key_size = 192257 group_order = 0xFFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831258 259 260class BrainpoolP256R1(EllipticCurve):261 name = "brainpoolP256r1"262 key_size = 256263 group_order = (264 0xA9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7265 )266 267 268class BrainpoolP384R1(EllipticCurve):269 name = "brainpoolP384r1"270 key_size = 384271 group_order = 0x8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565 # noqa: E501272 273 274class BrainpoolP512R1(EllipticCurve):275 name = "brainpoolP512r1"276 key_size = 512277 group_order = 0xAADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069 # noqa: E501278 279 280_CURVE_TYPES: dict[str, EllipticCurve] = {281 "prime192v1": SECP192R1(),282 "prime256v1": SECP256R1(),283 "secp192r1": SECP192R1(),284 "secp224r1": SECP224R1(),285 "secp256r1": SECP256R1(),286 "secp384r1": SECP384R1(),287 "secp521r1": SECP521R1(),288 "secp256k1": SECP256K1(),289 "brainpoolP256r1": BrainpoolP256R1(),290 "brainpoolP384r1": BrainpoolP384R1(),291 "brainpoolP512r1": BrainpoolP512R1(),292}293 294 295class ECDSA(EllipticCurveSignatureAlgorithm):296 def __init__(297 self,298 algorithm: asym_utils.Prehashed | hashes.HashAlgorithm,299 deterministic_signing: bool = False,300 ):301 from cryptography.hazmat.backends.openssl.backend import backend302 303 if (304 deterministic_signing305 and not backend.ecdsa_deterministic_supported()306 ):307 raise UnsupportedAlgorithm(308 "ECDSA with deterministic signature (RFC 6979) is not "309 "supported by this version of OpenSSL.",310 _Reasons.UNSUPPORTED_PUBLIC_KEY_ALGORITHM,311 )312 self._algorithm = algorithm313 self._deterministic_signing = deterministic_signing314 315 @property316 def algorithm(317 self,318 ) -> asym_utils.Prehashed | hashes.HashAlgorithm:319 return self._algorithm320 321 @property322 def deterministic_signing(323 self,324 ) -> bool:325 return self._deterministic_signing326 327 328generate_private_key = rust_openssl.ec.generate_private_key329 330 331def derive_private_key(332 private_value: int,333 curve: EllipticCurve,334 backend: typing.Any = None,335) -> EllipticCurvePrivateKey:336 if not isinstance(private_value, int):337 raise TypeError("private_value must be an integer type.")338 339 if private_value <= 0:340 raise ValueError("private_value must be a positive integer.")341 342 return rust_openssl.ec.derive_private_key(private_value, curve)343 344 345class ECDH:346 pass347 348 349_OID_TO_CURVE = {350 EllipticCurveOID.SECP192R1: SECP192R1,351 EllipticCurveOID.SECP224R1: SECP224R1,352 EllipticCurveOID.SECP256K1: SECP256K1,353 EllipticCurveOID.SECP256R1: SECP256R1,354 EllipticCurveOID.SECP384R1: SECP384R1,355 EllipticCurveOID.SECP521R1: SECP521R1,356 EllipticCurveOID.BRAINPOOLP256R1: BrainpoolP256R1,357 EllipticCurveOID.BRAINPOOLP384R1: BrainpoolP384R1,358 EllipticCurveOID.BRAINPOOLP512R1: BrainpoolP512R1,359}360 361 362def get_curve_for_oid(oid: ObjectIdentifier) -> type[EllipticCurve]:363 try:364 return _OID_TO_CURVE[oid]365 except KeyError:366 raise LookupError(367 "The provided object identifier has no matching elliptic "368 "curve class"369 )370 