--- a/.hgtags Wed Aug 29 12:00:47 2018 -0400
+++ b/.hgtags Wed Aug 29 19:48:28 2018 +0200
@@ -496,15 +496,16 @@
14708e1acdc3974f4539027cbbcfa6d69f83cf51 jdk-11+21
00b16d0457e43d23f6ca5ade6b243edce62750a0 jdk-12+1
9937ef7499dcd7673714517fd5e450410c14ba4e jdk-11+22
+69b438908512d3dfef5852c6a843a5778333a309 jdk-12+2
1edcf36fe15f79d6228d1a63eb680878e2386480 jdk-11+23
+990db216e7199b2ba9989d8fa20b657e0ca7d969 jdk-12+3
ea900a7dc7d77dee30865c60eabd87fc24b1037c jdk-11+24
+499b873761d8e8a1cc4aa649daf04cbe98cbce77 jdk-12+4
331888ea4a788df801b1edf8836646cd25fc758b jdk-11+25
+f8696e0ab9b795030429fc3374ec03e378fd9ed7 jdk-12+5
945ba9278a272a5477ffb1b3ea1b04174fed8036 jdk-11+26
+7939b3c4e4088bf4f70ec5bbd8030393b653372f jdk-12+6
9d7d74c6f2cbe522e39fa22dc557fdd3f79b32ad jdk-11+27
-69b438908512d3dfef5852c6a843a5778333a309 jdk-12+2
-990db216e7199b2ba9989d8fa20b657e0ca7d969 jdk-12+3
-499b873761d8e8a1cc4aa649daf04cbe98cbce77 jdk-12+4
-f8696e0ab9b795030429fc3374ec03e378fd9ed7 jdk-12+5
-7939b3c4e4088bf4f70ec5bbd8030393b653372f jdk-12+6
ef57958c7c511162da8d9a75f0b977f0f7ac464e jdk-12+7
+76072a077ee1d815152d45d1692c4b36c53c5c49 jdk-11+28
492b366f8e5784cc4927c2c98f9b8a3f16c067eb jdk-12+8
--- a/make/Docs.gmk Wed Aug 29 12:00:47 2018 -0400
+++ b/make/Docs.gmk Wed Aug 29 19:48:28 2018 +0200
@@ -61,7 +61,7 @@
$(SUPPORT_OUTPUTDIR)/rmic/* $(TOPDIR)/src/*/share/doc/stub)
# URLs
-JAVADOC_BASE_URL := http://www.oracle.com/pls/topic/lookup?ctx=javase10&id=homepage
+JAVADOC_BASE_URL := http://www.oracle.com/pls/topic/lookup?ctx=javase$(VERSION_NUMBER)&id=homepage
BUG_SUBMIT_URL := http://bugreport.java.com/bugreport/
COPYRIGHT_URL := {@docroot}/../legal/copyright.html
LICENSE_URL := http://www.oracle.com/technetwork/java/javase/terms/license/java$(VERSION_NUMBER)speclicense.html
--- a/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Wed Aug 29 12:00:47 2018 -0400
+++ b/src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp Wed Aug 29 19:48:28 2018 +0200
@@ -1107,7 +1107,7 @@
}
}
__ pop(x, sp);
- for ( int i = first_arg ; i < arg_count ; i++ ) {
+ for ( int i = arg_count - 1 ; i >= first_arg ; i-- ) {
if (args[i].first()->is_Register()) {
;
} else if (args[i].first()->is_FloatRegister()) {
--- a/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Wed Aug 29 12:00:47 2018 -0400
+++ b/src/hotspot/cpu/s390/templateInterpreterGenerator_s390.cpp Wed Aug 29 19:48:28 2018 +0200
@@ -1681,7 +1681,7 @@
__ z_lg(Z_R1/*active_handles*/, thread_(active_handles));
__ clear_mem(Address(Z_R1, JNIHandleBlock::top_offset_in_bytes()), 4);
- // Bandle exceptions (exception handling will handle unlocking!).
+ // Handle exceptions (exception handling will handle unlocking!).
{
Label L;
__ load_and_test_long(Z_R0/*pending_exception*/, thread_(pending_exception));
@@ -1710,17 +1710,9 @@
__ notify_method_exit(true/*native_method*/, ilgl, InterpreterMacroAssembler::NotifyJVMTI);
// Move native method result back into proper registers and return.
- // C++ interpreter does not use result handler. So do we need to here? TODO(ZASM): check if correct.
- { NearLabel no_oop_or_null;
__ mem2freg_opt(Z_FRET, Address(Z_fp, _z_ijava_state_neg(fresult)));
- __ load_and_test_long(Z_RET, Address(Z_fp, _z_ijava_state_neg(lresult)));
- __ z_bre(no_oop_or_null); // No unboxing if the result is NULL.
- __ load_absolute_address(Z_R1, AbstractInterpreter::result_handler(T_OBJECT));
- __ compareU64_and_branch(Z_R1, Rresult_handler, Assembler::bcondNotEqual, no_oop_or_null);
- __ z_lg(Z_RET, oop_tmp_offset, Z_fp);
- __ verify_oop(Z_RET);
- __ bind(no_oop_or_null);
- }
+ __ mem2reg_opt(Z_RET, Address(Z_fp, _z_ijava_state_neg(lresult)));
+ __ call_stub(Rresult_handler);
// Pop the native method's interpreter frame.
__ pop_interpreter_frame(Z_R14 /*return_pc*/, Z_ARG2/*tmp1*/, Z_ARG3/*tmp2*/);
--- a/src/hotspot/cpu/x86/globals_x86.hpp Wed Aug 29 12:00:47 2018 -0400
+++ b/src/hotspot/cpu/x86/globals_x86.hpp Wed Aug 29 19:48:28 2018 +0200
@@ -119,7 +119,7 @@
product(bool, UseStoreImmI16, true, \
"Use store immediate 16-bits value instruction on x86") \
\
- product(intx, UseAVX, 3, \
+ product(intx, UseAVX, 2, \
"Highest supported AVX instructions set on x86/x64") \
range(0, 99) \
\
--- a/src/hotspot/share/compiler/compileBroker.cpp Wed Aug 29 12:00:47 2018 -0400
+++ b/src/hotspot/share/compiler/compileBroker.cpp Wed Aug 29 19:48:28 2018 +0200
@@ -1637,6 +1637,12 @@
* out to be a problem.
*/
void CompileBroker::shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread) {
+ // Free buffer blob, if allocated
+ if (thread->get_buffer_blob() != NULL) {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ CodeCache::free(thread->get_buffer_blob());
+ }
+
if (comp->should_perform_shutdown()) {
// There are two reasons for shutting down the compiler
// 1) compiler runtime initialization failed
@@ -1767,6 +1773,11 @@
tty->print_cr("Removing compiler thread %s after " JLONG_FORMAT " ms idle time",
thread->name(), thread->idle_time_millis());
}
+ // Free buffer blob, if allocated
+ if (thread->get_buffer_blob() != NULL) {
+ MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+ CodeCache::free(thread->get_buffer_blob());
+ }
return; // Stop this thread.
}
}
--- a/src/hotspot/share/runtime/thread.cpp Wed Aug 29 12:00:47 2018 -0400
+++ b/src/hotspot/share/runtime/thread.cpp Wed Aug 29 19:48:28 2018 +0200
@@ -3340,11 +3340,6 @@
}
CompilerThread::~CompilerThread() {
- // Free buffer blob, if allocated
- if (get_buffer_blob() != NULL) {
- MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
- CodeCache::free(get_buffer_blob());
- }
// Delete objects which were allocated on heap.
delete _counters;
}
--- a/src/java.base/share/classes/sun/security/ssl/CertSignAlgsExtension.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/CertSignAlgsExtension.java Wed Aug 29 19:48:28 2018 +0200
@@ -191,12 +191,12 @@
}
// update the context
- List<SignatureScheme> shemes =
+ List<SignatureScheme> schemes =
SignatureScheme.getSupportedAlgorithms(
shc.algorithmConstraints, shc.negotiatedProtocol,
spec.signatureSchemes);
- shc.peerRequestedCertSignSchemes = shemes;
- shc.handshakeSession.setPeerSupportedSignatureAlgorithms(shemes);
+ shc.peerRequestedCertSignSchemes = schemes;
+ shc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes);
if (!shc.isResumption && shc.negotiatedProtocol.useTLS13PlusSpec()) {
if (shc.sslConfig.clientAuthType !=
@@ -337,12 +337,12 @@
}
// update the context
- List<SignatureScheme> shemes =
+ List<SignatureScheme> schemes =
SignatureScheme.getSupportedAlgorithms(
chc.algorithmConstraints, chc.negotiatedProtocol,
spec.signatureSchemes);
- chc.peerRequestedCertSignSchemes = shemes;
- chc.handshakeSession.setPeerSupportedSignatureAlgorithms(shemes);
+ chc.peerRequestedCertSignSchemes = schemes;
+ chc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes);
}
}
}
--- a/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/CertificateMessage.java Wed Aug 29 19:48:28 2018 +0200
@@ -1031,8 +1031,8 @@
// Don't select a signature scheme unless we will be able to
// produce a CertificateVerify message later
if (SignatureScheme.getPreferableAlgorithm(
- hc.peerRequestedSignatureSchemes,
- ss, hc.negotiatedProtocol) == null) {
+ hc.peerRequestedSignatureSchemes,
+ ss, hc.negotiatedProtocol) == null) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
SSLLogger.warning(
--- a/src/java.base/share/classes/sun/security/ssl/HandshakeOutStream.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/HandshakeOutStream.java Wed Aug 29 19:48:28 2018 +0200
@@ -50,7 +50,7 @@
this.outputRecord = outputRecord;
}
- // Complete a handshakin message writing. Called by HandshakeMessage.
+ // Complete a handshaking message write. Called by HandshakeMessage.
void complete() throws IOException {
if (size() < 4) { // 4: handshake message header size
// internal_error alert will be triggered
--- a/src/java.base/share/classes/sun/security/ssl/SSLCipher.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/SSLCipher.java Wed Aug 29 19:48:28 2018 +0200
@@ -379,10 +379,10 @@
private final Map.Entry<WriteCipherGenerator,
ProtocolVersion[]>[] writeCipherGenerators;
- // Map of Ciphers listed in jdk.tls.KeyLimit
+ // Map of Ciphers listed in jdk.tls.keyLimits
private static final HashMap<String, Long> cipherLimits = new HashMap<>();
- // Keywords found on the jdk.tls.KeyLimit security property.
+ // Keywords found on the jdk.tls.keyLimits security property.
final static String tag[] = {"KEYUPDATE"};
static {
@@ -407,7 +407,7 @@
index = 0;
} else {
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
- SSLLogger.fine("jdk.net.keyLimits: Unknown action: " +
+ SSLLogger.fine("jdk.tls.keyLimits: Unknown action: " +
entry);
}
continue;
@@ -423,17 +423,18 @@
size = Long.parseLong(values[2]);
}
if (size < 1 || size > max) {
- throw new NumberFormatException("Length exceeded limits");
+ throw new NumberFormatException(
+ "Length exceeded limits");
}
} catch (NumberFormatException e) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
- SSLLogger.fine("jdk.net.keyLimits: " + e.getMessage() +
+ SSLLogger.fine("jdk.tls.keyLimits: " + e.getMessage() +
": " + entry);
}
continue;
}
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
- SSLLogger.fine("jdk.net.keyLimits: entry = " + entry +
+ SSLLogger.fine("jdk.tls.keyLimits: entry = " + entry +
". " + values[0] + ":" + tag[index] + " = " + size);
}
cipherLimits.put(values[0] + ":" + tag[index], size);
--- a/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java Wed Aug 29 19:48:28 2018 +0200
@@ -127,9 +127,7 @@
}
// See if the handshaker needs to report back some SSLException.
- if (conContext.outputRecord.isEmpty()) {
- checkTaskThrown();
- } // Otherwise, deliver cached records before throwing task exception.
+ checkTaskThrown();
// check parameters
checkParams(srcs, srcsOffset, srcsLength, dsts, dstsOffset, dstsLength);
@@ -896,18 +894,58 @@
return true;
}
+ /*
+ * Depending on whether the error was just a warning and the
+ * handshaker wasn't closed, or fatal and the handshaker is now
+ * null, report back the Exception that happened in the delegated
+ * task(s).
+ */
private synchronized void checkTaskThrown() throws SSLException {
+
+ Exception exc = null;
+
+ // First check the handshake context.
HandshakeContext hc = conContext.handshakeContext;
- if (hc != null && hc.delegatedThrown != null) {
- try {
- throw getTaskThrown(hc.delegatedThrown);
- } finally {
- hc.delegatedThrown = null;
+ if ((hc != null) && (hc.delegatedThrown != null)) {
+ exc = hc.delegatedThrown;
+ hc.delegatedThrown = null;
+ }
+
+ /*
+ * hc.delegatedThrown and conContext.delegatedThrown are most likely
+ * the same, but it's possible we could have had a non-fatal
+ * exception and thus the new HandshakeContext is still valid
+ * (alert warning). If so, then we may have a secondary exception
+ * waiting to be reported from the TransportContext, so we will
+ * need to clear that on a successive call. Otherwise, clear it now.
+ */
+ if (conContext.delegatedThrown != null) {
+ if (exc != null) {
+ // hc object comparison
+ if (conContext.delegatedThrown == exc) {
+ // clear if/only if both are the same
+ conContext.delegatedThrown = null;
+ } // otherwise report the hc delegatedThrown
+ } else {
+ // Nothing waiting in HandshakeContext, but one is in the
+ // TransportContext.
+ exc = conContext.delegatedThrown;
+ conContext.delegatedThrown = null;
}
}
- if (conContext.isBroken && conContext.closeReason != null) {
- throw getTaskThrown(conContext.closeReason);
+ // Anything to report?
+ if (exc == null) {
+ return;
+ }
+
+ // If it wasn't a RuntimeException/SSLException, need to wrap it.
+ if (exc instanceof SSLException) {
+ throw (SSLException)exc;
+ } else if (exc instanceof RuntimeException) {
+ throw (RuntimeException)exc;
+ } else {
+ throw getTaskThrown(exc);
}
}
@@ -963,20 +1001,41 @@
} catch (PrivilegedActionException pae) {
// Get the handshake context again in case the
// handshaking has completed.
+ Exception reportedException = pae.getException();
+
+ // Report to both the TransportContext...
+ if (engine.conContext.delegatedThrown == null) {
+ engine.conContext.delegatedThrown = reportedException;
+ }
+
+ // ...and the HandshakeContext in case condition
+ // wasn't fatal and the handshakeContext is still
+ // around.
hc = engine.conContext.handshakeContext;
if (hc != null) {
- hc.delegatedThrown = pae.getException();
+ hc.delegatedThrown = reportedException;
} else if (engine.conContext.closeReason != null) {
+ // Update the reason in case there was a previous.
engine.conContext.closeReason =
- getTaskThrown(pae.getException());
+ getTaskThrown(reportedException);
}
} catch (RuntimeException rte) {
// Get the handshake context again in case the
// handshaking has completed.
+
+ // Report to both the TransportContext...
+ if (engine.conContext.delegatedThrown == null) {
+ engine.conContext.delegatedThrown = rte;
+ }
+
+ // ...and the HandshakeContext in case condition
+ // wasn't fatal and the handshakeContext is still
+ // around.
hc = engine.conContext.handshakeContext;
if (hc != null) {
hc.delegatedThrown = rte;
} else if (engine.conContext.closeReason != null) {
+ // Update the reason in case there was a previous.
engine.conContext.closeReason = rte;
}
}
@@ -1000,13 +1059,6 @@
@Override
public Void run() throws Exception {
while (!context.delegatedActions.isEmpty()) {
- // Report back the task SSLException
- if (context.delegatedThrown != null) {
- Exception delegatedThrown = context.delegatedThrown;
- context.delegatedThrown = null;
- throw getTaskThrown(delegatedThrown);
- }
-
Map.Entry<Byte, ByteBuffer> me =
context.delegatedActions.poll();
if (me != null) {
--- a/src/java.base/share/classes/sun/security/ssl/SSLTransport.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/SSLTransport.java Wed Aug 29 19:48:28 2018 +0200
@@ -167,9 +167,10 @@
if (plainText == null) {
plainText = Plaintext.PLAINTEXT_NULL;
} else {
- // File the destination buffers.
- if (dsts != null && dstsLength > 0 &&
- plainText.contentType == ContentType.APPLICATION_DATA.id) {
+ // Fill the destination buffers.
+ if ((dsts != null) && (dstsLength > 0) &&
+ (plainText.contentType ==
+ ContentType.APPLICATION_DATA.id)) {
ByteBuffer fragment = plainText.fragment;
int remains = fragment.remaining();
--- a/src/java.base/share/classes/sun/security/ssl/ServerHello.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/ServerHello.java Wed Aug 29 19:48:28 2018 +0200
@@ -40,6 +40,7 @@
import javax.crypto.spec.IvParameterSpec;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLProtocolException;
import sun.security.ssl.CipherSuite.KeyExchange;
import sun.security.ssl.ClientHello.ClientHelloMessage;
import sun.security.ssl.SSLCipher.SSLReadCipher;
@@ -139,8 +140,11 @@
this.serverRandom = new RandomCookie(m);
this.sessionId = new SessionId(Record.getBytes8(m));
- sessionId.checkLength(serverVersion.id);
-
+ try {
+ sessionId.checkLength(serverVersion.id);
+ } catch (SSLProtocolException ex) {
+ handshakeContext.conContext.fatal(Alert.ILLEGAL_PARAMETER, ex);
+ }
int cipherSuiteId = Record.getInt16(m);
this.cipherSuite = CipherSuite.valueOf(cipherSuiteId);
--- a/src/java.base/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/SignatureAlgorithmsExtension.java Wed Aug 29 19:48:28 2018 +0200
@@ -362,16 +362,16 @@
// certificates and server key exchange), it MUST send the
// signature_algorithms extension, listing the algorithms it
// is willing to accept.
- List<SignatureScheme> shemes = Arrays.asList(
+ List<SignatureScheme> schemes = Arrays.asList(
SignatureScheme.RSA_PKCS1_SHA1,
SignatureScheme.DSA_SHA1,
SignatureScheme.ECDSA_SHA1
);
- shc.peerRequestedSignatureSchemes = shemes;
+ shc.peerRequestedSignatureSchemes = schemes;
if (shc.peerRequestedCertSignSchemes == null ||
- shc.peerRequestedCertSignSchemes.isEmpty()) {
- shc.peerRequestedCertSignSchemes = shemes;
+ shc.peerRequestedCertSignSchemes.isEmpty()) {
+ shc.peerRequestedCertSignSchemes = schemes;
}
// Use the default peer signature algorithms.
--- a/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/SignatureScheme.java Wed Aug 29 19:48:28 2018 +0200
@@ -403,8 +403,8 @@
for (SignatureScheme ss : schemes) {
if (ss.isAvailable &&
- ss.handshakeSupportedProtocols.contains(version) &&
- certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) {
+ ss.handshakeSupportedProtocols.contains(version) &&
+ certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) {
return ss;
}
--- a/src/java.base/share/classes/sun/security/ssl/TransportContext.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/TransportContext.java Wed Aug 29 19:48:28 2018 +0200
@@ -63,6 +63,7 @@
boolean isInputCloseNotified = false;
boolean peerUserCanceled = false;
Exception closeReason = null;
+ Exception delegatedThrown = null;
// negotiated security parameters
SSLSessionImpl conSession;
@@ -364,12 +365,12 @@
}
}
- // terminal handshake context
+ // terminate the handshake context
if (handshakeContext != null) {
handshakeContext = null;
}
- // terminal the transport
+ // terminate the transport
try {
transport.shutdown();
} catch (IOException ioe) {
--- a/src/java.base/share/classes/sun/security/ssl/X509Authentication.java Wed Aug 29 12:00:47 2018 -0400
+++ b/src/java.base/share/classes/sun/security/ssl/X509Authentication.java Wed Aug 29 19:48:28 2018 +0200
@@ -73,7 +73,7 @@
}
static X509Authentication valueOf(SignatureScheme signatureScheme) {
- for (X509Authentication au: X509Authentication.values()) {
+ for (X509Authentication au : X509Authentication.values()) {
if (au.keyType.equals(signatureScheme.keyAlgorithm)) {
return au;
}
@@ -291,9 +291,9 @@
((ECPublicKey)serverPublicKey).getParams();
NamedGroup namedGroup = NamedGroup.valueOf(params);
if ((namedGroup == null) ||
- (!SupportedGroups.isSupported(namedGroup)) ||
- ((shc.clientRequestedNamedGroups != null) &&
- !shc.clientRequestedNamedGroups.contains(namedGroup))) {
+ (!SupportedGroups.isSupported(namedGroup)) ||
+ ((shc.clientRequestedNamedGroups != null) &&
+ !shc.clientRequestedNamedGroups.contains(namedGroup))) {
if (SSLLogger.isOn && SSLLogger.isOn("ssl")) {
SSLLogger.warning(
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/floatingpoint/TestFloatSyncJNIArgs.java Wed Aug 29 19:48:28 2018 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2015, 2016 SAP SE. All rights reserved.
+ * Copyright (c) 2018 Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/* @test
+ * @bug 8207838
+ * @summary Regression test for passing float args to a synchronized jni function.
+ *
+ *
+ * @run main/othervm/native compiler.floatingpoint.TestFloatSyncJNIArgs
+ */
+
+package compiler.floatingpoint;
+
+public class TestFloatSyncJNIArgs {
+ static {
+ try {
+ System.loadLibrary("TestFloatSyncJNIArgs");
+ } catch (UnsatisfiedLinkError e) {
+ System.out.println("could not load native lib: " + e);
+ }
+ }
+
+ private static final int numberOfThreads = 8;
+
+ static volatile Error testFailed = null;
+
+ public synchronized static native float combine15floats(
+ float f1, float f2, float f3, float f4,
+ float f5, float f6, float f7, float f8,
+ float f9, float f10, float f11, float f12,
+ float f13, float f14, float f15);
+
+ public synchronized static native double combine15doubles(
+ double d1, double d2, double d3, double d4,
+ double d5, double d6, double d7, double d8,
+ double d9, double d10, double d11, double d12,
+ double d13, double d14, double d15);
+
+ static void test() throws Exception {
+ Thread[] threads = new Thread[numberOfThreads];
+
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i] = new Thread(() -> {
+ for (int j = 0; j < 10000; j++) {
+ float f = combine15floats(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f,
+ 9, 10, 11, 12, 13, 14, 15);
+ if (f != 81720.0f) {
+ testFailed = new Error("jni function didn't combine 15 float args properly: " + f);
+ throw testFailed;
+ }
+ }
+ });
+ }
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i].start();
+ }
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i].join();
+ }
+ if (testFailed != null) {
+ throw testFailed;
+ }
+
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i] = new Thread(() -> {
+ for (int j = 0; j < 10000; j++) {
+ double d = combine15doubles(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
+ 9, 10, 11, 12, 13, 14, 15);
+ if (d != 81720.0) {
+ testFailed = new Error("jni function didn't combine 15 double args properly: " + d);
+ throw testFailed;
+ }
+ }
+ });
+ }
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i].start();
+ }
+ for (int i = 0; i < numberOfThreads; i++) {
+ threads[i].join();
+ }
+ if (testFailed != null) {
+ throw testFailed;
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ for (int i = 0; i < 200; ++i) {
+ test();
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/floatingpoint/libTestFloatSyncJNIArgs.c Wed Aug 29 19:48:28 2018 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2018 Red Hat, Inc. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <jni.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Fletcher checksum. This is a nonlinear function which detects both */
+/* missing or otherwise incorrect arguments and arguments in the wrong */
+/* order. */
+static jfloat fcombine(jfloat f[], int len) {
+ int i;
+ jfloat sum = 0, sum_of_sums = 0;
+ for (i = 0; i < len; i++) {
+ sum += f[i];
+ sum_of_sums += sum;
+ }
+ return sum + sum_of_sums * sum;
+}
+
+static jdouble combine(jdouble f[], int len) {
+ int i;
+ double sum = 0, sum_of_sums = 0;
+ for (i = 0; i < len; i++) {
+ sum += f[i];
+ sum_of_sums += sum;
+ }
+ return sum + sum_of_sums * sum;
+}
+
+JNIEXPORT jfloat JNICALL Java_compiler_floatingpoint_TestFloatSyncJNIArgs_combine15floats
+ (JNIEnv *env, jclass cls,
+ jfloat f1, jfloat f2, jfloat f3, jfloat f4,
+ jfloat f5, jfloat f6, jfloat f7, jfloat f8,
+ jfloat f9, jfloat f10, jfloat f11, jfloat f12,
+ jfloat f13, jfloat f14, jfloat f15) {
+
+ jfloat f[15];
+ f[0] = f1; f[1] = f2; f[2] = f3; f[3] = f4; f[4] = f5;
+ f[5] = f6; f[6] = f7; f[7] = f8; f[8] = f9; f[9] = f10;
+ f[10] = f11; f[11] = f12; f[12] = f13; f[13] = f14; f[14] = f15;
+
+ return fcombine(f, sizeof f / sizeof f[0]);
+}
+
+JNIEXPORT jdouble JNICALL Java_compiler_floatingpoint_TestFloatSyncJNIArgs_combine15doubles
+ (JNIEnv *env, jclass cls,
+ jdouble f1, jdouble f2, jdouble f3, jdouble f4,
+ jdouble f5, jdouble f6, jdouble f7, jdouble f8,
+ jdouble f9, jdouble f10, jdouble f11, jdouble f12,
+ jdouble f13, jdouble f14, jdouble f15) {
+
+ jdouble f[15];
+ f[0] = f1; f[1] = f2; f[2] = f3; f[3] = f4; f[4] = f5;
+ f[5] = f6; f[6] = f7; f[7] = f8; f[8] = f9; f[9] = f10;
+ f[10] = f11; f[11] = f12; f[12] = f13; f[13] = f14; f[14] = f15;
+
+ return combine(f, sizeof f / sizeof f[0]);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/BoolReturn/JNIBooleanTest.java Wed Aug 29 19:48:28 2018 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2018 SAP SE. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * @test
+ * @bug 8209637
+ * @summary [s390x] Interpreter doesn't call result handler after native calls
+ * @author Volker Simonis
+ *
+ * @run main/othervm/native -XX:-UseOnStackReplacement -Xbatch JNIBooleanTest 50000
+ * @run main/othervm/native -Xint JNIBooleanTest 256
+ */
+
+import java.lang.reflect.Method;
+
+public class JNIBooleanTest {
+ static native boolean foo(byte b);
+
+ static boolean bar(byte b) {
+ return foo(b);
+ }
+
+ public static void main(String args[]) throws Exception {
+ int count = args.length > 0 ? Integer.parseInt(args[0]) : 50_000;
+ byte b = 0;
+ for (int i = 0; i < count; i++) {
+ boolean bool = foo(b);
+ if ((b == 0 && bool) || (b != 0 && !bool)) {
+ throw new RuntimeException("Error: foo(" + b + ") = " + bool + " in iteration " + i);
+ }
+ b++;
+ }
+
+ b = 0;
+ for (int i = 0; i < count; i++) {
+ boolean bool = bar(b);
+ if ((b == 0 && bool) || (b != 0 && !bool)) {
+ throw new RuntimeException("Error: bar(" + b + ") = " + bool + " in iteration " + i);
+ }
+ b++;
+ }
+
+ Method foo = JNIBooleanTest.class.getDeclaredMethod("foo", byte.class);
+
+ b = 0;
+ for (int i = 0; i < count; i++) {
+ boolean bool = ((Boolean)foo.invoke(null, b)).booleanValue();
+ if ((b == 0 && bool) || (b != 0 && !bool)) {
+ throw new RuntimeException("Error: foo(" + b + ") = " + bool + " in iteration " + i + " (reflective)");
+ }
+ b++;
+ }
+
+ Method bar = JNIBooleanTest.class.getDeclaredMethod("bar", byte.class);
+
+ b = 0;
+ for (int i = 0; i < count; i++) {
+ boolean bool = ((Boolean)bar.invoke(null, b)).booleanValue();
+ if ((b == 0 && bool) || (b != 0 && !bool)) {
+ throw new RuntimeException("Error: bar(" + b + ") = " + bool + " in iteration " + i + " (reflective)");
+ }
+ b++;
+ }
+ }
+
+ static {
+ System.loadLibrary("JNIBooleanTest");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/runtime/BoolReturn/libJNIBooleanTest.c Wed Aug 29 19:48:28 2018 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2018 SAP SE. 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include "jni.h"
+
+JNIEXPORT jboolean JNICALL
+Java_JNIBooleanTest_foo(JNIEnv *env, jclass cls, jbyte b) {
+ jboolean old = b;
+ return old;
+}
--- a/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java Wed Aug 29 12:00:47 2018 -0400
+++ b/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java Wed Aug 29 19:48:28 2018 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2018, 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
@@ -30,7 +30,6 @@
* @summary SSLEngine has not yet caused Solaris kernel to panic
* @run main/othervm SSLEngineTemplate
*/
-
/**
* A SSLEngine usage example which simplifies the presentation
* by removing the I/O and multi-threading concerns.
@@ -66,7 +65,6 @@
* unwrap() ... ChangeCipherSpec
* unwrap() ... Finished
*/
-
import javax.net.ssl.*;
import javax.net.ssl.SSLEngineResult.*;
import java.io.*;
@@ -115,7 +113,7 @@
private static final String pathToStores = "../etc";
private static final String keyStoreFile = "keystore";
private static final String trustStoreFile = "truststore";
- private static final String passwd = "passphrase";
+ private static final char[] passphrase = "passphrase".toCharArray();
private static final String keyFilename =
System.getProperty("test.src", ".") + "/" + pathToStores +
@@ -146,8 +144,6 @@
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);
@@ -187,8 +183,11 @@
createSSLEngines();
createBuffers();
- SSLEngineResult clientResult; // results from client's last operation
- SSLEngineResult serverResult; // results from server's last operation
+ // results from client's last operation
+ SSLEngineResult clientResult;
+
+ // results from server's last operation
+ SSLEngineResult serverResult;
/*
* Examining the SSLEngineResults could be much more involved,
@@ -198,31 +197,62 @@
* to write to the output pipe, we could reallocate a larger
* pipe, but instead we wait for the peer to drain it.
*/
- while (!isEngineClosed(clientEngine) ||
- !isEngineClosed(serverEngine)) {
+ Exception clientException = null;
+ Exception serverException = null;
+
+ while (!isEngineClosed(clientEngine)
+ || !isEngineClosed(serverEngine)) {
log("================");
- clientResult = clientEngine.wrap(clientOut, cTOs);
- log("client wrap: ", clientResult);
- runDelegatedTasks(clientResult, clientEngine);
+ try {
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ } catch (Exception e) {
+ clientException = e;
+ System.out.println("Client wrap() threw: " + e.getMessage());
+ }
+ logEngineStatus(clientEngine);
+ runDelegatedTasks(clientEngine);
- serverResult = serverEngine.wrap(serverOut, sTOc);
- log("server wrap: ", serverResult);
- runDelegatedTasks(serverResult, serverEngine);
+ log("----");
+
+ try {
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ } catch (Exception e) {
+ serverException = e;
+ System.out.println("Server wrap() threw: " + e.getMessage());
+ }
+ logEngineStatus(serverEngine);
+ runDelegatedTasks(serverEngine);
cTOs.flip();
sTOc.flip();
+ log("--------");
+
+ try {
+ clientResult = clientEngine.unwrap(sTOc, clientIn);
+ log("client unwrap: ", clientResult);
+ } catch (Exception e) {
+ clientException = e;
+ System.out.println("Client unwrap() threw: " + e.getMessage());
+ }
+ logEngineStatus(clientEngine);
+ runDelegatedTasks(clientEngine);
+
log("----");
- clientResult = clientEngine.unwrap(sTOc, clientIn);
- log("client unwrap: ", clientResult);
- runDelegatedTasks(clientResult, clientEngine);
-
- serverResult = serverEngine.unwrap(cTOs, serverIn);
- log("server unwrap: ", serverResult);
- runDelegatedTasks(serverResult, serverEngine);
+ try {
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ } catch (Exception e) {
+ serverException = e;
+ System.out.println("Server unwrap() threw: " + e.getMessage());
+ }
+ logEngineStatus(serverEngine);
+ runDelegatedTasks(serverEngine);
cTOs.compact();
sTOc.compact();
@@ -244,13 +274,22 @@
log("\tClosing clientEngine's *OUTBOUND*...");
clientEngine.closeOutbound();
+ logEngineStatus(clientEngine);
+
dataDone = true;
log("\tClosing serverEngine's *OUTBOUND*...");
serverEngine.closeOutbound();
+ logEngineStatus(serverEngine);
}
}
}
+ private static void logEngineStatus(SSLEngine engine) {
+ log("\tCurrent HS State " + engine.getHandshakeStatus().toString());
+ log("\tisInboundDone(): " + engine.isInboundDone());
+ log("\tisOutboundDone(): " + engine.isOutboundDone());
+ }
+
/*
* Using the SSLContext created during object creation,
* create/configure the SSLEngines we'll use for this test.
@@ -264,11 +303,19 @@
serverEngine.setUseClientMode(false);
serverEngine.setNeedClientAuth(true);
+ // Get/set parameters if needed
+ SSLParameters paramsServer = serverEngine.getSSLParameters();
+ serverEngine.setSSLParameters(paramsServer);
+
/*
* Similar to above, but using client mode instead.
*/
clientEngine = sslc.createSSLEngine("client", 80);
clientEngine.setUseClientMode(true);
+
+ // Get/set parameters if needed
+ SSLParameters paramsClient = clientEngine.getSSLParameters();
+ clientEngine.setSSLParameters(paramsClient);
}
/*
@@ -307,13 +354,12 @@
* If the result indicates that we have outstanding tasks to do,
* go ahead and run them in this thread.
*/
- private static void runDelegatedTasks(SSLEngineResult result,
- SSLEngine engine) throws Exception {
+ private static void runDelegatedTasks(SSLEngine engine) throws Exception {
- if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
Runnable runnable;
while ((runnable = engine.getDelegatedTask()) != null) {
- log("\trunning delegated task...");
+ log(" running delegated task...");
runnable.run();
}
HandshakeStatus hsStatus = engine.getHandshakeStatus();
@@ -321,7 +367,7 @@
throw new Exception(
"handshake shouldn't need additional tasks");
}
- log("\tnew HandshakeStatus: " + hsStatus);
+ logEngineStatus(engine);
}
}
@@ -361,14 +407,14 @@
if (resultOnce) {
resultOnce = false;
System.out.println("The format of the SSLEngineResult is: \n" +
- "\t\"getStatus() / getHandshakeStatus()\" +\n" +
- "\t\"bytesConsumed() / bytesProduced()\"\n");
+ "\t\"getStatus() / getHandshakeStatus()\" +\n" +
+ "\t\"bytesConsumed() / bytesProduced()\"\n");
}
HandshakeStatus hsStatus = result.getHandshakeStatus();
log(str +
- result.getStatus() + "/" + hsStatus + ", " +
- result.bytesConsumed() + "/" + result.bytesProduced() +
- " bytes");
+ result.getStatus() + "/" + hsStatus + ", " +
+ result.bytesConsumed() + "/" + result.bytesProduced() +
+ " bytes");
if (hsStatus == HandshakeStatus.FINISHED) {
log("\t...ready for application data");
}
--- a/test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java Wed Aug 29 12:00:47 2018 -0400
+++ b/test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java Wed Aug 29 19:48:28 2018 +0200
@@ -74,6 +74,7 @@
import java.nio.*;
import java.util.List;
import java.util.ArrayList;
+import java.util.Iterator;
public class LengthCheckTest {
@@ -203,7 +204,11 @@
// Now send each ByteBuffer (each being a complete
// TLS record) into the client-side unwrap.
- for (ByteBuffer bBuf : recList) {
+ // for (ByteBuffer bBuf : recList) {
+
+ Iterator<ByteBuffer> iter = recList.iterator();
+ while (!gotException && (iter.hasNext())) {
+ ByteBuffer bBuf = iter.next();
dumpByteBuffer("SERVER-TO-CLIENT", bBuf);
try {
clientResult = clientEngine.unwrap(bBuf, clientIn);
@@ -232,8 +237,8 @@
// was thrown and the proper action (a TLS alert) was
// sent back to the server.
if (gotException == false ||
- !isTlsMessage(cTOs, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
- TLS_ALERT_UNEXPECTED_MSG)) {
+ !isTlsMessage(cTOs, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
+ TLS_ALERT_ILLEGAL_PARAMETER)) {
throw new SSLException(
"Client failed to throw Alert:fatal:internal_error");
}
@@ -253,38 +258,36 @@
ByteBuffer evilClientHello = createEvilClientHello(64);
dumpByteBuffer("CLIENT-TO-SERVER", evilClientHello);
+ // Server consumes Client Hello
+ serverResult = serverEngine.unwrap(evilClientHello, serverIn);
+ log("server unwrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ evilClientHello.compact();
+
+ // Under normal circumstances this should be a ServerHello
+ // But should throw an exception instead due to the invalid
+ // session ID.
try {
- // Server consumes Client Hello
- serverResult = serverEngine.unwrap(evilClientHello, serverIn);
- log("server unwrap: ", serverResult);
- runDelegatedTasks(serverResult, serverEngine);
- evilClientHello.compact();
-
- // Under normal circumstances this should be a ServerHello
- // But should throw an exception instead due to the invalid
- // session ID.
serverResult = serverEngine.wrap(serverOut, sTOc);
log("server wrap: ", serverResult);
runDelegatedTasks(serverResult, serverEngine);
- sTOc.flip();
- dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
-
- // We expect to see the server generate an alert here
- serverResult = serverEngine.wrap(serverOut, sTOc);
- log("server wrap: ", serverResult);
- runDelegatedTasks(serverResult, serverEngine);
- sTOc.flip();
- dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
} catch (SSLProtocolException ssle) {
log("Received expected SSLProtocolException: " + ssle);
gotException = true;
}
+ // We expect to see the server generate an alert here
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ runDelegatedTasks(serverResult, serverEngine);
+ sTOc.flip();
+ dumpByteBuffer("SERVER-TO-CLIENT", sTOc);
+
// At this point we can verify that both an exception
// was thrown and the proper action (a TLS alert) was
// sent back to the client.
if (gotException == false ||
- !isTlsMessage(sTOc, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
+ !isTlsMessage(sTOc, TLS_RECTYPE_ALERT, TLS_ALERT_LVL_FATAL,
TLS_ALERT_ILLEGAL_PARAMETER)) {
throw new SSLException(
"Server failed to throw Alert:fatal:internal_error");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/sun/security/ssl/SSLEngineImpl/SSLEngineFailedALPN.java Wed Aug 29 19:48:28 2018 +0200
@@ -0,0 +1,449 @@
+/*
+ * Copyright (c) 2003, 2018, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+
+/*
+ * @test
+ * @bug 8207317
+ * @summary SSLEngine negotiation fail Exception behavior changed from
+ * fail-fast to fail-lazy
+ * @run main/othervm SSLEngineFailedALPN
+ */
+/**
+ * A SSLEngine usage example which simplifies the presentation
+ * by removing the I/O and multi-threading concerns.
+ *
+ * The test creates two SSLEngines, simulating a client and server.
+ * The "transport" layer consists two byte buffers: think of them
+ * as directly connected pipes.
+ *
+ * Note, this is a *very* simple example: real code will be much more
+ * involved. For example, different threading and I/O models could be
+ * used, transport mechanisms could close unexpectedly, and so on.
+ *
+ * When this application runs, notice that several messages
+ * (wrap/unwrap) pass before any application data is consumed or
+ * produced. (For more information, please see the SSL/TLS
+ * specifications.) There may several steps for a successful handshake,
+ * so it's typical to see the following series of operations:
+ *
+ * client server message
+ * ====== ====== =======
+ * wrap() ... ClientHello
+ * ... unwrap() ClientHello
+ * ... wrap() ServerHello/Certificate
+ * unwrap() ... ServerHello/Certificate
+ * wrap() ... ClientKeyExchange
+ * wrap() ... ChangeCipherSpec
+ * wrap() ... Finished
+ * ... unwrap() ClientKeyExchange
+ * ... unwrap() ChangeCipherSpec
+ * ... unwrap() Finished
+ * ... wrap() ChangeCipherSpec
+ * ... wrap() Finished
+ * unwrap() ... ChangeCipherSpec
+ * unwrap() ... Finished
+ */
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.security.*;
+import java.nio.*;
+
+public class SSLEngineFailedALPN {
+
+ /*
+ * Enables logging of the SSLEngine operations.
+ */
+ private static final boolean logging = true;
+
+ /*
+ * Enables the JSSE system debugging system property:
+ *
+ * -Djavax.net.debug=all
+ *
+ * This gives a lot of low-level information about operations underway,
+ * including specific handshake messages, and might be best examined
+ * after gaining some familiarity with this application.
+ */
+ private static final boolean debug = false;
+
+ private final SSLContext sslc;
+
+ private SSLEngine clientEngine; // client Engine
+ private ByteBuffer clientOut; // write side of clientEngine
+ private ByteBuffer clientIn; // read side of clientEngine
+
+ private SSLEngine serverEngine; // server Engine
+ private ByteBuffer serverOut; // write side of serverEngine
+ private ByteBuffer serverIn; // read side of serverEngine
+
+ /*
+ * For data transport, this example uses local ByteBuffers. This
+ * isn't really useful, but the purpose of this example is to show
+ * SSLEngine concepts, not how to do network transport.
+ */
+ private ByteBuffer cTOs; // "reliable" transport client->server
+ private ByteBuffer sTOc; // "reliable" transport server->client
+
+ /*
+ * The following is to set up the keystores.
+ */
+ private static final String pathToStores = "../../../../javax/net/ssl/etc";
+ private static final String keyStoreFile = "keystore";
+ private static final String trustStoreFile = "truststore";
+ private static final char[] passphrase = "passphrase".toCharArray();
+
+ private static final String keyFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ private static final String trustFilename =
+ System.getProperty("test.src", ".") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ /*
+ * Main entry point for this test.
+ */
+ public static void main(String args[]) throws Exception {
+ if (debug) {
+ System.setProperty("javax.net.debug", "all");
+ }
+
+ SSLEngineFailedALPN test = new SSLEngineFailedALPN();
+ test.runTest();
+
+ System.out.println("Test Passed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for these tests.
+ */
+ public SSLEngineFailedALPN() throws Exception {
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ ks.load(new FileInputStream(keyFilename), passphrase);
+ ts.load(new FileInputStream(trustFilename), passphrase);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ sslc = sslCtx;
+ }
+
+ /*
+ * Run the test.
+ *
+ * Sit in a tight loop, both engines calling wrap/unwrap regardless
+ * of whether data is available or not. We do this until both engines
+ * report back they are closed.
+ *
+ * The main loop handles all of the I/O phases of the SSLEngine's
+ * lifetime:
+ *
+ * initial handshaking
+ * application data transfer
+ * engine closing
+ *
+ * One could easily separate these phases into separate
+ * sections of code.
+ */
+ private void runTest() throws Exception {
+ boolean dataDone = false;
+
+ createSSLEngines();
+ createBuffers();
+
+ // results from client's last operation
+ SSLEngineResult clientResult;
+
+ // results from server's last operation
+ SSLEngineResult serverResult;
+
+ /*
+ * Examining the SSLEngineResults could be much more involved,
+ * and may alter the overall flow of the application.
+ *
+ * For example, if we received a BUFFER_OVERFLOW when trying
+ * to write to the output pipe, we could reallocate a larger
+ * pipe, but instead we wait for the peer to drain it.
+ */
+ Exception clientException = null;
+ Exception serverException = null;
+
+ while (!isEngineClosed(clientEngine)
+ || !isEngineClosed(serverEngine)) {
+
+ log("================");
+
+ try {
+ clientResult = clientEngine.wrap(clientOut, cTOs);
+ log("client wrap: ", clientResult);
+ } catch (Exception e) {
+ clientException = e;
+ System.out.println("Client wrap() threw: " + e.getMessage());
+ }
+ logEngineStatus(clientEngine);
+ runDelegatedTasks(clientEngine);
+
+ log("----");
+
+ try {
+ serverResult = serverEngine.wrap(serverOut, sTOc);
+ log("server wrap: ", serverResult);
+ } catch (Exception e) {
+ serverException = e;
+ System.out.println("Server wrap() threw: " + e.getMessage());
+ }
+ logEngineStatus(serverEngine);
+ runDelegatedTasks(serverEngine);
+
+ cTOs.flip();
+ sTOc.flip();
+
+ log("--------");
+
+ try {
+ clientResult = clientEngine.unwrap(sTOc, clientIn);
+ log("client unwrap: ", clientResult);
+ } catch (Exception e) {
+ clientException = e;
+ System.out.println("Client unwrap() threw: " + e.getMessage());
+ }
+ logEngineStatus(clientEngine);
+ runDelegatedTasks(clientEngine);
+
+ log("----");
+
+ try {
+ serverResult = serverEngine.unwrap(cTOs, serverIn);
+ log("server unwrap: ", serverResult);
+ } catch (Exception e) {
+ serverException = e;
+ System.out.println("Server unwrap() threw: " + e.getMessage());
+ }
+ logEngineStatus(serverEngine);
+ runDelegatedTasks(serverEngine);
+
+ cTOs.compact();
+ sTOc.compact();
+
+ /*
+ * After we've transfered all application data between the client
+ * and server, we close the clientEngine's outbound stream.
+ * This generates a close_notify handshake message, which the
+ * server engine receives and responds by closing itself.
+ */
+ if (!dataDone && (clientOut.limit() == serverIn.position()) &&
+ (serverOut.limit() == clientIn.position())) {
+
+ /*
+ * A sanity check to ensure we got what was sent.
+ */
+ checkTransfer(serverOut, clientIn);
+ checkTransfer(clientOut, serverIn);
+
+ log("\tClosing clientEngine's *OUTBOUND*...");
+ clientEngine.closeOutbound();
+ logEngineStatus(clientEngine);
+
+ dataDone = true;
+ log("\tClosing serverEngine's *OUTBOUND*...");
+ serverEngine.closeOutbound();
+ logEngineStatus(serverEngine);
+ }
+ }
+
+ log("================");
+
+ if ((clientException != null) &&
+ (clientException instanceof SSLHandshakeException)) {
+ log("Client threw proper exception");
+ clientException.printStackTrace(System.out);
+ } else {
+ throw new Exception("Client Exception not seen");
+ }
+
+ if ((serverException != null) &&
+ (serverException instanceof SSLHandshakeException)) {
+ log("Server threw proper exception:");
+ serverException.printStackTrace(System.out);
+ } else {
+ throw new Exception("Server Exception not seen");
+ }
+ }
+
+ private static void logEngineStatus(SSLEngine engine) {
+ log("\tCurrent HS State " + engine.getHandshakeStatus().toString());
+ log("\tisInboundDone(): " + engine.isInboundDone());
+ log("\tisOutboundDone(): " + engine.isOutboundDone());
+ }
+
+ /*
+ * Using the SSLContext created during object creation,
+ * create/configure the SSLEngines we'll use for this test.
+ */
+ private void createSSLEngines() throws Exception {
+ /*
+ * Configure the serverEngine to act as a server in the SSL/TLS
+ * handshake. Also, require SSL client authentication.
+ */
+ serverEngine = sslc.createSSLEngine();
+ serverEngine.setUseClientMode(false);
+ serverEngine.setNeedClientAuth(true);
+
+ // Get/set parameters if needed
+ SSLParameters paramsServer = serverEngine.getSSLParameters();
+ paramsServer.setApplicationProtocols(new String[]{"one"});
+ serverEngine.setSSLParameters(paramsServer);
+
+ /*
+ * Similar to above, but using client mode instead.
+ */
+ clientEngine = sslc.createSSLEngine("client", 80);
+ clientEngine.setUseClientMode(true);
+
+ // Get/set parameters if needed
+ SSLParameters paramsClient = clientEngine.getSSLParameters();
+ paramsClient.setApplicationProtocols(new String[]{"two"});
+ clientEngine.setSSLParameters(paramsClient);
+ }
+
+ /*
+ * Create and size the buffers appropriately.
+ */
+ private void createBuffers() {
+
+ /*
+ * We'll assume the buffer sizes are the same
+ * between client and server.
+ */
+ SSLSession session = clientEngine.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ /*
+ * We'll make the input buffers a bit bigger than the max needed
+ * size, so that unwrap()s following a successful data transfer
+ * won't generate BUFFER_OVERFLOWS.
+ *
+ * We'll use a mix of direct and indirect ByteBuffers for
+ * tutorial purposes only. In reality, only use direct
+ * ByteBuffers when they give a clear performance enhancement.
+ */
+ clientIn = ByteBuffer.allocate(appBufferMax + 50);
+ serverIn = ByteBuffer.allocate(appBufferMax + 50);
+
+ cTOs = ByteBuffer.allocateDirect(netBufferMax);
+ sTOc = ByteBuffer.allocateDirect(netBufferMax);
+
+ clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes());
+ serverOut = ByteBuffer.wrap("Hello Client, I'm Server".getBytes());
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+ private static void runDelegatedTasks(SSLEngine engine) throws Exception {
+
+ if (engine.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log(" running delegated task...");
+ runnable.run();
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ logEngineStatus(engine);
+ }
+ }
+
+ private static boolean isEngineClosed(SSLEngine engine) {
+ return (engine.isOutboundDone() && engine.isInboundDone());
+ }
+
+ /*
+ * Simple check to make sure everything came across as expected.
+ */
+ private static void checkTransfer(ByteBuffer a, ByteBuffer b)
+ throws Exception {
+ a.flip();
+ b.flip();
+
+ if (!a.equals(b)) {
+ throw new Exception("Data didn't transfer cleanly");
+ } else {
+ log("\tData transferred cleanly");
+ }
+
+ a.position(a.limit());
+ b.position(b.limit());
+ a.limit(a.capacity());
+ b.limit(b.capacity());
+ }
+
+ /*
+ * Logging code
+ */
+ private static boolean resultOnce = true;
+
+ private static void log(String str, SSLEngineResult result) {
+ if (!logging) {
+ return;
+ }
+ if (resultOnce) {
+ resultOnce = false;
+ System.out.println("The format of the SSLEngineResult is: \n" +
+ "\t\"getStatus() / getHandshakeStatus()\" +\n" +
+ "\t\"bytesConsumed() / bytesProduced()\"\n");
+ }
+ HandshakeStatus hsStatus = result.getHandshakeStatus();
+ log(str +
+ result.getStatus() + "/" + hsStatus + ", " +
+ result.bytesConsumed() + "/" + result.bytesProduced() +
+ " bytes");
+ if (hsStatus == HandshakeStatus.FINISHED) {
+ log("\t...ready for application data");
+ }
+ }
+
+ private static void log(String str) {
+ if (logging) {
+ System.out.println(str);
+ }
+ }
+}