Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ internal enum EvpAlgorithmFamilyId
ECC = 3,
MLKem = 4,
SlhDsa = 5,
MLDsa = 6,
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -517,16 +517,16 @@ public void RoundTrip_Import_Export_Pkcs8PrivateKeyPem(MLDsaKeyInfo info)
{
MLDsaTestHelpers.AssertImportFromPem(import =>
MLDsaTestHelpers.AssertExportToPrivateKeyPem(export =>
WithDispose(import(info.PrivateKeyPem), mldsa =>
Assert.Equal(info.PrivateKeyPem, export(mldsa)))));
WithDispose(import(info.PrivateKeyPem_Seed), mldsa =>
Assert.Equal(info.PrivateKeyPem_Seed, export(mldsa)))));
}

[Theory]
[MemberData(nameof(MLDsaTestsData.IetfMLDsaAlgorithms), MemberType = typeof(MLDsaTestsData))]
public void RoundTrip_EncryptedPrivateKey(MLDsaKeyInfo info)
{
// Load key
using MLDsa mldsa = MLDsa.ImportEncryptedPkcs8PrivateKey(info.EncryptionPassword, info.Pkcs8EncryptedPrivateKey);
using MLDsa mldsa = MLDsa.ImportEncryptedPkcs8PrivateKey(info.EncryptionPassword, info.Pkcs8EncryptedPrivateKey_Seed);

byte[] secretKey = new byte[mldsa.Algorithm.SecretKeySizeInBytes];
mldsa.ExportMLDsaSecretKey(secretKey);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace System.Security.Cryptography.Tests
{
internal static class MLDsaTestHelpers
{
internal static bool MLDsaIsNotSupported => !MLDsa.IsSupported;

// DER encoding of ASN.1 BitString "foo"
internal static readonly ReadOnlyMemory<byte> s_derBitStringFoo = new byte[] { 0x03, 0x04, 0x00, 0x66, 0x6f, 0x6f };

Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@

using System.Collections.Generic;
using System.Text;
using Microsoft.DotNet.XUnitExtensions;
using Test.Cryptography;
using Xunit;

namespace System.Security.Cryptography.Tests
{
Expand All @@ -18,8 +16,13 @@ public record MLDsaKeyInfo(
string Pkcs8PrivateKey_Expanded_Base64,
string Pkcs8PrivateKey_Both_Base64,
string Pkcs8PublicKeyBase64,
string Pkcs8EncryptedPrivateKeyBase64,
string Pkcs8EncryptedPrivateKey_Seed_Base64,
string Pkcs8EncryptedPrivateKey_Expanded_Base64,
string Pkcs8EncryptedPrivateKey_Both_Base64,
string CertificateBase64,
string Pfx_Seed_Base64,
string Pfx_Expanded_Base64,
string Pfx_Both_Base64,
string EncryptionPassword,
PbeParameters EncryptionParameters)
{
Expand All @@ -30,12 +33,22 @@ public record MLDsaKeyInfo(
public byte[] Pkcs8PrivateKey_Expanded => Convert.FromBase64String(Pkcs8PrivateKey_Expanded_Base64);
public byte[] Pkcs8PrivateKey_Both => Convert.FromBase64String(Pkcs8PrivateKey_Both_Base64);
public byte[] Pkcs8PublicKey => Convert.FromBase64String(Pkcs8PublicKeyBase64);
public byte[] Pkcs8EncryptedPrivateKey => Convert.FromBase64String(Pkcs8EncryptedPrivateKeyBase64);
public byte[] Pkcs8EncryptedPrivateKey_Seed => Convert.FromBase64String(Pkcs8EncryptedPrivateKey_Seed_Base64);
public byte[] Pkcs8EncryptedPrivateKey_Expanded => Convert.FromBase64String(Pkcs8EncryptedPrivateKey_Expanded_Base64);
public byte[] Pkcs8EncryptedPrivateKey_Both => Convert.FromBase64String(Pkcs8EncryptedPrivateKey_Both_Base64);
public byte[] EncryptionPasswordBytes => Encoding.UTF8.GetBytes(EncryptionPassword); // Assuming UTF-8 encoding
public byte[] Certificate => Convert.FromBase64String(CertificateBase64);
public string EncryptedPem => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey);
public string PrivateKeyPem => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Seed);
public string EncryptedPem_Seed => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Seed);
public string EncryptedPem_Expanded => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Expanded);
public string EncryptedPem_Both => PemEncoding.WriteString("ENCRYPTED PRIVATE KEY", Pkcs8EncryptedPrivateKey_Both);
public string PrivateKeyPem_Seed => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Seed);
public string PrivateKeyPem_Expanded => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Expanded);
public string PrivateKeyPem_Both => PemEncoding.WriteString("PRIVATE KEY", Pkcs8PrivateKey_Both);
public string PublicKeyPem => PemEncoding.WriteString("PUBLIC KEY", Pkcs8PublicKey);
public string CertificatePem => PemEncoding.WriteString("CERTIFICATE", Certificate);
public byte[] Pfx_Seed => Convert.FromBase64String(Pfx_Seed_Base64);
public byte[] Pfx_Expanded => Convert.FromBase64String(Pfx_Expanded_Base64);
public byte[] Pfx_Both => Convert.FromBase64String(Pfx_Both_Base64);

public override string ToString() =>
$"{nameof(MLDsaKeyInfo)} {{ {nameof(Algorithm)} = \"{Algorithm.Name}\" }}";
Expand Down Expand Up @@ -2202,5 +2215,132 @@ public static IEnumerable<object[]> AllNistTestCases()
"00000000000000000000000000000000000000090F13161E242832",
},
];

internal static byte[] IetfMLDsa_Pfx_Pbes1 => field ??= Convert.FromBase64String(
"""
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
""");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3225,6 +3225,8 @@ public Pkcs12LoadLimitExceededException(string propertyName) { }
public sealed partial class PublicKey
{
public PublicKey(System.Security.Cryptography.AsymmetricAlgorithm key) { }
[System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006")]
public PublicKey(System.Security.Cryptography.MLDsa key) { }
[System.Diagnostics.CodeAnalysis.ExperimentalAttribute("SYSLIB5006", UrlFormat="https://aka.ms/dotnet-warnings/{0}")]
public PublicKey(System.Security.Cryptography.MLKem key) { }
public PublicKey(System.Security.Cryptography.Oid oid, System.Security.Cryptography.AsnEncodedData? parameters, System.Security.Cryptography.AsnEncodedData keyValue) { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ protected override byte[] ExportPkcs8(
}
}

if (evpAlgId == Interop.Crypto.EvpAlgorithmFamilyId.MLDsa)
{
using (MLDsaOpenSsl mldsa = new MLDsaOpenSsl(privateKey))
{
return mldsa.ExportEncryptedPkcs8PrivateKey(password, pbeParameters);
}
}

if (evpAlgId == Interop.Crypto.EvpAlgorithmFamilyId.SlhDsa)
{
using (SlhDsaOpenSsl slhDsa = new SlhDsaOpenSsl(privateKey))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@ public PublicKey(MLKem key) : this(key.ExportSubjectPublicKeyInfo())
{
}

/// <summary>
/// Initializes a new instance of the <see cref="PublicKey" /> class
/// using SubjectPublicKeyInfo from an <see cref="MLDsa" />.
/// </summary>
/// <param name="key">
/// An <see cref="MLDsa" /> key to obtain the SubjectPublicKeyInfo from.
/// </param>
/// <exception cref="CryptographicException">
/// The SubjectPublicKeyInfo could not be decoded. The
/// <see cref="MLDsa.ExportSubjectPublicKeyInfo" /> must return a
/// valid ASN.1-DER encoded X.509 SubjectPublicKeyInfo.
/// </exception>
[Experimental(Experimentals.PostQuantumCryptographyDiagId)]
public PublicKey(MLDsa key) : this(key.ExportSubjectPublicKeyInfo())
{
}

/// <summary>
/// Initializes a new instance of the <see cref="PublicKey" /> class
/// using SubjectPublicKeyInfo from an <see cref="SlhDsa" />.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1282,6 +1282,12 @@ Oids.EcPublicKey when IsECDsa(certificate) =>
[PemLabels.Pkcs8PrivateKey],
MLKem.ImportFromPem,
certificate.CopyWithPrivateKey),
Oids.MLDsa44 or Oids.MLDsa65 or Oids.MLDsa87 =>
ExtractKeyFromPem<MLDsa>(
keyPem,
[PemLabels.Pkcs8PrivateKey],
MLDsa.ImportFromPem,
certificate.CopyWithPrivateKey),
_ when Helpers.IsSlhDsaOid(keyAlgorithm) =>
ExtractKeyFromPem<SlhDsa>(
keyPem,
Expand Down Expand Up @@ -1375,6 +1381,12 @@ Oids.EcPublicKey when IsECDsa(certificate) =>
password,
MLKem.ImportFromEncryptedPem,
certificate.CopyWithPrivateKey),
Oids.MLDsa44 or Oids.MLDsa65 or Oids.MLDsa87 =>
ExtractKeyFromEncryptedPem<MLDsa>(
keyPem,
password,
MLDsa.ImportFromEncryptedPem,
certificate.CopyWithPrivateKey),
_ when Helpers.IsSlhDsaOid(keyAlgorithm) =>
ExtractKeyFromEncryptedPem<SlhDsa>(
keyPem,
Expand Down
Loading