1// Copyright 2019 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15//////////////////////////////////////////////////////////////////////////////// 16 17package awskms_test 18 19import ( 20 "bytes" 21 "os" 22 "path/filepath" 23 "testing" 24 25 "flag" 26 // context is used to cancel outstanding requests 27 "github.com/google/tink/go/aead" 28 "github.com/google/tink/go/tink" 29 30 "github.com/google/tink/go/integration/awskms" 31) 32 33const ( 34 keyPrefix = "aws-kms://arn:aws:kms:us-east-2:235739564943:" 35 keyAliasURI = "aws-kms://arn:aws:kms:us-east-2:235739564943:alias/unit-and-integration-testing" 36 keyURI = "aws-kms://arn:aws:kms:us-east-2:235739564943:key/3ee50705-5a82-4f5b-9753-05c4f473922f" 37 keyURI2 = "aws-kms://arn:aws:kms:us-east-2:235739564943:key/b3ca2efd-a8fb-47f2-b541-7e20f8c5cd11" 38) 39 40var ( 41 credCSVFile = "tink_go/testdata/aws/credentials.csv" 42 credINIFile = "tink_go/testdata/aws/credentials.ini" 43) 44 45func init() { 46 certPath := filepath.Join(os.Getenv("TEST_SRCDIR"), "tink_base/roots.pem") 47 flag.Set("cacerts", certPath) 48 os.Setenv("SSL_CERT_FILE", certPath) 49} 50 51func TestNewClientWithCredentialsGetAEADEncryptDecrypt(t *testing.T) { 52 srcDir, ok := os.LookupEnv("TEST_SRCDIR") 53 if !ok { 54 t.Skip("TEST_SRCDIR not set") 55 } 56 client, err := awskms.NewClientWithOptions(keyURI, awskms.WithCredentialPath(filepath.Join(srcDir, credCSVFile))) 57 if err != nil { 58 t.Fatalf("error setting up AWS client: %v", err) 59 } 60 a, err := client.GetAEAD(keyURI) 61 if err != nil { 62 t.Fatalf("client.GetAEAD(keyURI) err = %v, want nil", err) 63 } 64 plaintext := []byte("plaintext") 65 associatedData := []byte("associatedData") 66 ciphertext, err := a.Encrypt(plaintext, associatedData) 67 if err != nil { 68 t.Fatalf("a.Encrypt(plaintext, associatedData) err = %v, want nil", err) 69 } 70 gotPlaintext, err := a.Decrypt(ciphertext, associatedData) 71 if err != nil { 72 t.Fatalf("a.Decrypt(ciphertext, associatedData) err = %v, want nil", err) 73 } 74 if !bytes.Equal(gotPlaintext, plaintext) { 75 t.Errorf("a.Decrypt() = %q, want %q", gotPlaintext, plaintext) 76 } 77 78 invalidAssociatedData := []byte("invalidAssociatedData") 79 _, err = a.Decrypt(ciphertext, invalidAssociatedData) 80 if err == nil { 81 t.Error("a.Decrypt(ciphertext, invalidAssociatedData) err = nil, want error") 82 } 83} 84 85func TestEmptyAssociatedDataEncryptDecrypt(t *testing.T) { 86 srcDir, ok := os.LookupEnv("TEST_SRCDIR") 87 if !ok { 88 t.Skip("TEST_SRCDIR not set") 89 } 90 client, err := awskms.NewClientWithOptions(keyURI, awskms.WithCredentialPath(filepath.Join(srcDir, credCSVFile))) 91 if err != nil { 92 t.Fatalf("error setting up AWS client: %v", err) 93 } 94 a, err := client.GetAEAD(keyURI) 95 if err != nil { 96 t.Fatalf("client.GetAEAD(keyURI) err = %v, want nil", err) 97 } 98 plaintext := []byte("plaintext") 99 emptyAssociatedData := []byte{} 100 ciphertext, err := a.Encrypt(plaintext, emptyAssociatedData) 101 if err != nil { 102 t.Fatalf("a.Encrypt(plaintext, emptyAssociatedData) err = %v, want nil", err) 103 } 104 gotPlaintext, err := a.Decrypt(ciphertext, emptyAssociatedData) 105 if err != nil { 106 t.Fatalf("a.Decrypt(ciphertext, associatedData) err = %v, want nil", err) 107 } 108 if !bytes.Equal(gotPlaintext, plaintext) { 109 t.Errorf("a.Decrypt() = %q, want %q", gotPlaintext, plaintext) 110 } 111 112 gotPlaintext2, err := a.Decrypt(ciphertext, nil) 113 if err != nil { 114 t.Fatalf("a.Decrypt(ciphertext, nil) err = %v, want nil", err) 115 } 116 if !bytes.Equal(gotPlaintext2, plaintext) { 117 t.Errorf("a.Decrypt() = %q, want %q", gotPlaintext, plaintext) 118 } 119} 120 121func TestKeyCommitment(t *testing.T) { 122 srcDir, ok := os.LookupEnv("TEST_SRCDIR") 123 if !ok { 124 t.Skip("TEST_SRCDIR not set") 125 } 126 127 client, err := awskms.NewClientWithOptions(keyPrefix, awskms.WithCredentialPath(filepath.Join(srcDir, credCSVFile))) 128 if err != nil { 129 t.Fatalf("error setting up AWS client: %v", err) 130 } 131 132 // Create AEAD primitives for two keys. 133 keys := []string{keyURI, keyURI2} 134 aeads := make([]tink.AEAD, 0, len(keys)) 135 for _, k := range keys { 136 a, err := client.GetAEAD(k) 137 if err != nil { 138 t.Fatalf("client.GetAEAD(keyURI) err = %v, want nil", err) 139 } 140 aeads = append(aeads, a) 141 } 142 143 // Create a ciphertext using the first primitive. 144 plaintext := []byte("plaintext") 145 associatedData := []byte("associated data") 146 ciphertext, err := aeads[0].Encrypt(plaintext, associatedData) 147 if err != nil { 148 t.Fatalf("aeads[0].Encrypt(plaintext, associatedData) err = %v, want nil", err) 149 } 150 gotPlaintext, err := aeads[0].Decrypt(ciphertext, associatedData) 151 if err != nil { 152 t.Fatalf("aeads[0].Decrypt(ciphertext, associatedData) err = %v, want nil", err) 153 } 154 if !bytes.Equal(gotPlaintext, plaintext) { 155 t.Errorf("aeads[0].Decrypt() = %q, want %q", gotPlaintext, plaintext) 156 } 157 158 // Attempt to decrypt using the other primitive. 159 _, err = aeads[1].Decrypt(ciphertext, associatedData) 160 if err == nil { 161 t.Fatalf("aeads[1].Decrypt(ciphertext, associatedData) err = nil, want non-nil") 162 } 163} 164 165func TestKMSEnvelopeAEADEncryptAndDecrypt(t *testing.T) { 166 srcDir, ok := os.LookupEnv("TEST_SRCDIR") 167 if !ok { 168 t.Skip("TEST_SRCDIR not set") 169 } 170 171 for _, credFile := range []string{credCSVFile, credINIFile} { 172 credPath := filepath.Join(srcDir, credFile) 173 174 client, err := awskms.NewClientWithOptions(keyURI, awskms.WithCredentialPath(credPath)) 175 if err != nil { 176 t.Fatalf("awskms.NewClientWithOptions() err = %q, want nil", err) 177 } 178 179 kekAEAD, err := client.GetAEAD(keyURI) 180 if err != nil { 181 t.Fatalf("client.GetAEAD(keyURI) err = %q, want nil", err) 182 } 183 184 dekTemplate := aead.AES128CTRHMACSHA256KeyTemplate() 185 a := aead.NewKMSEnvelopeAEAD2(dekTemplate, kekAEAD) 186 if err != nil { 187 t.Fatalf("aead.NewKMSEnvelopeAEAD2(dekTemplate, kekAEAD) err = %q, want nil", err) 188 } 189 plaintext := []byte("plaintext") 190 for _, associatedData := range [][]byte{nil, []byte("associated data")} { 191 ciphertext, err := a.Encrypt(plaintext, associatedData) 192 if err != nil { 193 t.Fatalf("a.Encrypt(plaintext, associatedData) err = %q, want nil", err) 194 } 195 gotPlaintext, err := a.Decrypt(ciphertext, associatedData) 196 if err != nil { 197 t.Fatalf("a.Decrypt(ciphertext, associatedData) err = %q, want nil", err) 198 } 199 if !bytes.Equal(gotPlaintext, plaintext) { 200 t.Errorf("a.Decrypt() = %q, want %q", gotPlaintext, plaintext) 201 } 202 } 203 } 204} 205