/* * This file is part of the OWASP Proxy, a free intercepting proxy library. * Copyright (C) 2008-2010 Rogan Dawes <rogan@dawes.za.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to: * The Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ package org.owasp.proxy.ssl; import java.net.InetSocketAddress; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; public class DefaultClientContextSelector implements SSLContextSelector { private X509TrustManager trustManager; private Map<String, SSLContext> contextMap = new LinkedHashMap<String, SSLContext>(); public DefaultClientContextSelector() { initTrustManager(); } public SSLContext select(InetSocketAddress target) { String host = target.getHostName(); SSLContext context = contextMap.get(host); if (context != null) return context; try { context = SSLContext.getInstance("SSL"); context.init(null, new TrustManager[] { getTrustManager() }, new SecureRandom()); contextMap.put(host, context); } catch (NoSuchAlgorithmException e) { // should never happen e.printStackTrace(); } catch (KeyManagementException e) { // should never happen e.printStackTrace(); } return context; } public void setTrustManager(X509TrustManager trustManager) { this.trustManager = trustManager; } private void initTrustManager() { try { TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); tmf.init((KeyStore) null); TrustManager[] managers = tmf.getTrustManagers(); X509TrustManager manager = null; for (int i = 0; i < managers.length; i++) { if (managers[i] instanceof X509TrustManager) { manager = new LoggingTrustManager( (X509TrustManager) managers[i]); break; } } if (manager == null) { manager = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] certs, String authType) { } public void checkServerTrusted(X509Certificate[] certs, String authType) { } }; } trustManager = manager; } catch (NoSuchAlgorithmException nsae) { nsae.printStackTrace(); } catch (KeyStoreException kse) { kse.printStackTrace(); } } public X509TrustManager getTrustManager() { return trustManager; } private static class LoggingTrustManager implements X509TrustManager { private X509TrustManager trustManager; private HashMap<X509Certificate, X509Certificate[]> trusted, untrusted; public LoggingTrustManager(X509TrustManager trustManager) { this.trustManager = trustManager; trusted = new HashMap<X509Certificate, X509Certificate[]>(); untrusted = new HashMap<X509Certificate, X509Certificate[]>(); } public X509Certificate[] getAcceptedIssuers() { return trustManager.getAcceptedIssuers(); } public void checkClientTrusted(X509Certificate[] certs, String authType) { if (trusted.containsKey(certs[0]) || untrusted.containsKey(certs[0])) return; String dn = certs[0].getSubjectX500Principal().getName(); try { trustManager.checkClientTrusted(certs, authType); trusted.put(certs[0], certs); } catch (CertificateException ce) { untrusted.put(certs[0], certs); System.err.printf("Untrusted client certificate for %s", dn); } } public void checkServerTrusted(X509Certificate[] certs, String authType) { if (trusted.containsKey(certs[0]) || untrusted.containsKey(certs[0])) return; String dn = certs[0].getSubjectX500Principal().getName(); try { trustManager.checkClientTrusted(certs, authType); trusted.put(certs[0], certs); } catch (CertificateException ce) { untrusted.put(certs[0], certs); System.err.printf("Untrusted server certificate for %s", dn); } } } }