Skip to content

keygen: fix over-stripping of ED25519 public key bytes - #1515

Open
Soulstears2539 wants to merge 1 commit into
mscdex:masterfrom
Soulstears2539:fix/ed25519-pubkey-leading-zero-strip
Open

Soulstears2539 wants to merge 1 commit into
mscdex:masterfrom
Soulstears2539:fix/ed25519-pubkey-leading-zero-strip

Conversation

@Soulstears2539

Copy link
Copy Markdown

Fixes #1514.

Summary

parseDERs() in lib/keygen.js removed all leading 0x00 bytes from
the ED25519 SubjectPublicKeyInfo BIT STRING content instead of exactly
the one mandatory "unused bits" marker byte. Whenever the raw 32-byte
public key itself happened to start with 0x00 (~1/256 keys), the loop
over-stripped real key material, producing a truncated key that
parseKey() then correctly rejected as Malformed OpenSSH public key.

Fix

Strip exactly one byte when it is 0x00, not a variable-length run.

Note: the analogous ec (ECDSA) case uses the same style of loop but is
not affected, since the byte immediately following the leading 0x00 is
always the fixed 0x04 uncompressed-point marker (never zero), so that
loop always stops after exactly one byte regardless of the X/Y coordinate
values. Left unchanged.

Testing

  • Repro loop (generateKeyPairSync('ed25519') + parseKey()) over
    20000 iterations: 85 failures before the fix, 0 failures after.
  • test/test-keygen.js (existing suite) passes unchanged.

parseDERs() removed *all* leading 0x00 bytes from the ED25519
SubjectPublicKeyInfo BIT STRING content instead of exactly the one
mandatory 'unused bits' marker byte. Whenever the raw 32-byte public
key itself happened to start with 0x00 (~1/256 keys), the loop
over-stripped real key material, producing a truncated key that
parseKey() then correctly rejected as 'Malformed OpenSSH public key'.

Fixes mscdex#1514.
markomanninen added a commit to markomanninen/shellcraft that referenced this pull request Oct 28, 2026
* test(ui): link the ssh2 keygen bug the key retry works around

mscdex/ssh2#1513, fix in mscdex/ssh2#1515; the retry can go once a
release has it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(ui): testing: let useInput subscribe before a key is sent

Ink writes a frame when React commits, but useInput subscribes in an
effect that React's scheduler runs later from setImmediate. On a loaded
CI runner a test saw the new screen, pressed a key before the handler
was there, and the key was lost: admin-dashboard's "processes: the
table height follows the terminal" pressed down right after the table
appeared and the rows never scrolled (CI on #41; locally under full CPU
load 18 of 25 runs failed).

press() and write() now yield to setImmediate twice before sending, so
queued effects run first. The same test also waited a fixed 30 ms for
the process list; it now waits for the list itself.

Under full CPU load: 0 of 60 runs failed. ui 130, demo-shop 21+7,
admin-dashboard 48+7, adventure-game 68+8, animation-demo 33 pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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.

generateKeyPairSync('ed25519') + parseKey()

1 participant