Skip to content

Commit aab0448

Browse files
committed
(D)TLS: JcaTlsCrypto dynamically checks ML-DSA, SLH-DSA support
1 parent ebb64fd commit aab0448

File tree

1 file changed

+67
-30
lines changed

1 file changed

+67
-30
lines changed

tls/src/main/java/org/bouncycastle/tls/crypto/impl/jcajce/JcaTlsCrypto.java

Lines changed: 67 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ public class JcaTlsCrypto
9393
private final Hashtable supportedEncryptionAlgorithms = new Hashtable();
9494
private final Hashtable supportedNamedGroups = new Hashtable();
9595
private final Hashtable supportedOther = new Hashtable();
96+
private final Hashtable supportedSignatureSchemes = new Hashtable();
9697

9798
/**
9899
* Base constructor.
@@ -795,43 +796,35 @@ public boolean hasSignatureAndHashAlgorithm(SignatureAndHashAlgorithm sigAndHash
795796

796797
public boolean hasSignatureScheme(int signatureScheme)
797798
{
798-
switch (signatureScheme)
799+
final Integer key = Integers.valueOf(signatureScheme);
800+
synchronized (supportedSignatureSchemes)
801+
{
802+
Boolean cached = (Boolean)supportedSignatureSchemes.get(key);
803+
if (cached != null)
804+
{
805+
return cached.booleanValue();
806+
}
807+
}
808+
809+
Boolean supported = isSupportedSignatureScheme(signatureScheme);
810+
if (null == supported)
799811
{
800-
case SignatureScheme.sm2sig_sm3:
801812
return false;
802-
// TODO[tls] Dynamic detection of the signature algorithm
803-
case SignatureScheme.mldsa44:
804-
case SignatureScheme.mldsa65:
805-
case SignatureScheme.mldsa87:
806-
case SignatureScheme.DRAFT_slhdsa_sha2_128s:
807-
case SignatureScheme.DRAFT_slhdsa_sha2_128f:
808-
case SignatureScheme.DRAFT_slhdsa_sha2_192s:
809-
case SignatureScheme.DRAFT_slhdsa_sha2_192f:
810-
case SignatureScheme.DRAFT_slhdsa_sha2_256s:
811-
case SignatureScheme.DRAFT_slhdsa_sha2_256f:
812-
case SignatureScheme.DRAFT_slhdsa_shake_128s:
813-
case SignatureScheme.DRAFT_slhdsa_shake_128f:
814-
case SignatureScheme.DRAFT_slhdsa_shake_192s:
815-
case SignatureScheme.DRAFT_slhdsa_shake_192f:
816-
case SignatureScheme.DRAFT_slhdsa_shake_256s:
817-
case SignatureScheme.DRAFT_slhdsa_shake_256f:
818-
return true;
819-
default:
813+
}
814+
815+
synchronized (supportedSignatureSchemes)
820816
{
821-
short signature = SignatureScheme.getSignatureAlgorithm(signatureScheme);
817+
Boolean cached = (Boolean)supportedSignatureSchemes.put(key, supported);
822818

823-
switch (SignatureScheme.getCryptoHashAlgorithm(signatureScheme))
819+
// Unlikely, but we want a consistent result
820+
if (null != cached && supported != cached)
824821
{
825-
case CryptoHashAlgorithm.md5:
826-
return SignatureAlgorithm.rsa == signature && hasSignatureAlgorithm(signature);
827-
case CryptoHashAlgorithm.sha224:
828-
// Somewhat overkill, but simpler for now. It's also consistent with SunJSSE behaviour.
829-
return !JcaUtils.isSunMSCAPIProviderActive() && hasSignatureAlgorithm(signature);
830-
default:
831-
return hasSignatureAlgorithm(signature);
822+
supportedSignatureSchemes.put(key, cached);
823+
supported = cached;
832824
}
833825
}
834-
}
826+
827+
return supported.booleanValue();
835828
}
836829

837830
public boolean hasSRPAuthentication()
@@ -1267,6 +1260,50 @@ else if (NamedGroup.refersToASpecificFiniteField(namedGroup))
12671260
return null;
12681261
}
12691262

1263+
protected Boolean isSupportedSignatureScheme(int signatureScheme)
1264+
{
1265+
try
1266+
{
1267+
if (SignatureScheme.isMLDSA(signatureScheme))
1268+
{
1269+
helper.createSignature("ML-DSA");
1270+
return Boolean.TRUE;
1271+
}
1272+
1273+
if (SignatureScheme.isSLHDSA(signatureScheme))
1274+
{
1275+
helper.createSignature("SLH-DSA");
1276+
return Boolean.TRUE;
1277+
}
1278+
1279+
switch (signatureScheme)
1280+
{
1281+
case SignatureScheme.sm2sig_sm3:
1282+
return Boolean.FALSE;
1283+
1284+
default:
1285+
{
1286+
short signature = SignatureScheme.getSignatureAlgorithm(signatureScheme);
1287+
1288+
switch (SignatureScheme.getCryptoHashAlgorithm(signatureScheme))
1289+
{
1290+
case CryptoHashAlgorithm.md5:
1291+
return Boolean.valueOf(SignatureAlgorithm.rsa == signature && hasSignatureAlgorithm(signature));
1292+
case CryptoHashAlgorithm.sha224:
1293+
// Somewhat overkill, but simpler for now. It's also consistent with SunJSSE behaviour.
1294+
return Boolean.valueOf(!JcaUtils.isSunMSCAPIProviderActive() && hasSignatureAlgorithm(signature));
1295+
default:
1296+
return Boolean.valueOf(hasSignatureAlgorithm(signature));
1297+
}
1298+
}
1299+
}
1300+
}
1301+
catch (GeneralSecurityException e)
1302+
{
1303+
return Boolean.FALSE;
1304+
}
1305+
}
1306+
12701307
protected boolean isUsableCipher(String cipherAlgorithm, int keySize)
12711308
{
12721309
try

0 commit comments

Comments
 (0)