diff --git a/cmd/sops/main.go b/cmd/sops/main.go index add5571ac..98da824e6 100644 --- a/cmd/sops/main.go +++ b/cmd/sops/main.go @@ -362,9 +362,9 @@ func encrypt(c *cli.Context, file string, fileBytes []byte, output io.Writer) er KeySources: ks, } tree := sops.Tree{Branch: branch, Metadata: metadata} - key, err := tree.GenerateDataKey() - if err != nil { - return cli.NewExitError(err.Error(), exitCouldNotRetrieveKey) + key, errs := tree.GenerateDataKey() + if len(errs) > 0 { + return cli.NewExitError(fmt.Sprintf("Error encrypting the data key with one or more master keys: %s", errs), exitCouldNotRetrieveKey) } cipher := aes.Cipher{} mac, err := tree.Encrypt(key, cipher, nil) @@ -386,9 +386,9 @@ func rotate(c *cli.Context, file string, fileBytes []byte, output io.Writer) err if err != nil { return err } - newKey, err := tree.GenerateDataKey() - if err != nil { - return cli.NewExitError(err.Error(), exitCouldNotRetrieveKey) + newKey, errs := tree.GenerateDataKey() + if len(errs) > 0 { + return cli.NewExitError(fmt.Sprintf("Error encrypting the data key with one or more master keys: %s", errs), exitCouldNotRetrieveKey) } cipher := aes.Cipher{} mac, err := tree.Encrypt(newKey, cipher, nil) @@ -407,7 +407,10 @@ func rotate(c *cli.Context, file string, fileBytes []byte, output io.Writer) err tree.Metadata.AddPGPMasterKeys(c.String("add-pgp")) tree.Metadata.RemoveKMSMasterKeys(c.String("rm-kms")) tree.Metadata.RemovePGPMasterKeys(c.String("rm-pgp")) - tree.Metadata.UpdateMasterKeys(newKey) + errs = tree.Metadata.UpdateMasterKeysIfNeeded(newKey) + if len(errs) > 0 { + return cli.NewExitError(fmt.Sprintf("One or more keys could not be updated:\n%s", errs), exitErrorEncryptingTree) + } tree.Metadata.MessageAuthenticationCode = encryptedMac out, err := outputStore(c, file).MarshalWithMetadata(tree.Branch, tree.Metadata) @@ -481,9 +484,9 @@ func loadExample(c *cli.Context, file string) (sops.Tree, error) { tree.Metadata.UnencryptedSuffix = c.String("unencrypted-suffix") tree.Metadata.Version = version tree.Metadata.KeySources = ks - key, err := tree.GenerateDataKey() - if err != nil { - return tree, cli.NewExitError(err.Error(), exitCouldNotRetrieveKey) + key, errs := tree.GenerateDataKey() + if len(errs) > 0 { + return tree, cli.NewExitError(fmt.Sprintf("Error encrypting the data key with one or more master keys: %s", errs), exitCouldNotRetrieveKey) } tree.Metadata.UpdateMasterKeys(key) return tree, nil diff --git a/sops.go b/sops.go index 521bfda4c..49e51b63b 100644 --- a/sops.go +++ b/sops.go @@ -207,21 +207,13 @@ func (tree Tree) Decrypt(key []byte, cipher DataKeyCipher, stash map[string][]in } // GenerateDataKey generates a new random data key and encrypts it with all MasterKeys. -func (tree Tree) GenerateDataKey() ([]byte, error) { +func (tree Tree) GenerateDataKey() ([]byte, []error) { newKey := make([]byte, 32) _, err := rand.Read(newKey) if err != nil { - return nil, fmt.Errorf("Could not generate random key: %s", err) + return nil, []error{fmt.Errorf("Could not generate random key: %s", err)} } - for _, ks := range tree.Metadata.KeySources { - for _, k := range ks.Keys { - err := k.Encrypt(newKey) - if err != nil { - fmt.Printf("[WARNING]: Failed to encrypt new data key with master key: %s\n", err) - } - } - } - return newKey, nil + return newKey, tree.Metadata.UpdateMasterKeys(newKey) } // Metadata holds information about a file encrypted by sops @@ -280,16 +272,30 @@ func (m *Metadata) RemoveMasterKeys(keys []MasterKey) { } } -// UpdateMasterKeys encrypts the data key with all master keys if it's needed -func (m *Metadata) UpdateMasterKeys(dataKey []byte) { +// UpdateMasterKeysIfNeeded encrypts the data key with all master keys if it's needed +func (m *Metadata) UpdateMasterKeysIfNeeded(dataKey []byte) (errs []error) { for _, ks := range m.KeySources { for _, k := range ks.Keys { err := k.EncryptIfNeeded(dataKey) if err != nil { - fmt.Println("[WARNING]: could not encrypt data key with master key ", k.ToString()) + errs = append(errs, err) } } } + return +} + +// UpdateMasterKeys encrypts the data key with all master keys +func (m *Metadata) UpdateMasterKeys(dataKey []byte) (errs []error) { + for _, ks := range m.KeySources { + for _, k := range ks.Keys { + err := k.Encrypt(dataKey) + if err != nil { + errs = append(errs, err) + } + } + } + return } // AddPGPMasterKeys parses the input comma separated string of GPG fingerprints, generates a PGP MasterKey for each fingerprint, and adds the keys to the PGP KeySource