View Javadoc
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    *   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, 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.io.File;
20  
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  
29  /**
30   * A client-side {@link SslContext} which uses JDK's SSL/TLS implementation.
31   */
32  public final class JdkSslClientContext extends JdkSslContext {
33  
34      private final SSLContext ctx;
35  
36      /**
37       * Creates a new instance.
38       */
39      public JdkSslClientContext() throws SSLException {
40          this(null, null);
41      }
42  
43      /**
44       * Creates a new instance.
45       *
46       * @param certChainFile an X.509 certificate chain file in PEM format.
47       *                      {@code null} to use the system default
48       */
49      public JdkSslClientContext(File certChainFile) throws SSLException {
50          this(certChainFile, null);
51      }
52  
53      /**
54       * Creates a new instance.
55       *
56       * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
57       *                            that verifies the certificates sent from servers.
58       *                            {@code null} to use the default.
59       */
60      public JdkSslClientContext(TrustManagerFactory trustManagerFactory) throws SSLException {
61          this(null, trustManagerFactory);
62      }
63  
64      /**
65       * Creates a new instance.
66       *
67       * @param certChainFile an X.509 certificate chain file in PEM format.
68       *                      {@code null} to use the system default
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       */
73      public JdkSslClientContext(File certChainFile, TrustManagerFactory trustManagerFactory) throws SSLException {
74          this(certChainFile, trustManagerFactory, null, IdentityCipherSuiteFilter.INSTANCE,
75                  JdkDefaultApplicationProtocolNegotiator.INSTANCE, 0, 0);
76      }
77  
78      /**
79       * Creates a new instance.
80       *
81       * @param certChainFile an X.509 certificate chain file in PEM format.
82       *                      {@code null} to use the system default
83       * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
84       *                            that verifies the certificates sent from servers.
85       *                            {@code null} to use the default.
86       * @param ciphers the cipher suites to enable, in the order of preference.
87       *                {@code null} to use the default cipher suites.
88       * @param cipherFilter a filter to apply over the supplied list of ciphers
89       * @param apn Provides a means to configure parameters related to application protocol negotiation.
90       * @param sessionCacheSize the size of the cache used for storing SSL session objects.
91       *                         {@code 0} to use the default value.
92       * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
93       *                       {@code 0} to use the default value.
94       */
95      public JdkSslClientContext(
96              File certChainFile, TrustManagerFactory trustManagerFactory,
97              Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
98              long sessionCacheSize, long sessionTimeout) throws SSLException {
99          this(certChainFile, trustManagerFactory, ciphers, cipherFilter,
100                 toNegotiator(apn, false), sessionCacheSize, sessionTimeout);
101     }
102 
103     /**
104      * Creates a new instance.
105      *
106      * @param certChainFile an X.509 certificate chain file in PEM format.
107      *                      {@code null} to use the system default
108      * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
109      *                            that verifies the certificates sent from servers.
110      *                            {@code null} to use the default.
111      * @param ciphers the cipher suites to enable, in the order of preference.
112      *                {@code null} to use the default cipher suites.
113      * @param cipherFilter a filter to apply over the supplied list of ciphers
114      * @param apn Application Protocol Negotiator object.
115      * @param sessionCacheSize the size of the cache used for storing SSL session objects.
116      *                         {@code 0} to use the default value.
117      * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
118      *                       {@code 0} to use the default value.
119      */
120     public JdkSslClientContext(
121             File certChainFile, TrustManagerFactory trustManagerFactory,
122             Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
123             long sessionCacheSize, long sessionTimeout) throws SSLException {
124         this(certChainFile, trustManagerFactory, null, null, null, null,
125                 ciphers, cipherFilter, apn, sessionCacheSize, sessionTimeout);
126     }
127 
128     /**
129      * Creates a new instance.
130      * @param trustCertChainFile an X.509 certificate chain file in PEM format.
131      *                      {@code null} to use the system default
132      * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
133      *                            that verifies the certificates sent from servers.
134      *                            {@code null} to use the default or the results of parsing {@code trustCertChainFile}
135      * @param keyCertChainFile an X.509 certificate chain file in PEM format.
136      *                      This provides the public key for mutual authentication.
137      *                      {@code null} to use the system default
138      * @param keyFile a PKCS#8 private key file in PEM format.
139      *                      This provides the private key for mutual authentication.
140      *                      {@code null} for no mutual authentication.
141      * @param keyPassword the password of the {@code keyFile}.
142      *                    {@code null} if it's not password-protected.
143      *                    Ignored if {@code keyFile} is {@code null}.
144      * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s
145      *                          that is used to encrypt data being sent to servers.
146      *                          {@code null} to use the default or the results of parsing
147      *                          {@code keyCertChainFile} and {@code keyFile}.
148      * @param ciphers the cipher suites to enable, in the order of preference.
149      *                {@code null} to use the default cipher suites.
150      * @param cipherFilter a filter to apply over the supplied list of ciphers
151      * @param apn Provides a means to configure parameters related to application protocol negotiation.
152      * @param sessionCacheSize the size of the cache used for storing SSL session objects.
153      *                         {@code 0} to use the default value.
154      * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
155      *                       {@code 0} to use the default value.
156      */
157     public JdkSslClientContext(File trustCertChainFile, TrustManagerFactory trustManagerFactory,
158             File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
159             Iterable<String> ciphers, CipherSuiteFilter cipherFilter, ApplicationProtocolConfig apn,
160             long sessionCacheSize, long sessionTimeout) throws SSLException {
161         this(trustCertChainFile, trustManagerFactory, keyCertChainFile, keyFile, keyPassword, keyManagerFactory,
162                 ciphers, cipherFilter, toNegotiator(apn, false), sessionCacheSize, sessionTimeout);
163     }
164 
165     /**
166      * Creates a new instance.
167      * @param trustCertChainFile an X.509 certificate chain file in PEM format.
168      *                      {@code null} to use the system default
169      * @param trustManagerFactory the {@link TrustManagerFactory} that provides the {@link TrustManager}s
170      *                            that verifies the certificates sent from servers.
171      *                            {@code null} to use the default or the results of parsing {@code trustCertChainFile}
172      * @param keyCertChainFile an X.509 certificate chain file in PEM format.
173      *                      This provides the public key for mutual authentication.
174      *                      {@code null} to use the system default
175      * @param keyFile a PKCS#8 private key file in PEM format.
176      *                      This provides the private key for mutual authentication.
177      *                      {@code null} for no mutual authentication.
178      * @param keyPassword the password of the {@code keyFile}.
179      *                    {@code null} if it's not password-protected.
180      *                    Ignored if {@code keyFile} is {@code null}.
181      * @param keyManagerFactory the {@link KeyManagerFactory} that provides the {@link KeyManager}s
182      *                          that is used to encrypt data being sent to servers.
183      *                          {@code null} to use the default or the results of parsing
184      *                          {@code keyCertChainFile} and {@code keyFile}.
185      * @param ciphers the cipher suites to enable, in the order of preference.
186      *                {@code null} to use the default cipher suites.
187      * @param cipherFilter a filter to apply over the supplied list of ciphers
188      * @param apn Application Protocol Negotiator object.
189      * @param sessionCacheSize the size of the cache used for storing SSL session objects.
190      *                         {@code 0} to use the default value.
191      * @param sessionTimeout the timeout for the cached SSL session objects, in seconds.
192      *                       {@code 0} to use the default value.
193      */
194     public JdkSslClientContext(File trustCertChainFile, TrustManagerFactory trustManagerFactory,
195             File keyCertChainFile, File keyFile, String keyPassword, KeyManagerFactory keyManagerFactory,
196             Iterable<String> ciphers, CipherSuiteFilter cipherFilter, JdkApplicationProtocolNegotiator apn,
197             long sessionCacheSize, long sessionTimeout) throws SSLException {
198         super(ciphers, cipherFilter, apn);
199 
200         try {
201             if (trustCertChainFile != null) {
202                 trustManagerFactory = buildTrustManagerFactory(trustCertChainFile, trustManagerFactory);
203             }
204             if (keyFile != null) {
205                 keyManagerFactory = buildKeyManagerFactory(keyCertChainFile, keyFile, keyPassword, keyManagerFactory);
206             }
207             ctx = SSLContext.getInstance(PROTOCOL);
208             ctx.init(keyManagerFactory == null ? null : keyManagerFactory.getKeyManagers(),
209                      trustManagerFactory == null ? null : trustManagerFactory.getTrustManagers(),
210                      null);
211 
212             SSLSessionContext sessCtx = ctx.getClientSessionContext();
213             if (sessionCacheSize > 0) {
214                 sessCtx.setSessionCacheSize((int) Math.min(sessionCacheSize, Integer.MAX_VALUE));
215             }
216             if (sessionTimeout > 0) {
217                 sessCtx.setSessionTimeout((int) Math.min(sessionTimeout, Integer.MAX_VALUE));
218             }
219         } catch (Exception e) {
220             throw new SSLException("failed to initialize the client-side SSL context", e);
221         }
222     }
223 
224     @Override
225     public boolean isClient() {
226         return true;
227     }
228 
229     @Override
230     public SSLContext context() {
231         return ctx;
232     }
233 }