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.conn.ssl;
29  
30  import java.net.Socket;
31  import java.security.KeyManagementException;
32  import java.security.KeyStore;
33  import java.security.KeyStoreException;
34  import java.security.NoSuchAlgorithmException;
35  import java.security.Principal;
36  import java.security.PrivateKey;
37  import java.security.SecureRandom;
38  import java.security.UnrecoverableKeyException;
39  import java.security.cert.CertificateException;
40  import java.security.cert.X509Certificate;
41  import java.util.HashMap;
42  import java.util.LinkedHashSet;
43  import java.util.Map;
44  import java.util.Set;
45  
46  import javax.net.ssl.KeyManager;
47  import javax.net.ssl.KeyManagerFactory;
48  import javax.net.ssl.SSLContext;
49  import javax.net.ssl.TrustManager;
50  import javax.net.ssl.TrustManagerFactory;
51  import javax.net.ssl.X509KeyManager;
52  import javax.net.ssl.X509TrustManager;
53  
54  import org.apache.http.annotation.NotThreadSafe;
55  
56  /**
57   * Builder for {@link SSLContext} instances.
58   *
59   * @since 4.3
60   *
61   * @deprecated (4.4) use {@link org.apache.http.ssl.SSLContextBuilder}.
62   */
63  @NotThreadSafe
64  @Deprecated
65  public class SSLContextBuilder {
66  
67      static final String TLS   = "TLS";
68      static final String SSL   = "SSL";
69  
70      private String protocol;
71      private Set<KeyManager> keymanagers;
72      private Set<TrustManager> trustmanagers;
73      private SecureRandom secureRandom;
74  
75      public SSLContextBuilder() {
76          super();
77          this.keymanagers = new LinkedHashSet<KeyManager>();
78          this.trustmanagers = new LinkedHashSet<TrustManager>();
79      }
80  
81      public SSLContextBuilder useTLS() {
82          this.protocol = TLS;
83          return this;
84      }
85  
86      public SSLContextBuilder useSSL() {
87          this.protocol = SSL;
88          return this;
89      }
90  
91      public SSLContextBuilder useProtocol(final String protocol) {
92          this.protocol = protocol;
93          return this;
94      }
95  
96      public SSLContextBuilder setSecureRandom(final SecureRandom secureRandom) {
97          this.secureRandom = secureRandom;
98          return this;
99      }
100 
101     public SSLContextBuilder loadTrustMaterial(
102             final KeyStore truststore,
103             final TrustStrategy trustStrategy) throws NoSuchAlgorithmException, KeyStoreException {
104         final TrustManagerFactory tmfactory = TrustManagerFactory.getInstance(
105                 TrustManagerFactory.getDefaultAlgorithm());
106         tmfactory.init(truststore);
107         final TrustManager[] tms = tmfactory.getTrustManagers();
108         if (tms != null) {
109             if (trustStrategy != null) {
110                 for (int i = 0; i < tms.length; i++) {
111                     final TrustManager tm = tms[i];
112                     if (tm instanceof X509TrustManager) {
113                         tms[i] = new TrustManagerDelegate(
114                                 (X509TrustManager) tm, trustStrategy);
115                     }
116                 }
117             }
118             for (final TrustManager tm : tms) {
119                 this.trustmanagers.add(tm);
120             }
121         }
122         return this;
123     }
124 
125     public SSLContextBuilder loadTrustMaterial(
126             final KeyStore truststore) throws NoSuchAlgorithmException, KeyStoreException {
127         return loadTrustMaterial(truststore, null);
128     }
129 
130     public SSLContextBuilder loadKeyMaterial(
131             final KeyStore keystore,
132             final char[] keyPassword)
133                 throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
134         loadKeyMaterial(keystore, keyPassword, null);
135         return this;
136     }
137 
138     public SSLContextBuilder loadKeyMaterial(
139             final KeyStore keystore,
140             final char[] keyPassword,
141             final PrivateKeyStrategy aliasStrategy)
142             throws NoSuchAlgorithmException, KeyStoreException, UnrecoverableKeyException {
143         final KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(
144                 KeyManagerFactory.getDefaultAlgorithm());
145         kmfactory.init(keystore, keyPassword);
146         final KeyManager[] kms =  kmfactory.getKeyManagers();
147         if (kms != null) {
148             if (aliasStrategy != null) {
149                 for (int i = 0; i < kms.length; i++) {
150                     final KeyManager km = kms[i];
151                     if (km instanceof X509KeyManager) {
152                         kms[i] = new KeyManagerDelegate(
153                                 (X509KeyManager) km, aliasStrategy);
154                     }
155                 }
156             }
157             for (final KeyManager km : kms) {
158                 keymanagers.add(km);
159             }
160         }
161         return this;
162     }
163 
164     public SSLContext build() throws NoSuchAlgorithmException, KeyManagementException {
165         final SSLContext sslcontext = SSLContext.getInstance(
166                 this.protocol != null ? this.protocol : TLS);
167         sslcontext.init(
168                 !keymanagers.isEmpty() ? keymanagers.toArray(new KeyManager[keymanagers.size()]) : null,
169                 !trustmanagers.isEmpty() ? trustmanagers.toArray(new TrustManager[trustmanagers.size()]) : null,
170                 secureRandom);
171         return sslcontext;
172     }
173 
174     static class TrustManagerDelegate implements X509TrustManager {
175 
176         private final X509TrustManager trustManager;
177         private final TrustStrategy trustStrategy;
178 
179         TrustManagerDelegate(final X509TrustManager trustManager, final TrustStrategy trustStrategy) {
180             super();
181             this.trustManager = trustManager;
182             this.trustStrategy = trustStrategy;
183         }
184 
185         @Override
186         public void checkClientTrusted(
187                 final X509Certificate[] chain, final String authType) throws CertificateException {
188             this.trustManager.checkClientTrusted(chain, authType);
189         }
190 
191         @Override
192         public void checkServerTrusted(
193                 final X509Certificate[] chain, final String authType) throws CertificateException {
194             if (!this.trustStrategy.isTrusted(chain, authType)) {
195                 this.trustManager.checkServerTrusted(chain, authType);
196             }
197         }
198 
199         @Override
200         public X509Certificate[] getAcceptedIssuers() {
201             return this.trustManager.getAcceptedIssuers();
202         }
203 
204     }
205 
206     static class KeyManagerDelegate implements X509KeyManager {
207 
208         private final X509KeyManager keyManager;
209         private final PrivateKeyStrategy aliasStrategy;
210 
211         KeyManagerDelegate(final X509KeyManager keyManager, final PrivateKeyStrategy aliasStrategy) {
212             super();
213             this.keyManager = keyManager;
214             this.aliasStrategy = aliasStrategy;
215         }
216 
217         @Override
218         public String[] getClientAliases(
219                 final String keyType, final Principal[] issuers) {
220             return this.keyManager.getClientAliases(keyType, issuers);
221         }
222 
223         @Override
224         public String chooseClientAlias(
225                 final String[] keyTypes, final Principal[] issuers, final Socket socket) {
226             final Map<String, PrivateKeyDetails> validAliases = new HashMap<String, PrivateKeyDetails>();
227             for (final String keyType: keyTypes) {
228                 final String[] aliases = this.keyManager.getClientAliases(keyType, issuers);
229                 if (aliases != null) {
230                     for (final String alias: aliases) {
231                         validAliases.put(alias,
232                                 new PrivateKeyDetails(keyType, this.keyManager.getCertificateChain(alias)));
233                     }
234                 }
235             }
236             return this.aliasStrategy.chooseAlias(validAliases, socket);
237         }
238 
239         @Override
240         public String[] getServerAliases(
241                 final String keyType, final Principal[] issuers) {
242             return this.keyManager.getServerAliases(keyType, issuers);
243         }
244 
245         @Override
246         public String chooseServerAlias(
247                 final String keyType, final Principal[] issuers, final Socket socket) {
248             final Map<String, PrivateKeyDetails> validAliases = new HashMap<String, PrivateKeyDetails>();
249             final String[] aliases = this.keyManager.getServerAliases(keyType, issuers);
250             if (aliases != null) {
251                 for (final String alias: aliases) {
252                     validAliases.put(alias,
253                             new PrivateKeyDetails(keyType, this.keyManager.getCertificateChain(alias)));
254                 }
255             }
256             return this.aliasStrategy.chooseAlias(validAliases, socket);
257         }
258 
259         @Override
260         public X509Certificate[] getCertificateChain(final String alias) {
261             return this.keyManager.getCertificateChain(alias);
262         }
263 
264         @Override
265         public PrivateKey getPrivateKey(final String alias) {
266             return this.keyManager.getPrivateKey(alias);
267         }
268 
269     }
270 
271 }