Skip to content

Commit b352164

Browse files
Copilotrzikmbartonjs
authored
Use forTls parameter to enable TLS-compatible certificate key types while maintaining platform compatibility (#119265)
* Initial plan * Add CRYPTO_TESTS preprocessor directive and differentiate RSA key sizes Co-authored-by: rzikm <[email protected]> * Add comprehensive tests to validate different RSA key sizes in crypto vs networking tests Co-authored-by: rzikm <[email protected]> * Switch to NETWORKING_TESTS directive and remove test files per feedback Co-authored-by: rzikm <[email protected]> * Remove explicit keyFactory parameter to use conditional RSA key sizes Co-authored-by: rzikm <[email protected]> * Add NETWORKING_TESTS directive to all networking test projects that use CertificateAuthority Co-authored-by: rzikm <[email protected]> * Implement forTls parameter approach for TLS-compatible certificate key type selection Co-authored-by: bartonjs <[email protected]> * Revert all .csproj changes as they are no longer needed Co-authored-by: bartonjs <[email protected]> * Add debug * Disable SLH-DSA on linux * Revert "Add debug" This reverts commit 11d2ce2. * Force RSA certificates for MsQuic on non-windows platform --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: rzikm <[email protected]> Co-authored-by: bartonjs <[email protected]> Co-authored-by: Radek Zikmund <[email protected]>
1 parent 524b082 commit b352164

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

src/libraries/Common/tests/System/Net/Configuration.Certificates.Dynamic.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,8 @@ public void Dispose()
162162
}
163163
}
164164

165-
internal static PkiHolder GenerateCertificates(string targetName, [CallerMemberName] string? testName = null, bool longChain = false, bool serverCertificate = true, bool ephemeralKey = false)
165+
internal static PkiHolder GenerateCertificates(string targetName, [CallerMemberName] string? testName = null, bool longChain = false, bool serverCertificate = true, bool ephemeralKey = false, bool forceRsaCertificate = false)
166166
{
167-
const int keySize = 2048;
168167
if (PlatformDetection.IsWindows && testName != null)
169168
{
170169
CleanupCertificates(testName);
@@ -182,7 +181,9 @@ internal static PkiHolder GenerateCertificates(string targetName, [CallerMemberN
182181
intermediateAuthorityCount: longChain ? 3 : 1,
183182
subjectName: targetName,
184183
testName: testName,
185-
keyFactory: CertificateAuthority.KeyFactory.RSASize(keySize),
184+
forTls: true,
185+
// [ActiveIssue("https://github.com/dotnet/runtime/issues/119641")]
186+
keyFactory: !forceRsaCertificate ? null : CertificateAuthority.KeyFactory.RSASize(2048),
186187
extensions: extensions);
187188

188189
if (!ephemeralKey && PlatformDetection.IsWindows)

src/libraries/Common/tests/System/Security/Cryptography/X509Certificates/CertificateAuthority.cs

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ public class CertificateSetup : IDisposable
3434

3535
public CertificateSetup()
3636
{
37-
_pkiHolder = Configuration.Certificates.GenerateCertificates("localhost", nameof(MsQuicTests), longChain: true);
37+
_pkiHolder = Configuration.Certificates.GenerateCertificates("localhost", nameof(MsQuicTests), longChain: true,
38+
// [ActiveIssue("https://github.com/dotnet/runtime/issues/119641")]
39+
forceRsaCertificate: !PlatformDetection.IsWindows);
3840
}
3941

4042
public SslStreamCertificateContext CreateSslStreamCertificateContext() => _pkiHolder.CreateSslStreamCertificateContext();
@@ -572,7 +574,9 @@ public async Task ConnectWithCertificateForLoopbackIP_IndicatesExpectedError(str
572574
throw new SkipTestException("IPv6 is not available on this platform");
573575
}
574576

575-
using Configuration.Certificates.PkiHolder pkiHolder = Configuration.Certificates.GenerateCertificates(expectsError ? "badhost" : "localhost");
577+
using Configuration.Certificates.PkiHolder pkiHolder = Configuration.Certificates.GenerateCertificates(expectsError ? "badhost" : "localhost",
578+
// [ActiveIssue("https://github.com/dotnet/runtime/issues/119641")]
579+
forceRsaCertificate: !PlatformDetection.IsWindows);
576580
X509Certificate2 certificate = pkiHolder.EndEntity;
577581

578582
var listenerOptions = new QuicListenerOptions()

0 commit comments

Comments
 (0)