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
@@ -628,8 +627,8 @@ void absentOnTrade(ConnectionContext context,
628627 }
629628
630629 public boolean isAvailable (ProtocolVersion protocolVersion ) {
631- for (int i = 0 ; i < supportedProtocols . length ; i ++ ) {
632- if (supportedProtocols [ i ] == protocolVersion ) {
630+ for (ProtocolVersion supportedProtocol : supportedProtocols ) {
631+ if (supportedProtocol == protocolVersion ) {
633632 return true ;
634633 }
635634 }
@@ -693,18 +692,23 @@ static final class ClientExtensions {
693692 static final Collection <SSLExtension > defaults ;
694693
695694 static {
695+ Collection <String > clientDisabledExtensions =
696+ getDisabledExtensions ("jdk.tls.client.disableExtensions" );
696697 Collection <SSLExtension > extensions = new LinkedList <>();
697698 for (SSLExtension extension : SSLExtension .values ()) {
698- if (extension .handshakeType != SSLHandshake .NOT_APPLICABLE ) {
699+ if (extension .handshakeType != SSLHandshake .NOT_APPLICABLE &&
700+ !clientDisabledExtensions .contains (extension .name )) {
699701 extensions .add (extension );
700702 }
701703 }
702704
703- // Switch off SNI extention?
704- boolean enableExtension =
705- Utilities .getBooleanProperty ("jsse.enableSNIExtension" , true );
706- if (!enableExtension ) {
707- extensions .remove (CH_SERVER_NAME );
705+ // Switch off SNI extension?
706+ if (extensions .contains (CH_SERVER_NAME )) {
707+ boolean enableExtension = Utilities .getBooleanProperty (
708+ "jsse.enableSNIExtension" , true );
709+ if (!enableExtension ) {
710+ extensions .remove (CH_SERVER_NAME );
711+ }
708712 }
709713
710714 // To switch off the max_fragment_length extension.
@@ -715,13 +719,15 @@ static final class ClientExtensions {
715719 // the two properties set to true, the extension is switch on.
716720 // We may remove the "jsse.enableMFLExtension" property in the
717721 // future. Please don't continue to use the misspelling property.
718- enableExtension =
719- Utilities .getBooleanProperty (
720- "jsse.enableMFLNExtension" , false ) ||
721- Utilities .getBooleanProperty (
722- "jsse.enableMFLExtension" , false );
723- if (!enableExtension ) {
724- extensions .remove (CH_MAX_FRAGMENT_LENGTH );
722+ if (extensions .contains (CH_MAX_FRAGMENT_LENGTH )) {
723+ boolean enableExtension =
724+ Utilities .getBooleanProperty (
725+ "jsse.enableMFLNExtension" , false ) ||
726+ Utilities .getBooleanProperty (
727+ "jsse.enableMFLExtension" , false );
728+ if (!enableExtension ) {
729+ extensions .remove (CH_MAX_FRAGMENT_LENGTH );
730+ }
725731 }
726732
727733 // To switch on certificate_authorities extension in ClientHello.
@@ -762,10 +768,12 @@ static final class ClientExtensions {
762768 // lot in practice. When there is a need to use this extension
763769 // in ClientHello handshake message, please take care of the
764770 // potential compatibility and interoperability issues above.
765- enableExtension = Utilities .getBooleanProperty (
766- "jdk.tls.client.enableCAExtension" , false );
767- if (!enableExtension ) {
768- extensions .remove (CH_CERTIFICATE_AUTHORITIES );
771+ if (extensions .contains (CH_CERTIFICATE_AUTHORITIES )) {
772+ boolean enableExtension = Utilities .getBooleanProperty (
773+ "jdk.tls.client.enableCAExtension" , false );
774+ if (!enableExtension ) {
775+ extensions .remove (CH_CERTIFICATE_AUTHORITIES );
776+ }
769777 }
770778
771779 defaults = Collections .unmodifiableCollection (extensions );
@@ -777,14 +785,51 @@ static final class ServerExtensions {
777785 static final Collection <SSLExtension > defaults ;
778786
779787 static {
788+ Collection <String > serverDisabledExtensions =
789+ getDisabledExtensions ("jdk.tls.server.disableExtensions" );
780790 Collection <SSLExtension > extensions = new LinkedList <>();
781791 for (SSLExtension extension : SSLExtension .values ()) {
782- if (extension .handshakeType != SSLHandshake .NOT_APPLICABLE ) {
792+ if (extension .handshakeType != SSLHandshake .NOT_APPLICABLE &&
793+ !serverDisabledExtensions .contains (extension .name )) {
783794 extensions .add (extension );
784795 }
785796 }
786797
787798 defaults = Collections .unmodifiableCollection (extensions );
788799 }
789800 }
801+
802+ // Get disabled extensions, which could be customized with System Properties.
803+ private static Collection <String > getDisabledExtensions (
804+ String propertyName ) {
805+ String property = GetPropertyAction .privilegedGetProperty (propertyName );
806+ if (SSLLogger .isOn && SSLLogger .isOn ("ssl,sslctx" )) {
807+ SSLLogger .fine (
808+ "System property " + propertyName + " is set to '" +
809+ property + "'" );
810+ }
811+ if (property != null && !property .isEmpty ()) {
812+ // remove double quote marks from beginning/end of the property
813+ if (property .length () > 1 && property .charAt (0 ) == '"' &&
814+ property .charAt (property .length () - 1 ) == '"' ) {
815+ property = property .substring (1 , property .length () - 1 );
816+ }
817+ }
818+
819+ if (property != null && !property .isEmpty ()) {
820+ String [] extensionNames = property .split ("," );
821+ Collection <String > extensions =
822+ new ArrayList <>(extensionNames .length );
823+ for (String extension : extensionNames ) {
824+ extension = extension .trim ();
825+ if (!extension .isEmpty ()) {
826+ extensions .add (extension );
827+ }
828+ }
829+
830+ return extensions ;
831+ }
832+
833+ return Collections .emptyList ();
834+ }
790835}
0 commit comments