Skip to content

Comments

refactor: migrate from deprecated EC_KEY APIs to OpenSSL 3.x EVP parameter APIs#935

Merged
boorad merged 4 commits intomainfrom
refactor/migrate-ec-key-to-evp-params
Feb 16, 2026
Merged

refactor: migrate from deprecated EC_KEY APIs to OpenSSL 3.x EVP parameter APIs#935
boorad merged 4 commits intomainfrom
refactor/migrate-ec-key-to-evp-params

Conversation

@boorad
Copy link
Collaborator

@boorad boorad commented Feb 16, 2026

Summary

Migrates all deprecated EC_KEY_* and EVP_PKEY_get0_EC_KEY / EVP_PKEY_assign_EC_KEY APIs to modern OpenSSL 3.x EVP parameter APIs (OSSL_PARAM_BLD, EVP_PKEY_fromdata, EVP_PKEY_get_bn_param, EVP_PKEY_get_octet_string_param). Also implements JWK export for EC keys via createPrivateKey/createPublicKey.

Changes

C++ (OpenSSL migration)

  • HybridECDH.cpp: Replace all EC_KEY_* usage in computeSecret, getPrivateKey, setPrivateKey, getPublicKey, setPublicKey with EVP parameter APIs
  • HybridKeyObjectHandle.cpp: Migrate exportKey (raw EC public key), exportJwk (EC coordinate extraction), initJwk (EC key construction), keyDetail (curve name), and initECRaw to EVP APIs
  • SignUtils.hpp: Replace EVP_PKEY_get0_EC_KEY in getBytesOfRS() with EVP_PKEY_get_bn_param(OSSL_PKEY_PARAM_EC_ORDER)
  • QuickCryptoUtils.hpp/.cpp: Extract shared createEcEvpPkey() utility using OSSL_PARAM_BLD + EVP_PKEY_fromdata, moved from inline header to dedicated compilation unit
  • Remove #pragma clang diagnostic deprecation warning suppression (no longer needed)

TypeScript (JWK export)

  • classes.ts: Implement export({ format: 'jwk' }) for PublicKeyObject and PrivateKeyObject (previously threw "not implemented")
  • index.ts: Add JWK import support in createPublicKey and createPrivateKey
  • hkdf.ts: Replace CryptoKeyInternal duck-type interface with proper CryptoKey import (removes any escape hatch)

Tests

  • ECDH: P-384, P-521, secp256k1 setPrivateKey + computeSecret round-trip tests
  • JWK EC round-trip: generate → export JWK → import JWK → sign/verify for P-256, P-384, P-521 (private and public)
  • IEEE-P1363 encoding: P-384 and P-521 sign/verify tests

Testing

Tests run in the React Native example app. All new tests cover the migrated code paths across multiple EC curves.

Closes #920

…meter APIs (#920)

Replace all EVP_PKEY_get0_EC_KEY, EC_KEY_*, and EVP_PKEY_assign_EC_KEY
calls with modern EVP parameter APIs:

- EVP_PKEY_get_bn_param / EVP_PKEY_get_octet_string_param /
  EVP_PKEY_get_utf8_string_param for reading EC key data
- OSSL_PARAM_BLD + EVP_PKEY_fromdata for constructing EC keys

Affected files:
- SignUtils.hpp: getBytesOfRS() uses EVP param API for curve order
- HybridKeyObjectHandle.cpp: exportKey, exportJwk, initJwk, keyDetail,
  initECRaw all migrated to EVP param APIs
- HybridECDH.cpp: getPrivateKey, getPublicKey, setPrivateKey,
  setPublicKey, computeSecret all migrated; shared createEcEvpPkey
  helper added; deprecation warning pragmas removed

EC_GROUP, EC_POINT, and related functions remain as they are not
deprecated. The ncrypto dependency's internal deprecated usage is
out of scope.
- Extract shared createEcEvpPkey() utility to QuickCryptoUtils.hpp,
  eliminating 3 duplicate OSSL_PARAM_BLD patterns across HybridECDH.cpp,
  HybridKeyObjectHandle.cpp (initJwk + initECRaw)
- Fix getBytesOfRS() performance: query EC order directly via
  OSSL_PKEY_PARAM_EC_ORDER instead of allocating EC_GROUP per call
- Fix exportJwk() to throw when EC public key coordinates extraction
  fails instead of silently producing invalid JWK
- Add missing return value check on EC_POINT_point2oct in setPrivateKey
- Remove stale migration comment

Tests:
- Add ECDSA P1363 signing tests for P-384 (96-byte sig) and P-521
  (132-byte sig) to validate getBytesOfRS correctness
- Add ECDH setPrivateKey + computeSecret round-trip tests for P-384,
  P-521, and secp256k1 curves
- Add JWK EC round-trip tests (export -> import -> sign/verify) for
  P-256, P-384, P-521 via createPrivateKey/createPublicKey
…icKey)

Wire up PublicKeyObject.export({ format: 'jwk' }) and
PrivateKeyObject.export({ format: 'jwk' }) to the existing native
exportJwk() method instead of throwing 'not implemented'.

The native C++ implementation was already complete — this change
bridges the TypeScript layer to call it.
- Replace CryptoKeyInternal duck type with CryptoKey import in hkdf.ts,
  removing the any escape hatch (#2)
- Use EVP_PKEY_bits() instead of allocating EC_GROUP just for field_size
  in exportJwk; hardcode field sizes for known curves in initJwk (#3)
- Move createEcEvpPkey from inline header to QuickCryptoUtils.cpp to
  avoid code duplication across translation units (#4)
- Remove unnecessary 'as any' casts in JWK round-trip tests since
  KeyInputObject already accepts JWK (#6)
@boorad boorad self-assigned this Feb 16, 2026
@github-actions
Copy link
Contributor

🤖 End-to-End Test Results - Android

Status: ✅ Passed
Platform: Android
Run: 22047659168

📸 Final Test Screenshot

Maestro Test Results - android

Screenshot automatically captured from End-to-End tests and will expire in 30 days


This comment is automatically updated on each test run.

@github-actions
Copy link
Contributor

🤖 End-to-End Test Results - iOS

Status: ✅ Passed
Platform: iOS
Run: 22047659182

📸 Final Test Screenshot

Maestro Test Results - ios

Screenshot automatically captured from End-to-End tests and will expire in 30 days


This comment is automatically updated on each test run.

@boorad boorad merged commit 955b935 into main Feb 16, 2026
7 checks passed
@boorad boorad deleted the refactor/migrate-ec-key-to-evp-params branch February 16, 2026 02:17
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.

Migrate from deprecated EVP_PKEY_get0_EC_KEY / EC_KEY_* APIs to OpenSSL 3.x EVP parameter APIs

1 participant