Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/ssl/ExtendedMasterSecretExtension.java
38830 views
/*1* Copyright (c) 2017, Red Hat, Inc. and/or its affiliates.2* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation. Oracle designates this8* particular file as subject to the "Classpath" exception as provided9* by Oracle in the LICENSE file that accompanied this code.10*11* This code is distributed in the hope that it will be useful, but WITHOUT12* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or13* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License14* version 2 for more details (a copy is included in the LICENSE file that15* accompanied this code).16*17* You should have received a copy of the GNU General Public License version18* 2 along with this work; if not, write to the Free Software Foundation,19* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.20*21* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA22* or visit www.oracle.com if you need additional information or have any23* questions.24*/2526package sun.security.ssl;2728import java.io.IOException;29import java.nio.ByteBuffer;30import javax.net.ssl.SSLProtocolException;31import static sun.security.ssl.SSLExtension.CH_EXTENDED_MASTER_SECRET;32import sun.security.ssl.SSLExtension.ExtensionConsumer;33import static sun.security.ssl.SSLExtension.SH_EXTENDED_MASTER_SECRET;34import sun.security.ssl.SSLExtension.SSLExtensionSpec;35import sun.security.ssl.SSLHandshake.HandshakeMessage;3637/**38* Pack of the "extended_master_secret" extensions [RFC 7627].39*/40final class ExtendedMasterSecretExtension {41static final HandshakeProducer chNetworkProducer =42new CHExtendedMasterSecretProducer();43static final ExtensionConsumer chOnLoadConsumer =44new CHExtendedMasterSecretConsumer();45static final HandshakeAbsence chOnLoadAbsence =46new CHExtendedMasterSecretAbsence();4748static final HandshakeProducer shNetworkProducer =49new SHExtendedMasterSecretProducer();50static final ExtensionConsumer shOnLoadConsumer =51new SHExtendedMasterSecretConsumer();52static final HandshakeAbsence shOnLoadAbsence =53new SHExtendedMasterSecretAbsence();5455static final SSLStringizer emsStringizer =56new ExtendedMasterSecretStringizer();5758/**59* The "extended_master_secret" extension.60*/61static final class ExtendedMasterSecretSpec implements SSLExtensionSpec {62// A nominal object that does not holding any real renegotiation info.63static final ExtendedMasterSecretSpec NOMINAL =64new ExtendedMasterSecretSpec();6566private ExtendedMasterSecretSpec() {67// blank68}6970private ExtendedMasterSecretSpec(ByteBuffer m) throws IOException {71// Parse the extension.72if (m.hasRemaining()) {73throw new SSLProtocolException(74"Invalid extended_master_secret extension data: " +75"not empty");76}77}7879@Override80public String toString() {81return "<empty>";82}83}8485private static final86class ExtendedMasterSecretStringizer implements SSLStringizer {87@Override88public String toString(ByteBuffer buffer) {89try {90return (new ExtendedMasterSecretSpec(buffer)).toString();91} catch (IOException ioe) {92// For debug logging only, so please swallow exceptions.93return ioe.getMessage();94}95}96}9798/**99* Network data producer of a "extended_master_secret" extension in100* the ClientHello handshake message.101*/102private static final103class CHExtendedMasterSecretProducer implements HandshakeProducer {104// Prevent instantiation of this class.105private CHExtendedMasterSecretProducer() {106// blank107}108109@Override110public byte[] produce(ConnectionContext context,111HandshakeMessage message) throws IOException {112// The producing happens in client side only.113ClientHandshakeContext chc = (ClientHandshakeContext)context;114115// Is it a supported and enabled extension?116if (!chc.sslConfig.isAvailable(CH_EXTENDED_MASTER_SECRET) ||117!SSLConfiguration.useExtendedMasterSecret ||118!chc.conContext.protocolVersion.useTLS10PlusSpec()) {119if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {120SSLLogger.fine(121"Ignore unavailable extended_master_secret extension");122}123124return null;125}126127if (chc.handshakeSession == null ||128chc.handshakeSession.useExtendedMasterSecret) {129byte[] extData = new byte[0];130chc.handshakeExtensions.put(CH_EXTENDED_MASTER_SECRET,131ExtendedMasterSecretSpec.NOMINAL);132133return extData;134}135136return null;137}138}139140/**141* Network data producer of a "extended_master_secret" extension in142* the ServerHello handshake message.143*/144private static final145class CHExtendedMasterSecretConsumer implements ExtensionConsumer {146// Prevent instantiation of this class.147private CHExtendedMasterSecretConsumer() {148// blank149}150151@Override152public void consume(ConnectionContext context,153HandshakeMessage message, ByteBuffer buffer) throws IOException {154155// The consuming happens in server side only.156ServerHandshakeContext shc = (ServerHandshakeContext)context;157158// Is it a supported and enabled extension?159if (!shc.sslConfig.isAvailable(CH_EXTENDED_MASTER_SECRET) ||160!SSLConfiguration.useExtendedMasterSecret ||161!shc.negotiatedProtocol.useTLS10PlusSpec()) {162if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {163SSLLogger.fine("Ignore unavailable extension: " +164CH_EXTENDED_MASTER_SECRET.name);165}166return; // ignore the extension167}168169// Parse the extension.170ExtendedMasterSecretSpec spec;171try {172spec = new ExtendedMasterSecretSpec(buffer);173} catch (IOException ioe) {174throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);175}176177if (shc.isResumption && shc.resumingSession != null &&178!shc.resumingSession.useExtendedMasterSecret) {179// For abbreviated handshake request, If the original180// session did not use the "extended_master_secret"181// extension but the new ClientHello contains the182// extension, then the server MUST NOT perform the183// abbreviated handshake. Instead, it SHOULD continue184// with a full handshake.185shc.isResumption = false;186shc.resumingSession = null;187if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {188SSLLogger.fine(189"abort session resumption which did not use " +190"Extended Master Secret extension");191}192}193194// Update the context.195//196shc.handshakeExtensions.put(197CH_EXTENDED_MASTER_SECRET, ExtendedMasterSecretSpec.NOMINAL);198199// No impact on session resumption.200}201}202203/**204* The absence processing if a "extended_master_secret" extension is205* not present in the ClientHello handshake message.206*/207private static final208class CHExtendedMasterSecretAbsence implements HandshakeAbsence {209@Override210public void absent(ConnectionContext context,211HandshakeMessage message) throws IOException {212// The producing happens in server side only.213ServerHandshakeContext shc = (ServerHandshakeContext)context;214215// Is it a supported and enabled extension?216if (!shc.sslConfig.isAvailable(CH_EXTENDED_MASTER_SECRET) ||217!SSLConfiguration.useExtendedMasterSecret) {218if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {219SSLLogger.fine("Ignore unavailable extension: " +220CH_EXTENDED_MASTER_SECRET.name);221}222return; // ignore the extension223}224225if (shc.negotiatedProtocol.useTLS10PlusSpec() &&226!SSLConfiguration.allowLegacyMasterSecret) {227// For full handshake, if the server receives a ClientHello228// without the extension, it SHOULD abort the handshake if229// it does not wish to interoperate with legacy clients.230//231// As if extended master extension is required for full232// handshake, it MUST be used in abbreviated handshake too.233throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,234"Extended Master Secret extension is required");235}236237if (shc.isResumption && shc.resumingSession != null) {238if (shc.resumingSession.useExtendedMasterSecret) {239// For abbreviated handshake request, if the original240// session used the "extended_master_secret" extension241// but the new ClientHello does not contain it, the242// server MUST abort the abbreviated handshake.243throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,244"Missing Extended Master Secret extension " +245"on session resumption");246} else {247// For abbreviated handshake request, if neither the248// original session nor the new ClientHello uses the249// extension, the server SHOULD abort the handshake.250if (!SSLConfiguration.allowLegacyResumption) {251throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,252"Missing Extended Master Secret extension " +253"on session resumption");254} else { // Otherwise, continue with a full handshake.255shc.isResumption = false;256shc.resumingSession = null;257if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {258SSLLogger.fine(259"abort session resumption, " +260"missing Extended Master Secret extension");261}262}263}264}265}266}267268/**269* Network data producer of a "extended_master_secret" extension in270* the ServerHello handshake message.271*/272private static final273class SHExtendedMasterSecretProducer implements HandshakeProducer {274// Prevent instantiation of this class.275private SHExtendedMasterSecretProducer() {276// blank277}278279@Override280public byte[] produce(ConnectionContext context,281HandshakeMessage message) throws IOException {282// The producing happens in server side only.283ServerHandshakeContext shc = (ServerHandshakeContext)context;284285if (shc.handshakeSession.useExtendedMasterSecret) {286byte[] extData = new byte[0];287shc.handshakeExtensions.put(SH_EXTENDED_MASTER_SECRET,288ExtendedMasterSecretSpec.NOMINAL);289290return extData;291}292293return null;294}295}296297/**298* Network data consumer of a "extended_master_secret" extension in299* the ServerHello handshake message.300*/301private static final302class SHExtendedMasterSecretConsumer implements ExtensionConsumer {303// Prevent instantiation of this class.304private SHExtendedMasterSecretConsumer() {305// blank306}307308@Override309public void consume(ConnectionContext context,310HandshakeMessage message, ByteBuffer buffer) throws IOException {311// The producing happens in client side only.312ClientHandshakeContext chc = (ClientHandshakeContext)context;313314// In response to the client extended_master_secret extension315// request, which is mandatory for ClientHello message.316ExtendedMasterSecretSpec requstedSpec = (ExtendedMasterSecretSpec)317chc.handshakeExtensions.get(CH_EXTENDED_MASTER_SECRET);318if (requstedSpec == null) {319throw chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,320"Server sent the extended_master_secret " +321"extension improperly");322}323324// Parse the extension.325ExtendedMasterSecretSpec spec;326try {327spec = new ExtendedMasterSecretSpec(buffer);328} catch (IOException ioe) {329throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);330}331332if (chc.isResumption && chc.resumingSession != null &&333!chc.resumingSession.useExtendedMasterSecret) {334throw chc.conContext.fatal(Alert.UNSUPPORTED_EXTENSION,335"Server sent an unexpected extended_master_secret " +336"extension on session resumption");337}338339// Update the context.340chc.handshakeExtensions.put(341SH_EXTENDED_MASTER_SECRET, ExtendedMasterSecretSpec.NOMINAL);342343// No impact on session resumption.344}345}346347/**348* The absence processing if a "extended_master_secret" extension is349* not present in the ServerHello handshake message.350*/351private static final352class SHExtendedMasterSecretAbsence implements HandshakeAbsence {353@Override354public void absent(ConnectionContext context,355HandshakeMessage message) throws IOException {356// The producing happens in client side only.357ClientHandshakeContext chc = (ClientHandshakeContext)context;358359if (SSLConfiguration.useExtendedMasterSecret &&360!SSLConfiguration.allowLegacyMasterSecret) {361// For full handshake, if a client receives a ServerHello362// without the extension, it SHOULD abort the handshake if363// it does not wish to interoperate with legacy servers.364throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,365"Extended Master Secret extension is required");366}367368if (chc.isResumption && chc.resumingSession != null) {369if (chc.resumingSession.useExtendedMasterSecret) {370// For abbreviated handshake, if the original session used371// the "extended_master_secret" extension but the new372// ServerHello does not contain the extension, the client373// MUST abort the handshake.374throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,375"Missing Extended Master Secret extension " +376"on session resumption");377} else if (SSLConfiguration.useExtendedMasterSecret &&378!SSLConfiguration.allowLegacyResumption &&379chc.negotiatedProtocol.useTLS10PlusSpec()) {380// Unlikely, abbreviated handshake should be discarded.381throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,382"Extended Master Secret extension is required");383}384}385}386}387}388389390391