1// Copyright 2023 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 keyset_test 18 19import ( 20 "bytes" 21 "testing" 22 23 "google.golang.org/protobuf/proto" 24 "github.com/google/tink/go/aead" 25 "github.com/google/tink/go/insecurecleartextkeyset" 26 "github.com/google/tink/go/keyset" 27 "github.com/google/tink/go/mac" 28 "github.com/google/tink/go/signature" 29 "github.com/google/tink/go/testkeyset" 30 "github.com/google/tink/go/tink" 31 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 32) 33 34func TestConvertProtoKeysetIntoHandleInTests(t *testing.T) { 35 h, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) 36 if err != nil { 37 t.Fatal(err) 38 } 39 protoKeyset := testkeyset.KeysetMaterial(h) 40 41 // In tests, this: 42 wantHandle, err := insecurecleartextkeyset.Read(&keyset.MemReaderWriter{Keyset: protoKeyset}) 43 if err != nil { 44 t.Fatal(err) 45 } 46 47 // can be replaced by this: 48 gotHandle, err := testkeyset.NewHandle(protoKeyset) 49 if err != nil { 50 t.Fatal(err) 51 } 52 53 if got, want := testkeyset.KeysetMaterial(gotHandle), testkeyset.KeysetMaterial(wantHandle); !proto.Equal(got, want) { 54 t.Errorf("gotHandle contains %s, want %s", got, want) 55 } 56} 57 58func TestConvertHandleKeysetIntoProtoKeysetInTests(t *testing.T) { 59 handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) 60 if err != nil { 61 t.Fatal(err) 62 } 63 64 // In tests, this: 65 writer := &keyset.MemReaderWriter{} 66 if err := insecurecleartextkeyset.Write(handle, writer); err != nil { 67 t.Fatal(err) 68 } 69 wantKeyset := writer.Keyset 70 71 // can be replaced by this: 72 gotKeyset := testkeyset.KeysetMaterial(handle) 73 74 if !proto.Equal(gotKeyset, wantKeyset) { 75 t.Errorf("testkeyset.KeysetMaterial(handle) = %v, want %v", gotKeyset, wantKeyset) 76 } 77} 78 79func TestConvertProtoKeysetIntoHandle(t *testing.T) { 80 h, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) 81 if err != nil { 82 t.Fatal(err) 83 } 84 protoKeyset := testkeyset.KeysetMaterial(h) 85 86 // This: 87 wantHandle, err := insecurecleartextkeyset.Read(&keyset.MemReaderWriter{Keyset: protoKeyset}) 88 if err != nil { 89 t.Fatal(err) 90 } 91 92 // can be replaced by this: 93 serializedKeyset, err := proto.Marshal(protoKeyset) 94 if err != nil { 95 t.Fatal(err) 96 } 97 gotHandle, err := insecurecleartextkeyset.Read( 98 keyset.NewBinaryReader(bytes.NewBuffer(serializedKeyset))) 99 if err != nil { 100 t.Fatal(err) 101 } 102 103 if got, want := testkeyset.KeysetMaterial(gotHandle), testkeyset.KeysetMaterial(wantHandle); !proto.Equal(got, want) { 104 t.Errorf("gotHandle contains %s, want %s", got, want) 105 } 106} 107 108func TestConvertHandleKeysetIntoProtoKeyset(t *testing.T) { 109 handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) 110 if err != nil { 111 t.Fatal(err) 112 } 113 114 // This: 115 writer := &keyset.MemReaderWriter{} 116 if err := insecurecleartextkeyset.Write(handle, writer); err != nil { 117 t.Fatal(err) 118 } 119 wantKeyset := writer.Keyset 120 121 // can be replaced by this: 122 gotKeyset := insecurecleartextkeyset.KeysetMaterial(handle) 123 124 if !proto.Equal(gotKeyset, wantKeyset) { 125 t.Errorf("insecurecleartextkeyset.KeysetMaterial(handle) = %v, want %v", gotKeyset, wantKeyset) 126 } 127} 128 129func TestConvertHandleKeysetIntoSerializedKeyset(t *testing.T) { 130 handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) 131 if err != nil { 132 t.Fatal(err) 133 } 134 135 // This: 136 writer := &keyset.MemReaderWriter{} 137 if err := insecurecleartextkeyset.Write(handle, writer); err != nil { 138 t.Fatal(err) 139 } 140 wantSerializedKeyset, err := proto.Marshal(writer.Keyset) 141 if err != nil { 142 t.Fatal(err) 143 } 144 145 // can be replaced by this: 146 buff := &bytes.Buffer{} 147 if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil { 148 t.Fatal(err) 149 } 150 gotSerializedKeyset := buff.Bytes() 151 152 // Since serialization may not be deterministic, we parse the keyset and compare the protos. 153 wantKeyset := new(tinkpb.Keyset) 154 err = proto.Unmarshal(wantSerializedKeyset, wantKeyset) 155 if err != nil { 156 t.Fatal(err) 157 } 158 gotKeyset := new(tinkpb.Keyset) 159 err = proto.Unmarshal(gotSerializedKeyset, gotKeyset) 160 if err != nil { 161 t.Fatal(err) 162 } 163 if !proto.Equal(gotKeyset, wantKeyset) { 164 t.Errorf("gotKeyset = %v, want %v", gotKeyset, wantKeyset) 165 } 166} 167 168func TestConvertPublicKeyProtoKeysetIntoHandle(t *testing.T) { 169 privateHandle, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate()) 170 if err != nil { 171 t.Fatal(err) 172 } 173 publicHandle, err := privateHandle.Public() 174 if err != nil { 175 t.Fatal(err) 176 } 177 protoPublicKeyset := testkeyset.KeysetMaterial(publicHandle) 178 179 // This: 180 wantHandle, err := keyset.ReadWithNoSecrets(&keyset.MemReaderWriter{Keyset: protoPublicKeyset}) 181 if err != nil { 182 t.Fatal(err) 183 } 184 185 // can be replaced by this: 186 serializedKeyset, err := proto.Marshal(protoPublicKeyset) 187 if err != nil { 188 t.Fatal(err) 189 } 190 gotHandle, err := keyset.ReadWithNoSecrets( 191 keyset.NewBinaryReader(bytes.NewBuffer(serializedKeyset))) 192 if err != nil { 193 t.Fatal(err) 194 } 195 196 if got, want := testkeyset.KeysetMaterial(gotHandle), testkeyset.KeysetMaterial(wantHandle); !proto.Equal(got, want) { 197 t.Errorf("gotHandle contains %s, want %s", got, want) 198 } 199} 200 201func TestConvertPublicKeysetHandleIntoProtoKeyset(t *testing.T) { 202 privateHandle, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate()) 203 if err != nil { 204 t.Fatal(err) 205 } 206 publicHandle, err := privateHandle.Public() 207 if err != nil { 208 t.Fatal(err) 209 } 210 211 // This: 212 writer := &keyset.MemReaderWriter{} 213 if err := publicHandle.WriteWithNoSecrets(writer); err != nil { 214 t.Fatal(err) 215 } 216 wantKeyset := writer.Keyset 217 218 // can be replaced by this: 219 buff := &bytes.Buffer{} 220 if err := publicHandle.WriteWithNoSecrets(keyset.NewBinaryWriter(buff)); err != nil { 221 t.Fatal(err) 222 } 223 serializedKeyset := buff.Bytes() 224 gotKeyset := new(tinkpb.Keyset) 225 err = proto.Unmarshal(serializedKeyset, gotKeyset) 226 if err != nil { 227 t.Fatal(err) 228 } 229 230 if !proto.Equal(gotKeyset, wantKeyset) { 231 t.Errorf("gotKeyset = %v, want %v", gotKeyset, wantKeyset) 232 } 233} 234 235func decryptKeyset(encrypted *tinkpb.EncryptedKeyset, keysetEncryptionAEAD tink.AEAD) (*tinkpb.Keyset, error) { 236 decrypted, err := keysetEncryptionAEAD.Decrypt(encrypted.GetEncryptedKeyset(), nil) 237 if err != nil { 238 return nil, err 239 } 240 k := new(tinkpb.Keyset) 241 err = proto.Unmarshal(decrypted, k) 242 if err != nil { 243 return nil, err 244 } 245 return k, err 246} 247 248func TestConvertHandleKeysetIntoProtoEncryptedKeyset(t *testing.T) { 249 kekHandle, err := keyset.NewHandle(aead.AES128GCMKeyTemplate()) 250 if err != nil { 251 t.Fatal(err) 252 } 253 keysetEncryptionAEAD, err := aead.New(kekHandle) 254 if err != nil { 255 t.Fatal(err) 256 } 257 handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) 258 if err != nil { 259 t.Fatal(err) 260 } 261 262 // This: 263 memWriter := &keyset.MemReaderWriter{} 264 if err := handle.Write(memWriter, keysetEncryptionAEAD); err != nil { 265 t.Fatal(err) 266 } 267 wantEncryptedKeyset := memWriter.EncryptedKeyset 268 269 // can be replaced by this: 270 buff := &bytes.Buffer{} 271 if err := handle.Write(keyset.NewBinaryWriter(buff), keysetEncryptionAEAD); err != nil { 272 t.Fatal(err) 273 } 274 serializedKeyset := buff.Bytes() 275 gotEncryptedKeyset := new(tinkpb.EncryptedKeyset) 276 err = proto.Unmarshal(serializedKeyset, gotEncryptedKeyset) 277 if err != nil { 278 t.Fatal(err) 279 } 280 281 wantKeyset, err := decryptKeyset(wantEncryptedKeyset, keysetEncryptionAEAD) 282 if err != nil { 283 t.Fatal(err) 284 } 285 gotKeyset, err := decryptKeyset(gotEncryptedKeyset, keysetEncryptionAEAD) 286 if err != nil { 287 t.Fatal(err) 288 } 289 if !proto.Equal(gotKeyset, wantKeyset) { 290 t.Errorf("gotKeyset = %v, want %v", gotKeyset, wantKeyset) 291 } 292} 293 294func TestConvertProtoEncryptedKeysetIntoHandle(t *testing.T) { 295 kekHandle, err := keyset.NewHandle(aead.AES128GCMKeyTemplate()) 296 if err != nil { 297 t.Fatal(err) 298 } 299 keysetEncryptionAEAD, err := aead.New(kekHandle) 300 if err != nil { 301 t.Fatal(err) 302 } 303 handle, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) 304 if err != nil { 305 t.Fatal(err) 306 } 307 buff := &bytes.Buffer{} 308 if err := handle.Write(keyset.NewBinaryWriter(buff), keysetEncryptionAEAD); err != nil { 309 t.Fatal(err) 310 } 311 encryptedKeyset := new(tinkpb.EncryptedKeyset) 312 err = proto.Unmarshal(buff.Bytes(), encryptedKeyset) 313 if err != nil { 314 t.Fatal(err) 315 } 316 317 // This: 318 memReader := &keyset.MemReaderWriter{ 319 EncryptedKeyset: encryptedKeyset, 320 } 321 wantHandle, err := keyset.Read(memReader, keysetEncryptionAEAD) 322 if err != nil { 323 t.Fatal(err) 324 } 325 326 // can be replaced by this: 327 serializedKeyset, err := proto.Marshal(encryptedKeyset) 328 if err != nil { 329 t.Fatal(err) 330 } 331 gotHandle, err := keyset.Read( 332 keyset.NewBinaryReader(bytes.NewBuffer(serializedKeyset)), 333 keysetEncryptionAEAD) 334 if err != nil { 335 t.Fatal(err) 336 } 337 338 if got, want := testkeyset.KeysetMaterial(gotHandle), testkeyset.KeysetMaterial(wantHandle); !proto.Equal(got, want) { 339 t.Errorf("gotHandle contains %s, want %s", got, want) 340 } 341} 342