1 19 20 package com.sslexplorer.server.jetty; 21 22 import java.io.BufferedWriter ; 23 import java.io.File ; 24 import java.io.FileOutputStream ; 25 import java.io.IOException ; 26 import java.io.OutputStreamWriter ; 27 import java.net.ServerSocket ; 28 import java.security.KeyStore ; 29 import java.security.SecureRandom ; 30 31 import javax.net.ssl.KeyManager; 32 import javax.net.ssl.SSLContext; 33 import javax.net.ssl.SSLServerSocket; 34 import javax.net.ssl.SSLServerSocketFactory; 35 import javax.net.ssl.TrustManager; 36 import javax.net.ssl.TrustManagerFactory; 37 38 import org.apache.commons.logging.Log; 39 import org.apache.commons.logging.LogFactory; 40 import org.mortbay.http.JsseListener; 41 import org.mortbay.util.InetAddrPort; 42 43 import com.sslexplorer.boot.ContextHolder; 44 import com.sslexplorer.boot.ContextKey; 45 import com.sslexplorer.boot.KeyStoreManager; 46 import com.sslexplorer.boot.PropertyList; 47 import com.sslexplorer.server.CustomKeyManager; 48 49 50 57 public class CustomJsseListener extends JsseListener { 58 private String keyPassword; 59 private TrustManager trustManager; 60 private boolean initialised; 61 private boolean require = false; 62 private boolean configureContext = true; 63 private static boolean createAvailableCipherSuitesList = true; 64 final static Log log = LogFactory.getLog(CustomJsseListener.class); 65 66 71 public CustomJsseListener(String keyPassword) { 72 super(); 73 init(keyPassword); 74 } 75 76 82 public CustomJsseListener(InetAddrPort address, String keyPassword) { 83 super(address); 84 init(keyPassword); 85 } 86 87 private void init(String keyPassword) { 88 this.keyPassword = keyPassword; 89 } 90 91 100 public void setTrustManager(TrustManager trustManager, boolean require) { 101 if(initialised) { 102 throw new IllegalStateException ("Socket factory already created. Cannot set trust manager."); 103 } 104 this.trustManager = trustManager; 105 this.require = require; 106 107 } 108 109 protected ServerSocket newServerSocket( InetAddrPort p_address, 110 int p_acceptQueueSize ) 111 throws IOException 112 { 113 SSLServerSocket serverSocket = (SSLServerSocket)super.newServerSocket(p_address, p_acceptQueueSize); 114 if(serverSocket.getNeedClientAuth()) { 115 116 serverSocket.setNeedClientAuth(require); 117 setNeedClientAuth(require); 118 if(!require) 119 serverSocket.setWantClientAuth(true); 120 } 121 122 123 String [] ciphers = serverSocket.getSupportedCipherSuites(); 124 String [] protocols = serverSocket.getSupportedProtocols(); 125 126 if(log.isInfoEnabled()) { 127 log.info("The following protocols are supported:"); 128 for(int i=0;i<protocols.length;i++) { 129 log.info(" " + protocols[i]); 130 } 131 } 132 133 if(createAvailableCipherSuitesList) { 134 File f = new File (ContextHolder.getContext().getTempDirectory(), "availableCipherSuites.txt"); 135 BufferedWriter writer = null; 136 137 try { 138 writer = new BufferedWriter (new OutputStreamWriter (new FileOutputStream (f))); 139 if(log.isInfoEnabled()) 140 log.info("The following cipher suites are supported:"); 141 for(int i=0;i<ciphers.length;i++) { 142 if(log.isInfoEnabled()) 143 log.info(" " + ciphers[i]); 144 writer.write(ciphers[i]); 145 writer.newLine(); 146 } 147 } catch (Throwable e) { 148 log.error("Could not create cipher list!", e); 149 configureContext = false; 150 } finally { 151 if(writer!=null) 152 writer.close(); 153 } 154 createAvailableCipherSuitesList = false; 155 } 156 157 if(configureContext) { 158 159 PropertyList list = ContextHolder.getContext().getConfig().retrievePropertyList(new ContextKey("ssl.supportedProtocols")); 160 161 if(!list.isEmpty()) { 162 serverSocket.setEnabledProtocols(list.asArray()); 163 } 164 165 list = ContextHolder.getContext().getConfig().retrievePropertyList(new ContextKey("ssl.supportedCiphers")); 166 167 if(!list.isEmpty()) { 168 serverSocket.setEnabledCipherSuites(list.asArray()); 169 } 170 } 171 172 protocols = serverSocket.getEnabledProtocols(); 173 174 if(log.isInfoEnabled()) { 175 log.info("The following protocols are enabled:"); 176 for(int i=0;i<protocols.length;i++) { 177 log.info(" " + protocols[i]); 178 } 179 } 180 181 182 ciphers = serverSocket.getEnabledCipherSuites(); 183 if(log.isInfoEnabled()) { 184 log.info("The following cipher suites are enabled:"); 185 for(int i=0;i<ciphers.length;i++) { 186 log.info(" " + ciphers[i]); 187 } 188 } 189 190 return serverSocket; 191 } 192 193 protected SSLServerSocketFactory createFactory() throws Exception { 194 if(KeyStoreManager.getInstance(KeyStoreManager.DEFAULT_KEY_STORE).isKeyStoreEmpty()) { 195 throw new Exception ("The keystore does not contain any certificates. Please run the SSL-Explorer installation wizard (--install)."); 196 } 197 KeyStore ks = KeyStoreManager.getInstance(KeyStoreManager.DEFAULT_KEY_STORE).getKeyStore(); 198 String pw = ContextHolder.getContext().getConfig().retrieveProperty(new ContextKey("webServer.keystore.sslCertificate.password")); 199 KeyManager[] kma = new KeyManager[] { new CustomKeyManager(pw) }; 200 TrustManager[] tma = null; 201 if(trustManager == null) { 202 TrustManagerFactory tm = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 203 tm.init(ks); 204 tma = tm.getTrustManagers(); 205 } 206 else { 207 208 TrustManagerFactory tm = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 210 tm.init(ks); 211 212 tma = new TrustManager[tm.getTrustManagers().length + 1]; 213 for(int i=0;i<tm.getTrustManagers().length-1;i++) { 214 tma[i] = tm.getTrustManagers()[i]; 215 } 216 tma[tma.length-1] = trustManager; 217 } 218 SSLContext sslc = SSLContext.getInstance("SSL"); 219 sslc.init(kma, tma, SecureRandom.getInstance("SHA1PRNG")); 220 SSLServerSocketFactory ssfc = sslc.getServerSocketFactory(); 221 if (log.isInfoEnabled()) 222 log.info("SSLServerSocketFactory=" + ssfc); 223 initialised = true; 224 return ssfc; 225 } 226 227 public boolean isConfigureContext() { 228 return configureContext; 229 } 230 231 public void setConfigureContext(boolean configureContext) { 232 this.configureContext = configureContext; 233 } 234 235 } 236 | Popular Tags |