diff --git a/builtin/providers/aws/resource_aws_iam_access_key.go b/builtin/providers/aws/resource_aws_iam_access_key.go index f5a094c5a4e3..ef74fe88b740 100644 --- a/builtin/providers/aws/resource_aws_iam_access_key.go +++ b/builtin/providers/aws/resource_aws_iam_access_key.go @@ -1,6 +1,9 @@ package aws import ( + "crypto/hmac" + "crypto/sha256" + "encoding/base64" "fmt" "github.com/aws/aws-sdk-go/aws" @@ -32,6 +35,10 @@ func resourceAwsIamAccessKey() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "ses_smtp_password": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, }, } } @@ -55,6 +62,10 @@ func resourceAwsIamAccessKeyCreate(d *schema.ResourceData, meta interface{}) err if err := d.Set("secret", createResp.AccessKey.SecretAccessKey); err != nil { return err } + + d.Set("ses_smtp_password", + sesSmtpPasswordFromSecretKey(createResp.AccessKey.SecretAccessKey)) + return resourceAwsIamAccessKeyReadResult(d, &iam.AccessKeyMetadata{ AccessKeyId: createResp.AccessKey.AccessKeyId, CreateDate: createResp.AccessKey.CreateDate, @@ -115,3 +126,19 @@ func resourceAwsIamAccessKeyDelete(d *schema.ResourceData, meta interface{}) err } return nil } + +func sesSmtpPasswordFromSecretKey(key *string) string { + if key == nil { + return "" + } + version := byte(0x02) + message := []byte("SendRawEmail") + hmacKey := []byte(*key) + h := hmac.New(sha256.New, hmacKey) + h.Write(message) + rawSig := h.Sum(nil) + versionedSig := make([]byte, 0, len(rawSig)+1) + versionedSig = append(versionedSig, version) + versionedSig = append(versionedSig, rawSig...) + return base64.StdEncoding.EncodeToString(versionedSig) +} diff --git a/builtin/providers/aws/resource_aws_iam_access_key_test.go b/builtin/providers/aws/resource_aws_iam_access_key_test.go index 1d62b93b9ffd..3a1df33ae3ea 100644 --- a/builtin/providers/aws/resource_aws_iam_access_key_test.go +++ b/builtin/providers/aws/resource_aws_iam_access_key_test.go @@ -116,3 +116,20 @@ resource "aws_iam_access_key" "a_key" { user = "${aws_iam_user.a_user.name}" } ` + +func TestSesSmtpPasswordFromSecretKey(t *testing.T) { + cases := []struct { + Input string + Expected string + }{ + {"some+secret+key", "AnkqhOiWEcszZZzTMCQbOY1sPGoLFgMH9zhp4eNgSjo4"}, + {"another+secret+key", "Akwqr0Giwi8FsQFgW3DXWCC2DiiQ/jZjqLDWK8TeTBgL"}, + } + + for _, tc := range cases { + actual := sesSmtpPasswordFromSecretKey(&tc.Input) + if actual != tc.Expected { + t.Fatalf("%q: expected %q, got %q", tc.Input, tc.Expected, actual) + } + } +} diff --git a/website/source/docs/providers/aws/r/iam_access_key.html.markdown b/website/source/docs/providers/aws/r/iam_access_key.html.markdown index c3baeb998cde..529563ed5dcc 100644 --- a/website/source/docs/providers/aws/r/iam_access_key.html.markdown +++ b/website/source/docs/providers/aws/r/iam_access_key.html.markdown @@ -55,5 +55,8 @@ The following attributes are exported: * `id` - The access key ID. * `user` - The IAM user associated with this access key. * `secret` - The secret access key. Note that this will be written to the state file. +* `ses_smtp_password` - The secret access key converted into an SES SMTP + password by applying [AWS's documented conversion + algorithm](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/smtp-credentials.html#smtp-credentials-convert). * `status` - "Active" or "Inactive". Keys are initially active, but can be made inactive by other means.