src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java
changeset 55336 c2398053ee90
parent 52764 8a85d21d9616
child 57483 afeafa018937
equal deleted inserted replaced
55335:f7cc25dda38a 55336:c2398053ee90
     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     // Does this context support stateless session (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      */
   161 
   192 
   162         return null;
   193         return null;
   163     }
   194     }
   164 
   195 
   165     private static String getKey(String hostname, int port) {
   196     private static String getKey(String hostname, int port) {
   166         return (hostname + ":" +
   197         return (hostname + ":" + port).toLowerCase(Locale.ENGLISH);
   167             String.valueOf(port)).toLowerCase(Locale.ENGLISH);
       
   168     }
   198     }
   169 
   199 
   170     // cache a SSLSession
   200     // cache a SSLSession
   171     //
   201     //
   172     // In SunJSSE implementation, a session is created while getting a
   202     // In SunJSSE implementation, a session is created while getting a
   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             if (st.compareToIgnoreCase("false") == 0) {
       
   243                 statelessSession = false;
       
   244             }
       
   245 
       
   246             // Property for Session Ticket Timeout.  The value can be changed
       
   247             // by SSLSessionContext.setSessionTimeout(int)
       
   248             String s = GetPropertyAction.privilegedGetProperty(
       
   249                     "jdk.tls.server.sessionTicketTimeout");
       
   250             if (s != null) {
       
   251                 try {
       
   252                     int t = Integer.parseInt(s);
       
   253                     if (t < 0 ||
       
   254                             t > NewSessionTicket.MAX_TICKET_LIFETIME) {
       
   255                         timeout = DEFAULT_SESSION_TIMEOUT;
       
   256                         if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
       
   257                             SSLLogger.warning("Invalid timeout given " +
       
   258                                     "jdk.tls.server.sessionTicketTimeout: " + t +
       
   259                                     ".  Set to default value " + timeout);
       
   260                         }
       
   261                     } else {
       
   262                         timeout = t;
       
   263                     }
       
   264                 } catch (NumberFormatException e) {
       
   265                     setSessionTimeout(DEFAULT_SESSION_TIMEOUT);
       
   266                     if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
       
   267                         SSLLogger.warning("Invalid timeout for " +
       
   268                                 "jdk.tls.server.sessionTicketTimeout: " + s +
       
   269                                 ".  Set to default value " + timeout);
       
   270 
       
   271                     }
       
   272                 }
       
   273             }
       
   274 
   202             int defaultCacheLimit = GetIntegerAction.privilegedGetProperty(
   275             int defaultCacheLimit = GetIntegerAction.privilegedGetProperty(
   203                     "javax.net.ssl.sessionCacheSize", DEFAULT_MAX_CACHE_SIZE);
   276                     "javax.net.ssl.sessionCacheSize", DEFAULT_MAX_CACHE_SIZE);
   204 
   277 
   205             if (defaultCacheLimit >= 0) {
   278             if (defaultCacheLimit >= 0) {
   206                 return defaultCacheLimit;
   279                 return defaultCacheLimit;