Skip to content

Commit 71bfe96

Browse files
committed
8217633: Configurable extensions with system properties
Reviewed-by: rhalade, jnimeh
1 parent f5ca838 commit 71bfe96

File tree

2 files changed

+144
-24
lines changed

2 files changed

+144
-24
lines changed

src/java.base/share/classes/sun/security/ssl/SSLExtension.java

Lines changed: 69 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,9 @@
2828
import java.io.IOException;
2929
import java.nio.ByteBuffer;
3030
import java.text.MessageFormat;
31-
import java.util.Collection;
32-
import java.util.Collections;
33-
import java.util.LinkedList;
34-
import java.util.Locale;
31+
import java.util.*;
32+
33+
import sun.security.action.GetPropertyAction;
3534
import sun.security.ssl.SSLHandshake.HandshakeMessage;
3635
import sun.security.util.HexDumpEncoder;
3736

@@ -648,8 +647,8 @@ void absentOnTrade(ConnectionContext context,
648647
}
649648

650649
public boolean isAvailable(ProtocolVersion protocolVersion) {
651-
for (int i = 0; i < supportedProtocols.length; i++) {
652-
if (supportedProtocols[i] == protocolVersion) {
650+
for (ProtocolVersion supportedProtocol : supportedProtocols) {
651+
if (supportedProtocol == protocolVersion) {
653652
return true;
654653
}
655654
}
@@ -713,18 +712,23 @@ static final class ClientExtensions {
713712
static final Collection<SSLExtension> defaults;
714713

715714
static {
715+
Collection<String> clientDisabledExtensions =
716+
getDisabledExtensions("jdk.tls.client.disableExtensions");
716717
Collection<SSLExtension> extensions = new LinkedList<>();
717718
for (SSLExtension extension : SSLExtension.values()) {
718-
if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE) {
719+
if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE &&
720+
!clientDisabledExtensions.contains(extension.name)) {
719721
extensions.add(extension);
720722
}
721723
}
722724

723-
// Switch off SNI extention?
724-
boolean enableExtension =
725-
Utilities.getBooleanProperty("jsse.enableSNIExtension", true);
726-
if (!enableExtension) {
727-
extensions.remove(CH_SERVER_NAME);
725+
// Switch off SNI extension?
726+
if (extensions.contains(CH_SERVER_NAME)) {
727+
boolean enableExtension = Utilities.getBooleanProperty(
728+
"jsse.enableSNIExtension", true);
729+
if (!enableExtension) {
730+
extensions.remove(CH_SERVER_NAME);
731+
}
728732
}
729733

730734
// To switch off the max_fragment_length extension.
@@ -735,13 +739,15 @@ static final class ClientExtensions {
735739
// the two properties set to true, the extension is switch on.
736740
// We may remove the "jsse.enableMFLExtension" property in the
737741
// future. Please don't continue to use the misspelling property.
738-
enableExtension =
739-
Utilities.getBooleanProperty(
740-
"jsse.enableMFLNExtension", false) ||
741-
Utilities.getBooleanProperty(
742-
"jsse.enableMFLExtension", false);
743-
if (!enableExtension) {
744-
extensions.remove(CH_MAX_FRAGMENT_LENGTH);
742+
if (extensions.contains(CH_MAX_FRAGMENT_LENGTH)) {
743+
boolean enableExtension =
744+
Utilities.getBooleanProperty(
745+
"jsse.enableMFLNExtension", false) ||
746+
Utilities.getBooleanProperty(
747+
"jsse.enableMFLExtension", false);
748+
if (!enableExtension) {
749+
extensions.remove(CH_MAX_FRAGMENT_LENGTH);
750+
}
745751
}
746752

747753
// To switch on certificate_authorities extension in ClientHello.
@@ -782,10 +788,12 @@ static final class ClientExtensions {
782788
// lot in practice. When there is a need to use this extension
783789
// in ClientHello handshake message, please take care of the
784790
// potential compatibility and interoperability issues above.
785-
enableExtension = Utilities.getBooleanProperty(
786-
"jdk.tls.client.enableCAExtension", false);
787-
if (!enableExtension) {
788-
extensions.remove(CH_CERTIFICATE_AUTHORITIES);
791+
if (extensions.contains(CH_CERTIFICATE_AUTHORITIES)) {
792+
boolean enableExtension = Utilities.getBooleanProperty(
793+
"jdk.tls.client.enableCAExtension", false);
794+
if (!enableExtension) {
795+
extensions.remove(CH_CERTIFICATE_AUTHORITIES);
796+
}
789797
}
790798

791799
defaults = Collections.unmodifiableCollection(extensions);
@@ -797,14 +805,51 @@ static final class ServerExtensions {
797805
static final Collection<SSLExtension> defaults;
798806

799807
static {
808+
Collection<String> serverDisabledExtensions =
809+
getDisabledExtensions("jdk.tls.server.disableExtensions");
800810
Collection<SSLExtension> extensions = new LinkedList<>();
801811
for (SSLExtension extension : SSLExtension.values()) {
802-
if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE) {
812+
if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE &&
813+
!serverDisabledExtensions.contains(extension.name)) {
803814
extensions.add(extension);
804815
}
805816
}
806817

807818
defaults = Collections.unmodifiableCollection(extensions);
808819
}
809820
}
821+
822+
// Get disabled extensions, which could be customized with System Properties.
823+
private static Collection<String> getDisabledExtensions(
824+
String propertyName) {
825+
String property = GetPropertyAction.privilegedGetProperty(propertyName);
826+
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
827+
SSLLogger.fine(
828+
"System property " + propertyName + " is set to '" +
829+
property + "'");
830+
}
831+
if (property != null && !property.isEmpty()) {
832+
// remove double quote marks from beginning/end of the property
833+
if (property.length() > 1 && property.charAt(0) == '"' &&
834+
property.charAt(property.length() - 1) == '"') {
835+
property = property.substring(1, property.length() - 1);
836+
}
837+
}
838+
839+
if (property != null && !property.isEmpty()) {
840+
String[] extensionNames = property.split(",");
841+
Collection<String> extensions =
842+
new ArrayList<>(extensionNames.length);
843+
for (String extension : extensionNames) {
844+
extension = extension.trim();
845+
if (!extension.isEmpty()) {
846+
extensions.add(extension);
847+
}
848+
}
849+
850+
return extensions;
851+
}
852+
853+
return Collections.emptyList();
854+
}
810855
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 8217633
27+
* @library /javax/net/ssl/templates
28+
* @summary Configurable extensions with system properties
29+
* @run main/othervm DisableExtensions supported_versions TLSv1.3 fail
30+
* @run main/othervm DisableExtensions supported_versions TLSv1.2
31+
*/
32+
33+
import javax.net.ssl.SSLSocket;
34+
import javax.net.ssl.SSLException;
35+
36+
public class DisableExtensions extends SSLSocketTemplate {
37+
38+
private final String[] protocols;
39+
40+
public DisableExtensions(String[] protocols) {
41+
this.protocols = protocols;
42+
}
43+
44+
@Override
45+
protected void configureClientSocket(SSLSocket socket) {
46+
socket.setEnabledProtocols(protocols);
47+
}
48+
49+
// Run the test case.
50+
//
51+
// Check that the extension could be disabled, and the impact may be
52+
// different for different protocols.
53+
public static void main(String[] args) throws Exception {
54+
System.setProperty("jdk.tls.client.disableExtensions", args[0]);
55+
56+
boolean shouldSuccess = (args.length != 3);
57+
58+
try {
59+
(new DisableExtensions(new String[] {args[1]})).run();
60+
} catch (SSLException | IllegalStateException ssle) {
61+
if (shouldSuccess) {
62+
throw new RuntimeException(
63+
"The extension " + args[0] + " is disabled");
64+
}
65+
66+
return;
67+
}
68+
69+
if (!shouldSuccess) {
70+
throw new RuntimeException(
71+
"The extension " + args[0] +
72+
" should be disabled and the connection should fail");
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)