View Javadoc
1   /*
2    * ====================================================================
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   * ====================================================================
20   *
21   * This software consists of voluntary contributions made by many
22   * individuals on behalf of the Apache Software Foundation.  For more
23   * information on the Apache Software Foundation, please see
24   * <http://www.apache.org/>.
25   *
26   */
27  
28  package org.apache.http.nio.conn.ssl;
29  
30  import java.net.InetSocketAddress;
31  import java.security.KeyManagementException;
32  import java.security.KeyStore;
33  import java.security.KeyStoreException;
34  import java.security.NoSuchAlgorithmException;
35  import java.security.SecureRandom;
36  import java.security.UnrecoverableKeyException;
37  import java.security.cert.Certificate;
38  import java.security.cert.X509Certificate;
39  
40  import javax.net.ssl.KeyManager;
41  import javax.net.ssl.KeyManagerFactory;
42  import javax.net.ssl.SSLContext;
43  import javax.net.ssl.SSLEngine;
44  import javax.net.ssl.SSLException;
45  import javax.net.ssl.SSLSession;
46  import javax.net.ssl.TrustManager;
47  import javax.net.ssl.TrustManagerFactory;
48  import javax.net.ssl.X509TrustManager;
49  
50  import org.apache.http.conn.ssl.BrowserCompatHostnameVerifier;
51  import org.apache.http.conn.ssl.SSLContexts;
52  import org.apache.http.conn.ssl.TrustStrategy;
53  import org.apache.http.conn.ssl.X509HostnameVerifier;
54  import org.apache.http.nio.conn.scheme.LayeringStrategy;
55  import org.apache.http.nio.reactor.IOSession;
56  import org.apache.http.nio.reactor.ssl.SSLIOSession;
57  import org.apache.http.nio.reactor.ssl.SSLMode;
58  import org.apache.http.nio.reactor.ssl.SSLSetupHandler;
59  
60  @Deprecated
61  public class SSLLayeringStrategy implements LayeringStrategy {
62  
63      public static final String TLS   = "TLS";
64      public static final String SSL   = "SSL";
65      public static final String SSLV2 = "SSLv2";
66  
67      public static SSLLayeringStrategy getDefaultStrategy() {
68          return new SSLLayeringStrategy(SSLContexts.createDefault());
69      }
70  
71      public static SSLLayeringStrategy getSystemDefaultStrategy() {
72          return new SSLLayeringStrategy(SSLContexts.createSystemDefault());
73      }
74  
75      private final SSLContext sslContext;
76      private final X509HostnameVerifier hostnameVerifier;
77  
78      private static SSLContext createSSLContext(
79              final String algorithm,
80              final KeyStore keystore,
81              final String keystorePassword,
82              final KeyStore truststore,
83              final SecureRandom random,
84              final TrustStrategy trustStrategy)
85                  throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException, KeyManagementException {
86          final String algo = algorithm != null ? algorithm : TLS;
87          final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
88                  KeyManagerFactory.getDefaultAlgorithm());
89          kmfactory.init(keystore, keystorePassword != null ? keystorePassword.toCharArray(): null);
90          final KeyManager[] keymanagers =  kmfactory.getKeyManagers();
91          final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
92                  TrustManagerFactory.getDefaultAlgorithm());
93          tmfactory.init(truststore);
94          final TrustManager[] trustmanagers = tmfactory.getTrustManagers();
95          if (trustmanagers != null && trustStrategy != null) {
96              for (int i = 0; i < trustmanagers.length; i++) {
97                  final TrustManager tm = trustmanagers[i];
98                  if (tm instanceof X509TrustManager) {
99                      trustmanagers[i] = new TrustManagerDecorator(
100                             (X509TrustManager) tm, trustStrategy);
101                 }
102             }
103         }
104         final SSLContext sslcontext = SSLContext.getInstance(algo);
105         sslcontext.init(keymanagers, trustmanagers, random);
106         return sslcontext;
107     }
108 
109     public SSLLayeringStrategy(
110             final String algorithm,
111             final KeyStore keystore,
112             final String keystorePassword,
113             final KeyStore truststore,
114             final SecureRandom random,
115             final X509HostnameVerifier hostnameVerifier)
116                 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
117         this(createSSLContext(
118                 algorithm, keystore, keystorePassword, truststore, random, null),
119                 hostnameVerifier);
120     }
121 
122     public SSLLayeringStrategy(
123             final String algorithm,
124             final KeyStore keystore,
125             final String keystorePassword,
126             final KeyStore truststore,
127             final SecureRandom random,
128             final TrustStrategy trustStrategy,
129             final X509HostnameVerifier hostnameVerifier)
130                 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
131         this(createSSLContext(
132                 algorithm, keystore, keystorePassword, truststore, random, trustStrategy),
133                 hostnameVerifier);
134     }
135 
136     public SSLLayeringStrategy(
137             final KeyStore keystore,
138             final String keystorePassword,
139             final KeyStore truststore)
140                 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
141         this(TLS, keystore, keystorePassword, truststore, null, null, new BrowserCompatHostnameVerifier());
142     }
143 
144     public SSLLayeringStrategy(
145             final KeyStore keystore,
146             final String keystorePassword)
147                 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException{
148         this(TLS, keystore, keystorePassword, null, null, null, new BrowserCompatHostnameVerifier());
149     }
150 
151     public SSLLayeringStrategy(
152             final KeyStore truststore)
153                 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
154         this(TLS, null, null, truststore, null, null, new BrowserCompatHostnameVerifier());
155     }
156 
157     public SSLLayeringStrategy(
158             final TrustStrategy trustStrategy,
159             final X509HostnameVerifier hostnameVerifier)
160                 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
161         this(TLS, null, null, null, null, trustStrategy, hostnameVerifier);
162     }
163 
164     public SSLLayeringStrategy(
165             final TrustStrategy trustStrategy)
166                 throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
167         this(TLS, null, null, null, null, trustStrategy, new BrowserCompatHostnameVerifier());
168     }
169 
170     public SSLLayeringStrategy(
171             final SSLContext sslContext, final X509HostnameVerifier hostnameVerifier) {
172         super();
173         this.sslContext = sslContext;
174         this.hostnameVerifier = hostnameVerifier;
175     }
176 
177     public SSLLayeringStrategy(final SSLContext sslContext) {
178         this(sslContext, new BrowserCompatHostnameVerifier());
179     }
180 
181     @Override
182     public boolean isSecure() {
183         return true;
184     }
185 
186     @Override
187     public SSLIOSession layer(final IOSession iosession) {
188         final SSLIOSession ssliosession = new SSLIOSession(
189             iosession,
190             SSLMode.CLIENT,
191             this.sslContext,
192             new SSLSetupHandler() {
193 
194                 @Override
195                 public void initalize(
196                         final SSLEngine sslengine) throws SSLException {
197                     initializeEngine(sslengine);
198                 }
199 
200                 @Override
201                 public void verify(
202                         final IOSession iosession,
203                         final SSLSession sslsession) throws SSLException {
204                     verifySession(iosession, sslsession);
205                 }
206 
207         });
208         iosession.setAttribute(SSLIOSession.SESSION_KEY, ssliosession);
209         return ssliosession;
210     }
211 
212     protected void initializeEngine(final SSLEngine engine) {
213     }
214 
215     protected void verifySession(
216             final IOSession iosession,
217             final SSLSession sslsession) throws SSLException {
218         final InetSocketAddress address = (InetSocketAddress) iosession.getRemoteAddress();
219 
220         final Certificate[] certs = sslsession.getPeerCertificates();
221         final X509Certificate x509 = (X509Certificate) certs[0];
222         this.hostnameVerifier.verify(address.getHostName(), x509);
223     }
224 
225 }