mtproto_rsa_public_key.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #include "mtproto/details/mtproto_rsa_public_key.h"
  8. #include "base/openssl_help.h"
  9. namespace MTP::details {
  10. namespace {
  11. enum class Format {
  12. RSAPublicKey,
  13. RSA_PUBKEY,
  14. Unknown,
  15. };
  16. struct BIODeleter {
  17. void operator()(BIO *value) {
  18. BIO_free(value);
  19. }
  20. };
  21. Format GuessFormat(bytes::const_span key) {
  22. const auto array = QByteArray::fromRawData(
  23. reinterpret_cast<const char*>(key.data()),
  24. key.size());
  25. if (array.indexOf("BEGIN RSA PUBLIC KEY") >= 0) {
  26. return Format::RSAPublicKey;
  27. } else if (array.indexOf("BEGIN PUBLIC KEY") >= 0) {
  28. return Format::RSA_PUBKEY;
  29. }
  30. return Format::Unknown;
  31. }
  32. RSA *CreateRaw(bytes::const_span key) {
  33. const auto format = GuessFormat(key);
  34. const auto bio = std::unique_ptr<BIO, BIODeleter>{
  35. BIO_new_mem_buf(
  36. const_cast<gsl::byte*>(key.data()),
  37. key.size()),
  38. };
  39. switch (format) {
  40. case Format::RSAPublicKey:
  41. return PEM_read_bio_RSAPublicKey(bio.get(), nullptr, nullptr, nullptr);
  42. case Format::RSA_PUBKEY:
  43. return PEM_read_bio_RSA_PUBKEY(bio.get(), nullptr, nullptr, nullptr);
  44. }
  45. Unexpected("format in RSAPublicKey::Private::Create.");
  46. }
  47. } // namespace
  48. class RSAPublicKey::Private {
  49. public:
  50. explicit Private(bytes::const_span key);
  51. Private(bytes::const_span nBytes, bytes::const_span eBytes);
  52. ~Private();
  53. [[nodiscard]] bool valid() const;
  54. [[nodiscard]] uint64 fingerprint() const;
  55. [[nodiscard]] bytes::vector getN() const;
  56. [[nodiscard]] bytes::vector getE() const;
  57. [[nodiscard]] bytes::vector encrypt(bytes::const_span data) const;
  58. [[nodiscard]] bytes::vector decrypt(bytes::const_span data) const;
  59. [[nodiscard]] bytes::vector encryptOAEPpadding(
  60. bytes::const_span data) const;
  61. private:
  62. void computeFingerprint();
  63. [[nodiscard]] static bytes::vector ToBytes(const BIGNUM *number);
  64. RSA *_rsa = nullptr;
  65. uint64 _fingerprint = 0;
  66. };
  67. RSAPublicKey::Private::Private(bytes::const_span key)
  68. : _rsa(CreateRaw(key)) {
  69. if (_rsa) {
  70. computeFingerprint();
  71. }
  72. }
  73. RSAPublicKey::Private::Private(bytes::const_span nBytes, bytes::const_span eBytes)
  74. : _rsa(RSA_new()) {
  75. if (_rsa) {
  76. const auto n = openssl::BigNum(nBytes).takeRaw();
  77. const auto e = openssl::BigNum(eBytes).takeRaw();
  78. const auto valid = (n != nullptr) && (e != nullptr);
  79. // We still pass both values to RSA_set0_key() so that even
  80. // if only one of them is valid RSA would take ownership of it.
  81. if (!RSA_set0_key(_rsa, n, e, nullptr) || !valid) {
  82. RSA_free(base::take(_rsa));
  83. } else {
  84. computeFingerprint();
  85. }
  86. }
  87. }
  88. bool RSAPublicKey::Private::valid() const {
  89. return _rsa != nullptr;
  90. }
  91. uint64 RSAPublicKey::Private::fingerprint() const {
  92. return _fingerprint;
  93. }
  94. bytes::vector RSAPublicKey::Private::getN() const {
  95. Expects(valid());
  96. const BIGNUM *n;
  97. RSA_get0_key(_rsa, &n, nullptr, nullptr);
  98. return ToBytes(n);
  99. }
  100. bytes::vector RSAPublicKey::Private::getE() const {
  101. Expects(valid());
  102. const BIGNUM *e;
  103. RSA_get0_key(_rsa, nullptr, &e, nullptr);
  104. return ToBytes(e);
  105. }
  106. bytes::vector RSAPublicKey::Private::encrypt(bytes::const_span data) const {
  107. Expects(valid());
  108. constexpr auto kEncryptSize = 256;
  109. auto result = bytes::vector(kEncryptSize, gsl::byte{});
  110. auto res = RSA_public_encrypt(kEncryptSize, reinterpret_cast<const unsigned char*>(data.data()), reinterpret_cast<unsigned char*>(result.data()), _rsa, RSA_NO_PADDING);
  111. if (res < 0 || res > kEncryptSize) {
  112. OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
  113. LOG(("RSA Error: RSA_public_encrypt failed, key fp: %1, result: %2, error: %3").arg(fingerprint()).arg(res).arg(ERR_error_string(ERR_get_error(), 0)));
  114. return {};
  115. } else if (auto zeroBytes = kEncryptSize - res) {
  116. auto resultBytes = gsl::make_span(result);
  117. bytes::move(resultBytes.subspan(zeroBytes, res), resultBytes.subspan(0, res));
  118. bytes::set_with_const(resultBytes.subspan(0, zeroBytes), gsl::byte{});
  119. }
  120. return result;
  121. }
  122. bytes::vector RSAPublicKey::Private::decrypt(bytes::const_span data) const {
  123. Expects(valid());
  124. constexpr auto kDecryptSize = 256;
  125. auto result = bytes::vector(kDecryptSize, gsl::byte{});
  126. auto res = RSA_public_decrypt(kDecryptSize, reinterpret_cast<const unsigned char*>(data.data()), reinterpret_cast<unsigned char*>(result.data()), _rsa, RSA_NO_PADDING);
  127. if (res < 0 || res > kDecryptSize) {
  128. OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
  129. LOG(("RSA Error: RSA_public_encrypt failed, key fp: %1, result: %2, error: %3").arg(fingerprint()).arg(res).arg(ERR_error_string(ERR_get_error(), 0)));
  130. return {};
  131. } else if (auto zeroBytes = kDecryptSize - res) {
  132. auto resultBytes = gsl::make_span(result);
  133. bytes::move(resultBytes.subspan(zeroBytes - res, res), resultBytes.subspan(0, res));
  134. bytes::set_with_const(resultBytes.subspan(0, zeroBytes - res), gsl::byte{});
  135. }
  136. return result;
  137. }
  138. bytes::vector RSAPublicKey::Private::encryptOAEPpadding(bytes::const_span data) const {
  139. Expects(valid());
  140. const auto resultSize = RSA_size(_rsa);
  141. auto result = bytes::vector(resultSize, gsl::byte{});
  142. const auto encryptedSize = RSA_public_encrypt(
  143. data.size(),
  144. reinterpret_cast<const unsigned char*>(data.data()),
  145. reinterpret_cast<unsigned char*>(result.data()),
  146. _rsa,
  147. RSA_PKCS1_OAEP_PADDING);
  148. if (encryptedSize != resultSize) {
  149. OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, nullptr);
  150. LOG(("RSA Error: RSA_public_encrypt failed, "
  151. "key fp: %1, result: %2, error: %3"
  152. ).arg(fingerprint()
  153. ).arg(encryptedSize
  154. ).arg(ERR_error_string(ERR_get_error(), 0)
  155. ));
  156. return {};
  157. }
  158. return result;
  159. }
  160. RSAPublicKey::Private::~Private() {
  161. RSA_free(_rsa);
  162. }
  163. void RSAPublicKey::Private::computeFingerprint() {
  164. Expects(valid());
  165. const BIGNUM *n, *e;
  166. mtpBuffer string;
  167. RSA_get0_key(_rsa, &n, &e, nullptr);
  168. MTP_bytes(ToBytes(n)).write(string);
  169. MTP_bytes(ToBytes(e)).write(string);
  170. bytes::array<20> sha1Buffer;
  171. openssl::Sha1To(sha1Buffer, bytes::make_span(string));
  172. _fingerprint = *(uint64*)(sha1Buffer.data() + 12);
  173. }
  174. bytes::vector RSAPublicKey::Private::ToBytes(const BIGNUM *number) {
  175. auto size = BN_num_bytes(number);
  176. auto result = bytes::vector(size, gsl::byte{});
  177. BN_bn2bin(number, reinterpret_cast<unsigned char*>(result.data()));
  178. return result;
  179. }
  180. RSAPublicKey::RSAPublicKey(bytes::const_span key)
  181. : _private(std::make_shared<Private>(key)) {
  182. }
  183. RSAPublicKey::RSAPublicKey(
  184. bytes::const_span nBytes,
  185. bytes::const_span eBytes)
  186. : _private(std::make_shared<Private>(nBytes, eBytes)) {
  187. }
  188. bool RSAPublicKey::empty() const {
  189. return !_private;
  190. }
  191. bool RSAPublicKey::valid() const {
  192. return !empty() && _private->valid();
  193. }
  194. uint64 RSAPublicKey::fingerprint() const {
  195. Expects(valid());
  196. return _private->fingerprint();
  197. }
  198. bytes::vector RSAPublicKey::getN() const {
  199. Expects(valid());
  200. return _private->getN();
  201. }
  202. bytes::vector RSAPublicKey::getE() const {
  203. Expects(valid());
  204. return _private->getE();
  205. }
  206. bytes::vector RSAPublicKey::encrypt(bytes::const_span data) const {
  207. Expects(valid());
  208. return _private->encrypt(data);
  209. }
  210. bytes::vector RSAPublicKey::decrypt(bytes::const_span data) const {
  211. Expects(valid());
  212. return _private->decrypt(data);
  213. }
  214. bytes::vector RSAPublicKey::encryptOAEPpadding(
  215. bytes::const_span data) const {
  216. return _private->encryptOAEPpadding(data);
  217. }
  218. } // namespace MTP::details