1// Copyright 2022 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 18 19import ( 20 "bytes" 21 "testing" 22 23 "github.com/google/go-cmp/cmp" 24 "google.golang.org/protobuf/proto" 25 "google.golang.org/protobuf/testing/protocmp" 26 "github.com/google/tink/go/core/registry" 27 "github.com/google/tink/go/hybrid/internal/hpke" 28 "github.com/google/tink/go/subtle/random" 29 hpkepb "github.com/google/tink/go/proto/hpke_go_proto" 30 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 31) 32 33func TestPrivateKeyManagerPrimitiveRejectsInvalidKeyVersion(t *testing.T) { 34 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 35 if err != nil { 36 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 37 } 38 params := &hpkepb.HpkeParams{ 39 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 40 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 41 Aead: hpkepb.HpkeAead_AES_256_GCM, 42 } 43 _, privKey := pubPrivKeys(t, params) 44 privKey.Version = 1 45 serializedPrivKey, err := proto.Marshal(privKey) 46 if err != nil { 47 t.Fatal(err) 48 } 49 if _, err := km.Primitive(serializedPrivKey); err == nil { 50 t.Error("Primitive() err = nil, want error") 51 } 52} 53 54func TestPrivateKeyManagerPrimitiveRejectsInvalidParams(t *testing.T) { 55 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 56 if err != nil { 57 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 58 } 59 60 tests := []struct { 61 name string 62 params *hpkepb.HpkeParams 63 }{ 64 {"kem", &hpkepb.HpkeParams{ 65 Kem: hpkepb.HpkeKem_KEM_UNKNOWN, 66 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 67 Aead: hpkepb.HpkeAead_AES_256_GCM, 68 }}, 69 {"kdf", &hpkepb.HpkeParams{ 70 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 71 Kdf: hpkepb.HpkeKdf_KDF_UNKNOWN, 72 Aead: hpkepb.HpkeAead_AES_256_GCM, 73 }}, 74 {"aead", &hpkepb.HpkeParams{ 75 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 76 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 77 Aead: hpkepb.HpkeAead_AEAD_UNKNOWN, 78 }}, 79 } 80 81 for _, test := range tests { 82 t.Run(test.name, func(t *testing.T) { 83 _, serializedPrivKey := serializedPubPrivKeys(t, test.params) 84 if _, err := km.Primitive(serializedPrivKey); err == nil { 85 t.Error("Primitive() err = nil, want error") 86 } 87 }) 88 } 89} 90 91func TestPrivateKeyManagerPrimitiveRejectsMissingParams(t *testing.T) { 92 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 93 if err != nil { 94 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 95 } 96 _, serializedPrivKey := serializedPubPrivKeys(t, nil) 97 if _, err := km.Primitive(serializedPrivKey); err == nil { 98 t.Error("Primitive() err = nil, want error") 99 } 100} 101 102func TestPrivateKeyManagerPrimitiveRejectsNilKey(t *testing.T) { 103 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 104 if err != nil { 105 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 106 } 107 if _, err := km.Primitive(nil); err == nil { 108 t.Error("Primitive() err = nil, want error") 109 } 110} 111 112func TestPrivateKeyManagerPrimitiveEncryptDecrypt(t *testing.T) { 113 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 114 if err != nil { 115 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 116 } 117 pt := random.GetRandomBytes(200) 118 ctxInfo := random.GetRandomBytes(100) 119 120 for _, aeadID := range hpkeAEADs { 121 params := &hpkepb.HpkeParams{ 122 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 123 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 124 Aead: aeadID, 125 } 126 pubKey, privKey := pubPrivKeys(t, params) 127 serializedPrivKey, err := proto.Marshal(privKey) 128 if err != nil { 129 t.Fatal(err) 130 } 131 132 enc, err := hpke.NewEncrypt(pubKey) 133 if err != nil { 134 t.Fatalf("hpke.NewEncrypt() err = %v, want nil", err) 135 } 136 d, err := km.Primitive(serializedPrivKey) 137 if err != nil { 138 t.Fatalf("Primitive() err = %v, want nil", err) 139 } 140 dec, ok := d.(*hpke.Decrypt) 141 if !ok { 142 t.Fatal("primitive is not Decrypt") 143 } 144 145 ct, err := enc.Encrypt(pt, ctxInfo) 146 if err != nil { 147 t.Fatalf("Encrypt() err = %v, want nil", err) 148 } 149 gotPT, err := dec.Decrypt(ct, ctxInfo) 150 if err != nil { 151 t.Fatalf("Decrypt() err = %v, want nil", err) 152 } 153 if want := pt; !bytes.Equal(gotPT, want) { 154 t.Errorf("Decrypt() = %x, want %x", gotPT, want) 155 } 156 } 157} 158 159func TestPrivateKeyManagerNewKeyRejectsNilKeyFormat(t *testing.T) { 160 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 161 if err != nil { 162 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 163 } 164 if _, err := km.NewKey(nil); err == nil { 165 t.Error("NewKey() err = nil, want error") 166 } 167} 168 169func TestPrivateKeyManagerNewKeyRejectsInvalidKeyFormat(t *testing.T) { 170 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 171 if err != nil { 172 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 173 } 174 serializedKeyFormatUnknownKEM, err := proto.Marshal( 175 &hpkepb.HpkeParams{ 176 Kem: hpkepb.HpkeKem_KEM_UNKNOWN, 177 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 178 Aead: hpkepb.HpkeAead_AES_256_GCM, 179 }) 180 if err != nil { 181 t.Fatal(err) 182 } 183 serializedKeyFormatUnknownKDF, err := proto.Marshal( 184 &hpkepb.HpkeParams{ 185 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 186 Kdf: hpkepb.HpkeKdf_KDF_UNKNOWN, 187 Aead: hpkepb.HpkeAead_AES_256_GCM, 188 }) 189 if err != nil { 190 t.Fatal(err) 191 } 192 serializedKeyFormatUnknownAEAD, err := proto.Marshal( 193 &hpkepb.HpkeParams{ 194 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 195 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 196 Aead: hpkepb.HpkeAead_AEAD_UNKNOWN, 197 }) 198 if err != nil { 199 t.Fatal(err) 200 } 201 202 tests := []struct { 203 name string 204 keyFormat []byte 205 }{ 206 {"kem", serializedKeyFormatUnknownKEM}, 207 {"kdf", serializedKeyFormatUnknownKDF}, 208 {"aead", serializedKeyFormatUnknownAEAD}, 209 } 210 211 for _, test := range tests { 212 t.Run(test.name, func(t *testing.T) { 213 if _, err := km.NewKey(test.keyFormat); err == nil { 214 t.Error("NewKey() err = nil, want error") 215 } 216 }) 217 } 218} 219 220func TestPrivateKeyManagerNewKeyEncryptDecrypt(t *testing.T) { 221 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 222 if err != nil { 223 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 224 } 225 226 wantPT := random.GetRandomBytes(200) 227 ctxInfo := random.GetRandomBytes(100) 228 229 for _, aeadID := range hpkeAEADs { 230 keyFormat := &hpkepb.HpkeKeyFormat{ 231 Params: &hpkepb.HpkeParams{ 232 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 233 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 234 Aead: aeadID, 235 }, 236 } 237 serializedKeyFormat, err := proto.Marshal(keyFormat) 238 if err != nil { 239 t.Fatal(err) 240 } 241 242 privKeyProto, err := km.NewKey(serializedKeyFormat) 243 if err != nil { 244 t.Fatalf("NewKey() err = %v, want nil", err) 245 } 246 privKey, ok := privKeyProto.(*hpkepb.HpkePrivateKey) 247 if !ok { 248 t.Fatal("primitive is not HpkePrivateKey") 249 } 250 if privKey.GetVersion() != 0 { 251 t.Errorf("private key version = %d, want %d", privKey.GetVersion(), 0) 252 } 253 if len(privKey.GetPrivateKey()) == 0 { 254 t.Error("private key is missing") 255 } 256 257 pubKey := privKey.GetPublicKey() 258 if pubKey.GetVersion() != 0 { 259 t.Errorf("public key version = %d, want %d", pubKey.GetVersion(), 0) 260 } 261 if !cmp.Equal(pubKey.GetParams(), keyFormat.GetParams(), protocmp.Transform()) { 262 t.Errorf("key params = %v, want %v", pubKey.GetParams(), keyFormat.GetParams()) 263 } 264 if len(pubKey.GetPublicKey()) == 0 { 265 t.Error("public key is missing") 266 } 267 268 enc, err := hpke.NewEncrypt(pubKey) 269 if err != nil { 270 t.Fatalf("hpke.NewEncrypt() err = %v, want nil", err) 271 } 272 serializedPrivKey, err := proto.Marshal(privKeyProto) 273 if err != nil { 274 t.Fatal(err) 275 } 276 d, err := km.Primitive(serializedPrivKey) 277 if err != nil { 278 t.Fatalf("Primitive() err = %v, want nil", err) 279 } 280 dec, ok := d.(*hpke.Decrypt) 281 if !ok { 282 t.Fatal("primitive is not Decrypt") 283 } 284 285 ct, err := enc.Encrypt(wantPT, ctxInfo) 286 if err != nil { 287 t.Fatalf("Encrypt() err = %v, want nil", err) 288 } 289 gotPT, err := dec.Decrypt(ct, ctxInfo) 290 if err != nil { 291 t.Fatalf("Decrypt() err = %v, want nil", err) 292 } 293 if !bytes.Equal(gotPT, wantPT) { 294 t.Errorf("Decrypt() = %x, want %x", gotPT, wantPT) 295 } 296 } 297} 298 299func TestPrivateKeyManagerNewKeyDataRejectsNilKeyFormat(t *testing.T) { 300 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 301 if err != nil { 302 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 303 } 304 if _, err := km.NewKeyData(nil); err == nil { 305 t.Error("NewKey() err = nil, want error") 306 } 307} 308 309func TestPrivateKeyManagerNewKeyData(t *testing.T) { 310 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 311 if err != nil { 312 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 313 } 314 315 for _, aeadID := range hpkeAEADs { 316 keyFormat := &hpkepb.HpkeKeyFormat{ 317 Params: &hpkepb.HpkeParams{ 318 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 319 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 320 Aead: aeadID, 321 }, 322 } 323 serializedKeyFormat, err := proto.Marshal(keyFormat) 324 if err != nil { 325 t.Fatal(err) 326 } 327 328 keyData, err := km.NewKeyData(serializedKeyFormat) 329 if err != nil { 330 t.Fatalf("NewKeyData() err = %v, want nil", err) 331 } 332 if got, want := keyData.GetTypeUrl(), hpkePrivateKeyTypeURL; got != want { 333 t.Errorf("type URL = %q, want %q", got, want) 334 } 335 if got, want := keyData.GetKeyMaterialType(), tinkpb.KeyData_ASYMMETRIC_PRIVATE; got != want { 336 t.Errorf("key material type = %d, want %d", got, want) 337 } 338 339 privKey := new(hpkepb.HpkePrivateKey) 340 if err := proto.Unmarshal(keyData.GetValue(), privKey); err != nil { 341 t.Fatalf("Unmarshal err = %v, want nil", err) 342 } 343 if privKey.GetVersion() != 0 { 344 t.Errorf("private key version = %d, want %d", privKey.GetVersion(), 0) 345 } 346 if len(privKey.GetPrivateKey()) == 0 { 347 t.Error("private key is missing") 348 } 349 350 pubKey := privKey.GetPublicKey() 351 if pubKey.GetVersion() != 0 { 352 t.Errorf("public key version = %d, want %d", pubKey.GetVersion(), 0) 353 } 354 if !cmp.Equal(pubKey.GetParams(), keyFormat.GetParams(), protocmp.Transform()) { 355 t.Errorf("key params = %v, want %v", pubKey.GetParams(), keyFormat.GetParams()) 356 } 357 if len(pubKey.GetPublicKey()) == 0 { 358 t.Error("public key is missing") 359 } 360 } 361} 362 363func TestPrivateKeyManagerPublicKeyDataAcceptsNilKey(t *testing.T) { 364 k, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 365 if err != nil { 366 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 367 } 368 km, ok := k.(registry.PrivateKeyManager) 369 if !ok { 370 t.Errorf("primitive is not PrivateKeyManager") 371 } 372 if _, err := km.PublicKeyData(nil); err != nil { 373 t.Errorf("PublicKeyData() err = %v, want nil", err) 374 } 375} 376 377func TestPrivateKeyManagerPublicKeyData(t *testing.T) { 378 k, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 379 if err != nil { 380 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 381 } 382 km, ok := k.(registry.PrivateKeyManager) 383 if !ok { 384 t.Errorf("primitive is not PrivateKeyManager") 385 } 386 387 params := &hpkepb.HpkeParams{ 388 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 389 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 390 Aead: hpkepb.HpkeAead_AES_256_GCM, 391 } 392 _, privKey := pubPrivKeys(t, params) 393 serializedPrivKey, err := proto.Marshal(privKey) 394 if err != nil { 395 t.Fatal(err) 396 } 397 wantPubKey := privKey.GetPublicKey() 398 serializedPubKey, err := proto.Marshal(wantPubKey) 399 if err != nil { 400 t.Fatal(err) 401 } 402 403 pubKey, err := km.PublicKeyData(serializedPrivKey) 404 if err != nil { 405 t.Fatalf("PublicKeyData() err = %v, want nil", err) 406 } 407 if got, want := pubKey.GetTypeUrl(), hpkePublicKeyTypeURL; got != want { 408 t.Errorf("type URL = %q, want %q", got, want) 409 } 410 if !bytes.Equal(pubKey.GetValue(), serializedPubKey) { 411 t.Errorf("value = %v, want %v", pubKey.GetValue(), serializedPubKey) 412 } 413 if got, want := pubKey.GetKeyMaterialType(), tinkpb.KeyData_ASYMMETRIC_PUBLIC; got != want { 414 t.Errorf("Key material type = %d, want %d", got, want) 415 } 416} 417 418func TestPrivateKeyManagerDoesSupport(t *testing.T) { 419 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 420 if err != nil { 421 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 422 } 423 if !km.DoesSupport(hpkePrivateKeyTypeURL) { 424 t.Errorf("DoesSupport(%q) = false, want true", hpkePrivateKeyTypeURL) 425 } 426 unsupportedKeyTypeURL := "unsupported.key.type" 427 if km.DoesSupport(unsupportedKeyTypeURL) { 428 t.Errorf("DoesSupport(%q) = true, want false", unsupportedKeyTypeURL) 429 } 430} 431 432func TestPrivateKeyManagerTypeURL(t *testing.T) { 433 km, err := registry.GetKeyManager(hpkePrivateKeyTypeURL) 434 if err != nil { 435 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePrivateKeyTypeURL, err) 436 } 437 if km.TypeURL() != hpkePrivateKeyTypeURL { 438 t.Errorf("TypeURL = %q, want %q", km.TypeURL(), hpkePrivateKeyTypeURL) 439 } 440} 441