Skip to content

Commit ba9beaa

Browse files
reaperhulkalex
andauthored
rsa type hinting (pyca#5733)
* rsa type hinting * remove unused import * missed return type * type fixes * ignores no longer required * black gets me every time * Update src/cryptography/hazmat/backends/openssl/rsa.py Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com> Co-authored-by: Alex Gaynor <alex.gaynor@gmail.com>
1 parent 3d58647 commit ba9beaa

6 files changed

Lines changed: 218 additions & 83 deletions

File tree

src/cryptography/hazmat/backends/openssl/rsa.py

Lines changed: 94 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
# for complete details.
44

55

6+
import typing
7+
68
from cryptography import utils
79
from cryptography.exceptions import (
810
InvalidSignature,
@@ -14,11 +16,11 @@
1416
_check_not_prehashed,
1517
_warn_sign_verify_deprecated,
1618
)
17-
from cryptography.hazmat.primitives import hashes
19+
from cryptography.hazmat.primitives import hashes, serialization
1820
from cryptography.hazmat.primitives.asymmetric import (
1921
AsymmetricSignatureContext,
2022
AsymmetricVerificationContext,
21-
rsa,
23+
utils as asym_utils,
2224
)
2325
from cryptography.hazmat.primitives.asymmetric.padding import (
2426
AsymmetricPadding,
@@ -30,11 +32,17 @@
3032
)
3133
from cryptography.hazmat.primitives.asymmetric.rsa import (
3234
RSAPrivateKey,
35+
RSAPrivateNumbers,
3336
RSAPublicKey,
37+
RSAPublicNumbers,
3438
)
3539

3640

37-
def _get_rsa_pss_salt_length(pss, key, hash_algorithm):
41+
def _get_rsa_pss_salt_length(
42+
pss: PSS,
43+
key: typing.Union[RSAPrivateKey, RSAPublicKey],
44+
hash_algorithm: hashes.HashAlgorithm,
45+
) -> int:
3846
salt = pss._salt_length
3947

4048
if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH:
@@ -43,7 +51,12 @@ def _get_rsa_pss_salt_length(pss, key, hash_algorithm):
4351
return salt
4452

4553

46-
def _enc_dec_rsa(backend, key, data, padding):
54+
def _enc_dec_rsa(
55+
backend,
56+
key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"],
57+
data: bytes,
58+
padding: AsymmetricPadding,
59+
) -> bytes:
4760
if not isinstance(padding, AsymmetricPadding):
4861
raise TypeError("Padding must be an instance of AsymmetricPadding.")
4962

@@ -74,7 +87,13 @@ def _enc_dec_rsa(backend, key, data, padding):
7487
return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
7588

7689

77-
def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding):
90+
def _enc_dec_rsa_pkey_ctx(
91+
backend,
92+
key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"],
93+
data: bytes,
94+
padding_enum: int,
95+
padding: AsymmetricPadding,
96+
) -> bytes:
7897
if isinstance(key, _RSAPublicKey):
7998
init = backend._lib.EVP_PKEY_encrypt_init
8099
crypt = backend._lib.EVP_PKEY_encrypt
@@ -294,9 +313,14 @@ def _rsa_sig_recover(backend, padding, algorithm, public_key, signature):
294313
return resbuf
295314

296315

297-
@utils.register_interface(AsymmetricSignatureContext)
298-
class _RSASignatureContext(object):
299-
def __init__(self, backend, private_key, padding, algorithm):
316+
class _RSASignatureContext(AsymmetricSignatureContext):
317+
def __init__(
318+
self,
319+
backend,
320+
private_key: RSAPrivateKey,
321+
padding: AsymmetricPadding,
322+
algorithm: hashes.HashAlgorithm,
323+
):
300324
self._backend = backend
301325
self._private_key = private_key
302326

@@ -308,10 +332,10 @@ def __init__(self, backend, private_key, padding, algorithm):
308332
self._algorithm = algorithm
309333
self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
310334

311-
def update(self, data):
335+
def update(self, data: bytes) -> None:
312336
self._hash_ctx.update(data)
313337

314-
def finalize(self):
338+
def finalize(self) -> bytes:
315339
return _rsa_sig_sign(
316340
self._backend,
317341
self._padding,
@@ -321,9 +345,15 @@ def finalize(self):
321345
)
322346

323347

324-
@utils.register_interface(AsymmetricVerificationContext)
325-
class _RSAVerificationContext(object):
326-
def __init__(self, backend, public_key, signature, padding, algorithm):
348+
class _RSAVerificationContext(AsymmetricVerificationContext):
349+
def __init__(
350+
self,
351+
backend,
352+
public_key: RSAPublicKey,
353+
signature: bytes,
354+
padding: AsymmetricPadding,
355+
algorithm: hashes.HashAlgorithm,
356+
):
327357
self._backend = backend
328358
self._public_key = public_key
329359
self._signature = signature
@@ -337,10 +367,10 @@ def __init__(self, backend, public_key, signature, padding, algorithm):
337367
self._algorithm = algorithm
338368
self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
339369

340-
def update(self, data):
370+
def update(self, data: bytes) -> None:
341371
self._hash_ctx.update(data)
342372

343-
def verify(self):
373+
def verify(self) -> None:
344374
return _rsa_sig_verify(
345375
self._backend,
346376
self._padding,
@@ -351,8 +381,7 @@ def verify(self):
351381
)
352382

353383

354-
@utils.register_interface(RSAPrivateKey)
355-
class _RSAPrivateKey(object):
384+
class _RSAPrivateKey(RSAPrivateKey):
356385
def __init__(self, backend, rsa_cdata, evp_pkey):
357386
res = backend._lib.RSA_check_key(rsa_cdata)
358387
if res != 1:
@@ -380,26 +409,28 @@ def __init__(self, backend, rsa_cdata, evp_pkey):
380409

381410
key_size = utils.read_only_property("_key_size")
382411

383-
def signer(self, padding, algorithm):
412+
def signer(
413+
self, padding: AsymmetricPadding, algorithm: hashes.HashAlgorithm
414+
) -> AsymmetricSignatureContext:
384415
_warn_sign_verify_deprecated()
385416
_check_not_prehashed(algorithm)
386417
return _RSASignatureContext(self._backend, self, padding, algorithm)
387418

388-
def decrypt(self, ciphertext, padding):
419+
def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes:
389420
key_size_bytes = (self.key_size + 7) // 8
390421
if key_size_bytes != len(ciphertext):
391422
raise ValueError("Ciphertext length must be equal to key size.")
392423

393424
return _enc_dec_rsa(self._backend, self, ciphertext, padding)
394425

395-
def public_key(self):
426+
def public_key(self) -> RSAPublicKey:
396427
ctx = self._backend._lib.RSAPublicKey_dup(self._rsa_cdata)
397428
self._backend.openssl_assert(ctx != self._backend._ffi.NULL)
398429
ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free)
399430
evp_pkey = self._backend._rsa_cdata_to_evp_pkey(ctx)
400431
return _RSAPublicKey(self._backend, ctx, evp_pkey)
401432

402-
def private_numbers(self):
433+
def private_numbers(self) -> RSAPrivateNumbers:
403434
n = self._backend._ffi.new("BIGNUM **")
404435
e = self._backend._ffi.new("BIGNUM **")
405436
d = self._backend._ffi.new("BIGNUM **")
@@ -421,20 +452,25 @@ def private_numbers(self):
421452
self._backend.openssl_assert(dmp1[0] != self._backend._ffi.NULL)
422453
self._backend.openssl_assert(dmq1[0] != self._backend._ffi.NULL)
423454
self._backend.openssl_assert(iqmp[0] != self._backend._ffi.NULL)
424-
return rsa.RSAPrivateNumbers(
455+
return RSAPrivateNumbers(
425456
p=self._backend._bn_to_int(p[0]),
426457
q=self._backend._bn_to_int(q[0]),
427458
d=self._backend._bn_to_int(d[0]),
428459
dmp1=self._backend._bn_to_int(dmp1[0]),
429460
dmq1=self._backend._bn_to_int(dmq1[0]),
430461
iqmp=self._backend._bn_to_int(iqmp[0]),
431-
public_numbers=rsa.RSAPublicNumbers(
462+
public_numbers=RSAPublicNumbers(
432463
e=self._backend._bn_to_int(e[0]),
433464
n=self._backend._bn_to_int(n[0]),
434465
),
435466
)
436467

437-
def private_bytes(self, encoding, format, encryption_algorithm):
468+
def private_bytes(
469+
self,
470+
encoding: serialization.Encoding,
471+
format: serialization.PrivateFormat,
472+
encryption_algorithm: serialization.KeySerializationEncryption,
473+
) -> bytes:
438474
return self._backend._private_key_bytes(
439475
encoding,
440476
format,
@@ -444,15 +480,19 @@ def private_bytes(self, encoding, format, encryption_algorithm):
444480
self._rsa_cdata,
445481
)
446482

447-
def sign(self, data, padding, algorithm):
483+
def sign(
484+
self,
485+
data: bytes,
486+
padding: AsymmetricPadding,
487+
algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
488+
) -> bytes:
448489
data, algorithm = _calculate_digest_and_algorithm(
449490
self._backend, data, algorithm
450491
)
451492
return _rsa_sig_sign(self._backend, padding, algorithm, self, data)
452493

453494

454-
@utils.register_interface(RSAPublicKey)
455-
class _RSAPublicKey(object):
495+
class _RSAPublicKey(RSAPublicKey):
456496
def __init__(self, backend, rsa_cdata, evp_pkey):
457497
self._backend = backend
458498
self._rsa_cdata = rsa_cdata
@@ -470,7 +510,12 @@ def __init__(self, backend, rsa_cdata, evp_pkey):
470510

471511
key_size = utils.read_only_property("_key_size")
472512

473-
def verifier(self, signature, padding, algorithm):
513+
def verifier(
514+
self,
515+
signature: bytes,
516+
padding: AsymmetricPadding,
517+
algorithm: hashes.HashAlgorithm,
518+
) -> AsymmetricVerificationContext:
474519
_warn_sign_verify_deprecated()
475520
utils._check_bytes("signature", signature)
476521

@@ -479,36 +524,51 @@ def verifier(self, signature, padding, algorithm):
479524
self._backend, self, signature, padding, algorithm
480525
)
481526

482-
def encrypt(self, plaintext, padding):
527+
def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes:
483528
return _enc_dec_rsa(self._backend, self, plaintext, padding)
484529

485-
def public_numbers(self):
530+
def public_numbers(self) -> RSAPublicNumbers:
486531
n = self._backend._ffi.new("BIGNUM **")
487532
e = self._backend._ffi.new("BIGNUM **")
488533
self._backend._lib.RSA_get0_key(
489534
self._rsa_cdata, n, e, self._backend._ffi.NULL
490535
)
491536
self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
492537
self._backend.openssl_assert(e[0] != self._backend._ffi.NULL)
493-
return rsa.RSAPublicNumbers(
538+
return RSAPublicNumbers(
494539
e=self._backend._bn_to_int(e[0]),
495540
n=self._backend._bn_to_int(n[0]),
496541
)
497542

498-
def public_bytes(self, encoding, format):
543+
def public_bytes(
544+
self,
545+
encoding: serialization.Encoding,
546+
format: serialization.PublicFormat,
547+
) -> bytes:
499548
return self._backend._public_key_bytes(
500549
encoding, format, self, self._evp_pkey, self._rsa_cdata
501550
)
502551

503-
def verify(self, signature, data, padding, algorithm):
552+
def verify(
553+
self,
554+
signature: bytes,
555+
data: bytes,
556+
padding: AsymmetricPadding,
557+
algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
558+
) -> None:
504559
data, algorithm = _calculate_digest_and_algorithm(
505560
self._backend, data, algorithm
506561
)
507562
return _rsa_sig_verify(
508563
self._backend, padding, algorithm, self, signature, data
509564
)
510565

511-
def recover_data_from_signature(self, signature, padding, algorithm):
566+
def recover_data_from_signature(
567+
self,
568+
signature: bytes,
569+
padding: AsymmetricPadding,
570+
algorithm: typing.Optional[hashes.HashAlgorithm],
571+
) -> bytes:
512572
_check_not_prehashed(algorithm)
513573
return _rsa_sig_recover(
514574
self._backend, padding, algorithm, self, signature

src/cryptography/hazmat/primitives/asymmetric/padding.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import abc
77

8-
from cryptography import utils
98
from cryptography.hazmat.primitives import hashes
109
from cryptography.hazmat.primitives.asymmetric import rsa
1110

@@ -18,13 +17,11 @@ def name(self):
1817
"""
1918

2019

21-
@utils.register_interface(AsymmetricPadding)
22-
class PKCS1v15(object):
20+
class PKCS1v15(AsymmetricPadding):
2321
name = "EMSA-PKCS1-v1_5"
2422

2523

26-
@utils.register_interface(AsymmetricPadding)
27-
class PSS(object):
24+
class PSS(AsymmetricPadding):
2825
MAX_LENGTH = object()
2926
name = "EMSA-PSS"
3027

@@ -43,8 +40,7 @@ def __init__(self, mgf, salt_length):
4340
self._salt_length = salt_length
4441

4542

46-
@utils.register_interface(AsymmetricPadding)
47-
class OAEP(object):
43+
class OAEP(AsymmetricPadding):
4844
name = "EME-OAEP"
4945

5046
def __init__(self, mgf, algorithm, label):

0 commit comments

Comments
 (0)