001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.http.processors;
018
019 import java.io.IOException;
020 import java.net.InetAddress;
021 import java.net.InetSocketAddress;
022 import java.net.Socket;
023 import java.net.SocketAddress;
024 import java.net.URL;
025 import java.net.UnknownHostException;
026 import java.security.KeyStore;
027
028 import javax.jbi.JBIException;
029 import javax.net.ssl.KeyManagerFactory;
030 import javax.net.ssl.SSLContext;
031 import javax.net.ssl.SSLSocketFactory;
032 import javax.net.ssl.TrustManagerFactory;
033
034 import org.apache.commons.httpclient.ConnectTimeoutException;
035 import org.apache.commons.httpclient.params.HttpConnectionParams;
036 import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
037 import org.apache.servicemix.common.security.KeystoreManager;
038 import org.apache.servicemix.http.SslParameters;
039 import org.mortbay.resource.Resource;
040 import org.springframework.core.io.ClassPathResource;
041
042 public class CommonsHttpSSLSocketFactory implements SecureProtocolSocketFactory {
043
044 private SSLSocketFactory factory;
045
046 public CommonsHttpSSLSocketFactory(SslParameters ssl, KeystoreManager keystoreManager) throws Exception {
047 if (ssl.isManaged()) {
048 createManagedFactory(ssl, keystoreManager);
049 } else {
050 createUnmanagedFactory(ssl);
051 }
052 }
053
054 protected final void createManagedFactory(SslParameters ssl, KeystoreManager keystoreManager) throws Exception {
055 factory = keystoreManager.createSSLFactory(ssl.getProvider(), ssl.getProtocol(), ssl
056 .getKeyManagerFactoryAlgorithm(), ssl.getKeyStore(), ssl.getKeyAlias(), ssl.getTrustStore());
057 }
058
059 protected final void createUnmanagedFactory(SslParameters ssl) throws Exception {
060 SSLContext context;
061 if (ssl.getProvider() == null) {
062 context = SSLContext.getInstance(ssl.getProtocol());
063 } else {
064 context = SSLContext.getInstance(ssl.getProtocol(), ssl.getProvider());
065 }
066 KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(ssl.getKeyManagerFactoryAlgorithm());
067 String keyStore = ssl.getKeyStore();
068 if (keyStore == null) {
069 keyStore = System.getProperty("javax.net.ssl.keyStore");
070 if (keyStore == null) {
071 throw new IllegalArgumentException("keyStore or system property javax.net.ssl.keyStore must be set");
072 }
073 }
074 if (keyStore.startsWith("classpath:")) {
075 try {
076 String res = keyStore.substring(10);
077 URL url = new ClassPathResource(res).getURL();
078 keyStore = url.toString();
079 } catch (IOException e) {
080 throw new JBIException("Unable to find keyStore " + keyStore, e);
081 }
082 }
083 String keyStorePassword = ssl.getKeyStorePassword();
084 if (keyStorePassword == null) {
085 keyStorePassword = System.getProperty("javax.net.ssl.keyStorePassword");
086 if (keyStorePassword == null) {
087 throw new IllegalArgumentException(
088 "keyStorePassword or system property javax.net.ssl.keyStorePassword must be set");
089 }
090 }
091 String trustStore = ssl.getTrustStore();
092 String trustStorePassword = null;
093 if (trustStore == null) {
094 trustStore = System.getProperty("javax.net.ssl.trustStore");
095 }
096 if (trustStore != null) {
097 if (trustStore.startsWith("classpath:")) {
098 try {
099 String res = trustStore.substring(10);
100 URL url = new ClassPathResource(res).getURL();
101 trustStore = url.toString();
102 } catch (IOException e) {
103 throw new JBIException("Unable to find trustStore " + trustStore, e);
104 }
105 }
106 trustStorePassword = ssl.getTrustStorePassword();
107 if (trustStorePassword == null) {
108 trustStorePassword = System.getProperty("javax.net.ssl.trustStorePassword");
109 if (trustStorePassword == null) {
110 throw new IllegalArgumentException(
111 "trustStorePassword or system property javax.net.ssl.trustStorePassword must be set");
112 }
113 }
114 }
115 KeyStore ks = KeyStore.getInstance(ssl.getKeyStoreType());
116 ks.load(Resource.newResource(keyStore).getInputStream(), keyStorePassword.toCharArray());
117 keyManagerFactory.init(ks, ssl.getKeyPassword() != null ? ssl.getKeyPassword().toCharArray() : keyStorePassword
118 .toCharArray());
119 if (trustStore != null) {
120 KeyStore ts = KeyStore.getInstance(ssl.getTrustStoreType());
121 ts.load(Resource.newResource(trustStore).getInputStream(), trustStorePassword.toCharArray());
122 TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(ssl
123 .getTrustManagerFactoryAlgorithm());
124 trustManagerFactory.init(ts);
125 context.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(),
126 new java.security.SecureRandom());
127 } else {
128 context.init(keyManagerFactory.getKeyManagers(), null, new java.security.SecureRandom());
129 }
130 factory = context.getSocketFactory();
131 }
132
133 public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException,
134 UnknownHostException {
135 return factory.createSocket(socket, host, port, autoClose);
136 }
137
138 public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException,
139 UnknownHostException {
140 return factory.createSocket(host, port, localAddress, localPort);
141 }
142
143 public Socket createSocket(String host, int port, InetAddress localAddress, int localPort,
144 HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
145 if (params == null) {
146 throw new IllegalArgumentException("Parameters may not be null");
147 }
148 int timeout = params.getConnectionTimeout();
149 if (timeout == 0) {
150 return createSocket(host, port, localAddress, localPort);
151 } else {
152 Socket socket = factory.createSocket();
153 SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
154 SocketAddress remoteaddr = new InetSocketAddress(host, port);
155 socket.bind(localaddr);
156 socket.connect(remoteaddr, timeout);
157 return socket;
158 }
159 }
160
161 public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
162 return factory.createSocket(host, port);
163 }
164
165 }