8209632: Develop new tests for EdDSA API
New Tests for EdDSA Reviewed-by: ascarpino
This commit is contained in:
parent
77826c0a39
commit
13cf783154
109
test/jdk/sun/security/ec/ed/EdCRLSign.java
Normal file
109
test/jdk/sun/security/ec/ed/EdCRLSign.java
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.SecureRandom;
|
||||
import java.security.spec.NamedParameterSpec;
|
||||
import java.util.Date;
|
||||
import sun.security.x509.X500Name;
|
||||
import sun.security.x509.X509CRLImpl;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8209632
|
||||
* @summary CRL Sign
|
||||
* @modules java.base/sun.security.x509
|
||||
* @run main EdCRLSign
|
||||
*/
|
||||
public class EdCRLSign {
|
||||
|
||||
private static final String ED25519 = "Ed25519";
|
||||
private static final String ED448 = "Ed448";
|
||||
private static final String OIDN25519 = "1.3.101.112";
|
||||
private static final String OID25519 = "OID.1.3.101.112";
|
||||
private static final String OIDN448 = "1.3.101.113";
|
||||
private static final String OID448 = "OID.1.3.101.113";
|
||||
private static final String PROVIDER = "SunEC";
|
||||
private static final SecureRandom S_RND = new SecureRandom(new byte[]{0x1});
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
for (boolean initWithRandom : new boolean[]{true, false}) {
|
||||
// Default Parameter
|
||||
test(PROVIDER, ED25519, null, initWithRandom);
|
||||
test(PROVIDER, ED448, null, initWithRandom);
|
||||
|
||||
// With named parameter
|
||||
test(PROVIDER, ED25519, ED25519, initWithRandom);
|
||||
test(PROVIDER, OIDN25519, ED25519, initWithRandom);
|
||||
test(PROVIDER, OID25519, ED25519, initWithRandom);
|
||||
test(PROVIDER, ED448, ED448, initWithRandom);
|
||||
test(PROVIDER, OIDN448, ED448, initWithRandom);
|
||||
test(PROVIDER, OID448, ED448, initWithRandom);
|
||||
|
||||
// With size parameter
|
||||
test(PROVIDER, ED25519, 255, initWithRandom);
|
||||
test(PROVIDER, OIDN25519, 255, initWithRandom);
|
||||
test(PROVIDER, OID25519, 255, initWithRandom);
|
||||
test(PROVIDER, ED448, 448, initWithRandom);
|
||||
test(PROVIDER, OIDN448, 448, initWithRandom);
|
||||
test(PROVIDER, OID448, 448, initWithRandom);
|
||||
}
|
||||
}
|
||||
|
||||
// Test CRL signature using a KeyPair.
|
||||
private static void test(String provider, String name, Object param,
|
||||
boolean initWithRandom) throws Exception {
|
||||
|
||||
System.out.printf("Case Algo:%s, Param:%s, Intitiate with random:%s%n",
|
||||
name, param, initWithRandom);
|
||||
KeyPair kp = genKeyPair(provider, name, param, initWithRandom);
|
||||
X509CRLImpl crl = new X509CRLImpl(
|
||||
new X500Name("CN=Issuer"), new Date(), new Date());
|
||||
crl.sign(kp.getPrivate(), name);
|
||||
crl.verify(kp.getPublic());
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
|
||||
private static KeyPair genKeyPair(String provider, String name,
|
||||
Object param, boolean initWithRandom) throws Exception {
|
||||
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider);
|
||||
if (initWithRandom) {
|
||||
if (param instanceof Integer) {
|
||||
kpg.initialize((Integer) param, S_RND);
|
||||
} else if (param instanceof String) {
|
||||
kpg.initialize(new NamedParameterSpec((String) param), S_RND);
|
||||
}
|
||||
} else {
|
||||
if (param instanceof Integer) {
|
||||
kpg.initialize((Integer) param);
|
||||
} else if (param instanceof String) {
|
||||
kpg.initialize(new NamedParameterSpec((String) param));
|
||||
}
|
||||
}
|
||||
return kpg.generateKeyPair();
|
||||
}
|
||||
|
||||
}
|
222
test/jdk/sun/security/ec/ed/EdDSAKeyCompatibility.java
Normal file
222
test/jdk/sun/security/ec/ed/EdDSAKeyCompatibility.java
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.util.Base64;
|
||||
import sun.security.util.DerValue;
|
||||
import java.security.interfaces.EdECPrivateKey;
|
||||
import java.security.interfaces.EdECPublicKey;
|
||||
import java.security.spec.EdECPrivateKeySpec;
|
||||
import java.security.spec.EdECPublicKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.NamedParameterSpec;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8209632
|
||||
* @summary OpenSSL generated compatibility test with EDDSA Java.
|
||||
* @modules java.base/sun.security.util
|
||||
* @run main EdDSAKeyCompatibility
|
||||
*/
|
||||
public class EdDSAKeyCompatibility {
|
||||
|
||||
private static final String EDDSA = "EdDSA";
|
||||
private static final String ED25519 = "Ed25519";
|
||||
private static final String ED448 = "Ed448";
|
||||
private static final String PROVIDER = "SunEC";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
boolean result = true;
|
||||
result &= validateCert(EDDSA, PROVIDER, ED25519CERT);
|
||||
result &= validateCert(EDDSA, PROVIDER, ED448CERT);
|
||||
result &= validateCert(ED25519, PROVIDER, ED25519CERT);
|
||||
result &= validateCert(ED448, PROVIDER, ED448CERT);
|
||||
|
||||
result &= validatePrivate(ED25519, PROVIDER, ED25519KEY);
|
||||
result &= validatePrivate(ED448, PROVIDER, ED448KEY);
|
||||
|
||||
if (!result) {
|
||||
throw new RuntimeException("Some test cases failed");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean validatePrivate(String algorithm, String provider,
|
||||
String key) {
|
||||
|
||||
try {
|
||||
KeyFactory kf = KeyFactory.getInstance(algorithm, provider);
|
||||
PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(
|
||||
Base64.getMimeDecoder().decode(key));
|
||||
EdECPrivateKey privKey
|
||||
= (EdECPrivateKey) kf.generatePrivate(privSpec);
|
||||
checkPrivKeyFormat(privKey.getEncoded());
|
||||
|
||||
NamedParameterSpec namedSpec = new NamedParameterSpec(algorithm);
|
||||
EdECPrivateKeySpec edprivSpec = new EdECPrivateKeySpec(
|
||||
namedSpec, privKey.getBytes().get());
|
||||
EdECPrivateKey privKey1
|
||||
= (EdECPrivateKey) kf.generatePrivate(edprivSpec);
|
||||
checkPrivKeyFormat(privKey1.getEncoded());
|
||||
EdECPrivateKey privKey2 = (EdECPrivateKey) kf.translateKey(privKey);
|
||||
checkPrivKeyFormat(privKey2.getEncoded());
|
||||
equals(privKey, privKey1);
|
||||
equals(privKey, privKey2);
|
||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException
|
||||
| NoSuchProviderException | InvalidKeyException e) {
|
||||
e.printStackTrace(System.out);
|
||||
return false;
|
||||
}
|
||||
System.out.println("PASSED - validatePrivate");
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean validateCert(String algorithm, String provider,
|
||||
String certificate) {
|
||||
|
||||
try {
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
Certificate cert = cf.generateCertificate(
|
||||
new ByteArrayInputStream(certificate.getBytes()));
|
||||
System.out.println(cert);
|
||||
KeyFactory kf = KeyFactory.getInstance(algorithm, provider);
|
||||
X509EncodedKeySpec pubSpec = kf.getKeySpec(
|
||||
cert.getPublicKey(), X509EncodedKeySpec.class);
|
||||
EdECPublicKey pubKey = (EdECPublicKey) kf.generatePublic(pubSpec);
|
||||
EdECPublicKeySpec edpubSpec = kf.getKeySpec(
|
||||
cert.getPublicKey(), EdECPublicKeySpec.class);
|
||||
EdECPublicKey pubKey1 = (EdECPublicKey) kf.generatePublic(edpubSpec);
|
||||
EdECPublicKey pubKey2 = (EdECPublicKey) kf.translateKey(pubKey);
|
||||
equals(pubKey, pubKey1);
|
||||
equals(pubKey, pubKey2);
|
||||
equals(pubKey, cert.getPublicKey());
|
||||
} catch (CertificateException | NoSuchAlgorithmException
|
||||
| InvalidKeySpecException | NoSuchProviderException
|
||||
| InvalidKeyException e) {
|
||||
e.printStackTrace(System.out);
|
||||
return false;
|
||||
}
|
||||
System.out.println("PASSED - validateCert");
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void checkPrivKeyFormat(byte[] key) throws IOException {
|
||||
|
||||
// key value should be nested octet strings
|
||||
DerValue val = new DerValue(new ByteArrayInputStream(key));
|
||||
BigInteger version = val.data.getBigInteger();
|
||||
DerValue algId = val.data.getDerValue();
|
||||
byte[] keyValue = val.data.getOctetString();
|
||||
val = new DerValue(new ByteArrayInputStream(keyValue));
|
||||
if (val.tag != DerValue.tag_OctetString) {
|
||||
throw new RuntimeException("incorrect format");
|
||||
}
|
||||
}
|
||||
|
||||
private static void equals(Object actual, Object expected) {
|
||||
if (!actual.equals(expected)) {
|
||||
throw new RuntimeException(String.format("Actual: %s, Expected: %s",
|
||||
actual, expected));
|
||||
}
|
||||
}
|
||||
|
||||
// Following EdDSA Certificates/Keys are generated through openssl_1.1.1d
|
||||
|
||||
/*
|
||||
* Certificate:
|
||||
* Data:
|
||||
* Version: 3 (0x2)
|
||||
* Serial Number:
|
||||
* 1d:d3:87:b9:e4:c6:9e:4a:5c:78:a8:f0:c7:9b:37:be:1e:31:dd:20
|
||||
* Signature Algorithm: ED25519
|
||||
* Issuer: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost
|
||||
* Validity
|
||||
* Not Before: Mar 6 05:55:31 2020 GMT
|
||||
* Not After : Mar 1 05:55:31 2040 GMT
|
||||
* Subject: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost
|
||||
* Subject Public Key Info:
|
||||
* Public Key Algorithm: ED25519
|
||||
*/
|
||||
private static final String ED25519KEY
|
||||
= "MC4CAQAwBQYDK2VwBCIEIP8xGaQTMh+I+59I66AaN+B4qnY1oWGjPwbSY4r+D08f";
|
||||
|
||||
private static final String ED25519CERT
|
||||
= "-----BEGIN CERTIFICATE-----\n"
|
||||
+ "MIIByTCCAXugAwIBAgIUHdOHueTGnkpceKjwx5s3vh4x3SAwBQYDK2VwMFoxCzAJ\n"
|
||||
+ "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0NBMQ0wCwYDVQQKDAR0\n"
|
||||
+ "ZXN0MQ0wCwYDVQQLDAR0ZXN0MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwMzA2\n"
|
||||
+ "MDU1NTMxWhcNNDAwMzAxMDU1NTMxWjBaMQswCQYDVQQGEwJVUzELMAkGA1UECAwC\n"
|
||||
+ "Q0ExDDAKBgNVBAcMA1NDQTENMAsGA1UECgwEdGVzdDENMAsGA1UECwwEdGVzdDES\n"
|
||||
+ "MBAGA1UEAwwJbG9jYWxob3N0MCowBQYDK2VwAyEAdqQ4Nduhbl+ShGeKdOryVMKy\n"
|
||||
+ "1t1LjyjPyCBC+gSk0eCjUzBRMB0GA1UdDgQWBBS01/VQEzwkFNRW/esQxaB6+uId\n"
|
||||
+ "8jAfBgNVHSMEGDAWgBS01/VQEzwkFNRW/esQxaB6+uId8jAPBgNVHRMBAf8EBTAD\n"
|
||||
+ "AQH/MAUGAytlcANBAEJkLuNfyVws7HKqHL7oDqQkp5DSwh+bGjrr2p4zSvs5PZ8o\n"
|
||||
+ "jRXWV0SMt/MB+90ubMD5tL7H7J6DR5PUFBIwGwc=\n"
|
||||
+ "-----END CERTIFICATE-----";
|
||||
|
||||
/*
|
||||
* Certificate:
|
||||
* Data:
|
||||
* Version: 3 (0x2)
|
||||
* Serial Number:
|
||||
* 42:eb:8c:a2:a0:6f:8e:5a:a5:f8:7c:72:c1:f1:8b:7e:44:1b:37:80
|
||||
* Signature Algorithm: ED448
|
||||
* Issuer: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost
|
||||
* Validity
|
||||
* Not Before: Mar 6 05:57:42 2020 GMT
|
||||
* Not After : Mar 1 05:57:42 2040 GMT
|
||||
* Subject: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost
|
||||
* Subject Public Key Info:
|
||||
* Public Key Algorithm: ED448
|
||||
*/
|
||||
private static final String ED448KEY
|
||||
= "MEcCAQAwBQYDK2VxBDsEOdG4lrYO0xBaf3aJWYMZ8XAxitA1zV4/ghG8wPBag8HQ"
|
||||
+ "XN+3OmS8wR1KfeGQysHQr3JHco3Mwiaz8w==";
|
||||
|
||||
private static final String ED448CERT
|
||||
= "-----BEGIN CERTIFICATE-----\n"
|
||||
+ "MIICFDCCAZSgAwIBAgIUQuuMoqBvjlql+HxywfGLfkQbN4AwBQYDK2VxMFoxCzAJ\n"
|
||||
+ "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0NBMQ0wCwYDVQQKDAR0\n"
|
||||
+ "ZXN0MQ0wCwYDVQQLDAR0ZXN0MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwMzA2\n"
|
||||
+ "MDU1NzQyWhcNNDAwMzAxMDU1NzQyWjBaMQswCQYDVQQGEwJVUzELMAkGA1UECAwC\n"
|
||||
+ "Q0ExDDAKBgNVBAcMA1NDQTENMAsGA1UECgwEdGVzdDENMAsGA1UECwwEdGVzdDES\n"
|
||||
+ "MBAGA1UEAwwJbG9jYWxob3N0MEMwBQYDK2VxAzoAfKlXpT0ymcvz2Gp+8HLzBpaz\n"
|
||||
+ "5mQqMaDbGmcq8gSIdeEUtVmv4OplE+4GSnrbJnEn99LQdbanL/MAo1MwUTAdBgNV\n"
|
||||
+ "HQ4EFgQUXkm9LVUkB0f/1MiPFjQPHGJ8THIwHwYDVR0jBBgwFoAUXkm9LVUkB0f/\n"
|
||||
+ "1MiPFjQPHGJ8THIwDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXEDcwDvE3LKCg1bTjHi\n"
|
||||
+ "MI1EiMqZN3PJYVBsztecBXm3ELDlT+F0Z1H2vjaROkJc8PdpUOxyed1xDjwq3IB/\n"
|
||||
+ "nYYJNVyt6Dy3d12kl77ev+YMD83OuqM6F5O6MdDUxYQu9u3NasZAU5FQ6zklWWpI\n"
|
||||
+ "8jCPtOvcAQA=\n"
|
||||
+ "-----END CERTIFICATE-----";
|
||||
}
|
221
test/jdk/sun/security/ec/ed/EdDSAKeySize.java
Normal file
221
test/jdk/sun/security/ec/ed/EdDSAKeySize.java
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 static javax.crypto.Cipher.PRIVATE_KEY;
|
||||
import static javax.crypto.Cipher.PUBLIC_KEY;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.interfaces.EdECPrivateKey;
|
||||
import java.security.interfaces.EdECPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.security.spec.EdECPrivateKeySpec;
|
||||
import java.security.spec.EdECPublicKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.NamedParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import jdk.test.lib.Convert;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8209632
|
||||
* @summary Verify KeyLength for EDDSA, ED25519, ED448.
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Convert
|
||||
* @run main EdDSAKeySize
|
||||
*/
|
||||
public class EdDSAKeySize {
|
||||
|
||||
private static final String EDDSA = "EDDSA";
|
||||
private static final String ED25519 = "ED25519";
|
||||
private static final String ED448 = "ED448";
|
||||
private static final String OIDN25519 = "1.3.101.112";
|
||||
private static final String OID25519 = "OID.1.3.101.112";
|
||||
private static final String OIDN448 = "1.3.101.113";
|
||||
private static final String OID448 = "OID.1.3.101.113";
|
||||
private static final String PROVIDER = "SunEC";
|
||||
private static final SecureRandom RND = new SecureRandom(new byte[]{0x1});
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
for (boolean initWithRandom : new boolean[]{true, false}) {
|
||||
|
||||
// As per rfc8032 the generated keysize for ED25519 is
|
||||
// 32 octets(256 bits) and ED448 is 57 octets(456 bits).
|
||||
// Case with default parameter
|
||||
testKeyAttributes(PROVIDER, EDDSA, initWithRandom, null, 256);
|
||||
testKeyAttributes(PROVIDER, ED25519, initWithRandom, null, 256);
|
||||
testKeyAttributes(PROVIDER, ED448, initWithRandom, null, 456);
|
||||
|
||||
// With named parameter
|
||||
testKeyAttributes(PROVIDER, EDDSA, initWithRandom, ED25519, 256);
|
||||
testKeyAttributes(PROVIDER, ED25519, initWithRandom, ED25519, 256);
|
||||
testKeyAttributes(PROVIDER, OIDN25519, initWithRandom, ED25519, 256);
|
||||
testKeyAttributes(PROVIDER, OID25519, initWithRandom, ED25519, 256);
|
||||
testKeyAttributes(PROVIDER, ED448, initWithRandom, ED448, 456);
|
||||
testKeyAttributes(PROVIDER, OIDN448, initWithRandom, ED448, 456);
|
||||
testKeyAttributes(PROVIDER, OID448, initWithRandom, ED448, 456);
|
||||
|
||||
// With size parameter
|
||||
testKeyAttributes(PROVIDER, EDDSA, initWithRandom, 255, 256);
|
||||
testKeyAttributes(PROVIDER, ED25519, initWithRandom, 255, 256);
|
||||
testKeyAttributes(PROVIDER, OIDN25519, initWithRandom, 255, 256);
|
||||
testKeyAttributes(PROVIDER, OID25519, initWithRandom, 255, 256);
|
||||
testKeyAttributes(PROVIDER, ED448, initWithRandom, 448, 456);
|
||||
testKeyAttributes(PROVIDER, OIDN448, initWithRandom, 448, 456);
|
||||
testKeyAttributes(PROVIDER, OID448, initWithRandom, 448, 456);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test standard Key attributes.
|
||||
*/
|
||||
private static void testKeyAttributes(String provider, String name,
|
||||
boolean initWithRandom, Object param, int keySize) throws Exception {
|
||||
|
||||
System.out.printf("Case name: %s, param: %s, Expected keysize: %s, "
|
||||
+ "Initiate with random: %s%n", name, param, keySize,
|
||||
initWithRandom);
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider);
|
||||
if (initWithRandom) {
|
||||
if (param instanceof Integer) {
|
||||
kpg.initialize((Integer) param, RND);
|
||||
} else if (param instanceof String) {
|
||||
kpg.initialize(new NamedParameterSpec((String) param), RND);
|
||||
}
|
||||
} else {
|
||||
if (param instanceof Integer) {
|
||||
kpg.initialize((Integer) param);
|
||||
} else if (param instanceof String) {
|
||||
kpg.initialize(new NamedParameterSpec((String) param));
|
||||
}
|
||||
}
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
NamedParameterSpec namedSpec = getNamedParamSpec(name);
|
||||
|
||||
// Verify original PrivateKey with it's different representation
|
||||
Key[] privs = manipulateKey(provider, name, PRIVATE_KEY,
|
||||
kp.getPrivate(), namedSpec);
|
||||
Arrays.stream(privs).forEach(
|
||||
priv -> testPrivateKey((EdECPrivateKey) kp.getPrivate(),
|
||||
(EdECPrivateKey) priv, keySize));
|
||||
|
||||
// Verify original PublicKey with it's different representation
|
||||
Key[] pubs = manipulateKey(provider, name, PUBLIC_KEY,
|
||||
kp.getPublic(), namedSpec);
|
||||
Arrays.stream(pubs).forEach(
|
||||
pub -> testPublicKey((EdECPublicKey) kp.getPublic(),
|
||||
(EdECPublicKey) pub));
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
|
||||
private static NamedParameterSpec getNamedParamSpec(String algo) {
|
||||
NamedParameterSpec namedSpec = switch (algo) {
|
||||
case EDDSA
|
||||
, OIDN25519, OID25519 -> new NamedParameterSpec(ED25519);
|
||||
case OIDN448
|
||||
, OID448 -> new NamedParameterSpec(ED448);
|
||||
default->
|
||||
new NamedParameterSpec(algo);
|
||||
};
|
||||
return namedSpec;
|
||||
}
|
||||
|
||||
private static Key[] manipulateKey(String provider, String algo, int type,
|
||||
Key key, NamedParameterSpec namedSpec)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException,
|
||||
NoSuchProviderException, InvalidKeyException {
|
||||
|
||||
KeyFactory kf = KeyFactory.getInstance(algo, provider);
|
||||
switch (type) {
|
||||
case PUBLIC_KEY:
|
||||
return new Key[]{
|
||||
kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())),
|
||||
kf.generatePublic(kf.getKeySpec(
|
||||
key, EdECPublicKeySpec.class)),
|
||||
kf.generatePublic(new EdECPublicKeySpec(namedSpec,
|
||||
((EdECPublicKey) key).getPoint())),
|
||||
kf.translateKey(key)
|
||||
};
|
||||
case PRIVATE_KEY:
|
||||
return new Key[]{
|
||||
kf.generatePrivate(new PKCS8EncodedKeySpec(key.getEncoded())),
|
||||
kf.generatePrivate(
|
||||
kf.getKeySpec(key, EdECPrivateKeySpec.class)),
|
||||
kf.generatePrivate(new EdECPrivateKeySpec(namedSpec,
|
||||
((EdECPrivateKey) key).getBytes().get())),
|
||||
kf.translateKey(key)
|
||||
};
|
||||
}
|
||||
throw new RuntimeException("We shouldn't reach here");
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic PrivateKey Test cases
|
||||
*/
|
||||
private static void testPrivateKey(EdECPrivateKey orig,
|
||||
EdECPrivateKey generated, int size) {
|
||||
|
||||
equals(orig.getBytes().get().length * 8, size);
|
||||
equals(generated.getBytes().get().length * 8, size);
|
||||
equals(orig.getBytes().get(), generated.getBytes().get());
|
||||
equals(orig.getFormat(), generated.getFormat());
|
||||
equals(orig.getEncoded(), generated.getEncoded());
|
||||
equals(((NamedParameterSpec) orig.getParams()).getName(),
|
||||
((NamedParameterSpec) generated.getParams()).getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic PublicKey Test cases
|
||||
*/
|
||||
private static void testPublicKey(EdECPublicKey orig,
|
||||
EdECPublicKey generated) {
|
||||
|
||||
equals(orig.getPoint().getY(), generated.getPoint().getY());
|
||||
equals(orig.getPoint().isXOdd(), generated.getPoint().isXOdd());
|
||||
equals(orig.getFormat(), generated.getFormat());
|
||||
equals(orig.getEncoded(), generated.getEncoded());
|
||||
equals(((NamedParameterSpec) orig.getParams()).getName(),
|
||||
((NamedParameterSpec) generated.getParams()).getName());
|
||||
}
|
||||
|
||||
private static void equals(Object actual, Object expected) {
|
||||
if (!actual.equals(expected)) {
|
||||
throw new RuntimeException(String.format("Actual: %s, Expected: %s",
|
||||
actual, expected));
|
||||
}
|
||||
}
|
||||
|
||||
private static void equals(byte[] actual, byte[] expected) {
|
||||
if (!Arrays.equals(actual, expected)) {
|
||||
throw new RuntimeException(String.format("Actual array: %s, "
|
||||
+ "Expected array:%s", Convert.byteArrayToHexString(actual),
|
||||
Convert.byteArrayToHexString(expected)));
|
||||
}
|
||||
}
|
||||
}
|
299
test/jdk/sun/security/ec/ed/EdDSANegativeTest.java
Normal file
299
test/jdk/sun/security/ec/ed/EdDSANegativeTest.java
Normal file
@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.InvalidKeyException;
|
||||
import java.security.InvalidParameterException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Signature;
|
||||
import java.security.interfaces.EdECPrivateKey;
|
||||
import java.security.interfaces.EdECPublicKey;
|
||||
import java.security.spec.EdDSAParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import jdk.test.lib.Convert;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8209632
|
||||
* @summary Negative cases for EDDSA.
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Convert
|
||||
* @run main EdDSANegativeTest
|
||||
*/
|
||||
public class EdDSANegativeTest {
|
||||
|
||||
private static final String EDDSA = "EdDSA";
|
||||
private static final String ED25519 = "Ed25519";
|
||||
private static final String ED448 = "Ed448";
|
||||
private static final String PROVIDER = "SunEC";
|
||||
private static final String OTHER = "other";
|
||||
private static final byte[] MSG = "TEST".getBytes();
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
byName();
|
||||
byParam();
|
||||
byInvalidKey();
|
||||
byInvalidKeyType();
|
||||
}
|
||||
|
||||
private static void byName() throws Exception {
|
||||
|
||||
for (String name : new String[]{null, "", "EDDSA", "eddsa", "EDdsa",
|
||||
EDDSA, ED25519, "ed25519", "ED25519", ED448, "eD448", "ED448",
|
||||
"ed448", OTHER}) {
|
||||
try {
|
||||
KeyPair kp = genKeyPair(name);
|
||||
KeyFactory kf = KeyFactory.getInstance(name, PROVIDER);
|
||||
EdECPrivateKey edPri
|
||||
= (EdECPrivateKey) kf.translateKey(kp.getPrivate());
|
||||
EdECPublicKey edPub
|
||||
= (EdECPublicKey) kf.translateKey(kp.getPublic());
|
||||
Signature sig = Signature.getInstance(name, PROVIDER);
|
||||
byte[] computedSig = sign(sig, edPri, MSG);
|
||||
if (!verify(sig, edPub, MSG, computedSig)) {
|
||||
throw new RuntimeException("Signature verification failed");
|
||||
}
|
||||
if (name == null || "".equals(name)) {
|
||||
throw new RuntimeException(
|
||||
"Should not reach here for algo: " + name);
|
||||
}
|
||||
System.out.println("Passed: byName: " + name);
|
||||
} catch (NullPointerException e) {
|
||||
if (name != null) {
|
||||
throw new RuntimeException(
|
||||
"Unknown issue with algo name: " + name, e);
|
||||
}
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
if (!("".equals(name) || OTHER.equals(name))) {
|
||||
throw new RuntimeException(
|
||||
"Unknown issue with algo name: " + name, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void byParam() throws Exception {
|
||||
testParam(EDDSA);
|
||||
testParam(ED25519);
|
||||
testParam(ED448);
|
||||
}
|
||||
|
||||
private static void byInvalidKey() throws Exception {
|
||||
testInvalidKey(EDDSA);
|
||||
testInvalidKey(ED25519);
|
||||
testInvalidKey(ED448);
|
||||
}
|
||||
|
||||
private static void byInvalidKeyType() throws Exception {
|
||||
testInvalidKeyType(EDDSA);
|
||||
testInvalidKeyType(ED25519);
|
||||
testInvalidKeyType(ED448);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Signature.
|
||||
*/
|
||||
private static void testParam(String name) throws Exception {
|
||||
|
||||
KeyPair kp = genKeyPair(name);
|
||||
Signature sig = Signature.getInstance(name, PROVIDER);
|
||||
// Set initial paramter to generate a signature
|
||||
EdDSAParameterSpec initParam
|
||||
= new EdDSAParameterSpec(true, "testContext".getBytes());
|
||||
sig.setParameter(initParam);
|
||||
byte[] computedSig = sign(sig, kp.getPrivate(), MSG);
|
||||
// Signature should not get verified other than same parameter
|
||||
// which is set through the signature instance.
|
||||
for (boolean preHash : new boolean[]{true, false}) {
|
||||
// Test case with prehash as parameter without context set.
|
||||
verify(sig, kp.getPublic(), MSG, new EdDSAParameterSpec(preHash),
|
||||
initParam, computedSig);
|
||||
// Test Case with Context combined of different sizes.
|
||||
// As per rfc8032, value of context is maximum of 255 octet
|
||||
for (byte[] context : new byte[][]{{}, "other".getBytes(),
|
||||
new byte[255], new byte[500]}) {
|
||||
System.out.printf("Testing signature for name: %s, algorithm "
|
||||
+ "spec: (prehash:%s, context:%s)%n", name, preHash,
|
||||
Convert.byteArrayToHexString(context));
|
||||
try {
|
||||
verify(sig, kp.getPublic(), MSG,
|
||||
new EdDSAParameterSpec(preHash, context),
|
||||
initParam, computedSig);
|
||||
} catch (InvalidParameterException e) {
|
||||
if (context.length <= 255) {
|
||||
throw new RuntimeException("Should not throw exception "
|
||||
+ "when context size <= 255 octet: "
|
||||
+ context.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void testInvalidKey(String name) throws Exception {
|
||||
KeyPair kp = genKeyPair(name);
|
||||
KeyPair kp1 = genKeyPair(name);
|
||||
Signature sig = Signature.getInstance(name, PROVIDER);
|
||||
byte[] computedSig = sign(sig, kp.getPrivate(), MSG);
|
||||
if (verify(sig, kp1.getPublic(), MSG, computedSig)) {
|
||||
throw new RuntimeException("Signature verification failed "
|
||||
+ "for unpaired key.");
|
||||
}
|
||||
System.out.println("Passed: testInvalidKey: " + name);
|
||||
}
|
||||
|
||||
private static void testInvalidKeyType(String name) throws Exception {
|
||||
|
||||
KeyFactory kf = KeyFactory.getInstance(name, PROVIDER);
|
||||
try {
|
||||
kf.translateKey(new InvalidPrivateKey());
|
||||
} catch (InvalidKeyException e) {
|
||||
// Expected exception and not to be handled
|
||||
}
|
||||
try {
|
||||
kf.translateKey(new InvalidPublicKey());
|
||||
} catch (InvalidKeyException e) {
|
||||
// Expected exception and not to be handled
|
||||
}
|
||||
System.out.println("Passed: testInvalidKeyType: " + name);
|
||||
}
|
||||
|
||||
private static KeyPair genKeyPair(String name) throws Exception {
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, PROVIDER);
|
||||
return kpg.generateKeyPair();
|
||||
}
|
||||
|
||||
private static byte[] sign(Signature sig, PrivateKey priKey, byte[] msg)
|
||||
throws Exception {
|
||||
sig.initSign(priKey);
|
||||
sig.update(msg);
|
||||
return sig.sign();
|
||||
}
|
||||
|
||||
private static boolean verify(Signature sig, PublicKey pubKey, byte[] msg,
|
||||
byte[] sign) throws Exception {
|
||||
sig.initVerify(pubKey);
|
||||
sig.update(msg);
|
||||
return sig.verify(sign);
|
||||
}
|
||||
|
||||
private static void verify(Signature sig, PublicKey pubKey, byte[] msg,
|
||||
EdDSAParameterSpec params, EdDSAParameterSpec initParam,
|
||||
byte[] computedSig) throws Exception {
|
||||
|
||||
sig.setParameter(params);
|
||||
if (verify(sig, pubKey, msg, computedSig)) {
|
||||
byte[] context = params.getContext().isPresent()
|
||||
? params.getContext().get() : null;
|
||||
byte[] initContext = initParam.getContext().isPresent()
|
||||
? initParam.getContext().get() : null;
|
||||
boolean preHash = params.isPrehash();
|
||||
boolean initPreHash = initParam.isPrehash();
|
||||
// The signature should not get verified with other parameters
|
||||
// set through signature instance.
|
||||
if (!(equals(context, initContext) && equals(preHash, initPreHash))) {
|
||||
throw new RuntimeException(String.format("Signature verification"
|
||||
+ " success with different param context(actual:%s, "
|
||||
+ "expected:%s), Prehash(actual:%s, expected:%s)",
|
||||
Convert.byteArrayToHexString(context),
|
||||
Convert.byteArrayToHexString(initContext),
|
||||
preHash, initPreHash));
|
||||
} else {
|
||||
System.out.println("Atleast a case matched");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean equals(Object actual, Object expected) {
|
||||
if (actual == expected) {
|
||||
return true;
|
||||
}
|
||||
if (actual == null || expected == null) {
|
||||
return false;
|
||||
}
|
||||
boolean equals = actual.equals(expected);
|
||||
if (!equals) {
|
||||
throw new RuntimeException(String.format("Actual: %s, Expected: %s",
|
||||
actual, expected));
|
||||
}
|
||||
return equals;
|
||||
}
|
||||
|
||||
private static boolean equals(byte[] actual, byte[] expected) {
|
||||
if (actual == expected) {
|
||||
return true;
|
||||
}
|
||||
if (actual == null || expected == null) {
|
||||
return false;
|
||||
}
|
||||
boolean equals = Arrays.equals(actual, expected);
|
||||
if (!equals) {
|
||||
throw new RuntimeException(String.format("Actual array: %s, "
|
||||
+ "Expected array:%s", Convert.byteArrayToHexString(actual),
|
||||
Convert.byteArrayToHexString(expected)));
|
||||
}
|
||||
return equals;
|
||||
}
|
||||
|
||||
private static class InvalidPrivateKey implements PrivateKey {
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return "test".getBytes();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class InvalidPublicKey implements PublicKey {
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return "test";
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return "test".getBytes();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
174
test/jdk/sun/security/ec/ed/EdDSAParamSpec.java
Normal file
174
test/jdk/sun/security/ec/ed/EdDSAParamSpec.java
Normal file
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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.SecureRandom;
|
||||
import java.security.Signature;
|
||||
import java.security.spec.EdDSAParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import jdk.test.lib.Convert;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8209632
|
||||
* @summary Test EdDSAParameterSpec.
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Convert
|
||||
* @run main EdDSAParamSpec
|
||||
*/
|
||||
public class EdDSAParamSpec {
|
||||
|
||||
private static final String EDDSA = "EdDSA";
|
||||
private static final String ED25519 = "Ed25519";
|
||||
private static final String ED448 = "Ed448";
|
||||
private static final String PROVIDER = "SunEC";
|
||||
private static final byte[] MSG = "TEST".getBytes();
|
||||
private static final SecureRandom RND = new SecureRandom(new byte[]{0x1});
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
testParam(PROVIDER, EDDSA);
|
||||
testParam(PROVIDER, ED25519);
|
||||
testParam(PROVIDER, ED448);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Signature.
|
||||
*/
|
||||
private static void testParam(String provider, String name)
|
||||
throws Exception {
|
||||
|
||||
KeyPair kp = genKeyPair(provider, name);
|
||||
Signature sig = Signature.getInstance(name, provider);
|
||||
EdDSAParameterSpec initParam
|
||||
= new EdDSAParameterSpec(true, "testContext".getBytes());
|
||||
sig.setParameter(initParam);
|
||||
byte[] origSign = sign(sig, kp.getPrivate(), MSG);
|
||||
for (boolean preHash : new boolean[]{true, false}) {
|
||||
System.out.printf("Testing signature for name: %s,"
|
||||
+ " algorithm spec: (prehash:%s)%n", name, preHash);
|
||||
verifyPublic(sig, kp.getPublic(), MSG,
|
||||
new EdDSAParameterSpec(preHash), initParam, origSign);
|
||||
// Test Case with Context size combined.
|
||||
// As per rfc8032, value of context is maximum of 255 octet
|
||||
byte[] maxCtx = new byte[255];
|
||||
RND.nextBytes(maxCtx);
|
||||
for (byte[] context : new byte[][]{"others".getBytes(), maxCtx}) {
|
||||
System.out.printf("Testing signature for name: %s,"
|
||||
+ " algorithm spec: (prehash:%s, context:%s)%n",
|
||||
name, preHash, Convert.byteArrayToHexString(context));
|
||||
EdDSAParameterSpec params
|
||||
= new EdDSAParameterSpec(preHash, context);
|
||||
verifyPublic(sig, kp.getPublic(), MSG, params, initParam,
|
||||
origSign);
|
||||
}
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
|
||||
private static KeyPair genKeyPair(String provider, String name)
|
||||
throws Exception {
|
||||
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider);
|
||||
return kpg.generateKeyPair();
|
||||
}
|
||||
|
||||
private static byte[] sign(Signature sig, PrivateKey priKey, byte[] msg)
|
||||
throws Exception {
|
||||
|
||||
sig.initSign(priKey);
|
||||
sig.update(msg);
|
||||
return sig.sign();
|
||||
}
|
||||
|
||||
private static boolean verify(Signature sig, PublicKey pubKey, byte[] msg,
|
||||
byte[] sign) throws Exception {
|
||||
|
||||
sig.initVerify(pubKey);
|
||||
sig.update(msg);
|
||||
return sig.verify(sign);
|
||||
}
|
||||
|
||||
private static void verifyPublic(Signature sig, PublicKey pubKey,
|
||||
byte[] msg, EdDSAParameterSpec params, EdDSAParameterSpec initParam,
|
||||
byte[] origSign) throws Exception {
|
||||
|
||||
sig.setParameter(params);
|
||||
if (verify(sig, pubKey, msg, origSign)) {
|
||||
byte[] context = params.getContext().isPresent()
|
||||
? params.getContext().get() : null;
|
||||
byte[] initContext = initParam.getContext().isPresent()
|
||||
? initParam.getContext().get() : null;
|
||||
boolean preHash = params.isPrehash();
|
||||
boolean initPreHash = initParam.isPrehash();
|
||||
// The signature should not get verified other than same parameter
|
||||
// which is set through the signature instance.
|
||||
if (!(equals(context, initContext) && equals(preHash, initPreHash))) {
|
||||
throw new RuntimeException(String.format("Signature verification"
|
||||
+ " success with different param context(actual:%s, "
|
||||
+ "expected:%s), Prehash(actual:%s, expected:%s)",
|
||||
Convert.byteArrayToHexString(context),
|
||||
Convert.byteArrayToHexString(initContext),
|
||||
preHash, initPreHash));
|
||||
} else {
|
||||
System.out.println("Atleast a case matched");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean equals(Object actual, Object expected) {
|
||||
|
||||
if (actual == expected) {
|
||||
return true;
|
||||
}
|
||||
if (actual == null || expected == null) {
|
||||
return false;
|
||||
}
|
||||
boolean equals = actual.equals(expected);
|
||||
if (!equals) {
|
||||
throw new RuntimeException(String.format("Actual: %s, Expected: %s",
|
||||
actual, expected));
|
||||
}
|
||||
return equals;
|
||||
}
|
||||
|
||||
private static boolean equals(byte[] actual, byte[] expected) {
|
||||
|
||||
if (actual == expected) {
|
||||
return true;
|
||||
}
|
||||
if (actual == null || expected == null) {
|
||||
return false;
|
||||
}
|
||||
boolean equals = Arrays.equals(actual, expected);
|
||||
if (!equals) {
|
||||
throw new RuntimeException(String.format("Actual array: %s, "
|
||||
+ "Expected array:%s", Convert.byteArrayToHexString(actual),
|
||||
Convert.byteArrayToHexString(expected)));
|
||||
}
|
||||
return equals;
|
||||
}
|
||||
|
||||
}
|
133
test/jdk/sun/security/ec/ed/EdDSAReuseTest.java
Normal file
133
test/jdk/sun/security/ec/ed/EdDSAReuseTest.java
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 = "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);
|
||||
}
|
||||
}
|
356
test/jdk/sun/security/ec/ed/EdDSATest.java
Normal file
356
test/jdk/sun/security/ec/ed/EdDSATest.java
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (c) 2020, 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 static javax.crypto.Cipher.PRIVATE_KEY;
|
||||
import static javax.crypto.Cipher.PUBLIC_KEY;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.Key;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.Signature;
|
||||
import java.security.interfaces.EdECPrivateKey;
|
||||
import java.security.interfaces.EdECPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.security.spec.EdECPrivateKeySpec;
|
||||
import java.security.spec.EdECPublicKeySpec;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.NamedParameterSpec;
|
||||
import java.security.spec.EdDSAParameterSpec;
|
||||
import java.util.Arrays;
|
||||
import jdk.test.lib.Convert;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8209632
|
||||
* @summary Test Signature with variation of serialized EDDSA Keys.
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Convert
|
||||
* @run main EdDSATest
|
||||
*/
|
||||
public class EdDSATest {
|
||||
|
||||
private static final String EDDSA = "EdDSA";
|
||||
private static final String ED25519 = "Ed25519";
|
||||
private static final String ED448 = "Ed448";
|
||||
private static final String OIDN25519 = "1.3.101.112";
|
||||
private static final String OID25519 = "OID.1.3.101.112";
|
||||
private static final String OIDN448 = "1.3.101.113";
|
||||
private static final String OID448 = "OID.1.3.101.113";
|
||||
private static final String PROVIDER = "SunEC";
|
||||
private static final byte[] MSG = "TEST".getBytes();
|
||||
private static final SecureRandom S_RND = new SecureRandom(new byte[]{0x1});
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
for (boolean random : new boolean[]{true, false}) {
|
||||
|
||||
// Default Parameter
|
||||
test(PROVIDER, EDDSA, null, random);
|
||||
test(PROVIDER, ED25519, null, random);
|
||||
test(PROVIDER, ED448, null, random);
|
||||
|
||||
// With named parameter
|
||||
test(PROVIDER, EDDSA, ED25519, random);
|
||||
test(PROVIDER, ED25519, ED25519, random);
|
||||
test(PROVIDER, OIDN25519, ED25519, random);
|
||||
test(PROVIDER, OID25519, ED25519, random);
|
||||
test(PROVIDER, ED448, ED448, random);
|
||||
test(PROVIDER, OIDN448, ED448, random);
|
||||
test(PROVIDER, OID448, ED448, random);
|
||||
|
||||
// With size parameter
|
||||
test(PROVIDER, EDDSA, 255, random);
|
||||
test(PROVIDER, ED25519, 255, random);
|
||||
test(PROVIDER, OIDN25519, 255, random);
|
||||
test(PROVIDER, OID25519, 255, random);
|
||||
test(PROVIDER, ED448, 448, random);
|
||||
test(PROVIDER, OIDN448, 448, random);
|
||||
test(PROVIDER, OID448, 448, random);
|
||||
}
|
||||
}
|
||||
|
||||
// Test signature using a KeyPair and the corresponding transformed one.
|
||||
private static void test(String provider, String name, Object param,
|
||||
boolean random) throws Exception {
|
||||
|
||||
System.out.printf("Case Algo:%s, Param:%s, Intitiate with random:%s%n",
|
||||
name, param, random);
|
||||
KeyPair origkp = genKeyPair(provider, name, param, random);
|
||||
testSignature(provider, name, origkp, origkp);
|
||||
NamedParameterSpec namedSpec = namedParamSpec(name);
|
||||
// Test all possible transformed private/public keys
|
||||
for (Key priKey : manipulateKey(provider, name, PRIVATE_KEY,
|
||||
origkp.getPrivate(), namedSpec)) {
|
||||
for (Key pubKey : manipulateKey(provider, name, PUBLIC_KEY,
|
||||
origkp.getPublic(), namedSpec)) {
|
||||
EdECPrivateKey pri = (EdECPrivateKey) priKey;
|
||||
EdECPublicKey pub = (EdECPublicKey) pubKey;
|
||||
// Test the keys are serializable.
|
||||
testSerialize(origkp, new KeyPair(pub, pri));
|
||||
// Test signature
|
||||
testSignature(provider, name, origkp, new KeyPair(pub, pri));
|
||||
}
|
||||
}
|
||||
System.out.println("Passed.");
|
||||
}
|
||||
|
||||
private static KeyPair genKeyPair(String provider, String name,
|
||||
Object param, boolean random) throws Exception {
|
||||
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance(name, provider);
|
||||
if (random) {
|
||||
if (param instanceof Integer) {
|
||||
kpg.initialize((Integer) param, S_RND);
|
||||
} else if (param instanceof String) {
|
||||
kpg.initialize(new NamedParameterSpec((String) param), S_RND);
|
||||
}
|
||||
} else {
|
||||
if (param instanceof Integer) {
|
||||
kpg.initialize((Integer) param);
|
||||
} else if (param instanceof String) {
|
||||
kpg.initialize(new NamedParameterSpec((String) param));
|
||||
}
|
||||
}
|
||||
equals(kpg.getProvider().getName(), provider);
|
||||
equals(kpg.getAlgorithm(), name);
|
||||
return kpg.generateKeyPair();
|
||||
}
|
||||
|
||||
private static NamedParameterSpec namedParamSpec(String algo) {
|
||||
NamedParameterSpec namedSpec = switch (algo) {
|
||||
case EDDSA
|
||||
, OIDN25519, OID25519 -> new NamedParameterSpec(ED25519);
|
||||
case OIDN448
|
||||
, OID448 -> new NamedParameterSpec(ED448);
|
||||
default->
|
||||
new NamedParameterSpec(algo);
|
||||
};
|
||||
return namedSpec;
|
||||
}
|
||||
|
||||
private static Key[] manipulateKey(String provider, String name, int type,
|
||||
Key key, NamedParameterSpec namedSpec)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException,
|
||||
NoSuchProviderException, InvalidKeyException {
|
||||
|
||||
KeyFactory kf = KeyFactory.getInstance(name, provider);
|
||||
switch (type) {
|
||||
case PUBLIC_KEY:
|
||||
return new Key[]{
|
||||
kf.generatePublic(new X509EncodedKeySpec(key.getEncoded())),
|
||||
kf.generatePublic(kf.getKeySpec(
|
||||
key, EdECPublicKeySpec.class)),
|
||||
kf.generatePublic(new EdECPublicKeySpec(namedSpec,
|
||||
((EdECPublicKey) key).getPoint())),
|
||||
kf.translateKey(key)
|
||||
};
|
||||
case PRIVATE_KEY:
|
||||
return new Key[]{
|
||||
kf.generatePrivate(new PKCS8EncodedKeySpec(key.getEncoded())),
|
||||
kf.generatePrivate(
|
||||
kf.getKeySpec(key, EdECPrivateKeySpec.class)),
|
||||
kf.generatePrivate(new EdECPrivateKeySpec(namedSpec,
|
||||
((EdECPrivateKey) key).getBytes().get())),
|
||||
kf.translateKey(key)
|
||||
};
|
||||
}
|
||||
throw new RuntimeException("We shouldn't reach here");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Signature with a set of parameter combination.
|
||||
*/
|
||||
private static void testSignature(String provider, String name,
|
||||
KeyPair origkp, KeyPair kp) throws Exception {
|
||||
|
||||
signAndVerify(provider, name, origkp, kp, null);
|
||||
// Test Case with Pre-Hash enabled and disabled.
|
||||
for (boolean preHash : new boolean[]{true, false}) {
|
||||
signAndVerify(provider, name, origkp, kp,
|
||||
new EdDSAParameterSpec(preHash));
|
||||
// Test Case with Context combined.
|
||||
for (byte[] context : new byte[][]{
|
||||
{}, "a".getBytes(), new byte[255]}) {
|
||||
signAndVerify(provider, name, origkp, kp,
|
||||
new EdDSAParameterSpec(preHash, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void signAndVerify(String provider, String name,
|
||||
KeyPair origkp, KeyPair kp, EdDSAParameterSpec params)
|
||||
throws Exception {
|
||||
|
||||
Signature sig = Signature.getInstance(name, provider);
|
||||
if (params != null) {
|
||||
sig.setParameter(params);
|
||||
}
|
||||
sig.initSign(origkp.getPrivate());
|
||||
sig.update(MSG);
|
||||
byte[] origSign = sig.sign();
|
||||
|
||||
sig.update(MSG);
|
||||
byte[] computedSig = sig.sign();
|
||||
equals(origSign, computedSig);
|
||||
// EdDSA signatures size (64 and 114 bytes) for Ed25519 and Ed448.
|
||||
int expectedSigSize = edSignatureSize(name);
|
||||
equals(origSign.length, expectedSigSize);
|
||||
sig.initSign(kp.getPrivate());
|
||||
sig.update(MSG);
|
||||
equals(computedSig, sig.sign());
|
||||
// Use same signature instance to verify with transformed PublicKey.
|
||||
sig.initVerify(kp.getPublic());
|
||||
sig.update(MSG);
|
||||
if (!sig.verify(origSign)) {
|
||||
throw new RuntimeException(String.format("Signature did not verify"
|
||||
+ " for name:%s, prehash:%s, context:%s", name,
|
||||
(params == null) ? null : params.isPrehash(),
|
||||
(params == null) ? null : params.getContext().get()));
|
||||
}
|
||||
|
||||
// Create a new signature to re-verify.
|
||||
sig = Signature.getInstance(name, provider);
|
||||
if (params != null) {
|
||||
sig.setParameter(params);
|
||||
}
|
||||
// Verify the signature with transformed PublicKey.
|
||||
sig.initVerify(kp.getPublic());
|
||||
sig.update(MSG);
|
||||
if (!sig.verify(origSign)) {
|
||||
throw new RuntimeException(String.format("Signature did not verify"
|
||||
+ " for name:%s, prehash:%s, context:%s",
|
||||
name, (params == null) ? null : params.isPrehash(),
|
||||
(params == null) ? null : params.getContext().get()));
|
||||
}
|
||||
equals(sig.getAlgorithm(), name);
|
||||
equals(sig.getProvider().getName(), provider);
|
||||
}
|
||||
|
||||
private static int edSignatureSize(String algo) {
|
||||
int size = switch (algo) {
|
||||
case EDDSA
|
||||
, ED25519, OIDN25519, OID25519 -> 64;
|
||||
case ED448
|
||||
, OIDN448, OID448 -> 114;
|
||||
default->
|
||||
-1;
|
||||
};
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare original KeyPair with transformed ones.
|
||||
*/
|
||||
private static void testKeyEquals(KeyPair origkp, PublicKey pubKey,
|
||||
PrivateKey priKey) {
|
||||
|
||||
if (!origkp.getPrivate().equals(priKey)
|
||||
&& !Arrays.equals(origkp.getPrivate().getEncoded(),
|
||||
priKey.getEncoded())
|
||||
&& origkp.getPrivate().hashCode() != priKey.hashCode()) {
|
||||
throw new RuntimeException(
|
||||
"PrivateKey is not equal with transformed one");
|
||||
}
|
||||
if (!origkp.getPublic().equals(pubKey)
|
||||
&& !Arrays.equals(origkp.getPublic().getEncoded(),
|
||||
pubKey.getEncoded())
|
||||
&& origkp.getPublic().hashCode() != pubKey.hashCode()) {
|
||||
throw new RuntimeException(
|
||||
"PublicKey is not equal with transformed one");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test serialization of KeyPair and Keys.
|
||||
*/
|
||||
private static void testSerialize(KeyPair origkp, KeyPair kp)
|
||||
throws Exception {
|
||||
|
||||
testKeyEquals(origkp, kp.getPublic(), kp.getPrivate());
|
||||
PrivateKey priv = deserializedCopy(kp.getPrivate(), PrivateKey.class);
|
||||
PublicKey pub = deserializedCopy(kp.getPublic(), PublicKey.class);
|
||||
testKeyEquals(origkp, pub, priv);
|
||||
// Verify Serialized KeyPair instance.
|
||||
KeyPair copy = deserializedCopy(kp, KeyPair.class);
|
||||
testKeyEquals(origkp, copy.getPublic(), copy.getPrivate());
|
||||
}
|
||||
|
||||
private static <T extends Object> T deserializedCopy(T origkp, Class<T> type)
|
||||
throws IOException, ClassNotFoundException {
|
||||
return deserialize(serialize(origkp), type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deserialize the Key object.
|
||||
*/
|
||||
private static <T extends Object> T deserialize(byte[] serialized,
|
||||
Class<T> type) throws IOException, ClassNotFoundException {
|
||||
|
||||
T key = null;
|
||||
try (ByteArrayInputStream bis = new ByteArrayInputStream(serialized);
|
||||
ObjectInputStream ois = new ObjectInputStream(bis)) {
|
||||
key = (T) ois.readObject();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serialize the given Key object.
|
||||
*/
|
||||
private static <T extends Object> byte[] serialize(T key)
|
||||
throws IOException {
|
||||
|
||||
try (ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(bos)) {
|
||||
oos.writeObject(key);
|
||||
return bos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
private static void equals(Object actual, Object expected) {
|
||||
if (!actual.equals(expected)) {
|
||||
throw new RuntimeException(String.format("Actual: %s, Expected: %s",
|
||||
actual, expected));
|
||||
}
|
||||
}
|
||||
|
||||
private static void equals(byte[] actual, byte[] expected) {
|
||||
if (!Arrays.equals(actual, expected)) {
|
||||
throw new RuntimeException(String.format("Actual array: %s, "
|
||||
+ "Expected array:%s", Convert.byteArrayToHexString(actual),
|
||||
Convert.byteArrayToHexString(expected)));
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user