1// Copyright 2018 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 signature_test 18 19import ( 20 "bytes" 21 "fmt" 22 "testing" 23 24 "github.com/google/go-cmp/cmp" 25 "google.golang.org/protobuf/proto" 26 "github.com/google/tink/go/core/registry" 27 "github.com/google/tink/go/insecurecleartextkeyset" 28 "github.com/google/tink/go/internal/internalregistry" 29 "github.com/google/tink/go/internal/testing/stubkeymanager" 30 "github.com/google/tink/go/keyset" 31 "github.com/google/tink/go/mac" 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 42func TestSignerVerifyFactory(t *testing.T) { 43 tinkPriv, tinkPub := newECDSAKeysetKeypair(commonpb.HashType_SHA512, 44 commonpb.EllipticCurveType_NIST_P521, 45 tinkpb.OutputPrefixType_TINK, 46 1) 47 legacyPriv, legacyPub := newECDSAKeysetKeypair(commonpb.HashType_SHA256, 48 commonpb.EllipticCurveType_NIST_P256, 49 tinkpb.OutputPrefixType_LEGACY, 50 2) 51 rawPriv, rawPub := newECDSAKeysetKeypair(commonpb.HashType_SHA512, 52 commonpb.EllipticCurveType_NIST_P384, 53 tinkpb.OutputPrefixType_RAW, 54 3) 55 crunchyPriv, crunchyPub := newECDSAKeysetKeypair(commonpb.HashType_SHA512, 56 commonpb.EllipticCurveType_NIST_P384, 57 tinkpb.OutputPrefixType_CRUNCHY, 58 4) 59 privKeys := []*tinkpb.Keyset_Key{tinkPriv, legacyPriv, rawPriv, crunchyPriv} 60 privKeyset := testutil.NewKeyset(privKeys[0].KeyId, privKeys) 61 privKeysetHandle, _ := testkeyset.NewHandle(privKeyset) 62 pubKeys := []*tinkpb.Keyset_Key{tinkPub, legacyPub, rawPub, crunchyPub} 63 pubKeyset := testutil.NewKeyset(pubKeys[0].KeyId, pubKeys) 64 pubKeysetHandle, err := testkeyset.NewHandle(pubKeyset) 65 if err != nil { 66 t.Fatalf("testkeyset.NewHandle(pubKeyset) err = %v, want nil", err) 67 } 68 // sign some random data 69 signer, err := signature.NewSigner(privKeysetHandle) 70 if err != nil { 71 t.Fatalf("signature.NewSigner(privKeysetHandle) err = %v, want nil", err) 72 } 73 data := random.GetRandomBytes(1211) 74 sig, err := signer.Sign(data) 75 if err != nil { 76 t.Fatalf("signer.Sign(data) err = %v, want nil", err) 77 } 78 // verify with the same set of public keys should work 79 verifier, err := signature.NewVerifier(pubKeysetHandle) 80 if err != nil { 81 t.Fatalf("signature.NewVerifier(pubKeysetHandle) err = %v, want nil", err) 82 } 83 if err := verifier.Verify(sig, data); err != nil { 84 t.Errorf("verifier.Verify(sig, data) = %v, want nil", err) 85 } 86 // verify with other key should fail 87 _, otherPub := newECDSAKeysetKeypair(commonpb.HashType_SHA512, 88 commonpb.EllipticCurveType_NIST_P521, 89 tinkpb.OutputPrefixType_TINK, 90 1) 91 otherPubKeys := []*tinkpb.Keyset_Key{otherPub} 92 otherPubKeyset := testutil.NewKeyset(otherPubKeys[0].KeyId, otherPubKeys) 93 otherPubKeysetHandle, err := testkeyset.NewHandle(otherPubKeyset) 94 if err != nil { 95 t.Fatalf("testkeyset.NewHandle(otherPubKeyset) err = %v, want nil", err) 96 } 97 otherVerifier, err := signature.NewVerifier(otherPubKeysetHandle) 98 if err != nil { 99 t.Fatalf("signature.NewVerifier(otherPubKeysetHandle) err = %v, want nil", err) 100 } 101 if err = otherVerifier.Verify(sig, data); err == nil { 102 t.Error("otherVerifier.Verify(sig, data) = nil, want not nil") 103 } 104} 105 106func TestPrimitiveFactoryFailsWhenKeysetHasNoPrimary(t *testing.T) { 107 privateKey, _ := newECDSAKeysetKeypair(commonpb.HashType_SHA512, 108 commonpb.EllipticCurveType_NIST_P521, 109 tinkpb.OutputPrefixType_TINK, 110 1) 111 privateKeysetWithoutPrimary := &tinkpb.Keyset{ 112 Key: []*tinkpb.Keyset_Key{privateKey}, 113 } 114 privateHandleWithoutPrimary, err := testkeyset.NewHandle(privateKeysetWithoutPrimary) 115 if err != nil { 116 t.Fatalf("testkeyset.NewHandle(privateKeysetWithoutPrimary) err = %v, want nil", err) 117 } 118 publicHandleWithoutPrimary, err := privateHandleWithoutPrimary.Public() 119 if err != nil { 120 t.Fatalf("privateHandleWithoutPrimary.Public() err = %v, want nil", err) 121 } 122 123 if _, err = signature.NewSigner(privateHandleWithoutPrimary); err == nil { 124 t.Errorf("signature.NewSigner(privateHandleWithoutPrimary) err = nil, want not nil") 125 } 126 127 if _, err = signature.NewVerifier(publicHandleWithoutPrimary); err == nil { 128 t.Errorf("signature.NewVerifier(publicHandleWithoutPrimary) err = nil, want not nil") 129 } 130} 131 132func newECDSAKeysetKeypair(hashType commonpb.HashType, curve commonpb.EllipticCurveType, outputPrefixType tinkpb.OutputPrefixType, keyID uint32) (*tinkpb.Keyset_Key, *tinkpb.Keyset_Key) { 133 key := testutil.NewRandomECDSAPrivateKey(hashType, curve) 134 serializedKey, _ := proto.Marshal(key) 135 keyData := testutil.NewKeyData(testutil.ECDSASignerTypeURL, 136 serializedKey, 137 tinkpb.KeyData_ASYMMETRIC_PRIVATE) 138 privKey := testutil.NewKey(keyData, tinkpb.KeyStatusType_ENABLED, keyID, outputPrefixType) 139 140 serializedKey, _ = proto.Marshal(key.PublicKey) 141 keyData = testutil.NewKeyData(testutil.ECDSAVerifierTypeURL, 142 serializedKey, 143 tinkpb.KeyData_ASYMMETRIC_PUBLIC) 144 pubKey := testutil.NewKey(keyData, tinkpb.KeyStatusType_ENABLED, keyID, outputPrefixType) 145 return privKey, pubKey 146} 147 148func TestFactoryWithInvalidPrimitiveSetType(t *testing.T) { 149 wrongKH, err := keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) 150 if err != nil { 151 t.Fatalf("keyset.NewHandle(mac.HMACSHA256Tag128KeyTemplate()) err = %v, want nil", err) 152 } 153 154 _, err = signature.NewSigner(wrongKH) 155 if err == nil { 156 t.Error("signature.NewSigner(wrongKH) err = nil, want not nil") 157 } 158 159 _, err = signature.NewVerifier(wrongKH) 160 if err == nil { 161 t.Error("signature.NewVerifier(wrongKH) err = nil, want not nil") 162 } 163} 164 165func TestFactoryWithValidPrimitiveSetType(t *testing.T) { 166 goodKH, err := keyset.NewHandle(signature.ECDSAP256KeyTemplate()) 167 if err != nil { 168 t.Fatalf("keyset.NewHandle(signature.ECDSAP256KeyTemplate()) err = %v, want nil", err) 169 } 170 171 _, err = signature.NewSigner(goodKH) 172 if err != nil { 173 t.Fatalf("signature.NewSigner(goodKH) err = %v, want nil", err) 174 } 175 176 goodPublicKH, err := goodKH.Public() 177 if err != nil { 178 t.Fatalf("goodKH.Public() err = %v, want nil", err) 179 } 180 181 _, err = signature.NewVerifier(goodPublicKH) 182 if err != nil { 183 t.Errorf("signature.NewVerifier(goodPublicKH) err = %v, want nil", err) 184 } 185} 186 187func TestPrimitiveFactorySignVerifyWithoutAnnotationsDoesNothing(t *testing.T) { 188 defer internalregistry.ClearMonitoringClient() 189 client := fakemonitoring.NewClient("fake-client") 190 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 191 t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err) 192 } 193 privHandle, err := keyset.NewHandle(signature.ED25519KeyTemplate()) 194 if err != nil { 195 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 196 } 197 signer, err := signature.NewSigner(privHandle) 198 if err != nil { 199 t.Fatalf("signature.NewSigner() err = %v, want nil", err) 200 } 201 pubHandle, err := privHandle.Public() 202 if err != nil { 203 t.Fatalf("privHandle.Public() err = %v, want nil", err) 204 } 205 verifier, err := signature.NewVerifier(pubHandle) 206 if err != nil { 207 t.Fatalf("signature.NewVerifier() err = %v, want nil", err) 208 } 209 data := []byte("some_important_data") 210 sig, err := signer.Sign(data) 211 if err != nil { 212 t.Fatalf("signer.Sign() err = %v, want nil", err) 213 } 214 if err := verifier.Verify(sig, data); err != nil { 215 t.Fatalf("verifier.Verify() err = %v, want nil", err) 216 } 217 if len(client.Events()) != 0 { 218 t.Errorf("len(client.Events()) = %d, want 0", len(client.Events())) 219 } 220 if len(client.Failures()) != 0 { 221 t.Errorf("len(client.Failures()) = %d, want 0", len(client.Failures())) 222 } 223} 224 225func TestPrimitiveFactoryMonitoringWithAnnotationsLogSignVerify(t *testing.T) { 226 defer internalregistry.ClearMonitoringClient() 227 client := fakemonitoring.NewClient("fake-client") 228 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 229 t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err) 230 } 231 handle, err := keyset.NewHandle(signature.ED25519KeyTemplate()) 232 if err != nil { 233 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 234 } 235 buff := &bytes.Buffer{} 236 if err := insecurecleartextkeyset.Write(handle, keyset.NewBinaryWriter(buff)); err != nil { 237 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 238 } 239 annotations := map[string]string{"foo": "bar"} 240 privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 241 if err != nil { 242 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 243 } 244 signer, err := signature.NewSigner(privHandle) 245 if err != nil { 246 t.Fatalf("signature.NewSigner() err = %v, want nil", err) 247 } 248 pubHandle, err := privHandle.Public() 249 if err != nil { 250 t.Fatalf("privHandle.Public() err = %v, want nil", err) 251 } 252 buff.Reset() 253 if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil { 254 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 255 } 256 pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 257 if err != nil { 258 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 259 } 260 verifier, err := signature.NewVerifier(pubHandle) 261 if err != nil { 262 t.Fatalf("signature.NewVerifier() err = %v, want nil", err) 263 } 264 data := []byte("some_important_data") 265 sig, err := signer.Sign(data) 266 if err != nil { 267 t.Fatalf("signer.Sign() err = %v, want nil", err) 268 } 269 if err := verifier.Verify(sig, data); err != nil { 270 t.Fatalf("verifier.Verify() err = %v, want nil", err) 271 } 272 if len(client.Failures()) != 0 { 273 t.Errorf("len(client.Failures()) = %d, want 0", len(client.Failures())) 274 } 275 got := client.Events() 276 wantVerifyKeysetInfo := &monitoring.KeysetInfo{ 277 Annotations: annotations, 278 PrimaryKeyID: pubHandle.KeysetInfo().GetPrimaryKeyId(), 279 Entries: []*monitoring.Entry{ 280 { 281 KeyID: pubHandle.KeysetInfo().GetPrimaryKeyId(), 282 Status: monitoring.Enabled, 283 KeyType: "tink.Ed25519PublicKey", 284 KeyPrefix: "TINK", 285 }, 286 }, 287 } 288 wantSignKeysetInfo := &monitoring.KeysetInfo{ 289 Annotations: annotations, 290 PrimaryKeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 291 Entries: []*monitoring.Entry{ 292 { 293 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 294 Status: monitoring.Enabled, 295 KeyType: "tink.Ed25519PrivateKey", 296 KeyPrefix: "TINK", 297 }, 298 }, 299 } 300 want := []*fakemonitoring.LogEvent{ 301 { 302 Context: monitoring.NewContext("public_key_sign", "sign", wantSignKeysetInfo), 303 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 304 NumBytes: len(data), 305 }, 306 { 307 Context: monitoring.NewContext("public_key_verify", "verify", wantVerifyKeysetInfo), 308 KeyID: privHandle.KeysetInfo().GetPrimaryKeyId(), 309 NumBytes: len(data), 310 }, 311 } 312 if diff := cmp.Diff(want, got); diff != "" { 313 t.Errorf("%v", diff) 314 } 315} 316 317type alwaysFailingSigner struct{} 318 319func (a *alwaysFailingSigner) Sign(data []byte) ([]byte, error) { return nil, fmt.Errorf("failed") } 320 321func TestPrimitiveFactoryMonitoringWithAnnotationsSignFailureIsLogged(t *testing.T) { 322 defer internalregistry.ClearMonitoringClient() 323 client := fakemonitoring.NewClient("fake-client") 324 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 325 t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err) 326 } 327 typeURL := "TestPrimitiveFactoryMonitoringWithAnnotationsSignFailureIsLogged" + "PrivateKeyManager" 328 km := &stubkeymanager.StubPrivateKeyManager{ 329 StubKeyManager: stubkeymanager.StubKeyManager{ 330 URL: typeURL, 331 Prim: &alwaysFailingSigner{}, 332 KeyData: &tinkpb.KeyData{ 333 TypeUrl: typeURL, 334 Value: []byte("serialized_key"), 335 KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE, 336 }, 337 }, 338 } 339 if err := registry.RegisterKeyManager(km); err != nil { 340 t.Fatalf("registry.RegisterKeyManager() err = %v, want nil", err) 341 } 342 template := &tinkpb.KeyTemplate{ 343 TypeUrl: typeURL, 344 OutputPrefixType: tinkpb.OutputPrefixType_LEGACY, 345 } 346 kh, err := keyset.NewHandle(template) 347 if err != nil { 348 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 349 } 350 buff := &bytes.Buffer{} 351 if err := insecurecleartextkeyset.Write(kh, keyset.NewBinaryWriter(buff)); err != nil { 352 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 353 } 354 annotations := map[string]string{"foo": "bar"} 355 privHandle, err := insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 356 if err != nil { 357 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 358 } 359 signer, err := signature.NewSigner(privHandle) 360 if err != nil { 361 t.Fatalf("signature.NewSigner() err = %v, want nil", err) 362 } 363 if _, err := signer.Sign([]byte("some_data")); err == nil { 364 t.Fatalf("signer.Sign() err = nil, want error") 365 } 366 if len(client.Events()) != 0 { 367 t.Errorf("len(client.Events()) = %d, want 0", len(client.Events())) 368 } 369 got := client.Failures() 370 want := []*fakemonitoring.LogFailure{ 371 { 372 Context: monitoring.NewContext( 373 "public_key_sign", 374 "sign", 375 monitoring.NewKeysetInfo( 376 annotations, 377 kh.KeysetInfo().GetPrimaryKeyId(), 378 []*monitoring.Entry{ 379 { 380 KeyID: kh.KeysetInfo().GetPrimaryKeyId(), 381 Status: monitoring.Enabled, 382 KeyType: typeURL, 383 KeyPrefix: "LEGACY", 384 }, 385 }, 386 ), 387 ), 388 }, 389 } 390 if diff := cmp.Diff(want, got); diff != "" { 391 t.Errorf("%v", diff) 392 } 393} 394 395func TestPrimitiveFactoryMonitoringWithAnnotationsVerifyFailureIsLogged(t *testing.T) { 396 defer internalregistry.ClearMonitoringClient() 397 client := fakemonitoring.NewClient("fake-client") 398 if err := internalregistry.RegisterMonitoringClient(client); err != nil { 399 t.Fatalf("internalregistry.RegisterMonitoringClient() err = %v, want nil", err) 400 } 401 privHandle, err := keyset.NewHandle(signature.ED25519KeyTemplate()) 402 if err != nil { 403 t.Fatalf("keyset.NewHandle() err = %v, want nil", err) 404 } 405 pubHandle, err := privHandle.Public() 406 if err != nil { 407 t.Fatalf("privHandle.Public() err = %v, want nil", err) 408 } 409 buff := &bytes.Buffer{} 410 annotations := map[string]string{"foo": "bar"} 411 if err := insecurecleartextkeyset.Write(pubHandle, keyset.NewBinaryWriter(buff)); err != nil { 412 t.Fatalf("insecurecleartextkeyset.Write() err = %v, want nil", err) 413 } 414 pubHandle, err = insecurecleartextkeyset.Read(keyset.NewBinaryReader(buff), keyset.WithAnnotations(annotations)) 415 if err != nil { 416 t.Fatalf("insecurecleartextkeyset.Read() err = %v, want nil", err) 417 } 418 verifier, err := signature.NewVerifier(pubHandle) 419 if err != nil { 420 t.Fatalf("signature.NewVerifier() err = %v, want nil", err) 421 } 422 if err := verifier.Verify([]byte("some_invalid_signature"), []byte("some_invalid_data")); err == nil { 423 t.Fatalf("verifier.Verify() err = nil, want error") 424 } 425 if len(client.Events()) != 0 { 426 t.Errorf("len(client.Events()) = %d, want 0", len(client.Events())) 427 } 428 got := client.Failures() 429 want := []*fakemonitoring.LogFailure{ 430 { 431 Context: monitoring.NewContext( 432 "public_key_verify", 433 "verify", 434 monitoring.NewKeysetInfo( 435 annotations, 436 pubHandle.KeysetInfo().GetPrimaryKeyId(), 437 []*monitoring.Entry{ 438 { 439 KeyID: pubHandle.KeysetInfo().GetPrimaryKeyId(), 440 Status: monitoring.Enabled, 441 KeyType: "tink.Ed25519PublicKey", 442 KeyPrefix: "TINK", 443 }, 444 }, 445 ), 446 ), 447 }, 448 } 449 if diff := cmp.Diff(want, got); diff != "" { 450 t.Errorf("%v", diff) 451 } 452} 453 454func TestVerifyWithLegacyKeyDoesNotHaveSideEffectOnMessage(t *testing.T) { 455 privateKey, publicKey := newECDSAKeysetKeypair(commonpb.HashType_SHA256, 456 commonpb.EllipticCurveType_NIST_P256, 457 tinkpb.OutputPrefixType_LEGACY, 458 2) 459 privateKeyset := testutil.NewKeyset(privateKey.KeyId, []*tinkpb.Keyset_Key{privateKey}) 460 privateHandle, err := testkeyset.NewHandle(privateKeyset) 461 if err != nil { 462 t.Fatalf("testkeyset.NewHandle(privateHandle) err = %v, want nil", err) 463 } 464 publicKeyset := testutil.NewKeyset(publicKey.KeyId, []*tinkpb.Keyset_Key{publicKey}) 465 publicHandle, err := testkeyset.NewHandle(publicKeyset) 466 if err != nil { 467 t.Fatalf("testkeyset.NewHandle(publicKeyset) err = %v, want nil", err) 468 } 469 signer, err := signature.NewSigner(privateHandle) 470 if err != nil { 471 t.Fatalf("signature.NewSigner(privateHandle) err = %v, want nil", err) 472 } 473 verifier, err := signature.NewVerifier(publicHandle) 474 if err != nil { 475 t.Fatalf("signature.NewVerifier(publicHandle) err = %v, want nil", err) 476 } 477 478 data := []byte("data") 479 message := data[:3] // Let message be a slice of data. 480 481 sig, err := signer.Sign(message) 482 if err != nil { 483 t.Fatalf("signer.Sign(message) err = %v, want nil", err) 484 } 485 err = verifier.Verify(sig, message) 486 if err != nil { 487 t.Fatalf("verifier.Verify(sig, message) err = %v, want nil", err) 488 } 489 wantData := []byte("data") 490 if !bytes.Equal(data, wantData) { 491 t.Errorf("data = %q, want: %q", data, wantData) 492 } 493} 494