/* * Gets the SSL server's keystore password. */ protected String getKeystorePassword() { String keystorePass = endpoint.getKeystorePass(); if (keystorePass == null) { keystorePass = endpoint.getKeyPass(); } if (keystorePass == null) { keystorePass = DEFAULT_KEY_PASS; } return keystorePass; }
@Override public KeyManager[] getKeyManagers() throws Exception { String keystoreType = endpoint.getKeystoreType(); if (keystoreType == null) { keystoreType = defaultKeystoreType; } String algorithm = endpoint.getAlgorithm(); if (algorithm == null) { algorithm = KeyManagerFactory.getDefaultAlgorithm(); } return getKeyManagers( keystoreType, endpoint.getKeystoreProvider(), algorithm, endpoint.getKeyAlias()); }
/* * Gets the SSL server's keystore. */ protected KeyStore getKeystore(String type, String provider, String pass) throws IOException { String keystoreFile = endpoint.getKeystoreFile(); if (keystoreFile == null) keystoreFile = defaultKeystoreFile; return getStore(type, provider, keystoreFile, pass); }
/** Gets the initialized key managers. */ protected KeyManager[] getKeyManagers( String keystoreType, String keystoreProvider, String algorithm, String keyAlias) throws Exception { KeyManager[] kms = null; String keystorePass = getKeystorePassword(); KeyStore ks = getKeystore(keystoreType, keystoreProvider, keystorePass); if (keyAlias != null && !ks.isKeyEntry(keyAlias)) { throw new IOException(sm.getString("jsse.alias_no_key_entry", keyAlias)); } KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); String keyPass = endpoint.getKeyPass(); if (keyPass == null) { keyPass = keystorePass; } kmf.init(ks, keyPass.toCharArray()); kms = kmf.getKeyManagers(); if (keyAlias != null) { String alias = keyAlias; if (JSSESocketFactory.defaultKeystoreType.equals(keystoreType)) { alias = alias.toLowerCase(Locale.ENGLISH); } for (int i = 0; i < kms.length; i++) { kms[i] = new JSSEKeyManager((X509KeyManager) kms[i], alias); } } return kms; }
/** * Return the initialization parameters for the TrustManager. Currently, only the default <code> * PKIX</code> is supported. * * @param algorithm The algorithm to get parameters for. * @param crlf The path to the CRL file. * @param trustStore The configured TrustStore. * @return The parameters including the CRLs and TrustStore. */ protected CertPathParameters getParameters(String algorithm, String crlf, KeyStore trustStore) throws Exception { CertPathParameters params = null; if ("PKIX".equalsIgnoreCase(algorithm)) { PKIXBuilderParameters xparams = new PKIXBuilderParameters(trustStore, new X509CertSelector()); Collection<? extends CRL> crls = getCRLs(crlf); CertStoreParameters csp = new CollectionCertStoreParameters(crls); CertStore store = CertStore.getInstance("Collection", csp); xparams.addCertStore(store); xparams.setRevocationEnabled(true); String trustLength = endpoint.getTrustMaxCertLength(); if (trustLength != null) { try { xparams.setMaxPathLength(Integer.parseInt(trustLength)); } catch (Exception ex) { log.warn("Bad maxCertLength: " + trustLength); } } params = xparams; } else { throw new CRLException("CRLs not supported for type: " + algorithm); } return params; }
@Override public String[] getEnableableProtocols(SSLContext context) { String[] requestedProtocols = endpoint.getSslEnabledProtocolsArray(); if ((requestedProtocols == null) || (requestedProtocols.length == 0)) { return defaultServerProtocols; } List<String> protocols = new ArrayList<String>(Arrays.asList(requestedProtocols)); protocols.retainAll(Arrays.asList(context.getSupportedSSLParameters().getProtocols())); if (protocols.isEmpty()) { log.warn( sm.getString( "jsse.requested_protocols_not_supported", Arrays.asList(requestedProtocols))); } if (log.isDebugEnabled()) { log.debug(sm.getString("jsse.enableable_protocols", protocols)); if (protocols.size() != requestedProtocols.length) { List<String> skipped = new ArrayList<String>(Arrays.asList(requestedProtocols)); skipped.removeAll(protocols); log.debug(sm.getString("jsse.unsupported_protocols", skipped)); } } return protocols.toArray(new String[protocols.size()]); }
@Override public void configureSessionContext(SSLSessionContext sslSessionContext) { int sessionCacheSize; if (endpoint.getSessionCacheSize() != null) { sessionCacheSize = Integer.parseInt(endpoint.getSessionCacheSize()); } else { sessionCacheSize = defaultSessionCacheSize; } int sessionTimeout; if (endpoint.getSessionTimeout() != null) { sessionTimeout = Integer.parseInt(endpoint.getSessionTimeout()); } else { sessionTimeout = defaultSessionTimeout; } sslSessionContext.setSessionCacheSize(sessionCacheSize); sslSessionContext.setSessionTimeout(sessionTimeout); }
@Override public void stop() throws Exception { if (getLog().isInfoEnabled()) getLog().info(sm.getString("abstractProtocolHandler.stop", getName())); try { endpoint.stop(); } catch (Exception ex) { getLog().error(sm.getString("abstractProtocolHandler.stopError", getName()), ex); throw ex; } }
@Override public TrustManager[] getTrustManagers() throws Exception { String truststoreType = endpoint.getTruststoreType(); if (truststoreType == null) { truststoreType = System.getProperty("javax.net.ssl.trustStoreType"); } if (truststoreType == null) { truststoreType = endpoint.getKeystoreType(); } if (truststoreType == null) { truststoreType = defaultKeystoreType; } String algorithm = endpoint.getTruststoreAlgorithm(); if (algorithm == null) { algorithm = TrustManagerFactory.getDefaultAlgorithm(); } return getTrustManagers(truststoreType, endpoint.getKeystoreProvider(), algorithm); }
/** * Configures SSLEngine to honor cipher suites ordering based upon endpoint configuration. * * @throws InvalidAlgorithmParameterException If the runtime JVM doesn't support this setting. */ protected void configureUseServerCipherSuitesOrder(SSLServerSocket socket) { String useServerCipherSuitesOrderStr = endpoint.getUseServerCipherSuitesOrder().trim(); // Only use this feature if the user explicitly requested its use. if (!"".equals(useServerCipherSuitesOrderStr)) { boolean useServerCipherSuitesOrder = ("true".equalsIgnoreCase(useServerCipherSuitesOrderStr) || "yes".equalsIgnoreCase(useServerCipherSuitesOrderStr)); JreCompat jreCompat = JreCompat.getInstance(); jreCompat.setUseServerCipherSuitesOrder(socket, useServerCipherSuitesOrder); } }
@Override public SSLContext createSSLContext() throws Exception { // SSL protocol variant (e.g., TLS, SSL v3, etc.) String protocol = endpoint.getSslProtocol(); if (protocol == null) { protocol = defaultProtocol; } SSLContext context = SSLContext.getInstance(protocol); return context; }
@Override public void init() throws Exception { if (getLog().isInfoEnabled()) getLog().info(sm.getString("abstractProtocolHandler.init", getName())); if (oname == null) { // Component not pre-registered so register it oname = createObjectName(); if (oname != null) { Registry.getRegistry(null, null).registerComponent(this, oname, null); } } if (this.domain != null) { try { tpOname = new ObjectName(domain + ":" + "type=ThreadPool,name=" + getName()); Registry.getRegistry(null, null).registerComponent(endpoint, tpOname, null); } catch (Exception e) { getLog() .error( sm.getString("abstractProtocolHandler.mbeanRegistrationFailed", tpOname, getName()), e); } rgOname = new ObjectName(domain + ":type=GlobalRequestProcessor,name=" + getName()); Registry.getRegistry(null, null).registerComponent(getHandler().getGlobal(), rgOname, null); } String endpointName = getName(); endpoint.setName(endpointName.substring(1, endpointName.length() - 1)); try { endpoint.init(); } catch (Exception ex) { getLog().error(sm.getString("abstractProtocolHandler.initError", getName()), ex); throw ex; } }
/** Reads the keystore and initializes the SSL socket factory. */ void init() throws IOException { try { String clientAuthStr = endpoint.getClientAuth(); if ("true".equalsIgnoreCase(clientAuthStr) || "yes".equalsIgnoreCase(clientAuthStr)) { requireClientAuth = true; } else if ("want".equalsIgnoreCase(clientAuthStr)) { wantClientAuth = true; } SSLContext context = createSSLContext(); context.init(getKeyManagers(), getTrustManagers(), null); // Configure SSL session cache SSLSessionContext sessionContext = context.getServerSessionContext(); if (sessionContext != null) { configureSessionContext(sessionContext); } // create proxy sslProxy = context.getServerSocketFactory(); // Determine which cipher suites to enable enabledCiphers = getEnableableCiphers(context); enabledProtocols = getEnableableProtocols(context); allowUnsafeLegacyRenegotiation = "true".equals(endpoint.getAllowUnsafeLegacyRenegotiation()); // Check the SSL config is OK checkConfig(); } catch (Exception e) { if (e instanceof IOException) throw (IOException) e; throw new IOException(e.getMessage(), e); } }
/** Gets the initialized trust managers. */ protected TrustManager[] getTrustManagers( String keystoreType, String keystoreProvider, String algorithm) throws Exception { String crlf = endpoint.getCrlFile(); String className = endpoint.getTrustManagerClassName(); if (className != null && className.length() > 0) { ClassLoader classLoader = getClass().getClassLoader(); Class<?> clazz = classLoader.loadClass(className); if (!(TrustManager.class.isAssignableFrom(clazz))) { throw new InstantiationException( sm.getString("jsse.invalidTrustManagerClassName", className)); } Object trustManagerObject = clazz.newInstance(); TrustManager trustManager = (TrustManager) trustManagerObject; return new TrustManager[] {trustManager}; } TrustManager[] tms = null; KeyStore trustStore = getTrustStore(keystoreType, keystoreProvider); if (trustStore != null || endpoint.getTrustManagerClassName() != null) { if (crlf == null) { TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); tmf.init(trustStore); tms = tmf.getTrustManagers(); } else { TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); CertPathParameters params = getParameters(algorithm, crlf, trustStore); ManagerFactoryParameters mfp = new CertPathTrustManagerParameters(params); tmf.init(mfp); tms = tmf.getTrustManagers(); } } return tms; }
@Override public void destroy() { if (getLog().isInfoEnabled()) { getLog().info(sm.getString("abstractProtocolHandler.destroy", getName())); } try { endpoint.destroy(); } catch (Exception e) { getLog().error(sm.getString("abstractProtocolHandler.destroyError", getName()), e); } if (oname != null) { Registry.getRegistry(null, null).unregisterComponent(oname); } if (tpOname != null) Registry.getRegistry(null, null).unregisterComponent(tpOname); if (rgOname != null) Registry.getRegistry(null, null).unregisterComponent(rgOname); }
@Override public String[] getEnableableCiphers(SSLContext context) { String requestedCiphersStr = endpoint.getCiphers(); if (ALLOW_ALL_SUPPORTED_CIPHERS.equals(requestedCiphersStr)) { return context.getSupportedSSLParameters().getCipherSuites(); } if ((requestedCiphersStr == null) || (requestedCiphersStr.trim().length() == 0)) { return defaultServerCipherSuites; } List<String> requestedCiphers = new ArrayList<String>(); for (String rc : requestedCiphersStr.split(",")) { final String cipher = rc.trim(); if (cipher.length() > 0) { requestedCiphers.add(cipher); } } if (requestedCiphers.isEmpty()) { return defaultServerCipherSuites; } List<String> ciphers = new ArrayList<String>(requestedCiphers); ciphers.retainAll(Arrays.asList(context.getSupportedSSLParameters().getCipherSuites())); if (ciphers.isEmpty()) { log.warn(sm.getString("jsse.requested_ciphers_not_supported", requestedCiphersStr)); } if (log.isDebugEnabled()) { log.debug(sm.getString("jsse.enableable_ciphers", ciphers)); if (ciphers.size() != requestedCiphers.size()) { List<String> skipped = new ArrayList<String>(requestedCiphers); skipped.removeAll(ciphers); log.debug(sm.getString("jsse.unsupported_ciphers", skipped)); } } return ciphers.toArray(new String[ciphers.size()]); }
public JSSESocketFactory(AbstractEndpoint<?> endpoint) { this.endpoint = endpoint; String sslProtocol = endpoint.getSslProtocol(); if (sslProtocol == null) { sslProtocol = defaultProtocol; } SSLContext context; try { context = SSLContext.getInstance(sslProtocol); context.init(null, null, null); } catch (NoSuchAlgorithmException e) { // This is fatal for the connector so throw an exception to prevent // it from starting throw new IllegalArgumentException(e); } catch (KeyManagementException e) { // This is fatal for the connector so throw an exception to prevent // it from starting throw new IllegalArgumentException(e); } // Supported cipher suites aren't accessible directly from the // SSLContext so use the SSL server socket factory SSLServerSocketFactory ssf = context.getServerSocketFactory(); String supportedCiphers[] = ssf.getSupportedCipherSuites(); boolean found = false; for (String cipher : supportedCiphers) { if ("TLS_EMPTY_RENEGOTIATION_INFO_SCSV".equals(cipher)) { found = true; break; } } rfc5746Supported = found; // There is no standard way to determine the default protocols and // cipher suites so create a server socket to see what the defaults are SSLServerSocket socket; try { socket = (SSLServerSocket) ssf.createServerSocket(); } catch (IOException e) { // This is very likely to be fatal but there is a slim chance that // the JSSE implementation just doesn't like creating unbound // sockets so allow the code to proceed. defaultServerCipherSuites = new String[0]; defaultServerProtocols = new String[0]; log.warn(sm.getString("jsse.noDefaultCiphers", endpoint.getName())); log.warn(sm.getString("jsse.noDefaultProtocols", endpoint.getName())); return; } try { defaultServerCipherSuites = socket.getEnabledCipherSuites(); if (defaultServerCipherSuites.length == 0) { log.warn(sm.getString("jsse.noDefaultCiphers", endpoint.getName())); } // Filter out all the SSL protocols (SSLv2 and SSLv3) from the defaults // since they are no longer considered secure List<String> filteredProtocols = new ArrayList<String>(); for (String protocol : socket.getEnabledProtocols()) { if (protocol.toUpperCase(Locale.ENGLISH).contains("SSL")) { log.debug(sm.getString("jsse.excludeDefaultProtocol", protocol)); continue; } filteredProtocols.add(protocol); } defaultServerProtocols = filteredProtocols.toArray(new String[filteredProtocols.size()]); if (defaultServerProtocols.length == 0) { log.warn(sm.getString("jsse.noDefaultProtocols", endpoint.getName())); } } finally { try { socket.close(); } catch (IOException e) { log.warn(sm.getString("jsse.exceptionOnClose"), e); } } }
public int getLocalPort() { return endpoint.getLocalPort(); }
public void setPort(int port) { endpoint.setPort(port); }
public void setConnectionTimeout(int timeout) { // Note that the endpoint uses the alternative name endpoint.setSoTimeout(timeout); }
/* * When Tomcat expects data from the client, this is the time Tomcat will * wait for that data to arrive before closing the connection. */ public int getConnectionTimeout() { // Note that the endpoint uses the alternative name return endpoint.getSoTimeout(); }
public void setMaxHeaderCount(int maxHeaderCount) { endpoint.setMaxHeaderCount(maxHeaderCount); }
public int getMaxHeaderCount() { return endpoint.getMaxHeaderCount(); }
public long getConnectionCount() { return endpoint.getConnectionCount(); }
/** * Generic property setter used by the digester. Other code should not need to use this. The * digester will only use this method if it can't find a more specific setter. That means the * property belongs to the Endpoint, the ServerSocketFactory or some other lower level component. * This method ensures that it is visible to both. */ public boolean setProperty(String name, String value) { return endpoint.setProperty(name, value); }
/* * Gets the SSL server's truststore. */ protected KeyStore getTrustStore(String keystoreType, String keystoreProvider) throws IOException { KeyStore trustStore = null; String truststoreFile = endpoint.getTruststoreFile(); if (truststoreFile == null) { truststoreFile = System.getProperty("javax.net.ssl.trustStore"); } if (log.isDebugEnabled()) { log.debug("Truststore = " + truststoreFile); } String truststorePassword = endpoint.getTruststorePass(); if (truststorePassword == null) { truststorePassword = System.getProperty("javax.net.ssl.trustStorePassword"); } if (log.isDebugEnabled()) { log.debug("TrustPass = "******"javax.net.ssl.trustStoreType"); } if (truststoreType == null) { truststoreType = keystoreType; } if (log.isDebugEnabled()) { log.debug("trustType = " + truststoreType); } String truststoreProvider = endpoint.getTruststoreProvider(); if (truststoreProvider == null) { truststoreProvider = System.getProperty("javax.net.ssl.trustStoreProvider"); } if (truststoreProvider == null) { truststoreProvider = keystoreProvider; } if (log.isDebugEnabled()) { log.debug("trustProvider = " + truststoreProvider); } if (truststoreFile != null) { try { trustStore = getStore(truststoreType, truststoreProvider, truststoreFile, truststorePassword); } catch (IOException ioe) { Throwable cause = ioe.getCause(); if (cause instanceof UnrecoverableKeyException) { // Log a warning we had a password issue log.warn(sm.getString("jsse.invalid_truststore_password"), cause); // Re-try trustStore = getStore(truststoreType, truststoreProvider, truststoreFile, null); } else { // Something else went wrong - re-throw throw ioe; } } } return trustStore; }
/** Generic property getter used by the digester. Other code should not need to use this. */ public String getProperty(String name) { return endpoint.getProperty(name); }
public int getPort() { return endpoint.getPort(); }
/** Obtain the Executor used by the underlying endpoint. */ @Override public Executor getExecutor() { return endpoint.getExecutor(); }
public void setAddress(InetAddress ia) { endpoint.setAddress(ia); }