Skip to content

Fix EC public key export for provider keys - #13

Open
anurag6569201 wants to merge 1 commit into
qa/agent-dotnet-runtime/pr-13-133205/basefrom
qa/agent-dotnet-runtime/pr-13-133205/head
Open

anurag6569201 wants to merge 1 commit into
qa/agent-dotnet-runtime/pr-13-133205/basefrom
qa/agent-dotnet-runtime/pr-13-133205/head

Conversation

@anurag6569201

Copy link
Copy Markdown

Most of the explanation for this change is documented as comments in this pull request. However, before:

.NET 11.0.0-preview.6.26359.118
Unhandled exception. System.Security.Cryptography.CryptographicException: Error occurred during a cryptographic operation.
   at Interop.Crypto.EvpPKeyGetEcKeyParameters(SafeEvpPKeyHandle key, Boolean includePrivate)
   at System.Security.Cryptography.ECOpenSsl.ExportNamedCurveParametersFromEvpPKeyUsingParams(SafeEvpPKeyHandle pkey, String curveName, Boolean includePrivateParameters)
   at System.Security.Cryptography.X509Certificates.ECDsaCertificateExtensions.CopyWithPrivateKey(X509Certificate2 certificate, ECDsa privateKey)
   at Program.<Main>$(String[] args) in /home/vcsjones/ecdsa-pkcs11-repro/HsmPoc/Program.cs:line 17

After:

.NET 11.0.0-dev
Subject: CN=hsm-poc
Has private key: True
Public X: 1AE3DAFDDE6536E1FC23C7227ABA86E5A9F678BFBBF74674A0A75D29CDDB5770
Public Y: 97FB07F101E2E07D7D4828E3EB3C33B5B6DE4060CFA3D9EE9FF703700FFFA136
Signature valid: True

The general gist of the change is the the PKCS#11 OpenSSL provider does not "materialize" the public key until you go through an export KEYMGMT interface:

https://github.com/openssl-projects/pkcs11-provider/blob/c7a5c8b62a0ff012b16574f01651254ef7e664ee/src/kmgmt/common.c#L496-L498

Attempting to directly export the public key before this materialization happens results in an error.

We continue to try out existing way first - this is both performance and works in scenarios where a Provider has not implemented KEYMGMT APIs. If it fails, we attempt with EVP_PKEY_todata, which gives us the public key through a KEYMGMT API. It uses the same OSSL_PARAM OSSL_PKEY_PARAM_PUB_KEY as we were using before, so we can use the same point handling for the existing and fallback way.

Contributes to dotnet#133171

Source merge-base: 75cffcef7186a6a0b738f15a98d0b28c6c8e6507
Source head: 56562651f2f82b31d86d2869b922ee2e7b9bc834

@shipwright-agent

Copy link
Copy Markdown

⛔ Shipwright · Blocked

Recommendation: do not merge PR #13 · Tier T1
Checks: 0 total · 0 needing attention

Next step: resolve the blocking findings before merge.

Findings (3)

  • CRITICAL The fallback path calls OSSL_PARAM_free(exportedParameters) unconditionally at exit, but exportedParameters is only initialized to NULL at declaration and only assigned by EVP_PKEY · src/native/libs/System.Security.Cryptography.Native/pal_ecc_import_export.c:867
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • CRITICAL The fallback path uses OSSL_PARAM_get_octet_string_ptr to obtain a pointer to the public key data and then passes it to EC_POINT_oct2point without copying. · src/native/libs/System.Security.Cryptography.Native/pal_ecc_import_export.c:814
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.
  • HIGH The control flow uses a goto label public_key_exported that is placed after the fallback block, but the label is inside the function and the fallback block is conditionally compile · src/native/libs/System.Security.Cryptography.Native/pal_ecc_import_export.c:767
    • Fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

Fireworks usage: 10,277 input · 709 output · 10,986 total tokens · $0.0027 · 11s · 0 fix iteration(s)

Open the Shipwright check for full evidence and the audit bundle. Use /shipwright rerun to verify again.

*cbD = 0;

exit:
if (exportedParameters) OSSL_PARAM_free(exportedParameters);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shipwright · CRITICAL

The fallback path calls OSSL_PARAM_free(exportedParameters) unconditionally at exit, but exportedParameters is only initialized to NULL at declaration and only assigned by EVP_PKEY

Impact: The fallback path calls OSSL_PARAM_free(exportedParameters) unconditionally at exit, but exportedParameters is only initialized to NULL at declaration and only assigned by EVP_PKEY_todata. If EVP_PKEY_todata succeeds but returns a non-NULL pointer, this is fine; however, if the function is entered via the public_key_exported goto after the EVP_PKEY_get_octet_string_param path, exportedParameters remains NULL and OSS…

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.


pubKeyData = (const uint8_t*)publicKeyValue;

public_key_exported:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Shipwright · HIGH

The control flow uses a goto label public_key_exported that is placed after the fallback block, but the label is inside the function and the fallback block is conditionally compile

Impact: The control flow uses a goto label public_key_exported that is placed after the fallback block, but the label is inside the function and the fallback block is conditionally compiled with FEATURE_DISTRO_AGNOSTIC_SSL. On builds without FEATURE_DISTRO_AGNOSTIC_SSL, the fallback block is absent, but the goto public_key_exported from the first path still compiles because the label is present. This creates a confusing con…

Suggested fix: Review the cited evidence, fix the risk if confirmed, and rerun Shipwright.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant