undefect. CWE-407 — 63 sites patched across 27 ecosystems

Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com

Patches, unit tests, benchmarks, whitepaper, and outreach briefs.
Public domain — no copyright claimed. Use freely.
This commit is contained in:
russell@unturf.com 2026-03-26 17:11:57 -04:00
commit 0a580b313d
70422 changed files with 17213626 additions and 0 deletions

Binary file not shown.

View file

@ -0,0 +1,66 @@
/*
* Copyright (c) 2022, 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 jdk.test.lib.Asserts;
import jdk.test.lib.SecurityTools;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
/*
* @test
* @bug 6782021
* @requires os.family == "windows"
* @library /test/lib
* @summary More keystore types
*/
public class AllTypes {
public static void main(String[] args) throws Exception {
var nm = test("windows-my");
var nr = test("windows-root");
var nmu = test("windows-my-currentuser");
var nru = test("windows-root-currentuser");
var nmm = test("windows-my-localmachine");
var nrm = test("windows-root-localmachine");
Asserts.assertEQ(nm, nmu);
Asserts.assertEQ(nr, nru);
}
private static List<String> test(String type) throws Exception {
var stdType = "Windows-" + type.substring(8).toUpperCase(Locale.ROOT);
SecurityTools.keytool("-storetype " + type + " -list")
.shouldHaveExitValue(0)
.shouldContain("Keystore provider: SunMSCAPI")
.shouldContain("Keystore type: " + stdType);
KeyStore ks = KeyStore.getInstance(type);
ks.load(null, null);
var content = Collections.list(ks.aliases());
Collections.sort(content);
return content;
}
}

View file

@ -0,0 +1,52 @@
/*
* Copyright (c) 2015, 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.File;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
/**
* @test
* @bug 8143913
* @requires os.family == "windows"
* @summary MSCAPI keystore should accept Certificate[] in setEntry()
*/
public class CastError {
public static void main(String[] args) throws Exception {
KeyStore ks = KeyStore.getInstance(
new File(System.getProperty("test.src"),
"../tools/jarsigner/JarSigning.keystore"),
"bbbbbb".toCharArray());
PrivateKey pk = (PrivateKey) ks.getKey("c", "bbbbbb".toCharArray());
Certificate cert = ks.getCertificate("c");
ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
ks.setKeyEntry("8143913", pk, null, new Certificate[]{cert});
ks.deleteEntry("8143913");
}
}

View file

@ -0,0 +1,107 @@
/*
* Copyright (c) 2021, 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 jdk.test.lib.Asserts;
import jdk.test.lib.SecurityTools;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.security.KeyStore;
/**
* @test
* @bug 8251134
* @requires os.family == "windows"
* @summary Cipher operations on CNG keys
* @library /test/lib
*/
public class CngCipher {
final static String PREFIX = "8251134";
public static void main(String[] args) throws Exception {
cleanup();
prepare();
try {
test(PREFIX + "m");
test(PREFIX + "c");
} finally {
cleanup();
}
}
static void prepare() throws Exception {
// This will generate a MSCAPI key
SecurityTools.keytool("-storetype Windows-MY -genkeypair -alias "
+ PREFIX + "m -keyalg RSA -dname CN=" + PREFIX + "m");
// This will generate a CNG key
ProcessBuilder pb = new ProcessBuilder("powershell", "-Command",
"New-SelfSignedCertificate", "-DnsName", PREFIX + "c",
// -KeyAlgorithm not supported on Windows Server 2012
//"-KeyAlgorithm", "RSA",
"-CertStoreLocation", "Cert:\\CurrentUser\\My");
pb.inheritIO();
pb.start().waitFor();
}
static void cleanup() throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
ks.deleteEntry(PREFIX +"c");
ks.deleteEntry(PREFIX +"m");
ks.store(null, null);
}
static void test(String alias) throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
var alg = "RSA/ECB/PKCS1Padding";
var k1 = ks.getKey(alias, "changeit".toCharArray());
var k2 = ks.getCertificate(alias).getPublicKey();
Cipher c;
var k = KeyGenerator.getInstance("AES").generateKey();
c = Cipher.getInstance(alg, "SunMSCAPI");
c.init(Cipher.WRAP_MODE, k2);
var enc = c.wrap(k);
c = Cipher.getInstance(alg, "SunMSCAPI");
c.init(Cipher.UNWRAP_MODE, k1);
var dec = c.unwrap(enc, "AES", Cipher.SECRET_KEY);
Asserts.assertTrue(Arrays.equals(k.getEncoded(), dec.getEncoded()));
c = Cipher.getInstance(alg, "SunMSCAPI");
c.init(Cipher.ENCRYPT_MODE, k2);
byte[] msg = "hello you fool".getBytes(java.nio.charset.StandardCharsets.UTF_8);
c.update(msg);
var enc2 = c.doFinal();
c = Cipher.getInstance(alg, "SunMSCAPI");
c.init(Cipher.DECRYPT_MODE, k1);
c.update(enc2);
var dec2 = c.doFinal();
Asserts.assertTrue(Arrays.equals(msg, dec2));
}
}

View file

@ -0,0 +1,97 @@
/*
* 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 jdk.test.lib.Asserts;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.cert.X509Certificate;
import java.util.HexFormat;
/**
* @test
* @bug 8187634
* @requires os.family == "windows"
* @library /test/lib
* @modules java.base/sun.security.tools.keytool
* java.base/sun.security.x509
* @summary getCertificateAlias should return correct alias
*/
public class DupAlias {
public static void main(String[] args) throws Exception {
String nn = "8187634";
String na = nn + "a";
String nb = nn + "b";
String n1 = nn + " (1)";
CertAndKeyGen g = new CertAndKeyGen("EC", "SHA256withECDSA");
g.generate(-1);
X509Certificate a = g.getSelfCertificate(new X500Name("CN=" + na), 1000);
g.generate(-1);
X509Certificate b = g.getSelfCertificate(new X500Name("CN=" + nb), 1000);
KeyStore ks = KeyStore.getInstance("Windows-MY-CURRENTUSER");
try {
ks.load(null, null);
ks.deleteEntry(na);
ks.deleteEntry(nb);
ks.deleteEntry(nn);
ks.deleteEntry(n1);
ks.setCertificateEntry(na, a);
ks.setCertificateEntry(nb, b);
ps(String.format("""
$cert = Get-Item Cert:/CurrentUser/My/%s;
$cert.FriendlyName = %s;
$cert = Get-Item Cert:/CurrentUser/My/%s;
$cert.FriendlyName = %s;
""", thumbprint(a), nn, thumbprint(b), nn));
ks.load(null, null);
Asserts.assertFalse(ks.containsAlias(na));
Asserts.assertFalse(ks.containsAlias(nb));
Asserts.assertEquals(ks.getCertificateAlias(ks.getCertificate(nn)), nn);
Asserts.assertEquals(ks.getCertificateAlias(ks.getCertificate(n1)), n1);
} finally {
ks.deleteEntry(na);
ks.deleteEntry(nb);
ks.deleteEntry(nn);
ks.deleteEntry(n1);
}
}
static void ps(String f) throws Exception {
ProcessBuilder pb = new ProcessBuilder("powershell", "-Command", f);
pb.inheritIO();
if (pb.start().waitFor() != 0) {
throw new RuntimeException("Failed");
}
}
static String thumbprint(X509Certificate c) throws Exception {
return HexFormat.of().formatHex(
MessageDigest.getInstance("SHA-1").digest(c.getEncoded()));
}
}

View file

@ -0,0 +1,48 @@
/*
* 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.KeyPairGenerator;
import java.security.PublicKey;
/*
* @test
* @bug 8308808
* @requires os.family == "windows"
* @modules jdk.crypto.mscapi
* @run main EncodingMutability
*/
public class EncodingMutability {
public static void main(String[] args) throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", "SunMSCAPI");
PublicKey publicKey = keyGen.generateKeyPair().getPublic();
byte initialByte = publicKey.getEncoded()[0];
publicKey.getEncoded()[0] = 0;
byte mutatedByte = publicKey.getEncoded()[0];
if (initialByte != mutatedByte) {
System.out.println("Was able to mutate first byte of pubkey from " + initialByte + " to " + mutatedByte);
throw new RuntimeException("Pubkey was mutated via getEncoded");
}
}
}

View file

@ -0,0 +1,173 @@
/*
* Copyright (c) 2018, 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 8205445 8314148
* @summary Interop test between SunMSCAPI and SunRsaSign on RSASSA-PSS
* @requires os.family == "windows"
*/
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.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;
import java.util.Random;
public class InteropWithSunRsaSign {
private static final SecureRandom NOT_SECURE_RANDOM = new SecureRandom() {
Random r = new Random();
@Override
public void nextBytes(byte[] bytes) {
r.nextBytes(bytes);
}
};
private static boolean allResult = true;
private static byte[] msg = "hello".getBytes();
public static void main(String[] args) throws Exception {
matrix(new PSSParameterSpec(
"SHA-1",
"MGF1",
MGF1ParameterSpec.SHA1,
20,
PSSParameterSpec.TRAILER_FIELD_BC));
matrix(new PSSParameterSpec(
"SHA-256",
"MGF1",
MGF1ParameterSpec.SHA256,
32,
PSSParameterSpec.TRAILER_FIELD_BC));
matrix(new PSSParameterSpec(
"SHA-384",
"MGF1",
MGF1ParameterSpec.SHA384,
48,
PSSParameterSpec.TRAILER_FIELD_BC));
matrix(new PSSParameterSpec(
"SHA-512",
"MGF1",
MGF1ParameterSpec.SHA512,
64,
PSSParameterSpec.TRAILER_FIELD_BC));
// non-typical salt length
matrix(new PSSParameterSpec(
"SHA-1",
"MGF1",
MGF1ParameterSpec.SHA1,
17,
PSSParameterSpec.TRAILER_FIELD_BC));
if (!allResult) {
throw new Exception("Failed");
}
}
static void matrix(PSSParameterSpec pss) throws Exception {
System.out.printf("\n%10s%20s%20s%20s %s\n", pss.getDigestAlgorithm(),
"KeyPairGenerator", "signer", "verifier", "result");
System.out.printf("%10s%20s%20s%20s %s\n",
"-------", "----------------", "------", "--------", "------");
// KeyPairGenerator chooses SPI when getInstance() is called.
String[] provsForKPG = {System.getProperty("test.provider.name", "SunRsaSign"),
"SunMSCAPI"};
// "-" means no preferred provider. In this case, SPI is chosen
// when initSign/initVerify is called. Worth testing.
String[] provsForSignature = {System.getProperty("test.provider.name", "SunRsaSign"),
"SunMSCAPI", "-"};
int pos = 0;
for (String pg : provsForKPG) {
for (String ps : provsForSignature) {
for (String pv : provsForSignature) {
System.out.printf("%10d%20s%20s%20s ", ++pos, pg, ps, pv);
try {
boolean result = test(pg, ps, pv, pss);
System.out.println(result);
if (!result) {
allResult = false;
}
} catch (Exception e) {
if (pg.equals("-") || pg.equals(ps)) {
// When Signature provider is automatically
// chosen or the same with KeyPairGenerator,
// this is an error.
allResult = false;
System.out.println("X " + e.getMessage());
} else {
// Known restriction: SunRsaSign and SunMSCAPI can't
// use each other's private key for signing.
System.out.println(e.getMessage());
}
}
}
}
}
}
static boolean test(String pg, String ps, String pv, PSSParameterSpec pss)
throws Exception {
KeyPairGenerator kpg = pg.length() == 1
? KeyPairGenerator.getInstance("RSA")
:KeyPairGenerator.getInstance("RSA", pg);
kpg.initialize(
pss.getDigestAlgorithm().equals("SHA-512") ? 2048: 1024,
NOT_SECURE_RANDOM);
KeyPair kp = kpg.generateKeyPair();
PrivateKey pr = kp.getPrivate();
PublicKey pu = kp.getPublic();
Signature s = ps.length() == 1
? Signature.getInstance("RSASSA-PSS")
: Signature.getInstance("RSASSA-PSS", ps);
s.initSign(pr);
s.setParameter(pss);
s.update(msg);
byte[] sig = s.sign();
Signature s2 = pv.length() == 1
? Signature.getInstance("RSASSA-PSS")
: Signature.getInstance("RSASSA-PSS", pv);
s2.initVerify(pu);
s2.setParameter(pss);
s2.update(msg);
return s2.verify(sig);
}
}

View file

@ -0,0 +1,111 @@
/*
* Copyright (c) 2005, 2017, 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 6318171 6931562
* @requires os.family == "windows"
* @modules jdk.crypto.mscapi/sun.security.mscapi
* @run main/othervm IsSunMSCAPIAvailable
*/
import java.security.Provider;
import java.security.*;
import javax.crypto.Cipher;
public class IsSunMSCAPIAvailable {
public static void main(String[] args) throws Exception {
// Dynamically register the SunMSCAPI provider
Security.addProvider(new sun.security.mscapi.SunMSCAPI());
Provider p = Security.getProvider("SunMSCAPI");
System.out.println("SunMSCAPI provider classname is " +
p.getClass().getName());
System.out.println("SunMSCAPI provider name is " + p.getName());
System.out.println("SunMSCAPI provider version # is " + p.getVersion());
System.out.println("SunMSCAPI provider info is " + p.getInfo());
/*
* Secure Random
*/
SecureRandom random = SecureRandom.getInstance("Windows-PRNG", p);
System.out.println(" Windows-PRNG is implemented by: " +
random.getClass().getName());
/*
* Key Store
*/
KeyStore keystore = KeyStore.getInstance("Windows-MY", p);
System.out.println(" Windows-MY is implemented by: " +
keystore.getClass().getName());
keystore = KeyStore.getInstance("Windows-ROOT", p);
System.out.println(" Windows-ROOT is implemented by: " +
keystore.getClass().getName());
/*
* Signature
*/
Signature signature = Signature.getInstance("SHA1withRSA", p);
System.out.println(" SHA1withRSA is implemented by: " +
signature.getClass().getName());
signature = Signature.getInstance("MD5withRSA", p);
System.out.println(" MD5withRSA is implemented by: " +
signature.getClass().getName());
signature = Signature.getInstance("MD2withRSA", p);
System.out.println(" MD2withRSA is implemented by: " +
signature.getClass().getName());
/*
* Key Pair Generator
*/
KeyPairGenerator keypairGenerator =
KeyPairGenerator.getInstance("RSA", p);
System.out.println(" RSA is implemented by: " +
keypairGenerator.getClass().getName());
/*
* Cipher
*/
Cipher cipher = null;
try {
cipher = Cipher.getInstance("RSA", p);
System.out.println(" RSA is implemented by: " +
cipher.getClass().getName());
cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", p);
System.out.println(" RSA/ECB/PKCS1Padding is implemented by: " +
cipher.getClass().getName());
} catch (GeneralSecurityException e) {
System.out.println("Cipher not supported by provider, skipping...");
}
}
}

View file

@ -0,0 +1,130 @@
/*
* Copyright (c) 2015, 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.InputStream;
import java.security.KeyStore;
import java.security.Provider;
import java.security.Security;
import java.security.cert.CRL;
import java.security.cert.CRLException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactorySpi;
import java.util.Collection;
import java.util.Enumeration;
/*
* @test
* @bug 8139436
* @summary This test validates an iteration over the Windows-ROOT certificate store
* and retrieving all certificates.
* Bug 8139436 reports an issue when 3rd party JCE providers would throw exceptions
* upon creating Certificate objects.
* This would for instance happen when using IAIK 3.15 and Elliptic Curve certificates
* are contained in the Windows-ROOT certificate store.
* The test uses a simple dummy provider which just throws Exceptions in its CertificateFactory.
* To test an external provider, you can use property sun.security.mscapi.testprovider and
* set it to the provider class name which has to be constructible by a constructor without
* arguments. The provider jar has to be added to the classpath.
* E.g. run jtreg with -javaoption:-Dsun.security.mscapi.testprovider=iaik.security.provider.IAIK and
* -cpa:<path to iaik_jce.jar>
*
* @requires os.family == "windows"
* @author Christoph Langer
* @run main IterateWindowsRootStore
*/
public class IterateWindowsRootStore {
public static class TestFactory extends CertificateFactorySpi {
@Override
public Certificate engineGenerateCertificate(InputStream inStream) throws CertificateException {
throw new CertificateException("unimplemented");
}
@Override
public Collection<? extends Certificate> engineGenerateCertificates(InputStream inStream) throws CertificateException {
throw new CertificateException("unimplemented");
}
@Override
public CRL engineGenerateCRL(InputStream inStream) throws CRLException {
throw new CRLException("unimplemented");
}
@Override
public Collection<? extends CRL> engineGenerateCRLs(InputStream inStream) throws CRLException {
throw new CRLException("unimplemented");
}
}
public static class TestProvider extends Provider {
private static final long serialVersionUID = 1L;
public TestProvider() {
super("TestProvider", 0.1, "Test provider for IterateWindowsRootStore");
/*
* Certificates
*/
this.put("CertificateFactory.X.509", "IterateWindowsRootStore$TestFactory");
this.put("Alg.Alias.CertificateFactory.X509", "X.509");
}
}
public static void main(String[] args) throws Exception {
// Try to register a JCE provider from property sun.security.mscapi.testprovider in the first slot
// otherwise register a dummy provider which would provoke the issue of bug 8139436
boolean providerPrepended = false;
String testprovider = System.getProperty("sun.security.mscapi.testprovider");
if (testprovider != null && !testprovider.isEmpty()) {
try {
System.out.println("Trying to prepend external JCE provider " + testprovider);
Class<?> providerclass = Class.forName(testprovider);
Object provider = providerclass.newInstance();
Security.insertProviderAt((Provider)provider, 1);
} catch (Exception e) {
System.out.println("Could not load JCE provider " + testprovider +". Exception is:");
e.printStackTrace(System.out);
}
providerPrepended = true;
System.out.println("Sucessfully prepended JCE provider " + testprovider);
}
if (!providerPrepended) {
System.out.println("Trying to prepend dummy JCE provider");
Security.insertProviderAt(new TestProvider(), 1);
System.out.println("Sucessfully prepended dummy JCE provider");
}
// load Windows-ROOT KeyStore
KeyStore keyStore = KeyStore.getInstance("Windows-ROOT", "SunMSCAPI");
keyStore.load(null, null);
// iterate KeyStore
Enumeration<String> aliases = keyStore.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
System.out.print("Reading certificate for alias: " + alias + "...");
keyStore.getCertificate(alias);
System.out.println(" done.");
}
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2018, 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.
*/
/**
* @test
* @bug 8213009 8237804
* @summary Make sure SunMSCAPI keys have correct algorithm names
* @requires os.family == "windows"
* @library /test/lib
* @modules jdk.crypto.mscapi
*/
import java.security.*;
import jdk.test.lib.Asserts;
import jdk.test.lib.SecurityTools;
public class KeyAlgorithms {
private static final String ALIAS = "8213009";
private static final String ALG = "RSA";
public static void main(String[] arg) throws Exception {
cleanup();
SecurityTools.keytool("-genkeypair",
"-storetype", "Windows-My",
"-keyalg", ALG,
"-alias", ALIAS,
"-dname", "cn=" + ALIAS,
"-noprompt").shouldHaveExitValue(0);
try {
test(loadKeysFromKeyStore());
} finally {
cleanup();
}
test(generateKeys());
}
private static void cleanup() {
try {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
ks.deleteEntry(ALIAS);
ks.store(null, null);
} catch (Exception e) {
System.out.println("No such entry.");
}
}
static KeyPair loadKeysFromKeyStore() throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
return new KeyPair(ks.getCertificate(ALIAS).getPublicKey(),
(PrivateKey) ks.getKey(ALIAS, null));
}
static KeyPair generateKeys() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance(ALG, "SunMSCAPI");
return kpg.generateKeyPair();
}
static void test(KeyPair kp) {
Asserts.assertEQ(kp.getPrivate().getAlgorithm(), ALG);
Asserts.assertEQ(kp.getPublic().getAlgorithm(), ALG);
}
}

View file

@ -0,0 +1,122 @@
/*
* Copyright (c) 2005, 2018, 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 6324294 6931562 8180570
* @requires os.family == "windows"
* @run main KeyStoreCompatibilityMode
* @run main/othervm -Dsun.security.mscapi.keyStoreCompatibilityMode=true KeyStoreCompatibilityMode
* @run main/othervm -Dsun.security.mscapi.keyStoreCompatibilityMode=false KeyStoreCompatibilityMode -disable
* @summary Confirm that a null stream or password is not permitted when
* compatibility mode is enabled (and vice versa).
*/
import java.io.*;
import java.security.Provider;
import java.security.*;
public class KeyStoreCompatibilityMode {
private static final String KEYSTORE_COMPATIBILITY_MODE_PROP =
"sun.security.mscapi.keyStoreCompatibilityMode";
private static boolean mode;
public static void main(String[] args) throws Exception {
if (args.length > 0 && "-disable".equals(args[0])) {
mode = false;
} else {
mode = true;
}
Provider p = Security.getProvider("SunMSCAPI");
System.out.println("SunMSCAPI provider classname is " +
p.getClass().getName());
System.out.println(KEYSTORE_COMPATIBILITY_MODE_PROP + " = " +
System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP));
KeyStore myKeyStore = KeyStore.getInstance("Windows-MY", p);
KeyStore myKeyStore2 = KeyStore.getInstance("Windows-MY", p);
KeyStore rootKeyStore = KeyStore.getInstance("Windows-ROOT", p);
KeyStore rootKeyStore2 = KeyStore.getInstance("Windows-ROOT", p);
InputStream inStream = new ByteArrayInputStream(new byte[1]);
OutputStream outStream = new ByteArrayOutputStream();
char[] password = new char[1];
// Checking keystore load operations
testLoadStore(myKeyStore, null, null, true);
testLoadStore(myKeyStore2, null, password, true);
testLoadStore(rootKeyStore, inStream, null, true);
testLoadStore(rootKeyStore2, inStream, password, true);
// Checking keystore store operations
testLoadStore(myKeyStore, null, null, false);
testLoadStore(myKeyStore2, null, password, false);
testLoadStore(rootKeyStore, outStream, null, false);
testLoadStore(rootKeyStore2, outStream, password, false);
}
private static void testLoadStore(KeyStore keyStore, Object stream,
char[] password, boolean doLoad) throws Exception {
String streamValue = stream == null ? "null" : "non-null";
String passwordValue = password == null ? "null" : "non-null";
System.out.println("Checking " + (doLoad ? "load" : "store") +
"(stream=" + streamValue + ", password=" + passwordValue + ")...");
try {
if (doLoad) {
keyStore.load((InputStream) stream, password);
} else {
keyStore.store((OutputStream) stream, password);
}
if (!mode && keyStore != null && password != null) {
throw new Exception(
"Expected an IOException to be thrown by KeyStore.load");
}
} catch (IOException ioe) {
// When mode=false the exception is expected.
if (mode) {
throw ioe;
} else {
System.out.println("caught the expected exception: " + ioe);
}
} catch (KeyStoreException kse) {
// store will fail if load has previously failed
if (doLoad) {
throw kse;
} else {
System.out.println("caught the expected exception: " + kse);
}
}
}
}

View file

@ -0,0 +1,81 @@
/*
* Copyright (c) 2017, 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 8172244
* @summary Verify that no exception is thrown with empty cert chain
* in MSCAPI.
* @requires os.family == "windows"
* @modules java.base/sun.security.tools.keytool java.base/sun.security.x509
* @run main/othervm --add-opens java.base/java.security=ALL-UNNAMED
* KeyStoreEmptyCertChain
*/
import java.security.KeyStore;
import java.security.cert.Certificate;
import sun.security.x509.X500Name;
import sun.security.tools.keytool.CertAndKeyGen;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.KeyStoreSpi;
import java.lang.reflect.*;
public class KeyStoreEmptyCertChain {
public static void main(String[] args) {
try {
KeyStore keyStore = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
keyStore.load(null, null);
// Generate a certificate to use for testing
CertAndKeyGen gen = new CertAndKeyGen("RSA", "SHA256withRSA");
gen.generate(2048);
Certificate cert =
gen.getSelfCertificate(new X500Name("CN=test"), 3600);
String alias = "JDK-8172244";
char[] password = "password".toCharArray();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
// generate a private key for the certificate
kpg.initialize(2048);
KeyPair keyPair = kpg.generateKeyPair();
PrivateKey privKey = keyPair.getPrivate();
// need to bypass checks to store the private key without the cert
Field spiField = KeyStore.class.getDeclaredField("keyStoreSpi");
spiField.setAccessible(true);
KeyStoreSpi spi = (KeyStoreSpi) spiField.get(keyStore);
spi.engineSetKeyEntry(alias, privKey, password, new Certificate[0]);
keyStore.store(null, null);
keyStore.getCertificateAlias(cert);
keyStore.deleteEntry(alias);
// test passes if no exception is thrown
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
}

View file

@ -0,0 +1,89 @@
/*
* Copyright (c) 2018, 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 jdk.test.lib.SecurityTools;
import jdk.test.lib.security.CertUtils;
import java.security.KeyStore;
import java.security.SecureRandom;
/*
* @test
* @bug 6415696 6931562 8180570
* @requires os.family == "windows"
* @library /test/lib
* @summary Test "keytool -changealias" using the Microsoft CryptoAPI provider.
*/
public class KeytoolChangeAlias {
public static void main(String[] args) throws Exception {
SecureRandom random = new SecureRandom();
String alias = Integer.toString(random.nextInt(1000, 8192));
String newAlias = alias + "1";
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
try {
ks.setCertificateEntry(alias, CertUtils.getCertFromFile("246810.cer"));
if (ks.containsAlias(newAlias)) {
ks.deleteEntry(newAlias);
}
int before = ks.size();
ks.store(null, null); // no-op, but let's do it before a keytool command
SecurityTools.keytool("-changealias",
"-storetype", "Windows-My",
"-alias", alias,
"-destalias", newAlias).shouldHaveExitValue(0);
ks.load(null, null);
if (ks.size() != before) {
throw new Exception("error: unexpected number of entries in the "
+ "Windows-MY store. Before: " + before
+ ". After: " + ks.size());
}
if (!ks.containsAlias(newAlias)) {
throw new Exception("error: cannot find the new alias name"
+ " in the Windows-MY store");
}
} finally {
try {
ks.deleteEntry(newAlias);
} catch (Exception e) {
System.err.println("Couldn't delete alias " + newAlias);
e.printStackTrace(System.err);
}
try {
ks.deleteEntry(alias);
} catch (Exception e) {
System.err.println("Couldn't delete alias " + alias);
e.printStackTrace(System.err);
}
ks.store(null, null);
}
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright (c) 2022, 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 sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
import java.security.KeyStore;
import java.security.cert.Certificate;
import jdk.test.lib.Asserts;
/**
* @test
* @bug 6522064
* @library /test/lib
* @requires os.family == "windows"
* @modules java.base/sun.security.tools.keytool
* java.base/sun.security.x509
* @summary Aliases from Microsoft CryptoAPI has bad character encoding
*/
public class NonAsciiAlias {
public static void main(String[] args) throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY");
String alias = "\u58c6\u94a56522064";
try {
ks.load(null, null);
CertAndKeyGen cag = new CertAndKeyGen("RSA", "SHA256withRSA");
cag.generate(2048);
ks.setKeyEntry(alias, cag.getPrivateKey(), null, new Certificate[]{
cag.getSelfCertificate(new X500Name("CN=Me"), 1000)
});
// Confirms the alias is there
Asserts.assertTrue(ks.containsAlias(alias));
ks.store(null, null);
ks.load(null, null);
// Confirms the alias is there after reload
Asserts.assertTrue(ks.containsAlias(alias));
ks.deleteEntry(alias);
// Confirms the alias is removed
Asserts.assertFalse(ks.containsAlias(alias));
ks.store(null, null);
ks.load(null, null);
// Confirms the alias is removed after reload
Asserts.assertFalse(ks.containsAlias(alias));
} finally {
ks.deleteEntry(alias);
// in case the correct alias is not found, clean up a wrong one
ks.deleteEntry("??6522064");
}
}
}

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2019, 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.PublicKey;
import java.security.Signature;
import java.util.List;
/**
* @test
* @bug 8225180
* @requires os.family == "windows"
* @summary SunMSCAPI Signature should throw InvalidKeyException when
* initialized with a null key
*/
public class NullKey {
public static void main(String[] args) throws Exception {
for (String alg : List.of(
"SHA256withRSA", "SHA256withECDSA", "RSASSA-PSS")) {
Signature sig = Signature.getInstance(alg, "SunMSCAPI");
try {
sig.initSign(null);
} catch (InvalidKeyException e) {
// Expected
}
try {
sig.initVerify((PublicKey)null);
} catch (InvalidKeyException e) {
// Expected
}
}
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2018, 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 8210476
* @requires os.family == "windows"
* @summary MSCAPI's PRNG should support serialization
* @library /test/lib
* @run main PrngSerialize
*/
import jdk.test.lib.util.SerializationUtils;
import java.security.SecureRandom;
public class PrngSerialize {
public static void main(String[] args) throws Exception {
SecureRandom sr = SecureRandom.getInstance("Windows-PRNG", "SunMSCAPI");
sr = (SecureRandom) SerializationUtils.deserialize(SerializationUtils.serialize(sr));
// This line is likely to release the context in the original sr.
System.gc();
// Make sure the new object is still useable.
sr.nextInt();
}
}

View file

@ -0,0 +1,50 @@
/*
* Copyright (c) 2006, 2018, 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 6449335 8210476
* @requires os.family == "windows"
* @summary MSCAPI's PRNG is too slow
* @key randomness
*/
import java.security.SecureRandom;
public class PrngSlow {
public static void main(String[] args) throws Exception {
double t = 0.0;
SecureRandom sr = null;
sr = SecureRandom.getInstance("Windows-PRNG", "SunMSCAPI");
long start = System.nanoTime();
for (int i = 0; i < 10000; i++) {
if (i % 100 == 0) System.err.print(".");
sr.nextBoolean();
};
t = (System.nanoTime() - start) / 1000000000.0;
System.err.println("\nSpend " + t + " seconds");
if (t > 0.5)
throw new RuntimeException("Still too slow");
}
}

View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2019, 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 8231598
* @requires os.family == "windows"
* @library /test/lib
* @summary keytool does not export sun.security.mscapi
*/
import jdk.test.lib.SecurityTools;
public class ProviderClassOption {
public static void main(String[] args) throws Throwable {
SecurityTools.keytool("-v -storetype Windows-ROOT -list"
+ " -providerClass sun.security.mscapi.SunMSCAPI")
.shouldHaveExitValue(0);
}
}

View file

@ -0,0 +1,124 @@
/*
* Copyright (c) 2011, 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.
*/
/**
* @test
* @bug 6888925 8180570 8237804
* @summary SunMSCAPI's Cipher can't use RSA public keys obtained from other sources.
* @requires os.family == "windows"
* @library /test/lib
* @modules java.base/sun.security.util
*/
import java.security.*;
import java.util.*;
import javax.crypto.*;
import jdk.test.lib.SecurityTools;
import jdk.test.lib.hexdump.HexPrinter;
/*
* Confirm interoperability of RSA public keys between SunMSCAPI and SunJCE
* security providers.
*/
public class PublicKeyInterop {
public static void main(String[] arg) throws Exception {
cleanup();
SecurityTools.keytool("-genkeypair",
"-storetype", "Windows-My",
"-keyalg", "RSA",
"-alias", "6888925",
"-dname", "cn=6888925,c=US",
"-noprompt").shouldHaveExitValue(0);
try {
run();
} finally {
cleanup();
}
}
private static void cleanup() {
try {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
ks.deleteEntry("6888925");
ks.store(null, null);
} catch (Exception e) {
System.out.println("No such entry.");
}
}
static void run() throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
System.out.println("Loaded keystore: Windows-MY");
PublicKey myPuKey = ks.getCertificate("6888925").getPublicKey();
System.out.println("Public key is a " + myPuKey.getClass().getName());
PrivateKey myPrKey = (PrivateKey) ks.getKey("6888925", null);
System.out.println("Private key is a " + myPrKey.getClass().getName());
System.out.println();
byte[] plain = new byte[] {0x01, 0x02, 0x03, 0x04, 0x05};
HexPrinter hp = HexPrinter.simple();
System.out.println("Plaintext:\n" + hp.toString(plain) + "\n");
Cipher rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding");
rsa.init(Cipher.ENCRYPT_MODE, myPuKey);
byte[] encrypted = rsa.doFinal(plain);
System.out.println("Encrypted plaintext using RSA Cipher from " +
rsa.getProvider().getName() + " JCE provider\n");
System.out.println(hp.toString(encrypted) + "\n");
Cipher rsa2 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunMSCAPI");
rsa2.init(Cipher.ENCRYPT_MODE, myPuKey);
byte[] encrypted2 = rsa2.doFinal(plain);
System.out.println("Encrypted plaintext using RSA Cipher from " +
rsa2.getProvider().getName() + " JCE provider\n");
System.out.println(hp.toString(encrypted2) + "\n");
Cipher rsa3 = Cipher.getInstance("RSA/ECB/PKCS1Padding", "SunMSCAPI");
rsa3.init(Cipher.DECRYPT_MODE, myPrKey);
byte[] decrypted = rsa3.doFinal(encrypted);
System.out.println("Decrypted first ciphertext using RSA Cipher from " +
rsa3.getProvider().getName() + " JCE provider\n");
System.out.println(hp.toString(decrypted) + "\n");
if (! Arrays.equals(plain, decrypted)) {
throw new Exception("First decrypted ciphertext does not match " +
"original plaintext");
}
decrypted = rsa3.doFinal(encrypted2);
System.out.println("Decrypted second ciphertext using RSA Cipher from "
+ rsa3.getProvider().getName() + " JCE provider\n");
System.out.println(hp.toString(decrypted) + "\n");
if (! Arrays.equals(plain, decrypted)) {
throw new Exception("Second decrypted ciphertext does not match " +
"original plaintext");
}
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (c) 2006, 2018, 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 6457422 6931562 8180570
* @summary Confirm that plaintext can be encrypted and then decrypted using the
* RSA cipher in the SunMSCAPI crypto provider. NOTE: The RSA cipher is
* absent from the SunMSCAPI provider in OpenJDK builds.
* @requires os.family == "windows"
*/
import javax.crypto.Cipher;
import java.security.GeneralSecurityException;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.Key;
public class RSAEncryptDecrypt {
public static final byte[] PLAINTEXT = {1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6};
public static void main(String[] args) throws Exception {
KeyPairGenerator generator =
KeyPairGenerator.getInstance("RSA", "SunMSCAPI");
KeyPair keyPair = generator.generateKeyPair();
Key publicKey = keyPair.getPublic();
Key privateKey = keyPair.getPrivate();
Cipher cipher = null;
try {
cipher = Cipher.getInstance("RSA", "SunMSCAPI");
} catch (GeneralSecurityException e) {
System.out.println("Cipher not supported by provider, skipping...");
return;
}
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
displayBytes("Plaintext data:", PLAINTEXT);
byte[] data = cipher.doFinal(PLAINTEXT);
displayBytes("Encrypted data:", data);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
data = cipher.doFinal(data);
displayBytes("Decrypted data:", data);
}
private static void displayBytes(String label, byte[] bytes) {
System.out.println(label + " [length=" + bytes.length + "]");
for (byte b : bytes) {
System.out.print("0x" + Integer.toHexString(b & 0xFF) + " ");
}
System.out.println();
}
}

View file

@ -0,0 +1,98 @@
/*
* Copyright (c) 2021, 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.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Collections;
import jdk.test.lib.Asserts;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
/*
* @test
* @bug 8185844
* @summary ensure setEntry overwrite old entry
* @library /test/lib
* @requires os.family == "windows"
* @modules java.base/sun.security.tools.keytool
* java.base/sun.security.x509
*/
public class SetDupNameEntry {
final KeyStore keyStore;
final CertAndKeyGen ckg;
static final String PREFIX = "8185844";
public static void main(String[] args) throws Exception {
SetDupNameEntry test = new SetDupNameEntry();
test.cleanup();
try {
test.test(true); // test key entry
test.test(false); // test cert entry
} finally {
test.cleanup();
}
}
SetDupNameEntry() throws Exception {
keyStore = KeyStore.getInstance("Windows-MY");
ckg = new CertAndKeyGen("RSA", "SHA1withRSA");
}
void test(boolean testKey) throws Exception {
keyStore.load(null, null);
int size = keyStore.size();
String alias = PREFIX + (testKey ? "k" : "c");
for (int i = 0; i < 2; i++) {
ckg.generate(1024);
X509Certificate cert = ckg
.getSelfCertificate(new X500Name("CN=TEST"), 1000);
if (testKey) {
keyStore.setKeyEntry(
alias,
ckg.getPrivateKey(),
null,
new Certificate[] { cert });
} else {
keyStore.setCertificateEntry(alias, cert);
}
}
Asserts.assertEQ(keyStore.size(), size + 1);
keyStore.load(null, null);
Asserts.assertEQ(keyStore.size(), size + 1);
}
void cleanup() throws Exception {
keyStore.load(null, null);
for (String alias : Collections.list(keyStore.aliases())) {
if (alias.startsWith(PREFIX)) {
keyStore.deleteEntry(alias);
}
}
}
}

View file

@ -0,0 +1,454 @@
/*
* Copyright (c) 2012, 2025, 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 7106773 8180570 8314148
* @summary 512 bits RSA key cannot work with SHA384 and SHA512
* @requires os.family == "windows"
* @modules java.base/sun.security.util
* java.base/sun.security.tools.keytool
* java.base/sun.security.x509
* @library /test/lib
* @run main ShortRSAKeyWithinTLS 1024
* @run main ShortRSAKeyWithinTLS 768
* @run main ShortRSAKeyWithinTLS 512
*/
import java.io.*;
import java.net.*;
import java.security.cert.Certificate;
import java.util.*;
import java.security.*;
import java.security.cert.*;
import javax.net.*;
import javax.net.ssl.*;
import jdk.test.lib.security.SecurityUtils;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.util.KeyUtil;
import sun.security.x509.X500Name;
public class ShortRSAKeyWithinTLS {
/*
* =============================================================
* Set the various variables needed for the tests, then
* specify what tests to run on each side.
*/
/*
* Should we run the client or server in a separate thread?
* Both sides can throw exceptions, but do you have a preference
* as to which side should be the main thread.
*/
static boolean separateServerThread = false;
/*
* Is the server ready to serve?
*/
volatile static boolean serverReady = false;
/*
* Turn on SSL debugging?
*/
static boolean debug = false;
/*
* If the client or server is doing some kind of object creation
* that the other side depends on, and that thread prematurely
* exits, you may experience a hang. The test harness will
* terminate all hung threads after its timeout has expired,
* currently 3 minutes by default, but you might try to be
* smart about it....
*/
/*
* Define the server side of the test.
*
* If the server prematurely exits, serverReady will be set to true
* to avoid infinite hangs.
*/
void doServerSide() throws Exception {
// load the key store
serverKS = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
serverKS.load(null, null);
System.out.println("Loaded keystore: Windows-MY");
// check key size
checkKeySize(serverKS);
// initialize the SSLContext
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(serverKS, null);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(serverKS);
TrustManager[] tms = tmf.getTrustManagers();
if (tms == null || tms.length == 0) {
throw new Exception("unexpected trust manager implementation");
} else {
if (!(tms[0] instanceof X509TrustManager)) {
throw new Exception("unexpected trust manager" +
" implementation: " +
tms[0].getClass().getCanonicalName());
}
}
serverTM = new MyExtendedX509TM((X509TrustManager)tms[0]);
tms = new TrustManager[] {serverTM};
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tms, null);
ServerSocketFactory ssf = ctx.getServerSocketFactory();
SSLServerSocket sslServerSocket = (SSLServerSocket)
ssf.createServerSocket(serverPort);
sslServerSocket.setNeedClientAuth(true);
serverPort = sslServerSocket.getLocalPort();
System.out.println("serverPort = " + serverPort);
/*
* Signal Client, we're ready for his connect.
*/
serverReady = true;
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream();
sslIS.read();
sslOS.write(85);
sslOS.flush();
sslSocket.close();
}
/*
* Define the client side of the test.
*
* If the server prematurely exits, serverReady will be set to true
* to avoid infinite hangs.
*/
void doClientSide() throws Exception {
/*
* Wait for server to get started.
*/
while (!serverReady) {
Thread.sleep(50);
}
// load the key store
KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
ks.load(null, null);
System.out.println("Loaded keystore: Windows-MY");
// initialize the SSLContext
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, null);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ks);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLSocketFactory sslsf = ctx.getSocketFactory();
SSLSocket sslSocket = (SSLSocket)
sslsf.createSocket("localhost", serverPort);
if (clientProtocol != null) {
sslSocket.setEnabledProtocols(new String[] {clientProtocol});
}
if (clientCiperSuite != null) {
sslSocket.setEnabledCipherSuites(new String[] {clientCiperSuite});
}
InputStream sslIS = sslSocket.getInputStream();
OutputStream sslOS = sslSocket.getOutputStream();
sslOS.write(280);
sslOS.flush();
sslIS.read();
sslSocket.close();
}
private void checkKeySize(KeyStore ks) throws Exception {
PrivateKey privateKey = null;
PublicKey publicKey = null;
if (ks.containsAlias(keyAlias)) {
System.out.println("Loaded entry: " + keyAlias);
privateKey = (PrivateKey)ks.getKey(keyAlias, null);
publicKey = (PublicKey)ks.getCertificate(keyAlias).getPublicKey();
int privateKeySize = KeyUtil.getKeySize(privateKey);
if (privateKeySize != keySize) {
throw new Exception("Expected key size is " + keySize +
", but the private key size is " + privateKeySize);
}
int publicKeySize = KeyUtil.getKeySize(publicKey);
if (publicKeySize != keySize) {
throw new Exception("Expected key size is " + keySize +
", but the public key size is " + publicKeySize);
}
}
}
/*
* =============================================================
* The remainder is just support stuff
*/
// use any free port by default
volatile int serverPort = 0;
volatile Exception serverException = null;
volatile Exception clientException = null;
private static String keyAlias;
private static int keySize;
private static String clientProtocol = null;
private static String clientCiperSuite = null;
public static void main(String[] args) throws Exception {
// Make sure we don't block the key on algorithm constraints check.
SecurityUtils.removeFromDisabledAlgs("jdk.certpath.disabledAlgorithms",
List.of("RSA keySize < 1024"));
if (debug) {
System.setProperty("javax.net.debug", "all");
}
keyAlias = "7106773." + args[0];
keySize = Integer.parseInt(args[0]);
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
if (ks.containsAlias(keyAlias)) {
ks.deleteEntry(keyAlias);
}
CertAndKeyGen gen = new CertAndKeyGen("RSA", "SHA256withRSA");
gen.generate(keySize);
ks.setKeyEntry(keyAlias, gen.getPrivateKey(), null,
new Certificate[] {
gen.getSelfCertificate(new X500Name("cn=localhost,c=US"), 100)
});
clientProtocol = "TLSv1.2";
clientCiperSuite = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
try {
new ShortRSAKeyWithinTLS();
} finally {
ks.deleteEntry(keyAlias);
ks.store(null, null);
}
}
Thread clientThread = null;
Thread serverThread = null;
KeyStore serverKS;
MyExtendedX509TM serverTM;
/*
* Primary constructor, used to drive remainder of the test.
*
* Fork off the other side, then do your work.
*/
ShortRSAKeyWithinTLS() throws Exception {
try {
if (separateServerThread) {
startServer(true);
startClient(false);
} else {
startClient(true);
startServer(false);
}
} catch (Exception e) {
// swallow for now. Show later
}
/*
* Wait for other side to close down.
*/
if (separateServerThread) {
serverThread.join();
} else {
clientThread.join();
}
/*
* When we get here, the test is pretty much over.
* Which side threw the error?
*/
Exception local;
Exception remote;
String whichRemote;
if (separateServerThread) {
remote = serverException;
local = clientException;
whichRemote = "server";
} else {
remote = clientException;
local = serverException;
whichRemote = "client";
}
/*
* If both failed, return the curthread's exception, but also
* print the remote side Exception
*/
if ((local != null) && (remote != null)) {
System.out.println(whichRemote + " also threw:");
remote.printStackTrace();
System.out.println();
throw local;
}
if (remote != null) {
throw remote;
}
if (local != null) {
throw local;
}
}
void startServer(boolean newThread) throws Exception {
if (newThread) {
serverThread = new Thread() {
public void run() {
try {
doServerSide();
} catch (Exception e) {
/*
* Our server thread just died.
*
* Release the client, if not active already...
*/
System.err.println("Server died...");
serverReady = true;
serverException = e;
}
}
};
serverThread.start();
} else {
try {
doServerSide();
} catch (Exception e) {
serverException = e;
} finally {
serverReady = true;
}
}
}
void startClient(boolean newThread) throws Exception {
if (newThread) {
clientThread = new Thread() {
public void run() {
try {
doClientSide();
} catch (Exception e) {
/*
* Our client thread just died.
*/
System.err.println("Client died...");
clientException = e;
}
}
};
clientThread.start();
} else {
try {
doClientSide();
} catch (Exception e) {
clientException = e;
}
}
}
class MyExtendedX509TM extends X509ExtendedTrustManager
implements X509TrustManager {
X509TrustManager tm;
MyExtendedX509TM(X509TrustManager tm) {
this.tm = tm;
}
public void checkClientTrusted(X509Certificate chain[], String authType)
throws CertificateException {
tm.checkClientTrusted(chain, authType);
}
public void checkServerTrusted(X509Certificate chain[], String authType)
throws CertificateException {
tm.checkServerTrusted(chain, authType);
}
public X509Certificate[] getAcceptedIssuers() {
List<X509Certificate> certs = new ArrayList<>();
try {
for (X509Certificate c : tm.getAcceptedIssuers()) {
if (serverKS.getCertificateAlias(c).equals(keyAlias))
certs.add(c);
}
} catch (KeyStoreException kse) {
throw new RuntimeException(kse);
}
return certs.toArray(new X509Certificate[certs.size()]);
}
public void checkClientTrusted(X509Certificate[] chain, String authType,
Socket socket) throws CertificateException {
tm.checkClientTrusted(chain, authType);
}
public void checkServerTrusted(X509Certificate[] chain, String authType,
Socket socket) throws CertificateException {
tm.checkServerTrusted(chain, authType);
}
public void checkClientTrusted(X509Certificate[] chain, String authType,
SSLEngine engine) throws CertificateException {
tm.checkClientTrusted(chain, authType);
}
public void checkServerTrusted(X509Certificate[] chain, String authType,
SSLEngine engine) throws CertificateException {
tm.checkServerTrusted(chain, authType);
}
}
}

View file

@ -0,0 +1,252 @@
/*
* Copyright (c) 2011, 2016, 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 6578658
* @modules java.base/sun.security.x509
* java.base/sun.security.tools.keytool
* @requires os.family == "windows"
* @summary Sign using the NONEwithRSA signature algorithm from SunMSCAPI
*/
import java.security.*;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.util.*;
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
public class SignUsingNONEwithRSA {
private static final List<byte[]> precomputedHashes = Arrays.asList(
// A MD5 hash
new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16
},
// A SHA-1 hash
new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20
},
// A concatenation of SHA-1 and MD5 hashes (used during SSL handshake)
new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36
},
// A SHA-256 hash
new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
0x31, 0x32
},
// A SHA-384 hash
new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40,
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48
},
// A SHA-512 hash
new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40,
0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x50,
0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x60,
0x61, 0x62, 0x63, 0x64
});
private static List<byte[]> generatedSignatures = new ArrayList<>();
public static void main(String[] args) throws Exception {
Provider[] providers = Security.getProviders("Signature.NONEwithRSA");
if (providers == null) {
System.out.println("No JCE providers support the " +
"'Signature.NONEwithRSA' algorithm");
System.out.println("Skipping this test...");
return;
} else {
System.out.println("The following JCE providers support the " +
"'Signature.NONEwithRSA' algorithm: ");
for (Provider provider : providers) {
System.out.println(" " + provider.getName());
}
}
System.out.println(
"Creating a temporary RSA keypair in the Windows-My store");
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
CertAndKeyGen ckg = new CertAndKeyGen("RSA", "SHA1withRSA");
ckg.generate(1024);
RSAPrivateCrtKey k = (RSAPrivateCrtKey) ckg.getPrivateKey();
ks.setKeyEntry("6578658", k, null, new X509Certificate[]{
ckg.getSelfCertificate(new X500Name("cn=6578658,c=US"), 1000)
});
ks.store(null, null);
System.out.println("---------------------------------------------");
try {
KeyPair keys = getKeysFromKeyStore();
signAllUsing("SunMSCAPI", keys.getPrivate());
System.out.println("---------------------------------------------");
verifyAllUsing("SunMSCAPI", keys.getPublic());
System.out.println("---------------------------------------------");
verifyAllUsing("SunJCE", keys.getPublic());
System.out.println("---------------------------------------------");
keys = generateKeys();
signAllUsing("SunJCE", keys.getPrivate());
System.out.println("---------------------------------------------");
verifyAllUsing("SunMSCAPI", keys.getPublic());
System.out.println("---------------------------------------------");
} finally {
System.out.println(
"Deleting temporary RSA keypair from Windows-My store");
ks.deleteEntry("6578658");
}
}
private static KeyPair getKeysFromKeyStore() throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
ks.load(null, null);
System.out.println("Loaded keystore: Windows-MY");
Enumeration<String> e = ks.aliases();
PrivateKey privateKey = null;
PublicKey publicKey = null;
while (e.hasMoreElements()) {
String alias = e.nextElement();
if (alias.equals("6578658")) {
System.out.println("Loaded entry: " + alias);
privateKey = (PrivateKey) ks.getKey(alias, null);
publicKey = (PublicKey) ks.getCertificate(alias).getPublicKey();
}
}
if (privateKey == null || publicKey == null) {
throw new Exception("Cannot load the keys need to run this test");
}
return new KeyPair(publicKey, privateKey);
}
private static KeyPair generateKeys() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024, null);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey privateKey = pair.getPrivate();
PublicKey publicKey = pair.getPublic();
if (privateKey == null || publicKey == null) {
throw new Exception("Cannot load the keys need to run this test");
}
return new KeyPair(publicKey, privateKey);
}
private static void signAllUsing(String providerName, PrivateKey privateKey)
throws Exception {
Signature sig1 = Signature.getInstance("NONEwithRSA", providerName);
if (sig1 == null) {
throw new Exception("'NONEwithRSA' is not supported");
}
if (sig1.getProvider() != null) {
System.out.println("Using NONEwithRSA signer from the " +
sig1.getProvider().getName() + " JCE provider");
} else {
System.out.println(
"Using NONEwithRSA signer from the internal JCE provider");
}
System.out.println("Using key: " + privateKey);
generatedSignatures.clear();
for (byte[] hash : precomputedHashes) {
sig1.initSign(privateKey);
sig1.update(hash);
try {
byte [] sigBytes = sig1.sign();
System.out.println("\nGenerated RSA signature over a " +
hash.length + "-byte hash (signature length: " +
sigBytes.length * 8 + " bits)");
System.out.println(String.format("0x%0" +
(sigBytes.length * 2) + "x",
new java.math.BigInteger(1, sigBytes)));
generatedSignatures.add(sigBytes);
} catch (SignatureException se) {
System.out.println("Error generating RSA signature: " + se);
}
}
}
private static void verifyAllUsing(String providerName, PublicKey publicKey)
throws Exception {
Signature sig1 = Signature.getInstance("NONEwithRSA", providerName);
if (sig1.getProvider() != null) {
System.out.println("\nUsing NONEwithRSA verifier from the " +
sig1.getProvider().getName() + " JCE provider");
} else {
System.out.println(
"\nUsing NONEwithRSA verifier from the internal JCE provider");
}
System.out.println("Using key: " + publicKey);
int i = 0;
for (byte[] hash : precomputedHashes) {
byte[] sigBytes = generatedSignatures.get(i++);
System.out.println("\nVerifying RSA Signature over a " +
hash.length + "-byte hash (signature length: " +
sigBytes.length * 8 + " bits)");
System.out.println(String.format("0x%0" +
(sigBytes.length * 2) + "x",
new java.math.BigInteger(1, sigBytes)));
sig1.initVerify(publicKey);
sig1.update(hash);
if (sig1.verify(sigBytes)) {
System.out.println("Verify PASSED");
} else {
throw new Exception("Verify FAILED");
}
}
}
}

View file

@ -0,0 +1,185 @@
/*
* Copyright (c) 2011, 2018, 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 6753664 8180570
* @summary Support SHA256 (and higher) in SunMSCAPI
* @requires os.family == "windows"
* @modules java.base/sun.security.tools.keytool
* java.base/sun.security.x509
*/
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
import java.security.*;
import java.security.cert.Certificate;
import java.util.*;
public class SignUsingSHA2withRSA {
private static final byte[] toBeSigned = new byte[] {
0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10
};
private static List<byte[]> generatedSignatures = new ArrayList<>();
public static void main(String[] args) throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
if (ks.containsAlias("6753664")) {
ks.deleteEntry("6753664");
}
CertAndKeyGen gen = new CertAndKeyGen("RSA", "SHA256withRSA");
gen.generate(2048);
ks.setKeyEntry("6753664", gen.getPrivateKey(), null,
new Certificate[] {
gen.getSelfCertificate(new X500Name("cn=localhost,c=US"), 100)
});
try {
run();
} finally {
ks.deleteEntry("6753664");
ks.store(null, null);
}
}
static void run() throws Exception {
Provider[] providers = Security.getProviders("Signature.SHA256withRSA");
if (providers == null) {
System.out.println("No JCE providers support the " +
"'Signature.SHA256withRSA' algorithm");
System.out.println("Skipping this test...");
return;
} else {
System.out.println("The following JCE providers support the " +
"'Signature.SHA256withRSA' algorithm: ");
for (Provider provider : providers) {
System.out.println(" " + provider.getName());
}
}
System.out.println("-------------------------------------------------");
KeyStore ks = KeyStore.getInstance("Windows-MY", "SunMSCAPI");
ks.load(null, null);
System.out.println("Loaded keystore: Windows-MY");
Enumeration<String> e = ks.aliases();
PrivateKey privateKey = null;
PublicKey publicKey = null;
while (e.hasMoreElements()) {
String alias = e.nextElement();
if (alias.equals("6753664")) {
System.out.println("Loaded entry: " + alias);
privateKey = (PrivateKey) ks.getKey(alias, null);
publicKey = (PublicKey) ks.getCertificate(alias).getPublicKey();
}
}
if (privateKey == null || publicKey == null) {
throw new Exception("Cannot load the keys need to run this test");
}
System.out.println("-------------------------------------------------");
generatedSignatures.add(signUsing("SHA256withRSA", privateKey));
generatedSignatures.add(signUsing("SHA384withRSA", privateKey));
generatedSignatures.add(signUsing("SHA512withRSA", privateKey));
System.out.println("-------------------------------------------------");
verifyUsing("SHA256withRSA", publicKey, generatedSignatures.get(0));
verifyUsing("SHA384withRSA", publicKey, generatedSignatures.get(1));
verifyUsing("SHA512withRSA", publicKey, generatedSignatures.get(2));
System.out.println("-------------------------------------------------");
}
private static byte[] signUsing(String signAlgorithm,
PrivateKey privateKey) throws Exception {
// Must explicitly specify the SunMSCAPI JCE provider
// (otherwise SunJCE is chosen because it appears earlier in the list)
Signature sig1 = Signature.getInstance(signAlgorithm, "SunMSCAPI");
if (sig1 == null) {
throw new Exception("'" + signAlgorithm + "' is not supported");
}
System.out.println("Using " + signAlgorithm + " signer from the " +
sig1.getProvider().getName() + " JCE provider");
System.out.println("Using key: " + privateKey);
sig1.initSign(privateKey);
sig1.update(toBeSigned);
byte [] sigBytes = null;
try {
sigBytes = sig1.sign();
System.out.println("Generated RSA signature over a " +
toBeSigned.length + "-byte data (signature length: " +
sigBytes.length * 8 + " bits)");
System.out.println(String.format("0x%0" +
(sigBytes.length * 2) + "x",
new java.math.BigInteger(1, sigBytes)));
} catch (SignatureException se) {
System.out.println("Error generating RSA signature: " + se);
}
return sigBytes;
}
private static void verifyUsing(String signAlgorithm, PublicKey publicKey,
byte[] signature) throws Exception {
// Must explicitly specify the SunMSCAPI JCE provider
// (otherwise SunJCE is chosen because it appears earlier in the list)
Signature sig1 = Signature.getInstance(signAlgorithm, "SunMSCAPI");
if (sig1 == null) {
throw new Exception("'" + signAlgorithm + "' is not supported");
}
System.out.println("Using " + signAlgorithm + " verifier from the "
+ sig1.getProvider().getName() + " JCE provider");
System.out.println("Using key: " + publicKey);
System.out.println("\nVerifying RSA Signature over a " +
toBeSigned.length + "-byte data (signature length: " +
signature.length * 8 + " bits)");
System.out.println(String.format("0x%0" + (signature.length * 2) +
"x", new java.math.BigInteger(1, signature)));
sig1.initVerify(publicKey);
sig1.update(toBeSigned);
if (sig1.verify(signature)) {
System.out.println("Verify PASSED\n");
} else {
throw new Exception("Verify FAILED");
}
}
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (c) 2015, 2017, 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.NoSuchAlgorithmException;
import java.security.SignatureException;
/*
* @test
* @bug 8050374
* @key randomness intermittent
* @summary This test validates signature verification
* Signature.verify(byte[], int, int). The test uses RandomFactory to
* get random set of clear text data to sign. After the signature
* generation, the test tries to verify signature with the above API
* and passing in different signature offset (0, 33, 66, 99).
* @library /test/lib
* @build jdk.test.lib.RandomFactory
* @compile ../../../java/security/Signature/Offsets.java
* @requires os.family == "windows"
* @run main SignatureOffsets SunMSCAPI NONEwithRSA
* @run main SignatureOffsets SunMSCAPI MD2withRSA
* @run main SignatureOffsets SunMSCAPI MD5withRSA
* @run main SignatureOffsets SunMSCAPI SHA1withRSA
* @run main SignatureOffsets SunMSCAPI SHA256withRSA
* @run main SignatureOffsets SunMSCAPI SHA384withRSA
* @run main SignatureOffsets SunMSCAPI SHA512withRSA
*/
public class SignatureOffsets {
public static void main(String[] args) throws NoSuchAlgorithmException,
InvalidKeyException, SignatureException {
Offsets.main(args);
}
}

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2015, 2018, 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 8050374 8146293
* @summary Verify a chain of signed objects
* @library /test/lib
* @build jdk.test.lib.SigTestUtil
* @compile ../../../java/security/SignedObject/Chain.java
* @requires os.family == "windows"
* @run main SignedObjectChain
*/
public class SignedObjectChain {
private static class Test extends Chain.Test {
public Test(Chain.SigAlg sigAlg) {
super(sigAlg, Chain.KeyAlg.RSA, Chain.Provider.SunMSCAPI);
}
}
private static final Test[] tests = {
new Test(Chain.SigAlg.MD2withRSA),
new Test(Chain.SigAlg.MD5withRSA),
new Test(Chain.SigAlg.SHA1withRSA),
new Test(Chain.SigAlg.SHA256withRSA),
new Test(Chain.SigAlg.SHA384withRSA),
new Test(Chain.SigAlg.SHA512withRSA),
};
public static void main(String argv[]) {
boolean resutl = java.util.Arrays.stream(tests).allMatch(
(test) -> Chain.runTest(test));
if(resutl) {
System.out.println("All tests passed");
} else {
throw new RuntimeException("Some tests failed");
}
}
}

View file

@ -0,0 +1,112 @@
/*
* Copyright (c) 2015, 2017, 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 8023546 8151834
* @modules java.base/sun.security.x509
* java.base/sun.security.tools.keytool
* @summary Test prime exponent (p) lengths 63 and 65 bytes with SunMSCAPI.
* The seed 76 has the fastest test execution now (only 5 rounds) and is
* hard-coded in run tag. This number might change if algorithms for
* RSA key pair generation or BigInteger prime searching gets updated.
* @requires os.family == "windows"
* @run main SmallPrimeExponentP 76
*/
import sun.security.tools.keytool.CertAndKeyGen;
import sun.security.x509.X500Name;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateCrtKey;
import java.util.Random;
public class SmallPrimeExponentP {
public static void main(String argv[]) throws Exception {
long seed = Long.parseLong(argv[0]);
System.out.println("Seed for SecureRandom = " + seed + "L");
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
CertAndKeyGen ckg = new CertAndKeyGen("RSA", "SHA1withRSA");
ckg.setRandom(new MySecureRandom(seed));
String alias = "anything";
int count = 0;
boolean see63 = false;
boolean see65 = false;
while (!see63 || !see65) {
ckg.generate(1024);
RSAPrivateCrtKey k = (RSAPrivateCrtKey) ckg.getPrivateKey();
int len = k.getPrimeExponentP().toByteArray().length;
System.out.println("Length of P = " + len);
if (len == 63 || len == 65) {
if (len == 63) {
if (see63) {
continue;
} else {
see63 = true;
}
}
if (len == 65) {
if (see65) {
continue;
} else {
see65 = true;
}
}
ks.setKeyEntry(alias, k, null, new X509Certificate[]{
ckg.getSelfCertificate(new X500Name("CN=Me"), 1000)
});
count++;
}
}
// Because of JDK-8185844, it has to reload the key store after
// deleting an entry.
for (int i = 0; i < count; i++) {
ks.deleteEntry(alias);
ks.load(null, null);
}
}
static class MySecureRandom extends SecureRandom {
final Random random;
public MySecureRandom(long seed) {
random = new Random(seed);
}
@Override
public void nextBytes(byte[] bytes) {
random.nextBytes(bytes);
}
}
}

View file

@ -0,0 +1,120 @@
/*
* Copyright (c) 2019, 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.
*/
/*
* @test
* @bug 8223063 8153005
* @requires os.family == "windows"
* @library /test/lib
* @summary Support CNG RSA keys
*/
import jdk.test.lib.SecurityTools;
import jdk.test.lib.process.ProcessTools;
import java.io.File;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Random;
public class VeryLongAlias {
static String alias = String.format("%0512d", new Random().nextInt(100000));
public static void main(String[] args) throws Throwable {
// Using the old algorithms to make sure the file is recognized
// by the certutil command on old versions of Windows.
SecurityTools.keytool(
"-J-Dkeystore.pkcs12.legacy"
+ " -genkeypair -storetype pkcs12 -keystore ks"
+ " -storepass changeit -keyalg RSA -dname CN=A -alias "
+ alias);
String id = ((X509Certificate)KeyStore.getInstance(
new File("ks"), "changeit".toCharArray())
.getCertificate(alias)).getSerialNumber().toString(16);
try {
// Importing pkcs12 file. Long alias is only supported by CNG.
ProcessTools.executeCommand("certutil", "-v", "-p", "changeit",
"-csp", "Microsoft Software Key Storage Provider",
"-user", "-importpfx", "MY", "ks", "NoRoot,NoExport")
.shouldHaveExitValue(0);
test();
} finally {
ProcessTools.executeCommand("certutil", "-user", "-delstore", "MY",
id);
}
}
static void test() throws Exception {
char[] pass = "changeit".toCharArray();
KeyStore k1 = KeyStore.getInstance("Windows-MY");
k1.load(null, null);
KeyStore k2 = KeyStore.getInstance(new File("ks"), pass);
PrivateKey p1 = (PrivateKey)k1.getKey(alias, null);
PublicKey u1 = k1.getCertificate(alias).getPublicKey();
PrivateKey p2 = (PrivateKey)k2.getKey(alias, pass);
PublicKey u2 = k2.getCertificate(alias).getPublicKey();
System.out.println(p1.toString());
System.out.println(u1.toString());
if (!p1.toString().contains("type=CNG")) {
throw new Exception("Not a CNG key");
}
testSignature(p1, u1);
testSignature(p1, u2);
testSignature(p2, u1);
testSignature(p2, u2);
}
static void testSignature(PrivateKey p, PublicKey u) throws Exception {
byte[] data = "hello".getBytes();
for (String alg : List.of(
"NONEwithRSA", "SHA1withRSA",
"SHA256withRSA", "SHA512withRSA")) {
if (alg.contains("NONE")) {
data = MessageDigest.getInstance("SHA-256").digest(data);
}
Signature s1 = Signature.getInstance(alg);
Signature s2 = Signature.getInstance(alg);
s1.initSign(p);
s2.initVerify(u);
s1.update(data);
s2.update(data);
if (!s2.verify(s1.sign())) {
throw new Exception("Error");
}
}
}
}

View file

@ -0,0 +1,105 @@
/*
* Copyright (c) 2018, 2025, 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 6483657 8154113
* @requires os.family == "windows"
* @library /test/lib
* @summary Test "keytool -list" displays correctly same named certificates
*/
import jdk.test.lib.process.ProcessTools;
import java.io.IOException;
import java.security.KeyStore;
import java.util.Collections;
import jtreg.SkippedException;
public class NonUniqueAliases {
public static void main(String[] args) throws Throwable {
try {
runTest();
} catch (IOException ex) {
// It uses certutil.exe that isn't guaranteed to be installed
String certutilMsg = "Cannot run program \"certutil\"";
if (ex.getMessage().contains(certutilMsg)) {
throw new SkippedException("certutil is not installed");
}
throw ex;
}
}
private static void runTest() throws Exception {
String testSrc = System.getProperty("test.src", ".");
try {
// removing the alias NonUniqueName if it already exists
ProcessTools.executeCommand("certutil", "-user", "-delstore", "MY",
"NonUniqueName");
// Importing 1st certificate into MY keystore using certutil tool
ProcessTools.executeCommand("certutil", "-user", "-addstore", "MY",
testSrc + "/nonUniq1.pem");
// Importing 2nd certificate into MY keystore using certutil tool
ProcessTools.executeCommand("certutil", "-user", "-addstore", "MY",
testSrc + "/nonUniq2.pem");
// Now we have 2
checkCount(1, 1);
ProcessTools.executeCommand("certutil", "-user", "-delstore", "MY",
"NonUniqueName");
// Now we have 2
checkCount(0, 0);
} finally {
ProcessTools.executeCommand("certutil", "-user", "-delstore", "MY",
"NonUniqueName");
}
}
static void checkCount(int c0, int c1) throws Exception {
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
int count0 = 0, count1 = 0;
for (String alias : Collections.list(ks.aliases())) {
if (alias.equals("NonUniqueName")) {
count0++;
}
if (alias.equals("NonUniqueName (1)")) {
count1++;
}
}
if (count0 != c0) {
throw new Exception("error: unexpected number of entries ("
+ count0 + ") in the Windows-MY store");
}
if (count1 != c1) {
throw new Exception("error: unexpected number of entries ("
+ count1 + ") in the Windows-MY store");
}
}
}

View file

@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB/jCCAWegAwIBAgIJANy5XBGM4BSuMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
BAMMDU5vblVuaXF1ZU5hbWUwHhcNMTYwNDAxMTcyMjQ0WhcNMTYwNzEwMTcyMjQ0
WjAYMRYwFAYDVQQDDA1Ob25VbmlxdWVOYW1lMIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDI0hlED2YFVgTaVLKWvsqB9JN9EJpUWECkB97fJwb1x99dHf0TO2p6
HPPvkvjBiAMEZYbojCz+WpNhG1Ilu/UgKwPyHh1pL6kRcEhlS2G3i7p9SDLHWlk0
xfdhSZERgd6ROpDnY7eaj1CTdVCSyEATs4FFyNtN9Q39jyeCU++ksQIDAQABo1Aw
TjAdBgNVHQ4EFgQUpW/Wtw/OOTdnFTL7afIkNjuCVr8wHwYDVR0jBBgwFoAUpW/W
tw/OOTdnFTL7afIkNjuCVr8wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
gQAWC+xX1cGNNp3F6dAb5tKKJGgQwsjfrjDP0/AirWc7Im1kTCpVPT61Ayt0bHgH
n3hGivKmO7ChQAI3QsDMDKWE98tF6afPltBOoWh2a9tPd65JSD1HfkG+Wc1IZ5gL
8rKp1tdKTEG2A+qXRN/e6DdtMsgDrK1iPfX+rer53TC+Yg==
-----END CERTIFICATE-----

View file

@ -0,0 +1,13 @@
-----BEGIN CERTIFICATE-----
MIIB/jCCAWegAwIBAgIJAPyQune5t/SZMA0GCSqGSIb3DQEBCwUAMBgxFjAUBgNV
BAMMDU5vblVuaXF1ZU5hbWUwHhcNMTYwNDAxMTcyMzI0WhcNMTYwNzEwMTcyMzI0
WjAYMRYwFAYDVQQDDA1Ob25VbmlxdWVOYW1lMIGfMA0GCSqGSIb3DQEBAQUAA4GN
ADCBiQKBgQDeSu/pPzL9hA1kjA2Rs13LpN2lNrisbYg/Vj/swGDMJnVCzS3IFQQy
71515mru+ngrHnfPSo4FKUhZPJzET2D7CruR65SzhQ96SHGoR8rhmL41KRBKELuR
3MoarLFziFzeIil4NZg55xp6TE/WCXRfi7HNdIgoKQGLoIhehVGN8QIDAQABo1Aw
TjAdBgNVHQ4EFgQUxFw79pLSf5Ul3zLqi/Mc6pSxEtswHwYDVR0jBBgwFoAUxFw7
9pLSf5Ul3zLqi/Mc6pSxEtswDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOB
gQDPilBcFpFrjwqb+lJxDxXK992KjNUS8yFLo1DQ/LBTaoHvy/U5zxzRq+nvSaaf
h+RIKqTwIbuBhSjrXVdJ/gzob/UlPC7IDo7FVbZwOHqTkqEum8jQEpX67hEevw9s
+reyqGhLsCtQK6uBTd2Nt9uOVCHrWNzWgQewkVYAUM5QpA==
-----END CERTIFICATE-----