Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/security/ssl/CookieExtension.java
38830 views
/*1* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.security.ssl;2627import java.io.IOException;28import java.nio.ByteBuffer;29import java.text.MessageFormat;30import java.util.Locale;31import javax.net.ssl.SSLProtocolException;3233import sun.security.ssl.ClientHello.ClientHelloMessage;34import sun.security.ssl.SSLExtension.ExtensionConsumer;35import sun.security.ssl.SSLHandshake.HandshakeMessage;36import sun.security.ssl.SSLExtension.SSLExtensionSpec;37import sun.security.ssl.ServerHello.ServerHelloMessage;38import sun.misc.HexDumpEncoder;3940public class CookieExtension {41static final HandshakeProducer chNetworkProducer =42new CHCookieProducer();43static final ExtensionConsumer chOnLoadConsumer =44new CHCookieConsumer();45static final HandshakeConsumer chOnTradeConsumer =46new CHCookieUpdate();4748static final HandshakeProducer hrrNetworkProducer =49new HRRCookieProducer();50static final ExtensionConsumer hrrOnLoadConsumer =51new HRRCookieConsumer();5253static final HandshakeProducer hrrNetworkReproducer =54new HRRCookieReproducer();5556static final CookieStringizer cookieStringizer =57new CookieStringizer();5859/**60* The "cookie" extension.61*/62static class CookieSpec implements SSLExtensionSpec {63final byte[] cookie;6465private CookieSpec(ByteBuffer m) throws IOException {66// opaque cookie<1..2^16-1>;67if (m.remaining() < 3) {68throw new SSLProtocolException(69"Invalid cookie extension: insufficient data");70}7172this.cookie = Record.getBytes16(m);73}7475@Override76public String toString() {77MessageFormat messageFormat = new MessageFormat(78"\"cookie\": '{'\n" +79"{0}\n" +80"'}',", Locale.ENGLISH);81HexDumpEncoder hexEncoder = new HexDumpEncoder();82Object[] messageFields = {83Utilities.indent(hexEncoder.encode(cookie))84};8586return messageFormat.format(messageFields);87}88}8990private static final class CookieStringizer implements SSLStringizer {91@Override92public String toString(ByteBuffer buffer) {93try {94return (new CookieSpec(buffer)).toString();95} catch (IOException ioe) {96// For debug logging only, so please swallow exceptions.97return ioe.getMessage();98}99}100}101102private static final103class CHCookieProducer implements HandshakeProducer {104// Prevent instantiation of this class.105private CHCookieProducer() {106// blank107}108109@Override110public byte[] produce(ConnectionContext context,111HandshakeMessage message) throws IOException {112ClientHandshakeContext chc = (ClientHandshakeContext) context;113114// Is it a supported and enabled extension?115if (!chc.sslConfig.isAvailable(SSLExtension.CH_COOKIE)) {116if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {117SSLLogger.fine(118"Ignore unavailable cookie extension");119}120return null;121}122123// response to an HelloRetryRequest cookie124CookieSpec spec = (CookieSpec)chc.handshakeExtensions.get(125SSLExtension.HRR_COOKIE);126127if (spec != null &&128spec.cookie != null && spec.cookie.length != 0) {129byte[] extData = new byte[spec.cookie.length + 2];130ByteBuffer m = ByteBuffer.wrap(extData);131Record.putBytes16(m, spec.cookie);132return extData;133}134135return null;136}137}138139private static final140class CHCookieConsumer implements ExtensionConsumer {141// Prevent instantiation of this class.142private CHCookieConsumer() {143// blank144}145146@Override147public void consume(ConnectionContext context,148HandshakeMessage message, ByteBuffer buffer) throws IOException {149// The consuming happens in server side only.150ServerHandshakeContext shc = (ServerHandshakeContext)context;151152// Is it a supported and enabled extension?153if (!shc.sslConfig.isAvailable(SSLExtension.CH_COOKIE)) {154if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {155SSLLogger.fine(156"Ignore unavailable cookie extension");157}158return; // ignore the extension159}160161CookieSpec spec;162try {163spec = new CookieSpec(buffer);164} catch (IOException ioe) {165throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);166}167168shc.handshakeExtensions.put(SSLExtension.CH_COOKIE, spec);169170// No impact on session resumption.171//172// Note that the protocol version negotiation happens before the173// session resumption negotiation. And the session resumption174// negotiation depends on the negotiated protocol version.175}176}177178private static final179class CHCookieUpdate implements HandshakeConsumer {180// Prevent instantiation of this class.181private CHCookieUpdate() {182// blank183}184185@Override186public void consume(ConnectionContext context,187HandshakeMessage message) throws IOException {188// The consuming happens in server side only.189ServerHandshakeContext shc = (ServerHandshakeContext)context;190ClientHelloMessage clientHello = (ClientHelloMessage)message;191192CookieSpec spec = (CookieSpec)193shc.handshakeExtensions.get(SSLExtension.CH_COOKIE);194if (spec == null) {195// Ignore, no "cookie" extension requested.196return;197}198199HelloCookieManager hcm =200shc.sslContext.getHelloCookieManager(shc.negotiatedProtocol);201if (!hcm.isCookieValid(shc, clientHello, spec.cookie)) {202throw shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE,203"unrecognized cookie");204}205}206}207208private static final209class HRRCookieProducer implements HandshakeProducer {210// Prevent instantiation of this class.211private HRRCookieProducer() {212// blank213}214215@Override216public byte[] produce(ConnectionContext context,217HandshakeMessage message) throws IOException {218// The producing happens in server side only.219ServerHandshakeContext shc = (ServerHandshakeContext)context;220ServerHelloMessage hrrm = (ServerHelloMessage)message;221222// Is it a supported and enabled extension?223if (!shc.sslConfig.isAvailable(SSLExtension.HRR_COOKIE)) {224if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {225SSLLogger.fine(226"Ignore unavailable cookie extension");227}228return null;229}230231HelloCookieManager hcm =232shc.sslContext.getHelloCookieManager(shc.negotiatedProtocol);233234byte[] cookie = hcm.createCookie(shc, hrrm.clientHello);235236byte[] extData = new byte[cookie.length + 2];237ByteBuffer m = ByteBuffer.wrap(extData);238Record.putBytes16(m, cookie);239240return extData;241}242}243244private static final245class HRRCookieConsumer implements ExtensionConsumer {246// Prevent instantiation of this class.247private HRRCookieConsumer() {248// blank249}250251@Override252public void consume(ConnectionContext context,253HandshakeMessage message, ByteBuffer buffer) throws IOException {254// The consuming happens in client side only.255ClientHandshakeContext chc = (ClientHandshakeContext)context;256257// Is it a supported and enabled extension?258if (!chc.sslConfig.isAvailable(SSLExtension.HRR_COOKIE)) {259if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {260SSLLogger.fine(261"Ignore unavailable cookie extension");262}263return; // ignore the extension264}265266CookieSpec spec;267try {268spec = new CookieSpec(buffer);269} catch (IOException ioe) {270throw chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe);271}272273chc.handshakeExtensions.put(SSLExtension.HRR_COOKIE, spec);274}275}276277private static final278class HRRCookieReproducer implements HandshakeProducer {279// Prevent instantiation of this class.280private HRRCookieReproducer() {281// blank282}283284@Override285public byte[] produce(ConnectionContext context,286HandshakeMessage message) throws IOException {287// The producing happens in server side only.288ServerHandshakeContext shc = (ServerHandshakeContext) context;289290// Is it a supported and enabled extension?291if (!shc.sslConfig.isAvailable(SSLExtension.HRR_COOKIE)) {292if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {293SSLLogger.fine(294"Ignore unavailable cookie extension");295}296return null;297}298299// copy of the ClientHello cookie300CookieSpec spec = (CookieSpec)shc.handshakeExtensions.get(301SSLExtension.CH_COOKIE);302303if (spec != null &&304spec.cookie != null && spec.cookie.length != 0) {305byte[] extData = new byte[spec.cookie.length + 2];306ByteBuffer m = ByteBuffer.wrap(extData);307Record.putBytes16(m, spec.cookie);308return extData;309}310311return null;312}313}314}315316317