Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Side by Side Diff: net/android/java/src/org/chromium/net/AndroidKeyStoreInProcessImpl.java

Issue 166143002: Refactoring AndroidKeyStore to support a KeyStore running in another process (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 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 package org.chromium.net;
6
7 import android.util.Log;
8
9 import java.lang.reflect.Method;
10 import java.security.NoSuchAlgorithmException;
11 import java.security.PrivateKey;
12 import java.security.Signature;
13 import java.security.interfaces.DSAKey;
14 import java.security.interfaces.DSAParams;
15 import java.security.interfaces.DSAPrivateKey;
16 import java.security.interfaces.ECKey;
17 import java.security.interfaces.ECPrivateKey;
18 import java.security.interfaces.RSAKey;
19 import java.security.interfaces.RSAPrivateKey;
20 import java.security.spec.ECParameterSpec;
21
22 /**
23 * Simple implementation of the AndroidKeyStoreInterface for use with an in-proc ess Java KeyStore.
24 */
25 public class AndroidKeyStoreInProcessImpl implements AndroidKeyStore {
Ryan Sleevi 2014/02/14 20:57:51 Naming wise, this seems unduly verbose. I would j
Yaron 2014/02/14 22:06:59 Fair enough. Default* and Remote* it is. ALso upda
26
27 private static final String TAG = "AndroidKeyStoreInProcessImpl";
28
29 private static class InProcessPrivateKey implements AndroidPrivateKey {
30 // The actual Java key being wrapped.
31 final PrivateKey mKey;
32 // Key store handling this key.
33 final AndroidKeyStoreInProcessImpl mStore;
34
35 InProcessPrivateKey(PrivateKey key, AndroidKeyStoreInProcessImpl store) {
36 mKey = key;
37 mStore = store;
38 }
39
40 PrivateKey getJavaKey() {
41 return mKey;
42 }
43
44 @Override
45 public AndroidKeyStore getKeyStore() {
46 return mStore;
47 }
48 }
49
50 public AndroidPrivateKey createKey(PrivateKey javaKey) {
51 return new InProcessPrivateKey(javaKey, this);
52 }
53
54 @Override
55 public byte[] getRSAKeyModulus(AndroidPrivateKey key) {
56 PrivateKey javaKey = ((InProcessPrivateKey) key).getJavaKey();
57 if (javaKey instanceof RSAKey) {
58 return ((RSAKey) javaKey).getModulus().toByteArray();
59 }
60 Log.w(TAG, "Not a RSAKey instance!");
61 return null;
62 }
63
64 @Override
65 public byte[] getDSAKeyParamQ(AndroidPrivateKey key) {
66 PrivateKey javaKey = ((InProcessPrivateKey) key).getJavaKey();
67 if (javaKey instanceof DSAKey) {
68 DSAParams params = ((DSAKey) javaKey).getParams();
69 return params.getQ().toByteArray();
70 }
71 Log.w(TAG, "Not a DSAKey instance!");
72 return null;
73 }
74
75 @Override
76 public byte[] getECKeyOrder(AndroidPrivateKey key) {
77 PrivateKey javaKey = ((InProcessPrivateKey) key).getJavaKey();
78 if (javaKey instanceof ECKey) {
79 ECParameterSpec params = ((ECKey) javaKey).getParams();
80 return params.getOrder().toByteArray();
81 }
82 Log.w(TAG, "Not an ECKey instance!");
83 return null;
84 }
85
86 @Override
87 public byte[] getPrivateKeyEncodedBytes(AndroidPrivateKey key) {
88 PrivateKey javaKey = ((InProcessPrivateKey) key).getJavaKey();
89 return javaKey.getEncoded();
90 }
91
92 @Override
93 public byte[] rawSignDigestWithPrivateKey(AndroidPrivateKey key,
94 byte[] message) {
95 PrivateKey javaKey = ((InProcessPrivateKey) key).getJavaKey();
96 // Get the Signature for this key.
97 Signature signature = null;
98 // Hint: Algorithm names come from:
99 // http://docs.oracle.com/javase/6/docs/technotes/guides/security/Standa rdNames.html
100 try {
101 if (javaKey instanceof RSAPrivateKey) {
102 // IMPORTANT: Due to a platform bug, this will throw NoSuchAlgor ithmException
103 // on Android 4.0.x and 4.1.x. Fixed in 4.2 and higher.
104 // See https://android-review.googlesource.com/#/c/40352/
105 signature = Signature.getInstance("NONEwithRSA");
106 } else if (javaKey instanceof DSAPrivateKey) {
107 signature = Signature.getInstance("NONEwithDSA");
108 } else if (javaKey instanceof ECPrivateKey) {
109 signature = Signature.getInstance("NONEwithECDSA");
110 }
111 } catch (NoSuchAlgorithmException e) {
112 ;
113 }
114
115 if (signature == null) {
116 Log.e(TAG, "Unsupported private key algorithm: " + javaKey.getAlgori thm());
117 return null;
118 }
119
120 // Sign the message.
121 try {
122 signature.initSign(javaKey);
123 signature.update(message);
124 return signature.sign();
125 } catch (Exception e) {
126 Log.e(TAG, "Exception while signing message with " + javaKey.getAlgo rithm() +
127 " private key: " + e);
128 return null;
129 }
130 }
131
132 @Override
133 public int getPrivateKeyType(AndroidPrivateKey key) {
134 PrivateKey javaKey = ((InProcessPrivateKey) key).getJavaKey();
135 if (javaKey instanceof RSAPrivateKey)
136 return PrivateKeyType.RSA;
137 if (javaKey instanceof DSAPrivateKey)
138 return PrivateKeyType.DSA;
139 if (javaKey instanceof ECPrivateKey)
140 return PrivateKeyType.ECDSA;
141 else
142 return PrivateKeyType.INVALID;
143 }
144
145 @Override
146 public int getOpenSSLHandleForPrivateKey(AndroidPrivateKey key) {
147 PrivateKey javaKey = ((InProcessPrivateKey) key).getJavaKey();
148 // Sanity checks
149 if (javaKey == null) {
150 Log.e(TAG, "key == null");
151 return 0;
152 }
153 if (!(javaKey instanceof RSAPrivateKey)) {
154 Log.e(TAG, "does not implement RSAPrivateKey");
155 return 0;
156 }
157 // First, check that this is a proper instance of OpenSSLRSAPrivateKey
158 // or one of its sub-classes.
159 Class<?> superClass;
160 try {
161 superClass = Class.forName(
162 "org.apache.harmony.xnet.provider.jsse.OpenSSLRSAPrivateKey" );
163 } catch (Exception e) {
164 // This may happen if the target device has a completely different
165 // implementation of the java.security APIs, compared to vanilla
166 // Android. Highly unlikely, but still possible.
167 Log.e(TAG, "Cannot find system OpenSSLRSAPrivateKey class: " + e);
168 return 0;
169 }
170 if (!superClass.isInstance(key)) {
171 // This may happen if the PrivateKey was not created by the "Android OpenSSL"
172 // provider, which should be the default. That could happen if an OE M decided
173 // to implement a different default provider. Also highly unlikely.
174 Log.e(TAG, "Private key is not an OpenSSLRSAPrivateKey instance, its class name is:" +
175 javaKey.getClass().getCanonicalName());
176 return 0;
177 }
178
179 try {
180 // Use reflection to invoke the 'getOpenSSLKey()' method on
181 // the private key. This returns another Java object that wraps
182 // a native EVP_PKEY. Note that the method is final, so calling
183 // the superclass implementation is ok.
184 Method getKey = superClass.getDeclaredMethod("getOpenSSLKey");
185 getKey.setAccessible(true);
186 Object opensslKey = null;
187 try {
188 opensslKey = getKey.invoke(javaKey);
189 } finally {
190 getKey.setAccessible(false);
191 }
192 if (opensslKey == null) {
193 // Bail when detecting OEM "enhancement".
194 Log.e(TAG, "getOpenSSLKey() returned null");
195 return 0;
196 }
197
198 // Use reflection to invoke the 'getPkeyContext' method on the
199 // result of the getOpenSSLKey(). This is an 32-bit integer
200 // which is the address of an EVP_PKEY object.
201 Method getPkeyContext;
202 try {
203 getPkeyContext = opensslKey.getClass().getDeclaredMethod("getPke yContext");
204 } catch (Exception e) {
205 // Bail here too, something really not working as expected.
206 Log.e(TAG, "No getPkeyContext() method on OpenSSLKey member:" + e);
207 return 0;
208 }
209 getPkeyContext.setAccessible(true);
210 int evp_pkey = 0;
211 try {
212 evp_pkey = (Integer) getPkeyContext.invoke(opensslKey);
213 } finally {
214 getPkeyContext.setAccessible(false);
215 }
216 if (evp_pkey == 0) {
217 // The PrivateKey is probably rotten for some reason.
218 Log.e(TAG, "getPkeyContext() returned null");
219 }
220 return evp_pkey;
221
222 } catch (Exception e) {
223 Log.e(TAG, "Exception while trying to retrieve system EVP_PKEY handl e: " + e);
224 return 0;
225 }
226 }
227
228 @Override
229 public void releaseKey(AndroidPrivateKey key) {
230 // no-op for in-process. GC will handle key collection
231 }
232 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698