Skip to content

Commit b91c927

Browse files
committed
8349583: Add mechanism to disable signature schemes based on their TLS scope
Backport-of: 9c06dcb4396c3307d625663d92c0e11d794a56ea
1 parent 669026a commit b91c927

21 files changed

+1047
-348
lines changed

src/java.base/share/classes/sun/security/ssl/CertSignAlgsExtension.java

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,8 @@
2525

2626
package sun.security.ssl;
2727

28+
import static sun.security.ssl.SignatureScheme.CERTIFICATE_SCOPE;
29+
2830
import java.io.IOException;
2931
import java.nio.ByteBuffer;
3032
import java.util.List;
@@ -97,26 +99,27 @@ public byte[] produce(ConnectionContext context,
9799
}
98100

99101
// Produce the extension.
100-
if (chc.localSupportedSignAlgs == null) {
101-
chc.localSupportedSignAlgs =
102-
SignatureScheme.getSupportedAlgorithms(
103-
chc.sslConfig,
104-
chc.algorithmConstraints, chc.activeProtocols);
102+
if (chc.localSupportedCertSignAlgs == null) {
103+
chc.localSupportedCertSignAlgs =
104+
SignatureScheme.getSupportedAlgorithms(
105+
chc.sslConfig,
106+
chc.algorithmConstraints, chc.activeProtocols,
107+
CERTIFICATE_SCOPE);
105108
}
106109

107110
int vectorLen = SignatureScheme.sizeInRecord() *
108-
chc.localSupportedSignAlgs.size();
111+
chc.localSupportedCertSignAlgs.size();
109112
byte[] extData = new byte[vectorLen + 2];
110113
ByteBuffer m = ByteBuffer.wrap(extData);
111114
Record.putInt16(m, vectorLen);
112-
for (SignatureScheme ss : chc.localSupportedSignAlgs) {
115+
for (SignatureScheme ss : chc.localSupportedCertSignAlgs) {
113116
Record.putInt16(m, ss.id);
114117
}
115118

116119
// Update the context.
117120
chc.handshakeExtensions.put(
118121
SSLExtension.CH_SIGNATURE_ALGORITHMS_CERT,
119-
new SignatureSchemesSpec(chc.localSupportedSignAlgs));
122+
new SignatureSchemesSpec(chc.localSupportedCertSignAlgs));
120123

121124
return extData;
122125
}
@@ -191,7 +194,9 @@ public void consume(ConnectionContext context,
191194
SignatureScheme.getSupportedAlgorithms(
192195
shc.sslConfig,
193196
shc.algorithmConstraints, shc.negotiatedProtocol,
194-
spec.signatureSchemes);
197+
spec.signatureSchemes,
198+
CERTIFICATE_SCOPE);
199+
195200
shc.peerRequestedCertSignSchemes = schemes;
196201
shc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes);
197202

@@ -240,24 +245,28 @@ public byte[] produce(ConnectionContext context,
240245
}
241246

242247
// Produce the extension.
243-
List<SignatureScheme> sigAlgs =
244-
SignatureScheme.getSupportedAlgorithms(
245-
shc.sslConfig,
246-
shc.algorithmConstraints,
247-
List.of(shc.negotiatedProtocol));
248+
if (shc.localSupportedCertSignAlgs == null) {
249+
shc.localSupportedCertSignAlgs =
250+
SignatureScheme.getSupportedAlgorithms(
251+
shc.sslConfig,
252+
shc.algorithmConstraints,
253+
List.of(shc.negotiatedProtocol),
254+
CERTIFICATE_SCOPE);
255+
}
248256

249-
int vectorLen = SignatureScheme.sizeInRecord() * sigAlgs.size();
257+
int vectorLen = SignatureScheme.sizeInRecord()
258+
* shc.localSupportedCertSignAlgs.size();
250259
byte[] extData = new byte[vectorLen + 2];
251260
ByteBuffer m = ByteBuffer.wrap(extData);
252261
Record.putInt16(m, vectorLen);
253-
for (SignatureScheme ss : sigAlgs) {
262+
for (SignatureScheme ss : shc.localSupportedCertSignAlgs) {
254263
Record.putInt16(m, ss.id);
255264
}
256265

257266
// Update the context.
258267
shc.handshakeExtensions.put(
259268
SSLExtension.CR_SIGNATURE_ALGORITHMS_CERT,
260-
new SignatureSchemesSpec(shc.localSupportedSignAlgs));
269+
new SignatureSchemesSpec(shc.localSupportedCertSignAlgs));
261270

262271
return extData;
263272
}
@@ -331,7 +340,9 @@ public void consume(ConnectionContext context,
331340
SignatureScheme.getSupportedAlgorithms(
332341
chc.sslConfig,
333342
chc.algorithmConstraints, chc.negotiatedProtocol,
334-
spec.signatureSchemes);
343+
spec.signatureSchemes,
344+
CERTIFICATE_SCOPE);
345+
335346
chc.peerRequestedCertSignSchemes = schemes;
336347
chc.handshakeSession.setPeerSupportedSignatureAlgorithms(schemes);
337348
}

src/java.base/share/classes/sun/security/ssl/CertificateRequest.java

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,9 @@
2525

2626
package sun.security.ssl;
2727

28+
import static sun.security.ssl.SignatureScheme.CERTIFICATE_SCOPE;
29+
import static sun.security.ssl.SignatureScheme.HANDSHAKE_SCOPE;
30+
2831
import java.io.IOException;
2932
import java.nio.ByteBuffer;
3033
import java.security.PrivateKey;
@@ -396,7 +399,6 @@ public void consume(ConnectionContext context,
396399
iae);
397400
}
398401

399-
400402
if (clientAlias == null) {
401403
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
402404
SSLLogger.warning("No available client authentication");
@@ -632,15 +634,32 @@ private T12CertificateRequestProducer() {
632634
public byte[] produce(ConnectionContext context,
633635
HandshakeMessage message) throws IOException {
634636
// The producing happens in server side only.
635-
ServerHandshakeContext shc = (ServerHandshakeContext)context;
637+
ServerHandshakeContext shc = (ServerHandshakeContext) context;
638+
636639
if (shc.localSupportedSignAlgs == null) {
637640
shc.localSupportedSignAlgs =
638-
SignatureScheme.getSupportedAlgorithms(
639-
shc.sslConfig,
640-
shc.algorithmConstraints, shc.activeProtocols);
641+
SignatureScheme.getSupportedAlgorithms(
642+
shc.sslConfig,
643+
shc.algorithmConstraints, shc.activeProtocols,
644+
HANDSHAKE_SCOPE);
645+
}
646+
647+
if (shc.localSupportedCertSignAlgs == null) {
648+
shc.localSupportedCertSignAlgs =
649+
SignatureScheme.getSupportedAlgorithms(
650+
shc.sslConfig,
651+
shc.algorithmConstraints, shc.activeProtocols,
652+
CERTIFICATE_SCOPE);
641653
}
642654

643-
if (shc.localSupportedSignAlgs.isEmpty()) {
655+
// According to TLSv1.2 RFC, CertificateRequest message must
656+
// contain signature schemes supported for both:
657+
// handshake signatures and certificate signatures.
658+
List<SignatureScheme> certReqSignAlgs =
659+
new ArrayList<>(shc.localSupportedSignAlgs);
660+
certReqSignAlgs.retainAll(shc.localSupportedCertSignAlgs);
661+
662+
if (certReqSignAlgs.isEmpty()) {
644663
throw shc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
645664
"No supported signature algorithm");
646665
}
@@ -649,7 +668,7 @@ public byte[] produce(ConnectionContext context,
649668
shc.sslContext.getX509TrustManager().getAcceptedIssuers();
650669
T12CertificateRequestMessage crm = new T12CertificateRequestMessage(
651670
shc, caCerts, shc.negotiatedCipherSuite.keyExchange,
652-
shc.localSupportedSignAlgs);
671+
certReqSignAlgs);
653672
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
654673
SSLLogger.fine(
655674
"Produced CertificateRequest handshake message", crm);
@@ -730,19 +749,29 @@ public void consume(ConnectionContext context,
730749
chc.handshakeProducers.put(SSLHandshake.CERTIFICATE.id,
731750
SSLHandshake.CERTIFICATE);
732751

733-
List<SignatureScheme> sss =
752+
List<SignatureScheme> signAlgs =
734753
SignatureScheme.getSupportedAlgorithms(
735754
chc.sslConfig,
736755
chc.algorithmConstraints, chc.negotiatedProtocol,
737-
crm.algorithmIds);
738-
if (sss.isEmpty()) {
756+
crm.algorithmIds,
757+
HANDSHAKE_SCOPE);
758+
759+
List<SignatureScheme> signCertAlgs =
760+
SignatureScheme.getSupportedAlgorithms(
761+
chc.sslConfig,
762+
chc.algorithmConstraints, chc.negotiatedProtocol,
763+
crm.algorithmIds,
764+
CERTIFICATE_SCOPE);
765+
766+
if (signAlgs.isEmpty() || signCertAlgs.isEmpty()) {
739767
throw chc.conContext.fatal(Alert.HANDSHAKE_FAILURE,
740768
"No supported signature algorithm");
741769
}
742770

743-
chc.peerRequestedSignatureSchemes = sss;
744-
chc.peerRequestedCertSignSchemes = sss; // use the same schemes
745-
chc.handshakeSession.setPeerSupportedSignatureAlgorithms(sss);
771+
chc.peerRequestedSignatureSchemes = signAlgs;
772+
chc.peerRequestedCertSignSchemes = signCertAlgs;
773+
chc.handshakeSession.setPeerSupportedSignatureAlgorithms(signCertAlgs);
774+
746775
try {
747776
chc.peerSupportedAuthorities = crm.getAuthorities();
748777
} catch (IllegalArgumentException iae) {

src/java.base/share/classes/sun/security/ssl/HandshakeContext.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -72,7 +72,7 @@ abstract class HandshakeContext implements ConnectionContext {
7272
// consolidated parameters
7373
final List<ProtocolVersion> activeProtocols;
7474
final List<CipherSuite> activeCipherSuites;
75-
final AlgorithmConstraints algorithmConstraints;
75+
final SSLAlgorithmConstraints algorithmConstraints;
7676
final ProtocolVersion maximumActiveProtocol;
7777

7878
// output stream
@@ -127,6 +127,7 @@ abstract class HandshakeContext implements ConnectionContext {
127127

128128
// SignatureScheme
129129
List<SignatureScheme> localSupportedSignAlgs;
130+
List<SignatureScheme> localSupportedCertSignAlgs;
130131
List<SignatureScheme> peerRequestedSignatureSchemes;
131132
List<SignatureScheme> peerRequestedCertSignSchemes;
132133

src/java.base/share/classes/sun/security/ssl/PostHandshakeContext.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -43,7 +43,7 @@ final class PostHandshakeContext extends HandshakeContext {
4343
"Post-handshake not supported in " + negotiatedProtocol.name);
4444
}
4545

46-
this.localSupportedSignAlgs = new ArrayList<>(
46+
this.localSupportedCertSignAlgs = new ArrayList<>(
4747
context.conSession.getLocalSupportedSignatureSchemes());
4848

4949
// Add the potential post-handshake consumers.

src/java.base/share/classes/sun/security/ssl/PreSharedKeyExtension.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -42,6 +42,7 @@
4242
import sun.security.util.HexDumpEncoder;
4343

4444
import static sun.security.ssl.SSLExtension.*;
45+
import static sun.security.ssl.SignatureScheme.CERTIFICATE_SCOPE;
4546

4647
/**
4748
* Pack of the "pre_shared_key" extension.
@@ -440,15 +441,16 @@ private static boolean canRejoin(ClientHelloMessage clientHello,
440441
result = false;
441442
}
442443

443-
// Make sure that the server handshake context's localSupportedSignAlgs
444-
// field is populated. This is particularly important when
445-
// client authentication was used in an initial session, and it is
446-
// now being resumed.
447-
if (shc.localSupportedSignAlgs == null) {
448-
shc.localSupportedSignAlgs =
444+
// Make sure that the server handshake context's
445+
// localSupportedCertSignAlgs field is populated. This is particularly
446+
// important when client authentication was used in an initial session,
447+
// and it is now being resumed.
448+
if (shc.localSupportedCertSignAlgs == null) {
449+
shc.localSupportedCertSignAlgs =
449450
SignatureScheme.getSupportedAlgorithms(
450451
shc.sslConfig,
451-
shc.algorithmConstraints, shc.activeProtocols);
452+
shc.algorithmConstraints, shc.activeProtocols,
453+
CERTIFICATE_SCOPE);
452454
}
453455

454456
// Validate the required client authentication.
@@ -470,7 +472,7 @@ private static boolean canRejoin(ClientHelloMessage clientHello,
470472
Collection<SignatureScheme> sessionSigAlgs =
471473
s.getLocalSupportedSignatureSchemes();
472474
if (result &&
473-
!shc.localSupportedSignAlgs.containsAll(sessionSigAlgs)) {
475+
!shc.localSupportedCertSignAlgs.containsAll(sessionSigAlgs)) {
474476

475477
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
476478
SSLLogger.fine("Can't resume. Session uses different " +
@@ -664,7 +666,7 @@ public byte[] produce(ConnectionContext context,
664666
// Make sure the list of supported signature algorithms matches
665667
Collection<SignatureScheme> sessionSigAlgs =
666668
chc.resumingSession.getLocalSupportedSignatureSchemes();
667-
if (!chc.localSupportedSignAlgs.containsAll(sessionSigAlgs)) {
669+
if (!chc.localSupportedCertSignAlgs.containsAll(sessionSigAlgs)) {
668670
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
669671
SSLLogger.fine("Existing session uses different " +
670672
"signature algorithms");

0 commit comments

Comments
 (0)