package com.example.client.ssl; import android.util.Base64; import com.example.ExampleConfig; import java.io.UnsupportedEncodingException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; // useful articles about trusting SSL certificates: // http://blog.crazybob.org/2010/02/android-trusting-ssl-certificates.html // http://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https/6378872#6378872 // http://nelenkov.blogspot.cz/2011/12/using-custom-certificate-trust-store-on.html public class CertificateAuthorityTrustManager implements X509TrustManager { private X509TrustManager mDefaultTrustManager = null; public CertificateAuthorityTrustManager() throws NoSuchAlgorithmException, KeyStoreException { super(); // init factory TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); KeyStore keyStore = null; trustManagerFactory.init(keyStore); // create default trust manager checking certificates signed with certificate authority TrustManager[] trustManagers = trustManagerFactory.getTrustManagers(); if(trustManagers.length == 0) { throw new NoSuchAlgorithmException("No trust manager found."); } mDefaultTrustManager = (X509TrustManager) trustManagers[0]; } @Override public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException { // check client certificate //Logcat.d(""); mDefaultTrustManager.checkClientTrusted(certificates, authType); } @Override public void checkServerTrusted(X509Certificate[] certificates, String authType) throws CertificateException { boolean expectedCertificateFound = false; // manually verify certificate comparing encoded representation of the certificate for(X509Certificate certificate : certificates) { try { String certHash = SHA1Base64Encoded(certificate.getEncoded()); //Logcat.d("certificate public key = " + certificate.getPublicKey().toString().substring(0, 100) + " ..."); //Logcat.d("certificate hash = " + certHash); //Logcat.d("---------------------------------------"); if(certHash.trim().equals(ExampleConfig.SSL_CERTIFICATE_SHA1)) { // manual verification successfull expectedCertificateFound = true; } } catch(Exception e) { // manual verification failed throw new CertificateException("Failed to compare hashes of certificates."); } } if(!expectedCertificateFound) { // if manual verification failed, throw exception throw new CertificateException("Expected certificate not found."); } // if manual verification successfull, check server certificate //Logcat.d(""); mDefaultTrustManager.checkServerTrusted(certificates, authType); } @Override public X509Certificate[] getAcceptedIssuers() { return mDefaultTrustManager.getAcceptedIssuers(); } private String SHA1Base64Encoded(byte[] data) throws NoSuchAlgorithmException, UnsupportedEncodingException { MessageDigest md = MessageDigest.getInstance("SHA-1"); md.reset(); md.update(data); byte messageDigest[] = md.digest(); return Base64.encodeToString(messageDigest, Base64.NO_WRAP); } }