Commit b73fcc35 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Added a different truststore for c2s. This is required when validating client certs.

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@9565 b35dd754-fafc-0310-a699-88a17e54d16e
parent ca7cc1b0
...@@ -91,6 +91,7 @@ rm -rf $RPM_BUILD_ROOT ...@@ -91,6 +91,7 @@ rm -rf $RPM_BUILD_ROOT
%config(noreplace) %{confdir}/openfire.xml %config(noreplace) %{confdir}/openfire.xml
%config(noreplace) %{confdir}/security/keystore %config(noreplace) %{confdir}/security/keystore
%config(noreplace) %{confdir}/security/truststore %config(noreplace) %{confdir}/security/truststore
%config(noreplace) %{confdir}/security/client.truststore
%dir %{homedir}/lib %dir %{homedir}/lib
%{homedir}/lib/*.jar %{homedir}/lib/*.jar
%{homedir}/logs %{homedir}/logs
......
...@@ -115,6 +115,7 @@ chown -R daemon:daemon %{homedir} ...@@ -115,6 +115,7 @@ chown -R daemon:daemon %{homedir}
%dir %{homedir}/resources/security %dir %{homedir}/resources/security
%config(noreplace) %{homedir}/resources/security/keystore %config(noreplace) %{homedir}/resources/security/keystore
%config(noreplace) %{homedir}/resources/security/truststore %config(noreplace) %{homedir}/resources/security/truststore
%config(noreplace) %{homedir}/resources/security/client.truststore
%doc %{homedir}/documentation %doc %{homedir}/documentation
%doc %{homedir}/LICENSE.html %doc %{homedir}/LICENSE.html
%doc %{homedir}/README.html %doc %{homedir}/README.html
......
...@@ -82,8 +82,7 @@ ...@@ -82,8 +82,7 @@
<li>Copy the <i>embedded-db</i> directory from the backup to the installation directory.</li> <li>Copy the <i>embedded-db</i> directory from the backup to the installation directory.</li>
<li>Copy the <i>enterprise</i> directory from the backup to the installation directory, if it exists.</li> <li>Copy the <i>enterprise</i> directory from the backup to the installation directory, if it exists.</li>
<li>Copy the <i>plugins</i> directory from the backup to the installation directory except for _plugins/admin_.</li> <li>Copy the <i>plugins</i> directory from the backup to the installation directory except for _plugins/admin_.</li>
<li>Copy the <i>resources/security/keystore</i> file from the backup to the installation directory.</li> <li>Copy modified files located in <i>resources/security</i> from the backup to the installation directory.</li>
<li>Copy the <i>resources/security/truststore</i> file from the backup to the installation directory if you modified this file.</li>
<li>Start Openfire</li> <li>Start Openfire</li>
</ol> </ol>
</ul> </ul>
......
...@@ -104,9 +104,9 @@ public class AdminConsolePlugin implements Plugin { ...@@ -104,9 +104,9 @@ public class AdminConsolePlugin implements Plugin {
httpsConnector.setHost(bindInterface); httpsConnector.setHost(bindInterface);
httpsConnector.setPort(adminSecurePort); httpsConnector.setPort(adminSecurePort);
httpsConnector.setTrustPassword(SSLConfig.getTrustPassword()); httpsConnector.setTrustPassword(SSLConfig.gets2sTrustPassword());
httpsConnector.setTruststoreType(SSLConfig.getStoreType()); httpsConnector.setTruststoreType(SSLConfig.getStoreType());
httpsConnector.setTruststore(SSLConfig.getTruststoreLocation()); httpsConnector.setTruststore(SSLConfig.gets2sTruststoreLocation());
httpsConnector.setNeedClientAuth(false); httpsConnector.setNeedClientAuth(false);
httpsConnector.setWantClientAuth(false); httpsConnector.setWantClientAuth(false);
......
...@@ -141,9 +141,9 @@ public final class HttpBindManager { ...@@ -141,9 +141,9 @@ public final class HttpBindManager {
sslConnector.setHost(getBindInterface()); sslConnector.setHost(getBindInterface());
sslConnector.setPort(securePort); sslConnector.setPort(securePort);
sslConnector.setTrustPassword(SSLConfig.getTrustPassword()); sslConnector.setTrustPassword(SSLConfig.getc2sTrustPassword());
sslConnector.setTruststoreType(SSLConfig.getStoreType()); sslConnector.setTruststoreType(SSLConfig.getStoreType());
sslConnector.setTruststore(SSLConfig.getTruststoreLocation()); sslConnector.setTruststore(SSLConfig.getc2sTruststoreLocation());
sslConnector.setNeedClientAuth(false); sslConnector.setNeedClientAuth(false);
sslConnector.setWantClientAuth(false); sslConnector.setWantClientAuth(false);
......
...@@ -35,15 +35,25 @@ import java.util.List; ...@@ -35,15 +35,25 @@ import java.util.List;
*/ */
public class SSLConfig { public class SSLConfig {
private static SSLServerSocketFactory sslFactory; private static SSLServerSocketFactory s2sFactory;
private static SSLServerSocketFactory c2sFactory;
private static String storeType;
private static SSLContext s2sContext;
private static SSLContext c2sContext;
private static KeyStore keyStore; private static KeyStore keyStore;
private static String keypass;
private static KeyStore trustStore;
private static String trustpass;
private static String keyStoreLocation; private static String keyStoreLocation;
private static String trustStoreLocation; private static String keypass;
private static String storeType;
private static SSLContext sslContext; private static KeyStore s2sTrustStore;
private static String s2sTrustStoreLocation;
private static String s2sTrustpass;
private static KeyStore c2sTrustStore;
private static String c2sTrustStoreLocation;
private static String c2sTrustpass;
private SSLConfig() { private SSLConfig() {
} }
...@@ -61,34 +71,70 @@ public class SSLConfig { ...@@ -61,34 +71,70 @@ public class SSLConfig {
keypass = JiveGlobals.getProperty("xmpp.socket.ssl.keypass", "changeit"); keypass = JiveGlobals.getProperty("xmpp.socket.ssl.keypass", "changeit");
keypass = keypass.trim(); keypass = keypass.trim();
// Get the truststore location; default at security/truststore // Get the truststore location for c2s connections
trustStoreLocation = JiveGlobals.getProperty("xmpp.socket.ssl.truststore", c2sTrustStoreLocation = JiveGlobals.getProperty("xmpp.socket.ssl.client.truststore",
"resources" + File.separator + "security" + File.separator + "client.truststore");
c2sTrustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + c2sTrustStoreLocation;
c2sTrustpass = JiveGlobals.getProperty("xmpp.socket.ssl.client.trustpass", "changeit");
c2sTrustpass = c2sTrustpass.trim();
// Get the truststore location for s2s connections
s2sTrustStoreLocation = JiveGlobals.getProperty("xmpp.socket.ssl.truststore",
"resources" + File.separator + "security" + File.separator + "truststore"); "resources" + File.separator + "security" + File.separator + "truststore");
trustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + trustStoreLocation; s2sTrustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + s2sTrustStoreLocation;
// Get the truststore passwprd; default is "changeit". // Get the truststore passwprd; default is "changeit".
trustpass = JiveGlobals.getProperty("xmpp.socket.ssl.trustpass", "changeit"); s2sTrustpass = JiveGlobals.getProperty("xmpp.socket.ssl.trustpass", "changeit");
trustpass = trustpass.trim(); s2sTrustpass = s2sTrustpass.trim();
// Load s2s keystore and trusstore
try { try {
keyStore = KeyStore.getInstance(storeType); keyStore = KeyStore.getInstance(storeType);
keyStore.load(new FileInputStream(keyStoreLocation), keypass.toCharArray()); keyStore.load(new FileInputStream(keyStoreLocation), keypass.toCharArray());
trustStore = KeyStore.getInstance(storeType); s2sTrustStore = KeyStore.getInstance(storeType);
trustStore.load(new FileInputStream(trustStoreLocation), trustpass.toCharArray()); s2sTrustStore.load(new FileInputStream(s2sTrustStoreLocation), s2sTrustpass.toCharArray());
resetFactory();
} }
catch (Exception e) { catch (Exception e) {
Log.error("SSLConfig startup problem.\n" + Log.error("SSLConfig startup problem.\n" +
" storeType: [" + storeType + "]\n" + " storeType: [" + storeType + "]\n" +
" keyStoreLocation: [" + keyStoreLocation + "]\n" + " keyStoreLocation: [" + keyStoreLocation + "]\n" +
" keypass: [" + keypass + "]\n" + " keypass: [" + keypass + "]\n" +
" trustStoreLocation: [" + trustStoreLocation+ "]\n" + " s2sTrustStoreLocation: [" + s2sTrustStoreLocation + "]\n" +
" trustpass: [" + trustpass + "]", e); " s2sTrustpass: [" + s2sTrustpass + "]\n");
keyStore = null; keyStore = null;
trustStore = null; s2sTrustStore = null;
sslFactory = null; s2sFactory = null;
}
// Load c2s trusstore
try {
if (s2sTrustStoreLocation.equals(c2sTrustStoreLocation)) {
c2sTrustStore = s2sTrustStore;
c2sTrustpass = s2sTrustpass;
}
else {
c2sTrustStore = KeyStore.getInstance(storeType);
c2sTrustStore.load(new FileInputStream(c2sTrustStoreLocation), c2sTrustpass.toCharArray());
}
}
catch (Exception e) {
try {
c2sTrustStore = KeyStore.getInstance(storeType);
c2sTrustStore.load(null, c2sTrustpass.toCharArray());
} }
catch (Exception ex) {
Log.error("SSLConfig startup problem.\n" +
" storeType: [" + storeType + "]\n" +
" c2sTrustStoreLocation: [" + c2sTrustStoreLocation + "]\n" +
" c2sTrustPass: [" + c2sTrustpass + "]", e);
c2sTrustStore = null;
c2sFactory = null;
}
}
resetFactory();
// Reset ssl factoty when certificates are modified // Reset ssl factoty when certificates are modified
CertificateManager.addListener(new CertificateEventListener() { CertificateManager.addListener(new CertificateEventListener() {
...@@ -96,9 +142,11 @@ public class SSLConfig { ...@@ -96,9 +142,11 @@ public class SSLConfig {
public void certificateCreated(KeyStore keyStore, String alias, X509Certificate cert) { public void certificateCreated(KeyStore keyStore, String alias, X509Certificate cert) {
resetFactory(); resetFactory();
} }
public void certificateDeleted(KeyStore keyStore, String alias) { public void certificateDeleted(KeyStore keyStore, String alias) {
resetFactory(); resetFactory();
} }
public void certificateSigned(KeyStore keyStore, String alias, List<X509Certificate> certificates) { public void certificateSigned(KeyStore keyStore, String alias, List<X509Certificate> certificates) {
resetFactory(); resetFactory();
} }
...@@ -109,63 +157,109 @@ public class SSLConfig { ...@@ -109,63 +157,109 @@ public class SSLConfig {
try { try {
String algorithm = JiveGlobals.getProperty("xmpp.socket.ssl.algorithm", "TLS"); String algorithm = JiveGlobals.getProperty("xmpp.socket.ssl.algorithm", "TLS");
sslContext = SSLContext.getInstance(algorithm); s2sContext = SSLContext.getInstance(algorithm);
c2sContext = SSLContext.getInstance(algorithm);
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(keyStore, SSLConfig.getKeyPassword().toCharArray()); keyFactory.init(keyStore, SSLConfig.getKeyPassword().toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); TrustManagerFactory s2sTrustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(trustStore); s2sTrustFactory.init(s2sTrustStore);
s2sContext.init(keyFactory.getKeyManagers(),
s2sTrustFactory.getTrustManagers(),
new java.security.SecureRandom());
s2sFactory = s2sContext.getServerSocketFactory();
if (s2sTrustStore == c2sTrustStore) {
c2sContext = s2sContext;
c2sFactory = s2sFactory;
}
else {
TrustManagerFactory c2sTrustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
c2sTrustFactory.init(c2sTrustStore);
sslContext.init(keyFactory.getKeyManagers(), c2sContext.init(keyFactory.getKeyManagers(),
trustFactory.getTrustManagers(), s2sTrustFactory.getTrustManagers(),
new java.security.SecureRandom()); new java.security.SecureRandom());
sslFactory = sslContext.getServerSocketFactory(); c2sFactory = c2sContext.getServerSocketFactory();
}
} }
catch (Exception e) { catch (Exception e) {
Log.error("SSLConfig factory setup problem.\n" + Log.error("SSLConfig factory setup problem.\n" +
" storeType: [" + storeType + "]\n" + " storeType: [" + storeType + "]\n" +
" keyStoreLocation: [" + keyStoreLocation + "]\n" + " keyStoreLocation: [" + keyStoreLocation + "]\n" +
" keypass: [" + keypass + "]\n" + " keypass: [" + keypass + "]\n" +
" trustStoreLocation: [" + trustStoreLocation+ "]\n" + " s2sTrustStoreLocation: [" + s2sTrustStoreLocation+ "]\n" +
" trustpass: [" + trustpass + "]", e); " s2sTrustpass: [" + s2sTrustpass + "]" +
" c2sTrustStoreLocation: [" + c2sTrustStoreLocation + "]\n" +
" c2sTrustpass: [" + c2sTrustpass + "]", e);
keyStore = null; keyStore = null;
trustStore = null; s2sTrustStore = null;
sslFactory = null; c2sTrustStore = null;
s2sFactory = null;
c2sFactory = null;
} }
} }
/**
* Get the Key Store password
*
* @return the key store password
*/
public static String getKeyPassword() { public static String getKeyPassword() {
return keypass; return keypass;
} }
public static String getTrustPassword() { /**
return trustpass; * Return the Trust Store password for s2s connections.
*
* @return the s2s trust store password.
*/
public static String gets2sTrustPassword() {
return s2sTrustpass;
}
/**
* Return the Trust Store password for c2s connections.
*
* @return the c2s trust store password.
*/
public static String getc2sTrustPassword() {
return c2sTrustpass;
} }
public static String[] getDefaultCipherSuites() { public static String[] getDefaultCipherSuites() {
String[] suites; String[] suites;
if (sslFactory == null) { if (s2sFactory == null) {
suites = new String[]{}; suites = new String[]{};
} }
else { else {
suites = sslFactory.getDefaultCipherSuites(); suites = s2sFactory.getDefaultCipherSuites();
} }
return suites; return suites;
} }
public static String[] getSpportedCipherSuites() { public static String[] getSupportedCipherSuites() {
String[] suites; String[] suites;
if (sslFactory == null) { if (s2sFactory == null) {
suites = new String[]{}; suites = new String[]{};
} }
else { else {
suites = sslFactory.getSupportedCipherSuites(); suites = s2sFactory.getSupportedCipherSuites();
} }
return suites; return suites;
} }
/**
* Get the Key Store
*
* @return the Key Store
*/
public static KeyStore getKeyStore() throws IOException { public static KeyStore getKeyStore() throws IOException {
if (keyStore == null) { if (keyStore == null) {
throw new IOException(); throw new IOException();
...@@ -173,17 +267,40 @@ public class SSLConfig { ...@@ -173,17 +267,40 @@ public class SSLConfig {
return keyStore; return keyStore;
} }
public static KeyStore getTrustStore() throws IOException { /**
if (trustStore == null) { * Get the Trust Store for s2s connections
*
* @return the s2s Trust Store
*/
public static KeyStore gets2sTrustStore() throws IOException {
if (s2sTrustStore == null) {
throw new IOException();
}
return s2sTrustStore;
}
/**
* Get the Trust Store for c2s connections
*
* @return the c2s Trust Store
*/
public static KeyStore getc2sTrustStore() throws IOException {
if (c2sTrustStore == null) {
throw new IOException(); throw new IOException();
} }
return trustStore; return c2sTrustStore;
} }
/**
* Save all key and trust stores.
*/
public static void saveStores() throws IOException { public static void saveStores() throws IOException {
try { try {
keyStore.store(new FileOutputStream(keyStoreLocation), keypass.toCharArray()); keyStore.store(new FileOutputStream(keyStoreLocation), keypass.toCharArray());
trustStore.store(new FileOutputStream(trustStoreLocation), trustpass.toCharArray()); s2sTrustStore.store(new FileOutputStream(s2sTrustStoreLocation), s2sTrustpass.toCharArray());
if (c2sTrustStore != s2sTrustStore) {
c2sTrustStore.store(new FileOutputStream(c2sTrustStoreLocation), c2sTrustpass.toCharArray());
}
} }
catch (IOException e) { catch (IOException e) {
throw e; throw e;
...@@ -193,33 +310,99 @@ public class SSLConfig { ...@@ -193,33 +310,99 @@ public class SSLConfig {
} }
} }
/**
* Create a ServerSocket for s2s connections
*
* @return the ServerSocket for an s2s connection
*/
public static ServerSocket createServerSocket(int port, InetAddress ifAddress) throws public static ServerSocket createServerSocket(int port, InetAddress ifAddress) throws
IOException { IOException {
if (sslFactory == null) { if (s2sFactory == null) {
throw new IOException();
}
else {
return s2sFactory.createServerSocket(port, -1, ifAddress);
}
}
/**
* Create a ServerSocket for c2s connections
*
* @return the ServerSocket for an c2s connection
*/
public static ServerSocket createc2sServerSocket(int port, InetAddress ifAddress) throws
IOException {
if (c2sFactory == null) {
throw new IOException(); throw new IOException();
} }
else { else {
return sslFactory.createServerSocket(port, -1, ifAddress); return c2sFactory.createServerSocket(port, -1, ifAddress);
} }
} }
/**
* Get the Key Store location
*
* @return the keystore location
*/
public static String getKeystoreLocation() { public static String getKeystoreLocation() {
return keyStoreLocation; return keyStoreLocation;
} }
public static String getTruststoreLocation() { /**
return trustStoreLocation; * Get the s2s Trust Store location
*
* @return the s2s Trust Store location
*/
public static String gets2sTruststoreLocation() {
return s2sTrustStoreLocation;
}
/**
* Get the c2s Trust Store location
*
* @return the c2s Trust Store location
*/
public static String getc2sTruststoreLocation() {
return c2sTrustStoreLocation;
} }
public static String getStoreType() { public static String getStoreType() {
return storeType; return storeType;
} }
/**
* Get the SSLContext for s2s connections
*
* @return the SSLContext for s2s connections
*/
public static SSLContext getSSLContext() { public static SSLContext getSSLContext() {
return sslContext; return s2sContext;
}
/**
* Get the SSLContext for c2s connections
*
* @return the SSLContext for c2s connections
*/
public static SSLContext getc2sSSLContext() {
return c2sContext;
} }
/**
* Get the SSLServerSocketFactory for s2s connections
*
* @return the SSLServerSocketFactory for s2s connections
*/
public static SSLServerSocketFactory getServerSocketFactory() { public static SSLServerSocketFactory getServerSocketFactory() {
return sslFactory; return s2sFactory;
}
/**
* Get the SSLServerSocketFactory for c2s connections
*
* @return the SSLServerSocketFactory for c2s connections
*/
public static SSLServerSocketFactory getc2sServerSocketFactory() {
return c2sFactory;
} }
} }
...@@ -76,6 +76,8 @@ public class SSLJiveTrustManagerFactory { ...@@ -76,6 +76,8 @@ public class SSLJiveTrustManagerFactory {
return trustManagers; return trustManagers;
} }
//TODO: Is this for c2s or s2s connections? Or both?
public static TrustManager[] getTrustManagers(KeyStore truststore, public static TrustManager[] getTrustManagers(KeyStore truststore,
String trustpass) { String trustpass) {
TrustManager[] trustManagers; TrustManager[] trustManagers;
...@@ -86,7 +88,7 @@ public class SSLJiveTrustManagerFactory { ...@@ -86,7 +88,7 @@ public class SSLJiveTrustManagerFactory {
TrustManagerFactory trustFactory = TrustManagerFactory TrustManagerFactory trustFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm()); .getInstance(TrustManagerFactory.getDefaultAlgorithm());
if (trustpass == null) { if (trustpass == null) {
trustpass = SSLConfig.getTrustPassword(); trustpass = SSLConfig.gets2sTrustPassword();
} }
trustFactory.init(truststore); trustFactory.init(truststore);
......
...@@ -58,6 +58,7 @@ public class TLSWrapper { ...@@ -58,6 +58,7 @@ public class TLSWrapper {
public TLSWrapper(boolean clientMode, boolean needClientAuth, String remoteServer) { public TLSWrapper(boolean clientMode, boolean needClientAuth, String remoteServer) {
boolean c2sConnection = (remoteServer == null);
if (debug) { if (debug) {
System.setProperty("javax.net.debug", "all"); System.setProperty("javax.net.debug", "all");
} }
...@@ -68,8 +69,8 @@ public class TLSWrapper { ...@@ -68,8 +69,8 @@ public class TLSWrapper {
KeyStore ksKeys = SSLConfig.getKeyStore(); KeyStore ksKeys = SSLConfig.getKeyStore();
String keypass = SSLConfig.getKeyPassword(); String keypass = SSLConfig.getKeyPassword();
KeyStore ksTrust = SSLConfig.getTrustStore(); KeyStore ksTrust = (c2sConnection ? SSLConfig.getc2sTrustStore() : SSLConfig.gets2sTrustStore());
String trustpass = SSLConfig.getTrustPassword(); String trustpass = (c2sConnection ? SSLConfig.getc2sTrustPassword() : SSLConfig.gets2sTrustPassword());
// KeyManager's decide which key material to use. // KeyManager's decide which key material to use.
KeyManager[] km = SSLJiveKeyManagerFactory.getKeyManagers(ksKeys, keypass); KeyManager[] km = SSLJiveKeyManagerFactory.getKeyManagers(ksKeys, keypass);
...@@ -77,9 +78,15 @@ public class TLSWrapper { ...@@ -77,9 +78,15 @@ public class TLSWrapper {
// TrustManager's decide whether to allow connections. // TrustManager's decide whether to allow connections.
TrustManager[] tm = SSLJiveTrustManagerFactory.getTrustManagers(ksTrust, trustpass); TrustManager[] tm = SSLJiveTrustManagerFactory.getTrustManagers(ksTrust, trustpass);
if (clientMode || needClientAuth) { if (clientMode || needClientAuth) {
if (c2sConnection) {
// Check if we can trust certificates presented by the client
tm = new TrustManager[]{new ClientTrustManager(ksTrust)};
}
else {
// Check if we can trust certificates presented by the server // Check if we can trust certificates presented by the server
tm = new TrustManager[]{new ServerTrustManager(remoteServer, ksTrust)}; tm = new TrustManager[]{new ServerTrustManager(remoteServer, ksTrust)};
} }
}
SSLContext tlsContext = SSLContext.getInstance(PROTOCOL); SSLContext tlsContext = SSLContext.getInstance(PROTOCOL);
......
...@@ -24,6 +24,7 @@ import org.jivesoftware.openfire.net.SSLConfig; ...@@ -24,6 +24,7 @@ import org.jivesoftware.openfire.net.SSLConfig;
import org.jivesoftware.openfire.net.SSLJiveKeyManagerFactory; import org.jivesoftware.openfire.net.SSLJiveKeyManagerFactory;
import org.jivesoftware.openfire.net.SSLJiveTrustManagerFactory; import org.jivesoftware.openfire.net.SSLJiveTrustManagerFactory;
import org.jivesoftware.openfire.net.ServerTrustManager; import org.jivesoftware.openfire.net.ServerTrustManager;
import org.jivesoftware.openfire.net.ClientTrustManager;
import org.jivesoftware.openfire.session.LocalSession; import org.jivesoftware.openfire.session.LocalSession;
import org.jivesoftware.openfire.session.Session; import org.jivesoftware.openfire.session.Session;
import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.JiveGlobals;
...@@ -279,21 +280,30 @@ public class NIOConnection implements Connection { ...@@ -279,21 +280,30 @@ public class NIOConnection implements Connection {
} }
public void startTLS(boolean clientMode, String remoteServer, ClientAuth authentication) throws Exception { public void startTLS(boolean clientMode, String remoteServer, ClientAuth authentication) throws Exception {
boolean c2s = (remoteServer == null);
KeyStore ksKeys = SSLConfig.getKeyStore(); KeyStore ksKeys = SSLConfig.getKeyStore();
String keypass = SSLConfig.getKeyPassword(); String keypass = SSLConfig.getKeyPassword();
KeyStore ksTrust = SSLConfig.getTrustStore(); KeyStore ksTrust = (c2s ? SSLConfig.getc2sTrustStore() : SSLConfig.gets2sTrustStore() );
String trustpass = SSLConfig.getTrustPassword(); String trustpass = (c2s ? SSLConfig.getc2sTrustPassword() : SSLConfig.gets2sTrustPassword() );
if (c2s) Log.debug("NIOConnection: startTLS: using c2s");
else Log.debug("NIOConnection: startTLS: using s2s");
// KeyManager's decide which key material to use. // KeyManager's decide which key material to use.
KeyManager[] km = SSLJiveKeyManagerFactory.getKeyManagers(ksKeys, keypass); KeyManager[] km = SSLJiveKeyManagerFactory.getKeyManagers(ksKeys, keypass);
// TrustManager's decide whether to allow connections. // TrustManager's decide whether to allow connections.
TrustManager[] tm = SSLJiveTrustManagerFactory.getTrustManagers(ksTrust, trustpass); TrustManager[] tm = SSLJiveTrustManagerFactory.getTrustManagers(ksTrust, trustpass);
if (clientMode || authentication == ClientAuth.needed || authentication == ClientAuth.wanted) { if (clientMode || authentication == ClientAuth.needed || authentication == ClientAuth.wanted) {
// We might need to verify a certificate from our peer, so get different TrustManager[]'s
if(c2s) {
// Check if we can trust certificates presented by the client
tm = new TrustManager[]{new ClientTrustManager(ksTrust)};
} else {
// Check if we can trust certificates presented by the server // Check if we can trust certificates presented by the server
tm = new TrustManager[]{new ServerTrustManager(remoteServer, ksTrust)}; tm = new TrustManager[]{new ServerTrustManager(remoteServer, ksTrust)};
} }
}
SSLContext tlsContext = SSLContext.getInstance("TLS"); SSLContext tlsContext = SSLContext.getInstance("TLS");
......
...@@ -396,7 +396,7 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana ...@@ -396,7 +396,7 @@ public class ConnectionManagerImpl extends BasicModule implements ConnectionMana
KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyFactory.init(SSLConfig.getKeyStore(), SSLConfig.getKeyPassword().toCharArray()); keyFactory.init(SSLConfig.getKeyStore(), SSLConfig.getKeyPassword().toCharArray());
TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); TrustManagerFactory trustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustFactory.init(SSLConfig.getTrustStore()); trustFactory.init(SSLConfig.getc2sTrustStore());
sslContext.init(keyFactory.getKeyManagers(), sslContext.init(keyFactory.getKeyManagers(),
trustFactory.getTrustManagers(), trustFactory.getTrustManagers(),
......
...@@ -223,17 +223,17 @@ public class CertificateManager { ...@@ -223,17 +223,17 @@ public class CertificateManager {
// Ignore // Ignore
} }
catch (Exception e) { catch (Exception e) {
Log.error("Error decoding subjectAltName", e); Log.error("CertificateManager: Error decoding subjectAltName", e);
} }
} }
// Other types are not good for XMPP so ignore them // Other types are not good for XMPP so ignore them
else if (Log.isDebugEnabled()) { else if (Log.isDebugEnabled()) {
Log.debug("SubjectAltName of invalid type found: " + certificate); Log.debug("CertificateManager: SubjectAltName of invalid type found: " + certificate.getSubjectDN());
} }
} }
} }
catch (CertificateParsingException e) { catch (CertificateParsingException e) {
Log.error("Error parsing SubjectAltName in certificate: " + certificate, e); Log.error("CertificateManager: Error parsing SubjectAltName in certificate: " + certificate.getSubjectDN(), e);
} }
return identities; return identities;
} }
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
alias = domain + "_" + index; alias = domain + "_" + index;
} }
// Import certificate // Import certificate
CertificateManager.installCert(SSLConfig.getKeyStore(), SSLConfig.getTrustStore(), CertificateManager.installCert(SSLConfig.getKeyStore(), SSLConfig.gets2sTrustStore(),
SSLConfig.getKeyPassword(), alias, new ByteArrayInputStream(privateKey.getBytes()), passPhrase, SSLConfig.getKeyPassword(), alias, new ByteArrayInputStream(privateKey.getBytes()), passPhrase,
new ByteArrayInputStream(certificate.getBytes()), true, true); new ByteArrayInputStream(certificate.getBytes()), true, true);
// Save keystore // Save keystore
......
...@@ -73,7 +73,7 @@ ...@@ -73,7 +73,7 @@
String reply = ParamUtils.getParameter(request, "reply"); String reply = ParamUtils.getParameter(request, "reply");
if (alias != null && reply != null && reply.trim().length() > 0) { if (alias != null && reply != null && reply.trim().length() > 0) {
try { try {
CertificateManager.installReply(SSLConfig.getKeyStore(), SSLConfig.getTrustStore(), CertificateManager.installReply(SSLConfig.getKeyStore(), SSLConfig.gets2sTrustStore(),
SSLConfig.getKeyPassword(), alias, new ByteArrayInputStream(reply.getBytes()), true, true); SSLConfig.getKeyPassword(), alias, new ByteArrayInputStream(reply.getBytes()), true, true);
SSLConfig.saveStores(); SSLConfig.saveStores();
response.sendRedirect("ssl-certificates.jsp?importsuccess=true"); response.sendRedirect("ssl-certificates.jsp?importsuccess=true");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment