diff --git a/Makefile b/Makefile index 11a04e6d6..ee2860d60 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ test: gpg --import pgp/sops_functional_tests_key.asc 2>&1 1>/dev/null || exit 0 $(GO) test $(PROJECT)/pgp -coverprofile=coverage_tmp.txt -covermode=atomic && cat coverage_tmp.txt >> coverage.txt $(GO) test $(PROJECT)/kms -coverprofile=coverage_tmp.txt -covermode=atomic && cat coverage_tmp.txt >> coverage.txt - $(GO) test $(PROJECT)/cloudkms -coverprofile=coverage_tmp.txt -covermode=atomic && cat coverage_tmp.txt >> coverage.txt + $(GO) test $(PROJECT)/gcpkms -coverprofile=coverage_tmp.txt -covermode=atomic && cat coverage_tmp.txt >> coverage.txt showcoverage: test $(GO) tool cover -html=coverage.out diff --git a/cmd/sops/main.go b/cmd/sops/main.go index 35e894567..d780e0f4b 100644 --- a/cmd/sops/main.go +++ b/cmd/sops/main.go @@ -21,7 +21,7 @@ import ( "github.com/google/shlex" "go.mozilla.org/sops/aes" - "go.mozilla.org/sops/cloudkms" + "go.mozilla.org/sops/gcpkms" "go.mozilla.org/sops/json" "go.mozilla.org/sops/kms" "go.mozilla.org/sops/pgp" @@ -92,7 +92,7 @@ func main() { cli.VersionPrinter = printVersion app := cli.NewApp() app.Name = "sops" - app.Usage = "sops - encrypted file editor with AWS KMS, google cloud KMS and GPG support" + app.Usage = "sops - encrypted file editor with AWS KMS, GCP KMS and GPG support" app.ArgsUsage = "sops [options] file" app.Version = version app.Authors = []cli.Author{ @@ -105,8 +105,8 @@ func main() { in the -k flag or in the SOPS_KMS_ARN environment variable. (you need valid credentials in ~/.aws/credentials or in your env) - To encrypt or decrypt a document with google cloud KMS, specify the - cloud KMS resource Id in the -c flag or in the SOPS_CLOUD_KMS_IDS + To encrypt or decrypt a document with GCP KMS, specify the + GCP KMS resource ID in the --gcp-kms flag or in the SOPS_GCP_KMS_IDS environment variable. (you need to setup google application default credentials. See https://developers.google.com/identity/protocols/application-default-credentials) @@ -121,7 +121,7 @@ func main() { decrypting existing documents can be done with "sops file" or "sops -d file" respectively. The KMS and PGP keys listed in the encrypted documents are used then. To manage master keys in existing documents, use - the "add-{kms,pgp,cloud-kms}" and "rm-{kms,pgp,cloud-kms}" flags. + the "add-{kms,pgp,gcp-kms}" and "rm-{kms,pgp,gcp-kms}" flags. To use a different GPG binary than the one in your PATH, set SOPS_GPG_EXEC. @@ -148,9 +148,9 @@ func main() { EnvVar: "SOPS_KMS_ARN", }, cli.StringFlag{ - Name: "cloud-kms, c", - Usage: "comma separated list of google cloud KMS resource IDs", - EnvVar: "SOPS_CLOUD_KMS_IDS", + Name: "gcp-kms", + Usage: "comma separated list of GCP KMS resource IDs", + EnvVar: "SOPS_CGP_KMS_IDS", }, cli.StringFlag{ Name: "pgp, p", @@ -178,12 +178,12 @@ func main() { Usage: "display master encryption keys in the file during editing", }, cli.StringFlag{ - Name: "add-cloud-kms", - Usage: "add the provided comma-separated list of google cloud KMS key resource IDs to the list of master keys on the given file", + Name: "add-gcp-kms", + Usage: "add the provided comma-separated list of GCP KMS key resource IDs to the list of master keys on the given file", }, cli.StringFlag{ - Name: "rm-cloud-kms", - Usage: "remove the provided comma-separated list of google cloud KMS key resource IDs from the list of master keys on the given file", + Name: "rm-gcp-kms", + Usage: "remove the provided comma-separated list of GCP KMS key resource IDs from the list of master keys on the given file", }, cli.StringFlag{ Name: "add-kms", @@ -230,7 +230,7 @@ func main() { } fileName := c.Args()[0] if _, err := os.Stat(fileName); os.IsNotExist(err) { - if c.String("add-kms") != "" || c.String("add-pgp") != "" || c.String("add-cloud-kms") != "" || c.String("rm-kms") != "" || c.String("rm-pgp") != "" || c.String("rm-cloud-kms") != "" { + if c.String("add-kms") != "" || c.String("add-pgp") != "" || c.String("add-gcp-kms") != "" || c.String("rm-kms") != "" || c.String("rm-pgp") != "" || c.String("rm-gcp-kms") != "" { return cli.NewExitError("Error: cannot add or remove keys on non-existent files, use `--kms` and `--pgp` instead.", 49) } if c.Bool("encrypt") || c.Bool("decrypt") || c.Bool("rotate") { @@ -423,8 +423,8 @@ func getKeySources(c *cli.Context, file string) ([]sops.KeySource, error) { kmsKeys = append(kmsKeys, k) } } - if c.String("cloud-kms") != "" { - for _, k := range cloudkms.MasterKeysFromResourceIdString(c.String("cloud-kms")) { + if c.String("gcp-kms") != "" { + for _, k := range gcpkms.MasterKeysFromResourceIdString(c.String("gcp-kms")) { cloudKmsKeys = append(cloudKmsKeys, k) } } @@ -434,7 +434,7 @@ func getKeySources(c *cli.Context, file string) ([]sops.KeySource, error) { } } var err error - if c.String("kms") == "" && c.String("pgp") == "" && c.String("cloud-kms") == "" { + if c.String("kms") == "" && c.String("pgp") == "" && c.String("gcp-kms") == "" { var confBytes []byte if c.String("config") != "" { confBytes, err = ioutil.ReadFile(c.String("config")) @@ -454,7 +454,7 @@ func getKeySources(c *cli.Context, file string) ([]sops.KeySource, error) { } kmsKs := sops.KeySource{Name: "kms", Keys: kmsKeys} pgpKs := sops.KeySource{Name: "pgp", Keys: pgpKeys} - cloudKmsKs := sops.KeySource{Name: "cloud-kms", Keys: cloudKmsKeys} + cloudKmsKs := sops.KeySource{Name: "gcp_kms", Keys: cloudKmsKeys} return []sops.KeySource{kmsKs, cloudKmsKs, pgpKs}, nil } @@ -500,10 +500,10 @@ func rotate(c *cli.Context, tree sops.Tree, outputStore sops.Store) ([]byte, err } tree.Metadata.AddKMSMasterKeys(c.String("add-kms"), kmsEncryptionContext) tree.Metadata.AddPGPMasterKeys(c.String("add-pgp")) - tree.Metadata.AddCloudKMSMasterKeys(c.String("add-cloud-kms")) + tree.Metadata.AddGCPKMSMasterKeys(c.String("add-gcp-kms")) tree.Metadata.RemoveKMSMasterKeys(c.String("rm-kms")) tree.Metadata.RemovePGPMasterKeys(c.String("rm-pgp")) - tree.Metadata.RemoveCloudKMSMasterKeys(c.String("rm-cloud-kms")) + tree.Metadata.RemoveGCPKMSMasterKeys(c.String("rm-gcp-kms")) _, errs := tree.GenerateDataKey() if len(errs) > 0 { return nil, cli.NewExitError(fmt.Sprintf("Error encrypting the data key with one or more master keys: %s", errs), exitCouldNotRetrieveKey) diff --git a/cloudkms/keysource.go b/gcpkms/keysource.go similarity index 77% rename from cloudkms/keysource.go rename to gcpkms/keysource.go index 30167b615..408f80d2f 100644 --- a/cloudkms/keysource.go +++ b/gcpkms/keysource.go @@ -1,4 +1,4 @@ -package cloudkms //import "go.mozilla.org/sops/cloudkms" +package gcpkms //import "go.mozilla.org/sops/gcpkms" import ( "encoding/base64" @@ -13,30 +13,25 @@ import ( cloudkms "google.golang.org/api/cloudkms/v1" ) -// this needs to be a global var for unit tests to work (mockKMS redefines -// it in keysource_test.go) -// var kmsSvc kmsiface.KMSAPI -// var isMocked bool - -// MasterKey is a cloud KMS key used to encrypt and decrypt sops' data key. +// MasterKey is a GCP KMS key used to encrypt and decrypt sops' data key. type MasterKey struct { ResourceId string EncryptedKey string CreationDate time.Time } -// Encrypt takes a sops data key, encrypts it with cloud KMS and stores the result in the EncryptedKey field +// Encrypt takes a sops data key, encrypts it with GCP KMS and stores the result in the EncryptedKey field func (key *MasterKey) Encrypt(dataKey []byte) error { cloudkmsService, err := key.createCloudKMSService() if err != nil { - return fmt.Errorf("Cannot create cloud KMS service: %v", err) + return fmt.Errorf("Cannot create GCP KMS service: %v", err) } req := &cloudkms.EncryptRequest{ Plaintext: base64.StdEncoding.EncodeToString(dataKey), } resp, err := cloudkmsService.Projects.Locations.KeyRings.CryptoKeys.Encrypt(key.ResourceId, req).Do() if err != nil { - return fmt.Errorf("Failed to call cloud KMS encryption service: %v", err) + return fmt.Errorf("Failed to call GCP KMS encryption service: %v", err) } key.EncryptedKey = resp.Ciphertext @@ -51,11 +46,11 @@ func (key *MasterKey) EncryptIfNeeded(dataKey []byte) error { return nil } -// Decrypt decrypts the EncryptedKey field with cloud KMS and returns the result. +// Decrypt decrypts the EncryptedKey field with CGP KMS and returns the result. func (key *MasterKey) Decrypt() ([]byte, error) { cloudkmsService, err := key.createCloudKMSService() if err != nil { - return nil, fmt.Errorf("Cannot create cloud KMS service: %v", err) + return nil, fmt.Errorf("Cannot create GCP KMS service: %v", err) } req := &cloudkms.DecryptRequest{ @@ -78,7 +73,7 @@ func (key *MasterKey) ToString() string { return key.ResourceId } -// NewMasterKeyFromResourceId takes an cloud KMS resource id string and returns a new MasterKey for that +// NewMasterKeyFromResourceId takes a GCP KMS resource ID string and returns a new MasterKey for that func NewMasterKeyFromResourceId(resourceId string) *MasterKey { k := &MasterKey{} resourceId = strings.Replace(resourceId, " ", "", -1) @@ -87,8 +82,7 @@ func NewMasterKeyFromResourceId(resourceId string) *MasterKey { return k } -// MasterKeysFromResourceIdString takes a comma separated list of cloud KMS -// resourece IDs and returns a slice of new MasterKeys for them +// MasterKeysFromResourceIdString takes a comma separated list of GCP KMS resourece IDs and returns a slice of new MasterKeys for them func MasterKeysFromResourceIdString(resourceId string) []*MasterKey { var keys []*MasterKey if resourceId == "" { diff --git a/cloudkms/keysource_test.go b/gcpkms/keysource_test.go similarity index 94% rename from cloudkms/keysource_test.go rename to gcpkms/keysource_test.go index d24a6dcf8..4c546c1e5 100644 --- a/cloudkms/keysource_test.go +++ b/gcpkms/keysource_test.go @@ -1,4 +1,4 @@ -package cloudkms +package gcpkms import ( "testing" @@ -7,7 +7,7 @@ import ( "github.com/stretchr/testify/assert" ) -func TestCloudKMSKeySourceFromString(t *testing.T) { +func TestGCPKMSKeySourceFromString(t *testing.T) { s := "projects/sops-testing1/locations/global/keyRings/creds/cryptoKeys/key1, projects/sops-testing2/locations/global/keyRings/creds/cryptoKeys/key2" ks := MasterKeysFromResourceIdString(s) k1 := ks[0] diff --git a/sops.go b/sops.go index cd6e3a3ba..4842f240b 100644 --- a/sops.go +++ b/sops.go @@ -43,7 +43,7 @@ import ( "strings" "time" - "go.mozilla.org/sops/cloudkms" + "go.mozilla.org/sops/gcpkms" "go.mozilla.org/sops/kms" "go.mozilla.org/sops/pgp" ) @@ -386,14 +386,14 @@ func (m *Metadata) AddPGPMasterKeys(pgpFps string) { } } -// AddCloudKMSMasterKeys parses the input comma separated string of cloud KMS resource IDs, generates a KMS MasterKey for each resource ID, and then adds the keys to the cloud KMS KeySource -func (m *Metadata) AddCloudKMSMasterKeys(resourceIds string) { +// AddGCPKMSMasterKeys parses the input comma separated string of GCP KMS resource IDs, generates a MasterKey for each resource ID, and then adds the keys to the GCP KMS KeySource +func (m *Metadata) AddGCPKMSMasterKeys(resourceIds string) { for i, ks := range m.KeySources { - if ks.Name == "cloud-kms" { + if ks.Name == "gcp_kms" { var keys []MasterKey - for _, k := range cloudkms.MasterKeysFromResourceIdString(resourceIds) { + for _, k := range gcpkms.MasterKeysFromResourceIdString(resourceIds) { keys = append(keys, k) - fmt.Printf("Adding new cloud KMS master key: %s\n", k.ResourceId) + fmt.Printf("Adding new GCP KMS master key: %s\n", k.ResourceId) } ks.Keys = append(ks.Keys, keys...) m.KeySources[i] = ks @@ -434,10 +434,10 @@ func (m *Metadata) RemoveKMSMasterKeys(arns string) { m.RemoveMasterKeys(keys) } -// RemoveCloudKMSMasterKeys takes a comma separated string of cloud KMS resource IDs and removes the corresponding keys -func (m *Metadata) RemoveCloudKMSMasterKeys(resourceIds string) { +// RemoveGCPKMSMasterKeys takes a comma separated string of GCP KMS resource IDs and removes the corresponding keys +func (m *Metadata) RemoveGCPKMSMasterKeys(resourceIds string) { var keys []MasterKey - for _, k := range cloudkms.MasterKeysFromResourceIdString(resourceIds) { + for _, k := range gcpkms.MasterKeysFromResourceIdString(resourceIds) { keys = append(keys, k) } m.RemoveMasterKeys(keys) @@ -472,6 +472,8 @@ func (m Metadata) GetDataKey() ([]byte, error) { keyType := "Unknown" if _, ok := k.(*pgp.MasterKey); ok { keyType = "GPG" + } else if _, ok := k.(*gcpkms.MasterKey); ok { + keyType = "GCP KMS" } else if _, ok := k.(*kms.MasterKey); ok { keyType = "KMS" } @@ -528,8 +530,8 @@ func MapToMetadata(data map[string]interface{}) (Metadata, error) { } } - if cloudk, ok := data["cloud-kms"].([]interface{}); ok { - ks, err := mapCloudKMSEntriesToKeySource(cloudk) + if gcpk, ok := data["gcp_kms"].([]interface{}); ok { + ks, err := mapGCPKMSEntriesToKeySource(gcpk) if err == nil { metadata.KeySources = append(metadata.KeySources, ks) } @@ -556,9 +558,9 @@ func convertToMapStringInterface(in map[interface{}]interface{}) (map[string]int return m, nil } -func mapCloudKMSEntriesToKeySource(in []interface{}) (KeySource, error) { +func mapGCPKMSEntriesToKeySource(in []interface{}) (KeySource, error) { var keys []MasterKey - keysource := KeySource{Name: "cloud-kms", Keys: keys} + keysource := KeySource{Name: "gcp_kms", Keys: keys} for _, v := range in { entry, ok := v.(map[string]interface{}) if !ok { @@ -566,11 +568,11 @@ func mapCloudKMSEntriesToKeySource(in []interface{}) (KeySource, error) { var err error entry, err = convertToMapStringInterface(m) if !ok || err != nil { - fmt.Println("Cloud KMS entry has invalid format, skipping...") + fmt.Println("GCP KMS entry has invalid format, skipping...") continue } } - key := &cloudkms.MasterKey{} + key := &gcpkms.MasterKey{} key.ResourceId = entry["resource_id"].(string) key.EncryptedKey = entry["enc"].(string) creationDate, err := time.Parse(time.RFC3339, entry["created_at"].(string))