diff options
author | Huahui Wu <hwu@google.com> | 2011-01-26 22:11:02 -0800 |
---|---|---|
committer | Huahui Wu <hwu@google.com> | 2011-01-27 09:51:37 -0800 |
commit | c7939b1750ba98ab745110a138209d8b981fdc21 (patch) | |
tree | f2cfef72a8c0a20bdc040b8501a4ec556c050805 | |
parent | c291a7bf7a163cea10be135279103f72a6418383 (diff) | |
download | frameworks_base-c7939b1750ba98ab745110a138209d8b981fdc21.zip frameworks_base-c7939b1750ba98ab745110a138209d8b981fdc21.tar.gz frameworks_base-c7939b1750ba98ab745110a138209d8b981fdc21.tar.bz2 |
b/3347670 Support installing online certs to the system keystore.
Requires another CL in external/webkit.
https://android-git.corp.google.com/g/#change,93328
Change-Id: I33d642d370ddf330199f2b296d5f8b08923e49cd
-rw-r--r-- | core/java/android/webkit/BrowserFrame.java | 24 | ||||
-rw-r--r-- | core/java/android/webkit/CertTool.java | 13 | ||||
-rw-r--r-- | core/java/android/webkit/KeyStoreHandler.java | 77 | ||||
-rw-r--r-- | core/java/android/webkit/LoadListener.java | 12 |
4 files changed, 115 insertions, 11 deletions
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index ec3c329..b7ffd14 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -88,6 +88,9 @@ class BrowserFrame extends Handler { // Attached Javascript interfaces private Map<String, Object> mJSInterfaceMap; + // Key store handler when Chromium HTTP stack is used. + private KeyStoreHandler mKeyStoreHandler = null; + // message ids // a message posted when a frame loading is completed static final int FRAME_COMPLETED = 1001; @@ -1173,8 +1176,27 @@ class BrowserFrame extends Handler { } mimeType = MimeTypeMap.getSingleton().remapGenericMimeType( mimeType, url, contentDisposition); - mCallbackProxy.onDownloadStart(url, userAgent, + + if (CertTool.getCertType(mimeType) != null) { + mKeyStoreHandler = new KeyStoreHandler(mimeType); + } else { + mCallbackProxy.onDownloadStart(url, userAgent, contentDisposition, mimeType, contentLength); + } + } + + /** + * Called by JNI for Chrome HTTP stack when the Java side needs to access the data. + */ + private void didReceiveData(byte data[], int size) { + if (mKeyStoreHandler != null) mKeyStoreHandler.didReceiveData(data, size); + } + + private void didFinishLoading() { + if (mKeyStoreHandler != null) { + mKeyStoreHandler.installCert(mContext); + mKeyStoreHandler = null; + } } /** diff --git a/core/java/android/webkit/CertTool.java b/core/java/android/webkit/CertTool.java index d25d970..4c534f9 100644 --- a/core/java/android/webkit/CertTool.java +++ b/core/java/android/webkit/CertTool.java @@ -29,6 +29,7 @@ import android.util.Log; import java.security.KeyPair; import java.security.KeyPairGenerator; +import java.util.HashMap; class CertTool { private static final String LOGTAG = "CertTool"; @@ -39,6 +40,14 @@ class CertTool { static final String CERT = Credentials.CERTIFICATE; static final String PKCS12 = Credentials.PKCS12; + private static HashMap<String, String> sCertificateTypeMap; + static { + sCertificateTypeMap = new HashMap<String, String>(); + sCertificateTypeMap.put("application/x-x509-ca-cert", CertTool.CERT); + sCertificateTypeMap.put("application/x-x509-user-cert", CertTool.CERT); + sCertificateTypeMap.put("application/x-pkcs12", CertTool.PKCS12); + } + static String[] getKeyStrengthList() { return new String[] {"High Grade", "Medium Grade"}; } @@ -66,5 +75,9 @@ class CertTool { Credentials.getInstance().install(context, type, value); } + static String getCertType(String mimeType) { + return sCertificateTypeMap.get(mimeType); + } + private CertTool() {} } diff --git a/core/java/android/webkit/KeyStoreHandler.java b/core/java/android/webkit/KeyStoreHandler.java new file mode 100644 index 0000000..849007e --- /dev/null +++ b/core/java/android/webkit/KeyStoreHandler.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.webkit; + +import android.content.Context; +import android.os.Handler; +import android.util.Log; + +/** + * KeyStoreHandler: class responsible for certificate installation to + * the system key store. It reads the certificates file from network + * then pass the bytes to class CertTool. + * This class is only needed if the Chromium HTTP stack is used. + */ +class KeyStoreHandler extends Handler { + private static final String LOGTAG = "KeyStoreHandler"; + + private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder(); + + private String mMimeType; + + public KeyStoreHandler(String mimeType) { + mMimeType = mimeType; + } + + /** + * Add data to the internal collection of data. + * @param data A byte array containing the content. + * @param length The length of data. + */ + public void didReceiveData(byte[] data, int length) { + synchronized (mDataBuilder) { + mDataBuilder.append(data, 0, length); + } + } + + public void installCert(Context context) { + String type = CertTool.getCertType(mMimeType); + if (type == null) return; + + // This must be synchronized so that no more data can be added + // after getByteSize returns. + synchronized (mDataBuilder) { + // 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 offset = 0; + while (true) { + ByteArrayBuilder.Chunk c = mDataBuilder.getFirstChunk(); + if (c == null) break; + + if (c.mLength != 0) { + System.arraycopy(c.mArray, 0, cert, offset, c.mLength); + offset += c.mLength; + } + c.release(); + } + CertTool.addCertificate(context, type, cert); + return; + } + } +} diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java index 6d1d39a..04af738 100644 --- a/core/java/android/webkit/LoadListener.java +++ b/core/java/android/webkit/LoadListener.java @@ -75,14 +75,6 @@ class LoadListener extends Handler implements EventHandler { private static final int HTTP_NOT_FOUND = 404; private static final int HTTP_PROXY_AUTH = 407; - private static HashMap<String, String> sCertificateTypeMap; - static { - sCertificateTypeMap = new HashMap<String, String>(); - sCertificateTypeMap.put("application/x-x509-ca-cert", CertTool.CERT); - sCertificateTypeMap.put("application/x-x509-user-cert", CertTool.CERT); - sCertificateTypeMap.put("application/x-pkcs12", CertTool.PKCS12); - } - private static int sNativeLoaderCount; private final ByteArrayBuilder mDataBuilder = new ByteArrayBuilder(); @@ -1053,7 +1045,7 @@ class LoadListener extends Handler implements EventHandler { // This commits the headers without checking the response status code. private void commitHeaders() { - if (mIsMainPageLoader && sCertificateTypeMap.containsKey(mMimeType)) { + if (mIsMainPageLoader && CertTool.getCertType(mMimeType) != null) { // In the case of downloading certificate, we will save it to the // KeyStore in commitLoad. Do not call webcore. return; @@ -1114,7 +1106,7 @@ class LoadListener extends Handler implements EventHandler { } if (mIsMainPageLoader) { - String type = sCertificateTypeMap.get(mMimeType); + String type = CertTool.getCertType(mMimeType); if (type != null) { // This must be synchronized so that no more data can be added // after getByteSize returns. |