Path: blob/master/src/java.base/share/classes/sun/security/ssl/CertSignAlgsExtension.java
41159 views
/*1* Copyright (c) 2018, 2020, 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.util.List;30import sun.security.ssl.SSLExtension.ExtensionConsumer;31import sun.security.ssl.SSLHandshake.HandshakeMessage;32import sun.security.ssl.SignatureAlgorithmsExtension.SignatureSchemesSpec;3334/**35* Pack of the "signature_algorithms_cert" extensions.36*/37final class CertSignAlgsExtension {38static final HandshakeProducer chNetworkProducer =39new CHCertSignatureSchemesProducer();40static final ExtensionConsumer chOnLoadConsumer =41new CHCertSignatureSchemesConsumer();42static final HandshakeConsumer chOnTradeConsumer =43new CHCertSignatureSchemesUpdate();4445static final HandshakeProducer crNetworkProducer =46new CRCertSignatureSchemesProducer();47static final ExtensionConsumer crOnLoadConsumer =48new CRCertSignatureSchemesConsumer();49static final HandshakeConsumer crOnTradeConsumer =50new CRCertSignatureSchemesUpdate();5152static final SSLStringizer ssStringizer =53new CertSignatureSchemesStringizer();5455private static final56class CertSignatureSchemesStringizer implements SSLStringizer {57@Override58public String toString(HandshakeContext hc, ByteBuffer buffer) {59try {60return (new SignatureSchemesSpec(hc, buffer))61.toString();62} catch (IOException ioe) {63// For debug logging only, so please swallow exceptions.64return ioe.getMessage();65}66}67}6869/**70* Network data producer of a "signature_algorithms_cert" extension in71* the ClientHello handshake message.72*/73private static final74class CHCertSignatureSchemesProducer implements HandshakeProducer {75// Prevent instantiation of this class.76private CHCertSignatureSchemesProducer() {77// blank78}7980@Override81public byte[] produce(ConnectionContext context,82HandshakeMessage message) throws IOException {83// The producing happens in client side only.84ClientHandshakeContext chc = (ClientHandshakeContext)context;8586// Is it a supported and enabled extension?87if (!chc.sslConfig.isAvailable(88SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT)) {89if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {90SSLLogger.fine(91"Ignore unavailable " +92"signature_algorithms_cert extension");93}9495return null; // ignore the extension96}9798// Produce the extension.99if (chc.localSupportedSignAlgs == null) {100chc.localSupportedSignAlgs =101SignatureScheme.getSupportedAlgorithms(102chc.sslConfig,103chc.algorithmConstraints, chc.activeProtocols);104}105106int vectorLen = SignatureScheme.sizeInRecord() *107chc.localSupportedSignAlgs.size();108byte[] extData = new byte[vectorLen + 2];109ByteBuffer m = ByteBuffer.wrap(extData);110Record.putInt16(m, vectorLen);111for (SignatureScheme ss : chc.localSupportedSignAlgs) {112Record.putInt16(m, ss.id);113}114115// Update the context.116chc.handshakeExtensions.put(117SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT,118new SignatureSchemesSpec(chc.localSupportedSignAlgs));119120return extData;121}122}123124/**125* Network data consumer of a "signature_algorithms_cert" extension in126* the ClientHello handshake message.127*/128private static final129class CHCertSignatureSchemesConsumer implements ExtensionConsumer {130// Prevent instantiation of this class.131private CHCertSignatureSchemesConsumer() {132// blank133}134135@Override136public void consume(ConnectionContext context,137HandshakeMessage message, ByteBuffer buffer) throws IOException {138// The consuming happens in server side only.139ServerHandshakeContext shc = (ServerHandshakeContext)context;140141// Is it a supported and enabled extension?142if (!shc.sslConfig.isAvailable(143SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT)) {144if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {145SSLLogger.fine(146"Ignore unavailable " +147"signature_algorithms_cert extension");148}149return; // ignore the extension150}151152// Parse the extension.153SignatureSchemesSpec spec = new SignatureSchemesSpec(shc, buffer);154155// Update the context.156shc.handshakeExtensions.put(157SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT, spec);158159// No impact on session resumption.160}161}162163/**164* After session creation consuming of a "signature_algorithms_cert"165* extension in the ClientHello handshake message.166*/167private static final class CHCertSignatureSchemesUpdate168implements HandshakeConsumer {169// Prevent instantiation of this class.170private CHCertSignatureSchemesUpdate() {171// blank172}173174@Override175public void consume(ConnectionContext context,176HandshakeMessage message) throws IOException {177// The consuming happens in server side only.178ServerHandshakeContext shc = (ServerHandshakeContext)context;179180SignatureSchemesSpec spec = (SignatureSchemesSpec)181shc.handshakeExtensions.get(182SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT);183if (spec == null) {184// Ignore, no signature_algorithms_cert extension requested.185return;186}187188// update the context189List<SignatureScheme> schemes =190SignatureScheme.getSupportedAlgorithms(191shc.sslConfig,192shc.algorithmConstraints, shc.negotiatedProtocol,193spec.signatureSchemes);194shc.peerRequestedCertSignSchemes = schemes;195shc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes);196197if (!shc.isResumption && shc.negotiatedProtocol.useTLS13PlusSpec()) {198if (shc.sslConfig.clientAuthType !=199ClientAuthType.CLIENT_AUTH_NONE) {200shc.handshakeProducers.putIfAbsent(201SSLHandshake.CERTIFICATE_REQUEST.id,202SSLHandshake.CERTIFICATE_REQUEST);203}204shc.handshakeProducers.put(SSLHandshake.CERTIFICATE.id,205SSLHandshake.CERTIFICATE);206shc.handshakeProducers.putIfAbsent(207SSLHandshake.CERTIFICATE_VERIFY.id,208SSLHandshake.CERTIFICATE_VERIFY);209}210}211}212213/**214* Network data producer of a "signature_algorithms_cert" extension in215* the CertificateRequest handshake message.216*/217private static final218class CRCertSignatureSchemesProducer implements HandshakeProducer {219// Prevent instantiation of this class.220private CRCertSignatureSchemesProducer() {221// blank222}223224@Override225public byte[] produce(ConnectionContext context,226HandshakeMessage message) throws IOException {227// The producing happens in server side only.228ServerHandshakeContext shc = (ServerHandshakeContext)context;229230// Is it a supported and enabled extension?231if (!shc.sslConfig.isAvailable(232SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT)) {233if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {234SSLLogger.fine(235"Ignore unavailable " +236"signature_algorithms_cert extension");237}238return null; // ignore the extension239}240241// Produce the extension.242List<SignatureScheme> sigAlgs =243SignatureScheme.getSupportedAlgorithms(244shc.sslConfig,245shc.algorithmConstraints,246List.of(shc.negotiatedProtocol));247248int vectorLen = SignatureScheme.sizeInRecord() * sigAlgs.size();249byte[] extData = new byte[vectorLen + 2];250ByteBuffer m = ByteBuffer.wrap(extData);251Record.putInt16(m, vectorLen);252for (SignatureScheme ss : sigAlgs) {253Record.putInt16(m, ss.id);254}255256// Update the context.257shc.handshakeExtensions.put(258SSLExtension.CR_SIGNATURE_ALGORITHMS_CERT,259new SignatureSchemesSpec(shc.localSupportedSignAlgs));260261return extData;262}263}264265/**266* Network data consumer of a "signature_algorithms_cert" extension in267* the CertificateRequest handshake message.268*/269private static final270class CRCertSignatureSchemesConsumer implements ExtensionConsumer {271// Prevent instantiation of this class.272private CRCertSignatureSchemesConsumer() {273// blank274}275@Override276public void consume(ConnectionContext context,277HandshakeMessage message, ByteBuffer buffer) throws IOException {278// The consuming happens in client side only.279ClientHandshakeContext chc = (ClientHandshakeContext)context;280281// Is it a supported and enabled extension?282if (!chc.sslConfig.isAvailable(283SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT)) {284if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {285SSLLogger.fine(286"Ignore unavailable " +287"signature_algorithms_cert extension");288}289return; // ignore the extension290}291292// Parse the extension.293SignatureSchemesSpec spec = new SignatureSchemesSpec(chc, buffer);294295// Update the context.296chc.handshakeExtensions.put(297SSLExtension.CR_SIGNATURE_ALGORITHMS_CERT, spec);298299// No impact on session resumption.300}301}302303/**304* After session creation consuming of a "signature_algorithms_cert"305* extension in the CertificateRequest handshake message.306*/307private static final class CRCertSignatureSchemesUpdate308implements HandshakeConsumer {309// Prevent instantiation of this class.310private CRCertSignatureSchemesUpdate() {311// blank312}313314@Override315public void consume(ConnectionContext context,316HandshakeMessage message) throws IOException {317// The consuming happens in client side only.318ClientHandshakeContext chc = (ClientHandshakeContext)context;319320SignatureSchemesSpec spec = (SignatureSchemesSpec)321chc.handshakeExtensions.get(322SSLExtension.CR_SIGNATURE_ALGORITHMS_CERT);323if (spec == null) {324// Ignore, no "signature_algorithms_cert" extension requested.325return;326}327328// update the context329List<SignatureScheme> schemes =330SignatureScheme.getSupportedAlgorithms(331chc.sslConfig,332chc.algorithmConstraints, chc.negotiatedProtocol,333spec.signatureSchemes);334chc.peerRequestedCertSignSchemes = schemes;335chc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes);336}337}338}339340341