1 package main
2
3 import (
4 "encoding/json"
5 "fmt"
6 "log"
7 "os"
8 "os/exec"
9 "path/filepath"
10 "time"
11
12 tuf "github.com/theupdateframework/go-tuf"
13 "github.com/theupdateframework/go-tuf/data"
14 "github.com/theupdateframework/go-tuf/pkg/keys"
15 )
16
17 var expirationDate = time.Date(2100, time.January, 1, 0, 0, 0, 0, time.UTC)
18
19 type persistedKeys struct {
20 Encrypted bool `json:"encrypted"`
21 Data []*data.PrivateKey `json:"data"`
22 }
23
24 func assertNoError(err error) {
25 if err != nil {
26 panic(fmt.Sprintf("assertion failed: %s", err))
27 }
28 }
29
30 func copyRepo(src string, dst string) {
31 cmd := exec.Command("cp", "-r", src, dst)
32 assertNoError(cmd.Run())
33 }
34
35 func newRepo(dir string) *tuf.Repo {
36 repo, err := tuf.NewRepoIndent(tuf.FileSystemStore(dir, nil), "", "\t")
37 assertNoError(err)
38
39 return repo
40 }
41
42 func commit(dir string, repo *tuf.Repo) {
43 assertNoError(repo.SnapshotWithExpires(expirationDate))
44 assertNoError(repo.TimestampWithExpires(expirationDate))
45 assertNoError(repo.Commit())
46
47
48 assertNoError(os.RemoveAll(filepath.Join(dir, "keys")))
49 }
50
51 func addKeys(repo *tuf.Repo, roleKeys map[string][]*data.PrivateKey) {
52 for role, keyList := range roleKeys {
53 for _, key := range keyList {
54 signer, err := keys.GetSigner(key)
55 assertNoError(err)
56 assertNoError(repo.AddPrivateKeyWithExpires(role, signer, expirationDate))
57 }
58 }
59 }
60
61 func addTargets(repo *tuf.Repo, dir string, files map[string][]byte) {
62 paths := []string{}
63 for file, data := range files {
64 path := filepath.Join(dir, "staged", "targets", file)
65 assertNoError(os.MkdirAll(filepath.Dir(path), 0755))
66 assertNoError(os.WriteFile(path, data, 0644))
67 paths = append(paths, file)
68 }
69 assertNoError(repo.AddTargetsWithExpires(paths, nil, expirationDate))
70 }
71
72 func revokeKeys(repo *tuf.Repo, role string, keyList []*data.PrivateKey) {
73 for _, key := range keyList {
74 signer, err := keys.GetSigner(key)
75 assertNoError(err)
76 assertNoError(repo.RevokeKeyWithExpires(role, signer.PublicData().IDs()[0], expirationDate))
77 }
78 }
79
80 func generateRepos(dir string, consistentSnapshot bool) {
81 f, err := os.Open("../keys.json")
82 assertNoError(err)
83
84 var roleKeys map[string][][]*data.PrivateKey
85 assertNoError(json.NewDecoder(f).Decode(&roleKeys))
86
87
88
89 keys := map[string][]*data.PrivateKey{
90 "root": roleKeys["root"][0],
91 "targets": roleKeys["targets"][0],
92 "snapshot": roleKeys["snapshot"][0],
93 "timestamp": roleKeys["timestamp"][0],
94 }
95
96
97 dir0 := filepath.Join(dir, "0")
98 repo0 := newRepo(dir0)
99 repo0.Init(consistentSnapshot)
100 addKeys(repo0, keys)
101 addTargets(repo0, dir0, map[string][]byte{"0": []byte("0")})
102 commit(dir0, repo0)
103
104
105 oldDir := dir0
106 i := 1
107 for _, role := range []string{"root", "targets", "snapshot", "timestamp"} {
108
109 stepName := fmt.Sprintf("%d", i)
110 d := filepath.Join(dir, stepName)
111 copyRepo(oldDir, d)
112 repo := newRepo(d)
113 addKeys(repo, keys)
114
115
116 revokeKeys(repo, role, roleKeys[role][0])
117 addKeys(repo, map[string][]*data.PrivateKey{
118 role: roleKeys[role][1],
119 })
120 keys[role] = roleKeys[role][1]
121
122
123 addTargets(repo, d, map[string][]byte{stepName: []byte(stepName)})
124 commit(d, repo)
125
126 i += 1
127 oldDir = d
128 }
129
130
131 stepName := fmt.Sprintf("%d", i)
132 d := filepath.Join(dir, stepName)
133 copyRepo(oldDir, d)
134 repo := newRepo(d)
135 addKeys(repo, keys)
136 addTargets(repo, d, map[string][]byte{stepName: []byte(stepName)})
137 commit(d, repo)
138 }
139
140 func main() {
141 cwd, err := os.Getwd()
142 assertNoError(err)
143
144 for _, consistentSnapshot := range []bool{false, true} {
145 name := fmt.Sprintf("consistent-snapshot-%t", consistentSnapshot)
146 log.Printf("generating %s", name)
147 generateRepos(filepath.Join(cwd, name), consistentSnapshot)
148 }
149
150 }
151
View as plain text