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 "google.golang.org/protobuf/proto" 24 "github.com/google/tink/go/core/registry" 25 "github.com/google/tink/go/hybrid/internal/hpke" 26 "github.com/google/tink/go/subtle/random" 27 "github.com/google/tink/go/subtle" 28 hpkepb "github.com/google/tink/go/proto/hpke_go_proto" 29) 30 31var hpkeAEADs = []hpkepb.HpkeAead{ 32 hpkepb.HpkeAead_AES_128_GCM, 33 hpkepb.HpkeAead_AES_256_GCM, 34 hpkepb.HpkeAead_CHACHA20_POLY1305, 35} 36 37func TestPublicKeyManagerPrimitiveRejectsInvalidKeyVersion(t *testing.T) { 38 km, err := registry.GetKeyManager(hpkePublicKeyTypeURL) 39 if err != nil { 40 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err) 41 } 42 params := &hpkepb.HpkeParams{ 43 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 44 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 45 Aead: hpkepb.HpkeAead_AES_256_GCM, 46 } 47 pubKey, _ := pubPrivKeys(t, params) 48 pubKey.Version = 1 49 serializedPubKey, err := proto.Marshal(pubKey) 50 if err != nil { 51 t.Fatal(err) 52 } 53 if _, err := km.Primitive(serializedPubKey); err == nil { 54 t.Error("Primitive() err = nil, want error") 55 } 56} 57 58func TestPublicKeyManagerPrimitiveRejectsInvalidParams(t *testing.T) { 59 km, err := registry.GetKeyManager(hpkePublicKeyTypeURL) 60 if err != nil { 61 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err) 62 } 63 64 tests := []struct { 65 name string 66 params *hpkepb.HpkeParams 67 }{ 68 {"kem", &hpkepb.HpkeParams{ 69 Kem: hpkepb.HpkeKem_KEM_UNKNOWN, 70 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 71 Aead: hpkepb.HpkeAead_AES_256_GCM, 72 }}, 73 {"kdf", &hpkepb.HpkeParams{ 74 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 75 Kdf: hpkepb.HpkeKdf_KDF_UNKNOWN, 76 Aead: hpkepb.HpkeAead_AES_256_GCM, 77 }}, 78 {"aead", &hpkepb.HpkeParams{ 79 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 80 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 81 Aead: hpkepb.HpkeAead_AEAD_UNKNOWN, 82 }}, 83 } 84 85 for _, test := range tests { 86 t.Run(test.name, func(t *testing.T) { 87 serializedPubKey, _ := serializedPubPrivKeys(t, test.params) 88 if _, err := km.Primitive(serializedPubKey); err == nil { 89 t.Error("Primitive() err = nil, want error") 90 } 91 }) 92 } 93} 94 95func TestPublicKeyManagerPrimitiveRejectsMissingParams(t *testing.T) { 96 km, err := registry.GetKeyManager(hpkePublicKeyTypeURL) 97 if err != nil { 98 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err) 99 } 100 serializedPubKey, _ := serializedPubPrivKeys(t, nil) 101 if _, err := km.Primitive(serializedPubKey); err == nil { 102 t.Error("Primitive() err = nil, want error") 103 } 104} 105 106func TestPublicKeyManagerPrimitiveRejectsNilKey(t *testing.T) { 107 km, err := registry.GetKeyManager(hpkePublicKeyTypeURL) 108 if err != nil { 109 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err) 110 } 111 if _, err := km.Primitive(nil); err == nil { 112 t.Error("Primitive() err = nil, want error") 113 } 114} 115 116func TestPublicKeyManagerPrimitiveEncryptDecrypt(t *testing.T) { 117 km, err := registry.GetKeyManager(hpkePublicKeyTypeURL) 118 if err != nil { 119 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err) 120 } 121 122 wantPT := random.GetRandomBytes(200) 123 ctxInfo := random.GetRandomBytes(100) 124 125 for _, aeadID := range hpkeAEADs { 126 params := &hpkepb.HpkeParams{ 127 Kem: hpkepb.HpkeKem_DHKEM_X25519_HKDF_SHA256, 128 Kdf: hpkepb.HpkeKdf_HKDF_SHA256, 129 Aead: aeadID, 130 } 131 pubKey, privKey := pubPrivKeys(t, params) 132 serializedPubKey, err := proto.Marshal(pubKey) 133 if err != nil { 134 t.Fatal(err) 135 } 136 137 e, err := km.Primitive(serializedPubKey) 138 if err != nil { 139 t.Fatalf("Primitive() err = %v, want nil", err) 140 } 141 enc, ok := e.(*hpke.Encrypt) 142 if !ok { 143 t.Fatal("primitive is not Encrypt") 144 } 145 dec, err := hpke.NewDecrypt(privKey) 146 if err != nil { 147 t.Fatalf("hpke.NewDecrypt() err = %v, want nil", err) 148 } 149 150 ct, err := enc.Encrypt(wantPT, ctxInfo) 151 if err != nil { 152 t.Fatalf("Encrypt() err = %v, want nil", err) 153 } 154 gotPT, err := dec.Decrypt(ct, ctxInfo) 155 if err != nil { 156 t.Fatalf("Decrypt() err = %v, want nil", err) 157 } 158 if !bytes.Equal(gotPT, wantPT) { 159 t.Errorf("Decrypt() = %x, want %x", gotPT, wantPT) 160 } 161 } 162} 163 164func TestPublicKeyManagerDoesSupport(t *testing.T) { 165 km, err := registry.GetKeyManager(hpkePublicKeyTypeURL) 166 if err != nil { 167 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err) 168 } 169 if !km.DoesSupport(hpkePublicKeyTypeURL) { 170 t.Errorf("DoesSupport(%q) = false, want true", hpkePublicKeyTypeURL) 171 } 172 unsupportedKeyTypeURL := "unsupported.key.type" 173 if km.DoesSupport(unsupportedKeyTypeURL) { 174 t.Errorf("DoesSupport(%q) = true, want false", unsupportedKeyTypeURL) 175 } 176} 177 178func TestPublicKeyManagerTypeURL(t *testing.T) { 179 km, err := registry.GetKeyManager(hpkePublicKeyTypeURL) 180 if err != nil { 181 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err) 182 } 183 if km.TypeURL() != hpkePublicKeyTypeURL { 184 t.Errorf("TypeURL = %q, want %q", km.TypeURL(), hpkePublicKeyTypeURL) 185 } 186} 187 188func TestPublicKeyManagerNotSupported(t *testing.T) { 189 km, err := registry.GetKeyManager(hpkePublicKeyTypeURL) 190 if err != nil { 191 t.Fatalf("GetKeyManager(%q) err = %v, want nil", hpkePublicKeyTypeURL, err) 192 } 193 if _, err := km.NewKey(nil); err == nil { 194 t.Error("NewKey(nil) err = nil, want error") 195 } 196 if _, err := km.NewKeyData(nil); err == nil { 197 t.Error("NewKeyData(nil) err = nil, want error") 198 } 199} 200 201func serializedPubPrivKeys(t *testing.T, params *hpkepb.HpkeParams) ([]byte, []byte) { 202 t.Helper() 203 pub, priv := pubPrivKeys(t, params) 204 serializedPub, err := proto.Marshal(pub) 205 if err != nil { 206 t.Fatal(err) 207 } 208 serializedPriv, err := proto.Marshal(priv) 209 if err != nil { 210 t.Fatal(err) 211 } 212 return serializedPub, serializedPriv 213} 214 215func pubPrivKeys(t *testing.T, params *hpkepb.HpkeParams) (*hpkepb.HpkePublicKey, *hpkepb.HpkePrivateKey) { 216 t.Helper() 217 218 priv, err := subtle.GeneratePrivateKeyX25519() 219 if err != nil { 220 t.Fatalf("GeneratePrivateKeyX25519: err %q", err) 221 } 222 pub, err := subtle.PublicFromPrivateX25519(priv) 223 if err != nil { 224 t.Fatalf("PublicFromPrivateX25519: err %q", err) 225 } 226 227 pubKey := &hpkepb.HpkePublicKey{ 228 Version: 0, 229 Params: params, 230 PublicKey: pub, 231 } 232 privKey := &hpkepb.HpkePrivateKey{ 233 Version: 0, 234 PublicKey: pubKey, 235 PrivateKey: priv, 236 } 237 return pubKey, privKey 238} 239