Skip to content

ML-KEM: ImportFrom{Encrypted}Pem #114155

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 12 commits into from
Apr 4, 2025
Merged

Conversation

vcsjones
Copy link
Member

@vcsjones vcsjones commented Apr 2, 2025

This adds ImportFromPem and ImportFromEncryptedPem to MLKem.

Contributes to #113508

@vcsjones vcsjones added this to the 10.0.0 milestone Apr 2, 2025
@vcsjones vcsjones requested a review from bartonjs April 2, 2025 14:43
@vcsjones vcsjones self-assigned this Apr 2, 2025
@Copilot Copilot AI review requested due to automatic review settings April 2, 2025 14:43
@ghost
Copy link

ghost commented Apr 2, 2025

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
@ghost
Copy link

ghost commented Apr 2, 2025

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 pull request adds ImportFromPem functionality to MLKem, expanding the API to enable importing keys from RFC 7468 PEM-encoded strings.

  • Updates PemKeyHelpers to be a partial class to enable splitting of functionality
  • Adds ImportFromPem overloads in both the reference assembly and core implementation
  • Introduces a suite of tests to validate proper PEM import behavior and exception handling

Reviewed Changes

Copilot reviewed 8 out of 13 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/PemKeyHelpers.cs Changed to partial class to support new PEM import functionality
src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs Added ImportFromPem overloads in the reference API
src/libraries/Microsoft.Bcl.Cryptography/src/System/Security/Cryptography/PemEncoding.cs Added a downlevel PEM encoding implementation
src/libraries/Common/tests/System/Security/Cryptography/MLKemTests.cs Extended tests covering various ImportFromPem scenarios including ambiguous inputs and roundtrip validations
src/libraries/Common/tests/System/Security/Cryptography/MLKemNotSupportedTests.cs Added tests to ensure proper exception throwing in unsupported scenarios
src/libraries/Common/src/System/Security/Cryptography/PemKeyHelpers.Factory.cs Introduced a supporting factory method for PEM import processing
src/libraries/Common/src/System/Security/Cryptography/MLKem.cs Implemented ImportFromPem methods wrapping the new factory and PEM import logic
Files not reviewed (5)
  • eng/Versions.props: Language not supported
  • src/libraries/Microsoft.Bcl.Cryptography/src/Microsoft.Bcl.Cryptography.csproj: Language not supported
  • src/libraries/Microsoft.Bcl.Cryptography/src/Resources/Strings.resx: Language not supported
  • src/libraries/Microsoft.Bcl.Cryptography/tests/Microsoft.Bcl.Cryptography.Tests.csproj: Language not supported
  • src/libraries/System.Security.Cryptography/src/System.Security.Cryptography.csproj: Language not supported

Tip: Copilot code review supports C#, Go, Java, JavaScript, Markdown, Python, Ruby and TypeScript, with more languages coming soon. Learn more

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.

/// <exception cref="ArgumentNullException">
/// <paramref name="source" /> is <see langword="null" />
/// </exception>
public static MLKem ImportFromPem(string source)
Copy link
Member Author

Choose a reason for hiding this comment

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

This was not in the initial API design, and we don't have it on other types like RSA. However, I think it is useful for .NET Framework. In .NET Framework, there is no implicit conversion from string to ReadOnlySpan<char>. So even C# developers will be forced to use the AsSpan extension method, unless we give them a nice overload to use.

internal delegate TAlg ImportFactoryKeyAction<TAlg>(ReadOnlySpan<byte> source);
internal delegate ImportFactoryKeyAction<TAlg>? FindImportFactoryActionFunc<TAlg>(ReadOnlySpan<char> label);

internal static TAlg ImportFactoryPem<TAlg>(ReadOnlySpan<char> source, FindImportFactoryActionFunc<TAlg> callback) where TAlg : class
Copy link
Member Author

Choose a reason for hiding this comment

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

This is largely based on the already existing ImportPem from PemKeyHelpers. We need a new import method because the new PQC types have a different API shape than the ones on AsymmetricAlgorithm (they are static, and they don't out the number of bytes read).

Copy link
Member Author

Choose a reason for hiding this comment

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

I tried de-duping the logic between the two but it got real messy because the delegates are different types and we need type parameters in this one.

{
// Downlevel implementation of PemEncoding. This was originally taken from the .NET 5 implementation of PemEncoding
// https://github.com/dotnet/runtime/blob/4aadfea70082ae23e6c54a449268341e9429434e/src/libraries/System.Security.Cryptography.Encoding/src/System/Security/Cryptography/PemEncoding.cs
internal static class PemEncoding
Copy link
Member Author

Choose a reason for hiding this comment

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

This is basically a direct clone of the .NET 5 implementation from PemEncoding, with the exception of being internal the XML doc comments are stripped out, and not having the Write methods (yet).

// Tests for Downlevel implementation of PemEncoding. This was originally taken from the .NET 5 implementation of
// PemEncodingFindTests.
// https://github.com/dotnet/runtime/blob/4aadfea70082ae23e6c54a449268341e9429434e/src/libraries/System.Security.Cryptography.Encoding/tests/PemEncodingFindTests.cs
public abstract class PemEncodingFindTests
Copy link
Member Author

Choose a reason for hiding this comment

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

Likewise this is a copy from the .NET 5 unit tests, with some changes for visibility purposes.

<Compile Include="X509Certificates\TestFiles.cs" />
</ItemGroup>

<ItemGroup Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
<Compile Include="$(CoreLibSharedDir)System\Runtime\CompilerServices\IsExternalInit.cs"
Link="Common\System\Runtime\CompilerServices\IsExternalInit.cs" />
<Compile Include="$(LibrariesProjectRoot)\Microsoft.Bcl.Cryptography\src\System\Security\Cryptography\PemEncoding.cs"
Copy link
Member Author

Choose a reason for hiding this comment

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

Since our downlevel PemEncoding implementation is internal we can only test it by including it in the test project, and I don't want it untested. And we can only test in in the .NET Framework test target, since the netcoreapp ones will have the in-box one already.

@vcsjones vcsjones changed the title ML-KEM: ImportFromPem ML-KEM: ImportFrom{Encrypted}Pem Apr 2, 2025
Copy link
Member

@bartonjs bartonjs left a comment

Choose a reason for hiding this comment

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

LGTM, aside from the fact that all builds are on the floor.

@vcsjones
Copy link
Member Author

vcsjones commented Apr 3, 2025

Looks like build was fixed in #114233.

@vcsjones
Copy link
Member Author

vcsjones commented Apr 4, 2025

@vcsjones-bot test f7a9f18 with openssl-3.5

@vcsjones vcsjones merged commit 6dc03c2 into dotnet:main Apr 4, 2025
86 of 88 checks passed
@vcsjones vcsjones deleted the ml-kem-import-pem branch April 4, 2025 03:30
@github-actions github-actions bot locked and limited conversation to collaborators May 4, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants