8312428: PKCS11 tests fail with NSS 3.91

Backport-of: 1c598c2245c5c348e946f4d0df653daa6e42da94
This commit is contained in:
Goetz Lindenmaier 2024-01-23 08:40:47 +00:00
parent b186446511
commit b4f1deb597
4 changed files with 212 additions and 119 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2023, 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
@ -39,6 +39,8 @@ import java.util.Arrays;
import java.util.Random;
import java.util.List;
import jtreg.SkippedException;
public class TestCloning extends PKCS11Test {
public static void main(String[] args) throws Exception {
@ -57,15 +59,31 @@ public class TestCloning extends PKCS11Test {
r.nextBytes(data1);
r.nextBytes(data2);
System.out.println("Testing against provider " + p.getName());
boolean skipTest = true;
for (String alg : ALGS) {
System.out.println("Testing " + alg);
System.out.println("Digest algo: " + alg);
MessageDigest md = MessageDigest.getInstance(alg, p);
md = testCloning(md, p);
try {
md = testCloning(md, p);;
} catch (CloneNotSupportedException cnse) {
// skip test if clone isn't supported
System.out.println("=> Clone not supported; skip!");
continue;
}
// start testing below
skipTest = false;
// repeat the test again after generating digest once
for (int j = 0; j < 10; j++) {
md = testCloning(md, p);
}
}
if (skipTest) {
throw new SkippedException("Test Skipped!");
}
}
private static MessageDigest testCloning(MessageDigest mdObj, Provider p)
@ -125,4 +143,3 @@ public class TestCloning extends PKCS11Test {
}
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2023, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.Signature;
public class PSSUtil {
/**
* ALGORITHM name, fixed as RSA for PKCS11
*/
private static final String KEYALG = "RSA";
private static final String SIGALG = "RSASSA-PSS";
public static enum AlgoSupport {
NO, MAYBE, YES
};
public static boolean isSignatureSupported(Provider p) {
try {
Signature.getInstance(SIGALG, p);
return true;
} catch (NoSuchAlgorithmException e) {
System.out.println("Skip testing " + SIGALG +
" due to no support");
return false;
}
}
public static AlgoSupport isHashSupported(Provider p, String... hashAlgs) {
AlgoSupport status = AlgoSupport.YES;
for (String h : hashAlgs) {
String sigAlg = (h.startsWith("SHA3-") ?
h : h.replace("-", "")) + "with" + SIGALG;
try {
Signature.getInstance(sigAlg, p);
// Yes, proceed to check next hash algorithm
continue;
} catch (NoSuchAlgorithmException e) {
// continue trying other checks
}
try {
MessageDigest.getInstance(h, p);
status = AlgoSupport.MAYBE;
} catch (NoSuchAlgorithmException e) {
// if not supported as a standalone digest algo, chance of it
// being supported by PSS is very very low
return AlgoSupport.NO;
}
}
return status;
}
public static KeyPair generateKeys(Provider p, int size)
throws NoSuchAlgorithmException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEYALG, p);
kpg.initialize(size);
return kpg.generateKeyPair();
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2023, 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
@ -24,6 +24,8 @@ import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import jtreg.SkippedException;
/**
* @test
* @bug 8080462 8226651 8242332
@ -35,25 +37,19 @@ import java.security.spec.*;
*/
public class KeyAndParamCheckForPSS extends PKCS11Test {
/**
* ALGORITHM name, fixed as RSA for PKCS11
*/
private static final String KEYALG = "RSA";
private static final String SIGALG = "RSASSA-PSS";
public static void main(String[] args) throws Exception {
main(new KeyAndParamCheckForPSS(), args);
}
private static boolean skipTest = true;
@Override
public void main(Provider p) throws Exception {
Signature sig;
try {
sig = Signature.getInstance(SIGALG, p);
} catch (NoSuchAlgorithmException e) {
System.out.println("Skip testing RSASSA-PSS" +
" due to no support");
return;
if (!PSSUtil.isSignatureSupported(p)) {
throw new SkippedException("Skip due to no support for " +
SIGALG);
}
// NOTE: key length >= (digest length + 2) in bytes
@ -76,27 +72,26 @@ public class KeyAndParamCheckForPSS extends PKCS11Test {
runTest(p, 1040, "SHA3-512", "SHA3-256");
runTest(p, 1040, "SHA3-512", "SHA3-384");
runTest(p, 1040, "SHA3-512", "SHA3-512");
if (skipTest) {
throw new SkippedException("Test Skipped");
}
}
private void runTest(Provider p, int keySize, String hashAlg,
private static void runTest(Provider p, int keySize, String hashAlg,
String mgfHashAlg) throws Exception {
// skip further test if this provider does not support hashAlg or
// mgfHashAlg
try {
MessageDigest.getInstance(hashAlg, p);
MessageDigest.getInstance(mgfHashAlg, p);
} catch (NoSuchAlgorithmException nsae) {
System.out.println("No support for " + hashAlg + ", skip");
System.out.println("Testing " + hashAlg + " and MGF1" + mgfHashAlg);
PSSUtil.AlgoSupport s = PSSUtil.isHashSupported(p, hashAlg, mgfHashAlg);
if (s == PSSUtil.AlgoSupport.NO) {
System.out.println("=> Skip; no support");
return;
}
System.out.println("Testing [" + keySize + " " + hashAlg + "]");
Signature sig = Signature.getInstance(SIGALG, p);
// create a key pair with the supplied size
KeyPairGenerator kpg = KeyPairGenerator.getInstance(KEYALG, p);
kpg.initialize(keySize);
KeyPair kp = kpg.generateKeyPair();
KeyPair kp = PSSUtil.generateKeys(p, keySize);
int bigSaltLen = keySize/8 - 14;
AlgorithmParameterSpec paramsBad = new PSSParameterSpec(hashAlg,
@ -108,58 +103,71 @@ public class KeyAndParamCheckForPSS extends PKCS11Test {
PublicKey pub = kp.getPublic();
// test#1 - setParameter then initSign
Signature sig = Signature.getInstance("RSASSA-PSS", p);
sig.setParameter(paramsBad);
sig = Signature.getInstance(SIGALG, p);
try {
sig.setParameter(paramsGood);
sig.initSign(priv);
// algorithm support confirmed
skipTest = false;
} catch (Exception ex) {
if (s == PSSUtil.AlgoSupport.MAYBE) {
// confirmed to be unsupported; skip the rest of the test
System.out.println("=> Skip; no PSS support");
return;
} else {
throw new RuntimeException("Unexpected Exception", ex);
}
}
sig = Signature.getInstance(SIGALG, p);
try {
sig.setParameter(paramsBad);
sig.initSign(priv);
throw new RuntimeException("Expected IKE not thrown");
} catch (InvalidKeyException ike) {
System.out.println("test#1: got expected IKE");
// expected
}
sig.setParameter(paramsGood);
sig.initSign(priv);
System.out.println("test#1: pass");
// test#2 - setParameter then initVerify
sig = Signature.getInstance("RSASSA-PSS", p);
sig.setParameter(paramsBad);
sig = Signature.getInstance(SIGALG, p);
sig.setParameter(paramsGood);
sig.initVerify(pub);
sig = Signature.getInstance(SIGALG, p);
try {
sig.setParameter(paramsBad);
sig.initVerify(pub);
throw new RuntimeException("Expected IKE not thrown");
} catch (InvalidKeyException ike) {
System.out.println("test#2: got expected IKE");
// expected
}
sig.setParameter(paramsGood);
sig.initVerify(pub);
System.out.println("test#2: pass");
// test#3 - initSign, then setParameter
sig = Signature.getInstance("RSASSA-PSS", p);
sig = Signature.getInstance(SIGALG, p);
sig.initSign(priv);
sig.setParameter(paramsGood);
sig = Signature.getInstance(SIGALG, p);
try {
sig.initSign(priv);
sig.setParameter(paramsBad);
throw new RuntimeException("Expected IAPE not thrown");
} catch (InvalidAlgorithmParameterException iape) {
System.out.println("test#3: got expected IAPE");
// expected
}
sig.setParameter(paramsGood);
System.out.println("test#3: pass");
// test#4 - initVerify, then setParameter
sig = Signature.getInstance("RSASSA-PSS", p);
sig = Signature.getInstance(SIGALG, p);
sig.setParameter(paramsGood);
sig.initVerify(pub);
sig = Signature.getInstance(SIGALG, p);
try {
sig.initVerify(pub);
sig.setParameter(paramsBad);
throw new RuntimeException("Expected IAPE not thrown");
} catch (InvalidAlgorithmParameterException iape) {
System.out.println("test#4: got expected IAPE");
// expected
}
sig.setParameter(paramsGood);
System.out.println("test#4: pass");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2023, 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
@ -24,6 +24,7 @@ import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import java.util.stream.IntStream;
import jtreg.SkippedException;
/**
* @test
@ -35,8 +36,6 @@ import java.util.stream.IntStream;
*/
public class SignatureTestPSS extends PKCS11Test {
// PKCS11 does not support RSASSA-PSS keys yet
private static final String KEYALG = "RSA";
private static final String SIGALG = "RSASSA-PSS";
private static final int[] KEYSIZES = { 2048, 3072 };
@ -44,7 +43,7 @@ public class SignatureTestPSS extends PKCS11Test {
"SHA-224", "SHA-256", "SHA-384" , "SHA-512",
"SHA3-224", "SHA3-256", "SHA3-384" , "SHA3-512",
};
private Provider prov;
private static final byte[] DATA = generateData(100);
/**
* How much times signature updated.
@ -56,88 +55,72 @@ public class SignatureTestPSS extends PKCS11Test {
*/
private static final int UPDATE_TIMES_HUNDRED = 100;
private static boolean skipTest = true;
public static void main(String[] args) throws Exception {
main(new SignatureTestPSS(), args);
}
@Override
public void main(Provider p) throws Exception {
Signature sig;
try {
sig = Signature.getInstance(SIGALG, p);
} catch (NoSuchAlgorithmException e) {
System.out.println("Skip testing RSASSA-PSS" +
" due to no support");
return;
if (!PSSUtil.isSignatureSupported(p)) {
throw new SkippedException("Skip due to no support for " + SIGALG);
}
this.prov = p;
for (int i : KEYSIZES) {
runTest(i);
}
}
private void runTest(int keySize) throws Exception {
byte[] data = new byte[100];
IntStream.range(0, data.length).forEach(j -> {
data[j] = (byte) j;
});
System.out.println("[KEYSIZE = " + keySize + "]");
// create a key pair
KeyPair kpair = generateKeys(KEYALG, keySize);
test(DIGESTS, kpair.getPrivate(), kpair.getPublic(), data);
}
private void test(String[] digestAlgs, PrivateKey privKey,
PublicKey pubKey, byte[] data) throws RuntimeException {
// For signature algorithm, create and verify a signature
for (String hash : digestAlgs) {
for (String mgfHash : digestAlgs) {
try {
checkSignature(data, pubKey, privKey, hash, mgfHash);
} catch (NoSuchAlgorithmException | InvalidKeyException |
SignatureException | NoSuchProviderException ex) {
throw new RuntimeException(ex);
} catch (InvalidAlgorithmParameterException ex2) {
System.out.println("Skip test due to " + ex2);
for (int kSize : KEYSIZES) {
System.out.println("[KEYSIZE = " + kSize + "]");
KeyPair kp = PSSUtil.generateKeys(p, kSize);
PrivateKey privKey = kp.getPrivate();
PublicKey pubKey = kp.getPublic();
for (String hash : DIGESTS) {
for (String mgfHash : DIGESTS) {
System.out.println(" [Hash = " + hash +
", MGF1 Hash = " + mgfHash + "]");
PSSUtil.AlgoSupport s =
PSSUtil.isHashSupported(p, hash, mgfHash);
if (s == PSSUtil.AlgoSupport.NO) {
System.out.println(" => Skip; no support");
continue;
}
checkSignature(p, DATA, pubKey, privKey, hash, mgfHash, s);
}
}
};
};
}
// start testing below
if (skipTest) {
throw new SkippedException("Test Skipped");
}
}
private KeyPair generateKeys(String keyalg, int size)
throws NoSuchAlgorithmException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(keyalg, prov);
kpg.initialize(size);
return kpg.generateKeyPair();
}
private void checkSignature(byte[] data, PublicKey pub,
PrivateKey priv, String hash, String mgfHash)
private static void checkSignature(Provider p, byte[] data, PublicKey pub,
PrivateKey priv, String hash, String mgfHash, PSSUtil.AlgoSupport s)
throws NoSuchAlgorithmException, InvalidKeyException,
SignatureException, NoSuchProviderException,
InvalidAlgorithmParameterException {
String testName = hash + " and MGF1_" + mgfHash;
// only test RSASSA-PSS signature against the supplied hash/mgfHash
// if they are supported; otherwise PKCS11 library will throw
// CKR_MECHANISM_PARAM_INVALID at Signature.initXXX calls
try {
MessageDigest md = MessageDigest.getInstance(hash, prov);
if (!hash.equalsIgnoreCase(mgfHash)) {
md = MessageDigest.getInstance(mgfHash, prov);
}
} catch (NoSuchAlgorithmException nsae) {
System.out.println("Skip testing " + hash + "/" + mgfHash);
return;
}
System.out.println("Testing against " + testName);
Signature sig = Signature.getInstance(SIGALG, prov);
Signature sig = Signature.getInstance(SIGALG, p);
AlgorithmParameterSpec params = new PSSParameterSpec(
hash, "MGF1", new MGF1ParameterSpec(mgfHash), 0, 1);
sig.setParameter(params);
hash, "MGF1", new MGF1ParameterSpec(mgfHash), 0, 1);
sig.initSign(priv);
try {
sig.setParameter(params);
} catch (InvalidAlgorithmParameterException iape) {
if (s == PSSUtil.AlgoSupport.MAYBE) {
// confirmed to be unsupported; skip the rest of the test
System.out.println(" => Skip; no PSS support");
return;
} else {
throw new RuntimeException("Unexpected Exception", iape);
}
}
// start testing below
skipTest = false;
for (int i = 0; i < UPDATE_TIMES_HUNDRED; i++) {
sig.update(data);
}
@ -163,5 +146,6 @@ public class SignatureTestPSS extends PKCS11Test {
if (sig.verify(signedData)) {
throw new RuntimeException("Failed to detect bad signature");
}
System.out.println(" => Passed");
}
}