xref: /aosp_15_r20/external/tink/go/signature/signature_factory_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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