Skip to content

Commit

Permalink
Support TLSv1.3 (#4528)
Browse files Browse the repository at this point in the history
* Support TLSv 1.3

Signed-off-by: Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com>
  • Loading branch information
jbescos authored Sep 24, 2020
1 parent 0f65e5d commit a73db94
Show file tree
Hide file tree
Showing 16 changed files with 219 additions and 67 deletions.
31 changes: 24 additions & 7 deletions connectors/jdk-connector/pom.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!--
Copyright (c) 2011, 2019 Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the
terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -73,19 +73,36 @@
<artifactId>maven-bundle-plugin</artifactId>
<inherited>true</inherited>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
</configuration>
</plugin>
</plugins>
</build>

<profiles>
<profile>
<id>jdk11+</id>
<id>jdk8</id>
<activation>
<jdk>[11,)</jdk>
<jdk>(,9)</jdk>
</activation>
<properties>
<!-- https://bugs.openjdk.java.net/browse/JDK-8211426 -->
<surefire.security.argline>-Djdk.tls.server.protocols=TLSv1.2</surefire.security.argline>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
<excludes>
<exclude>**/SslFilterTLS13Test.java</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -50,6 +50,7 @@ class SslFilter extends Filter<ByteBuffer, ByteBuffer, ByteBuffer, ByteBuffer> {
/* Some operations on SSL engine require a buffer as a parameter even if they don't need any data.
This buffer is for that purpose. */
private static final ByteBuffer emptyBuffer = ByteBuffer.allocate(0);
private static final String TLSV13 = "TLSv1.3";

// buffer for passing data to the upper filter
private final ByteBuffer applicationInputBuffer;
Expand All @@ -61,6 +62,7 @@ class SslFilter extends Filter<ByteBuffer, ByteBuffer, ByteBuffer, ByteBuffer> {
private final WriteQueue writeQueue = new WriteQueue();

private volatile State state = State.NOT_STARTED;
private volatile boolean tlsv13 = false;
/*
* Pending write operation stored when writing data was not possible. It will be resumed when write operation is
* available again. Only one write operation can be in progress at a time. Trying to store more than one pending
Expand Down Expand Up @@ -169,14 +171,14 @@ BUFFER_UNDERFLOW can occur only after unwrap(), but to be 100% sure we handle al
}

case CLOSED: {
state = State.CLOSED;
setState(State.CLOSED);
break;
}

case OK: {
// check if we started re-handshaking
if (result.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING) {
state = State.REHANDSHAKING;
if (isHandshaking(result.getHandshakeStatus())) {
setState(State.REHANDSHAKING);
}

((Buffer) networkOutputBuffer).flip();
Expand Down Expand Up @@ -367,10 +369,10 @@ private boolean handleRead(ByteBuffer networkData) {
}

// we started re-handshaking
if (result.getHandshakeStatus() != SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING
if (!tlsv13 && isHandshaking(result.getHandshakeStatus())
// make sure we don't confuse re-handshake with closing handshake
&& !sslEngine.isOutboundDone()) {
state = State.REHANDSHAKING;
setState(State.REHANDSHAKING);
return doHandshakeStep(networkData);
}

Expand All @@ -392,7 +394,8 @@ private boolean doHandshakeStep(ByteBuffer networkData) {
boolean handshakeFinished = false;

synchronized (this) {
if (SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING.equals(sslEngine.getHandshakeStatus())) {
SSLEngineResult.HandshakeStatus hs = sslEngine.getHandshakeStatus();
if (!isHandshaking(hs)) {
// we stopped handshaking while waiting for the lock
return true;
}
Expand All @@ -403,18 +406,16 @@ private boolean doHandshakeStep(ByteBuffer networkData) {
LazyBuffer outputBuffer = new LazyBuffer();
boolean stepFinished = false;
while (!stepFinished) {
SSLEngineResult.HandshakeStatus hs = sslEngine.getHandshakeStatus();
hs = sslEngine.getHandshakeStatus();

switch (hs) {
case NOT_HANDSHAKING: {
/* This should never happen. If we are here and not handshaking, it means a bug
in the state machine of this class, because we stopped handshaking and did not exit this while loop.
The could be caused either by overlooking FINISHED state or incorrectly treating an error. */

throw new IllegalStateException("Trying to handshake, but SSL engine not in HANDSHAKING state."
+ "SSL filter state: \n" + getDebugState());
throw new IllegalStateException(
LocalizationMessages.HTTP_CONNECTION_INVALID_HANDSHAKE_STATUS(getDebugState()));
}

case FINISHED: {
/* According to SSLEngine javadoc FINISHED status can be returned only in SSLEngineResult,
but just to make sure we don't end up in an infinite loop when presented with an SSLEngine
Expand Down Expand Up @@ -449,7 +450,7 @@ that BUFFER_UNDERFLOW can occur only after unwrap(), but to be 100% sure we hand

case CLOSED: {
stepFinished = true;
state = State.CLOSED;
setState(State.CLOSED);
break;
}
}
Expand Down Expand Up @@ -490,7 +491,7 @@ that BUFFER_UNDERFLOW can occur only after unwrap(), but to be 100% sure we hand

case CLOSED: {
stepFinished = true;
state = State.CLOSED;
setState(State.CLOSED);
break;
}
}
Expand Down Expand Up @@ -532,6 +533,7 @@ that BUFFER_UNDERFLOW can occur only after unwrap(), but to be 100% sure we hand

if (handshakeFinished) {
handleHandshakeFinished();
tlsv13 = TLSV13.equals(sslEngine.getSession().getProtocol());
// indicate that there still might be usable data in the input buffer
return true;
}
Expand All @@ -550,10 +552,10 @@ private void handleHandshakeFinished() {
}

if (state == State.HANDSHAKING) {
state = State.DATA;
setState(State.DATA);
upstreamFilter.onSslHandshakeCompleted();
} else if (state == State.REHANDSHAKING) {
state = State.DATA;
setState(State.DATA);
if (pendingApplicationWrite != null) {
Runnable write = pendingApplicationWrite;
// set pending write to null to cover the extremely improbable case that we start re-handshaking again
Expand All @@ -571,7 +573,7 @@ private void handleSslError(Throwable t) {
@Override
void startSsl() {
try {
state = State.HANDSHAKING;
setState(State.HANDSHAKING);
sslEngine.beginHandshake();
doHandshakeStep(emptyBuffer);
} catch (SSLException e) {
Expand Down Expand Up @@ -707,4 +709,14 @@ public String toString() {
}
}
}

private void setState(State state) {
this.state = state;
}

private boolean isHandshaking(SSLEngineResult.HandshakeStatus hs) {
return SSLEngineResult.HandshakeStatus.NOT_HANDSHAKING != hs
// TLSv1.3 introduces this, and it is considered as not handshaking
&& SSLEngineResult.HandshakeStatus.FINISHED != hs;
}
}
Original file line number Diff line number Diff line change
@@ -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.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -71,3 +71,4 @@ thread.pool.core.size.too.small="Core thread pool size cannot be smaller than 0.
http.connection.establishing.illegal.state="Cannot try to establish connection if the connection is in other than CREATED state\
. Current state: {0}.
http.connection.not.idle="Http request cannot be sent over a connection that is in other state than IDLE. Current state: {0}"
http.connection.invalid.handshake.status="Trying to handshake, but SSL engine not in HANDSHAKING state. SSL filter state: {0}"
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.jdk.connector.internal;

public class SslFilterTLS11Test extends SslFilterTest {

public SslFilterTLS11Test() {
System.setProperty("jdk.tls.server.protocols", "TLSv1.1");
System.setProperty("jdk.tls.client.protocols", "TLSv1.1");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.jdk.connector.internal;

public class SslFilterTLS12Test extends SslFilterTest {

public SslFilterTLS12Test() {
System.setProperty("jdk.tls.server.protocols", "TLSv1.2");
System.setProperty("jdk.tls.client.protocols", "TLSv1.2");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.jdk.connector.internal;

public class SslFilterTLS13Test extends SslFilterTest {

public SslFilterTLS13Test() {
System.setProperty("jdk.tls.server.protocols", "TLSv1.3");
System.setProperty("jdk.tls.client.protocols", "TLSv1.3");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the
* Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
* version 2 with the GNU Classpath Exception, which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
*/

package org.glassfish.jersey.jdk.connector.internal;

public class SslFilterTLS1Test extends SslFilterTest {

public SslFilterTLS1Test() {
System.setProperty("jdk.tls.server.protocols", "TLSv1");
System.setProperty("jdk.tls.client.protocols", "TLSv1");
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0, which is available at
Expand Down Expand Up @@ -39,25 +39,23 @@
import javax.net.ssl.SSLSocket;

import org.glassfish.jersey.SslConfigurator;

import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
* @author Petr Janouch
*/
public class SslFilterTest {
public abstract class SslFilterTest {

private static final int PORT = 8321;

@Before
public void beforeTest() {
System.setProperty("javax.net.ssl.keyStore", this.getClass().getResource("/keystore_server").getPath());
static {
System.setProperty("javax.net.ssl.keyStore", SslFilterTest.class.getResource("/keystore_server").getPath());
System.setProperty("javax.net.ssl.keyStorePassword", "asdfgh");
System.setProperty("javax.net.ssl.trustStore", this.getClass().getResource("/truststore_server").getPath());
System.setProperty("javax.net.ssl.trustStore", SslFilterTest.class.getResource("/truststore_server").getPath());
System.setProperty("javax.net.ssl.trustStorePassword", "asdfgh");
}

Expand Down
17 changes: 0 additions & 17 deletions connectors/jdk-connector/src/test/resources/client.cert

This file was deleted.

Loading

0 comments on commit a73db94

Please sign in to comment.