8298867: Basics.java fails with SSL handshake exception

Reviewed-by: xuelei, rhalade
This commit is contained in:
Matthew Donovan 2023-01-17 04:41:55 +00:00 committed by Julian Waters
parent 859ccd1a15
commit 06f9374e0c
2 changed files with 92 additions and 65 deletions

View File

@ -590,7 +590,6 @@ javax/net/ssl/SSLEngine/IllegalRecordVersion.java 8298873 generic-
javax/net/ssl/SSLEngine/EngineCloseOnAlert.java 8298868 generic-all
javax/net/ssl/SSLEngine/ConnectionTest.java 8298869 generic-all
javax/net/ssl/SSLEngine/CheckStatus.java 8298872 generic-all
javax/net/ssl/SSLEngine/Basics.java 8298867 generic-all
sun/security/provider/KeyStore/DKSTest.sh 8180266 windows-all

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 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
@ -26,41 +26,53 @@
* @bug 4495742
* @summary Add non-blocking SSL/TLS functionality, usable with any
* I/O abstraction
*
* This is intended to test many of the basic API calls to the SSLEngine
* interface. This doesn't really exercise much of the SSL code.
*
* @library /test/lib
* @author Brad Wetmore
* @run main/othervm Basics
*/
import java.security.*;
import java.io.*;
import java.nio.*;
import java.util.Arrays;
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.*;
import jdk.test.lib.security.SecurityUtils;
public class Basics {
private static String pathToStores = "../etc";
private static String keyStoreFile = "keystore";
private static String trustStoreFile = "truststore";
private static String passwd = "passphrase";
private static final String PATH_TO_STORES = "../etc";
private static final String KEY_STORE_FILE = "keystore";
private static final String TRUSTSTORE_FILE = "truststore";
private static String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + keyStoreFile;
private static String trustFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + trustStoreFile;
private static final String KEYSTORE_PATH =
System.getProperty("test.src", "./") + "/" + PATH_TO_STORES +
"/" + KEY_STORE_FILE;
private static final String TRUSTSTORE_PATH =
System.getProperty("test.src", "./") + "/" + PATH_TO_STORES +
"/" + TRUSTSTORE_FILE;
public static void main(String args[]) throws Exception {
public static void main(String[] args) throws Exception {
SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1");
runTest("TLSv1.3", "TLS_AES_256_GCM_SHA384");
runTest("TLSv1.2", "TLS_RSA_WITH_AES_256_GCM_SHA384");
runTest("TLSv1.1", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA");
}
private static void runTest(String protocol, String cipherSuite) throws Exception {
System.out.printf("Testing %s with %s%n", protocol, cipherSuite);
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS");
char[] passphrase = "passphrase".toCharArray();
ks.load(new FileInputStream(keyFilename), passphrase);
ts.load(new FileInputStream(trustFilename), passphrase);
ks.load(new FileInputStream(KEYSTORE_PATH), passphrase);
ts.load(new FileInputStream(TRUSTSTORE_PATH), passphrase);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, passphrase);
@ -77,75 +89,85 @@ public class Basics {
System.out.println(ssle);
String [] suites = ssle.getSupportedCipherSuites();
String secondSuite = suites[1];
String [] oneSuites = new String [] { secondSuite };
// sanity check that the ciphersuite we want to use is still supported
Arrays.stream(suites)
.filter(s -> s.equals(cipherSuite))
.findFirst()
.orElseThrow((() ->
new RuntimeException(cipherSuite +
" is not a supported ciphersuite.")));
printStrings("Supported Ciphersuites", suites);
printStrings("Enabled Ciphersuites", ssle.getEnabledCipherSuites());
ssle.setEnabledCipherSuites(oneSuites);
ssle.setEnabledCipherSuites(new String [] { cipherSuite });
printStrings("Set Ciphersuites", ssle.getEnabledCipherSuites());
suites = ssle.getEnabledCipherSuites();
if ((ssle.getEnabledCipherSuites().length != 1) ||
!(suites[0].equals(secondSuite))) {
throw new Exception("set ciphers not what was expected");
!(suites[0].equals(cipherSuite))) {
throw new RuntimeException("set ciphers not what was expected");
}
System.out.println();
String [] protocols = ssle.getSupportedProtocols();
String secondProtocol = protocols[1];
String [] oneProtocols = new String [] { protocols[1] };
// sanity check that the protocol we want is still supported
Arrays.stream(protocols)
.filter(p -> p.equals(protocol))
.findFirst()
.orElseThrow(() ->
new RuntimeException(protocol +
" is not a supported TLS protocol."));
printStrings("Supported Protocols", protocols);
printStrings("Enabled Protocols", ssle.getEnabledProtocols());
ssle.setEnabledProtocols(oneProtocols);
ssle.setEnabledProtocols(new String[]{ protocol });
printStrings("Set Protocols", ssle.getEnabledProtocols());
protocols = ssle.getEnabledProtocols();
if ((ssle.getEnabledProtocols().length != 1) ||
!(protocols[0].equals(secondProtocol))) {
throw new Exception("set protocols not what was expected");
!(protocols[0].equals(protocol))) {
throw new RuntimeException("set protocols not what was expected");
}
System.out.println("Checking get/setUseClientMode");
ssle.setUseClientMode(true);
if (ssle.getUseClientMode() != true) {
throw new Exception("set/getUseClientMode false");
if (!ssle.getUseClientMode()) {
throw new RuntimeException("set/getUseClientMode false");
}
ssle.setUseClientMode(false);
if (ssle.getUseClientMode() != false) {
throw new Exception("set/getUseClientMode true");
if (ssle.getUseClientMode()) {
throw new RuntimeException("set/getUseClientMode true");
}
System.out.println("Checking get/setClientAuth");
ssle.setNeedClientAuth(false);
if (ssle.getNeedClientAuth() != false) {
throw new Exception("set/getNeedClientAuth true");
if (ssle.getNeedClientAuth()) {
throw new RuntimeException("set/getNeedClientAuth true");
}
ssle.setNeedClientAuth(true);
if (ssle.getNeedClientAuth() != true) {
throw new Exception("set/getNeedClientAuth false");
if (!ssle.getNeedClientAuth()) {
throw new RuntimeException("set/getNeedClientAuth false");
}
ssle.setWantClientAuth(true);
if (ssle.getNeedClientAuth() == true) {
throw new Exception("set/getWantClientAuth need = true");
if (ssle.getNeedClientAuth()) {
throw new RuntimeException("set/getWantClientAuth need = true");
}
if (ssle.getWantClientAuth() != true) {
throw new Exception("set/getNeedClientAuth false");
if (!ssle.getWantClientAuth()) {
throw new RuntimeException("set/getNeedClientAuth false");
}
ssle.setWantClientAuth(false);
if (ssle.getWantClientAuth() != false) {
throw new Exception("set/getNeedClientAuth true");
if (ssle.getWantClientAuth()) {
throw new RuntimeException("set/getNeedClientAuth true");
}
/*
@ -156,13 +178,13 @@ public class Basics {
System.out.println("checking session creation");
ssle.setEnableSessionCreation(false);
if (ssle.getEnableSessionCreation() != false) {
throw new Exception("set/getSessionCreation true");
if (ssle.getEnableSessionCreation()) {
throw new RuntimeException("set/getSessionCreation true");
}
ssle.setEnableSessionCreation(true);
if (ssle.getEnableSessionCreation() != true) {
throw new Exception("set/getSessionCreation false");
if (!ssle.getEnableSessionCreation()) {
throw new RuntimeException("set/getSessionCreation false");
}
/* Checking for overflow wrap/unwrap() */
@ -170,18 +192,13 @@ public class Basics {
if (ssle.wrap(smallBB, smallBB).getStatus() !=
Status.BUFFER_OVERFLOW) {
throw new Exception("wrap should have overflowed");
throw new RuntimeException("wrap should have overflowed");
}
// For unwrap(), the BUFFER_OVERFLOW will not be generated
// until received SSL/TLS application data.
// Test test/jdk/javax/net/ssl/SSLEngine/LargePacket.java will check
// BUFFER_OVERFLOW/UNDERFLOW for both wrap() and unwrap().
//
//if (ssle.unwrap(smallBB, smallBB).getStatus() !=
// Status.BUFFER_OVERFLOW) {
// throw new Exception("unwrap should have overflowed");
//}
SSLSession ssls = ssle.getSession();
@ -196,14 +213,18 @@ public class Basics {
*/
if (ssle.wrap(appBB, netBB).getHandshakeStatus() !=
HandshakeStatus.NEED_UNWRAP) {
throw new Exception("initial client hello needs unwrap");
throw new RuntimeException("initial client hello needs unwrap");
}
/* Checking for overflow wrap/unwrap() */
if (ssle.wrap(appBB, netBB).getStatus() !=
Status.BUFFER_OVERFLOW) {
throw new Exception("unwrap should have overflowed");
/*
* After the first call to wrap(), the handshake status is
* NEED_UNWRAP and we need to receive data before doing anymore
* handshaking.
*/
SSLEngineResult result = ssle.wrap(appBB, netBB);
if (result.getStatus() != Status.OK
&& result.bytesConsumed() != 0 && result.bytesProduced() != 0) {
throw new RuntimeException("wrap should have returned without doing anything");
}
ByteBuffer ro = appBB.asReadOnlyBuffer();
@ -218,7 +239,7 @@ public class Basics {
try {
ssle.unwrap(netBB, ro);
throw new Exception("unwrap wasn't ReadOnlyBufferException");
throw new RuntimeException("unwrap wasn't ReadOnlyBufferException");
} catch (ReadOnlyBufferException e) {
System.out.println("Caught the ReadOnlyBuffer: " + e);
}
@ -233,7 +254,7 @@ public class Basics {
appBB)).getStatus() !=
Status.BUFFER_UNDERFLOW) {
System.out.println(sslER);
throw new Exception("unwrap should underflow");
throw new RuntimeException("unwrap should underflow");
}
if ((sslER =
@ -241,7 +262,7 @@ public class Basics {
appBB)).getStatus() !=
Status.BUFFER_UNDERFLOW) {
System.out.println(sslER);
throw new Exception("unwrap should underflow");
throw new RuntimeException("unwrap should underflow");
}
if ((sslER =
@ -249,15 +270,22 @@ public class Basics {
appBB)).getStatus() !=
Status.BUFFER_UNDERFLOW) {
System.out.println(sslER);
throw new Exception("unwrap should underflow");
throw new RuntimeException("unwrap should underflow");
}
// junk inbound message
try {
/*
* Exceptions are thrown when:
* - the length field is correct but the data can't be decoded.
* - the length field is larger than max allowed.
*/
ssle.unwrap(ByteBuffer.wrap(gobblydegook), appBB);
throw new Exception("Didn't catch the nasty SSLException");
} catch (SSLException e) {
System.out.println("caught the nasty SSLException: " + e);
throw new RuntimeException("Expected SSLProtocolException was not thrown "
+ "for bad input");
} catch (SSLProtocolException e) {
System.out.println("caught the SSLProtocolException for bad decoding: "
+ e);
}
System.out.println("Test PASSED");
@ -278,8 +306,8 @@ public class Basics {
(byte) 0x00 };
static byte [] gobblydegook = new byte [] {
// "HELLO HELLO"
(byte) 0x48, (byte) 0x45, (byte) 0x4C, (byte) 0x4C, (byte) 0x20,
// bad data but correct record length to cause decryption error
(byte) 0x48, (byte) 0x45, (byte) 0x4C, (byte) 0x00, (byte) 0x04,
(byte) 0x48, (byte) 0x45, (byte) 0x4C, (byte) 0x4C };
static void printStrings(String label, String [] strs) {