private static void exploreHandshake(
         ByteBuffer input, byte recordMajorVersion,
         byte recordMinorVersion, int recordLength, List<String> alpnProtocols, ByteArrayOutputStream out) throws SSLException {

      // What is the handshake type?
      byte handshakeType = input.get();
      if (handshakeType != 0x01) {   // 0x01: client_hello message
         throw new SSLException("Expected client hello");
      }
      if(out != null) {
         out.write(handshakeType & 0xFF);
      }

      // What is the handshake body length?
      int handshakeLength = getInt24(input);
      if(out != null) {
         //placeholder
         out.write(0);
         out.write(0);
         out.write(0);
      }

      // Theoretically, a single handshake message might span multiple
      // records, but in practice this does not occur.
      if (handshakeLength > recordLength - 4) { // 4: handshake header size
         throw new SSLException("Multi record handshake");
      }

      input = input.duplicate();
      input.limit(handshakeLength + input.position());
      exploreClientHello(input, alpnProtocols, out);
   }
private static void exploreHandshake ( ByteBuffer input , byte recordMajorVersion , byte recordMinorVersion , int recordLength , List < String > alpnProtocols , ByteArrayOutputStream out ) throws SSLException { byte handshakeType = input . get ( ) ; if ( handshakeType != 0x01 ) { throw new SSLException ( "Expected client hello" ) ; } if ( out != null ) { out . write ( handshakeType & 0xFF ) ; } int handshakeLength = getInt24 ( input ) ; if ( out != null ) { out . write ( 0 ) ; out . write ( 0 ) ; out . write ( 0 ) ; } if ( handshakeLength > recordLength - 4 ) { throw new SSLException ( "Multi record handshake" ) ; } input = input . duplicate ( ) ; input . limit ( handshakeLength + input . position ( ) ) ; exploreClientHello ( input , alpnProtocols , out ) ; }
/*
enum {
hello_request(0), client_hello(1), server_hello(2),
certificate(11), server_key_exchange (12),
certificate_request(13), server_hello_done(14),
certificate_verify(15), client_key_exchange(16),
finished(20)
(255)
} HandshakeType;

struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request:       HelloRequest;
case client_hello:        ClientHello;
case server_hello:        ServerHello;
case certificate:         Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done:   ServerHelloDone;
case certificate_verify:  CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished:            Finished;
} body;
} Handshake;