xref: /aosp_15_r20/external/tink/go/jwt/jwk_converter_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_test
18
19import (
20	"bytes"
21	"fmt"
22	"testing"
23
24	spb "google.golang.org/protobuf/types/known/structpb"
25	"github.com/google/go-cmp/cmp"
26	"google.golang.org/protobuf/proto"
27	"google.golang.org/protobuf/testing/protocmp"
28	"github.com/google/tink/go/jwt"
29	"github.com/google/tink/go/keyset"
30	"github.com/google/tink/go/testkeyset"
31	jepb "github.com/google/tink/go/proto/jwt_ecdsa_go_proto"
32	jrsppb "github.com/google/tink/go/proto/jwt_rsa_ssa_pkcs1_go_proto"
33	jrpsspb "github.com/google/tink/go/proto/jwt_rsa_ssa_pss_go_proto"
34	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
35)
36
37type jwkSetTestCase struct {
38	tag           string
39	jwkSet        string
40	privateKeyset string
41	publicKeyset  string
42}
43
44// synchronized with tests cases from JWK converter for C++
45var jwkSetTestCases = []jwkSetTestCase{
46	{
47		tag: "ES256",
48		jwkSet: `{
49			"keys":[{
50			"kty":"EC",
51			"crv":"P-256",
52			"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
53			"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
54			"use":"sig","alg":"ES256","key_ops":["verify"],
55			"kid":"EhuduQ"}]
56		}`,
57		privateKeyset: `{
58				"primaryKeyId": 303799737,
59				"key": [
60				{
61					"keyData": {
62					"typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey",
63					"value": "GiA2S/eedsXqu0DhnOlCJugsHugdpPaAGr/byxXXsZBiVRJGIiDuhGJiGeaQ/qeqt1daC2xZRarm4VEsmSHJUWJY9EHbvxogwO6uIxh8SkKOO8VjZXNRTteRcwCPE4/4JElKyaa0fcQQAQ==",
64					"keyMaterialType": "ASYMMETRIC_PRIVATE"
65					},
66					"status": "ENABLED",
67					"keyId": 303799737,
68					"outputPrefixType": "TINK"
69				}
70			]
71		}`,
72	},
73	{
74		tag: "ES384",
75		jwkSet: `{
76			"keys":[{"kty":"EC","crv":"P-384",
77			"x":"AEUCTkKhRDEgJ2pTiyPoSsIOERywrB2xjBDgUH8LLg0Ao9xT2SxKadxLdRFIr8Ll",
78			"y":"wQcqkI9pV66PJFmJVyZ7BsqvFaqoWT-jAFvYNjsgdvAIpyB3MHWXkxNhlPYcpEIf",
79			"use":"sig","alg":"ES384","key_ops":["verify"],"kid":"f-fUcw"}]
80		}`,
81		privateKeyset: `{
82			"primaryKeyId": 2145899635,
83			"key": [
84				{
85					"keyData": {
86						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey",
87						"value": "GjCfHcFYHsiwTcBCATSyjOyJ64iy4LGa4OuFaR9wZqkYTuYrY1I3ssxO4UK11j/IUe4SZiIwwQcqkI9pV66PJFmJVyZ7BsqvFaqoWT+jAFvYNjsgdvAIpyB3MHWXkxNhlPYcpEIfGjAARQJOQqFEMSAnalOLI+hKwg4RHLCsHbGMEOBQfwsuDQCj3FPZLEpp3Et1EUivwuUQAg==",
88						"keyMaterialType": "ASYMMETRIC_PRIVATE"
89					},
90					"status": "ENABLED",
91					"keyId": 2145899635,
92					"outputPrefixType": "TINK"
93				}
94			]
95		}`,
96	},
97	{
98		tag: "ES512",
99		jwkSet: `{
100			"keys":[{"kty":"EC","crv":"P-521",
101			"x":"AKRFrHHoTaFAO-d4sCOw78KyUlZijBgqfp2rXtkLZ_QQGLtDM2nScAilkryvw3c_4fM39CEygtSunFLI9xyUyE3m",
102			"y":"ANZK5JjTcNAKtezmXFvDSkrxdxPiuX2uPq6oR3M0pb2wqnfDL-nWeWcKb2nAOxYSyydsrZ98bxBL60lEr20x1Gc_",
103			"use":"sig","alg":"ES512","key_ops":["verify"],"kid":"WDqzeQ"}]
104		}`,
105		privateKeyset: `{
106			"primaryKeyId": 1480242041,
107			"key": [
108				{
109					"keyData": {
110						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey",
111						"value": "GkIBnhWq6UrOj8hKwGovjSsLT+dtAGlRqoIkQ2FzMeKxIApx0dT3O4yHrmi6v5sElZHM6BsLz47IopAOajVRYGh48b0SigEiQgDWSuSY03DQCrXs5lxbw0pK8XcT4rl9rj6uqEdzNKW9sKp3wy/p1nlnCm9pwDsWEssnbK2ffG8QS+tJRK9tMdRnPxpCAKRFrHHoTaFAO+d4sCOw78KyUlZijBgqfp2rXtkLZ/QQGLtDM2nScAilkryvw3c/4fM39CEygtSunFLI9xyUyE3mEAM=",
112						"keyMaterialType": "ASYMMETRIC_PRIVATE"
113					},
114					"status": "ENABLED",
115					"keyId": 1480242041,
116					"outputPrefixType": "TINK"
117				}
118			]
119		}`,
120	},
121	{
122		tag: "ES256_NO_KID",
123		jwkSet: `{
124			"keys":[{
125			"kty":"EC",
126			"crv":"P-256",
127			"x":"ytH8MlvqTx3X-eL0pdx4ULKUb2YOi2DPnIPpSaIk28M",
128			"y":"AO5TMe5lNcjJpuGjjGtHd4gX9POG9dh_vG-8ptp7HJs",
129			"use":"sig","alg":"ES256","key_ops":["verify"]}]
130		}`,
131		privateKeyset: `{
132			"primaryKeyId": 765975903,
133			"key": [
134				{
135					"keyData": {
136						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey",
137						"value": "GiCbUAItoAVleOSwYdPWs563CCFhGHSdX4t/C2xBY2J/ERJGIiAA7lMx7mU1yMmm4aOMa0d3iBf084b12H+8b7ym2nscmxogytH8MlvqTx3X+eL0pdx4ULKUb2YOi2DPnIPpSaIk28MQAQ==",
138						"keyMaterialType": "ASYMMETRIC_PRIVATE"
139					},
140					"status": "ENABLED",
141					"keyId": 765975903,
142					"outputPrefixType": "RAW"
143				}
144			]
145		}`,
146	},
147	{
148		tag: "multiple keys",
149		jwkSet: `{
150			"keys":[
151				{
152					"kty":"EC",
153					"crv":"P-256",
154					"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
155					"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
156					"use":"sig","alg":"ES256","key_ops":["verify"],
157					"kid":"EhuduQ"
158				},
159				{
160					"kty":"EC",
161					"crv":"P-384",
162					"x":"AEUCTkKhRDEgJ2pTiyPoSsIOERywrB2xjBDgUH8LLg0Ao9xT2SxKadxLdRFIr8Ll",
163					"y":"wQcqkI9pV66PJFmJVyZ7BsqvFaqoWT-jAFvYNjsgdvAIpyB3MHWXkxNhlPYcpEIf",
164					"use":"sig","alg":"ES384","key_ops":["verify"],
165					"kid":"f-fUcw"
166				}
167			]
168		}`,
169		privateKeyset: `{
170				"primaryKeyId": 303799737,
171				"key": [
172				{
173					"keyData": {
174					"typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey",
175					"value": "GiA2S/eedsXqu0DhnOlCJugsHugdpPaAGr/byxXXsZBiVRJGIiDuhGJiGeaQ/qeqt1daC2xZRarm4VEsmSHJUWJY9EHbvxogwO6uIxh8SkKOO8VjZXNRTteRcwCPE4/4JElKyaa0fcQQAQ==",
176					"keyMaterialType": "ASYMMETRIC_PRIVATE"
177					},
178					"status": "ENABLED",
179					"keyId": 303799737,
180					"outputPrefixType": "TINK"
181				},
182				{
183					"keyData": {
184						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey",
185						"value": "GjCfHcFYHsiwTcBCATSyjOyJ64iy4LGa4OuFaR9wZqkYTuYrY1I3ssxO4UK11j/IUe4SZiIwwQcqkI9pV66PJFmJVyZ7BsqvFaqoWT+jAFvYNjsgdvAIpyB3MHWXkxNhlPYcpEIfGjAARQJOQqFEMSAnalOLI+hKwg4RHLCsHbGMEOBQfwsuDQCj3FPZLEpp3Et1EUivwuUQAg==",
186						"keyMaterialType": "ASYMMETRIC_PRIVATE"
187					},
188					"status": "ENABLED",
189					"keyId": 2145899635,
190					"outputPrefixType": "TINK"
191				}
192			]
193		}`,
194	},
195	{
196		tag: "RS256",
197		jwkSet: `{
198			"keys":[{
199				"kty":"RSA",
200				"n": "vmUOa62TYrxj7N8rZVAzoEdSnmsRQaNWBMAdB8adGa8n4ycGiYWoGv0uZWc8vH2jn6l3Pa_72bb2IHf3-KD2UaTwLk1x3yShXybEoS5ZF9bemzrn2ohNixGoN7Ofj7wPb61Z-F1Nv53nq308z-RI1WeyIH-9HjuIcuUxaWY0VevsXzCehMJP5g7kVzyl55bYcRi28didkVazrzVgNG35yNNMEL32oW1Vfvvp7hfQHtxSwkFOPzJgzIPHbJFbxALGrrgXHsoq7UtDQdS9vvoEp4_JzQhCtnCEKahgkTwOWyT96OlRGYiPJSFHWTujy1Qnd6OKc8LGEspAX4oD6Zl-YQ",
201				"e":"AQAB",
202				"use":"sig",
203				"alg":"RS256",
204				"key_ops":["verify"],
205				"kid":"TCGiGw"
206			}]
207		}`,
208		privateKeyset: `{
209			"primaryKeyId":1277272603,
210			"key":[{
211				"keyData":{
212					"typeUrl":
213							"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PrivateKey",
214					"value":"QoABP3S5U0JiFQcqcMFT0Ysqk7FK2NunBCY9o+EAE+svaQi6zWQq2ODFoxB2NU9nqa3ZbhRiCdKNLz6o+jOTIpemKx8Gh/7GufRGLFAjjMchZYs3ripiTNSMaqXgm6ECt8DqrAZbMQ7D3Ha1vArcZG97pbE9t3m4M87zhLs3wPYd/kQ6gAEFPE2GLD5ai8VYd/Q0ePZR0ttLgkJ/2yIig5T8YyJaoZEPjK+v3zVFQuGguJApnl2tC0S7OqOtqsDZ5Dux0H3Cx85FLeyB2STHlXtq9GUGI2VrC/TP3OASc6ap75WMKZRpowEVaip8wWehAOL+VIgTajiFf0yXdSodc4ZjJKreiTKAAd6ahHQiVJapNKY6XANgA+JmluAWq/Fk1LmEnTybWVelcODbppwIvhJ6Xuz6kjuEhhxsUtkPO4vuZJfEF8DWAH5L/FHjJpgP3NnDoNVzGOL5w8SdgIfgCS0UqBLSv2/KhlIEijuL9NYaqydN1cPcjdeadSMcDSIwKjNASRVaPZDJKoABx1/CfOqCbE8eh450YvGwYvII+ro8tR+uusnt2QuQZux3wvl9eto9Dr+5Iq/0bKqpMMgvYHIT+mlkgK6SYLcynZx+SYMAtbixa0nH1lJnnBodOJS6zdMRTcFkpI4g/CbCvzTp5gF5EkfBSbVToVLqICydokKnTvNK6chX3MEUjskigAH0eGwQwn174yJzJTUWH4cRxDredI6LkjADm/ikza76AHT8qRJHJkmwSXL88p3M2bYFN+g9Z/FTL21Ylc0mxn/iII3vabfZWZTWK9QGR7YjAicFyLDeu/ZccCkCXgTFzqqlZ7w4Sv05hWz57xxm81JyxftzapeflfAmjRircFXG2RqAAgub/Z28+SFSf6zSPFMKiYVWx//DI0ubbiuuu65tUse9xYq9JtHEobgYk0dJXNuY9RzPkGblZ8/SD06yRf9l8DMRAbivDfgXY5QZ2PBDk1jn6A2y0S+i80h9MILJ+/sfkljiyvtBFDQwiI9tPOOnxbWmg6bl5xYUdvjbhxBoVB1fgOtAid6gGuLstbf8ycV+DkaWg3mo4054ge9BBT4eWKGC/LHctSaQ/OBs5cbGW+UqZxIjSN9YeOTkbvNKO4l4jGTg0BUBPB3GH8KQPtE4sbBhUDyjYYgAZZcSaRq7AfhLUkiDSfIVcKAIoEOaTS63vf2BQlbW8/HuNlWNUX0M+hkSigIiAwEAARqAAr5lDmutk2K8Y+zfK2VQM6BHUp5rEUGjVgTAHQfGnRmvJ+MnBomFqBr9LmVnPLx9o5+pdz2v+9m29iB39/ig9lGk8C5Ncd8koV8mxKEuWRfW3ps659qITYsRqDezn4+8D2+tWfhdTb+d56t9PM/kSNVnsiB/vR47iHLlMWlmNFXr7F8wnoTCT+YO5Fc8peeW2HEYtvHYnZFWs681YDRt+cjTTBC99qFtVX776e4X0B7cUsJBTj8yYMyDx2yRW8QCxq64Fx7KKu1LQ0HUvb76BKePyc0IQrZwhCmoYJE8Dlsk/ejpURmIjyUhR1k7o8tUJ3ejinPCxhLKQF+KA+mZfmEQAQ==",
215					"keyMaterialType":"ASYMMETRIC_PRIVATE"
216				},
217				"status":"ENABLED",
218				"keyId":1277272603,
219				"outputPrefixType":"TINK"
220			}]
221		}`,
222	},
223	{
224		tag: "RS384",
225		jwkSet: `{
226			"keys":[{
227				"kty":"RSA",
228				"n":"AI83_8Uy0v4xS6kDZKqcqzSbeyksy2C67ajtI41J2KMDtO9jUaEAQ9uDhMubjZzPYh1wf_gtJgAC5PSiI3fOLUG0AHCbi_yXVfH3_1U_Yl4b_e8yx_NPyuIvwHwXwE5a32hiss9PuY2-qEivH5LK4AXxPiTiUc9x4gh1OwZaSTYWT7SRO-0ROwYwCwpg4Uf0IMLtmHou_NmNw0uOlOgKfx-EFmMzV-5pspEnwsHq_ijFSxmHNAdy5S0n4u1LIKKmgXJIyUu3AKfAJMydn6nTKzrOcpX0yMnxPq9yP8xKuK_mXysFyNvmS0Sq5c-grOETFeMFScweoUpWVnYOCCSyZ93yAhsTUWnDjZd7iuji9Y7zUo4PWlKXyRRz_aSpxrsn70LOZNLLUjILVeyfCRs2JXptfxCNg3wg6FVAH0xTORmPGICgWDmwOFgP1Y6tW-p0cnK8LwVkuRclyKAMvTtYm9xZZHUSjw86rHEnB2VfsPTIn0_WAVnJ2OAKhuVMtwjB7Q",
229				"e":"AQAB",
230				"use":"sig",
231				"alg":"RS384",
232				"key_ops":["verify"],
233				"kid":"FVLRIg"
234			}]
235		}`,
236		privateKeyset: `{
237			"primaryKeyId":357749026,
238			"key":[{
239				"keyData":{
240					"typeUrl":
241							"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PrivateKey",
242					"value":"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",
243					"keyMaterialType":"ASYMMETRIC_PRIVATE"
244				},
245				"status":"ENABLED",
246				"keyId":357749026,
247				"outputPrefixType":"TINK"
248			}]
249		}`,
250	},
251	{
252		tag: "RS512",
253		jwkSet: `{
254			"keys":[{
255				"kty":"RSA",
256				"n":"AKZtuHAGYy-1Mc78sdp1gOV3jMCJtO7NmhyLSproWcBnqSN1g9mB2EdB22-WLWhB_U_JlZRCdHT6CxPHSid0c9JJc-2CmiV9zU2sVTJUkCytOVS0hrcPEz5JK6a6VVy-Skc_1-I0D2YurXd0aRByDALC8heHMok6VQXW8qwHgRyc0Jr1RcbY-CF_SMlRXn88g4e3bnk1AJiPcmHsJOcwkanwlWxq46DxPv5ff0ruXN4gPDYU-6_J6yZJreYjwrl-LhkqzOkz6e-LE4sdI5WFJQR9cGGRMf4ktgF3kqFtcFNFkGtdOvw5MdLe0eaENDzZ8TZyQDgiHYl878x8uPPpmoeif5af_ZUAsrv_bV-h3RpSoTdTP4SlQMmP-3y2R2LxvUs_CiUahoVFwTt_bRHO0Qy-QwpTvAdJX8CzrK2auqycFawYm8xYjj_epTFSwBCJuZjamxpZSa29zTDqP4AXwt2-9LO-70j5muzDQL35czpBgaXSAEJkrM9du91OjkJ2vtYFVLjWougN5uVpEBx1Isk_KgreOgl3lF1vs2EjTuihaxJhM-17alJLmDL06ZEDsht2Uhu_ZExEfPwTKaR_-kfjlamuoLUvTtVhzNZuOHD_XAOrGafMjM9WVq_D5XjqF7WFnb_t4YIOQNmGeOeIFLb4LlR5nHB1HIHUpAWazrvl",
257				"e":"AQAB",
258				"use":"sig",
259				"alg":"RS512",
260				"key_ops":["verify"],
261				"kid":"fVf-Qw"
262			}]
263		}`,
264		privateKeyset: `{
265			"primaryKeyId":2102918723,
266			"key":[{
267				"keyData":{
268					"typeUrl":
269							"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PrivateKey",
270					"value":"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",
271					"keyMaterialType":"ASYMMETRIC_PRIVATE"
272				},
273				"status":"ENABLED",
274				"keyId":2102918723,
275				"outputPrefixType":"TINK"
276			}]
277		}`,
278	},
279	{
280		tag: "RS256_NO_KID",
281		jwkSet: `{
282			"keys":[{
283				"kty":"RSA",
284				"n":"AImrUP3PDttint7alBxKexY-Oe4nCj0TOZ06yuKgq7UQu-3Gc8KJyQHO5SzPlMBy6FjcWqOzz-kkNm9sej3AsdGhTJCcOCYDoLgArYCaMQoMLOOjMQJTVbHeiPpyVgHzvpG9Xw_IVNPbRJhsT4mzqHuyopUEEexVQcFo6F3U8zE1kppxzoMvIiz5-Zm6dFX8EozolMD2TLDh4NZFAb-6uJs8TYzS8Od6V0BVh1CfHL1CuIpvIirkgki2RGXNE1r57bhJfMZUWtqAUXb5SM2IFhLUcgGLV-PfxP2cxcJ7HHhk5-lFf5794CmqcFa4mliR2tJRnhUR2vmlgxqUjzwK3HE",
285				"e":"AQAB",
286				"use":"sig",
287				"alg":"RS256",
288				"key_ops":["verify"]
289			}]
290		}`,
291		privateKeyset: `{
292			"primaryKeyId":234505441,
293			"key":[{
294				"keyData":{
295					"typeUrl":
296							"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PrivateKey",
297					"value":"EosCEAEagQIAiatQ/c8O22Ke3tqUHEp7Fj457icKPRM5nTrK4qCrtRC77cZzwonJAc7lLM+UwHLoWNxao7PP6SQ2b2x6PcCx0aFMkJw4JgOguACtgJoxCgws46MxAlNVsd6I+nJWAfO+kb1fD8hU09tEmGxPibOoe7KilQQR7FVBwWjoXdTzMTWSmnHOgy8iLPn5mbp0VfwSjOiUwPZMsOHg1kUBv7q4mzxNjNLw53pXQFWHUJ8cvUK4im8iKuSCSLZEZc0TWvntuEl8xlRa2oBRdvlIzYgWEtRyAYtX49/E/ZzFwnsceGTn6UV/nv3gKapwVriaWJHa0lGeFRHa+aWDGpSPPArccSIDAQABGoACOgE5vcbpLpxt7d3Qu97R37xWMja2xKb+BnZIF5a04jRryjJsgdIGJEHlI61Osot3xEEL25+egU/ls6rUEoLHKVk55lA8BCBRLlXyxJWzBdW9cChJNP6hw7DMrCFShb4KVGOi0waIXz8qtsIj/RP6cCwC/qBZYOdHLlOiXC6mTNv0blQ2Cb9yfZZ1Lz855DH0l2/GMdZYXwb6JElM+u/vR7lxTp4Wc6kq/31PULDH7G+Ps+QpXxHMIqghgSWyRsJ9+SHv5yo7JxA58eTQEUXkI6RCJJQ3pSXjdveBzzPyN6ZCmjz91Np3oPh36dZtknW0UspZ6Jnpc5GLphkvG8GblSKBAQC/vcua6r6FGW0VO2yD93nWgX1qepmULYGw7lv+mfOvodPUr+8EqDZXaRzUqCHynhVfb1BDEsoxP9aLoPVFZoJbL1MqBnUx6X0FXoKu2FzqsEJYw2qnl4VLhFn7xebnR+vwv+MMYf+yvnIdcMfmrZhWmCS4hTFQlJDfxji2SPSdByqBAQC3znfJnB2xC7eDUCTSH49h/xW1YWaS6nTqXvk3LJeq4tX2WGBWxfCLh6xpNpzF31xCDdYlt+yGcy6UUBKr4TteePrWf6jY9TWJZO7FvAqIIIxaQv3a/0A4/sgzYcrr2ansWzhNtfCESxOaPFVfLE1wh/PpJBzbcltRbG/mEY3UxzKBAQCfvXhN5Pm6m1c0lCAwxVE88v5QYjlmqI7en4YG062gCbsX+0au45D6O7joNfaqUSdPLcZ5SsMmSp/sDbmpCuDZJNEtNtoWLgaZHYbUMa8fWp67onpNiz9ija4Fwnc/Ab1AAi0fGNnUyTL68gWoWcGLiw80pspR7qPPui1vN9KKqzqAASl2qg8Q6KHHwt4cdjHwbKfuozcHgdwih71XL2EC7jPed+XaieEJRfoz4PDbIQKCII3GEUjw9Kpf0WIjrhKX/IyTPgKlSbGnnywfWL3CbZ3HueGiuyFr81DoKMFujhgmQe7PpSPipx8w0Hs6oQeXNuDryloNi3T1lyQHEjcUPqqBQoABcIm6r6QyTlBactKBKEqyhkXF1tCvw7YR9herJoubM/xklWzU5J8bgSQ1h4dutlANutXFqeOInUufyPChP3inQhcirp3CccJFaMP9uevRMMhUxyOyQkpOfxnAe7hvCjRsDDZZqh5bi5siNzeIEnU1s7sq/0XvzZA7G5fGZgb+dZs=",
298					"keyMaterialType":"ASYMMETRIC_PRIVATE"
299				},
300				"status":"ENABLED",
301				"keyId":234505441,
302				"outputPrefixType":"RAW"
303			}]
304		}`,
305	},
306	{
307		tag: "PS256",
308		jwkSet: `{
309		"keys":[{
310			"kty":"RSA",
311			"n":"0JqDlgy_KaDpCWhaB95cKdLsyBGCbh865tHHK3LM1Iv5qlt4eqO9n2Bn5R5_ZHrMEGvVoBmwpkfnWmaMxqZg-69k8id0dN4PKeBuIYeO5C2IE3D0uO1UWzsPi4XHtXf3CYmwYOUHJ5DT8q_jgMXYCefys4OvYkRcfSpWVvFtF1PzBSijQaxDQUx0rdJvi0JZTQOXHl4MwgzrFoERTdZswAXh21MK1Uav68Aa_Z8TZU3R_qY-TX78qhBCv8T_1wrooprF_xaJqpywXktUnQxVgu-aG6-yooqrICvobc_LHdF_8R-Qp2pYfsHSmPDSKu-5JqyyIIoxfXpLdUsrDl4HDw",
312			"e":"AQAB",
313			"use":"sig",
314			"alg":"PS256",
315			"key_ops":["verify"],
316			"kid":"a4D_hA"
317			}]
318		}`,
319		privateKeyset: `{
320			"primaryKeyId": 1803616132,
321			"key": [
322				{
323					"keyData": {
324						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtRsaSsaPssPrivateKey",
325						"value": "QoABPzsxHq7K5f91YucwaXUDk7ERgE8pqLSc8w34gEnc/wo5vk0BamvQaWRVQQdzEfK+eqVbrHmWi5mhY9QXpOv0dhuhyvo8ZS0ya60cT6DYSu2LBLDHFa68Wp6SWbIwFN4X5uGC8DYvWpJU9PCYg6XUu67T37FhGFekGHTSXDLf9Ko6gAFm7TJOM/v8MbHkCpY5NTtda7fb09XBXFDSC2XFGKvOkfQrGEKdEAvOCffpTBHsyvZAEJag/p2OZ+4W2D3upPNFkrmtS9MSGU39o0kn2fd6Cw90w5S1gjfxgWDbZpzs4AvbpU436Zy2wZYjJSIG6xbjDuYwizrflPX/sq5GUpuCuTKAAW+ovScT/DR/doxZm+xykUTTfEr2W4pd5PpLQiI1gUA2UTnY6p0svW+IbbSaj6vTE8s6+STsTGYAteUgdFBo7Ao501XbAJpJQX4ONI6o66BUvvzy0S6VLs+YQ6MWpArvNnnzRo5NbznO6IESyumWNm+8HQMaJ12sAqpWOoH4bz1xKoAB02eSVf5ZSDiYa4uF85NvvAVvEVPOPAd2gOqXzOWH+AXtTHJ8n/gcvUMnFR3W7cdZdyY2HslV0qphvkL7mCwsoOUBH5dA+F10Ebmk4hU9XEkeQvgFVgffzyqKjG521WOnAXQXudhOkJgXqGoTB/fESyRvSqA7ZKwPL1dvZnpJRv8igAH8m64q3qJFFcHWsnUb3hS58BXm8aTuk8Reju8XDXjBa9DPy5UySS0P/Chyh8HF5PAIwWSXTYDtFvdve3UN28oxTzhZ1xsz86BOeF2lFHpZ1y8/uNzwLRTIYWCXhbAS+bGpQOUR4JJDjSyivJCBqrkMCDUWAXQSqIZzHnyD+wbP8RqAAkukY+fCuoTpXOd06ASnbIsb+ZF4y++LsoulcQ//wmemVEOihJcQDgAfcL0j6HTylFG2EJJMDoLVWv6sZgrYpR1O1g97IB8KsLvyLm1JHxb9rbTDBnKSWL72NSZWPfs/Q5y5SXRxSD1gJoL/pcL5uuOosJjIvQ2olVMryYAgbnsA5UHZP7N8YpX0njZxBl9/PFNrTkWBMr15+A0VqOGh0TGnE/D4iAAduMJn1f4a3ZYVC4FgxKVxLxkB3oOLZz+QXKvs61slwRjotY3BXoKeImedOFmZoOJCA9qD+9rT01mQ113Fi9ylkBD1VGqtvIoB1CZa4tZZkRyoAeIMU7vMUpESigIiAwEAARqAAtCag5YMvymg6QloWgfeXCnS7MgRgm4fOubRxytyzNSL+apbeHqjvZ9gZ+Uef2R6zBBr1aAZsKZH51pmjMamYPuvZPIndHTeDyngbiGHjuQtiBNw9LjtVFs7D4uFx7V39wmJsGDlByeQ0/Kv44DF2Ann8rODr2JEXH0qVlbxbRdT8wUoo0GsQ0FMdK3Sb4tCWU0Dlx5eDMIM6xaBEU3WbMAF4dtTCtVGr+vAGv2fE2VN0f6mPk1+/KoQQr/E/9cK6KKaxf8WiaqcsF5LVJ0MVYLvmhuvsqKKqyAr6G3Pyx3Rf/EfkKdqWH7B0pjw0irvuSassiCKMX16S3VLKw5eBw8QAQ==",
326						"keyMaterialType": "ASYMMETRIC_PRIVATE"
327					},
328					"status": "ENABLED",
329					"keyId": 1803616132,
330					"outputPrefixType": "TINK"
331				}
332			]
333		}`,
334	},
335	{
336		tag: "PS384",
337		jwkSet: `{
338			 "keys":[{
339				 "kty":"RSA",
340				 "n":"rMnTRrTk3zWf0ZqukmshN9GH9UsCcD0a2WlmO-0q7x_k31JIe2wtqhlQRwszfuOJmL5M4cpsvkDBT8th5yDqzzHMJRAs61Jq6ACNepj3_0hK8GszxiyxFQL3msxmu8e3F14M-V35n9aLr0meRHk9tzm968-wvp7I_IXlv1hbzHejh_gD14gy-GjdiJYGwg1oWINL6YzSv5DISxIAv9HLu5fmBLtoVyvU9iZLHfUJdq3Rlj5iCBUEFMJVb68PfWiB_xoA7nj3vpgAfGjDzQ62bVrVaOHOg2I4X2OxJBWJ8uFw6RRocpAfD_lEZBet-w6FaMHXh_iVwxPWNuNTbVHlerfdUHTMHO2jCR1JKKkI5px7aVM7fQUVtYSBk754LINhShkMCO9o--k7sZOFL_VohaCHtE9fRxIM5MYOKPyvPTf38EyCrAqreFd4ol0FCPea8n89BwV371GrXgP5C_9BdoG2uY6rxRwTzMNiLxzxWpkvlprNRxAsdRSZPEzKOI_t",
341				 "e":"AQAB",
342				 "use":"sig",
343				 "alg":"PS384",
344				 "key_ops":["verify"],
345				 "kid":"LFa3bw"
346			 }]
347		}`,
348		privateKeyset: `{
349			"primaryKeyId": 743880559,
350			"key": [
351				{
352					"keyData": {
353						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtRsaSsaPssPrivateKey",
354						"value": "QsABGgBRiQlPP7T0l7qjag22t5qPSbLa/PkaEnEatcxTqtJ18qo9ncTqNa7Ts851twenilUdELx+HLARFmRtmYcJuanBNMIrJ4ua/I0+rWY2rU/NwxB39x3SglT2T/wvwOx0fZAhXPNqgF6m2aGLMsppgDN6TKrvWZdC8YTC1e+ZoDlq4miBuU+NEOOsrS6Zv0SW/ZI5OxUqvGqQwaaiiy0VCsIzpJjO8GkaPntCYnA6Z1MNZTREOUcncMg2MsPEmYslOsABxBOOesQfs2aiCmt50XjN9bUvTlu/Z9z6/k327kwLpWloxZuzZWz1LMpbchnmrNvl8uj+N8qSvaIk6/Gq2y6w5TtDEdELZuuNcCkUqnnOaUJyVqkZ10PwILL0Ig+tt4GSIGlEFmdt1cL9tdU8Za/IQTkYzDQG11iG6h6llYPmj4aJxeDc/wnon5dT1pMuW93uFygwXpSkYMIvzDBQys6sUGtRbPVjNRsndRVl9w8oiF5wvEeLMtAMpAUgFxmXdC5JMsABHN4zpQrc8qsuYZa57/5gCmi4qGhECQNdsJlu7YjqjScBcRQZEK5F4pUZl2lY4zGQlClRnXUgx/g6F9FGW/ENnHebfYQ63eg2wL/EqvWBujDdYjYvs1oUBXcMFSG66VAkOYkkS8a8JnQpOfEPCkvo4/Hmz32YXjExEZWe450v8KhE4JYsaEolyoH/EoDAfG++NoIfUR6A+slyXqeQlnWK8+GMitoLKaN6EMdc31YeVsioEhn/rFfzd7p5FlLbjqBJKsABzisQA/QhytqNUWQhnhYFSs9QF+Z10ZCuUxwaSZKmD8SV4JTiHcMy7LK7RGt3Btlf76HmTNVOtTTsjXbBftVv4HDNamPmtzg1ggZi05cjPYi3STFZu3lUVAv2tJP5gdjuMe7slW+MqECUfPyz7OkJRBVAPQl0fbH/FSeSb529H6R+/1uXQ9nmXmikUFEt5PvY77li7Qyb6p67B1krBQusW0Lk2SL1Fs8Y8bj/lkjJar86sxGIGl2JNfSwajyK/waJIsAB1o1XIXWE82dw1r/TmkhY+bF4vvApYMYSz7lhsK5shZcY6VeQMXNUY/SCMTTndHzUNmbwdi4NCbnNt/vEOvmZnvQ2Q3YNphd6BLfeZxEmBcPzUMDTKXNaZBLbe8j1HUtaOHoaCfVuLhxxDT8knntNZNIJNuGhAK8YweR96qKQSDyL1zZRXBqnPZlGNnVCDVx0ijMmAmAY43IC5/XCR5h03TwbiJTQ5tG3FImoSXqA7RmwTSr1ynR4EKmRWt34uiVFGoADF4o9gu4FGlXDarpwmxkGQwUESUpJUEI65LDD0Vk71q0ZMMWUg2AXDov5UFx5zQkxx0Hx1ncN/pNy4qyaL3NgGg82OTxtajflwarFm5S4gKp4Ly3jtVWEYJDxa8D6JA4O5xuUl+qSJhEEIcLdUYXU/x/aPISklyupxSF2ze07QG1yNYV3/IadLxOWTtPlos1R0HE+x9g8JAYVC4kt2fQ6ldmZaD6h9fJORqSr6i5mdikzGw1vrJs0XaGmIxuN+C9jAS031tkD15BgK9vd6wrlT9d5C/KDJT7zJShYnNTJ2E9vRXBby7AaiOGjeRx/E67oPzdWH/8qwsLNfkS4eYLT9nbwmIMQ7pWVxcatnWKzuQuYLpCR/O2iJlaSoO76Xuy8RklES38lB2+FNzHuHtN2xAPms74WAUX+dLrIlcA7ceWwUqeF8iyXL9vmCuMmd5kHZGxUJbzVpLOkRUdcDNtc1qXm8qufzWABOUtzVnkn1CuejH/Xv9IpbuCHhQEv8o4REooDIgMBAAEagAOsydNGtOTfNZ/Rmq6SayE30Yf1SwJwPRrZaWY77SrvH+TfUkh7bC2qGVBHCzN+44mYvkzhymy+QMFPy2HnIOrPMcwlECzrUmroAI16mPf/SErwazPGLLEVAveazGa7x7cXXgz5Xfmf1ouvSZ5EeT23Ob3rz7C+nsj8heW/WFvMd6OH+APXiDL4aN2IlgbCDWhYg0vpjNK/kMhLEgC/0cu7l+YEu2hXK9T2Jksd9Ql2rdGWPmIIFQQUwlVvrw99aIH/GgDuePe+mAB8aMPNDrZtWtVo4c6DYjhfY7EkFYny4XDpFGhykB8P+URkF637DoVowdeH+JXDE9Y241NtUeV6t91QdMwc7aMJHUkoqQjmnHtpUzt9BRW1hIGTvngsg2FKGQwI72j76Tuxk4Uv9WiFoIe0T19HEgzkxg4o/K89N/fwTIKsCqt4V3iiXQUI95ryfz0HBXfvUateA/kL/0F2gba5jqvFHBPMw2IvHPFamS+Wms1HECx1FJk8TMo4j+0QAg==",
355						"keyMaterialType": "ASYMMETRIC_PRIVATE"
356					},
357					"status": "ENABLED",
358					"keyId": 743880559,
359					"outputPrefixType": "TINK"
360				}
361			]
362		}`,
363	},
364	{
365		tag: "PS512",
366		jwkSet: `{
367			"keys":[{
368				"kty":"RSA",
369				"n":"ubM3lgyGn8IyKO-56q18hvuJkkxPrDXgalRWNmnA3QEseglU_9tp598dlq04eF1G4Xkrmk9OVyVSCuRdvMoko6wP4Jum-3cn42_Gsk8PdTwm3WD-yEBg_Usa_omLGiTfktyqqoZhh1TeOOBtNpD1U_p1wQxP3-bLl4__uR75CqlK9FYdBrIuqLP3nqa3_OAFuPBX77BuD1kcr5pUxPZkXBNAWpnvsW56swyIMZF2GRhfv2n2bZJgT4iybQcmEnvt1wfY3ecO5ZMSX2QNKpnRRejlIEqR9uAQa4wIJMViL8jDbAV-ZvUjMM1G0aAyMHPQzb2Hfkr9OtEi-_xyUCwqF2IUZfUb0-mCjOutpbBlSfkYULOrwd9RQTaLeNe3GhRjYWTJ-gLDS8DUWz8AcpCI7xoQSfuZLmBwxslqsObMYolxQJXej1IDmGX-Rjr4ro80EpMkv67gxYQwjP8p7FMHfK7FSDZMtT-h4mO7AD68vwHd99c9ALDJfPO7tAMG53opzD7YEZU-ySKRcMBIFRe5Kxj-m1fbN9q2ictzoQOvKh8TBlCsPLRbF5WVheUtE9anKiIik5zQInihoZidH5YJksdipMVWLeRs1Qk5J8ddv7n2dlbW7zoC60sh3ubLQ_MDm-eHlXoeKGioCMjDABRdokqal4wugvQUZyQcBBtfWT0",
370				"e":"AQAB",
371				"use":"sig",
372				"alg":"PS512",
373				"key_ops":["verify"],
374				"kid":"L-LcIw"
375			 }]
376		}`,
377		privateKeyset: `{
378			"primaryKeyId": 803396643,
379			"key": [
380				{
381					"keyData": {
382						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtRsaSsaPssPrivateKey",
383						"value": "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",
384						"keyMaterialType": "ASYMMETRIC_PRIVATE"
385					},
386					"status": "ENABLED",
387					"keyId": 803396643,
388					"outputPrefixType": "TINK"
389				}
390			]
391		}`,
392	},
393	{
394		tag: "PS256_NO_KID",
395		jwkSet: `{
396		"keys":[{
397			"kty":"RSA",
398			"n":"rzu_DRFtzFpMUy-tXC98YxtyASy-3hVtM1X9KiwAoahSfd7VfzIlIXcbn3VewkZBtKGC98sGQJSQWA-EagOjMDua4rAGVCZ9Cj011Mxy1e2j6w7qRCudtWaMormfMpP6n2ht61HkZkQDZIlbdRvr20Glf2KWgd8KgSoEZKS7AjIHvoGbJCU7A7ajbONyKuicrYq1XYs4b1dYSqQ4VIZaei5NQM7_tddYJl-lSKN3mLEPhdWKHWf1rVfDbJNobAbqN7C70rUKJS3DZkwo-q3-QOoZleJXKTXurdRAhT66nfa-1f7idmIO37LwReX8zrgDWmMZPZ2mpfA86dIlkkk89Q",
399			"e":"AQAB",
400			"use":"sig",
401			"alg":"PS256",
402			"key_ops":["verify"]
403			}]
404		}`,
405		privateKeyset: `{
406			"primaryKeyId": 1629784556,
407			"key": [
408				{
409					"keyData": {
410						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtRsaSsaPssPrivateKey",
411						"value": "QoABP9TTJpZ3lfj28Zh9hqHMNydjyJGup+Q8xjYubqsE+E3AlnSIvRDp9r0VVHZzsHBEdKtQQgCW4FT0I7Cy4z4W3ecKskuJWFYYn0PYOXLZoFo2MF3yZ0wI04aWhRS2+Zwl3BSr1eu84jiCm9rTsODyZ0MQORvpeBVaX9Y2IOPclvQ6gAGBpXDhI/1yKJq6vlymUBwKS2FG9Tf3as3YkH2B0b7wtv1Ir+WEa78ub52BwxnOKsf3V57WLnuQppLiw/bvHFxKVDNuWGiGTzEVhJW2qK3RgryXtqzkACm6cjL1FT22B9VmVx/GqWOOOLX4He1pq+UYkboWgXVkAdP0OaPv2hWIMTKAASnEMbcFq+ZbOJIJBwZXsSmrdSnfg8A2kwuatK2U2Of7/YCE5i11CUjWUvi99plk8g/mAinYu0Gfw6YSRgbWsAvK4GsIJ4322WT1yy4g6XuncL8MKC2rCYIkhFWpI1qcsS/PxU3zWMYodV6GjK31HXvqczlJfBYNEBo9HxeYDtchKoAB0vRt2QsYTMSVYw1gIDeKdHnhMDaakaIazjc4o+DCQSk+dU0EStSn8GHON0nIrEA8A5UHqF8/yh1mW+M0mkSaSiBp+7CLAowEu72wgdrymK/e6eIELH+joEDDgWpcF/WMEWSvls2a0q1atiYvC2ERLuSxSFjoJ8IRKVfVmjPi53EigAHUpqb3E/I863RAT2ocS5CnT7A8PBgttZqIyR1H8iC2bocre8H+8z8fVf4SeYsLhqvuBcTPXxZSUT+ZVf+LeELfmcd54savTU/yTQJ27s8WIkuLeTj+80FWCVtengLwP+Bte7nyzqbuXSWHUTUSVTCMK5PiBdWrOElVYlp3JxvTxRqAAgNrTEVGQYjy+xnFbKHHmGr7olwVAi1lqCGQDDZKMQH2fZOQqURH13MhdpPEL8LlKYuLejl5B+hzLaTWOqxx4TmD9Df3nMwAC0ELpDUAfz4e2quvuRD28+cR9u0G560ON53sJPbqPGVlbtaDmpn8nzvCOmczpoGmtzcBeZ/4GeEHThzq1sRE+tBJ6B4oS8R4LUtldg+FBUnZgqJvSC1gYYHO7oySCPC5V0R3EhpWDcVbYf7PyMC7oaxIPmCAu5Wc4DFirh13BAZI2FKW+Np/heZAjYUKa4Gtb0dMxvLwz3OcPPa/AQKSjko6aMRAQvjgd/UgQ+Sr496td45I4JGandESigIiAwEAARqAAq87vw0RbcxaTFMvrVwvfGMbcgEsvt4VbTNV/SosAKGoUn3e1X8yJSF3G591XsJGQbShgvfLBkCUkFgPhGoDozA7muKwBlQmfQo9NdTMctXto+sO6kQrnbVmjKK5nzKT+p9obetR5GZEA2SJW3Ub69tBpX9iloHfCoEqBGSkuwIyB76BmyQlOwO2o2zjcironK2KtV2LOG9XWEqkOFSGWnouTUDO/7XXWCZfpUijd5ixD4XVih1n9a1Xw2yTaGwG6jewu9K1CiUtw2ZMKPqt/kDqGZXiVyk17q3UQIU+up32vtX+4nZiDt+y8EXl/M64A1pjGT2dpqXwPOnSJZJJPPUQAQ==",
412						"keyMaterialType": "ASYMMETRIC_PRIVATE"
413					},
414					"status": "ENABLED",
415					"keyId": 1629784556,
416					"outputPrefixType": "RAW"
417				}
418			]
419		}`,
420	},
421}
422
423func TestToPublicKeysetHandle(t *testing.T) {
424	for _, tc := range jwkSetTestCases {
425		t.Run(tc.tag, func(t *testing.T) {
426			ks, err := jwt.JWKSetToPublicKeysetHandle([]byte(tc.jwkSet))
427			if err != nil {
428				t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
429			}
430			jwkSet, err := jwt.JWKSetFromPublicKeysetHandle(ks)
431			if err != nil {
432				t.Fatalf("jwt.JWKSetFromPublicKeysetHandle() err = %v, want nil", err)
433			}
434			want := &spb.Struct{}
435			if err := want.UnmarshalJSON([]byte(tc.jwkSet)); err != nil {
436				t.Fatalf("want.UnmarshalJSON() err = %v, want nil", err)
437			}
438			got := &spb.Struct{}
439			if err := got.UnmarshalJSON(jwkSet); err != nil {
440				t.Fatalf("got.UnmarshalJSON() err = %v, want nil", err)
441			}
442			if !cmp.Equal(want, got, protocmp.Transform()) {
443				t.Errorf("mismatch in jwk sets: diff (-want,+got): %v", cmp.Diff(want, got, protocmp.Transform()))
444			}
445		})
446	}
447}
448
449func createKeysetHandle(key string) (*keyset.Handle, error) {
450	ks, err := keyset.NewJSONReader(bytes.NewReader([]byte(key))).Read()
451	if err != nil {
452		return nil, fmt.Errorf("keyset.NewJSONReader().Read() err = %v, want nil", err)
453	}
454	return testkeyset.NewHandle(ks)
455}
456
457func TestJWKSetToPublicKeysetHandleVerifyValidJWT(t *testing.T) {
458	rawJWT, err := jwt.NewRawJWT(&jwt.RawJWTOptions{WithoutExpiration: true})
459	if err != nil {
460		t.Fatalf("jwt.NewRawJWT() err = %v, want nil", err)
461	}
462	validator, err := jwt.NewValidator(&jwt.ValidatorOpts{AllowMissingExpiration: true})
463	if err != nil {
464		t.Fatalf("jwt.NewValidator() err = %v, want nil", err)
465	}
466	for _, tc := range jwkSetTestCases {
467		t.Run(tc.tag, func(t *testing.T) {
468			privateHandle, err := createKeysetHandle(tc.privateKeyset)
469			if err != nil {
470				t.Fatalf("createKeysetHandle() err = %v, want nil", err)
471			}
472			signer, err := jwt.NewSigner(privateHandle)
473			if err != nil {
474				t.Fatalf("jwt.NewSigner() err = %v, want nil", err)
475			}
476			compact, err := signer.SignAndEncode(rawJWT)
477			if err != nil {
478				t.Fatalf("signer.SignAndEncode() err = %v, want nil", err)
479			}
480			pubHandle, err := jwt.JWKSetToPublicKeysetHandle([]byte(tc.jwkSet))
481			if err != nil {
482				t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
483			}
484			verifier, err := jwt.NewVerifier(pubHandle)
485			if err != nil {
486				t.Fatalf("jwt.NewVerifier() err = %v, want nil", err)
487			}
488			if _, err := verifier.VerifyAndDecode(compact, validator); err != nil {
489				t.Errorf("verifier.VerifyAndDecode() err = %v, want nil", err)
490			}
491		})
492	}
493}
494
495func TestJWKSetToPublicKeysetHandleInvalidJSONFails(t *testing.T) {
496	if _, err := jwt.JWKSetToPublicKeysetHandle([]byte(`({[}])`)); err == nil {
497		t.Errorf("jwt.JWKSetToPublicKeysetHandle() err = nil, want error")
498	}
499}
500
501func TestJWKSetToPublicKeysetPrimitivePS256SmallModulusFails(t *testing.T) {
502	jwk := `{"keys":[
503		{"kty":"RSA",
504		 "n":"AQAB",
505		 "e":"AQAB",
506		 "use":"sig",
507		 "alg":"PS256",
508		 "key_ops":["verify"],
509		 "kid":"DfpE4Q"
510		}]
511	}`
512	// Keys in the keyset are validated when the primitive is generated.
513	// JWKSetToPublicKeysetHandle doesn't fail, but NewVerifier will fail.
514	pubHandle, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwk))
515	if err != nil {
516		t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
517	}
518	if _, err := jwt.NewVerifier(pubHandle); err == nil {
519		t.Errorf("jwt.NewVerifier() err = nil, want error")
520	}
521}
522
523func TestJWKSetToPublicKeysetPS256CorrectlySetsKID(t *testing.T) {
524	jwkSet := `{"keys":[
525      {"kty":"RSA",
526       "n":"AQAB",
527       "e":"AQAB",
528       "use":"sig",
529       "alg":"PS256",
530       "key_ops":["verify"],
531       "kid":"DfpE4Q"
532      }]}`
533	kh, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwkSet))
534	if err != nil {
535		t.Fatalf("JWKSetToPublicKeysetHandle() err = %v, want nil", err)
536	}
537	ks := testkeyset.KeysetMaterial(kh)
538	key := ks.GetKey()[0]
539	if key.GetOutputPrefixType() != tinkpb.OutputPrefixType_RAW {
540		t.Errorf("key.GetOutputPrefixType() got %q, want %q", key.GetOutputPrefixType(), tinkpb.OutputPrefixType_RAW)
541	}
542	if key.GetKeyData() == nil {
543		t.Fatalf("GetKeyData() got nil, want *tinkpb.KeyData")
544	}
545	pubKey := &jrpsspb.JwtRsaSsaPssPublicKey{}
546	if err := proto.Unmarshal(key.GetKeyData().GetValue(), pubKey); err != nil {
547		t.Fatalf("proto.Unmarshal() err = %v, want nil", err)
548	}
549	if pubKey.GetCustomKid().GetValue() != "DfpE4Q" {
550		t.Errorf("pubKey.GetCustomKid().GetValue() = %q, want %q", pubKey.GetCustomKid().GetValue(), "DfpE4Q")
551	}
552}
553
554func TestJWKSetToPublicKeysetPS256WithoutOptionalFieldsSucceeds(t *testing.T) {
555	jwkSet := `{"keys":[
556      {"kty":"RSA",
557       "n":"AQAB",
558       "e":"AQAB",
559       "alg":"PS256"
560      }]}`
561	if _, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwkSet)); err != nil {
562		t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
563	}
564}
565
566func TestJWKSetToPublicKeysetInvalidPS256JWKSet(t *testing.T) {
567	for _, tc := range []jwkSetTestCase{
568		{
569			tag: "PS256 without kty",
570			jwkSet: `{"keys":[
571				{"n":"AQAB",
572				 "e":"AQAB",
573				 "use":"sig",
574				 "alg":"PS256",
575				 "key_ops":["verify"],
576				 "kid":"DfpE4Q"
577				}]
578			}`,
579		},
580		{
581			tag: "PS256 without alg",
582			jwkSet: `{"keys":[
583				{"kty":"RSA",
584				 "n":"AQAB",
585				 "e":"AQAB",
586				 "use":"sig",
587				 "key_ops":["verify"],
588				 "kid":"DfpE4Q"
589				}]
590			}`,
591		},
592		{
593			tag: "PS256 invalid kty",
594			jwkSet: `{"keys":[
595				{"kty":"EC",
596				 "n":"AQAB",
597				 "e":"AQAB",
598				 "use":"sig",
599				 "alg":"PS256",
600				 "key_ops":["verify"],
601				 "kid":"DfpE4Q"
602				}]
603			}`,
604		},
605		{
606			tag: "PS256 invalid key ops",
607			jwkSet: `{"keys":[
608				{"kty":"RSA",
609				 "n":"AQAB",
610				 "e":"AQAB",
611				 "use":"sig",
612				 "alg":"PS256",
613				 "key_ops":["verify "],
614				 "kid":"DfpE4Q"
615				}]
616			}`,
617		},
618		{
619			tag: "PS invalid alg",
620			jwkSet: `{"keys":[
621				{"kty":"RSA",
622				 "n":"AQAB",
623				 "e":"AQAB",
624				 "use":"sig",
625				 "alg":"PS257",
626				 "key_ops":["verify"],
627				 "kid":"DfpE4Q"
628				}]
629			}`,
630		},
631		{
632			tag: "PS256 invalid key ops type",
633			jwkSet: `{"keys":[
634				{"kty":"RSA",
635				 "n":"AQAB",
636				 "e":"AQAB",
637				 "use":"sig",
638				 "alg":"PS256",
639				 "key_ops":"verify",
640				 "kid":"DfpE4Q"
641				}]
642			}`,
643		},
644		{
645			tag: "PS256 invalid use",
646			jwkSet: `{"keys":[
647				{"kty":"RSA",
648				 "n":"AQAB",
649				 "e":"AQAB",
650				 "use":"zag",
651				 "alg":"PS256",
652				 "key_ops":["verify"],
653				 "kid":"DfpE4Q"
654				}]
655			}	`,
656		},
657		{
658			tag: "PS256 without modulus",
659			jwkSet: `{"keys":[
660				{"kty":"RSA",
661				 "e":"AQAB",
662				 "use":"sig",
663				 "alg":"PS256",
664				 "key_ops":["verify"],
665				 "kid":"DfpE4Q"
666				}]
667			}`,
668		},
669		{
670			tag: "PSS256 without exponent",
671			jwkSet: `{"keys":[
672				{"kty":"RSA",
673				 "n":"AQAB",
674				 "use":"sig",
675				 "alg":"PS256",
676				 "key_ops":["verify"],
677				 "kid":"DfpE4Q"
678				}]
679			}`,
680		},
681	} {
682		t.Run(tc.tag, func(t *testing.T) {
683			if _, err := jwt.JWKSetToPublicKeysetHandle([]byte(tc.jwkSet)); err == nil {
684				t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = nil, want error")
685			}
686		})
687	}
688}
689
690func TestJWKSetToPublicKeysetPrimitiveRS256SmallModulusFails(t *testing.T) {
691	jwk := `{"keys":[
692		{"kty":"RSA",
693		 "n":"AQAB",
694		 "e":"AQAB",
695		 "use":"sig",
696		 "alg":"RS256",
697		 "key_ops":["verify"],
698		 "kid":"DfpE4Q"
699		}]
700	}`
701	// Keys in the keyset are validated when the primitive is generated.
702	// JWKSetToPublicKeysetHandle but NewVerifier will fail.
703	pubHandle, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwk))
704	if err != nil {
705		t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
706	}
707	if _, err := jwt.NewVerifier(pubHandle); err == nil {
708		t.Errorf("jwt.NewVerifier() err = nil, want error")
709	}
710}
711
712func TestJWKSetToPublicKeysetRS256CorrectlySetsKID(t *testing.T) {
713	jwkSet := `{"keys":[
714      {"kty":"RSA",
715       "n":"AQAB",
716       "e":"AQAB",
717       "use":"sig",
718       "alg":"RS256",
719       "key_ops":["verify"],
720       "kid":"DfpE4Q"
721      }]}`
722	kh, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwkSet))
723	if err != nil {
724		t.Fatalf("JWKSetToPublicKeysetHandle() err = %v, want nil", err)
725	}
726	ks := testkeyset.KeysetMaterial(kh)
727	key := ks.GetKey()[0]
728	if key.GetOutputPrefixType() != tinkpb.OutputPrefixType_RAW {
729		t.Errorf("key.GetOutputPrefixType() got %q, want %q", key.GetOutputPrefixType(), tinkpb.OutputPrefixType_RAW)
730	}
731	if key.GetKeyData() == nil {
732		t.Fatalf("GetKeyData() got nil, want *tinkpb.KeyData")
733	}
734	pubKey := &jrsppb.JwtRsaSsaPkcs1PublicKey{}
735	if err := proto.Unmarshal(key.GetKeyData().GetValue(), pubKey); err != nil {
736		t.Fatalf("proto.Unmarshal() err = %v, want nil", err)
737	}
738	if pubKey.GetCustomKid().GetValue() != "DfpE4Q" {
739		t.Errorf("pubKey.GetCustomKid().GetValue() = %q, want %q", pubKey.GetCustomKid().GetValue(), "DfpE4Q")
740	}
741}
742
743func TestJWKSetToPublicKeysetRS256WithoutOptionalFieldsSucceeds(t *testing.T) {
744	jwkSet := `{"keys":[
745      {"kty":"RSA",
746       "n":"AQAB",
747       "e":"AQAB",
748       "alg":"RS256"
749      }]}`
750	if _, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwkSet)); err != nil {
751		t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
752	}
753}
754
755func TestJWKSetToPublicKeysetInvalidRS256JWKSet(t *testing.T) {
756	for _, tc := range []jwkSetTestCase{
757		{
758			tag: "RS256 without kty",
759			jwkSet: `{"keys":[
760				{"n":"AQAB",
761				 "e":"AQAB",
762				 "use":"sig",
763				 "alg":"RS256",
764				 "key_ops":["verify"],
765				 "kid":"DfpE4Q"
766				}]
767			}`,
768		},
769		{
770			tag: "RS256 without alg",
771			jwkSet: `{"keys":[
772				{"kty":"RSA",
773				 "n":"AQAB",
774				 "e":"AQAB",
775				 "use":"sig",
776				 "key_ops":["verify"],
777				 "kid":"DfpE4Q"
778				}]
779			}`,
780		},
781		{
782			tag: "RS256 invalid kty",
783			jwkSet: `{"keys":[
784				{"kty":"EC",
785				 "n":"AQAB",
786				 "e":"AQAB",
787				 "use":"sig",
788				 "alg":"RS256",
789				 "key_ops":["verify"],
790				 "kid":"DfpE4Q"
791				}]
792			}`,
793		},
794		{
795			tag: "RS256 invalid key ops",
796			jwkSet: `{"keys":[
797				{"kty":"RSA",
798				 "n":"AQAB",
799				 "e":"AQAB",
800				 "use":"sig",
801				 "alg":"RS256",
802				 "key_ops":["verify "],
803				 "kid":"DfpE4Q"
804				}]
805			}`,
806		},
807		{
808			tag: "RS invalid alg",
809			jwkSet: `{"keys":[
810				{"kty":"RSA",
811				 "n":"AQAB",
812				 "e":"AQAB",
813				 "use":"sig",
814				 "alg":"RS257",
815				 "key_ops":["verify"],
816				 "kid":"DfpE4Q"
817				}]
818			}`,
819		},
820		{
821			tag: "RS256 invalid key ops type",
822			jwkSet: `{"keys":[
823				{"kty":"RSA",
824				 "n":"AQAB",
825				 "e":"AQAB",
826				 "use":"sig",
827				 "alg":"RS256",
828				 "key_ops":"verify",
829				 "kid":"DfpE4Q"
830				}]
831			}`,
832		},
833		{
834			tag: "RS256 invalid use",
835			jwkSet: `{"keys":[
836				{"kty":"RSA",
837				 "n":"AQAB",
838				 "e":"AQAB",
839				 "use":"zag",
840				 "alg":"RS256",
841				 "key_ops":["verify"],
842				 "kid":"DfpE4Q"
843				}]
844			}	`,
845		},
846		{
847			tag: "RS256 without modulus",
848			jwkSet: `{"keys":[
849				{"kty":"RSA",
850				 "e":"AQAB",
851				 "use":"sig",
852				 "alg":"RS256",
853				 "key_ops":["verify"],
854				 "kid":"DfpE4Q"
855				}]
856			}`,
857		},
858		{
859			tag: "RSS256 without exponent",
860			jwkSet: `{"keys":[
861				{"kty":"RSA",
862				 "n":"AQAB",
863				 "use":"sig",
864				 "alg":"RS256",
865				 "key_ops":["verify"],
866				 "kid":"DfpE4Q"
867				}]
868			}`,
869		},
870	} {
871		t.Run(tc.tag, func(t *testing.T) {
872			if _, err := jwt.JWKSetToPublicKeysetHandle([]byte(tc.jwkSet)); err == nil {
873				t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = nil, want error")
874			}
875		})
876	}
877}
878
879func TestJWKSetToPublicKeysetES256WithSmallXPrimitiveFails(t *testing.T) {
880	jwk := `{
881    "keys":[{
882    "kty":"EC",
883    "crv":"P-256",
884    "x":"wO6uIxh8Sk",
885    "y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
886    "use":"sig","alg":"ES256","key_ops":["verify"]}],
887    "kid":"EhuduQ"
888  }`
889	// Keys in the keyset are validated when the primitive is generated.
890	// JWKSetToPublicKeysetHandle but NewVerifier will fail.
891	pubHandle, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwk))
892	if err != nil {
893		t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
894	}
895	if _, err := jwt.NewVerifier(pubHandle); err == nil {
896		t.Errorf("jwt.NewVerifier() err = nil, want error")
897	}
898}
899
900func TestJWKSetToPublicKeysetES256WithSmallYFails(t *testing.T) {
901	jwk := `{
902    "keys":[{
903    "kty":"EC",
904    "crv":"P-256",
905    "x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
906    "y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB27",
907    "use":"sig","alg":"ES256","key_ops":["verify"]}],
908    "kid":"EhuduQ"
909  }`
910	// Keys in the keyset are validated when the primitive is generated.
911	// JWKSetToPublicKeysetHandle but NewVerifier will fail.
912	pubHandle, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwk))
913	if err != nil {
914		t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
915	}
916	if _, err := jwt.NewVerifier(pubHandle); err == nil {
917		t.Errorf("jwt.NewVerifier() err = nil, want error")
918	}
919}
920
921func TestJWKSetToPublicKeysetES256CorrectlySetsKID(t *testing.T) {
922	jwk := `{
923    "keys":[{
924    "kty":"EC",
925    "crv":"P-256",
926    "x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
927    "y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
928    "use":"sig","alg":"ES256","key_ops":["verify"],
929    "kid":"EhuduQ"}]
930  }`
931	pubHandle, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwk))
932	if err != nil {
933		t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
934	}
935	ks := testkeyset.KeysetMaterial(pubHandle)
936
937	if len(ks.GetKey()) != 1 {
938		t.Errorf("len(ks.GetKey()) got %d keys, want 1", len(ks.GetKey()))
939	}
940	key := ks.GetKey()[0]
941	if key.GetOutputPrefixType() != tinkpb.OutputPrefixType_RAW {
942		t.Errorf("key.GetOutputPrefixType() got %q, want %q", key.GetOutputPrefixType(), tinkpb.OutputPrefixType_RAW)
943	}
944	if key.GetKeyData() == nil {
945		t.Fatalf("invalid key")
946	}
947	pubKey := &jepb.JwtEcdsaPublicKey{}
948	if err := proto.Unmarshal(key.GetKeyData().GetValue(), pubKey); err != nil {
949		t.Fatalf("proto.Unmarshal(key.GetKeyData(), pubKey) err = %v, want nil", err)
950	}
951	if pubKey.GetCustomKid().GetValue() != "EhuduQ" {
952		t.Errorf("key.GetCustomKid() got %q, want EhuduQ", pubKey.GetCustomKid())
953	}
954}
955
956func TestJWKSetToPublicKeysetES256WithoutOptionalFieldsSucceeds(t *testing.T) {
957	jwk := `{
958    "keys":[{
959    "kty":"EC",
960    "crv":"P-256",
961    "x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
962    "y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
963    "alg":"ES256"}]
964  }`
965	if _, err := jwt.JWKSetToPublicKeysetHandle([]byte(jwk)); err != nil {
966		t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = %v, want nil", err)
967	}
968}
969
970func TestJWKSetToPublicKeysetInvalidES256PublicKeys(t *testing.T) {
971	for _, tc := range []jwkSetTestCase{
972		{
973			tag:    "jwk set is not a json",
974			jwkSet: `5`,
975		},
976		{
977			tag:    "empty jwk set",
978			jwkSet: `{}`,
979		},
980		{
981			tag:    "no keys in jwk set",
982			jwkSet: `{"keys": []}`,
983		},
984		{
985			tag:    "keys of wrong type in jwk set",
986			jwkSet: `{"keys": "value"}`,
987		},
988		{
989			tag:    "keys not a json object",
990			jwkSet: `{"keys":[1]}`,
991		},
992		{
993			tag: "without kty",
994			jwkSet: `{
995				"keys":[{
996				"crv":"P-256",
997				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
998				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
999				"use":"sig","alg":"ES256","key_ops":["verify"],
1000				"kid":"EhuduQ"}]
1001			}`,
1002		},
1003		{
1004			tag: "without algorithm",
1005			jwkSet: `{
1006				"keys":[{
1007				"kty":"EC",
1008				"crv":"P-256",
1009				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1010				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1011				"use":"sig","key_ops":["verify"],
1012				"kid":"EhuduQ"}]
1013			}`,
1014		},
1015		{
1016			tag: "empty algorithm",
1017			jwkSet: `{
1018				"keys":[{
1019				"kty":"EC",
1020				"crv":"P-256",
1021				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1022				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1023				"use":"sig", "alg":"", "key_ops":["verify"],
1024				"kid":"EhuduQ"}]
1025			}`,
1026		},
1027		{
1028			tag: "invalid algorthm prefix",
1029			jwkSet: `{
1030				"keys":[{
1031				"kty":"EC",
1032				"crv":"P-256",
1033				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1034				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1035				"use":"sig", "alg":"SS256", "key_ops":["verify"],
1036				"kid":"EhuduQ"}]
1037			}`,
1038		},
1039		{
1040			tag: "invalid algorithm",
1041			jwkSet: `{
1042				"keys":[{
1043				"kty":"EC",
1044				"crv":"P-256",
1045				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1046				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1047				"use":"sig","alg":"ES257","key_ops":["verify"],
1048				"kid":"EhuduQ"}]
1049			}`,
1050		},
1051		{
1052			tag: "algorithm not a string",
1053			jwkSet: `{
1054				"keys":[{
1055				"kty":"EC",
1056				"crv":"P-256",
1057				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1058				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1059				"use":"sig","alg":256,"key_ops":["verify"],
1060				"kid":"EhuduQ"}]
1061			}`,
1062		},
1063		{
1064			tag: "invalid curve and algorithm",
1065			jwkSet: `{
1066				"keys":[{
1067				"kty":"EC",
1068				"crv":"P-384",
1069				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1070				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1071				"use":"sig","alg":"ES512","key_ops":["verify"],
1072				"kid":"EhuduQ"}]
1073			}`,
1074		},
1075		{
1076			tag: "without curve",
1077			jwkSet: `{
1078				"keys":[{
1079				"kty":"EC",
1080				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1081				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1082				"use":"sig","alg":"ES512","key_ops":["verify"],
1083				"kid":"EhuduQ"}]
1084			}`,
1085		},
1086		{
1087			tag: "invalid key ops",
1088			jwkSet: `{
1089				"keys":[{
1090				"kty":"EC",
1091				"crv":"P-256",
1092				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1093				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1094				"use":"sig","alg":"ES256","key_ops":["verify "],
1095				"kid":"EhuduQ"}]
1096			}`,
1097		},
1098		{
1099			tag: "multiple key ops",
1100			jwkSet: `{
1101				"keys":[{
1102				"kty":"EC",
1103				"crv":"P-256",
1104				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1105				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1106				"use":"sig","alg":"ES256","key_ops":["verify", "sign"],
1107				"kid":"EhuduQ"}]
1108			}`,
1109		},
1110		{
1111			tag: "invalid key ops type",
1112			jwkSet: `{
1113				"keys":[{
1114				"kty":"EC",
1115				"crv":"P-256",
1116				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1117				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1118				"use":"sig","alg":"ES256","key_ops":"verify",
1119				"kid":"EhuduQ"}]
1120			}`,
1121		},
1122		{
1123			tag: "invalid key ops type inside list",
1124			jwkSet: `{
1125				"keys":[{
1126				"kty":"EC",
1127				"crv":"P-256",
1128				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1129				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1130				"use":"sig","alg":"ES256","key_ops":[1],
1131				"kid":"EhuduQ"}]
1132			}`,
1133		},
1134		{
1135			tag: "invalid use",
1136			jwkSet: `{
1137				"keys":[{
1138				"kty":"EC",
1139				"crv":"P-256",
1140				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1141				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1142				"use":"zag","alg":"ES256","key_ops":["verify"],
1143				"kid":"EhuduQ"}]
1144			}`,
1145		},
1146		{
1147			tag: "without x coordinate",
1148			jwkSet: `{
1149				"keys":[{
1150				"kty":"EC",
1151				"crv":"P-256",
1152				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1153				"use":"sig","alg":"ES256","key_ops":["verify"],
1154				"kid":"EhuduQ"}]
1155			}`,
1156		},
1157		{
1158			tag: "without y coordinate",
1159			jwkSet: `{
1160				"keys":[{
1161				"kty":"EC",
1162				"crv":"P-256",
1163				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1164				"use":"sig","alg":"ES256","key_ops":["verify"],
1165				"kid":"EhuduQ"}]
1166			}`,
1167		},
1168		{
1169			tag: "kid of invalid type",
1170			jwkSet: `{
1171			"keys":[{
1172			"kty":"EC",
1173			"crv":"P-256",
1174			"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1175			"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1176			"use":"sig","alg":"ES256","key_ops":["verify"],
1177			"kid":5}]
1178			}`,
1179		},
1180		{
1181			tag: "with private key",
1182			jwkSet: `{
1183				"keys":[{
1184				"kty":"EC",
1185				"crv":"P-256",
1186				"alg":"ES256",
1187				"x":"SVqB4JcUD6lsfvqMr-OKUNUphdNn64Eay60978ZlL74",
1188				"y":"lf0u0pMj4lGAzZix5u4Cm5CMQIgMNpkwy163wtKYVKI",
1189				"d":"0g5vAEKzugrXaRbgKG0Tj2qJ5lMP4Bezds1_sTybkfk"
1190				}]
1191			}`,
1192		},
1193	} {
1194		t.Run(tc.tag, func(t *testing.T) {
1195			if _, err := jwt.JWKSetToPublicKeysetHandle([]byte(tc.jwkSet)); err == nil {
1196				t.Fatalf("jwt.JWKSetToPublicKeysetHandle() err = nil, want error")
1197			}
1198		})
1199	}
1200}
1201
1202func TestJWKSetFromPublicKeysetNonEnabledKeysAreIgnored(t *testing.T) {
1203	key := `{
1204      "primaryKeyId": 303799737,
1205      "key": [
1206          {
1207              "keyId": 303799737,
1208              "status": "DISABLED",
1209              "outputPrefixType": "TINK",
1210              "keyData": {
1211                  "typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",
1212                  "keyMaterialType": "ASYMMETRIC_PUBLIC",
1213                  "value": "IiDuhGJiGeaQ/qeqt1daC2xZRarm4VEsmSHJUWJY9EHbvxogwO6uIxh8SkKOO8VjZXNRTteRcwCPE4/4JElKyaa0fcQQAQ=="
1214              }
1215          }
1216      ]
1217  }`
1218	handle, err := createKeysetHandle(key)
1219	if err != nil {
1220		t.Fatalf("createKeysetHandle() err = %v, want nil", err)
1221	}
1222	jwkSet, err := jwt.JWKSetFromPublicKeysetHandle(handle)
1223	if err != nil {
1224		t.Fatalf("jwt.JWKSetFromPublicKeysetHandle() err = %v, want nil", err)
1225	}
1226	want := `{"keys":[]}`
1227	if string(jwkSet) != want {
1228		t.Fatalf("jwt.JWKSetFromPublicKeysetHandle() = %q, want %q", string(jwkSet), want)
1229	}
1230}
1231
1232func TestJWKSetFromPublicKeysetHandleTinkOutputPrefixHasKID(t *testing.T) {
1233	for _, tc := range []jwkSetTestCase{
1234		{
1235			tag: "JwtEcdsaPublicKey",
1236			publicKeyset: `{
1237					"primaryKeyId": 303799737,
1238					"key": [
1239							{
1240									"keyId": 303799737,
1241									"status": "ENABLED",
1242									"outputPrefixType": "TINK",
1243									"keyData": {
1244											"typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",
1245											"keyMaterialType": "ASYMMETRIC_PUBLIC",
1246											"value": "IiDuhGJiGeaQ/qeqt1daC2xZRarm4VEsmSHJUWJY9EHbvxogwO6uIxh8SkKOO8VjZXNRTteRcwCPE4/4JElKyaa0fcQQAQ=="
1247									}
1248							}
1249					]
1250			}`,
1251			jwkSet: `{
1252				"keys":[{
1253				"kty":"EC",
1254				"crv":"P-256",
1255				"x":"wO6uIxh8SkKOO8VjZXNRTteRcwCPE4_4JElKyaa0fcQ",
1256				"y":"7oRiYhnmkP6nqrdXWgtsWUWq5uFRLJkhyVFiWPRB278",
1257				"use":"sig",
1258				"alg":"ES256",
1259				"key_ops":["verify"],
1260				"kid":"EhuduQ"}]
1261			}`,
1262		},
1263		{
1264			tag: "JwtRsaSsaPkcs1PublicKey",
1265			publicKeyset: `{
1266				"primaryKeyId": 1277272603,
1267				"key": [
1268					{
1269						"keyData": {
1270							"typeUrl": "type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PublicKey",
1271							"value": "IgMBAAEagAK+ZQ5rrZNivGPs3ytlUDOgR1KeaxFBo1YEwB0Hxp0ZryfjJwaJhaga/S5lZzy8faOfqXc9r/vZtvYgd/f4oPZRpPAuTXHfJKFfJsShLlkX1t6bOufaiE2LEag3s5+PvA9vrVn4XU2/neerfTzP5EjVZ7Igf70eO4hy5TFpZjRV6+xfMJ6Ewk/mDuRXPKXnlthxGLbx2J2RVrOvNWA0bfnI00wQvfahbVV+++nuF9Ae3FLCQU4/MmDMg8dskVvEAsauuBceyirtS0NB1L2++gSnj8nNCEK2cIQpqGCRPA5bJP3o6VEZiI8lIUdZO6PLVCd3o4pzwsYSykBfigPpmX5hEAE=",
1272							"keyMaterialType": "ASYMMETRIC_PUBLIC"
1273						},
1274						"status": "ENABLED",
1275						"keyId": 1277272603,
1276						"outputPrefixType": "TINK"
1277					}
1278				]
1279			}`,
1280			jwkSet: `{
1281				"keys":[{
1282					"kty":"RSA",
1283					"n": "vmUOa62TYrxj7N8rZVAzoEdSnmsRQaNWBMAdB8adGa8n4ycGiYWoGv0uZWc8vH2jn6l3Pa_72bb2IHf3-KD2UaTwLk1x3yShXybEoS5ZF9bemzrn2ohNixGoN7Ofj7wPb61Z-F1Nv53nq308z-RI1WeyIH-9HjuIcuUxaWY0VevsXzCehMJP5g7kVzyl55bYcRi28didkVazrzVgNG35yNNMEL32oW1Vfvvp7hfQHtxSwkFOPzJgzIPHbJFbxALGrrgXHsoq7UtDQdS9vvoEp4_JzQhCtnCEKahgkTwOWyT96OlRGYiPJSFHWTujy1Qnd6OKc8LGEspAX4oD6Zl-YQ",
1284					"e":"AQAB",
1285					"use":"sig",
1286					"alg":"RS256",
1287					"key_ops":["verify"],
1288					"kid":"TCGiGw"
1289				}]
1290			}`,
1291		},
1292	} {
1293		t.Run(tc.tag, func(t *testing.T) {
1294			handle, err := createKeysetHandle(tc.publicKeyset)
1295			if err != nil {
1296				t.Fatalf("createKeysetHandle() err = %v, want nil", err)
1297			}
1298			js, err := jwt.JWKSetFromPublicKeysetHandle(handle)
1299			if err != nil {
1300				t.Fatalf("jwt.JWKSetFromPublicKeysetHandle() err = %v, want nil", err)
1301			}
1302			got := &spb.Struct{}
1303			if err := got.UnmarshalJSON(js); err != nil {
1304				t.Fatalf("got.UnmarshalJSON() err = %v, want nil", err)
1305			}
1306			want := &spb.Struct{}
1307			if err := want.UnmarshalJSON([]byte(tc.jwkSet)); err != nil {
1308				t.Fatalf("want.UnmarshalJSON() err = %v, want nil", err)
1309			}
1310			if !cmp.Equal(want, got, protocmp.Transform()) {
1311				t.Errorf("mismatch in jwk sets: diff (-want,+got): %v", cmp.Diff(want, got, protocmp.Transform()))
1312			}
1313		})
1314	}
1315}
1316
1317func TestJWKSetFromPublicKeysetHandleInvalidKeysetsFails(t *testing.T) {
1318	for _, tc := range []jwkSetTestCase{
1319		{
1320			tag: "invalid output prefix",
1321			publicKeyset: `{
1322      "primaryKeyId": 303799737,
1323      "key": [
1324          {
1325              "keyId": 303799737,
1326              "status": "ENABLED",
1327              "outputPrefixType": "LEGACY",
1328              "keyData": {
1329                  "typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",
1330                  "keyMaterialType": "ASYMMETRIC_PUBLIC",
1331                  "value": "IiDuhGJiGeaQ/qeqt1daC2xZRarm4VEsmSHJUWJY9EHbvxogwO6uIxh8SkKOO8VjZXNRTteRcwCPE4/4JElKyaa0fcQQAQ=="
1332              }
1333          }
1334      ]
1335  	}`,
1336		},
1337		{
1338			tag: "JwtEcdsaPublicKey unknown algorithm", // The algorithm is set in the base64 encoded value of the key data.
1339			publicKeyset: `{
1340			"primaryKeyId": 303799737,
1341			"key": [
1342				{
1343					"keyId": 303799737,
1344					"status": "ENABLED",
1345					"outputPrefixType": "TINK",
1346					"keyData": {
1347						"typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",
1348						"value": "IiDuhGJiGeaQ/qeqt1daC2xZRarm4VEsmSHJUWJY9EHbvxogwO6uIxh8SkKOO8VjZXNRTteRcwCPE4/4JElKyaa0fcQ=",
1349						"keyMaterialType": "ASYMMETRIC_PUBLIC"
1350					}
1351				}
1352			]
1353		}`,
1354		},
1355		{
1356			tag: "private ecdsa keyset",
1357			publicKeyset: `{
1358      "primaryKeyId": 303799737,
1359      "key": [
1360          {
1361              "keyId": 303799737,
1362              "status": "ENABLED",
1363              "outputPrefixType": "TINK",
1364              "keyData": {
1365                  "typeUrl": "type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",
1366                  "keyMaterialType": "ASYMMETRIC_PRIVATE",
1367                  "value": "IiDuhGJiGeaQ/qeqt1daC2xZRarm4VEsmSHJUWJY9EHbvxogwO6uIxh8SkKOO8VjZXNRTteRcwCPE4/4JElKyaa0fcQQAQ=="
1368              }
1369          }
1370      ]
1371  }`,
1372		},
1373		{
1374			tag: "unknown key type",
1375			publicKeyset: `{
1376      "primaryKeyId": 303799737,
1377      "key": [
1378          {
1379              "keyId": 303799737,
1380              "status": "ENABLED",
1381              "outputPrefixType": "TINK",
1382              "keyData": {
1383                  "typeUrl": "type.googleapis.com/google.crypto.tink.Unknown",
1384                  "keyMaterialType": "ASYMMETRIC_PUBLIC",
1385                  "value": "IiDuhGJiGeaQ/qeqt1daC2xZRarm4VEsmSHJUWJY9EHbvxogwO6uIxh8SkKOO8VjZXNRTteRcwCPE4/4JElKyaa0fcQQAQ=="
1386              }
1387          }
1388      ]
1389  }`,
1390		},
1391		{
1392			tag: "JwtRsaSsaPkcs1 unknown algorithm", // The algorithm is set in the base64 encoded value of the key data.
1393			publicKeyset: `{
1394				"primaryKeyId": 1277272603,
1395				"key": [
1396					{
1397						"keyData": {
1398							"typeUrl": "type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PublicKey",
1399							"value": "IgMBAAEagAK+ZQ5rrZNivGPs3ytlUDOgR1KeaxFBo1YEwB0Hxp0ZryfjJwaJhaga/S5lZzy8faOfqXc9r/vZtvYgd/f4oPZRpPAuTXHfJKFfJsShLlkX1t6bOufaiE2LEag3s5+PvA9vrVn4XU2/neerfTzP5EjVZ7Igf70eO4hy5TFpZjRV6+xfMJ6Ewk/mDuRXPKXnlthxGLbx2J2RVrOvNWA0bfnI00wQvfahbVV+++nuF9Ae3FLCQU4/MmDMg8dskVvEAsauuBceyirtS0NB1L2++gSnj8nNCEK2cIQpqGCRPA5bJP3o6VEZiI8lIUdZO6PLVCd3o4pzwsYSykBfigPpmX5h",
1400							"keyMaterialType": "ASYMMETRIC_PUBLIC"
1401						},
1402						"status": "ENABLED",
1403						"keyId": 1277272603,
1404						"outputPrefixType": "TINK"
1405					}
1406				]
1407			}`,
1408		},
1409	} {
1410		t.Run(tc.tag, func(t *testing.T) {
1411			handle, err := createKeysetHandle(tc.publicKeyset)
1412			if err != nil {
1413				t.Fatalf("createKeysetHandle() err = %v, want nil", err)
1414			}
1415			if _, err := jwt.JWKSetFromPublicKeysetHandle(handle); err == nil {
1416				t.Errorf("jwt.JWKSetFromPublicKeysetHandle() err = nil, want error")
1417			}
1418		})
1419	}
1420}
1421