carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package hostactors
2
3import (
4 "context"
5 "crypto"
6 "crypto/rand"
7 "crypto/rsa"
8 "crypto/sha256"
9 "crypto/x509"
10 "encoding/base64"
11 "encoding/json"
12 "github.com/carlosframework/platform/internal/boxid"
13 "testing"
14)
15
16func TestEnrollmentUsesSignedCloudAndRefusesRebinding(t *testing.T) {
17 d, sg, o := fixture(t)
18 key, err := rsa.GenerateKey(rand.Reader, 2048)
19 if err != nil {
20 t.Fatal(err)
21 }
22 cert := &x509.Certificate{PublicKey: &key.PublicKey, PublicKeyAlgorithm: x509.RSA}
23 document := []byte(`{"accountId":"123","region":"eu-west-1","instanceId":"i-new"}`)
24 sum := sha256.Sum256(document)
25 signature, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, sum[:])
26 if err != nil {
27 t.Fatal(err)
28 }
29 rec := boxid.Record{V: 1, Box: "new-label", IdentityDocument: base64.StdEncoding.EncodeToString(document), IdentitySignature: base64.StdEncoding.EncodeToString(signature)}
30 raw, _ := json.Marshal(rec)
31 v := boxid.Verifier{Account: "123", Certs: map[string]*x509.Certificate{"eu-west-1": cert}}
32 in := EnrollmentRequest{Reference: rec.Box, Namespace: "platform", Label: rec.Box, Region: "ie", Pool: "default", AWSRegion: "eu-west-1", Operator: "operator", ExistingReference: true, TofuInstanceID: "i-new"}
33 for _, wrong := range []string{"region", "tofu", "missing-tofu", "operator", "signature"} {
34 request := in
35 body := raw
36 switch wrong {
37 case "region":
38 request.AWSRegion = "us-east-1"
39 case "tofu":
40 request.TofuInstanceID = "i-other"
41 case "missing-tofu":
42 request.TofuInstanceID = ""
43 case "operator":
44 request.Operator = ""
45 case "signature":
46 bad := rec
47 bad.IdentitySignature = base64.StdEncoding.EncodeToString([]byte("wrong"))
48 body, _ = json.Marshal(bad)
49 }
50 if _, err = d.Enroll(context.Background(), sg, o, v, request, body); err == nil {
51 t.Fatal(wrong)
52 }
53 }
54 if _, err = d.Invite(context.Background(), sg, in.Reference, raw); err != nil {
55 t.Fatal(err)
56 }
57 next, err := d.Enroll(context.Background(), sg, o, v, in, raw)
58 if err != nil {
59 t.Fatal(err)
60 }
61 got := next.Roster.Boxes[rec.Box]
62 if got.Cloud.InstanceID != "i-new" || got.BoxID != rec.Box || got.Enrollment == "" {
63 t.Fatal(got)
64 }
65 duplicate := rec
66 duplicate.Box = "second-label"
67 duplicateRaw, _ := json.Marshal(duplicate)
68 duplicateRequest := in
69 duplicateRequest.Reference = duplicate.Box
70 duplicateRequest.Label = duplicate.Box
71 if _, err := d.Invite(context.Background(), sg, duplicate.Box, duplicateRaw); err != nil {
72 t.Fatal(err)
73 }
74 if _, err := d.Enroll(context.Background(), sg, next, v, duplicateRequest, duplicateRaw); err == nil {
75 t.Fatal("one instance enrolled under a second reference")
76 }
77 in.Reference = "box"
78 rec.Box = "box"
79 raw, _ = json.Marshal(rec)
80 if _, err = d.Enroll(context.Background(), sg, next, v, in, raw); err == nil {
81 t.Fatal("reference rebound")
82 }
83}
84
85func TestFleetInvitationBindsReferenceToEnrollment(t *testing.T) {
86 d, sg, o := fixture(t)
87 key, err := rsa.GenerateKey(rand.Reader, 2048)
88 if err != nil {
89 t.Fatal(err)
90 }
91 cert := &x509.Certificate{PublicKey: &key.PublicKey, PublicKeyAlgorithm: x509.RSA}
92 document := []byte(`{"accountId":"123","region":"eu-west-1","instanceId":"i-fleet"}`)
93 sum := sha256.Sum256(document)
94 signature, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA256, sum[:])
95 if err != nil {
96 t.Fatal(err)
97 }
98 rec := boxid.Record{V: 1, IdentityDocument: base64.StdEncoding.EncodeToString(document), IdentitySignature: base64.StdEncoding.EncodeToString(signature)}
99 raw, _ := json.Marshal(rec)
100 invite, err := d.Invite(context.Background(), sg, "", raw)
101 if err != nil {
102 t.Fatal(err)
103 }
104 if invite.Reference != "fleet-"+invite.Enrollment {
105 t.Fatalf("reference = %q, enrollment = %q", invite.Reference, invite.Enrollment)
106 }
107 rec.Box = invite.Reference
108 bound, _ := json.Marshal(rec)
109 retry, err := d.Invite(context.Background(), sg, invite.Reference, bound)
110 if err != nil || retry != invite {
111 t.Fatalf("retry = %+v, %v", retry, err)
112 }
113 if _, err := d.Invite(context.Background(), sg, "fleet-00000000000000000000000000000000", bound); err == nil {
114 t.Fatal("caller-chosen fleet reference accepted")
115 }
116 v := boxid.Verifier{Account: "123", Certs: map[string]*x509.Certificate{"eu-west-1": cert}}
117 ordinary := rec
118 ordinary.Box = "ordinary-label"
119 ordinaryRaw, _ := json.Marshal(ordinary)
120 if _, err := d.Invite(context.Background(), sg, ordinary.Box, ordinaryRaw); err != nil {
121 t.Fatal(err)
122 }
123 badFleet := EnrollmentRequest{Reference: ordinary.Box, Namespace: "fleet:workers", Label: "fleet", Region: "ie", Pool: "default", AWSRegion: "eu-west-1", Operator: "operator"}
124 if _, err := d.Enroll(context.Background(), sg, o, v, badFleet, ordinaryRaw); err == nil {
125 t.Fatal("fleet namespace accepted arbitrary reference")
126 }
127 in := EnrollmentRequest{Reference: invite.Reference, Namespace: "fleet:workers", Label: "fleet", Region: "ie", Pool: "default", AWSRegion: "eu-west-1", Operator: "operator"}
128 next, err := d.Enroll(context.Background(), sg, o, v, in, bound)
129 if err != nil {
130 t.Fatal(err)
131 }
132 if got := next.Roster.Boxes[invite.Reference]; got.Enrollment != invite.Enrollment || got.BoxID != invite.Reference {
133 t.Fatal(got)
134 }
135 rec.Box = "fleet-ffffffffffffffffffffffffffffffff"
136 mismatched, _ := json.Marshal(rec)
137 if _, err := d.Enroll(context.Background(), sg, o, v, in, mismatched); err == nil {
138 t.Fatal("mismatched fleet evidence accepted")
139 }
140}
141