Skip to content
This repository was archived by the owner on Feb 2, 2023. It is now read-only.

Commit 384445d

Browse files
omikhaltsovaYuri Nesterenko
authored andcommitted
8226374: Restrict TLS signature schemes and named groups
Reviewed-by: yan Backport-of: 316140f
1 parent a4794b2 commit 384445d

18 files changed

+803
-619
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ private static SSLPossession choosePossession(
10551055
// Don't select a signature scheme unless we will be able to
10561056
// produce a CertificateVerify message later
10571057
if (SignatureScheme.getPreferableAlgorithm(
1058+
hc.algorithmConstraints,
10581059
hc.peerRequestedSignatureSchemes,
10591060
ss, hc.negotiatedProtocol) == null) {
10601061

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,7 @@ private static SSLPossession choosePossession(HandshakeContext hc)
737737
// Don't select a signature scheme unless we will be able to
738738
// produce a CertificateVerify message later
739739
if (SignatureScheme.getPreferableAlgorithm(
740+
hc.algorithmConstraints,
740741
hc.peerRequestedSignatureSchemes,
741742
ss, hc.negotiatedProtocol) == null) {
742743

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ static final class T12CertificateVerifyMessage extends HandshakeMessage {
586586
// This happens in client side only.
587587
ClientHandshakeContext chc = (ClientHandshakeContext)context;
588588
this.signatureScheme = SignatureScheme.getPreferableAlgorithm(
589+
chc.algorithmConstraints,
589590
chc.peerRequestedSignatureSchemes,
590591
x509Possession,
591592
chc.negotiatedProtocol);
@@ -898,6 +899,7 @@ static final class T13CertificateVerifyMessage extends HandshakeMessage {
898899
super(context);
899900

900901
this.signatureScheme = SignatureScheme.getPreferableAlgorithm(
902+
context.algorithmConstraints,
901903
context.peerRequestedSignatureSchemes,
902904
x509Possession,
903905
context.negotiatedProtocol);

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@
3535
import static sun.security.ssl.CipherSuite.KeyExchange.*;
3636
import static sun.security.ssl.CipherSuite.MacAlg.*;
3737
import static sun.security.ssl.SSLCipher.*;
38-
import sun.security.ssl.NamedGroup.NamedGroupType;
39-
import static sun.security.ssl.NamedGroup.NamedGroupType.*;
38+
import sun.security.ssl.NamedGroup.NamedGroupSpec;
39+
import static sun.security.ssl.NamedGroup.NamedGroupSpec.*;
4040

4141
/**
4242
* Enum for SSL/(D)TLS cipher suites.
@@ -1125,12 +1125,12 @@ static enum KeyExchange {
11251125
// name of the key exchange algorithm, e.g. DHE_DSS
11261126
final String name;
11271127
final boolean allowed;
1128-
final NamedGroupType[] groupTypes;
1128+
final NamedGroupSpec[] groupTypes;
11291129
private final boolean alwaysAvailable;
11301130
private final boolean isAnonymous;
11311131

11321132
KeyExchange(String name, boolean allowed,
1133-
boolean isAnonymous, NamedGroupType... groupTypes) {
1133+
boolean isAnonymous, NamedGroupSpec... groupTypes) {
11341134
this.name = name;
11351135
this.groupTypes = groupTypes;
11361136
this.allowed = allowed;
@@ -1144,8 +1144,8 @@ boolean isAvailable() {
11441144
return true;
11451145
}
11461146

1147-
if (NamedGroupType.arrayContains(
1148-
groupTypes, NamedGroupType.NAMED_GROUP_ECDHE)) {
1147+
if (NamedGroupSpec.arrayContains(groupTypes,
1148+
NamedGroupSpec.NAMED_GROUP_ECDHE)) {
11491149
return (allowed && JsseJce.isEcAvailable());
11501150
} else {
11511151
return allowed;

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

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
import javax.crypto.spec.DHParameterSpec;
4242
import javax.crypto.spec.DHPublicKeySpec;
4343
import sun.security.action.GetPropertyAction;
44-
import sun.security.ssl.NamedGroup.NamedGroupType;
44+
import sun.security.ssl.NamedGroup.NamedGroupSpec;
4545
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
4646
import sun.security.ssl.X509Authentication.X509Possession;
4747
import sun.security.util.KeyUtil;
@@ -76,7 +76,7 @@ public NamedGroup getNamedGroup() {
7676
static DHECredentials valueOf(NamedGroup ng,
7777
byte[] encodedPublic) throws IOException, GeneralSecurityException {
7878

79-
if (ng.type != NamedGroupType.NAMED_GROUP_FFDHE) {
79+
if (ng.spec != NamedGroupSpec.NAMED_GROUP_FFDHE) {
8080
throw new RuntimeException(
8181
"Credentials decoding: Not FFDHE named group");
8282
}
@@ -85,11 +85,7 @@ static DHECredentials valueOf(NamedGroup ng,
8585
return null;
8686
}
8787

88-
DHParameterSpec params = (DHParameterSpec)ng.getParameterSpec();
89-
if (params == null) {
90-
return null;
91-
}
92-
88+
DHParameterSpec params = (DHParameterSpec)ng.keAlgParamSpec;
9389
KeyFactory kf = KeyFactory.getInstance("DiffieHellman");
9490
DHPublicKeySpec spec = new DHPublicKeySpec(
9591
new BigInteger(1, encodedPublic),
@@ -110,9 +106,7 @@ static final class DHEPossession implements NamedGroupPossession {
110106
try {
111107
KeyPairGenerator kpg =
112108
KeyPairGenerator.getInstance("DiffieHellman");
113-
DHParameterSpec params =
114-
(DHParameterSpec)namedGroup.getParameterSpec();
115-
kpg.initialize(params, random);
109+
kpg.initialize(namedGroup.keAlgParamSpec, random);
116110
KeyPair kp = generateDHKeyPair(kpg);
117111
if (kp == null) {
118112
throw new RuntimeException("Could not generate DH keypair");
@@ -321,11 +315,10 @@ public SSLPossession createPossession(HandshakeContext context) {
321315
(context.clientRequestedNamedGroups != null) &&
322316
(!context.clientRequestedNamedGroups.isEmpty())) {
323317
preferableNamedGroup =
324-
SupportedGroups.getPreferredGroup(
325-
context.negotiatedProtocol,
318+
SupportedGroups.getPreferredGroup(context.negotiatedProtocol,
326319
context.algorithmConstraints,
327-
new NamedGroupType [] {
328-
NamedGroupType.NAMED_GROUP_FFDHE },
320+
new NamedGroupSpec [] {
321+
NamedGroupSpec.NAMED_GROUP_FFDHE },
329322
context.clientRequestedNamedGroups);
330323
if (preferableNamedGroup != null) {
331324
return new DHEPossession(preferableNamedGroup,

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class DHServerKeyExchangeMessage extends HandshakeMessage {
125125
Signature signer = null;
126126
if (useExplicitSigAlgorithm) {
127127
signatureScheme = SignatureScheme.getPreferableAlgorithm(
128+
shc.algorithmConstraints,
128129
shc.peerRequestedSignatureSchemes,
129130
x509Possession,
130131
shc.negotiatedProtocol);

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

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,14 @@
3636
import java.security.PublicKey;
3737
import java.security.SecureRandom;
3838
import java.security.interfaces.ECPublicKey;
39-
import java.security.spec.ECGenParameterSpec;
4039
import java.security.spec.ECParameterSpec;
4140
import java.security.spec.ECPoint;
4241
import java.security.spec.ECPublicKeySpec;
4342
import java.util.EnumSet;
4443
import javax.crypto.KeyAgreement;
4544
import javax.crypto.SecretKey;
4645
import javax.net.ssl.SSLHandshakeException;
47-
import sun.security.ssl.NamedGroup.NamedGroupType;
46+
import sun.security.ssl.NamedGroup.NamedGroupSpec;
4847
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
4948
import sun.security.ssl.X509Authentication.X509Credentials;
5049
import sun.security.ssl.X509Authentication.X509Possession;
@@ -88,7 +87,7 @@ public NamedGroup getNamedGroup() {
8887
static ECDHECredentials valueOf(NamedGroup namedGroup,
8988
byte[] encodedPoint) throws IOException, GeneralSecurityException {
9089

91-
if (namedGroup.type != NamedGroupType.NAMED_GROUP_ECDHE) {
90+
if (namedGroup.spec != NamedGroupSpec.NAMED_GROUP_ECDHE) {
9291
throw new RuntimeException(
9392
"Credentials decoding: Not ECDHE named group");
9493
}
@@ -98,11 +97,7 @@ static ECDHECredentials valueOf(NamedGroup namedGroup,
9897
}
9998

10099
ECParameterSpec parameters =
101-
ECUtil.getECParameterSpec(null, namedGroup.oid);
102-
if (parameters == null) {
103-
return null;
104-
}
105-
100+
(ECParameterSpec)namedGroup.keAlgParamSpec;
106101
ECPoint point = ECUtil.decodePoint(
107102
encodedPoint, parameters.getCurve());
108103
KeyFactory factory = KeyFactory.getInstance("EC");
@@ -120,9 +115,7 @@ static final class ECDHEPossession implements NamedGroupPossession {
120115
ECDHEPossession(NamedGroup namedGroup, SecureRandom random) {
121116
try {
122117
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
123-
ECGenParameterSpec params =
124-
(ECGenParameterSpec)namedGroup.getParameterSpec();
125-
kpg.initialize(params, random);
118+
kpg.initialize(namedGroup.keAlgParamSpec, random);
126119
KeyPair kp = kpg.generateKeyPair();
127120
privateKey = kp.getPrivate();
128121
publicKey = (ECPublicKey)kp.getPublic();
@@ -248,17 +241,17 @@ public SSLPossession createPossession(HandshakeContext context) {
248241
preferableNamedGroup = SupportedGroups.getPreferredGroup(
249242
context.negotiatedProtocol,
250243
context.algorithmConstraints,
251-
new NamedGroupType[] {
252-
NamedGroupType.NAMED_GROUP_ECDHE,
253-
NamedGroupType.NAMED_GROUP_XDH },
244+
new NamedGroupSpec[] {
245+
NamedGroupSpec.NAMED_GROUP_ECDHE,
246+
NamedGroupSpec.NAMED_GROUP_XDH },
254247
context.clientRequestedNamedGroups);
255248
} else {
256249
preferableNamedGroup = SupportedGroups.getPreferredGroup(
257250
context.negotiatedProtocol,
258251
context.algorithmConstraints,
259-
new NamedGroupType[] {
260-
NamedGroupType.NAMED_GROUP_ECDHE,
261-
NamedGroupType.NAMED_GROUP_XDH });
252+
new NamedGroupSpec[] {
253+
NamedGroupSpec.NAMED_GROUP_ECDHE,
254+
NamedGroupSpec.NAMED_GROUP_XDH });
262255
}
263256

264257
if (preferableNamedGroup != null) {
@@ -308,7 +301,8 @@ private SSLKeyDerivation createServerKeyDerivation(
308301

309302
NamedGroup ng = NamedGroup.valueOf(params);
310303
if (ng == null) {
311-
// unlikely, have been checked during cipher suite negotiation.
304+
// unlikely, have been checked during cipher suite
305+
// negotiation.
312306
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
313307
"Unsupported EC server cert for ECDH key exchange");
314308
}
@@ -480,7 +474,7 @@ public SSLKeyDerivation createKeyDerivation(
480474
}
481475

482476
String alg;
483-
switch (namedGroup.type) {
477+
switch (namedGroup.spec) {
484478
case NAMED_GROUP_ECDHE:
485479
alg = "ECDH";
486480
break;

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import java.security.SignatureException;
3939
import java.text.MessageFormat;
4040
import java.util.Locale;
41+
import sun.security.ssl.NamedGroup.NamedGroupSpec;
4142
import sun.security.ssl.SSLHandshake.HandshakeMessage;
4243
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
4344
import sun.security.ssl.X509Authentication.X509Credentials;
@@ -110,13 +111,18 @@ class ECDHServerKeyExchangeMessage extends HandshakeMessage {
110111

111112
// Find the NamedGroup used for the ephemeral keys.
112113
namedGroup = namedGroupPossession.getNamedGroup();
114+
if ((namedGroup == null) || (!namedGroup.isAvailable)) {
115+
// unlikely
116+
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
117+
"Missing or improper named group: " + namedGroup);
118+
}
119+
113120
publicPoint = namedGroup.encodePossessionPublicKey(
114121
namedGroupPossession);
115-
116-
if ((namedGroup == null) || (namedGroup.oid == null) ) {
122+
if (publicPoint == null) {
117123
// unlikely
118124
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
119-
"Missing Named Group");
125+
"Missing public point for named group: " + namedGroup);
120126
}
121127

122128
if (x509Possession == null) {
@@ -130,6 +136,7 @@ class ECDHServerKeyExchangeMessage extends HandshakeMessage {
130136
Signature signer = null;
131137
if (useExplicitSigAlgorithm) {
132138
signatureScheme = SignatureScheme.getPreferableAlgorithm(
139+
shc.algorithmConstraints,
133140
shc.peerRequestedSignatureSchemes,
134141
x509Possession,
135142
shc.negotiatedProtocol);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
import sun.security.ssl.SSLExtension.ExtensionConsumer;
3535
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
3636
import sun.security.ssl.SSLHandshake.HandshakeMessage;
37-
import sun.security.ssl.NamedGroup.NamedGroupType;
37+
import sun.security.ssl.NamedGroup.NamedGroupSpec;
3838

3939
/**
4040
* Pack of the "ec_point_formats" extensions [RFC 4492].
@@ -179,7 +179,7 @@ public byte[] produce(ConnectionContext context,
179179
// Produce the extension.
180180
//
181181
// produce the extension only if EC cipher suite is activated.
182-
if (NamedGroupType.NAMED_GROUP_ECDHE.isSupported(
182+
if (NamedGroupSpec.NAMED_GROUP_ECDHE.isSupported(
183183
chc.activeCipherSuites)) {
184184
// We are using uncompressed ECPointFormat only at present.
185185
byte[] extData = new byte[] {0x01, 0x00};

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

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@
4646
import javax.net.ssl.SNIServerName;
4747
import javax.net.ssl.SSLHandshakeException;
4848
import javax.security.auth.x500.X500Principal;
49-
import sun.security.ssl.NamedGroup.NamedGroupType;
50-
import static sun.security.ssl.NamedGroup.NamedGroupType.*;
49+
import sun.security.ssl.NamedGroup.NamedGroupSpec;
50+
import static sun.security.ssl.NamedGroup.NamedGroupSpec.*;
5151
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
5252

5353
abstract class HandshakeContext implements ConnectionContext {
@@ -284,8 +284,8 @@ private static List<ProtocolVersion> getActiveProtocols(
284284
}
285285

286286
boolean found = false;
287-
Map<NamedGroupType, Boolean> cachedStatus =
288-
new EnumMap<>(NamedGroupType.class);
287+
Map<NamedGroupSpec, Boolean> cachedStatus =
288+
new EnumMap<>(NamedGroupSpec.class);
289289
for (CipherSuite suite : enabledCipherSuites) {
290290
if (suite.isAvailable() && suite.supports(protocol)) {
291291
if (isActivatable(suite,
@@ -324,8 +324,8 @@ private static List<CipherSuite> getActiveCipherSuites(
324324

325325
List<CipherSuite> suites = new LinkedList<>();
326326
if (enabledProtocols != null && !enabledProtocols.isEmpty()) {
327-
Map<NamedGroupType, Boolean> cachedStatus =
328-
new EnumMap<>(NamedGroupType.class);
327+
Map<NamedGroupSpec, Boolean> cachedStatus =
328+
new EnumMap<>(NamedGroupSpec.class);
329329
for (CipherSuite suite : enabledCipherSuites) {
330330
if (!suite.isAvailable()) {
331331
continue;
@@ -510,7 +510,7 @@ void setVersion(ProtocolVersion protocolVersion) {
510510

511511
private static boolean isActivatable(CipherSuite suite,
512512
AlgorithmConstraints algorithmConstraints,
513-
Map<NamedGroupType, Boolean> cachedStatus) {
513+
Map<NamedGroupSpec, Boolean> cachedStatus) {
514514

515515
if (algorithmConstraints.permits(
516516
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) {
@@ -521,8 +521,8 @@ private static boolean isActivatable(CipherSuite suite,
521521

522522
// Is at least one of the group types available?
523523
boolean groupAvailable, retval = false;
524-
NamedGroupType[] groupTypes = suite.keyExchange.groupTypes;
525-
for (NamedGroupType groupType : groupTypes) {
524+
NamedGroupSpec[] groupTypes = suite.keyExchange.groupTypes;
525+
for (NamedGroupSpec groupType : groupTypes) {
526526
if (groupType != NAMED_GROUP_NONE) {
527527
Boolean checkedStatus = cachedStatus.get(groupType);
528528
if (checkedStatus == null) {

0 commit comments

Comments
 (0)