blob: c1a90a04e8a00ceb314c988a25463bc4a9531807 [file] [log] [blame]
/*
* Copyright (c) 2018, 2020, 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 SSLStringizer {
// Extensions defined in RFC 6066
CH_SERVER_NAME (0x0000, "server_name",
SSLHandshake.CLIENT_HELLO,
ProtocolVersion.PROTOCOLS_TO_13,
ServerNameExtension.chNetworkProducer,
ServerNameExtension.chOnLoadConsumer,
null,
null,
null,
ServerNameExtension.chStringizer),
SH_SERVER_NAME (0x0000, "server_name",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
ServerNameExtension.shNetworkProducer,
ServerNameExtension.shOnLoadConsumer,
null,
null,
null,
ServerNameExtension.shStringizer),
EE_SERVER_NAME (0x0000, "server_name",
SSLHandshake.ENCRYPTED_EXTENSIONS,
ProtocolVersion.PROTOCOLS_OF_13,
ServerNameExtension.eeNetworkProducer,
ServerNameExtension.eeOnLoadConsumer,
null,
null,
null,
ServerNameExtension.shStringizer),
CH_MAX_FRAGMENT_LENGTH (0x0001, "max_fragment_length",
SSLHandshake.CLIENT_HELLO,
ProtocolVersion.PROTOCOLS_TO_13,
MaxFragExtension.chNetworkProducer,
MaxFragExtension.chOnLoadConsumer,
null,
null,
null,
MaxFragExtension.maxFragLenStringizer),
SH_MAX_FRAGMENT_LENGTH (0x0001, "max_fragment_length",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
MaxFragExtension.shNetworkProducer,
MaxFragExtension.shOnLoadConsumer,
null,
MaxFragExtension.shOnTradeConsumer,
null,
MaxFragExtension.maxFragLenStringizer),
EE_MAX_FRAGMENT_LENGTH (0x0001, "max_fragment_length",
SSLHandshake.ENCRYPTED_EXTENSIONS,
ProtocolVersion.PROTOCOLS_OF_13,
MaxFragExtension.eeNetworkProducer,
MaxFragExtension.eeOnLoadConsumer,
null,
MaxFragExtension.eeOnTradeConsumer,
null,
MaxFragExtension.maxFragLenStringizer),
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,
null,
CertStatusExtension.certStatusReqStringizer),
SH_STATUS_REQUEST (0x0005, "status_request",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
CertStatusExtension.shNetworkProducer,
CertStatusExtension.shOnLoadConsumer,
null,
null,
null,
CertStatusExtension.certStatusReqStringizer),
CR_STATUS_REQUEST (0x0005, "status_request"),
CT_STATUS_REQUEST (0x0005, "status_request",
SSLHandshake.CERTIFICATE,
ProtocolVersion.PROTOCOLS_OF_13,
CertStatusExtension.ctNetworkProducer,
CertStatusExtension.ctOnLoadConsumer,
null,
null,
null,
CertStatusExtension.certStatusRespStringizer),
// 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.chOnLoadConsumer,
null,
null,
SupportedGroupsExtension.chOnTradAbsence,
SupportedGroupsExtension.sgsStringizer),
EE_SUPPORTED_GROUPS (0x000A, "supported_groups",
SSLHandshake.ENCRYPTED_EXTENSIONS,
ProtocolVersion.PROTOCOLS_OF_13,
SupportedGroupsExtension.eeNetworkProducer,
SupportedGroupsExtension.eeOnLoadConsumer,
null,
null,
null,
SupportedGroupsExtension.sgsStringizer),
CH_EC_POINT_FORMATS (0x000B, "ec_point_formats",
SSLHandshake.CLIENT_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
ECPointFormatsExtension.chNetworkProducer,
ECPointFormatsExtension.chOnLoadConsumer,
null,
null,
null,
ECPointFormatsExtension.epfStringizer),
SH_EC_POINT_FORMATS (0x000B, "ec_point_formats",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
null, // not use of the producer
ECPointFormatsExtension.shOnLoadConsumer,
null,
null,
null,
ECPointFormatsExtension.epfStringizer),
// 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.chOnLoadConsumer,
SignatureAlgorithmsExtension.chOnLoadAbsence,
SignatureAlgorithmsExtension.chOnTradeConsumer,
SignatureAlgorithmsExtension.chOnTradeAbsence,
SignatureAlgorithmsExtension.ssStringizer),
CR_SIGNATURE_ALGORITHMS (0x000D, "signature_algorithms",
SSLHandshake.CERTIFICATE_REQUEST,
ProtocolVersion.PROTOCOLS_OF_13,
SignatureAlgorithmsExtension.crNetworkProducer,
SignatureAlgorithmsExtension.crOnLoadConsumer,
SignatureAlgorithmsExtension.crOnLoadAbsence,
SignatureAlgorithmsExtension.crOnTradeConsumer,
null,
SignatureAlgorithmsExtension.ssStringizer),
CH_SIGNATURE_ALGORITHMS_CERT (0x0032, "signature_algorithms_cert",
SSLHandshake.CLIENT_HELLO,
ProtocolVersion.PROTOCOLS_12_13,
CertSignAlgsExtension.chNetworkProducer,
CertSignAlgsExtension.chOnLoadConsumer,
null,
CertSignAlgsExtension.chOnTradeConsumer,
null,
CertSignAlgsExtension.ssStringizer),
CR_SIGNATURE_ALGORITHMS_CERT (0x0032, "signature_algorithms_cert",
SSLHandshake.CERTIFICATE_REQUEST,
ProtocolVersion.PROTOCOLS_OF_13,
CertSignAlgsExtension.crNetworkProducer,
CertSignAlgsExtension.crOnLoadConsumer,
null,
CertSignAlgsExtension.crOnTradeConsumer,
null,
CertSignAlgsExtension.ssStringizer),
// 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.chOnLoadConsumer,
AlpnExtension.chOnLoadAbsence,
null,
null,
AlpnExtension.alpnStringizer),
SH_ALPN (0x0010, "application_layer_protocol_negotiation",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
AlpnExtension.shNetworkProducer,
AlpnExtension.shOnLoadConsumer,
AlpnExtension.shOnLoadAbsence,
null,
null,
AlpnExtension.alpnStringizer),
EE_ALPN (0x0010, "application_layer_protocol_negotiation",
SSLHandshake.ENCRYPTED_EXTENSIONS,
ProtocolVersion.PROTOCOLS_OF_13,
AlpnExtension.shNetworkProducer,
AlpnExtension.shOnLoadConsumer,
AlpnExtension.shOnLoadAbsence,
null,
null,
AlpnExtension.alpnStringizer),
// 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,
null,
CertStatusExtension.certStatusReqV2Stringizer),
SH_STATUS_REQUEST_V2 (0x0011, "status_request_v2",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
CertStatusExtension.shV2NetworkProducer,
CertStatusExtension.shV2OnLoadConsumer,
null,
null,
null,
CertStatusExtension.certStatusReqV2Stringizer),
// 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_TO_12,
ExtendedMasterSecretExtension.chNetworkProducer,
ExtendedMasterSecretExtension.chOnLoadConsumer,
ExtendedMasterSecretExtension.chOnLoadAbsence,
null,
null,
ExtendedMasterSecretExtension.emsStringizer),
SH_EXTENDED_MASTER_SECRET (0x0017, "extended_master_secret",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
ExtendedMasterSecretExtension.shNetworkProducer,
ExtendedMasterSecretExtension.shOnLoadConsumer,
ExtendedMasterSecretExtension.shOnLoadAbsence,
null,
null,
ExtendedMasterSecretExtension.emsStringizer),
// 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_TO_13,
SupportedVersionsExtension.chNetworkProducer,
SupportedVersionsExtension.chOnLoadConsumer,
null,
null,
null,
SupportedVersionsExtension.chStringizer),
SH_SUPPORTED_VERSIONS (0x002B, "supported_versions",
SSLHandshake.SERVER_HELLO,
// and HelloRetryRequest
ProtocolVersion.PROTOCOLS_OF_13,
SupportedVersionsExtension.shNetworkProducer,
SupportedVersionsExtension.shOnLoadConsumer,
null,
null,
null,
SupportedVersionsExtension.shStringizer),
HRR_SUPPORTED_VERSIONS (0x002B, "supported_versions",
SSLHandshake.HELLO_RETRY_REQUEST,
ProtocolVersion.PROTOCOLS_OF_13,
SupportedVersionsExtension.hrrNetworkProducer,
SupportedVersionsExtension.hrrOnLoadConsumer,
null,
null,
null,
SupportedVersionsExtension.hrrStringizer),
MH_SUPPORTED_VERSIONS (0x002B, "supported_versions",
SSLHandshake.MESSAGE_HASH,
ProtocolVersion.PROTOCOLS_OF_13,
SupportedVersionsExtension.hrrReproducer,
null, null, null,
null,
SupportedVersionsExtension.hrrStringizer),
CH_COOKIE (0x002C, "cookie",
SSLHandshake.CLIENT_HELLO,
ProtocolVersion.PROTOCOLS_OF_13,
CookieExtension.chNetworkProducer,
CookieExtension.chOnLoadConsumer,
null,
CookieExtension.chOnTradeConsumer,
null,
CookieExtension.cookieStringizer),
HRR_COOKIE (0x002C, "cookie",
SSLHandshake.HELLO_RETRY_REQUEST,
ProtocolVersion.PROTOCOLS_OF_13,
CookieExtension.hrrNetworkProducer,
CookieExtension.hrrOnLoadConsumer,
null, null,
null,
CookieExtension.cookieStringizer),
MH_COOKIE (0x002C, "cookie",
SSLHandshake.MESSAGE_HASH,
ProtocolVersion.PROTOCOLS_OF_13,
CookieExtension.hrrNetworkReproducer,
null, null, null,
null,
CookieExtension.cookieStringizer),
PSK_KEY_EXCHANGE_MODES (0x002D, "psk_key_exchange_modes",
SSLHandshake.CLIENT_HELLO,
ProtocolVersion.PROTOCOLS_OF_13,
PskKeyExchangeModesExtension.chNetworkProducer,
PskKeyExchangeModesExtension.chOnLoadConsumer,
PskKeyExchangeModesExtension.chOnLoadAbsence,
null,
PskKeyExchangeModesExtension.chOnTradeAbsence,
PskKeyExchangeModesExtension.pkemStringizer),
CH_CERTIFICATE_AUTHORITIES (0x002F, "certificate_authorities",
SSLHandshake.CLIENT_HELLO,
ProtocolVersion.PROTOCOLS_OF_13,
CertificateAuthoritiesExtension.chNetworkProducer,
CertificateAuthoritiesExtension.chOnLoadConsumer,
null,
null,
null,
CertificateAuthoritiesExtension.ssStringizer),
CR_CERTIFICATE_AUTHORITIES (0x002F, "certificate_authorities",
SSLHandshake.CERTIFICATE_REQUEST,
ProtocolVersion.PROTOCOLS_OF_13,
CertificateAuthoritiesExtension.crNetworkProducer,
CertificateAuthoritiesExtension.crOnLoadConsumer,
null,
null,
null,
CertificateAuthoritiesExtension.ssStringizer),
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.chOnLoadConsumer,
null,
null,
KeyShareExtension.chOnTradAbsence,
KeyShareExtension.chStringizer),
SH_KEY_SHARE (0x0033, "key_share",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_OF_13,
KeyShareExtension.shNetworkProducer,
KeyShareExtension.shOnLoadConsumer,
KeyShareExtension.shOnLoadAbsence,
null,
null,
KeyShareExtension.shStringizer),
HRR_KEY_SHARE (0x0033, "key_share",
SSLHandshake.HELLO_RETRY_REQUEST,
ProtocolVersion.PROTOCOLS_OF_13,
KeyShareExtension.hrrNetworkProducer,
KeyShareExtension.hrrOnLoadConsumer,
null, null, null,
KeyShareExtension.hrrStringizer),
MH_KEY_SHARE (0x0033, "key_share",
SSLHandshake.MESSAGE_HASH,
ProtocolVersion.PROTOCOLS_OF_13,
KeyShareExtension.hrrNetworkReproducer,
null, null, null, null,
KeyShareExtension.hrrStringizer),
// Extensions defined in RFC 5746
CH_RENEGOTIATION_INFO (0xff01, "renegotiation_info",
SSLHandshake.CLIENT_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
RenegoInfoExtension.chNetworkProducer,
RenegoInfoExtension.chOnLoadConsumer,
RenegoInfoExtension.chOnLoadAbsence,
null,
null,
RenegoInfoExtension.rniStringizer),
SH_RENEGOTIATION_INFO (0xff01, "renegotiation_info",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_TO_12,
RenegoInfoExtension.shNetworkProducer,
RenegoInfoExtension.shOnLoadConsumer,
RenegoInfoExtension.shOnLoadAbsence,
null,
null,
RenegoInfoExtension.rniStringizer),
// 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,
PreSharedKeyExtension.chOnTradAbsence,
PreSharedKeyExtension.chStringizer),
SH_PRE_SHARED_KEY (0x0029, "pre_shared_key",
SSLHandshake.SERVER_HELLO,
ProtocolVersion.PROTOCOLS_OF_13,
PreSharedKeyExtension.shNetworkProducer,
PreSharedKeyExtension.shOnLoadConsumer,
PreSharedKeyExtension.shOnLoadAbsence,
null, null,
PreSharedKeyExtension.shStringizer);
final int id;
final SSLHandshake handshakeType;
final String name;
final ProtocolVersion[] supportedProtocols;
/*
* networkProducer: produces outbound handshake data.
*
* onLoadConsumer: parses inbound data. It may not be appropriate
* to act until all of the message inputs have
* been parsed. (e.g. parsing keyShares and choosing
* a local value without having seen the SupportedGroups
* extension.)
*
* onLoadAbsence: if a missing message needs special handling
* during the load phase.
*
* onTradeConsumer: act on the parsed message once all inbound data has
* been traded and parsed.
*
* onTradeAbsence: if a missing message needs special handling
* during the trade phase.
*/
final HandshakeProducer networkProducer;
final ExtensionConsumer onLoadConsumer;
final HandshakeAbsence onLoadAbsence;
final HandshakeConsumer onTradeConsumer;
final HandshakeAbsence onTradeAbsence;
final SSLStringizer stringizer;
// 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.onLoadConsumer = null;
this.onLoadAbsence = null;
this.onTradeConsumer = null;
this.onTradeAbsence = null;
this.stringizer = null;
}
// supported extension
private SSLExtension(int id, String name, SSLHandshake handshakeType,
ProtocolVersion[] supportedProtocols,
HandshakeProducer producer,
ExtensionConsumer onLoadConsumer, HandshakeAbsence onLoadAbsence,
HandshakeConsumer onTradeConsumer, HandshakeAbsence onTradeAbsence,
SSLStringizer stringize) {
this.id = id;
this.handshakeType = handshakeType;
this.name = name;
this.supportedProtocols = supportedProtocols;
this.networkProducer = producer;
this.onLoadConsumer = onLoadConsumer;
this.onLoadAbsence = onLoadAbsence;
this.onTradeConsumer = onTradeConsumer;
this.onTradeAbsence = onTradeAbsence;
this.stringizer = 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 String nameOf(int extensionType) {
for (SSLExtension ext : SSLExtension.values()) {
if (ext.id == extensionType) {
return ext.name;
}
}
return "unknown extension";
}
static boolean isConsumable(int extensionType) {
for (SSLExtension ext : SSLExtension.values()) {
if (ext.id == extensionType &&
ext.onLoadConsumer != 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 (onLoadConsumer != null) {
onLoadConsumer.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 absentOnLoad(ConnectionContext context,
HandshakeMessage message) throws IOException {
if (onLoadAbsence != null) {
onLoadAbsence.absent(context, message);
} else {
throw new UnsupportedOperationException(
"Not yet supported extension absence processing.");
}
}
void absentOnTrade(ConnectionContext context,
HandshakeMessage message) throws IOException {
if (onTradeAbsence != null) {
onTradeAbsence.absent(context, message);
} else {
throw new UnsupportedOperationException(
"Not yet supported extension absence processing.");
}
}
public boolean isAvailable(ProtocolVersion protocolVersion) {
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 (stringizer == null) {
HexDumpEncoder hexEncoder = new HexDumpEncoder();
String encoded = hexEncoder.encode(byteBuffer.duplicate());
extData = encoded;
} else {
extData = stringizer.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.
//
// Note that "jsse.enableMFLNExtension" is the CSR approved
// property name. However, "jsse.enableMFLExtension" was used
// in the original implementation. Temporarily, if either of
// 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);
}
// To switch on certificate_authorities extension in ClientHello.
//
// Note: Please be careful to enable this extension in ClientHello.
//
// In practice, if the server certificate cannot be validated by
// the underlying programs, the user may manually check the
// certificate in order to access the service. The certificate
// could be accepted manually, and the handshake continues. For
// example, the browsers provide the manual option to accept
// untrusted server certificate. If this extension is enabled in
// the ClientHello handshake message, and the server's certificate
// does not chain back to any of the CAs in the extension, then the
// server will terminate the handshake and close the connection.
// There is no chance for the client to perform the manual check.
// Therefore, enabling this extension in ClientHello may lead to
// unexpected compatibility issues for such cases.
//
// According to TLS 1.3 specification [RFC 8446] the maximum size
// of the certificate_authorities extension is 2^16 bytes. The
// maximum TLS record size is 2^14 bytes. If the handshake
// message is bigger than maximum TLS record size, it should be
// splitted into several records. In fact, some server
// implementations do not allow ClientHello messages bigger than
// the maximum TLS record size and will immediately abort the
// connection with a fatal alert. Therefore, if the client trusts
// too many certificate authorities, there may be unexpected
// interoperability issues.
//
// Furthermore, if the client trusts more CAs such that it exceeds
// the size limit of the extension, enabling this extension in
// client side does not really make sense any longer as there is
// no way to indicate the server certificate selection accurately.
//
// In general, a server does not use multiple certificates issued
// from different CAs. It is not expected to use this extension a
// 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);
}
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);
}
}
defaults = Collections.unmodifiableCollection(extensions);
}
}
}