|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package sun.security.ssl; |
|
|
|
import java.io.IOException; |
|
import java.nio.ByteBuffer; |
|
import java.util.List; |
|
import sun.security.ssl.SSLExtension.ExtensionConsumer; |
|
import sun.security.ssl.SSLHandshake.HandshakeMessage; |
|
import sun.security.ssl.SignatureAlgorithmsExtension.SignatureSchemesSpec; |
|
|
|
|
|
|
|
*/ |
|
final class CertSignAlgsExtension { |
|
static final HandshakeProducer chNetworkProducer = |
|
new CHCertSignatureSchemesProducer(); |
|
static final ExtensionConsumer chOnLoadConsumer = |
|
new CHCertSignatureSchemesConsumer(); |
|
static final HandshakeConsumer chOnTradeConsumer = |
|
new CHCertSignatureSchemesUpdate(); |
|
|
|
static final HandshakeProducer crNetworkProducer = |
|
new CRCertSignatureSchemesProducer(); |
|
static final ExtensionConsumer crOnLoadConsumer = |
|
new CRCertSignatureSchemesConsumer(); |
|
static final HandshakeConsumer crOnTradeConsumer = |
|
new CRCertSignatureSchemesUpdate(); |
|
|
|
static final SSLStringizer ssStringizer = |
|
new CertSignatureSchemesStringizer(); |
|
|
|
private static final |
|
class CertSignatureSchemesStringizer implements SSLStringizer { |
|
@Override |
|
public String toString(ByteBuffer buffer) { |
|
try { |
|
return (new SignatureSchemesSpec(buffer)).toString(); |
|
} catch (IOException ioe) { |
|
|
|
return ioe.getMessage(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static final |
|
class CHCertSignatureSchemesProducer implements HandshakeProducer { |
|
|
|
private CHCertSignatureSchemesProducer() { |
|
// blank |
|
} |
|
|
|
@Override |
|
public byte[] produce(ConnectionContext context, |
|
HandshakeMessage message) throws IOException { |
|
|
|
ClientHandshakeContext chc = (ClientHandshakeContext)context; |
|
|
|
|
|
if (!chc.sslConfig.isAvailable( |
|
SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT)) { |
|
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { |
|
SSLLogger.fine( |
|
"Ignore unavailable " + |
|
"signature_algorithms_cert extension"); |
|
} |
|
|
|
return null; |
|
} |
|
|
|
|
|
if (chc.localSupportedSignAlgs == null) { |
|
chc.localSupportedSignAlgs = |
|
SignatureScheme.getSupportedAlgorithms( |
|
chc.algorithmConstraints, chc.activeProtocols); |
|
} |
|
|
|
int vectorLen = SignatureScheme.sizeInRecord() * |
|
chc.localSupportedSignAlgs.size(); |
|
byte[] extData = new byte[vectorLen + 2]; |
|
ByteBuffer m = ByteBuffer.wrap(extData); |
|
Record.putInt16(m, vectorLen); |
|
for (SignatureScheme ss : chc.localSupportedSignAlgs) { |
|
Record.putInt16(m, ss.id); |
|
} |
|
|
|
|
|
chc.handshakeExtensions.put( |
|
SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT, |
|
new SignatureSchemesSpec(chc.localSupportedSignAlgs)); |
|
|
|
return extData; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static final |
|
class CHCertSignatureSchemesConsumer implements ExtensionConsumer { |
|
|
|
private CHCertSignatureSchemesConsumer() { |
|
// blank |
|
} |
|
|
|
@Override |
|
public void consume(ConnectionContext context, |
|
HandshakeMessage message, ByteBuffer buffer) throws IOException { |
|
|
|
ServerHandshakeContext shc = (ServerHandshakeContext)context; |
|
|
|
|
|
if (!shc.sslConfig.isAvailable( |
|
SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT)) { |
|
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { |
|
SSLLogger.fine( |
|
"Ignore unavailable " + |
|
"signature_algorithms_cert extension"); |
|
} |
|
return; |
|
} |
|
|
|
|
|
SignatureSchemesSpec spec; |
|
try { |
|
spec = new SignatureSchemesSpec(buffer); |
|
} catch (IOException ioe) { |
|
shc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe); |
|
return; |
|
} |
|
|
|
|
|
shc.handshakeExtensions.put( |
|
SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT, spec); |
|
|
|
// No impact on session resumption. |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static final class CHCertSignatureSchemesUpdate |
|
implements HandshakeConsumer { |
|
|
|
private CHCertSignatureSchemesUpdate() { |
|
// blank |
|
} |
|
|
|
@Override |
|
public void consume(ConnectionContext context, |
|
HandshakeMessage message) throws IOException { |
|
|
|
ServerHandshakeContext shc = (ServerHandshakeContext)context; |
|
|
|
SignatureSchemesSpec spec = (SignatureSchemesSpec) |
|
shc.handshakeExtensions.get( |
|
SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT); |
|
if (spec == null) { |
|
|
|
return; |
|
} |
|
|
|
|
|
List<SignatureScheme> schemes = |
|
SignatureScheme.getSupportedAlgorithms( |
|
shc.algorithmConstraints, shc.negotiatedProtocol, |
|
spec.signatureSchemes); |
|
shc.peerRequestedCertSignSchemes = schemes; |
|
shc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes); |
|
|
|
if (!shc.isResumption && shc.negotiatedProtocol.useTLS13PlusSpec()) { |
|
if (shc.sslConfig.clientAuthType != |
|
ClientAuthType.CLIENT_AUTH_NONE) { |
|
shc.handshakeProducers.putIfAbsent( |
|
SSLHandshake.CERTIFICATE_REQUEST.id, |
|
SSLHandshake.CERTIFICATE_REQUEST); |
|
} |
|
shc.handshakeProducers.put(SSLHandshake.CERTIFICATE.id, |
|
SSLHandshake.CERTIFICATE); |
|
shc.handshakeProducers.putIfAbsent( |
|
SSLHandshake.CERTIFICATE_VERIFY.id, |
|
SSLHandshake.CERTIFICATE_VERIFY); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static final |
|
class CRCertSignatureSchemesProducer implements HandshakeProducer { |
|
|
|
private CRCertSignatureSchemesProducer() { |
|
// blank |
|
} |
|
|
|
@Override |
|
public byte[] produce(ConnectionContext context, |
|
HandshakeMessage message) throws IOException { |
|
|
|
ServerHandshakeContext shc = (ServerHandshakeContext)context; |
|
|
|
|
|
if (!shc.sslConfig.isAvailable( |
|
SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT)) { |
|
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { |
|
SSLLogger.fine( |
|
"Ignore unavailable " + |
|
"signature_algorithms_cert extension"); |
|
} |
|
return null; |
|
} |
|
|
|
|
|
if (shc.localSupportedSignAlgs == null) { |
|
shc.localSupportedSignAlgs = |
|
SignatureScheme.getSupportedAlgorithms( |
|
shc.algorithmConstraints, shc.activeProtocols); |
|
} |
|
|
|
int vectorLen = SignatureScheme.sizeInRecord() * |
|
shc.localSupportedSignAlgs.size(); |
|
byte[] extData = new byte[vectorLen + 2]; |
|
ByteBuffer m = ByteBuffer.wrap(extData); |
|
Record.putInt16(m, vectorLen); |
|
for (SignatureScheme ss : shc.localSupportedSignAlgs) { |
|
Record.putInt16(m, ss.id); |
|
} |
|
|
|
|
|
shc.handshakeExtensions.put( |
|
SSLExtension.CR_SIGNATURE_ALGORITHMS_CERT, |
|
new SignatureSchemesSpec(shc.localSupportedSignAlgs)); |
|
|
|
return extData; |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static final |
|
class CRCertSignatureSchemesConsumer implements ExtensionConsumer { |
|
|
|
private CRCertSignatureSchemesConsumer() { |
|
// blank |
|
} |
|
@Override |
|
public void consume(ConnectionContext context, |
|
HandshakeMessage message, ByteBuffer buffer) throws IOException { |
|
|
|
ClientHandshakeContext chc = (ClientHandshakeContext)context; |
|
|
|
|
|
if (!chc.sslConfig.isAvailable( |
|
SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT)) { |
|
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) { |
|
SSLLogger.fine( |
|
"Ignore unavailable " + |
|
"signature_algorithms_cert extension"); |
|
} |
|
return; |
|
} |
|
|
|
|
|
SignatureSchemesSpec spec; |
|
try { |
|
spec = new SignatureSchemesSpec(buffer); |
|
} catch (IOException ioe) { |
|
chc.conContext.fatal(Alert.UNEXPECTED_MESSAGE, ioe); |
|
return; |
|
} |
|
|
|
|
|
chc.handshakeExtensions.put( |
|
SSLExtension.CR_SIGNATURE_ALGORITHMS_CERT, spec); |
|
|
|
// No impact on session resumption. |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
*/ |
|
private static final class CRCertSignatureSchemesUpdate |
|
implements HandshakeConsumer { |
|
|
|
private CRCertSignatureSchemesUpdate() { |
|
// blank |
|
} |
|
|
|
@Override |
|
public void consume(ConnectionContext context, |
|
HandshakeMessage message) throws IOException { |
|
|
|
ClientHandshakeContext chc = (ClientHandshakeContext)context; |
|
|
|
SignatureSchemesSpec spec = (SignatureSchemesSpec) |
|
chc.handshakeExtensions.get( |
|
SSLExtension.CR_SIGNATURE_ALGORITHMS_CERT); |
|
if (spec == null) { |
|
|
|
return; |
|
} |
|
|
|
|
|
List<SignatureScheme> schemes = |
|
SignatureScheme.getSupportedAlgorithms( |
|
chc.algorithmConstraints, chc.negotiatedProtocol, |
|
spec.signatureSchemes); |
|
chc.peerRequestedCertSignSchemes = schemes; |
|
chc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes); |
|
} |
|
} |
|
} |