X509Util.java revision 5821806d5e7f356e8fa4b058a389a808ea183019
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 3// found in the LICENSE file. 4 5package org.chromium.net; 6 7import android.util.Log; 8 9import java.io.ByteArrayInputStream; 10import java.security.KeyStore; 11import java.security.KeyStoreException; 12import java.security.NoSuchAlgorithmException; 13import java.security.cert.CertificateException; 14import java.security.cert.CertificateFactory; 15import java.security.cert.X509Certificate; 16 17import javax.net.ssl.TrustManager; 18import javax.net.ssl.TrustManagerFactory; 19import javax.net.ssl.X509TrustManager; 20 21public class X509Util { 22 23 private static final String TAG = X509Util.class.getName(); 24 25 private static CertificateFactory sCertificateFactory; 26 27 /** 28 * Default sources of authentication trust decisions and certificate object 29 * creation. 30 */ 31 private static X509TrustManager sDefaultTrustManager; 32 33 /** 34 * Ensures that |sCertificateFactory| and |sDefaultTrustManager| are 35 * initialized. 36 */ 37 private static synchronized void ensureInitialized() throws CertificateException, 38 KeyStoreException, NoSuchAlgorithmException { 39 if (sCertificateFactory == null) { 40 sCertificateFactory = CertificateFactory.getInstance("X.509"); 41 } 42 if (sDefaultTrustManager == null) { 43 sDefaultTrustManager = X509Util.createDefaultTrustManager(); 44 } 45 } 46 47 /** 48 * Creates a TrustManagerFactory and returns the X509TrustManager instance 49 * if one can be found. 50 * 51 * @throws CertificateException,KeyStoreException,NoSuchAlgorithmException 52 * on error initializing the TrustManager. 53 */ 54 private static X509TrustManager createDefaultTrustManager() 55 throws KeyStoreException, NoSuchAlgorithmException { 56 String algorithm = TrustManagerFactory.getDefaultAlgorithm(); 57 TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); 58 tmf.init((KeyStore) null); 59 60 for (TrustManager tm : tmf.getTrustManagers()) { 61 if (tm instanceof X509TrustManager) { 62 return (X509TrustManager) tm; 63 } 64 } 65 return null; 66 } 67 68 /** 69 * Convert a DER encoded certificate to an X509Certificate 70 */ 71 public static X509Certificate createCertificateFromBytes(byte[] derBytes) throws 72 CertificateException, KeyStoreException, NoSuchAlgorithmException { 73 ensureInitialized(); 74 return (X509Certificate) sCertificateFactory.generateCertificate( 75 new ByteArrayInputStream(derBytes)); 76 } 77 78 public static boolean verifyServerCertificates(byte[][] certChain, String authType) 79 throws CertificateException, KeyStoreException, NoSuchAlgorithmException { 80 if (certChain == null || certChain.length == 0 || certChain[0] == null) { 81 throw new IllegalArgumentException("Expected non-null and non-empty certificate " + 82 "chain passed as |certChain|. |certChain|=" + certChain); 83 } 84 85 ensureInitialized(); 86 X509Certificate[] serverCertificates = new X509Certificate[certChain.length]; 87 for (int i = 0; i < certChain.length; ++i) { 88 serverCertificates[i] = createCertificateFromBytes(certChain[i]); 89 } 90 91 try { 92 sDefaultTrustManager.checkServerTrusted(serverCertificates, authType); 93 return true; 94 } catch (CertificateException e) { 95 Log.i(TAG, "failed to validate the certificate chain, error: " + 96 e.getMessage()); 97 } 98 return false; 99 } 100 101} 102