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

TLSv1.3 may generate TLSInnerPlainText longer than 2^14+1 bytes

    Details

    • Subcomponent:
    • Resolved In Build:
      b21
    • CPU:
      x86_64
    • OS:
      linux
    • Verification:
      Verified

      Backports

        Description

        ADDITIONAL SYSTEM INFORMATION :
        Linux 64-bit. Originally discovered with OpenJDK 11.0.2, but I can reproduce it with the tip of http://hg.openjdk.java.net/jdk-updates/jdk12u/

        A DESCRIPTION OF THE PROBLEM :
        The TLSv1.3 spec has this to say about the allowed length of TLSInnerPlaintext:

           The presence of padding does not change the overall record size
           limitations - the full encoded TLSInnerPlaintext MUST NOT exceed 2^14
           + 1 octets. If the maximum fragment length is reduced, as for
           example by the max_fragment_length extension from [RFC6066], then the
           reduced limit applies to the full plaintext, including the content
           type and padding.

        However, t13Encrypt in src/java.base/share/classes/sun/security/ssl/OutputRecord.java will always append 16 padding bytes to the fragment, without taking into account its original size:

            private static final class T13PaddingHolder {
                private static final byte[] zeros = new byte[16];
            }

            private long t13Encrypt(
                    SSLWriteCipher encCipher, byte contentType, int headerSize) {
                if (!encCipher.isNullCipher()) {
                    // inner plaintext
                    write(contentType);
                    write(T13PaddingHolder.zeros, 0, T13PaddingHolder.zeros.length);
                }
                ...

        This causes trouble with TLSv1.3 servers because we set Record.maxDataSize to 2^14, and so the added 1 + 16 bytes may cause the resulting TLSInnerPlaintext to go over the length limit.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Compile and run Test.java

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        The test TLSv1.3 server page at https://tls13.crypto.mozilla.org/ should be printed to console.
        ACTUAL -
        https://tls13.crypto.mozilla.org/ returns a "record_overflow" error.

        ---------- BEGIN SOURCE ----------
        import javax.net.ssl.HttpsURLConnection;
        import java.net.URL;
        import java.io.*;
        import java.nio.*;
        import java.nio.charset.StandardCharsets;
        import java.nio.file.*;

        public class Test {
            public static void main(String[] args) throws Exception {
                StringBuilder data = new StringBuilder();
                data.append("----abc\r\n")
                    .append("Content-Disposition: form-data; name=\"json_file\"; filename=\"test.json\"\r\n")
                    .append("Content-Type: application/octet-stream\r\n")
                    .append("\r\n");
                for (int i = 0; i < 325717; i++)
                    data.append("a");
                data.append("----abc--");
                URL url = new URL("https://tls13.crypto.mozilla.org/");
                HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
                connection.setRequestMethod("POST");
                connection.setDoInput(true);
                connection.setDoOutput(true);
                connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=--abc");
                OutputStreamWriter osw = new OutputStreamWriter(connection.getOutputStream());
                osw.write(data.toString());
                osw.flush();
                osw.close();
                BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                String line;
                while((line = br.readLine()) != null) {
                    System.out.println(line);
                }
            }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Disabling TLSv1.3 support by setting jdk.tls.client.protocols="TLSv1,TLSv1.1,TLSv1.2"

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  xuelei Xue-Lei Fan
                  Reporter:
                  webbuggrp Webbug Group
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  6 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: