--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java Fri May 11 15:53:12 2018 -0700
@@ -0,0 +1,691 @@
+/*
+ * Copyright (c) 2018, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+package sun.security.ssl;
+
+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 sun.security.ssl.SSLHandshake.HandshakeMessage;
+import sun.security.util.HexDumpEncoder;
+
+enum SSLExtension implements SSLStringize {
+ // Extensions defined in RFC 3546
+ CH_SERVER_NAME (0x0000, "server_name",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_13,
+ ServerNameExtension.chNetworkProducer,
+ ServerNameExtension.chOnLoadConcumer,
+ null,
+ null,
+ ServerNameExtension.chStringize),
+ SH_SERVER_NAME (0x0000, "server_name",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ ServerNameExtension.shNetworkProducer,
+ ServerNameExtension.shOnLoadConcumer,
+ null,
+ null,
+ ServerNameExtension.shStringize),
+ EE_SERVER_NAME (0x0000, "server_name",
+ SSLHandshake.ENCRYPTED_EXTENSIONS,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ ServerNameExtension.eeNetworkProducer,
+ ServerNameExtension.eeOnLoadConcumer,
+ null,
+ null,
+ ServerNameExtension.shStringize),
+ CH_MAX_FRAGMENT_LENGTH (0x0001, "max_fragment_length",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_13,
+ MaxFragExtension.chNetworkProducer,
+ MaxFragExtension.chOnLoadConcumer,
+ null,
+ null,
+ MaxFragExtension.maxFragLenStringize),
+ SH_MAX_FRAGMENT_LENGTH (0x0001, "max_fragment_length",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ MaxFragExtension.shNetworkProducer,
+ MaxFragExtension.shOnLoadConcumer,
+ null,
+ MaxFragExtension.shOnTradeConsumer,
+ MaxFragExtension.maxFragLenStringize),
+ EE_MAX_FRAGMENT_LENGTH (0x0001, "max_fragment_length",
+ SSLHandshake.ENCRYPTED_EXTENSIONS,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ MaxFragExtension.eeNetworkProducer,
+ MaxFragExtension.eeOnLoadConcumer,
+ null,
+ MaxFragExtension.eeOnTradeConsumer,
+ MaxFragExtension.maxFragLenStringize),
+ CLIENT_CERTIFICATE_URL (0x0002, "client_certificate_url"),
+ TRUSTED_CA_KEYS (0x0003, "trusted_ca_keys"),
+ TRUNCATED_HMAC (0x0004, "truncated_hmac"),
+
+ CH_STATUS_REQUEST (0x0005, "status_request",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_13,
+ CertStatusExtension.chNetworkProducer,
+ CertStatusExtension.chOnLoadConsumer,
+ null,
+ null,
+ CertStatusExtension.certStatusReqStringize),
+ SH_STATUS_REQUEST (0x0005, "status_request",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ CertStatusExtension.shNetworkProducer,
+ CertStatusExtension.shOnLoadConsumer,
+ null,
+ null,
+ CertStatusExtension.certStatusReqStringize),
+
+ CR_STATUS_REQUEST (0x0005, "status_request"),
+ CT_STATUS_REQUEST (0x0005, "status_request",
+ SSLHandshake.CERTIFICATE,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ CertStatusExtension.ctNetworkProducer,
+ CertStatusExtension.ctOnLoadConsumer,
+ null,
+ null,
+ CertStatusExtension.certStatusRespStringize),
+ // extensions defined in RFC 4681
+ USER_MAPPING (0x0006, "user_mapping"),
+
+ // extensions defined in RFC 5878
+ CLIENT_AUTHZ (0x0007, "client_authz"),
+ SERVER_AUTHZ (0x0008, "server_authz"),
+
+ // extensions defined in RFC 5081
+ CERT_TYPE (0x0009, "cert_type"),
+
+ // extensions defined in RFC 4492 (ECC)
+ CH_SUPPORTED_GROUPS (0x000A, "supported_groups",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_13,
+ SupportedGroupsExtension.chNetworkProducer,
+ SupportedGroupsExtension.chOnLoadConcumer,
+ null,
+ null,
+ SupportedGroupsExtension.sgsStringize),
+ EE_SUPPORTED_GROUPS (0x000A, "supported_groups",
+ SSLHandshake.ENCRYPTED_EXTENSIONS,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ SupportedGroupsExtension.eeNetworkProducer,
+ SupportedGroupsExtension.eeOnLoadConcumer,
+ null,
+ null,
+ SupportedGroupsExtension.sgsStringize),
+
+ CH_EC_POINT_FORMATS (0x000B, "ec_point_formats",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ ECPointFormatsExtension.chNetworkProducer,
+ ECPointFormatsExtension.chOnLoadConcumer,
+ null,
+ null,
+ ECPointFormatsExtension.epfStringize),
+ SH_EC_POINT_FORMATS (0x000B, "ec_point_formats",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ null, // not use of the producer
+ ECPointFormatsExtension.shOnLoadConcumer,
+ null,
+ null,
+ ECPointFormatsExtension.epfStringize),
+
+ // extensions defined in RFC 5054
+ SRP (0x000C, "srp"),
+
+ // extensions defined in RFC 5246
+ CH_SIGNATURE_ALGORITHMS (0x000D, "signature_algorithms",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_12_13,
+ SignatureAlgorithmsExtension.chNetworkProducer,
+ SignatureAlgorithmsExtension.chOnLoadConcumer,
+ SignatureAlgorithmsExtension.chOnLoadAbsence,
+ SignatureAlgorithmsExtension.chOnTradeConsumer,
+ SignatureAlgorithmsExtension.ssStringize),
+ CR_SIGNATURE_ALGORITHMS (0x000D, "signature_algorithms",
+ SSLHandshake.CERTIFICATE_REQUEST,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ SignatureAlgorithmsExtension.crNetworkProducer,
+ SignatureAlgorithmsExtension.crOnLoadConcumer,
+ SignatureAlgorithmsExtension.crOnLoadAbsence,
+ SignatureAlgorithmsExtension.crOnTradeConsumer,
+ SignatureAlgorithmsExtension.ssStringize),
+
+ CH_SIGNATURE_ALGORITHMS_CERT (0x0032, "signature_algorithms_cert",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_12_13,
+ CertSignAlgsExtension.chNetworkProducer,
+ CertSignAlgsExtension.chOnLoadConcumer,
+ null,
+ CertSignAlgsExtension.chOnTradeConsumer,
+ CertSignAlgsExtension.ssStringize),
+ CR_SIGNATURE_ALGORITHMS_CERT (0x0032, "signature_algorithms_cert",
+ SSLHandshake.CERTIFICATE_REQUEST,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ CertSignAlgsExtension.crNetworkProducer,
+ CertSignAlgsExtension.crOnLoadConcumer,
+ null,
+ CertSignAlgsExtension.crOnTradeConsumer,
+ CertSignAlgsExtension.ssStringize),
+
+ // extensions defined in RFC 5764
+ USE_SRTP (0x000E, "use_srtp"),
+
+ // extensions defined in RFC 6520
+ HEARTBEAT (0x000E, "heartbeat"),
+
+ // extension defined in RFC 7301 (ALPN)
+ CH_ALPN (0x0010, "application_layer_protocol_negotiation",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_13,
+ AlpnExtension.chNetworkProducer,
+ AlpnExtension.chOnLoadConcumer,
+ AlpnExtension.chOnLoadAbsence,
+ null,
+ AlpnExtension.alpnStringize),
+ SH_ALPN (0x0010, "application_layer_protocol_negotiation",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ AlpnExtension.shNetworkProducer,
+ AlpnExtension.shOnLoadConcumer,
+ AlpnExtension.shOnLoadAbsence,
+ null,
+ AlpnExtension.alpnStringize),
+ EE_ALPN (0x0010, "application_layer_protocol_negotiation",
+ SSLHandshake.ENCRYPTED_EXTENSIONS,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ AlpnExtension.shNetworkProducer,
+ AlpnExtension.shOnLoadConcumer,
+ AlpnExtension.shOnLoadAbsence,
+ null,
+ AlpnExtension.alpnStringize),
+
+ // extensions defined in RFC 6961
+ CH_STATUS_REQUEST_V2 (0x0011, "status_request_v2",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ CertStatusExtension.chV2NetworkProducer,
+ CertStatusExtension.chV2OnLoadConsumer,
+ null,
+ null,
+ CertStatusExtension.certStatusReqV2Stringize),
+ SH_STATUS_REQUEST_V2 (0x0011, "status_request_v2",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ CertStatusExtension.shV2NetworkProducer,
+ CertStatusExtension.shV2OnLoadConsumer,
+ null,
+ null,
+ CertStatusExtension.certStatusReqV2Stringize),
+
+ // extensions defined in RFC 6962
+ SIGNED_CERT_TIMESTAMP (0x0012, "signed_certificate_timestamp"),
+
+ // extensions defined in RFC 7250
+ CLIENT_CERT_TYPE (0x0013, "padding"),
+ SERVER_CERT_TYPE (0x0014, "server_certificate_type"),
+
+ // extensions defined in RFC 7685
+ PADDING (0x0015, "client_certificate_type"),
+
+ // extensions defined in RFC 7366
+ ENCRYPT_THEN_MAC (0x0016, "encrypt_then_mac"),
+
+ // extensions defined in RFC 7627
+ CH_EXTENDED_MASTER_SECRET (0x0017, "extended_master_secret",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_10_12,
+ ExtendedMasterSecretExtension.chNetworkProducer,
+ ExtendedMasterSecretExtension.chOnLoadConcumer,
+ ExtendedMasterSecretExtension.chOnLoadAbsence,
+ null,
+ ExtendedMasterSecretExtension.emsStringize),
+ SH_EXTENDED_MASTER_SECRET (0x0017, "extended_master_secret",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_10_12,
+ ExtendedMasterSecretExtension.shNetworkProducer,
+ ExtendedMasterSecretExtension.shOnLoadConcumer,
+ ExtendedMasterSecretExtension.shOnLoadAbsence,
+ null,
+ ExtendedMasterSecretExtension.emsStringize),
+
+ // extensions defined in RFC draft-ietf-tokbind-negotiation
+ TOKEN_BINDING (0x0018, "token_binding "),
+
+ // extensions defined in RFC 7924
+ CACHED_INFO (0x0019, "cached_info"),
+
+ // extensions defined in RFC 4507/5077
+ SESSION_TICKET (0x0023, "session_ticket"),
+
+ // extensions defined in TLS 1.3
+ CH_EARLY_DATA (0x002A, "early_data"),
+ EE_EARLY_DATA (0x002A, "early_data"),
+ NST_EARLY_DATA (0x002A, "early_data"),
+
+ CH_SUPPORTED_VERSIONS (0x002B, "supported_versions",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ SupportedVersionsExtension.chNetworkProducer,
+ SupportedVersionsExtension.chOnLoadConcumer,
+ null,
+ null,
+ SupportedVersionsExtension.chStringize),
+ SH_SUPPORTED_VERSIONS (0x002B, "supported_versions",
+ SSLHandshake.SERVER_HELLO,
+ // and HelloRetryRequest
+ ProtocolVersion.PROTOCOLS_OF_13,
+ SupportedVersionsExtension.shNetworkProducer,
+ SupportedVersionsExtension.shOnLoadConcumer,
+ null,
+ null,
+ SupportedVersionsExtension.shStringize),
+ HRR_SUPPORTED_VERSIONS (0x002B, "supported_versions",
+ SSLHandshake.HELLO_RETRY_REQUEST,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ SupportedVersionsExtension.hrrNetworkProducer,
+ SupportedVersionsExtension.hrrOnLoadConcumer,
+ null,
+ null,
+ SupportedVersionsExtension.hrrStringize),
+ MH_SUPPORTED_VERSIONS (0x002B, "supported_versions",
+ SSLHandshake.MESSAGE_HASH,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ SupportedVersionsExtension.hrrReproducer,
+ null, null, null,
+ SupportedVersionsExtension.hrrStringize),
+
+ CH_COOKIE (0x002C, "cookie",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ CookieExtension.chNetworkProducer,
+ CookieExtension.chOnLoadConcumer,
+ null,
+ CookieExtension.chOnTradeConsumer,
+ CookieExtension.cookieStringize),
+ HRR_COOKIE (0x002C, "cookie",
+ SSLHandshake.HELLO_RETRY_REQUEST,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ CookieExtension.hrrNetworkProducer,
+ CookieExtension.hrrOnLoadConcumer,
+ null, null,
+ CookieExtension.cookieStringize),
+ MH_COOKIE (0x002C, "cookie",
+ SSLHandshake.MESSAGE_HASH,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ CookieExtension.hrrNetworkReproducer,
+ null, null, null,
+ CookieExtension.cookieStringize),
+
+ PSK_KEY_EXCHANGE_MODES (0x002D, "psk_key_exchange_modes",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ PskKeyExchangeModesExtension.chNetworkProducer,
+ PskKeyExchangeModesExtension.chOnLoadConsumer,
+ null, null, null),
+ CERTIFICATE_AUTHORITIES (0x002F, "certificate_authorities"),
+ OID_FILTERS (0x0030, "oid_filters"),
+ POST_HANDSHAKE_AUTH (0x0030, "post_handshake_auth"),
+
+ CH_KEY_SHARE (0x0033, "key_share",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ KeyShareExtension.chNetworkProducer,
+ KeyShareExtension.chOnLoadConcumer,
+ null, null,
+ KeyShareExtension.chStringize),
+ SH_KEY_SHARE (0x0033, "key_share",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ KeyShareExtension.shNetworkProducer,
+ KeyShareExtension.shOnLoadConcumer,
+ KeyShareExtension.shOnLoadAbsence,
+ null,
+ KeyShareExtension.shStringize),
+ HRR_KEY_SHARE (0x0033, "key_share",
+ SSLHandshake.HELLO_RETRY_REQUEST,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ KeyShareExtension.hrrNetworkProducer,
+ KeyShareExtension.hrrOnLoadConcumer,
+ null, null,
+ KeyShareExtension.hrrStringize),
+ MH_KEY_SHARE (0x0033, "key_share",
+ SSLHandshake.MESSAGE_HASH,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ KeyShareExtension.hrrNetworkReproducer,
+ null, null, null,
+ KeyShareExtension.hrrStringize),
+
+ // Extensions defined in RFC 5746
+ CH_RENEGOTIATION_INFO (0xff01, "renegotiation_info",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ RenegoInfoExtension.chNetworkProducer,
+ RenegoInfoExtension.chOnLoadConcumer,
+ RenegoInfoExtension.chOnLoadAbsence,
+ null,
+ RenegoInfoExtension.rniStringize),
+ SH_RENEGOTIATION_INFO (0xff01, "renegotiation_info",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_TO_12,
+ RenegoInfoExtension.shNetworkProducer,
+ RenegoInfoExtension.shOnLoadConcumer,
+ RenegoInfoExtension.shOnLoadAbsence,
+ null,
+ RenegoInfoExtension.rniStringize),
+
+ // TLS 1.3 PSK extension must be last
+ CH_PRE_SHARED_KEY (0x0029, "pre_shared_key",
+ SSLHandshake.CLIENT_HELLO,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ PreSharedKeyExtension.chNetworkProducer,
+ PreSharedKeyExtension.chOnLoadConsumer,
+ PreSharedKeyExtension.chOnLoadAbsence,
+ PreSharedKeyExtension.chOnTradeConsumer,
+ null),
+ SH_PRE_SHARED_KEY (0x0029, "pre_shared_key",
+ SSLHandshake.SERVER_HELLO,
+ ProtocolVersion.PROTOCOLS_OF_13,
+ PreSharedKeyExtension.shNetworkProducer,
+ PreSharedKeyExtension.shOnLoadConsumer,
+ PreSharedKeyExtension.shOnLoadAbsence,
+ null, null);
+
+ final int id;
+ final SSLHandshake handshakeType;
+ final String name;
+ final ProtocolVersion[] supportedProtocols;
+ final HandshakeProducer networkProducer;
+ final ExtensionConsumer onLoadConcumer;
+ final HandshakeAbsence onLoadAbsence;
+ final HandshakeConsumer onTradeConsumer;
+ final SSLStringize stringize;
+
+ // known but unsupported extension
+ private SSLExtension(int id, String name) {
+ this.id = id;
+ this.handshakeType = SSLHandshake.NOT_APPLICABLE;
+ this.name = name;
+ this.supportedProtocols = new ProtocolVersion[0];
+ this.networkProducer = null;
+ this.onLoadConcumer = null;
+ this.onLoadAbsence = null;
+ this.onTradeConsumer = null;
+ this.stringize = null;
+ }
+
+ // supported extension
+ private SSLExtension(int id, String name, SSLHandshake handshakeType,
+ ProtocolVersion[] supportedProtocols,
+ HandshakeProducer producer,
+ ExtensionConsumer onLoadConcumer, HandshakeAbsence onLoadAbsence,
+ HandshakeConsumer onTradeConsumer, SSLStringize stringize) {
+
+ this.id = id;
+ this.handshakeType = handshakeType;
+ this.name = name;
+ this.supportedProtocols = supportedProtocols;
+ this.networkProducer = producer;
+ this.onLoadConcumer = onLoadConcumer;
+ this.onLoadAbsence = onLoadAbsence;
+ this.onTradeConsumer = onTradeConsumer;
+ this.stringize = stringize;
+ }
+
+ static SSLExtension valueOf(SSLHandshake handshakeType, int extensionType) {
+ for (SSLExtension ext : SSLExtension.values()) {
+ if (ext.id == extensionType &&
+ ext.handshakeType == handshakeType) {
+ return ext;
+ }
+ }
+
+ return null;
+ }
+
+ static boolean isConsumable(int extensionType) {
+ for (SSLExtension ext : SSLExtension.values()) {
+ if (ext.id == extensionType &&
+ ext.onLoadConcumer != null) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ public byte[] produce(ConnectionContext context,
+ HandshakeMessage message) throws IOException {
+ if (networkProducer != null) {
+ return networkProducer.produce(context, message);
+ } else {
+ throw new UnsupportedOperationException(
+ "Not yet supported extension producing.");
+ }
+ }
+
+ public void consumeOnLoad(ConnectionContext context,
+ HandshakeMessage message, ByteBuffer buffer) throws IOException {
+ if (onLoadConcumer != null) {
+ onLoadConcumer.consume(context, message, buffer);
+ } else {
+ throw new UnsupportedOperationException(
+ "Not yet supported extension loading.");
+ }
+ }
+
+ public void consumeOnTrade(ConnectionContext context,
+ HandshakeMessage message) throws IOException {
+ if (onTradeConsumer != null) {
+ onTradeConsumer.consume(context, message);
+ } else {
+ throw new UnsupportedOperationException(
+ "Not yet supported extension processing.");
+ }
+ }
+
+ void absent(ConnectionContext context,
+ HandshakeMessage message) throws IOException {
+ if (onLoadAbsence != null) {
+ onLoadAbsence.absent(context, message);
+ } else {
+ throw new UnsupportedOperationException(
+ "Not yet supported extension absence processing.");
+ }
+ }
+
+ public boolean isAvailable(ProtocolVersion protocolVersion) {
+ /*
+ for (ProtocolVersion pv : supportedProtocols) {
+ if (pv == protocolVersion) {
+ return true;
+ }
+ }
+ */
+ for (int i = 0; i < supportedProtocols.length; i++) {
+ if (supportedProtocols[i] == protocolVersion) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+ @Override
+ public String toString(ByteBuffer byteBuffer) {
+ MessageFormat messageFormat = new MessageFormat(
+ "\"{0} ({1})\": '{'\n" +
+ "{2}\n" +
+ "'}'",
+ Locale.ENGLISH);
+
+ String extData;
+ if (stringize == null) {
+ HexDumpEncoder hexEncoder = new HexDumpEncoder();
+ String encoded = hexEncoder.encode(byteBuffer.duplicate());
+ extData = encoded;
+ } else {
+ extData = stringize.toString(byteBuffer);
+ }
+
+ Object[] messageFields = {
+ this.name,
+ this.id,
+ Utilities.indent(extData)
+ };
+
+ return messageFormat.format(messageFields);
+ }
+
+ //////////////////////////////////////////////////////
+ // Nested extension, consumer and producer interfaces.
+
+ static interface ExtensionConsumer {
+ void consume(ConnectionContext context,
+ HandshakeMessage message, ByteBuffer buffer) throws IOException;
+ }
+
+ /**
+ * A (transparent) specification of extension data.
+ *
+ * This interface contains no methods or constants. Its only purpose is to
+ * group all extension data. All extension data should implement this
+ * interface if the data is expected to handle in the following handshake
+ * processes.
+ */
+ static interface SSLExtensionSpec {
+ // blank
+ }
+
+ // Default enabled client extensions.
+ static final class ClientExtensions {
+ static final Collection<SSLExtension> defaults;
+
+ static {
+ Collection<SSLExtension> extensions = new LinkedList<>();
+ for (SSLExtension extension : SSLExtension.values()) {
+ if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE) {
+ extensions.add(extension);
+ }
+ }
+
+ // Switch off SNI extention?
+ boolean enableExtension =
+ Utilities.getBooleanProperty("jsse.enableSNIExtension", true);
+ if (!enableExtension) {
+ extensions.remove(CH_SERVER_NAME);
+ }
+
+ // To switch off the max_fragment_length extension.
+ enableExtension =
+ Utilities.getBooleanProperty("jsse.enableMFLExtension", false);
+ if (!enableExtension) {
+ extensions.remove(CH_MAX_FRAGMENT_LENGTH);
+ }
+
+// enableExtension = Utilities.getBooleanProperty(
+// "jdk.tls.client.enableStatusRequestExtension", true);
+// if (!enableExtension) {
+// extensions.remove(CH_STATUS_REQUEST);
+// extensions.remove(CR_STATUS_REQUEST);
+// extensions.remove(CT_STATUS_REQUEST);
+//
+// extensions.remove(CH_STATUS_REQUEST_V2);
+// }
+
+ if (!SSLConfiguration.useExtendedMasterSecret) {
+ extensions.remove(CH_EXTENDED_MASTER_SECRET);
+ }
+
+ defaults = Collections.unmodifiableCollection(extensions);
+ }
+ }
+
+ // Default enabled server extensions.
+ static final class ServerExtensions {
+ static final Collection<SSLExtension> defaults;
+
+ static {
+ Collection<SSLExtension> extensions = new LinkedList<>();
+ for (SSLExtension extension : SSLExtension.values()) {
+ if (extension.handshakeType != SSLHandshake.NOT_APPLICABLE) {
+ extensions.add(extension);
+ }
+ }
+
+/*
+ // Switch off SNI extention?
+ boolean enableExtension =
+ Utilities.getBooleanProperty("jsse.enableSNIExtension", true);
+ if (!enableExtension) {
+ extensions.remove(CH_SERVER_NAME);
+ extensions.remove(SH_SERVER_NAME);
+ extensions.remove(EE_SERVER_NAME);
+ }
+
+ // To switch off the max_fragment_length extension.
+ enableExtension =
+ Utilities.getBooleanProperty("jsse.enableMFLExtension", false);
+ if (!enableExtension) {
+ extensions.remove(CH_MAX_FRAGMENT_LENGTH);
+ extensions.remove(SH_MAX_FRAGMENT_LENGTH);
+ extensions.remove(EE_MAX_FRAGMENT_LENGTH);
+ }
+*/
+
+// enableExtension = Utilities.getBooleanProperty(
+// "jdk.tls.server.enableStatusRequestExtension", true);
+// if (!enableExtension) {
+// extensions.remove(CH_STATUS_REQUEST);
+// extensions.remove(SH_STATUS_REQUEST);
+// extensions.remove(CR_STATUS_REQUEST);
+// extensions.remove(CT_STATUS_REQUEST);
+//
+// extensions.remove(SH_STATUS_REQUEST_V2);
+// }
+
+/*
+ if (!SSLConfiguration.useExtendedMasterSecret) {
+ extensions.remove(CH_EXTENDED_MASTER_SECRET);
+ extensions.remove(SH_EXTENDED_MASTER_SECRET);
+ }
+*/
+ defaults = Collections.unmodifiableCollection(extensions);
+ }
+ }
+}