diff --git a/mmv1/third_party/terraform/data_sources/data_source_google_kms_secret_asymmetric.go b/mmv1/third_party/terraform/data_sources/data_source_google_kms_secret_asymmetric.go deleted file mode 100644 index 64d82d727a2c..000000000000 --- a/mmv1/third_party/terraform/data_sources/data_source_google_kms_secret_asymmetric.go +++ /dev/null @@ -1,141 +0,0 @@ -package google - -import ( - "context" - "encoding/base64" - "fmt" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1" - "google.golang.org/protobuf/types/known/wrapperspb" - "hash/crc32" - "regexp" - "strconv" -) - -var ( - cryptoKeyVersionRegexp = regexp.MustCompile(`^(//[^/]*/[^/]*/)?(projects/[^/]+/locations/[^/]+/keyRings/[^/]+/cryptoKeys/[^/]+/cryptoKeyVersions/[^/]+)$`) -) - -func dataSourceGoogleKmsSecretAsymmetric() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceGoogleKmsSecretAsymmetricReadContext, - Schema: map[string]*schema.Schema{ - "crypto_key_version": { - Type: schema.TypeString, - Description: "The fully qualified KMS crypto key version name", - ValidateFunc: validateRegexp(cryptoKeyVersionRegexp.String()), - Required: true, - }, - "ciphertext": { - Type: schema.TypeString, - Description: "The public key encrypted ciphertext in base64 encoding", - ValidateFunc: validateBase64WithWhitespaces, - Required: true, - }, - "crc32": { - Type: schema.TypeString, - Description: "The crc32 checksum of the ciphertext, hexadecimal encoding", - ValidateFunc: validateHexadecimalUint32, - Optional: true, - }, - "plaintext": { - Type: schema.TypeString, - Computed: true, - Sensitive: true, - }, - }, - } -} - -func dataSourceGoogleKmsSecretAsymmetricReadContext(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - var diags diag.Diagnostics - - err := dataSourceGoogleKmsSecretAsymmetricRead(ctx, d, meta) - if err != nil { - diags = diag.FromErr(err) - } - return diags -} - -func dataSourceGoogleKmsSecretAsymmetricRead(ctx context.Context, d *schema.ResourceData, meta interface{}) error { - config := meta.(*Config) - userAgent, err := generateUserAgentString(d, config.userAgent) - if err != nil { - return err - } - - // `google_kms_crypto_key_version` returns an id with the prefix - // //cloudkms.googleapis.com/v1, which is an invalid name. To allow for the most elegant - // configuration, we will allow it as an input. - keyVersion := cryptoKeyVersionRegexp.FindStringSubmatch(d.Get("crypto_key_version").(string)) - cryptoKeyVersion := keyVersion[len(keyVersion)-1] - - base64CipherText := removeWhiteSpaceFromString(d.Get("ciphertext").(string)) - ciphertext, err := base64.StdEncoding.DecodeString(base64CipherText) - if err != nil { - return err - } - - crc32c := func(data []byte) uint32 { - t := crc32.MakeTable(crc32.Castagnoli) - return crc32.Checksum(data, t) - } - - ciphertextCRC32C := crc32c(ciphertext) - if s, ok := d.Get("crc32").(string); ok && s != "" { - u, err := strconv.ParseUint(s, 16, 32) - if err != nil { - return fmt.Errorf("failed to convert crc32 into uint32, %s", err) - } - ciphertextCRC32C = uint32(u) - } else { - if err := d.Set("crc32", fmt.Sprintf("%x", ciphertextCRC32C)); err != nil { - return fmt.Errorf("failed to set crc32, %s", err) - } - } - - req := &kmspb.AsymmetricDecryptRequest{ - Name: cryptoKeyVersion, - Ciphertext: ciphertext, - CiphertextCrc32C: wrapperspb.Int64(int64(ciphertextCRC32C)), - } - - client := config.NewKeyManagementClient(ctx, userAgent) - result, err := client.AsymmetricDecrypt(ctx, req) - if err != nil { - return fmt.Errorf("failed to decrypt ciphertext: %v", err) - } - - if !result.VerifiedCiphertextCrc32C || int64(crc32c(result.Plaintext)) != result.PlaintextCrc32C.Value { - return fmt.Errorf("asymmetricDecrypt request corrupted in-transit") - } - - if err := d.Set("plaintext", string(result.Plaintext)); err != nil { - return fmt.Errorf("error setting plaintext: %s", err) - } - - d.SetId(fmt.Sprintf("%s:%x:%s", cryptoKeyVersion, ciphertextCRC32C, base64CipherText)) - return nil -} - -func removeWhiteSpaceFromString(s string) string { - whitespaceRegexp := regexp.MustCompile(`(?m)[\s]+`) - return whitespaceRegexp.ReplaceAllString(s, "") -} - -func validateBase64WithWhitespaces(i interface{}, val string) ([]string, []error) { - _, err := base64.StdEncoding.DecodeString(removeWhiteSpaceFromString(i.(string))) - if err != nil { - return nil, []error{fmt.Errorf("could not decode %q as a valid base64 value. Please use the terraform base64 functions such as base64encode() or filebase64() to supply a valid base64 string", val)} - } - return nil, nil -} - -func validateHexadecimalUint32(i interface{}, val string) ([]string, []error) { - _, err := strconv.ParseUint(i.(string), 16, 32) - if err != nil { - return nil, []error{fmt.Errorf("could not decode %q as a unsigned 32 bit hexadecimal integer", val)} - } - return nil, nil -} diff --git a/mmv1/third_party/terraform/tests/data_source_google_kms_secret_asymmetric_test.go b/mmv1/third_party/terraform/tests/data_source_google_kms_secret_asymmetric_test.go deleted file mode 100644 index 74d55ee1fa49..000000000000 --- a/mmv1/third_party/terraform/tests/data_source_google_kms_secret_asymmetric_test.go +++ /dev/null @@ -1,153 +0,0 @@ -package google - -import ( - "crypto/rand" - "crypto/rsa" - "crypto/sha256" - "crypto/x509" - "encoding/base64" - "encoding/pem" - "fmt" - "hash/crc32" - "log" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func TestAccKmsSecretAsymmetricBasic(t *testing.T) { - // Nested tests confuse VCR - skipIfVcr(t) - t.Parallel() - - projectOrg := getTestOrgFromEnv(t) - projectBillingAccount := getTestBillingAccountFromEnv(t) - - projectID := "terraform-" + randString(t, 10) - keyRingName := fmt.Sprintf("tf-test-%s", randString(t, 10)) - cryptoKeyName := fmt.Sprintf("tf-test-%s", randString(t, 10)) - - plaintext := fmt.Sprintf("secret-%s", randString(t, 10)) - - // The first test creates resources needed to encrypt plaintext and produce ciphertext - vcrTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: kmsCryptoKeyAsymmetricDecryptBasic(projectID, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName), - Check: func(s *terraform.State) error { - ciphertext, cryptoKeyVersionID, crc, err := testAccEncryptSecretDataAsymmetricWithPublicKey(t, s, "data.google_kms_crypto_key_version.crypto_key", plaintext) - if err != nil { - return err - } - - // The second test asserts that the data source has the correct plaintext, given the created ciphertext - vcrTest(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - Steps: []resource.TestStep{ - { - Config: googleKmsSecretAsymmetricDatasource(cryptoKeyVersionID, ciphertext), - Check: resource.TestCheckResourceAttr("data.google_kms_secret_asymmetric.acceptance", "plaintext", plaintext), - }, - { - Config: googleKmsSecretAsymmetricDatasourceWithCrc(cryptoKeyVersionID, ciphertext, crc), - Check: resource.TestCheckResourceAttr("data.google_kms_secret_asymmetric.acceptance_with_crc", "plaintext", plaintext), - }, - }, - }) - - return nil - }, - }, - }, - }) -} - -func testAccEncryptSecretDataAsymmetricWithPublicKey(t *testing.T, s *terraform.State, cryptoKeyResourceName, plaintext string) (string, string, uint32, error) { - rs, ok := s.RootModule().Resources[cryptoKeyResourceName] - if !ok { - return "", "", 0, fmt.Errorf("resource not found: %s", cryptoKeyResourceName) - } - - cryptoKeyVersionID := rs.Primary.Attributes["id"] - - block, _ := pem.Decode([]byte(rs.Primary.Attributes["public_key.0.pem"])) - publicKey, err := x509.ParsePKIXPublicKey(block.Bytes) - if err != nil { - return "", "", 0, fmt.Errorf("failed to parse public key: %v", err) - } - rsaKey, ok := publicKey.(*rsa.PublicKey) - if !ok { - return "", "", 0, fmt.Errorf("public key is not rsa") - } - - ciphertext, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, rsaKey, []byte(plaintext), nil) - if err != nil { - return "", "", 0, fmt.Errorf("rsa.EncryptOAEP: %v", err) - } - - crc := crc32.Checksum(ciphertext, crc32.MakeTable(crc32.Castagnoli)) - - result := base64.StdEncoding.EncodeToString(ciphertext) - log.Printf("[INFO] Successfully encrypted plaintext and got ciphertext: %s", result) - - return result, cryptoKeyVersionID, crc, nil -} - -func googleKmsSecretAsymmetricDatasource(cryptoKeyTerraformID, ciphertext string) string { - return fmt.Sprintf(` -data "google_kms_secret_asymmetric" "acceptance" { - crypto_key_version = "%s" - ciphertext = "%s" -} -`, cryptoKeyTerraformID, ciphertext) -} - -func googleKmsSecretAsymmetricDatasourceWithCrc(cryptoKeyTerraformID, ciphertext string, crc uint32) string { - return fmt.Sprintf(` -data "google_kms_secret_asymmetric" "acceptance_with_crc" { - crypto_key_version = "%s" - ciphertext = "%s" - crc32 = "%x" -} -`, cryptoKeyTerraformID, ciphertext, crc) -} - -func kmsCryptoKeyAsymmetricDecryptBasic(projectID, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName string) string { - return fmt.Sprintf(` -resource "google_project" "acceptance" { - name = "%s" - project_id = "%s" - org_id = "%s" - billing_account = "%s" -} - -resource "google_project_service" "acceptance" { - project = google_project.acceptance.project_id - service = "cloudkms.googleapis.com" -} - -resource "google_kms_key_ring" "key_ring" { - project = google_project_service.acceptance.project - name = "%s" - location = "us-central1" - depends_on = [google_project_service.acceptance] -} - -resource "google_kms_crypto_key" "crypto_key" { - name = "%s" - key_ring = google_kms_key_ring.key_ring.self_link - purpose = "ASYMMETRIC_DECRYPT" - version_template { - algorithm = "RSA_DECRYPT_OAEP_4096_SHA256" - } -} - -data "google_kms_crypto_key_version" "crypto_key" { - crypto_key = google_kms_crypto_key.crypto_key.id -} -`, projectID, projectID, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName) -} diff --git a/mmv1/third_party/terraform/utils/config.go.erb b/mmv1/third_party/terraform/utils/config.go.erb index 31ef4b736734..d178d2c82c29 100644 --- a/mmv1/third_party/terraform/utils/config.go.erb +++ b/mmv1/third_party/terraform/utils/config.go.erb @@ -6,16 +6,14 @@ import ( "fmt" "log" "net/http" - "net/url" "regexp" "strings" "time" + "google.golang.org/api/option" "github.com/hashicorp/go-cleanhttp" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" - "google.golang.org/api/option" - kms "cloud.google.com/go/kms/apiv1" "golang.org/x/oauth2" googleoauth "golang.org/x/oauth2/google" "golang.org/x/oauth2/jwt" @@ -335,26 +333,6 @@ func (c *Config) NewKmsClient(userAgent string) *cloudkms.Service { return clientKms } -func (c *Config) NewKeyManagementClient(ctx context.Context, userAgent string) *kms.KeyManagementClient { - u, err := url.Parse(c.KMSBasePath) - if err != nil { - log.Printf("[WARN] Error creating client kms invalid base path url %s, %s", c.KMSBasePath, err) - return nil - } - endpoint := u.Host - if u.Port() == "" { - endpoint = fmt.Sprintf("%s:443", u.Host) - } - - log.Printf("[INFO] Instantiating Google Cloud KMS client for path on endpoint %s", endpoint) - clientKms, err := kms.NewKeyManagementClient(ctx, option.WithUserAgent(userAgent), option.WithEndpoint(endpoint)) - if err != nil { - log.Printf("[WARN] Error creating client kms: %s", err) - return nil - } - return clientKms -} - func (c *Config) NewLoggingClient(userAgent string) *cloudlogging.Service { loggingClientBasePath := removeBasePathVersion(c.LoggingBasePath) log.Printf("[INFO] Instantiating Google Stackdriver Logging client for path %s", loggingClientBasePath) diff --git a/mmv1/third_party/terraform/utils/provider.go.erb b/mmv1/third_party/terraform/utils/provider.go.erb index 1467679a1374..3c1e9511f61f 100644 --- a/mmv1/third_party/terraform/utils/provider.go.erb +++ b/mmv1/third_party/terraform/utils/provider.go.erb @@ -233,7 +233,6 @@ func Provider() *schema.Provider { "google_kms_key_ring": dataSourceGoogleKmsKeyRing(), "google_kms_secret": dataSourceGoogleKmsSecret(), "google_kms_secret_ciphertext": dataSourceGoogleKmsSecretCiphertext(), - "google_kms_secret_asymmetric": dataSourceGoogleKmsSecretAsymmetric(), <% unless version == 'ga' -%> "google_firebase_web_app": dataSourceGoogleFirebaseWebApp(), "google_firebase_web_app_config": dataSourceGoogleFirebaseWebappConfig(), diff --git a/mmv1/third_party/terraform/website/docs/d/kms_secret_asymmetric.html.markdown b/mmv1/third_party/terraform/website/docs/d/kms_secret_asymmetric.html.markdown deleted file mode 100644 index 808e49bb2318..000000000000 --- a/mmv1/third_party/terraform/website/docs/d/kms_secret_asymmetric.html.markdown +++ /dev/null @@ -1,149 +0,0 @@ ---- -subcategory: "Cloud Key Management Service" -layout: "google" -page_title: "Google: google_kms_secret_asymmetric" -sidebar_current: "docs-google-kms-secret-asymmetric" -description: |- - Provides access to secret data encrypted with Google Cloud KMS asymmetric key ---- - -# google\_kms\_secret\_asymmetric - -This data source allows you to use data encrypted with a Google Cloud KMS asymmetric key -within your resource definitions. - -For more information see -[the official documentation](https://cloud.google.com/kms/docs/encrypt-decrypt-rsa). - -~> **NOTE:** Using this data provider will allow you to conceal secret data within your -resource definitions, but it does not take care of protecting that data in the -logging output, plan output, or state output. Please take care to secure your secret -data outside of resource definitions. - -## Example Usage - -First, create a KMS KeyRing and CryptoKey using the resource definitions: - -```hcl -resource "google_kms_key_ring" "my_key_ring" { - project = "my-project" - name = "my-key-ring" - location = "us-central1" -} - -resource "google_kms_crypto_key" "my_crypto_key" { - name = "my-crypto-key" - key_ring = google_kms_key_ring.my_key_ring.self_link - purpose = "ASYMMETRIC_DECRYPT" - version_template { - algorithm = "RSA_DECRYPT_OAEP_4096_SHA256" - } -} - -data "google_kms_crypto_key" "my_crypto_key" { - crypto_key = google_kms_crypto_key.my_crypto_key.id -} -``` - -Next, use the [Cloud SDK](https://cloud.google.com/kms/docs/encrypt-decrypt-rsa#kms-encrypt-asymmetric-cli) to encrypt -some sensitive information: - -```bash -## get the public key to encrypt the secret with -$ gcloud kms keys versions get-public-key \ - --project my-project \ - --location us-central1 \ - --keyring my-key-ring \ - --key my-crypto-key \ - --output-file public-key.pem - -## encrypt secret with the public key -$ echo -n my-secret-password | \ - openssl pkeyutl -in - \ - -encrypt \ - -pubin \ - -inkey public-key.pem \ - -pkeyopt rsa_padding_mode:oaep \ - -pkeyopt rsa_oaep_md:sha256 \ - -pkeyopt rsa_mgf1_md:sha256 > \ - my-secret-password.enc - -## base64 encode the ciphertext -$ openssl base64 -in my-secret-password.enc -M7nUoba9EGVTu2LjNjBKGdGVBYjyS/i/AY+4yQMQF0Qf/RfUfX31Jw6+VO9OuThq -ylu/7ihX9XD4bM7yYdXnMv9p1OHQUlorSBSbb/J6n1W9UJhcp6um8Tw8/Isx4f75 -4PskYS6f8Y2ItliGt1/A9iR5BTgGtJBwOxMlgoX2Ggq+Nh4E5SbdoaE5o6CO1nBx -eIPsPEebQ6qC4JehQM3IGuV/lrm58+hZhaXAqNzX1cEYyAt5GYqJIVCiI585SUYs -wRToGyTgaN+zthF0HP9IWlR4Am4LmJ/1OcePTnYw11CkU8wNRbDzVAzogwNH+rXr -LTmf7hxVjBm6bBSVSNFcBKAXFlllubSfIeZ5hgzGqn54OmSf6odO12L5JxllddHc -yAd54vWKs2kJtnsKV2V4ZdkI0w6y1TeI67baFZDNGo6qsCpFMPnvv7d46Pg2VOp1 -J6Ivner0NnNHE4MzNmpZRk8WXMwqq4P/gTiT7F/aCX6oFCUQ4AWPQhJYh2dkcOmL -IP+47Veb10aFn61F1CJwpmOOiGNXKdDT1vK8CMnnwhm825K0q/q9Zqpzc1+1ae1z -mSqol1zCoa88CuSN6nTLQlVnN/dzfrGbc0boJPaM0iGhHtSzHk4SWg84LhiJB1q9 -A9XFJmOVdkvRY9nnz/iVLAdd0Q3vFtLqCdUYsNN2yh4= - -## optionally calculate the CRC32 of the ciphertext -$ go get github.com/binxio/crc32 -$ $GOPATH/bin/crc32 -polynomial castagnoli < my-secret-password.enc -12c59e54 -``` - -Finally, reference the encrypted ciphertext in your resource definitions: - -```hcl -data "google_kms_secret_asymmetric" "sql_user_password" { - crypto_key = data.google_kms_crypto_key_version.my_crypto_key.id - crc32 = "12c59e54" - ciphertext = <