| package org.wordpress.android.networking; |
| |
| import java.io.IOException; |
| import java.security.GeneralSecurityException; |
| import java.security.KeyStore; |
| import java.security.cert.CertificateException; |
| import java.security.cert.X509Certificate; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| |
| import javax.net.ssl.TrustManager; |
| import javax.net.ssl.TrustManagerFactory; |
| import javax.net.ssl.X509TrustManager; |
| |
| import org.wordpress.android.util.AppLog; |
| import org.wordpress.android.util.AppLog.T; |
| |
| public class WPTrustManager implements X509TrustManager { |
| private X509TrustManager defaultTrustManager; |
| private X509TrustManager localTrustManager; |
| private X509Certificate[] acceptedIssuers; |
| |
| public WPTrustManager(KeyStore localKeyStore) { |
| try { |
| TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
| tmf.init((KeyStore) null); |
| |
| defaultTrustManager = findX509TrustManager(tmf); |
| if (defaultTrustManager == null) { |
| throw new IllegalStateException("Couldn't find X509TrustManager"); |
| } |
| |
| localTrustManager = new LocalStoreX509TrustManager(localKeyStore); |
| |
| List<X509Certificate> allIssuers = new ArrayList<X509Certificate>(); |
| Collections.addAll(allIssuers, defaultTrustManager.getAcceptedIssuers()); |
| Collections.addAll(allIssuers, localTrustManager.getAcceptedIssuers()); |
| acceptedIssuers = allIssuers.toArray(new X509Certificate[allIssuers.size()]); |
| } catch (GeneralSecurityException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| |
| private static X509TrustManager findX509TrustManager(TrustManagerFactory tmf) { |
| TrustManager tms[] = tmf.getTrustManagers(); |
| for (int i = 0; i < tms.length; i++) { |
| if (tms[i] instanceof X509TrustManager) { |
| return (X509TrustManager) tms[i]; |
| } |
| } |
| return null; |
| } |
| |
| |
| public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { |
| try { |
| defaultTrustManager.checkClientTrusted(chain, authType); |
| } catch (CertificateException ce) { |
| localTrustManager.checkClientTrusted(chain, authType); |
| } |
| } |
| |
| public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { |
| try { |
| defaultTrustManager.checkServerTrusted(chain, authType); |
| } catch (CertificateException ce) { |
| localTrustManager.checkServerTrusted(chain, authType); |
| } |
| } |
| |
| public X509Certificate[] getAcceptedIssuers() { |
| return acceptedIssuers; |
| } |
| |
| static class LocalStoreX509TrustManager implements X509TrustManager { |
| private X509TrustManager trustManager; |
| |
| LocalStoreX509TrustManager(KeyStore localKeyStore) { |
| try { |
| TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); |
| tmf.init(localKeyStore); |
| |
| trustManager = findX509TrustManager(tmf); |
| if (trustManager == null) { |
| throw new IllegalStateException("Couldn't find X509TrustManager"); |
| } |
| } catch (GeneralSecurityException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| @Override |
| public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { |
| trustManager.checkClientTrusted(chain, authType); |
| } |
| |
| @Override |
| public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { |
| try { |
| trustManager.checkServerTrusted(chain, authType); |
| } catch (CertificateException e) { |
| AppLog.e(T.API, "Cannot trust the certificate with the local trust manager...", e); |
| try { |
| SelfSignedSSLCertsManager.getInstance(null).setLastFailureChain(chain); |
| } catch (GeneralSecurityException e1) { |
| } catch (IOException e1) { |
| } |
| throw e; |
| } |
| } |
| |
| @Override |
| public X509Certificate[] getAcceptedIssuers() { |
| return trustManager.getAcceptedIssuers(); |
| } |
| } |
| } |