Skip to content

Commit

Permalink
Add "keys copy-targets" command
Browse files Browse the repository at this point in the history
This helps operators not need the super secure offline root keys
for rolling out updates

Signed-off-by: Andy Doan <andy@foundries.io>
  • Loading branch information
doanac committed Apr 5, 2021
1 parent 4c121dd commit 48da76b
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 1 deletion.
68 changes: 68 additions & 0 deletions subcommands/keys/copy_targets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package keys

import (
"encoding/json"
"errors"
"strings"

"github.com/foundriesio/fioctl/client"
"github.com/foundriesio/fioctl/subcommands"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

func init() {
copy := &cobra.Command{
Use: "copy-targets <offline key archive> <new targets archive>",
Short: "Copy the target signing credentials from the offline key archive",
Run: doCopyTargets,
Args: cobra.ExactArgs(2),
Long: `This command extracts the target signing credentials required for initializing
waves into a new tarball so that the offline key archive isn't required for
rolling out production updates. This should be run after each target key
rotation and distributed to the operator in charge of production OTAs.`,
}
subcommands.RequireFactory(copy)
cmd.AddCommand(copy)
}

func doCopyTargets(cmd *cobra.Command, args []string) {
factory := viper.GetString("factory")
credsFile := args[0]
creds, err := GetOfflineCreds(credsFile)
subcommands.DieNotNil(err)

root, err := api.TufRootGet(factory)
subcommands.DieNotNil(err)

targetsCreds, err := createTargetsCreds(factory, *root, creds)
subcommands.DieNotNil(err)
saveCreds(args[1], targetsCreds)
}

func createTargetsCreds(factory string, root client.AtsTufRoot, creds OfflineCreds) (OfflineCreds, error) {
targets := make(OfflineCreds)
onlinePub, err := api.GetFoundriesTargetsKey(factory)
subcommands.DieNotNil(err)
for _, keyid := range root.Signed.Roles["targets"].KeyIDs {
pubkey := root.Signed.Keys[keyid].KeyValue.Public
if pubkey != onlinePub.KeyValue.Public {
pubkey = strings.TrimSpace(pubkey)
for k, v := range creds {
if strings.HasSuffix(k, ".pub") {
tk := client.AtsKey{}
if err := json.Unmarshal(v, &tk); err != nil {
return nil, err
}
if strings.TrimSpace(tk.KeyValue.Public) == pubkey {
targets[k] = v
pkname := strings.Replace(k, ".pub", ".sec", 1)
targets[pkname] = creds[pkname]
return targets, nil
}
}
}
}
}
return targets, errors.New("Unable to find offline target key for factory")
}
5 changes: 4 additions & 1 deletion subcommands/keys/rotate_root.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,11 @@ Please move this file somewhere safe before re-running this command.`,
path,
))
}
saveCreds(path, creds)
return path
}

func saveCreds(path string, creds OfflineCreds) {
file, err := os.Create(path)
subcommands.DieNotNil(err)
defer file.Close()
Expand All @@ -246,7 +250,6 @@ Please move this file somewhere safe before re-running this command.`,
_, err := tarWriter.Write(val)
subcommands.DieNotNil(err)
}
return path
}

func findRoot(root client.AtsTufRoot, creds OfflineCreds) (string, *rsa.PrivateKey, error) {
Expand Down

0 comments on commit 48da76b

Please sign in to comment.