8189441: Define algorithm names for keys derived from KeyAgreement

Reviewed-by: mullan
This commit is contained in:
Weijun Wang 2025-01-27 18:09:17 +00:00
parent 03106eb2d3
commit aba60a9274
10 changed files with 160 additions and 44 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2025, 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
@ -379,11 +379,10 @@ extends KeyAgreementSpi {
throw new NoSuchAlgorithmException("null algorithm");
}
if (!algorithm.equalsIgnoreCase("TlsPremasterSecret") &&
!AllowKDF.VALUE) {
throw new NoSuchAlgorithmException("Unsupported secret key "
+ "algorithm: " + algorithm);
if (!KeyUtil.isSupportedKeyAgreementOutputAlgorithm(algorithm) &&
!AllowKDF.VALUE) {
throw new NoSuchAlgorithmException(
"Unsupported secret key algorithm: " + algorithm);
}
byte[] secret = engineGenerateSecret();
@ -419,13 +418,17 @@ extends KeyAgreementSpi {
throw new InvalidKeyException("Key material is too short");
}
return skey;
} else if (algorithm.equals("TlsPremasterSecret")) {
// remove leading zero bytes per RFC 5246 Section 8.1.2
return new SecretKeySpec(
} else if (KeyUtil.isSupportedKeyAgreementOutputAlgorithm(algorithm)) {
if (algorithm.equalsIgnoreCase("TlsPremasterSecret")) {
// remove leading zero bytes per RFC 5246 Section 8.1.2
return new SecretKeySpec(
KeyUtil.trimZeroes(secret), "TlsPremasterSecret");
} else {
return new SecretKeySpec(secret, algorithm);
}
} else {
throw new NoSuchAlgorithmException("Unsupported secret key "
+ "algorithm: "+ algorithm);
throw new NoSuchAlgorithmException(
"Unsupported secret key algorithm: " + algorithm);
}
}
}

View file

@ -666,18 +666,30 @@ public class KeyAgreement {
* {@code generateSecret} to change the private information used in
* subsequent operations.
*
* @param algorithm the requested secret-key algorithm
* @param algorithm the requested secret key algorithm. This is different
* from the {@code KeyAgreement} algorithm provided to the
* {@code getInstance} method. See the SecretKey Algorithms section in the
* <a href="{@docRoot}/../specs/security/standard-names.html#secretkey-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard secret key algorithm names.
* Specify "Generic" if the output will be used as the input keying
* material of a key derivation function (KDF).
*
* @return the shared secret key
* @return the shared secret key. The length of the key material
* may be adjusted to be compatible with the specified algorithm,
* regardless of whether the key is extractable. If {@code algorithm}
* is specified as "Generic" and it is supported by the implementation,
* the full shared secret is returned.
*
* @exception IllegalStateException if this key agreement has not been
* initialized or if {@code doPhase} has not been called to supply the
* keys for all parties in the agreement
* @exception NoSuchAlgorithmException if the specified secret-key
* algorithm is not available
* @exception InvalidKeyException if the shared secret-key material cannot
* @exception NoSuchAlgorithmException if the specified secret key
* algorithm is not supported
* @exception InvalidKeyException if the shared secret key material cannot
* be used to generate a secret key of the specified algorithm (e.g.,
* the key material is too short)
* @spec security/standard-names.html Java Security Standard Algorithm Names
*/
public final SecretKey generateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1997, 2025, 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
@ -205,18 +205,30 @@ public abstract class KeyAgreementSpi {
* {@code generateSecret} to change the private information used in
* subsequent operations.
*
* @param algorithm the requested secret key algorithm
* @param algorithm the requested secret key algorithm. This is different
* from the {@code KeyAgreement} algorithm provided to the
* {@code getInstance} method. See the SecretKey Algorithms section in the
* <a href="{@docRoot}/../specs/security/standard-names.html#secretkey-algorithms">
* Java Security Standard Algorithm Names Specification</a>
* for information about standard secret key algorithm names.
* Specify "Generic" if the output will be used as the input keying
* material of a key derivation function (KDF).
*
* @return the shared secret key
* @return the shared secret key. The length of the key material
* may be adjusted to be compatible with the specified algorithm,
* regardless of whether the key is extractable. If {@code algorithm}
* is specified as "Generic" and it is supported by the implementation,
* the full shared secret is returned.
*
* @exception IllegalStateException if this key agreement has not been
* initialized or if {@code doPhase} has not been called to supply the
* keys for all parties in the agreement
* @exception NoSuchAlgorithmException if the requested secret key
* algorithm is not available
* @exception NoSuchAlgorithmException if the specified secret key
* algorithm is not supported
* @exception InvalidKeyException if the shared secret key material cannot
* be used to generate a secret key of the requested algorithm type (e.g.,
* the key material is too short)
* @spec security/standard-names.html Java Security Standard Algorithm Names
*/
protected abstract SecretKey engineGenerateSecret(String algorithm)
throws IllegalStateException, NoSuchAlgorithmException,

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2025, 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
@ -29,6 +29,7 @@ import sun.security.ec.point.Point;
import sun.security.util.ArrayUtil;
import sun.security.util.CurveDB;
import sun.security.util.ECUtil;
import sun.security.util.KeyUtil;
import sun.security.util.NamedCurve;
import sun.security.util.math.IntegerFieldModuloP;
import sun.security.util.math.IntegerMontgomeryFieldModuloP;
@ -254,11 +255,11 @@ public final class ECDHKeyAgreement extends KeyAgreementSpi {
if (algorithm == null) {
throw new NoSuchAlgorithmException("Algorithm must not be null");
}
if (!(algorithm.equals("TlsPremasterSecret"))) {
throw new NoSuchAlgorithmException
("Only supported for algorithm TlsPremasterSecret");
if (!KeyUtil.isSupportedKeyAgreementOutputAlgorithm(algorithm)) {
throw new NoSuchAlgorithmException(
"Unsupported secret key algorithm: " + algorithm);
}
return new SecretKeySpec(engineGenerateSecret(), "TlsPremasterSecret");
return new SecretKeySpec(engineGenerateSecret(), algorithm);
}
private static

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2025, 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
@ -25,6 +25,8 @@
package sun.security.ec;
import sun.security.util.KeyUtil;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@ -207,9 +209,9 @@ public class XDHKeyAgreement extends KeyAgreementSpi {
throw new NoSuchAlgorithmException("Algorithm must not be null");
}
if (!(algorithm.equals("TlsPremasterSecret"))) {
if (!KeyUtil.isSupportedKeyAgreementOutputAlgorithm(algorithm)) {
throw new NoSuchAlgorithmException(
"Only supported for algorithm TlsPremasterSecret");
"Unsupported secret key algorithm: " + algorithm);
}
return new SecretKeySpec(engineGenerateSecret(), algorithm);
}

View file

@ -424,5 +424,10 @@ public final class KeyUtil {
throw new NoSuchAlgorithmException("Cannot decode public key", e);
}
}
public static boolean isSupportedKeyAgreementOutputAlgorithm(String alg) {
return alg.equalsIgnoreCase("TlsPremasterSecret")
|| alg.equalsIgnoreCase("Generic");
}
}