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": "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", 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