1package pgp
2
3import (
4 "strings"
5 "testing"
6)
7
8// TestParseASN1Signature_TruncatedDoesNotPanic covers the bounds-check path
9// added for #613. Each input would have panicked in the original parser
10// with "index out of range"; here we expect a typed error instead.
11func TestParseASN1Signature_TruncatedDoesNotPanic(t *testing.T) {
12 cases := []struct {
13 name string
14 der []byte
15 wantErr string
16 }{
17 {
18 // Length byte declares 0x10 bytes of R but only 1 byte follows.
19 name: "R length overruns buffer",
20 der: []byte{0x30, 0x06, 0x02, 0x10, 0xAA, 0x00},
21 wantErr: "R length overflow",
22 },
23 {
24 // Length byte declares 0x10 bytes of S but only 1 byte follows.
25 name: "S length overruns buffer",
26 der: []byte{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x10, 0xAA},
27 wantErr: "S length overflow",
28 },
29 {
30 // Valid R, then no S block at all.
31 name: "missing S after R",
32 der: []byte{0x30, 0x06, 0x02, 0x01, 0x01, 0x00},
33 wantErr: "expected INTEGER tag for S",
34 },
35 }
36
37 for _, tc := range cases {
38 tc := tc
39 t.Run(tc.name, func(t *testing.T) {
40 // The test must not panic: the fix replaces panics with errors.
41 defer func() {
42 if r := recover(); r != nil {
43 t.Fatalf("parseASN1Signature panicked: %v", r)
44 }
45 }()
46 _, _, err := parseASN1Signature(tc.der)
47 if err == nil {
48 t.Fatalf("want error, got nil")
49 }
50 if !strings.Contains(err.Error(), tc.wantErr) {
51 t.Fatalf("error = %q, want it to mention %q", err.Error(), tc.wantErr)
52 }
53 })
54 }
55}
56
57// TestParseASN1Signature_WellFormed guards against regressions in the
58// happy path: a minimal SEQUENCE { INTEGER, INTEGER } must still decode
59// to the original r and s bytes.
60func TestParseASN1Signature_WellFormed(t *testing.T) {
61 // SEQUENCE (6 bytes) { INTEGER 0x01, INTEGER 0x02 }
62 der := []byte{0x30, 0x06, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}
63
64 r, s, err := parseASN1Signature(der)
65 if err != nil {
66 t.Fatalf("unexpected error: %v", err)
67 }
68 if len(r) != 1 || r[0] != 0x01 {
69 t.Errorf("r = %x, want 01", r)
70 }
71 if len(s) != 1 || s[0] != 0x02 {
72 t.Errorf("s = %x, want 02", s)
73 }
74}