/* * On input, we hash messages one at a time since servers may need * to access an intermediate hash to validate a CertificateVerify * message. * * Note that many handshake messages can come in one record (and often * do, to reduce network resource utilization), and one message can also * require multiple records (e.g. very large Certificate messages). */ void processLoop() throws IOException { // need to read off 4 bytes at least to get the handshake // message type and length. while (input.available() >= 4) { byte messageType; int messageLen; /* * See if we can read the handshake message header, and * then the entire handshake message. If not, wait till * we can read and process an entire message. */ input.mark(4); messageType = (byte) input.getInt8(); messageLen = input.getInt24(); if (input.available() < messageLen) { input.reset(); return; } /* * Process the messsage. We require * that processMessage() consumes the entire message. In * lieu of explicit error checks (how?!) we assume that the * data will look like garbage on encoding/processing errors, * and that other protocol code will detect such errors. * * Note that digesting is normally deferred till after the * message has been processed, though to process at least the * client's Finished message (i.e. send the server's) we need * to acccelerate that digesting. * * Also, note that hello request messages are never hashed; * that includes the hello request header, too. */ if (messageType == HandshakeMessage.ht_hello_request) { input.reset(); processMessage(messageType, messageLen); input.ignore(4 + messageLen); } else { input.mark(messageLen); processMessage(messageType, messageLen); input.digestNow(); } } }
/* * This routine is fed SSL handshake records when they become available, * and processes messages found therein. */ void process_record(InputRecord r, boolean expectingFinished) throws IOException { checkThrown(); /* * Store the incoming handshake data, then see if we can * now process any completed handshake messages */ input.incomingRecord(r); /* * We don't need to create a separate delegatable task * for finished messages. */ if ((conn != null) || expectingFinished) { processLoop(); } else { delegateTask( new PrivilegedExceptionAction<Void>() { public Void run() throws Exception { processLoop(); return null; } }); } }