| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/android/keystore_openssl.h" | 5 #include "net/android/keystore_openssl.h" |
| 6 | 6 |
| 7 #include <jni.h> | 7 #include <jni.h> |
| 8 #include <openssl/bn.h> | 8 #include <openssl/bn.h> |
| 9 // This include is required to get the ECDSA_METHOD structure definition | 9 // This include is required to get the ECDSA_METHOD structure definition |
| 10 // which isn't currently part of the OpenSSL official ABI. This should | 10 // which isn't currently part of the OpenSSL official ABI. This should |
| 11 // not be a concern for Chromium which always links against its own | 11 // not be a concern for Chromium which always links against its own |
| 12 // version of the library on Android. | 12 // version of the library on Android. |
| 13 #include <openssl/crypto/ecdsa/ecs_locl.h> | 13 #include <openssl/crypto/ecdsa/ecs_locl.h> |
| 14 // And this one is needed for the EC_GROUP definition. | 14 // And this one is needed for the EC_GROUP definition. |
| 15 #include <openssl/crypto/ec/ec_lcl.h> | 15 #include <openssl/crypto/ec/ec_lcl.h> |
| 16 #include <openssl/dsa.h> | 16 #include <openssl/dsa.h> |
| 17 #include <openssl/ec.h> | 17 #include <openssl/ec.h> |
| 18 #include <openssl/engine.h> | 18 #include <openssl/engine.h> |
| 19 #include <openssl/evp.h> | 19 #include <openssl/evp.h> |
| 20 #include <openssl/rsa.h> | 20 #include <openssl/rsa.h> |
| 21 | 21 |
| 22 #include "base/android/build_info.h" | 22 #include "base/android/build_info.h" |
| 23 #include "base/android/jni_android.h" | 23 #include "base/android/jni_android.h" |
| 24 #include "base/android/scoped_java_ref.h" | 24 #include "base/android/scoped_java_ref.h" |
| 25 #include "base/basictypes.h" | 25 #include "base/basictypes.h" |
| 26 #include "base/lazy_instance.h" | 26 #include "base/lazy_instance.h" |
| 27 #include "base/logging.h" | 27 #include "base/logging.h" |
| 28 #include "crypto/openssl_util.h" | 28 #include "crypto/openssl_util.h" |
| 29 #include "crypto/scoped_openssl_types.h" |
| 29 #include "net/android/keystore.h" | 30 #include "net/android/keystore.h" |
| 30 #include "net/ssl/ssl_client_cert_type.h" | 31 #include "net/ssl/ssl_client_cert_type.h" |
| 31 | 32 |
| 32 // IMPORTANT NOTE: The following code will currently only work when used | 33 // IMPORTANT NOTE: The following code will currently only work when used |
| 33 // to implement client certificate support with OpenSSL. That's because | 34 // to implement client certificate support with OpenSSL. That's because |
| 34 // only the signing operations used in this use case are implemented here. | 35 // only the signing operations used in this use case are implemented here. |
| 35 // | 36 // |
| 36 // Generally speaking, OpenSSL provides many different ways to sign | 37 // Generally speaking, OpenSSL provides many different ways to sign |
| 37 // digests. This code doesn't support all these cases, only the ones that | 38 // digests. This code doesn't support all these cases, only the ones that |
| 38 // are required to sign the digest during the OpenSSL handshake for TLS. | 39 // are required to sign the digest during the OpenSSL handshake for TLS. |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 // default for a lot of operations. Very fortunately, this is not needed | 95 // default for a lot of operations. Very fortunately, this is not needed |
| 95 // here, which saves a lot of complexity. | 96 // here, which saves a lot of complexity. |
| 96 | 97 |
| 97 using base::android::ScopedJavaGlobalRef; | 98 using base::android::ScopedJavaGlobalRef; |
| 98 | 99 |
| 99 namespace net { | 100 namespace net { |
| 100 namespace android { | 101 namespace android { |
| 101 | 102 |
| 102 namespace { | 103 namespace { |
| 103 | 104 |
| 104 typedef crypto::ScopedOpenSSL<EVP_PKEY, EVP_PKEY_free> ScopedEVP_PKEY; | 105 typedef scoped_ptr<EC_GROUP, crypto::OpenSSLDestroyer<EC_GROUP, EC_GROUP_free> > |
| 105 typedef crypto::ScopedOpenSSL<RSA, RSA_free> ScopedRSA; | 106 ScopedEC_GROUP; |
| 106 typedef crypto::ScopedOpenSSL<DSA, DSA_free> ScopedDSA; | |
| 107 typedef crypto::ScopedOpenSSL<EC_KEY, EC_KEY_free> ScopedEC_KEY; | |
| 108 typedef crypto::ScopedOpenSSL<EC_GROUP, EC_GROUP_free> ScopedEC_GROUP; | |
| 109 | 107 |
| 110 // Custom RSA_METHOD that uses the platform APIs. | 108 // Custom RSA_METHOD that uses the platform APIs. |
| 111 // Note that for now, only signing through RSA_sign() is really supported. | 109 // Note that for now, only signing through RSA_sign() is really supported. |
| 112 // all other method pointers are either stubs returning errors, or no-ops. | 110 // all other method pointers are either stubs returning errors, or no-ops. |
| 113 // See <openssl/rsa.h> for exact declaration of RSA_METHOD. | 111 // See <openssl/rsa.h> for exact declaration of RSA_METHOD. |
| 114 | 112 |
| 115 int RsaMethodPubEnc(int flen, | 113 int RsaMethodPubEnc(int flen, |
| 116 const unsigned char* from, | 114 const unsigned char* from, |
| 117 unsigned char* to, | 115 unsigned char* to, |
| 118 RSA* rsa, | 116 RSA* rsa, |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object. | 274 // Setup an EVP_PKEY to wrap an existing platform RSA PrivateKey object. |
| 277 // |private_key| is the JNI reference (local or global) to the object. | 275 // |private_key| is the JNI reference (local or global) to the object. |
| 278 // |pkey| is the EVP_PKEY to setup as a wrapper. | 276 // |pkey| is the EVP_PKEY to setup as a wrapper. |
| 279 // Returns true on success, false otherwise. | 277 // Returns true on success, false otherwise. |
| 280 // On success, this creates a new global JNI reference to the object | 278 // On success, this creates a new global JNI reference to the object |
| 281 // that is owned by and destroyed with the EVP_PKEY. I.e. caller can | 279 // that is owned by and destroyed with the EVP_PKEY. I.e. caller can |
| 282 // free |private_key| after the call. | 280 // free |private_key| after the call. |
| 283 // IMPORTANT: The EVP_PKEY will *only* work on Android >= 4.2. For older | 281 // IMPORTANT: The EVP_PKEY will *only* work on Android >= 4.2. For older |
| 284 // platforms, use GetRsaLegacyKey() instead. | 282 // platforms, use GetRsaLegacyKey() instead. |
| 285 bool GetRsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { | 283 bool GetRsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { |
| 286 ScopedRSA rsa(RSA_new()); | 284 crypto::ScopedRSA rsa(RSA_new()); |
| 287 RSA_set_method(rsa.get(), &android_rsa_method); | 285 RSA_set_method(rsa.get(), &android_rsa_method); |
| 288 | 286 |
| 289 // HACK: RSA_size() doesn't work with custom RSA_METHODs. To ensure that | 287 // HACK: RSA_size() doesn't work with custom RSA_METHODs. To ensure that |
| 290 // it will return the right value, set the 'n' field of the RSA object | 288 // it will return the right value, set the 'n' field of the RSA object |
| 291 // to match the private key's modulus. | 289 // to match the private key's modulus. |
| 292 std::vector<uint8> modulus; | 290 std::vector<uint8> modulus; |
| 293 if (!GetRSAKeyModulus(private_key, &modulus)) { | 291 if (!GetRSAKeyModulus(private_key, &modulus)) { |
| 294 LOG(ERROR) << "Failed to get private key modulus"; | 292 LOG(ERROR) << "Failed to get private key modulus"; |
| 295 return false; | 293 return false; |
| 296 } | 294 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 320 // https://android.googlesource.com/platform/libcore/+/106a8928fb4249f2f3d4dba1d
ddbe73ca5cb3d61 | 318 // https://android.googlesource.com/platform/libcore/+/106a8928fb4249f2f3d4dba1d
ddbe73ca5cb3d61 |
| 321 // | 319 // |
| 322 // https://crbug.com/381465 | 320 // https://crbug.com/381465 |
| 323 class KeystoreEngineWorkaround { | 321 class KeystoreEngineWorkaround { |
| 324 public: | 322 public: |
| 325 KeystoreEngineWorkaround() : leaked_engine_(false) {} | 323 KeystoreEngineWorkaround() : leaked_engine_(false) {} |
| 326 | 324 |
| 327 void LeakRsaEngine(EVP_PKEY* pkey) { | 325 void LeakRsaEngine(EVP_PKEY* pkey) { |
| 328 if (leaked_engine_) | 326 if (leaked_engine_) |
| 329 return; | 327 return; |
| 330 ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey)); | 328 crypto::ScopedRSA rsa(EVP_PKEY_get1_RSA(pkey)); |
| 331 if (!rsa.get() || | 329 if (!rsa.get() || |
| 332 !rsa.get()->engine || | 330 !rsa.get()->engine || |
| 333 strcmp(ENGINE_get_id(rsa.get()->engine), "keystore") || | 331 strcmp(ENGINE_get_id(rsa.get()->engine), "keystore") || |
| 334 !ENGINE_init(rsa.get()->engine)) { | 332 !ENGINE_init(rsa.get()->engine)) { |
| 335 NOTREACHED(); | 333 NOTREACHED(); |
| 336 return; | 334 return; |
| 337 } | 335 } |
| 338 leaked_engine_ = true; | 336 leaked_engine_ = true; |
| 339 } | 337 } |
| 340 | 338 |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 473 /* .dsa_keygen = */ NULL | 471 /* .dsa_keygen = */ NULL |
| 474 }; | 472 }; |
| 475 | 473 |
| 476 // Setup an EVP_PKEY to wrap an existing DSA platform PrivateKey object. | 474 // Setup an EVP_PKEY to wrap an existing DSA platform PrivateKey object. |
| 477 // |private_key| is a JNI reference (local or global) to the object. | 475 // |private_key| is a JNI reference (local or global) to the object. |
| 478 // |pkey| is the EVP_PKEY to setup as a wrapper. | 476 // |pkey| is the EVP_PKEY to setup as a wrapper. |
| 479 // Returns true on success, false otherwise. | 477 // Returns true on success, false otherwise. |
| 480 // On success, this creates a global JNI reference to the same object | 478 // On success, this creates a global JNI reference to the same object |
| 481 // that will be owned by and destroyed with the EVP_PKEY. | 479 // that will be owned by and destroyed with the EVP_PKEY. |
| 482 bool GetDsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { | 480 bool GetDsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { |
| 483 ScopedDSA dsa(DSA_new()); | 481 crypto::ScopedDSA dsa(DSA_new()); |
| 484 DSA_set_method(dsa.get(), &android_dsa_method); | 482 DSA_set_method(dsa.get(), &android_dsa_method); |
| 485 | 483 |
| 486 // DSA_size() doesn't work with custom DSA_METHODs. To ensure it | 484 // DSA_size() doesn't work with custom DSA_METHODs. To ensure it |
| 487 // returns the right value, set the 'q' field in the DSA object to | 485 // returns the right value, set the 'q' field in the DSA object to |
| 488 // match the parameter from the platform key. | 486 // match the parameter from the platform key. |
| 489 std::vector<uint8> q; | 487 std::vector<uint8> q; |
| 490 if (!GetDSAKeyParamQ(private_key, &q)) { | 488 if (!GetDSAKeyParamQ(private_key, &q)) { |
| 491 LOG(ERROR) << "Can't extract Q parameter from DSA private key"; | 489 LOG(ERROR) << "Can't extract Q parameter from DSA private key"; |
| 492 return false; | 490 return false; |
| 493 } | 491 } |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 }; | 640 }; |
| 643 | 641 |
| 644 // Setup an EVP_PKEY to wrap an existing platform PrivateKey object. | 642 // Setup an EVP_PKEY to wrap an existing platform PrivateKey object. |
| 645 // |private_key| is the JNI reference (local or global) to the object. | 643 // |private_key| is the JNI reference (local or global) to the object. |
| 646 // |pkey| is the EVP_PKEY to setup as a wrapper. | 644 // |pkey| is the EVP_PKEY to setup as a wrapper. |
| 647 // Returns true on success, false otherwise. | 645 // Returns true on success, false otherwise. |
| 648 // On success, this creates a global JNI reference to the object that | 646 // On success, this creates a global JNI reference to the object that |
| 649 // is owned by and destroyed with the EVP_PKEY. I.e. the caller shall | 647 // is owned by and destroyed with the EVP_PKEY. I.e. the caller shall |
| 650 // always free |private_key| after the call. | 648 // always free |private_key| after the call. |
| 651 bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { | 649 bool GetEcdsaPkeyWrapper(jobject private_key, EVP_PKEY* pkey) { |
| 652 ScopedEC_KEY eckey(EC_KEY_new()); | 650 crypto::ScopedEC_KEY eckey(EC_KEY_new()); |
| 653 ECDSA_set_method(eckey.get(), &android_ecdsa_method); | 651 ECDSA_set_method(eckey.get(), &android_ecdsa_method); |
| 654 | 652 |
| 655 // To ensure that ECDSA_size() works properly, craft a custom EC_GROUP | 653 // To ensure that ECDSA_size() works properly, craft a custom EC_GROUP |
| 656 // that has the same order than the private key. | 654 // that has the same order than the private key. |
| 657 std::vector<uint8> order; | 655 std::vector<uint8> order; |
| 658 if (!GetECKeyOrder(private_key, &order)) { | 656 if (!GetECKeyOrder(private_key, &order)) { |
| 659 LOG(ERROR) << "Can't extract order parameter from EC private key"; | 657 LOG(ERROR) << "Can't extract order parameter from EC private key"; |
| 660 return false; | 658 return false; |
| 661 } | 659 } |
| 662 ScopedEC_GROUP group(EC_GROUP_new(EC_GFp_nist_method())); | 660 ScopedEC_GROUP group(EC_GROUP_new(EC_GFp_nist_method())); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 681 global_key.Release()); | 679 global_key.Release()); |
| 682 | 680 |
| 683 EVP_PKEY_assign_EC_KEY(pkey, eckey.release()); | 681 EVP_PKEY_assign_EC_KEY(pkey, eckey.release()); |
| 684 return true; | 682 return true; |
| 685 } | 683 } |
| 686 | 684 |
| 687 } // namespace | 685 } // namespace |
| 688 | 686 |
| 689 EVP_PKEY* GetOpenSSLPrivateKeyWrapper(jobject private_key) { | 687 EVP_PKEY* GetOpenSSLPrivateKeyWrapper(jobject private_key) { |
| 690 // Create new empty EVP_PKEY instance. | 688 // Create new empty EVP_PKEY instance. |
| 691 ScopedEVP_PKEY pkey(EVP_PKEY_new()); | 689 crypto::ScopedEVP_PKEY pkey(EVP_PKEY_new()); |
| 692 if (!pkey.get()) | 690 if (!pkey.get()) |
| 693 return NULL; | 691 return NULL; |
| 694 | 692 |
| 695 // Create sub key type, depending on private key's algorithm type. | 693 // Create sub key type, depending on private key's algorithm type. |
| 696 PrivateKeyType key_type = GetPrivateKeyType(private_key); | 694 PrivateKeyType key_type = GetPrivateKeyType(private_key); |
| 697 switch (key_type) { | 695 switch (key_type) { |
| 698 case PRIVATE_KEY_TYPE_RSA: | 696 case PRIVATE_KEY_TYPE_RSA: |
| 699 { | 697 { |
| 700 // Route around platform bug: if Android < 4.2, then | 698 // Route around platform bug: if Android < 4.2, then |
| 701 // base::android::RawSignDigestWithPrivateKey() cannot work, so | 699 // base::android::RawSignDigestWithPrivateKey() cannot work, so |
| (...skipping 24 matching lines...) Expand all Loading... |
| 726 default: | 724 default: |
| 727 LOG(WARNING) | 725 LOG(WARNING) |
| 728 << "GetOpenSSLPrivateKeyWrapper() called with invalid key type"; | 726 << "GetOpenSSLPrivateKeyWrapper() called with invalid key type"; |
| 729 return NULL; | 727 return NULL; |
| 730 } | 728 } |
| 731 return pkey.release(); | 729 return pkey.release(); |
| 732 } | 730 } |
| 733 | 731 |
| 734 } // namespace android | 732 } // namespace android |
| 735 } // namespace net | 733 } // namespace net |
| OLD | NEW |