9a9ac1d005
Reviewed-by: mullan, ascarpino, rhalade
134 lines
5.3 KiB
Java
134 lines
5.3 KiB
Java
/*
|
|
* Copyright (c) 2020, 2024, 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.PrivateKey;
|
|
import java.security.PublicKey;
|
|
import java.security.Signature;
|
|
import java.security.spec.NamedParameterSpec;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8209632
|
|
* @summary Test behaviour of Signature instance by re-using it multiple times
|
|
* in different way.
|
|
* @run main EdDSAReuseTest
|
|
*/
|
|
public class EdDSAReuseTest {
|
|
|
|
private static final String EDDSA = "EdDSA";
|
|
private static final String ED25519 = "Ed25519";
|
|
private static final String ED448 = "Ed448";
|
|
private static final String PROVIDER = System.getProperty("test.provider.name", "SunEC");
|
|
private static final String MSG = "TEST";
|
|
private static final int REUSE = 20;
|
|
private static final int ONCE = 1;
|
|
private static final int TENTH = 10;
|
|
private static final int FIFTH = 5;
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
|
|
for (boolean initKey : new boolean[]{true, false}) {
|
|
// Sign and Verify with data update once
|
|
test(PROVIDER, EDDSA, null, initKey, ONCE, ONCE);
|
|
test(PROVIDER, ED25519, ED25519, initKey, ONCE, ONCE);
|
|
test(PROVIDER, ED448, ED448, initKey, ONCE, ONCE);
|
|
|
|
// Sign and Verify with data update 10 times
|
|
test(PROVIDER, EDDSA, null, initKey, TENTH, TENTH);
|
|
test(PROVIDER, ED25519, ED25519, initKey, TENTH, TENTH);
|
|
test(PROVIDER, ED448, ED448, initKey, TENTH, TENTH);
|
|
|
|
// Sign and Verify with data update unmatched number of times
|
|
test(PROVIDER, EDDSA, null, initKey, TENTH, FIFTH);
|
|
test(PROVIDER, ED25519, ED25519, initKey, TENTH, FIFTH);
|
|
test(PROVIDER, ED448, ED448, initKey, TENTH, FIFTH);
|
|
}
|
|
}
|
|
|
|
private static void test(String provider, String name, Object param,
|
|
boolean initKey, int signUpdate, int verifyUpdate)
|
|
throws Exception {
|
|
|
|
System.out.printf("Case for signature name: %s, param: %s,"
|
|
+ " initialize signature instance before each operation: %s%n",
|
|
name, param, initKey);
|
|
KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider);
|
|
if (param != null) {
|
|
kpg.initialize(new NamedParameterSpec((String) param));
|
|
}
|
|
KeyPair kp = kpg.generateKeyPair();
|
|
Signature sig = Signature.getInstance(name, provider);
|
|
testAPI(sig, kp, initKey, signUpdate, verifyUpdate);
|
|
System.out.println("Passed.");
|
|
}
|
|
|
|
private static void testAPI(Signature sig, KeyPair kp, boolean initKey,
|
|
int signUpdate, int verifyUpdate) throws Exception {
|
|
|
|
sig.initSign(kp.getPrivate());
|
|
List<byte[]> signatures = new ArrayList<>();
|
|
// Re-use the signature instance 20 times
|
|
for (int i = 0; i < REUSE; i++) {
|
|
signatures.add(sign(sig, kp.getPrivate(), MSG, initKey, signUpdate));
|
|
}
|
|
System.out.printf("Generated signatures %s times%n", signatures.size());
|
|
sig.initVerify(kp.getPublic());
|
|
for (byte[] sign : signatures) {
|
|
// Verification will pass when message update matches with
|
|
// the same used for sign
|
|
if (verify(sig, kp.getPublic(), MSG, sign, initKey, verifyUpdate)
|
|
!= (signUpdate == verifyUpdate)) {
|
|
throw new RuntimeException(
|
|
"Verification succed with unmatched message");
|
|
}
|
|
}
|
|
System.out.printf("Verified signatures %s times%n", signatures.size());
|
|
}
|
|
|
|
private static byte[] sign(Signature sig, PrivateKey priKey, String msg,
|
|
boolean initKey, int signUpdate) throws Exception {
|
|
if (initKey) {
|
|
sig.initSign(priKey);
|
|
}
|
|
for (int update = 0; update < signUpdate; update++) {
|
|
sig.update(msg.getBytes());
|
|
}
|
|
return sig.sign();
|
|
}
|
|
|
|
private static boolean verify(Signature sig, PublicKey pubKey, String msg,
|
|
byte[] sign, boolean initKey, int verifyUpdate) throws Exception {
|
|
if (initKey) {
|
|
sig.initVerify(pubKey);
|
|
}
|
|
for (int update = 0; update < verifyUpdate; update++) {
|
|
sig.update(msg.getBytes());
|
|
}
|
|
return sig.verify(sign);
|
|
}
|
|
}
|