From 3af8e9389e008c0076b86cc6b3c6f005e7473d10 Mon Sep 17 00:00:00 2001 From: Grace Kloba Date: Fri, 19 Jun 2009 15:03:46 -0700 Subject: [PATCH] Change addCertificate to take byte[] instead of String as we don't know the encoding. In WebView, if we run into the certificate, we will save it to the Keystore instead of sending it to the WebKit. --- .../java/android/webkit/ByteArrayBuilder.java | 15 ++++++++ core/java/android/webkit/LoadListener.java | 36 +++++++++++++++++-- core/res/res/values/strings.xml | 2 ++ keystore/java/android/security/Keystore.java | 4 +-- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/core/java/android/webkit/ByteArrayBuilder.java b/core/java/android/webkit/ByteArrayBuilder.java index 806b458fa8c09..145411cf7a6a6 100644 --- a/core/java/android/webkit/ByteArrayBuilder.java +++ b/core/java/android/webkit/ByteArrayBuilder.java @@ -17,6 +17,7 @@ package android.webkit; import java.util.LinkedList; +import java.util.ListIterator; /** Utility class optimized for accumulating bytes, and then spitting them back out. It does not optimize for returning the result in a @@ -94,6 +95,20 @@ class ByteArrayBuilder { return mChunks.isEmpty(); } + public int size() { + return mChunks.size(); + } + + public int getByteSize() { + int total = 0; + ListIterator it = mChunks.listIterator(0); + while (it.hasNext()) { + Chunk c = it.next(); + total += c.mLength; + } + return total; + } + public synchronized void clear() { Chunk c = getFirstChunk(); while (c != null) { diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index d583eb18a0435..07e03ff8dcfae 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -25,16 +25,16 @@ import android.net.http.HttpAuthHeader; import android.net.http.RequestHandle; import android.net.http.SslCertificate; import android.net.http.SslError; -import android.net.http.SslCertificate; import android.os.Handler; import android.os.Message; +import android.security.Keystore; import android.util.Log; import android.webkit.CacheManager.CacheResult; +import android.widget.Toast; import com.android.internal.R; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; @@ -72,6 +72,8 @@ class LoadListener extends Handler implements EventHandler { private static final int HTTP_NOT_FOUND = 404; private static final int HTTP_PROXY_AUTH = 407; + private static final String CERT_MIMETYPE = "application/x-x509-ca-cert"; + private static int sNativeLoaderCount; private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder(8192); @@ -934,6 +936,12 @@ class LoadListener extends Handler implements EventHandler { // This commits the headers without checking the response status code. private void commitHeaders() { + if (mIsMainPageLoader && CERT_MIMETYPE.equals(mMimeType)) { + // In the case of downloading certificate, we will save it to the + // Keystore in commitLoad. Do not call webcore. + return; + } + // Commit the headers to WebCore int nativeResponse = createNativeResponse(); // The native code deletes the native response object. @@ -974,6 +982,30 @@ class LoadListener extends Handler implements EventHandler { private void commitLoad() { if (mCancelled) return; + if (mIsMainPageLoader && CERT_MIMETYPE.equals(mMimeType)) { + // In the case of downloading certificate, we will save it to the + // Keystore and stop the current loading so that it will not + // generate a new history page + byte[] cert = new byte[mDataBuilder.getByteSize()]; + int position = 0; + ByteArrayBuilder.Chunk c; + while (true) { + c = mDataBuilder.getFirstChunk(); + if (c == null) break; + + if (c.mLength != 0) { + System.arraycopy(c.mArray, 0, cert, position, c.mLength); + position += c.mLength; + } + mDataBuilder.releaseChunk(c); + } + Keystore.getInstance().addCertificate(cert); + Toast.makeText(mContext, R.string.certificateSaved, + Toast.LENGTH_SHORT).show(); + mBrowserFrame.stopLoading(); + return; + } + // Give the data to WebKit now PerfChecker checker = new PerfChecker(); ByteArrayBuilder.Chunk c; diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index bdfccd6b6f3ee..72bdc3a6dfe41 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -228,6 +228,8 @@ The requested file was not found. Too many requests are being processed. Try again later. + + The certificate is saved in the system\'s key store. diff --git a/keystore/java/android/security/Keystore.java b/keystore/java/android/security/Keystore.java index ce3fa88642904..2a3e6a7c0a212 100644 --- a/keystore/java/android/security/Keystore.java +++ b/keystore/java/android/security/Keystore.java @@ -88,7 +88,7 @@ public abstract class Keystore { public abstract String generateKeyPair( int keyStrengthIndex, String challenge, String organizations); - public abstract void addCertificate(String cert); + public abstract void addCertificate(byte[] cert); private static class FileKeystore extends Keystore { private static final String SERVICE_NAME = "keystore"; @@ -217,7 +217,7 @@ public abstract class Keystore { } @Override - public void addCertificate(String cert) { + public void addCertificate(byte[] cert) { // TODO: real implementation }