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
1 change: 0 additions & 1 deletion test/jdk/ProblemList.txt
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,6 @@ javax/net/ssl/SSLEngine/TestAllSuites.java 8298874 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

javax/net/ssl/DTLS/PacketLossRetransmission.java 8169086 macosx-x64
javax/net/ssl/DTLS/RespondToRetransmit.java 8169086 macosx-all
Expand Down
155 changes: 90 additions & 65 deletions test/jdk/javax/net/ssl/SSLEngine/Basics.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,43 +26,52 @@
* @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 {
// Re-enable TLSv1.1 and TLS_RSA_* since test depends on it.
SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1", "TLS_RSA_*");
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);
Expand All @@ -79,75 +88,85 @@ public static void main(String args[]) throws Exception {
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");
}

/*
Expand All @@ -158,32 +177,27 @@ public static void main(String args[]) throws Exception {
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() */
ByteBuffer smallBB = ByteBuffer.allocate(10);

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();

Expand All @@ -198,14 +212,18 @@ public static void main(String args[]) throws Exception {
*/
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();
Expand All @@ -220,7 +238,7 @@ public static void main(String args[]) throws Exception {

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);
}
Expand All @@ -235,31 +253,38 @@ public static void main(String args[]) throws Exception {
appBB)).getStatus() !=
Status.BUFFER_UNDERFLOW) {
System.out.println(sslER);
throw new Exception("unwrap should underflow");
throw new RuntimeException("unwrap should underflow");
}

if ((sslER =
ssle.unwrap(ByteBuffer.wrap(incompleteSSLHeader),
appBB)).getStatus() !=
Status.BUFFER_UNDERFLOW) {
System.out.println(sslER);
throw new Exception("unwrap should underflow");
throw new RuntimeException("unwrap should underflow");
}

if ((sslER =
ssle.unwrap(ByteBuffer.wrap(smallv2Header),
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");
Expand All @@ -280,8 +305,8 @@ public static void main(String args[]) throws Exception {
(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) {
Expand Down