Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Support SLH-DSA keys in certs #115212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 2, 2025

Conversation

PranavSenthilnathan
Copy link
Member

Implementation mirrors ML-KEM (#114743 and #115100) and ML-DSA (#114471).

  • Certificate request
  • X509Certificate2
  • Certificate revocation list
  • PEM and PFX (loading and exporting)
  • Tests

Note: SlhDsaTestData.cs now is very large after adding pem and pfx cert raw data for each algorithm (generated from the OpenSsl CLI). The alternative is to generate these certs in the test itself, but the current approach avoids internal dependencies and allows validation against an external implementation.

@Copilot Copilot AI review requested due to automatic review settings May 1, 2025 01:11
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

1 similar comment
Copy link

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces SLH-DSA key support in certificate-related APIs to mirror previous implementations for ML-KEM and ML-DSA. Key changes include new public methods for SLH-DSA key extraction and conversion in PublicKey, certificate readers/exporters, and certificate request APIs, as well as necessary updates across platform-specific implementations and helper classes.

Reviewed Changes

Copilot reviewed 39 out of 40 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
PublicKey.cs Added GetSlhDsaPublicKey() to retrieve the SLH-DSA public key.
OpenSslX509CertificateReader.cs Introduced GetSlhDsaPrivateKey() and CopyWithPrivateKey overloads for SLH-DSA.
OpenSslExportProvider.cs Added export path for SLH-DSA cert export.
ICertificatePal.cs Extended interface with SLH-DSA key retrieval and copy methods.
CertificateRevocationListBuilder.Build.cs Handled multiple SLH-DSA OIDs for signature generation.
CertificateRequest.cs Added new constructors for SLH-DSA keys and adjusted self-signed certificate creation.
CertificateRequest.Load.cs Updated signature verification to include SLH-DSA keys.
Platform-specific CertificatePal files Updated implementations to indicate lack of SLH-DSA support where applicable.
SlhDsaImplementation.* Updated internal SLH-DSA implementation signatures and helper methods.
Ref/System.Security.Cryptography.cs Updated public reference to include SLH-DSA related APIs.
Common tests and helpers Added SLH-DSA related test helpers and updated certificate authority tests.
SlhDsaAlgorithm.cs & Interop.EvpPkey.cs Adjusted algorithm lookup and added enum definition for SLH-DSA.
Files not reviewed (1)
  • src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj: Language not supported

Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones
See info in area-owners.md if you want to be subscribed.

Co-authored-by: Kevin Jones <[email protected]>
@@ -8,7 +8,7 @@

namespace System.Security.Cryptography.SLHDsa.Tests
{
public static class SlhDsaTestData
public static partial class SlhDsaTestData
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub warning that the other partial segment is too big has me wondering if we're over-testing. E.g. perhaps we should check all algorithms in generate, but we can probably get by with a ladder of "do each size, but alternate between SHAKE and SHA-2 as we go up the ladder".

If our test runtime hasn't grown out of control from this, and we think we're done editing that other segment then it's probably fine.

RSA has way too many options, so we spot check. ML-DSA and ML-KEM have "the biggest, the smallest, and (the only) one from the middle". EC-DSA/EC-DH have a lot of curve options, we mostly spot check. But here we have this "it's small enough that 'everything' is feasible, but large enough that it might be a bad idea".

So, no change immediately requested... but just sharing where my feelings are.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, no change immediately requested... but just sharing where my feelings are.

Yeah I kind of weighed this in my head. Part of what made me waffle on this is that, unlike ecPublicKey, each and every SLH-DSA algorithm is a distinct algorithm OID.

Copy link
Member Author

@PranavSenthilnathan PranavSenthilnathan May 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this during an earlier PR and generally I went with testing everything unless it includes signing. When it has signing then we can just test the 'f' and 2 or 3 of the 's' since 's' + 'SHAKE' is the real time consumer.

I'm wary of typos that could sneak in because all the algos need to be enumerated in the source code (as OIDs generally). But if import and export generally works, then that's enough confidence that we went from OID to the SlhDsa implementation and we don't need to check signing on each one (except the basic signing tests on SlhDsa itself).

That's actually another reason that I included the certs as data instead of generating them at runtime - to avoid the self-signing cost.

@PranavSenthilnathan PranavSenthilnathan merged commit 7fae5e0 into dotnet:main May 2, 2025
98 checks passed
@filipnavara
Copy link
Member

The tests seem to be failing quite a lot on my CI runs for PRs:

https://dev.azure.com/dnceng-public/public/_build/results?buildId=1032891&view=ms.vss-test-web.build-test-results-tab&runId=27745738&resultId=205103&paneView=dotnet-dnceng.dnceng-anon-build-release-tasks.helix-anon-test-information-tab
https://helixr1107v0xdcypoyl9e7f.blob.core.windows.net/dotnet-runtime-refs-pull-115253-merge-3f173333270f4e529b/System.Security.Cryptography.Tests/1/console.099bcd36.log?skoid=8eda00af-b5ec-4be9-b69b-0919a2338892&sktid=72f988bf-86f1-41af-91ab-2d7cd011db47&skt=2025-05-03T12%3A18%3A10Z&ske=2025-05-03T13%3A18%3A10Z&sks=b&skv=2024-11-04&sv=2024-11-04&st=2025-05-03T12%3A18%3A10Z&se=2025-05-03T13%3A18%3A10Z&sr=c&sp=r&sig=3GR7lSivyx7anRwee6%2FmuZpbxU1PVxAj26C%2FiI9G9AQ%3D

    System.Security.Cryptography.X509Certificates.Tests.PfxTests.ReadSlhDsa_Pfx_Ietf_NotSupported(keyStorageFlags: DefaultKeySet) [FAIL]
      System.Security.Cryptography.CryptographicException : The specified network password is not correct.
      Stack Trace:
        /_/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.Windows.cs(274,0): at System.Security.Cryptography.X509Certificates.X509CertificateLoader.ImportPfx(ReadOnlySpan`1 data, ReadOnlySpan`1 password, X509KeyStorageFlags keyStorageFlags)
        /_/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.Windows.cs(51,0): at System.Security.Cryptography.X509Certificates.X509CertificateLoader.LoadPkcs12NoLimits(ReadOnlyMemory`1 data, ReadOnlySpan`1 password, X509KeyStorageFlags keyStorageFlags, Pkcs12Return& earlyReturn)
        /_/src/libraries/Common/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.Pkcs12.cs(65,0): at System.Security.Cryptography.X509Certificates.X509CertificateLoader.LoadPkcs12(ReadOnlyMemory`1 data, ReadOnlySpan`1 password, X509KeyStorageFlags keyStorageFlags, Pkcs12LoaderLimits loaderLimits)
        /_/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.netcore.cs(56,0): at System.Security.Cryptography.X509Certificates.X509CertificateLoader.LoadPkcs12Pal(ReadOnlySpan`1 data, ReadOnlySpan`1 password, X509KeyStorageFlags keyStorageFlags, Pkcs12LoaderLimits loaderLimits)
        /_/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.Import.cs(93,0): at System.Security.Cryptography.X509Certificates.CertificatePal.FromBlobOrFile(ReadOnlySpan`1 rawData, String fileName, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        /_/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/CertificatePal.Windows.Import.cs(15,0): at System.Security.Cryptography.X509Certificates.CertificatePal.FromBlob(ReadOnlySpan`1 rawData, SafePasswordHandle password, X509KeyStorageFlags keyStorageFlags)
        /_/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate.cs(101,0): at System.Security.Cryptography.X509Certificates.X509Certificate..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
        /_/src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509Certificate2.cs(76,0): at System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(Byte[] rawData, String password, X509KeyStorageFlags keyStorageFlags)
        /_/src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxTests.cs(702,0): at System.Security.Cryptography.X509Certificates.Tests.PfxTests.ReadSlhDsa_Pfx_Ietf_NotSupported(X509KeyStorageFlags keyStorageFlags)
           at System.RuntimeMethodHandle.InvokeMethod(ObjectHandleOnStack target, Void** arguments, ObjectHandleOnStack sig, BOOL isConstructor, ObjectHandleOnStack result)
        /_/src/coreclr/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.CoreCLR.cs(36,0): at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
        /_/src/libraries/System.Private.CoreLib/src/System/Reflection/MethodBaseInvoker.cs(174,0): at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr)

@vcsjones
Copy link
Member

vcsjones commented May 3, 2025

@filipnavara This is basically #115156 again except for SLH-DSA. The reason it fails is described in #115162.

I opened #115270 to unblock Build Analysis.

@filipnavara
Copy link
Member

The reason it fails is described in #115162.

Thanks! I suspected that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants