JDK-8241047 : Retire the deprecated SSLSession.getPeerCertificateChain() method
  • Type: CSR
  • Component: security-libs
  • Sub-Component: javax.net.ssl
  • Priority: P3
  • Status: Closed
  • Resolution: Approved
  • Fix Versions: 15
  • Submitted: 2020-03-16
  • Updated: 2020-03-19
  • Resolved: 2020-03-19
Related Reports
CSR :  
Description
Summary
-------
Degrade the terminally deprecated `javax.net.ssl.SSLSession::getPeerCertificateChain` and `javax.net.ssl.HandshakeCompletedEvent::getPeerCertificateChain` methods to throw `UnsupportedOperationException` by default. Drop the implementations from the SunJSSE provider and the related HTTP client code.

Problem
-------
The deprecated SSLSession.getPeerCertificateChain() method is using the deprecated javax.security.cert.X509Certificate. As it is an interface method, removing the javax.security.cert.X509Certificate package and this method would cause compatibility issues for old SSLSession implementations that are compiled and run across a range of JDK releases.

Solution
--------
We need to move forward to clear up deprecated APIs.   To reduce the compatibility, we will add a default implementation to the SSLSession.getPeerCertificateChain() method that throws an exception, and remove the current implementation.  This will reduce the source code compatibility risks.  We will plan to remove the deprecated package javax.security.cert in a few years, when the impact is minimal.

Specification
-------------
1. Change SSLSession.getPeerCertificateChain() to default method.

             /**
              * Returns the identity of the peer which was identified as part
              * of defining the session.
              * <P>
              * Note: This method can be used only when using certificate-based
              * cipher suites; using it with non-certificate-based cipher suites,
              * such as Kerberos, will throw an SSLPeerUnverifiedException.
              * <P>
              * Note: The returned value may not be a valid certificate chain
              * and should not be relied on for trust decisions.
              *
              * <p><em>Note: this method exists for compatibility with previous
              * releases. New applications should use
              * {@link #getPeerCertificates} instead.</em></p>
              *
        +     * @implSpec
        +     *     The default implementation throws UnsupportedOperationException.
        +     *
              * @return an ordered array of peer X.509 certificates,
              *          with the peer's own certificate first followed by any
              *          certificate authorities.  (The certificates are in
              *          the original JSSE certificate
              *          {@link javax.security.cert.X509Certificate} format.)
        -     * @exception SSLPeerUnverifiedException if the peer's identity
        -     *          has not been verified
        +     * @throws SSLPeerUnverifiedException if the peer's identity
        +     *         has not been verified.
        +     * @throws UnsupportedOperationException if the underlying provider
        +     *         does not implement the operation.
        +     *
              * @see #getPeerPrincipal()
              * @deprecated The {@link #getPeerCertificates()} method that returns an
              *               array of {@code java.security.cert.Certificate} should
              *               be used instead.
              */
             @SuppressWarnings("removal")
             @Deprecated(since="9", forRemoval=true)
        -    public javax.security.cert.X509Certificate [] getPeerCertificateChain()
        -            throws SSLPeerUnverifiedException;
        +    public default javax.security.cert.X509Certificate[]
        +            getPeerCertificateChain() throws SSLPeerUnverifiedException {
        +        throw new UnsupportedOperationException(
        +            "This method has retired, pleaase use the " +
        +            "getPeerCertificates() method instead.");
        +    }

2. Indicate the impact on HandshakeCompletedEvent

             /**
              * Returns the identity of the peer which was identified as part
              * of defining the session.
              * Note: This method can be used only when using certificate-based
              * cipher suites; using it with non-certificate-based cipher suites,
              * such as Kerberos, will throw an SSLPeerUnverifiedException.
              * <P>
              * Note: The returned value may not be a valid certificate chain
              * and should not be relied on for trust decisions.
              *
              * <p><em>Note: this method exists for compatibility with previous
              * releases. New applications should use
              * {@link #getPeerCertificates} instead.</em></p>          *
              * <p><em>Note: this method exists for compatibility with previous
              * releases. New applications should use
              * {@link #getPeerCertificates} instead.</em></p>
              *
              * @return an ordered array of peer X.509 certificates,
              *          with the peer's own certificate first followed by any
              *          certificate authorities.  (The certificates are in
              *          the original JSSE
              *          {@link javax.security.cert.X509Certificate} format).
        -     * @exception SSLPeerUnverifiedException if the peer is not verified.
        +     * @throws SSLPeerUnverifiedException if the peer is not verified.
        +     * @throws UnsupportedOperationException if the underlying provider
        +     *         does not implement the
        +     *         {@link SSLSession#getPeerCertificateChain} operation.
        +     * @see #getPeerPrincipal()
              * @see #getPeerPrincipal()
              * @deprecated The {@link #getPeerCertificates()} method that returns an
              *               array of {@code java.security.cert.Certificate} should
              *               be used instead.
              */
             @SuppressWarnings("removal")
             @Deprecated(since="9", forRemoval=true)
             public javax.security.cert.X509Certificate [] getPeerCertificateChain()
                     throws SSLPeerUnverifiedException {
                 return session.getPeerCertificateChain();
             }

3. Remove the current implementation
The current implementation in the SunJSSE provider and httpclient will be removed.  The call to SSLSession.getPeerCertificateChain() will throw UnsupportedOperationException in JDK.

Comments
Moving to Approved.
19-03-2020

I did a bit of tidy up the Summary section to make it a bit clearer and added myself as Reviewer. The approach taken is good as it gives a migration path for 3rd party SSLSession implementations. They can drop their override of the getPeerCertificateChain when they migrate to Java SE 15 or newer.
16-03-2020