TestBodyHashIsBound ensures auth headers cannot be replayed under a modified message body. Without BodyHash in the canonical, an attacker who captured a valid (headers, MAC) pair could attach the same auth claim to a body they've rewritten — keeping verified=true while changing the message content.
(t *testing.T)
| 184 | // claim to a body they've rewritten — keeping verified=true while |
| 185 | // changing the message content. |
| 186 | func TestBodyHashIsBound(t *testing.T) { |
| 187 | s := NewSigner("test-secret") |
| 188 | body := []byte("Subject: hi\r\n\r\nhello bob") |
| 189 | h := s.Sign(AuthPayload{ |
| 190 | Verified: true, |
| 191 | Sender: "alice@example.com", |
| 192 | EntityType: "human", |
| 193 | MessageID: "msg_abc123", |
| 194 | BodyHash: HashBody(body), |
| 195 | }) |
| 196 | |
| 197 | if h[HeaderBodyHash] != HashBody(body) { |
| 198 | t.Errorf("HeaderBodyHash mismatch") |
| 199 | } |
| 200 | if !s.Verify(h) { |
| 201 | t.Error("expected Verify to pass for matching body") |
| 202 | } |
| 203 | |
| 204 | // Substituting the body hash without recomputing the MAC must fail. |
| 205 | h[HeaderBodyHash] = HashBody([]byte("forged body")) |
| 206 | if s.Verify(h) { |
| 207 | t.Error("Verify accepted a tampered BodyHash — body integrity is not bound") |
| 208 | } |
| 209 | } |
| 210 | |
| 211 | func TestVerifyRejectsMissingBodyHash(t *testing.T) { |
| 212 | s := NewSigner("test-secret") |