Skip to content

Commit bc1249a

Browse files
PranavSenthilnathanvcsjonesbartonjs
authored
ML-DSA PFX support (#115758)
Co-authored-by: Kevin Jones <vcsjones@github.com> Co-authored-by: Jeremy Barton <jbarton@microsoft.com>
1 parent e117adb commit bc1249a

File tree

19 files changed

+2636
-9
lines changed

19 files changed

+2636
-9
lines changed

src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ internal enum EvpAlgorithmFamilyId
339339
ECC = 3,
340340
MLKem = 4,
341341
SlhDsa = 5,
342+
MLDsa = 6,
342343
}
343344
}
344345
}

src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaImplementationTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -517,16 +517,16 @@ public void RoundTrip_Import_Export_Pkcs8PrivateKeyPem(MLDsaKeyInfo info)
517517
{
518518
MLDsaTestHelpers.AssertImportFromPem(import =>
519519
MLDsaTestHelpers.AssertExportToPrivateKeyPem(export =>
520-
WithDispose(import(info.PrivateKeyPem), mldsa =>
521-
Assert.Equal(info.PrivateKeyPem, export(mldsa)))));
520+
WithDispose(import(info.PrivateKeyPem_Seed), mldsa =>
521+
Assert.Equal(info.PrivateKeyPem_Seed, export(mldsa)))));
522522
}
523523

524524
[Theory]
525525
[MemberData(nameof(MLDsaTestsData.IetfMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))]
526526
public void RoundTrip_EncryptedPrivateKey(MLDsaKeyInfo info)
527527
{
528528
// Load key
529-
using MLDsa mldsa = MLDsa.ImportEncryptedPkcs8PrivateKey(info.EncryptionPassword, info.Pkcs8EncryptedPrivateKey);
529+
using MLDsa mldsa = MLDsa.ImportEncryptedPkcs8PrivateKey(info.EncryptionPassword, info.Pkcs8EncryptedPrivateKey_Seed);
530530

531531
byte[] secretKey = new byte[mldsa.Algorithm.SecretKeySizeInBytes];
532532
mldsa.ExportMLDsaSecretKey(secretKey);

src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestHelpers.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ namespace System.Security.Cryptography.Tests
1212
{
1313
internal static class MLDsaTestHelpers
1414
{
15+
internal static bool MLDsaIsNotSupported => !MLDsa.IsSupported;
16+
1517
// DER encoding of ASN.1 BitString "foo"
1618
internal static readonly ReadOnlyMemory<byte> s_derBitStringFoo = new byte[] { 0x03, 0x04, 0x00, 0x66, 0x6f, 0x6f };
1719

src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.Ietf.cs

Lines changed: 1918 additions & 0 deletions
Large diffs are not rendered by default.

src/libraries/Common/tests/System/Security/Cryptography/AlgorithmImplementations/MLDsa/MLDsaTestsData.cs

Lines changed: 146 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33

44
using System.Collections.Generic;
55
using System.Text;
6-
using Microsoft.DotNet.XUnitExtensions;
76
using Test.Cryptography;
8-
using Xunit;
97

108
namespace System.Security.Cryptography.Tests
119
{
@@ -18,8 +16,13 @@ public record MLDsaKeyInfo(
1816
string Pkcs8PrivateKey_Expanded_Base64,
1917
string Pkcs8PrivateKey_Both_Base64,
2018
string Pkcs8PublicKeyBase64,
21-
string Pkcs8EncryptedPrivateKeyBase64,
19+
string Pkcs8EncryptedPrivateKey_Seed_Base64,
20+
string Pkcs8EncryptedPrivateKey_Expanded_Base64,
21+
string Pkcs8EncryptedPrivateKey_Both_Base64,
2222
string CertificateBase64,
23+
string Pfx_Seed_Base64,
24+
string Pfx_Expanded_Base64,
25+
string Pfx_Both_Base64,
2326
string EncryptionPassword,
2427
PbeParameters EncryptionParameters)
2528
{
@@ -30,12 +33,22 @@ public record MLDsaKeyInfo(
3033
public byte[] Pkcs8PrivateKey_Expanded => Convert.FromBase64String(Pkcs8PrivateKey_Expanded_Base64);
3134
public byte[] Pkcs8PrivateKey_Both => Convert.FromBase64String(Pkcs8PrivateKey_Both_Base64);
3235
public byte[] Pkcs8PublicKey => Convert.FromBase64String(Pkcs8PublicKeyBase64);
33-
public byte[] Pkcs8EncryptedPrivateKey => Convert.FromBase64String(Pkcs8EncryptedPrivateKeyBase64);
36+
public byte[] Pkcs8EncryptedPrivateKey_Seed => Convert.FromBase64String(Pkcs8EncryptedPrivateKey_Seed_Base64);
37+
public byte[] Pkcs8EncryptedPrivateKey_Expanded => Convert.FromBase64String(Pkcs8EncryptedPrivateKey_Expanded_Base64);
38+
public byte[] Pkcs8EncryptedPrivateKey_Both => Convert.FromBase64String(Pkcs8EncryptedPrivateKey_Both_Base64);
3439
public byte[] EncryptionPasswordBytes => Encoding.UTF8.GetBytes(EncryptionPassword); // Assuming UTF-8 encoding
3540
public byte[] Certificate => Convert.FromBase64String(CertificateBase64);
36-
public string EncryptedPem => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey);
37-
public string PrivateKeyPem => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Seed);
41+
public string EncryptedPem_Seed => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Seed);
42+
public string EncryptedPem_Expanded => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Expanded);
43+
public string EncryptedPem_Both => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Both);
44+
public string PrivateKeyPem_Seed => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Seed);
45+
public string PrivateKeyPem_Expanded => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Expanded);
46+
public string PrivateKeyPem_Both => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Both);
3847
public string PublicKeyPem => PemEncoding.WriteString("PUBLIC KEY", Pkcs8PublicKey);
48+
public string CertificatePem => PemEncoding.WriteString("CERTIFICATE", Certificate);
49+
public byte[] Pfx_Seed => Convert.FromBase64String(Pfx_Seed_Base64);
50+
public byte[] Pfx_Expanded => Convert.FromBase64String(Pfx_Expanded_Base64);
51+
public byte[] Pfx_Both => Convert.FromBase64String(Pfx_Both_Base64);
3952

4053
public override string ToString() =>
4154
$"{nameof(MLDsaKeyInfo)} {{ {nameof(Algorithm)} = \"{Algorithm.Name}\" }}";
@@ -2202,5 +2215,132 @@ public static IEnumerable<object[]> AllNistTestCases()
22022215
"00000000000000000000000000000000000000090F13161E242832",
22032216
},
22042217
];
2218+
2219+
internal static byte[] IetfMLDsa_Pfx_Pbes1 => field ??= Convert.FromBase64String(
2220+
"""
2221+
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
2344+
""");
22052345
}
22062346
}

src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3225,6 +3225,8 @@ public Pkcs12LoadLimitExceededException(string propertyName) { }
32253225
public sealed partial class PublicKey
32263226
{
32273227
public PublicKey(System.Security.Cryptography.AsymmetricAlgorithm key) { }
3228+
[System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006")]
3229+
public PublicKey(System.Security.Cryptography.MLDsa key) { }
32283230
[System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
32293231
public PublicKey(System.Security.Cryptography.MLKem key) { }
32303232
public PublicKey(System.Security.Cryptography.Oid oid, System.Security.Cryptography.AsnEncodedData? parameters, System.Security.Cryptography.AsnEncodedData keyValue) { }

src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/OpenSslExportProvider.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ protected override byte[] ExportPkcs8(
5656
}
5757
}
5858

59+
if (evpAlgId == Interop.Crypto.EvpAlgorithmFamilyId.MLDsa)
60+
{
61+
using (MLDsaOpenSsl mldsa = new MLDsaOpenSsl(privateKey))
62+
{
63+
return mldsa.ExportEncryptedPkcs8PrivateKey(password, pbeParameters);
64+
}
65+
}
66+
5967
if (evpAlgId == Interop.Crypto.EvpAlgorithmFamilyId.SlhDsa)
6068
{
6169
using (SlhDsaOpenSsl slhDsa = new SlhDsaOpenSsl(privateKey))

src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/PublicKey.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,23 @@ public PublicKey(MLKem key) : this(key.ExportSubjectPublicKeyInfo())
7474
{
7575
}
7676

77+
/// <summary>
78+
/// Initializes a new instance of the <see cref="PublicKey" /> class
79+
/// using SubjectPublicKeyInfo from an <see cref="MLDsa" />.
80+
/// </summary>
81+
/// <param name="key">
82+
/// An <see cref="MLDsa" /> key to obtain the SubjectPublicKeyInfo from.
83+
/// </param>
84+
/// <exception cref="CryptographicException">
85+
/// The SubjectPublicKeyInfo could not be decoded. The
86+
/// <see cref="MLDsa.ExportSubjectPublicKeyInfo" /> must return a
87+
/// valid ASN.1-DER encoded X.509 SubjectPublicKeyInfo.
88+
/// </exception>
89+
[Experimental(Experimentals.PostQuantumCryptographyDiagId)]
90+
public PublicKey(MLDsa key) : this(key.ExportSubjectPublicKeyInfo())
91+
{
92+
}
93+
7794
/// <summary>
7895
/// Initializes a new instance of the <see cref="PublicKey" /> class
7996
/// using SubjectPublicKeyInfo from an <see cref="SlhDsa" />.

src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,12 @@ Oids.EcPublicKey when IsECDsa(certificate) =>
12821282
[PemLabels.Pkcs8PrivateKey],
12831283
MLKem.ImportFromPem,
12841284
certificate.CopyWithPrivateKey),
1285+
Oids.MLDsa44 or Oids.MLDsa65 or Oids.MLDsa87 =>
1286+
ExtractKeyFromPem<MLDsa>(
1287+
keyPem,
1288+
[PemLabels.Pkcs8PrivateKey],
1289+
MLDsa.ImportFromPem,
1290+
certificate.CopyWithPrivateKey),
12851291
_ when Helpers.IsSlhDsaOid(keyAlgorithm) =>
12861292
ExtractKeyFromPem<SlhDsa>(
12871293
keyPem,
@@ -1375,6 +1381,12 @@ Oids.EcPublicKey when IsECDsa(certificate) =>
13751381
password,
13761382
MLKem.ImportFromEncryptedPem,
13771383
certificate.CopyWithPrivateKey),
1384+
Oids.MLDsa44 or Oids.MLDsa65 or Oids.MLDsa87 =>
1385+
ExtractKeyFromEncryptedPem<MLDsa>(
1386+
keyPem,
1387+
password,
1388+
MLDsa.ImportFromEncryptedPem,
1389+
certificate.CopyWithPrivateKey),
13781390
_ when Helpers.IsSlhDsaOid(keyAlgorithm) =>
13791391
ExtractKeyFromEncryptedPem<SlhDsa>(
13801392
keyPem,

0 commit comments

Comments
 (0)