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

Introduce AsymmetricKey interface with a getParams method

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 22
    • security-libs
    • None
    • source
    • low
    • Hide
      If an existing algorithm-specific interface already has this method but does not return an `AlgorithmParameterSpec` object there will be a conflict. In fact, inside JDK, `DSAKey`'s `getParams`() returns a `DSAParams` object which is not an `AlgorithmParameterSpec`. We've modified it to extend `AlgorithmParameterSpec` in this enhancement. This kind of key interfaces are usually defined inside JDK itself and not commonly in a third-party library or user application. For example, Bouncy Castle builds fine with no issue after this change.
      Show
      If an existing algorithm-specific interface already has this method but does not return an `AlgorithmParameterSpec` object there will be a conflict. In fact, inside JDK, `DSAKey`'s `getParams`() returns a `DSAParams` object which is not an `AlgorithmParameterSpec`. We've modified it to extend `AlgorithmParameterSpec` in this enhancement. This kind of key interfaces are usually defined inside JDK itself and not commonly in a third-party library or user application. For example, Bouncy Castle builds fine with no issue after this change.
    • Java API
    • SE

      Summary

      Introduce a new AsymmetricKey interface as the parent of existing PublicKey and PrivateKey interfaces with a getParams method inside.

      Problem

      Every existing algorithm-specific asymmetric key interface (Ex: RSAKey and ECKey) has a getParams() method that returns the parameters for a key. An application usually calls the method in this way:

      AlgorithmParameterSpec spec;
      if (key instanceof RSAKey rsaKey) {
          spec = rsaKey.getParams();
      } else if (key instanceof ECKey ecKey) {
          spec = ecKey.getParams();
      }  else if ....
      }  else {
          throw new Exception("Unknown key type");
      }

      This approach has several problems:

      1. The code is cumbersome, and the user would have to add a new else block whenever a new algorithm is introduced.

      2. We have to create a new algorithm-specific key interface whenever a new algorithm is introduced. Normally, we can backport a new algorithm but we are not allowed to backport a new interface. Thus there is no way to retrieve the parameters in an old release.

      Solution

      Created a new interface that is the parent of the PublicKey and PrivateKey interfaces.

      public interface AsymmetricKey extends Key {
          default AlgorithmParameterSpec getParams() {
              return null;
          }
      }

      In the future, whenever a new algorithm is introduced its public key and private key objects automatically inherit this method.

      For existing interfaces (e.g. ECKey) that already has this method, add a default implementation into its child interface (e.g. ECPublicKey and ECPrivateKey) to resolve the conflict where the compiler cannot determine which implementation to choose.

      Note that for the DSA algorithm, DSAKey::getParams returns DSAParams which is not a child of AlgorithmParameterSpec. Redefine this type to extend AlgorithmParameterSpec.

      Specification

      Created a new interface with a new method with a default implementation:

      package java.security;
      
      /**
       * An asymmetric key, which can be either a public key or a private key.
       * This interface contains methods that are common to either a public key or
       * a private key.
       *
       * @since 22
       */
      
      public interface AsymmetricKey extends Key {
          /**
           * Returns the parameters associated with this key.
           * The parameters are optional and may be either
           * explicitly specified or implicitly created during
           * key pair generation.
           *
           * @implSpec
           * The default implementation returns {@code null}.
           *
           * @return the associated parameters, may be {@code null}
           */
          default AlgorithmParameterSpec getParams() {
              return null;
          }
      }

      Add a getParams method to algorithm-specific child interfaces that return null as the default implementation, including DSAPrivateKey, RSAPublicKey, DHPrivateKey, DHPublicKey, RSAPrivateKey, RSAPublicKey, ECPrivateKey, ECPublicKey, EdEcPrivateKey, EdEcPublicKey, XECPrivateKey, and XECPublicKey. For an algorithm-specific interface whose getParams() method already returns a child type, return the same type in its child classes. For example:

       interface ECKey {
           ECParameterSpec getParams();
       }
      
       interface ECPrivateKey extends ECKey, PrivateKey {
      +    default ECParameterSpec getParams() {
      +        return null;
      +    }
       }
      
       interface ECPublicKey extends ECKey, PublicKey {
      +    default ECParameterSpec getParams() {
      +        return null;
      +    }
       }

      Update the DSAParams interface to be a child type of AlgorithmParameterSpec.

      -public interface DSAParams {
      +public interface DSAParams extends AlgorithmParameterSpec {

            weijun Weijun Wang
            weijun Weijun Wang
            Sean Mullan
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: