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

com.sun.net.httpserver.HttpsParameters and SSLStreams incorrectly handle needClientAuth and wantClientAuth

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P4 P4
    • 23
    • core-libs
    • None
    • behavioral
    • low
    • Hide
      The change fixes the current implementation in setWantClientAuth() and setNeedClientAuth() to match the javadoc of those methods. The chances of applications relying on a buggy implementation that contradicts the javadoc are low.
      The deprecation of some other methods in this change is merely formalizing an already existing instruction on the HttpsParameters class directing the applications to use setSSLParameters() method.
      Show
      The change fixes the current implementation in setWantClientAuth() and setNeedClientAuth() to match the javadoc of those methods. The chances of applications relying on a buggy implementation that contradicts the javadoc are low. The deprecation of some other methods in this change is merely formalizing an already existing instruction on the HttpsParameters class directing the applications to use setSSLParameters() method.
    • Java API
    • JDK

      Summary

      Deprecate configuring individual SSL parameters through the methods on com.sun.net.httpserver.HttpsParameters class.

      Problem

      The com.sun.net.httpserver.HttpsServer class in the JDK provides support for implementing a HTTPS server. The HttpsServer for its communication uses Transport Layer Security (TLS). Certain aspects of TLS, like whether or not the server requires the client to present a certificate during TLS handshake, are allowed to be configured by the application that uses the HttpsServer. The HttpsServer allows the application to set an instance of com.sun.net.httpserver.HttpsConfigurator on the HttpsServer instance. Whenever the HttpsServer is establishing a connection, the HttpsServer invokes the configure(HttpsParameters params) method on the application configured HttpsConfigurator, passing it a new instance of HttpsParameters. The HttpsParameters exposes the following TLS configuration methods:

          public abstract void setSSLParameters(SSLParameters params)
          public String[] getCipherSuites()
      public void setCipherSuites(String[] cipherSuites) public String[] getProtocols()
      public void setProtocols(String[] protocols) public boolean getWantClientAuth() public void setWantClientAuth(boolean wantClientAuth) public boolean getNeedClientAuth() public void setNeedClientAuth(boolean needClientAuth)

      Except for the void setSSLParameters(SSLParameters params) method, rest all methods were introduced through https://bugs.openjdk.org/browse/JDK-6398764 to allow for the HttpsServer to be used in Java versions where javax.net.ssl.SSLParameters class wasn't available as a Java API. In fact, the class level javadoc of HttpsParameters already states:

       * <p> The underlying SSL parameters may be established either via the set/get
       * methods of this class, or else via a {@link javax.net.ssl.SSLParameters}
       * object. {@code SSLParameters} is the preferred method, because in the future,
       * additional configuration capabilities may be added to that class, and it is
       * easier to determine the set of supported parameters and their default values
       * with SSLParameters. Also, if an {@code SSLParameters} object is provided via
       * {@link #setSSLParameters(SSLParameters)} then those parameter settings are
       * used, and any settings made in this object are ignored.
      

      It has recently been discovered that the implementation of the setWantClientAuth(boolean wantClientAuth) and setNeedClientAuth(boolean needClientAuth), is buggy and it doesn't match their method javadocs.

      The setWantClientAuth(boolean wantClientAuth) method states that other than setting the "wantClientAuth" flag, it will also clear the other "needClientAuth" flag:

      Calling this method clears the {@code needClientAuth} flag.

      However, the implementation has a bug and it doesn't clear the "needClientAuth" flag.

      Similarly, the setNeedClientAuth(boolean needClientAuth) method states that other than setting the "needClientAuth" flag, it will also clear the other "wantClientAuth" flag:

      Calling this method clears the {@code wantClientAuth} flag.

      The implementation of this method too has a bug and it doesn't clear the "wantClientAuth" flag.

      Furthermore, the usage of these methods within an internal implementation class sun.net.httpserver.SSLStreams of the HttpsServer too is buggy. The SSLStreams class copies over these "needClientAuth" and "wantClientAuth" flags from the HttpsParameters to the javax.net.ssl.SSLParameters instance. The SSLParameters class exposes a setWantClientAuth(boolean) and setNeedClientAuth(boolean) methods. These methods on SSLParameters class set the "wantClientAuth" and "needClientAuth" flags and clear the other flag, respectively. Thus when copying over these values to the SSLParameters, it is necessary that SSLStreams should first check if the flag it is copying over is set to true and only then call the respective method. However, SSLStreams has a bug and it does unconditional calls to SSLParameters.setWantClientAuth() and SSLParameters.setNeedClientAuth() to copy over the flags from the HttpsParameters.

      Solution

      The usages and the implementation of setWantClientAuth() and setNeedClientAuth() methods will be fixed to match the expectations set by the method javadocs. Additionally, the following methods on the HttpsParameters class will be deprecated:

          public String[] getCipherSuites()
      public void setCipherSuites(String[] cipherSuites) public String[] getProtocols()
      public void setProtocols(String[] protocols) public boolean getWantClientAuth() public void setWantClientAuth(boolean wantClientAuth) public boolean getNeedClientAuth() public void setNeedClientAuth(boolean needClientAuth)

      Applications that want to configure TLS parameters on the HttpsServer will be expected to call the, already present, setSSLParameters(SSLParameters params) on the HttpsParameters class.

      Specification

      diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpsParameters.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpsParameters.java
      index 5943b70615c..3a0a3d76680 100644
      --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpsParameters.java
      +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpsParameters.java
      @@ -1,5 +1,5 @@
       /*
      - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
      + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
        * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
        *
        * This code is free software; you can redistribute it and/or modify it
      @@ -90,9 +90,13 @@ protected HttpsParameters() {}
            * Returns a copy of the array of ciphersuites or {@code null} if none
            * have been set.
            *
      +     * @deprecated It is recommended that the SSL parameters be configured and
      +     * read through the use of {@link #setSSLParameters(SSLParameters) SSLParameters}.
      +     *
            * @return a copy of the array of ciphersuites or {@code null} if none have
            * been set
            */
      +    @Deprecated(since = "23")
           public String[] getCipherSuites() {
               return cipherSuites != null ? cipherSuites.clone() : null;
           }
      @@ -100,8 +104,13 @@ public String[] getCipherSuites() {
      /**
      • Sets the array of ciphersuites.
        *
        + * @deprecated It is recommended that the SSL parameters be configured and
        + * read through the use of {@link #setSSLParameters(SSLParameters) SSLParameters} . Use
        + * {@link SSLParameters#setCipherSuites(String[]
      )} instead. + * * @param cipherSuites the array of ciphersuites (or {@code null}) */ + @Deprecated(since = "23") public void setCipherSuites(String[] cipherSuites) { this.cipherSuites = cipherSuites != null ? cipherSuites.clone() : null; } @@ -110,9 +119,13 @@ public void setCipherSuites(String[] cipherSuites) {
      • Returns a copy of the array of protocols or {@code null} if none have been
        * set.
        *
        + * @deprecated It is recommended that the SSL parameters be configured and
        + * read through the use of {@link #setSSLParameters(SSLParameters) SSLParameters}.
        + *
        * @return a copy of the array of protocols or {@code null} if none have been
      • set
        */
        + @Deprecated(since = "23")
        public String[]
      getProtocols() { return protocols != null ? protocols.clone() : null; } @@ -120,8 +133,13 @@ public String[] getProtocols() {
      /**
      • Sets the array of protocols.
        *
        + * @deprecated It is recommended that the SSL parameters be configured and
        + * read through the use of {@link #setSSLParameters(SSLParameters) SSLParameters} . Use
        + * {@link SSLParameters#setProtocols(String[]
      )} instead. + * * @param protocols the array of protocols (or {@code null}) */ + @Deprecated(since = "23") public void setProtocols(String[] protocols) { this.protocols = protocols != null ? protocols.clone() : null; } @@ -129,8 +147,12 @@ public void setProtocols(String[] protocols) { /** * Returns whether client authentication should be requested. * + * @deprecated It is recommended that the SSL parameters be configured and + * read through the use of {@link #setSSLParameters(SSLParameters) SSLParameters}. + * * @return whether client authentication should be requested */ + @Deprecated(since = "23") public boolean getWantClientAuth() { return wantClientAuth; } @@ -139,17 +161,27 @@ public boolean getWantClientAuth() { * Sets whether client authentication should be requested. Calling this * method clears the {@code needClientAuth} flag. * + * @deprecated It is recommended that the SSL parameters be configured and + * read through the use of {@link #setSSLParameters(SSLParameters) SSLParameters}. Use + * {@link SSLParameters#setWantClientAuth(boolean)} instead. + * * @param wantClientAuth whether client authentication should be requested */ + @Deprecated(since = "23") public void setWantClientAuth(boolean wantClientAuth) { /** * Returns whether client authentication should be required. * + * @deprecated It is recommended that the SSL parameters be configured and + * read through the use of {@link #setSSLParameters(SSLParameters) SSLParameters}. + * * @return whether client authentication should be required */ + @Deprecated(since = "23") public boolean getNeedClientAuth() { return needClientAuth; } @@ -158,9 +190,15 @@ public boolean getNeedClientAuth() { * Sets whether client authentication should be required. Calling this method * clears the {@code wantClientAuth} flag. * + * @deprecated It is recommended that the SSL parameters be configured and + * read through the use of {@link #setSSLParameters(SSLParameters) SSLParameters}. Use + * {@link SSLParameters#setNeedClientAuth(boolean)} instead. + * * @param needClientAuth whether client authentication should be required */ + @Deprecated(since = "23") public void setNeedClientAuth(boolean needClientAuth) {

            jpai Jaikiran Pai
            jpai Jaikiran Pai
            Daniel Fuchs
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: