JDK-8243678 : SSLSession.invalidate() should not be implicitly required
  • Type: CSR
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Priority: P3
  • Status: Closed
  • Resolution: Withdrawn
  • Fix Versions: 16
  • Submitted: 2020-04-27
  • Updated: 2020-11-30
  • Resolved: 2020-11-30
Related Reports
CSR :  
Description
Summary
-------

The specifications for TLS 1.3 (RFC 8446)([1]) and Stateless Resumption for TLS 1.2 (RFC 5077)([2]) does not define session invalidation.  Additionally, RFC 5077 provides research that it is unnecessary.  This change is to clarify that session invalidation method in the Java API, in javax.net.ssl.SSLSession.invalidate(), may not be supported in some circumstances.


Problem
-------

Session resumption is used to open additional connections from a previously established TLS connection.  Resumption passes less network data using the previously established TLS security parameters.  Invalidation is used to prevent a session from resuming because of an error or by the application's choice.  Invalidation is easy for a server-based session cache because the entry can be quickly removed when invalidate() is called.
After TLS 1.2, RFC 5077([2]) defines Stateless Resumption in TLS 1.2.  This allowed for the server to securely store session cache information on the client.  It also points to a research paper about how invalidation is not necessary.  With TLS 1.3(1), there is no mention of invalidation.

The API description for SSLSession.invalidate() describes how invalidation works.  However, by not saying that a TLS implementation may not support invalidation, it is implicitly requiring it.

Solution
--------

Given the RFCs do not require invalidation in recent specifications, the solution is to change the SSLSession.invalidate() javadoc to say that invalidation may not be supported in some circumstances.

When implementing a stateless invalidation for JSSE, it was found to be problematic. A scheme was developed to use an identifier in the stateless session information and the server would store that identifier when invalidated.  However, depending how the application uses invalidation, it would be possible for the server to run out of memory or allow for a DoS.  These problems and the lack of an invalidation requirement in the RFCs caused us to abandon this solution and change the specification.


Specification
-------------
     /**
      * Invalidates the session.
      * <P>
    - * Future connections will not be able to
    - * resume or join this session.  However, any existing connection
    - * using this session can continue to use the session until the
    + * Future connections will not be able to resume or join this session,
    + * if the underlying TLS implementation supports invalidation,
    + * Existing connection using this session can continue to until the
      * connection is closed.
      *
    + * If invalidation is not supported, this method will do nothing.
    + * A session can be identified as invalidated by the implementation
    + * if {@link #isValid()} returns false.
    + *
    + * @apiNote 
    + * This optional behavior could occur with server
    + * implementations of Stateless Resumption (RFC 5077) or
    + * TLS 1.3 (RFC 8446) which may not store cached session information.
      *
      * @see #isValid()
      */

[1]: https://tools.ietf.org/html/rfc8446
[2]: https://tools.ietf.org/html/rfc5077#section-5.1
Comments
I merged much of the details into the description, but left an apiNote about the RFCs that could cause an unsupported behavior. It was my feeling that RFC details shouldn���t be in the main body of the description. I realize opinions may differ.
23-06-2020

Looking at this request again, I think the addendum needs to be upgraded from an informative apiNote to normative specification text. In particular, I think some explicit mention should be made of "this method might do nothing; the isValid method might not return false, etc." Moving back to Provisional.
18-06-2020

With regard to invalidate(), nothing will happen. As you mention, the API throws no exception and has no return value. So unfortunately there is no way to communicate a result directly. The way to determined a session's validity was is using inValid(), which is already mentioned in the method description. This returns true or false if the session is valid or not. So in a stateless situation, inValid() will always return true. A release note was planned.
18-06-2020

Moving to Provisional, not Finalized. What happens exactly when invalidate is called and not supported? Noting (the method is a no-op), an exception is thrown, something else? Should this change be documented in a release note?
18-06-2020