From 2aba401607c47f7eb97f02645e5721287bc42b4f Mon Sep 17 00:00:00 2001 From: David Lawrence Date: Tue, 16 Jun 2015 14:07:11 -0700 Subject: [PATCH] good start on tuf commands --- cmd/notary/tuf.go | 221 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 216 insertions(+), 5 deletions(-) diff --git a/cmd/notary/tuf.go b/cmd/notary/tuf.go index da7ca238be..f585b177be 100644 --- a/cmd/notary/tuf.go +++ b/cmd/notary/tuf.go @@ -1,9 +1,21 @@ package main import ( + "bytes" + "encoding/json" "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + "github.com/endophage/gotuf" + "github.com/endophage/gotuf/client" + "github.com/endophage/gotuf/data" + "github.com/endophage/gotuf/keys" + "github.com/endophage/gotuf/store" "github.com/spf13/cobra" + "github.com/spf13/viper" ) var cmdTuf = &cobra.Command{ @@ -69,10 +81,77 @@ var cmdTufPush = &cobra.Command{ } func tufAdd(cmd *cobra.Command, args []string) { - if len(args) < 1 { + if len(args) < 3 { cmd.Usage() - fatalf("must specify a QDN") + fatalf("must specify a QDN, target name, and local path to target data") } + + qdn := args[0] + targetName := args[1] + targetPath := args[2] + kdb := keys.NewDB() + repo := tuf.NewTufRepo(kdb, nil) + + filestore, err := store.NewFilesystemStore( + path.Join(viper.GetString("tufDir"), qdn), // TODO: base trust dir from config + "metadata", + "json", + "targets", + ) + + b, err := ioutil.ReadFile(targetPath) + if err != nil { + fatalf(err.Error()) + } + + rootJSON, err := filestore.GetMeta("root", 0) + if err != nil { + fatalf(err.Error()) + } + root := &data.Signed{} + err = json.Unmarshal(rootJSON, root) + if err != nil { + fatalf(err.Error()) + } + repo.SetRoot(root) + targetsJSON, err := filestore.GetMeta("targets", 0) + if err != nil { + fatalf(err.Error()) + } + targets := &data.Signed{} + err = json.Unmarshal(targetsJSON, targets) + if err != nil { + fatalf(err.Error()) + } + repo.SetTargets("targets", targets) + snapshotJSON, err := filestore.GetMeta("snapshot", 0) + if err != nil { + fatalf(err.Error()) + } + snapshot := &data.Signed{} + err = json.Unmarshal(snapshotJSON, snapshot) + if err != nil { + fatalf(err.Error()) + } + repo.SetSnapshot(snapshot) + timestampJSON, err := filestore.GetMeta("timestamp", 0) + if err != nil { + fatalf(err.Error()) + } + timestamp := &data.Signed{} + err = json.Unmarshal(timestampJSON, timestamp) + if err != nil { + fatalf(err.Error()) + } + repo.SetTimestamp(timestamp) + + meta, err := data.NewFileMeta(bytes.NewBuffer(b)) + if err != nil { + fatalf(err.Error()) + } + repo.AddTargets("targets", data.Files{targetName: meta}) + + saveRepo(repo, filestore) } func tufInit(cmd *cobra.Command, args []string) { @@ -80,6 +159,23 @@ func tufInit(cmd *cobra.Command, args []string) { cmd.Usage() fatalf("must specify a QDN") } + + qdn := args[0] + kdb := keys.NewDB() + repo := tuf.NewTufRepo(kdb, nil) + + filestore, err := store.NewFilesystemStore( + path.Join(viper.GetString("tufDir"), qdn), // TODO: base trust dir from config + "metadata", + "json", + "targets", + ) + + err = repo.InitRepo(false) + if err != nil { + fatalf(err.Error()) + } + saveRepo(repo, filestore) } func tufList(cmd *cobra.Command, args []string) { @@ -90,13 +186,46 @@ func tufList(cmd *cobra.Command, args []string) { } func tufLookup(cmd *cobra.Command, args []string) { - if len(args) < 1 { + if len(args) < 2 { cmd.Usage() - fatalf("must specify a QDN") + fatalf("must specify a QDN and target path to look up.") } fmt.Println("Remote trust server configured: " + remoteTrustServer) + qdn := args[0] + targetName := args[1] + kdb := keys.NewDB() + repo := tuf.NewTufRepo(kdb, nil) + remote, err := store.NewHTTPStore( + "https://localhost:4443/v2"+qdn+"/_trust/tuf/", + "", + "json", + "", + ) + + rootJSON, err := remote.GetMeta("root", 0) + root := &data.Signed{} + err = json.Unmarshal(rootJSON, root) + if err != nil { + fatalf(err.Error()) + } + // TODO: Validate the root file against the key store + repo.SetRoot(root) + + c := client.NewClient( + repo, + remote, + kdb, + ) + + err = c.Update() + if err != nil { + fatalf(err.Error()) + } + m := c.TargetMeta(targetName) + // TODO: how to we want to output hash and size + fmt.Println(m.Hashes["sha256"], " ", m.Length) } func tufPush(cmd *cobra.Command, args []string) { @@ -105,7 +234,54 @@ func tufPush(cmd *cobra.Command, args []string) { fatalf("must specify a QDN") } - fmt.Println("Remote trust server configured: " + remoteTrustServer) + qdn := args[0] + + remote, err := store.NewHTTPStore( + "https://localhost:4443/v2"+qdn+"/_trust/tuf/", + "", + "json", + "", + ) + filestore, err := store.NewFilesystemStore( + "", // TODO: base trust dir from config + "metadata", + "json", + "targets", + ) + + root, err := filestore.GetMeta("root", 0) + if err != nil { + fatalf(err.Error()) + } + targets, err := filestore.GetMeta("targets", 0) + if err != nil { + fatalf(err.Error()) + } + snapshot, err := filestore.GetMeta("snapshot", 0) + if err != nil { + fatalf(err.Error()) + } + timestamp, err := filestore.GetMeta("timestamp", 0) + if err != nil { + fatalf(err.Error()) + } + + err = remote.SetMeta("root", root) + if err != nil { + fatalf(err.Error()) + } + err = remote.SetMeta("targets", targets) + if err != nil { + fatalf(err.Error()) + } + err = remote.SetMeta("snapshot", snapshot) + if err != nil { + fatalf(err.Error()) + } + err = remote.SetMeta("timestamp", timestamp) + if err != nil { + fatalf(err.Error()) + } } func tufRemove(cmd *cobra.Command, args []string) { @@ -114,3 +290,38 @@ func tufRemove(cmd *cobra.Command, args []string) { fatalf("must specify a QDN") } } + +func saveRepo(repo *tuf.TufRepo, filestore store.MetadataStore) error { + signedRoot, err := repo.SignRoot(data.DefaultExpires("root")) + if err != nil { + return err + } + rootJSON, _ := json.Marshal(signedRoot) + filestore.SetMeta("root", rootJSON) + + for r, _ := range repo.Targets { + signedTargets, err := repo.SignTargets(r, data.DefaultExpires("targets")) + if err != nil { + return err + } + targetsJSON, _ := json.Marshal(signedTargets) + parentDir := filepath.Dir(r) + os.MkdirAll(parentDir, 0755) + filestore.SetMeta(r, targetsJSON) + } + + signedSnapshot, err := repo.SignSnapshot(data.DefaultExpires("snapshot")) + if err != nil { + return err + } + snapshotJSON, _ := json.Marshal(signedSnapshot) + filestore.SetMeta("snapshot", snapshotJSON) + + signedTimestamp, err := repo.SignTimestamp(data.DefaultExpires("timestamp")) + if err != nil { + return err + } + timestampJSON, _ := json.Marshal(signedTimestamp) + filestore.SetMeta("timestamp", timestampJSON) + return nil +}