/** Starts renegotiation on a new session */
 @DSComment("Private Method")
 @DSBan(DSCat.PRIVATE_METHOD)
 @DSGenerator(
     tool_name = "Doppelganger",
     tool_version = "2.0",
     generated_on = "2013-12-30 13:01:10.412 -0500",
     hash_original_method = "A1AF1BC51EE82C9340D705103AD7A155",
     hash_generated_method = "B095B45DF7DE60E1EB58901C0B717D81")
 private void renegotiateNewSession() {
   if (parameters.getEnableSessionCreation()) {
     isResuming = false;
     session = new SSLSessionImpl(parameters.getSecureRandom());
     if (engineOwner != null) {
       session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
     } else {
       session.setPeer(socketOwner.getInetAddress().getHostName(), socketOwner.getPort());
     }
     session.protocol = ProtocolVersion.getLatestVersion(parameters.getEnabledProtocols());
     recordProtocol.setVersion(session.protocol.version);
     startSession();
   } else {
     status = NOT_HANDSHAKING;
     sendWarningAlert(AlertProtocol.NO_RENEGOTIATION);
   }
 }
 /** Starts handshake */
 @DSGenerator(
     tool_name = "Doppelganger",
     tool_version = "2.0",
     generated_on = "2013-12-30 13:01:10.409 -0500",
     hash_original_method = "6C060C09ED0246441EBDE47DFEF048B2",
     hash_generated_method = "4BC410302B6F252CC3D835E7B02F89AC")
 @Override
 public void start() {
   if (session == null) { // initial handshake
     session = findSessionToResume();
   } else { // start session renegotiation
     if (clientHello != null && this.status != FINISHED) {
       // current negotiation has not completed
       return; // ignore
     }
     if (!session.isValid()) {
       session = null;
     }
   }
   if (session != null) {
     isResuming = true;
   } else if (parameters.getEnableSessionCreation()) {
     isResuming = false;
     session = new SSLSessionImpl(parameters.getSecureRandom());
     if (engineOwner != null) {
       session.setPeer(engineOwner.getPeerHost(), engineOwner.getPeerPort());
     } else {
       session.setPeer(socketOwner.getInetAddress().getHostName(), socketOwner.getPort());
     }
     session.protocol = ProtocolVersion.getLatestVersion(parameters.getEnabledProtocols());
     recordProtocol.setVersion(session.protocol.version);
   } else {
     fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "SSL Session may not be created ");
   }
   startSession();
 }
  /**
   * Processes inbound handshake messages
   *
   * @param bytes
   */
  @DSGenerator(
      tool_name = "Doppelganger",
      tool_version = "2.0",
      generated_on = "2013-12-30 13:01:10.423 -0500",
      hash_original_method = "A389390FF4680222C458E1D6E9083717",
      hash_generated_method = "4F35B217867E297BC43CAC891648AAE5")
  @Override
  public void unwrap(byte[] bytes) {
    if (this.delegatedTaskErr != null) {
      Exception e = this.delegatedTaskErr;
      this.delegatedTaskErr = null;
      this.fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Error in delegated task", e);
    }
    int handshakeType;
    io_stream.append(bytes);
    while (io_stream.available() > 0) {
      io_stream.mark();
      int length;
      try {
        handshakeType = io_stream.read();
        length = io_stream.readUint24();
        if (io_stream.available() < length) {
          io_stream.reset();
          return;
        }
        switch (handshakeType) {
          case 0: // HELLO_REQUEST
            // we don't need to take this message into account
            // during FINISH message verification, so remove it
            io_stream.removeFromMarkedPosition();
            if (clientHello != null && (clientFinished == null || serverFinished == null)) {
              // currently negotiating - ignore
              break;
            }
            // renegotiate
            if (session.isValid()) {
              session = (SSLSessionImpl) session.clone();
              isResuming = true;
              startSession();
            } else {
              // if SSLSession is invalidated (e.g. timeout limit is
              // exceeded) connection can't resume the session.
              renegotiateNewSession();
            }
            break;
          case 2: // SERVER_HELLO
            if (clientHello == null || serverHello != null) {
              unexpectedMessage();
              return;
            }
            serverHello = new ServerHello(io_stream, length);

            // check protocol version
            ProtocolVersion servProt = ProtocolVersion.getByVersion(serverHello.server_version);
            String[] enabled = parameters.getEnabledProtocols();
            find:
            {
              for (int i = 0; i < enabled.length; i++) {
                if (servProt.equals(ProtocolVersion.getByName(enabled[i]))) {
                  break find;
                }
              }
              fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello protocol version");
            }

            // check compression method
            if (serverHello.compression_method != 0) {
              fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello compression method");
            }

            // check cipher_suite
            CipherSuite[] enabledSuites = parameters.getEnabledCipherSuitesMember();
            find:
            {
              for (int i = 0; i < enabledSuites.length; i++) {
                if (serverHello.cipher_suite.equals(enabledSuites[i])) {
                  break find;
                }
              }
              fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello cipher suite");
            }

            if (isResuming) {
              if (serverHello.session_id.length == 0) {
                // server is not willing to establish the new connection
                // using specified session
                isResuming = false;
              } else if (!Arrays.equals(serverHello.session_id, clientHello.session_id)) {
                isResuming = false;
              } else if (!session.protocol.equals(servProt)) {
                fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello protocol version");
              } else if (!session.cipherSuite.equals(serverHello.cipher_suite)) {
                fatalAlert(AlertProtocol.HANDSHAKE_FAILURE, "Bad server hello cipher suite");
              }
              if (serverHello.server_version[1] == 1) {
                computerReferenceVerifyDataTLS("server finished");
              } else {
                computerReferenceVerifyDataSSLv3(SSLv3Constants.server);
              }
            }
            session.protocol = servProt;
            recordProtocol.setVersion(session.protocol.version);
            session.cipherSuite = serverHello.cipher_suite;
            session.id = serverHello.session_id.clone();
            session.serverRandom = serverHello.random;
            break;
          case 11: // CERTIFICATE
            if (serverHello == null
                || serverKeyExchange != null
                || serverCert != null
                || isResuming) {
              unexpectedMessage();
              return;
            }
            serverCert = new CertificateMessage(io_stream, length);
            break;
          case 12: // SERVER_KEY_EXCHANGE
            if (serverHello == null || serverKeyExchange != null || isResuming) {
              unexpectedMessage();
              return;
            }
            serverKeyExchange =
                new ServerKeyExchange(io_stream, length, session.cipherSuite.keyExchange);
            break;
          case 13: // CERTIFICATE_REQUEST
            if (serverCert == null
                || certificateRequest != null
                || session.cipherSuite.isAnonymous()
                || isResuming) {
              unexpectedMessage();
              return;
            }
            certificateRequest = new CertificateRequest(io_stream, length);
            break;
          case 14: // SERVER_HELLO_DONE
            if (serverHello == null || serverHelloDone != null || isResuming) {
              unexpectedMessage();
              return;
            }
            serverHelloDone = new ServerHelloDone(io_stream, length);
            if (this.nonBlocking) {
              delegatedTasks.add(
                  new DelegatedTask(
                      new Runnable() {
                        @DSSafe(DSCat.SAFE_LIST)
                        public void run() {
                          processServerHelloDone();
                        }
                      },
                      this));
              return;
            }
            processServerHelloDone();
            break;
          case 20: // FINISHED
            if (!changeCipherSpecReceived) {
              unexpectedMessage();
              return;
            }
            serverFinished = new Finished(io_stream, length);
            verifyFinished(serverFinished.getData());
            session.lastAccessedTime = System.currentTimeMillis();
            session.context = parameters.getClientSessionContext();
            parameters.getClientSessionContext().putSession(session);
            if (isResuming) {
              sendChangeCipherSpec();
            } else {
              session.lastAccessedTime = System.currentTimeMillis();
              status = FINISHED;
            }
            // XXX there is no cleanup work
            break;
          default:
            unexpectedMessage();
            return;
        }
      } catch (IOException e) {
        // io stream dosn't contain complete handshake message
        io_stream.reset();
        return;
      }
    }
  }