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