// Decision verification uses the unchanged Access Engine producer implementation. package main import ( "crypto/ed25519" "encoding/base64" "encoding/json" "fmt" "github.com/netkingdom/access-engine/internal/sign" "io" "os" ) type input struct { Envelope json.RawMessage `json:"envelope"` Keys map[string]string `json:"keys"` } func run() error { var in input if err := json.NewDecoder(io.LimitReader(os.Stdin, 1048577)).Decode(&in); err != nil { return err } envelope, err := sign.DecodeEnvelope(in.Envelope) if err != nil { return err } keys := map[string]ed25519.PublicKey{} for kid, encoded := range in.Keys { raw, err := base64.RawURLEncoding.Strict().DecodeString(encoded) if err != nil || len(raw) != ed25519.PublicKeySize || kid == "" { return fmt.Errorf("invalid admitted key") } keys[kid] = ed25519.PublicKey(raw) } if err := sign.Verify(envelope, keys); err != nil { return err } // Return the exact typed interpretation authenticated by the producer; Python // must never act on a second interpretation of unverified response fields. return json.NewEncoder(os.Stdout).Encode(envelope) } func main() { if run() != nil { fmt.Fprintln(os.Stderr, "decision signature verification refused") os.Exit(1) } }