• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "jni/AndroidKeyStore_jni.h"
13 #include "net/android/android_private_key.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 
GetRSAKeyModulus(jobject private_key_ref,std::vector<uint8> * result)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,
32                                             GetKeyStore(private_key_ref).obj(),
33                                             private_key_ref);
34   if (modulus_ref.is_null())
35     return false;
36 
37   JavaByteArrayToByteVector(env, modulus_ref.obj(), result);
38   return true;
39 }
40 
GetDSAKeyParamQ(jobject private_key_ref,std::vector<uint8> * result)41 bool GetDSAKeyParamQ(jobject private_key_ref,
42                      std::vector<uint8>* result) {
43   JNIEnv* env = AttachCurrentThread();
44 
45   ScopedJavaLocalRef<jbyteArray> q_ref =
46       Java_AndroidKeyStore_getDSAKeyParamQ(
47           env,
48           GetKeyStore(private_key_ref).obj(),
49           private_key_ref);
50   if (q_ref.is_null())
51     return false;
52 
53   JavaByteArrayToByteVector(env, q_ref.obj(), result);
54   return true;
55 }
56 
GetECKeyOrder(jobject private_key_ref,std::vector<uint8> * result)57 bool GetECKeyOrder(jobject private_key_ref,
58                    std::vector<uint8>* result) {
59   JNIEnv* env = AttachCurrentThread();
60 
61   ScopedJavaLocalRef<jbyteArray> order_ref =
62       Java_AndroidKeyStore_getECKeyOrder(
63           env,
64           GetKeyStore(private_key_ref).obj(),
65           private_key_ref);
66 
67   if (order_ref.is_null())
68     return false;
69 
70   JavaByteArrayToByteVector(env, order_ref.obj(), result);
71   return true;
72 }
73 
GetPrivateKeyEncodedBytes(jobject private_key_ref,std::vector<uint8> * result)74 bool GetPrivateKeyEncodedBytes(jobject private_key_ref,
75                                std::vector<uint8>* result) {
76   JNIEnv* env = AttachCurrentThread();
77 
78   ScopedJavaLocalRef<jbyteArray> encoded_ref =
79       Java_AndroidKeyStore_getPrivateKeyEncodedBytes(
80           env,
81           GetKeyStore(private_key_ref).obj(),
82           private_key_ref);
83   if (encoded_ref.is_null())
84     return false;
85 
86   JavaByteArrayToByteVector(env, encoded_ref.obj(), result);
87   return true;
88 }
89 
RawSignDigestWithPrivateKey(jobject private_key_ref,const base::StringPiece & digest,std::vector<uint8> * signature)90 bool RawSignDigestWithPrivateKey(
91     jobject private_key_ref,
92     const base::StringPiece& digest,
93     std::vector<uint8>* signature) {
94   JNIEnv* env = AttachCurrentThread();
95 
96   // Convert message to byte[] array.
97   ScopedJavaLocalRef<jbyteArray> digest_ref =
98       ToJavaByteArray(env,
99                       reinterpret_cast<const uint8*>(digest.data()),
100                       digest.length());
101   DCHECK(!digest_ref.is_null());
102 
103   // Invoke platform API
104   ScopedJavaLocalRef<jbyteArray> signature_ref =
105       Java_AndroidKeyStore_rawSignDigestWithPrivateKey(
106           env,
107           GetKeyStore(private_key_ref).obj(),
108           private_key_ref,
109           digest_ref.obj());
110   if (HasException(env) || signature_ref.is_null())
111     return false;
112 
113   // Write signature to string.
114   JavaByteArrayToByteVector(env, signature_ref.obj(), signature);
115   return true;
116 }
117 
GetPrivateKeyType(jobject private_key_ref)118 PrivateKeyType GetPrivateKeyType(jobject private_key_ref) {
119   JNIEnv* env = AttachCurrentThread();
120   int type = Java_AndroidKeyStore_getPrivateKeyType(
121       env,
122       GetKeyStore(private_key_ref).obj(),
123       private_key_ref);
124   return static_cast<PrivateKeyType>(type);
125 }
126 
GetOpenSSLSystemHandleForPrivateKey(jobject private_key_ref)127 EVP_PKEY* GetOpenSSLSystemHandleForPrivateKey(jobject private_key_ref) {
128   JNIEnv* env = AttachCurrentThread();
129   // Note: the pointer is passed as a jint here because that's how it
130   // is stored in the Java object. Java doesn't have a primitive type
131   // like intptr_t that matches the size of pointers on the host
132   // machine, and Android only runs on 32-bit CPUs.
133   //
134   // Given that this routine shall only be called on Android < 4.2,
135   // this won't be a problem in the far future (e.g. when Android gets
136   // ported to 64-bit environments, if ever).
137   long pkey = Java_AndroidKeyStore_getOpenSSLHandleForPrivateKey(
138       env,
139       GetKeyStore(private_key_ref).obj(),
140       private_key_ref);
141   return reinterpret_cast<EVP_PKEY*>(pkey);
142 }
143 
ReleaseKey(jobject private_key_ref)144 void ReleaseKey(jobject private_key_ref) {
145   JNIEnv* env = AttachCurrentThread();
146   Java_AndroidKeyStore_releaseKey(env,
147                                   GetKeyStore(private_key_ref).obj(),
148                                   private_key_ref);
149   env->DeleteGlobalRef(private_key_ref);
150 }
151 
RegisterKeyStore(JNIEnv * env)152 bool RegisterKeyStore(JNIEnv* env) {
153   return RegisterNativesImpl(env);
154 }
155 
156 }  // namespace android
157 }  // namespace net
158