예제 #1
0
  /**
   * Prior to handshaking, activate the handshake and initialize the version, input stream and
   * output stream.
   */
  void activate(ProtocolVersion helloVersion) throws IOException {
    if (activeProtocols == null) {
      activeProtocols = getActiveProtocols();
    }

    if (activeProtocols.collection().isEmpty() || activeProtocols.max.v == ProtocolVersion.NONE.v) {
      throw new SSLHandshakeException("No appropriate protocol");
    }

    if (activeCipherSuites == null) {
      activeCipherSuites = getActiveCipherSuites();
    }

    if (activeCipherSuites.collection().isEmpty()) {
      throw new SSLHandshakeException("No appropriate cipher suite");
    }

    // temporary protocol version until the actual protocol version
    // is negotiated in the Hello exchange. This affects the record
    // version we sent with the ClientHello.
    if (!isInitialHandshake) {
      protocolVersion = activeProtocolVersion;
    } else {
      protocolVersion = activeProtocols.max;
    }

    if (helloVersion == null || helloVersion.v == ProtocolVersion.NONE.v) {
      helloVersion = activeProtocols.helloVersion;
    }

    // We accumulate digests of the handshake messages so that
    // we can read/write CertificateVerify and Finished messages,
    // getting assurance against some particular active attacks.
    Set<String> localSupportedHashAlgorithms =
        SignatureAndHashAlgorithm.getHashAlgorithmNames(getLocalSupportedSignAlgs());
    handshakeHash = new HandshakeHash(!isClient, needCertVerify, localSupportedHashAlgorithms);

    // Generate handshake input/output stream.
    input = new HandshakeInStream(handshakeHash);
    if (conn != null) {
      output = new HandshakeOutStream(protocolVersion, helloVersion, handshakeHash, conn);
      conn.getAppInputStream().r.setHandshakeHash(handshakeHash);
      conn.getAppInputStream().r.setHelloVersion(helloVersion);
      conn.getAppOutputStream().r.setHelloVersion(helloVersion);
    } else {
      output = new HandshakeOutStream(protocolVersion, helloVersion, handshakeHash, engine);
      engine.inputRecord.setHandshakeHash(handshakeHash);
      engine.inputRecord.setHelloVersion(helloVersion);
      engine.outputRecord.setHelloVersion(helloVersion);
    }

    // move state to activated
    state = -1;
  }
예제 #2
0
  /*
   * Sends a change cipher spec message and updates the write side
   * cipher state so that future messages use the just-negotiated spec.
   */
  void sendChangeCipherSpec(Finished mesg, boolean lastMessage) throws IOException {

    output.flush(); // i.e. handshake data

    /*
     * The write cipher state is protected by the connection write lock
     * so we must grab it while making the change. We also
     * make sure no writes occur between sending the ChangeCipherSpec
     * message, installing the new cipher state, and sending the
     * Finished message.
     *
     * We already hold SSLEngine/SSLSocket "this" by virtue
     * of this being called from the readRecord code.
     */
    OutputRecord r;
    if (conn != null) {
      r = new OutputRecord(Record.ct_change_cipher_spec);
    } else {
      r = new EngineOutputRecord(Record.ct_change_cipher_spec, engine);
    }

    r.setVersion(protocolVersion);
    r.write(1); // single byte of data

    if (conn != null) {
      conn.writeLock.lock();
      try {
        conn.writeRecord(r);
        conn.changeWriteCiphers();
        if (debug != null && Debug.isOn("handshake")) {
          mesg.print(System.out);
        }
        mesg.write(output);
        output.flush();
      } finally {
        conn.writeLock.unlock();
      }
    } else {
      synchronized (engine.writeLock) {
        engine.writeRecord((EngineOutputRecord) r);
        engine.changeWriteCiphers();
        if (debug != null && Debug.isOn("handshake")) {
          mesg.print(System.out);
        }
        mesg.write(output);

        if (lastMessage) {
          output.setFinishedMsg();
        }
        output.flush();
      }
    }
  }
예제 #3
0
 /*
  * Set the handshake session
  */
 void setHandshakeSessionSE(SSLSessionImpl handshakeSession) {
   if (conn != null) {
     conn.setHandshakeSession(handshakeSession);
   } else {
     engine.setHandshakeSession(handshakeSession);
   }
 }
예제 #4
0
 private void setVersionSE(ProtocolVersion protocolVersion) {
   if (conn != null) {
     conn.setVersion(protocolVersion);
   } else {
     engine.setVersion(protocolVersion);
   }
 }
예제 #5
0
 int getLocalPortSE() {
   if (conn != null) {
     return conn.getLocalPort();
   } else {
     return -1;
   }
 }
예제 #6
0
 AccessControlContext getAccSE() {
   if (conn != null) {
     return conn.getAcc();
   } else {
     return engine.getAcc();
   }
 }
예제 #7
0
 boolean isLoopbackSE() {
   if (conn != null) {
     return conn.getInetAddress().isLoopbackAddress();
   } else {
     return false;
   }
 }
예제 #8
0
 int getPortSE() {
   if (conn != null) {
     return conn.getPort();
   } else {
     return engine.getPeerPort();
   }
 }
예제 #9
0
 String getHostSE() {
   if (conn != null) {
     return conn.getHost();
   } else {
     return engine.getPeerHost();
   }
 }
예제 #10
0
 String getRawHostnameSE() {
   if (conn != null) {
     return conn.getRawHostname();
   } else {
     return engine.getPeerHost();
   }
 }
예제 #11
0
 void warningSE(byte b) {
   if (conn != null) {
     conn.warning(b);
   } else {
     engine.warning(b);
   }
 }
예제 #12
0
 void fatalSE(byte b, String diagnostic, Throwable cause) throws IOException {
   if (conn != null) {
     conn.fatal(b, diagnostic, cause);
   } else {
     engine.fatal(b, diagnostic, cause);
   }
 }
예제 #13
0
 String getHostAddressSE() {
   if (conn != null) {
     return conn.getInetAddress().getHostAddress();
   } else {
     /*
      * This is for caching only, doesn't matter that's is really
      * a hostname.  The main thing is that it doesn't do
      * a reverse DNS lookup, potentially slowing things down.
      */
     return engine.getPeerHost();
   }
 }