Created SslParameters class and converted connectors to use it
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/sandbox/trunk@2746 7e9141cc-0065-0410-87d8-b60c137991c4
diff --git a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslConnector.java b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslConnector.java
index e601aed..f4f5bf8 100644
--- a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslConnector.java
+++ b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslConnector.java
@@ -305,13 +305,13 @@
/**
* @return true if SSL certificate has to be validated
*/
- public abstract boolean getValidateCert();
+ public abstract boolean getValidateCerts();
/* ------------------------------------------------------------ */
/**
* @param validateServerCert true if SSL certificate has to be validated
*/
- public abstract void setValidateCert(boolean validateCert);
+ public abstract void setValidateCerts(boolean validateCert);
/* ------------------------------------------------------------ */
/**
diff --git a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslSelectChannelConnector.java b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslSelectChannelConnector.java
index 1d893d8..556323d 100644
--- a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslSelectChannelConnector.java
+++ b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslSelectChannelConnector.java
@@ -80,62 +80,6 @@
*/
public class EnhancedSslSelectChannelConnector extends SelectChannelConnector implements EnhancedSslConnector
{
- /** Excluded cipher suites. */
- private String _excludeCipherSuites[]=null;
- /** Included cipher suites. */
- private String _includeCipherSuites[]=null;
-
- /** KeyStore path. */
- private String _keystorePath=DEFAULT_KEYSTORE;
- /** KeyStore provider name */
- private String _keystoreProvider;
- /** KeyStore type */
- private String _keystoreType="JKS";
- /** SSL certificate alias */
- private String _certAlias;
-
- /** TrustStore path */
- private String _truststorePath;
- /** TrustStore provider name */
- private String _truststoreProvider;
- /** TrustStore type */
- private String _truststoreType="JKS";
-
- /** Set to true if client certificate authentication is required */
- private boolean _needClientAuth=false;
- /** Set to true if client certificate authentication is desired */
- private boolean _wantClientAuth=false;
- /** Set to true if SSL certificate validation is required */
- private boolean _validateCert;
- /** Set to true if renegotiation is allowed */
- private boolean _allowRenegotiate=false;
-
- /** KeyStore password */
- private transient Password _password;
- /** Key password */
- private transient Password _keyPassword;
- /** TrustStore password */
- private transient Password _trustPassword;
-
- /** SSL Provider name */
- private String _sslProvider;
- /** SSL Protocol name */
- private String _sslProtocol="TLS";
-
- /** SecureRandom algorithm */
- private String _secureRandomAlgorithm;
- /** KeyManager factory algorithm */
- private String _sslKeyManagerFactoryAlgorithm=DEFAULT_KEYSTORE_ALGORITHM;
- /** TrustManager factory algorithm */
- private String _sslTrustManagerFactoryAlgorithm=DEFAULT_TRUSTSTORE_ALGORITHM;
-
- /** Path to file that contains Certificate Revocation List */
- private String _crlPath;
- /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
- private int _maxCertPathLength = -1;
-
- /** SSL context */
- private SSLContext _context;
/** SSL buffers */
private Buffers _sslBuffers;
@@ -147,450 +91,6 @@
/* ------------------------------------------------------------ */
/**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
- */
- public String[] getExcludeCipherSuites()
- {
- return _excludeCipherSuites;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
- */
- public void setExcludeCipherSuites(String[] cipherSuites)
- {
- this._excludeCipherSuites=cipherSuites;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
- */
- public String[] getIncludeCipherSuites()
- {
- return _includeCipherSuites;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
- */
- public void setIncludeCipherSuites(String[] cipherSuites)
- {
- this._includeCipherSuites=cipherSuites;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystore()
- */
- public String getKeystore()
- {
- return _keystorePath;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystore(java.lang.String)
- */
- public void setKeystore(String keystore)
- {
- _keystorePath=keystore;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#getKeystoreProvider()
- */
- public String getKeystoreProvider()
- {
- return _keystoreProvider;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#setKeystoreProvider(java.lang.String)
- */
- public void setKeystoreProvider(String keystoreProvider)
- {
- _keystoreProvider = keystoreProvider;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystoreType()
- */
- public String getKeystoreType()
- {
- return (_keystoreType);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystoreType(java.lang.String)
- */
- public void setKeystoreType(String keystoreType)
- {
- _keystoreType=keystoreType;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#getCertAlias()
- */
- public String getCertAlias()
- {
- return _certAlias;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#setCertAlias(java.lang.String)
- */
- public void setCertAlias(String certAlias)
- {
- this._certAlias = certAlias;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststore()
- */
- public String getTruststore()
- {
- return _truststorePath;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststore(java.lang.String)
- */
- public void setTruststore(String truststore)
- {
- _truststorePath=truststore;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#getTruststoreProvider()
- */
- public String getTruststoreProvider()
- {
- return _truststoreProvider;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#setTruststoreProvider(java.lang.String)
- */
- public void setTruststoreProvider(String truststoreProvider)
- {
- _truststoreProvider = truststoreProvider;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststoreType()
- */
- public String getTruststoreType()
- {
- return _truststoreType;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String)
- */
- public void setTruststoreType(String truststoreType)
- {
- _truststoreType=truststoreType;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getNeedClientAuth()
- */
- public boolean getNeedClientAuth()
- {
- return _needClientAuth;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setNeedClientAuth(boolean)
- */
- public void setNeedClientAuth(boolean needClientAuth)
- {
- _needClientAuth=needClientAuth;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getWantClientAuth()
- */
- public boolean getWantClientAuth()
- {
- return _wantClientAuth;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setWantClientAuth(boolean)
- */
- public void setWantClientAuth(boolean wantClientAuth)
- {
- _wantClientAuth=wantClientAuth;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#getValidateCert()
- */
- public boolean getValidateCert()
- {
- return _validateCert;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#setValidateCert(boolean)
- */
- public void setValidateCert(boolean validateCert)
- {
- _validateCert = validateCert;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @return True if SSL re-negotiation is allowed (default false)
- */
- public boolean isAllowRenegotiate()
- {
- return _allowRenegotiate;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
- * a vulnerability in SSL/TLS with re-negotiation. If your JVM
- * does not have CVE-2009-3555 fixed, then re-negotiation should
- * not be allowed.
- * @param allowRenegotiate true if re-negotiation is allowed (default false)
- */
- public void setAllowRenegotiate(boolean allowRenegotiate)
- {
- _allowRenegotiate = allowRenegotiate;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String)
- */
- public void setPassword(String password)
- {
- _password=Password.getPassword(PASSWORD_PROPERTY,password,null);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setKeyPassword(java.lang.String)
- */
- public void setKeyPassword(String password)
- {
- _keyPassword=Password.getPassword(KEYPASSWORD_PROPERTY,password,null);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String)
- */
- public void setTrustPassword(String password)
- {
- _trustPassword=Password.getPassword(PASSWORD_PROPERTY,password,null);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getProvider()
- */
- public String getProvider()
- {
- return _sslProvider;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setProvider(java.lang.String)
- */
- public void setProvider(String provider)
- {
- _sslProvider=provider;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getProtocol()
- */
- public String getProtocol()
- {
- return _sslProtocol;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setProtocol(java.lang.String)
- */
- public void setProtocol(String protocol)
- {
- _sslProtocol=protocol;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getSecureRandomAlgorithm()
- */
- public String getSecureRandomAlgorithm()
- {
- return _secureRandomAlgorithm;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setSecureRandomAlgorithm(java.lang.String)
- */
- public void setSecureRandomAlgorithm(String algorithm)
- {
- this._secureRandomAlgorithm=algorithm;
- }
-
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getSslKeyManagerFactoryAlgorithm()
- */
- public String getSslKeyManagerFactoryAlgorithm()
- {
- return (this._sslKeyManagerFactoryAlgorithm);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setSslKeyManagerFactoryAlgorithm(java.lang.String)
- */
- public void setSslKeyManagerFactoryAlgorithm(String algorithm)
- {
- this._sslKeyManagerFactoryAlgorithm=algorithm;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#getSslTrustManagerFactoryAlgorithm()
- */
- public String getSslTrustManagerFactoryAlgorithm()
- {
- return (this._sslTrustManagerFactoryAlgorithm);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String)
- */
- public void setSslTrustManagerFactoryAlgorithm(String algorithm)
- {
- this._sslTrustManagerFactoryAlgorithm=algorithm;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @deprecated use {@link #getSslKeyManagerFactoryAlgorithm()} or
- * {@link #getSslTrustManagerFactoryAlgorithm()}
- */
- @Deprecated
- public String getAlgorithm()
- {
- return getSslKeyManagerFactoryAlgorithm();
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @deprecated use {@link #setSslKeyManagerFactoryAlgorithm(String)} or
- * {@link #setSslTrustManagerFactoryAlgorithm(String)}
- */
- @Deprecated
- public void setAlgorithm(String algorithm)
- {
- setSslKeyManagerFactoryAlgorithm(algorithm);
- setSslTrustManagerFactoryAlgorithm(algorithm);
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#setCrlPath(java.lang.String)
- */
- public void setCrlPath(String crlPath)
- {
- _crlPath = crlPath;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#getCrlPath()
- */
- public String getCrlPath()
- {
- return _crlPath;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#getMaxCertPathLength()
- */
- public int getMaxCertPathLength()
- {
- return _maxCertPathLength;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#setMaxCertPathLength(int)
- */
- public void setMaxCertPathLength(int maxCertPathLength)
- {
- _maxCertPathLength = maxCertPathLength;
- }
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
- */
- public SSLContext getSslContext()
- {
- try
- {
- if (_context == null)
- _context=createSSLContext();
- }
- catch(Exception e)
- {
- throw new RuntimeException(e);
- }
-
- return _context;
- }
-
-
- /* ------------------------------------------------------------ */
- /**
- * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
- */
- public void setSslContext(SSLContext sslContext)
- {
- _context = sslContext;
- }
-
- /* ------------------------------------------------------------ */
- /**
* @return SSL buffers
*/
public Buffers getSslBuffers()
@@ -798,190 +298,4 @@
}
return engine;
}
-
- /* ------------------------------------------------------------ */
- protected SSLContext createSSLContext() throws Exception
- {
- KeyStore keyStore = getKeyStore(_keystorePath, _keystoreType, _keystoreProvider, _password==null?null:_password.toString());
- KeyStore trustStore = getTrustStore(_truststorePath, _truststoreType, _truststoreProvider, _trustPassword == null ? null : _trustPassword.toString());
- Collection<? extends CRL> crls = loadCRL(_crlPath);
-
- if (_certAlias == null)
- {
- List<String> aliases = Collections.list(keyStore.aliases());
- _certAlias = aliases.size() == 1 ? aliases.get(0) : null;
- }
-
- Certificate cert = _certAlias == null ? null : keyStore.getCertificate(_certAlias);
- if (cert == null)
- {
- throw new Exception("No certificate found in the keystore"+
- (_certAlias == null ? "" : " for alias "+_certAlias));
- }
-
- if (_validateCert)
- {
- CertificateValidator validator = new CertificateValidator(keyStore,trustStore,crls);
- validator.validate(cert);
- }
-
- KeyManager[] keyManagers = getKeyManagers(keyStore);
- TrustManager[] trustManagers = getTrustManagers(trustStore, crls);
-
- SecureRandom secureRandom =
- _secureRandomAlgorithm == null ? null : SecureRandom.getInstance(_secureRandomAlgorithm);
- SSLContext context = _sslProvider == null ? SSLContext.getInstance(_sslProtocol) :
- SSLContext.getInstance(_sslProtocol,_sslProvider);
- context.init(keyManagers,trustManagers,secureRandom);
-
- return context;
- }
-
- /* ------------------------------------------------------------ */
- protected KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception
- {
- KeyManagerFactory keyManagerFactory=KeyManagerFactory.getInstance(_sslKeyManagerFactoryAlgorithm);
- keyManagerFactory.init(keyStore,_keyPassword==null?(_password==null?null:_password.toString().toCharArray()):_keyPassword.toString().toCharArray());
- KeyManager[] managers = keyManagerFactory.getKeyManagers();
-
- if (_certAlias != null)
- {
- for (int idx=0; idx < managers.length; idx++)
- {
- if (managers[idx] instanceof X509KeyManager)
- {
- managers[idx] = new SslExtendedKeyManager(_certAlias, (X509KeyManager)managers[idx]);
- }
- }
- }
-
- return managers;
- }
-
- /* ------------------------------------------------------------ */
- protected TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception
- {
- TrustManager[] managers = null;
- if (trustStore != null)
- {
- // Revocation checking is only supported for PKIX algorithm
- if (_sslTrustManagerFactoryAlgorithm.equalsIgnoreCase("PKIX"))
- {
- PKIXBuilderParameters pbParams =
- new PKIXBuilderParameters(trustStore, new X509CertSelector());
-
- // Enable revocation checking
- pbParams.setRevocationEnabled(true);
-
- // Set maximum certification path length
- pbParams.setMaxPathLength(_maxCertPathLength);
-
- if (crls != null && !crls.isEmpty())
- {
- pbParams.addCertStore(CertStore.getInstance("Collection",
- new CollectionCertStoreParameters(crls)));
- }
-
- // Enable On-Line Certificate Status Protocol (OCSP) support
- Security.setProperty("ocsp.enable", "true");
-
- // Enable Certificate Revocation List Distribution Points (CRLDP) support
- System.setProperty("com.sun.security.enableCRLDP","true");
-
- TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_sslTrustManagerFactoryAlgorithm);
- trustManagerFactory.init(new CertPathTrustManagerParameters(pbParams));
-
- managers = trustManagerFactory.getTrustManagers();
- }
- else
- {
- TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_sslTrustManagerFactoryAlgorithm);
- trustManagerFactory.init(trustStore);
-
- managers = trustManagerFactory.getTrustManagers();
- }
- }
-
- return managers;
- }
-
- /* ------------------------------------------------------------ */
- protected KeyStore getKeyStore(String storePath, String storeType, String storeProvider, String storePassword) throws Exception
- {
- if (storePath == null)
- return null;
-
- KeyStore keystore = null;
- InputStream inStream = null;
- try
- {
- if (storeProvider != null)
- {
- keystore = KeyStore.getInstance(storeType, storeProvider);
- }
- else
- {
- keystore = KeyStore.getInstance(storeType);
- }
-
- inStream = Resource.newResource(storePath).getInputStream();
- keystore.load(inStream, storePassword == null ? null : storePassword.toCharArray());
-
- return keystore;
- }
- finally
- {
- if (inStream != null)
- {
- inStream.close();
- }
- }
- }
-
- /* ------------------------------------------------------------ */
- protected KeyStore getTrustStore(String trustPath, String trustType, String trustProvider, String trustPassword) throws Exception
- {
- if (trustPath==null)
- {
- trustPath = System.getProperty("javax.net.ssl.trustStore");
- trustType = System.getProperty("javax.net.ssl.trustStoreType");
- trustProvider = System.getProperty("javax.net.ssl.trustStoreProvider");
- trustPassword = System.getProperty("javax.net.ssl.trustStorePassword");
- }
-
- if (trustPath==null)
- {
- trustPath = _keystorePath;
- trustType = _keystoreType;
- trustProvider = _keystoreProvider;
- trustPassword = _password.toString();
- _sslTrustManagerFactoryAlgorithm = _sslKeyManagerFactoryAlgorithm;
- }
-
- return getKeyStore(trustPath, trustType, trustProvider, trustPassword);
- }
-
- /* ------------------------------------------------------------ */
- private Collection<? extends CRL> loadCRL(String crlPath) throws Exception
- {
- Collection<? extends CRL> crlList = null;
-
- if (crlPath != null)
- {
- InputStream in = null;
- try {
- in = Resource.newResource(crlPath).getInputStream();
- crlList = CertificateFactory.getInstance("X.509").generateCRLs(in);
- }
- finally
- {
- if (in != null)
- {
- in.close();
- }
- }
- }
-
- return crlList;
- }
}
diff --git a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslSocketConnector.java b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslSocketConnector.java
index e111cd4..eab6df0 100644
--- a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslSocketConnector.java
+++ b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/EnhancedSslSocketConnector.java
@@ -102,7 +102,7 @@
/** Set to true if client certificate authentication is desired */
private boolean _wantClientAuth=false;
/** Set to true if SSL certificate validation is required */
- private boolean _validateCert;
+ private boolean _validateCerts;
/** Set to true if renegotiation is allowed */
private boolean _allowRenegotiate=false;
@@ -345,20 +345,20 @@
/* ------------------------------------------------------------ */
/**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#getValidateCert()
+ * @see org.eclipse.jetty.exssl.EnhancedSslConnector#getValidateCerts()
*/
- public boolean getValidateCert()
+ public boolean getValidateCerts()
{
- return _validateCert;
+ return _validateCerts;
}
/* ------------------------------------------------------------ */
/**
- * @see org.eclipse.jetty.exssl.EnhancedSslConnector#setValidateCert(boolean)
+ * @see org.eclipse.jetty.exssl.EnhancedSslConnector#setValidateCerts(boolean)
*/
- public void setValidateCert(boolean validateCert)
+ public void setValidateCerts(boolean validateCerts)
{
- _validateCert = validateCert;
+ _validateCerts = validateCerts;
}
/* ------------------------------------------------------------ */
@@ -821,7 +821,7 @@
(_certAlias == null ? "" : " for alias "+_certAlias));
}
- if (_validateCert)
+ if (_validateCerts)
{
CertificateValidator certValidator = new CertificateValidator(keyStore,trustStore,crls);
certValidator.validate(cert);
diff --git a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslExtendedKeyManager.java b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslExtendedKeyManager.java
index 1bcf964..e15c38d 100644
--- a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslExtendedKeyManager.java
+++ b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslExtendedKeyManager.java
@@ -20,8 +20,8 @@
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLEngine;
-import javax.net.ssl.X509KeyManager;
import javax.net.ssl.X509ExtendedKeyManager;
+import javax.net.ssl.X509KeyManager;
/* ------------------------------------------------------------ */
@@ -46,7 +46,7 @@
*/
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
{
- return _keyManager.chooseClientAlias(keyType, issuers, socket);
+ return _keyAlias == null ? _keyManager.chooseClientAlias(keyType, issuers, socket) : _keyAlias;
}
/* ------------------------------------------------------------ */
@@ -55,7 +55,7 @@
*/
public String chooseServerAlias(String keyType, Principal[] issuers, Socket socket)
{
- return _keyAlias == null ?_keyManager.chooseServerAlias(keyType, issuers, socket) : _keyAlias;
+ return _keyAlias == null ? _keyManager.chooseServerAlias(keyType, issuers, socket) : _keyAlias;
}
/* ------------------------------------------------------------ */
@@ -104,4 +104,15 @@
{
return _keyAlias == null ? super.chooseEngineServerAlias(keyType,issuers,engine) : _keyAlias;
}
+
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see javax.net.ssl.X509ExtendedKeyManager#chooseEngineClientAlias(java.lang.String, java.security.Principal[], javax.net.ssl.SSLEngine)
+ */
+ @Override
+ public String chooseEngineClientAlias(String keyType[], Principal[] issuers, SSLEngine engine)
+ {
+ return _keyAlias == null ? super.chooseEngineClientAlias(keyType,issuers,engine) : _keyAlias;
+ }
}
diff --git a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslKeyManager.java b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslKeyManager.java
index da468d6..3a58c9a 100644
--- a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslKeyManager.java
+++ b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslKeyManager.java
@@ -44,7 +44,7 @@
*/
public String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket)
{
- return _keyManager.chooseClientAlias(keyType, issuers, socket);
+ return _keyAlias == null ? _keyManager.chooseClientAlias(keyType, issuers, socket) : _keyAlias;
}
/* ------------------------------------------------------------ */
@@ -92,9 +92,4 @@
{
return _keyManager.getPrivateKey(alias);
}
-
- public String getKeyAlias()
- {
- return _keyAlias;
- }
}
diff --git a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslParameters.java b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslParameters.java
new file mode 100644
index 0000000..90f9e40
--- /dev/null
+++ b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslParameters.java
@@ -0,0 +1,792 @@
+package org.eclipse.jetty.exssl;
+
+import java.io.File;
+import java.io.InputStream;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.CRL;
+import java.security.cert.CertStore;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateFactory;
+import java.security.cert.CollectionCertStoreParameters;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.X509CertSelector;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.net.ssl.CertPathTrustManagerParameters;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.TrustManagerFactory;
+import javax.net.ssl.X509KeyManager;
+
+import org.eclipse.jetty.http.security.Password;
+import org.eclipse.jetty.util.resource.Resource;
+
+public class SslParameters
+{
+ public static final String DEFAULT_KEYSTORE_ALGORITHM =
+ (Security.getProperty("ssl.KeyManagerFactory.algorithm") == null ?
+ "SunX509" : Security.getProperty("ssl.KeyManagerFactory.algorithm"));
+ public static final String DEFAULT_TRUSTSTORE_ALGORITHM =
+ (Security.getProperty("ssl.TrustManagerFactory.algorithm") == null ?
+ "SunX509" : Security.getProperty("ssl.TrustManagerFactory.algorithm"));
+
+ /** Default value for the keystore location path. */
+ public static final String DEFAULT_KEYSTORE =
+ System.getProperty("user.home") + File.separator + ".keystore";
+
+ /** String name of key password property. */
+ public static final String KEYPASSWORD_PROPERTY = "org.eclipse.jetty.ssl.keypassword";
+
+ /** String name of keystore password property. */
+ public static final String PASSWORD_PROPERTY = "org.eclipse.jetty.ssl.password";
+
+ /** Excluded cipher suites. */
+ private String _excludeCipherSuites[] = null;
+ /** Included cipher suites. */
+ private String _includeCipherSuites[] = null;
+
+ /** KeyStore path. */
+ private String _keystorePath = DEFAULT_KEYSTORE;
+ /** KeyStore provider name */
+ private String _keystoreProvider;
+ /** KeyStore type */
+ private String _keystoreType = "JKS";
+ /** SSL certificate alias */
+ private String _certAlias;
+
+ /** TrustStore path */
+ private String _truststorePath;
+ /** TrustStore provider name */
+ private String _truststoreProvider;
+ /** TrustStore type */
+ private String _truststoreType = "JKS";
+
+ /** Set to true if client certificate authentication is required */
+ private boolean _needClientAuth = false;
+ /** Set to true if client certificate authentication is desired */
+ private boolean _wantClientAuth = false;
+ /** Set to true if SSL certificate validation is required */
+ private boolean _validateCerts;
+ /** Set to true if renegotiation is allowed */
+ private boolean _allowRenegotiate = false;
+
+ /** KeyStore password */
+ private transient Password _password;
+ /** Key password */
+ private transient Password _keyPassword;
+ /** TrustStore password */
+ private transient Password _trustPassword;
+
+ /** SSL Provider name */
+ private String _sslProvider;
+ /** SSL Protocol name */
+ private String _sslProtocol = "TLS";
+
+ /** SecureRandom algorithm */
+ private String _secureRandomAlgorithm;
+ /** KeyManager factory algorithm */
+ private String _sslKeyManagerFactoryAlgorithm = DEFAULT_KEYSTORE_ALGORITHM;
+ /** TrustManager factory algorithm */
+ private String _sslTrustManagerFactoryAlgorithm = DEFAULT_TRUSTSTORE_ALGORITHM;
+
+ /** Path to file that contains Certificate Revocation List */
+ private String _crlPath;
+ /** Maximum certification path length (n - number of intermediate certs, -1 for unlimited) */
+ private int _maxCertPathLength = -1;
+
+ /** SSL context */
+ private SSLContext _context;
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The array of cipher suite names to exclude from
+ * {@link SSLEngine#setEnabledCipherSuites(String[])}
+ */
+ public String[] getExcludeCipherSuites()
+ {
+ return _excludeCipherSuites;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param cipherSuites
+ * The array of cipher suite names to exclude from
+ * {@link SSLEngine#setEnabledCipherSuites(String[])}
+ */
+ public void setExcludeCipherSuites(String[] cipherSuites)
+ {
+ _excludeCipherSuites = cipherSuites;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The array of cipher suite names to include in
+ * {@link SSLEngine#setEnabledCipherSuites(String[])}
+ */
+ public String[] getIncludeCipherSuites()
+ {
+ return _includeCipherSuites;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param cipherSuites
+ * The array of cipher suite names to include in
+ * {@link SSLEngine#setEnabledCipherSuites(String[])}
+ */
+ public void setIncludeCipherSuites(String[] cipherSuites)
+ {
+ _includeCipherSuites = cipherSuites;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The file or URL of the SSL Key store.
+ */
+ public String getKeystore()
+ {
+ return _keystorePath;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param keystore
+ * The file or URL of the SSL Key store.
+ */
+ public void setKeystore(String keystore)
+ {
+ _keystorePath = keystore;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The provider of the key store
+ */
+ public String getKeystoreProvider()
+ {
+ return _keystoreProvider;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param keystoreProvider
+ * The provider of the key store
+ */
+ public void setKeystoreProvider(String keystoreProvider)
+ {
+ _keystoreProvider = keystoreProvider;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The type of the key store (default "JKS")
+ */
+ public String getKeystoreType()
+ {
+ return (_keystoreType);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param keystoreType
+ * The type of the key store (default "JKS")
+ */
+ public void setKeystoreType(String keystoreType)
+ {
+ _keystoreType = keystoreType;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return Alias of SSL certificate for the connector
+ */
+ public String getCertAlias()
+ {
+ return _certAlias;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param certAlias
+ * Alias of SSL certificate for the connector
+ */
+ public void setCertAlias(String certAlias)
+ {
+ _certAlias = certAlias;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The file name or URL of the trust store location
+ */
+ public String getTruststore()
+ {
+ return _truststorePath;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param truststore
+ * The file name or URL of the trust store location
+ */
+ public void setTruststore(String truststore)
+ {
+ _truststorePath = truststore;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The provider of the trust store
+ */
+ public String getTruststoreProvider()
+ {
+ return _truststoreProvider;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param truststoreProvider
+ * The provider of the trust store
+ */
+ public void setTruststoreProvider(String truststoreProvider)
+ {
+ _truststoreProvider = truststoreProvider;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The type of the trust store (default "JKS")
+ */
+ public String getTruststoreType()
+ {
+ return _truststoreType;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param truststoreType
+ * The type of the trust store (default "JKS")
+ */
+ public void setTruststoreType(String truststoreType)
+ {
+ _truststoreType = truststoreType;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return True if SSL needs client authentication.
+ * @see SSLEngine#getNeedClientAuth()
+ */
+ public boolean getNeedClientAuth()
+ {
+ return _needClientAuth;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param needClientAuth
+ * True if SSL needs client authentication.
+ * @see SSLEngine#getNeedClientAuth()
+ */
+ public void setNeedClientAuth(boolean needClientAuth)
+ {
+ _needClientAuth = needClientAuth;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return True if SSL wants client authentication.
+ * @see SSLEngine#getWantClientAuth()
+ */
+ public boolean getWantClientAuth()
+ {
+ return _wantClientAuth;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param wantClientAuth
+ * True if SSL wants client authentication.
+ * @see SSLEngine#getWantClientAuth()
+ */
+ public void setWantClientAuth(boolean wantClientAuth)
+ {
+ _wantClientAuth = wantClientAuth;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return true if SSL certificate has to be validated
+ */
+ public boolean getValidateCerts()
+ {
+ return _validateCerts;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param validateServerCert
+ * true if SSL certificate has to be validated
+ */
+ public void setValidateCerts(boolean validateCerts)
+ {
+ _validateCerts = validateCerts;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return True if SSL re-negotiation is allowed (default false)
+ */
+ public boolean isAllowRenegotiate()
+ {
+ return _allowRenegotiate;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered a vulnerability
+ * in SSL/TLS with re-negotiation. If your JVM does not have CVE-2009-3555 fixed,
+ * then re-negotiation should not be allowed.
+ *
+ * @param allowRenegotiate
+ * true if re-negotiation is allowed (default false)
+ */
+ public void setAllowRenegotiate(boolean allowRenegotiate)
+ {
+ _allowRenegotiate = allowRenegotiate;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param password
+ * The password for the key store
+ */
+ public void setPassword(String password)
+ {
+ _password = Password.getPassword(PASSWORD_PROPERTY,password,null);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param password
+ * The password (if any) for the specific key within the key store
+ */
+ public void setKeyPassword(String password)
+ {
+ _keyPassword = Password.getPassword(KEYPASSWORD_PROPERTY,password,null);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param password
+ * The password for the trust store
+ */
+ public void setTrustPassword(String password)
+ {
+ _trustPassword = Password.getPassword(PASSWORD_PROPERTY,password,null);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The SSL provider name, which if set is passed to
+ * {@link SSLContext#getInstance(String, String)}
+ */
+ public String getProvider()
+ {
+ return _sslProvider;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param provider
+ * The SSL provider name, which if set is passed to
+ * {@link SSLContext#getInstance(String, String)}
+ */
+ public void setProvider(String provider)
+ {
+ _sslProvider = provider;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The SSL protocol (default "TLS") passed to
+ * {@link SSLContext#getInstance(String, String)}
+ */
+ public String getProtocol()
+ {
+ return _sslProtocol;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param protocol
+ * The SSL protocol (default "TLS") passed to
+ * {@link SSLContext#getInstance(String, String)}
+ */
+ public void setProtocol(String protocol)
+ {
+ _sslProtocol = protocol;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The algorithm name, which if set is passed to
+ * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to
+ * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
+ */
+ public String getSecureRandomAlgorithm()
+ {
+ return _secureRandomAlgorithm;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param algorithm
+ * The algorithm name, which if set is passed to
+ * {@link SecureRandom#getInstance(String)} to obtain the {@link SecureRandom} instance passed to
+ * {@link SSLContext#init(javax.net.ssl.KeyManager[], javax.net.ssl.TrustManager[], SecureRandom)}
+ */
+ public void setSecureRandomAlgorithm(String algorithm)
+ {
+ _secureRandomAlgorithm = algorithm;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
+ */
+ public String getSslKeyManagerFactoryAlgorithm()
+ {
+ return (_sslKeyManagerFactoryAlgorithm);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param algorithm
+ * The algorithm name (default "SunX509") used by the {@link KeyManagerFactory}
+ */
+ public void setSslKeyManagerFactoryAlgorithm(String algorithm)
+ {
+ _sslKeyManagerFactoryAlgorithm = algorithm;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
+ */
+ public String getSslTrustManagerFactoryAlgorithm()
+ {
+ return (_sslTrustManagerFactoryAlgorithm);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param algorithm
+ * The algorithm name (default "SunX509") used by the {@link TrustManagerFactory}
+ */
+ public void setSslTrustManagerFactoryAlgorithm(String algorithm)
+ {
+ _sslTrustManagerFactoryAlgorithm = algorithm;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return Path to file that contains Certificate Revocation List
+ */
+ public String getCrlPath()
+ {
+ return _crlPath;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param crlPath
+ * Path to file that contains Certificate Revocation List
+ */
+ public void setCrlPath(String crlPath)
+ {
+ _crlPath = crlPath;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return Maximum number of intermediate certificates in
+ * the certification path (-1 for unlimited)
+ */
+ public int getMaxCertPathLength()
+ {
+ return _maxCertPathLength;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param maxCertPathLength
+ * maximum number of intermediate certificates in
+ * the certification path (-1 for unlimited)
+ */
+ public void setMaxCertPathLength(int maxCertPathLength)
+ {
+ _maxCertPathLength = maxCertPathLength;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return The SSLContext
+ */
+ public SSLContext getSslContext()
+ {
+ try
+ {
+ if (_context == null)
+ _context = createSSLContext();
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+
+ return _context;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param sslContext
+ * Set a preconfigured SSLContext
+ */
+ public void setSslContext(SSLContext sslContext)
+ {
+ _context = sslContext;
+ }
+
+ /* ------------------------------------------------------------ */
+ protected SSLContext createSSLContext() throws Exception
+ {
+ KeyStore keyStore = getKeyStore(_keystorePath,_keystoreType,_keystoreProvider,_password == null?null:_password.toString());
+ KeyStore trustStore = getTrustStore(_truststorePath,_truststoreType,_truststoreProvider,_trustPassword == null?null:_trustPassword.toString());
+ Collection<? extends CRL> crls = loadCRL(_crlPath);
+
+ if (_certAlias == null)
+ {
+ List<String> aliases = Collections.list(keyStore.aliases());
+ _certAlias = aliases.size() == 1?aliases.get(0):null;
+ }
+
+ Certificate cert = _certAlias == null?null:keyStore.getCertificate(_certAlias);
+ if (cert == null)
+ {
+ throw new Exception("No certificate found in the keystore" + (_certAlias == null?"":" for alias " + _certAlias));
+ }
+
+ if (_validateCerts)
+ {
+ CertificateValidator validator = new CertificateValidator(keyStore,trustStore,crls);
+ validator.validate(cert);
+ }
+
+ KeyManager[] keyManagers = getKeyManagers(keyStore);
+ TrustManager[] trustManagers = getTrustManagers(trustStore,crls);
+
+ SecureRandom secureRandom = _secureRandomAlgorithm == null?null:SecureRandom.getInstance(_secureRandomAlgorithm);
+ SSLContext context = _sslProvider == null?SSLContext.getInstance(_sslProtocol):SSLContext.getInstance(_sslProtocol,_sslProvider);
+ context.init(keyManagers,trustManagers,secureRandom);
+
+ return context;
+ }
+
+ /* ------------------------------------------------------------ */
+ public KeyManager[] getKeyManagers(KeyStore keyStore) throws Exception
+ {
+ KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(_sslKeyManagerFactoryAlgorithm);
+ keyManagerFactory.init(keyStore,_keyPassword == null?(_password == null?null:_password.toString().toCharArray()):_keyPassword.toString().toCharArray());
+ KeyManager[] managers = keyManagerFactory.getKeyManagers();
+
+ if (_certAlias != null)
+ {
+ for (int idx = 0; idx < managers.length; idx++)
+ {
+ if (managers[idx] instanceof X509KeyManager)
+ {
+ managers[idx] = new SslExtendedKeyManager(_certAlias,(X509KeyManager)managers[idx]);
+ }
+ }
+ }
+
+ return managers;
+ }
+
+ /* ------------------------------------------------------------ */
+ public TrustManager[] getTrustManagers(KeyStore trustStore, Collection<? extends CRL> crls) throws Exception
+ {
+ TrustManager[] managers = null;
+ if (trustStore != null && _validateCerts)
+ {
+ // Revocation checking is only supported for PKIX algorithm
+ if (_sslTrustManagerFactoryAlgorithm.equalsIgnoreCase("PKIX"))
+ {
+ PKIXBuilderParameters pbParams = new PKIXBuilderParameters(trustStore,new X509CertSelector());
+
+ // Enable revocation checking
+ pbParams.setRevocationEnabled(true);
+
+ // Set maximum certification path length
+ pbParams.setMaxPathLength(_maxCertPathLength);
+
+ if (crls != null && !crls.isEmpty())
+ {
+ pbParams.addCertStore(CertStore.getInstance("Collection",new CollectionCertStoreParameters(crls)));
+ }
+
+ // Enable On-Line Certificate Status Protocol (OCSP) support
+ Security.setProperty("ocsp.enable","true");
+
+ // Enable Certificate Revocation List Distribution Points (CRLDP) support
+ System.setProperty("com.sun.security.enableCRLDP","true");
+
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_sslTrustManagerFactoryAlgorithm);
+ trustManagerFactory.init(new CertPathTrustManagerParameters(pbParams));
+
+ managers = trustManagerFactory.getTrustManagers();
+ }
+ else
+ {
+ TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(_sslTrustManagerFactoryAlgorithm);
+ trustManagerFactory.init(trustStore);
+
+ managers = trustManagerFactory.getTrustManagers();
+ }
+ }
+
+ return managers;
+ }
+
+ /* ------------------------------------------------------------ */
+ public KeyStore getKeyStore(String storePath, String storeType, String storeProvider, String storePassword) throws Exception
+ {
+ if (storePath == null)
+ return null;
+
+ KeyStore keystore = null;
+ InputStream inStream = null;
+ try
+ {
+ if (storeProvider != null)
+ {
+ keystore = KeyStore.getInstance(storeType,storeProvider);
+ }
+ else
+ {
+ keystore = KeyStore.getInstance(storeType);
+ }
+
+ inStream = Resource.newResource(storePath).getInputStream();
+ keystore.load(inStream,storePassword == null?null:storePassword.toCharArray());
+
+ return keystore;
+ }
+ finally
+ {
+ if (inStream != null)
+ {
+ inStream.close();
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ public KeyStore getTrustStore(String trustPath, String trustType, String trustProvider, String trustPassword) throws Exception
+ {
+ if (trustPath == null)
+ {
+ trustPath = System.getProperty("javax.net.ssl.trustStore");
+ trustType = System.getProperty("javax.net.ssl.trustStoreType");
+ trustProvider = System.getProperty("javax.net.ssl.trustStoreProvider");
+ trustPassword = System.getProperty("javax.net.ssl.trustStorePassword");
+ }
+
+ if (trustPath == null)
+ {
+ trustPath = _keystorePath;
+ trustType = _keystoreType;
+ trustProvider = _keystoreProvider;
+ trustPassword = _password.toString();
+ _sslTrustManagerFactoryAlgorithm = _sslKeyManagerFactoryAlgorithm;
+ }
+
+ return getKeyStore(trustPath,trustType,trustProvider,trustPassword);
+ }
+
+ /* ------------------------------------------------------------ */
+ private Collection<? extends CRL> loadCRL(String crlPath) throws Exception
+ {
+ Collection<? extends CRL> crlList = null;
+
+ if (crlPath != null)
+ {
+ InputStream in = null;
+ try
+ {
+ in = Resource.newResource(crlPath).getInputStream();
+ crlList = CertificateFactory.getInstance("X.509").generateCRLs(in);
+ }
+ finally
+ {
+ if (in != null)
+ {
+ in.close();
+ }
+ }
+ }
+
+ return crlList;
+ }
+
+ public String[] selectCipherSuites(String[] enabledCipherSuites, String[] supportedCipherSuites)
+ {
+ List<String> selectedCipherSuites = null;
+ if (enabledCipherSuites != null)
+ {
+ selectedCipherSuites = new ArrayList<String>(Arrays.asList(enabledCipherSuites));
+ }
+ else
+ {
+ selectedCipherSuites = new ArrayList<String>();
+ }
+
+ if ((supportedCipherSuites != null && supportedCipherSuites.length > 0) && (_includeCipherSuites != null && _includeCipherSuites.length > 0))
+ {
+ List<String> supportedCSList = Arrays.asList(supportedCipherSuites);
+ List<String> includedCSList = Arrays.asList(_includeCipherSuites);
+
+ for (String cipherName : includedCSList)
+ {
+ if ((!selectedCipherSuites.contains(cipherName)) && supportedCSList.contains(cipherName))
+ {
+ selectedCipherSuites.add(cipherName);
+ }
+ }
+ }
+
+ if (_excludeCipherSuites != null && _excludeCipherSuites.length > 0)
+ {
+ List<String> excludedCSList = Arrays.asList(_excludeCipherSuites);
+ for (String cipherName : excludedCSList)
+ {
+ if (selectedCipherSuites.contains(cipherName))
+ {
+ selectedCipherSuites.remove(cipherName);
+ }
+ }
+ }
+
+ return selectedCipherSuites.toArray(new String[0]);
+ }
+}
diff --git a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslSelectChannelConnector.java b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslSelectChannelConnector.java
new file mode 100644
index 0000000..c5dfabc
--- /dev/null
+++ b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslSelectChannelConnector.java
@@ -0,0 +1,560 @@
+// ========================================================================
+// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.exssl;
+
+import java.io.IOException;
+import java.nio.channels.SelectionKey;
+import java.nio.channels.SocketChannel;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.http.HttpParser;
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.Buffers;
+import org.eclipse.jetty.io.Connection;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.ThreadLocalBuffers;
+import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.io.nio.DirectNIOBuffer;
+import org.eclipse.jetty.io.nio.IndirectNIOBuffer;
+import org.eclipse.jetty.io.nio.SelectChannelEndPoint;
+import org.eclipse.jetty.io.nio.SelectorManager.SelectSet;
+import org.eclipse.jetty.io.nio.SslSelectChannelEndPoint;
+import org.eclipse.jetty.server.HttpConnection;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.nio.SelectChannelConnector;
+import org.eclipse.jetty.server.ssl.SslCertificates;
+import org.eclipse.jetty.server.ssl.SslConnector;
+import org.eclipse.jetty.util.log.Log;
+
+/* ------------------------------------------------------------ */
+/**
+ * SslSelectChannelConnector.
+ *
+ * @org.apache.xbean.XBean element="sslConnector" description="Creates an NIO ssl connector"
+ *
+ *
+ *
+ */
+public class SslSelectChannelConnector extends SelectChannelConnector implements SslConnector
+{
+ private final SslParameters _sslParams;
+ private Buffers _sslBuffers;
+
+ /* ------------------------------------------------------------ */
+ public SslSelectChannelConnector()
+ {
+ this(new SslParameters());
+ }
+
+ /* ------------------------------------------------------------ */
+ public SslSelectChannelConnector(SslParameters sslParams)
+ {
+ _sslParams = sslParams;
+ setUseDirectBuffers(false);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Allow the Listener a chance to customise the request. before the server
+ * does its stuff. <br>
+ * This allows the required attributes to be set for SSL requests. <br>
+ * The requirements of the Servlet specs are:
+ * <ul>
+ * <li> an attribute named "javax.servlet.request.ssl_session_id" of type
+ * String (since Servlet Spec 3.0).</li>
+ * <li> an attribute named "javax.servlet.request.cipher_suite" of type
+ * String.</li>
+ * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
+ * <li> an attribute named "javax.servlet.request.X509Certificate" of type
+ * java.security.cert.X509Certificate[]. This is an array of objects of type
+ * X509Certificate, the order of this array is defined as being in ascending
+ * order of trust. The first certificate in the chain is the one set by the
+ * client, the next is the one used to authenticate the first, and so on.
+ * </li>
+ * </ul>
+ *
+ * @param endpoint
+ * The Socket the request arrived on. This should be a
+ * {@link SocketEndPoint} wrapping a {@link SSLSocket}.
+ * @param request
+ * HttpRequest to be customised.
+ */
+ @Override
+ public void customize(EndPoint endpoint, Request request) throws IOException
+ {
+ request.setScheme(HttpSchemes.HTTPS);
+ super.customize(endpoint,request);
+
+ SslSelectChannelEndPoint sslHttpChannelEndpoint=(SslSelectChannelEndPoint)endpoint;
+ SSLEngine sslEngine=sslHttpChannelEndpoint.getSSLEngine();
+ SSLSession sslSession=sslEngine.getSession();
+
+ SslCertificates.customize(sslSession,endpoint,request);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return True if SSL re-negotiation is allowed (default false)
+ */
+ public boolean isAllowRenegotiate()
+ {
+ return _sslParams.isAllowRenegotiate();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
+ * a vulnerability in SSL/TLS with re-negotiation. If your JVM
+ * does not have CVE-2009-3555 fixed, then re-negotiation should
+ * not be allowed.
+ * @param allowRenegotiate true if re-negotiation is allowed (default false)
+ */
+ public void setAllowRenegotiate(boolean allowRenegotiate)
+ {
+ _sslParams.setAllowRenegotiate(allowRenegotiate);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
+ */
+ public String[] getExcludeCipherSuites()
+ {
+ return _sslParams.getExcludeCipherSuites();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
+ */
+ public void setExcludeCipherSuites(String[] cipherSuites)
+ {
+ _sslParams.setExcludeCipherSuites(cipherSuites);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getExcludeCipherSuites()
+ */
+ public String[] getIncludeCipherSuites()
+ {
+ return _sslParams.getIncludeCipherSuites();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setExcludeCipherSuites(java.lang.String[])
+ */
+ public void setIncludeCipherSuites(String[] cipherSuites)
+ {
+ _sslParams.setIncludeCipherSuites(cipherSuites);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setPassword(java.lang.String)
+ */
+ public void setPassword(String password)
+ {
+ _sslParams.setPassword(password);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setTrustPassword(java.lang.String)
+ */
+ public void setTrustPassword(String password)
+ {
+ _sslParams.setTrustPassword(password);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setKeyPassword(java.lang.String)
+ */
+ public void setKeyPassword(String password)
+ {
+ _sslParams.setKeyPassword(password);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Unsupported.
+ *
+ * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
+ */
+ public String getAlgorithm()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Unsupported.
+ *
+ * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
+ */
+ public void setAlgorithm(String algorithm)
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getProtocol()
+ */
+ public String getProtocol()
+ {
+ return _sslParams.getProtocol();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setProtocol(java.lang.String)
+ */
+ public void setProtocol(String protocol)
+ {
+ _sslParams.setProtocol(protocol);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystore(java.lang.String)
+ */
+ public void setKeystore(String keystore)
+ {
+ _sslParams.setKeystore(keystore);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystore()
+ */
+ public String getKeystore()
+ {
+ return _sslParams.getKeystore();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getKeystoreType()
+ */
+ public String getKeystoreType()
+ {
+ return _sslParams.getKeystoreType();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getNeedClientAuth()
+ */
+ public boolean getNeedClientAuth()
+ {
+ return _sslParams.getNeedClientAuth();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getWantClientAuth()
+ */
+ public boolean getWantClientAuth()
+ {
+ return _sslParams.getWantClientAuth();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setNeedClientAuth(boolean)
+ */
+ public void setNeedClientAuth(boolean needClientAuth)
+ {
+ _sslParams.setNeedClientAuth(needClientAuth);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setWantClientAuth(boolean)
+ */
+ public void setWantClientAuth(boolean wantClientAuth)
+ {
+ _sslParams.setWantClientAuth(wantClientAuth);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setKeystoreType(java.lang.String)
+ */
+ public void setKeystoreType(String keystoreType)
+ {
+ _sslParams.setKeystoreType(keystoreType);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getProvider()
+ */
+ public String getProvider()
+ {
+ return _sslParams.getProvider();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getSecureRandomAlgorithm()
+ */
+ public String getSecureRandomAlgorithm()
+ {
+ return _sslParams.getSecureRandomAlgorithm();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getSslKeyManagerFactoryAlgorithm()
+ */
+ public String getSslKeyManagerFactoryAlgorithm()
+ {
+ return _sslParams.getSslKeyManagerFactoryAlgorithm();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getSslTrustManagerFactoryAlgorithm()
+ */
+ public String getSslTrustManagerFactoryAlgorithm()
+ {
+ return _sslParams.getSslTrustManagerFactoryAlgorithm();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststore()
+ */
+ public String getTruststore()
+ {
+ return _sslParams.getTruststore();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#getTruststoreType()
+ */
+ public String getTruststoreType()
+ {
+ return _sslParams.getTruststoreType();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setProvider(java.lang.String)
+ */
+ public void setProvider(String provider)
+ {
+ _sslParams.setProvider(provider);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setSecureRandomAlgorithm(java.lang.String)
+ */
+ public void setSecureRandomAlgorithm(String algorithm)
+ {
+ _sslParams.setSecureRandomAlgorithm(algorithm);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setSslKeyManagerFactoryAlgorithm(java.lang.String)
+ */
+ public void setSslKeyManagerFactoryAlgorithm(String algorithm)
+ {
+ _sslParams.setSslKeyManagerFactoryAlgorithm(algorithm);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setSslTrustManagerFactoryAlgorithm(java.lang.String)
+ */
+ public void setSslTrustManagerFactoryAlgorithm(String algorithm)
+ {
+ _sslParams.setSslTrustManagerFactoryAlgorithm(algorithm);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststore(java.lang.String)
+ */
+ public void setTruststore(String truststore)
+ {
+ _sslParams.setTruststore(truststore);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setTruststoreType(java.lang.String)
+ */
+ public void setTruststoreType(String truststoreType)
+ {
+ _sslParams.setTruststoreType(truststoreType);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
+ */
+ public void setSslContext(SSLContext sslContext)
+ {
+ _sslParams.setSslContext(sslContext);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
+ */
+ public SSLContext getSslContext()
+ {
+ return _sslParams.getSslContext();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * By default, we're confidential, given we speak SSL. But, if we've been
+ * told about an confidential port, and said port is not our port, then
+ * we're not. This allows separation of listeners providing INTEGRAL versus
+ * CONFIDENTIAL constraints, such as one SSL listener configured to require
+ * client certs providing CONFIDENTIAL, whereas another SSL listener not
+ * requiring client certs providing mere INTEGRAL constraints.
+ */
+ @Override
+ public boolean isConfidential(Request request)
+ {
+ final int confidentialPort=getConfidentialPort();
+ return confidentialPort==0||confidentialPort==request.getServerPort();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * By default, we're integral, given we speak SSL. But, if we've been told
+ * about an integral port, and said port is not our port, then we're not.
+ * This allows separation of listeners providing INTEGRAL versus
+ * CONFIDENTIAL constraints, such as one SSL listener configured to require
+ * client certs providing CONFIDENTIAL, whereas another SSL listener not
+ * requiring client certs providing mere INTEGRAL constraints.
+ */
+ @Override
+ public boolean isIntegral(Request request)
+ {
+ final int integralPort=getIntegralPort();
+ return integralPort==0||integralPort==request.getServerPort();
+ }
+
+ /* ------------------------------------------------------------------------------- */
+ @Override
+ protected SelectChannelEndPoint newEndPoint(SocketChannel channel, SelectSet selectSet, SelectionKey key) throws IOException
+ {
+ SslSelectChannelEndPoint endp = new SslSelectChannelEndPoint(_sslBuffers,channel,selectSet,key,createSSLEngine(), SslSelectChannelConnector.this._maxIdleTime);
+ endp.setAllowRenegotiate(_sslParams.isAllowRenegotiate());
+ return endp;
+ }
+
+ /* ------------------------------------------------------------------------------- */
+ @Override
+ protected Connection newConnection(SocketChannel channel, SelectChannelEndPoint endpoint)
+ {
+ HttpConnection connection=(HttpConnection)super.newConnection(channel,endpoint);
+ ((HttpParser)connection.getParser()).setForceContentBuffer(true);
+ return connection;
+ }
+
+ /* ------------------------------------------------------------ */
+ protected SSLEngine createSSLEngine() throws IOException
+ {
+ SSLEngine engine = null;
+ try
+ {
+
+ }
+ catch (Exception e)
+ {
+ Log.warn("Error creating sslEngine -- closing this connector",e);
+ close();
+ throw new IllegalStateException(e);
+ }
+ return engine;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStart()
+ */
+ @Override
+ protected void doStart() throws Exception
+ {
+ _sslParams.createSSLContext(); // called here to prevent exception wrapping
+
+ SSLEngine sslEngine = _sslParams.getSslContext().createSSLEngine();
+
+ sslEngine.setUseClientMode(false);
+ sslEngine.setWantClientAuth(_sslParams.getWantClientAuth());
+ sslEngine.setNeedClientAuth(_sslParams.getNeedClientAuth());
+
+ sslEngine.setEnabledCipherSuites(_sslParams.selectCipherSuites(
+ sslEngine.getEnabledCipherSuites(),
+ sslEngine.getSupportedCipherSuites()));
+
+ SSLSession sslSession = sslEngine.getSession();
+
+ ThreadLocalBuffers buffers = new ThreadLocalBuffers()
+ {
+ @Override
+ protected Buffer newBuffer(int size)
+ {
+ if (getUseDirectBuffers())
+ return new DirectNIOBuffer(size);
+ return new IndirectNIOBuffer(size);
+ }
+ @Override
+ protected Buffer newHeader(int size)
+ {
+ if (getUseDirectBuffers())
+ return new DirectNIOBuffer(size);
+ return new IndirectNIOBuffer(size);
+ }
+ @Override
+ protected boolean isHeader(Buffer buffer)
+ {
+ return true;
+ }
+ };
+ buffers.setBufferSize(sslSession.getApplicationBufferSize());
+ buffers.setHeaderSize(sslSession.getApplicationBufferSize());
+ _sslBuffers=buffers;
+
+ if (getRequestHeaderSize()<sslSession.getApplicationBufferSize())
+ setRequestHeaderSize(sslSession.getApplicationBufferSize());
+ if (getRequestBufferSize()<sslSession.getApplicationBufferSize())
+ setRequestBufferSize(sslSession.getApplicationBufferSize());
+
+ super.doStart();
+ }
+
+ public Buffers getSslBuffers()
+ {
+ return _sslBuffers;
+ }
+}
diff --git a/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslSocketConnector.java b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslSocketConnector.java
new file mode 100644
index 0000000..a441329
--- /dev/null
+++ b/jetty-exssl/src/main/java/org/eclipse/jetty/exssl/SslSocketConnector.java
@@ -0,0 +1,527 @@
+// ========================================================================
+// Copyright (c) 2000-2009 Mort Bay Consulting Pty. Ltd.
+// ------------------------------------------------------------------------
+// All rights reserved. This program and the accompanying materials
+// are made available under the terms of the Eclipse Public License v1.0
+// and Apache License v2.0 which accompanies this distribution.
+// The Eclipse Public License is available at
+// http://www.eclipse.org/legal/epl-v10.html
+// The Apache License v2.0 is available at
+// http://www.opensource.org/licenses/apache2.0.php
+// You may elect to redistribute this code under either of these licenses.
+// ========================================================================
+
+package org.eclipse.jetty.exssl;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+import javax.net.ssl.HandshakeCompletedEvent;
+import javax.net.ssl.HandshakeCompletedListener;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLServerSocket;
+import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
+
+import org.eclipse.jetty.http.HttpSchemes;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.io.bio.SocketEndPoint;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.bio.SocketConnector;
+import org.eclipse.jetty.server.ssl.SslCertificates;
+import org.eclipse.jetty.server.ssl.SslConnector;
+import org.eclipse.jetty.util.log.Log;
+
+/* ------------------------------------------------------------ */
+/**
+ * SSL Socket Connector.
+ *
+ * This specialization of SocketConnector is an abstract listener that can be used as the basis for a
+ * specific JSSE listener.
+ *
+ * The original of this class was heavily based on the work from Court Demas, which in turn is
+ * based on the work from Forge Research. Since JSSE, this class has evolved significantly from
+ * that early work.
+ *
+ * @org.apache.xbean.XBean element="sslSocketConnector" description="Creates an ssl socket connector"
+ *
+ *
+ */
+public class SslSocketConnector extends SocketConnector implements SslConnector
+{
+ private final SslParameters _sslParams;
+ private int _handshakeTimeout = 0; //0 means use maxIdleTime
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Constructor.
+ */
+ public SslSocketConnector()
+ {
+ this(new SslParameters());
+ }
+
+ public SslSocketConnector(SslParameters sslParams)
+ {
+ _sslParams = sslParams;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @return True if SSL re-negotiation is allowed (default false)
+ */
+ public boolean isAllowRenegotiate()
+ {
+ return _sslParams.isAllowRenegotiate();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set if SSL re-negotiation is allowed. CVE-2009-3555 discovered
+ * a vulnerability in SSL/TLS with re-negotiation. If your JVM
+ * does not have CVE-2009-3555 fixed, then re-negotiation should
+ * not be allowed.
+ * @param allowRenegotiate true if re-negotiation is allowed (default false)
+ */
+ public void setAllowRenegotiate(boolean allowRenegotiate)
+ {
+ _sslParams.setAllowRenegotiate(allowRenegotiate);
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ public void accept(int acceptorID)
+ throws IOException, InterruptedException
+ {
+ Socket socket = _serverSocket.accept();
+ configure(socket);
+
+ ConnectorEndPoint connection=new SslConnectorEndPoint(socket);
+ connection.dispatch();
+ }
+
+ /* ------------------------------------------------------------ */
+ @Override
+ protected void configure(Socket socket)
+ throws IOException
+ {
+ super.configure(socket);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Allow the Listener a chance to customise the request. before the server does its stuff. <br>
+ * This allows the required attributes to be set for SSL requests. <br>
+ * The requirements of the Servlet specs are:
+ * <ul>
+ * <li> an attribute named "javax.servlet.request.ssl_id" of type String (since Spec 3.0).</li>
+ * <li> an attribute named "javax.servlet.request.cipher_suite" of type String.</li>
+ * <li> an attribute named "javax.servlet.request.key_size" of type Integer.</li>
+ * <li> an attribute named "javax.servlet.request.X509Certificate" of type
+ * java.security.cert.X509Certificate[]. This is an array of objects of type X509Certificate,
+ * the order of this array is defined as being in ascending order of trust. The first
+ * certificate in the chain is the one set by the client, the next is the one used to
+ * authenticate the first, and so on. </li>
+ * </ul>
+ *
+ * @param endpoint The Socket the request arrived on.
+ * This should be a {@link SocketEndPoint} wrapping a {@link SSLSocket}.
+ * @param request HttpRequest to be customised.
+ */
+ @Override
+ public void customize(EndPoint endpoint, Request request)
+ throws IOException
+ {
+ super.customize(endpoint, request);
+ request.setScheme(HttpSchemes.HTTPS);
+
+ SocketEndPoint socket_end_point = (SocketEndPoint)endpoint;
+ SSLSocket sslSocket = (SSLSocket)socket_end_point.getTransport();
+ SSLSession sslSession = sslSocket.getSession();
+
+ SslCertificates.customize(sslSession,endpoint,request);
+ }
+
+ /* ------------------------------------------------------------ */
+ public String[] getExcludeCipherSuites() {
+ return _sslParams.getExcludeCipherSuites();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String[] getIncludeCipherSuites()
+ {
+ return _sslParams.getIncludeCipherSuites();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getKeystore()
+ {
+ return _sslParams.getKeystore();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getKeystoreType()
+ {
+ return _sslParams.getKeystoreType();
+ }
+
+ /* ------------------------------------------------------------ */
+ public boolean getNeedClientAuth()
+ {
+ return _sslParams.getNeedClientAuth();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getProtocol()
+ {
+ return _sslParams.getProtocol();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getProvider() {
+ return _sslParams.getProvider();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getSecureRandomAlgorithm()
+ {
+ return _sslParams.getSecureRandomAlgorithm();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getSslKeyManagerFactoryAlgorithm()
+ {
+ return _sslParams.getSslKeyManagerFactoryAlgorithm();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getSslTrustManagerFactoryAlgorithm()
+ {
+ return _sslParams.getSslTrustManagerFactoryAlgorithm();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getTruststore()
+ {
+ return _sslParams.getTruststore();
+ }
+
+ /* ------------------------------------------------------------ */
+ public String getTruststoreType()
+ {
+ return _sslParams.getTruststoreType();
+ }
+
+ /* ------------------------------------------------------------ */
+ public boolean getWantClientAuth()
+ {
+ return _sslParams.getWantClientAuth();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * By default, we're confidential, given we speak SSL. But, if we've been told about an
+ * confidential port, and said port is not our port, then we're not. This allows separation of
+ * listeners providing INTEGRAL versus CONFIDENTIAL constraints, such as one SSL listener
+ * configured to require client certs providing CONFIDENTIAL, whereas another SSL listener not
+ * requiring client certs providing mere INTEGRAL constraints.
+ */
+ @Override
+ public boolean isConfidential(Request request)
+ {
+ final int confidentialPort = getConfidentialPort();
+ return confidentialPort == 0 || confidentialPort == request.getServerPort();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * By default, we're integral, given we speak SSL. But, if we've been told about an integral
+ * port, and said port is not our port, then we're not. This allows separation of listeners
+ * providing INTEGRAL versus CONFIDENTIAL constraints, such as one SSL listener configured to
+ * require client certs providing CONFIDENTIAL, whereas another SSL listener not requiring
+ * client certs providing mere INTEGRAL constraints.
+ */
+ @Override
+ public boolean isIntegral(Request request)
+ {
+ final int integralPort = getIntegralPort();
+ return integralPort == 0 || integralPort == request.getServerPort();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.nio.SelectChannelConnector#doStart()
+ */
+ @Override
+ protected void doStart() throws Exception
+ {
+ _sslParams.createSSLContext(); // called here to prevent exception wrapping
+
+ super.doStart();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param host The host name that this server should listen on
+ * @param port the port that this server should listen on
+ * @param backlog See {@link ServerSocket#bind(java.net.SocketAddress, int)}
+ * @return A new {@link ServerSocket socket object} bound to the supplied address with all other
+ * settings as per the current configuration of this connector.
+ * @see #setWantClientAuth(boolean)
+ * @see #setNeedClientAuth(boolean)
+ * @exception IOException
+ */
+ @Override
+ protected ServerSocket newServerSocket(String host, int port,int backlog) throws IOException
+ {
+ SSLServerSocketFactory factory = _sslParams.getSslContext().getServerSocketFactory();
+
+ SSLServerSocket socket =
+ (SSLServerSocket) (host==null ?
+ factory.createServerSocket(port,backlog):
+ factory.createServerSocket(port,backlog,InetAddress.getByName(host)));
+
+ socket.setWantClientAuth(_sslParams.getWantClientAuth());
+ socket.setNeedClientAuth(_sslParams.getNeedClientAuth());
+
+ socket.setEnabledCipherSuites(_sslParams.selectCipherSuites(
+ socket.getEnabledCipherSuites(),
+ socket.getSupportedCipherSuites()));
+ return socket;
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ *
+ */
+ public void setExcludeCipherSuites(String[] cipherSuites)
+ {
+ _sslParams.setExcludeCipherSuites(cipherSuites);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setIncludeCipherSuites(String[] cipherSuites)
+ {
+ _sslParams.setIncludeCipherSuites(cipherSuites);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setKeyPassword(String password)
+ {
+ _sslParams.setKeyPassword(password);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @param keystore The resource path to the keystore, or null for built in keystores.
+ */
+ public void setKeystore(String keystore)
+ {
+ _sslParams.setKeystore(keystore);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setKeystoreType(String keystoreType)
+ {
+ _sslParams.setKeystoreType(keystoreType);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the value of the needClientAuth property
+ *
+ * @param needClientAuth true iff we require client certificate authentication.
+ */
+ public void setNeedClientAuth(boolean needClientAuth)
+ {
+ _sslParams.setNeedClientAuth(needClientAuth);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setPassword(String password)
+ {
+ _sslParams.setPassword(password);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setTrustPassword(String password)
+ {
+ _sslParams.setTrustPassword(password);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setProtocol(String protocol)
+ {
+ _sslParams.setProtocol(protocol);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setProvider(String provider) {
+ _sslParams.setProvider(provider);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setSecureRandomAlgorithm(String algorithm)
+ {
+ _sslParams.setSecureRandomAlgorithm(algorithm);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setSslKeyManagerFactoryAlgorithm(String algorithm)
+ {
+ _sslParams.setSslKeyManagerFactoryAlgorithm(algorithm);
+ }
+
+ /* ------------------------------------------------------------ */
+ public void setSslTrustManagerFactoryAlgorithm(String algorithm)
+ {
+ _sslParams.setSslTrustManagerFactoryAlgorithm(algorithm);
+ }
+
+
+ public void setTruststore(String truststore)
+ {
+ _sslParams.setTruststore(truststore);
+ }
+
+
+ public void setTruststoreType(String truststoreType)
+ {
+ _sslParams.setTruststoreType(truststoreType);
+ }
+
+ public void setSslContext(SSLContext sslContext)
+ {
+ _sslParams.setSslContext(sslContext);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * @see org.eclipse.jetty.server.ssl.SslConnector#setSslContext(javax.net.ssl.SSLContext)
+ */
+ public SSLContext getSslContext()
+ {
+ return _sslParams.getSslContext();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the value of the _wantClientAuth property. This property is used
+ * internally when opening server sockets.
+ *
+ * @param wantClientAuth true if we want client certificate authentication.
+ * @see SSLServerSocket#setWantClientAuth
+ */
+ public void setWantClientAuth(boolean wantClientAuth)
+ {
+ _sslParams.setWantClientAuth(wantClientAuth);
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Set the time in milliseconds for so_timeout during ssl handshaking
+ * @param msec a non-zero value will be used to set so_timeout during
+ * ssl handshakes. A zero value means the maxIdleTime is used instead.
+ */
+ public void setHandshakeTimeout (int msec)
+ {
+ _handshakeTimeout = msec;
+ }
+
+
+ /* ------------------------------------------------------------ */
+ public int getHandshakeTimeout ()
+ {
+ return _handshakeTimeout;
+ }
+
+ /* ------------------------------------------------------------ */
+ public class SslConnectorEndPoint extends ConnectorEndPoint
+ {
+ public SslConnectorEndPoint(Socket socket) throws IOException
+ {
+ super(socket);
+ }
+
+ @Override
+ public void shutdownOutput() throws IOException
+ {
+ close();
+ }
+
+ @Override
+ public void run()
+ {
+ try
+ {
+ int handshakeTimeout = getHandshakeTimeout();
+ int oldTimeout = _socket.getSoTimeout();
+ if (handshakeTimeout > 0)
+ _socket.setSoTimeout(handshakeTimeout);
+
+ final SSLSocket ssl=(SSLSocket)_socket;
+ ssl.addHandshakeCompletedListener(new HandshakeCompletedListener()
+ {
+ boolean handshook=false;
+ public void handshakeCompleted(HandshakeCompletedEvent event)
+ {
+ if (handshook)
+ {
+ if (!_sslParams.isAllowRenegotiate())
+ {
+ Log.warn("SSL renegotiate denied: "+ssl);
+ try{ssl.close();}catch(IOException e){Log.warn(e);}
+ }
+ }
+ else
+ handshook=true;
+ }
+ });
+ ssl.startHandshake();
+
+ if (handshakeTimeout>0)
+ _socket.setSoTimeout(oldTimeout);
+
+ super.run();
+ }
+ catch (SSLException e)
+ {
+ Log.debug(e);
+ try{close();}
+ catch(IOException e2){Log.ignore(e2);}
+ }
+ catch (IOException e)
+ {
+ Log.debug(e);
+ try{close();}
+ catch(IOException e2){Log.ignore(e2);}
+ }
+ }
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Unsupported.
+ *
+ * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
+ */
+ public String getAlgorithm()
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ /* ------------------------------------------------------------ */
+ /**
+ * Unsupported.
+ *
+ * TODO: we should remove this as it is no longer an overridden method from SslConnector (like it was in the past)
+ */
+ public void setAlgorithm(String algorithm)
+ {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/CertificateValidationTestBase.java b/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/CertificateValidationTestBase.java
index 4dfa494..da25770 100644
--- a/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/CertificateValidationTestBase.java
+++ b/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/CertificateValidationTestBase.java
@@ -1,9 +1,11 @@
package org.eclipse.jetty.exssl;
import java.io.File;
+import java.lang.reflect.Constructor;
import java.security.cert.CertificateException;
import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.ssl.SslConnector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.After;
import org.junit.Test;
@@ -11,7 +13,7 @@
public abstract class CertificateValidationTestBase
{
protected Server _server;
- protected EnhancedSslConnector _connector;
+ protected Class<? extends SslConnector> _klass;
@After
public void tearDown()
@@ -19,7 +21,6 @@
try
{
_server.stop();
- _connector = null;
_server = null;
}
catch (Exception ex) {}
@@ -31,17 +32,21 @@
String trustpath = new File(System.getProperty("java.home"),"./lib/security/cacerts").getAbsolutePath();
String crlpath = MavenTestingUtils.getTestResourceFile("crlfile.pem").getAbsolutePath();
- _connector.setPort(0);
- _connector.setValidateCert(true);
- _connector.setKeystore(keypath);
- _connector.setPassword("webtide");
- _connector.setKeyPassword("webtide");
- _connector.setTruststore(trustpath);
- _connector.setTrustPassword("changeit");
- _connector.setCrlPath(crlpath);
+ SslParameters sslParams = new SslParameters();
+ sslParams.setValidateCerts(true);
+ sslParams.setKeystore(keypath);
+ sslParams.setPassword("webtide");
+ sslParams.setKeyPassword("webtide");
+ sslParams.setTruststore(trustpath);
+ sslParams.setTrustPassword("changeit");
+ sslParams.setCrlPath(crlpath);
+ Constructor<? extends SslConnector> constructor = _klass.getConstructor(SslParameters.class);
+ SslConnector connector = constructor.newInstance(sslParams);
+ connector.setPort(0);
+
_server = new Server();
- _server.addConnector(_connector);
+ _server.addConnector(connector);
_server.start();
Thread.sleep(1000);
diff --git a/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/SslSelectChannelValidationTest.java b/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/SslSelectChannelValidationTest.java
index f02c595..56fadd6 100644
--- a/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/SslSelectChannelValidationTest.java
+++ b/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/SslSelectChannelValidationTest.java
@@ -1,13 +1,12 @@
package org.eclipse.jetty.exssl;
import org.junit.Before;
-import org.junit.Test;
public class SslSelectChannelValidationTest extends CertificateValidationTestBase
{
@Before
public void setUp()
{
- _connector = new EnhancedSslSelectChannelConnector();
+ _klass = SslSelectChannelConnector.class;
}
}
diff --git a/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/SslSocketValidationTest.java b/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/SslSocketValidationTest.java
index 20b67cd..5337d27 100644
--- a/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/SslSocketValidationTest.java
+++ b/jetty-exssl/src/test/java/org/eclipse/jetty/exssl/SslSocketValidationTest.java
@@ -1,13 +1,12 @@
package org.eclipse.jetty.exssl;
import org.junit.Before;
-import org.junit.Test;
public class SslSocketValidationTest extends CertificateValidationTestBase
{
@Before
public void setUp()
{
- _connector = new EnhancedSslSocketConnector();
+ _klass = SslSocketConnector.class;
}
}