Skip to content

Fix key-reuse and race conditions in keychain encrypt/decrypt; add cr… - #2

Open
DavidValin wants to merge 2 commits into
mainfrom
commit
Open

Fix key-reuse and race conditions in keychain encrypt/decrypt; add cr…#2
DavidValin wants to merge 2 commits into
mainfrom
commit

Conversation

@DavidValin

@DavidValin DavidValin commented Aug 14, 2026

Copy link
Copy Markdown
Owner

Fixes five related vulnerabilities/gaps in the keychain (-c ) encrypt/decrypt path where OTP key material could be reused or lost:

  • Multi-chunk key leak: a message spanning several 4MB chunks that exceeded the remaining key could leak already-encrypted chunks to output before the oversize was detected, leaving that key range falsely marked unused and reusable.
  • Crash-time key reuse: a kill/crash between emitting ciphertext and committing key consumption could leave a key range looking unspent after it was already used. Fixed with a stage → verify (read-back) → atomic-publish commit protocol and deterministic 3-window crash recovery, applied to both encrypt and decrypt.
  • Concurrent same-contact reuse: two processes racing on one contact could each read and consume the same key offset. Fixed with per-contact flock()-based locking plus a metadata reload after acquiring the lock.
  • Concurrent cross-contact corruption: all contacts shared one keychain.txt, so concurrent writes to different contacts could silently overwrite each other's metadata. Fixed by splitting metadata into one file per contact, with transparent migration from the old format.
  • Windows gap: the above fixes relied on POSIX-only dirent.h/flock(), leaving Windows builds without recovery scanning or locking. Added platform.h, a shim providing the same APIs via Win32 FindFirstFile/LockFileEx, so both platforms run identical code.

…ash safety and Windows support

Fixes five related vulnerabilities/gaps in the keychain (-c <contact>)
encrypt/decrypt path where OTP key material could be reused or lost:

- Multi-chunk key leak: a message spanning several 4MB chunks that
exceeded the remaining key could leak already-encrypted chunks to output
before the oversize was detected, leaving that key range falsely marked
unused and reusable.
- Crash-time key reuse: a kill/crash between emitting ciphertext and
committing key consumption could leave a key range looking unspent after
it was already used. Fixed with a stage → verify (read-back) →
atomic-publish commit protocol and deterministic 3-window crash
recovery, applied to both encrypt and decrypt.
- Concurrent same-contact reuse: two processes racing on one contact
could each read and consume the same key offset. Fixed with per-contact
flock()-based locking plus a metadata reload after acquiring the lock.
- Concurrent cross-contact corruption: all contacts shared one
keychain.txt, so concurrent writes to different contacts could silently
overwrite each other's metadata. Fixed by splitting metadata into one
file per contact, with transparent migration from the old format.
- Windows gap: the above fixes relied on POSIX-only dirent.h/flock(),
leaving Windows builds without recovery scanning or locking. Added
platform.h, a shim providing the same APIs via Win32
FindFirstFile/LockFileEx, so both platforms run identical code.
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