From 4522ce53ae07dac6a41a949054bae4c42cf9cc65 Mon Sep 17 00:00:00 2001 From: jcalabro Date: Fri, 3 Apr 2026 15:08:39 -0400 Subject: [PATCH] fix integer overflow in ECDSA signature verification Reject high-S signatures before calling Signature.fromBytes, which does internal scalar arithmetic that overflows on out-of-range S values. The check was previously done after fromBytes using the parsed sig.s field, but the construction itself panicked on malformed signatures (e.g., high-S or DER-encoded test vectors from the interop fixtures). Now rejectHighS operates on the raw signature bytes directly. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/internal/crypto/jwt.zig | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/internal/crypto/jwt.zig b/src/internal/crypto/jwt.zig index 739db35..f3f8e60 100644 --- a/src/internal/crypto/jwt.zig +++ b/src/internal/crypto/jwt.zig @@ -288,9 +288,12 @@ fn signEcdsa(comptime Scheme: type, comptime Curve: type, comptime half_order: [ /// verify an ECDSA signature, rejecting high-S fn verifyEcdsa(comptime Scheme: type, comptime half_order: [32]u8, message: []const u8, sig_bytes: []const u8, public_key_raw: []const u8) !void { if (sig_bytes.len != 64) return error.InvalidSignature; - const sig = Scheme.Signature.fromBytes(sig_bytes[0..64].*); - rejectHighS(half_order, sig.s) catch return error.SignatureVerificationFailed; + // reject high-S before constructing Signature — fromBytes does scalar + // arithmetic that can overflow on out-of-range values + rejectHighS(half_order, sig_bytes[32..64].*) catch return error.SignatureVerificationFailed; + + const sig = Scheme.Signature.fromBytes(sig_bytes[0..64].*); if (public_key_raw.len != 33) return error.InvalidPublicKey; const public_key = Scheme.PublicKey.fromSec1(public_key_raw) catch return error.InvalidPublicKey; -- 2.51.2