@@ -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