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

TLS 1.3 Implementation

    XMLWordPrintable

Details

    • CSR
    • Resolution: Approved
    • P2
    • 11
    • security-libs
    • None
    • behavioral
    • low
    • See discussion in Specification section
    • Java API, System or security property, Other
    • SE

    Description

      Summary

      Implement a minimal inter-operable and compatible Transport Layer Security (TLS) Protocol version 1.3.

      Problem

      TLS 1.3 is a major overhaul of the TLS protocol and provides significant security and performance improvements over previous versions. Several early implementations from other vendors are available already. We need to support TLS 1.3 to remain competitive and keep pace with the latest standard.

      A minimal inter-operable and compatible TLS 1.3 implementation should support:

      • Protocol version negotiation
      • TLS 1.3 full handshake
      • TLS 1.3 session resumption
      • TLS 1.3 key and iv update
      • TLS 1.3 updated OCSP stapling
      • TLS 1.3 backward compatibility mode
      • TLS 1.3 required extensions and algorithms
      • RSASSA-PSS signature algorithms (JDK-8146293)

      As a new version, TLS 1.3 supersedes and obsoletes previous versions of TLS including version 1.2 (RFC 5246). It also obsoletes or changes other TLS features such as the OCSP stapling extensions (RFC 6066, RFC 6961), and the session hash and extended master secret extension (RFC 7627). The Java Secure Socket Extension (JSSE) in the JDK provides a framework and a Java implementation of the SSL, TLS, and DTLS protocols. Currently, the JSSE API and JDK implementation supports SSL 3.0, TLS 1.0, TLS 1.1, TLS 1.2, DTLS 1.0 and DTLS 1.2.

      No new public APIs are required for the minimal implementation. However, it is required to define new algorithms for TLS 1.3, and document the behavior difference between TLS 1.3 and TLS 1.2 or prior versions.

      Note that the TLS 1.3 Internet Draft has undergone many revisions but is not yet a Standard. The most recent draft (28) has been approved by the TLS Working Group and the IESG, and is now in the RFC Editor's Queue.

      See more in the JEP description: http://openjdk.java.net/jeps/332

      Solution

      This CSR requests to support a minimal inter-operable and compatible TLS 1.3 implementation in the SunJSSE provider in JDK. See the "Specification" section for the details.

      Specification

      1. new standard algorithm name for SSLContext protocols

      Define the standard algorithm name for TLS 1.3 for SSLContext protocols:

      TLSv1.3: supports RFC (*TBD): TLS version 1.3; may support other TLS versions
      
      (*TBD): the RFC is not yet published.

      Need to add the standard algorithm name to the SSLContext section in the "Java Security Standard Algorithm Names" specification, and update the "JDK Providers" and "Java Secure Socket Extension (JSSE) Reference Guide" documentation accordingly.

      2. new standard algorithm names for the enabled or supported protocols

      Define the following standard algorithm name for TLS 1.3 for the negotiated, enabled or supported protocols of classes SSLSession, SSLEngine, SSLServerSocket, SSLSocket and SSLParameters:

      TLSv1.3: TLS version 1.3 protocol (defined in RFC (*TBD))
      
      (*TBD): the RFC is not yet published.

      Need to add the standard algorithm name to the protocols block of the "Additional JSSE Standard Names" section in the "Java Security Standard Algorithm Names" specification, and update the "Java Secure Socket Extension (JSSE) Reference Guide" documentation accordingly.

      3. new System Property to configure the default server enabled protocol suite

      A System Property, "jdk.tls.server.protocols", is added to configure the default enabled protocol suite in server side of SunJSSE provider.

      The property string is a list of comma separated standard SSL protocol names. The syntax of the property string can be described as this Java BNF-style:

       ServerProtocols:
              ('"' SSLProtocolNames '"') | SSLProtocolNames
       SSLProtocolNames:
              SSLProtocolName { , SSLProtocolName }
       SSLProtocolName:
              (see below)

      The "SSLProtocolName" is the standard SSL protocol name as described in the "Java Cryptography Architecture Standard Algorithm Name Documentation". If the property value does not comply to the above syntax, or the specified value of SSLProtocolName is not a supported SSL protocol name, the instantiation of the SSLContext provider service (via SSLContext.getInstance() methods) may generate a java.security.NoSuchAlgorithmException. Please note that the protocol name is case-sensitive.

      Note that this System Property impact only the default protocol suite (SSLContext of algorithm "SSL", "TLS" and "DTLS"). If an application uses a version specified SSLContext ("SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3", "DTLSv1.0", "DTLSv1.2"), or set the enabled protocol version explicitly, this System Property has no impact.

      Note that this System Property does not impact the API specification of JSSE, JSSE client side and third party's provider.

      4. enable TLS 1.3 by default

      TLS version 1.3 will be enabled in the default SSLContext ("SSL" or "TLS") in JDK. The supported, client default enabled and server default enabled TLS versions of different SSLContext protocols can be summarized as follow:

      -----------------------+---------------+----------------------------
      SSLContext protocols   | supported TLS |   enabled TLS versions
                             |   versions    +-------------+--------------
                             |               | client mode |  server mode
      -----------------------+---------------+-------------+--------------
      SSL                    | TLSv1.3       |  TLSv1.3    |  TLSv1.3
                             | TLSv1.2       |  TLSv1.2    |  TLSv1.2
                             | TLSv1.1       |  TLSv1.1    |  TLSv1.1
                             | TLSv1         |  TLSv1      |  TLSv1
                             | SSLv3         |  SSLv3      |  SSLv3
      -----------------------+ (SSLv2Hello)  +-------------+  (SSLv2Hello)
      SSLv3                  |               |  TLSv1      |
                             |               |  SSLv3      |
      -----------------------+               +-------------+
      TLS                    |               |  TLSv1.3    |
                             |               |  TLSv1.2    |
                             |               |  TLSv1.1    |
                             |               |  TLSv1      |
                             |               |  SSLv3      |
      -----------------------+               +-------------+
      TLSv1                  |               |  TLSv1      |
                             |               |  SSLv3      |
      -----------------------+               +-------------+
      TLSv1.1                |               |  TLSv1.1    |
                             |               |  TLSv1      |
                             |               |  SSLv3      |
      -----------------------+               +-------------+
      TLSv1.2                |               |  TLSv1.2    |
                             |               |  TLSv1.1    |
                             |               |  TLSv1      |
                             |               |  SSLv3      |
      -----------------------+               +-------------+
      TLSv1.3                |               |  TLSv1.3    |
                             |               |  TLSv1.2    |
                             |               |  TLSv1.1    |
                             |               |  TLSv1      |
                             |               |  SSLv3      |
      -----------------------+---------------+-------------+--------------

      If there is a need, TLSv1.3 can be disabled explicitly. See the "Customizing JSSE" section in the "Java Secure Socket Extension (JSSE) Reference Guide" documentation.

      5. new TLS cipher suite names for TLS 1.3

      Define two new standard cipher suite names for TLS 1.3 in this implementation.

      • TLS_AES_128_GCM_SHA256
      • TLS_AES_256_GCM_SHA384

      Although TLS 1.3 uses the same cipher suite space as previous versions, TLS 1.3 cipher suites are defined differently and cannot be used with TLS 1.2. Similarly, TLS 1.2 and lower cipher suites cannot be used with TLS 1.3. Need to update the "JSSE Cipher Suite Names" section in the "Java Security Standard Algorithm Names" specification, and the "Java Secure Socket Extension (JSSE) Reference Guide" and "SunJSSE" section of the "JDK Providers" documentation accordingly.

      6. New TLS handshake extensions

      Implement TLS 1.3 mandatory-to-implement extensions, including:

      • supported_versions (new TLS handshake extension in JDK)
      • cookie (new TLS handshake extension in JDK)
      • signature_algorithms
      • signature_algorithms_cert (new TLS handshake extension in JDK)
      • supported_groups
      • key_share (new TLS handshake extension in JDK)
      • server_name

      and the required extensions for session resumption:

      • pre_shared_key (new TLS handshake extension in JDK)
      • psk_key_exchange_modes (new TLS handshake extension in JDK)

      Note that the following optional extensions are also supported:

      • max_fragment_length
      • status_request
      • application_layer_protocol_negotiation

      7. Support stateless HelloRetryRequest

      In JDK, a TLS 1.3 server will operate a stateless HelloRetryRequest for performance and security improvement.

      8. Support post-handshake key and IV update

      TLS 1.3 has a post-handshake key and IV update, which will update the sending and receiving keys for one side of the connection. Applications can trigger an update by calling SSLSocket.startHandshake() or SSLEngine.beginHandshake(). Key Usage Limits will also trigger an update when the algorithm limits are reached

      9. Support session resumption with post-handshake new session ticket

      After TLS 1.3 handshake complete, a JDK server will send a NewSessionTicket message. The client may use this message for session resumption if needed later.

      10. Support RSASSA-PSS key exchange and X.509 certificate

      Support RSASSA-PSS algorithms with public key OID either rsaEncryption or RSASSA-PSS. See also the RSSSSA-PSS CSR for JCE components: https://bugs.openjdk.java.net/browse/JDK-8190180

      11. Support OCSP stapling for server certificate authentication

      TLS 1.3 improves the Online Certificate Status Protocol (OCSP) stapling by using different handshake messages. JDK will support OCSP stapling for server certificate authentication. It is a pure implementation update in JDK, applications should not be impacted.

      As JDK 10, OCSP stapling request can be enabled on the client side by setting the system property jdk.tls.client.enableStatusRequestExtension to true (default value); and OCSP stapling response on the server side can be enabled by setting the system property jdk.tls.server.enableStatusRequestExtension to true (default is false). More details, please refer to the "OCSP Stapling and Certificate Revocation" section in the "Java Secure Socket Extension (JSSE) Reference Guide" documentation.

      Note that TLS 1.3 deprecate the "status_request_v2" extension, and therefore deprecate the OCSP stapling implementation based on the "status_request_v2" extension. TLS 1.3 uses different handshake messages for OCSP stapling. Although the update is transparent to applications, we should update the OCSP stapling descriptions accordingly in the "Java Secure Socket Extension (JSSE) Reference Guide" documentation.

      12. Limits on key usage

      There are cryptographic limits some algorithms have on the amount of plaintext which can be safely encrypted under a given set of keys. A new Security Property, "jdk.tls.keyLimits" has been added for TLS 1.3. When the amount of encrypted data by the algorithm has been reached a post-handshake Key and IV Update is triggered to derive new keys. This value is configurable so administrators can control their own security policies.

      #
      # TLS key limits on symmetric cryptographic algorithms
      #
      # This security property sets limits on algorithms key usage in TLS 1.3.
      # When the amount of data encrypted exceeds the algorithm value listed below,
      # a KeyUpdate message will trigger a key change.  This is for symmetric ciphers
      # with TLS 1.3 only.
      #
      # The syntax for the property is described below:
      #   KeyLimits:
      #       " KeyLimit { , KeyLimit } "
      #
      #   WeakKeyLimit:
      #       AlgorithmName Action Length
      #
      #   AlgorithmName:
      #       A full algorithm transformation.
      #
      #   Action:
      #       KeyUpdate
      #
      #   Length:
      #       The amount of encrypted data in a session before the Action occurs
      #       This value may be an integer value in bytes, or as a power of two, 2^29.
      #
      #   KeyUpdate:
      #       The TLS 1.3 KeyUpdate handshake process begins when the Length amount
      #       is fulfilled.
      #
      # Note: This property is currently used by OpenJDK's JSSE implementation. It
      # is not guaranteed to be examined and used by other implementations.
      #
      jdk.tls.keyLimits=AES/GCM/NoPadding KeyUpdate 2^37

      13. Deprecated extensions in TLS 1.3

      The following extensions are deprecated, and do not apply to TLS 1.3 any more:

      • status_request_v2 (RFC 6961)
      • extended_master_secret (RFC 7627)
      • renegotiation_info (RFC5746)
      • ec_point_formats (RFC 4492)

      Note that the JDK will continue the support of them for TLS 1.2 and prior versions.

      14. Implement in compatibility mode

      In order to mitigate the compatibility impact, TLS 1.3 will be implemented in the compatibility mode, as described in the "Middlebox Compatibility Mode" section of the TLS 1.3 specification.

      15. New debug logger

      The current implementation dumps debug log to both System.err and System.out, and hard to read and analyze. A new debug logger will be used with this enhancement. For compatibility, the System Property "javax.net.debug" is still used to switch on/off the debug log.

      If the System Property "javax.net.debug" is not defined, the debug logging is turned
      off.  If the System Property "javax.net.debug" is defined as empty, the debug logger
      is specified by System.getLogger("javax.net.ssl"), and applications can customize
      and configure the logger or use external logging mechanisms.  If the System
      Property "javax.net.debug" is defined and non-empty, a JDK private debug logger
      implemented is used.

      For the JDK private debug logger, there are a few enhancement so that it is easier to read and analyze. For example, in the current implementation, a handshake message debug log may look like:

      *** ServerHello, TLSv1.2
      RandomCookie:  random_bytes = {5A 4E F9 E3 0C C5 C3 FE B6 50 ED 3E 40 2D 5D 75 27 12 B7 C0 FB CA C5 DD 6E 79 DB FF AE C8 32 63}
      Session ID:  {90, 78, 249, 227, 53, 127, 161, 141, 161, 33, 124, 107, 167, 128, 131, 252, 2, 170, 193, 168, 50, 40, 183, 150, 161, 217, 57, 214, 248, 78, 138, 158}
      Cipher Suite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
      Compression Method: 0
      Extension renegotiation_info, renegotiated_connection: <empty>

      A similar debug log in the enhanced implementation may look like:

      javax.net.ssl|DEBUG|01|main|2018-05-03 18:51:03.351 PDT|ServerHello.java:362|Produced ServerHello handshake message (
      "ServerHello": {
        "server version"      : "TLSv1.2",
        "random"              : "84 89 84 9A B9 76 10 11 14 8E 0A 2E 66 F5 32 D9 6A B4 5A 92 41 ED 01 BA E3 DB 9E 4C 81 C5 54 29",
        "session id"          : "57 D7 69 7B 34 C8 5F 67 03 AF 9E 11 69 C3 29 86 7C 88 35 34 54 72 5E 7F A6 54 C8 A1 9C A0 3D 24",
        "cipher suite"        : "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384(0xC02C)",
        "compression methods" : "00",
        "extensions"          : [
          "renegotiation_info (65,281)": {
            "renegotiated connection": [<no renegotiated connection>]
          }
        ]
      }
      )

      The new JDK private debug logger will record the logger name, the logger level, the thread ID, the thread name, the time and the caller for each log item.

      16. Remove KRB5 cipher suites implementation from the JDK

      The KRB5 cipher suites implementation will be removed from the JDK because they are no longer considered safe to use. The removed KRB5 cipher suites include:

      • TLS_KRB5_WITH_3DES_EDE_CBC_SHA
      • TLS_KRB5_WITH_3DES_EDE_CBC_MD5
      • TLS_KRB5_WITH_RC4_128_SHA
      • TLS_KRB5_WITH_RC4_128_MD5
      • TLS_KRB5_WITH_DES_CBC_SHA
      • TLS_KRB5_WITH_DES_CBC_MD5
      • TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA
      • TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5
      • TLS_KRB5_EXPORT_WITH_RC4_40_SHA
      • TLS_KRB5_EXPORT_WITH_RC4_40_MD5

      Need to remove the KRB5 cipher suite algorithm names and related descriptions from the "Java Secure Socket Extension (JSSE) Reference Guide" and the "SunJSSE" section of the "JDK Providers" documentation.

      17.A minimal Java specification change

      javax.net.ssl.ExtendedSSLSession:

      public abstract class ExtendedSSLSession implements SSLSession {
          /**
           * Obtains an array of supported signature algorithms that the local side
           * is willing to use.
           * <p>
           * Note: this method is used to indicate to the peer which signature
      -    * algorithms may be used for digital signatures in TLS/DTLS 1.2. It is
      +    * algorithms may be used for digital signatures since TLS/DTLS 1.2. It is
           * not meaningful for TLS/DTLS versions prior to 1.2.
           * <p>
           * The signature algorithm name must be a standard Java Security
           * name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
           * See the <a href=
           * "{@docRoot}/../specs/security/standard-names.html">
           * Java Security Standard Algorithm Names</a> document
           * for information about standard algorithm names.
           * <p>
           * Note: the local supported signature algorithms should conform to
           * the algorithm constraints specified by
           * {@link SSLParameters#getAlgorithmConstraints getAlgorithmConstraints()}
           * method in {@code SSLParameters}.
           *
           * @return An array of supported signature algorithms, in descending
           *     order of preference.  The return value is an empty array if
           *     no signature algorithm is supported.
           *
           * @see SSLParameters#getAlgorithmConstraints
           */
          public abstract String[] getLocalSupportedSignatureAlgorithms();
      
          /**
           * Obtains an array of supported signature algorithms that the peer is
           * able to use.
           * <p>
           * Note: this method is used to indicate to the local side which signature
      -    * algorithms may be used for digital signatures in TLS/DTLS 1.2. It is
      +    * algorithms may be used for digital signatures since TLS/DTLS 1.2. It is
           * not meaningful for TLS/DTLS versions prior to 1.2.
           * <p>
           * The signature algorithm name must be a standard Java Security
           * name (such as "SHA1withRSA", "SHA256withECDSA", and so on).
           * See the <a href=
           * "{@docRoot}/../specs/security/standard-names.html">
           * Java Security Standard Algorithm Names</a> document
           * for information about standard algorithm names.
           *
           * @return An array of supported signature algorithms, in descending
           *     order of preference.  The return value is an empty array if
           *     the peer has not sent the supported signature algorithms.
           *
           * @see X509KeyManager
           * @see X509ExtendedKeyManager
           */
          public abstract String[] getPeerSupportedSignatureAlgorithms();
      
          ...
      }

      Compatibility Risk

      Note that TLS 1.3 is not directly compatible with previous versions. Although TLS 1.3 can be implemented with a backward-compatibility mode, there are still several compatibility risks to upgrade to TLS 1.3:

      • TLS 1.3 uses a half-close policy, while TLS 1.2 and prior versions use a duplex-close policy. For applications that depend on the duplex-close policy, there may be compatibility issues when upgrading to TLS 1.3.
      • The signature_algorithms_cert extension requires that pre-defined signature algorithms are used for certificate authentication. In practice, however, an application may use non-supported signature algorithms.
      • The DSA signature algorithm is not supported in TLS 1.3. If a server is configured to only use DSA certificates, it cannot upgrade to TLS 1.3.
      • The supported cipher suites for TLS 1.3 are not the same as TLS 1.2 and prior versions. If an application hard-codes cipher suites which are no longer supported, it may not be able to use TLS 1.3 without modifying the application code.
      • The TLS 1.3 session resumption and key update behaviors are different from TLS 1.2 and prior versions. The compatibility should be minimal, but it could be a risk if an application depends on the handshake details of the TLS protocols.

      The compatibility risk should be low. If there is a need, TLSv1.3 can be disabled explicitly. See the "Customizing JSSE" section in the "Java Secure Socket Extension (JSSE) Reference Guide" documentation.

      Attachments

        Issue Links

          Activity

            People

              xuelei Xuelei Fan
              xuelei Xuelei Fan
              Sean Mullan
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: