/* * Copyright (c) 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. */ /* * @test * @bug 8340327 * @modules java.base/sun.security.x509 * java.base/sun.security.pkcs * java.base/sun.security.provider * java.base/sun.security.util * @library /test/lib */ import jdk.test.lib.Asserts; import jdk.test.lib.Utils; import jdk.test.lib.security.SeededSecureRandom; import sun.security.pkcs.NamedPKCS8Key; import sun.security.provider.NamedKeyFactory; import sun.security.provider.NamedKeyPairGenerator; import sun.security.util.RawKeySpec; import sun.security.x509.NamedX509Key; import java.security.*; import java.security.spec.*; public class NamedKeyFactoryTest { private static final SeededSecureRandom RAND = SeededSecureRandom.one(); public static void main(String[] args) throws Exception { Security.addProvider(new ProviderImpl()); var g = KeyPairGenerator.getInstance("sHA"); var g2 = KeyPairGenerator.getInstance("ShA-256"); var g5 = KeyPairGenerator.getInstance("SHa-512"); var kf = KeyFactory.getInstance("ShA"); var kf2 = KeyFactory.getInstance("Sha-256"); var kf5 = KeyFactory.getInstance("Sha-512"); checkKeyPair(g.generateKeyPair(), "SHA", "SHA-256"); checkKeyPair(g2.generateKeyPair(), "SHA", "SHA-256"); checkKeyPair(g5.generateKeyPair(), "SHA", "SHA-512"); checkKeyPair(g.generateKeyPair(), "SHA", "SHA-256"); checkKeyPair(g2.generateKeyPair(), "SHA", "SHA-256"); checkKeyPair(g5.generateKeyPair(), "SHA", "SHA-512"); Utils.runAndCheckException(() -> g.initialize(NamedParameterSpec.ED448), InvalidAlgorithmParameterException.class); // wrong pname Utils.runAndCheckException(() -> g.initialize(new NamedParameterSpec("SHA-384")), InvalidAlgorithmParameterException.class); // wrong pname Utils.runAndCheckException(() -> g5.initialize(new NamedParameterSpec("SHA-256")), InvalidAlgorithmParameterException.class); // diff pname g5.initialize(new NamedParameterSpec("SHA-512")); g.initialize(new NamedParameterSpec("sHA-512")); checkKeyPair(g.generateKeyPair(), "SHA", "SHA-512"); g.initialize(new NamedParameterSpec("ShA-256")); checkKeyPair(g.generateKeyPair(), "SHA", "SHA-256"); var pk = new NamedX509Key("sHa", "ShA-256", RAND.nBytes(2)); var sk = new NamedPKCS8Key("sHa", "SHa-256", RAND.nBytes(2)); checkKey(pk, "sHa", "ShA-256"); checkKey(sk, "sHa", "SHa-256"); Asserts.assertEquals("X.509", pk.getFormat()); Asserts.assertEquals("PKCS#8", sk.getFormat()); var pkSpec = kf.getKeySpec(pk, X509EncodedKeySpec.class); var skSpec = kf.getKeySpec(sk, PKCS8EncodedKeySpec.class); kf2.getKeySpec(pk, X509EncodedKeySpec.class); kf2.getKeySpec(sk, PKCS8EncodedKeySpec.class); Utils.runAndCheckException(() -> kf5.getKeySpec(pk, X509EncodedKeySpec.class), InvalidKeySpecException.class); // wrong KF Utils.runAndCheckException(() -> kf5.getKeySpec(sk, PKCS8EncodedKeySpec.class), InvalidKeySpecException.class); Utils.runAndCheckException(() -> kf.getKeySpec(pk, PKCS8EncodedKeySpec.class), InvalidKeySpecException.class); // wrong KeySpec Utils.runAndCheckException(() -> kf.getKeySpec(sk, X509EncodedKeySpec.class), InvalidKeySpecException.class); checkKey(kf.generatePublic(pkSpec), "SHA", "SHA-256"); Utils.runAndCheckException(() -> kf.generatePrivate(pkSpec), InvalidKeySpecException.class); checkKey(kf.generatePrivate(skSpec), "SHA", "SHA-256"); Utils.runAndCheckException(() -> kf.generatePublic(skSpec), InvalidKeySpecException.class); checkKey(kf2.generatePrivate(skSpec), "SHA", "SHA-256"); checkKey(kf2.generatePublic(pkSpec), "SHA", "SHA-256"); Utils.runAndCheckException(() -> kf5.generatePublic(pkSpec), InvalidKeySpecException.class); // wrong KF Utils.runAndCheckException(() -> kf5.generatePublic(skSpec), InvalidKeySpecException.class); // The private RawKeySpec and unnamed RAW EncodedKeySpec var prk = kf.getKeySpec(pk, RawKeySpec.class); Asserts.assertEqualsByteArray(prk.getKeyArr(), pk.getRawBytes()); var prk2 = kf.getKeySpec(pk, EncodedKeySpec.class); Asserts.assertEquals("RAW", prk2.getFormat()); Asserts.assertEqualsByteArray(prk.getKeyArr(), prk2.getEncoded()); Asserts.assertEqualsByteArray(kf2.generatePublic(prk).getEncoded(), pk.getEncoded()); Utils.runAndCheckException(() -> kf.generatePublic(prk), InvalidKeySpecException.class); // no pname Asserts.assertEqualsByteArray(kf2.generatePublic(prk2).getEncoded(), pk.getEncoded()); Utils.runAndCheckException(() -> kf.generatePublic(prk2), InvalidKeySpecException.class); // no pname var srk = kf.getKeySpec(sk, RawKeySpec.class); Asserts.assertEqualsByteArray(srk.getKeyArr(), sk.getRawBytes()); var srk2 = kf.getKeySpec(sk, EncodedKeySpec.class); Asserts.assertEquals("RAW", srk2.getFormat()); Asserts.assertEqualsByteArray(srk2.getEncoded(), sk.getRawBytes()); Asserts.assertEqualsByteArray(kf2.generatePrivate(srk).getEncoded(), sk.getEncoded()); Utils.runAndCheckException(() -> kf.generatePrivate(srk), InvalidKeySpecException.class); // no pname Asserts.assertEqualsByteArray(kf2.generatePrivate(srk2).getEncoded(), sk.getEncoded()); Utils.runAndCheckException(() -> kf.generatePrivate(srk2), InvalidKeySpecException.class); // no pname var pk1 = new PublicKey() { public String getAlgorithm() { return "SHA"; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { return RAND.nBytes(2); } }; var pk2 = new PublicKey() { public String getAlgorithm() { return "sHA-256"; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { return RAND.nBytes(2); } }; var pk3 = new PublicKey() { public String getAlgorithm() { return "SHA"; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { return RAND.nBytes(2); } public AlgorithmParameterSpec getParams() { return new NamedParameterSpec("sHA-256"); } }; checkKey(kf2.translateKey(pk1), "SHA", "SHA-256"); checkKey(kf.translateKey(pk2), "SHA", "SHA-256"); checkKey(kf.translateKey(pk3), "SHA", "SHA-256"); Utils.runAndCheckException(() -> kf.translateKey(pk1), InvalidKeyException.class); Utils.runAndCheckException(() -> kf5.translateKey(pk2), InvalidKeyException.class); Utils.runAndCheckException(() -> kf5.translateKey(pk3), InvalidKeyException.class); var sk1 = new PrivateKey() { public String getAlgorithm() { return "SHA"; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { return RAND.nBytes(2); } }; var sk2 = new PrivateKey() { public String getAlgorithm() { return "sHA-256"; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { return RAND.nBytes(2); } }; var sk3 = new PrivateKey() { public String getAlgorithm() { return "SHA"; } public String getFormat() { return "RAW"; } public byte[] getEncoded() { return RAND.nBytes(2); } public AlgorithmParameterSpec getParams() { return new NamedParameterSpec("sHA-256"); } }; checkKey(kf2.translateKey(sk1), "SHA", "SHA-256"); checkKey(kf.translateKey(sk2), "SHA", "SHA-256"); checkKey(kf.translateKey(sk3), "SHA", "SHA-256"); Utils.runAndCheckException(() -> kf.translateKey(sk1), InvalidKeyException.class); Utils.runAndCheckException(() -> kf5.translateKey(sk2), InvalidKeyException.class); Utils.runAndCheckException(() -> kf5.translateKey(sk3), InvalidKeyException.class); } static void checkKeyPair(KeyPair kp, String algName, String toString) { checkKey(kp.getPrivate(), algName, toString); checkKey(kp.getPublic(), algName, toString); } static void checkKey(Key k, String algName, String pname) { Asserts.assertEquals(algName, k.getAlgorithm()); Asserts.assertTrue(k.toString().contains(pname)); if (k instanceof AsymmetricKey ak && ak.getParams() instanceof NamedParameterSpec nps) { Asserts.assertEquals(pname, nps.getName()); } } // Provider public static class ProviderImpl extends Provider { public ProviderImpl() { super("P", "1", "..."); put("KeyFactory.SHA", KF.class.getName()); put("KeyFactory.SHA-256", KF1.class.getName()); put("KeyFactory.SHA-512", KF2.class.getName()); put("KeyPairGenerator.SHA", KPG.class.getName()); put("KeyPairGenerator.SHA-256", KPG1.class.getName()); put("KeyPairGenerator.SHA-512", KPG2.class.getName()); } } public static class KF extends NamedKeyFactory { public KF() { super("SHA", "SHA-256", "SHA-512"); } } public static class KF1 extends NamedKeyFactory { public KF1() { super("SHA", "SHA-256"); } } public static class KF2 extends NamedKeyFactory { public KF2() { super("SHA", "SHA-512"); } } public static class KPG extends NamedKeyPairGenerator { public KPG() { super("SHA", "SHA-256", "SHA-512"); } public KPG(String pname) { super("SHA", pname); } @Override public byte[][] implGenerateKeyPair(String name, SecureRandom sr) { var out = new byte[2][]; out[0] = RAND.nBytes(name.endsWith("256") ? 2 : 4); out[1] = RAND.nBytes(name.endsWith("256") ? 2 : 4); return out; } } public static class KPG1 extends KPG { public KPG1() { super("SHA-256"); } } public static class KPG2 extends KPG { public KPG2() { super("SHA-512"); } } }