-
Notifications
You must be signed in to change notification settings - Fork 5.2k
ML-KEM: PKCS12/PFX Loading #115100
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
ML-KEM: PKCS12/PFX Loading #115100
Conversation
There was a problem hiding this 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 implements ML-KEM key support for loading PKCS#12/PFX files by introducing a new Pkcs12Key abstraction and corresponding derived types for ML-KEM and AsymmetricAlgorithm-based keys. Key changes include:
- Introducing an abstract Pkcs12Key type along with MLKemPkcs12PrivateKey and AsymmetricAlgorithmPkcs12PrivateKey implementations.
- Updating platform-specific certificate loaders (macOS, iOS, Unix, OpenSsl, and Android) to use the new key abstraction.
- Adding comprehensive unit tests in PfxTests.cs to validate ML-KEM key loading and behavior.
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxTests.cs | Adds new tests for various ML-KEM key loading scenarios and introduces a new MLKemIsNotSupported property. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.macOS.cs | Refactors CreateKey and GetPrivateKey to use Pkcs12Key instead of AsymmetricAlgorithm. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.iOS.cs | Updates key creation and handling to correctly pattern-match on Pkcs12Key, with diagnostic Debug.Fail for unsupported types. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.Unix.cs | Adjusts key matching and resource handling to support the Pkcs12Key abstraction. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.OpenSsl.cs | Adds ML-KEM support and refines key duplication logic using the new abstraction. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.Android.cs | Updates key creation using Pkcs12Key and ensures consistency in lambda usage for key factory methods. |
Comments suppressed due to low confidence (1)
src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.Android.cs:88
- [nitpick] For consistency with the RSA and ECDsa cases, consider using a static lambda (e.g. static () => new DSAImplementation.DSAAndroid()) for the DSA case.
return new AsymmetricAlgorithmPkcs12PrivateKey(pkcs8, () => new DSAImplementation.DSAAndroid());
....Cryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.iOS.cs
Outdated
Show resolved
Hide resolved
|
Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones |
This comment was marked as outdated.
This comment was marked as outdated.
| } | ||
| } | ||
|
|
||
| int32_t CryptoNative_EvpPKeyFamily(const EVP_PKEY* key) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally, I thought about trying to re-purpose CryptoNative_EvpPKeyType to not return the actual base ID, but instead just return an enum that we map (just like we do here). The problem with that is we really need the actual base ID from CryptoNative_EvpPKeyType because it passes the ID back to OpenSSL in some cases. We can't just arbitrarily make up our own base IDs (because, as far as I can tell, it always return "Unknown" for ML-KEM), so this became a separate function with its own enum values.
|
Latest run from runtime-ci. https://github.com/vcsjones/runtime-ci/actions/runs/14700741954 |
| } | ||
| } | ||
|
|
||
| internal abstract class Pkcs12Key : IDisposable |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should just implement AsymmetricAlgorithm at this point, there doesn't seem enough benefit not doing it. At least here you don't seem to need any new public APIs but IMO implementing will just make it easier for everyone
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m pretty firmly against it.
- It would only very minimally help this pull request. We still have quite a number of type tests
if (alg is RSAOpenSsl),if (alg is DSAOpenSsl), etc. Looking at it from a fresh perspective, all it would really do is make the SubjectPublicKeyInfo export easier. - Implementing AsymmetricAlgorithm significantly complicates implementation of the actual algorithm. It makes the algorithm instances mutable and it makes PKCS#8/SPKI import and export more difficult to support for .NET Framework because AsymmetricAlgorithm on .NET Framework doesn’t have any of the key loading methods.
Since it doesn’t help consumers of the algorithm, and it doesn’t help with the implementation of the algorithm, I guess I don’t see much of a reason to do it.
...ryptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.macOS.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Security.Cryptography/tests/X509Certificates/PfxTests.cs
Outdated
Show resolved
Hide resolved
...ptography/src/System/Security/Cryptography/X509Certificates/X509CertificateLoader.Android.cs
Outdated
Show resolved
Hide resolved
| return new AsymmetricAlgorithmPkcs12PrivateKey( | ||
| pkcs8, | ||
| static () => new RSAImplementation.RSAAndroid()); | ||
| case Oids.EcPublicKey or Oids.EcDiffieHellman: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it was already like this, but this change is making me realize how often we repeat code.
It'd be nice (in a future change) to have just a central registration of "here's my RSA importer, or null if I don't support RSA". Something like
private static partial KeyLoader GetKeyLoader();
...
private static partial KeyLoader GetKeyLoader()
{
return new KeyLoader(
rsa: pkcs8 => new ...,
ecc: ...but that's a very half-formed idea
This implements PKCS#12 / PFX loading for ML-KEM keys on platforms that support ML-KEM.
Since
MLKemand other PQC types do not derive fromAsymmetricAlgorithm, an encapsulating type (pun intended),Pkcs12Keywas introduced to abstract over the two.Pkcs12Keyis an abstract type. The expected way to add new algorithms, like SLH-DSA would be to implement a new derived type likeMLKemPkcs12PrivateKey, then wire in the OID mapping to return the new type for SLH-DSA private keys. The second place to touch isGetPrivateKey(Pkcs12Key key)to handle mapping the key type to duplicating the handle.