mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-24 12:28:12 +00:00
8239052: java/net/httpclient/whitebox/SSLEchoTubeTestDriver.java failed with BufferUnderflowException against TLSv1.3
The test assumed that ByteBuffer would be split at long boundaries. This is obviously not always the case. A carry has been added to support reading a long split over several buffers. Reviewed-by: chegar
This commit is contained in:
parent
965e330cb4
commit
f7c819a72d
@ -49,6 +49,7 @@ import javax.net.ssl.SSLSocket;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @test
|
* @test
|
||||||
|
* @bug 8238990
|
||||||
* @run main/othervm -Djdk.internal.httpclient.debug=true HandshakeFailureTest TLSv1.2
|
* @run main/othervm -Djdk.internal.httpclient.debug=true HandshakeFailureTest TLSv1.2
|
||||||
* @run main/othervm -Djdk.internal.httpclient.debug=true HandshakeFailureTest TLSv1.3
|
* @run main/othervm -Djdk.internal.httpclient.debug=true HandshakeFailureTest TLSv1.3
|
||||||
* @summary Verify SSLHandshakeException is received when the handshake fails,
|
* @summary Verify SSLHandshakeException is received when the handshake fails,
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -126,6 +126,7 @@ public class AbstractSSLTubeTest extends AbstractRandomTest {
|
|||||||
protected static class EndSubscriber implements FlowTube.TubeSubscriber {
|
protected static class EndSubscriber implements FlowTube.TubeSubscriber {
|
||||||
|
|
||||||
private static final int REQUEST_WINDOW = 13;
|
private static final int REQUEST_WINDOW = 13;
|
||||||
|
private static final int SIZEOF_LONG = 8;
|
||||||
|
|
||||||
private final long nbytes;
|
private final long nbytes;
|
||||||
private final AtomicLong counter = new AtomicLong();
|
private final AtomicLong counter = new AtomicLong();
|
||||||
@ -133,12 +134,16 @@ public class AbstractSSLTubeTest extends AbstractRandomTest {
|
|||||||
private final CountDownLatch allBytesReceived;
|
private final CountDownLatch allBytesReceived;
|
||||||
private volatile Flow.Subscription subscription;
|
private volatile Flow.Subscription subscription;
|
||||||
private long unfulfilled;
|
private long unfulfilled;
|
||||||
|
private final ByteBuffer carry; // used if buffers don't break at long boundaries.
|
||||||
|
|
||||||
|
|
||||||
EndSubscriber(long nbytes, CompletableFuture<?> completion,
|
EndSubscriber(long nbytes, CompletableFuture<?> completion,
|
||||||
CountDownLatch allBytesReceived) {
|
CountDownLatch allBytesReceived) {
|
||||||
this.nbytes = nbytes;
|
this.nbytes = nbytes;
|
||||||
this.completion = completion;
|
this.completion = completion;
|
||||||
this.allBytesReceived = allBytesReceived;
|
this.allBytesReceived = allBytesReceived;
|
||||||
|
this.carry = ByteBuffer.allocate(SIZEOF_LONG);
|
||||||
|
carry.position(carry.limit());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -159,6 +164,56 @@ public class AbstractSSLTubeTest extends AbstractRandomTest {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check whether we need bytes from the next buffer to read
|
||||||
|
// the next long. If yes, drains the current buffer into the
|
||||||
|
// carry and returns true. If no and the current buffer
|
||||||
|
// or the carry have enough bytes to read a long, return
|
||||||
|
// false.
|
||||||
|
private boolean requiresMoreBytes(ByteBuffer buf) {
|
||||||
|
// First see if the carry contains some left over bytes
|
||||||
|
// from the previous buffer
|
||||||
|
if (carry.hasRemaining()) {
|
||||||
|
// If so fills up the carry, if we can
|
||||||
|
while (carry.hasRemaining() && buf.hasRemaining()) {
|
||||||
|
carry.put(buf.get());
|
||||||
|
}
|
||||||
|
if (!carry.hasRemaining()) {
|
||||||
|
// The carry is full: we can use it.
|
||||||
|
carry.flip();
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
// There was not enough bytes to fill the carry,
|
||||||
|
// continue with next buffer.
|
||||||
|
assert !buf.hasRemaining();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else if (buf.remaining() < SIZEOF_LONG) {
|
||||||
|
// The carry is empty and the current buffer doesn't
|
||||||
|
// have enough bytes: drains it into the carry.
|
||||||
|
carry.clear();
|
||||||
|
carry.put(buf);
|
||||||
|
assert carry.hasRemaining();
|
||||||
|
assert !buf.hasRemaining();
|
||||||
|
// We still need more bytes from the next buffer.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// We have enough bytes to read a long. No need
|
||||||
|
// to read from next buffer.
|
||||||
|
assert buf.remaining() >= SIZEOF_LONG;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long readNextLong(ByteBuffer buf) {
|
||||||
|
// either the carry is ready to use (it must have 8 bytes to read)
|
||||||
|
// or it must be used up and at the limit.
|
||||||
|
assert !carry.hasRemaining() || carry.remaining() == SIZEOF_LONG;
|
||||||
|
// either we have a long in the carry, or we have enough bytes in the buffer
|
||||||
|
assert carry.remaining() == SIZEOF_LONG || buf.remaining() >= SIZEOF_LONG;
|
||||||
|
|
||||||
|
ByteBuffer source = carry.hasRemaining() ? carry : buf;
|
||||||
|
return source.getLong();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onNext(List<ByteBuffer> buffers) {
|
public void onNext(List<ByteBuffer> buffers) {
|
||||||
if (--unfulfilled == (REQUEST_WINDOW / 2)) {
|
if (--unfulfilled == (REQUEST_WINDOW / 2)) {
|
||||||
@ -176,7 +231,17 @@ public class AbstractSSLTubeTest extends AbstractRandomTest {
|
|||||||
|
|
||||||
for (ByteBuffer buf : buffers) {
|
for (ByteBuffer buf : buffers) {
|
||||||
while (buf.hasRemaining()) {
|
while (buf.hasRemaining()) {
|
||||||
long n = buf.getLong();
|
// first check if we have enough bytes to
|
||||||
|
// read a long. If not, place the bytes in
|
||||||
|
// the carry and continue with next buffer.
|
||||||
|
if (requiresMoreBytes(buf)) continue;
|
||||||
|
|
||||||
|
// either we have a long in the carry, or we have
|
||||||
|
// enough bytes in the buffer to read a long.
|
||||||
|
long n = readNextLong(buf);
|
||||||
|
|
||||||
|
assert !carry.hasRemaining();
|
||||||
|
|
||||||
if (currval > (TOTAL_LONGS - 50)) {
|
if (currval > (TOTAL_LONGS - 50)) {
|
||||||
System.out.println("End: " + currval);
|
System.out.println("End: " + currval);
|
||||||
}
|
}
|
||||||
@ -225,7 +290,6 @@ public class AbstractSSLTubeTest extends AbstractRandomTest {
|
|||||||
SSLContext context = (new SimpleSSLContext()).get();
|
SSLContext context = (new SimpleSSLContext()).get();
|
||||||
SSLEngine engine = context.createSSLEngine();
|
SSLEngine engine = context.createSSLEngine();
|
||||||
SSLParameters params = context.getSupportedSSLParameters();
|
SSLParameters params = context.getSupportedSSLParameters();
|
||||||
params.setProtocols(new String[]{"TLSv1.2"}); // TODO: This is essential. Needs to be protocol impl
|
|
||||||
if (client) {
|
if (client) {
|
||||||
params.setApplicationProtocols(new String[]{"proto1", "proto2"}); // server will choose proto2
|
params.setApplicationProtocols(new String[]{"proto1", "proto2"}); // server will choose proto2
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user