001 /*
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one
004 * or more contributor license agreements. See the NOTICE file
005 * distributed with this work for additional information
006 * regarding copyright ownership. The ASF licenses this file
007 * to you under the Apache License, Version 2.0 (the
008 * "License"); you may not use this file except in compliance
009 * with the License. You may obtain a copy of the License at
010 *
011 * http://www.apache.org/licenses/LICENSE-2.0
012 *
013 * Unless required by applicable law or agreed to in writing,
014 * software distributed under the License is distributed on an
015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016 * KIND, either express or implied. See the License for the
017 * specific language governing permissions and limitations
018 * under the License.
019 *
020 */
021 package org.apache.qpid.ssl;
022
023 import java.io.File;
024 import java.io.FileInputStream;
025 import java.io.IOException;
026 import java.io.InputStream;
027 import java.security.GeneralSecurityException;
028 import java.security.KeyStore;
029
030 import javax.net.ssl.KeyManagerFactory;
031 import javax.net.ssl.SSLContext;
032 import javax.net.ssl.TrustManagerFactory;
033
034 /**
035 * Factory used to create SSLContexts. SSL needs to be configured
036 * before this will work.
037 *
038 */
039 public class SSLContextFactory {
040
041 /**
042 * Path to the Java keystore file
043 */
044 private String _keyStorePath;
045
046 /**
047 * Password for the keystore
048 */
049 private String _keyStorePassword;
050
051 /**
052 * Cert type to use in keystore
053 */
054 private String _keyStoreCertType;
055
056 /**
057 * Path to the Java truststore file
058 */
059 private String _trustStorePath;
060
061 /**
062 * Password for the truststore
063 */
064 private String _trustStorePassword;
065
066 /**
067 * Cert type to use in truststore
068 */
069 private String _trustStoreCertType;
070
071
072
073 public SSLContextFactory(String trustStorePath, String trustStorePassword,
074 String trustStoreCertType)
075 {
076 this(trustStorePath,trustStorePassword,trustStoreCertType,
077 trustStorePath,trustStorePassword,trustStoreCertType);
078 }
079
080 /**
081 * Create a factory instance
082 * @param keystorePath path to the Java keystore file
083 * @param keystorePassword password for the Java keystore
084 * @param certType certificate type
085 */
086 public SSLContextFactory(String trustStorePath, String trustStorePassword, String trustStoreCertType,
087 String keyStorePath, String keyStorePassword, String keyStoreCertType)
088 {
089
090 _trustStorePath = trustStorePath;
091 _trustStorePassword = trustStorePassword;
092
093 if (_trustStorePassword.equals("none"))
094 {
095 _trustStorePassword = null;
096 }
097 _trustStoreCertType = trustStoreCertType;
098
099 _keyStorePath = keyStorePath;
100 _keyStorePassword = keyStorePassword;
101
102 if (_keyStorePassword.equals("none"))
103 {
104 _keyStorePassword = null;
105 }
106 _keyStoreCertType = keyStoreCertType;
107
108 if (_trustStorePath == null) {
109 throw new IllegalArgumentException("A TrustStore path or KeyStore path must be specified");
110 }
111 if (_trustStoreCertType == null) {
112 throw new IllegalArgumentException("Cert type must be specified");
113 }
114 }
115
116 /**
117 * Builds a SSLContext appropriate for use with a server
118 * @return SSLContext
119 * @throws GeneralSecurityException
120 * @throws IOException
121 */
122 public SSLContext buildServerContext() throws GeneralSecurityException, IOException
123 {
124 // Create keystore
125 KeyStore ks = getInitializedKeyStore(_keyStorePath,_keyStorePassword);
126
127 // Set up key manager factory to use our key store
128 KeyManagerFactory kmf = KeyManagerFactory.getInstance(_keyStoreCertType);
129 kmf.init(ks, _keyStorePassword.toCharArray());
130
131 KeyStore ts = getInitializedKeyStore(_trustStorePath,_trustStorePassword);
132 TrustManagerFactory tmf = TrustManagerFactory.getInstance(_trustStoreCertType);
133 tmf.init(ts);
134
135 // Initialize the SSLContext to work with our key managers.
136 SSLContext sslContext = SSLContext.getInstance("TLS");
137 sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
138
139 return sslContext;
140 }
141
142 /**
143 * Creates a SSLContext factory appropriate for use with a client
144 * @return SSLContext
145 * @throws GeneralSecurityException
146 * @throws IOException
147 */
148 public SSLContext buildClientContext() throws GeneralSecurityException, IOException
149 {
150 KeyStore ks = getInitializedKeyStore(_trustStorePath,_trustStorePassword);
151 TrustManagerFactory tmf = TrustManagerFactory.getInstance(_trustStoreCertType);
152 tmf.init(ks);
153 SSLContext context = SSLContext.getInstance("TLS");
154 context.init(null, tmf.getTrustManagers(), null);
155 return context;
156 }
157
158 private KeyStore getInitializedKeyStore(String storePath, String storePassword) throws GeneralSecurityException, IOException
159 {
160 KeyStore ks = KeyStore.getInstance("JKS");
161 InputStream in = null;
162 try
163 {
164 File f = new File(storePath);
165 if (f.exists())
166 {
167 in = new FileInputStream(f);
168 }
169 else
170 {
171 in = Thread.currentThread().getContextClassLoader().getResourceAsStream(storePath);
172 }
173 if (in == null)
174 {
175 throw new IOException("Unable to load keystore resource: " + storePath);
176 }
177 ks.load(in, storePassword.toCharArray());
178 }
179 finally
180 {
181 if (in != null)
182 {
183 //noinspection EmptyCatchBlock
184 try
185 {
186 in.close();
187 }
188 catch (IOException ignored)
189 {
190 }
191 }
192 }
193 return ks;
194 }
195 }
|