Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
61 lines
2.8 KiB
Go
61 lines
2.8 KiB
Go
package taskexecution
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/sha256"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestCryptographicInitiatorContract(t *testing.T) {
|
|
key, e := rsa.GenerateKey(rand.Reader, 2048)
|
|
if e != nil {
|
|
t.Fatal(e)
|
|
}
|
|
now := time.Now()
|
|
pins := IssuerPins{Issuer: "https://synthetic.invalid", Audience: "synthetic-task-test", Keys: map[string]*rsa.PublicKey{"synthetic": &key.PublicKey}}
|
|
claims := func() map[string]any {
|
|
return map[string]any{"iss": pins.Issuer, "aud": pins.Audience, "sub": "synthetic-human", "principal_type": "human", "tenant": "tenant:platform", "tenant_source": "directory", "iat": now.Unix() - 1, "exp": now.Unix() + 60, "assurance": map[string]any{"level": "aal2", "mfa": true, "source": "key-cape", "at": now.Unix() - 1}}
|
|
}
|
|
sign := func(c map[string]any) string {
|
|
h, _ := json.Marshal(map[string]any{"alg": "RS256", "kid": "synthetic"})
|
|
b, _ := json.Marshal(c)
|
|
v := base64.RawURLEncoding.EncodeToString(h) + "." + base64.RawURLEncoding.EncodeToString(b)
|
|
d := sha256.Sum256([]byte(v))
|
|
s, _ := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, d[:])
|
|
return v + "." + base64.RawURLEncoding.EncodeToString(s)
|
|
}
|
|
token := sign(claims())
|
|
i, e := VerifyKeyCapeHuman(token, pins, now)
|
|
if e != nil || i.Subject() != "synthetic-human" {
|
|
t.Fatal("synthetic signature verification failed")
|
|
}
|
|
cases := map[string]func(map[string]any){"service": func(c map[string]any) { c["principal_type"] = "service" }, "registered tenant": func(c map[string]any) { c["tenant_source"] = "registration" }, "foreign tenant": func(c map[string]any) { c["tenant"] = "tenant:coulomb" }, "issuer": func(c map[string]any) { c["iss"] = "https://wrong.invalid" }, "audience": func(c map[string]any) { c["aud"] = "approval-engine" }, "expired": func(c map[string]any) { c["exp"] = now.Unix() }, "future": func(c map[string]any) { c["nbf"] = now.Unix() + 1 }, "no mfa": func(c map[string]any) { c["assurance"].(map[string]any)["mfa"] = false }, "old mfa": func(c map[string]any) { c["assurance"].(map[string]any)["at"] = now.Unix() - 301 }}
|
|
for name, mutate := range cases {
|
|
t.Run(name, func(t *testing.T) {
|
|
c := claims()
|
|
mutate(c)
|
|
if _, e := VerifyKeyCapeHuman(sign(c), pins, now); e == nil {
|
|
t.Fatal("invalid human accepted")
|
|
}
|
|
})
|
|
}
|
|
if _, e := VerifyKeyCapeHuman(token, IssuerPins{}, now); e == nil {
|
|
t.Fatal("unadmitted issuer accepted")
|
|
}
|
|
if _, e := VerifyKeyCapeHuman(token+"x", pins, now); e == nil {
|
|
t.Fatal("tampered signature accepted")
|
|
}
|
|
}
|
|
func TestStrictClaimJSON(t *testing.T) {
|
|
for _, raw := range []string{`{"iss":"a","iss":"b"}`, `{"assurance":{"mfa":true,"mfa":false}}`, `{"x":1} {"x":2}`} {
|
|
var v map[string]any
|
|
if strictObject([]byte(raw), &v) == nil {
|
|
t.Fatal("ambiguous claims accepted")
|
|
}
|
|
}
|
|
}
|