Index: net/android/java/src/org/chromium/net/AndroidKeyStoreLocalImpl.java |
diff --git a/net/android/java/src/org/chromium/net/AndroidKeyStore.java b/net/android/java/src/org/chromium/net/AndroidKeyStoreLocalImpl.java |
similarity index 77% |
copy from net/android/java/src/org/chromium/net/AndroidKeyStore.java |
copy to net/android/java/src/org/chromium/net/AndroidKeyStoreLocalImpl.java |
index 1396bf1807e215ed38e4d2c61b8f220bf8a32111..2448f727fff96cd8fbe7a02f6a3a21e7eab0a907 100644 |
--- a/net/android/java/src/org/chromium/net/AndroidKeyStore.java |
+++ b/net/android/java/src/org/chromium/net/AndroidKeyStoreLocalImpl.java |
@@ -6,9 +6,6 @@ package org.chromium.net; |
import android.util.Log; |
-import org.chromium.base.CalledByNative; |
-import org.chromium.base.JNINamespace; |
- |
import java.lang.reflect.Method; |
import java.security.NoSuchAlgorithmException; |
import java.security.PrivateKey; |
@@ -22,10 +19,37 @@ import java.security.interfaces.RSAKey; |
import java.security.interfaces.RSAPrivateKey; |
import java.security.spec.ECParameterSpec; |
-@JNINamespace("net::android") |
-public class AndroidKeyStore { |
+/** |
+ * Simple implementation of the AndroidKeyStoreInterface for use with an in-process Java KeyStore. |
+ */ |
+public class AndroidKeyStoreLocalImpl implements AndroidKeyStore { |
+ |
+ private static final String TAG = "AndroidKeyStoreLocalImpl"; |
+ |
+ private static class LocalPrivateKey implements AndroidPrivateKey { |
+ // The actual Java key being wrapped. |
+ final PrivateKey mKey; |
+ // Key store handling this key. |
+ final AndroidKeyStoreLocalImpl mStore; |
+ |
+ LocalPrivateKey(PrivateKey key, AndroidKeyStoreLocalImpl store) { |
+ mKey = key; |
+ mStore = store; |
+ } |
+ |
+ PrivateKey getJavaKey() { |
+ return mKey; |
+ } |
+ |
+ @Override |
+ public AndroidKeyStore getKeyStore() { |
+ return mStore; |
+ } |
+ } |
- private static final String TAG = "AndroidKeyStore"; |
+ public AndroidPrivateKey createKey(PrivateKey javaKey) { |
+ return new LocalPrivateKey(javaKey, this); |
+ } |
//////////////////////////////////////////////////////////////////// |
// |
@@ -42,10 +66,12 @@ public class AndroidKeyStore { |
* @return A byte buffer corresponding to the modulus. This is |
* big-endian representation of a BigInteger. |
*/ |
- @CalledByNative |
- public static byte[] getRSAKeyModulus(PrivateKey key) { |
- if (key instanceof RSAKey) { |
- return ((RSAKey) key).getModulus().toByteArray(); |
+ |
+ @Override |
+ public byte[] getRSAKeyModulus(AndroidPrivateKey key) { |
+ PrivateKey javaKey = ((LocalPrivateKey) key).getJavaKey(); |
+ if (javaKey instanceof RSAKey) { |
+ return ((RSAKey) javaKey).getModulus().toByteArray(); |
} else { |
Log.w(TAG, "Not a RSAKey instance!"); |
return null; |
@@ -62,10 +88,12 @@ public class AndroidKeyStore { |
* @return A byte buffer corresponding to the Q parameter. This is |
* a big-endian representation of a BigInteger. |
*/ |
- @CalledByNative |
- public static byte[] getDSAKeyParamQ(PrivateKey key) { |
- if (key instanceof DSAKey) { |
- DSAParams params = ((DSAKey) key).getParams(); |
+ |
+ @Override |
+ public byte[] getDSAKeyParamQ(AndroidPrivateKey key) { |
+ PrivateKey javaKey = ((LocalPrivateKey) key).getJavaKey(); |
+ if (javaKey instanceof DSAKey) { |
+ DSAParams params = ((DSAKey) javaKey).getParams(); |
return params.getQ().toByteArray(); |
} else { |
Log.w(TAG, "Not a DSAKey instance!"); |
@@ -80,10 +108,12 @@ public class AndroidKeyStore { |
* @return A byte buffer corresponding to the 'order' parameter. |
* This is a big-endian representation of a BigInteger. |
*/ |
- @CalledByNative |
- public static byte[] getECKeyOrder(PrivateKey key) { |
- if (key instanceof ECKey) { |
- ECParameterSpec params = ((ECKey) key).getParams(); |
+ |
+ @Override |
+ public byte[] getECKeyOrder(AndroidPrivateKey key) { |
+ PrivateKey javaKey = ((LocalPrivateKey) key).getJavaKey(); |
+ if (javaKey instanceof ECKey) { |
+ ECParameterSpec params = ((ECKey) javaKey).getParams(); |
return params.getOrder().toByteArray(); |
} else { |
Log.w(TAG, "Not an ECKey instance!"); |
@@ -99,9 +129,11 @@ public class AndroidKeyStore { |
* @param key A PrivateKey instance |
* @return encoded key as PKCS#8 byte array, can be null. |
*/ |
- @CalledByNative |
- public static byte[] getPrivateKeyEncodedBytes(PrivateKey key) { |
- return key.getEncoded(); |
+ |
+ @Override |
+ public byte[] getPrivateKeyEncodedBytes(AndroidPrivateKey key) { |
+ PrivateKey javaKey = ((LocalPrivateKey) key).getJavaKey(); |
+ return javaKey.getEncoded(); |
} |
/** |
@@ -125,7 +157,7 @@ public class AndroidKeyStore { |
* message must be a hash and the function shall compute a direct |
* DSA/ECDSA signature for it. |
* |
- * @param privateKey The PrivateKey handle. |
+ * @param key The PrivateKey handle. |
* @param message The message to sign. |
* @return signature as a byte buffer. |
* |
@@ -133,22 +165,24 @@ public class AndroidKeyStore { |
* Android < 4.2 for RSA PrivateKey objects. See the |
* getOpenSSLHandleForPrivateKey() below for work-around. |
*/ |
- @CalledByNative |
- public static byte[] rawSignDigestWithPrivateKey(PrivateKey privateKey, |
+ |
+ @Override |
+ public byte[] rawSignDigestWithPrivateKey(AndroidPrivateKey key, |
byte[] message) { |
+ PrivateKey javaKey = ((LocalPrivateKey) key).getJavaKey(); |
// Get the Signature for this key. |
Signature signature = null; |
// Hint: Algorithm names come from: |
// http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html |
try { |
- if (privateKey instanceof RSAPrivateKey) { |
+ if (javaKey instanceof RSAPrivateKey) { |
// IMPORTANT: Due to a platform bug, this will throw NoSuchAlgorithmException |
// on Android 4.0.x and 4.1.x. Fixed in 4.2 and higher. |
// See https://android-review.googlesource.com/#/c/40352/ |
signature = Signature.getInstance("NONEwithRSA"); |
- } else if (privateKey instanceof DSAPrivateKey) { |
+ } else if (javaKey instanceof DSAPrivateKey) { |
signature = Signature.getInstance("NONEwithDSA"); |
- } else if (privateKey instanceof ECPrivateKey) { |
+ } else if (javaKey instanceof ECPrivateKey) { |
signature = Signature.getInstance("NONEwithECDSA"); |
} |
} catch (NoSuchAlgorithmException e) { |
@@ -156,17 +190,17 @@ public class AndroidKeyStore { |
} |
if (signature == null) { |
- Log.e(TAG, "Unsupported private key algorithm: " + privateKey.getAlgorithm()); |
+ Log.e(TAG, "Unsupported private key algorithm: " + javaKey.getAlgorithm()); |
return null; |
} |
// Sign the message. |
try { |
- signature.initSign(privateKey); |
+ signature.initSign(javaKey); |
signature.update(message); |
return signature.sign(); |
} catch (Exception e) { |
- Log.e(TAG, "Exception while signing message with " + privateKey.getAlgorithm() + |
+ Log.e(TAG, "Exception while signing message with " + javaKey.getAlgorithm() + |
" private key: " + e); |
return null; |
} |
@@ -176,16 +210,18 @@ public class AndroidKeyStore { |
* Return the type of a given PrivateKey object. This is an integer |
* that maps to one of the values defined by org.chromium.net.PrivateKeyType, |
* which is itself auto-generated from net/android/private_key_type_list.h |
- * @param privateKey The PrivateKey handle |
+ * @param key The PrivateKey handle |
* @return key type, or PrivateKeyType.INVALID if unknown. |
*/ |
- @CalledByNative |
- public static int getPrivateKeyType(PrivateKey privateKey) { |
- if (privateKey instanceof RSAPrivateKey) |
+ |
+ @Override |
+ public int getPrivateKeyType(AndroidPrivateKey key) { |
+ PrivateKey javaKey = ((LocalPrivateKey) key).getJavaKey(); |
+ if (javaKey instanceof RSAPrivateKey) |
return PrivateKeyType.RSA; |
- if (privateKey instanceof DSAPrivateKey) |
+ if (javaKey instanceof DSAPrivateKey) |
return PrivateKeyType.DSA; |
- if (privateKey instanceof ECPrivateKey) |
+ if (javaKey instanceof ECPrivateKey) |
return PrivateKeyType.ECDSA; |
else |
return PrivateKeyType.INVALID; |
@@ -219,17 +255,19 @@ public class AndroidKeyStore { |
* libcore/luni/src/main/java/org/apache/harmony/xnet/provider/jsse/OpenSSLRSAPrivateKey.java |
* libcore/luni/src/main/native/org_apache_harmony_xnet_provider_jsse_NativeCrypto.cpp |
* |
- * @param privateKey The PrivateKey handle. |
+ * @param key The PrivateKey handle. |
* @return The EVP_PKEY handle, as a 32-bit integer (0 if not available) |
*/ |
- @CalledByNative |
- public static int getOpenSSLHandleForPrivateKey(PrivateKey privateKey) { |
+ |
+ @Override |
+ public int getOpenSSLHandleForPrivateKey(AndroidPrivateKey key) { |
+ PrivateKey javaKey = ((LocalPrivateKey) key).getJavaKey(); |
// Sanity checks |
- if (privateKey == null) { |
- Log.e(TAG, "privateKey == null"); |
+ if (javaKey == null) { |
+ Log.e(TAG, "key == null"); |
return 0; |
} |
- if (!(privateKey instanceof RSAPrivateKey)) { |
+ if (!(javaKey instanceof RSAPrivateKey)) { |
Log.e(TAG, "does not implement RSAPrivateKey"); |
return 0; |
} |
@@ -246,12 +284,12 @@ public class AndroidKeyStore { |
Log.e(TAG, "Cannot find system OpenSSLRSAPrivateKey class: " + e); |
return 0; |
} |
- if (!superClass.isInstance(privateKey)) { |
+ if (!superClass.isInstance(key)) { |
// This may happen if the PrivateKey was not created by the "AndroidOpenSSL" |
// provider, which should be the default. That could happen if an OEM decided |
// to implement a different default provider. Also highly unlikely. |
Log.e(TAG, "Private key is not an OpenSSLRSAPrivateKey instance, its class name is:" + |
- privateKey.getClass().getCanonicalName()); |
+ javaKey.getClass().getCanonicalName()); |
return 0; |
} |
@@ -264,7 +302,7 @@ public class AndroidKeyStore { |
getKey.setAccessible(true); |
Object opensslKey = null; |
try { |
- opensslKey = getKey.invoke(privateKey); |
+ opensslKey = getKey.invoke(javaKey); |
} finally { |
getKey.setAccessible(false); |
} |