Index: net/android/java/org/chromium/net/AndroidNetworkLibrary.java |
diff --git a/net/android/java/org/chromium/net/AndroidNetworkLibrary.java b/net/android/java/org/chromium/net/AndroidNetworkLibrary.java |
new file mode 100644 |
index 0000000000000000000000000000000000000000..699a3a4ae058ec2b62c5bf98961a66cb3074eb69 |
--- /dev/null |
+++ b/net/android/java/org/chromium/net/AndroidNetworkLibrary.java |
@@ -0,0 +1,144 @@ |
+// Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+package org.chromium.net; |
+ |
+import android.content.ActivityNotFoundException; |
+import android.content.Context; |
+import android.content.Intent; |
+import android.util.Log; |
+ |
+import org.chromium.base.CalledByNative; |
+import org.chromium.base.CalledByNativeUnchecked; |
+ |
+import java.io.ByteArrayInputStream; |
+import java.net.URLConnection; |
+import java.security.KeyStore; |
+import java.security.KeyStoreException; |
+import java.security.NoSuchAlgorithmException; |
+import java.security.cert.CertificateException; |
+import java.security.cert.CertificateFactory; |
+import java.security.cert.X509Certificate; |
+import java.util.concurrent.atomic.AtomicReference; |
+ |
+import javax.net.ssl.TrustManager; |
+import javax.net.ssl.TrustManagerFactory; |
+import javax.net.ssl.X509TrustManager; |
+ |
+// This class implements net utilities required by the net component. |
+class AndroidNetworkLibrary { |
+ private static final String TAG = "AndroidNetworkLibrary"; |
+ |
+ // Stores the key pair into the CertInstaller application. |
+ @CalledByNative |
+ static public boolean storeKeyPair(Context context, byte[] public_key, byte[] private_key) { |
+ // This is based on android.security.Credentials.install() |
+ // TODO(joth): Use KeyChain API instead of hard-coding constants here: |
+ // http://crbug.com/124660 |
+ try { |
+ Intent intent = new Intent("android.credentials.INSTALL"); |
+ intent.setClassName("com.android.certinstaller", |
+ "com.android.certinstaller.CertInstallerMain"); |
+ intent.putExtra("KEY", private_key); |
+ intent.putExtra("PKEY", public_key); |
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
+ context.startActivity(intent); |
+ return true; |
+ } catch (ActivityNotFoundException e) { |
+ Log.w(TAG, "could not store certificate: " + e); |
+ } |
+ return false; |
+ } |
+ |
+ // Get the mime type (if any) that is associated with the file extension. |
+ // Returns null if no corresponding mime type exists. |
+ @CalledByNative |
+ static public String getMimeTypeFromExtension(String extension) { |
+ return URLConnection.guessContentTypeFromName("foo." + extension); |
+ } |
+ |
+ /** |
+ * Validate the server's certificate chain is trusted. |
+ * @param certChain The ASN.1 DER encoded bytes for certificates. |
+ * @param authType The key exchange algorithm name (e.g. RSA) |
+ * @return true if the server is trusted |
+ * @throws CertificateException,KeyStoreException,NoSuchAlgorithmException on error |
+ * initializing the TrustManager or reading the certChain |
+ */ |
+ @CalledByNativeUnchecked |
+ public static boolean verifyServerCertificates(byte[][] certChain, String authType) |
+ throws CertificateException, KeyStoreException, NoSuchAlgorithmException { |
+ if (certChain == null || certChain.length == 0 || certChain[0] == null) { |
+ throw new IllegalArgumentException("Expected non-null and non-empty certificate " + |
+ "chain passed as |certChain|. |certChain|=" + |
+ certChain); |
+ } |
+ |
+ ensureInitialized(); |
+ X509Certificate[] serverCertificates = new X509Certificate[certChain.length]; |
+ for (int i = 0; i < certChain.length; ++i) { |
+ serverCertificates[i] = |
+ (X509Certificate) sCertificateFactory.get().generateCertificate( |
+ new ByteArrayInputStream(certChain[i])); |
+ } |
+ |
+ try { |
+ sDefaultTrustManager.get().checkServerTrusted(serverCertificates, authType); |
+ return true; |
+ } catch (CertificateException e) { |
+ Log.i(TAG, "failed to validate the certificate chain, error: " + |
+ e.getMessage()); |
+ } |
+ return false; |
+ } |
+ |
+ // Default sources of authentication trust decisions and certificate object creation. |
+ private static AtomicReference<X509TrustManager> sDefaultTrustManager = |
+ new AtomicReference<X509TrustManager>(); |
+ private static AtomicReference<CertificateFactory> sCertificateFactory = |
+ new AtomicReference<CertificateFactory>(); |
+ |
+ /** |
+ * Ensures that |sDefaultTrustManager| and |sCertificateFactory| are initialized. |
+ * |
+ * @throws CertificateException,KeyStoreException,NoSuchAlgorithmException on error initializing |
+ * the TrustManager. |
+ */ |
+ private static void ensureInitialized() |
+ throws CertificateException, KeyStoreException, NoSuchAlgorithmException { |
+ // There could be a begin race creating two instances of these objects, which |
+ // is harmless save for a bit of wasted effort. |
+ if (sDefaultTrustManager.get() == null) { |
+ sDefaultTrustManager.compareAndSet(null, createDefaultTrustManager()); |
+ } |
+ if (sCertificateFactory.get() == null) { |
+ sCertificateFactory.compareAndSet(null, CertificateFactory.getInstance("X.509")); |
+ } |
+ } |
+ |
+ /* |
+ * Creates a TrustManagerFactory and returns the X509TrustManager instance if one can be found. |
+ * |
+ * @throws CertificateException,KeyStoreException,NoSuchAlgorithmException on error initializing |
+ * the TrustManager. |
+ */ |
+ private static X509TrustManager createDefaultTrustManager() |
+ throws KeyStoreException, NoSuchAlgorithmException { |
+ String algorithm = TrustManagerFactory.getDefaultAlgorithm(); |
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); |
+ tmf.init((KeyStore) null); |
+ TrustManager[] tms = tmf.getTrustManagers(); |
+ X509TrustManager trustManager = findX509TrustManager(tms); |
+ return trustManager; |
+ } |
+ |
+ private static X509TrustManager findX509TrustManager(TrustManager[] tms) { |
+ for (TrustManager tm : tms) { |
+ if (tm instanceof X509TrustManager) { |
+ return (X509TrustManager)tm; |
+ } |
+ } |
+ return null; |
+ } |
+} |