summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--android_webview/java/src/org/chromium/android_webview/AwTokenBindingManager.java51
-rw-r--r--android_webview/native/token_binding_manager_bridge.cc27
2 files changed, 71 insertions, 7 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwTokenBindingManager.java b/android_webview/java/src/org/chromium/android_webview/AwTokenBindingManager.java
index 3f2f695..a622781 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwTokenBindingManager.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwTokenBindingManager.java
@@ -7,11 +7,27 @@ package org.chromium.android_webview;
import android.net.Uri;
import android.webkit.ValueCallback;
+import org.chromium.base.Log;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.JNINamespace;
+import java.io.IOException;
+import java.security.InvalidAlgorithmParameterException;
+import java.security.InvalidKeyException;
+import java.security.Key;
+import java.security.KeyFactory;
import java.security.KeyPair;
-import java.security.spec.AlgorithmParameterSpec;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.X509EncodedKeySpec;
+
+import javax.crypto.Cipher;
+import javax.crypto.EncryptedPrivateKeyInfo;
+import javax.crypto.NoSuchPaddingException;
+import javax.crypto.SecretKeyFactory;
+import javax.crypto.spec.PBEKeySpec;
/**
* AwTokenBindingManager manages the token binding protocol.
@@ -25,11 +41,16 @@ import java.security.spec.AlgorithmParameterSpec;
*/
@JNINamespace("android_webview")
public final class AwTokenBindingManager {
+ private static final String TAG = "TokenBindingManager";
+ private static final String PASSWORD = "";
+ private static final String ALGORITHM = "PBEWITHSHAAND3-KEYTRIPLEDES-CBC";
+ private static final String ELLIPTIC_CURVE = "EC";
+
public void enableTokenBinding() {
nativeEnableTokenBinding();
}
- public void getKey(Uri origin, AlgorithmParameterSpec[] spec, ValueCallback<KeyPair> callback) {
+ public void getKey(Uri origin, String[] spec, ValueCallback<KeyPair> callback) {
if (callback == null) {
throw new IllegalArgumentException("callback can't be null");
}
@@ -50,8 +71,30 @@ public final class AwTokenBindingManager {
}
@CalledByNative
- private static void onKeyReady(ValueCallback<KeyPair> callback) {
- callback.onReceiveValue(null);
+ private static void onKeyReady(
+ ValueCallback<KeyPair> callback, byte[] privateKeyBytes, byte[] publicKeyBytes) {
+ if (privateKeyBytes == null || publicKeyBytes == null) {
+ callback.onReceiveValue(null);
+ return;
+ }
+ KeyPair keyPair = null;
+ try {
+ EncryptedPrivateKeyInfo epkInfo = new EncryptedPrivateKeyInfo(privateKeyBytes);
+ SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(ALGORITHM);
+ Key key = secretKeyFactory.generateSecret(new PBEKeySpec(PASSWORD.toCharArray()));
+ Cipher cipher = Cipher.getInstance(ALGORITHM);
+ cipher.init(Cipher.DECRYPT_MODE, key, epkInfo.getAlgParameters());
+ KeyFactory factory = KeyFactory.getInstance(ELLIPTIC_CURVE);
+ PrivateKey privateKey = factory.generatePrivate(epkInfo.getKeySpec(cipher));
+ PublicKey publicKey =
+ factory.generatePublic(new X509EncodedKeySpec(publicKeyBytes));
+ keyPair = new KeyPair(publicKey, privateKey);
+ } catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException
+ | NoSuchPaddingException | InvalidKeyException
+ | InvalidAlgorithmParameterException ex) {
+ Log.e(TAG, "Failed converting key ", ex);
+ }
+ callback.onReceiveValue(keyPair);
}
@CalledByNative
diff --git a/android_webview/native/token_binding_manager_bridge.cc b/android_webview/native/token_binding_manager_bridge.cc
index 07c690f..cf959f5 100644
--- a/android_webview/native/token_binding_manager_bridge.cc
+++ b/android_webview/native/token_binding_manager_bridge.cc
@@ -6,15 +6,19 @@
#include "android_webview/browser/net/token_binding_manager.h"
#include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/bind.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/ec_private_key.h"
#include "jni/AwTokenBindingManager_jni.h"
+#include "net/base/net_errors.h"
+#include "net/ssl/channel_id_service.h"
using base::android::ConvertJavaStringToUTF8;
using base::android::ScopedJavaGlobalRef;
using content::BrowserThread;
+using net::ChannelIDService;
namespace android_webview {
@@ -26,10 +30,27 @@ void OnKeyReady(const ScopedJavaGlobalRef<jobject>& callback,
crypto::ECPrivateKey* key) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
- // TODO(sgurun) implement conversion and plumbing the keypair to java.
-
JNIEnv* env = base::android::AttachCurrentThread();
- Java_AwTokenBindingManager_onKeyReady(env, callback.obj());
+
+ if (status != net::OK || !key) {
+ Java_AwTokenBindingManager_onKeyReady(env, callback.obj(), nullptr,
+ nullptr);
+ return;
+ }
+
+ std::vector<uint8_t> private_key;
+ key->ExportEncryptedPrivateKey(ChannelIDService::kEPKIPassword, 1,
+ &private_key);
+ ScopedJavaLocalRef<jbyteArray> jprivate_key = base::android::ToJavaByteArray(
+ env, private_key.data(), private_key.size());
+
+ std::vector<uint8_t> public_key;
+ key->ExportPublicKey(&public_key);
+ ScopedJavaLocalRef<jbyteArray> jpublic_key = base::android::ToJavaByteArray(
+ env, public_key.data(), public_key.size());
+
+ Java_AwTokenBindingManager_onKeyReady(env, callback.obj(), jprivate_key.obj(),
+ jpublic_key.obj());
}
// Indicates webview client that key deletion is complete.