org.bouncycastle.jsse.provider.SignatureSchemeInfo Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of impersonator Show documentation
Show all versions of impersonator Show documentation
Spoof TLS/JA3/JA4 and HTTP/2 fingerprints in Java
package org.bouncycastle.jsse.provider;
import java.security.AlgorithmParameters;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicReference;
import java.util.logging.Logger;
import org.bouncycastle.jsse.java.security.BCAlgorithmConstraints;
import org.bouncycastle.jsse.java.security.BCCryptoPrimitive;
import org.bouncycastle.tls.NamedGroup;
import org.bouncycastle.tls.ProtocolVersion;
import org.bouncycastle.tls.SignatureAndHashAlgorithm;
import org.bouncycastle.tls.SignatureScheme;
import org.bouncycastle.tls.TlsUtils;
import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCrypto;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.Integers;
class SignatureSchemeInfo
{
private static final Logger LOG = Logger.getLogger(SignatureSchemeInfo.class.getName());
static final int historical_dsa_sha1 = 0x0202;
static final int historical_dsa_sha224 = 0x0302;
static final int historical_dsa_sha256 = 0x0402;
static final int historical_ecdsa_sha224 = 0x0303;
static final int historical_rsa_md5 = 0x0101;
static final int historical_rsa_sha224 = 0x0301;
private static final String PROPERTY_CLIENT_SIGNATURE_SCHEMES = "jdk.tls.client.SignatureSchemes";
private static final String PROPERTY_SERVER_SIGNATURE_SCHEMES = "jdk.tls.server.SignatureSchemes";
private static final String PROPERTY_CLIENT_SIGNATURE_SCHEMES_CERT = "org.bouncycastle.jsse.client.SignatureSchemesCert";
private static final String PROPERTY_SERVER_SIGNATURE_SCHEMES_CERT = "org.bouncycastle.jsse.server.SignatureSchemesCert";
// NOTE: Not all of these are necessarily enabled/supported; it will be checked at runtime
private enum All
{
ed25519(SignatureScheme.ed25519, "Ed25519", "Ed25519"),
ed448(SignatureScheme.ed448, "Ed448", "Ed448"),
ecdsa_secp256r1_sha256(SignatureScheme.ecdsa_secp256r1_sha256, "SHA256withECDSA", "EC"),
ecdsa_secp384r1_sha384(SignatureScheme.ecdsa_secp384r1_sha384, "SHA384withECDSA", "EC"),
ecdsa_secp521r1_sha512(SignatureScheme.ecdsa_secp521r1_sha512, "SHA512withECDSA", "EC"),
ecdsa_brainpoolP256r1tls13_sha256(SignatureScheme.ecdsa_brainpoolP256r1tls13_sha256, "SHA256withECDSA", "EC"),
ecdsa_brainpoolP384r1tls13_sha384(SignatureScheme.ecdsa_brainpoolP384r1tls13_sha384, "SHA384withECDSA", "EC"),
ecdsa_brainpoolP512r1tls13_sha512(SignatureScheme.ecdsa_brainpoolP512r1tls13_sha512, "SHA512withECDSA", "EC"),
// NOTE: SunJSSE is using "RSASSA-PSS" as 'jcaSignatureAlgorithm' for all these
rsa_pss_pss_sha256(SignatureScheme.rsa_pss_pss_sha256, "SHA256withRSAandMGF1", "RSASSA-PSS"),
rsa_pss_pss_sha384(SignatureScheme.rsa_pss_pss_sha384, "SHA384withRSAandMGF1", "RSASSA-PSS"),
rsa_pss_pss_sha512(SignatureScheme.rsa_pss_pss_sha512, "SHA512withRSAandMGF1", "RSASSA-PSS"),
// NOTE: SunJSSE is using "RSASSA-PSS" as 'jcaSignatureAlgorithm' for all these
rsa_pss_rsae_sha256(SignatureScheme.rsa_pss_rsae_sha256, "SHA256withRSAandMGF1", "RSA"),
rsa_pss_rsae_sha384(SignatureScheme.rsa_pss_rsae_sha384, "SHA384withRSAandMGF1", "RSA"),
rsa_pss_rsae_sha512(SignatureScheme.rsa_pss_rsae_sha512, "SHA512withRSAandMGF1", "RSA"),
// Deprecated: only for certs in 1.3
rsa_pkcs1_sha256(SignatureScheme.rsa_pkcs1_sha256, "SHA256withRSA", "RSA", true),
rsa_pkcs1_sha384(SignatureScheme.rsa_pkcs1_sha384, "SHA384withRSA", "RSA", true),
rsa_pkcs1_sha512(SignatureScheme.rsa_pkcs1_sha512, "SHA512withRSA", "RSA", true),
sm2sig_sm3(SignatureScheme.sm2sig_sm3, "SM3withSM2", "EC"),
/*
* Legacy/Historical: mostly not supported in 1.3, except ecdsa_sha1 and rsa_pkcs1_sha1 are
* still permitted as a last resort for certs.
*/
dsa_sha256(historical_dsa_sha256, "dsa_sha256", "SHA256withDSA", "DSA"),
ecdsa_sha224(historical_ecdsa_sha224, "ecdsa_sha224", "SHA224withECDSA", "EC"),
rsa_sha224(historical_rsa_sha224, "rsa_sha224", "SHA224withRSA", "RSA"),
dsa_sha224(historical_dsa_sha224, "dsa_sha224", "SHA224withDSA", "DSA"),
ecdsa_sha1(SignatureScheme.ecdsa_sha1, "SHA1withECDSA", "EC", true),
rsa_pkcs1_sha1(SignatureScheme.rsa_pkcs1_sha1, "SHA1withRSA", "RSA", true),
dsa_sha1(historical_dsa_sha1, "dsa_sha1", "SHA1withDSA", "DSA"),
rsa_md5(historical_rsa_md5, "rsa_md5", "MD5withRSA", "RSA");
private final int signatureScheme;
private final String name;
private final String text;
private final String jcaSignatureAlgorithm;
private final String jcaSignatureAlgorithmBC;
private final String keyAlgorithm;
private final String keyType13;
private final boolean supportedPost13;
private final boolean supportedPre13;
private final boolean supportedCerts13;
private final int namedGroup13;
private All(int signatureScheme, String jcaSignatureAlgorithm, String keyAlgorithm)
{
this(signatureScheme, jcaSignatureAlgorithm, keyAlgorithm, true, true,
SignatureScheme.getNamedGroup(signatureScheme));
}
// Deprecated/Legacy
private All(int signatureScheme, String jcaSignatureAlgorithm, String keyAlgorithm, boolean supportedCerts13)
{
this(signatureScheme, jcaSignatureAlgorithm, keyAlgorithm, false, supportedCerts13, -1);
}
private All(int signatureScheme, String jcaSignatureAlgorithm, String keyAlgorithm, boolean supportedPost13,
boolean supportedCerts13, int namedGroup13)
{
this(signatureScheme, SignatureScheme.getName(signatureScheme), jcaSignatureAlgorithm, keyAlgorithm,
supportedPost13, supportedCerts13, namedGroup13);
}
// Historical
private All(int signatureScheme, String name, String jcaSignatureAlgorithm, String keyAlgorithm)
{
this(signatureScheme, name, jcaSignatureAlgorithm, keyAlgorithm, false, false, -1);
}
private All(int signatureScheme, String name, String jcaSignatureAlgorithm, String keyAlgorithm,
boolean supportedPost13, boolean supportedCerts13, int namedGroup13)
{
String keyType13 = JsseUtils.getKeyType13(keyAlgorithm, namedGroup13);
String jcaSignatureAlgorithmBC = JsseUtils.getJcaSignatureAlgorithmBC(jcaSignatureAlgorithm, keyAlgorithm);
this.signatureScheme = signatureScheme;
this.name = name;
this.text = name + "(0x" + Integer.toHexString(signatureScheme) + ")";
this.jcaSignatureAlgorithm = jcaSignatureAlgorithm;
this.jcaSignatureAlgorithmBC = jcaSignatureAlgorithmBC;
this.keyAlgorithm = keyAlgorithm;
this.keyType13 = keyType13;
this.supportedPost13 = supportedPost13;
this.supportedPre13 = (namedGroup13 < 0) || NamedGroup.canBeNegotiated(namedGroup13, ProtocolVersion.TLSv12);
this.supportedCerts13 = supportedCerts13;
this.namedGroup13 = namedGroup13;
}
}
private static final int[] CANDIDATES_DEFAULT = createCandidatesDefault();
static class PerConnection
{
private final List localSigSchemes;
private final List localSigSchemesCert;
private final AtomicReference> peerSigSchemes;
private final AtomicReference> peerSigSchemesCert;
PerConnection(List localSigSchemes, List localSigSchemesCert)
{
this.localSigSchemes = localSigSchemes;
this.localSigSchemesCert = localSigSchemesCert;
this.peerSigSchemes = new AtomicReference>();
this.peerSigSchemesCert = new AtomicReference>();
}
String[] getLocalJcaSignatureAlgorithms()
{
return getJcaSignatureAlgorithms(getLocalSigSchemesCert());
}
String[] getLocalJcaSignatureAlgorithmsBC()
{
return getJcaSignatureAlgorithmsBC(getLocalSigSchemesCert());
}
Vector getLocalSignatureAndHashAlgorithms()
{
return getSignatureAndHashAlgorithms(localSigSchemes);
}
Vector getLocalSignatureAndHashAlgorithmsCert()
{
return getSignatureAndHashAlgorithms(localSigSchemesCert);
}
List getLocalSigSchemes()
{
return localSigSchemes;
}
List getLocalSigSchemesCert()
{
return localSigSchemesCert != null ? localSigSchemesCert : getLocalSigSchemes();
}
String[] getPeerJcaSignatureAlgorithms()
{
return getJcaSignatureAlgorithms(getPeerSigSchemesCert());
}
String[] getPeerJcaSignatureAlgorithmsBC()
{
return getJcaSignatureAlgorithmsBC(getPeerSigSchemesCert());
}
List getPeerSigSchemes()
{
return peerSigSchemes.get();
}
List getPeerSigSchemesCert()
{
List sigSchemesCert = peerSigSchemesCert.get();
return sigSchemesCert != null ? sigSchemesCert : getPeerSigSchemes();
}
boolean hasLocalSignatureScheme(SignatureSchemeInfo signatureSchemeInfo)
{
return localSigSchemes.contains(signatureSchemeInfo);
}
void notifyPeerData(List sigSchemes, List sigSchemesCert)
{
peerSigSchemes.set(sigSchemes);
peerSigSchemesCert.set(sigSchemesCert);
}
}
static class PerContext
{
private final Map index;
private final int[] candidatesClient, candidatesServer;
private final int[] candidatesCertClient, candidatesCertServer;
PerContext(Map index, int[] candidatesClient, int[] candidatesServer,
int[] candidatesCertClient, int[] candidatesCertServer)
{
this.index = index;
this.candidatesClient = candidatesClient;
this.candidatesServer = candidatesServer;
this.candidatesCertClient = candidatesCertClient;
this.candidatesCertServer = candidatesCertServer;
}
}
static PerConnection createPerConnectionClient(PerContext perContext, ProvSSLParameters sslParameters,
ProtocolVersion[] activeProtocolVersions, NamedGroupInfo.PerConnection namedGroups)
{
ProtocolVersion latest = ProtocolVersion.getLatestTLS(activeProtocolVersions);
if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(latest))
{
return new PerConnection(null, null);
}
ProtocolVersion earliest = ProtocolVersion.getEarliestTLS(activeProtocolVersions);
return createPerConnection(perContext, false, sslParameters, earliest, latest, namedGroups);
}
static PerConnection createPerConnectionServer(PerContext perContext, ProvSSLParameters sslParameters,
ProtocolVersion negotiatedVersion, NamedGroupInfo.PerConnection namedGroups)
{
if (!TlsUtils.isSignatureAlgorithmsExtensionAllowed(negotiatedVersion))
{
return new PerConnection(null, null);
}
return createPerConnection(perContext, true, sslParameters, negotiatedVersion, negotiatedVersion, namedGroups);
}
private static PerConnection createPerConnection(PerContext perContext, boolean isServer, ProvSSLParameters sslParameters,
ProtocolVersion earliest, ProtocolVersion latest, NamedGroupInfo.PerConnection namedGroups)
{
int[] candidates;
{
String[] signatureSchemes = sslParameters.getSignatureSchemes();
if (signatureSchemes == null)
{
candidates = isServer ? perContext.candidatesServer : perContext.candidatesClient;
if (candidates == null)
{
candidates = CANDIDATES_DEFAULT;
}
}
else
{
candidates = createCandidates(perContext.index, signatureSchemes, "SSLParameters.signatureSchemes");
}
}
int[] candidatesCert;
{
String[] signatureSchemesCert = sslParameters.getSignatureSchemesCert();
if (signatureSchemesCert == null)
{
candidatesCert = isServer ? perContext.candidatesCertServer : perContext.candidatesCertClient;
}
else
{
candidatesCert = createCandidates(perContext.index, signatureSchemesCert,
"SSLParameters.signatureSchemesCert");
}
}
BCAlgorithmConstraints algorithmConstraints = sslParameters.getAlgorithmConstraints();
boolean post13Active = TlsUtils.isTLSv13(latest);
boolean pre13Active = !TlsUtils.isTLSv13(earliest);
ArrayList localSigSchemes;
{
int count = candidates.length;
localSigSchemes = new ArrayList(count);
for (int i = 0; i < count; ++i)
{
Integer candidate = Integers.valueOf(candidates[i]);
SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(candidate);
if (null != signatureSchemeInfo
&& signatureSchemeInfo.isActiveCerts(algorithmConstraints, post13Active, pre13Active, namedGroups))
{
localSigSchemes.add(signatureSchemeInfo);
}
}
localSigSchemes.trimToSize();
}
ArrayList localSigSchemesCert = null;
if (candidatesCert != null)
{
int count = candidatesCert.length;
localSigSchemesCert = new ArrayList(count);
for (int i = 0; i < count; ++i)
{
Integer candidate = Integers.valueOf(candidatesCert[i]);
SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(candidate);
if (null != signatureSchemeInfo
&& signatureSchemeInfo.isActiveCerts(algorithmConstraints, post13Active, pre13Active, namedGroups))
{
localSigSchemesCert.add(signatureSchemeInfo);
}
}
localSigSchemesCert.trimToSize();
}
return new PerConnection(localSigSchemes, localSigSchemesCert);
}
static PerContext createPerContext(boolean isFipsContext, JcaTlsCrypto crypto,
NamedGroupInfo.PerContext namedGroups)
{
Map index = createIndex(isFipsContext, crypto, namedGroups);
int[] candidatesClient = createCandidatesFromProperty(index, PROPERTY_CLIENT_SIGNATURE_SCHEMES);
int[] candidatesServer = createCandidatesFromProperty(index, PROPERTY_SERVER_SIGNATURE_SCHEMES);
int[] candidatesCertClient = createCandidatesFromProperty(index, PROPERTY_CLIENT_SIGNATURE_SCHEMES_CERT);
int[] candidatesCertServer = createCandidatesFromProperty(index, PROPERTY_SERVER_SIGNATURE_SCHEMES_CERT);
return new PerContext(index, candidatesClient, candidatesServer, candidatesCertClient, candidatesCertServer);
}
private static String[] getJcaSignatureAlgorithms(Collection infos)
{
if (null == infos)
{
return TlsUtils.EMPTY_STRINGS;
}
String[] result = new String[infos.size()];
int resultPos = 0;
for (SignatureSchemeInfo info : infos)
{
// TODO The two kinds of PSS signature scheme can give duplicates here
result[resultPos++] = info.getJcaSignatureAlgorithm();
}
return result;
}
private static String[] getJcaSignatureAlgorithmsBC(Collection infos)
{
if (null == infos)
{
return TlsUtils.EMPTY_STRINGS;
}
String[] result = new String[infos.size()];
int resultPos = 0;
for (SignatureSchemeInfo info : infos)
{
result[resultPos++] = info.getJcaSignatureAlgorithmBC();
}
return result;
}
static SignatureAndHashAlgorithm getSignatureAndHashAlgorithm(int signatureScheme)
{
if (!TlsUtils.isValidUint16(signatureScheme))
{
throw new IllegalArgumentException();
}
return SignatureScheme.getSignatureAndHashAlgorithm(signatureScheme);
}
private static Vector getSignatureAndHashAlgorithms(
Collection signatureSchemeInfos)
{
// TODO[tls13] Actually should return empty for empty?
if (null == signatureSchemeInfos || signatureSchemeInfos.isEmpty())
{
return null;
}
int count = signatureSchemeInfos.size();
Vector result = new Vector(count);
for (SignatureSchemeInfo signatureSchemeInfo : signatureSchemeInfos)
{
if (null != signatureSchemeInfo)
{
SignatureAndHashAlgorithm sigAndHashAlg = signatureSchemeInfo.getSignatureAndHashAlgorithm();
result.add(sigAndHashAlg);
}
}
if (result.isEmpty())
{
// TODO[tls13] Actually should return empty for empty?
return null;
}
result.trimToSize();
return result;
}
static List getSignatureSchemes(PerContext perContext,
Vector sigAndHashAlgs)
{
if (null == sigAndHashAlgs || sigAndHashAlgs.isEmpty())
{
return null;
}
int count = sigAndHashAlgs.size();
ArrayList result = new ArrayList(count);
for (int i = 0; i < count; ++i)
{
SignatureAndHashAlgorithm sigAndHashAlg = sigAndHashAlgs.elementAt(i);
if (null != sigAndHashAlg)
{
int signatureScheme = SignatureScheme.from(sigAndHashAlg);
SignatureSchemeInfo signatureSchemeInfo = perContext.index.get(signatureScheme);
if (null != signatureSchemeInfo)
{
result.add(signatureSchemeInfo);
}
}
}
if (result.isEmpty())
{
return null;
}
result.trimToSize();
return Collections.unmodifiableList(result);
}
private static void addSignatureScheme(boolean isFipsContext, JcaTlsCrypto crypto, NamedGroupInfo.PerContext ng,
Map ss, All all)
{
final int signatureScheme = all.signatureScheme;
if (isFipsContext && !FipsUtils.isFipsSignatureScheme(signatureScheme))
{
// In FIPS mode, non-FIPS schemes are currently not even entered into the map
return;
}
NamedGroupInfo namedGroupInfo = null;
boolean disabled13 = false;
int namedGroup13 = all.namedGroup13;
if (namedGroup13 >= 0)
{
namedGroupInfo = NamedGroupInfo.getNamedGroup(ng, namedGroup13);
if (null == namedGroupInfo || !namedGroupInfo.isEnabled() || !namedGroupInfo.isSupportedPost13())
{
disabled13 = true;
}
}
boolean enabled = crypto.hasSignatureScheme(signatureScheme);
AlgorithmParameters algorithmParameters = null;
if (enabled)
{
// TODO[jsse] Consider also fetching 'jcaSignatureAlgorithm' and 'keyAlgorithm'
try
{
algorithmParameters = crypto.getSignatureSchemeAlgorithmParameters(signatureScheme);
}
catch (Exception e)
{
enabled = false;
}
}
SignatureSchemeInfo signatureSchemeInfo = new SignatureSchemeInfo(all, algorithmParameters, namedGroupInfo,
enabled, disabled13);
if (null != ss.put(signatureScheme, signatureSchemeInfo))
{
throw new IllegalStateException("Duplicate entries for SignatureSchemeInfo");
}
}
private static int[] createCandidatesFromProperty(Map index, String propertyName)
{
String[] names = PropertyUtils.getStringArraySystemProperty(propertyName);
if (null == names)
{
return null;
}
return createCandidates(index, names, propertyName);
}
private static int[] createCandidates(Map index, String[] names, String description)
{
int[] result = new int[names.length];
int count = 0;
for (String name : names)
{
int signatureScheme = getSignatureSchemeByName(name);
if (signatureScheme < 0)
{
LOG.warning("'" + description + "' contains unrecognised SignatureScheme: " + name);
continue;
}
SignatureSchemeInfo signatureSchemeInfo = index.get(signatureScheme);
if (null == signatureSchemeInfo)
{
LOG.warning("'" + description + "' contains unsupported SignatureScheme: " + name);
continue;
}
if (!signatureSchemeInfo.isEnabled())
{
LOG.warning("'" + description + "' contains disabled SignatureScheme: " + name);
continue;
}
result[count++] = signatureScheme;
}
if (count < result.length)
{
result = Arrays.copyOf(result, count);
}
if (result.length < 1)
{
LOG.severe("'" + description + "' contained no usable SignatureScheme values");
}
return result;
}
private static int[] createCandidatesDefault()
{
All[] values = All.values();
int[] result = new int[values.length];
for (int i = 0; i < values.length; ++i)
{
result[i] = values[i].signatureScheme;
}
return result;
}
private static Map createIndex(boolean isFipsContext, JcaTlsCrypto crypto,
NamedGroupInfo.PerContext ng)
{
Map ss = new TreeMap();
for (All all : All.values())
{
addSignatureScheme(isFipsContext, crypto, ng, ss, all);
}
return ss;
}
private static int getSignatureSchemeByName(String name)
{
for (All all : All.values())
{
if (all.name.equalsIgnoreCase(name))
{
return all.signatureScheme;
}
}
return -1;
}
private static boolean isECDSA(int signatureScheme)
{
switch (signatureScheme)
{
case SignatureScheme.ecdsa_brainpoolP256r1tls13_sha256:
case SignatureScheme.ecdsa_brainpoolP384r1tls13_sha384:
case SignatureScheme.ecdsa_brainpoolP512r1tls13_sha512:
case SignatureScheme.ecdsa_secp256r1_sha256:
case SignatureScheme.ecdsa_secp384r1_sha384:
case SignatureScheme.ecdsa_secp521r1_sha512:
case SignatureScheme.ecdsa_sha1:
case historical_ecdsa_sha224:
return true;
default:
return false;
}
}
private final All all;
private final AlgorithmParameters algorithmParameters;
private final NamedGroupInfo namedGroupInfo;
private final boolean enabled;
private final boolean disabled13;
SignatureSchemeInfo(All all, AlgorithmParameters algorithmParameters, NamedGroupInfo namedGroupInfo,
boolean enabled, boolean disabled13)
{
this.all = all;
this.algorithmParameters = algorithmParameters;
this.namedGroupInfo = namedGroupInfo;
this.enabled = enabled;
this.disabled13 = disabled13;
}
short getHashAlgorithm()
{
return SignatureScheme.getHashAlgorithm(all.signatureScheme);
}
String getJcaSignatureAlgorithm()
{
return all.jcaSignatureAlgorithm;
}
String getJcaSignatureAlgorithmBC()
{
return all.jcaSignatureAlgorithmBC;
}
String getKeyType()
{
return all.keyAlgorithm;
}
String getKeyType13()
{
return all.keyType13;
}
String getName()
{
return all.name;
}
NamedGroupInfo getNamedGroupInfo()
{
return namedGroupInfo;
}
short getSignatureAlgorithm()
{
return SignatureScheme.getSignatureAlgorithm(all.signatureScheme);
}
SignatureAndHashAlgorithm getSignatureAndHashAlgorithm()
{
return getSignatureAndHashAlgorithm(all.signatureScheme);
}
int getSignatureScheme()
{
return all.signatureScheme;
}
boolean isEnabled()
{
return enabled;
}
boolean isSupportedPost13()
{
return !disabled13 && all.supportedPost13;
}
boolean isSupportedPre13()
{
return all.supportedPre13;
}
boolean isSupportedCerts13()
{
return !disabled13 && all.supportedCerts13;
}
@Override
public String toString()
{
return all.text;
}
// TODO Refactor to use this in non-cert contexts (careful for signatureSchemesCert defaulting case)
// private boolean isActive(BCAlgorithmConstraints algorithmConstraints, boolean post13Active, boolean pre13Active,
// NamedGroupInfo.PerConnection namedGroupInfos)
// {
// return enabled
// && isNamedGroupOK(post13Active && isSupportedPost13(), pre13Active && isSupportedPre13(), namedGroupInfos)
// && isPermittedBy(algorithmConstraints);
// }
private boolean isActiveCerts(BCAlgorithmConstraints algorithmConstraints, boolean post13Active,
boolean pre13Active, NamedGroupInfo.PerConnection namedGroupInfos)
{
return enabled
&& isNamedGroupOK(post13Active && isSupportedCerts13(), pre13Active && isSupportedPre13(), namedGroupInfos)
&& isPermittedBy(algorithmConstraints);
}
private boolean isNamedGroupOK(boolean post13Allowed, boolean pre13Allowed, NamedGroupInfo.PerConnection namedGroupInfos)
{
if (null != namedGroupInfo)
{
// TODO[tls13] NOTE: a "restricted group" scheme actually supporting TLS 1.3 usage
return (post13Allowed && NamedGroupInfo.hasLocal(namedGroupInfos, namedGroupInfo.getNamedGroup()))
// TODO[tls13] NOTE: this can result in a "restricted group" scheme being active, but not actually supporting TLS 1.3
|| (pre13Allowed && NamedGroupInfo.hasAnyECDSALocal(namedGroupInfos));
}
return (post13Allowed || pre13Allowed)
&& (!isECDSA(all.signatureScheme) || NamedGroupInfo.hasAnyECDSALocal(namedGroupInfos));
}
private boolean isPermittedBy(BCAlgorithmConstraints algorithmConstraints)
{
Set primitives = JsseUtils.SIGNATURE_CRYPTO_PRIMITIVES_BC;
return algorithmConstraints.permits(primitives, all.name, null)
&& algorithmConstraints.permits(primitives, all.keyAlgorithm, null)
&& algorithmConstraints.permits(primitives, all.jcaSignatureAlgorithm, algorithmParameters);
}
}