View Javadoc

1   /*
2    * Copyright 2008 University Corporation for Advanced Internet Development, Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.opensaml.ws.soap.client.http;
18  
19  import java.io.IOException;
20  import java.net.InetAddress;
21  import java.net.InetSocketAddress;
22  import java.net.Socket;
23  import java.net.SocketAddress;
24  import java.security.GeneralSecurityException;
25  
26  import javax.net.SocketFactory;
27  import javax.net.ssl.KeyManager;
28  import javax.net.ssl.SSLContext;
29  import javax.net.ssl.TrustManager;
30  import javax.net.ssl.X509KeyManager;
31  import javax.net.ssl.X509TrustManager;
32  
33  import net.jcip.annotations.ThreadSafe;
34  
35  import org.apache.commons.httpclient.params.HttpConnectionParams;
36  import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
37  
38  /** An SSL/TLS socket factory that uses {@link KeyStoreFactory}s to get its key and trust material. */
39  @ThreadSafe
40  public class TLSProtocolSocketFactory implements SecureProtocolSocketFactory {
41  
42      /** Manager used to retrieve client-cert authentication keys for a given host. */
43      private X509KeyManager keyManager;
44  
45      /** Manager used to validate the X.509 credentials of a given host. */
46      private X509TrustManager trustManager;
47  
48      /** Currently active SSL context. */
49      private SSLContext sslContext;
50  
51      /**
52       * Constructor.
53       * 
54       * @param keyMgr manager used to retrieve client-cert authentication keys for a given host
55       * @param trustMgr manager used to validate the X.509 credentials of a given host
56       * 
57       * @throws IllegalArgumentException thrown if the given key or trust manager can not be used to create the
58       *             {@link SSLContext} used to create new sockets
59       */
60      public TLSProtocolSocketFactory(X509KeyManager keyMgr, X509TrustManager trustMgr) throws IllegalArgumentException {
61          keyManager = keyMgr;
62          trustManager = trustMgr;
63  
64          try {
65              sslContext = SSLContext.getInstance("SSL");
66              sslContext.init(new KeyManager[] { keyManager }, new TrustManager[] { trustManager }, null);
67          } catch (GeneralSecurityException e) {
68              throw new IllegalArgumentException("Error create SSL context", e);
69          }
70      }
71  
72      /** {@inheritDoc} */
73      public Socket createSocket(String host, int port) throws IOException {
74          return sslContext.getSocketFactory().createSocket(host, port);
75      }
76  
77      /** {@inheritDoc} */
78      public Socket createSocket(String host, int port, InetAddress localHost, int clientPort) throws IOException {
79          return sslContext.getSocketFactory().createSocket(host, port, localHost, clientPort);
80      }
81  
82      /** {@inheritDoc} */
83      public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException {
84          return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose);
85      }
86  
87      /** {@inheritDoc} */
88      public Socket createSocket(String host, int port, InetAddress localHost, int localPort,
89              HttpConnectionParams connParams) throws IOException {
90          if (connParams == null) {
91              throw new IllegalArgumentException("Parameters may not be null");
92          }
93          int timeout = connParams.getConnectionTimeout();
94          SocketFactory socketfactory = sslContext.getSocketFactory();
95          if (timeout == 0) {
96              return socketfactory.createSocket(host, port, localHost, localPort);
97          } else {
98              Socket socket = socketfactory.createSocket();
99              SocketAddress localaddr = new InetSocketAddress(localHost, localPort);
100             SocketAddress remoteaddr = new InetSocketAddress(host, port);
101             socket.bind(localaddr);
102             socket.connect(remoteaddr, timeout);
103             return socket;
104         }
105     }
106 
107     /** {@inheritDoc} */
108     public boolean equals(Object obj) {
109         return (obj != null) && obj.getClass().equals(getClass());
110     }
111 
112     /** {@inheritDoc} */
113     public int hashCode() {
114         return getClass().hashCode();
115     }
116 }