Mining/pkg/ueps/reader_test.go
Claude 72d85986c6
Some checks are pending
Security Scan / security (push) Waiting to run
Test / test (push) Waiting to run
ax(ueps): add reader_test.go with Good/Bad/Ugly coverage for ReadAndVerify
One test file per source file is mandatory per AX conventions. reader.go
had no corresponding test file — this adds the three required test cases
covering valid round-trip, tampered frame rejection, and wrong-secret rejection.

Co-Authored-By: Charon <charon@lethean.io>
2026-04-02 08:11:05 +01:00

96 lines
3 KiB
Go

package ueps
import (
"bufio"
"bytes"
"testing"
)
// TestReader_ReadAndVerify_Good verifies a well-formed signed frame round-trips correctly.
// builder := NewBuilder(0x01, []byte("hello")); frame, _ := builder.MarshalAndSign(secret)
// packet, err := ReadAndVerify(bufio.NewReader(bytes.NewReader(frame)), secret)
// // packet.Header.IntentID == 0x01; packet.Payload == []byte("hello")
func TestReader_ReadAndVerify_Good(t *testing.T) {
sharedSecret := []byte("test-shared-secret")
payload := []byte("hello world")
intentID := uint8(0x01)
builder := NewBuilder(intentID, payload)
frame, err := builder.MarshalAndSign(sharedSecret)
if err != nil {
t.Fatalf("MarshalAndSign failed: %v", err)
}
reader := bufio.NewReader(bytes.NewReader(frame))
packet, err := ReadAndVerify(reader, sharedSecret)
if err != nil {
t.Fatalf("ReadAndVerify failed: %v", err)
}
if packet == nil {
t.Fatal("ReadAndVerify returned nil packet")
}
if packet.Header.IntentID != intentID {
t.Errorf("expected IntentID 0x%02x, got 0x%02x", intentID, packet.Header.IntentID)
}
if packet.Header.Version != 0x09 {
t.Errorf("expected Version 0x09, got 0x%02x", packet.Header.Version)
}
if !bytes.Equal(packet.Payload, payload) {
t.Errorf("expected Payload %q, got %q", payload, packet.Payload)
}
}
// TestReader_ReadAndVerify_Bad verifies that a tampered frame is rejected with an integrity error.
// frame[len(frame)-1] ^= 0xFF // corrupt last byte
// packet, err := ReadAndVerify(bufio.NewReader(bytes.NewReader(frame)), secret)
// // err != nil; "integrity violation" in error message
func TestReader_ReadAndVerify_Bad(t *testing.T) {
sharedSecret := []byte("test-shared-secret")
builder := NewBuilder(0x02, []byte("sensitive data"))
frame, err := builder.MarshalAndSign(sharedSecret)
if err != nil {
t.Fatalf("MarshalAndSign failed: %v", err)
}
// Corrupt the last byte of the payload
corrupted := make([]byte, len(frame))
copy(corrupted, frame)
corrupted[len(corrupted)-1] ^= 0xFF
reader := bufio.NewReader(bytes.NewReader(corrupted))
packet, err := ReadAndVerify(reader, sharedSecret)
if err == nil {
t.Fatal("expected error for corrupted frame, got nil")
}
if packet != nil {
t.Error("expected nil packet for corrupted frame")
}
}
// TestReader_ReadAndVerify_Ugly verifies that a valid frame fails verification with the wrong secret.
// frame, _ := builder.MarshalAndSign([]byte("correct-secret"))
// packet, err := ReadAndVerify(reader, []byte("wrong-secret"))
// // err != nil; packet == nil
func TestReader_ReadAndVerify_Ugly(t *testing.T) {
correctSecret := []byte("correct-secret")
wrongSecret := []byte("wrong-secret")
builder := NewBuilder(0x03, []byte("private payload"))
frame, err := builder.MarshalAndSign(correctSecret)
if err != nil {
t.Fatalf("MarshalAndSign failed: %v", err)
}
reader := bufio.NewReader(bytes.NewReader(frame))
packet, err := ReadAndVerify(reader, wrongSecret)
if err == nil {
t.Fatal("expected HMAC mismatch error with wrong secret, got nil")
}
if packet != nil {
t.Error("expected nil packet when secret is wrong")
}
}