Implement support for loading multiple providers into a single context#129477
Implement support for loading multiple providers into a single context#129477vcsjones wants to merge 6 commits into
Conversation
| { | ||
| ArgumentException.ThrowIfNullOrEmpty(providerName); | ||
| ArgumentException.ThrowIfNullOrEmpty(keyUri); | ||
| ValidateProviderName(providerName, nameof(providerName)); |
There was a problem hiding this comment.
This is, technically, a breaking change but not one anyone should observe. NULL characters are now straight-up disallowed as inputs into provider names. I don't recall exactly why we permitted it before, but this makes this easier along with the multi-provider implementation.
|
Tagging subscribers to this area: @bartonjs, @vcsjones, @dotnet/area-system-security |
There was a problem hiding this comment.
Pull request overview
This PR extends the OpenSSL provider key-loading path to support loading multiple OpenSSL 3 providers into a single OSSL_LIB_CTX, and exposes a new managed overload that accepts a provider list plus an optional OpenSSL property query passed to OSSL_STORE_open_ex.
Changes:
- Add
SafeEvpPKeyHandle.OpenKeyFromProvider(IEnumerable<string> providerNames, string keyUri, string? propertyQuery = null)and update the native interop to accept multiple provider names. - Update native provider loading to load all requested providers into one library context and pass
propertyQuerythrough toOSSL_STORE_open_ex. - Expand manual tests to cover new overload argument validation and property query scenarios.
Show a summary per file
| File | Description |
|---|---|
| src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.h | Update native API contract to accept multiple providers + property query. |
| src/native/libs/System.Security.Cryptography.Native/pal_evp_pkey.c | Implement multi-provider loading/unload-on-partial-failure; pass property query to OSSL_STORE_open_ex. |
| src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EvpPkey.cs | Update P/Invoke signature and managed interop wrapper for the new native contract. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs | Add new public overload, argument validation, provider-set caching keying, and wire to updated interop. |
| src/libraries/System.Security.Cryptography/src/System/Security/Cryptography/OpenSsl.NotSupported.cs | Add the new overload stub for unsupported platforms. |
| src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs | Add the new public API surface to the reference assembly. |
| src/libraries/System.Security.Cryptography/src/Resources/Strings.resx | Add a new resource string for empty-collection validation. |
| src/libraries/System.Security.Cryptography/tests/OpenSslNamedKeysTests.manual.cs | Add/adjust manual tests for the new overload and property query behavior. |
Copilot's findings
- Files reviewed: 8/8 changed files
- Comments generated: 3
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| } | ||
|
|
||
| string[] providerNameArray = new string[providersHashSet.Count]; | ||
| providersHashSet.CopyTo(providerNameArray); |
There was a problem hiding this comment.
I can't imagine a HashSet implementation that doesn't provide a stable ordering during a given process execution, but does this introduce potential issues?
Does an input of [a, b, c] (potentially) unify with [c, b, a]? Should it? (Does the OSSL order the providers are added matter?)
There was a problem hiding this comment.
Oh, right, Sort on the next line changes some of that.
There was a problem hiding this comment.
In theory it is possible for one provider to check if another provider is registered and care about order. If order is important than I would argue we got the parameter type wrong and it shouldn't have been IEnumerable.
There was a problem hiding this comment.
I don't think it would be sane for a provider to check if another provider is registered during load. I think it would most likely be done during an actual operation, and by the time that happens the loaded providers is coherent.
There was a problem hiding this comment.
OpenSSL documentation pretty clearly says "Don't do that"
In particular, provider initialization should not depend on other providers already having been initialized.
https://docs.openssl.org/3.5/man7/provider/#provider-dependencies
So, dependencies seems sane - but initialization order should not be depended upon.
Closes #113118