Skip to content
Permalink
Browse files

8237977: Further update javax/net/ssl/compatibility/Compatibility.java

Reviewed-by: rhalade
  • Loading branch information
John Jiang committed Mar 25, 2020
1 parent ffe5e84 commit 60fae7797438ea0e7d6e4354af0f8406fab2b16c
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
* 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
@@ -147,7 +147,7 @@
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256(
0x0067, KeyExAlgorithm.DHE_RSA, Protocol.TLSV1_2, Protocol.TLSV1_2),
TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA(
0x004C, KeyExAlgorithm.ECDH_ECDSA, Protocol.TLSV1, Protocol.TLSV1_2),
0x004C, KeyExAlgorithm.ECDH_ECDSA, Protocol.SSLV3, Protocol.TLSV1_2),
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256(
0x0040, KeyExAlgorithm.DHE_DSS, Protocol.TLSV1_2, Protocol.TLSV1_2),
TLS_RSA_WITH_AES_256_CBC_SHA256(
@@ -159,7 +159,7 @@
TLS_DH_anon_WITH_AES_256_CBC_SHA(
0x003A, KeyExAlgorithm.DH_ANON, Protocol.SSLV3, Protocol.TLSV1_2),
TLS_DHE_RSA_WITH_AES_256_CBC_SHA(
0x0039, KeyExAlgorithm.DHE_RSA, Protocol.TLSV1, Protocol.TLSV1_2),
0x0039, KeyExAlgorithm.DHE_RSA, Protocol.SSLV3, Protocol.TLSV1_2),
TLS_DHE_DSS_WITH_AES_256_CBC_SHA(
0x0038, KeyExAlgorithm.DHE_DSS, Protocol.TLSV1_2, Protocol.TLSV1_2),
TLS_RSA_WITH_AES_256_CBC_SHA(
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@@ -389,6 +389,14 @@ private Cert(
this.privKeyMaterials = privKeyMaterials;
}

public static Cert[] getCerts(String... certNames) {
Cert[] certs = new Cert[certNames.length];
for(int i = 0; i < certNames.length; i++) {
certs[i] = Cert.valueOf(certNames[i]);
}
return certs;
}

// Two certificates (mainCert and exampleCert) are selected to respect the
// specified cipher suite. SNI-associated cases specify exampleCert as desired.
public static Cert[] getCerts(CipherSuite cipherSuite) {
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@@ -73,17 +73,6 @@
PrintStream origStdOut = System.out;
PrintStream origStdErr = System.err;

boolean debug = Boolean.getBoolean("debug");

String securityPropertiesFile = System.getProperty(
"test.security.properties",
System.getProperty("test.src") + "/java.security");
System.out.println("security properties: " + securityPropertiesFile);

// If true, server and client CANNOT be a same JDK
boolean disallowSameEndpoint = Boolean.getBoolean("disallowSameEndpoint");
System.out.println("disallowSameEndpoint: " + disallowSameEndpoint);

try (PrintStream printStream = new PrintStream(
new FileOutputStream(Utils.TEST_LOG, true))) {
System.setOut(printStream);
@@ -92,83 +81,13 @@
System.out.println(Utils.startHtml());
System.out.println(Utils.startPre());

JdkInfo targetJdkInfo = new JdkInfo(System.getProperty("test.jdk"));
for (UseCase useCase : getUseCases()) {
for (JdkInfo serverJdk : jdkInfos) {
Map<String, String> props = new LinkedHashMap<>();
if (debug) {
props.put("javax.net.debug", "all");
}
props.put("java.security.properties", securityPropertiesFile);

props.put(Utils.PROP_PROTOCOL, useCase.protocol.name);
props.put(Utils.PROP_CIPHER_SUITE, useCase.cipherSuite.name());
props.put(Utils.PROP_CLIENT_AUTH, String.valueOf(useCase.clientAuth));
if (useCase.appProtocol != UseCase.AppProtocol.NONE) {
props.put(Utils.PROP_APP_PROTOCOLS,
Utils.join(Utils.VALUE_DELIMITER,
useCase.appProtocol.appProtocols));
props.put(Utils.PROP_NEGO_APP_PROTOCOL,
useCase.appProtocol.negoAppProtocol);
}
props.put(Utils.PROP_SERVER_JDK, serverJdk.version);

props.put(Utils.PROP_SUPPORTS_SNI_ON_SERVER,
serverJdk.supportsSNI + "");
props.put(Utils.PROP_SUPPORTS_ALPN_ON_SERVER,
serverJdk.supportsALPN + "");

for (JdkInfo clientJdk : jdkInfos) {
if (disallowSameEndpoint && clientJdk == serverJdk) {
continue;
}

TestCase testCase = new TestCase(serverJdk, clientJdk,
useCase);
System.out.println(Utils.anchorName(testCase.toString(),
"===== Case start ====="));
System.out.println(testCase.toString());

props.put(Utils.PROP_NEGATIVE_CASE_ON_SERVER,
testCase.negativeCaseOnServer + "");
props.put(Utils.PROP_NEGATIVE_CASE_ON_CLIENT,
testCase.negativeCaseOnClient + "");

Future<OutputAnalyzer> serverFuture = executor.submit(() -> {
return runServer(serverJdk.jdkPath, props);
});
int port = waitForServerStarted();
System.out.println("port=" + port);

props.put(Utils.PROP_PORT, port + "");

props.put(Utils.PROP_CLIENT_JDK, clientJdk.version);

props.put(Utils.PROP_SUPPORTS_SNI_ON_CLIENT,
clientJdk.supportsSNI + "");
props.put(Utils.PROP_SUPPORTS_ALPN_ON_CLIENT,
clientJdk.supportsALPN + "");
if (useCase.serverName != UseCase.ServerName.NONE) {
props.put(Utils.PROP_SERVER_NAME,
useCase.serverName.name);
}

Status clientStatus = null;
if (port != -1) {
String clientOutput = runClient(clientJdk.jdkPath,
props).getOutput();
clientStatus = getStatus(clientOutput);
}

String serverOutput = serverFuture.get().getOutput();
Status serverStatus = getStatus(serverOutput);
testCase.setStatus(caseStatus(serverStatus, clientStatus));
testCases.add(testCase);
System.out.printf(
"ServerStatus=%s, ClientStatus=%s, CaseStatus=%s%n",
serverStatus, clientStatus, testCase.getStatus());

System.out.println("===== Case end =====");
}
for (JdkInfo jdkInfo : jdkInfos) {
testCases.add(
runCase(targetJdkInfo, jdkInfo, useCase, executor));
testCases.add(
runCase(jdkInfo, targetJdkInfo, useCase, executor));
}
}

@@ -182,6 +101,81 @@
return testCases;
}

private TestCase runCase(JdkInfo serverJdk, JdkInfo clientJdk,
UseCase useCase, ExecutorService executor) throws Exception {
Map<String, String> props = new LinkedHashMap<>();
if (Utils.DEBUG) {
props.put("javax.net.debug", "all");
}

props.put("java.security.properties", Utils.SECURITY_PROPERTIES_FILE);

props.put(Utils.PROP_CERTS, Utils.join(Utils.VALUE_DELIMITER,
Cert.getCerts(useCase.cipherSuite)));
props.put(Utils.PROP_CLIENT_AUTH, String.valueOf(useCase.clientAuth));
if (useCase.appProtocol != UseCase.AppProtocol.NONE) {
props.put(Utils.PROP_APP_PROTOCOLS,
Utils.join(Utils.VALUE_DELIMITER,
useCase.appProtocol.appProtocols));
props.put(Utils.PROP_NEGO_APP_PROTOCOL,
useCase.appProtocol.negoAppProtocol);
}
props.put(Utils.PROP_SERVER_JDK, serverJdk.version);

props.put(Utils.PROP_SUPPORTS_SNI_ON_SERVER,
serverJdk.supportsSNI + "");
props.put(Utils.PROP_SUPPORTS_ALPN_ON_SERVER,
serverJdk.supportsALPN + "");

TestCase testCase = new TestCase(serverJdk, clientJdk, useCase);
System.out.println(Utils.anchorName(testCase.toString(),
"===== Case start ====="));
System.out.println(testCase.toString());

props.put(Utils.PROP_NEGATIVE_CASE_ON_SERVER,
testCase.negativeCaseOnServer + "");
props.put(Utils.PROP_NEGATIVE_CASE_ON_CLIENT,
testCase.negativeCaseOnClient + "");

Future<OutputAnalyzer> serverFuture = executor.submit(() -> {
return runServer(serverJdk.jdkPath, props);
});
int port = waitForServerStarted();
System.out.println("port=" + port);

props.put(Utils.PROP_PORT, port + "");

props.put(Utils.PROP_CLIENT_JDK, clientJdk.version);

props.put(Utils.PROP_PROTOCOL, useCase.protocol.name);
props.put(Utils.PROP_CIPHER_SUITE, useCase.cipherSuite.name());
props.put(Utils.PROP_SUPPORTS_SNI_ON_CLIENT,
clientJdk.supportsSNI + "");
props.put(Utils.PROP_SUPPORTS_ALPN_ON_CLIENT,
clientJdk.supportsALPN + "");
if (useCase.serverName != UseCase.ServerName.NONE) {
props.put(Utils.PROP_SERVER_NAME,
useCase.serverName.name);
}

Status clientStatus = null;
if (port != -1) {
String clientOutput = runClient(clientJdk.jdkPath,
props).getOutput();
clientStatus = getStatus(clientOutput);
}

String serverOutput = serverFuture.get().getOutput();
Status serverStatus = getStatus(serverOutput);
testCase.setStatus(caseStatus(serverStatus, clientStatus));
System.out.printf(
"ServerStatus=%s, ClientStatus=%s, CaseStatus=%s%n",
serverStatus, clientStatus, testCase.getStatus());

System.out.println("===== Case end =====");
return testCase;
}

// Generates the test result report.
protected boolean generateReport(List<TestCase> testCases)
throws IOException {
@@ -192,14 +186,15 @@ protected boolean generateReport(List<TestCase> testCases)
report.append(Utils.startTable());
report.append(Utils.row(
"No.",
"ServerJDK",
"ClientJDK",
"Client",
"Server",
"Protocol",
"CipherSuite",
"ClientAuth",
"Cipher suite",
"Client auth",
"SNI",
"ALPN",
"Status"));
"Status",
"Reason"));
for (int i = 0, size = testCases.size(); i < size; i++) {
TestCase testCase = testCases.get(i);

@@ -208,8 +203,8 @@ protected boolean generateReport(List<TestCase> testCases)
Utils.TEST_LOG,
testCase.toString(),
i + ""),
testCase.serverJdk.version,
testCase.clientJdk.version,
testCase.serverJdk.version,
testCase.useCase.protocol.name,
testCase.useCase.cipherSuite,
Utils.boolToStr(
@@ -218,10 +213,10 @@ protected boolean generateReport(List<TestCase> testCases)
testCase.useCase.serverName == UseCase.ServerName.EXAMPLE),
Utils.boolToStr(
testCase.useCase.appProtocol == UseCase.AppProtocol.EXAMPLE),
testCase.getStatus()));
failed = failed
|| testCase.getStatus() == Status.FAIL
|| testCase.getStatus() == Status.UNEXPECTED_SUCCESS;
testCase.getStatus(),
testCase.reason()));

failed = failed || testCase.isFailed();
}
report.append(Utils.endTable());
report.append(Utils.endHtml());
@@ -263,26 +258,15 @@ private static Status getStatus(String log) {
}

private static Status caseStatus(Status serverStatus, Status clientStatus) {
if (clientStatus == null || clientStatus == Status.TIMEOUT) {
return serverStatus == Status.EXPECTED_FAIL
? Status.EXPECTED_FAIL
: Status.FAIL;
} else if (serverStatus == Status.TIMEOUT) {
return clientStatus == Status.EXPECTED_FAIL
? Status.EXPECTED_FAIL
: Status.FAIL;
} else {
return serverStatus == clientStatus
? serverStatus
: Status.FAIL;
}
return (serverStatus == Status.EXPECTED_FAIL && clientStatus != Status.SUCCESS)
|| (clientStatus == Status.EXPECTED_FAIL && serverStatus != Status.SUCCESS)
? Status.EXPECTED_FAIL
: (serverStatus == clientStatus ? serverStatus : Status.FAIL);
}

// Retrieves JDK info from the file which is specified by jdkListFile.
// And the current testing JDK, which is specified by test.jdk, always be used.
private static Set<JdkInfo> jdkInfoList() {
List<String> jdkList = jdkList();
jdkList.add(System.getProperty("test.jdk"));

Set<JdkInfo> jdkInfoList = new LinkedHashSet<>();
for (String jdkPath : jdkList) {
@@ -1,5 +1,6 @@

/*
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 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
@@ -21,6 +22,9 @@
* questions.
*/

import java.util.LinkedHashMap;
import java.util.Map;

/*
* It represents a JDK with some specific attributes.
* If two JdkInfo instances have the same version value, the instances are
@@ -32,7 +36,9 @@

public final String version;
public final String supportedProtocols;
public final String enabledProtocols;
public final String supportedCipherSuites;
public final String enabledCipherSuites;
public final boolean supportsSNI;
public final boolean supportsALPN;

@@ -48,14 +54,18 @@ public JdkInfo(String jdkPath) {
String[] attributes = Utils.split(output, Utils.PARAM_DELIMITER);
version = attributes[0].replaceAll(".*=", "");
supportedProtocols = attributes[1].replaceAll(".*=", "");
supportedCipherSuites = attributes[2].replaceAll(".*=", "");
supportsSNI = Boolean.valueOf(attributes[3].replaceAll(".*=", ""));
supportsALPN = Boolean.valueOf(attributes[4].replaceAll(".*=", ""));
enabledProtocols = attributes[2].replaceAll(".*=", "");
supportedCipherSuites = attributes[3].replaceAll(".*=", "");
enabledCipherSuites = attributes[4].replaceAll(".*=", "");
supportsSNI = Boolean.valueOf(attributes[5].replaceAll(".*=", ""));
supportsALPN = Boolean.valueOf(attributes[6].replaceAll(".*=", ""));
}

// Determines the specific attributes for the specified JDK.
private static String jdkAttributes(String jdkPath) {
return ProcessUtils.java(jdkPath, null, JdkUtils.class).getOutput();
Map<String, String> props = new LinkedHashMap<>();
props.put("java.security.properties", Utils.SECURITY_PROPERTIES_FILE);
return ProcessUtils.java(jdkPath, props, JdkUtils.class).getOutput();
}

@Override
@@ -89,7 +99,15 @@ public boolean supportsProtocol(Protocol protocol) {
return supportedProtocols.contains(protocol.name);
}

public boolean enablesProtocol(Protocol protocol) {
return enabledProtocols.contains(protocol.name);
}

public boolean supportsCipherSuite(CipherSuite cipherSuite) {
return supportedCipherSuites.contains(cipherSuite.name());
}

public boolean enablesCipherSuite(CipherSuite cipherSuite) {
return enabledCipherSuites.contains(cipherSuite.name());
}
}

0 comments on commit 60fae77

Please sign in to comment.