JDK-8046321 : JEP 249: OCSP Stapling for TLS
  • Type: JEP
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Priority: P2
  • Status: Closed
  • Resolution: Delivered
  • Fix Versions: 9
  • Submitted: 2014-06-09
  • Updated: 2020-07-03
  • Resolved: 2016-10-28
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8062969 :  
JDK-8062988 :  
JDK-8063033 :  
JDK-8063034 :  
JDK-8063035 :  
JDK-8063042 :  
JDK-8076365 :  
JDK-8076366 :  

Implement OCSP stapling via the TLS Certificate Status Request extension
(section 8 of [RFC 6066][1]) and the Multiple Certificate Status Request
Extension ([RFC 6961][2]).

[1]: http://tools.ietf.org/html/rfc6066
[2]: http://tools.ietf.org/html/rfc6961

Success Metrics

The implementation, for both client and server modes, must interoperate
successfully with at least two third-party TLS implementations that
support OCSP stapling.


Checking the revocation status of an X.509 certificate is a critical part
of valid certificate-based authentication.  However, certificate status
checking using OCSP typically involves a network request for each
certificate being checked.  Because of the additional network requests,
enabling OCSP checking for TLS on the client side can have a significant
impact on performance.

OCSP stapling allows the presenter of a certificate, rather than the
issuing Certificate Authority (CA), to bear the resource cost of
providing OCSP responses.  In a TLS context, it is the responsibility of
the TLS server to request the OCSP response and send it to clients during
the SSL/TLS handshake.  This also allows the server to cache OCSP
responses and supply them to all clients that are connecting to it.  This
significantly reduces the load on the OCSP responder since the response
can be cached and periodically refreshed by the server rather than by
each client.

Currently, certificate revocation-status checking can be enabled on the
client side.  This classical approach, however, faces several challenges:

### Performance

If a client obtains the revocation status directly from the OCSP
responder then, for each client making a connection to a specific server,
the OCSP responder has to respond with a particular certificate status.
For a high-traffic web site, the OCSP responder is likely to be the
performance bottleneck.  Also, revocation-status checking involves
several round-trips.  There is a significant performance impact if OCSP
checking is enabled on the client side.

### Security

Adam Langley in [one of his blogs][3] talks about the security challenges
that client applications face with traditional OCSP.  He describes the
"soft-fail" behavior implemented by most browsers, a policy where a
failure to contact an OCSP responder does not result in a failed
revocation check.  This allows an attacker to cause the client to bypass
revocation checking, either by intercepting or blocking the OCSP request
from the client, or by mounting a denial-of-service attack against the
responder itself.

OCSP stapling by itself does not totally mitigate this challenge, but it
removes the need for OCSP checks between the client and the responder.
The server must still be able to obtain its own OCSP response and place
it in-band as part of the TLS handshake.

Currently in draft form in IETF is a proposal for a
["must-staple" certificate extension][4] which would require the
attachment of an OCSP response during the TLS handshake.  This would,
essentially, override any soft-fail behavior that may be employed by a
client.  This proposed extension is beyond the scope of this JEP, but if
this extension proceeds beyond a draft it could be a useful addition in
the future.

Finally, Java clients may not have the same needs for soft-fail defaults
that browsers do.  In some cases clients may prefer a hard-fail approach,
or opt to get user feedback through a dialog box in the event of a
failure to receive an OCSP response.  As examples, the default soft-fail
approach for both the Java Plugin and Java Web Start is to display a
warning dialog box when loading signed applets.

### Potential privacy impairment of OCSP requests

In normal OCSP scenarios, when a client sends an OCSP request, it exposes
both the server (via the server certificate entry) and itself (via the IP
address at least) to the OCSP responder, and hence can disclose client
behaviors.  OCSP stapling addresses this issue since the client is no
longer making the request to the OCSP responder.

### Limitations of the "captive portal" technique

The "captive portal" technique forces an HTTP client on a network to
download a special web page, usually for authentication purposes, before
using the network normally.  In such environments, clients are not able
to check the OCSP status of the SSL/TLS certificate since all network
access is blocked until authentication is successful.

### Summary

The above issues can be partially mitigated by using CRLs, or better
addressed via OCSP stapling.

In summary, OCSP stapling can help improve the performance of TLS by
reducing the performance bottleneck of the OCSP responder.  It can also
prevent the potential privacy impairment of the OCSP request, and avoid
the limitation of the "captive portal" technique.


This feature will be implemented in the `SunJSSE` provider
implementation.  Minor API changes are planned, with the goal to keep these changes as small as possible.  The implementation will choose reasonable defaults for OCSP specific parameters, and will provide configuration of these defaults via the following system properties:

 - `jdk.tls.client.enableStatusRequestExtension`: This property is true by default.  This enables the `status_request` and `status_request_v2` extensions, and enables processing for `CertificateStatus` messages sent by the server.
 - `jdk.tls.server.enableStatusRequestExtension`: This property is false by default.  This enables the server-side support for OCSP stapling.
 - `jdk.tls.stapling.responseTimeout`: This property controls the maximum amount of time the server will use to obtain OCSP responses, whether from the cache or by contacting an OCSP responder.  Those responses that have been received will be sent in a CertificateStatus message, if applicable based on the type of stapling being done.  This property takes an integer value in milliseconds, with a default value of 5000.
 - `jdk.tls.stapling.cacheSize`: This property controls the maximum cache size in entries.  The default value is 256 objects.  If the cache is full and a new response needs to be cached, the least-recently-used cache entry will be replaced with the new one.  A value of zero or less for this property means that the cache will have no upper bound on the number of responses it may contain.
 - `jdk.tls.stapling.cacheLifetime`: This property controls the maximum life of a cached response.  The value is specified in seconds, and has a default value of 3600 (1 hour).  It is possible for responses to have shorter lifetimes than the value set with this property if the response has a nextUpdate field that expires sooner than the cache lifetime.  A value of zero or less for this property disables the cache lifetime.  If an object has no nextUpdate and cache lifetimes have been disabled, then the response will not be cached.
 - `jdk.tls.stapling.responderURI`: This property allows the administrator to set a default URI in the event that certificates used for TLS do not have the Authority Info Access extension.  It will not override the AIA extension value unless the jdk.tls.stapling.responderOverride property is set (see below).  This property is not set by default.
 - `jdk.tls.stapling.responderOverride`: This property allows a URI provided through the jdk.tls.stapling.responderURI property to override any AIA extension value.  It is false by default.
 - `jdk.tls.stapling.ignoreExtensions`: This property disables the forwarding of OCSP extensions specified in the `status_request` or `status_request_v2` TLS extensions.  It is false by default.

Client and server-side Java implementations will be capable of supporting
the `status_request` and `status_request_v2` TLS hello extensions.  The
`status_request` extension is described in RFC 6066.  Supporting servers
would include a single OCSP response for the certificate used to identify
the server in a new TLS handshake message (`CertificateStatus`).  The
`status_request_v2` extension is described in RFC 6961.  The extension
allows the client to request the server to provide a single OCSP response
in the `CertificateStatus` message (similar to `status_request`) or
request that the server fetch an OCSP response for each certificate in
the list of certificates provided in the Certificate message (referenced
below as the `ocsp_multi` type).

### Client side

 - OCSP Stapling will be enabled by default and can be disabled by
   setting a system property.  This may be done
   through the `jdk.tls.client.enableStatusRequestExtension` property.

 - Clients will, by default, assert both the `status_request` and
   `status_request_v2` extensions in the `ClientHello` handshake message.
   For the `status_request_v2` extension, both `ocsp` and `ocsp_multi`
   types will be asserted.

 - Creation of the hello extensions will require the creation of new
   classes in `sun.security.ssl`, similar to how `ServerNameIndicator`,
   `RenegotiationInfoExtension`, and other extensions were implemented.

 - In order to employ the new extensions the `ClientHello` class will
   have additional methods defined that add these extensions.  These
   methods will be invoked from `ClientHandshaker.clientHello()`.

 - A new handshake message class in the `HandshakeMessage` class will
   need to be created to handle encoding and parsing of the
   `CertificateStatus` message.

 - A public API change is necessary in `ExtendedSSLSession` which allows
   callers to obtain the OCSP responses received during the handshake
   process.  The new method is:

       public List<byte[]> getStatusResponses();

### Server side

 - The server-side implementation will have OCSP stapling disabled by default, but may be
   enabled through the `jdk.tls.server.enableStatusRequestExtension` system property.
   Servers with OCSP stapling support disabled will ignore the `status_request` and
   `status_request_v2` extensions.

 - Server-side population of either `status_request` or
   `status_request_v2` information in the `ServerHello` message will
   depend upon how the client asserted these extensions.  In general the
   same request extension in the `ClientHello` will be returned in the
   `ServerHello`, with the following exceptions:

      - Servers receiving both `status_request` and `status_request_v2`
        extensions in the `ClientHello` will assert `status_request_v2`
        in the `ServerHello`.

      - Servers receiving `status_request_v2` extensions in the
        `ClientHello` with both `ocsp` and `ocsp_multi` types will assert
        `status_request_v2` in the `ServerHello` mesage and `ocsp_multi` in
        the `CertificateStatus` message.

      - In the case where `status_request_v2`/`ocsp_multi` is selected,
        different threads will be used to fetch each response.  This will be
        managed by a `StatusResponseManager` which will handle both fetching
        and caching of OCSP responses.

 - OCSP responses should be cached whenever possible.  Clients that do
   not specify nonces in their `status_request[_v2]` extension may
   receive a cached response.

    - Cached responses should not be used if current time is later than
      the `nextUpdate` field.

    - Cached responses with no `nextUpdate` field may be kept in the
      cache for a pre-determined lifetime (see Tunables below).

    - Servers receiving `status_requests` with the nonce extension must
      not return cached responses in the `CertificateStatus` message.

 - Server-side stapling support will be tunable via the system properties described

 - The `StatusResponseManager` is created as part of `SSLContext` instantiation.  The
   property values are sampled during `SSLContext` construction.  These property values
   can be changed and when a new `SSLContext` object is created, the StatusResponseManager
   will have those new values.

### Stapling and X509ExtendedTrustManagers

Developers have some flexibility in terms of how to handle the responses
provided through OCSP stapling.  This JEP makes no changes to the current
methodologies involved in certificate path checking and revocation
checking.  This means that it is possible to have both client and server
assert the `status_request` extensions, obtain OCSP responses through the
`CertificateStatus` message, and allow the user flexibility in how to
react to revocation information, or the lack thereof.

As with previous JDK releases, if no `PKIXBuilderParameters` is provided
by the caller, revocation checking is disabled.  If the caller creates a
`PKIXBuilderParameters` and uses the `setRevocationEnabled` method to
enable revocation checking, then stapling OCSP responses will be
evaluated.  This is also the case if the
`com.sun.net.ssl.checkRevocation` property is set to `true`.  The table
below shows a few different approaches as examples (assume OCSP stapling
is enabled both in the client and server):

      <th>checkRevocation Property</th>
      <td>Revocation checking is disabled</td>
      <td>Revocation checking enabled*, SOFT_FAIL set</td>
      <td>Revocation checking enabled*, SOFT_FAIL set</td>
      <td>instantiated, added to PKIXBuilderParameters</td>
      <td>Revocation checking enabled*, hard fail behavior.</td>

\* Client-side OCSP fallback will occur only if the ocsp.enable Security
property has been set to true

Further details about the configuration of the `PKIXBuilderParameters`
and `PKIXRevocationChecker` objects and their relationship to JSSE can be
found in both the *Java PKI API Programmer's Guide* and the *JSSE
Reference Guide*.


 1. The OCSP Stapling implementation must not break backward

 2. The client implementation must be able to send RFC 6066-style
    `status_request` `ClientHello` extensions to supporting servers.  It
    must be able to properly parse the same hello extension in the
    `ServerHello` handshake message, and properly parse the subsequent
    `CertificateStatus` handshake-message contents.

 3. The client implementation must be able to send RFC 6961-style
    `status_request_v2` `ClientHello` extensions to supporting servers.
    It must be able to assert `ocsp` or `ocsp_multi` types (or both) in
    the hello extension.  It must be able to properly parse the same
    hello extensions in the `ServerHello` handshake message, and properly
    parse the subsequent `CertificateStatus` handshake-message contents.

 4. The server implementation must be able to receive `status_request`
    and `status_request_v2` extensions in the `ClientHello` handshake
    message and query the appropriate OCSP responder.  It must be able to
    place OCSP responses in a `CertificateStatus` TLS handshake message
    to be returned to the client.

 5. The server implementation must be capable of caching valid OCSP
    responses for reuse with clients that do not make requests with nonce
    extensions in their `status_request[_v2]` hello extensions.

 6. The client must be able to interoperate with at least two different
    web servers capable of performing OCSP stapling (e.g. Apache 2.4+).

 7. The server must be able to interoperate with at least two different
    client implementations capable of asserting `status_request` or
    `status_request_v2`.  At this time, most major browsers (Firefox,
    Chrome, etc.) can generate the `status_request` hello extension, as
    can other tools such as OpenSSL's `s_client`.  For automated testing
    purposes, small applications could be created that link against NSS
    and OpenSSL libraries to establish TLS connections with OCSP

Risks and Assumptions

The OCSP stapling feature will be enabled by default for java clients in JDK with this
implementation.  However, there are potential interoperability issues
with TLS servers that cannot accept the `status_request` or
`status_request_v2` TLS extensions.  A system or security property has been
defined to disable OCSP stapling if necessary.

[3]: https://www.imperialviolet.org/2014/04/19/revchecking.html
[4]: https://tools.ietf.org/html/draft-hallambaker-tlsfeature-05

Moving out to new due date to allow for SQE test dev.

Changeset (for future reference): http://hg.openjdk.java.net/jdk9/dev/jdk/rev/250b2eae3121