Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support TLSv1.3 #4528

Merged
merged 4 commits into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from 3 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
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
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}"
senivam marked this conversation as resolved.
Show resolved Hide resolved
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.

27 changes: 27 additions & 0 deletions connectors/jdk-connector/src/test/resources/clientkey.cert
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Alias name: clientkey
Creation date: Jun 22, 2020
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
-----BEGIN CERTIFICATE-----
MIIDjTCCAnWgAwIBAgIEdX5IhDANBgkqhkiG9w0BAQsFADB2MQswCQYDVQQGEwJD
WjEXMBUGA1UECBMOQ3plY2ggUmVwdWJsaWMxDzANBgNVBAcTBlByYWd1ZTEbMBkG
A1UEChMST3JhY2xlIENvcnBvcmF0aW9uMQ8wDQYDVQQLEwZKZXJzZXkxDzANBgNV
BAMTBkNsaWVudDAgFw0yMDA2MjIwNzI5MzZaGA8yMTIwMDUyOTA3MjkzNlowdjEL
MAkGA1UEBhMCQ1oxFzAVBgNVBAgTDkN6ZWNoIFJlcHVibGljMQ8wDQYDVQQHEwZQ
cmFndWUxGzAZBgNVBAoTEk9yYWNsZSBDb3Jwb3JhdGlvbjEPMA0GA1UECxMGSmVy
c2V5MQ8wDQYDVQQDEwZDbGllbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
AoIBAQClVUtMXL/+WK5Ma6mV+BeGZlSlGqT9teUUDwPkipZMA9wdXTC3iSIp098s
NCiPJBPXs+0KSrrPVgcHlMONcAzg3FHQrbP1aIH0oFOHR1bF/KNG1/XzV8HLMHqM
ynnDJ69sYOUy6BO6lYQM1GaPf0fdqkdii2/clKiKzzT/Ohr6549q3vdzHw4hKmoE
SKrdmv4OkOFGKzAH2dzNciHGnpiQj03DhjAN/8KobdUbsxoklnYOdDkg2UErI0zC
qPRg2DVVOxhViMOmPBheXVvdDiIAdLlXRiPTraetr1KxDHV6KXsQhKmADZhIj8jY
NjIyMo52bRTToaJQL5DKF6Boyx/tAgMBAAGjITAfMB0GA1UdDgQWBBSjbPqA6Tkv
6oS99eZLNQk11M+DODANBgkqhkiG9w0BAQsFAAOCAQEACNAqN0lz1cUlIocfhSk8
JlAHsRbWoCxxJZNJE0WWZ6lfH5xdlW0/87yfSvtLwDOY/8OYAhbzjG5O8mQv/I32
b2Acs42Sh+otVyLjbYicv+1yMuvmBnhEImeMHSGFjczYf9zQ+2PlerxdNwVKdpUL
V3Dt68wTlWNRYm9X6uVpNRG7fy7/goeJhAXuVER9Gtl/LQ6GJyZjVxYemckoXWDY
DCqVlzsZpnyoI2lrYXlcT3liPlRLJjqnWvmmF9GyqiIVeng9VTfStsEQ6LUfwKQO
dtvwYhbVtL++fuX/99WYCDRL8mSFu8REruQln3TJf79wOQ14O0H5jWjr4QoeOIf9
aw==
-----END CERTIFICATE-----
Binary file modified connectors/jdk-connector/src/test/resources/keystore_client
Binary file not shown.
Binary file modified connectors/jdk-connector/src/test/resources/keystore_server
Binary file not shown.
Loading