Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions test/jdk/java/security/testlibrary/CertificateBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
import java.security.cert.Extension;
import javax.security.auth.x500.X500Principal;
import java.math.BigInteger;
import java.time.temporal.ChronoUnit;
import java.time.Instant;

import sun.security.util.DerOutputStream;
import sun.security.util.DerValue;
Expand Down Expand Up @@ -190,6 +192,12 @@ public void setValidity(Date nbDate, Date naDate) {
setNotAfter(naDate);
}

public CertificateBuilder setOneHourValidity() {
setNotBefore(Date.from(Instant.now().minus(5, ChronoUnit.MINUTES)));
setNotAfter(Date.from(Instant.now().plus(1, ChronoUnit.HOURS)));
return this;
}

/**
* Set the serial number on the certificate.
*
Expand Down
139 changes: 72 additions & 67 deletions test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2026, 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
Expand All @@ -21,90 +21,95 @@
* questions.
*/

//
// Security properties, once set, cannot revert to unset. To avoid
// conflicts with tests running in the same VM isolate this test by
// running it in otherVM mode.
//

/*
* @test
* @bug 6302644
* @summary X509KeyManager implementation for NewSunX509 doesn't return most
* preferable key
* @run main/othervm PreferredKey
* @modules java.base/sun.security.x509
* java.base/sun.security.util
* @library ../../../../java/security/testlibrary/
* @library /test/lib
* @build CertificateBuilder
* @run main PreferredKey

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe:

 * @library ../../../../java/security/testlibrary/
 * @library /test/lib
 * @build jdk.test.lib.Utils
 *        CertificateBuilder

Is a better approach? (we're using it elsewhere in JDK11, e.g.

)

@sendaoYan sendaoYan May 22, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have split the '@library' as two lines. But I do not add '@build jdk.test.lib.Utils', seems these two tests do not need build this class jdk.test.lib.Utils.

*/
import java.io.*;
import java.net.*;
import java.security.*;
import javax.net.ssl.*;
import jdk.test.lib.Asserts;
import sun.security.testlibrary.CertificateBuilder;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.X509KeyManager;
import java.io.IOException;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class PreferredKey {

/*
* =============================================================
* Set the various variables needed for the tests, then
* specify what tests to run on each side.
*/
public static void main(String[] args) throws Exception {
X509KeyManager km = getKeyManager();

testPreferredKey(km, "RSA", new String[] {"RSA", "DSA"});
testPreferredKey(km, "DSA", new String[] {"DSA", "RSA"});
}

/*
* Where do we find the keystores?
*/
static String pathToStores = "../../../../javax/net/ssl/etc";
static String keyStoreFile = "keystore";
static String passwd = "passphrase";
private static void testPreferredKey(X509KeyManager km,
String keyType,
String[] multiKeyTypes) {
String[] aliases = km.getClientAliases(keyType, null);
String alias = km.chooseClientAlias(multiKeyTypes, null, null);

Asserts.assertTrue(aliases != null && alias != null,
"Should return preferred alias");

public static void main(String[] args) throws Exception {
// MD5 is used in this test case, don't disable MD5 algorithm.
Security.setProperty("jdk.certpath.disabledAlgorithms",
"MD2, RSA keySize < 1024");
Security.setProperty("jdk.tls.disabledAlgorithms",
"SSLv3, RC4, DH keySize < 768");
String algorithm = km.getPrivateKey(alias).getAlgorithm();
Asserts.assertTrue(algorithm.equals(keyType) && algorithm.equals(
km.getPrivateKey(aliases[0]).getAlgorithm()),
"Failed to get the preferable key aliases");
}

KeyStore ks;
KeyManagerFactory kmf;
X509KeyManager km;
private static X509KeyManager getKeyManager() throws Exception {
char[] passphrase = "passphrase".toCharArray();

String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
"/" + keyStoreFile;
char [] password = passwd.toCharArray();
KeyPair rsaKey = KeyPairGenerator.getInstance("RSA").generateKeyPair();
KeyPair dsaKey = KeyPairGenerator.getInstance("DSA").generateKeyPair();

ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keyFilename), password);
kmf = KeyManagerFactory.getInstance("NewSunX509");
kmf.init(ks, password);
km = (X509KeyManager) kmf.getKeyManagers()[0];
// create a key store
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null, passphrase);

/*
* There should be both an rsa and a dsa entry in the
* keystore, otherwise the test will no work.
*/
String[] aliases = km.getClientAliases("RSA", null);
String alias = km.chooseClientAlias(new String[] {"RSA", "DSA"},
null, null);
ks.setKeyEntry("dummyrsa",
rsaKey.getPrivate(),
passphrase,
new Certificate[]{createSelfSignedCert(rsaKey,
"SHA256withRSA")});
ks.setKeyEntry("dummydsa",
dsaKey.getPrivate(),
passphrase,
new Certificate[]{createSelfSignedCert(dsaKey,
"SHA256withDSA")});

// there're should both be null or nonnull
if (aliases != null || alias != null) {
String algorithm = km.getPrivateKey(alias).getAlgorithm();
if (!algorithm.equals("RSA") || !algorithm.equals(
km.getPrivateKey(aliases[0]).getAlgorithm())) {
throw new Exception("Failed to get the preferable key aliases");
}
}
KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509");
kmf.init(ks, passphrase);

aliases = km.getClientAliases("DSA", null);
alias = km.chooseClientAlias(new String[] {"DSA", "RSA"},
null, null);
return (X509KeyManager) kmf.getKeyManagers()[0];
}

// there're should both be null or nonnull
if (aliases != null || alias != null) {
String algorithm = km.getPrivateKey(alias).getAlgorithm();
if (!algorithm.equals("DSA") || !algorithm.equals(
km.getPrivateKey(aliases[0]).getAlgorithm())) {
throw new Exception("Failed to get the preferable key aliases");
}
}
private static X509Certificate createSelfSignedCert(KeyPair caKeys,
String keyAlg)
throws CertificateException, IOException, NoSuchAlgorithmException {
long randomSerial = (long) (new SecureRandom().nextDouble() * 1000000) + 1;
CertificateBuilder certBuilder = new CertificateBuilder();
certBuilder.setSubjectName("CN=://example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US");
certBuilder.setPublicKey(caKeys.getPublic());
certBuilder.setOneHourValidity();
certBuilder.setSerialNumber(BigInteger.valueOf(randomSerial));
certBuilder.addSubjectKeyIdExt(caKeys.getPublic());
return certBuilder.build(null, caKeys.getPrivate(), keyAlg);
}
}
Loading