xref: /aosp_15_r20/external/tink/go/jwt/jwt_ecdsa_verifier_key_manager_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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 jwt
18
19import (
20	"fmt"
21	"testing"
22	"time"
23
24	"google.golang.org/protobuf/proto"
25	"github.com/google/tink/go/core/registry"
26	jepb "github.com/google/tink/go/proto/jwt_ecdsa_go_proto"
27)
28
29const testECDSAVerifierKeyType = "type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey"
30
31func TestECDSAVerifierNotImplemented(t *testing.T) {
32	km, err := registry.GetKeyManager(testECDSAVerifierKeyType)
33	if err != nil {
34		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testECDSAVerifierKeyType, err)
35	}
36	if _, err := km.NewKey(nil); err != errECDSAVerifierNotImplemented {
37		t.Fatalf("km.NewKey() err = %v, want %v", err, errECDSAVerifierNotImplemented)
38	}
39	if _, err := km.NewKeyData(nil); err != errECDSAVerifierNotImplemented {
40		t.Fatalf("km.NewKeyData() err = %v, want %v", err, errECDSAVerifierNotImplemented)
41	}
42}
43
44func TestECDSAVerifierDoesSupport(t *testing.T) {
45	km, err := registry.GetKeyManager(testECDSAVerifierKeyType)
46	if err != nil {
47		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testECDSAVerifierKeyType, err)
48	}
49	if !km.DoesSupport(testECDSAVerifierKeyType) {
50		t.Errorf("km.DoesSupport(%q) = false, want true", testECDSAVerifierKeyType)
51	}
52	if km.DoesSupport("not.the.actual.key.type") {
53		t.Errorf("km.DoesSupport('not.the.actual.key.type') = true, want false")
54	}
55}
56
57func TestECDSAVerifierTypeURL(t *testing.T) {
58	km, err := registry.GetKeyManager(testECDSAVerifierKeyType)
59	if err != nil {
60		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testECDSAVerifierKeyType, err)
61	}
62	if km.TypeURL() != testECDSAVerifierKeyType {
63		t.Errorf("km.TypeURL() = %q, want %q", km.TypeURL(), testECDSAVerifierKeyType)
64	}
65}
66
67func TestECDSAVerifierPrimitiveWithNilKey(t *testing.T) {
68	km, err := registry.GetKeyManager(testECDSAVerifierKeyType)
69	if err != nil {
70		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testECDSAVerifierKeyType, err)
71	}
72	if _, err := km.Primitive(nil); err == nil {
73		t.Errorf("km.Primitive(nil) err = nil, want error")
74	}
75}
76
77func createECDSAPublicKey(algorithm jepb.JwtEcdsaAlgorithm, kid *string, version uint32) (*jepb.JwtEcdsaPublicKey, error) {
78	// Public key from: https://datatracker.ietf.org/doc/html/rfc7515#appendix-A.3
79	x, err := base64Decode("f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU")
80	if err != nil {
81		return nil, fmt.Errorf("base64 decoding x coordinate of public key: %v", err)
82	}
83	y, err := base64Decode("x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0")
84	if err != nil {
85		return nil, fmt.Errorf("base64 decoding y coordinate of public key: %v", err)
86	}
87	var customKID *jepb.JwtEcdsaPublicKey_CustomKid = nil
88	if kid != nil {
89		customKID = &jepb.JwtEcdsaPublicKey_CustomKid{Value: *kid}
90	}
91	return &jepb.JwtEcdsaPublicKey{
92		Version:   version,
93		Algorithm: algorithm,
94		X:         x,
95		Y:         y,
96		CustomKid: customKID,
97	}, nil
98}
99
100func createECDSASerializedPublicKey(algorithm jepb.JwtEcdsaAlgorithm, kid *string, version uint32) ([]byte, error) {
101	pubKey, err := createECDSAPublicKey(algorithm, kid, version)
102	if err != nil {
103		return nil, err
104	}
105	return proto.Marshal(pubKey)
106}
107
108func TestECDSAVerifierPrimitiveInvalidKeyVersion(t *testing.T) {
109	km, err := registry.GetKeyManager(testECDSAVerifierKeyType)
110	if err != nil {
111		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testECDSAVerifierKeyType, err)
112	}
113	var invalidKeyVersion uint32 = 1
114	serializedPubKey, err := createECDSASerializedPublicKey(jepb.JwtEcdsaAlgorithm_ES384, nil, invalidKeyVersion)
115	if err != nil {
116		t.Fatal(err)
117	}
118	if _, err := km.Primitive(serializedPubKey); err == nil {
119		t.Errorf("km.Primitive() err = nil, want error")
120	}
121}
122
123func TestECDSAVerifierPrimitiveWithInvalidAlgorithm(t *testing.T) {
124	km, err := registry.GetKeyManager(testECDSAVerifierKeyType)
125	if err != nil {
126		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testECDSAVerifierKeyType, err)
127	}
128	serializedPubKey, err := createECDSASerializedPublicKey(jepb.JwtEcdsaAlgorithm_ES_UNKNOWN, nil /*=kid*/, 0 /*=version*/)
129	if err != nil {
130		t.Fatal(err)
131	}
132	if _, err := km.Primitive(serializedPubKey); err == nil {
133		t.Errorf("km.Primitive() err = nil, want error")
134	}
135}
136
137func TestECDSAVerifierPrimitiveVerifyFixedToken(t *testing.T) {
138	km, err := registry.GetKeyManager(testECDSAVerifierKeyType)
139	if err != nil {
140		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testECDSAVerifierKeyType, err)
141	}
142	serializedPubKey, err := createECDSASerializedPublicKey(jepb.JwtEcdsaAlgorithm_ES256, nil /*=kid*/, 0 /*=version*/)
143	if err != nil {
144		t.Fatal(err)
145	}
146	v, err := km.Primitive(serializedPubKey)
147	if err != nil {
148		t.Fatalf("km.Primitive() err = %v, want nil", err)
149	}
150	verifier, ok := v.(*verifierWithKID)
151	if !ok {
152		t.Fatalf("primitive is not a JWT Verifier")
153	}
154	// compact from https://datatracker.ietf.org/doc/html/rfc7515#appendix-A.3
155	compact := "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ.DtEhU3ljbEg8L38VWAfUAqOyKAM6-Xx-F4GawxaepmXFCgfTjDxw5djxLa8ISlSApmWQxfKTUJqPP3-Kg6NU1Q"
156	opts := &ValidatorOpts{
157		ExpectedIssuer: refString("joe"),
158		FixedNow:       time.Unix(12345, 0),
159	}
160	validator, err := NewValidator(opts)
161	if err != nil {
162		t.Fatalf("creating JWTValidator: %v", err)
163	}
164	// verification succeeds because token was valid valid on January 1, 1970 UTC.
165	if _, err := verifier.VerifyAndDecodeWithKID(compact, validator, nil); err != nil {
166		t.Errorf("verifier.VerifyAndDecodeWithKID(kid = nil) err = %v, want nil", err)
167	}
168	// verification with KID fails because token contains no KID.
169	if _, err := verifier.VerifyAndDecodeWithKID(compact, validator, refString("1234")); err == nil {
170		t.Errorf("verifier.VerifyAndDecodeWithKID(kid = '1234') err = nil, want error")
171	}
172}
173
174func TestECDSAVerifierPrimitiveFixedTokenWithKID(t *testing.T) {
175	km, err := registry.GetKeyManager(testECDSAVerifierKeyType)
176	if err != nil {
177		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testECDSAVerifierKeyType, err)
178	}
179	serializedPubKey, err := createECDSASerializedPublicKey(jepb.JwtEcdsaAlgorithm_ES256, refString("1234"), 0 /*=version*/)
180	if err != nil {
181		t.Fatal(err)
182	}
183	v, err := km.Primitive(serializedPubKey)
184	if err != nil {
185		t.Fatalf("km.Primitive() err = %v, want nil", err)
186	}
187	verifier, ok := v.(*verifierWithKID)
188	if !ok {
189		t.Fatalf("primitive is not a JWT Verifier")
190	}
191	// compact is the claim set '{}' with header '{"alg":"ES256", "kid":"1234"}'
192	// signed with private key as specified in https://datatracker.ietf.org/doc/html/rfc7515#appendix-A.3
193	compact := "eyJhbGciOiJFUzI1NiIsImtpZCI6IjEyMzQifQ.e30.3jdIhPC4qfXrzE8ds6tyrLoqqmwfXX-CyfP9YG0k_LFeuF5wYPsmgPeUthMFfvPIN63zQ9i-I5BQLJVwaRTTdw"
194	validator, err := NewValidator(&ValidatorOpts{AllowMissingExpiration: true})
195	if err != nil {
196		t.Fatalf("creating JWTValidator: %v", err)
197	}
198	if _, err := verifier.VerifyAndDecodeWithKID(compact, validator, nil); err != nil {
199		t.Errorf("verifier.VerifyAndDecodeWithKID(kid = nil) err = %v, want nil ", err)
200	}
201	if _, err := verifier.VerifyAndDecodeWithKID(compact, validator, refString("1234")); err == nil {
202		t.Errorf("verifier.VerifyAndDecodeWithKID(kid = 1234) err = nil, want error ")
203	}
204}
205