/** Creates and sends Finished message */ @DSGenerator( tool_name = "Doppelganger", tool_version = "2.0", generated_on = "2013-12-30 13:01:10.428 -0500", hash_original_method = "8B073BF3F8F00875CF9B653567C3900A", hash_generated_method = "782E43CE43B7326AF0F4F50C66FB2FDB") @Override protected void makeFinished() { byte[] verify_data; if (serverHello.server_version[1] == 1) { verify_data = new byte[12]; computerVerifyDataTLS("client finished", verify_data); } else { verify_data = new byte[36]; computerVerifyDataSSLv3(SSLv3Constants.client, verify_data); } clientFinished = new Finished(verify_data); send(clientFinished); if (isResuming) { session.lastAccessedTime = System.currentTimeMillis(); status = FINISHED; } else { if (serverHello.server_version[1] == 1) { computerReferenceVerifyDataTLS("server finished"); } else { computerReferenceVerifyDataSSLv3(SSLv3Constants.server); } status = NEED_UNWRAP; } }
/** * 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; } } }