SSLContextFactory.java
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 storePasswordthrows 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 }