src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java
branchdatagramsocketimpl-branch
changeset 58678 9cf78a70fa4f
parent 52764 8a85d21d9616
child 58679 9c3209ff7550
equal deleted inserted replaced
58677:13588c901957 58678:9cf78a70fa4f
     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      */
   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 
       
   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;