-
Notifications
You must be signed in to change notification settings - Fork 4.7k
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
OpenSSL ENGINE support #88656
OpenSSL ENGINE support #88656
Conversation
Note regarding the 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. |
Tagging subscribers to this area: @dotnet/area-system-security, @bartonjs, @vcsjones Issue DetailsFixes: #55356 Allows using ENGINE with OpenSSL, for example to use TPM ECDSA key using tpm2tss engine: // 0x81000007 - needs to be created first - see osslplugins/README.md how to get it
using SafeEvpPKeyHandle priKeyHandle = SafeEvpPKeyHandle.OpenPrivateKeyFromEngine("tpm2tss", "0x81000007");
using ECDsa ecdsaPri = new ECDsaOpenSsl(priKeyHandle);
// do stuff with ecdsaPri Tests are manual and can be enabled with environmental variable. See osslplugins/README.md for more information on how to do it. Note: Providers are cut from the proposal. This code is based on @bartonjs's work https://github.com/bartonjs/runtime/blob/open_named_keys/ - it extends tests, ENGINE implementation is simplified and testing instructions document is added with how to run tests and what's required to set it up.
|
I sincerely believe that this should be deferred to vNext. Since ENGINEs are deprecated, ENGINE support shouldn't be added without Provider support, and it sounds like you're deferring Providers. |
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 have a concern regarding lifetimes of the structural and functional references for the engine.
In my interpretation, these need to be kept alive for the duration of the key handle (e.g. in case SslStream decides to use the private key in a TLS handshake).
} | ||
|
||
[LibraryImport(Libraries.CryptoNative, StringMarshalling = StringMarshalling.Utf8)] | ||
private static partial SafeEvpPKeyHandle CryptoNative_LoadPublicKeyFromEngine( |
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.
Note: I've never been able to store/load a public key in an engine before. Usually, with both TPM and PKCS#11 (via SoftHSM) the public keys were embedded in the X.509 certificate. That said, this could be allowed by some engines.
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.
Fair point but as @bartonjs has already responded:#55356 (comment) "it's a low enough incremental cost that it doesn't hurt." which I fully agree
@@ -0,0 +1,194 @@ | |||
// Licensed to the .NET Foundation under one or more agreements. |
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.
This could help setting up an e2e test:
Running in this container: https://github.com/Azure/azure-iot-sdk-c/blob/main/jenkins/openssl-engine/Dockerfile
Script to prepare the HSM simulator: https://github.com/Azure/azure-iot-sdk-c/blob/main/jenkins/linux_openssl_engine.sh
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.
Thanks, I will leave this out of scope of this PR and investigate this separately (or create issue depends on time).
src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Security.Cryptography/ref/System.Security.Cryptography.cs
Outdated
Show resolved
Hide resolved
...s/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Security.Cryptography/tests/osslplugins/test.sh
Outdated
Show resolved
Hide resolved
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.
My concerns regarding object lifetime were addressed in openssl/openssl#21427
src/libraries/System.Security.Cryptography/tests/OpenSslNamedKeysTests.manual.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Security.Cryptography/tests/OpenSslNamedKeysTests.manual.cs
Outdated
Show resolved
Hide resolved
[ConditionalFact(nameof(ShouldRunEngineTests))] | ||
public static void Engine_SanityTest() | ||
{ | ||
Assert.False(ShouldFailTests, "This test is supposed to fail"); | ||
} | ||
|
||
[ConditionalFact(nameof(ShouldRunTpmTssTests))] | ||
public static void Tpm_SanityTest() | ||
{ | ||
Assert.False(ShouldFailTests, "This test is supposed to fail"); | ||
} |
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.
While I generally do something like this during development, I don't know that we've checked in "I fail to prove the tests ran" tests before.
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.
Since it's referenced in the instructions as how to verify manual test setup is working, I guess it makes sense.
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 found it useful when doing manual testing. Green on the first try always makes me a bit nervous for these kinds of tests. With this I can immediately exclude wrong env name or other external factors causing me to have green tests by accident
// PKCS#1 format | ||
static char g_pubRsaKey[140] = { | ||
0x30,0x81,0x89,0x02,0x81,0x81,0x00,0xBF,0x67,0x16,0x84,0x85,0x21,0x5A,0x6A,0xB8, | ||
0x9B,0xCA,0xB9,0x33,0x1F,0x6F,0x5F,0x36,0x0F,0x43,0x00,0xBE,0x5C,0xF2,0x82,0xF7, | ||
0x70,0x42,0x95,0x7E,0xA2,0x02,0x90,0x8B,0x22,0x79,0xF3,0x4A,0x42,0x6D,0x62,0xF5, | ||
0x9D,0x6C,0x10,0x56,0xE3,0x6D,0xC9,0xF6,0xEE,0xA9,0xAE,0xB1,0xB3,0x1F,0x81,0x22, | ||
0xF5,0x83,0xEE,0x9C,0xAE,0x2A,0x86,0xA4,0x71,0x44,0x90,0x5D,0xF0,0x54,0x41,0xB0, | ||
0xA5,0xF2,0x9E,0x03,0xC5,0xAC,0x18,0x88,0xD9,0x37,0x44,0xD8,0x96,0x38,0xD8,0x3A, | ||
0xC3,0x77,0x74,0xB3,0x39,0xE4,0xAF,0xB3,0x49,0xC7,0x14,0xB1,0x22,0x38,0xB0,0xF8, | ||
0x1A,0x71,0x38,0x0F,0x05,0x1C,0x58,0x5C,0xB2,0x74,0x34,0xFA,0x54,0x4B,0xDA,0xC6, | ||
0x79,0xE1,0xE1,0x65,0x81,0xD0,0xE9,0x02,0x03,0x01,0x00,0x01 | ||
}; | ||
|
||
// PKCS#1 format | ||
char g_priRsaKey[608] = { | ||
0x30,0x82,0x02,0x5C,0x02,0x01,0x00,0x02,0x81,0x81,0x00,0xBF,0x67,0x16,0x84,0x85, |
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.
When I was doing development on this, the public key named "first" and the private key named "first" didn't match (not that you necessarily could have seen that since I wrote it to load keys from files that I didn't check in). It looks like you've changed that here so that they're the same.
I thought it was valuable that they were mismatched, to show that the public/private namespace mattered.
Whether they're the same (as-is) or different (because you change it up), add a comment saying what their relationship is.
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.
added a comment. I intentionally called the same to ensure we don't accidentally load the wrong one when same name is used
src/libraries/System.Security.Cryptography/tests/osslplugins/e_dntest.c
Outdated
Show resolved
Hide resolved
src/libraries/System.Security.Cryptography/tests/osslplugins/e_dntest.c
Outdated
Show resolved
Hide resolved
src/libraries/System.Security.Cryptography/tests/osslplugins/e_dntest.c
Outdated
Show resolved
Hide resolved
src/libraries/System.Security.Cryptography/tests/OpenSslNamedKeysTests.manual.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Security.Cryptography/tests/OpenSslNamedKeysTests.manual.cs
Outdated
Show resolved
Hide resolved
...s/System.Security.Cryptography/src/System/Security/Cryptography/SafeEvpPKeyHandle.OpenSsl.cs
Show resolved
Hide resolved
7288886
to
62ef5e5
Compare
This is rebase only (trying to get CI to be green since I'm seeing lots of unrelated failures) |
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
This comment was marked as off-topic.
62ef5e5
to
5463146
Compare
Fixes: #55356
Allows using ENGINE with OpenSSL, for example to use TPM ECDSA key using tpm2tss engine:
Tests are manual and can be enabled with environmental variable. See osslplugins/README.md for more information on how to do it.
Note: Providers are cut from the proposal.
This code is based on @bartonjs's work https://github.com/bartonjs/runtime/blob/open_named_keys/ - it extends tests and make it react to environmental variable, ENGINE implementation is simplified and testing instructions document is added with how to run tests and what's required to set it up.