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