carlos / platform Public

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

Plain git — no account needed to clone.

Download

Download this file

1package release
2
3import (
4 "context"
5 "encoding/json"
6 "os"
7 "os/exec"
8 "testing"
9
10 "github.com/carlosframework/platform/internal/rootstate"
11)
12
13type generationCertificateCrash struct {
14 rootstate.Store
15 phase string
16}
17
18func (s generationCertificateCrash) Write(k string, b []byte) error {
19 if err := s.Store.Write(k, b); err != nil {
20 return err
21 }
22 var c GenerationCompleteness
23 if k == generationCompletenessKey && json.Unmarshal(b, &c) == nil {
24 if s.phase == "invalidate" && !c.Complete {
25 os.Exit(74)
26 }
27 if s.phase == "certified" && c.Complete && c.Revision > 1 {
28 os.Exit(74)
29 }
30 }
31 return nil
32}
33
34func TestPlan14GenerationCompletenessProcessCrash(t *testing.T) {
35 if dir := os.Getenv("PLAN14_GENERATION_CERT_CHILD"); dir != "" {
36 phase := os.Getenv("PLAN14_GENERATION_CERT_PHASE")
37 disk := &healthyRetryStore{dir: dir}
38 g := &RootGenerations{Store: generationCertificateCrash{disk, phase}}
39 records, err := g.Reservations(t.Context())
40 if err != nil {
41 t.Fatal(err)
42 }
43 _, err = g.Certify(t.Context(), records, func(context.Context, []GenerationReservation) (GenerationEvidence, error) {
44 if phase == "verify" {
45 os.Exit(74)
46 }
47 return generationEvidence(), nil
48 })
49 t.Fatal("crash not reached", err)
50 }
51 for _, phase := range []string{"invalidate", "verify", "certified"} {
52 t.Run(phase, func(t *testing.T) {
53 g, s, b := generationFixture(t)
54 r, err := g.Reserve(b)
55 if err != nil {
56 t.Fatal(err)
57 }
58 records, err := g.Reservations(t.Context())
59 if err != nil {
60 t.Fatal(err)
61 }
62 verify := func(context.Context, []GenerationReservation) (GenerationEvidence, error) {
63 return generationEvidence(), nil
64 }
65 if _, err = g.Certify(t.Context(), records, verify); err != nil {
66 t.Fatal(err)
67 }
68 cmd := exec.Command(os.Args[0], "-test.run=^TestPlan14GenerationCompletenessProcessCrash$", "-test.count=1")
69 cmd.Dir = t.TempDir()
70 cmd.Env = append(os.Environ(), "PLAN14_GENERATION_CERT_CHILD="+s.dir, "PLAN14_GENERATION_CERT_PHASE="+phase)
71 out, err := cmd.CombinedOutput()
72 if code, ok := err.(*exec.ExitError); !ok || code.ExitCode() != 74 {
73 t.Fatalf("wrong crash %v %s", err, out)
74 }
75 reopened := &RootGenerations{Store: s}
76 c, err := reopened.Completeness()
77 if err != nil || c.Complete != (phase == "certified") {
78 t.Fatalf("crash state %+v %v", c, err)
79 }
80 if got, err := reopened.Read(b); err != nil || got != r {
81 t.Fatal("crash lost pin", err)
82 }
83 // Even the positive record cannot replace fresh kernel reconciliation.
84 if _, err := reopened.Certify(t.Context(), records, func(context.Context, []GenerationReservation) (GenerationEvidence, error) {
85 return GenerationEvidence{}, os.ErrPermission
86 }); err == nil {
87 t.Fatal("crashed certificate supplied authority")
88 }
89 if _, err := reopened.Certify(t.Context(), records, verify); err != nil {
90 t.Fatal(err)
91 }
92 })
93 }
94}
95