|
package main |
|
|
|
import ( |
|
"flag" |
|
"log" |
|
"os" |
|
"path/filepath" |
|
|
|
"github.com/theupdateframework/go-tuf" |
|
"github.com/theupdateframework/go-tuf/data" |
|
"github.com/theupdateframework/go-tuf/pkg/keys" |
|
"github.com/xyproto/randomstring" |
|
) |
|
|
|
var ( |
|
workDir string |
|
initMode bool |
|
) |
|
|
|
func init() { |
|
flag.StringVar(&workDir, "work-dir", ".", "Path to directory to generate repository") |
|
flag.BoolVar(&initMode, "init", false, "If true, initialize TUF repository whereas false update the repository.") |
|
} |
|
|
|
func main() { |
|
flag.Parse() |
|
|
|
ls := tuf.FileSystemStore(workDir, nil) |
|
r, err := tuf.NewRepo(ls) |
|
if err != nil { |
|
log.Fatalf("Failed to initialize the repository: %v", err) |
|
} |
|
|
|
if initMode { |
|
log.Println("Initialize TUF repository") |
|
initRepo(r, ls) |
|
} else { |
|
log.Println("Update TUF repository") |
|
updateRepo(r, "my-role/apple.txt") |
|
} |
|
} |
|
|
|
func initRepo(r *tuf.Repo, ls tuf.LocalStore) { |
|
log.Println("Initialize top-level roles") |
|
|
|
_, err := r.GenKey("root") |
|
if err != nil { |
|
log.Fatalf("Failed to generate the root role key: %v", err) |
|
} |
|
_, err = r.GenKey("targets") |
|
if err != nil { |
|
log.Fatalf("Failed to generate the targets role key: %v", err) |
|
} |
|
_, err = r.GenKey("snapshot") |
|
if err != nil { |
|
log.Fatalf("Failed to generate the snapshot role key: %v", err) |
|
} |
|
_, err = r.GenKey("timestamp") |
|
if err != nil { |
|
log.Fatalf("Failed to generate the timestamp role key: %v", err) |
|
} |
|
|
|
// The targets role delegates contents under my-role dir to the my-role role. |
|
log.Println("Initialize delegations") |
|
|
|
myRoleKey, err := keys.GenerateEd25519Key() |
|
if err != nil { |
|
log.Fatalf("Failed to generate the delegated role key: %v", err) |
|
} |
|
if err := ls.SaveSigner("my-role", myRoleKey); err != nil { |
|
log.Fatalf("Failed to save signer: %v", err) |
|
} |
|
delegatedRole := data.DelegatedRole{ |
|
Name: "my-role", |
|
KeyIDs: myRoleKey.PublicData().IDs(), |
|
Paths: []string{"my-role/*"}, |
|
Threshold: 1, |
|
} |
|
if err := r.AddDelegatedRole("targets", delegatedRole, []*data.PublicKey{myRoleKey.PublicData()}); err != nil { |
|
log.Fatalf("Failed to add the delegated role: %v", err) |
|
} |
|
|
|
log.Println("Add some targets") |
|
|
|
files := map[string]string{ |
|
"potato.txt": "potatoes can be starchy or waxy", |
|
"foo/bar/baz.txt": "foo, bar, baz", |
|
"my-role/apple.txt": "apples are sometimes red", |
|
"my-role/banana.txt": "bananas are yellow and sometimes brown", |
|
} |
|
for name, data := range files { |
|
p := filepath.Join(workDir, "staged/targets", name) |
|
os.MkdirAll(filepath.Dir(p), 0755) |
|
os.WriteFile(p, []byte(data), 0644) |
|
r.AddTarget(name, nil) |
|
} |
|
|
|
log.Println("Snapshot") |
|
r.Snapshot() |
|
log.Println("Timestamp") |
|
r.Timestamp() |
|
log.Println("Commit") |
|
r.Commit() |
|
} |
|
|
|
func updateRepo(r *tuf.Repo, name string) { |
|
p := filepath.Join(workDir, "staged/targets", name) |
|
os.MkdirAll(filepath.Dir(p), 0755) |
|
os.WriteFile(p, []byte(randomstring.HumanFriendlyEnglishString(8)), 0644) |
|
r.AddTarget(name, nil) |
|
|
|
log.Println("Snapshot") |
|
r.Snapshot() |
|
r.Timestamp() |
|
|
|
// move contents from staged dir to repository dir |
|
log.Println("Commit") |
|
r.Commit() |
|
} |