Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(200)

Side by Side Diff: net/android/java/src/org/chromium/net/X509Util.java

Issue 11316210: Implement TestRootCerts for Android (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.net; 5 package org.chromium.net;
6 6
7 import android.util.Log; 7 import android.util.Log;
8 8
9 import java.io.ByteArrayInputStream; 9 import java.io.ByteArrayInputStream;
10 import java.io.IOException;
10 import java.security.KeyStore; 11 import java.security.KeyStore;
11 import java.security.KeyStoreException; 12 import java.security.KeyStoreException;
12 import java.security.NoSuchAlgorithmException; 13 import java.security.NoSuchAlgorithmException;
13 import java.security.cert.CertificateException; 14 import java.security.cert.CertificateException;
14 import java.security.cert.CertificateFactory; 15 import java.security.cert.CertificateFactory;
15 import java.security.cert.X509Certificate; 16 import java.security.cert.X509Certificate;
16 17
17 import javax.net.ssl.TrustManager; 18 import javax.net.ssl.TrustManager;
18 import javax.net.ssl.TrustManagerFactory; 19 import javax.net.ssl.TrustManagerFactory;
19 import javax.net.ssl.X509TrustManager; 20 import javax.net.ssl.X509TrustManager;
20 21
21 public class X509Util { 22 public class X509Util {
22 23
23 private static final String TAG = X509Util.class.getName(); 24 private static final String TAG = X509Util.class.getName();
24 25
25 private static CertificateFactory sCertificateFactory; 26 private static CertificateFactory sCertificateFactory;
26 27
27 /** 28 /**
28 * Default sources of authentication trust decisions and certificate object 29 * Trust manager backed up by the read-only system certificate store.
29 * creation.
30 */ 30 */
31 private static X509TrustManager sDefaultTrustManager; 31 private static X509TrustManager sDefaultTrustManager;
32 32
33 /** 33 /**
34 * Ensures that |sCertificateFactory| and |sDefaultTrustManager| are 34 * Trust manager backed up by a custom certificate store.
35 * initialized. 35 */
36 private static X509TrustManager sLocalTrustManager;
37 private static KeyStore sLocalKeyStore;
38
39 /**
40 * Ensures that the trust managers and certificate factory are initialized.
36 */ 41 */
37 private static synchronized void ensureInitialized() throws CertificateExcep tion, 42 private static synchronized void ensureInitialized() throws CertificateExcep tion,
38 KeyStoreException, NoSuchAlgorithmException { 43 KeyStoreException, NoSuchAlgorithmException {
39 if (sCertificateFactory == null) { 44 if (sCertificateFactory == null) {
40 sCertificateFactory = CertificateFactory.getInstance("X.509"); 45 sCertificateFactory = CertificateFactory.getInstance("X.509");
41 } 46 }
42 if (sDefaultTrustManager == null) { 47 if (sDefaultTrustManager == null) {
43 sDefaultTrustManager = X509Util.createDefaultTrustManager(); 48 sDefaultTrustManager = X509Util.createTrustManager(null);
49 }
50 if (sLocalKeyStore == null) {
51 sLocalKeyStore = KeyStore.getInstance(KeyStore.getDefaultType());
52 try {
53 sLocalKeyStore.load(null);
54 } catch(IOException e) {} // No IO operation is attempted.
55 }
56 if (sLocalTrustManager == null) {
57 sLocalTrustManager = X509Util.createTrustManager(sLocalKeyStore);
44 } 58 }
45 } 59 }
46 60
47 /** 61 /**
48 * Creates a TrustManagerFactory and returns the X509TrustManager instance 62 * Creates a X509TrustManager backed up by the given key store. When null
49 * if one can be found. 63 * is passed as a key store, system default trust store is used.
50 * 64 * @throws KeyStoreException, NoSuchAlgorithmException on error
51 * @throws CertificateException,KeyStoreException,NoSuchAlgorithmException 65 * initializing the TrustManager.
52 * on error initializing the TrustManager.
53 */ 66 */
54 private static X509TrustManager createDefaultTrustManager() 67 private static X509TrustManager createTrustManager(KeyStore keyStore)
55 throws KeyStoreException, NoSuchAlgorithmException { 68 throws KeyStoreException, NoSuchAlgorithmException {
56 String algorithm = TrustManagerFactory.getDefaultAlgorithm(); 69 String algorithm = TrustManagerFactory.getDefaultAlgorithm();
57 TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); 70 TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
58 tmf.init((KeyStore) null); 71 tmf.init(keyStore);
59 72
60 for (TrustManager tm : tmf.getTrustManagers()) { 73 for (TrustManager tm : tmf.getTrustManagers()) {
61 if (tm instanceof X509TrustManager) { 74 if (tm instanceof X509TrustManager) {
62 return (X509TrustManager) tm; 75 return (X509TrustManager) tm;
63 } 76 }
64 } 77 }
65 return null; 78 return null;
66 } 79 }
67 80
68 /** 81 /**
69 * Convert a DER encoded certificate to an X509Certificate 82 * Convert a DER encoded certificate to an X509Certificate.
70 */ 83 */
71 public static X509Certificate createCertificateFromBytes(byte[] derBytes) th rows 84 public static X509Certificate createCertificateFromBytes(byte[] derBytes) th rows
72 CertificateException, KeyStoreException, NoSuchAlgorithmException { 85 CertificateException, KeyStoreException, NoSuchAlgorithmException {
73 ensureInitialized(); 86 ensureInitialized();
74 return (X509Certificate) sCertificateFactory.generateCertificate( 87 return (X509Certificate) sCertificateFactory.generateCertificate(
75 new ByteArrayInputStream(derBytes)); 88 new ByteArrayInputStream(derBytes));
76 } 89 }
77 90
91 public static void addLocalRootCertificate(byte[] rootCertBytes)
92 throws CertificateException, KeyStoreException,
93 NoSuchAlgorithmException {
94 ensureInitialized();
95 X509Certificate rootCert = createCertificateFromBytes(rootCertBytes);
96 sLocalKeyStore.setCertificateEntry(
97 "root_cert_" + Integer.toString(sLocalKeyStore.size()),
98 rootCert);
99 }
100
101 public static void clearLocalRootCertificates()
102 throws NoSuchAlgorithmException, CertificateException, KeyStoreExcep tion {
103 ensureInitialized();
104 try {
105 sLocalKeyStore.load(null);
106 } catch(IOException e) {} // No IO operation is attempted.
107
108 }
109
78 public static boolean verifyServerCertificates(byte[][] certChain, String au thType) 110 public static boolean verifyServerCertificates(byte[][] certChain, String au thType)
79 throws CertificateException, KeyStoreException, NoSuchAlgorithmExcep tion { 111 throws CertificateException, KeyStoreException, NoSuchAlgorithmExcep tion {
80 if (certChain == null || certChain.length == 0 || certChain[0] == null) { 112 if (certChain == null || certChain.length == 0 || certChain[0] == null) {
81 throw new IllegalArgumentException("Expected non-null and non-empty certificate " + 113 throw new IllegalArgumentException("Expected non-null and non-empty certificate " +
82 "chain passed as |certChain|. |certChain|=" + certChain); 114 "chain passed as |certChain|. |certChain|=" + certChain);
83 } 115 }
84 116
85 ensureInitialized(); 117 ensureInitialized();
86 X509Certificate[] serverCertificates = new X509Certificate[certChain.len gth]; 118 X509Certificate[] serverCertificates = new X509Certificate[certChain.len gth];
87 for (int i = 0; i < certChain.length; ++i) { 119 for (int i = 0; i < certChain.length; ++i) {
88 serverCertificates[i] = createCertificateFromBytes(certChain[i]); 120 serverCertificates[i] = createCertificateFromBytes(certChain[i]);
89 } 121 }
90 122
91 try { 123 try {
92 sDefaultTrustManager.checkServerTrusted(serverCertificates, authType ); 124 sDefaultTrustManager.checkServerTrusted(serverCertificates, authType );
93 return true; 125 return true;
94 } catch (CertificateException e) { 126 } catch (CertificateException e) {
95 Log.i(TAG, "failed to validate the certificate chain, error: " + 127 try {
digit1 2012/11/28 10:42:34 I think it'd be preferable to separate the usage o
ppi 2012/11/28 13:37:31 Sounds right, thanks. In patch set 2 I use additi
96 e.getMessage()); 128 sLocalTrustManager.checkServerTrusted(serverCertificates, authTy pe);
129 return true;
130 }
131 catch (CertificateException eInner) {
132 Log.i(TAG, "failed to validate the certificate chain, error: " +
133 eInner.getMessage());
digit1 2012/11/28 10:42:34 Doesn't this lose the exception message from the d
ppi 2012/11/28 13:37:31 Thanks, n/a in patch set 2. On 2012/11/28 10:42:3
134 }
97 } 135 }
98 return false; 136 return false;
99 } 137 }
100 138
101 } 139 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698