Merge "Use private key context when necessary" into jb-dev

This commit is contained in:
Selim Gurun
2012-05-07 10:54:24 -07:00
committed by Android (Google) Code Review
3 changed files with 66 additions and 21 deletions

View File

@@ -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);
/**

View File

@@ -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);
}
});
}

View File

@@ -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<String, byte[]> privateKeys;
private final Map<String, PrivateKey> privateKeys;
private final Map<String, byte[][]> certificateChains;
private final Set<String> denied;
@@ -38,12 +39,12 @@ final class SslClientCertLookupTable {
}
private SslClientCertLookupTable() {
privateKeys = new HashMap<String, byte[]>();
privateKeys = new HashMap<String, PrivateKey>();
certificateChains = new HashMap<String, byte[][]>();
denied = new HashSet<String>();
}
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);
}