mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8226374: Restrict TLS signature schemes and named groups
Reviewed-by: mullan
This commit is contained in:
parent
de8ce983b3
commit
316140ff92
18 changed files with 810 additions and 626 deletions
|
@ -1034,6 +1034,7 @@ final class CertificateMessage {
|
|||
// Don't select a signature scheme unless we will be able to
|
||||
// produce a CertificateVerify message later
|
||||
if (SignatureScheme.getPreferableAlgorithm(
|
||||
hc.algorithmConstraints,
|
||||
hc.peerRequestedSignatureSchemes,
|
||||
ss, hc.negotiatedProtocol) == null) {
|
||||
|
||||
|
|
|
@ -736,6 +736,7 @@ final class CertificateRequest {
|
|||
// Don't select a signature scheme unless we will be able to
|
||||
// produce a CertificateVerify message later
|
||||
if (SignatureScheme.getPreferableAlgorithm(
|
||||
hc.algorithmConstraints,
|
||||
hc.peerRequestedSignatureSchemes,
|
||||
ss, hc.negotiatedProtocol) == null) {
|
||||
|
||||
|
|
|
@ -564,6 +564,7 @@ final class CertificateVerify {
|
|||
// This happens in client side only.
|
||||
ClientHandshakeContext chc = (ClientHandshakeContext)context;
|
||||
this.signatureScheme = SignatureScheme.getPreferableAlgorithm(
|
||||
chc.algorithmConstraints,
|
||||
chc.peerRequestedSignatureSchemes,
|
||||
x509Possession,
|
||||
chc.negotiatedProtocol);
|
||||
|
@ -865,6 +866,7 @@ final class CertificateVerify {
|
|||
super(context);
|
||||
|
||||
this.signatureScheme = SignatureScheme.getPreferableAlgorithm(
|
||||
context.algorithmConstraints,
|
||||
context.peerRequestedSignatureSchemes,
|
||||
x509Possession,
|
||||
context.negotiatedProtocol);
|
||||
|
|
|
@ -35,8 +35,8 @@ import static sun.security.ssl.CipherSuite.HashAlg.*;
|
|||
import static sun.security.ssl.CipherSuite.KeyExchange.*;
|
||||
import static sun.security.ssl.CipherSuite.MacAlg.*;
|
||||
import static sun.security.ssl.SSLCipher.*;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupType;
|
||||
import static sun.security.ssl.NamedGroup.NamedGroupType.*;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
import static sun.security.ssl.NamedGroup.NamedGroupSpec.*;
|
||||
|
||||
/**
|
||||
* Enum for SSL/(D)TLS cipher suites.
|
||||
|
@ -1125,12 +1125,12 @@ enum CipherSuite {
|
|||
// name of the key exchange algorithm, e.g. DHE_DSS
|
||||
final String name;
|
||||
final boolean allowed;
|
||||
final NamedGroupType[] groupTypes;
|
||||
final NamedGroupSpec[] groupTypes;
|
||||
private final boolean alwaysAvailable;
|
||||
private final boolean isAnonymous;
|
||||
|
||||
KeyExchange(String name, boolean allowed,
|
||||
boolean isAnonymous, NamedGroupType... groupTypes) {
|
||||
boolean isAnonymous, NamedGroupSpec... groupTypes) {
|
||||
this.name = name;
|
||||
this.groupTypes = groupTypes;
|
||||
this.allowed = allowed;
|
||||
|
@ -1144,8 +1144,8 @@ enum CipherSuite {
|
|||
return true;
|
||||
}
|
||||
|
||||
if (NamedGroupType.arrayContains(
|
||||
groupTypes, NamedGroupType.NAMED_GROUP_ECDHE)) {
|
||||
if (NamedGroupSpec.arrayContains(groupTypes,
|
||||
NamedGroupSpec.NAMED_GROUP_ECDHE)) {
|
||||
return (allowed && JsseJce.isEcAvailable());
|
||||
} else {
|
||||
return allowed;
|
||||
|
|
|
@ -41,7 +41,7 @@ import javax.crypto.interfaces.DHPublicKey;
|
|||
import javax.crypto.spec.DHParameterSpec;
|
||||
import javax.crypto.spec.DHPublicKeySpec;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupType;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
|
||||
import sun.security.ssl.X509Authentication.X509Possession;
|
||||
import sun.security.util.KeyUtil;
|
||||
|
@ -76,7 +76,7 @@ final class DHKeyExchange {
|
|||
static DHECredentials valueOf(NamedGroup ng,
|
||||
byte[] encodedPublic) throws IOException, GeneralSecurityException {
|
||||
|
||||
if (ng.type != NamedGroupType.NAMED_GROUP_FFDHE) {
|
||||
if (ng.spec != NamedGroupSpec.NAMED_GROUP_FFDHE) {
|
||||
throw new RuntimeException(
|
||||
"Credentials decoding: Not FFDHE named group");
|
||||
}
|
||||
|
@ -85,11 +85,7 @@ final class DHKeyExchange {
|
|||
return null;
|
||||
}
|
||||
|
||||
DHParameterSpec params = (DHParameterSpec)ng.getParameterSpec();
|
||||
if (params == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DHParameterSpec params = (DHParameterSpec)ng.keAlgParamSpec;
|
||||
KeyFactory kf = KeyFactory.getInstance("DiffieHellman");
|
||||
DHPublicKeySpec spec = new DHPublicKeySpec(
|
||||
new BigInteger(1, encodedPublic),
|
||||
|
@ -110,9 +106,7 @@ final class DHKeyExchange {
|
|||
try {
|
||||
KeyPairGenerator kpg =
|
||||
KeyPairGenerator.getInstance("DiffieHellman");
|
||||
DHParameterSpec params =
|
||||
(DHParameterSpec)namedGroup.getParameterSpec();
|
||||
kpg.initialize(params, random);
|
||||
kpg.initialize(namedGroup.keAlgParamSpec, random);
|
||||
KeyPair kp = generateDHKeyPair(kpg);
|
||||
if (kp == null) {
|
||||
throw new RuntimeException("Could not generate DH keypair");
|
||||
|
@ -321,11 +315,10 @@ final class DHKeyExchange {
|
|||
(context.clientRequestedNamedGroups != null) &&
|
||||
(!context.clientRequestedNamedGroups.isEmpty())) {
|
||||
preferableNamedGroup =
|
||||
SupportedGroups.getPreferredGroup(
|
||||
context.negotiatedProtocol,
|
||||
SupportedGroups.getPreferredGroup(context.negotiatedProtocol,
|
||||
context.algorithmConstraints,
|
||||
new NamedGroupType [] {
|
||||
NamedGroupType.NAMED_GROUP_FFDHE },
|
||||
new NamedGroupSpec [] {
|
||||
NamedGroupSpec.NAMED_GROUP_FFDHE },
|
||||
context.clientRequestedNamedGroups);
|
||||
if (preferableNamedGroup != null) {
|
||||
return new DHEPossession(preferableNamedGroup,
|
||||
|
|
|
@ -125,6 +125,7 @@ final class DHServerKeyExchange {
|
|||
Signature signer = null;
|
||||
if (useExplicitSigAlgorithm) {
|
||||
signatureScheme = SignatureScheme.getPreferableAlgorithm(
|
||||
shc.algorithmConstraints,
|
||||
shc.peerRequestedSignatureSchemes,
|
||||
x509Possession,
|
||||
shc.negotiatedProtocol);
|
||||
|
|
|
@ -36,7 +36,6 @@ import java.security.PrivateKey;
|
|||
import java.security.PublicKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.security.spec.ECParameterSpec;
|
||||
import java.security.spec.ECPoint;
|
||||
import java.security.spec.ECPublicKeySpec;
|
||||
|
@ -44,7 +43,7 @@ import java.util.EnumSet;
|
|||
import javax.crypto.KeyAgreement;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupType;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
|
||||
import sun.security.ssl.X509Authentication.X509Credentials;
|
||||
import sun.security.ssl.X509Authentication.X509Possession;
|
||||
|
@ -88,7 +87,7 @@ final class ECDHKeyExchange {
|
|||
static ECDHECredentials valueOf(NamedGroup namedGroup,
|
||||
byte[] encodedPoint) throws IOException, GeneralSecurityException {
|
||||
|
||||
if (namedGroup.type != NamedGroupType.NAMED_GROUP_ECDHE) {
|
||||
if (namedGroup.spec != NamedGroupSpec.NAMED_GROUP_ECDHE) {
|
||||
throw new RuntimeException(
|
||||
"Credentials decoding: Not ECDHE named group");
|
||||
}
|
||||
|
@ -98,11 +97,7 @@ final class ECDHKeyExchange {
|
|||
}
|
||||
|
||||
ECParameterSpec parameters =
|
||||
ECUtil.getECParameterSpec(null, namedGroup.oid);
|
||||
if (parameters == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
(ECParameterSpec)namedGroup.keAlgParamSpec;
|
||||
ECPoint point = ECUtil.decodePoint(
|
||||
encodedPoint, parameters.getCurve());
|
||||
KeyFactory factory = KeyFactory.getInstance("EC");
|
||||
|
@ -120,9 +115,7 @@ final class ECDHKeyExchange {
|
|||
ECDHEPossession(NamedGroup namedGroup, SecureRandom random) {
|
||||
try {
|
||||
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
|
||||
ECGenParameterSpec params =
|
||||
(ECGenParameterSpec)namedGroup.getParameterSpec();
|
||||
kpg.initialize(params, random);
|
||||
kpg.initialize(namedGroup.keAlgParamSpec, random);
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
privateKey = kp.getPrivate();
|
||||
publicKey = (ECPublicKey)kp.getPublic();
|
||||
|
@ -248,17 +241,17 @@ final class ECDHKeyExchange {
|
|||
preferableNamedGroup = SupportedGroups.getPreferredGroup(
|
||||
context.negotiatedProtocol,
|
||||
context.algorithmConstraints,
|
||||
new NamedGroupType[] {
|
||||
NamedGroupType.NAMED_GROUP_ECDHE,
|
||||
NamedGroupType.NAMED_GROUP_XDH },
|
||||
new NamedGroupSpec[] {
|
||||
NamedGroupSpec.NAMED_GROUP_ECDHE,
|
||||
NamedGroupSpec.NAMED_GROUP_XDH },
|
||||
context.clientRequestedNamedGroups);
|
||||
} else {
|
||||
preferableNamedGroup = SupportedGroups.getPreferredGroup(
|
||||
context.negotiatedProtocol,
|
||||
context.algorithmConstraints,
|
||||
new NamedGroupType[] {
|
||||
NamedGroupType.NAMED_GROUP_ECDHE,
|
||||
NamedGroupType.NAMED_GROUP_XDH });
|
||||
new NamedGroupSpec[] {
|
||||
NamedGroupSpec.NAMED_GROUP_ECDHE,
|
||||
NamedGroupSpec.NAMED_GROUP_XDH });
|
||||
}
|
||||
|
||||
if (preferableNamedGroup != null) {
|
||||
|
@ -308,7 +301,8 @@ final class ECDHKeyExchange {
|
|||
|
||||
NamedGroup ng = NamedGroup.valueOf(params);
|
||||
if (ng == null) {
|
||||
// unlikely, have been checked during cipher suite negotiation.
|
||||
// unlikely, have been checked during cipher suite
|
||||
// negotiation.
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Unsupported EC server cert for ECDH key exchange");
|
||||
}
|
||||
|
@ -480,7 +474,7 @@ final class ECDHKeyExchange {
|
|||
}
|
||||
|
||||
String alg;
|
||||
switch (namedGroup.type) {
|
||||
switch (namedGroup.spec) {
|
||||
case NAMED_GROUP_ECDHE:
|
||||
alg = "ECDH";
|
||||
break;
|
||||
|
|
|
@ -38,6 +38,7 @@ import java.security.Signature;
|
|||
import java.security.SignatureException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Locale;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
import sun.security.ssl.SSLHandshake.HandshakeMessage;
|
||||
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
|
||||
import sun.security.ssl.X509Authentication.X509Credentials;
|
||||
|
@ -110,13 +111,18 @@ final class ECDHServerKeyExchange {
|
|||
|
||||
// Find the NamedGroup used for the ephemeral keys.
|
||||
namedGroup = namedGroupPossession.getNamedGroup();
|
||||
publicPoint = namedGroup.encodePossessionPublicKey(
|
||||
namedGroupPossession);
|
||||
|
||||
if ((namedGroup == null) || (namedGroup.oid == null) ) {
|
||||
if ((namedGroup == null) || (!namedGroup.isAvailable)) {
|
||||
// unlikely
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Missing Named Group");
|
||||
"Missing or improper named group: " + namedGroup);
|
||||
}
|
||||
|
||||
publicPoint = namedGroup.encodePossessionPublicKey(
|
||||
namedGroupPossession);
|
||||
if (publicPoint == null) {
|
||||
// unlikely
|
||||
throw shc.conContext.fatal(Alert.ILLEGAL_PARAMETER,
|
||||
"Missing public point for named group: " + namedGroup);
|
||||
}
|
||||
|
||||
if (x509Possession == null) {
|
||||
|
@ -130,6 +136,7 @@ final class ECDHServerKeyExchange {
|
|||
Signature signer = null;
|
||||
if (useExplicitSigAlgorithm) {
|
||||
signatureScheme = SignatureScheme.getPreferableAlgorithm(
|
||||
shc.algorithmConstraints,
|
||||
shc.peerRequestedSignatureSchemes,
|
||||
x509Possession,
|
||||
shc.negotiatedProtocol);
|
||||
|
|
|
@ -34,7 +34,7 @@ import static sun.security.ssl.SSLExtension.CH_EC_POINT_FORMATS;
|
|||
import sun.security.ssl.SSLExtension.ExtensionConsumer;
|
||||
import sun.security.ssl.SSLExtension.SSLExtensionSpec;
|
||||
import sun.security.ssl.SSLHandshake.HandshakeMessage;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupType;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
|
||||
/**
|
||||
* Pack of the "ec_point_formats" extensions [RFC 4492].
|
||||
|
@ -179,7 +179,7 @@ final class ECPointFormatsExtension {
|
|||
// Produce the extension.
|
||||
//
|
||||
// produce the extension only if EC cipher suite is activated.
|
||||
if (NamedGroupType.NAMED_GROUP_ECDHE.isSupported(
|
||||
if (NamedGroupSpec.NAMED_GROUP_ECDHE.isSupported(
|
||||
chc.activeCipherSuites)) {
|
||||
// We are using uncompressed ECPointFormat only at present.
|
||||
byte[] extData = new byte[] {0x01, 0x00};
|
||||
|
|
|
@ -46,8 +46,8 @@ import javax.crypto.SecretKey;
|
|||
import javax.net.ssl.SNIServerName;
|
||||
import javax.net.ssl.SSLHandshakeException;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupType;
|
||||
import static sun.security.ssl.NamedGroup.NamedGroupType.*;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
import static sun.security.ssl.NamedGroup.NamedGroupSpec.*;
|
||||
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
|
||||
|
||||
abstract class HandshakeContext implements ConnectionContext {
|
||||
|
@ -283,8 +283,8 @@ abstract class HandshakeContext implements ConnectionContext {
|
|||
}
|
||||
|
||||
boolean found = false;
|
||||
Map<NamedGroupType, Boolean> cachedStatus =
|
||||
new EnumMap<>(NamedGroupType.class);
|
||||
Map<NamedGroupSpec, Boolean> cachedStatus =
|
||||
new EnumMap<>(NamedGroupSpec.class);
|
||||
for (CipherSuite suite : enabledCipherSuites) {
|
||||
if (suite.isAvailable() && suite.supports(protocol)) {
|
||||
if (isActivatable(suite,
|
||||
|
@ -323,8 +323,8 @@ abstract class HandshakeContext implements ConnectionContext {
|
|||
|
||||
List<CipherSuite> suites = new LinkedList<>();
|
||||
if (enabledProtocols != null && !enabledProtocols.isEmpty()) {
|
||||
Map<NamedGroupType, Boolean> cachedStatus =
|
||||
new EnumMap<>(NamedGroupType.class);
|
||||
Map<NamedGroupSpec, Boolean> cachedStatus =
|
||||
new EnumMap<>(NamedGroupSpec.class);
|
||||
for (CipherSuite suite : enabledCipherSuites) {
|
||||
if (!suite.isAvailable()) {
|
||||
continue;
|
||||
|
@ -509,7 +509,7 @@ abstract class HandshakeContext implements ConnectionContext {
|
|||
|
||||
private static boolean isActivatable(CipherSuite suite,
|
||||
AlgorithmConstraints algorithmConstraints,
|
||||
Map<NamedGroupType, Boolean> cachedStatus) {
|
||||
Map<NamedGroupSpec, Boolean> cachedStatus) {
|
||||
|
||||
if (algorithmConstraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT), suite.name, null)) {
|
||||
|
@ -520,8 +520,8 @@ abstract class HandshakeContext implements ConnectionContext {
|
|||
|
||||
// Is at least one of the group types available?
|
||||
boolean groupAvailable, retval = false;
|
||||
NamedGroupType[] groupTypes = suite.keyExchange.groupTypes;
|
||||
for (NamedGroupType groupType : groupTypes) {
|
||||
NamedGroupSpec[] groupTypes = suite.keyExchange.groupTypes;
|
||||
for (NamedGroupSpec groupType : groupTypes) {
|
||||
if (groupType != NAMED_GROUP_NONE) {
|
||||
Boolean checkedStatus = cachedStatus.get(groupType);
|
||||
if (checkedStatus == null) {
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,7 +38,7 @@ import java.util.EnumSet;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupType;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
import sun.security.ssl.SupportedGroupsExtension.SupportedGroups;
|
||||
import sun.security.ssl.X509Authentication.X509Possession;
|
||||
import sun.security.util.KeyUtil;
|
||||
|
@ -149,7 +149,7 @@ enum SignatureScheme {
|
|||
final String name; // literal name
|
||||
private final String algorithm; // signature algorithm
|
||||
final String keyAlgorithm; // signature key algorithm
|
||||
private final AlgorithmParameterSpec signAlgParameter;
|
||||
private final SigAlgParamSpec signAlgParams; // signature parameters
|
||||
private final NamedGroup namedGroup; // associated named group
|
||||
|
||||
// The minimal required key size in bits.
|
||||
|
@ -184,21 +184,25 @@ enum SignatureScheme {
|
|||
RSA_PSS_SHA384 ("SHA-384", 48),
|
||||
RSA_PSS_SHA512 ("SHA-512", 64);
|
||||
|
||||
final private AlgorithmParameterSpec parameterSpec;
|
||||
final boolean isAvailable;
|
||||
private final AlgorithmParameterSpec parameterSpec;
|
||||
private final AlgorithmParameters parameters;
|
||||
private final boolean isAvailable;
|
||||
|
||||
SigAlgParamSpec(String hash, int saltLength) {
|
||||
// See RFC 8017
|
||||
PSSParameterSpec pssParamSpec =
|
||||
new PSSParameterSpec(hash, "MGF1",
|
||||
new MGF1ParameterSpec(hash), saltLength, 1);
|
||||
AlgorithmParameters pssParams = null;
|
||||
|
||||
boolean mediator = true;
|
||||
try {
|
||||
Signature signer = Signature.getInstance("RSASSA-PSS");
|
||||
signer.setParameter(pssParamSpec);
|
||||
pssParams = signer.getParameters();
|
||||
} catch (InvalidAlgorithmParameterException |
|
||||
NoSuchAlgorithmException exp) {
|
||||
NoSuchAlgorithmException | RuntimeException exp) {
|
||||
// Signature.getParameters() may throw RuntimeException.
|
||||
mediator = false;
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.warning(
|
||||
|
@ -209,10 +213,7 @@ enum SignatureScheme {
|
|||
|
||||
this.isAvailable = mediator;
|
||||
this.parameterSpec = mediator ? pssParamSpec : null;
|
||||
}
|
||||
|
||||
AlgorithmParameterSpec getParameterSpec() {
|
||||
return parameterSpec;
|
||||
this.parameters = mediator ? pssParams : null;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +256,7 @@ enum SignatureScheme {
|
|||
|
||||
private SignatureScheme(int id, String name,
|
||||
String algorithm, String keyAlgorithm,
|
||||
SigAlgParamSpec signAlgParamSpec,
|
||||
SigAlgParamSpec signAlgParams,
|
||||
NamedGroup namedGroup, int minimalKeySize,
|
||||
ProtocolVersion[] supportedProtocols,
|
||||
ProtocolVersion[] handshakeSupportedProtocols) {
|
||||
|
@ -263,8 +264,7 @@ enum SignatureScheme {
|
|||
this.name = name;
|
||||
this.algorithm = algorithm;
|
||||
this.keyAlgorithm = keyAlgorithm;
|
||||
this.signAlgParameter =
|
||||
signAlgParamSpec != null ? signAlgParamSpec.parameterSpec : null;
|
||||
this.signAlgParams = signAlgParams;
|
||||
this.namedGroup = namedGroup;
|
||||
this.minimalKeySize = minimalKeySize;
|
||||
this.supportedProtocols = Arrays.asList(supportedProtocols);
|
||||
|
@ -272,8 +272,8 @@ enum SignatureScheme {
|
|||
Arrays.asList(handshakeSupportedProtocols);
|
||||
|
||||
boolean mediator = true;
|
||||
if (signAlgParamSpec != null) {
|
||||
mediator = signAlgParamSpec.isAvailable;
|
||||
if (signAlgParams != null) {
|
||||
mediator = signAlgParams.isAvailable;
|
||||
} else {
|
||||
try {
|
||||
Signature.getInstance(algorithm);
|
||||
|
@ -331,6 +331,18 @@ enum SignatureScheme {
|
|||
return 2;
|
||||
}
|
||||
|
||||
private boolean isPermitted(AlgorithmConstraints constraints) {
|
||||
return constraints.permits(SIGNATURE_PRIMITIVE_SET,
|
||||
this.name, null) &&
|
||||
constraints.permits(SIGNATURE_PRIMITIVE_SET,
|
||||
this.keyAlgorithm, null) &&
|
||||
constraints.permits(SIGNATURE_PRIMITIVE_SET,
|
||||
this.algorithm, (signAlgParams != null ?
|
||||
signAlgParams.parameters : null)) &&
|
||||
(namedGroup != null ?
|
||||
namedGroup.isPermitted(constraints) : true);
|
||||
}
|
||||
|
||||
// Get local supported algorithm collection complying to algorithm
|
||||
// constraints.
|
||||
static List<SignatureScheme> getSupportedAlgorithms(
|
||||
|
@ -351,8 +363,7 @@ enum SignatureScheme {
|
|||
}
|
||||
|
||||
if (isMatch) {
|
||||
if (constraints.permits(
|
||||
SIGNATURE_PRIMITIVE_SET, ss.algorithm, null)) {
|
||||
if (ss.isPermitted(constraints)) {
|
||||
supported.add(ss);
|
||||
} else if (SSLLogger.isOn &&
|
||||
SSLLogger.isOn("ssl,handshake,verbose")) {
|
||||
|
@ -383,8 +394,7 @@ enum SignatureScheme {
|
|||
}
|
||||
} else if (ss.isAvailable &&
|
||||
ss.supportedProtocols.contains(protocolVersion) &&
|
||||
constraints.permits(SIGNATURE_PRIMITIVE_SET,
|
||||
ss.algorithm, null)) {
|
||||
ss.isPermitted(constraints)) {
|
||||
supported.add(ss);
|
||||
} else {
|
||||
if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
|
@ -398,6 +408,7 @@ enum SignatureScheme {
|
|||
}
|
||||
|
||||
static SignatureScheme getPreferableAlgorithm(
|
||||
AlgorithmConstraints constraints,
|
||||
List<SignatureScheme> schemes,
|
||||
SignatureScheme certScheme,
|
||||
ProtocolVersion version) {
|
||||
|
@ -405,8 +416,8 @@ enum SignatureScheme {
|
|||
for (SignatureScheme ss : schemes) {
|
||||
if (ss.isAvailable &&
|
||||
ss.handshakeSupportedProtocols.contains(version) &&
|
||||
certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) {
|
||||
|
||||
certScheme.keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm) &&
|
||||
ss.isPermitted(constraints)) {
|
||||
return ss;
|
||||
}
|
||||
}
|
||||
|
@ -415,6 +426,7 @@ enum SignatureScheme {
|
|||
}
|
||||
|
||||
static SignatureScheme getPreferableAlgorithm(
|
||||
AlgorithmConstraints constraints,
|
||||
List<SignatureScheme> schemes,
|
||||
X509Possession x509Possession,
|
||||
ProtocolVersion version) {
|
||||
|
@ -432,9 +444,10 @@ enum SignatureScheme {
|
|||
for (SignatureScheme ss : schemes) {
|
||||
if (ss.isAvailable && (keySize >= ss.minimalKeySize) &&
|
||||
ss.handshakeSupportedProtocols.contains(version) &&
|
||||
keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm)) {
|
||||
if ((ss.namedGroup != null) && (ss.namedGroup.type ==
|
||||
NamedGroupType.NAMED_GROUP_ECDHE)) {
|
||||
keyAlgorithm.equalsIgnoreCase(ss.keyAlgorithm) &&
|
||||
ss.isPermitted(constraints)) {
|
||||
if ((ss.namedGroup != null) && (ss.namedGroup.spec ==
|
||||
NamedGroupSpec.NAMED_GROUP_ECDHE)) {
|
||||
ECParameterSpec params =
|
||||
x509Possession.getECParameterSpec();
|
||||
if (params != null &&
|
||||
|
@ -505,10 +518,13 @@ enum SignatureScheme {
|
|||
Signature signer = Signature.getInstance(algorithm);
|
||||
if (key instanceof PublicKey) {
|
||||
SignatureUtil.initVerifyWithParam(signer, (PublicKey)key,
|
||||
signAlgParameter);
|
||||
(signAlgParams != null ?
|
||||
signAlgParams.parameterSpec : null));
|
||||
} else {
|
||||
SignatureUtil.initSignWithParam(signer, (PrivateKey)key,
|
||||
signAlgParameter, null);
|
||||
(signAlgParams != null ?
|
||||
signAlgParams.parameterSpec : null),
|
||||
null);
|
||||
}
|
||||
|
||||
return signer;
|
||||
|
|
|
@ -28,20 +28,15 @@ package sun.security.ssl;
|
|||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.AlgorithmConstraints;
|
||||
import java.security.AlgorithmParameters;
|
||||
import java.security.CryptoPrimitive;
|
||||
import java.security.spec.ECGenParameterSpec;
|
||||
import java.security.spec.InvalidParameterSpecException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import javax.net.ssl.SSLProtocolException;
|
||||
import sun.security.action.GetPropertyAction;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupType;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
import static sun.security.ssl.SSLExtension.CH_SUPPORTED_GROUPS;
|
||||
import static sun.security.ssl.SSLExtension.EE_SUPPORTED_GROUPS;
|
||||
import sun.security.ssl.SSLExtension.ExtensionConsumer;
|
||||
|
@ -188,7 +183,7 @@ final class SupportedGroupsExtension {
|
|||
if (!group.isEmpty()) {
|
||||
NamedGroup namedGroup = NamedGroup.nameOf(group);
|
||||
if (namedGroup != null) {
|
||||
if (isAvailableGroup(namedGroup)) {
|
||||
if (namedGroup.isAvailable) {
|
||||
groupList.add(namedGroup);
|
||||
}
|
||||
} // ignore unknown groups
|
||||
|
@ -235,7 +230,7 @@ final class SupportedGroupsExtension {
|
|||
|
||||
groupList = new ArrayList<>(groups.length);
|
||||
for (NamedGroup group : groups) {
|
||||
if (isAvailableGroup(group)) {
|
||||
if (group.isAvailable) {
|
||||
groupList.add(group);
|
||||
}
|
||||
}
|
||||
|
@ -253,48 +248,19 @@ final class SupportedGroupsExtension {
|
|||
}
|
||||
}
|
||||
|
||||
// check whether the group is supported by the underlying providers
|
||||
private static boolean isAvailableGroup(NamedGroup namedGroup) {
|
||||
return namedGroup.isAvailableGroup();
|
||||
}
|
||||
|
||||
static ECGenParameterSpec getECGenParamSpec(NamedGroup ng) {
|
||||
if (ng.type != NamedGroupType.NAMED_GROUP_ECDHE) {
|
||||
throw new RuntimeException(
|
||||
"Not a named EC group: " + ng);
|
||||
}
|
||||
|
||||
// parameters are non-null
|
||||
AlgorithmParameters params = ng.getParameters();
|
||||
try {
|
||||
return params.getParameterSpec(ECGenParameterSpec.class);
|
||||
} catch (InvalidParameterSpecException ipse) {
|
||||
// should be unlikely
|
||||
return new ECGenParameterSpec(ng.oid);
|
||||
}
|
||||
}
|
||||
|
||||
static AlgorithmParameters getParameters(NamedGroup ng) {
|
||||
return ng.getParameters();
|
||||
}
|
||||
|
||||
// Is there any supported group permitted by the constraints?
|
||||
static boolean isActivatable(
|
||||
AlgorithmConstraints constraints, NamedGroupType type) {
|
||||
AlgorithmConstraints constraints, NamedGroupSpec type) {
|
||||
|
||||
boolean hasFFDHEGroups = false;
|
||||
for (NamedGroup namedGroup : supportedNamedGroups) {
|
||||
if (namedGroup.type == type) {
|
||||
if (constraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
namedGroup.algorithm,
|
||||
getParameters(namedGroup))) {
|
||||
|
||||
if (namedGroup.isAvailable && namedGroup.spec == type) {
|
||||
if (namedGroup.isPermitted(constraints)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!hasFFDHEGroups &&
|
||||
(type == NamedGroupType.NAMED_GROUP_FFDHE)) {
|
||||
(type == NamedGroupSpec.NAMED_GROUP_FFDHE)) {
|
||||
hasFFDHEGroups = true;
|
||||
}
|
||||
}
|
||||
|
@ -306,20 +272,17 @@ final class SupportedGroupsExtension {
|
|||
//
|
||||
// Note that the constraints checking on DHE parameters will be
|
||||
// performed during key exchanging in a handshake.
|
||||
return !hasFFDHEGroups && type == NamedGroupType.NAMED_GROUP_FFDHE;
|
||||
return !hasFFDHEGroups && type == NamedGroupSpec.NAMED_GROUP_FFDHE;
|
||||
}
|
||||
|
||||
// Is the named group permitted by the constraints?
|
||||
static boolean isActivatable(
|
||||
AlgorithmConstraints constraints, NamedGroup namedGroup) {
|
||||
if (!isSupported(namedGroup)) {
|
||||
if (!namedGroup.isAvailable || !isSupported(namedGroup)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return constraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
namedGroup.algorithm,
|
||||
getParameters(namedGroup));
|
||||
return namedGroup.isPermitted(constraints);
|
||||
}
|
||||
|
||||
// Is the named group supported?
|
||||
|
@ -335,16 +298,13 @@ final class SupportedGroupsExtension {
|
|||
|
||||
static NamedGroup getPreferredGroup(
|
||||
ProtocolVersion negotiatedProtocol,
|
||||
AlgorithmConstraints constraints, NamedGroupType[] types,
|
||||
AlgorithmConstraints constraints, NamedGroupSpec[] types,
|
||||
List<NamedGroup> requestedNamedGroups) {
|
||||
for (NamedGroup namedGroup : requestedNamedGroups) {
|
||||
if ((NamedGroupType.arrayContains(types, namedGroup.type)) &&
|
||||
if ((NamedGroupSpec.arrayContains(types, namedGroup.spec)) &&
|
||||
namedGroup.isAvailable(negotiatedProtocol) &&
|
||||
isSupported(namedGroup) &&
|
||||
constraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
namedGroup.algorithm,
|
||||
getParameters(namedGroup))) {
|
||||
namedGroup.isPermitted(constraints)) {
|
||||
return namedGroup;
|
||||
}
|
||||
}
|
||||
|
@ -354,14 +314,11 @@ final class SupportedGroupsExtension {
|
|||
|
||||
static NamedGroup getPreferredGroup(
|
||||
ProtocolVersion negotiatedProtocol,
|
||||
AlgorithmConstraints constraints, NamedGroupType[] types) {
|
||||
AlgorithmConstraints constraints, NamedGroupSpec[] types) {
|
||||
for (NamedGroup namedGroup : supportedNamedGroups) {
|
||||
if ((NamedGroupType.arrayContains(types, namedGroup.type)) &&
|
||||
if ((NamedGroupSpec.arrayContains(types, namedGroup.spec)) &&
|
||||
namedGroup.isAvailable(negotiatedProtocol) &&
|
||||
constraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
namedGroup.algorithm,
|
||||
getParameters(namedGroup))) {
|
||||
namedGroup.isPermitted(constraints)) {
|
||||
return namedGroup;
|
||||
}
|
||||
}
|
||||
|
@ -401,15 +358,13 @@ final class SupportedGroupsExtension {
|
|||
new ArrayList<>(SupportedGroups.supportedNamedGroups.length);
|
||||
for (NamedGroup ng : SupportedGroups.supportedNamedGroups) {
|
||||
if ((!SupportedGroups.enableFFDHE) &&
|
||||
(ng.type == NamedGroupType.NAMED_GROUP_FFDHE)) {
|
||||
(ng.spec == NamedGroupSpec.NAMED_GROUP_FFDHE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ng.isAvailable(chc.activeProtocols) &&
|
||||
ng.isSupported(chc.activeCipherSuites) &&
|
||||
chc.algorithmConstraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
ng.algorithm, getParameters(ng))) {
|
||||
ng.isPermitted(chc.algorithmConstraints)) {
|
||||
namedGroups.add(ng);
|
||||
} else if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
|
@ -528,15 +483,13 @@ final class SupportedGroupsExtension {
|
|||
SupportedGroups.supportedNamedGroups.length);
|
||||
for (NamedGroup ng : SupportedGroups.supportedNamedGroups) {
|
||||
if ((!SupportedGroups.enableFFDHE) &&
|
||||
(ng.type == NamedGroupType.NAMED_GROUP_FFDHE)) {
|
||||
(ng.spec == NamedGroupSpec.NAMED_GROUP_FFDHE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ng.isAvailable(shc.activeProtocols) &&
|
||||
ng.isSupported(shc.activeCipherSuites) &&
|
||||
shc.algorithmConstraints.permits(
|
||||
EnumSet.of(CryptoPrimitive.KEY_AGREEMENT),
|
||||
ng.algorithm, getParameters(ng))) {
|
||||
ng.isPermitted(shc.algorithmConstraints)) {
|
||||
namedGroups.add(ng);
|
||||
} else if (SSLLogger.isOn && SSLLogger.isOn("ssl,handshake")) {
|
||||
SSLLogger.fine(
|
||||
|
|
|
@ -29,7 +29,7 @@ import java.math.BigInteger;
|
|||
import java.security.*;
|
||||
import java.security.interfaces.XECPublicKey;
|
||||
import java.security.spec.*;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupType;
|
||||
import sun.security.ssl.NamedGroup.NamedGroupSpec;
|
||||
import sun.security.util.*;
|
||||
|
||||
/**
|
||||
|
@ -68,7 +68,7 @@ final class XDHKeyExchange {
|
|||
byte[] encodedPoint) throws IOException,
|
||||
GeneralSecurityException {
|
||||
|
||||
if (namedGroup.type != NamedGroupType.NAMED_GROUP_XDH) {
|
||||
if (namedGroup.spec != NamedGroupSpec.NAMED_GROUP_XDH) {
|
||||
throw new RuntimeException(
|
||||
"Credentials decoding: Not XDH named group");
|
||||
}
|
||||
|
@ -101,8 +101,7 @@ final class XDHKeyExchange {
|
|||
try {
|
||||
KeyPairGenerator kpg
|
||||
= KeyPairGenerator.getInstance(namedGroup.algorithm);
|
||||
AlgorithmParameterSpec params = namedGroup.getParameterSpec();
|
||||
kpg.initialize(params, random);
|
||||
kpg.initialize(namedGroup.keAlgParamSpec, random);
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
privateKey = kp.getPrivate();
|
||||
publicKey = (XECPublicKey) kp.getPublic();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue