This commit is contained in:
Jesper Wilhelmsson 2018-08-29 19:48:28 +02:00
commit d40735db17
25 changed files with 1004 additions and 130 deletions

11
.hgtags
View File

@ -496,15 +496,16 @@ e1b3def126240d5433902f3cb0e91a4c27f6db50 jdk-11+18
14708e1acdc3974f4539027cbbcfa6d69f83cf51 jdk-11+21
00b16d0457e43d23f6ca5ade6b243edce62750a0 jdk-12+1
9937ef7499dcd7673714517fd5e450410c14ba4e jdk-11+22
1edcf36fe15f79d6228d1a63eb680878e2386480 jdk-11+23
ea900a7dc7d77dee30865c60eabd87fc24b1037c jdk-11+24
331888ea4a788df801b1edf8836646cd25fc758b jdk-11+25
945ba9278a272a5477ffb1b3ea1b04174fed8036 jdk-11+26
9d7d74c6f2cbe522e39fa22dc557fdd3f79b32ad jdk-11+27
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
ef57958c7c511162da8d9a75f0b977f0f7ac464e jdk-12+7
76072a077ee1d815152d45d1692c4b36c53c5c49 jdk-11+28
492b366f8e5784cc4927c2c98f9b8a3f16c067eb jdk-12+8

View File

@ -61,7 +61,7 @@ MODULES_SOURCE_PATH := $(call PathList, $(call GetModuleSrcPath) \
$(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

View File

@ -1107,7 +1107,7 @@ static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMR
}
}
__ 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()) {

View File

@ -1681,7 +1681,7 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
__ 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 @@ address TemplateInterpreterGenerator::generate_native_entry(bool synchronized) {
__ 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*/);

View File

@ -119,7 +119,7 @@ define_pd_global(bool, ThreadLocalHandshakes, false);
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) \
\

View File

@ -1637,6 +1637,12 @@ bool CompileBroker::init_compiler_runtime() {
* 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 @@ void CompileBroker::compiler_thread_loop() {
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.
}
}

View File

@ -3340,11 +3340,6 @@ CompilerThread::CompilerThread(CompileQueue* queue,
}
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;
}

View File

@ -191,12 +191,12 @@ final class CertSignAlgsExtension {
}
// 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 @@ final class CertSignAlgsExtension {
}
// 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);
}
}
}

View File

@ -1031,8 +1031,8 @@ final class CertificateMessage {
// 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(

View File

@ -50,7 +50,7 @@ public class HandshakeOutStream extends ByteArrayOutputStream {
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

View File

@ -379,10 +379,10 @@ enum SSLCipher {
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 @@ enum SSLCipher {
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 @@ enum SSLCipher {
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);

View File

@ -127,9 +127,7 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
}
// 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 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
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 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
} 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 @@ final class SSLEngineImpl extends SSLEngine implements SSLTransport {
@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) {

View File

@ -167,9 +167,10 @@ interface SSLTransport {
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();

View File

@ -40,6 +40,7 @@ import javax.crypto.SecretKey;
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 @@ final class ServerHello {
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);

View File

@ -362,16 +362,16 @@ final class SignatureAlgorithmsExtension {
// 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.

View File

@ -403,8 +403,8 @@ enum SignatureScheme {
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;
}

View File

@ -63,6 +63,7 @@ class TransportContext implements ConnectionContext {
boolean isInputCloseNotified = false;
boolean peerUserCanceled = false;
Exception closeReason = null;
Exception delegatedThrown = null;
// negotiated security parameters
SSLSessionImpl conSession;
@ -364,12 +365,12 @@ class TransportContext implements ConnectionContext {
}
}
// terminal handshake context
// terminate the handshake context
if (handshakeContext != null) {
handshakeContext = null;
}
// terminal the transport
// terminate the transport
try {
transport.shutdown();
} catch (IOException ioe) {

View File

@ -73,7 +73,7 @@ enum X509Authentication implements SSLAuthentication {
}
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 @@ enum X509Authentication implements SSLAuthentication {
((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(

View File

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

View File

@ -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

View File

@ -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");
}
}

View File

@ -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;
}

View File

@ -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 @@ public class SSLEngineTemplate {
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 @@ public class SSLEngineTemplate {
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 @@ public class SSLEngineTemplate {
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 @@ public class SSLEngineTemplate {
* 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 @@ public class SSLEngineTemplate {
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 @@ public class SSLEngineTemplate {
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 @@ public class SSLEngineTemplate {
* 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 @@ public class SSLEngineTemplate {
throw new Exception(
"handshake shouldn't need additional tasks");
}
log("\tnew HandshakeStatus: " + hsStatus);
logEngineStatus(engine);
}
}
@ -361,14 +407,14 @@ public class SSLEngineTemplate {
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");
}

View File

@ -74,6 +74,7 @@ import java.security.*;
import java.nio.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
public class LengthCheckTest {
@ -203,7 +204,11 @@ public class LengthCheckTest {
// 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 @@ public class LengthCheckTest {
// 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 @@ public class LengthCheckTest {
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");

View File

@ -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);
}
}
}