@@ -48,6 +48,7 @@ internal sealed class CertificateAuthority : IDisposable
4848 private static readonly Asn1Tag s_context1 = new Asn1Tag ( TagClass . ContextSpecific , 1 ) ;
4949 private static readonly Asn1Tag s_context2 = new Asn1Tag ( TagClass . ContextSpecific , 2 ) ;
5050 private static readonly KeyFactory [ ] s_variantKeyFactories = KeyFactory . BuildVariantFactories ( ) ;
51+ private static readonly KeyFactory [ ] s_tlsVariantKeyFactories = KeyFactory . BuildTlsVariantFactories ( ) ;
5152
5253 private static readonly X500DistinguishedName s_nonParticipatingName =
5354 new X500DistinguishedName ( "CN=The Ghost in the Machine" ) ;
@@ -804,6 +805,7 @@ internal static void BuildPrivatePki(
804805 bool pkiOptionsInSubject = false ,
805806 string subjectName = null ,
806807 KeyFactory keyFactory = null ,
808+ bool forTls = false ,
807809 X509ExtensionCollection extensions = null )
808810 {
809811 bool rootDistributionViaHttp = ! pkiOptions . HasFlag ( PkiOptions . NoRootCertDistributionUri ) ;
@@ -842,9 +844,10 @@ internal static void BuildPrivatePki(
842844 int written = hasher . GetCurrentHash ( hash ) ;
843845 Debug . Assert ( written == hash . Length ) ;
844846
845- // Using mod here will create an imbalance any time s_variantKeyFactories isn't a power of 2,
847+ // Using mod here will create an imbalance any time the key factories array isn't a power of 2,
846848 // but that's OK.
847- keyFactory = s_variantKeyFactories [ hash [ 0 ] % s_variantKeyFactories . Length ] ;
849+ KeyFactory [ ] keyFactories = forTls ? s_tlsVariantKeyFactories : s_variantKeyFactories ;
850+ keyFactory = keyFactories [ hash [ 0 ] % keyFactories . Length ] ;
848851 }
849852 }
850853
@@ -946,6 +949,7 @@ internal static void BuildPrivatePki(
946949 bool pkiOptionsInSubject = false ,
947950 string subjectName = null ,
948951 KeyFactory keyFactory = null ,
952+ bool forTls = false ,
949953 X509ExtensionCollection extensions = null )
950954 {
951955 BuildPrivatePki (
@@ -960,6 +964,7 @@ internal static void BuildPrivatePki(
960964 pkiOptionsInSubject : pkiOptionsInSubject ,
961965 subjectName : subjectName ,
962966 keyFactory : keyFactory ,
967+ forTls : forTls ,
963968 extensions : extensions ) ;
964969
965970 intermediateAuthority = intermediateAuthorities . Single ( ) ;
@@ -1052,6 +1057,29 @@ internal static KeyFactory[] BuildVariantFactories()
10521057
10531058 return factories . ToArray ( ) ;
10541059 }
1060+
1061+ internal static KeyFactory [ ] BuildTlsVariantFactories ( )
1062+ {
1063+ List < KeyFactory > factories = [ RSASize ( 2048 ) , ECDsa ] ;
1064+
1065+ if ( ! RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
1066+ {
1067+ if ( Cryptography . MLDsa . IsSupported )
1068+ {
1069+ factories . Add ( MLDsa ) ;
1070+ }
1071+
1072+ // OpenSSL default provider does not advertise SLH-DSA in TLS-SIGALG capability,
1073+ // causing it to not recognize SLH-DSA certificates for use in TLS connections
1074+ // [ActiveIssue("https://github.com/dotnet/runtime/issues/119573")]
1075+ if ( ! PlatformDetection . IsOpenSslSupported && Cryptography . SlhDsa . IsSupported )
1076+ {
1077+ factories . Add ( SlhDsa ) ;
1078+ }
1079+ }
1080+
1081+ return factories . ToArray ( ) ;
1082+ }
10551083 }
10561084
10571085 private sealed class KeyHolder : IDisposable
0 commit comments