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, keys := range roleKeys {
53 for _, key := range keys {
54 assertNoError(repo.AddPrivateKeyWithExpires(role, key, expirationDate))
55 }
56 }
57 }
58
59 func addTargets(repo *tuf.Repo, dir string, files map[string][]byte) {
60 paths := []string{}
61 for file, data := range files {
62 path := filepath.Join(dir, "staged", "targets", file)
63 assertNoError(os.MkdirAll(filepath.Dir(path), 0755))
64 assertNoError(os.WriteFile(path, data, 0644))
65 paths = append(paths, file)
66 }
67 assertNoError(repo.AddTargetsWithExpires(paths, nil, expirationDate))
68 }
69
70 func revokeKeys(repo *tuf.Repo, role string, keyList []*data.PrivateKey) {
71 for _, key := range keyList {
72 signer, err := keys.GetSigner(key)
73 assertNoError(err)
74 assertNoError(repo.RevokeKeyWithExpires(role, signer.PublicData().IDs()[0], expirationDate))
75 }
76 }
77
78 func generateRepos(dir string, consistentSnapshot bool) {
79 f, err := os.Open("../keys.json")
80 assertNoError(err)
81
82 var roleKeys map[string][][]*data.PrivateKey
83 assertNoError(json.NewDecoder(f).Decode(&roleKeys))
84
85
86
87 keys := map[string][]*data.PrivateKey{
88 "root": roleKeys["root"][0],
89 "targets": roleKeys["targets"][0],
90 "snapshot": roleKeys["snapshot"][0],
91 "timestamp": roleKeys["timestamp"][0],
92 }
93
94
95 dir0 := filepath.Join(dir, "0")
96 repo0 := newRepo(dir0)
97 repo0.Init(consistentSnapshot)
98 addKeys(repo0, keys)
99 addTargets(repo0, dir0, map[string][]byte{"0": []byte("0")})
100 commit(dir0, repo0)
101
102
103 oldDir := dir0
104 i := 1
105 for _, role := range []string{"root", "targets", "snapshot", "timestamp"} {
106
107 stepName := fmt.Sprintf("%d", i)
108 d := filepath.Join(dir, stepName)
109 copyRepo(oldDir, d)
110 repo := newRepo(d)
111 addKeys(repo, keys)
112
113
114 revokeKeys(repo, role, roleKeys[role][0])
115 addKeys(repo, map[string][]*data.PrivateKey{
116 role: roleKeys[role][1],
117 })
118 keys[role] = roleKeys[role][1]
119
120
121 addTargets(repo, d, map[string][]byte{stepName: []byte(stepName)})
122 commit(d, repo)
123
124 i += 1
125 oldDir = d
126 }
127
128
129 stepName := fmt.Sprintf("%d", i)
130 d := filepath.Join(dir, stepName)
131 copyRepo(oldDir, d)
132 repo := newRepo(d)
133 addKeys(repo, keys)
134 addTargets(repo, d, map[string][]byte{stepName: []byte(stepName)})
135 commit(d, repo)
136 }
137
138 func main() {
139 cwd, err := os.Getwd()
140 assertNoError(err)
141
142 for _, consistentSnapshot := range []bool{false, true} {
143 name := fmt.Sprintf("consistent-snapshot-%t", consistentSnapshot)
144 log.Printf("generating %s", name)
145 generateRepos(filepath.Join(cwd, name), consistentSnapshot)
146 }
147
148 }
149
View as plain text