/openfire/src/java/org/jivesoftware/openfire/net/SSLConfig.java
https://github.com/joechen2010/IM · Java · 456 lines · 283 code · 56 blank · 117 comment · 32 complexity · 8d1a31baf186ba7326a569eb736318ff MD5 · raw file
- /**
- * $RCSfile$
- * $Revision: 1217 $
- * $Date: 2005-04-11 18:11:06 -0300 (Mon, 11 Apr 2005) $
- *
- * Copyright (C) 2005-2008 Jive Software. All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package org.jivesoftware.openfire.net;
-
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.net.InetAddress;
- import java.net.ServerSocket;
- import java.security.KeyStore;
- import java.security.cert.X509Certificate;
- import java.util.List;
-
- import javax.net.ssl.KeyManagerFactory;
- import javax.net.ssl.SSLContext;
- import javax.net.ssl.SSLServerSocketFactory;
- import javax.net.ssl.TrustManagerFactory;
-
- import org.jivesoftware.util.CertificateEventListener;
- import org.jivesoftware.util.CertificateManager;
- import org.jivesoftware.util.JiveGlobals;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
- /**
- * Configuration of Openfire's SSL settings.
- *
- * @author Iain Shigeoka
- */
- public class SSLConfig {
-
- private static final Logger Log = LoggerFactory.getLogger(SSLConfig.class);
-
- 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 String keyStoreLocation;
- private static String keypass;
-
- 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() {
- }
-
- static {
- storeType = JiveGlobals.getProperty("xmpp.socket.ssl.storeType", "jks");
-
- // Get the keystore location. The default location is security/keystore
- keyStoreLocation = JiveGlobals.getProperty("xmpp.socket.ssl.keystore",
- "resources" + File.separator + "security" + File.separator + "keystore");
- keyStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + keyStoreLocation;
-
- // Get the keystore password. The default password is "changeit".
- keypass = JiveGlobals.getProperty("xmpp.socket.ssl.keypass", "changeit");
- keypass = keypass.trim();
-
- // Get the truststore location for c2s connections
- 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");
- s2sTrustStoreLocation = JiveGlobals.getHomeDirectory() + File.separator + s2sTrustStoreLocation;
-
- // Get the truststore passwprd; default is "changeit".
- s2sTrustpass = JiveGlobals.getProperty("xmpp.socket.ssl.trustpass", "changeit");
- s2sTrustpass = s2sTrustpass.trim();
-
- // Load s2s keystore
- try {
- keyStore = KeyStore.getInstance(storeType);
- keyStore.load(new FileInputStream(keyStoreLocation), keypass.toCharArray());
- }
- catch (Exception e) {
- Log.error("SSLConfig startup problem.\n" +
- " storeType: [" + storeType + "]\n" +
- " keyStoreLocation: [" + keyStoreLocation + "]\n" +
- " keypass: [" + keypass + "]\n", e);
- keyStore = null;
- s2sFactory = null;
- }
- // Load s2s trusstore
- try {
- s2sTrustStore = KeyStore.getInstance(storeType);
- s2sTrustStore.load(new FileInputStream(s2sTrustStoreLocation), s2sTrustpass.toCharArray());
- }
- catch (Exception e) {
- Log.error("SSLConfig startup problem.\n" +
- " storeType: [" + storeType + "]\n" +
- " s2sTrustStoreLocation: [" + s2sTrustStoreLocation + "]\n" +
- " s2sTrustpass: [" + s2sTrustpass + "]\n", e);
- s2sTrustStore = 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
- CertificateManager.addListener(new CertificateEventListener() {
- // Reset ssl factory since keystores have changed
- public void certificateCreated(KeyStore keyStore, String alias, X509Certificate cert) {
- resetFactory();
- }
-
- public void certificateDeleted(KeyStore keyStore, String alias) {
- resetFactory();
- }
-
- public void certificateSigned(KeyStore keyStore, String alias, List<X509Certificate> certificates) {
- resetFactory();
- }
- });
- }
-
- private static void resetFactory() {
- try {
- String algorithm = JiveGlobals.getProperty("xmpp.socket.ssl.algorithm", "TLS");
-
- s2sContext = SSLContext.getInstance(algorithm);
- c2sContext = SSLContext.getInstance(algorithm);
-
- KeyManagerFactory keyFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
- keyFactory.init(keyStore, SSLConfig.getKeyPassword().toCharArray());
-
- TrustManagerFactory s2sTrustFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
- 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);
-
- c2sContext.init(keyFactory.getKeyManagers(),
- c2sTrustFactory.getTrustManagers(),
- new java.security.SecureRandom());
-
- c2sFactory = c2sContext.getServerSocketFactory();
- }
-
- }
- catch (Exception e) {
- Log.error("SSLConfig factory setup problem.\n" +
- " storeType: [" + storeType + "]\n" +
- " keyStoreLocation: [" + keyStoreLocation + "]\n" +
- " keypass: [" + keypass + "]\n" +
- " s2sTrustStoreLocation: [" + s2sTrustStoreLocation+ "]\n" +
- " s2sTrustpass: [" + s2sTrustpass + "]" +
- " c2sTrustStoreLocation: [" + c2sTrustStoreLocation + "]\n" +
- " c2sTrustpass: [" + c2sTrustpass + "]", e);
- keyStore = null;
- s2sTrustStore = null;
- c2sTrustStore = null;
- s2sFactory = null;
- c2sFactory = null;
- }
- }
-
- /**
- * Get the Key Store password
- *
- * @return the key store password
- */
- public static String getKeyPassword() {
- return keypass;
- }
-
- /**
- * 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() {
- String[] suites;
- if (s2sFactory == null) {
- suites = new String[]{};
- }
- else {
- suites = s2sFactory.getDefaultCipherSuites();
- }
- return suites;
- }
-
- public static String[] getSupportedCipherSuites() {
- String[] suites;
- if (s2sFactory == null) {
- suites = new String[]{};
- }
- else {
- suites = s2sFactory.getSupportedCipherSuites();
- }
- return suites;
- }
-
- /**
- * Get the Key Store
- *
- * @return the Key Store
- */
- public static KeyStore getKeyStore() throws IOException {
- if (keyStore == null) {
- throw new IOException();
- }
- return keyStore;
- }
-
- /**
- * 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();
- }
- return c2sTrustStore;
- }
-
- /**
- * Initializes (wipes and recreates) the keystore, and returns the new keystore.
- *
- * @return Newly initialized keystore.
- */
- public static KeyStore initializeKeyStore() {
- try {
- keyStore = KeyStore.getInstance(storeType);
- keyStore.load(null, keypass.toCharArray());
- }
- catch (Exception e) {
- Log.error("Unable to initialize keystore: ", e);
- }
- return keyStore;
- }
-
- /**
- * Save all key and trust stores.
- */
- public static void saveStores() throws IOException {
- try {
- File keyStoreDirectory = new File(keyStoreLocation).getParentFile();
- if (!keyStoreDirectory.exists())
- keyStoreDirectory.mkdirs();
- keyStore.store(new FileOutputStream(keyStoreLocation), keypass.toCharArray());
-
- if (s2sTrustStore != null) {
- File s2sTrustStoreDirectory = new File(s2sTrustStoreLocation).getParentFile();
- if (!s2sTrustStoreDirectory.exists())
- s2sTrustStoreDirectory.mkdirs();
- s2sTrustStore.store(new FileOutputStream(s2sTrustStoreLocation), s2sTrustpass.toCharArray());
- }
-
- if (c2sTrustStore != null && c2sTrustStore != s2sTrustStore) {
- File c2sTrustStoreDirectory = new File(c2sTrustStoreLocation).getParentFile();
- if (!c2sTrustStoreDirectory.exists())
- c2sTrustStoreDirectory.mkdirs();
- c2sTrustStore.store(new FileOutputStream(c2sTrustStoreLocation), c2sTrustpass.toCharArray());
- }
- }
- catch (IOException e) {
- throw e;
- }
- catch (Exception e) {
- throw new IOException(e.getMessage());
- }
- }
-
- /**
- * Create a ServerSocket for s2s connections
- *
- * @return the ServerSocket for an s2s connection
- */
- public static ServerSocket createServerSocket(int port, InetAddress ifAddress) throws
- IOException {
- 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();
- }
- else {
- return c2sFactory.createServerSocket(port, -1, ifAddress);
- }
- }
-
- /**
- * Get the Key Store location
- *
- * @return the keystore location
- */
- public static String getKeystoreLocation() {
- return keyStoreLocation;
- }
-
- /**
- * 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() {
- return storeType;
- }
-
- /**
- * Get the SSLContext for s2s connections
- *
- * @return the SSLContext for s2s connections
- */
- public static SSLContext getSSLContext() {
- 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() {
- return s2sFactory;
- }
- /**
- * Get the SSLServerSocketFactory for c2s connections
- *
- * @return the SSLServerSocketFactory for c2s connections
- */
- public static SSLServerSocketFactory getc2sServerSocketFactory() {
- return c2sFactory;
- }
- }