Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,22 @@ public void onCompleted() {
public int onFill(Buffer buffer, Object... args) throws IOException {
int srcSize = buffer.remaining();
ByteBuffer applicationBuffer = (ByteBuffer) args[0];
SSLEngineResult sslResult = getConnection().getSslEngine().wrap(
applicationBuffer, buffer.getBytes());

HandshakeStatus handshakeStatus = getConnection().getSslHandshakeStatus();
SSLEngineResult sslResult;

// Empty buffers should generally only be passed to SSLEngine during the handshaking process,
// when SSLEngine will be generating handshake packets itself. The behavior of SSLEngine when
// an empty buffer is passed during normal operation varies across platforms. To avoid problems
// due to this inconsistency, we avoid calling SSLEngine with empty buffers when not handshaking,
// and return what J2SE's SSLEngine would have in that case. See the following issue for more details:
// https://github.com/restlet/restlet-framework-java/issues/852
if (applicationBuffer.hasRemaining() || handshakeStatus != HandshakeStatus.NOT_HANDSHAKING) {
sslResult = getConnection().getSslEngine().wrap(applicationBuffer, buffer.getBytes());
} else {
sslResult = new SSLEngineResult(Status.BUFFER_OVERFLOW, handshakeStatus, 0, 0);
}

getConnection().setSslResult(sslResult);
return srcSize - buffer.remaining();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ public class SslConnection<T extends Connector> extends Connection<T> {
/** The engine result. */
private volatile SSLEngineResult sslEngineResult;

/** Whether a handshake is in progress. */
private volatile boolean isHandshaking;

/**
* Constructor.
*
Expand Down Expand Up @@ -275,8 +278,25 @@ private void handleSslHandshake() throws IOException {
getLogger().log(Level.FINER, "Handling SSL handshake: " + hs);
}

if (isHandshaking && hs == HandshakeStatus.NOT_HANDSHAKING) {
// In some cases, on some platforms, the engine can go directly from a handshaking state to NOT_HANDSHAKING.
// We handle this situation as if it had returned FINISHED. See the following issues:
// https://github.com/restlet/restlet-framework-java/issues/852
// and
// https://github.com/restlet/restlet-framework-java/issues/862
hs = HandshakeStatus.FINISHED;

if (getLogger().isLoggable(Level.FINER)) {
getLogger().log(Level.FINER, "SSLEngine went directly from handshaking to NOT_HANDSHAKING, " +
"treating as FINISHED.");
}

}

if (hs != HandshakeStatus.NOT_HANDSHAKING) {
switch (getSslHandshakeStatus()) {
isHandshaking = true;

switch (hs) {
case FINISHED:
onFinished();
break;
Expand Down Expand Up @@ -371,6 +391,8 @@ public boolean isSslHandshaking() {
* exchanged.
*/
private void onFinished() {
isHandshaking = false;

if (isClientSide()) {
getInboundWay().setIoState(IoState.IDLE);
getOutboundWay().setIoState(IoState.INTEREST);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ public void init(Series<Parameter> helperParameters) {
enabledProtocols.toArray(enabledProtocolsArray);
setEnabledProtocols(enabledProtocolsArray);
} else {
setEnabledCipherSuites(null);
setEnabledProtocols(null);
}

setKeyManagerAlgorithm(helperParameters.getFirstValue(
Expand Down