Skip to content

Commit

Permalink
8217633: Configurable extensions with system properties
Browse files Browse the repository at this point in the history
Reviewed-by: rhalade, jnimeh
  • Loading branch information
XueleiFan committed Jan 30, 2021
1 parent f5ca838 commit 71bfe96
Show file tree
Hide file tree
Showing 2 changed files with 144 additions and 24 deletions.
93 changes: 69 additions & 24 deletions src/java.base/share/classes/sun/security/ssl/SSLExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,9 @@
import java.io.IOException;
import java.nio.ByteBuffer;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Locale;
import java.util.*;

import sun.security.action.GetPropertyAction;
import sun.security.ssl.SSLHandshake.HandshakeMessage;
import sun.security.util.HexDumpEncoder;

Expand Down Expand Up @@ -648,8 +647,8 @@ void absentOnTrade(ConnectionContext context,
}

public boolean isAvailable(ProtocolVersion protocolVersion) {
for (int i = 0; i < supportedProtocols.length; i++) {
if (supportedProtocols[i] == protocolVersion) {
for (ProtocolVersion supportedProtocol : supportedProtocols) {
if (supportedProtocol == protocolVersion) {
return true;
}
}
Expand Down Expand Up @@ -713,18 +712,23 @@ static final class ClientExtensions {
static final Collection<SSLExtension> defaults;

static {
Collection<String> clientDisabledExtensions =
getDisabledExtensions("jdk.tls.client.disableExtensions");
Collection<SSLExtension> extensions = new LinkedList<>();
for (SSLExtension extension : SSLExtension.values()) {
if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE) {
if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE &&
!clientDisabledExtensions.contains(extension.name)) {
extensions.add(extension);
}
}

// Switch off SNI extention?
boolean enableExtension =
Utilities.getBooleanProperty("jsse.enableSNIExtension", true);
if (!enableExtension) {
extensions.remove(CH_SERVER_NAME);
// Switch off SNI extension?
if (extensions.contains(CH_SERVER_NAME)) {
boolean enableExtension = Utilities.getBooleanProperty(
"jsse.enableSNIExtension", true);
if (!enableExtension) {
extensions.remove(CH_SERVER_NAME);
}
}

// To switch off the max_fragment_length extension.
Expand All @@ -735,13 +739,15 @@ static final class ClientExtensions {
// the two properties set to true, the extension is switch on.
// We may remove the "jsse.enableMFLExtension" property in the
// future. Please don't continue to use the misspelling property.
enableExtension =
Utilities.getBooleanProperty(
"jsse.enableMFLNExtension", false) ||
Utilities.getBooleanProperty(
"jsse.enableMFLExtension", false);
if (!enableExtension) {
extensions.remove(CH_MAX_FRAGMENT_LENGTH);
if (extensions.contains(CH_MAX_FRAGMENT_LENGTH)) {
boolean enableExtension =
Utilities.getBooleanProperty(
"jsse.enableMFLNExtension", false) ||
Utilities.getBooleanProperty(
"jsse.enableMFLExtension", false);
if (!enableExtension) {
extensions.remove(CH_MAX_FRAGMENT_LENGTH);
}
}

// To switch on certificate_authorities extension in ClientHello.
Expand Down Expand Up @@ -782,10 +788,12 @@ static final class ClientExtensions {
// lot in practice. When there is a need to use this extension
// in ClientHello handshake message, please take care of the
// potential compatibility and interoperability issues above.
enableExtension = Utilities.getBooleanProperty(
"jdk.tls.client.enableCAExtension", false);
if (!enableExtension) {
extensions.remove(CH_CERTIFICATE_AUTHORITIES);
if (extensions.contains(CH_CERTIFICATE_AUTHORITIES)) {
boolean enableExtension = Utilities.getBooleanProperty(
"jdk.tls.client.enableCAExtension", false);
if (!enableExtension) {
extensions.remove(CH_CERTIFICATE_AUTHORITIES);
}
}

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

static {
Collection<String> serverDisabledExtensions =
getDisabledExtensions("jdk.tls.server.disableExtensions");
Collection<SSLExtension> extensions = new LinkedList<>();
for (SSLExtension extension : SSLExtension.values()) {
if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE) {
if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE &&
!serverDisabledExtensions.contains(extension.name)) {
extensions.add(extension);
}
}

defaults = Collections.unmodifiableCollection(extensions);
}
}

// Get disabled extensions, which could be customized with System Properties.
private static Collection<String> getDisabledExtensions(
String propertyName) {
String property = GetPropertyAction.privilegedGetProperty(propertyName);
if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) {
SSLLogger.fine(
"System property " + propertyName + " is set to '" +
property + "'");
}
if (property != null && !property.isEmpty()) {
// remove double quote marks from beginning/end of the property
if (property.length() > 1 && property.charAt(0) == '"' &&
property.charAt(property.length() - 1) == '"') {
property = property.substring(1, property.length() - 1);
}
}

if (property != null && !property.isEmpty()) {
String[] extensionNames = property.split(",");
Collection<String> extensions =
new ArrayList<>(extensionNames.length);
for (String extension : extensionNames) {
extension = extension.trim();
if (!extension.isEmpty()) {
extensions.add(extension);
}
}

return extensions;
}

return Collections.emptyList();
}
}
75 changes: 75 additions & 0 deletions test/jdk/sun/security/ssl/SSLSocketImpl/DisableExtensions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

/*
* @test
* @bug 8217633
* @library /javax/net/ssl/templates
* @summary Configurable extensions with system properties
* @run main/othervm DisableExtensions supported_versions TLSv1.3 fail
* @run main/othervm DisableExtensions supported_versions TLSv1.2
*/

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLException;

public class DisableExtensions extends SSLSocketTemplate {

private final String[] protocols;

public DisableExtensions(String[] protocols) {
this.protocols = protocols;
}

@Override
protected void configureClientSocket(SSLSocket socket) {
socket.setEnabledProtocols(protocols);
}

// Run the test case.
//
// Check that the extension could be disabled, and the impact may be
// different for different protocols.
public static void main(String[] args) throws Exception {
System.setProperty("jdk.tls.client.disableExtensions", args[0]);

boolean shouldSuccess = (args.length != 3);

try {
(new DisableExtensions(new String[] {args[1]})).run();
} catch (SSLException | IllegalStateException ssle) {
if (shouldSuccess) {
throw new RuntimeException(
"The extension " + args[0] + " is disabled");
}

return;
}

if (!shouldSuccess) {
throw new RuntimeException(
"The extension " + args[0] +
" should be disabled and the connection should fail");
}
}
}

0 comments on commit 71bfe96

Please sign in to comment.