82 lines
2.5 KiB
Go
82 lines
2.5 KiB
Go
package attesto
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
func TestGoldenVectorCanonicalJSONAndHashes(t *testing.T) {
|
|
vector := loadGoldenVector(t)
|
|
events := vector["events"].([]any)
|
|
first := events[0].(map[string]any)
|
|
envelope := M(first["envelope"].(map[string]any))
|
|
gotCanonicalHex, err := CanonicalJSONHex(envelope)
|
|
if err != nil {
|
|
t.Fatalf("canonical json: %v", err)
|
|
}
|
|
if gotCanonicalHex != first["canonical_json_hex"].(string) {
|
|
t.Fatalf("canonical json hex mismatch\ngot %s\nwant %s", gotCanonicalHex, first["canonical_json_hex"])
|
|
}
|
|
domains := vector["domains"].(map[string]any)
|
|
gotHash, err := DomainHashHex(domains["event"].(string), envelope)
|
|
if err != nil {
|
|
t.Fatalf("domain hash: %v", err)
|
|
}
|
|
if gotHash != first["event_hash"].(string) {
|
|
t.Fatalf("event hash mismatch\ngot %s\nwant %s", gotHash, first["event_hash"])
|
|
}
|
|
}
|
|
|
|
func TestGoldenVectorReceiptOfflineVerification(t *testing.T) {
|
|
vector := loadGoldenVector(t)
|
|
rawReceipt, err := json.Marshal(vector["receipt"])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var receipt SignedReceipt
|
|
if err := json.Unmarshal(rawReceipt, &receipt); err != nil {
|
|
t.Fatalf("unmarshal receipt: %v", err)
|
|
}
|
|
signing := vector["signing"].(map[string]any)
|
|
report := VerifyReceiptOffline(receipt, signing["public_key_hex"].(string))
|
|
if !report.OK {
|
|
t.Fatalf("receipt should verify: %#v", report.Problems)
|
|
}
|
|
receipt.Payload["event_hash"] = "00" + receipt.Payload["event_hash"].(string)[2:]
|
|
tampered := VerifyReceiptOffline(receipt, signing["public_key_hex"].(string))
|
|
if tampered.OK {
|
|
t.Fatal("tampered receipt unexpectedly verified")
|
|
}
|
|
}
|
|
|
|
func TestSignedConnectorWebhookHeaders(t *testing.T) {
|
|
headers := SignedConnectorWebhookHeaders("secret", []byte(`{"eventType":"decision"}`), 1710000000)
|
|
if headers["X-Attesto-Connector-Timestamp"] != "1710000000" {
|
|
t.Fatalf("timestamp mismatch: %v", headers)
|
|
}
|
|
signature := headers["X-Attesto-Connector-Signature"]
|
|
if _, err := hex.DecodeString(signature); err != nil {
|
|
t.Fatalf("signature is not hex: %v", err)
|
|
}
|
|
if len(signature) != 64 {
|
|
t.Fatalf("signature length mismatch: %d", len(signature))
|
|
}
|
|
}
|
|
|
|
func loadGoldenVector(t *testing.T) map[string]any {
|
|
t.Helper()
|
|
path := filepath.Join("..", "..", "golden-vectors", "proofstream-v0.1-alpha", "one-stream-two-events.json")
|
|
raw, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("read golden vector: %v", err)
|
|
}
|
|
var data map[string]any
|
|
if err := json.Unmarshal(raw, &data); err != nil {
|
|
t.Fatalf("parse golden vector: %v", err)
|
|
}
|
|
return data
|
|
}
|