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 3 // found in the LICENSE file. 4 5 #include "net/android/keystore.h" 6 7 #include <vector> 8 9 #include "base/android/jni_android.h" 10 #include "base/android/jni_array.h" 11 #include "base/logging.h" 12 13 #include "jni/AndroidKeyStore_jni.h" 14 15 using base::android::AttachCurrentThread; 16 using base::android::HasException; 17 using base::android::JavaByteArrayToByteVector; 18 using base::android::ScopedJavaLocalRef; 19 using base::android::ToJavaByteArray; 20 using base::android::JavaArrayOfByteArrayToStringVector; 21 22 namespace net { 23 namespace android { 24 25 bool GetRSAKeyModulus( 26 jobject private_key_ref, 27 std::vector<uint8>* result) { 28 JNIEnv* env = AttachCurrentThread(); 29 30 ScopedJavaLocalRef<jbyteArray> modulus_ref = 31 Java_AndroidKeyStore_getRSAKeyModulus(env, private_key_ref); 32 if (modulus_ref.is_null()) 33 return false; 34 35 JavaByteArrayToByteVector(env, modulus_ref.obj(), result); 36 return true; 37 } 38 39 bool GetDSAKeyParamQ(jobject private_key_ref, 40 std::vector<uint8>* result) { 41 JNIEnv* env = AttachCurrentThread(); 42 43 ScopedJavaLocalRef<jbyteArray> q_ref = 44 Java_AndroidKeyStore_getDSAKeyParamQ(env, private_key_ref); 45 if (q_ref.is_null()) 46 return false; 47 48 JavaByteArrayToByteVector(env, q_ref.obj(), result); 49 return true; 50 } 51 52 bool GetECKeyOrder(jobject private_key_ref, 53 std::vector<uint8>* result) { 54 JNIEnv* env = AttachCurrentThread(); 55 56 ScopedJavaLocalRef<jbyteArray> order_ref = 57 Java_AndroidKeyStore_getECKeyOrder(env, private_key_ref); 58 if (order_ref.is_null()) 59 return false; 60 61 JavaByteArrayToByteVector(env, order_ref.obj(), result); 62 return true; 63 } 64 65 bool GetPrivateKeyEncodedBytes(jobject private_key, 66 std::vector<uint8>* result) { 67 JNIEnv* env = AttachCurrentThread(); 68 69 ScopedJavaLocalRef<jbyteArray> encoded_ref = 70 Java_AndroidKeyStore_getPrivateKeyEncodedBytes(env, private_key); 71 if (encoded_ref.is_null()) 72 return false; 73 74 JavaByteArrayToByteVector(env, encoded_ref.obj(), result); 75 return true; 76 } 77 78 bool RawSignDigestWithPrivateKey( 79 jobject private_key_ref, 80 const base::StringPiece& digest, 81 std::vector<uint8>* signature) { 82 JNIEnv* env = AttachCurrentThread(); 83 84 // Convert message to byte[] array. 85 ScopedJavaLocalRef<jbyteArray> digest_ref = 86 ToJavaByteArray(env, 87 reinterpret_cast<const uint8*>(digest.data()), 88 digest.length()); 89 DCHECK(!digest_ref.is_null()); 90 91 // Invoke platform API 92 ScopedJavaLocalRef<jbyteArray> signature_ref = 93 Java_AndroidKeyStore_rawSignDigestWithPrivateKey( 94 env, private_key_ref, digest_ref.obj()); 95 if (HasException(env) || signature_ref.is_null()) 96 return false; 97 98 // Write signature to string. 99 JavaByteArrayToByteVector(env, signature_ref.obj(), signature); 100 return true; 101 } 102 103 PrivateKeyType GetPrivateKeyType(jobject private_key) { 104 JNIEnv* env = AttachCurrentThread(); 105 int type = Java_AndroidKeyStore_getPrivateKeyType( 106 env, private_key); 107 return static_cast<PrivateKeyType>(type); 108 } 109 110 EVP_PKEY* GetOpenSSLSystemHandleForPrivateKey(jobject private_key) { 111 JNIEnv* env = AttachCurrentThread(); 112 // Note: the pointer is passed as a jint here because that's how it 113 // is stored in the Java object. Java doesn't have a primitive type 114 // like intptr_t that matches the size of pointers on the host 115 // machine, and Android only runs on 32-bit CPUs. 116 // 117 // Given that this routine shall only be called on Android < 4.2, 118 // this won't be a problem in the far future (e.g. when Android gets 119 // ported to 64-bit environments, if ever). 120 int pkey = 121 Java_AndroidKeyStore_getOpenSSLHandleForPrivateKey(env, private_key); 122 return reinterpret_cast<EVP_PKEY*>(pkey); 123 } 124 125 bool RegisterKeyStore(JNIEnv* env) { 126 return RegisterNativesImpl(env); 127 } 128 129 } // namespace android 130 } // namespace net 131