gt:     SecretKey getMasterSecret() {
context: /*
   * Copyright (c) 1996, 2018, Oracle and/or its affiliates. All rights reserved.
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   *
   * This code is free software; you can redistribute it and/or modify it
   * under the terms of the GNU General Public License version 2 only, as
   * published by the Free Software Foundation.  Oracle designates this
   * particular file as subject to the "Classpath" exception as provided
   * by Oracle in the LICENSE file that accompanied this code.
   *
   * This code is distributed in the hope that it will be useful, but WITHOUT
   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   * version 2 for more details (a copy is included in the LICENSE file that
   * accompanied this code).
   *
   * You should have received a copy of the GNU General Public License version
   * 2 along with this work; if not, write to the Free Software Foundation,
   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   *
   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   */
  
  
  package sun.security.ssl;
  
  import java.net.*;
  import java.util.Enumeration;
  import java.util.Hashtable;
  import java.util.Vector;
  import java.util.Collection;
  import java.util.Collections;
  import java.util.List;
  import java.util.ArrayList;
  
  import java.security.Principal;
  import java.security.PrivateKey;
  import java.security.SecureRandom;
  import java.security.cert.X509Certificate;
  import java.security.cert.CertificateEncodingException;
  
  import javax.crypto.SecretKey;
  
  import javax.net.ssl.SSLSessionContext;
  import javax.net.ssl.SSLSessionBindingListener;
  import javax.net.ssl.SSLSessionBindingEvent;
  import javax.net.ssl.SSLPeerUnverifiedException;
  import javax.net.ssl.SSLPermission;
  import javax.net.ssl.ExtendedSSLSession;
  import javax.net.ssl.SNIServerName;
  
  import static sun.security.ssl.CipherSuite.KeyExchange.*;
  
  /**
   * Implements the SSL session interface, and exposes the session context
   * which is maintained by SSL servers.
   *
   * <P> Servers have the ability to manage the sessions associated with
   * their authentication context(s).  They can do this by enumerating the
   * IDs of the sessions which are cached, examining those sessions, and then
   * perhaps invalidating a given session so that it can't be used again.
   * If servers do not explicitly manage the cache, sessions will linger
   * until memory is low enough that the runtime environment purges cache
   * entries automatically to reclaim space.
   *
   * <P><em> The only reason this class is not package-private is that
   * there's no other public way to get at the server session context which
   * is associated with any given authentication context. </em>
   *
   * @author David Brownell
   */
  final class SSLSessionImpl extends ExtendedSSLSession {
  
      /*
       * we only really need a single null session
       */
      static final SSLSessionImpl         nullSession = new SSLSessionImpl();
  
      // compression methods
      private static final byte           compression_null = 0;
  
      /*
       * The state of a single session, as described in section 7.1
       * of the SSLv3 spec.
       */
      private final ProtocolVersion       protocolVersion;
      private final SessionId             sessionId;
      private X509Certificate[]   peerCerts;
      private byte                compressionMethod;
      private CipherSuite         cipherSuite;
      private SecretKey           masterSecret;
      private final boolean       useExtendedMasterSecret;
  
      /*
       * Information not part of the SSLv3 protocol spec, but used
       * to support session management policies.
       */
      private final long          creationTime = System.currentTimeMillis();
      private long                lastUsedTime = 0;
      private final String        host;
      private final int           port;
      private SSLSessionContextImpl       context;
      private int                 sessionCount;
      private boolean             invalidated;
      private X509Certificate[]   localCerts;
      private PrivateKey          localPrivateKey;
      private String[]            localSupportedSignAlgs;
      private String[]            peerSupportedSignAlgs;
      private List<SNIServerName>    requestedServerNames;
  
  
      // Principals for non-certificate based cipher suites
      private Principal peerPrincipal;
      private Principal localPrincipal;
  
      // The endpoint identification algorithm used to check certificates
      // in this session.
      private final String              endpointIdentificationAlgorithm;
  
      /*
       * Is the session currently re-established with a session-resumption
       * abbreviated initial handshake?
       *
       * Note that currently we only set this variable in client side.
       */
      private boolean isSessionResumption = false;
  
      /*
       * We count session creations, eventually for statistical data but
       * also since counters make shorter debugging IDs than the big ones
       * we use in the protocol for uniqueness-over-time.
       */
      private static volatile int counter = 0;
  
      /*
       * Use of session caches is globally enabled/disabled.
       */
      private static boolean      defaultRejoinable = true;
  
      /* Class and subclass dynamic debugging support */
      private static final Debug debug = Debug.getInstance("ssl");
  
      /*
       * Create a new non-rejoinable session, using the default (null)
       * cipher spec.  This constructor returns a session which could
       * be used either by a client or by a server, as a connection is
       * first opened and before handshaking begins.
       */
      private SSLSessionImpl() {
          this(ProtocolVersion.NONE, CipherSuite.C_NULL, null,
              new SessionId(false, null), null, -1, false, null);
      }
  
      /*
       * Create a new session, using a given cipher spec.  This will
       * be rejoinable if session caching is enabled; the constructor
       * is intended mostly for use by serves.
       */
      SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
              Collection<SignatureAndHashAlgorithm> algorithms,
              SecureRandom generator, String host, int port,
              boolean useExtendedMasterSecret, String endpointIdAlgorithm) {
          this(protocolVersion, cipherSuite, algorithms,
               new SessionId(defaultRejoinable, generator), host, port,
               useExtendedMasterSecret, endpointIdAlgorithm);
      }
  
      /*
       * Record a new session, using a given cipher spec and session ID.
       */
      SSLSessionImpl(ProtocolVersion protocolVersion, CipherSuite cipherSuite,
              Collection<SignatureAndHashAlgorithm> algorithms,
              SessionId id, String host, int port,
              boolean useExtendedMasterSecret,
              String endpointIdAlgorithm){
          this.protocolVersion = protocolVersion;
          sessionId = id;
          peerCerts = null;
          compressionMethod = compression_null;
          this.cipherSuite = cipherSuite;
          masterSecret = null;
          this.host = host;
          this.port = port;
          sessionCount = ++counter;
          localSupportedSignAlgs =
              SignatureAndHashAlgorithm.getAlgorithmNames(algorithms);
          this.useExtendedMasterSecret = useExtendedMasterSecret;
          this.endpointIdentificationAlgorithm = endpointIdAlgorithm;
  
          if (debug != null && Debug.isOn("session")) {
              System.out.println("%% Initialized:  " + this);
          }
      }
  
      void setMasterSecret(SecretKey secret) {
          if (masterSecret == null) {
              masterSecret = secret;
          } else {
              throw new RuntimeException("setMasterSecret() error");
          }
      }
  
      /**
       * Returns the master secret ... treat with extreme caution!
       */
  