Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
14 changes: 8 additions & 6 deletions src/libraries/Common/src/System/Security/Cryptography/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,16 @@ internal static int HashOidToByteLength(string hashOid)
internal static CryptographicException CreateAlgorithmUnknownException(AsnWriter encodedId)
{
#if NET10_0_OR_GREATER
return encodedId.Encode(static encoded =>
new CryptographicException(
SR.Format(SR.Cryptography_UnknownAlgorithmIdentifier, Convert.ToHexString(encoded))));
return encodedId.Encode(static encoded => CreateAlgorithmUnknownException(Convert.ToHexString(encoded)));
#else
return new CryptographicException(
SR.Format(SR.Cryptography_UnknownAlgorithmIdentifier,
HexConverter.ToString(encodedId.Encode(), HexConverter.Casing.Upper)));
return CreateAlgorithmUnknownException(HexConverter.ToString(encodedId.Encode(), HexConverter.Casing.Upper));
#endif
}

internal static CryptographicException CreateAlgorithmUnknownException(string algorithmId)
{
throw new CryptographicException(
SR.Format(SR.Cryptography_UnknownAlgorithmIdentifier, algorithmId));
}
}
}
14 changes: 12 additions & 2 deletions src/libraries/Common/src/System/Security/Cryptography/MLDsa.cs
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,12 @@ public static MLDsa ImportSubjectPublicKeyInfo(ReadOnlySpan<byte> source)
AsnValueReader reader = new AsnValueReader(source, AsnEncodingRules.DER);
SubjectPublicKeyInfoAsn.Decode(ref reader, manager.Memory, out SubjectPublicKeyInfoAsn spki);

MLDsaAlgorithm algorithm = MLDsaAlgorithm.GetMLDsaAlgorithmFromOid(spki.Algorithm.Algorithm);
MLDsaAlgorithm? algorithm = MLDsaAlgorithm.GetMLDsaAlgorithmFromOid(spki.Algorithm.Algorithm);

if (algorithm is null)
{
throw Helpers.CreateAlgorithmUnknownException(spki.Algorithm.Algorithm);
}

if (spki.Algorithm.Parameters.HasValue)
{
Expand Down Expand Up @@ -803,7 +808,12 @@ public static MLDsa ImportPkcs8PrivateKey(ReadOnlySpan<byte> source)
AsnValueReader reader = new AsnValueReader(source, AsnEncodingRules.DER);
PrivateKeyInfoAsn.Decode(ref reader, manager.Memory, out PrivateKeyInfoAsn pki);

MLDsaAlgorithm algorithm = MLDsaAlgorithm.GetMLDsaAlgorithmFromOid(pki.PrivateKeyAlgorithm.Algorithm);
MLDsaAlgorithm? algorithm = MLDsaAlgorithm.GetMLDsaAlgorithmFromOid(pki.PrivateKeyAlgorithm.Algorithm);

if (algorithm is null)
{
throw Helpers.CreateAlgorithmUnknownException(pki.PrivateKeyAlgorithm.Algorithm);
}

if (pki.PrivateKeyAlgorithm.Parameters.HasValue)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,22 +107,15 @@ private MLDsaAlgorithm(string name, int secretKeySizeInBytes, int publicKeySizeI
/// </value>
public static MLDsaAlgorithm MLDsa87 { get; } = new MLDsaAlgorithm("ML-DSA-87", 4896, 2592, 4627, Oids.MLDsa87);

internal static MLDsaAlgorithm GetMLDsaAlgorithmFromOid(string oid)
internal static MLDsaAlgorithm? GetMLDsaAlgorithmFromOid(string? oid)
{
return oid switch
{
Oids.MLDsa44 => MLDsa44,
Oids.MLDsa65 => MLDsa65,
Oids.MLDsa87 => MLDsa87,
_ => ThrowAlgorithmUnknown(oid),
_ => null,
};
}

[DoesNotReturn]
private static MLDsaAlgorithm ThrowAlgorithmUnknown(string algorithmId)
{
throw new CryptographicException(
SR.Format(SR.Cryptography_UnknownAlgorithmIdentifier, algorithmId));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Xunit;

namespace System.Security.Cryptography.Tests
{
internal sealed class MLDsaTestImplementation : MLDsa
{
internal delegate void ExportAction(Span<byte> destination);
internal delegate void SignAction(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, Span<byte> destination);
internal delegate bool VerifyFunc(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, ReadOnlySpan<byte> signature);

internal ExportAction ExportMLDsaPrivateSeedHook { get; set; }
internal ExportAction ExportMLDsaPublicKeyHook { get; set; }
internal ExportAction ExportMLDsaSecretKeyHook { get; set; }
internal SignAction SignDataHook { get; set; }
internal VerifyFunc VerifyDataHook { get; set; }
internal Action<bool> DisposeHook { get; set; } = _ => { };

private MLDsaTestImplementation(MLDsaAlgorithm algorithm) : base(algorithm)
{
}

protected override void Dispose(bool disposing) => DisposeHook(disposing);

protected override void ExportMLDsaPrivateSeedCore(Span<byte> destination) => ExportMLDsaPrivateSeedHook(destination);
protected override void ExportMLDsaPublicKeyCore(Span<byte> destination) => ExportMLDsaPublicKeyHook(destination);
protected override void ExportMLDsaSecretKeyCore(Span<byte> destination) => ExportMLDsaSecretKeyHook(destination);

protected override void SignDataCore(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, Span<byte> destination) =>
SignDataHook(data, context, destination);

protected override bool VerifyDataCore(ReadOnlySpan<byte> data, ReadOnlySpan<byte> context, ReadOnlySpan<byte> signature) =>
VerifyDataHook(data, context, signature);

internal static MLDsaTestImplementation CreateOverriddenCoreMethodsFail(MLDsaAlgorithm algorithm)
{
return new MLDsaTestImplementation(algorithm)
{
ExportMLDsaPrivateSeedHook = _ => Assert.Fail(),
ExportMLDsaPublicKeyHook = _ => Assert.Fail(),
ExportMLDsaSecretKeyHook = _ => Assert.Fail(),
SignDataHook = (_, _, _) => Assert.Fail(),
VerifyDataHook = (_, _, _) => { Assert.Fail(); return false; },
};
}

internal static MLDsaTestImplementation CreateNoOp(MLDsaAlgorithm algorithm)
{
return new MLDsaTestImplementation(algorithm)
{
ExportMLDsaPrivateSeedHook = d => d.Clear(),
ExportMLDsaPublicKeyHook = d => d.Clear(),
ExportMLDsaSecretKeyHook = d => d.Clear(),
SignDataHook = (data, context, destination) => destination.Clear(),
VerifyDataHook = (data, context, signature) => signature.IndexOfAnyExcept((byte)0) == -1,
};
}

internal static MLDsaTestImplementation Wrap(MLDsa other)
{
return new MLDsaTestImplementation(other.Algorithm)
{
ExportMLDsaPrivateSeedHook = d => other.ExportMLDsaPrivateSeed(d),
ExportMLDsaPublicKeyHook = d => other.ExportMLDsaPublicKey(d),
ExportMLDsaSecretKeyHook = d => other.ExportMLDsaSecretKey(d),
SignDataHook = (data, context, destination) => other.SignData(data, destination, context),
VerifyDataHook = (data, context, signature) => other.VerifyData(data, signature, context),
};
}
}
}
Loading
Loading