src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java
changeset 55336 c2398053ee90
parent 54443 dfba4e321ab3
child 57485 af4b0fc25bc4
equal deleted inserted replaced
55335:f7cc25dda38a 55336:c2398053ee90
    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 package sun.security.ssl;
    25 package sun.security.ssl;
    26 
    26 
       
    27 import sun.security.x509.X509CertImpl;
       
    28 
       
    29 import java.io.IOException;
    27 import java.math.BigInteger;
    30 import java.math.BigInteger;
    28 import java.net.InetAddress;
    31 import java.net.InetAddress;
       
    32 import java.nio.ByteBuffer;
    29 import java.security.Principal;
    33 import java.security.Principal;
    30 import java.security.PrivateKey;
    34 import java.security.PrivateKey;
    31 import java.security.cert.CertificateEncodingException;
    35 import java.security.cert.CertificateEncodingException;
    32 import java.security.cert.X509Certificate;
    36 import java.security.cert.X509Certificate;
    33 import java.util.ArrayList;
    37 import java.util.ArrayList;
    38 import java.util.List;
    42 import java.util.List;
    39 import java.util.concurrent.ConcurrentHashMap;
    43 import java.util.concurrent.ConcurrentHashMap;
    40 import java.util.concurrent.ConcurrentLinkedQueue;
    44 import java.util.concurrent.ConcurrentLinkedQueue;
    41 import java.util.concurrent.locks.ReentrantLock;
    45 import java.util.concurrent.locks.ReentrantLock;
    42 import javax.crypto.SecretKey;
    46 import javax.crypto.SecretKey;
       
    47 import javax.crypto.spec.SecretKeySpec;
    43 import javax.net.ssl.ExtendedSSLSession;
    48 import javax.net.ssl.ExtendedSSLSession;
       
    49 import javax.net.ssl.SNIHostName;
    44 import javax.net.ssl.SNIServerName;
    50 import javax.net.ssl.SNIServerName;
       
    51 import javax.net.ssl.SSLException;
    45 import javax.net.ssl.SSLPeerUnverifiedException;
    52 import javax.net.ssl.SSLPeerUnverifiedException;
    46 import javax.net.ssl.SSLPermission;
    53 import javax.net.ssl.SSLPermission;
    47 import javax.net.ssl.SSLSessionBindingEvent;
    54 import javax.net.ssl.SSLSessionBindingEvent;
    48 import javax.net.ssl.SSLSessionBindingListener;
    55 import javax.net.ssl.SSLSessionBindingListener;
    49 import javax.net.ssl.SSLSessionContext;
    56 import javax.net.ssl.SSLSessionContext;
   249         if (SSLLogger.isOn && SSLLogger.isOn("session")) {
   256         if (SSLLogger.isOn && SSLLogger.isOn("session")) {
   250              SSLLogger.finest("Session initialized:  " + this);
   257              SSLLogger.finest("Session initialized:  " + this);
   251         }
   258         }
   252     }
   259     }
   253 
   260 
       
   261     /**
       
   262      * < 2 bytes > protocolVersion
       
   263      * < 2 bytes > cipherSuite
       
   264      * < 2 bytes > localSupportedSignAlgs entries
       
   265      *   < 2 bytes per entries > localSupportedSignAlgs
       
   266      * < 2 bytes > preSharedKey length
       
   267      * < length in bytes > preSharedKey
       
   268      * < 1 byte > pskIdentity length
       
   269      * < length in bytes > pskIdentity
       
   270      * < 1 byte > masterSecret length
       
   271      *   < 1 byte > masterSecret algorithm length
       
   272      *   < length in bytes > masterSecret algorithm
       
   273      *   < 2 bytes > masterSecretKey length
       
   274      *   < length in bytes> masterSecretKey
       
   275      * < 1 byte > useExtendedMasterSecret
       
   276      * < 1 byte > identificationProtocol length
       
   277      * < length in bytes > identificationProtocol
       
   278      * < 1 byte > serverNameIndication length
       
   279      * < length in bytes > serverNameIndication
       
   280      * < 1 byte > Number of requestedServerNames entries
       
   281      *   < 1 byte > ServerName length
       
   282      *   < length in bytes > ServerName
       
   283      * < 4 bytes > creationTime
       
   284      * < 1 byte > Length of peer host
       
   285      *   < length in bytes > peer host
       
   286      * < 2 bytes> peer port
       
   287      * < 1 byte > Number of peerCerts entries
       
   288      *   < 4 byte > peerCert length
       
   289      *   < length in bytes > peerCert
       
   290      * < 1 byte > localCerts type (Cert, PSK, Anonymous)
       
   291      *   Certificate
       
   292      *     < 1 byte > Number of Certificate entries
       
   293      *       < 4 byte> Certificate length
       
   294      *       < length in bytes> Certificate
       
   295      *   PSK
       
   296      *     < 1 byte > Number of PSK entries
       
   297      *       < 1 bytes > PSK algorithm length
       
   298      *       < length in bytes > PSK algorithm string
       
   299      *       < 4 bytes > PSK key length
       
   300      *       < length in bytes> PSK key
       
   301      *       < 4 bytes > PSK identity length
       
   302      *       < length in bytes> PSK identity
       
   303      *   Anonymous
       
   304      *     < 1 byte >
       
   305     */
       
   306 
       
   307     SSLSessionImpl(HandshakeContext hc, ByteBuffer buf) throws IOException {
       
   308         int i = 0;
       
   309         byte[] b;
       
   310 
       
   311         this.localSupportedSignAlgs = new ArrayList<>();
       
   312 
       
   313         boundValues = null;
       
   314 
       
   315         this.protocolVersion = ProtocolVersion.valueOf(Short.toUnsignedInt(buf.getShort()));
       
   316 
       
   317         if (protocolVersion.useTLS13PlusSpec()) {
       
   318             this.sessionId = new SessionId(false, null);
       
   319         } else {
       
   320             // The CH session id may reset this if it's provided
       
   321             this.sessionId = new SessionId(true,
       
   322                     hc.sslContext.getSecureRandom());
       
   323         }
       
   324 
       
   325         this.cipherSuite = CipherSuite.valueOf(Short.toUnsignedInt(buf.getShort()));
       
   326 
       
   327         // Local Supported signature algorithms
       
   328         i = Short.toUnsignedInt(buf.getShort());
       
   329         while (i-- > 0) {
       
   330             this.localSupportedSignAlgs.add(SignatureScheme.valueOf(
       
   331                     Short.toUnsignedInt(buf.getShort())));
       
   332         }
       
   333 
       
   334         // PSK
       
   335         i = Short.toUnsignedInt(buf.getShort());
       
   336         if (i > 0) {
       
   337             b = new byte[i];
       
   338             // Get algorithm string
       
   339             buf.get(b, 0, i);
       
   340             // Encoded length
       
   341             i = Short.toUnsignedInt(buf.getShort());
       
   342             // Encoded SecretKey
       
   343             b = new byte[i];
       
   344             buf.get(b);
       
   345             this.preSharedKey = new SecretKeySpec(b, "TlsMasterSecret");
       
   346         } else {
       
   347             this.preSharedKey = null;
       
   348         }
       
   349 
       
   350         // PSK identity
       
   351         i = buf.get();
       
   352         if (i > 0) {
       
   353             b = new byte[i];
       
   354             buf.get(b);
       
   355             this.pskIdentity = b;
       
   356         } else {
       
   357             this.pskIdentity = null;
       
   358         }
       
   359 
       
   360         // Master secret length of secret key algorithm  (one byte)
       
   361         i = buf.get();
       
   362         if (i > 0) {
       
   363             b = new byte[i];
       
   364             // Get algorithm string
       
   365             buf.get(b, 0, i);
       
   366             // Encoded length
       
   367             i = Short.toUnsignedInt(buf.getShort());
       
   368             // Encoded SecretKey
       
   369             b = new byte[i];
       
   370             buf.get(b);
       
   371             this.masterSecret = new SecretKeySpec(b, "TlsMasterSecret");
       
   372         } else {
       
   373             this.masterSecret = null;
       
   374         }
       
   375         // Use extended master secret
       
   376         this.useExtendedMasterSecret = (buf.get() != 0);
       
   377 
       
   378         // Identification Protocol
       
   379         i = buf.get();
       
   380         if (i == 0) {
       
   381             identificationProtocol = null;
       
   382         } else {
       
   383             b = new byte[i];
       
   384             identificationProtocol =
       
   385                     buf.get(b, 0, i).asCharBuffer().toString();
       
   386         }
       
   387 
       
   388         // SNI
       
   389         i = buf.get();  // length
       
   390         if (i == 0) {
       
   391             serverNameIndication = null;
       
   392         } else {
       
   393             b = new byte[i];
       
   394             buf.get(b, 0, b.length);
       
   395             serverNameIndication = new SNIHostName(b);
       
   396         }
       
   397 
       
   398         // List of SNIServerName
       
   399         int len = Short.toUnsignedInt(buf.getShort());
       
   400         if (len == 0) {
       
   401             this.requestedServerNames = Collections.<SNIServerName>emptyList();
       
   402         } else {
       
   403             requestedServerNames = new ArrayList<>();
       
   404             while (len > 0) {
       
   405                 int l = buf.get();
       
   406                 b = new byte[l];
       
   407                 buf.get(b, 0, l);
       
   408                 requestedServerNames.add(new SNIHostName(new String(b)));
       
   409                 len--;
       
   410             }
       
   411         }
       
   412 
       
   413         // Get creation time
       
   414         this.creationTime = buf.getLong();
       
   415 
       
   416         // Get Peer host & port
       
   417         i = Byte.toUnsignedInt(buf.get());
       
   418         if (i == 0) {
       
   419             this.host = new String();
       
   420         } else {
       
   421             b = new byte[i];
       
   422             this.host = buf.get(b).toString();
       
   423         }
       
   424         this.port = Short.toUnsignedInt(buf.getShort());
       
   425 
       
   426         // Peer certs
       
   427         i = buf.get();
       
   428         if (i == 0) {
       
   429             this.peerCerts = null;
       
   430         } else {
       
   431             this.peerCerts = new X509Certificate[i];
       
   432             int j = 0;
       
   433             while (i > j) {
       
   434                 b = new byte[buf.getInt()];
       
   435                 buf.get(b);
       
   436                 try {
       
   437                     this.peerCerts[j] = new X509CertImpl(b);
       
   438                 } catch (Exception e) {
       
   439                     throw new IOException(e);
       
   440                 }
       
   441                 j++;
       
   442             }
       
   443         }
       
   444 
       
   445         // Get local certs of PSK
       
   446         switch (buf.get()) {
       
   447             case 0:
       
   448                 break;
       
   449             case 1:
       
   450                 // number of certs
       
   451                 len = buf.get();
       
   452                 this.localCerts = new X509Certificate[len];
       
   453                 i = 0;
       
   454                 while (len > i) {
       
   455                     b = new byte[buf.getInt()];
       
   456                     buf.get(b);
       
   457                     try {
       
   458                         this.localCerts[i] = new X509CertImpl(b);
       
   459                     } catch (Exception e) {
       
   460                         throw new IOException(e);
       
   461                     }
       
   462                     i++;
       
   463                 }
       
   464                 break;
       
   465             case 2:
       
   466                 // pre-shared key
       
   467                 // Length of pre-shared key algorithm  (one byte)
       
   468                 i = buf.get();
       
   469                 b = new byte[i];
       
   470                 String alg = buf.get(b, 0, i).asCharBuffer().toString();
       
   471                 // Get length of encoding
       
   472                 i = Short.toUnsignedInt(buf.getShort());
       
   473                 // Get encoding
       
   474                 b = new byte[i];
       
   475                 buf.get(b);
       
   476                 this.preSharedKey = new SecretKeySpec(b, alg);
       
   477                 // Get identity len
       
   478                 this.pskIdentity = new byte[buf.get()];
       
   479                 buf.get(pskIdentity);
       
   480                 break;
       
   481             default:
       
   482                 throw new SSLException("Failed local certs of session.");
       
   483         }
       
   484 
       
   485         context = (SSLSessionContextImpl)
       
   486                 hc.sslContext.engineGetServerSessionContext();
       
   487     }
       
   488 
       
   489     /**
       
   490      * Write out a SSLSessionImpl in a byte array for a stateless session ticket
       
   491      */
       
   492     byte[] write() throws Exception {
       
   493         byte[] b;
       
   494         HandshakeOutStream hos = new HandshakeOutStream(null);
       
   495 
       
   496         hos.putInt16(protocolVersion.id);
       
   497         hos.putInt16(cipherSuite.id);
       
   498 
       
   499         // Local Supported signature algorithms
       
   500         int l = localSupportedSignAlgs.size();
       
   501         hos.putInt16(l);
       
   502         SignatureScheme[] sig = new SignatureScheme[l];
       
   503         localSupportedSignAlgs.toArray(sig);
       
   504         for (SignatureScheme s : sig) {
       
   505             hos.putInt16(s.id);
       
   506         }
       
   507 
       
   508         // PSK
       
   509         if (preSharedKey == null ||
       
   510                 preSharedKey.getAlgorithm() == null) {
       
   511             hos.putInt16(0);
       
   512         } else {
       
   513             hos.putInt16(preSharedKey.getAlgorithm().length());
       
   514             if (preSharedKey.getAlgorithm().length() != 0) {
       
   515                 hos.write(preSharedKey.getAlgorithm().getBytes());
       
   516             }
       
   517             b = preSharedKey.getEncoded();
       
   518             hos.putInt16(b.length);
       
   519             hos.write(b, 0, b.length);
       
   520         }
       
   521 
       
   522         // PSK Identity
       
   523         if (pskIdentity == null) {
       
   524             hos.putInt8(0);
       
   525         } else {
       
   526             hos.putInt8(pskIdentity.length);
       
   527             hos.write(pskIdentity, 0, pskIdentity.length);
       
   528         }
       
   529 
       
   530         // Master Secret
       
   531         if (getMasterSecret() == null ||
       
   532                 getMasterSecret().getAlgorithm() == null) {
       
   533             hos.putInt8(0);
       
   534         } else {
       
   535             hos.putInt8(getMasterSecret().getAlgorithm().length());
       
   536             if (getMasterSecret().getAlgorithm().length() != 0) {
       
   537                 hos.write(getMasterSecret().getAlgorithm().getBytes());
       
   538             }
       
   539             b = getMasterSecret().getEncoded();
       
   540             hos.putInt16(b.length);
       
   541             hos.write(b, 0, b.length);
       
   542         }
       
   543 
       
   544         hos.putInt8(useExtendedMasterSecret ? 1 : 0);
       
   545 
       
   546         // Identification Protocol
       
   547         if (identificationProtocol == null) {
       
   548             hos.putInt8(0);
       
   549         } else {
       
   550             hos.putInt8(identificationProtocol.length());
       
   551             hos.write(identificationProtocol.getBytes(), 0,
       
   552                     identificationProtocol.length());
       
   553         }
       
   554 
       
   555         // SNI
       
   556         if (serverNameIndication == null) {
       
   557             hos.putInt8(0);
       
   558         } else {
       
   559             b = serverNameIndication.getEncoded();
       
   560             hos.putInt8(b.length);
       
   561             hos.write(b, 0, b.length);
       
   562         }
       
   563 
       
   564         // List of SNIServerName
       
   565         hos.putInt16(requestedServerNames.size());
       
   566         if (requestedServerNames.size() > 0) {
       
   567             for (SNIServerName host: requestedServerNames) {
       
   568                 b = host.getEncoded();
       
   569                 hos.putInt8(b.length);
       
   570                 hos.write(b, 0, b.length);
       
   571             }
       
   572         }
       
   573 
       
   574         ByteBuffer buffer = ByteBuffer.allocate(Long.BYTES);
       
   575         hos.writeBytes(buffer.putLong(creationTime).array());
       
   576 
       
   577         // peer Host & Port
       
   578         if (host == null || host.length() == 0) {
       
   579             hos.putInt8(0);
       
   580         } else {
       
   581             hos.putInt8(host.length());
       
   582             hos.writeBytes(host.getBytes());
       
   583         }
       
   584         hos.putInt16(port);
       
   585 
       
   586         // Peer cert
       
   587         if (peerCerts == null || peerCerts.length == 0) {
       
   588             hos.putInt8(0);
       
   589         } else {
       
   590             hos.putInt8(peerCerts.length);
       
   591             for (X509Certificate c : peerCerts) {
       
   592                 b = c.getEncoded();
       
   593                 hos.putInt32(b.length);
       
   594                 hos.writeBytes(b);
       
   595             }
       
   596         }
       
   597 
       
   598         // Client identity
       
   599         if (localCerts != null && localCerts.length > 0) {
       
   600             // certificate based
       
   601             hos.putInt8(1);
       
   602             hos.putInt8(localCerts.length);
       
   603             for (X509Certificate c : localCerts) {
       
   604                 b = c.getEncoded();
       
   605                 hos.putInt32(b.length);
       
   606                 hos.writeBytes(b);
       
   607             }
       
   608         } else if (preSharedKey != null) {
       
   609             // pre-shared key
       
   610             hos.putInt8(2);
       
   611             hos.putInt8(preSharedKey.getAlgorithm().length());
       
   612             hos.write(preSharedKey.getAlgorithm().getBytes());
       
   613             b = preSharedKey.getEncoded();
       
   614             hos.putInt32(b.length);
       
   615             hos.writeBytes(b);
       
   616             hos.putInt32(pskIdentity.length);
       
   617             hos.writeBytes(pskIdentity);
       
   618         } else {
       
   619             // anonymous
       
   620             hos.putInt8(0);
       
   621         }
       
   622 
       
   623         return hos.toByteArray();
       
   624     }
       
   625 
   254     void setMasterSecret(SecretKey secret) {
   626     void setMasterSecret(SecretKey secret) {
   255         masterSecret = secret;
   627         masterSecret = secret;
   256     }
   628     }
   257 
   629 
   258     void setResumptionMasterSecret(SecretKey secret) {
   630     void setResumptionMasterSecret(SecretKey secret) {
   329             return pskIdentity;
   701             return pskIdentity;
   330         } finally {
   702         } finally {
   331             pskIdentity = null;
   703             pskIdentity = null;
   332             sessionLock.unlock();
   704             sessionLock.unlock();
   333         }
   705         }
       
   706     }
       
   707 
       
   708     byte[] getPskIdentity() {
       
   709         return pskIdentity;
   334     }
   710     }
   335 
   711 
   336     void setPeerCertificates(X509Certificate[] peer) {
   712     void setPeerCertificates(X509Certificate[] peer) {
   337         if (peerCerts == null) {
   713         if (peerCerts == null) {
   338             peerCerts = peer;
   714             peerCerts = peer;
   398      * for example sessions that haven't been used for a while (say,
   774      * for example sessions that haven't been used for a while (say,
   399      * a working day) won't be resumable, and sessions might have a
   775      * a working day) won't be resumable, and sessions might have a
   400      * maximum lifetime in any case.
   776      * maximum lifetime in any case.
   401      */
   777      */
   402     boolean isRejoinable() {
   778     boolean isRejoinable() {
       
   779         // TLS 1.3 can have no session id
       
   780         if (protocolVersion.useTLS13PlusSpec()) {
       
   781             return (!invalidated && isLocalAuthenticationValid());
       
   782         }
   403         return sessionId != null && sessionId.length() != 0 &&
   783         return sessionId != null && sessionId.length() != 0 &&
   404             !invalidated && isLocalAuthenticationValid();
   784                 !invalidated && isLocalAuthenticationValid();
   405     }
   785     }
   406 
   786 
   407     @Override
   787     @Override
   408     public boolean isValid() {
   788     public boolean isValid() {
   409         sessionLock.lock();
   789         sessionLock.lock();