diff --git a/src/java.base/share/classes/sun/security/pkcs/NamedPKCS8Key.java b/src/java.base/share/classes/sun/security/pkcs/NamedPKCS8Key.java index b002792ab1aa2..bd11fce37d139 100644 --- a/src/java.base/share/classes/sun/security/pkcs/NamedPKCS8Key.java +++ b/src/java.base/share/classes/sun/security/pkcs/NamedPKCS8Key.java @@ -40,6 +40,11 @@ import java.security.spec.NamedParameterSpec; import java.util.Arrays; +/// Modeling private keys generated by a [sun.security.provider.NamedKeyPairGenerator] +/// or [sun.security.provider.NamedKeyFactory]. Its [#getParams()] method always +/// returns its name as a [NamedParameterSpec] object. +/// +/// @see sun.security.provider.NamedKeyPairGenerator public final class NamedPKCS8Key extends PKCS8Key { @Serial private static final long serialVersionUID = 1L; diff --git a/src/java.base/share/classes/sun/security/provider/NamedKEM.java b/src/java.base/share/classes/sun/security/provider/NamedKEM.java index c3b9e27dd892a..1d02d385376c4 100644 --- a/src/java.base/share/classes/sun/security/provider/NamedKEM.java +++ b/src/java.base/share/classes/sun/security/provider/NamedKEM.java @@ -44,9 +44,9 @@ import java.util.Arrays; import java.util.Objects; -/// An implementation extends this class to create its own `KEM`. -/// -/// @see NamedKeyPairGenerator +/// A base class for all `KEM` implementations that can be +/// configured with a named parameter set. See [NamedKeyPairGenerator] +/// for more details. public abstract class NamedKEM implements KEMSpi { private final String fname; // family name @@ -154,7 +154,7 @@ private static KeyConsumerImpl getKeyConsumerImpl(NamedKEM kem, /// @param sr SecureRandom object, `null` if not initialized /// @return the key encapsulation message and the shared key (in this order) /// @throws ProviderException if there is an internal error - public abstract byte[][] implEncapsulate(String name, byte[] pk, Object pk2, SecureRandom sr); + protected abstract byte[][] implEncapsulate(String name, byte[] pk, Object pk2, SecureRandom sr); /// User-defined decap function. /// @@ -165,7 +165,7 @@ private static KeyConsumerImpl getKeyConsumerImpl(NamedKEM kem, /// @return the shared key /// @throws ProviderException if there is an internal error /// @throws DecapsulateException if there is another error - public abstract byte[] implDecapsulate(String name, byte[] sk, Object sk2, byte[] encap) + protected abstract byte[] implDecapsulate(String name, byte[] sk, Object sk2, byte[] encap) throws DecapsulateException; /// User-defined function returning shared secret key length. @@ -173,14 +173,14 @@ public abstract byte[] implDecapsulate(String name, byte[] sk, Object sk2, byte[ /// @param name parameter name /// @return shared secret key length /// @throws ProviderException if there is an internal error - public abstract int implSecretSize(String name); + protected abstract int implSecretSize(String name); /// User-defined function returning key encapsulation message length. /// /// @param name parameter name /// @return key encapsulation message length /// @throws ProviderException if there is an internal error - public abstract int implEncapsulationSize(String name); + protected abstract int implEncapsulationSize(String name); /// User-defined function to validate a public key. /// @@ -195,7 +195,7 @@ public abstract byte[] implDecapsulate(String name, byte[] sk, Object sk2, byte[ /// @param pk public key in raw bytes /// @return a parsed key, `null` if none. /// @throws InvalidKeyException if the key is invalid - public Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyException { + protected Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyException { return null; } @@ -212,7 +212,7 @@ public Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyExcept /// @param sk public key in raw bytes /// @return a parsed key, `null` if none. /// @throws InvalidKeyException if the key is invalid - public Object implCheckPrivateKey(String name, byte[] sk) throws InvalidKeyException { + protected Object implCheckPrivateKey(String name, byte[] sk) throws InvalidKeyException { return null; } } diff --git a/src/java.base/share/classes/sun/security/provider/NamedKeyFactory.java b/src/java.base/share/classes/sun/security/provider/NamedKeyFactory.java index 42a3ea8020183..301f183be02ea 100644 --- a/src/java.base/share/classes/sun/security/provider/NamedKeyFactory.java +++ b/src/java.base/share/classes/sun/security/provider/NamedKeyFactory.java @@ -44,9 +44,11 @@ import java.util.Arrays; import java.util.Objects; -/// An implementation extends this class to create its own `KeyFactory`. +/// A base class for all `KeyFactory` implementations that can be +/// configured with a named parameter set. See [NamedKeyPairGenerator] +/// for more details. /// -/// Bonus: This factory supports reading and writing to RAW formats: +/// This factory supports reading and writing to RAW formats: /// /// 1. It reads from a RAW key using `translateKey` if `key.getFormat` is "RAW". /// 2. It writes to a RAW [EncodedKeySpec] if `getKeySpec(key, EncodedKeySpec.class)` @@ -56,8 +58,6 @@ /// /// When reading from a RAW format, it needs enough info to derive the /// parameter set name. -/// -/// @see NamedKeyPairGenerator public class NamedKeyFactory extends KeyFactorySpi { private final String fname; // family name @@ -240,7 +240,7 @@ protected Key engineTranslateKey(Key key) throws InvalidKeyException { var kAlg = key.getAlgorithm(); if (key instanceof AsymmetricKey pk) { String name; - // Three case that we can find the parameter set name from a RAW key: + // Three cases that we can find the parameter set name from a RAW key: // 1. getParams() returns one // 2. getAlgorithm() returns param set name (some provider does this) // 3. getAlgorithm() returns family name but this KF is for param set name diff --git a/src/java.base/share/classes/sun/security/provider/NamedKeyPairGenerator.java b/src/java.base/share/classes/sun/security/provider/NamedKeyPairGenerator.java index bc21f02daee57..11539d4f0e8df 100644 --- a/src/java.base/share/classes/sun/security/provider/NamedKeyPairGenerator.java +++ b/src/java.base/share/classes/sun/security/provider/NamedKeyPairGenerator.java @@ -38,17 +38,28 @@ import java.security.spec.NamedParameterSpec; import java.util.Objects; -/// An implementation extends this class to create its own `KeyPairGenerator`. +/// A base class for all `KeyPairGenerator` implementations that can be +/// configured with a named parameter set. /// -/// An implementation must include a zero-argument public constructor that calls -/// `super(fname, pnames)`, where `fname` is the family name of the algorithm and -/// `pnames` are the supported parameter set names. `pnames` must contain at least -/// one element and the first element is the default parameter set name, -/// i.e. the parameter set to be used in key pair generation unless +/// Together with [NamedKeyFactory], [NamedKEM], and [NamedSignature], these +/// classes form a compact framework designed to support any public key +/// algorithm standardized with named parameter sets. In this scenario, +/// the algorithm name is the "family name" and each standardized parameter +/// set has a "parameter set name". Implementations of these classes are able +/// to instantiate a `KeyPairGenerator`, `KeyFactory`, or `KEM` or `Signature` +/// object using either the family name or a parameter set name. All keys used +/// in this context will be of the type [NamedPKCS8Key] or [NamedX509Key], +/// with `getAlgorithm` returning the family name, and `getParams` returning +/// the parameter set name as a [NamedParameterSpec] object. +/// +/// An implementation must include a zero-argument public constructor that +/// calls `super(fname, pnames)`, where `fname` is the family name of the +/// algorithm and `pnames` are its supported parameter set names. `pnames` +/// must contain at least one element. For an implementation of +/// `NamedKeyPairGenerator`, the first element becomes its default parameter +/// set, i.e. the parameter set to be used in key pair generation unless /// [#initialize(AlgorithmParameterSpec, java.security.SecureRandom)] -/// is called to choose a specific parameter set. This requirement also applies -/// to implementations of [NamedKeyFactory], [NamedKEM], and [NamedSignature], -/// although there is no default parameter set concept for these classes. +/// is called on a different parameter set. /// /// An implementation must implement all abstract methods. For all these /// methods, the implementation must relinquish any "ownership" of any input @@ -57,19 +68,19 @@ /// content later. Similarly, the implementation must not modify any input /// array argument and must not retain any reference to an input array argument /// after the call. Together, this makes sure that the caller does not need to -/// make any defensive copy on the input and output arrays. This requirement -/// also applies to abstract methods defined in [NamedKEM] and [NamedSignature]. +/// make any defensive copy on the input and output arrays. /// /// Also, an implementation must not keep any extra copy of a private key. /// For key generation, the only copy is the one returned in the /// [#implGenerateKeyPair] call. For all other methods, it must not make -/// a copy of the input private key. A `KEM` implementation also must -/// not keep a copy of the shared secret key, no matter if it's an -/// encapsulator or a decapsulator. +/// a copy of the input private key. A `KEM` implementation also must not +/// keep a copy of the shared secret key, no matter if it's an encapsulator +/// or a decapsulator. Only the code that owns these sensitive data can +/// choose to perform cleanup when it determines they are no longer needed. /// /// The `NamedSignature` and `NamedKEM` classes provide `implCheckPublicKey` /// and `implCheckPrivateKey` methods that allow an implementation to validate -/// a key before using it. An implementation may return a parsed key of +/// a key before using it. An implementation may return a parsed key in /// a local type, and this parsed key will be passed to an operational method /// (For example, `implSign`) later. An implementation must not retain /// a reference of the parsed key. @@ -78,7 +89,7 @@ public abstract class NamedKeyPairGenerator extends KeyPairGeneratorSpi { private final String fname; // family name private final String[] pnames; // allowed parameter set name (at least one) - protected String name = null; // init as + protected String name; // init as private SecureRandom secureRandom; /// Creates a new `NamedKeyPairGenerator` object. @@ -114,14 +125,14 @@ public void initialize(AlgorithmParameterSpec params, SecureRandom random) throw new InvalidAlgorithmParameterException( "Unknown AlgorithmParameterSpec: " + params); } - this.secureRandom = random ; + this.secureRandom = random; } @Override public void initialize(int keysize, SecureRandom random) { if (keysize != -1) { - // Bonus: a chance to provide a SecureRandom without - // specifying a parameter set name + // User can call initialize(-1, sr) to provide a SecureRandom + // without touching the parameter set currently used throw new InvalidParameterException("keysize not supported"); } this.secureRandom = random; @@ -141,5 +152,5 @@ public KeyPair generateKeyPair() { /// @param sr `SecureRandom` object, `null` if not initialized /// @return public key and private key (in this order) in raw bytes /// @throws ProviderException if there is an internal error - public abstract byte[][] implGenerateKeyPair(String pname, SecureRandom sr); + protected abstract byte[][] implGenerateKeyPair(String pname, SecureRandom sr); } diff --git a/src/java.base/share/classes/sun/security/provider/NamedSignature.java b/src/java.base/share/classes/sun/security/provider/NamedSignature.java index 0f4a46e5cec8c..163b7e834f45a 100644 --- a/src/java.base/share/classes/sun/security/provider/NamedSignature.java +++ b/src/java.base/share/classes/sun/security/provider/NamedSignature.java @@ -42,11 +42,11 @@ import java.security.spec.AlgorithmParameterSpec; import java.util.Objects; -/// An implementation extends this class to create its own `Signature`. +/// A base class for all `Signature` implementations that can be +/// configured with a named parameter set. See [NamedKeyPairGenerator] +/// for more details. /// /// This class does not work with preHash signatures. -/// -/// @see NamedKeyPairGenerator public abstract class NamedSignature extends SignatureSpi { private final String fname; // family name @@ -166,7 +166,7 @@ protected AlgorithmParameters engineGetParameters() { /// @return the signature /// @throws ProviderException if there is an internal error /// @throws SignatureException if there is another error - public abstract byte[] implSign(String name, byte[] sk, Object sk2, + protected abstract byte[] implSign(String name, byte[] sk, Object sk2, byte[] msg, SecureRandom sr) throws SignatureException; /// User-defined verify function. @@ -179,7 +179,7 @@ public abstract byte[] implSign(String name, byte[] sk, Object sk2, /// @return true if verified /// @throws ProviderException if there is an internal error /// @throws SignatureException if there is another error - public abstract boolean implVerify(String name, byte[] pk, Object pk2, + protected abstract boolean implVerify(String name, byte[] pk, Object pk2, byte[] msg, byte[] sig) throws SignatureException; /// User-defined function to validate a public key. @@ -195,7 +195,7 @@ public abstract boolean implVerify(String name, byte[] pk, Object pk2, /// @param pk public key in raw bytes /// @return a parsed key, `null` if none. /// @throws InvalidKeyException if the key is invalid - public Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyException { + protected Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyException { return null; } @@ -212,7 +212,7 @@ public Object implCheckPublicKey(String name, byte[] pk) throws InvalidKeyExcept /// @param sk public key in raw bytes /// @return a parsed key, `null` if none. /// @throws InvalidKeyException if the key is invalid - public Object implCheckPrivateKey(String name, byte[] sk) throws InvalidKeyException { + protected Object implCheckPrivateKey(String name, byte[] sk) throws InvalidKeyException { return null; } } diff --git a/src/java.base/share/classes/sun/security/x509/NamedX509Key.java b/src/java.base/share/classes/sun/security/x509/NamedX509Key.java index 7817255b5421c..254ce4e2f0f1c 100644 --- a/src/java.base/share/classes/sun/security/x509/NamedX509Key.java +++ b/src/java.base/share/classes/sun/security/x509/NamedX509Key.java @@ -37,6 +37,11 @@ import java.security.ProviderException; import java.security.spec.NamedParameterSpec; +/// Modeling public keys generated by a [sun.security.provider.NamedKeyPairGenerator] +/// or [sun.security.provider.NamedKeyFactory]. Its [#getParams()] method always +/// returns its name as a [NamedParameterSpec] object. +/// +/// @see sun.security.provider.NamedKeyPairGenerator public final class NamedX509Key extends X509Key { @Serial private static final long serialVersionUID = 1L; @@ -64,11 +69,11 @@ public NamedX509Key(String fname, String pname, byte[] h) { public NamedX509Key(String fname, byte[] encoded) throws InvalidKeyException { this.fname = fname; decode(encoded); - paramSpec = new NamedParameterSpec(algid.getName()); + this.paramSpec = new NamedParameterSpec(algid.getName()); if (algid.encodedParams != null) { throw new InvalidKeyException("algorithm identifier has params"); } - h = getKey().toByteArray(); + this.h = getKey().toByteArray(); } @Override