2828import java .io .IOException ;
2929import java .nio .ByteBuffer ;
3030import 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 ;
3534import sun .security .ssl .SSLHandshake .HandshakeMessage ;
3635import 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}
0 commit comments