rsa.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  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. import typing
  5. from cryptography import utils
  6. from cryptography.exceptions import (
  7. InvalidSignature,
  8. UnsupportedAlgorithm,
  9. _Reasons,
  10. )
  11. from cryptography.hazmat.backends.openssl.utils import (
  12. _calculate_digest_and_algorithm,
  13. _check_not_prehashed,
  14. _warn_sign_verify_deprecated,
  15. )
  16. from cryptography.hazmat.primitives import hashes, serialization
  17. from cryptography.hazmat.primitives.asymmetric import (
  18. AsymmetricSignatureContext,
  19. AsymmetricVerificationContext,
  20. utils as asym_utils,
  21. )
  22. from cryptography.hazmat.primitives.asymmetric.padding import (
  23. AsymmetricPadding,
  24. MGF1,
  25. OAEP,
  26. PKCS1v15,
  27. PSS,
  28. calculate_max_pss_salt_length,
  29. )
  30. from cryptography.hazmat.primitives.asymmetric.rsa import (
  31. RSAPrivateKey,
  32. RSAPrivateNumbers,
  33. RSAPublicKey,
  34. RSAPublicNumbers,
  35. )
  36. def _get_rsa_pss_salt_length(
  37. pss: PSS,
  38. key: typing.Union[RSAPrivateKey, RSAPublicKey],
  39. hash_algorithm: hashes.HashAlgorithm,
  40. ) -> int:
  41. salt = pss._salt_length
  42. if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH:
  43. return calculate_max_pss_salt_length(key, hash_algorithm)
  44. else:
  45. return salt
  46. def _enc_dec_rsa(
  47. backend,
  48. key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"],
  49. data: bytes,
  50. padding: AsymmetricPadding,
  51. ) -> bytes:
  52. if not isinstance(padding, AsymmetricPadding):
  53. raise TypeError("Padding must be an instance of AsymmetricPadding.")
  54. if isinstance(padding, PKCS1v15):
  55. padding_enum = backend._lib.RSA_PKCS1_PADDING
  56. elif isinstance(padding, OAEP):
  57. padding_enum = backend._lib.RSA_PKCS1_OAEP_PADDING
  58. if not isinstance(padding._mgf, MGF1):
  59. raise UnsupportedAlgorithm(
  60. "Only MGF1 is supported by this backend.",
  61. _Reasons.UNSUPPORTED_MGF,
  62. )
  63. if not backend.rsa_padding_supported(padding):
  64. raise UnsupportedAlgorithm(
  65. "This combination of padding and hash algorithm is not "
  66. "supported by this backend.",
  67. _Reasons.UNSUPPORTED_PADDING,
  68. )
  69. else:
  70. raise UnsupportedAlgorithm(
  71. "{} is not supported by this backend.".format(padding.name),
  72. _Reasons.UNSUPPORTED_PADDING,
  73. )
  74. return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
  75. def _enc_dec_rsa_pkey_ctx(
  76. backend,
  77. key: typing.Union["_RSAPrivateKey", "_RSAPublicKey"],
  78. data: bytes,
  79. padding_enum: int,
  80. padding: AsymmetricPadding,
  81. ) -> bytes:
  82. if isinstance(key, _RSAPublicKey):
  83. init = backend._lib.EVP_PKEY_encrypt_init
  84. crypt = backend._lib.EVP_PKEY_encrypt
  85. else:
  86. init = backend._lib.EVP_PKEY_decrypt_init
  87. crypt = backend._lib.EVP_PKEY_decrypt
  88. pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL)
  89. backend.openssl_assert(pkey_ctx != backend._ffi.NULL)
  90. pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free)
  91. res = init(pkey_ctx)
  92. backend.openssl_assert(res == 1)
  93. res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum)
  94. backend.openssl_assert(res > 0)
  95. buf_size = backend._lib.EVP_PKEY_size(key._evp_pkey)
  96. backend.openssl_assert(buf_size > 0)
  97. if isinstance(padding, OAEP) and backend._lib.Cryptography_HAS_RSA_OAEP_MD:
  98. mgf1_md = backend._evp_md_non_null_from_algorithm(
  99. padding._mgf._algorithm
  100. )
  101. res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md)
  102. backend.openssl_assert(res > 0)
  103. oaep_md = backend._evp_md_non_null_from_algorithm(padding._algorithm)
  104. res = backend._lib.EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, oaep_md)
  105. backend.openssl_assert(res > 0)
  106. if (
  107. isinstance(padding, OAEP)
  108. and padding._label is not None
  109. and len(padding._label) > 0
  110. ):
  111. # set0_rsa_oaep_label takes ownership of the char * so we need to
  112. # copy it into some new memory
  113. labelptr = backend._lib.OPENSSL_malloc(len(padding._label))
  114. backend.openssl_assert(labelptr != backend._ffi.NULL)
  115. backend._ffi.memmove(labelptr, padding._label, len(padding._label))
  116. res = backend._lib.EVP_PKEY_CTX_set0_rsa_oaep_label(
  117. pkey_ctx, labelptr, len(padding._label)
  118. )
  119. backend.openssl_assert(res == 1)
  120. outlen = backend._ffi.new("size_t *", buf_size)
  121. buf = backend._ffi.new("unsigned char[]", buf_size)
  122. # Everything from this line onwards is written with the goal of being as
  123. # constant-time as is practical given the constraints of Python and our
  124. # API. See Bleichenbacher's '98 attack on RSA, and its many many variants.
  125. # As such, you should not attempt to change this (particularly to "clean it
  126. # up") without understanding why it was written this way (see
  127. # Chesterton's Fence), and without measuring to verify you have not
  128. # introduced observable time differences.
  129. res = crypt(pkey_ctx, buf, outlen, data, len(data))
  130. resbuf = backend._ffi.buffer(buf)[: outlen[0]]
  131. backend._lib.ERR_clear_error()
  132. if res <= 0:
  133. raise ValueError("Encryption/decryption failed.")
  134. return resbuf
  135. def _rsa_sig_determine_padding(backend, key, padding, algorithm):
  136. if not isinstance(padding, AsymmetricPadding):
  137. raise TypeError("Expected provider of AsymmetricPadding.")
  138. pkey_size = backend._lib.EVP_PKEY_size(key._evp_pkey)
  139. backend.openssl_assert(pkey_size > 0)
  140. if isinstance(padding, PKCS1v15):
  141. # Hash algorithm is ignored for PKCS1v15-padding, may be None.
  142. padding_enum = backend._lib.RSA_PKCS1_PADDING
  143. elif isinstance(padding, PSS):
  144. if not isinstance(padding._mgf, MGF1):
  145. raise UnsupportedAlgorithm(
  146. "Only MGF1 is supported by this backend.",
  147. _Reasons.UNSUPPORTED_MGF,
  148. )
  149. # PSS padding requires a hash algorithm
  150. if not isinstance(algorithm, hashes.HashAlgorithm):
  151. raise TypeError("Expected instance of hashes.HashAlgorithm.")
  152. # Size of key in bytes - 2 is the maximum
  153. # PSS signature length (salt length is checked later)
  154. if pkey_size - algorithm.digest_size - 2 < 0:
  155. raise ValueError(
  156. "Digest too large for key size. Use a larger "
  157. "key or different digest."
  158. )
  159. padding_enum = backend._lib.RSA_PKCS1_PSS_PADDING
  160. else:
  161. raise UnsupportedAlgorithm(
  162. "{} is not supported by this backend.".format(padding.name),
  163. _Reasons.UNSUPPORTED_PADDING,
  164. )
  165. return padding_enum
  166. # Hash algorithm can be absent (None) to initialize the context without setting
  167. # any message digest algorithm. This is currently only valid for the PKCS1v15
  168. # padding type, where it means that the signature data is encoded/decoded
  169. # as provided, without being wrapped in a DigestInfo structure.
  170. def _rsa_sig_setup(backend, padding, algorithm, key, init_func):
  171. padding_enum = _rsa_sig_determine_padding(backend, key, padding, algorithm)
  172. pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL)
  173. backend.openssl_assert(pkey_ctx != backend._ffi.NULL)
  174. pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free)
  175. res = init_func(pkey_ctx)
  176. backend.openssl_assert(res == 1)
  177. if algorithm is not None:
  178. evp_md = backend._evp_md_non_null_from_algorithm(algorithm)
  179. res = backend._lib.EVP_PKEY_CTX_set_signature_md(pkey_ctx, evp_md)
  180. if res == 0:
  181. backend._consume_errors()
  182. raise UnsupportedAlgorithm(
  183. "{} is not supported by this backend for RSA signing.".format(
  184. algorithm.name
  185. ),
  186. _Reasons.UNSUPPORTED_HASH,
  187. )
  188. res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum)
  189. if res <= 0:
  190. backend._consume_errors()
  191. raise UnsupportedAlgorithm(
  192. "{} is not supported for the RSA signature operation.".format(
  193. padding.name
  194. ),
  195. _Reasons.UNSUPPORTED_PADDING,
  196. )
  197. if isinstance(padding, PSS):
  198. res = backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen(
  199. pkey_ctx, _get_rsa_pss_salt_length(padding, key, algorithm)
  200. )
  201. backend.openssl_assert(res > 0)
  202. mgf1_md = backend._evp_md_non_null_from_algorithm(
  203. padding._mgf._algorithm
  204. )
  205. res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md)
  206. backend.openssl_assert(res > 0)
  207. return pkey_ctx
  208. def _rsa_sig_sign(backend, padding, algorithm, private_key, data):
  209. pkey_ctx = _rsa_sig_setup(
  210. backend,
  211. padding,
  212. algorithm,
  213. private_key,
  214. backend._lib.EVP_PKEY_sign_init,
  215. )
  216. buflen = backend._ffi.new("size_t *")
  217. res = backend._lib.EVP_PKEY_sign(
  218. pkey_ctx, backend._ffi.NULL, buflen, data, len(data)
  219. )
  220. backend.openssl_assert(res == 1)
  221. buf = backend._ffi.new("unsigned char[]", buflen[0])
  222. res = backend._lib.EVP_PKEY_sign(pkey_ctx, buf, buflen, data, len(data))
  223. if res != 1:
  224. errors = backend._consume_errors_with_text()
  225. raise ValueError(
  226. "Digest or salt length too long for key size. Use a larger key "
  227. "or shorter salt length if you are specifying a PSS salt",
  228. errors,
  229. )
  230. return backend._ffi.buffer(buf)[:]
  231. def _rsa_sig_verify(backend, padding, algorithm, public_key, signature, data):
  232. pkey_ctx = _rsa_sig_setup(
  233. backend,
  234. padding,
  235. algorithm,
  236. public_key,
  237. backend._lib.EVP_PKEY_verify_init,
  238. )
  239. res = backend._lib.EVP_PKEY_verify(
  240. pkey_ctx, signature, len(signature), data, len(data)
  241. )
  242. # The previous call can return negative numbers in the event of an
  243. # error. This is not a signature failure but we need to fail if it
  244. # occurs.
  245. backend.openssl_assert(res >= 0)
  246. if res == 0:
  247. backend._consume_errors()
  248. raise InvalidSignature
  249. def _rsa_sig_recover(backend, padding, algorithm, public_key, signature):
  250. pkey_ctx = _rsa_sig_setup(
  251. backend,
  252. padding,
  253. algorithm,
  254. public_key,
  255. backend._lib.EVP_PKEY_verify_recover_init,
  256. )
  257. # Attempt to keep the rest of the code in this function as constant/time
  258. # as possible. See the comment in _enc_dec_rsa_pkey_ctx. Note that the
  259. # buflen parameter is used even though its value may be undefined in the
  260. # error case. Due to the tolerant nature of Python slicing this does not
  261. # trigger any exceptions.
  262. maxlen = backend._lib.EVP_PKEY_size(public_key._evp_pkey)
  263. backend.openssl_assert(maxlen > 0)
  264. buf = backend._ffi.new("unsigned char[]", maxlen)
  265. buflen = backend._ffi.new("size_t *", maxlen)
  266. res = backend._lib.EVP_PKEY_verify_recover(
  267. pkey_ctx, buf, buflen, signature, len(signature)
  268. )
  269. resbuf = backend._ffi.buffer(buf)[: buflen[0]]
  270. backend._lib.ERR_clear_error()
  271. # Assume that all parameter errors are handled during the setup phase and
  272. # any error here is due to invalid signature.
  273. if res != 1:
  274. raise InvalidSignature
  275. return resbuf
  276. class _RSASignatureContext(AsymmetricSignatureContext):
  277. def __init__(
  278. self,
  279. backend,
  280. private_key: RSAPrivateKey,
  281. padding: AsymmetricPadding,
  282. algorithm: hashes.HashAlgorithm,
  283. ):
  284. self._backend = backend
  285. self._private_key = private_key
  286. # We now call _rsa_sig_determine_padding in _rsa_sig_setup. However
  287. # we need to make a pointless call to it here so we maintain the
  288. # API of erroring on init with this context if the values are invalid.
  289. _rsa_sig_determine_padding(backend, private_key, padding, algorithm)
  290. self._padding = padding
  291. self._algorithm = algorithm
  292. self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
  293. def update(self, data: bytes) -> None:
  294. self._hash_ctx.update(data)
  295. def finalize(self) -> bytes:
  296. return _rsa_sig_sign(
  297. self._backend,
  298. self._padding,
  299. self._algorithm,
  300. self._private_key,
  301. self._hash_ctx.finalize(),
  302. )
  303. class _RSAVerificationContext(AsymmetricVerificationContext):
  304. def __init__(
  305. self,
  306. backend,
  307. public_key: RSAPublicKey,
  308. signature: bytes,
  309. padding: AsymmetricPadding,
  310. algorithm: hashes.HashAlgorithm,
  311. ):
  312. self._backend = backend
  313. self._public_key = public_key
  314. self._signature = signature
  315. self._padding = padding
  316. # We now call _rsa_sig_determine_padding in _rsa_sig_setup. However
  317. # we need to make a pointless call to it here so we maintain the
  318. # API of erroring on init with this context if the values are invalid.
  319. _rsa_sig_determine_padding(backend, public_key, padding, algorithm)
  320. padding = padding
  321. self._algorithm = algorithm
  322. self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
  323. def update(self, data: bytes) -> None:
  324. self._hash_ctx.update(data)
  325. def verify(self) -> None:
  326. return _rsa_sig_verify(
  327. self._backend,
  328. self._padding,
  329. self._algorithm,
  330. self._public_key,
  331. self._signature,
  332. self._hash_ctx.finalize(),
  333. )
  334. class _RSAPrivateKey(RSAPrivateKey):
  335. def __init__(self, backend, rsa_cdata, evp_pkey, _skip_check_key):
  336. # RSA_check_key is slower in OpenSSL 3.0.0 due to improved
  337. # primality checking. In normal use this is unlikely to be a problem
  338. # since users don't load new keys constantly, but for TESTING we've
  339. # added an init arg that allows skipping the checks. You should not
  340. # use this in production code unless you understand the consequences.
  341. if not _skip_check_key:
  342. res = backend._lib.RSA_check_key(rsa_cdata)
  343. if res != 1:
  344. errors = backend._consume_errors_with_text()
  345. raise ValueError("Invalid private key", errors)
  346. # Blinding is on by default in many versions of OpenSSL, but let's
  347. # just be conservative here.
  348. res = backend._lib.RSA_blinding_on(rsa_cdata, backend._ffi.NULL)
  349. backend.openssl_assert(res == 1)
  350. self._backend = backend
  351. self._rsa_cdata = rsa_cdata
  352. self._evp_pkey = evp_pkey
  353. n = self._backend._ffi.new("BIGNUM **")
  354. self._backend._lib.RSA_get0_key(
  355. self._rsa_cdata,
  356. n,
  357. self._backend._ffi.NULL,
  358. self._backend._ffi.NULL,
  359. )
  360. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  361. self._key_size = self._backend._lib.BN_num_bits(n[0])
  362. key_size = utils.read_only_property("_key_size")
  363. def signer(
  364. self, padding: AsymmetricPadding, algorithm: hashes.HashAlgorithm
  365. ) -> AsymmetricSignatureContext:
  366. _warn_sign_verify_deprecated()
  367. _check_not_prehashed(algorithm)
  368. return _RSASignatureContext(self._backend, self, padding, algorithm)
  369. def decrypt(self, ciphertext: bytes, padding: AsymmetricPadding) -> bytes:
  370. key_size_bytes = (self.key_size + 7) // 8
  371. if key_size_bytes != len(ciphertext):
  372. raise ValueError("Ciphertext length must be equal to key size.")
  373. return _enc_dec_rsa(self._backend, self, ciphertext, padding)
  374. def public_key(self) -> RSAPublicKey:
  375. ctx = self._backend._lib.RSAPublicKey_dup(self._rsa_cdata)
  376. self._backend.openssl_assert(ctx != self._backend._ffi.NULL)
  377. ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free)
  378. evp_pkey = self._backend._rsa_cdata_to_evp_pkey(ctx)
  379. return _RSAPublicKey(self._backend, ctx, evp_pkey)
  380. def private_numbers(self) -> RSAPrivateNumbers:
  381. n = self._backend._ffi.new("BIGNUM **")
  382. e = self._backend._ffi.new("BIGNUM **")
  383. d = self._backend._ffi.new("BIGNUM **")
  384. p = self._backend._ffi.new("BIGNUM **")
  385. q = self._backend._ffi.new("BIGNUM **")
  386. dmp1 = self._backend._ffi.new("BIGNUM **")
  387. dmq1 = self._backend._ffi.new("BIGNUM **")
  388. iqmp = self._backend._ffi.new("BIGNUM **")
  389. self._backend._lib.RSA_get0_key(self._rsa_cdata, n, e, d)
  390. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  391. self._backend.openssl_assert(e[0] != self._backend._ffi.NULL)
  392. self._backend.openssl_assert(d[0] != self._backend._ffi.NULL)
  393. self._backend._lib.RSA_get0_factors(self._rsa_cdata, p, q)
  394. self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
  395. self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
  396. self._backend._lib.RSA_get0_crt_params(
  397. self._rsa_cdata, dmp1, dmq1, iqmp
  398. )
  399. self._backend.openssl_assert(dmp1[0] != self._backend._ffi.NULL)
  400. self._backend.openssl_assert(dmq1[0] != self._backend._ffi.NULL)
  401. self._backend.openssl_assert(iqmp[0] != self._backend._ffi.NULL)
  402. return RSAPrivateNumbers(
  403. p=self._backend._bn_to_int(p[0]),
  404. q=self._backend._bn_to_int(q[0]),
  405. d=self._backend._bn_to_int(d[0]),
  406. dmp1=self._backend._bn_to_int(dmp1[0]),
  407. dmq1=self._backend._bn_to_int(dmq1[0]),
  408. iqmp=self._backend._bn_to_int(iqmp[0]),
  409. public_numbers=RSAPublicNumbers(
  410. e=self._backend._bn_to_int(e[0]),
  411. n=self._backend._bn_to_int(n[0]),
  412. ),
  413. )
  414. def private_bytes(
  415. self,
  416. encoding: serialization.Encoding,
  417. format: serialization.PrivateFormat,
  418. encryption_algorithm: serialization.KeySerializationEncryption,
  419. ) -> bytes:
  420. return self._backend._private_key_bytes(
  421. encoding,
  422. format,
  423. encryption_algorithm,
  424. self,
  425. self._evp_pkey,
  426. self._rsa_cdata,
  427. )
  428. def sign(
  429. self,
  430. data: bytes,
  431. padding: AsymmetricPadding,
  432. algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
  433. ) -> bytes:
  434. data, algorithm = _calculate_digest_and_algorithm(
  435. self._backend, data, algorithm
  436. )
  437. return _rsa_sig_sign(self._backend, padding, algorithm, self, data)
  438. class _RSAPublicKey(RSAPublicKey):
  439. def __init__(self, backend, rsa_cdata, evp_pkey):
  440. self._backend = backend
  441. self._rsa_cdata = rsa_cdata
  442. self._evp_pkey = evp_pkey
  443. n = self._backend._ffi.new("BIGNUM **")
  444. self._backend._lib.RSA_get0_key(
  445. self._rsa_cdata,
  446. n,
  447. self._backend._ffi.NULL,
  448. self._backend._ffi.NULL,
  449. )
  450. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  451. self._key_size = self._backend._lib.BN_num_bits(n[0])
  452. key_size = utils.read_only_property("_key_size")
  453. def verifier(
  454. self,
  455. signature: bytes,
  456. padding: AsymmetricPadding,
  457. algorithm: hashes.HashAlgorithm,
  458. ) -> AsymmetricVerificationContext:
  459. _warn_sign_verify_deprecated()
  460. utils._check_bytes("signature", signature)
  461. _check_not_prehashed(algorithm)
  462. return _RSAVerificationContext(
  463. self._backend, self, signature, padding, algorithm
  464. )
  465. def encrypt(self, plaintext: bytes, padding: AsymmetricPadding) -> bytes:
  466. return _enc_dec_rsa(self._backend, self, plaintext, padding)
  467. def public_numbers(self) -> RSAPublicNumbers:
  468. n = self._backend._ffi.new("BIGNUM **")
  469. e = self._backend._ffi.new("BIGNUM **")
  470. self._backend._lib.RSA_get0_key(
  471. self._rsa_cdata, n, e, self._backend._ffi.NULL
  472. )
  473. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  474. self._backend.openssl_assert(e[0] != self._backend._ffi.NULL)
  475. return RSAPublicNumbers(
  476. e=self._backend._bn_to_int(e[0]),
  477. n=self._backend._bn_to_int(n[0]),
  478. )
  479. def public_bytes(
  480. self,
  481. encoding: serialization.Encoding,
  482. format: serialization.PublicFormat,
  483. ) -> bytes:
  484. return self._backend._public_key_bytes(
  485. encoding, format, self, self._evp_pkey, self._rsa_cdata
  486. )
  487. def verify(
  488. self,
  489. signature: bytes,
  490. data: bytes,
  491. padding: AsymmetricPadding,
  492. algorithm: typing.Union[asym_utils.Prehashed, hashes.HashAlgorithm],
  493. ) -> None:
  494. data, algorithm = _calculate_digest_and_algorithm(
  495. self._backend, data, algorithm
  496. )
  497. return _rsa_sig_verify(
  498. self._backend, padding, algorithm, self, signature, data
  499. )
  500. def recover_data_from_signature(
  501. self,
  502. signature: bytes,
  503. padding: AsymmetricPadding,
  504. algorithm: typing.Optional[hashes.HashAlgorithm],
  505. ) -> bytes:
  506. _check_not_prehashed(algorithm)
  507. return _rsa_sig_recover(
  508. self._backend, padding, algorithm, self, signature
  509. )