ssl_platform_key_android.cc 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright 2015 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "net/ssl/ssl_platform_key_android.h"
  5. #include <strings.h>
  6. #include <memory>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/android/scoped_java_ref.h"
  10. #include "base/containers/flat_set.h"
  11. #include "base/logging.h"
  12. #include "net/android/keystore.h"
  13. #include "net/base/net_errors.h"
  14. #include "net/ssl/ssl_platform_key_util.h"
  15. #include "net/ssl/threaded_ssl_private_key.h"
  16. #include "third_party/abseil-cpp/absl/types/optional.h"
  17. #include "third_party/boringssl/src/include/openssl/ecdsa.h"
  18. #include "third_party/boringssl/src/include/openssl/evp.h"
  19. #include "third_party/boringssl/src/include/openssl/mem.h"
  20. #include "third_party/boringssl/src/include/openssl/nid.h"
  21. #include "third_party/boringssl/src/include/openssl/rsa.h"
  22. #include "third_party/boringssl/src/include/openssl/ssl.h"
  23. using base::android::JavaRef;
  24. using base::android::ScopedJavaGlobalRef;
  25. namespace net {
  26. namespace {
  27. const char* GetJavaAlgorithm(uint16_t algorithm) {
  28. switch (algorithm) {
  29. case SSL_SIGN_RSA_PKCS1_SHA1:
  30. return "SHA1withRSA";
  31. case SSL_SIGN_RSA_PKCS1_SHA256:
  32. return "SHA256withRSA";
  33. case SSL_SIGN_RSA_PKCS1_SHA384:
  34. return "SHA384withRSA";
  35. case SSL_SIGN_RSA_PKCS1_SHA512:
  36. return "SHA512withRSA";
  37. case SSL_SIGN_ECDSA_SHA1:
  38. return "SHA1withECDSA";
  39. case SSL_SIGN_ECDSA_SECP256R1_SHA256:
  40. return "SHA256withECDSA";
  41. case SSL_SIGN_ECDSA_SECP384R1_SHA384:
  42. return "SHA384withECDSA";
  43. case SSL_SIGN_ECDSA_SECP521R1_SHA512:
  44. return "SHA512withECDSA";
  45. case SSL_SIGN_RSA_PSS_SHA256:
  46. return "SHA256withRSA/PSS";
  47. case SSL_SIGN_RSA_PSS_SHA384:
  48. return "SHA384withRSA/PSS";
  49. case SSL_SIGN_RSA_PSS_SHA512:
  50. return "SHA512withRSA/PSS";
  51. default:
  52. return nullptr;
  53. }
  54. }
  55. // Java's public-key encryption algorithms are mis-named. It incorrectly
  56. // classifies RSA's "mode" as ECB.
  57. const char kRSANoPadding[] = "RSA/ECB/NoPadding";
  58. class SSLPlatformKeyAndroid : public ThreadedSSLPrivateKey::Delegate {
  59. public:
  60. SSLPlatformKeyAndroid(bssl::UniquePtr<EVP_PKEY> pubkey,
  61. const JavaRef<jobject>& key)
  62. : pubkey_(std::move(pubkey)),
  63. provider_name_(android::GetPrivateKeyClassName(key)) {
  64. key_.Reset(key);
  65. absl::optional<bool> supports_rsa_no_padding;
  66. for (uint16_t algorithm : SSLPrivateKey::DefaultAlgorithmPreferences(
  67. EVP_PKEY_id(pubkey_.get()), true /* include PSS */)) {
  68. const char* java_algorithm = GetJavaAlgorithm(algorithm);
  69. if (java_algorithm &&
  70. android::PrivateKeySupportsSignature(key_, java_algorithm)) {
  71. preferences_.push_back(algorithm);
  72. } else if (SSL_is_signature_algorithm_rsa_pss(algorithm)) {
  73. // Check if we can use the fallback path instead.
  74. if (!supports_rsa_no_padding) {
  75. supports_rsa_no_padding =
  76. android::PrivateKeySupportsCipher(key_, kRSANoPadding);
  77. }
  78. if (*supports_rsa_no_padding) {
  79. preferences_.push_back(algorithm);
  80. use_pss_fallback_.insert(algorithm);
  81. }
  82. }
  83. }
  84. }
  85. SSLPlatformKeyAndroid(const SSLPlatformKeyAndroid&) = delete;
  86. SSLPlatformKeyAndroid& operator=(const SSLPlatformKeyAndroid&) = delete;
  87. ~SSLPlatformKeyAndroid() override = default;
  88. std::string GetProviderName() override { return provider_name_; }
  89. std::vector<uint16_t> GetAlgorithmPreferences() override {
  90. return preferences_;
  91. }
  92. Error Sign(uint16_t algorithm,
  93. base::span<const uint8_t> input,
  94. std::vector<uint8_t>* signature) override {
  95. if (algorithm == SSL_SIGN_RSA_PKCS1_MD5_SHA1) {
  96. // SSL_SIGN_RSA_PKCS1_MD5_SHA1 cannot be implemented with the Java
  97. // signature API directly.
  98. return SignRSAWithMD5SHA1(input, signature);
  99. }
  100. if (use_pss_fallback_.contains(algorithm)) {
  101. return SignPSSFallback(algorithm, input, signature);
  102. }
  103. const char* java_algorithm = GetJavaAlgorithm(algorithm);
  104. if (!java_algorithm) {
  105. LOG(ERROR) << "Unknown algorithm " << algorithm;
  106. return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
  107. }
  108. if (!android::SignWithPrivateKey(key_, java_algorithm, input, signature)) {
  109. LOG(ERROR) << "Could not sign message with private key!";
  110. return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
  111. }
  112. return OK;
  113. }
  114. private:
  115. Error SignRSAWithMD5SHA1(base::span<const uint8_t> input,
  116. std::vector<uint8_t>* signature) {
  117. uint8_t digest[EVP_MAX_MD_SIZE];
  118. unsigned digest_len;
  119. if (!EVP_Digest(input.data(), input.size(), digest, &digest_len,
  120. EVP_md5_sha1(), nullptr)) {
  121. LOG(ERROR) << "Could not take digest.";
  122. return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
  123. }
  124. if (!android::SignWithPrivateKey(key_, "NONEwithRSA",
  125. base::make_span(digest, digest_len),
  126. signature)) {
  127. LOG(ERROR) << "Could not sign message with private key!";
  128. return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
  129. }
  130. return OK;
  131. }
  132. Error SignPSSFallback(uint16_t algorithm,
  133. base::span<const uint8_t> input,
  134. std::vector<uint8_t>* signature) {
  135. const EVP_MD* md = SSL_get_signature_algorithm_digest(algorithm);
  136. uint8_t digest[EVP_MAX_MD_SIZE];
  137. unsigned digest_len;
  138. if (!EVP_Digest(input.data(), input.size(), digest, &digest_len, md,
  139. nullptr)) {
  140. return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
  141. }
  142. absl::optional<std::vector<uint8_t>> padded =
  143. AddPSSPadding(pubkey_.get(), md, base::make_span(digest, digest_len));
  144. if (!padded) {
  145. return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
  146. }
  147. if (!android::EncryptWithPrivateKey(key_, kRSANoPadding, *padded,
  148. signature)) {
  149. return ERR_SSL_CLIENT_AUTH_SIGNATURE_FAILED;
  150. }
  151. return OK;
  152. }
  153. bssl::UniquePtr<EVP_PKEY> pubkey_;
  154. ScopedJavaGlobalRef<jobject> key_;
  155. std::string provider_name_;
  156. std::vector<uint16_t> preferences_;
  157. base::flat_set<uint16_t> use_pss_fallback_;
  158. };
  159. } // namespace
  160. scoped_refptr<SSLPrivateKey> WrapJavaPrivateKey(
  161. const X509Certificate* certificate,
  162. const JavaRef<jobject>& key) {
  163. bssl::UniquePtr<EVP_PKEY> pubkey = GetClientCertPublicKey(certificate);
  164. if (!pubkey)
  165. return nullptr;
  166. return base::MakeRefCounted<ThreadedSSLPrivateKey>(
  167. std::make_unique<SSLPlatformKeyAndroid>(std::move(pubkey), key),
  168. GetSSLPlatformKeyTaskRunner());
  169. }
  170. } // namespace net