From 275fce8a2ca45e640abf451552dd1bdbbc0cb54c Mon Sep 17 00:00:00 2001 From: Selim Gurun Date: Fri, 4 May 2012 13:36:50 -0700 Subject: [PATCH] Use private key context when necessary Bug: 6249185 Due to recent changes to keystore, we cannot rely on encoded key format anymore. Rather we receive the key context (a pointer to private key really) and pass it to native openssl. We also keep the original logic however. Change-Id: Iefe9f0336dd5f47eec4222fcb6fec58807e7cac0 --- core/java/android/webkit/BrowserFrame.java | 27 ++++++++-- .../webkit/ClientCertRequestHandler.java | 51 ++++++++++++++----- .../webkit/SslClientCertLookupTable.java | 9 ++-- 3 files changed, 66 insertions(+), 21 deletions(-) diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index c169de4cd69aa..fe812af3f4516 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -56,6 +56,8 @@ import java.util.Map; import java.util.Set; import org.apache.harmony.security.provider.cert.X509CertImpl; +import org.apache.harmony.xnet.provider.jsse.OpenSSLDSAPrivateKey; +import org.apache.harmony.xnet.provider.jsse.OpenSSLRSAPrivateKey; class BrowserFrame extends Handler { @@ -1104,12 +1106,23 @@ class BrowserFrame extends Handler { SslClientCertLookupTable table = SslClientCertLookupTable.getInstance(); if (table.IsAllowed(hostAndPort)) { // previously allowed - nativeSslClientCert(handle, - table.PrivateKey(hostAndPort), - table.CertificateChain(hostAndPort)); + PrivateKey pkey = table.PrivateKey(hostAndPort); + if (pkey instanceof OpenSSLRSAPrivateKey) { + nativeSslClientCert(handle, + ((OpenSSLRSAPrivateKey)pkey).getPkeyContext(), + table.CertificateChain(hostAndPort)); + } else if (pkey instanceof OpenSSLDSAPrivateKey) { + nativeSslClientCert(handle, + ((OpenSSLDSAPrivateKey)pkey).getPkeyContext(), + table.CertificateChain(hostAndPort)); + } else { + nativeSslClientCert(handle, + pkey.getEncoded(), + table.CertificateChain(hostAndPort)); + } } else if (table.IsDenied(hostAndPort)) { // previously denied - nativeSslClientCert(handle, null, null); + nativeSslClientCert(handle, 0, null); } else { // previously ignored or new mCallbackProxy.onReceivedClientCertRequest( @@ -1296,7 +1309,11 @@ class BrowserFrame extends Handler { private native void nativeSslCertErrorCancel(int handle, int certError); native void nativeSslClientCert(int handle, - byte[] pkcs8EncodedPrivateKey, + int ctx, + byte[][] asn1DerEncodedCertificateChain); + + native void nativeSslClientCert(int handle, + byte[] pkey, byte[][] asn1DerEncodedCertificateChain); /** diff --git a/core/java/android/webkit/ClientCertRequestHandler.java b/core/java/android/webkit/ClientCertRequestHandler.java index f86261305559e..6570a9b8ad4ca 100644 --- a/core/java/android/webkit/ClientCertRequestHandler.java +++ b/core/java/android/webkit/ClientCertRequestHandler.java @@ -21,6 +21,8 @@ import java.security.PrivateKey; import java.security.cert.CertificateEncodingException; import java.security.cert.X509Certificate; import org.apache.harmony.xnet.provider.jsse.NativeCrypto; +import org.apache.harmony.xnet.provider.jsse.OpenSSLDSAPrivateKey; +import org.apache.harmony.xnet.provider.jsse.OpenSSLRSAPrivateKey; /** * ClientCertRequestHandler: class responsible for handling client @@ -50,33 +52,58 @@ public final class ClientCertRequestHandler extends Handler { * Proceed with the specified private key and client certificate chain. */ public void proceed(PrivateKey privateKey, X509Certificate[] chain) { - final byte[] privateKeyBytes = privateKey.getEncoded(); - final byte[][] chainBytes; try { - chainBytes = NativeCrypto.encodeCertificates(chain); - mTable.Allow(mHostAndPort, privateKeyBytes, chainBytes); - post(new Runnable() { - public void run() { - mBrowserFrame.nativeSslClientCert(mHandle, privateKeyBytes, chainBytes); - } - }); + byte[][] chainBytes = NativeCrypto.encodeCertificates(chain); + mTable.Allow(mHostAndPort, privateKey, chainBytes); + + if (privateKey instanceof OpenSSLRSAPrivateKey) { + setSslClientCertFromCtx(((OpenSSLRSAPrivateKey)privateKey).getPkeyContext(), + chainBytes); + } else if (privateKey instanceof OpenSSLDSAPrivateKey) { + setSslClientCertFromCtx(((OpenSSLDSAPrivateKey)privateKey).getPkeyContext(), + chainBytes); + } else { + setSslClientCertFromPKCS8(privateKey.getEncoded(),chainBytes); + } } catch (CertificateEncodingException e) { post(new Runnable() { public void run() { - mBrowserFrame.nativeSslClientCert(mHandle, null, null); + mBrowserFrame.nativeSslClientCert(mHandle, 0, null); return; } }); } } + /** + * Proceed with the specified private key bytes and client certificate chain. + */ + private void setSslClientCertFromCtx(final int ctx, final byte[][] chainBytes) { + post(new Runnable() { + public void run() { + mBrowserFrame.nativeSslClientCert(mHandle, ctx, chainBytes); + } + }); + } + + /** + * Proceed with the specified private key context and client certificate chain. + */ + private void setSslClientCertFromPKCS8(final byte[] key, final byte[][] chainBytes) { + post(new Runnable() { + public void run() { + mBrowserFrame.nativeSslClientCert(mHandle, key, chainBytes); + } + }); + } + /** * Igore the request for now, the user may be prompted again. */ public void ignore() { post(new Runnable() { public void run() { - mBrowserFrame.nativeSslClientCert(mHandle, null, null); + mBrowserFrame.nativeSslClientCert(mHandle, 0, null); } }); } @@ -88,7 +115,7 @@ public final class ClientCertRequestHandler extends Handler { mTable.Deny(mHostAndPort); post(new Runnable() { public void run() { - mBrowserFrame.nativeSslClientCert(mHandle, null, null); + mBrowserFrame.nativeSslClientCert(mHandle, 0, null); } }); } diff --git a/core/java/android/webkit/SslClientCertLookupTable.java b/core/java/android/webkit/SslClientCertLookupTable.java index 630debd9cace3..c52b7e867bc94 100644 --- a/core/java/android/webkit/SslClientCertLookupTable.java +++ b/core/java/android/webkit/SslClientCertLookupTable.java @@ -16,6 +16,7 @@ package android.webkit; +import java.security.PrivateKey; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -26,7 +27,7 @@ import java.util.Set; */ final class SslClientCertLookupTable { private static SslClientCertLookupTable sTable; - private final Map privateKeys; + private final Map privateKeys; private final Map certificateChains; private final Set denied; @@ -38,12 +39,12 @@ final class SslClientCertLookupTable { } private SslClientCertLookupTable() { - privateKeys = new HashMap(); + privateKeys = new HashMap(); certificateChains = new HashMap(); denied = new HashSet(); } - public void Allow(String host_and_port, byte[] privateKey, byte[][] chain) { + public void Allow(String host_and_port, PrivateKey privateKey, byte[][] chain) { privateKeys.put(host_and_port, privateKey); certificateChains.put(host_and_port, chain); denied.remove(host_and_port); @@ -63,7 +64,7 @@ final class SslClientCertLookupTable { return denied.contains(host_and_port); } - public byte[] PrivateKey(String host_and_port) { + public PrivateKey PrivateKey(String host_and_port) { return privateKeys.get(host_and_port); }