src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
changeset 50768 68fa3d4026ea
parent 48225 718669e6b375
child 50987 e4a92c455d1c
equal deleted inserted replaced
50767:356eaea05bf0 50768:68fa3d4026ea
     1 /*
     1 /*
     2  * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1996, 2018, 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
    20  *
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    23  * questions.
    24  */
    24  */
    25 
       
    26 
       
    27 package sun.security.ssl;
    25 package sun.security.ssl;
    28 
    26 
    29 import java.net.*;
    27 import java.math.BigInteger;
    30 import java.util.Enumeration;
    28 import java.net.InetAddress;
    31 import java.util.Hashtable;
    29 import java.security.Principal;
    32 import java.util.Vector;
    30 import java.security.PrivateKey;
       
    31 import java.security.cert.CertificateEncodingException;
       
    32 import java.security.cert.X509Certificate;
       
    33 import java.util.ArrayList;
       
    34 import java.util.Queue;
    33 import java.util.Collection;
    35 import java.util.Collection;
    34 import java.util.Collections;
    36 import java.util.Collections;
       
    37 import java.util.Enumeration;
    35 import java.util.List;
    38 import java.util.List;
    36 import java.util.ArrayList;
    39 import java.util.Optional;
    37 
    40 import java.util.concurrent.ConcurrentHashMap;
    38 import java.security.Principal;
    41 import java.util.concurrent.ConcurrentLinkedQueue;
    39 import java.security.PrivateKey;
       
    40 import java.security.SecureRandom;
       
    41 import java.security.cert.X509Certificate;
       
    42 import java.security.cert.CertificateEncodingException;
       
    43 
       
    44 import javax.crypto.SecretKey;
    42 import javax.crypto.SecretKey;
    45 
    43 import javax.net.ssl.ExtendedSSLSession;
    46 import javax.net.ssl.SSLSessionContext;
    44 import javax.net.ssl.SNIServerName;
    47 import javax.net.ssl.SSLSessionBindingListener;
       
    48 import javax.net.ssl.SSLSessionBindingEvent;
       
    49 import javax.net.ssl.SSLPeerUnverifiedException;
    45 import javax.net.ssl.SSLPeerUnverifiedException;
    50 import javax.net.ssl.SSLPermission;
    46 import javax.net.ssl.SSLPermission;
    51 import javax.net.ssl.ExtendedSSLSession;
    47 import javax.net.ssl.SSLSessionBindingEvent;
    52 import javax.net.ssl.SNIServerName;
    48 import javax.net.ssl.SSLSessionBindingListener;
    53 
    49 import javax.net.ssl.SSLSessionContext;
    54 import static sun.security.ssl.CipherSuite.KeyExchange.*;
       
    55 
    50 
    56 /**
    51 /**
    57  * Implements the SSL session interface, and exposes the session context
    52  * Implements the SSL session interface, and exposes the session context
    58  * which is maintained by SSL servers.
    53  * which is maintained by SSL servers.
    59  *
    54  *
    76     /*
    71     /*
    77      * we only really need a single null session
    72      * we only really need a single null session
    78      */
    73      */
    79     static final SSLSessionImpl         nullSession = new SSLSessionImpl();
    74     static final SSLSessionImpl         nullSession = new SSLSessionImpl();
    80 
    75 
    81     // compression methods
       
    82     private static final byte           compression_null = 0;
       
    83 
       
    84     /*
    76     /*
    85      * 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
    86      * of the SSLv3 spec.
    78      * of the SSLv3 spec.
    87      */
    79      */
    88     private final ProtocolVersion       protocolVersion;
    80     private final ProtocolVersion       protocolVersion;
    89     private final SessionId             sessionId;
    81     private final SessionId             sessionId;
    90     private X509Certificate[]   peerCerts;
    82     private X509Certificate[]   peerCerts;
    91     private byte                compressionMethod;
       
    92     private CipherSuite         cipherSuite;
    83     private CipherSuite         cipherSuite;
    93     private SecretKey           masterSecret;
    84     private SecretKey           masterSecret;
    94     private final boolean       useExtendedMasterSecret;
    85     final boolean               useExtendedMasterSecret;
    95 
    86 
    96     /*
    87     /*
    97      * Information not part of the SSLv3 protocol spec, but used
    88      * Information not part of the SSLv3 protocol spec, but used
    98      * to support session management policies.
    89      * to support session management policies.
    99      */
    90      */
   100     private final long          creationTime = System.currentTimeMillis();
    91     private final long          creationTime;
   101     private long                lastUsedTime = 0;
    92     private long                lastUsedTime = 0;
   102     private final String        host;
    93     private final String        host;
   103     private final int           port;
    94     private final int           port;
   104     private SSLSessionContextImpl       context;
    95     private SSLSessionContextImpl       context;
   105     private int                 sessionCount;
       
   106     private boolean             invalidated;
    96     private boolean             invalidated;
   107     private X509Certificate[]   localCerts;
    97     private X509Certificate[]   localCerts;
   108     private PrivateKey          localPrivateKey;
    98     private PrivateKey          localPrivateKey;
   109     private String[]            localSupportedSignAlgs;
    99     private final String[]      localSupportedSignAlgs;
   110     private String[]            peerSupportedSignAlgs;
   100     private String[]            peerSupportedSignAlgs;      // for certificate
   111     private List<SNIServerName>    requestedServerNames;
   101     private boolean             useDefaultPeerSignAlgs = false;
   112     private List<byte[]>        statusResponses;
   102     private List<byte[]>        statusResponses;
   113 
   103     private SecretKey           resumptionMasterSecret;
   114     private int                 negotiatedMaxFragLen;
   104     private SecretKey           preSharedKey;
       
   105     private byte[]              pskIdentity;
       
   106     private final long          ticketCreationTime = System.currentTimeMillis();
       
   107     private int                 ticketAgeAdd;
       
   108 
       
   109     private int                 negotiatedMaxFragLen = -1;
   115     private int                 maximumPacketSize;
   110     private int                 maximumPacketSize;
   116 
   111 
   117     // Principals for non-certificate based cipher suites
   112     private final Queue<SSLSessionImpl> childSessions =
   118     private Principal peerPrincipal;
   113                                         new ConcurrentLinkedQueue<>();
   119     private Principal localPrincipal;
       
   120 
   114 
   121     /*
   115     /*
   122      * Is the session currently re-established with a session-resumption
   116      * Is the session currently re-established with a session-resumption
   123      * abbreviated initial handshake?
   117      * abbreviated initial handshake?
   124      *
   118      *
   125      * Note that currently we only set this variable in client side.
   119      * Note that currently we only set this variable in client side.
   126      */
   120      */
   127     private boolean isSessionResumption = false;
   121     private boolean isSessionResumption = false;
   128 
   122 
   129     /*
   123     /*
   130      * We count session creations, eventually for statistical data but
       
   131      * also since counters make shorter debugging IDs than the big ones
       
   132      * we use in the protocol for uniqueness-over-time.
       
   133      */
       
   134     private static volatile int counter;
       
   135 
       
   136     /*
       
   137      * Use of session caches is globally enabled/disabled.
   124      * Use of session caches is globally enabled/disabled.
   138      */
   125      */
   139     private static boolean      defaultRejoinable = true;
   126     private static boolean      defaultRejoinable = true;
   140 
   127 
   141     /* Class and subclass dynamic debugging support */
   128     // server name indication
   142     private static final Debug debug = Debug.getInstance("ssl");
   129     final SNIServerName         serverNameIndication;
       
   130     private final List<SNIServerName>    requestedServerNames;
       
   131 
       
   132     // Counter used to create unique nonces in NewSessionTicket
       
   133     private BigInteger ticketNonceCounter = BigInteger.ONE;
   143 
   134 
   144     /*
   135     /*
   145      * Create a new non-rejoinable session, using the default (null)
   136      * Create a new non-rejoinable session, using the default (null)
   146      * cipher spec.  This constructor returns a session which could
   137      * cipher spec.  This constructor returns a session which could
   147      * be used either by a client or by a server, as a connection is
   138      * be used either by a client or by a server, as a connection is
   148      * first opened and before handshaking begins.
   139      * first opened and before handshaking begins.
   149      */
   140      */
   150     private SSLSessionImpl() {
   141     private SSLSessionImpl() {
   151         this(ProtocolVersion.NONE, CipherSuite.C_NULL, null,
   142         this.protocolVersion = ProtocolVersion.NONE;
   152             new SessionId(false, null), null, -1, false);
   143         this.cipherSuite = CipherSuite.C_NULL;
       
   144         this.sessionId = new SessionId(false, null);
       
   145         this.host = null;
       
   146         this.port = -1;
       
   147         this.localSupportedSignAlgs = new String[0];
       
   148         this.serverNameIndication = null;
       
   149         this.requestedServerNames = Collections.<SNIServerName>emptyList();
       
   150         this.useExtendedMasterSecret = false;
       
   151         this.creationTime = System.currentTimeMillis();
   153     }
   152     }
   154 
   153 
   155     /*
   154     /*
   156      * Create a new session, using a given cipher spec.  This will
   155      * Create a new session, using a given cipher spec.  This will
   157      * be rejoinable if session caching is enabled; the constructor
   156      * be rejoinable if session caching is enabled; the constructor
   158      * is intended mostly for use by serves.
   157      * is intended mostly for use by serves.
   159      */
   158      */
   160     SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
   159     SSLSessionImpl(HandshakeContext hc, CipherSuite cipherSuite) {
   161             Collection<SignatureAndHashAlgorithm> algorithms,
   160         this(hc, cipherSuite,
   162             SecureRandom generator, String host, int port,
   161             new SessionId(defaultRejoinable, hc.sslContext.getSecureRandom()));
   163             boolean useExtendedMasterSecret) {
       
   164         this(protocolVersion, cipherSuite, algorithms,
       
   165              new SessionId(defaultRejoinable, generator), host, port,
       
   166              useExtendedMasterSecret);
       
   167     }
   162     }
   168 
   163 
   169     /*
   164     /*
   170      * Record a new session, using a given cipher spec and session ID.
   165      * Record a new session, using a given cipher spec and session ID.
   171      */
   166      */
   172     SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
   167     SSLSessionImpl(HandshakeContext hc, CipherSuite cipherSuite, SessionId id) {
   173             Collection<SignatureAndHashAlgorithm> algorithms,
   168         this(hc, cipherSuite, id, System.currentTimeMillis());
   174             SessionId id, String host, int port,
   169     }
   175             boolean useExtendedMasterSecret) {
   170 
   176         this.protocolVersion = protocolVersion;
   171     /*
   177         sessionId = id;
   172      * Record a new session, using a given cipher spec, session ID,
   178         peerCerts = null;
   173      * and creation time
   179         compressionMethod = compression_null;
   174      */
       
   175     SSLSessionImpl(HandshakeContext hc,
       
   176             CipherSuite cipherSuite, SessionId id, long creationTime) {
       
   177         this.protocolVersion = hc.negotiatedProtocol;
   180         this.cipherSuite = cipherSuite;
   178         this.cipherSuite = cipherSuite;
   181         masterSecret = null;
   179         this.sessionId = id;
   182         this.host = host;
   180         this.host = hc.conContext.transport.getPeerHost();
   183         this.port = port;
   181         this.port = hc.conContext.transport.getPeerPort();
   184         sessionCount = ++counter;
   182         this.localSupportedSignAlgs =
   185         localSupportedSignAlgs =
   183                 SignatureScheme.getAlgorithmNames(hc.localSupportedSignAlgs);
   186             SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
   184         this.serverNameIndication = hc.negotiatedServerName;
   187         negotiatedMaxFragLen = -1;
   185         this.requestedServerNames = Collections.<SNIServerName>unmodifiableList(
   188         statusResponses = null;
   186                 hc.getRequestedServerNames());
   189         this.useExtendedMasterSecret = useExtendedMasterSecret;
   187         if (hc.sslConfig.isClientMode) {
   190 
   188             this.useExtendedMasterSecret =
   191         if (debug != null && Debug.isOn("session")) {
   189                 (hc.handshakeExtensions.get(
   192             System.out.println("%% Initialized:  " + this);
   190                         SSLExtension.CH_EXTENDED_MASTER_SECRET) != null) &&
       
   191                 (hc.handshakeExtensions.get(
       
   192                         SSLExtension.SH_EXTENDED_MASTER_SECRET) != null);
       
   193         } else {
       
   194             this.useExtendedMasterSecret =
       
   195                 (hc.handshakeExtensions.get(
       
   196                         SSLExtension.CH_EXTENDED_MASTER_SECRET) != null) &&
       
   197                 (!hc.negotiatedProtocol.useTLS13PlusSpec());
       
   198         }
       
   199         this.creationTime = creationTime;
       
   200 
       
   201         if (SSLLogger.isOn && SSLLogger.isOn("session")) {
       
   202              SSLLogger.finest("Session initialized:  " + this);
   193         }
   203         }
   194     }
   204     }
   195 
   205 
   196     void setMasterSecret(SecretKey secret) {
   206     void setMasterSecret(SecretKey secret) {
   197         if (masterSecret == null) {
   207         masterSecret = secret;
   198             masterSecret = secret;
   208     }
   199         } else {
   209 
   200             throw new RuntimeException("setMasterSecret() error");
   210     void setResumptionMasterSecret(SecretKey secret) {
   201         }
   211         resumptionMasterSecret = secret;
       
   212     }
       
   213 
       
   214     void setPreSharedKey(SecretKey key) {
       
   215         preSharedKey = key;
       
   216     }
       
   217 
       
   218     void addChild(SSLSessionImpl session) {
       
   219         childSessions.add(session);
       
   220     }
       
   221 
       
   222     void setTicketAgeAdd(int ticketAgeAdd) {
       
   223         this.ticketAgeAdd = ticketAgeAdd;
       
   224     }
       
   225 
       
   226     void setPskIdentity(byte[] pskIdentity) {
       
   227         this.pskIdentity = pskIdentity;
       
   228     }
       
   229 
       
   230     BigInteger incrTicketNonceCounter() {
       
   231         BigInteger result = ticketNonceCounter;
       
   232         ticketNonceCounter = ticketNonceCounter.add(BigInteger.valueOf(1));
       
   233         return result;
   202     }
   234     }
   203 
   235 
   204     /**
   236     /**
   205      * Returns the master secret ... treat with extreme caution!
   237      * Returns the master secret ... treat with extreme caution!
   206      */
   238      */
   207     SecretKey getMasterSecret() {
   239     SecretKey getMasterSecret() {
   208         return masterSecret;
   240         return masterSecret;
   209     }
   241     }
   210 
   242 
   211     boolean getUseExtendedMasterSecret() {
   243     Optional<SecretKey> getResumptionMasterSecret() {
   212         return useExtendedMasterSecret;
   244         return Optional.ofNullable(resumptionMasterSecret);
       
   245     }
       
   246 
       
   247     synchronized Optional<SecretKey> getPreSharedKey() {
       
   248         return Optional.ofNullable(preSharedKey);
       
   249     }
       
   250 
       
   251     synchronized Optional<SecretKey> consumePreSharedKey() {
       
   252         Optional<SecretKey> result = Optional.ofNullable(preSharedKey);
       
   253         preSharedKey = null;
       
   254         return result;
       
   255     }
       
   256 
       
   257     int getTicketAgeAdd() {
       
   258         return ticketAgeAdd;
       
   259     }
       
   260 
       
   261     /*
       
   262      * Get the PSK identity. Take care not to use it in multiple connections.
       
   263      */
       
   264     synchronized Optional<byte[]> getPskIdentity() {
       
   265         return Optional.ofNullable(pskIdentity);
       
   266     }
       
   267 
       
   268     /* PSK identities created from new_session_ticket messages should only
       
   269      * be used once. This method will return the identity and then clear it
       
   270      * so it cannot be used again.
       
   271      */
       
   272     synchronized Optional<byte[]> consumePskIdentity() {
       
   273         Optional<byte[]> result = Optional.ofNullable(pskIdentity);
       
   274         pskIdentity = null;
       
   275         return result;
   213     }
   276     }
   214 
   277 
   215     void setPeerCertificates(X509Certificate[] peer) {
   278     void setPeerCertificates(X509Certificate[] peer) {
   216         if (peerCerts == null) {
   279         if (peerCerts == null) {
   217             peerCerts = peer;
   280             peerCerts = peer;
   225     void setLocalPrivateKey(PrivateKey privateKey) {
   288     void setLocalPrivateKey(PrivateKey privateKey) {
   226         localPrivateKey = privateKey;
   289         localPrivateKey = privateKey;
   227     }
   290     }
   228 
   291 
   229     void setPeerSupportedSignatureAlgorithms(
   292     void setPeerSupportedSignatureAlgorithms(
   230             Collection<SignatureAndHashAlgorithm> algorithms) {
   293             Collection<SignatureScheme> signatureSchemes) {
   231         peerSupportedSignAlgs =
   294         peerSupportedSignAlgs =
   232             SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
   295             SignatureScheme.getAlgorithmNames(signatureSchemes);
   233     }
   296     }
   234 
   297 
   235     void setRequestedServerNames(List<SNIServerName> requestedServerNames) {
   298     // TLS 1.2 only
   236         this.requestedServerNames = new ArrayList<>(requestedServerNames);
   299     //
       
   300     // Per RFC 5246, If the client supports only the default hash
       
   301     // and signature algorithms, it MAY omit the
       
   302     // signature_algorithms extension.  If the client does not
       
   303     // support the default algorithms, or supports other hash
       
   304     // and signature algorithms (and it is willing to use them
       
   305     // for verifying messages sent by the server, i.e., server
       
   306     // certificates and server key exchange), it MUST send the
       
   307     // signature_algorithms extension, listing the algorithms it
       
   308     // is willing to accept.
       
   309     void setUseDefaultPeerSignAlgs() {
       
   310         useDefaultPeerSignAlgs = true;
       
   311         peerSupportedSignAlgs = new String[] {
       
   312             "SHA1withRSA", "SHA1withDSA", "SHA1withECDSA"};
       
   313     }
       
   314 
       
   315     // Returns the connection session.
       
   316     SSLSessionImpl finish() {
       
   317         if (useDefaultPeerSignAlgs) {
       
   318             this.peerSupportedSignAlgs = new String[0];
       
   319         }
       
   320 
       
   321         return this;
   237     }
   322     }
   238 
   323 
   239     /**
   324     /**
   240      * Provide status response data obtained during the SSL handshake.
   325      * Provide status response data obtained during the SSL handshake.
   241      *
   326      *
   248             statusResponses = Collections.emptyList();
   333             statusResponses = Collections.emptyList();
   249         }
   334         }
   250     }
   335     }
   251 
   336 
   252     /**
   337     /**
   253      * Set the peer principal.
       
   254      */
       
   255     void setPeerPrincipal(Principal principal) {
       
   256         if (peerPrincipal == null) {
       
   257             peerPrincipal = principal;
       
   258         }
       
   259     }
       
   260 
       
   261     /**
       
   262      * Set the local principal.
       
   263      */
       
   264     void setLocalPrincipal(Principal principal) {
       
   265         localPrincipal = principal;
       
   266     }
       
   267 
       
   268     /**
       
   269      * Returns true iff this session may be resumed ... sessions are
   338      * Returns true iff this session may be resumed ... sessions are
   270      * usually resumable.  Security policies may suggest otherwise,
   339      * usually resumable.  Security policies may suggest otherwise,
   271      * 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,
   272      * 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
   273      * maximum lifetime in any case.
   342      * maximum lifetime in any case.
   284 
   353 
   285     /**
   354     /**
   286      * Check if the authentication used when establishing this session
   355      * Check if the authentication used when establishing this session
   287      * is still valid. Returns true if no authentication was used
   356      * is still valid. Returns true if no authentication was used
   288      */
   357      */
   289     boolean isLocalAuthenticationValid() {
   358     private boolean isLocalAuthenticationValid() {
   290         if (localPrivateKey != null) {
   359         if (localPrivateKey != null) {
   291             try {
   360             try {
   292                 // if the private key is no longer valid, getAlgorithm()
   361                 // if the private key is no longer valid, getAlgorithm()
   293                 // should throw an exception
   362                 // should throw an exception
   294                 // (e.g. Smartcard has been removed from the reader)
   363                 // (e.g. Smartcard has been removed from the reader)
   296             } catch (Exception e) {
   365             } catch (Exception e) {
   297                 invalidate();
   366                 invalidate();
   298                 return false;
   367                 return false;
   299             }
   368             }
   300         }
   369         }
       
   370 
   301         return true;
   371         return true;
   302     }
   372     }
   303 
   373 
   304     /**
   374     /**
   305      * Returns the ID for this session.  The ID is fixed for the
   375      * Returns the ID for this session.  The ID is fixed for the
   352      * Resets the cipher spec in use on this session
   422      * Resets the cipher spec in use on this session
   353      */
   423      */
   354     void setSuite(CipherSuite suite) {
   424     void setSuite(CipherSuite suite) {
   355        cipherSuite = suite;
   425        cipherSuite = suite;
   356 
   426 
   357        if (debug != null && Debug.isOn("session")) {
   427         if (SSLLogger.isOn && SSLLogger.isOn("session")) {
   358            System.out.println("%% Negotiating:  " + this);
   428              SSLLogger.finest("Negotiating session:  " + this);
   359        }
   429        }
   360     }
   430     }
   361 
   431 
   362     /**
   432     /**
   363      * Return true if the session is currently re-established with a
   433      * Return true if the session is currently re-established with a
   394     public String getProtocol() {
   464     public String getProtocol() {
   395         return getProtocolVersion().name;
   465         return getProtocolVersion().name;
   396     }
   466     }
   397 
   467 
   398     /**
   468     /**
   399      * Returns the compression technique used in this session
       
   400      */
       
   401     byte getCompression() {
       
   402         return compressionMethod;
       
   403     }
       
   404 
       
   405     /**
       
   406      * Returns the hashcode for this session
   469      * Returns the hashcode for this session
   407      */
   470      */
   408     @Override
   471     @Override
   409     public int hashCode() {
   472     public int hashCode() {
   410         return sessionId.hashCode();
   473         return sessionId.hashCode();
   411     }
   474     }
   412 
       
   413 
   475 
   414     /**
   476     /**
   415      * Returns true if sessions have same ids, false otherwise.
   477      * Returns true if sessions have same ids, false otherwise.
   416      */
   478      */
   417     @Override
   479     @Override
   433 
   495 
   434     /**
   496     /**
   435      * Return the cert chain presented by the peer in the
   497      * Return the cert chain presented by the peer in the
   436      * java.security.cert format.
   498      * java.security.cert format.
   437      * Note: This method can be used only when using certificate-based
   499      * Note: This method can be used only when using certificate-based
   438      * cipher suites; using it with non-certificate-based cipher suites,
   500      * cipher suites; using it with non-certificate-based cipher suites
   439      * such as Kerberos, will throw an SSLPeerUnverifiedException.
   501      * will throw an SSLPeerUnverifiedException.
   440      *
   502      *
   441      * @return array of peer X.509 certs, with the peer's own cert
   503      * @return array of peer X.509 certs, with the peer's own cert
   442      *  first in the chain, and with the "root" CA last.
   504      *  first in the chain, and with the "root" CA last.
   443      */
   505      */
   444     @Override
   506     @Override
   447         //
   509         //
   448         // clone to preserve integrity of session ... caller can't
   510         // clone to preserve integrity of session ... caller can't
   449         // change record of peer identity even by accident, much
   511         // change record of peer identity even by accident, much
   450         // less do it intentionally.
   512         // less do it intentionally.
   451         //
   513         //
   452         if (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) {
       
   453             throw new SSLPeerUnverifiedException("no certificates expected"
       
   454                         + " for " + cipherSuite.keyExchange + " cipher suites");
       
   455         }
       
   456         if (peerCerts == null) {
   514         if (peerCerts == null) {
   457             throw new SSLPeerUnverifiedException("peer not authenticated");
   515             throw new SSLPeerUnverifiedException("peer not authenticated");
   458         }
   516         }
   459         // Certs are immutable objects, therefore we don't clone them.
   517         // Certs are immutable objects, therefore we don't clone them.
   460         // But do need to clone the array, so that nothing is inserted
   518         // But do need to clone the array, so that nothing is inserted
   483 
   541 
   484     /**
   542     /**
   485      * Return the cert chain presented by the peer in the
   543      * Return the cert chain presented by the peer in the
   486      * javax.security.cert format.
   544      * javax.security.cert format.
   487      * Note: This method can be used only when using certificate-based
   545      * Note: This method can be used only when using certificate-based
   488      * cipher suites; using it with non-certificate-based cipher suites,
   546      * cipher suites; using it with non-certificate-based cipher suites
   489      * such as Kerberos, will throw an SSLPeerUnverifiedException.
   547      * will throw an SSLPeerUnverifiedException.
   490      *
   548      *
   491      * @return array of peer X.509 certs, with the peer's own cert
   549      * @return array of peer X.509 certs, with the peer's own cert
   492      *  first in the chain, and with the "root" CA last.
   550      *  first in the chain, and with the "root" CA last.
   493      *
   551      *
   494      * @deprecated This method returns the deprecated
   552      * @deprecated This method returns the deprecated
   502         //
   560         //
   503         // clone to preserve integrity of session ... caller can't
   561         // clone to preserve integrity of session ... caller can't
   504         // change record of peer identity even by accident, much
   562         // change record of peer identity even by accident, much
   505         // less do it intentionally.
   563         // less do it intentionally.
   506         //
   564         //
   507         if (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) {
       
   508             throw new SSLPeerUnverifiedException("no certificates expected"
       
   509                         + " for " + cipherSuite.keyExchange + " cipher suites");
       
   510         }
       
   511         if (peerCerts == null) {
   565         if (peerCerts == null) {
   512             throw new SSLPeerUnverifiedException("peer not authenticated");
   566             throw new SSLPeerUnverifiedException("peer not authenticated");
   513         }
   567         }
   514         javax.security.cert.X509Certificate[] certs;
   568         javax.security.cert.X509Certificate[] certs;
   515         certs = new javax.security.cert.X509Certificate[peerCerts.length];
   569         certs = new javax.security.cert.X509Certificate[peerCerts.length];
   529     }
   583     }
   530 
   584 
   531     /**
   585     /**
   532      * Return the cert chain presented by the peer.
   586      * Return the cert chain presented by the peer.
   533      * Note: This method can be used only when using certificate-based
   587      * Note: This method can be used only when using certificate-based
   534      * cipher suites; using it with non-certificate-based cipher suites,
   588      * cipher suites; using it with non-certificate-based cipher suites
   535      * such as Kerberos, will throw an SSLPeerUnverifiedException.
   589      * will throw an SSLPeerUnverifiedException.
   536      *
   590      *
   537      * @return array of peer X.509 certs, with the peer's own cert
   591      * @return array of peer X.509 certs, with the peer's own cert
   538      *  first in the chain, and with the "root" CA last.
   592      *  first in the chain, and with the "root" CA last.
   539      */
   593      */
   540     public X509Certificate[] getCertificateChain()
   594     public X509Certificate[] getCertificateChain()
   542         /*
   596         /*
   543          * clone to preserve integrity of session ... caller can't
   597          * clone to preserve integrity of session ... caller can't
   544          * change record of peer identity even by accident, much
   598          * change record of peer identity even by accident, much
   545          * less do it intentionally.
   599          * less do it intentionally.
   546          */
   600          */
   547         if (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) {
       
   548             throw new SSLPeerUnverifiedException("no certificates expected"
       
   549                         + " for " + cipherSuite.keyExchange + " cipher suites");
       
   550         }
       
   551         if (peerCerts != null) {
   601         if (peerCerts != null) {
   552             return peerCerts.clone();
   602             return peerCerts.clone();
   553         } else {
   603         } else {
   554             throw new SSLPeerUnverifiedException("peer not authenticated");
   604             throw new SSLPeerUnverifiedException("peer not authenticated");
   555         }
   605         }
   582     /**
   632     /**
   583      * Returns the identity of the peer which was established as part of
   633      * Returns the identity of the peer which was established as part of
   584      * defining the session.
   634      * defining the session.
   585      *
   635      *
   586      * @return the peer's principal. Returns an X500Principal of the
   636      * @return the peer's principal. Returns an X500Principal of the
   587      * end-entity certificate for X509-based cipher suites, and
   637      * end-entity certificate for X509-based cipher suites.
   588      * Principal for Kerberos cipher suites, etc.
       
   589      *
   638      *
   590      * @throws SSLPeerUnverifiedException if the peer's identity has not
   639      * @throws SSLPeerUnverifiedException if the peer's identity has not
   591      *          been verified
   640      *          been verified
   592      */
   641      */
   593     @Override
   642     @Override
   594     public Principal getPeerPrincipal()
   643     public Principal getPeerPrincipal()
   595                 throws SSLPeerUnverifiedException
   644                 throws SSLPeerUnverifiedException
   596     {
   645     {
   597         if (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) {
       
   598             if (peerPrincipal == null) {
       
   599                 throw new SSLPeerUnverifiedException("peer not authenticated");
       
   600             } else {
       
   601                 return peerPrincipal;
       
   602             }
       
   603         }
       
   604         if (peerCerts == null) {
   646         if (peerCerts == null) {
   605             throw new SSLPeerUnverifiedException("peer not authenticated");
   647             throw new SSLPeerUnverifiedException("peer not authenticated");
   606         }
   648         }
   607         return peerCerts[0].getSubjectX500Principal();
   649         return peerCerts[0].getSubjectX500Principal();
   608     }
   650     }
   609 
   651 
   610     /**
   652     /**
   611      * Returns the principal that was sent to the peer during handshaking.
   653      * Returns the principal that was sent to the peer during handshaking.
   612      *
   654      *
   613      * @return the principal sent to the peer. Returns an X500Principal
   655      * @return the principal sent to the peer. Returns an X500Principal
   614      * of the end-entity certificate for X509-based cipher suites, and
   656      * of the end-entity certificate for X509-based cipher suites.
   615      * Principal for Kerberos cipher suites, etc. If no principal was
   657      * If no principal was sent, then null is returned.
   616      * sent, then null is returned.
       
   617      */
   658      */
   618     @Override
   659     @Override
   619     public Principal getLocalPrincipal() {
   660     public Principal getLocalPrincipal() {
   620 
   661         return ((localCerts == null && localCerts.length != 0) ? null :
   621         if (ClientKeyExchangeService.find(cipherSuite.keyExchange.name) != null) {
       
   622                 return (localPrincipal == null ? null : localPrincipal);
       
   623         }
       
   624         return (localCerts == null ? null :
       
   625                 localCerts[0].getSubjectX500Principal());
   662                 localCerts[0].getSubjectX500Principal());
       
   663     }
       
   664 
       
   665     /*
       
   666      * Return the time the ticket for this session was created.
       
   667      */
       
   668     public long getTicketCreationTime() {
       
   669         return ticketCreationTime;
   626     }
   670     }
   627 
   671 
   628     /**
   672     /**
   629      * Returns the time this session was created.
   673      * Returns the time this session was created.
   630      */
   674      */
   693         // new connection, with no "real" session yet.
   737         // new connection, with no "real" session yet.
   694         //
   738         //
   695         if (this == nullSession) {
   739         if (this == nullSession) {
   696             return;
   740             return;
   697         }
   741         }
   698         invalidated = true;
   742 
   699         if (debug != null && Debug.isOn("session")) {
       
   700             System.out.println("%% Invalidated:  " + this);
       
   701         }
       
   702         if (context != null) {
   743         if (context != null) {
   703             context.remove(sessionId);
   744             context.remove(sessionId);
   704             context = null;
   745             context = null;
   705         }
   746         }
       
   747         if (invalidated) {
       
   748             return;
       
   749         }
       
   750         invalidated = true;
       
   751         if (SSLLogger.isOn && SSLLogger.isOn("session")) {
       
   752              SSLLogger.finest("Invalidated session:  " + this);
       
   753         }
       
   754         for (SSLSessionImpl child : childSessions) {
       
   755             child.invalidate();
       
   756         }
   706     }
   757     }
   707 
   758 
   708     /*
   759     /*
   709      * Table of application-specific session data indexed by an application
   760      * Table of application-specific session data indexed by an application
   710      * key and the calling security context. This is important since
   761      * key and the calling security context. This is important since
   711      * sessions can be shared across different protection domains.
   762      * sessions can be shared across different protection domains.
   712      */
   763      */
   713     private Hashtable<SecureKey, Object> table = new Hashtable<>();
   764     private final ConcurrentHashMap<SecureKey, Object> boundValues =
       
   765             new ConcurrentHashMap<>();
   714 
   766 
   715     /**
   767     /**
   716      * Assigns a session value.  Session change events are given if
   768      * Assigns a session value.  Session change events are given if
   717      * appropriate, to any original value as well as the new value.
   769      * appropriate, to any original value as well as the new value.
   718      */
   770      */
   721         if ((key == null) || (value == null)) {
   773         if ((key == null) || (value == null)) {
   722             throw new IllegalArgumentException("arguments can not be null");
   774             throw new IllegalArgumentException("arguments can not be null");
   723         }
   775         }
   724 
   776 
   725         SecureKey secureKey = new SecureKey(key);
   777         SecureKey secureKey = new SecureKey(key);
   726         Object oldValue = table.put(secureKey, value);
   778         Object oldValue = boundValues.put(secureKey, value);
   727 
   779 
   728         if (oldValue instanceof SSLSessionBindingListener) {
   780         if (oldValue instanceof SSLSessionBindingListener) {
   729             SSLSessionBindingEvent e;
   781             SSLSessionBindingEvent e;
   730 
   782 
   731             e = new SSLSessionBindingEvent(this, key);
   783             e = new SSLSessionBindingEvent(this, key);
   736 
   788 
   737             e = new SSLSessionBindingEvent(this, key);
   789             e = new SSLSessionBindingEvent(this, key);
   738             ((SSLSessionBindingListener)value).valueBound(e);
   790             ((SSLSessionBindingListener)value).valueBound(e);
   739         }
   791         }
   740     }
   792     }
   741 
       
   742 
   793 
   743     /**
   794     /**
   744      * Returns the specified session value.
   795      * Returns the specified session value.
   745      */
   796      */
   746     @Override
   797     @Override
   748         if (key == null) {
   799         if (key == null) {
   749             throw new IllegalArgumentException("argument can not be null");
   800             throw new IllegalArgumentException("argument can not be null");
   750         }
   801         }
   751 
   802 
   752         SecureKey secureKey = new SecureKey(key);
   803         SecureKey secureKey = new SecureKey(key);
   753         return table.get(secureKey);
   804         return boundValues.get(secureKey);
   754     }
   805     }
   755 
   806 
   756 
   807 
   757     /**
   808     /**
   758      * Removes the specified session value, delivering a session changed
   809      * Removes the specified session value, delivering a session changed
   763         if (key == null) {
   814         if (key == null) {
   764             throw new IllegalArgumentException("argument can not be null");
   815             throw new IllegalArgumentException("argument can not be null");
   765         }
   816         }
   766 
   817 
   767         SecureKey secureKey = new SecureKey(key);
   818         SecureKey secureKey = new SecureKey(key);
   768         Object value = table.remove(secureKey);
   819         Object value = boundValues.remove(secureKey);
   769 
   820 
   770         if (value instanceof SSLSessionBindingListener) {
   821         if (value instanceof SSLSessionBindingListener) {
   771             SSLSessionBindingEvent e;
   822             SSLSessionBindingEvent e;
   772 
   823 
   773             e = new SSLSessionBindingEvent(this, key);
   824             e = new SSLSessionBindingEvent(this, key);
   779     /**
   830     /**
   780      * Lists the names of the session values.
   831      * Lists the names of the session values.
   781      */
   832      */
   782     @Override
   833     @Override
   783     public String[] getValueNames() {
   834     public String[] getValueNames() {
   784         Enumeration<SecureKey> e;
   835         ArrayList<Object> v = new ArrayList<>();
   785         Vector<Object> v = new Vector<>();
       
   786         SecureKey key;
       
   787         Object securityCtx = SecureKey.getCurrentSecurityContext();
   836         Object securityCtx = SecureKey.getCurrentSecurityContext();
   788 
   837         for (Enumeration<SecureKey> e = boundValues.keys();
   789         for (e = table.keys(); e.hasMoreElements(); ) {
   838                 e.hasMoreElements(); ) {
   790             key = e.nextElement();
   839             SecureKey key = e.nextElement();
   791 
       
   792             if (securityCtx.equals(key.getSecurityContext())) {
   840             if (securityCtx.equals(key.getSecurityContext())) {
   793                 v.addElement(key.getAppKey());
   841                 v.add(key.getAppKey());
   794             }
   842             }
   795         }
   843         }
   796         String[] names = new String[v.size()];
   844 
   797         v.copyInto(names);
   845         return v.toArray(new String[0]);
   798 
       
   799         return names;
       
   800     }
   846     }
   801 
   847 
   802     /**
   848     /**
   803      * 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)
   804      * until changed.
   850      * until changed.
   811      * Application could accept large fragments up to 2^15 bytes by
   857      * Application could accept large fragments up to 2^15 bytes by
   812      * setting the system property jsse.SSLEngine.acceptLargeFragments
   858      * setting the system property jsse.SSLEngine.acceptLargeFragments
   813      * to "true".
   859      * to "true".
   814      */
   860      */
   815     private boolean acceptLargeFragments =
   861     private boolean acceptLargeFragments =
   816         Debug.getBooleanProperty("jsse.SSLEngine.acceptLargeFragments", false);
   862             Utilities.getBooleanProperty(
       
   863                     "jsse.SSLEngine.acceptLargeFragments", false);
   817 
   864 
   818     /**
   865     /**
   819      * Expand the buffer size of both SSL/TLS network packet and
   866      * Expand the buffer size of both SSL/TLS network packet and
   820      * application data.
   867      * application data.
   821      */
   868      */
   833         // and negotiatedMaxFragLen.
   880         // and negotiatedMaxFragLen.
   834         int packetSize = 0;
   881         int packetSize = 0;
   835         if (negotiatedMaxFragLen > 0) {
   882         if (negotiatedMaxFragLen > 0) {
   836             packetSize = cipherSuite.calculatePacketSize(
   883             packetSize = cipherSuite.calculatePacketSize(
   837                     negotiatedMaxFragLen, protocolVersion,
   884                     negotiatedMaxFragLen, protocolVersion,
   838                     protocolVersion.isDTLSProtocol());
   885                     protocolVersion.isDTLS);
   839         }
   886         }
   840 
   887 
   841         if (maximumPacketSize > 0) {
   888         if (maximumPacketSize > 0) {
   842             return (maximumPacketSize > packetSize) ?
   889             return (maximumPacketSize > packetSize) ?
   843                     maximumPacketSize : packetSize;
   890                     maximumPacketSize : packetSize;
   845 
   892 
   846         if (packetSize != 0) {
   893         if (packetSize != 0) {
   847            return packetSize;
   894            return packetSize;
   848         }
   895         }
   849 
   896 
   850         if (protocolVersion.isDTLSProtocol()) {
   897         if (protocolVersion.isDTLS) {
   851             return DTLSRecord.maxRecordSize;
   898             return DTLSRecord.maxRecordSize;
   852         } else {
   899         } else {
   853             return acceptLargeFragments ?
   900             return acceptLargeFragments ?
   854                     SSLRecord.maxLargeRecordSize : SSLRecord.maxRecordSize;
   901                     SSLRecord.maxLargeRecordSize : SSLRecord.maxRecordSize;
   855         }
   902         }
   865         // and negotiatedMaxFragLen.
   912         // and negotiatedMaxFragLen.
   866         int fragmentSize = 0;
   913         int fragmentSize = 0;
   867         if (maximumPacketSize > 0) {
   914         if (maximumPacketSize > 0) {
   868             fragmentSize = cipherSuite.calculateFragSize(
   915             fragmentSize = cipherSuite.calculateFragSize(
   869                     maximumPacketSize, protocolVersion,
   916                     maximumPacketSize, protocolVersion,
   870                     protocolVersion.isDTLSProtocol());
   917                     protocolVersion.isDTLS);
   871         }
   918         }
   872 
   919 
   873         if (negotiatedMaxFragLen > 0) {
   920         if (negotiatedMaxFragLen > 0) {
   874             return (negotiatedMaxFragLen > fragmentSize) ?
   921             return (negotiatedMaxFragLen > fragmentSize) ?
   875                     negotiatedMaxFragLen : fragmentSize;
   922                     negotiatedMaxFragLen : fragmentSize;
   877 
   924 
   878         if (fragmentSize != 0) {
   925         if (fragmentSize != 0) {
   879             return fragmentSize;
   926             return fragmentSize;
   880         }
   927         }
   881 
   928 
   882         if (protocolVersion.isDTLSProtocol()) {
   929         if (protocolVersion.isDTLS) {
   883             return Record.maxDataSize;
   930             return Record.maxDataSize;
   884         } else {
   931         } else {
   885             int maxPacketSize = acceptLargeFragments ?
   932             int maxPacketSize = acceptLargeFragments ?
   886                         SSLRecord.maxLargeRecordSize : SSLRecord.maxRecordSize;
   933                         SSLRecord.maxLargeRecordSize : SSLRecord.maxRecordSize;
   887             return (maxPacketSize - SSLRecord.headerSize);
   934             return (maxPacketSize - SSLRecord.headerSize);
   951      * Obtains a <code>List</code> containing all {@link SNIServerName}s
   998      * Obtains a <code>List</code> containing all {@link SNIServerName}s
   952      * of the requested Server Name Indication (SNI) extension.
   999      * of the requested Server Name Indication (SNI) extension.
   953      */
  1000      */
   954     @Override
  1001     @Override
   955     public List<SNIServerName> getRequestedServerNames() {
  1002     public List<SNIServerName> getRequestedServerNames() {
   956         if (requestedServerNames != null && !requestedServerNames.isEmpty()) {
  1003         return requestedServerNames;
   957             return Collections.<SNIServerName>unmodifiableList(
       
   958                                                 requestedServerNames);
       
   959         }
       
   960 
       
   961         return Collections.<SNIServerName>emptyList();
       
   962     }
  1004     }
   963 
  1005 
   964     /** Returns a string representation of this SSL session */
  1006     /** Returns a string representation of this SSL session */
   965     @Override
  1007     @Override
   966     public String toString() {
  1008     public String toString() {
   967         return "[Session-" + sessionCount
  1009         return "Session(" + creationTime + "|" + getCipherSuite() + ")";
   968             + ", " + getCipherSuite()
  1010     }
   969             + "]";
       
   970     }
       
   971 
       
   972 }
  1011 }
   973 
       
   974 
  1012 
   975 /**
  1013 /**
   976  * This "struct" class serves as a Hash Key that combines an
  1014  * This "struct" class serves as a Hash Key that combines an
   977  * application-specific key and a security context.
  1015  * application-specific key and a security context.
   978  */
  1016  */
   979 class SecureKey {
  1017 class SecureKey {
   980     private static Object       nullObject = new Object();
  1018     private static final Object     nullObject = new Object();
   981     private Object        appKey;
  1019     private final Object            appKey;
   982     private Object      securityCtx;
  1020     private final Object            securityCtx;
   983 
  1021 
   984     static Object getCurrentSecurityContext() {
  1022     static Object getCurrentSecurityContext() {
   985         SecurityManager sm = System.getSecurityManager();
  1023         SecurityManager sm = System.getSecurityManager();
   986         Object context = null;
  1024         Object context = null;
   987 
  1025