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 hybrid_test 18 19import ( 20 "bytes" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 "github.com/google/go-cmp/cmp/cmpopts" 25 "google.golang.org/protobuf/proto" 26 "github.com/google/tink/go/aead" 27 "github.com/google/tink/go/core/cryptofmt" 28 "github.com/google/tink/go/hybrid" 29 "github.com/google/tink/go/insecurecleartextkeyset" 30 "github.com/google/tink/go/internal/internalregistry" 31 "github.com/google/tink/go/keyset" 32 "github.com/google/tink/go/monitoring" 33 "github.com/google/tink/go/signature" 34 "github.com/google/tink/go/subtle/random" 35 "github.com/google/tink/go/testing/fakemonitoring" 36 "github.com/google/tink/go/testkeyset" 37 "github.com/google/tink/go/testutil" 38 commonpb "github.com/google/tink/go/proto/common_go_proto" 39 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 40) 41 42const eciesAEADHKDFPrivateKeyTypeURL = "type.googleapis.com/google.crypto.tink.EciesAeadHkdfPrivateKey" 43 44func TestHybridFactoryTest(t *testing.T) { 45 c := commonpb.EllipticCurveType_NIST_P256 46 ht := commonpb.HashType_SHA256 47 primaryPtFmt := commonpb.EcPointFormat_UNCOMPRESSED 48 rawPtFmt := commonpb.EcPointFormat_COMPRESSED 49 primaryDek := aead.AES128CTRHMACSHA256KeyTemplate() 50 rawDek := aead.AES128CTRHMACSHA256KeyTemplate() 51 primarySalt := []byte("some salt") 52 rawSalt := []byte("other salt") 53 54 primaryPrivProto, err := testutil.GenerateECIESAEADHKDFPrivateKey(c, ht, primaryPtFmt, primaryDek, primarySalt) 55 if err != nil { 56 t.Fatalf("testutil.GenerateECIESAEADHKDFPrivateKey(c, ht, primaryPtFmt, primaryDek, primarySalt) err = %v, want nil", err) 57 } 58 sPrimaryPriv, err := proto.Marshal(primaryPrivProto) 59 if err != nil { 60 t.Fatalf("proto.Marshal(primaryPrivProto) err = %v, want nil", err) 61 } 62 63 primaryPrivKey := testutil.NewKey( 64 testutil.NewKeyData(eciesAEADHKDFPrivateKeyTypeURL, sPrimaryPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE), 65 tinkpb.KeyStatusType_ENABLED, 8, tinkpb.OutputPrefixType_RAW) 66 67 rawPrivProto, err := testutil.GenerateECIESAEADHKDFPrivateKey(c, ht, rawPtFmt, rawDek, rawSalt) 68 if err != nil { 69 t.Fatalf("testutil.GenerateECIESAEADHKDFPrivateKey(c, ht, rawPtFmt, rawDek, rawSalt) err = %v, want nil", err) 70 } 71 sRawPriv, err := proto.Marshal(rawPrivProto) 72 if err != nil { 73 t.Fatalf("proto.Marshal(rawPrivProto) err = %v, want nil", err) 74 } 75 rawPrivKey := testutil.NewKey( 76 testutil.NewKeyData(eciesAEADHKDFPrivateKeyTypeURL, sRawPriv, tinkpb.KeyData_ASYMMETRIC_PRIVATE), 77 tinkpb.KeyStatusType_ENABLED, 11, tinkpb.OutputPrefixType_RAW) 78 79 privKeys := []*tinkpb.Keyset_Key{primaryPrivKey, rawPrivKey} 80 privKeyset := testutil.NewKeyset(privKeys[0].KeyId, privKeys) 81 khPriv, err := testkeyset.NewHandle(privKeyset) 82 if err != nil { 83 t.Fatalf("testkeyset.NewHandle(privKeyset) err = %v, want nil", err) 84 } 85 86 khPub, err := khPriv.Public() 87 if err != nil { 88 t.Fatalf("khPriv.Public() err = %v, want nil", err) 89 } 90 91 e, err := hybrid.NewHybridEncrypt(khPub) 92 if err != nil { 93 t.Fatalf("hybrid.NewHybridEncrypt(khPub) err = %v, want nil", err) 94 } 95 d, err := hybrid.NewHybridDecrypt(khPriv) 96 if err != nil { 97 t.Fatalf("hybrid.NewHybridDecrypt(khPriv) err = %v, want nil", err) 98 } 99 100 for i := 0; i < 1000; i++ { 101 pt := random.GetRandomBytes(20) 102 ci := random.GetRandomBytes(20) 103 ct, err := e.Encrypt(pt, ci) 104 if err != nil { 105 t.Fatalf("e.Encrypt(pt, ci) err = %v, want nil", err) 106 } 107 gotpt, err := d.Decrypt(ct, ci) 108 if err != nil { 109 t.Fatalf("d.Decrypt(ct, ci) err = %v, want nil", err) 110 } 111 if !bytes.Equal(pt, gotpt) { 112 t.Errorf("got plaintext %q, want %q", gotpt, pt) 113 } 114 } 115} 116 117func TestFactoryWithInvalidPrimitiveSetType(t *testing.T) { 118 wrongKH, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate()) 119 if err != nil { 120 t.Fatalf("keyset.NewHandle(signature.ECDSAP256KeyTemplate()) err = %v, want nil", err) 121 } 122 123 _, err = hybrid.NewHybridEncrypt(wrongKH) 124 if err == nil { 125 t.Error("hybrid.NewHybridEncrypt(wrongKH) err = nil, want not nil") 126 } 127 128 _, err = hybrid.NewHybridDecrypt(wrongKH) 129 if err == nil { 130 t.Error("hybrid.NewHybridDecrypt(wrongKH) err = nil, want not nil") 131 } 132} 133 134func TestFactoryWithValidPrimitiveSetType(t *testing.T) { 135 goodKH, err := keyset.NewHandle(hybrid.ECIESHKDFAES128GCMKeyTemplate()) 136 if err != nil { 137 t.Fatalf("keyset.NewHandle(hybrid.ECIESHKDFAES128GCMKeyTemplate()) err = %v, want nil", err) 138 } 139 140 goodPublicKH, err := goodKH.Public() 141 if err != nil { 142 t.Fatalf("goodKH.Public() err = %v, want nil", err) 143 } 144 _, err = hybrid.NewHybridEncrypt(goodPublicKH) 145 if err != nil { 146 t.Errorf("hybrid.NewHybridEncrypt(goodPublicKH) err = %v, want nil", err) 147 } 148 149 _, err = hybrid.NewHybridDecrypt(goodKH) 150 if err != nil { 151 t.Errorf("hybrid.NewHybridDecrypt(goodKH) err = %v, want nil", err) 152 } 153} 154 155func TestPrimitiveFactoryFailsWhenKeysetHasNoPrimary(t *testing.T) { 156 curve := commonpb.EllipticCurveType_NIST_P256 157 hash := commonpb.HashType_SHA256 158 format := commonpb.EcPointFormat_UNCOMPRESSED 159 dek := aead.AES128CTRHMACSHA256KeyTemplate() 160 salt := []byte("some salt") 161 privProto, err := testutil.GenerateECIESAEADHKDFPrivateKey(curve, hash, format, dek, salt) 162 if err != nil { 163 t.Fatalf("testutil.GenerateECIESAEADHKDFPrivateKey(curve, hash, format, dek, salt) failed: %s", err) 164 } 165 serialized, err := proto.Marshal(privProto) 166 if err != nil { 167 t.Fatalf("proto.Marshal(privateProto) err = %v, want nil", err) 168 } 169 privKey := testutil.NewKey( 170 testutil.NewKeyData(eciesAEADHKDFPrivateKeyTypeURL, serialized, tinkpb.KeyData_ASYMMETRIC_PRIVATE), 171 tinkpb.KeyStatusType_ENABLED, 8, tinkpb.OutputPrefixType_RAW) 172 privKeysetWithoutPrimary := &tinkpb.Keyset{ 173 Key: []*tinkpb.Keyset_Key{privKey}, 174 } 175 privHandleWithoutPrimary, err := testkeyset.NewHandle(privKeysetWithoutPrimary) 176 if err != nil { 177 t.Fatalf("testkeyset.NewHandle(privKeysetWithoutPrimary) err = %v, want nil", err) 178 } 179 pubHandleWithoutPrimary, err := privHandleWithoutPrimary.Public() 180 if err != nil { 181 t.Fatalf("privateHandleWithoutPrimary.Public() err = %v, want nil", err) 182 } 183 184 if _, err = hybrid.NewHybridEncrypt(pubHandleWithoutPrimary); err == nil { 185 t.Errorf("NewHybridEncrypt(pubHandleWithoutPrimary) err = nil, want not nil") 186 } 187 188 if _, err = hybrid.NewHybridDecrypt(privHandleWithoutPrimary); err == nil { 189 t.Errorf("NewHybridDecrypt(privHandleWithoutPrimary) err = nil, want not nil") 190 } 191} 192 193func TestPrimitiveFactoryMonitoringWithAnnotationsLogsEncryptAndDecryptWithPrefix(t *testing.T) { 194 defer internalregistry.ClearMonitoringClient() 195 client := fakemonitoring.NewClient("fake-client") 196 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 197 t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err) 198 } 199 handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template()) 200 if err != nil { 201 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 202 } 203 buff := &bytes.Buffer{} 204 if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil { 205 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 206 } 207 annotations := map[string]string{"foo": "bar"} 208 privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 209 if err != nil { 210 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 211 } 212 pubHandle, err := privHandle.Public() 213 if err != nil { 214 t.Fatalf("privHandle.Public() err = %v, want nil", err) 215 } 216 buff.Reset() 217 if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil { 218 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 219 } 220 pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 221 if err != nil { 222 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 223 } 224 e, err := hybrid.NewHybridEncrypt(pubHandle) 225 if err != nil { 226 t.Fatalf("hybrid.NewHybridEncrypt() err = %v, want nil", err) 227 } 228 d, err := hybrid.NewHybridDecrypt(privHandle) 229 if err != nil { 230 t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err) 231 } 232 data := []byte("some_secret_piece_of_data") 233 aad := []byte("some_non_secret_piece_of_data") 234 ct, err := e.Encrypt(data, aad) 235 if err != nil { 236 t.Fatalf("e.Encrypt() err = %v, want nil", err) 237 } 238 if _, err := d.Decrypt(ct, aad); err != nil { 239 t.Fatalf("d.Decrypt() err = %v, want nil", err) 240 } 241 got := client.Events() 242 wantEncryptKeysetInfo := &monitoring.KeysetInfo{ 243 Annotations: annotations, 244 PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 245 Entries: []*monitoring.Entry{ 246 { 247 KeyID: pubHandle.KeysetInfo().GetPrimaryKeyId(), 248 Status: monitoring.Enabled, 249 KeyType: "tink.HpkePublicKey", 250 KeyPrefix: "TINK", 251 }, 252 }, 253 } 254 wantDecryptKeysetInfo := &monitoring.KeysetInfo{ 255 Annotations: annotations, 256 PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 257 Entries: []*monitoring.Entry{ 258 { 259 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 260 Status: monitoring.Enabled, 261 KeyType: "tink.HpkePrivateKey", 262 KeyPrefix: "TINK", 263 }, 264 }, 265 } 266 want := []*fakemonitoring.LogEvent{ 267 { 268 Context: monitoring.NewContext("hybrid_encrypt", "encrypt", wantEncryptKeysetInfo), 269 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 270 NumBytes: len(data), 271 }, 272 { 273 Context: monitoring.NewContext("hybrid_decrypt", "decrypt", wantDecryptKeysetInfo), 274 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 275 // ciphertext was encrypted with a key that has a TINK output prefix. This adds a 276 // 5-byte prefix to the ciphertext. This prefix is not included in the `Log` call. 277 NumBytes: len(ct) - cryptofmt.NonRawPrefixSize, 278 }, 279 } 280 if diff := cmp.Diff(want, got); diff != "" { 281 t.Errorf("%v", diff) 282 } 283} 284 285func TestPrimitiveFactoryMonitoringWithAnnotationsLogsEncryptAndDecryptWithoutPrefix(t *testing.T) { 286 defer internalregistry.ClearMonitoringClient() 287 client := fakemonitoring.NewClient("fake-client") 288 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 289 t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err) 290 } 291 handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Raw_Key_Template()) 292 if err != nil { 293 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 294 } 295 buff := &bytes.Buffer{} 296 if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil { 297 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 298 } 299 annotations := map[string]string{"foo": "bar"} 300 privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 301 if err != nil { 302 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 303 } 304 pubHandle, err := privHandle.Public() 305 if err != nil { 306 t.Fatalf("privHandle.Public() err = %v, want nil", err) 307 } 308 buff.Reset() 309 if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil { 310 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 311 } 312 pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 313 if err != nil { 314 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 315 } 316 e, err := hybrid.NewHybridEncrypt(pubHandle) 317 if err != nil { 318 t.Fatalf("hybrid.NewHybridEncrypt() err = %v, want nil", err) 319 } 320 d, err := hybrid.NewHybridDecrypt(privHandle) 321 if err != nil { 322 t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err) 323 } 324 data := []byte("some_secret_piece_of_data") 325 aad := []byte("some_non_secret_piece_of_data") 326 ct, err := e.Encrypt(data, aad) 327 if err != nil { 328 t.Fatalf("e.Encrypt() err = %v, want nil", err) 329 } 330 if _, err := d.Decrypt(ct, aad); err != nil { 331 t.Fatalf("d.Decrypt() err = %v, want nil", err) 332 } 333 got := client.Events() 334 wantEncryptKeysetInfo := &monitoring.KeysetInfo{ 335 Annotations: annotations, 336 PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 337 Entries: []*monitoring.Entry{ 338 { 339 KeyID: pubHandle.KeysetInfo().GetPrimaryKeyId(), 340 Status: monitoring.Enabled, 341 KeyType: "tink.HpkePublicKey", 342 KeyPrefix: "RAW", 343 }, 344 }, 345 } 346 wantDecryptKeysetInfo := &monitoring.KeysetInfo{ 347 Annotations: annotations, 348 PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 349 Entries: []*monitoring.Entry{ 350 { 351 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 352 Status: monitoring.Enabled, 353 KeyType: "tink.HpkePrivateKey", 354 KeyPrefix: "RAW", 355 }, 356 }, 357 } 358 want := []*fakemonitoring.LogEvent{ 359 { 360 Context: monitoring.NewContext("hybrid_encrypt", "encrypt", wantEncryptKeysetInfo), 361 KeyID: pubHandle.KeysetInfo().GetPrimaryKeyId(), 362 NumBytes: len(data), 363 }, 364 { 365 Context: monitoring.NewContext("hybrid_decrypt", "decrypt", wantDecryptKeysetInfo), 366 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 367 NumBytes: len(ct), 368 }, 369 } 370 if diff := cmp.Diff(want, got); diff != "" { 371 t.Errorf("%v", diff) 372 } 373} 374 375func TestPrimitiveFactoryWithMonitoringWithMultipleKeysLogsEncryptionDecryption(t *testing.T) { 376 defer internalregistry.ClearMonitoringClient() 377 client := fakemonitoring.NewClient("fake-client") 378 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 379 t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err) 380 } 381 manager := keyset.NewManager() 382 templates := []*tinkpb.KeyTemplate{ 383 hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template(), 384 hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_256_GCM_Raw_Key_Template(), 385 hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_CHACHA20_POLY1305_Key_Template(), 386 hybrid.ECIESHKDFAES128GCMKeyTemplate(), 387 } 388 keyIDs := make([]uint32, 4, 4) 389 var err error 390 for i, tm := range templates { 391 keyIDs[i], err = manager.Add(tm) 392 if err != nil { 393 t.Fatalf("manager.Add() err = %v, want nil", err) 394 } 395 } 396 if err := manager.SetPrimary(keyIDs[1]); err != nil { 397 t.Fatalf("manager.SetPrimary(%d) err = %v, want nil", keyIDs[1], err) 398 } 399 if err := manager.Disable(keyIDs[0]); err != nil { 400 t.Fatalf("manager.Disable(%d) err = %v, want nil", keyIDs[0], err) 401 } 402 handle, err := manager.Handle() 403 if err != nil { 404 t.Fatalf("manager.Handle() err = %v, want nil", err) 405 } 406 buff := &bytes.Buffer{} 407 if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil { 408 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 409 } 410 annotations := map[string]string{"foo": "bar"} 411 privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 412 if err != nil { 413 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 414 } 415 pubHandle, err := privHandle.Public() 416 if err != nil { 417 t.Fatalf("privHandle.Public() err = %v, want nil", err) 418 } 419 buff.Reset() 420 if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil { 421 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 422 } 423 pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 424 if err != nil { 425 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 426 } 427 e, err := hybrid.NewHybridEncrypt(pubHandle) 428 if err != nil { 429 t.Fatalf("hybrid.NewHybridEncrypt() err = %v, want nil", err) 430 } 431 d, err := hybrid.NewHybridDecrypt(privHandle) 432 if err != nil { 433 t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err) 434 } 435 data := []byte("some_secret_piece_of_data") 436 aad := []byte("some_non_secret_piece_of_data") 437 ct, err := e.Encrypt(data, aad) 438 if err != nil { 439 t.Fatalf("e.Encrypt() err = %v, want nil", err) 440 } 441 if _, err := d.Decrypt(ct, aad); err != nil { 442 t.Fatalf("d.Decrypt() err = %v, want nil", err) 443 } 444 failures := len(client.Failures()) 445 if failures != 0 { 446 t.Errorf("len(client.Failures()) = %d, want 0", failures) 447 } 448 got := client.Events() 449 wantEncryptKeysetInfo := &monitoring.KeysetInfo{ 450 Annotations: annotations, 451 PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 452 Entries: []*monitoring.Entry{ 453 { 454 KeyID: pubHandle.KeysetInfo().GetPrimaryKeyId(), 455 Status: monitoring.Enabled, 456 KeyType: "tink.HpkePublicKey", 457 KeyPrefix: "RAW", 458 }, 459 { 460 KeyID: keyIDs[2], 461 Status: monitoring.Enabled, 462 KeyType: "tink.HpkePublicKey", 463 KeyPrefix: "TINK", 464 }, 465 { 466 KeyID: keyIDs[3], 467 Status: monitoring.Enabled, 468 KeyType: "tink.EciesAeadHkdfPublicKey", 469 KeyPrefix: "TINK", 470 }, 471 }, 472 } 473 wantDecryptKeysetInfo := &monitoring.KeysetInfo{ 474 Annotations: annotations, 475 PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 476 Entries: []*monitoring.Entry{ 477 { 478 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 479 Status: monitoring.Enabled, 480 KeyType: "tink.HpkePrivateKey", 481 KeyPrefix: "RAW", 482 }, 483 { 484 KeyID: keyIDs[2], 485 Status: monitoring.Enabled, 486 KeyType: "tink.HpkePrivateKey", 487 KeyPrefix: "TINK", 488 }, 489 { 490 KeyID: keyIDs[3], 491 Status: monitoring.Enabled, 492 KeyType: "tink.EciesAeadHkdfPrivateKey", 493 KeyPrefix: "TINK", 494 }, 495 }, 496 } 497 want := []*fakemonitoring.LogEvent{ 498 { 499 Context: monitoring.NewContext("hybrid_encrypt", "encrypt", wantEncryptKeysetInfo), 500 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 501 NumBytes: len(data), 502 }, 503 { 504 Context: monitoring.NewContext("hybrid_decrypt", "decrypt", wantDecryptKeysetInfo), 505 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 506 NumBytes: len(ct), 507 }, 508 } 509 // sort by keyID to avoid non deterministic order. 510 entryLessFunc := func(a, b *monitoring.Entry) bool { 511 return a.KeyID < b.KeyID 512 } 513 if diff := cmp.Diff(want, got, cmpopts.SortSlices(entryLessFunc)); diff != "" { 514 t.Errorf("%v", diff) 515 } 516} 517 518func TestPrimitiveFactoryMonitoringWithAnnotationsEncryptFailureIsLogged(t *testing.T) { 519 defer internalregistry.ClearMonitoringClient() 520 client := fakemonitoring.NewClient("fake-client") 521 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 522 t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err) 523 } 524 525 handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template()) 526 if err != nil { 527 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 528 } 529 buff := &bytes.Buffer{} 530 if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil { 531 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 532 } 533 annotations := map[string]string{"foo": "bar"} 534 privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 535 if err != nil { 536 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 537 } 538 buff.Reset() 539 540 pubHandle, err := privHandle.Public() 541 if err != nil { 542 t.Fatalf("privHandle.Public() err = %v, want nil", err) 543 } 544 if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil { 545 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 546 } 547 pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 548 if err != nil { 549 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 550 } 551 552 e, err := hybrid.NewHybridEncrypt(pubHandle) 553 if err != nil { 554 t.Fatalf("NewHybridEncrypt() err = %v, want nil", err) 555 } 556 d, err := hybrid.NewHybridDecrypt(privHandle) 557 if err != nil { 558 t.Fatalf("NewHybridDecrypt() err = %v, want nil", err) 559 } 560 561 ct, err := e.Encrypt([]byte("plaintext"), []byte("info")) 562 if err != nil { 563 t.Fatalf("Encrypt() err = nil, want non-nil") 564 } 565 if _, err := d.Decrypt(ct, []byte("wrong info")); err == nil { 566 t.Fatalf("Decrypt() err = nil, want non-nil") 567 } 568 569 got := client.Failures() 570 primaryKeyID := privHandle.KeysetInfo().GetPrimaryKeyId() 571 want := []*fakemonitoring.LogFailure{ 572 { 573 Context: monitoring.NewContext( 574 "hybrid_decrypt", 575 "decrypt", 576 monitoring.NewKeysetInfo( 577 annotations, 578 primaryKeyID, 579 []*monitoring.Entry{ 580 { 581 KeyID: primaryKeyID, 582 Status: monitoring.Enabled, 583 KeyType: "tink.HpkePrivateKey", 584 KeyPrefix: "TINK", 585 }, 586 }, 587 ), 588 ), 589 }, 590 } 591 if diff := cmp.Diff(want, got); diff != "" { 592 t.Errorf("%v", diff) 593 } 594} 595 596func TestPrimitiveFactoryMonitoringWithAnnotationsDecryptFailureIsLogged(t *testing.T) { 597 defer internalregistry.ClearMonitoringClient() 598 client := fakemonitoring.NewClient("fake-client") 599 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 600 t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err) 601 } 602 handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template()) 603 if err != nil { 604 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 605 } 606 buff := &bytes.Buffer{} 607 if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil { 608 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 609 } 610 annotations := map[string]string{"foo": "bar"} 611 privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 612 if err != nil { 613 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 614 } 615 e, err := hybrid.NewHybridDecrypt(privHandle) 616 if err != nil { 617 t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err) 618 } 619 if _, err := e.Decrypt([]byte("invalid_data"), nil); err == nil { 620 t.Fatalf("e.Decrypt() err = nil, want non-nil error") 621 } 622 got := client.Failures() 623 want := []*fakemonitoring.LogFailure{ 624 { 625 Context: monitoring.NewContext( 626 "hybrid_decrypt", 627 "decrypt", 628 monitoring.NewKeysetInfo( 629 annotations, 630 privHandle.KeysetInfo().GetPrimaryKeyId(), 631 []*monitoring.Entry{ 632 { 633 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 634 Status: monitoring.Enabled, 635 KeyType: "tink.HpkePrivateKey", 636 KeyPrefix: "TINK", 637 }, 638 }, 639 ), 640 ), 641 }, 642 } 643 if diff := cmp.Diff(want, got); diff != "" { 644 t.Errorf("%v", diff) 645 } 646} 647 648func TestPrimitiveFactoryEncryptDecryptWithoutAnnotationsDoesNotMonitor(t *testing.T) { 649 defer internalregistry.ClearMonitoringClient() 650 client := fakemonitoring.NewClient("fake-client") 651 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 652 t.Fatalf("registry.RegisterMonitoringClient() err = %v, want nil", err) 653 } 654 privHandle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template()) 655 if err != nil { 656 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 657 } 658 pubHandle, err := privHandle.Public() 659 if err != nil { 660 t.Fatalf("privHandle.Public() err = %v, want nil", err) 661 } 662 e, err := hybrid.NewHybridEncrypt(pubHandle) 663 if err != nil { 664 t.Fatalf("hybrid.NewHybridEncrypt() err = %v, want nil", err) 665 } 666 d, err := hybrid.NewHybridDecrypt(privHandle) 667 if err != nil { 668 t.Fatalf("hybrid.NewHybridDecrypt() err = %v, want nil", err) 669 } 670 data := []byte("some_secret_piece_of_data") 671 aad := []byte("some_non_secret_piece_of_data") 672 ct, err := e.Encrypt(data, aad) 673 if err != nil { 674 t.Fatalf("e.Encrypt() err = %v, want nil", err) 675 } 676 if _, err := d.Decrypt(ct, aad); err != nil { 677 t.Fatalf("d.Decrypt() err = %v, want nil", err) 678 } 679 if len(client.Events()) != 0 { 680 t.Errorf("len(client.Events()) = %d, want 0", len(client.Events())) 681 } 682 if len(client.Failures()) != 0 { 683 t.Errorf("len(client.Failures()) = %d, want 0", len(client.Failures())) 684 } 685} 686 687// Since the HybridEncrypt interface is a subset of the AEAD interface, verify 688// that a HybridEncrypt primitive cannot be obtained from a keyset handle 689// containing an AEAD key. 690func TestEncryptFactoryFailsOnAEADHandle(t *testing.T) { 691 handle, err := keyset.NewHandle(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template()) 692 if err != nil { 693 t.Fatalf("keyset.NewHandle gives err = '%v', want nil", err) 694 } 695 pub, err := handle.Public() 696 if err != nil { 697 t.Fatalf("handle.Public gives err = '%v', want nil", err) 698 } 699 manager := keyset.NewManagerFromHandle(pub) 700 _, err = manager.Add(aead.AES128GCMKeyTemplate()) 701 if err != nil { 702 t.Fatalf("manager.Add gives err = '%v', want nil", err) 703 } 704 mixedHandle, err := manager.Handle() 705 if err != nil { 706 t.Fatalf("manager.Handle gives err = '%v', want nil", err) 707 } 708 if _, err := hybrid.NewHybridEncrypt(mixedHandle); err == nil { 709 t.Error("hybrid.NewHybridDecrypt err = nil, want err") 710 } 711} 712 713// Similar to the above but for HybridDecrypt. 714func TestDecryptFactoryFailsOnAEADHandle(t *testing.T) { 715 manager := keyset.NewManager() 716 id, err := manager.Add(aead.AES256GCMKeyTemplate()) 717 if err != nil { 718 t.Fatalf("manager.Add gives err = '%v', want nil", err) 719 } 720 err = manager.SetPrimary(id) 721 if err != nil { 722 t.Fatalf("manager.SetPrimary gives err = '%v', want nil", err) 723 } 724 _, err = manager.Add(hybrid.DHKEM_X25519_HKDF_SHA256_HKDF_SHA256_AES_128_GCM_Key_Template()) 725 if err != nil { 726 t.Fatalf("manager.Add gives err = '%v', want nil", err) 727 } 728 handle, err := manager.Handle() 729 if err != nil { 730 t.Fatalf("manager.Handle gives err = '%v', want nil", err) 731 } 732 733 if _, err := hybrid.NewHybridDecrypt(handle); err == nil { 734 t.Error("hybrid.NewHybridDecrypt err = nil, want err") 735 } 736} 737