1 /*
2 * Copyright 2014 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License,
5 * version 2.0 (the "License"); you may not use this file except in compliance
6 * with the License. You may obtain a copy of the License at:
7 *
8 * https://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, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations
14 * under the License.
15 */
16
17 package io.netty.handler.ssl;
18
19 import java.security.KeyStore;
20 import java.security.Provider;
21 import javax.net.ssl.KeyManager;
22 import javax.net.ssl.KeyManagerFactory;
23 import javax.net.ssl.SNIServerName;
24 import javax.net.ssl.SSLContext;
25 import javax.net.ssl.SSLException;
26 import javax.net.ssl.SSLSessionContext;
27 import javax.net.ssl.TrustManager;
28 import javax.net.ssl.TrustManagerFactory;
29 import java.io.File;
30 import java.security.PrivateKey;
31 import java.security.SecureRandom;
32 import java.security.cert.X509Certificate;
33 import java.util.List;
34
35 /**
36 * A client-side {@link SslContext} which uses JDK's SSL/TLS implementation.
37 *
38 * @deprecated Use {@link SslContextBuilder} to create {@link JdkSslContext} instances and only
39 * use {@link JdkSslContext} in your code.
40 */
41 @Deprecated
42 public final class JdkSslClientContext extends JdkSslContext {
43
44 /**
45 * Creates a new instance.
46 *
47 * @deprecated use {@link SslContextBuilder}
48 */
49 @Deprecated
50 public JdkSslClientContext() throws SSLException {
51 this(null, null);
52 }
53
54 /**
55 * Creates a new instance.
56 *
57 * @param certChainFile an X.509 certificate chain file in PEM format.
58 * {@code null} to use the system default
59 * @deprecated use {@link SslContextBuilder}
60 */
61 @Deprecated
62 public JdkSslClientContext(File certChainFile) throws SSLException {
63 this(certChainFile, null);
64 }
65
66 /**
67 * Creates a new instance.
68 *
69 * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
70 * that verifies the certificates sent from servers.
71 * {@code null} to use the default.
72 * @deprecated use {@link SslContextBuilder}
73 */
74 @Deprecated
75 public JdkSslClientContext(TrustManagerFactory trustManagerFactory) throws SSLException {
76 this(null, trustManagerFactory);
77 }
78
79 /**
80 * Creates a new instance.
81 *
82 * @param certChainFile an X.509 certificate chain file in PEM format.
83 * {@code null} to use the system default
84 * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
85 * that verifies the certificates sent from servers.
86 * {@code null} to use the default.
87 * @deprecated use {@link SslContextBuilder}
88 */
89 @Deprecated
90 public JdkSslClientContext(File certChainFile, TrustManagerFactory trustManagerFactory) throws SSLException {
91 this(certChainFile, trustManagerFactory, null, IdentityCipherSuiteFilter.INSTANCE,
92 JdkDefaultApplicationProtocolNegotiator.INSTANCE, 0, 0);
93 }
94
95 /**
96 * Creates a new instance.
97 *
98 * @param certChainFile an X.509 certificate chain file in PEM format.
99 * {@code null} to use the system default
100 * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
101 * that verifies the certificates sent from servers.
102 * {@code null} to use the default.
103 * @param ciphers the cipher suites to enable, in the order of preference.
104 * {@code null} to use the default cipher suites.
105 * @param nextProtocols the application layer protocols to accept, in the order of preference.
106 * {@code null} to disable TLS NPN/ALPN extension.
107 * @param sessionCacheSize the size of the cache used for storing SSL session objects.
108 * {@code 0} to use the default value.
109 * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
110 * {@code 0} to use the default value.
111 * @deprecated use {@link SslContextBuilder}
112 */
113 @Deprecated
114 public JdkSslClientContext(
115 File certChainFile, TrustManagerFactory trustManagerFactory,
116 Iterable<String> ciphers, Iterable<String> nextProtocols,
117 long sessionCacheSize, long sessionTimeout) throws SSLException {
118 this(certChainFile, trustManagerFactory, ciphers, IdentityCipherSuiteFilter.INSTANCE,
119 toNegotiator(toApplicationProtocolConfig(nextProtocols), false), sessionCacheSize, sessionTimeout);
120 }
121
122 /**
123 * Creates a new instance.
124 *
125 * @param certChainFile an X.509 certificate chain file in PEM format.
126 * {@code null} to use the system default
127 * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
128 * that verifies the certificates sent from servers.
129 * {@code null} to use the default.
130 * @param ciphers the cipher suites to enable, in the order of preference.
131 * {@code null} to use the default cipher suites.
132 * @param cipherFilter a filter to apply over the supplied list of ciphers
133 * @param apn Provides a means to configure parameters related to application protocol negotiation.
134 * @param sessionCacheSize the size of the cache used for storing SSL session objects.
135 * {@code 0} to use the default value.
136 * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
137 * {@code 0} to use the default value.
138 * @deprecated use {@link SslContextBuilder}
139 */
140 @Deprecated
141 public JdkSslClientContext(
142 File certChainFile, TrustManagerFactory trustManagerFactory,
143 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
144 long sessionCacheSize, long sessionTimeout) throws SSLException {
145 this(certChainFile, trustManagerFactory, ciphers, cipherFilter,
146 toNegotiator(apn, false), sessionCacheSize, sessionTimeout);
147 }
148
149 /**
150 * Creates a new instance.
151 *
152 * @param certChainFile an X.509 certificate chain file in PEM format.
153 * {@code null} to use the system default
154 * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
155 * that verifies the certificates sent from servers.
156 * {@code null} to use the default.
157 * @param ciphers the cipher suites to enable, in the order of preference.
158 * {@code null} to use the default cipher suites.
159 * @param cipherFilter a filter to apply over the supplied list of ciphers
160 * @param apn Application Protocol Negotiator object.
161 * @param sessionCacheSize the size of the cache used for storing SSL session objects.
162 * {@code 0} to use the default value.
163 * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
164 * {@code 0} to use the default value.
165 * @deprecated use {@link SslContextBuilder}
166 */
167 @Deprecated
168 public JdkSslClientContext(
169 File certChainFile, TrustManagerFactory trustManagerFactory,
170 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
171 long sessionCacheSize, long sessionTimeout) throws SSLException {
172 this(null, certChainFile, trustManagerFactory, ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
173 }
174
175 JdkSslClientContext(Provider provider,
176 File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
177 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
178 long sessionCacheSize, long sessionTimeout) throws SSLException {
179 super(newSSLContext(provider, toX509CertificatesInternal(trustCertCollectionFile),
180 trustManagerFactory, null, null,
181 null, null, sessionCacheSize, sessionTimeout, null, KeyStore.getDefaultType(), null), true,
182 ciphers, cipherFilter, apn, ClientAuth.NONE, null, false);
183 }
184
185 /**
186 * Creates a new instance.
187 * @param trustCertCollectionFile an X.509 certificate collection file in PEM format.
188 * {@code null} to use the system default
189 * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
190 * that verifies the certificates sent from servers.
191 * {@code null} to use the default or the results of parsing
192 * {@code trustCertCollectionFile}
193 * @param keyCertChainFile an X.509 certificate chain file in PEM format.
194 * This provides the public key for mutual authentication.
195 * {@code null} to use the system default
196 * @param keyFile a PKCS#8 private key file in PEM format.
197 * This provides the private key for mutual authentication.
198 * {@code null} for no mutual authentication.
199 * @param keyPassword the password of the {@code keyFile}.
200 * {@code null} if it's not password-protected.
201 * Ignored if {@code keyFile} is {@code null}.
202 * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s
203 * that is used to encrypt data being sent to servers.
204 * {@code null} to use the default or the results of parsing
205 * {@code keyCertChainFile} and {@code keyFile}.
206 * @param ciphers the cipher suites to enable, in the order of preference.
207 * {@code null} to use the default cipher suites.
208 * @param cipherFilter a filter to apply over the supplied list of ciphers
209 * @param apn Provides a means to configure parameters related to application protocol negotiation.
210 * @param sessionCacheSize the size of the cache used for storing SSL session objects.
211 * {@code 0} to use the default value.
212 * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
213 * {@code 0} to use the default value.
214 * @deprecated use {@link SslContextBuilder}
215 */
216 @Deprecated
217 public JdkSslClientContext(File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
218 File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
219 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
220 long sessionCacheSize, long sessionTimeout) throws SSLException {
221 this(trustCertCollectionFile, trustManagerFactory, keyCertChainFile, keyFile, keyPassword, keyManagerFactory,
222 ciphers, cipherFilter, toNegotiator(apn, false), sessionCacheSize, sessionTimeout);
223 }
224
225 /**
226 * Creates a new instance.
227 * @param trustCertCollectionFile an X.509 certificate collection file in PEM format.
228 * {@code null} to use the system default
229 * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
230 * that verifies the certificates sent from servers.
231 * {@code null} to use the default or the results of parsing
232 * {@code trustCertCollectionFile}
233 * @param keyCertChainFile an X.509 certificate chain file in PEM format.
234 * This provides the public key for mutual authentication.
235 * {@code null} to use the system default
236 * @param keyFile a PKCS#8 private key file in PEM format.
237 * This provides the private key for mutual authentication.
238 * {@code null} for no mutual authentication.
239 * @param keyPassword the password of the {@code keyFile}.
240 * {@code null} if it's not password-protected.
241 * Ignored if {@code keyFile} is {@code null}.
242 * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s
243 * that is used to encrypt data being sent to servers.
244 * {@code null} to use the default or the results of parsing
245 * {@code keyCertChainFile} and {@code keyFile}.
246 * @param ciphers the cipher suites to enable, in the order of preference.
247 * {@code null} to use the default cipher suites.
248 * @param cipherFilter a filter to apply over the supplied list of ciphers
249 * @param apn Application Protocol Negotiator object.
250 * @param sessionCacheSize the size of the cache used for storing SSL session objects.
251 * {@code 0} to use the default value.
252 * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
253 * {@code 0} to use the default value.
254 * @deprecated use {@link SslContextBuilder}
255 */
256 @Deprecated
257 public JdkSslClientContext(File trustCertCollectionFile, TrustManagerFactory trustManagerFactory,
258 File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
259 Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
260 long sessionCacheSize, long sessionTimeout) throws SSLException {
261 super(newSSLContext(null, toX509CertificatesInternal(
262 trustCertCollectionFile), trustManagerFactory,
263 toX509CertificatesInternal(keyCertChainFile), toPrivateKeyInternal(keyFile, keyPassword),
264 keyPassword, keyManagerFactory, sessionCacheSize, sessionTimeout,
265 null, KeyStore.getDefaultType(), null), true,
266 ciphers, cipherFilter, apn, ClientAuth.NONE, null, false);
267 }
268
269 JdkSslClientContext(Provider sslContextProvider,
270 X509Certificate[] trustCertCollection, TrustManagerFactory trustManagerFactory,
271 X509Certificate[] keyCertChain, PrivateKey key, String keyPassword,
272 KeyManagerFactory keyManagerFactory, Iterable<String> ciphers, CipherSuiteFilter cipherFilter,
273 ApplicationProtocolConfig apn, String[] protocols, long sessionCacheSize, long sessionTimeout,
274 SecureRandom secureRandom, String keyStoreType, String endpointIdentificationAlgorithm,
275 List<SNIServerName> serverNames, ResumptionController resumptionController)
276 throws SSLException {
277 super(newSSLContext(sslContextProvider, trustCertCollection, trustManagerFactory,
278 keyCertChain, key, keyPassword, keyManagerFactory, sessionCacheSize,
279 sessionTimeout, secureRandom, keyStoreType, resumptionController),
280 true, ciphers, cipherFilter, toNegotiator(apn, false), ClientAuth.NONE, protocols, false,
281 endpointIdentificationAlgorithm, serverNames, resumptionController);
282 }
283
284 private static SSLContext newSSLContext(Provider sslContextProvider,
285 X509Certificate[] trustCertCollection,
286 TrustManagerFactory trustManagerFactory, X509Certificate[] keyCertChain,
287 PrivateKey key, String keyPassword, KeyManagerFactory keyManagerFactory,
288 long sessionCacheSize, long sessionTimeout,
289 SecureRandom secureRandom, String keyStore,
290 ResumptionController resumptionController) throws SSLException {
291 try {
292 if (trustCertCollection != null) {
293 trustManagerFactory = buildTrustManagerFactory(trustCertCollection, trustManagerFactory, keyStore);
294 }
295 if (keyCertChain != null) {
296 keyManagerFactory = buildKeyManagerFactory(keyCertChain, null,
297 key, keyPassword, keyManagerFactory, keyStore);
298 }
299 SSLContext ctx = sslContextProvider == null ? SSLContext.getInstance(PROTOCOL)
300 : SSLContext.getInstance(PROTOCOL, sslContextProvider);
301 ctx.init(keyManagerFactory == null ? null : keyManagerFactory.getKeyManagers(),
302 trustManagerFactory == null ? null :
303 wrapIfNeeded(trustManagerFactory.getTrustManagers(), resumptionController),
304 secureRandom);
305
306 SSLSessionContext sessCtx = ctx.getClientSessionContext();
307 if (sessionCacheSize > 0) {
308 sessCtx.setSessionCacheSize((int) Math.min(sessionCacheSize, Integer.MAX_VALUE));
309 }
310 if (sessionTimeout > 0) {
311 sessCtx.setSessionTimeout((int) Math.min(sessionTimeout, Integer.MAX_VALUE));
312 }
313 return ctx;
314 } catch (Exception e) {
315 if (e instanceof SSLException) {
316 throw (SSLException) e;
317 }
318 throw new SSLException("failed to initialize the client-side SSL context", e);
319 }
320 }
321
322 private static TrustManager[] wrapIfNeeded(TrustManager[] tms, ResumptionController resumptionController) {
323 if (resumptionController != null) {
324 for (int i = 0; i < tms.length; i++) {
325 tms[i] = resumptionController.wrapIfNeeded(tms[i]);
326 }
327 }
328 return tms;
329 }
330 }