mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 14:54:52 +02:00
8172366: Support SHA-3 based signatures
Enhance default JDK providers including SUN, SunRsaSign, and SunEC, with signatures using SHA-3 family of digests. Reviewed-by: xuelei
This commit is contained in:
parent
46598c8644
commit
40206822f4
20 changed files with 673 additions and 95 deletions
|
@ -45,8 +45,8 @@ import sun.security.jca.JCAUtil;
|
|||
* PKCS#1 v2.2 RSASSA-PSS signatures with various message digest algorithms.
|
||||
* RSASSA-PSS implementation takes the message digest algorithm, MGF algorithm,
|
||||
* and salt length values through the required signature PSS parameters.
|
||||
* We support SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, and
|
||||
* SHA-512/256 message digest algorithms and MGF1 mask generation function.
|
||||
* We support SHA-1, SHA-2 family and SHA3 family of message digest algorithms,
|
||||
* and MGF1 mask generation function.
|
||||
*
|
||||
* @since 11
|
||||
*/
|
||||
|
@ -81,24 +81,20 @@ public class RSAPSSSignature extends SignatureSpi {
|
|||
|
||||
private static final byte[] EIGHT_BYTES_OF_ZEROS = new byte[8];
|
||||
|
||||
private static final Hashtable<String, Integer> DIGEST_LENGTHS =
|
||||
new Hashtable<String, Integer>();
|
||||
private static final Hashtable<KnownOIDs, Integer> DIGEST_LENGTHS =
|
||||
new Hashtable<KnownOIDs, Integer>();
|
||||
static {
|
||||
DIGEST_LENGTHS.put("SHA-1", 20);
|
||||
DIGEST_LENGTHS.put("SHA", 20);
|
||||
DIGEST_LENGTHS.put("SHA1", 20);
|
||||
DIGEST_LENGTHS.put("SHA-224", 28);
|
||||
DIGEST_LENGTHS.put("SHA224", 28);
|
||||
DIGEST_LENGTHS.put("SHA-256", 32);
|
||||
DIGEST_LENGTHS.put("SHA256", 32);
|
||||
DIGEST_LENGTHS.put("SHA-384", 48);
|
||||
DIGEST_LENGTHS.put("SHA384", 48);
|
||||
DIGEST_LENGTHS.put("SHA-512", 64);
|
||||
DIGEST_LENGTHS.put("SHA512", 64);
|
||||
DIGEST_LENGTHS.put("SHA-512/224", 28);
|
||||
DIGEST_LENGTHS.put("SHA512/224", 28);
|
||||
DIGEST_LENGTHS.put("SHA-512/256", 32);
|
||||
DIGEST_LENGTHS.put("SHA512/256", 32);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA_1, 20);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA_224, 28);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA_256, 32);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA_384, 48);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA_512, 64);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA_512$224, 28);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA_512$256, 32);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA3_224, 28);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA3_256, 32);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA3_384, 48);
|
||||
DIGEST_LENGTHS.put(KnownOIDs.SHA3_512, 64);
|
||||
}
|
||||
|
||||
// message digest implementation we use for hashing the data
|
||||
|
@ -210,27 +206,33 @@ public class RSAPSSSignature extends SignatureSpi {
|
|||
* internal signature parameters.
|
||||
*/
|
||||
private RSAKey isValid(RSAKey rsaKey) throws InvalidKeyException {
|
||||
try {
|
||||
AlgorithmParameterSpec keyParams = rsaKey.getParams();
|
||||
// validate key parameters
|
||||
if (!isCompatible(rsaKey.getParams(), this.sigParams)) {
|
||||
throw new InvalidKeyException
|
||||
("Key contains incompatible PSS parameter values");
|
||||
}
|
||||
// validate key length
|
||||
if (this.sigParams != null) {
|
||||
Integer hLen =
|
||||
DIGEST_LENGTHS.get(this.sigParams.getDigestAlgorithm());
|
||||
if (hLen == null) {
|
||||
throw new ProviderException("Unsupported digest algo: " +
|
||||
this.sigParams.getDigestAlgorithm());
|
||||
}
|
||||
checkKeyLength(rsaKey, hLen, this.sigParams.getSaltLength());
|
||||
}
|
||||
return rsaKey;
|
||||
} catch (SignatureException e) {
|
||||
throw new InvalidKeyException(e);
|
||||
AlgorithmParameterSpec keyParams = rsaKey.getParams();
|
||||
// validate key parameters
|
||||
if (!isCompatible(rsaKey.getParams(), this.sigParams)) {
|
||||
throw new InvalidKeyException
|
||||
("Key contains incompatible PSS parameter values");
|
||||
}
|
||||
// validate key length
|
||||
if (this.sigParams != null) {
|
||||
String digestAlgo = this.sigParams.getDigestAlgorithm();
|
||||
KnownOIDs ko = KnownOIDs.findMatch(digestAlgo);
|
||||
if (ko != null) {
|
||||
Integer hLen = DIGEST_LENGTHS.get(ko);
|
||||
if (hLen != null) {
|
||||
checkKeyLength(rsaKey, hLen,
|
||||
this.sigParams.getSaltLength());
|
||||
} else {
|
||||
// should never happen; checked in validateSigParams()
|
||||
throw new ProviderException
|
||||
("Unsupported digest algo: " + digestAlgo);
|
||||
}
|
||||
} else {
|
||||
// should never happen; checked in validateSigParams()
|
||||
throw new ProviderException
|
||||
("Unrecognized digest algo: " + digestAlgo);
|
||||
}
|
||||
}
|
||||
return rsaKey;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,14 +270,26 @@ public class RSAPSSSignature extends SignatureSpi {
|
|||
("Only supports TrailerFieldBC(1)");
|
||||
|
||||
}
|
||||
String digestAlgo = params.getDigestAlgorithm();
|
||||
|
||||
// check key length again
|
||||
if (key != null) {
|
||||
try {
|
||||
int hLen = DIGEST_LENGTHS.get(digestAlgo);
|
||||
checkKeyLength(key, hLen, params.getSaltLength());
|
||||
} catch (SignatureException e) {
|
||||
throw new InvalidAlgorithmParameterException(e);
|
||||
String digestAlgo = params.getDigestAlgorithm();
|
||||
KnownOIDs ko = KnownOIDs.findMatch(digestAlgo);
|
||||
if (ko != null) {
|
||||
Integer hLen = DIGEST_LENGTHS.get(ko);
|
||||
if (hLen != null) {
|
||||
try {
|
||||
checkKeyLength(key, hLen, params.getSaltLength());
|
||||
} catch (InvalidKeyException e) {
|
||||
throw new InvalidAlgorithmParameterException(e);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unsupported digest algo: " + digestAlgo);
|
||||
}
|
||||
} else {
|
||||
throw new InvalidAlgorithmParameterException
|
||||
("Unrecognized digest algo: " + digestAlgo);
|
||||
}
|
||||
}
|
||||
return params;
|
||||
|
@ -302,12 +316,12 @@ public class RSAPSSSignature extends SignatureSpi {
|
|||
* salt length
|
||||
*/
|
||||
private static void checkKeyLength(RSAKey key, int digestLen,
|
||||
int saltLen) throws SignatureException {
|
||||
int saltLen) throws InvalidKeyException {
|
||||
if (key != null) {
|
||||
int keyLength = (getKeyLengthInBits(key) + 7) >> 3;
|
||||
int minLength = Math.addExact(Math.addExact(digestLen, saltLen), 2);
|
||||
if (keyLength < minLength) {
|
||||
throw new SignatureException
|
||||
throw new InvalidKeyException
|
||||
("Key is too short, need min " + minLength + " bytes");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue