1 17 18 package org.apache.avalon.cornerstone.blocks.sockets; 19 20 import javax.net.ssl.KeyManagerFactory; 21 import javax.net.ssl.SSLContext; 22 import javax.net.ssl.TrustManagerFactory; 23 import java.io.File ; 24 import java.io.FileInputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.security.GeneralSecurityException ; 28 import java.security.KeyStore ; 29 import java.util.Arrays ; 30 import javax.net.ssl.SSLServerSocketFactory; 31 import javax.net.ssl.SSLSocketFactory; 32 import org.apache.avalon.framework.activity.Disposable; 33 import org.apache.avalon.framework.activity.Initializable; 34 import org.apache.avalon.framework.configuration.Configurable; 35 import org.apache.avalon.framework.configuration.Configuration; 36 import org.apache.avalon.framework.configuration.ConfigurationException; 37 import org.apache.avalon.framework.context.Context; 38 import org.apache.avalon.framework.context.ContextException; 39 import org.apache.avalon.framework.context.Contextualizable; 40 import org.apache.avalon.framework.logger.AbstractLogEnabled; 41 42 71 public class SSLFactoryBuilder extends AbstractLogEnabled 72 implements Configurable, Contextualizable, Disposable, Initializable 73 { 74 private File m_baseDirectory; 75 private File m_keystoreFile; 76 77 private String m_keystorePassword; 78 private String m_keyPassword; 79 private String m_protocol; 80 private String m_provider; 81 private String m_keystoreFormat; 82 83 private SSLContext m_ctx; 84 85 static 86 { 87 java.security.Security.addProvider( new sun.security.provider.Sun() ); 89 java.security.Security.addProvider( new com.sun.net.ssl.internal.ssl.Provider() ); 90 } 91 92 97 public void contextualize( final Context context ) throws ContextException 98 { 99 try 100 { 101 m_baseDirectory = (File ) context.get( "urn:avalon:home" ); 102 } 103 catch( ContextException ce ) 104 { 105 m_baseDirectory = (File )context.get( "app.home" ); 106 } 107 } 108 109 public void configure( final Configuration configuration ) 110 throws ConfigurationException 111 { 112 final Configuration storeConfig = configuration.getChild( "keystore" ); 113 final String fileName = storeConfig.getChild( "file" ).getValue( "conf/keystore" ); 114 final File configuredFile = new File ( fileName ); 115 if( !configuredFile.isAbsolute() ) 116 { 117 m_keystoreFile = new File ( m_baseDirectory, fileName ); 118 } 119 else 120 { 121 m_keystoreFile = configuredFile; 122 } 123 124 m_keystorePassword = storeConfig.getChild( "password" ).getValue( null ); 125 m_keyPassword = storeConfig.getChild( "key-password" ).getValue( null ); 126 m_provider = storeConfig.getChild( "algorithm" ).getValue( "SunX509" ); 128 m_keystoreFormat = storeConfig.getChild( "type" ).getValue( "JKS" ); 130 m_protocol = configuration.getChild( "protocol" ). 132 getValue( storeConfig.getChild( "protocol" ).getValue( "TLS" ) ); 133 } 134 135 138 public SSLSocketFactory buildSocketFactory() 139 { 140 return m_ctx.getSocketFactory(); 141 } 142 143 147 public SSLServerSocketFactory buildServerSocketFactory() 148 { 149 return m_ctx.getServerSocketFactory(); 150 } 151 152 public void initialize() 153 throws IOException , GeneralSecurityException 154 { 155 final FileInputStream keyStream = new FileInputStream ( m_keystoreFile ); 156 try 157 { 158 m_ctx = makeContext( keyStream, m_keystorePassword, 159 m_keyPassword, m_protocol, 160 m_provider, m_keystoreFormat ); 161 } 162 finally 163 { 164 try 165 { 166 keyStream.close(); 167 } 168 catch( IOException e ) 169 { 170 getLogger().error( "Error keyStream.close failed", e ); 173 } 174 } 175 } 176 177 public void dispose() 178 { 179 m_keystorePassword = null; 180 m_keyPassword = null; 181 } 182 183 203 private static SSLContext makeContext( InputStream keyStream, 204 String keystorePassword, 205 String keyPassword, 206 String protocol, 207 String provider, 208 String keystoreFormat ) 209 throws IOException , GeneralSecurityException 210 { 211 final KeyStore keystore = loadKeystore( keyStream, 212 keystorePassword, 213 keystoreFormat ); 214 final KeyManagerFactory kmf = KeyManagerFactory.getInstance( provider ); 215 final char[] passChars = ( keyPassword != null ) ? 218 keyPassword.toCharArray() : new char[ 0 ]; 219 try 220 { 221 kmf.init( keystore, passChars ); 222 } 223 finally 224 { 225 Arrays.fill( passChars, (char)0 ); 226 } 227 228 final TrustManagerFactory tmf = 229 TrustManagerFactory.getInstance( provider ); 230 tmf.init( keystore ); 231 232 final SSLContext result = SSLContext.getInstance( protocol ); 233 result.init( kmf.getKeyManagers(), 234 tmf.getTrustManagers(), 235 new java.security.SecureRandom () ); 236 return result; 237 } 238 239 250 private static KeyStore loadKeystore( InputStream keyStream, 251 String passphrase, 252 String keystoreFormat ) 253 throws GeneralSecurityException , IOException 254 { 255 final KeyStore ks = KeyStore.getInstance( keystoreFormat ); 256 257 if( passphrase != null ) 258 { 259 final char[] passChars = passphrase.toCharArray(); 260 try 261 { 262 ks.load( keyStream, passChars ); 263 } 264 finally 265 { 266 Arrays.fill( passChars, (char)0 ); 267 } 268 } 269 else 270 { 271 ks.load( keyStream, null ); 272 } 273 274 return ks; 275 } 276 } 277 | Popular Tags |