Path: blob/master/test/jdk/sun/security/ec/ed/EdDSAKeyCompatibility.java
41152 views
/*1* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223import java.io.ByteArrayInputStream;24import java.io.IOException;25import java.math.BigInteger;26import java.security.InvalidKeyException;27import java.security.KeyFactory;28import java.security.NoSuchAlgorithmException;29import java.security.NoSuchProviderException;30import java.security.cert.Certificate;31import java.security.cert.CertificateException;32import java.security.cert.CertificateFactory;33import java.util.Base64;34import sun.security.util.DerValue;35import java.security.interfaces.EdECPrivateKey;36import java.security.interfaces.EdECPublicKey;37import java.security.spec.EdECPrivateKeySpec;38import java.security.spec.EdECPublicKeySpec;39import java.security.spec.InvalidKeySpecException;40import java.security.spec.NamedParameterSpec;41import java.security.spec.PKCS8EncodedKeySpec;42import java.security.spec.X509EncodedKeySpec;4344/*45* @test46* @bug 820963247* @summary OpenSSL generated compatibility test with EDDSA Java.48* @modules java.base/sun.security.util49* @run main EdDSAKeyCompatibility50*/51public class EdDSAKeyCompatibility {5253private static final String EDDSA = "EdDSA";54private static final String ED25519 = "Ed25519";55private static final String ED448 = "Ed448";56private static final String PROVIDER = "SunEC";5758public static void main(String[] args) throws Exception {5960boolean result = true;61result &= validateCert(EDDSA, PROVIDER, ED25519CERT);62result &= validateCert(EDDSA, PROVIDER, ED448CERT);63result &= validateCert(ED25519, PROVIDER, ED25519CERT);64result &= validateCert(ED448, PROVIDER, ED448CERT);6566result &= validatePrivate(ED25519, PROVIDER, ED25519KEY);67result &= validatePrivate(ED448, PROVIDER, ED448KEY);6869if (!result) {70throw new RuntimeException("Some test cases failed");71}72}7374private static boolean validatePrivate(String algorithm, String provider,75String key) {7677try {78KeyFactory kf = KeyFactory.getInstance(algorithm, provider);79PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(80Base64.getMimeDecoder().decode(key));81EdECPrivateKey privKey82= (EdECPrivateKey) kf.generatePrivate(privSpec);83checkPrivKeyFormat(privKey.getEncoded());8485NamedParameterSpec namedSpec = new NamedParameterSpec(algorithm);86EdECPrivateKeySpec edprivSpec = new EdECPrivateKeySpec(87namedSpec, privKey.getBytes().get());88EdECPrivateKey privKey189= (EdECPrivateKey) kf.generatePrivate(edprivSpec);90checkPrivKeyFormat(privKey1.getEncoded());91EdECPrivateKey privKey2 = (EdECPrivateKey) kf.translateKey(privKey);92checkPrivKeyFormat(privKey2.getEncoded());93equals(privKey, privKey1);94equals(privKey, privKey2);95} catch (NoSuchAlgorithmException | InvalidKeySpecException | IOException96| NoSuchProviderException | InvalidKeyException e) {97e.printStackTrace(System.out);98return false;99}100System.out.println("PASSED - validatePrivate");101return true;102}103104private static boolean validateCert(String algorithm, String provider,105String certificate) {106107try {108CertificateFactory cf = CertificateFactory.getInstance("X.509");109Certificate cert = cf.generateCertificate(110new ByteArrayInputStream(certificate.getBytes()));111System.out.println(cert);112KeyFactory kf = KeyFactory.getInstance(algorithm, provider);113X509EncodedKeySpec pubSpec = kf.getKeySpec(114cert.getPublicKey(), X509EncodedKeySpec.class);115EdECPublicKey pubKey = (EdECPublicKey) kf.generatePublic(pubSpec);116EdECPublicKeySpec edpubSpec = kf.getKeySpec(117cert.getPublicKey(), EdECPublicKeySpec.class);118EdECPublicKey pubKey1 = (EdECPublicKey) kf.generatePublic(edpubSpec);119EdECPublicKey pubKey2 = (EdECPublicKey) kf.translateKey(pubKey);120equals(pubKey, pubKey1);121equals(pubKey, pubKey2);122equals(pubKey, cert.getPublicKey());123} catch (CertificateException | NoSuchAlgorithmException124| InvalidKeySpecException | NoSuchProviderException125| InvalidKeyException e) {126e.printStackTrace(System.out);127return false;128}129System.out.println("PASSED - validateCert");130return true;131}132133private static void checkPrivKeyFormat(byte[] key) throws IOException {134135// key value should be nested octet strings136DerValue val = new DerValue(new ByteArrayInputStream(key));137BigInteger version = val.data.getBigInteger();138DerValue algId = val.data.getDerValue();139byte[] keyValue = val.data.getOctetString();140val = new DerValue(new ByteArrayInputStream(keyValue));141if (val.tag != DerValue.tag_OctetString) {142throw new RuntimeException("incorrect format");143}144}145146private static void equals(Object actual, Object expected) {147if (!actual.equals(expected)) {148throw new RuntimeException(String.format("Actual: %s, Expected: %s",149actual, expected));150}151}152153// Following EdDSA Certificates/Keys are generated through openssl_1.1.1d154155/*156* Certificate:157* Data:158* Version: 3 (0x2)159* Serial Number:160* 1d:d3:87:b9:e4:c6:9e:4a:5c:78:a8:f0:c7:9b:37:be:1e:31:dd:20161* Signature Algorithm: ED25519162* Issuer: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost163* Validity164* Not Before: Mar 6 05:55:31 2020 GMT165* Not After : Mar 1 05:55:31 2040 GMT166* Subject: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost167* Subject Public Key Info:168* Public Key Algorithm: ED25519169*/170private static final String ED25519KEY171= "MC4CAQAwBQYDK2VwBCIEIP8xGaQTMh+I+59I66AaN+B4qnY1oWGjPwbSY4r+D08f";172173private static final String ED25519CERT174= "-----BEGIN CERTIFICATE-----\n"175+ "MIIByTCCAXugAwIBAgIUHdOHueTGnkpceKjwx5s3vh4x3SAwBQYDK2VwMFoxCzAJ\n"176+ "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0NBMQ0wCwYDVQQKDAR0\n"177+ "ZXN0MQ0wCwYDVQQLDAR0ZXN0MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwMzA2\n"178+ "MDU1NTMxWhcNNDAwMzAxMDU1NTMxWjBaMQswCQYDVQQGEwJVUzELMAkGA1UECAwC\n"179+ "Q0ExDDAKBgNVBAcMA1NDQTENMAsGA1UECgwEdGVzdDENMAsGA1UECwwEdGVzdDES\n"180+ "MBAGA1UEAwwJbG9jYWxob3N0MCowBQYDK2VwAyEAdqQ4Nduhbl+ShGeKdOryVMKy\n"181+ "1t1LjyjPyCBC+gSk0eCjUzBRMB0GA1UdDgQWBBS01/VQEzwkFNRW/esQxaB6+uId\n"182+ "8jAfBgNVHSMEGDAWgBS01/VQEzwkFNRW/esQxaB6+uId8jAPBgNVHRMBAf8EBTAD\n"183+ "AQH/MAUGAytlcANBAEJkLuNfyVws7HKqHL7oDqQkp5DSwh+bGjrr2p4zSvs5PZ8o\n"184+ "jRXWV0SMt/MB+90ubMD5tL7H7J6DR5PUFBIwGwc=\n"185+ "-----END CERTIFICATE-----";186187/*188* Certificate:189* Data:190* Version: 3 (0x2)191* Serial Number:192* 42:eb:8c:a2:a0:6f:8e:5a:a5:f8:7c:72:c1:f1:8b:7e:44:1b:37:80193* Signature Algorithm: ED448194* Issuer: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost195* Validity196* Not Before: Mar 6 05:57:42 2020 GMT197* Not After : Mar 1 05:57:42 2040 GMT198* Subject: C = US, ST = CA, L = SCA, O = test, OU = test, CN = localhost199* Subject Public Key Info:200* Public Key Algorithm: ED448201*/202private static final String ED448KEY203= "MEcCAQAwBQYDK2VxBDsEOdG4lrYO0xBaf3aJWYMZ8XAxitA1zV4/ghG8wPBag8HQ"204+ "XN+3OmS8wR1KfeGQysHQr3JHco3Mwiaz8w==";205206private static final String ED448CERT207= "-----BEGIN CERTIFICATE-----\n"208+ "MIICFDCCAZSgAwIBAgIUQuuMoqBvjlql+HxywfGLfkQbN4AwBQYDK2VxMFoxCzAJ\n"209+ "BgNVBAYTAlVTMQswCQYDVQQIDAJDQTEMMAoGA1UEBwwDU0NBMQ0wCwYDVQQKDAR0\n"210+ "ZXN0MQ0wCwYDVQQLDAR0ZXN0MRIwEAYDVQQDDAlsb2NhbGhvc3QwHhcNMjAwMzA2\n"211+ "MDU1NzQyWhcNNDAwMzAxMDU1NzQyWjBaMQswCQYDVQQGEwJVUzELMAkGA1UECAwC\n"212+ "Q0ExDDAKBgNVBAcMA1NDQTENMAsGA1UECgwEdGVzdDENMAsGA1UECwwEdGVzdDES\n"213+ "MBAGA1UEAwwJbG9jYWxob3N0MEMwBQYDK2VxAzoAfKlXpT0ymcvz2Gp+8HLzBpaz\n"214+ "5mQqMaDbGmcq8gSIdeEUtVmv4OplE+4GSnrbJnEn99LQdbanL/MAo1MwUTAdBgNV\n"215+ "HQ4EFgQUXkm9LVUkB0f/1MiPFjQPHGJ8THIwHwYDVR0jBBgwFoAUXkm9LVUkB0f/\n"216+ "1MiPFjQPHGJ8THIwDwYDVR0TAQH/BAUwAwEB/zAFBgMrZXEDcwDvE3LKCg1bTjHi\n"217+ "MI1EiMqZN3PJYVBsztecBXm3ELDlT+F0Z1H2vjaROkJc8PdpUOxyed1xDjwq3IB/\n"218+ "nYYJNVyt6Dy3d12kl77ev+YMD83OuqM6F5O6MdDUxYQu9u3NasZAU5FQ6zklWWpI\n"219+ "8jCPtOvcAQA=\n"220+ "-----END CERTIFICATE-----";221}222223224