diff --git a/products/kms/api.yaml b/products/kms/api.yaml index d81ab71b4159..bb37ac0818b7 100644 --- a/products/kms/api.yaml +++ b/products/kms/api.yaml @@ -168,6 +168,10 @@ objects: description: | The plaintext to be encrypted. required: true + - !ruby/object:Api::Type::String + name: 'additionalAuthenticatedData' + description: | + The additional authenticated data used for integrity checks during encryption and decryption. - !ruby/object:Api::Type::String name: 'ciphertext' description: | diff --git a/products/kms/terraform.yaml b/products/kms/terraform.yaml index d562ee246c9d..ab48f697aa00 100644 --- a/products/kms/terraform.yaml +++ b/products/kms/terraform.yaml @@ -130,6 +130,10 @@ overrides: !ruby/object:Overrides::ResourceOverrides ignore_read: true sensitive: true custom_expand: templates/terraform/custom_expand/base64.go.erb + additionalAuthenticatedData: !ruby/object:Overrides::Terraform::PropertyOverride + ignore_read: true + sensitive: true + custom_expand: templates/terraform/custom_expand/base64.go.erb ciphertext: !ruby/object:Overrides::Terraform::PropertyOverride ignore_read: true custom_code: !ruby/object:Provider::Terraform::CustomCode diff --git a/third_party/terraform/data_sources/data_source_google_kms_secret.go b/third_party/terraform/data_sources/data_source_google_kms_secret.go index 580d0f647497..10b2aaa22133 100644 --- a/third_party/terraform/data_sources/data_source_google_kms_secret.go +++ b/third_party/terraform/data_sources/data_source_google_kms_secret.go @@ -27,6 +27,10 @@ func dataSourceGoogleKmsSecret() *schema.Resource { Computed: true, Sensitive: true, }, + "additional_authenticated_data": { + Type: schema.TypeString, + Optional: true, + }, }, } } @@ -46,6 +50,10 @@ func dataSourceGoogleKmsSecretRead(d *schema.ResourceData, meta interface{}) err Ciphertext: ciphertext, } + if aad, ok := d.GetOk("additional_authenticated_data"); ok { + kmsDecryptRequest.AdditionalAuthenticatedData = aad.(string) + } + decryptResponse, err := config.clientKms.Projects.Locations.KeyRings.CryptoKeys.Decrypt(cryptoKeyId.cryptoKeyId(), kmsDecryptRequest).Do() if err != nil { diff --git a/third_party/terraform/tests/data_source_google_kms_secret_ciphertext_test.go b/third_party/terraform/tests/data_source_google_kms_secret_ciphertext_test.go index f13409161fa9..d20b40f80bd8 100644 --- a/third_party/terraform/tests/data_source_google_kms_secret_ciphertext_test.go +++ b/third_party/terraform/tests/data_source_google_kms_secret_ciphertext_test.go @@ -23,7 +23,7 @@ func TestAccDataKmsSecretCiphertext_basic(t *testing.T) { { Config: testGoogleKmsSecretCiphertext_datasource(kms.CryptoKey.Name, plaintext), Check: func(s *terraform.State) error { - plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, kms.CryptoKey.Name, "data.google_kms_secret_ciphertext.acceptance") + plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, kms.CryptoKey.Name, "data.google_kms_secret_ciphertext.acceptance", "") if err != nil { return err diff --git a/third_party/terraform/tests/data_source_google_kms_secret_test.go b/third_party/terraform/tests/data_source_google_kms_secret_test.go index 1b3d49a8f2f3..e7766487d81b 100644 --- a/third_party/terraform/tests/data_source_google_kms_secret_test.go +++ b/third_party/terraform/tests/data_source_google_kms_secret_test.go @@ -23,6 +23,7 @@ func TestAccKmsSecret_basic(t *testing.T) { cryptoKeyName := fmt.Sprintf("tf-test-%s", acctest.RandString(10)) plaintext := fmt.Sprintf("secret-%s", acctest.RandString(10)) + aad := "plainaad" // The first test creates resources needed to encrypt plaintext and produce ciphertext resource.Test(t, resource.TestCase{ @@ -32,7 +33,7 @@ func TestAccKmsSecret_basic(t *testing.T) { { Config: testGoogleKmsCryptoKey_basic(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName), Check: func(s *terraform.State) error { - ciphertext, cryptoKeyId, err := testAccEncryptSecretDataWithCryptoKey(s, "google_kms_crypto_key.crypto_key", plaintext) + ciphertext, cryptoKeyId, err := testAccEncryptSecretDataWithCryptoKey(s, "google_kms_crypto_key.crypto_key", plaintext, "") if err != nil { return err @@ -50,6 +51,31 @@ func TestAccKmsSecret_basic(t *testing.T) { }, }) + return nil + }, + }, + // With AAD + { + Config: testGoogleKmsCryptoKey_basic(projectId, projectOrg, projectBillingAccount, keyRingName, cryptoKeyName), + Check: func(s *terraform.State) error { + ciphertext, cryptoKeyId, err := testAccEncryptSecretDataWithCryptoKey(s, "google_kms_crypto_key.crypto_key", plaintext, aad) + + if err != nil { + return err + } + + // The second test asserts that the data source has the correct plaintext, given the created ciphertext + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testGoogleKmsSecret_aadDatasource(cryptoKeyId.terraformId(), ciphertext, base64.StdEncoding.EncodeToString([]byte(aad))), + Check: resource.TestCheckResourceAttr("data.google_kms_secret.acceptance", "plaintext", plaintext), + }, + }, + }) + return nil }, }, @@ -57,7 +83,7 @@ func TestAccKmsSecret_basic(t *testing.T) { }) } -func testAccEncryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyResourceName, plaintext string) (string, *kmsCryptoKeyId, error) { +func testAccEncryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyResourceName, plaintext, aad string) (string, *kmsCryptoKeyId, error) { config := testAccProvider.Meta().(*Config) rs, ok := s.RootModule().Resources[cryptoKeyResourceName] @@ -75,6 +101,10 @@ func testAccEncryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyResource Plaintext: base64.StdEncoding.EncodeToString([]byte(plaintext)), } + if aad != "" { + kmsEncryptRequest.AdditionalAuthenticatedData = base64.StdEncoding.EncodeToString([]byte(aad)) + } + encryptResponse, err := config.clientKms.Projects.Locations.KeyRings.CryptoKeys.Encrypt(cryptoKeyId.cryptoKeyId(), kmsEncryptRequest).Do() if err != nil { @@ -94,3 +124,13 @@ data "google_kms_secret" "acceptance" { } `, cryptoKeyTerraformId, ciphertext) } + +func testGoogleKmsSecret_aadDatasource(cryptoKeyTerraformId, ciphertext, aad string) string { + return fmt.Sprintf(` +data "google_kms_secret" "acceptance" { + crypto_key = "%s" + ciphertext = "%s" + additional_authenticated_data = "%s" +} +`, cryptoKeyTerraformId, ciphertext, aad) +} diff --git a/third_party/terraform/tests/resource_kms_secret_ciphertext_test.go b/third_party/terraform/tests/resource_kms_secret_ciphertext_test.go index 03400ca461f1..33e8e891ed11 100644 --- a/third_party/terraform/tests/resource_kms_secret_ciphertext_test.go +++ b/third_party/terraform/tests/resource_kms_secret_ciphertext_test.go @@ -18,6 +18,7 @@ func TestAccKmsSecretCiphertext_basic(t *testing.T) { kms := BootstrapKMSKey(t) plaintext := fmt.Sprintf("secret-%s", acctest.RandString(10)) + aad := "plainaad" resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, @@ -26,7 +27,20 @@ func TestAccKmsSecretCiphertext_basic(t *testing.T) { { Config: testGoogleKmsSecretCiphertext(kms.CryptoKey.Name, plaintext), Check: func(s *terraform.State) error { - plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, kms.CryptoKey.Name, "google_kms_secret_ciphertext.acceptance") + plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, kms.CryptoKey.Name, "google_kms_secret_ciphertext.acceptance", "") + + if err != nil { + return err + } + + return resource.TestCheckResourceAttr("google_kms_secret_ciphertext.acceptance", "plaintext", plaintext)(s) + }, + }, + // With AAD + { + Config: testGoogleKmsSecretCiphertext_withAAD(kms.CryptoKey.Name, plaintext, aad), + Check: func(s *terraform.State) error { + plaintext, err := testAccDecryptSecretDataWithCryptoKey(s, kms.CryptoKey.Name, "google_kms_secret_ciphertext.acceptance", aad) if err != nil { return err @@ -39,7 +53,7 @@ func TestAccKmsSecretCiphertext_basic(t *testing.T) { }) } -func testAccDecryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyId string, secretCiphertextResourceName string) (string, error) { +func testAccDecryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyId string, secretCiphertextResourceName, aad string) (string, error) { config := testAccProvider.Meta().(*Config) rs, ok := s.RootModule().Resources[secretCiphertextResourceName] if !ok { @@ -54,6 +68,10 @@ func testAccDecryptSecretDataWithCryptoKey(s *terraform.State, cryptoKeyId strin Ciphertext: ciphertext, } + if aad != "" { + kmsDecryptRequest.AdditionalAuthenticatedData = base64.StdEncoding.EncodeToString([]byte(aad)) + } + decryptResponse, err := config.clientKms.Projects.Locations.KeyRings.CryptoKeys.Decrypt(cryptoKeyId, kmsDecryptRequest).Do() if err != nil { @@ -80,3 +98,13 @@ resource "google_kms_secret_ciphertext" "acceptance" { } `, cryptoKeyTerraformId, plaintext) } + +func testGoogleKmsSecretCiphertext_withAAD(cryptoKeyTerraformId, plaintext, aad string) string { + return fmt.Sprintf(` +resource "google_kms_secret_ciphertext" "acceptance" { + crypto_key = "%s" + plaintext = "%s" + additional_authenticated_data = "%s" +} +`, cryptoKeyTerraformId, plaintext, aad) +} diff --git a/third_party/terraform/website/docs/d/google_kms_secret.html.markdown b/third_party/terraform/website/docs/d/google_kms_secret.html.markdown index ce1a7d62862c..28a59ddd9b60 100644 --- a/third_party/terraform/website/docs/d/google_kms_secret.html.markdown +++ b/third_party/terraform/website/docs/d/google_kms_secret.html.markdown @@ -90,6 +90,7 @@ The following arguments are supported: * `crypto_key` (Required) - The id of the CryptoKey that will be used to decrypt the provided ciphertext. This is represented by the format `{projectId}/{location}/{keyRingName}/{cryptoKeyName}`. +* `additional_authenticated_data` (Optional) - The [additional authenticated data](https://cloud.google.com/kms/docs/additional-authenticated-data) used for integrity checks during encryption and decryption. ## Attributes Reference