Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/cryptography/hazmat/primitives/asymmetric/ec.py: 90%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

164 statements  

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. 

4 

5from __future__ import annotations 

6 

7import abc 

8import typing 

9 

10from cryptography import utils 

11from cryptography.hazmat._oid import ObjectIdentifier 

12from cryptography.hazmat.bindings._rust import openssl as rust_openssl 

13from cryptography.hazmat.primitives import _serialization, hashes 

14from cryptography.hazmat.primitives.asymmetric import utils as asym_utils 

15 

16 

17class EllipticCurveOID: 

18 SECP192R1 = ObjectIdentifier("1.2.840.10045.3.1.1") 

19 SECP224R1 = ObjectIdentifier("1.3.132.0.33") 

20 SECP256K1 = ObjectIdentifier("1.3.132.0.10") 

21 SECP256R1 = ObjectIdentifier("1.2.840.10045.3.1.7") 

22 SECP384R1 = ObjectIdentifier("1.3.132.0.34") 

23 SECP521R1 = ObjectIdentifier("1.3.132.0.35") 

24 BRAINPOOLP256R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.7") 

25 BRAINPOOLP384R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.11") 

26 BRAINPOOLP512R1 = ObjectIdentifier("1.3.36.3.3.2.8.1.1.13") 

27 SECT163K1 = ObjectIdentifier("1.3.132.0.1") 

28 SECT163R2 = ObjectIdentifier("1.3.132.0.15") 

29 SECT233K1 = ObjectIdentifier("1.3.132.0.26") 

30 SECT233R1 = ObjectIdentifier("1.3.132.0.27") 

31 SECT283K1 = ObjectIdentifier("1.3.132.0.16") 

32 SECT283R1 = ObjectIdentifier("1.3.132.0.17") 

33 SECT409K1 = ObjectIdentifier("1.3.132.0.36") 

34 SECT409R1 = ObjectIdentifier("1.3.132.0.37") 

35 SECT571K1 = ObjectIdentifier("1.3.132.0.38") 

36 SECT571R1 = ObjectIdentifier("1.3.132.0.39") 

37 

38 

39class EllipticCurve(metaclass=abc.ABCMeta): 

40 @property 

41 @abc.abstractmethod 

42 def name(self) -> str: 

43 """ 

44 The name of the curve. e.g. secp256r1. 

45 """ 

46 

47 @property 

48 @abc.abstractmethod 

49 def key_size(self) -> int: 

50 """ 

51 Bit size of a secret scalar for the curve. 

52 """ 

53 

54 

55class EllipticCurveSignatureAlgorithm(metaclass=abc.ABCMeta): 

56 @property 

57 @abc.abstractmethod 

58 def algorithm( 

59 self, 

60 ) -> asym_utils.Prehashed | hashes.HashAlgorithm: 

61 """ 

62 The digest algorithm used with this signature. 

63 """ 

64 

65 

66class EllipticCurvePrivateKey(metaclass=abc.ABCMeta): 

67 @abc.abstractmethod 

68 def exchange( 

69 self, algorithm: ECDH, peer_public_key: EllipticCurvePublicKey 

70 ) -> bytes: 

71 """ 

72 Performs a key exchange operation using the provided algorithm with the 

73 provided peer's public key. 

74 """ 

75 

76 @abc.abstractmethod 

77 def public_key(self) -> EllipticCurvePublicKey: 

78 """ 

79 The EllipticCurvePublicKey for this private key. 

80 """ 

81 

82 @property 

83 @abc.abstractmethod 

84 def curve(self) -> EllipticCurve: 

85 """ 

86 The EllipticCurve that this key is on. 

87 """ 

88 

89 @property 

90 @abc.abstractmethod 

91 def key_size(self) -> int: 

92 """ 

93 Bit size of a secret scalar for the curve. 

94 """ 

95 

96 @abc.abstractmethod 

97 def sign( 

98 self, 

99 data: bytes, 

100 signature_algorithm: EllipticCurveSignatureAlgorithm, 

101 ) -> bytes: 

102 """ 

103 Signs the data 

104 """ 

105 

106 @abc.abstractmethod 

107 def private_numbers(self) -> EllipticCurvePrivateNumbers: 

108 """ 

109 Returns an EllipticCurvePrivateNumbers. 

110 """ 

111 

112 @abc.abstractmethod 

113 def private_bytes( 

114 self, 

115 encoding: _serialization.Encoding, 

116 format: _serialization.PrivateFormat, 

117 encryption_algorithm: _serialization.KeySerializationEncryption, 

118 ) -> bytes: 

119 """ 

120 Returns the key serialized as bytes. 

121 """ 

122 

123 

124EllipticCurvePrivateKeyWithSerialization = EllipticCurvePrivateKey 

125EllipticCurvePrivateKey.register(rust_openssl.ec.ECPrivateKey) 

126 

127 

128class EllipticCurvePublicKey(metaclass=abc.ABCMeta): 

129 @property 

130 @abc.abstractmethod 

131 def curve(self) -> EllipticCurve: 

132 """ 

133 The EllipticCurve that this key is on. 

134 """ 

135 

136 @property 

137 @abc.abstractmethod 

138 def key_size(self) -> int: 

139 """ 

140 Bit size of a secret scalar for the curve. 

141 """ 

142 

143 @abc.abstractmethod 

144 def public_numbers(self) -> EllipticCurvePublicNumbers: 

145 """ 

146 Returns an EllipticCurvePublicNumbers. 

147 """ 

148 

149 @abc.abstractmethod 

150 def public_bytes( 

151 self, 

152 encoding: _serialization.Encoding, 

153 format: _serialization.PublicFormat, 

154 ) -> bytes: 

155 """ 

156 Returns the key serialized as bytes. 

157 """ 

158 

159 @abc.abstractmethod 

160 def verify( 

161 self, 

162 signature: bytes, 

163 data: bytes, 

164 signature_algorithm: EllipticCurveSignatureAlgorithm, 

165 ) -> None: 

166 """ 

167 Verifies the signature of the data. 

168 """ 

169 

170 @classmethod 

171 def from_encoded_point( 

172 cls, curve: EllipticCurve, data: bytes 

173 ) -> EllipticCurvePublicKey: 

174 utils._check_bytes("data", data) 

175 

176 if len(data) == 0: 

177 raise ValueError("data must not be an empty byte string") 

178 

179 if data[0] not in [0x02, 0x03, 0x04]: 

180 raise ValueError("Unsupported elliptic curve point type") 

181 

182 return rust_openssl.ec.from_public_bytes(curve, data) 

183 

184 @abc.abstractmethod 

185 def __eq__(self, other: object) -> bool: 

186 """ 

187 Checks equality. 

188 """ 

189 

190 

191EllipticCurvePublicKeyWithSerialization = EllipticCurvePublicKey 

192EllipticCurvePublicKey.register(rust_openssl.ec.ECPublicKey) 

193 

194EllipticCurvePrivateNumbers = rust_openssl.ec.EllipticCurvePrivateNumbers 

195EllipticCurvePublicNumbers = rust_openssl.ec.EllipticCurvePublicNumbers 

196 

197 

198class SECT571R1(EllipticCurve): 

199 name = "sect571r1" 

200 key_size = 570 

201 

202 

203class SECT409R1(EllipticCurve): 

204 name = "sect409r1" 

205 key_size = 409 

206 

207 

208class SECT283R1(EllipticCurve): 

209 name = "sect283r1" 

210 key_size = 283 

211 

212 

213class SECT233R1(EllipticCurve): 

214 name = "sect233r1" 

215 key_size = 233 

216 

217 

218class SECT163R2(EllipticCurve): 

219 name = "sect163r2" 

220 key_size = 163 

221 

222 

223class SECT571K1(EllipticCurve): 

224 name = "sect571k1" 

225 key_size = 571 

226 

227 

228class SECT409K1(EllipticCurve): 

229 name = "sect409k1" 

230 key_size = 409 

231 

232 

233class SECT283K1(EllipticCurve): 

234 name = "sect283k1" 

235 key_size = 283 

236 

237 

238class SECT233K1(EllipticCurve): 

239 name = "sect233k1" 

240 key_size = 233 

241 

242 

243class SECT163K1(EllipticCurve): 

244 name = "sect163k1" 

245 key_size = 163 

246 

247 

248class SECP521R1(EllipticCurve): 

249 name = "secp521r1" 

250 key_size = 521 

251 

252 

253class SECP384R1(EllipticCurve): 

254 name = "secp384r1" 

255 key_size = 384 

256 

257 

258class SECP256R1(EllipticCurve): 

259 name = "secp256r1" 

260 key_size = 256 

261 

262 

263class SECP256K1(EllipticCurve): 

264 name = "secp256k1" 

265 key_size = 256 

266 

267 

268class SECP224R1(EllipticCurve): 

269 name = "secp224r1" 

270 key_size = 224 

271 

272 

273class SECP192R1(EllipticCurve): 

274 name = "secp192r1" 

275 key_size = 192 

276 

277 

278class BrainpoolP256R1(EllipticCurve): 

279 name = "brainpoolP256r1" 

280 key_size = 256 

281 

282 

283class BrainpoolP384R1(EllipticCurve): 

284 name = "brainpoolP384r1" 

285 key_size = 384 

286 

287 

288class BrainpoolP512R1(EllipticCurve): 

289 name = "brainpoolP512r1" 

290 key_size = 512 

291 

292 

293_CURVE_TYPES: dict[str, EllipticCurve] = { 

294 "prime192v1": SECP192R1(), 

295 "prime256v1": SECP256R1(), 

296 "secp192r1": SECP192R1(), 

297 "secp224r1": SECP224R1(), 

298 "secp256r1": SECP256R1(), 

299 "secp384r1": SECP384R1(), 

300 "secp521r1": SECP521R1(), 

301 "secp256k1": SECP256K1(), 

302 "sect163k1": SECT163K1(), 

303 "sect233k1": SECT233K1(), 

304 "sect283k1": SECT283K1(), 

305 "sect409k1": SECT409K1(), 

306 "sect571k1": SECT571K1(), 

307 "sect163r2": SECT163R2(), 

308 "sect233r1": SECT233R1(), 

309 "sect283r1": SECT283R1(), 

310 "sect409r1": SECT409R1(), 

311 "sect571r1": SECT571R1(), 

312 "brainpoolP256r1": BrainpoolP256R1(), 

313 "brainpoolP384r1": BrainpoolP384R1(), 

314 "brainpoolP512r1": BrainpoolP512R1(), 

315} 

316 

317 

318class ECDSA(EllipticCurveSignatureAlgorithm): 

319 def __init__( 

320 self, 

321 algorithm: asym_utils.Prehashed | hashes.HashAlgorithm, 

322 ): 

323 self._algorithm = algorithm 

324 

325 @property 

326 def algorithm( 

327 self, 

328 ) -> asym_utils.Prehashed | hashes.HashAlgorithm: 

329 return self._algorithm 

330 

331 

332generate_private_key = rust_openssl.ec.generate_private_key 

333 

334 

335def derive_private_key( 

336 private_value: int, 

337 curve: EllipticCurve, 

338 backend: typing.Any = None, 

339) -> EllipticCurvePrivateKey: 

340 if not isinstance(private_value, int): 

341 raise TypeError("private_value must be an integer type.") 

342 

343 if private_value <= 0: 

344 raise ValueError("private_value must be a positive integer.") 

345 

346 return rust_openssl.ec.derive_private_key(private_value, curve) 

347 

348 

349class ECDH: 

350 pass 

351 

352 

353_OID_TO_CURVE = { 

354 EllipticCurveOID.SECP192R1: SECP192R1, 

355 EllipticCurveOID.SECP224R1: SECP224R1, 

356 EllipticCurveOID.SECP256K1: SECP256K1, 

357 EllipticCurveOID.SECP256R1: SECP256R1, 

358 EllipticCurveOID.SECP384R1: SECP384R1, 

359 EllipticCurveOID.SECP521R1: SECP521R1, 

360 EllipticCurveOID.BRAINPOOLP256R1: BrainpoolP256R1, 

361 EllipticCurveOID.BRAINPOOLP384R1: BrainpoolP384R1, 

362 EllipticCurveOID.BRAINPOOLP512R1: BrainpoolP512R1, 

363 EllipticCurveOID.SECT163K1: SECT163K1, 

364 EllipticCurveOID.SECT163R2: SECT163R2, 

365 EllipticCurveOID.SECT233K1: SECT233K1, 

366 EllipticCurveOID.SECT233R1: SECT233R1, 

367 EllipticCurveOID.SECT283K1: SECT283K1, 

368 EllipticCurveOID.SECT283R1: SECT283R1, 

369 EllipticCurveOID.SECT409K1: SECT409K1, 

370 EllipticCurveOID.SECT409R1: SECT409R1, 

371 EllipticCurveOID.SECT571K1: SECT571K1, 

372 EllipticCurveOID.SECT571R1: SECT571R1, 

373} 

374 

375 

376def get_curve_for_oid(oid: ObjectIdentifier) -> type[EllipticCurve]: 

377 try: 

378 return _OID_TO_CURVE[oid] 

379 except KeyError: 

380 raise LookupError( 

381 "The provided object identifier has no matching elliptic " 

382 "curve class" 

383 )