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_test 18 19import ( 20 "testing" 21 "time" 22 23 "github.com/google/tink/go/jwt" 24 "github.com/google/tink/go/keyset" 25 26 tinkpb "github.com/google/tink/go/proto/tink_go_proto" 27) 28 29type templateTestCase struct { 30 tag string 31 template *tinkpb.KeyTemplate 32} 33 34func TestJWTComputeVerifyMAC(t *testing.T) { 35 expiresAt := time.Now().Add(time.Hour) 36 rawJWT, err := jwt.NewRawJWT(&jwt.RawJWTOptions{ 37 ExpiresAt: &expiresAt, 38 }) 39 if err != nil { 40 t.Errorf("NewRawJWT() err = %v, want nil", err) 41 } 42 for _, tc := range []templateTestCase{ 43 {tag: "JWT_HS256", template: jwt.HS256Template()}, 44 {tag: "JWT_HS384", template: jwt.HS384Template()}, 45 {tag: "JWT_HS512", template: jwt.HS512Template()}, 46 {tag: "JWT_HS256_RAW", template: jwt.RawHS256Template()}, 47 {tag: "JWT_HS384_RAW", template: jwt.RawHS384Template()}, 48 {tag: "JWT_HS512_RAW", template: jwt.RawHS512Template()}, 49 } { 50 t.Run(tc.tag, func(t *testing.T) { 51 handle, err := keyset.NewHandle(tc.template) 52 if err != nil { 53 t.Errorf("keyset.NewHandle() err = %v, want nil", err) 54 } 55 m, err := jwt.NewMAC(handle) 56 if err != nil { 57 t.Errorf("jwt.NewMAC() err = %v, want nil", err) 58 } 59 compact, err := m.ComputeMACAndEncode(rawJWT) 60 if err != nil { 61 t.Errorf("m.ComputeMACAndEncode() err = %v, want nil", err) 62 } 63 validator, err := jwt.NewValidator(&jwt.ValidatorOpts{}) 64 if err != nil { 65 t.Errorf("jwt.NewValidator() err = %v, want nil", err) 66 } 67 if _, err := m.VerifyMACAndDecode(compact, validator); err != nil { 68 t.Errorf("m.VerifyMACAndDecode() err = %v, want nil", err) 69 } 70 71 // In two hours, VerifyMACAndDecode should fail with an expiration error. 72 inTwoHours := time.Now().Add(time.Hour * 2) 73 futureValidator, err := jwt.NewValidator(&jwt.ValidatorOpts{FixedNow: inTwoHours}) 74 if err != nil { 75 t.Errorf("jwt.NewValidator() err = %v, want nil", err) 76 } 77 _, futureError := m.VerifyMACAndDecode(compact, futureValidator) 78 if futureError == nil { 79 t.Errorf("m.VerifyMACAndDecode(compact, futureValidator) err = nil, want error") 80 } 81 if !jwt.IsExpirationErr(futureError) { 82 t.Errorf("jwt.IsExpirationErr(futureError) = false, want true") 83 } 84 }) 85 } 86} 87 88func TestJWTSignVerify(t *testing.T) { 89 expiresAt := time.Now().Add(time.Hour) 90 rawJWT, err := jwt.NewRawJWT(&jwt.RawJWTOptions{ 91 ExpiresAt: &expiresAt, 92 }) 93 if err != nil { 94 t.Errorf("jwt.NewRawJWT() err = %v, want nil", err) 95 } 96 for _, tc := range []templateTestCase{ 97 {tag: "JWT_ES256", template: jwt.ES256Template()}, 98 {tag: "JWT_ES384", template: jwt.ES384Template()}, 99 {tag: "JWT_ES512", template: jwt.ES512Template()}, 100 {tag: "JWT_ES256_RAW", template: jwt.RawES256Template()}, 101 {tag: "JWT_ES384_RAW", template: jwt.RawES384Template()}, 102 {tag: "JWT_ES512_RAW", template: jwt.RawES512Template()}, 103 {tag: "JWT_RS256_2048_R4", template: jwt.RS256_2048_F4_Key_Template()}, 104 {tag: "JWT_RS256_2048_R4_RAW", template: jwt.RawRS256_2048_F4_Key_Template()}, 105 {tag: "JWT_RS256_3072_R4", template: jwt.RS256_3072_F4_Key_Template()}, 106 {tag: "JWT_RS256_3072_R4_RAW", template: jwt.RawRS256_3072_F4_Key_Template()}, 107 {tag: "JWT_RS384_3072_R4", template: jwt.RS384_3072_F4_Key_Template()}, 108 {tag: "JWT_RS384_3072_R4_RAW", template: jwt.RawRS384_3072_F4_Key_Template()}, 109 {tag: "JWT_RS512_4096_R4", template: jwt.RS512_4096_F4_Key_Template()}, 110 {tag: "JWT_RS512_4096_R4_RAW", template: jwt.RawRS384_3072_F4_Key_Template()}, 111 {tag: "JWT_PS256_2048_R4", template: jwt.PS256_2048_F4_Key_Template()}, 112 {tag: "JWT_PS256_2048_R4_RAW", template: jwt.RawPS256_2048_F4_Key_Template()}, 113 {tag: "JWT_PS256_3072_R4", template: jwt.PS256_3072_F4_Key_Template()}, 114 {tag: "JWT_PS256_3072_R4_RAW", template: jwt.RawPS256_3072_F4_Key_Template()}, 115 {tag: "JWT_PS384_3072_R4", template: jwt.PS384_3072_F4_Key_Template()}, 116 {tag: "JWT_PS384_3072_R4_RAW", template: jwt.RawPS384_3072_F4_Key_Template()}, 117 {tag: "JWT_PS512_4096_R4", template: jwt.PS512_4096_F4_Key_Template()}, 118 {tag: "JWT_PS512_4096_R4_RAW", template: jwt.RawPS384_3072_F4_Key_Template()}, 119 } { 120 t.Run(tc.tag, func(t *testing.T) { 121 kh, err := keyset.NewHandle(tc.template) 122 if err != nil { 123 t.Errorf("keyset.NewHandle() err = %v, want nil", err) 124 } 125 signer, err := jwt.NewSigner(kh) 126 if err != nil { 127 t.Errorf("jwt.NewSigner() err = %v, want nil", err) 128 } 129 compact, err := signer.SignAndEncode(rawJWT) 130 if err != nil { 131 t.Errorf("signer.SignAndEncode() err = %v, want nil", err) 132 } 133 pubkh, err := kh.Public() 134 if err != nil { 135 t.Fatalf("key handle Public() err = %v, want nil", err) 136 } 137 verifier, err := jwt.NewVerifier(pubkh) 138 if err != nil { 139 t.Fatalf("jwt.NewVerifier() err = %v, want nil", err) 140 } 141 validator, err := jwt.NewValidator(&jwt.ValidatorOpts{}) 142 if err != nil { 143 t.Fatalf("jwt.NewValidator() err = %v, want nil", err) 144 } 145 if _, err := verifier.VerifyAndDecode(compact, validator); err != nil { 146 t.Errorf("verifier.VerifyAndDecode() err = %v, want nil", err) 147 } 148 149 // In two hours, VerifyAndDecode should fail with an expiration error. 150 inTwoHours := time.Now().Add(time.Hour * 2) 151 futureValidator, err := jwt.NewValidator(&jwt.ValidatorOpts{FixedNow: inTwoHours}) 152 if err != nil { 153 t.Errorf("jwt.NewValidator() err = %v, want nil", err) 154 } 155 _, futureError := verifier.VerifyAndDecode(compact, futureValidator) 156 if futureError == nil { 157 t.Errorf("verifier.VerifyAndDecode(compact, futureValidator) err = nil, want error") 158 } 159 if !jwt.IsExpirationErr(futureError) { 160 t.Errorf("jwt.IsExpirationErr(expirationError) = false, want true") 161 } 162 }) 163 } 164} 165