src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
branchJDK-8145252-TLS13-branch
changeset 56716 38c2a4078033
parent 56692 7b0bde908f58
equal deleted inserted replaced
56715:b152d06ed6a9 56716:38c2a4078033
    33 import java.util.ArrayList;
    33 import java.util.ArrayList;
    34 import java.util.Queue;
    34 import java.util.Queue;
    35 import java.util.Collection;
    35 import java.util.Collection;
    36 import java.util.Collections;
    36 import java.util.Collections;
    37 import java.util.Enumeration;
    37 import java.util.Enumeration;
    38 import java.util.Hashtable;
       
    39 import java.util.List;
    38 import java.util.List;
    40 import java.util.Vector;
       
    41 import java.util.Optional;
    39 import java.util.Optional;
       
    40 import java.util.concurrent.ConcurrentHashMap;
    42 import java.util.concurrent.ConcurrentLinkedQueue;
    41 import java.util.concurrent.ConcurrentLinkedQueue;
    43 import javax.crypto.SecretKey;
    42 import javax.crypto.SecretKey;
    44 import javax.net.ssl.ExtendedSSLSession;
    43 import javax.net.ssl.ExtendedSSLSession;
    45 import javax.net.ssl.SNIServerName;
    44 import javax.net.ssl.SNIServerName;
    46 import javax.net.ssl.SSLPeerUnverifiedException;
    45 import javax.net.ssl.SSLPeerUnverifiedException;
    72     /*
    71     /*
    73      * we only really need a single null session
    72      * we only really need a single null session
    74      */
    73      */
    75     static final SSLSessionImpl         nullSession = new SSLSessionImpl();
    74     static final SSLSessionImpl         nullSession = new SSLSessionImpl();
    76 
    75 
    77     // compression methods
       
    78     private static final byte           compression_null = 0;
       
    79 
       
    80     /*
    76     /*
    81      * The state of a single session, as described in section 7.1
    77      * The state of a single session, as described in section 7.1
    82      * of the SSLv3 spec.
    78      * of the SSLv3 spec.
    83      */
    79      */
    84     private final ProtocolVersion       protocolVersion;
    80     private final ProtocolVersion       protocolVersion;
    85     private final SessionId             sessionId;
    81     private final SessionId             sessionId;
    86     private X509Certificate[]   peerCerts;
    82     private X509Certificate[]   peerCerts;
    87     private byte                compressionMethod;
       
    88     private CipherSuite         cipherSuite;
    83     private CipherSuite         cipherSuite;
    89     private SecretKey           masterSecret;
    84     private SecretKey           masterSecret;
    90     final boolean               useExtendedMasterSecret;
    85     final boolean               useExtendedMasterSecret;
    91 
    86 
    92     /*
    87     /*
    96     private final long          creationTime;
    91     private final long          creationTime;
    97     private long                lastUsedTime = 0;
    92     private long                lastUsedTime = 0;
    98     private final String        host;
    93     private final String        host;
    99     private final int           port;
    94     private final int           port;
   100     private SSLSessionContextImpl       context;
    95     private SSLSessionContextImpl       context;
   101     private int                 sessionCount;
       
   102     private boolean             invalidated;
    96     private boolean             invalidated;
   103     private X509Certificate[]   localCerts;
    97     private X509Certificate[]   localCerts;
   104     private PrivateKey          localPrivateKey;
    98     private PrivateKey          localPrivateKey;
   105     private final String[]      localSupportedSignAlgs;
    99     private final String[]      localSupportedSignAlgs;
   106     private String[]            peerSupportedSignAlgs;      // for certificate
   100     private String[]            peerSupportedSignAlgs;      // for certificate
   110     private SecretKey           preSharedKey;
   104     private SecretKey           preSharedKey;
   111     private byte[]              pskIdentity;
   105     private byte[]              pskIdentity;
   112     private final long          ticketCreationTime = System.currentTimeMillis();
   106     private final long          ticketCreationTime = System.currentTimeMillis();
   113     private int                 ticketAgeAdd;
   107     private int                 ticketAgeAdd;
   114 
   108 
   115     private int                 negotiatedMaxFragLen;
   109     private int                 negotiatedMaxFragLen = -1;
   116     private int                 maximumPacketSize;
   110     private int                 maximumPacketSize;
   117 
   111 
   118     // Principals for non-certificate based cipher suites
   112     private final Queue<SSLSessionImpl> childSessions =
   119     private Principal peerPrincipal;
   113                                         new ConcurrentLinkedQueue<>();
   120     private Principal localPrincipal;
       
   121 
       
   122     private Queue<SSLSessionImpl> childSessions = new ConcurrentLinkedQueue<SSLSessionImpl>();
       
   123 
   114 
   124     /*
   115     /*
   125      * Is the session currently re-established with a session-resumption
   116      * Is the session currently re-established with a session-resumption
   126      * abbreviated initial handshake?
   117      * abbreviated initial handshake?
   127      *
   118      *
   128      * Note that currently we only set this variable in client side.
   119      * Note that currently we only set this variable in client side.
   129      */
   120      */
   130     private boolean isSessionResumption = false;
   121     private boolean isSessionResumption = false;
   131 
       
   132     /*
       
   133      * We count session creations, eventually for statistical data but
       
   134      * also since counters make shorter debugging IDs than the big ones
       
   135      * we use in the protocol for uniqueness-over-time.
       
   136      */
       
   137     private static volatile int counter;
       
   138 
   122 
   139     /*
   123     /*
   140      * Use of session caches is globally enabled/disabled.
   124      * Use of session caches is globally enabled/disabled.
   141      */
   125      */
   142     private static boolean      defaultRejoinable = true;
   126     private static boolean      defaultRejoinable = true;
   188      * Record a new session, using a given cipher spec, session ID,
   172      * Record a new session, using a given cipher spec, session ID,
   189      * and creation time
   173      * and creation time
   190      */
   174      */
   191     SSLSessionImpl(HandshakeContext hc,
   175     SSLSessionImpl(HandshakeContext hc,
   192             CipherSuite cipherSuite, SessionId id, long creationTime) {
   176             CipherSuite cipherSuite, SessionId id, long creationTime) {
   193         this.creationTime = creationTime;
       
   194         this.protocolVersion = hc.negotiatedProtocol;
   177         this.protocolVersion = hc.negotiatedProtocol;
       
   178         this.cipherSuite = cipherSuite;
   195         this.sessionId = id;
   179         this.sessionId = id;
   196         peerCerts = null;
       
   197         compressionMethod = compression_null;
       
   198         this.cipherSuite = cipherSuite;
       
   199         masterSecret = null;
       
   200         this.host = hc.conContext.transport.getPeerHost();
   180         this.host = hc.conContext.transport.getPeerHost();
   201         this.port = hc.conContext.transport.getPeerPort();
   181         this.port = hc.conContext.transport.getPeerPort();
   202         sessionCount = ++counter;
       
   203         this.localSupportedSignAlgs =
   182         this.localSupportedSignAlgs =
   204             SignatureScheme.getAlgorithmNames(hc.localSupportedSignAlgs);
   183                 SignatureScheme.getAlgorithmNames(hc.localSupportedSignAlgs);
   205         negotiatedMaxFragLen = -1;
   184         this.serverNameIndication = hc.negotiatedServerName;
   206         statusResponses = null;
       
   207         this.requestedServerNames = Collections.<SNIServerName>unmodifiableList(
   185         this.requestedServerNames = Collections.<SNIServerName>unmodifiableList(
   208                 hc.getRequestedServerNames());
   186                 hc.getRequestedServerNames());
   209         this.serverNameIndication = hc.negotiatedServerName;
       
   210         if (hc.sslConfig.isClientMode) {
   187         if (hc.sslConfig.isClientMode) {
   211             this.useExtendedMasterSecret =
   188             this.useExtendedMasterSecret =
   212                 (hc.handshakeExtensions.get(
   189                 (hc.handshakeExtensions.get(
   213                         SSLExtension.CH_EXTENDED_MASTER_SECRET) != null) &&
   190                         SSLExtension.CH_EXTENDED_MASTER_SECRET) != null) &&
   214                 (hc.handshakeExtensions.get(
   191                 (hc.handshakeExtensions.get(
   217             this.useExtendedMasterSecret =
   194             this.useExtendedMasterSecret =
   218                 (hc.handshakeExtensions.get(
   195                 (hc.handshakeExtensions.get(
   219                         SSLExtension.CH_EXTENDED_MASTER_SECRET) != null) &&
   196                         SSLExtension.CH_EXTENDED_MASTER_SECRET) != null) &&
   220                 (!hc.negotiatedProtocol.useTLS13PlusSpec());
   197                 (!hc.negotiatedProtocol.useTLS13PlusSpec());
   221         }
   198         }
       
   199         this.creationTime = creationTime;
   222 
   200 
   223         if (SSLLogger.isOn && SSLLogger.isOn("session")) {
   201         if (SSLLogger.isOn && SSLLogger.isOn("session")) {
   224              SSLLogger.finest("Session initialized:  " + this);
   202              SSLLogger.finest("Session initialized:  " + this);
   225         }
   203         }
   226     }
   204     }
   227 
   205 
   228     void setMasterSecret(SecretKey secret) {
   206     void setMasterSecret(SecretKey secret) {
   229         if (masterSecret == null) {
   207         masterSecret = secret;
   230             masterSecret = secret;
       
   231         } else {
       
   232             throw new RuntimeException("setMasterSecret() error");
       
   233         }
       
   234     }
   208     }
   235 
   209 
   236     void setResumptionMasterSecret(SecretKey secret) {
   210     void setResumptionMasterSecret(SecretKey secret) {
   237         if (resumptionMasterSecret == null) {
   211         resumptionMasterSecret = secret;
   238             resumptionMasterSecret = secret;
       
   239         } else {
       
   240             throw new RuntimeException("setResumptionMasterSecret() error");
       
   241         }
       
   242     }
   212     }
   243 
   213 
   244     void setPreSharedKey(SecretKey key) {
   214     void setPreSharedKey(SecretKey key) {
   245         if (preSharedKey == null) {
   215         preSharedKey = key;
   246             preSharedKey = key;
       
   247         } else {
       
   248             throw new RuntimeException("setPreSharedKey() error");
       
   249         }
       
   250     }
   216     }
   251 
   217 
   252     void addChild(SSLSessionImpl session) {
   218     void addChild(SSLSessionImpl session) {
   253         childSessions.add(session);
   219         childSessions.add(session);
   254     }
   220     }
   256     void setTicketAgeAdd(int ticketAgeAdd) {
   222     void setTicketAgeAdd(int ticketAgeAdd) {
   257         this.ticketAgeAdd = ticketAgeAdd;
   223         this.ticketAgeAdd = ticketAgeAdd;
   258     }
   224     }
   259 
   225 
   260     void setPskIdentity(byte[] pskIdentity) {
   226     void setPskIdentity(byte[] pskIdentity) {
   261         if (this.pskIdentity == null) {
   227         this.pskIdentity = pskIdentity;
   262             this.pskIdentity = pskIdentity;
       
   263         } else {
       
   264             throw new RuntimeException("setPskIdentity() error");
       
   265         }
       
   266     }
   228     }
   267 
   229 
   268     BigInteger incrTicketNonceCounter() {
   230     BigInteger incrTicketNonceCounter() {
   269         BigInteger result = ticketNonceCounter;
   231         BigInteger result = ticketNonceCounter;
   270         ticketNonceCounter = ticketNonceCounter.add(BigInteger.valueOf(1));
   232         ticketNonceCounter = ticketNonceCounter.add(BigInteger.valueOf(1));
   371             statusResponses = Collections.emptyList();
   333             statusResponses = Collections.emptyList();
   372         }
   334         }
   373     }
   335     }
   374 
   336 
   375     /**
   337     /**
   376      * Set the peer principal.
       
   377      */
       
   378     void setPeerPrincipal(Principal principal) {
       
   379         if (peerPrincipal == null) {
       
   380             peerPrincipal = principal;
       
   381         }
       
   382     }
       
   383 
       
   384     /**
       
   385      * Set the local principal.
       
   386      */
       
   387     void setLocalPrincipal(Principal principal) {
       
   388         localPrincipal = principal;
       
   389     }
       
   390 
       
   391     /**
       
   392      * Returns true iff this session may be resumed ... sessions are
   338      * Returns true iff this session may be resumed ... sessions are
   393      * usually resumable.  Security policies may suggest otherwise,
   339      * usually resumable.  Security policies may suggest otherwise,
   394      * for example sessions that haven't been used for a while (say,
   340      * for example sessions that haven't been used for a while (say,
   395      * a working day) won't be resumable, and sessions might have a
   341      * a working day) won't be resumable, and sessions might have a
   396      * maximum lifetime in any case.
   342      * maximum lifetime in any case.
   518     public String getProtocol() {
   464     public String getProtocol() {
   519         return getProtocolVersion().name;
   465         return getProtocolVersion().name;
   520     }
   466     }
   521 
   467 
   522     /**
   468     /**
   523      * Returns the compression technique used in this session
       
   524      */
       
   525     byte getCompression() {
       
   526         return compressionMethod;
       
   527     }
       
   528 
       
   529     /**
       
   530      * Returns the hashcode for this session
   469      * Returns the hashcode for this session
   531      */
   470      */
   532     @Override
   471     @Override
   533     public int hashCode() {
   472     public int hashCode() {
   534         return sessionId.hashCode();
   473         return sessionId.hashCode();
   820     /*
   759     /*
   821      * Table of application-specific session data indexed by an application
   760      * Table of application-specific session data indexed by an application
   822      * key and the calling security context. This is important since
   761      * key and the calling security context. This is important since
   823      * sessions can be shared across different protection domains.
   762      * sessions can be shared across different protection domains.
   824      */
   763      */
   825     private Hashtable<SecureKey, Object> table = new Hashtable<>();
   764     private final ConcurrentHashMap<SecureKey, Object> boundValues =
       
   765             new ConcurrentHashMap<>();
   826 
   766 
   827     /**
   767     /**
   828      * Assigns a session value.  Session change events are given if
   768      * Assigns a session value.  Session change events are given if
   829      * appropriate, to any original value as well as the new value.
   769      * appropriate, to any original value as well as the new value.
   830      */
   770      */
   833         if ((key == null) || (value == null)) {
   773         if ((key == null) || (value == null)) {
   834             throw new IllegalArgumentException("arguments can not be null");
   774             throw new IllegalArgumentException("arguments can not be null");
   835         }
   775         }
   836 
   776 
   837         SecureKey secureKey = new SecureKey(key);
   777         SecureKey secureKey = new SecureKey(key);
   838         Object oldValue = table.put(secureKey, value);
   778         Object oldValue = boundValues.put(secureKey, value);
   839 
   779 
   840         if (oldValue instanceof SSLSessionBindingListener) {
   780         if (oldValue instanceof SSLSessionBindingListener) {
   841             SSLSessionBindingEvent e;
   781             SSLSessionBindingEvent e;
   842 
   782 
   843             e = new SSLSessionBindingEvent(this, key);
   783             e = new SSLSessionBindingEvent(this, key);
   859         if (key == null) {
   799         if (key == null) {
   860             throw new IllegalArgumentException("argument can not be null");
   800             throw new IllegalArgumentException("argument can not be null");
   861         }
   801         }
   862 
   802 
   863         SecureKey secureKey = new SecureKey(key);
   803         SecureKey secureKey = new SecureKey(key);
   864         return table.get(secureKey);
   804         return boundValues.get(secureKey);
   865     }
   805     }
   866 
   806 
   867 
   807 
   868     /**
   808     /**
   869      * Removes the specified session value, delivering a session changed
   809      * Removes the specified session value, delivering a session changed
   874         if (key == null) {
   814         if (key == null) {
   875             throw new IllegalArgumentException("argument can not be null");
   815             throw new IllegalArgumentException("argument can not be null");
   876         }
   816         }
   877 
   817 
   878         SecureKey secureKey = new SecureKey(key);
   818         SecureKey secureKey = new SecureKey(key);
   879         Object value = table.remove(secureKey);
   819         Object value = boundValues.remove(secureKey);
   880 
   820 
   881         if (value instanceof SSLSessionBindingListener) {
   821         if (value instanceof SSLSessionBindingListener) {
   882             SSLSessionBindingEvent e;
   822             SSLSessionBindingEvent e;
   883 
   823 
   884             e = new SSLSessionBindingEvent(this, key);
   824             e = new SSLSessionBindingEvent(this, key);
   890     /**
   830     /**
   891      * Lists the names of the session values.
   831      * Lists the names of the session values.
   892      */
   832      */
   893     @Override
   833     @Override
   894     public String[] getValueNames() {
   834     public String[] getValueNames() {
   895         Enumeration<SecureKey> e;
   835         ArrayList<Object> v = new ArrayList<>();
   896         Vector<Object> v = new Vector<>();
       
   897         SecureKey key;
       
   898         Object securityCtx = SecureKey.getCurrentSecurityContext();
   836         Object securityCtx = SecureKey.getCurrentSecurityContext();
   899 
   837         for (Enumeration<SecureKey> e = boundValues.keys();
   900         for (e = table.keys(); e.hasMoreElements(); ) {
   838                 e.hasMoreElements(); ) {
   901             key = e.nextElement();
   839             SecureKey key = e.nextElement();
   902 
       
   903             if (securityCtx.equals(key.getSecurityContext())) {
   840             if (securityCtx.equals(key.getSecurityContext())) {
   904                 v.addElement(key.getAppKey());
   841                 v.add(key.getAppKey());
   905             }
   842             }
   906         }
   843         }
   907         String[] names = new String[v.size()];
   844 
   908         v.copyInto(names);
   845         return v.toArray(new String[0]);
   909 
       
   910         return names;
       
   911     }
   846     }
   912 
   847 
   913     /**
   848     /**
   914      * Use large packet sizes now or follow RFC 2246 packet sizes (2^14)
   849      * Use large packet sizes now or follow RFC 2246 packet sizes (2^14)
   915      * until changed.
   850      * until changed.
  1063      * Obtains a <code>List</code> containing all {@link SNIServerName}s
   998      * Obtains a <code>List</code> containing all {@link SNIServerName}s
  1064      * of the requested Server Name Indication (SNI) extension.
   999      * of the requested Server Name Indication (SNI) extension.
  1065      */
  1000      */
  1066     @Override
  1001     @Override
  1067     public List<SNIServerName> getRequestedServerNames() {
  1002     public List<SNIServerName> getRequestedServerNames() {
  1068         if (requestedServerNames == null) {
       
  1069             return Collections.<SNIServerName>emptyList();
       
  1070         }
       
  1071         return requestedServerNames;
  1003         return requestedServerNames;
  1072     }
  1004     }
  1073 
  1005 
  1074     /** Returns a string representation of this SSL session */
  1006     /** Returns a string representation of this SSL session */
  1075     @Override
  1007     @Override
  1076     public String toString() {
  1008     public String toString() {
  1077         return "[Session-" + sessionCount
  1009         return "Session(" + creationTime + "|" + getCipherSuite() + ")";
  1078             + ", " + getCipherSuite()
       
  1079             + "]";
       
  1080     }
  1010     }
  1081 }
  1011 }
  1082 
       
  1083 
  1012 
  1084 /**
  1013 /**
  1085  * This "struct" class serves as a Hash Key that combines an
  1014  * This "struct" class serves as a Hash Key that combines an
  1086  * application-specific key and a security context.
  1015  * application-specific key and a security context.
  1087  */
  1016  */
  1088 class SecureKey {
  1017 class SecureKey {
  1089     private static Object       nullObject = new Object();
  1018     private static final Object     nullObject = new Object();
  1090     private Object              appKey;
  1019     private final Object            appKey;
  1091     private Object              securityCtx;
  1020     private final Object            securityCtx;
  1092 
  1021 
  1093     static Object getCurrentSecurityContext() {
  1022     static Object getCurrentSecurityContext() {
  1094         SecurityManager sm = System.getSecurityManager();
  1023         SecurityManager sm = System.getSecurityManager();
  1095         Object context = null;
  1024         Object context = null;
  1096 
  1025