/** * 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; }
/* * 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(); } } }
/* * Set the handshake session */ void setHandshakeSessionSE(SSLSessionImpl handshakeSession) { if (conn != null) { conn.setHandshakeSession(handshakeSession); } else { engine.setHandshakeSession(handshakeSession); } }
private void setVersionSE(ProtocolVersion protocolVersion) { if (conn != null) { conn.setVersion(protocolVersion); } else { engine.setVersion(protocolVersion); } }
int getLocalPortSE() { if (conn != null) { return conn.getLocalPort(); } else { return -1; } }
AccessControlContext getAccSE() { if (conn != null) { return conn.getAcc(); } else { return engine.getAcc(); } }
boolean isLoopbackSE() { if (conn != null) { return conn.getInetAddress().isLoopbackAddress(); } else { return false; } }
int getPortSE() { if (conn != null) { return conn.getPort(); } else { return engine.getPeerPort(); } }
String getHostSE() { if (conn != null) { return conn.getHost(); } else { return engine.getPeerHost(); } }
String getRawHostnameSE() { if (conn != null) { return conn.getRawHostname(); } else { return engine.getPeerHost(); } }
void warningSE(byte b) { if (conn != null) { conn.warning(b); } else { engine.warning(b); } }
void fatalSE(byte b, String diagnostic, Throwable cause) throws IOException { if (conn != null) { conn.fatal(b, diagnostic, cause); } else { engine.fatal(b, diagnostic, cause); } }
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(); } }