1 /* |
1 /* |
2 * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
31 import java.util.Locale; |
31 import java.util.Locale; |
32 import javax.net.ssl.SSLSession; |
32 import javax.net.ssl.SSLSession; |
33 import javax.net.ssl.SSLSessionContext; |
33 import javax.net.ssl.SSLSessionContext; |
34 |
34 |
35 import sun.security.action.GetIntegerAction; |
35 import sun.security.action.GetIntegerAction; |
|
36 import sun.security.action.GetPropertyAction; |
36 import sun.security.util.Cache; |
37 import sun.security.util.Cache; |
37 |
38 |
|
39 |
|
40 /** |
|
41 * @systemProperty jdk.tls.server.enableSessionTicketExtension} determines if the |
|
42 * server will provide stateless session tickets, if the client supports it, |
|
43 * as described in RFC 5077 and RFC 8446. a stateless session ticket |
|
44 * contains the encrypted server's state which saves server resources. |
|
45 * |
|
46 * {@systemProperty jdk.tls.client.enableSessionTicketExtension} determines if the |
|
47 * client will send an extension in the ClientHello in the pre-TLS 1.3. |
|
48 * This extension allows the client to accept the server's session state for |
|
49 * Server Side stateless resumption (RFC 5077). Setting the property to |
|
50 * "true" turns this on, by default it is false. For TLS 1.3, the system |
|
51 * property is not needed as this support is part of the spec. |
|
52 * |
|
53 * {@systemProperty jdk.tls.server.sessionTicketTimeout} determines how long |
|
54 * a session in the server cache or the stateless resumption tickets are |
|
55 * available for use. The value set by the property can be modified by |
|
56 * {@code SSLSessionContext.setSessionTimeout()} during runtime. |
|
57 * |
|
58 */ |
38 |
59 |
39 final class SSLSessionContextImpl implements SSLSessionContext { |
60 final class SSLSessionContextImpl implements SSLSessionContext { |
40 private final static int DEFAULT_MAX_CACHE_SIZE = 20480; |
61 private final static int DEFAULT_MAX_CACHE_SIZE = 20480; |
|
62 // Default lifetime of a session. 24 hours |
|
63 final static int DEFAULT_SESSION_TIMEOUT = 86400; |
41 |
64 |
42 private final Cache<SessionId, SSLSessionImpl> sessionCache; |
65 private final Cache<SessionId, SSLSessionImpl> sessionCache; |
43 // session cache, session id as key |
66 // session cache, session id as key |
44 private final Cache<String, SSLSessionImpl> sessionHostPortCache; |
67 private final Cache<String, SSLSessionImpl> sessionHostPortCache; |
45 // session cache, "host:port" as key |
68 // session cache, "host:port" as key |
46 private int cacheLimit; // the max cache size |
69 private int cacheLimit; // the max cache size |
47 private int timeout; // timeout in seconds |
70 private int timeout; // timeout in seconds |
48 |
71 |
|
72 // Default setting for stateless session resumption support (RFC 5077) |
|
73 private boolean statelessSession = true; |
|
74 |
49 // package private |
75 // package private |
50 SSLSessionContextImpl() { |
76 SSLSessionContextImpl(boolean server) { |
51 cacheLimit = getDefaultCacheLimit(); // default cache size |
77 timeout = DEFAULT_SESSION_TIMEOUT; |
52 timeout = 86400; // default, 24 hours |
78 cacheLimit = getDefaults(server); // default cache size |
53 |
79 |
54 // use soft reference |
80 // use soft reference |
55 sessionCache = Cache.newSoftMemoryCache(cacheLimit, timeout); |
81 sessionCache = Cache.newSoftMemoryCache(cacheLimit, timeout); |
56 sessionHostPortCache = Cache.newSoftMemoryCache(cacheLimit, timeout); |
82 sessionHostPortCache = Cache.newSoftMemoryCache(cacheLimit, timeout); |
|
83 } |
|
84 |
|
85 // Stateless sessions when available, but there is a cache |
|
86 boolean statelessEnabled() { |
|
87 return statelessSession; |
57 } |
88 } |
58 |
89 |
59 /** |
90 /** |
60 * Returns the <code>SSLSession</code> bound to the specified session id. |
91 * Returns the <code>SSLSession</code> bound to the specified session id. |
61 */ |
92 */ |
195 sessionHostPortCache.remove( |
225 sessionHostPortCache.remove( |
196 getKey(s.getPeerHost(), s.getPeerPort())); |
226 getKey(s.getPeerHost(), s.getPeerPort())); |
197 } |
227 } |
198 } |
228 } |
199 |
229 |
200 private static int getDefaultCacheLimit() { |
230 private int getDefaults(boolean server) { |
201 try { |
231 try { |
|
232 String st; |
|
233 |
|
234 // Property for Session Cache state |
|
235 if (server) { |
|
236 st = GetPropertyAction.privilegedGetProperty( |
|
237 "jdk.tls.server.enableSessionTicketExtension", "true"); |
|
238 } else { |
|
239 st = GetPropertyAction.privilegedGetProperty( |
|
240 "jdk.tls.client.enableSessionTicketExtension", "true"); |
|
241 } |
|
242 |
|
243 if (st.compareToIgnoreCase("false") == 0) { |
|
244 statelessSession = false; |
|
245 } |
|
246 |
|
247 // Property for Session Ticket Timeout. The value can be changed |
|
248 // by SSLSessionContext.setSessionTimeout(int) |
|
249 String s = GetPropertyAction.privilegedGetProperty( |
|
250 "jdk.tls.server.sessionTicketTimeout"); |
|
251 if (s != null) { |
|
252 try { |
|
253 int t = Integer.parseInt(s); |
|
254 if (t < 0 || |
|
255 t > NewSessionTicket.MAX_TICKET_LIFETIME) { |
|
256 timeout = DEFAULT_SESSION_TIMEOUT; |
|
257 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { |
|
258 SSLLogger.warning("Invalid timeout given " + |
|
259 "jdk.tls.server.sessionTicketTimeout: " + t + |
|
260 ". Set to default value " + timeout); |
|
261 } |
|
262 } else { |
|
263 timeout = t; |
|
264 } |
|
265 } catch (NumberFormatException e) { |
|
266 setSessionTimeout(DEFAULT_SESSION_TIMEOUT); |
|
267 if (SSLLogger.isOn && SSLLogger.isOn("ssl")) { |
|
268 SSLLogger.warning("Invalid timeout for " + |
|
269 "jdk.tls.server.sessionTicketTimeout: " + s + |
|
270 ". Set to default value " + timeout); |
|
271 |
|
272 } |
|
273 } |
|
274 } |
|
275 |
202 int defaultCacheLimit = GetIntegerAction.privilegedGetProperty( |
276 int defaultCacheLimit = GetIntegerAction.privilegedGetProperty( |
203 "javax.net.ssl.sessionCacheSize", DEFAULT_MAX_CACHE_SIZE); |
277 "javax.net.ssl.sessionCacheSize", DEFAULT_MAX_CACHE_SIZE); |
204 |
278 |
205 if (defaultCacheLimit >= 0) { |
279 if (defaultCacheLimit >= 0) { |
206 return defaultCacheLimit; |
280 return defaultCacheLimit; |