rsa.py 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  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. from __future__ import absolute_import, division, print_function
  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
  17. from cryptography.hazmat.primitives.asymmetric import (
  18. AsymmetricSignatureContext,
  19. AsymmetricVerificationContext,
  20. rsa,
  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. RSAPrivateKeyWithSerialization,
  32. RSAPublicKeyWithSerialization,
  33. )
  34. def _get_rsa_pss_salt_length(pss, key, hash_algorithm):
  35. salt = pss._salt_length
  36. if salt is MGF1.MAX_LENGTH or salt is PSS.MAX_LENGTH:
  37. return calculate_max_pss_salt_length(key, hash_algorithm)
  38. else:
  39. return salt
  40. def _enc_dec_rsa(backend, key, data, padding):
  41. if not isinstance(padding, AsymmetricPadding):
  42. raise TypeError("Padding must be an instance of AsymmetricPadding.")
  43. if isinstance(padding, PKCS1v15):
  44. padding_enum = backend._lib.RSA_PKCS1_PADDING
  45. elif isinstance(padding, OAEP):
  46. padding_enum = backend._lib.RSA_PKCS1_OAEP_PADDING
  47. if not isinstance(padding._mgf, MGF1):
  48. raise UnsupportedAlgorithm(
  49. "Only MGF1 is supported by this backend.",
  50. _Reasons.UNSUPPORTED_MGF,
  51. )
  52. if not backend.rsa_padding_supported(padding):
  53. raise UnsupportedAlgorithm(
  54. "This combination of padding and hash algorithm is not "
  55. "supported by this backend.",
  56. _Reasons.UNSUPPORTED_PADDING,
  57. )
  58. else:
  59. raise UnsupportedAlgorithm(
  60. "{} is not supported by this backend.".format(padding.name),
  61. _Reasons.UNSUPPORTED_PADDING,
  62. )
  63. return _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding)
  64. def _enc_dec_rsa_pkey_ctx(backend, key, data, padding_enum, padding):
  65. if isinstance(key, _RSAPublicKey):
  66. init = backend._lib.EVP_PKEY_encrypt_init
  67. crypt = backend._lib.EVP_PKEY_encrypt
  68. else:
  69. init = backend._lib.EVP_PKEY_decrypt_init
  70. crypt = backend._lib.EVP_PKEY_decrypt
  71. pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL)
  72. backend.openssl_assert(pkey_ctx != backend._ffi.NULL)
  73. pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free)
  74. res = init(pkey_ctx)
  75. backend.openssl_assert(res == 1)
  76. res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum)
  77. backend.openssl_assert(res > 0)
  78. buf_size = backend._lib.EVP_PKEY_size(key._evp_pkey)
  79. backend.openssl_assert(buf_size > 0)
  80. if isinstance(padding, OAEP) and backend._lib.Cryptography_HAS_RSA_OAEP_MD:
  81. mgf1_md = backend._evp_md_non_null_from_algorithm(
  82. padding._mgf._algorithm
  83. )
  84. res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md)
  85. backend.openssl_assert(res > 0)
  86. oaep_md = backend._evp_md_non_null_from_algorithm(padding._algorithm)
  87. res = backend._lib.EVP_PKEY_CTX_set_rsa_oaep_md(pkey_ctx, oaep_md)
  88. backend.openssl_assert(res > 0)
  89. if (
  90. isinstance(padding, OAEP)
  91. and padding._label is not None
  92. and len(padding._label) > 0
  93. ):
  94. # set0_rsa_oaep_label takes ownership of the char * so we need to
  95. # copy it into some new memory
  96. labelptr = backend._lib.OPENSSL_malloc(len(padding._label))
  97. backend.openssl_assert(labelptr != backend._ffi.NULL)
  98. backend._ffi.memmove(labelptr, padding._label, len(padding._label))
  99. res = backend._lib.EVP_PKEY_CTX_set0_rsa_oaep_label(
  100. pkey_ctx, labelptr, len(padding._label)
  101. )
  102. backend.openssl_assert(res == 1)
  103. outlen = backend._ffi.new("size_t *", buf_size)
  104. buf = backend._ffi.new("unsigned char[]", buf_size)
  105. # Everything from this line onwards is written with the goal of being as
  106. # constant-time as is practical given the constraints of Python and our
  107. # API. See Bleichenbacher's '98 attack on RSA, and its many many variants.
  108. # As such, you should not attempt to change this (particularly to "clean it
  109. # up") without understanding why it was written this way (see
  110. # Chesterton's Fence), and without measuring to verify you have not
  111. # introduced observable time differences.
  112. res = crypt(pkey_ctx, buf, outlen, data, len(data))
  113. resbuf = backend._ffi.buffer(buf)[: outlen[0]]
  114. backend._lib.ERR_clear_error()
  115. if res <= 0:
  116. raise ValueError("Encryption/decryption failed.")
  117. return resbuf
  118. def _rsa_sig_determine_padding(backend, key, padding, algorithm):
  119. if not isinstance(padding, AsymmetricPadding):
  120. raise TypeError("Expected provider of AsymmetricPadding.")
  121. pkey_size = backend._lib.EVP_PKEY_size(key._evp_pkey)
  122. backend.openssl_assert(pkey_size > 0)
  123. if isinstance(padding, PKCS1v15):
  124. padding_enum = backend._lib.RSA_PKCS1_PADDING
  125. elif isinstance(padding, PSS):
  126. if not isinstance(padding._mgf, MGF1):
  127. raise UnsupportedAlgorithm(
  128. "Only MGF1 is supported by this backend.",
  129. _Reasons.UNSUPPORTED_MGF,
  130. )
  131. # Size of key in bytes - 2 is the maximum
  132. # PSS signature length (salt length is checked later)
  133. if pkey_size - algorithm.digest_size - 2 < 0:
  134. raise ValueError(
  135. "Digest too large for key size. Use a larger "
  136. "key or different digest."
  137. )
  138. padding_enum = backend._lib.RSA_PKCS1_PSS_PADDING
  139. else:
  140. raise UnsupportedAlgorithm(
  141. "{} is not supported by this backend.".format(padding.name),
  142. _Reasons.UNSUPPORTED_PADDING,
  143. )
  144. return padding_enum
  145. def _rsa_sig_setup(backend, padding, algorithm, key, data, init_func):
  146. padding_enum = _rsa_sig_determine_padding(backend, key, padding, algorithm)
  147. evp_md = backend._evp_md_non_null_from_algorithm(algorithm)
  148. pkey_ctx = backend._lib.EVP_PKEY_CTX_new(key._evp_pkey, backend._ffi.NULL)
  149. backend.openssl_assert(pkey_ctx != backend._ffi.NULL)
  150. pkey_ctx = backend._ffi.gc(pkey_ctx, backend._lib.EVP_PKEY_CTX_free)
  151. res = init_func(pkey_ctx)
  152. backend.openssl_assert(res == 1)
  153. res = backend._lib.EVP_PKEY_CTX_set_signature_md(pkey_ctx, evp_md)
  154. if res == 0:
  155. backend._consume_errors()
  156. raise UnsupportedAlgorithm(
  157. "{} is not supported by this backend for RSA signing.".format(
  158. algorithm.name
  159. ),
  160. _Reasons.UNSUPPORTED_HASH,
  161. )
  162. res = backend._lib.EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, padding_enum)
  163. backend.openssl_assert(res > 0)
  164. if isinstance(padding, PSS):
  165. res = backend._lib.EVP_PKEY_CTX_set_rsa_pss_saltlen(
  166. pkey_ctx, _get_rsa_pss_salt_length(padding, key, algorithm)
  167. )
  168. backend.openssl_assert(res > 0)
  169. mgf1_md = backend._evp_md_non_null_from_algorithm(
  170. padding._mgf._algorithm
  171. )
  172. res = backend._lib.EVP_PKEY_CTX_set_rsa_mgf1_md(pkey_ctx, mgf1_md)
  173. backend.openssl_assert(res > 0)
  174. return pkey_ctx
  175. def _rsa_sig_sign(backend, padding, algorithm, private_key, data):
  176. pkey_ctx = _rsa_sig_setup(
  177. backend,
  178. padding,
  179. algorithm,
  180. private_key,
  181. data,
  182. backend._lib.EVP_PKEY_sign_init,
  183. )
  184. buflen = backend._ffi.new("size_t *")
  185. res = backend._lib.EVP_PKEY_sign(
  186. pkey_ctx, backend._ffi.NULL, buflen, data, len(data)
  187. )
  188. backend.openssl_assert(res == 1)
  189. buf = backend._ffi.new("unsigned char[]", buflen[0])
  190. res = backend._lib.EVP_PKEY_sign(pkey_ctx, buf, buflen, data, len(data))
  191. if res != 1:
  192. errors = backend._consume_errors_with_text()
  193. raise ValueError(
  194. "Digest or salt length too long for key size. Use a larger key "
  195. "or shorter salt length if you are specifying a PSS salt",
  196. errors,
  197. )
  198. return backend._ffi.buffer(buf)[:]
  199. def _rsa_sig_verify(backend, padding, algorithm, public_key, signature, data):
  200. pkey_ctx = _rsa_sig_setup(
  201. backend,
  202. padding,
  203. algorithm,
  204. public_key,
  205. data,
  206. backend._lib.EVP_PKEY_verify_init,
  207. )
  208. res = backend._lib.EVP_PKEY_verify(
  209. pkey_ctx, signature, len(signature), data, len(data)
  210. )
  211. # The previous call can return negative numbers in the event of an
  212. # error. This is not a signature failure but we need to fail if it
  213. # occurs.
  214. backend.openssl_assert(res >= 0)
  215. if res == 0:
  216. backend._consume_errors()
  217. raise InvalidSignature
  218. @utils.register_interface(AsymmetricSignatureContext)
  219. class _RSASignatureContext(object):
  220. def __init__(self, backend, private_key, padding, algorithm):
  221. self._backend = backend
  222. self._private_key = private_key
  223. # We now call _rsa_sig_determine_padding in _rsa_sig_setup. However
  224. # we need to make a pointless call to it here so we maintain the
  225. # API of erroring on init with this context if the values are invalid.
  226. _rsa_sig_determine_padding(backend, private_key, padding, algorithm)
  227. self._padding = padding
  228. self._algorithm = algorithm
  229. self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
  230. def update(self, data):
  231. self._hash_ctx.update(data)
  232. def finalize(self):
  233. return _rsa_sig_sign(
  234. self._backend,
  235. self._padding,
  236. self._algorithm,
  237. self._private_key,
  238. self._hash_ctx.finalize(),
  239. )
  240. @utils.register_interface(AsymmetricVerificationContext)
  241. class _RSAVerificationContext(object):
  242. def __init__(self, backend, public_key, signature, padding, algorithm):
  243. self._backend = backend
  244. self._public_key = public_key
  245. self._signature = signature
  246. self._padding = padding
  247. # We now call _rsa_sig_determine_padding in _rsa_sig_setup. However
  248. # we need to make a pointless call to it here so we maintain the
  249. # API of erroring on init with this context if the values are invalid.
  250. _rsa_sig_determine_padding(backend, public_key, padding, algorithm)
  251. padding = padding
  252. self._algorithm = algorithm
  253. self._hash_ctx = hashes.Hash(self._algorithm, self._backend)
  254. def update(self, data):
  255. self._hash_ctx.update(data)
  256. def verify(self):
  257. return _rsa_sig_verify(
  258. self._backend,
  259. self._padding,
  260. self._algorithm,
  261. self._public_key,
  262. self._signature,
  263. self._hash_ctx.finalize(),
  264. )
  265. @utils.register_interface(RSAPrivateKeyWithSerialization)
  266. class _RSAPrivateKey(object):
  267. def __init__(self, backend, rsa_cdata, evp_pkey):
  268. res = backend._lib.RSA_check_key(rsa_cdata)
  269. if res != 1:
  270. errors = backend._consume_errors_with_text()
  271. raise ValueError("Invalid private key", errors)
  272. # Blinding is on by default in many versions of OpenSSL, but let's
  273. # just be conservative here.
  274. res = backend._lib.RSA_blinding_on(rsa_cdata, backend._ffi.NULL)
  275. backend.openssl_assert(res == 1)
  276. self._backend = backend
  277. self._rsa_cdata = rsa_cdata
  278. self._evp_pkey = evp_pkey
  279. n = self._backend._ffi.new("BIGNUM **")
  280. self._backend._lib.RSA_get0_key(
  281. self._rsa_cdata,
  282. n,
  283. self._backend._ffi.NULL,
  284. self._backend._ffi.NULL,
  285. )
  286. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  287. self._key_size = self._backend._lib.BN_num_bits(n[0])
  288. key_size = utils.read_only_property("_key_size")
  289. def signer(self, padding, algorithm):
  290. _warn_sign_verify_deprecated()
  291. _check_not_prehashed(algorithm)
  292. return _RSASignatureContext(self._backend, self, padding, algorithm)
  293. def decrypt(self, ciphertext, padding):
  294. key_size_bytes = (self.key_size + 7) // 8
  295. if key_size_bytes != len(ciphertext):
  296. raise ValueError("Ciphertext length must be equal to key size.")
  297. return _enc_dec_rsa(self._backend, self, ciphertext, padding)
  298. def public_key(self):
  299. ctx = self._backend._lib.RSAPublicKey_dup(self._rsa_cdata)
  300. self._backend.openssl_assert(ctx != self._backend._ffi.NULL)
  301. ctx = self._backend._ffi.gc(ctx, self._backend._lib.RSA_free)
  302. evp_pkey = self._backend._rsa_cdata_to_evp_pkey(ctx)
  303. return _RSAPublicKey(self._backend, ctx, evp_pkey)
  304. def private_numbers(self):
  305. n = self._backend._ffi.new("BIGNUM **")
  306. e = self._backend._ffi.new("BIGNUM **")
  307. d = self._backend._ffi.new("BIGNUM **")
  308. p = self._backend._ffi.new("BIGNUM **")
  309. q = self._backend._ffi.new("BIGNUM **")
  310. dmp1 = self._backend._ffi.new("BIGNUM **")
  311. dmq1 = self._backend._ffi.new("BIGNUM **")
  312. iqmp = self._backend._ffi.new("BIGNUM **")
  313. self._backend._lib.RSA_get0_key(self._rsa_cdata, n, e, d)
  314. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  315. self._backend.openssl_assert(e[0] != self._backend._ffi.NULL)
  316. self._backend.openssl_assert(d[0] != self._backend._ffi.NULL)
  317. self._backend._lib.RSA_get0_factors(self._rsa_cdata, p, q)
  318. self._backend.openssl_assert(p[0] != self._backend._ffi.NULL)
  319. self._backend.openssl_assert(q[0] != self._backend._ffi.NULL)
  320. self._backend._lib.RSA_get0_crt_params(
  321. self._rsa_cdata, dmp1, dmq1, iqmp
  322. )
  323. self._backend.openssl_assert(dmp1[0] != self._backend._ffi.NULL)
  324. self._backend.openssl_assert(dmq1[0] != self._backend._ffi.NULL)
  325. self._backend.openssl_assert(iqmp[0] != self._backend._ffi.NULL)
  326. return rsa.RSAPrivateNumbers(
  327. p=self._backend._bn_to_int(p[0]),
  328. q=self._backend._bn_to_int(q[0]),
  329. d=self._backend._bn_to_int(d[0]),
  330. dmp1=self._backend._bn_to_int(dmp1[0]),
  331. dmq1=self._backend._bn_to_int(dmq1[0]),
  332. iqmp=self._backend._bn_to_int(iqmp[0]),
  333. public_numbers=rsa.RSAPublicNumbers(
  334. e=self._backend._bn_to_int(e[0]),
  335. n=self._backend._bn_to_int(n[0]),
  336. ),
  337. )
  338. def private_bytes(self, encoding, format, encryption_algorithm):
  339. return self._backend._private_key_bytes(
  340. encoding,
  341. format,
  342. encryption_algorithm,
  343. self,
  344. self._evp_pkey,
  345. self._rsa_cdata,
  346. )
  347. def sign(self, data, padding, algorithm):
  348. data, algorithm = _calculate_digest_and_algorithm(
  349. self._backend, data, algorithm
  350. )
  351. return _rsa_sig_sign(self._backend, padding, algorithm, self, data)
  352. @utils.register_interface(RSAPublicKeyWithSerialization)
  353. class _RSAPublicKey(object):
  354. def __init__(self, backend, rsa_cdata, evp_pkey):
  355. self._backend = backend
  356. self._rsa_cdata = rsa_cdata
  357. self._evp_pkey = evp_pkey
  358. n = self._backend._ffi.new("BIGNUM **")
  359. self._backend._lib.RSA_get0_key(
  360. self._rsa_cdata,
  361. n,
  362. self._backend._ffi.NULL,
  363. self._backend._ffi.NULL,
  364. )
  365. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  366. self._key_size = self._backend._lib.BN_num_bits(n[0])
  367. key_size = utils.read_only_property("_key_size")
  368. def verifier(self, signature, padding, algorithm):
  369. _warn_sign_verify_deprecated()
  370. utils._check_bytes("signature", signature)
  371. _check_not_prehashed(algorithm)
  372. return _RSAVerificationContext(
  373. self._backend, self, signature, padding, algorithm
  374. )
  375. def encrypt(self, plaintext, padding):
  376. return _enc_dec_rsa(self._backend, self, plaintext, padding)
  377. def public_numbers(self):
  378. n = self._backend._ffi.new("BIGNUM **")
  379. e = self._backend._ffi.new("BIGNUM **")
  380. self._backend._lib.RSA_get0_key(
  381. self._rsa_cdata, n, e, self._backend._ffi.NULL
  382. )
  383. self._backend.openssl_assert(n[0] != self._backend._ffi.NULL)
  384. self._backend.openssl_assert(e[0] != self._backend._ffi.NULL)
  385. return rsa.RSAPublicNumbers(
  386. e=self._backend._bn_to_int(e[0]),
  387. n=self._backend._bn_to_int(n[0]),
  388. )
  389. def public_bytes(self, encoding, format):
  390. return self._backend._public_key_bytes(
  391. encoding, format, self, self._evp_pkey, self._rsa_cdata
  392. )
  393. def verify(self, signature, data, padding, algorithm):
  394. data, algorithm = _calculate_digest_and_algorithm(
  395. self._backend, data, algorithm
  396. )
  397. return _rsa_sig_verify(
  398. self._backend, padding, algorithm, self, signature, data
  399. )