Skip to content

fix: preserve existing keys in DH generateKeys()#954

Merged
boorad merged 3 commits intomainfrom
fix/dh-generate-keys-preserve
Feb 23, 2026
Merged

fix: preserve existing keys in DH generateKeys()#954
boorad merged 3 commits intomainfrom
fix/dh-generate-keys-preserve

Conversation

@boorad
Copy link
Collaborator

@boorad boorad commented Feb 23, 2026

Summary

diffieHellman.generateKeys() was overwriting existing keys instead of preserving a previously set private key and computing the public key from it. This fixes the behavior to match Node.js semantics.

Fixes #952

Changes

  • Use EVP_PKEY_get1_DH (owned copy) instead of EVP_PKEY_get0_DH (internal pointer) in generateKeys() — OpenSSL 3.x's provider layer can return a cached copy from get0, so mutations via DH_generate_key don't persist
  • Replace EVP_PKEY_keygen (which always generates a new key pair) with DH_generate_key (which preserves an existing private key and only computes the public key)
  • Re-wrap the mutated DH in a fresh EVP_PKEY after key generation
  • Add tests for private key preservation and idempotent generateKeys() calls
  • Use workspace:* for rnqc dependency in example app

Testing

  • Two new tests in the DH suite:
    • generateKeys should preserve a previously set private key
    • generateKeys should not regenerate keys on second call
  • All existing DH tests continue to pass

Use DH_generate_key() directly instead of EVP_PKEY_keygen(), matching
Node.js/ncrypto behavior. DH_generate_key() preserves an already-set
private key and only derives the public key from it, whereas
EVP_PKEY_keygen() unconditionally generates a fresh keypair.

Fixes #952
EVP_PKEY_get0_DH can return a provider-cached copy in OpenSSL 3.x,
so mutating it via DH_generate_key doesn't persist. Switch to
EVP_PKEY_get1_DH to get an owned copy, generate keys on it, then
re-wrap in a fresh EVP_PKEY.
@boorad boorad self-assigned this Feb 23, 2026
@github-actions
Copy link
Contributor

🤖 End-to-End Test Results - Android

Status: ✅ Passed
Platform: Android
Run: 22293093053

📸 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

github-actions bot commented Feb 23, 2026

🤖 End-to-End Test Results - iOS

Status: ✅ Passed
Platform: iOS
Run: 22293093025

📸 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 8bab2be into main Feb 23, 2026
8 of 9 checks passed
@boorad boorad deleted the fix/dh-generate-keys-preserve branch February 23, 2026 05:09
boorad added a commit that referenced this pull request Feb 24, 2026
New pages: PQC (ML-DSA/ML-KEM), Argon2, KMAC, Certificate (SPKAC),
and Utilities (one-shot hash, timingSafeEqual, primes, introspection).

Updated 8 existing pages with missing API sections: SubtleCrypto
(deriveBits, deriveKey, wrapKey/unwrapKey, encapsulation), Keys
(KeyObject.from, equals, toCryptoKey), Signing (standalone sign/verify),
DiffieHellman (diffieHellman function), Ed25519 (Ed448/X448), Hash
(crypto.hash one-shot, SHA3), ECDH (convertKey), and reorganized the
API index into Core/Key Exchange/Key Derivation/Advanced sections.

Annotated 7 pages with behavioral notes from recent fix PRs (#929,
#930, #932, #933, #939, #948, #949, #951, #954, #955): cipher
single-use warning, generateKeys preservation, PBKDF2 validation,
OAEP hash default, randomFill view correctness, RSA-* aliases, and
flexible curve names.

Added llms.txt index route and fixed llms-full.txt JSX stripping in
source.ts to produce clean LLM-friendly output.
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.

🐛 diffieHellman.generateKeys overwrites existing keys

1 participant