Skip to content

8272875: Change the default key manager to PKIX #24756

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 6 commits into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public class KeyManagerFactory {
public static final String getDefaultAlgorithm() {
String type = Security.getProperty("ssl.KeyManagerFactory.algorithm");
if (type == null) {
type = "SunX509";
type = "PKIX";
}
return type;
}
Expand Down
2 changes: 1 addition & 1 deletion src/java.base/share/conf/security/java.security
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ security.overridePropertiesFile=true
# Determines the default key and trust manager factory algorithms for
# the javax.net.ssl package.
#
ssl.KeyManagerFactory.algorithm=SunX509
ssl.KeyManagerFactory.algorithm=PKIX
ssl.TrustManagerFactory.algorithm=PKIX

#
Expand Down
33 changes: 10 additions & 23 deletions test/jdk/javax/rmi/ssl/SSLSocketParametersTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 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
Expand All @@ -24,7 +24,8 @@
/*
* @test
* @bug 5016500
* @library /test/lib/
* @library /javax/net/ssl/templates
* /test/lib/
* @summary Test SslRmi[Client|Server]SocketFactory SSL socket parameters.
* @run main/othervm SSLSocketParametersTest 1
* @run main/othervm SSLSocketParametersTest 2
Expand All @@ -36,8 +37,6 @@
*/
import jdk.test.lib.Asserts;

import java.io.IOException;
import java.io.File;
import java.io.Serializable;
import java.lang.ref.Reference;
import java.rmi.ConnectIOException;
Expand All @@ -49,13 +48,17 @@
import javax.rmi.ssl.SslRMIClientSocketFactory;
import javax.rmi.ssl.SslRMIServerSocketFactory;

public class SSLSocketParametersTest implements Serializable {
public class SSLSocketParametersTest extends SSLContextTemplate {

public SSLSocketParametersTest() throws Exception {
SSLContext.setDefault(createServerSSLContext());
}

public interface Hello extends Remote {
String sayHello() throws RemoteException;
}

public class HelloImpl implements Hello {
public static class HelloImpl implements Hello {
public String sayHello() {
return "Hello World!";
}
Expand Down Expand Up @@ -134,23 +137,7 @@ public void runTest(int testNumber) throws Exception {
}

public static void main(String[] args) throws Exception {
// Set keystore properties (server-side)
//
final String keystore = System.getProperty("test.src") +
File.separator + "keystore";
System.out.println("KeyStore = " + keystore);
System.setProperty("javax.net.ssl.keyStore", keystore);
System.setProperty("javax.net.ssl.keyStorePassword", "password");

// Set truststore properties (client-side)
//
final String truststore = System.getProperty("test.src") +
File.separator + "truststore";
System.out.println("TrustStore = " + truststore);
System.setProperty("javax.net.ssl.trustStore", truststore);
System.setProperty("javax.net.ssl.trustStorePassword", "trustword");

SSLSocketParametersTest test = new SSLSocketParametersTest();
test.runTest(Integer.parseInt(args[0]));
}
}
}
Binary file removed test/jdk/javax/rmi/ssl/keystore
Binary file not shown.
Binary file removed test/jdk/javax/rmi/ssl/truststore
Binary file not shown.
177 changes: 150 additions & 27 deletions test/jdk/sun/net/www/protocol/https/HttpsClient/ServerIdentityTest.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 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
Expand Down Expand Up @@ -31,31 +31,58 @@
* @bug 4328195
* @summary Need to include the alternate subject DN for certs,
* https should check for this
* @modules java.base/sun.security.x509
* java.base/sun.security.util
* @library /javax/net/ssl/templates
* @run main/othervm ServerIdentityTest dnsstore localhost
* @run main/othervm ServerIdentityTest ipstore 127.0.0.1
* /test/lib
* @run main/othervm ServerIdentityTest dns localhost
* @run main/othervm ServerIdentityTest ip 127.0.0.1
*
* @author Yingxian Wang
*/

import java.io.InputStream;
import static jdk.test.lib.Asserts.fail;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.Proxy;
import java.net.URL;
import java.net.UnknownHostException;

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManagerFactory;
import jdk.test.lib.security.CertificateBuilder;
import sun.security.x509.AuthorityKeyIdentifierExtension;
import sun.security.x509.GeneralName;
import sun.security.x509.GeneralNames;
import sun.security.x509.KeyIdentifier;
import sun.security.x509.SerialNumber;
import sun.security.x509.X500Name;

public final class ServerIdentityTest extends SSLSocketTemplate {

private static String keystore;
private static String hostname;
private static SSLContext context;
private static SSLContext serverContext;

/*
* Run the test case.
Expand All @@ -64,7 +91,7 @@ public static void main(String[] args) throws Exception {
// Get the customized arguments.
initialize(args);

(new ServerIdentityTest()).run();
new ServerIdentityTest().run();
}

ServerIdentityTest() throws UnknownHostException {
Expand Down Expand Up @@ -95,7 +122,7 @@ protected void runClientApplication(int serverPort) throws Exception {
HttpURLConnection urlc = null;
InputStream is = null;
try {
urlc = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
urlc = (HttpURLConnection) url.openConnection(Proxy.NO_PROXY);
is = urlc.getInputStream();
} finally {
if (is != null) {
Expand All @@ -109,31 +136,127 @@ protected void runClientApplication(int serverPort) throws Exception {

@Override
protected SSLContext createServerSSLContext() throws Exception {
return context;
}

@Override
protected SSLContext createClientSSLContext() throws Exception {
return context;
return serverContext;
}

private static void initialize(String[] args) throws Exception {
keystore = args[0];
String mode = args[0];
hostname = args[1];

String password = "changeit";
String keyFilename =
System.getProperty("test.src", ".") + "/" + keystore;
String trustFilename =
System.getProperty("test.src", ".") + "/" + keystore;
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
KeyPair caKeys = kpg.generateKeyPair();
KeyPair serverKeys = kpg.generateKeyPair();
KeyPair clientKeys = kpg.generateKeyPair();

CertificateBuilder serverCertificateBuilder = customCertificateBuilder(
"CN=server, O=Some-Org, L=Some-City, ST=Some-State, C=US",
serverKeys.getPublic(), caKeys.getPublic())
.addBasicConstraintsExt(false, false, -1);

System.setProperty("javax.net.ssl.keyStore", keyFilename);
System.setProperty("javax.net.ssl.keyStorePassword", password);
System.setProperty("javax.net.ssl.trustStore", trustFilename);
System.setProperty("javax.net.ssl.trustStorePassword", password);
if (mode.equalsIgnoreCase("dns")) {
serverCertificateBuilder.addSubjectAltNameDNSExt(List.of(hostname));
} else if (mode.equalsIgnoreCase("ip")) {
serverCertificateBuilder.addSubjectAltNameIPExt(List.of(hostname));
} else {
fail("Unknown mode: " + mode);
}

X509Certificate trustedCert = createTrustedCert(caKeys);

X509Certificate serverCert = serverCertificateBuilder.build(
trustedCert, caKeys.getPrivate(), "SHA256WithRSA");

X509Certificate clientCert = customCertificateBuilder(
"CN=localhost, OU=SSL-Client, O=Some-Org, L=Some-City, ST=Some-State, C=US",
clientKeys.getPublic(), caKeys.getPublic())
.addBasicConstraintsExt(false, false, -1)
.build(trustedCert, caKeys.getPrivate(), "SHA256WithRSA");

serverContext = getSSLContext(
trustedCert, serverCert, serverKeys.getPrivate());

SSLContext clientContext = getSSLContext(
trustedCert, clientCert, clientKeys.getPrivate());

context = SSLContext.getDefault();
HttpsURLConnection.setDefaultSSLSocketFactory(
context.getSocketFactory());
clientContext.getSocketFactory());
}

private static SSLContext getSSLContext(
X509Certificate trustedCertificate, X509Certificate keyCertificate,
PrivateKey privateKey)
throws Exception {

// create a key store
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(null, null);

// import the trusted cert
ks.setCertificateEntry("TLS Signer", trustedCertificate);

// generate certificate chain
Certificate[] chain = new Certificate[2];
chain[0] = keyCertificate;
chain[1] = trustedCertificate;

// import the key entry.
final char[] passphrase = "passphrase".toCharArray();
ks.setKeyEntry("Whatever", privateKey, passphrase, chain);

// Using PKIX TrustManager
TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
tmf.init(ks);

// Using PKIX KeyManager
KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");

// create SSL context
SSLContext ctx = SSLContext.getInstance("TLS");
kmf.init(ks, passphrase);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
return ctx;
}

private static X509Certificate createTrustedCert(KeyPair caKeys)
throws Exception {
SecureRandom random = new SecureRandom();

KeyIdentifier kid = new KeyIdentifier(caKeys.getPublic());
GeneralNames gns = new GeneralNames();
GeneralName name = new GeneralName(new X500Name(
"O=Some-Org, L=Some-City, ST=Some-State, C=US"));
gns.add(name);
BigInteger serialNumber = BigInteger.valueOf(
random.nextLong(1000000) + 1);
return customCertificateBuilder(
"O=Some-Org, L=Some-City, ST=Some-State, C=US",
caKeys.getPublic(), caKeys.getPublic())
.setSerialNumber(serialNumber)
.addExtension(new AuthorityKeyIdentifierExtension(kid, gns,
new SerialNumber(serialNumber)))
.addBasicConstraintsExt(true, true, -1)
.build(null, caKeys.getPrivate(), "SHA256WithRSA");
}

private static CertificateBuilder customCertificateBuilder(
String subjectName, PublicKey publicKey, PublicKey caKey)
throws CertificateException, IOException {
SecureRandom random = new SecureRandom();

CertificateBuilder builder = new CertificateBuilder()
.setSubjectName(subjectName)
.setPublicKey(publicKey)
.setNotAfter(
Date.from(Instant.now().minus(1, ChronoUnit.HOURS)))
.setNotAfter(Date.from(Instant.now().plus(1, ChronoUnit.HOURS)))
.setSerialNumber(
BigInteger.valueOf(random.nextLong(1000000) + 1))
.addSubjectKeyIdExt(publicKey)
.addAuthorityKeyIdExt(caKey);
builder.addKeyUsageExt(
new boolean[]{true, true, true, true, true, true});

return builder;
}

}
Binary file not shown.
Binary file not shown.
8 changes: 7 additions & 1 deletion test/jdk/sun/security/tools/keytool/PrintSSL.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2008, 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
Expand Down Expand Up @@ -39,6 +39,7 @@
import java.net.ServerSocket;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Security;
import java.util.concurrent.CountDownLatch;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.SSLSocket;
Expand All @@ -48,6 +49,11 @@
public class PrintSSL {

public static void main(String[] args) throws Throwable {
// Using "SunX509" KeyManager which doesn't check peer supported
// signature algorithms, so we can make keytool print certificate
// with weak MD5withRSA signature algorithm.
Security.setProperty("ssl.KeyManagerFactory.algorithm", "SunX509");

Files.deleteIfExists(Paths.get("keystore"));

// make sure that "-printcert" works with weak algorithms
Expand Down
21 changes: 21 additions & 0 deletions test/lib/jdk/test/lib/security/CertificateBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import sun.security.x509.AlgorithmId;
import sun.security.x509.AuthorityInfoAccessExtension;
import sun.security.x509.AuthorityKeyIdentifierExtension;
import sun.security.x509.IPAddressName;
import sun.security.x509.SubjectKeyIdentifierExtension;
import sun.security.x509.BasicConstraintsExtension;
import sun.security.x509.CertificateSerialNumber;
Expand Down Expand Up @@ -233,6 +234,26 @@ public CertificateBuilder addSubjectAltNameDNSExt(List<String> dnsNames)
return this;
}

/**
* Helper method to add IPAddress types for the SAN extension
*
* @param IPAddresses A {@code List} of names to add as IPAddress
* types
* @throws IOException if an encoding error occurs.
*/
public CertificateBuilder addSubjectAltNameIPExt(List<String> IPAddresses)
throws IOException {
if (!IPAddresses.isEmpty()) {
GeneralNames gNames = new GeneralNames();
for (String name : IPAddresses) {
gNames.add(new GeneralName(new IPAddressName(name)));
}
addExtension(new SubjectAlternativeNameExtension(false,
gNames));
}
return this;
}

/**
* Helper method to add one or more OCSP URIs to the Authority Info Access
* certificate extension. Location strings can be in two forms:
Expand Down