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

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: remove an obsolete findbugs suppression 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.
36 */ 35 */
37 private static synchronized void ensureInitialized() throws CertificateExcep tion, 36 private static X509TrustManager sLocalTrustManager;
37 private static KeyStore sLocalKeyStore;
38
39 /**
40 * The trust manager used to make trust decisions. If |sLocalKeyStore| is no nempty, this is
41 * |sLocalTrustManager|, otherwise this is |sDefaultTrustManager|.
42 */
43 private static X509TrustManager sTrustManager;
Ryan Sleevi 2012/12/03 02:29:03 Note: On all other platforms, TestRootCerts is add
digit1 2012/12/03 13:44:13 Ah, my bad, I was the one advising ppi to implemen
44
45 /**
46 * Lock used to synchronize all calls that initialize or modify the trust ma nagers or
47 * certificate factory.
48 */
49 private static final Object sLock = new Object();
50
51 /**
52 * Ensures that the trust managers and certificate factory are initialized.
53 */
54 private static void ensureInitialized() throws CertificateException,
38 KeyStoreException, NoSuchAlgorithmException { 55 KeyStoreException, NoSuchAlgorithmException {
39 if (sCertificateFactory == null) { 56 synchronized(sLock) {
40 sCertificateFactory = CertificateFactory.getInstance("X.509"); 57 if (sCertificateFactory == null) {
41 } 58 sCertificateFactory = CertificateFactory.getInstance("X.509");
42 if (sDefaultTrustManager == null) { 59 }
43 sDefaultTrustManager = X509Util.createDefaultTrustManager(); 60 if (sDefaultTrustManager == null) {
61 sDefaultTrustManager = X509Util.createTrustManager(null);
62 }
63 if (sLocalKeyStore == null) {
64 sLocalKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()) ;
65 try {
66 sLocalKeyStore.load(null);
67 } catch(IOException e) {} // No IO operation is attempted.
68 }
69 if (sLocalTrustManager == null) {
70 sLocalTrustManager = X509Util.createTrustManager(sLocalKeyStore) ;
71 }
72 sTrustManager = sLocalKeyStore.size() > 0 ? sLocalTrustManager : sDe faultTrustManager;
44 } 73 }
45 } 74 }
46 75
47 /** 76 /**
48 * Creates a TrustManagerFactory and returns the X509TrustManager instance 77 * Creates a X509TrustManager backed up by the given key store. When null is passed as a key
49 * if one can be found. 78 * store, system default trust store is used.
50 * 79 * @throws KeyStoreException, NoSuchAlgorithmException on error initializing the TrustManager.
51 * @throws CertificateException,KeyStoreException,NoSuchAlgorithmException
52 * on error initializing the TrustManager.
53 */ 80 */
54 private static X509TrustManager createDefaultTrustManager() 81 private static X509TrustManager createTrustManager(KeyStore keyStore) throws KeyStoreException,
55 throws KeyStoreException, NoSuchAlgorithmException { 82 NoSuchAlgorithmException {
56 String algorithm = TrustManagerFactory.getDefaultAlgorithm(); 83 String algorithm = TrustManagerFactory.getDefaultAlgorithm();
57 TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); 84 TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
58 tmf.init((KeyStore) null); 85 tmf.init(keyStore);
59 86
60 for (TrustManager tm : tmf.getTrustManagers()) { 87 for (TrustManager tm : tmf.getTrustManagers()) {
61 if (tm instanceof X509TrustManager) { 88 if (tm instanceof X509TrustManager) {
62 return (X509TrustManager) tm; 89 return (X509TrustManager) tm;
63 } 90 }
64 } 91 }
65 return null; 92 return null;
66 } 93 }
67 94
68 /** 95 /**
69 * Convert a DER encoded certificate to an X509Certificate 96 * Convert a DER encoded certificate to an X509Certificate.
70 */ 97 */
71 public static X509Certificate createCertificateFromBytes(byte[] derBytes) th rows 98 public static X509Certificate createCertificateFromBytes(byte[] derBytes) th rows
72 CertificateException, KeyStoreException, NoSuchAlgorithmException { 99 CertificateException, KeyStoreException, NoSuchAlgorithmException {
73 ensureInitialized(); 100 ensureInitialized();
74 return (X509Certificate) sCertificateFactory.generateCertificate( 101 return (X509Certificate) sCertificateFactory.generateCertificate(
75 new ByteArrayInputStream(derBytes)); 102 new ByteArrayInputStream(derBytes));
76 } 103 }
77 104
105 public static void addTestRootCertificate(byte[] rootCertBytes) throws Certi ficateException,
106 KeyStoreException, NoSuchAlgorithmException {
107 ensureInitialized();
108 X509Certificate rootCert = createCertificateFromBytes(rootCertBytes);
109 synchronized(sLock) {
110 sLocalKeyStore.setCertificateEntry(
111 "root_cert_" + Integer.toString(sLocalKeyStore.size()), root Cert);
112
113 sTrustManager = sLocalTrustManager;
114 }
115 }
116
117 public static void clearTestRootCertificates() throws NoSuchAlgorithmExcepti on,
118 CertificateException, KeyStoreException {
119 ensureInitialized();
120 synchronized(sLock) {
121 try {
122 sLocalKeyStore.load(null);
123 } catch(IOException e) {} // No IO operation is attempted.
124
125 sTrustManager = sDefaultTrustManager;
126 }
127 }
128
78 public static boolean verifyServerCertificates(byte[][] certChain, String au thType) 129 public static boolean verifyServerCertificates(byte[][] certChain, String au thType)
79 throws CertificateException, KeyStoreException, NoSuchAlgorithmExcep tion { 130 throws CertificateException, KeyStoreException, NoSuchAlgorithmExcep tion {
80 if (certChain == null || certChain.length == 0 || certChain[0] == null) { 131 if (certChain == null || certChain.length == 0 || certChain[0] == null) {
81 throw new IllegalArgumentException("Expected non-null and non-empty certificate " + 132 throw new IllegalArgumentException("Expected non-null and non-empty certificate " +
82 "chain passed as |certChain|. |certChain|=" + certChain); 133 "chain passed as |certChain|. |certChain|=" + certChain);
83 } 134 }
84 135
85 ensureInitialized(); 136 ensureInitialized();
86 X509Certificate[] serverCertificates = new X509Certificate[certChain.len gth]; 137 X509Certificate[] serverCertificates = new X509Certificate[certChain.len gth];
87 for (int i = 0; i < certChain.length; ++i) { 138 for (int i = 0; i < certChain.length; ++i) {
88 serverCertificates[i] = createCertificateFromBytes(certChain[i]); 139 serverCertificates[i] = createCertificateFromBytes(certChain[i]);
89 } 140 }
90 141
91 try { 142 try {
92 sDefaultTrustManager.checkServerTrusted(serverCertificates, authType ); 143 synchronized (sLock) {
144 sTrustManager.checkServerTrusted(serverCertificates, authType);
145 }
93 return true; 146 return true;
94 } catch (CertificateException e) { 147 } catch (CertificateException e) {
95 Log.i(TAG, "failed to validate the certificate chain, error: " + 148 Log.i(TAG, "failed to validate the certificate chain, error: " + e.g etMessage());
96 e.getMessage());
97 } 149 }
98 return false; 150 return false;
99 } 151 }
100 152 }
101 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698