tests: finish parsing and X25519 tests, distinguish HMAC errors

If the implementation re-encodes the header before checking the HMAC,
that would mask malleability issues: the HMAC check would fail because
the tests HMAC'd the original header, but an attacker could also produce
the right HMAC. Instead of duplicating every parsing tests (with the
original and re-encoded HMAC), we make the test framework distinguish
HMAC errors, which ensures bad encodings are recognized as such and not
bypassable HMAC errors.
This commit is contained in:
Filippo Valsorda
2022-06-18 13:47:00 +02:00
parent f8a121dd87
commit eaa4e03cfe
43 changed files with 557 additions and 59 deletions

View File

@@ -75,10 +75,9 @@ func TestVectors(t *testing.T) {
func testVector(t *testing.T, test []byte) {
var (
expectHeaderFailure bool
expectPayloadFailure bool
payloadHash *[32]byte
identities []age.Identity
expect string
payloadHash *[32]byte
identities []age.Identity
)
for {
@@ -95,13 +94,13 @@ func testVector(t *testing.T, test []byte) {
case "expect":
switch value {
case "success":
case "HMAC failure":
case "header failure":
expectHeaderFailure = true
case "payload failure":
expectPayloadFailure = true
default:
t.Fatal("invalid test file: unknown expect value:", value)
}
expect = value
case "payload":
h, err := hex.DecodeString(value)
if err != nil {
@@ -130,24 +129,30 @@ func testVector(t *testing.T, test []byte) {
}
r, err := age.Decrypt(bytes.NewReader(test), identities...)
if err != nil {
if expectHeaderFailure {
if err != nil && strings.HasSuffix(err.Error(), "bad header MAC") {
if expect == "HMAC failure" {
t.Log(err)
return
}
t.Fatal("unexpected header error:", err)
} else if expectHeaderFailure {
t.Fatal("expected header error")
t.Fatalf("expected %s, got HMAC error", expect)
} else if err != nil {
if expect == "header failure" {
t.Log(err)
return
}
t.Fatalf("expected %s, got: %v", expect, err)
} else if expect != "success" && expect != "payload failure" {
t.Fatalf("expected %s, got success", expect)
}
out, err := io.ReadAll(r)
if err != nil {
if expectPayloadFailure {
if expect == "payload failure" {
t.Log(err)
return
}
t.Fatal("unexpected payload error:", err)
} else if expectPayloadFailure {
t.Fatal("expected payload error")
t.Fatalf("expected %s, got: %v", expect, err)
} else if expect != "success" {
t.Fatalf("expected %s, got success", expect)
}
if sha256.Sum256(out) != *payloadHash {
t.Error("payload hash mismatch")