Repository navigation
Conversation
a2271a0 to
a10ebed
Compare
|
Green and mergeable since 16 July with no review yet, so flagging it in case it slipped past. The failure mode is intermittent, which is what makes it awkward to diagnose: Base is 5 commits behind main — happy to rebase if that helps. @rdimitrov |
|
This is a real bug and the fix is correct. I reproduced the failure rate ReproductionSigned 30,000 random messages with a freshly generated P-384 key, encoded each Which matches the analysis in your comment exactly: each component drops its Both existing test suites pass on the head commit: Verifier assumption confirmedThe fixed-width encoding is not just one valid choice here — it is the only one if len(signature) != 96 {
return fmt.Errorf("invalid signature size for ECDSA P-384")
}
r := new(big.Int).SetBytes(signature[:48])
s := new(big.Int).SetBytes(signature[48:])A hard length check plus a split at a fixed offset, so the producer has to Worth noting for anyone reading this later: the old encoding could only ever I also checked the sibling signers for the same pattern. Two small notes, neither blocking
Magic numbers. Nice find on an intermittent bug — the ~1-in-128 rate is exactly the kind that |
|
Thanks for running the numbers, 234 out of 30000 landing right on the 1 in 128 estimate is satisfying to see. Agree with the framing too, publish reliability bug, not security, the hard length check means a short r can only ever fail clean. I'll add a short comment saying r and s are locally generated and bounded so FillBytes can't panic, and I'll rebase onto main so it's fresh. Keeping 96/48 as literals for now to keep the diff small. |
|
Done, brought the branch up to date with main and added the FillBytes bounds comment. |
|
Checked the updated branch ( The bounds comment is accurate as written: Nothing blocking from my side. CI is green and this is ready for a maintainer whenever one has a moment. |
r.Bytes() and s.Bytes() drop leading zero bytes, so the R || S signature was occasionally shorter than 96 bytes and the registry rejected it with "invalid signature size for ECDSA P-384". Left-pad each component to 48 bytes with FillBytes, matching the googlekms signer.
132878a to
ad788f5
Compare
rdimitrov
left a comment
There was a problem hiding this comment.
Reviewed the rebased head ad788f5 on main c434598. No blocking findings.
The fixed 48-byte R and S components match the server verifier's existing 96-byte format. Compatibility/security stress checks covered 4,096 signatures: 4,061 previously valid encodings remained byte-identical, and 35 short encodings were repaired. Wrong-message, wrong-key, tampered-signature and malformed-length cases were rejected. The authentication suites pass with race detection, go vet passes, and range-diff confirms the two original commits are otherwise unchanged after the rebase.
This changes serialization only; signing, hashing, key handling and server verification are unchanged. Approval is for this exact head; merge remains gated on the required CI checks.
The in-process ECDSA P-384 signer built the signature with
append(r.Bytes(), s.Bytes()...). big.Int.Bytes() strips leading zero bytes, so whenever r or s had a high zero byte (roughly 1 in 128 signatures) the concatenation came out shorter than 96 bytes and the registry rejected the publish with "invalid signature size for ECDSA P-384". Intermittent and confusing to debug. Fixed by left-padding each component to 48 bytes with FillBytes, same as the googlekms signer already does. Added a test pinning the fixed-width encoding plus a sign/verify round-trip.