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

TLS 1.3 Implementation

    XMLWordPrintable

Details

    • CSR
    • Resolution: Approved
    • P2
    • 8-pool
    • security-libs
    • None
    • behavioral
    • low
    • See discussion in Specification section
    • System or security property
    • SE

    Description

      Summary

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

      Problem

      TLSv1.3: TLS version 1.3 protocol (defined in RFC 8446)

      TLS 1.3 is a major overhaul of the TLS protocol and provides significant security and performance improvements over previous versions. TLS 1.3 introduced in Java SE 11 under JEP 332 (JDK-8145252).

      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, and TLS protocols. Currently, the JSSE API and JDK implementation supports SSL 3.0, TLS 1.0, TLS 1.1 and TLS 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.

      Solution

      This is a CSR request to introduce a minimal inter-operable and compatible TLS 1.3 implementation in the SunJSSE provider to an Oracle JDK 8 Update release. The enhancement is listed on the Oracle Java Crypto roadmap.

      OCSP Stapling added as part of this backport and CCC approved for JAVA SE 9, https://bugs.openjdk.java.net/browse/CCC-8046321

      A Java 8 Maintenance Release is currently being progressed to support this feature and the following CCCs are approved for that relesae (MR3)

      Specification

      1. New standard algorithm name for SSLContext protocols

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

      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:

      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" and "TLS"). If an application uses a version specified SSLContext ("SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2", "TLSv1.3"), 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 in server only

      In the default SSLContext("SSL" or "TLS"), TLS version 1.3 will be enabled in server side but not in client side. If there is a need, the default TLS versions, including TLSv1.3, could be customized. 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. A new System Property, "jdk.tls.acknowledgeCloseNotify", is added.

      The default value of the System Property is "false". If the System Property is set to "true", a corresponding close_notify alert will be sent when receiving a close_notify alert, and the connection will be duplex closed.

      TLS 1.2 and prior versions use a duplex-close policy, while TLS 1.3 uses a half-close policy. The inbound and the outbound close_notify alerts for TLS 1.3 are independent. When upgrading to TLS 1.3, unexpected behavior may occur if your application shuts down the TLS connection using only one of the SSLEngine.closeInbound() or SSLEngine.closeOutbound() APIs, but not both in each side of the connection. If your application exhibits unexpected hangs or timeouts when the underlying TLS transportation is not duplex closed, you may need to set this property to true.

      This property introduced in JAVA SE 11 and approved through https://bugs.openjdk.java.net/browse/JDK-8208526 CSR.

      11. 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 CCC for JCE components: http://ccc.us.oracle.com/8230978

      12. New System Properties added for OCSP stapling.

      The OCSP stapling solution is implemented mostly as an internal solution, and therefore is in the sun.security.ssl package. Some configurability will be exposed through jdk.tls.stapling properties as documented below. In many cases, the default OCSP stapling behavior will be adequate with no modifications. Reasonable defaults will be chosen for the properties to make this feature useful to as wide an audience as possible.

      The System properties and a brief description of their use and effects are described below:

      jdk.tls.client.enableStatusRequestExtension (default false) - Enables support for OCSP stapling in the client. This will cause the client to assert the status_request and status_request_v2 extensions in the Client Hello message.

      jdk.tls.server.enableStatusRequestExtension (default false) - Enables support for OCSP stapling in the server. This will cause the server to fetch OCSP responses for its server certificate chain and place the responses in a CertificateStatus message.

      jdk.tls.stapling.cacheLifetime = Server only, default 3600 seconds - This property alters the length of time that retrieved responses will be cached by the server before fetching new ones. The property accepts an integer value in the range 0 to Integer.MAX_VALUE, inclusive. A value of zero will cause the cache to hold entries only until their nextUpdate date has been passed. Those responses without a nextUpdate will not be cached if the cacheLifetime is zero. Negative values will be treated as zero. The default cacheLifetime will be used if non-numeric, overflowing or underflowing values are provided for this property.

      jdk.tls.stapling.cacheSize = Server only, default 256 entries - This setting controls the number of responses that will be cached by the server. New responses added to a full cache will cause existing responses to be flushed on a least-recently-used basis. The property accepts an integer value in the range 0 to Integer.MAX_VALUE, inclusive. A value of zero will remove the upper-bound on the number of cached objects. Negative values will be treated as zero. The default cacheSize will be used if non-numeric, overflowing or underflowing values are provided for this property.

      jdk.tls.stapling.responderURI = Server only, default None (blank) - Servers with a non-blank setting for this property will use the provided URI if no URI is found in its certificates through the Authority Info Access certificate extension. An invalid URI string provided by this property will result in the default behavior (no default URI).

      jdk.tls.stapling.responderOverride = Server only, default false - If this property is set to true the server will always used the value provided through the responderURI property, overriding URIs found in the Authority Info Access certificate extension. If responderURI has not been set, this property has no effect.

      jdk.tls.stapling.responseTimeout = Server only, default 5000 milliseconds - The amount of time the server handshaker will wait for OCSP responses before proceeding with the handshake. The property accepts an integer value in the range 0 to Long.MAX_VALUE, inclusive. A value of zero will effectively disable stapling, since the server is allowed no time to obtain responses. A negative, non-numeric or over/underflow value will cause JSSE to use the default setting.

      jdk.tls.stapling.ignoreExtensions = Server only, default false - This setting allows the server to not forward OCSP extensions provided in the status_request[_v2] TLS extension.

      These properties introduced in JAVA SE 9 and approved through https://bugs.openjdk.java.net/browse/CCC-8046321 CCC.

      13. 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.

      OCSP stapling request can be enabled on the client side by setting the system property jdk.tls.client.enableStatusRequestExtension to true (default is false); 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.

      14. 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

      15. 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.

      16. 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.

      17. Increase the priorities of GCM cipher suites

      Set GCM-based cipher suites as the most preferable cipher suites by default in SunJSSE provider. The following cipher suites will be move the head of default enabled cipher suite list:

      • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
      • TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
      • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
      • TLS_RSA_WITH_AES_256_GCM_SHA384
      • TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
      • TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
      • TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
      • TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
      • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
      • TLS_RSA_WITH_AES_128_GCM_SHA256
      • TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
      • TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
      • TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
      • TLS_DHE_DSS_WITH_AES_128_GCM_SHA256

      This update does not impact the API specification, other components or third party's providers. Here is the CSR aprroved for JAVA SE 9, https://bugs.openjdk.java.net/browse/CCC-8028518

      18. Define a new System Property jsse.enableFFDHE

      To disable the FFDHE mechanism For RFC 7919 compatible client, the predefined FFDHE parameter names are present in the "supported_groups" TLS extension. Some server may not be able to handle this extension or the FFDHE groups in the extension. If there is an interop issue, the new defined System Property, "jsse.enableFFDHE", can be used to dismiss the predefined FFDHE parameters for DHE cipher suites. Its approved in CSR, https://bugs.openjdk.java.net/browse/CCC-8140436

      19. A new system property, "jsse.enableMFLNExtension"

      In order to negotiate smaller maximum fragment lengths, clients MAY include an extension of type "max_fragment_length" in the (extended) client hello [RFC 6066].

      A new system property, "jsse.enableMFLNExtension", is defined to enable or disable the MFLN extension.   The value of the system property can be "true" (enable the MFLN extension) or "false" (disable the MFLN extension).  By default, JDK does not enable the MFLN extension.

      The maximum fragment length in MFLN extension should not count in the header size.  The record header size (header-size) is 5 bytes for SSL/TLS protocols.  Therefore, in theory, a minimal record size MUST be larger than the header-size.

      If the returned value of SSLParameters.getMaximumPacketSize() is less than (2^12 + header-size) and the System Property "jsse.enableMFLNExtension" is set to "true" explicitly, the maximum fragment length negotiation extension would be enabled.

      The map between the expected maximum network packet size and the desired maximum fragment size in MFLN extension can be summarized with the following table:

      ---------------------------------+--------------------------------------------
      the maximum network packet size  | the maximum fragment size in MFLN extension
      ---------------------------------+--------------------------------------------
       < 2^9 + header-size             | 2^9
      ---------------------------------+--------------------------------------------
       [2^9,  2^10] + header-size      | 2^10
      ---------------------------------+--------------------------------------------
       [2^10, 2^11] + header-size      | 2^11
      ---------------------------------+--------------------------------------------
       [2^11, 2^12] + header-size      | 2^12
      ---------------------------------+--------------------------------------------
       > 2^12 + header-size            | N/A (no MFLN extension)
      ---------------------------------+--------------------------------------------

      "jsse.enableMFLNExtension" is defined as an external public system property.  Other JSSE provider should also follow the specification if MFLN extension is supported. Needs to update the "JSSE Reference Guide" documentation accordingly.

      This property approved in JAVA SE 9 CSR, https://bugs.openjdk.java.net/browse/CCC-8043758

      20. 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.

      21. A system property com.sun.net.ssl.dhKeyExchangeFix removed

      Its an old property to fix 'DH ServerKeyExchange DSA signature encoding' bug. With refactored code, fix implemented without this property, hence its not required any more in latest code.

      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.
      • With new logger, "javax.net.debug=ssl" usage is significantly different, please refer https://bugs.openjdk.java.net/browse/JDK-8044609 for more information.

      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

              pkoppula Prasadarao Koppula
              xuelei Xuelei Fan
              Sean Coffey, Xuelei Fan
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: