diff --git a/cmd/tuf/add_signatures.go b/cmd/tuf/add_signatures.go index 65087360..d825b1b0 100644 --- a/cmd/tuf/add_signatures.go +++ b/cmd/tuf/add_signatures.go @@ -1,6 +1,7 @@ package main import ( + "encoding/base64" "encoding/json" "fmt" "os" @@ -12,25 +13,46 @@ import ( func init() { register("add-signatures", cmdAddSignature, ` -usage: tuf add-signatures --signatures +usage: tuf add-signatures --signatures= [--format=] [--key-id=] Adds signatures (the output of "sign-payload") to the given role metadata file. If the signature does not verify, it will not be added. + +Options: + --signatures= the path to the file containing the signature(s) + --format= One of 'json', 'hex', or 'base64'. Defaults to 'json' + --key-id= The key-id of the signature being added. Only required if the format is not 'json' `) } func cmdAddSignature(args *docopt.Args, repo *tuf.Repo) error { roleFilename := args.String[""] - f := args.String[""] + f := args.String["--signatures"] sigBytes, err := os.ReadFile(f) if err != nil { return err } sigs := []data.Signature{} - if err = json.Unmarshal(sigBytes, &sigs); err != nil { - return err + switch args.String["--format"] { + case "base64": + base64bytes, err := base64.StdEncoding.DecodeString(string(sigBytes)) + if err != nil { + return err + } + sigs = append(sigs, data.Signature{KeyID: args.String["--key-id"], Signature: base64bytes}) + case "hex": + hex := data.HexBytes{} + if err = hex.FromString(sigBytes); err != nil { + return err + } + sigs = append(sigs, data.Signature{KeyID: args.String["--key-id"], Signature: hex}) + case "json": + default: + if err = json.Unmarshal(sigBytes, &sigs); err != nil { + return err + } } for _, sig := range sigs { if err = repo.AddOrUpdateSignature(roleFilename, sig); err != nil { diff --git a/data/hex_bytes.go b/data/hex_bytes.go index ec200412..36e5a5a3 100644 --- a/data/hex_bytes.go +++ b/data/hex_bytes.go @@ -20,6 +20,15 @@ func (b *HexBytes) UnmarshalJSON(data []byte) error { *b = res return nil } +func (b *HexBytes) FromString(data []byte) error { + res := make([]byte, hex.DecodedLen(len(data))) + _, err := hex.Decode(res, data) + if err != nil { + return err + } + *b = res + return nil +} func (b HexBytes) MarshalJSON() ([]byte, error) { res := make([]byte, hex.EncodedLen(len(b))+2)