Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8180643

Illegal handshake message

    XMLWordPrintable

Details

    • b18
    • x86_64
    • linux
    • Verified

    Backports

      Description

        FULL PRODUCT VERSION :
        openjdk version "1.8.0-jdk8u112-b00"
        OpenJDK Runtime Environment (build 1.8.0-jdk8u112-b00-20160510)
        OpenJDK 64-Bit Server VM (build 25.71-b20160510, mixed mode)


        ADDITIONAL OS VERSION INFORMATION :
        Linux anuemss 3.5.0 #1 SMP Wed Feb 22 13:01:16 CST 2017 x86_64 GNU/Linux

        A DESCRIPTION OF THE PROBLEM :
        We are currently in the process of getting Federal certification for common criteria (NDcPP) on a product using OpenJDK.

        When testing the OpenJDK as a TLS server, the test requires sending the TLS client handshake Finished message before the ChangeCipherSpec message. The test should result in the OpenJDK TLS server sending a TLS fatalAlert, but instead the unexpected Finished message is ignored. The ChangeCipherSpec message is processed and The TLS connection eventually times out waiting for the real client Finished message.

        From debugging, I believe the problem is the Finished message is encrypted, but since the ChangeCiperSpec message has not been received, no cipher is in place for decryption. The Finished message is handed unencrypted to the ServerHandshaker and is processed in Handshaker.processLoop as is. The messageType and messageLen are read, then the messageLen is determined to be larger than the available input so the input is reset and the function returns.

        From sun.security.ssl.Handshaker.java
            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;
                    }
        <snip>

        For what it's worth, openssl handles this by retrieving a max message size based on messageType. If the returned max length is less than the messageLen retrieved from the input an illegal_parameter fatalAlert is sent. If the messageType is not valid this function returns 0 for the max size.



        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        We used python scapy scripts to simulate a TLS client that could send messages out of order. The message sequence is as follows:

        Client sends
            * Client Hello message
        Server sends
            * Server Hello,
            * Certificate,
            * Server Hello Done
        Client sends
            * Client Key Exchange
            * Finished (NOTE out of order)
            * Change Ciper Spec

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        We expected a fatalError when the Finished message was received by the server. Instead, the out of order Finished message is ignored.
        ACTUAL -
        The server receives the Change Cipher Spec message and waits for the Finished message. The socket eventually times out.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        SUPPORT :
        YES

        Attachments

          Issue Links

            Activity

              People

                xuelei Xuelei Fan
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                6 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: