xref: /aosp_15_r20/external/tink/python/tink/jwt/_jwk_set_converter_test.py (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1# Copyright 2021 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"""Tests for tink.python.tink.jwt._jwk_set_converter."""
15
16from absl.testing import absltest
17from absl.testing import parameterized
18
19from tink.proto import tink_pb2
20import tink
21from tink import cleartext_keyset_handle
22from tink import jwt
23
24ES256_KEYSET = (
25    '{"primaryKeyId":282600252,"key":[{"keyData":{'
26    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",'
27    '"value":"EAEaIBDPI66hjLHvjxmUJ2nyHIBDmdOtQ4gPsvWgYYgZ0gygIiBTEK0rTACpAb97m'
28    '+mvtJKAk0q3mHjPcUZm0C4EueDW4Q==",'
29    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
30    '},"status":"ENABLED","keyId":282600252,"outputPrefixType":"RAW"}]}')
31
32ES256_JWK_SET = ('{"keys":[{'
33                 '"kty":"EC",'
34                 '"crv":"P-256",'
35                 '"x":"EM8jrqGMse-PGZQnafIcgEOZ061DiA-y9aBhiBnSDKA",'
36                 '"y":"UxCtK0wAqQG_e5vpr7SSgJNKt5h4z3FGZtAuBLng1uE",'
37                 '"use":"sig","alg":"ES256","key_ops":["verify"]}]}')
38
39ES256_KEYSET_TINK = (
40    '{"primaryKeyId":282600252,"key":[{"keyData":{'
41    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",'
42    '"value":"EAEaIBDPI66hjLHvjxmUJ2nyHIBDmdOtQ4gPsvWgYYgZ0gygIiBTEK0rTACpAb97m'
43    '+mvtJKAk0q3mHjPcUZm0C4EueDW4Q==",'
44    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
45    '},"status":"ENABLED","keyId":282600252,"outputPrefixType":"TINK"}]}')
46
47ES256_JWK_SET_KID = ('{"keys":[{'
48                     '"kty":"EC",'
49                     '"crv":"P-256",'
50                     '"x":"EM8jrqGMse-PGZQnafIcgEOZ061DiA-y9aBhiBnSDKA",'
51                     '"y":"UxCtK0wAqQG_e5vpr7SSgJNKt5h4z3FGZtAuBLng1uE",'
52                     '"use":"sig","alg":"ES256","key_ops":["verify"],'
53                     '"kid":"ENgjPA"}]}')
54
55ES384_KEYSET = (
56    '{"primaryKeyId":456087424,"key":[{"keyData":{'
57    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",'
58    '"value":"EAIaMQDSjvWihoKGmr4nlDuI/KkvuPvEZr+B4bU0MuXQQXgyNMGApFm2iTeotv7LC'
59    'SsG3mQiMEHIMGx4wa+Y8yeJQWMiSpukpPM7jP9GqaykZQQ2GY/NLg/n9+BJtntgvFhG5gWLTg='
60    '=","keyMaterialType":"ASYMMETRIC_PUBLIC"'
61    '},"status":"ENABLED","keyId":456087424,"outputPrefixType":"RAW"}]}')
62
63ES384_JWK_SET = (
64    '{"keys":[{"kty":"EC","crv":"P-384",'
65    '"x":"ANKO9aKGgoaavieUO4j8qS-4-8Rmv4HhtTQy5dBBeDI0wYCkWbaJN6i2_ssJKwbeZA",'
66    '"y":"QcgwbHjBr5jzJ4lBYyJKm6Sk8zuM_0aprKRlBDYZj80uD-f34Em2e2C8WEbmBYtO",'
67    '"use":"sig","alg":"ES384","key_ops":["verify"]}]}')
68
69ES512_KEYSET = (
70    '{"primaryKeyId":1570200439,"key":[{"keyData":{'
71    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",'
72    '"value":"EAMaQgEV3nweRej6Z1/aPTqCkc1tQla5eVI68+qfwR1kB/wXCuYCB5otarhomUt64'
73    'Fah/8Tjf0WJHMZyFr86RUitiRQm1SJCATht/NOX8RcbaEr1MaH+0BFTaepvpTzSfQ04C2P8VCo'
74    'URB3GeVKk4VQh8O/KLSYfX+58bqEnaZ0G7W9qjHa2ols2",'
75    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
76    '},"status":"ENABLED","keyId":1570200439,"outputPrefixType":"RAW"}]}')
77
78ES512_JWK_SET = (
79    '{"keys":[{"kty":"EC","crv":"P-521",'
80    '"x":"ARXefB5F6PpnX9o9OoKRzW1CVrl5Ujrz6p_BHWQH_BcK5gIHmi1quGiZS3rgVqH_xON_R'
81    'YkcxnIWvzpFSK2JFCbV",'
82    '"y":"ATht_NOX8RcbaEr1MaH-0BFTaepvpTzSfQ04C2P8VCoURB3GeVKk4VQh8O_KLSYfX-58b'
83    'qEnaZ0G7W9qjHa2ols2",'
84    '"use":"sig","alg":"ES512","key_ops":["verify"]}]}')
85
86RS256_KEYSET = (
87    '{"primaryKeyId":482168993,"key":[{"keyData":{'
88    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PublicKey"'
89    ',"value":"EAEagQIAkspk37lGBqXmPPq2CL5KdDeRx7xFiTadpL3jc4nXaqftCtpM6qExfrc2'
90    'JLaIsnwpwfGMClfe/alIs2GrT9fpM8oDeCccvC39DzZhsSFnAELggi3hnWNKRLfSV0UJzBI+5h'
91    'Z6ifUsv8W8mSHKlsVMmvOfC2P5+l72qTwN6Le3hy6CxFp5s9pw011B7J3PU65sty6GI9sehB2B'
92    '/n7nfiWw9YN5++pfwyoitzoMoVKOOpj7fFq88f8ArpC7kR1SBTe20Bt1AmpZDT2Dmfmlb/Q1UF'
93    'jj/F3C77NCNQ344ZcAEI42HY+uighy5GdKQRHMoTT1OzyDG90ABjggQqDGW+zXzyIDAQAB",'
94    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
95    '},"status":"ENABLED","keyId":482168993,"outputPrefixType":"RAW"}]}')
96
97RS256_JWK_SET = (
98    '{"keys":[{"kty":"RSA",'
99    '"n":"AJLKZN-5Rgal5jz6tgi-SnQ3kce8RYk2naS943OJ12qn7QraTOqhMX63NiS2iLJ8KcHxj'
100    'ApX3v2pSLNhq0_X6TPKA3gnHLwt_Q82YbEhZwBC4IIt4Z1jSkS30ldFCcwSPuYWeon1LL_FvJk'
101    'hypbFTJrznwtj-fpe9qk8Dei3t4cugsRaebPacNNdQeydz1OubLcuhiPbHoQdgf5-534lsPWDe'
102    'fvqX8MqIrc6DKFSjjqY-3xavPH_AK6Qu5EdUgU3ttAbdQJqWQ09g5n5pW_0NVBY4_xdwu-zQjU'
103    'N-OGXABCONh2ProoIcuRnSkERzKE09Ts8gxvdAAY4IEKgxlvs188",'
104    '"e":"AQAB","use":"sig","alg":"RS256","key_ops":["verify"]}]}')
105
106RS256_KEYSET_TINK = (
107    '{"primaryKeyId":482168993,"key":[{"keyData":{'
108    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PublicKey"'
109    ',"value":"EAEagQIAkspk37lGBqXmPPq2CL5KdDeRx7xFiTadpL3jc4nXaqftCtpM6qExfrc2'
110    'JLaIsnwpwfGMClfe/alIs2GrT9fpM8oDeCccvC39DzZhsSFnAELggi3hnWNKRLfSV0UJzBI+5h'
111    'Z6ifUsv8W8mSHKlsVMmvOfC2P5+l72qTwN6Le3hy6CxFp5s9pw011B7J3PU65sty6GI9sehB2B'
112    '/n7nfiWw9YN5++pfwyoitzoMoVKOOpj7fFq88f8ArpC7kR1SBTe20Bt1AmpZDT2Dmfmlb/Q1UF'
113    'jj/F3C77NCNQ344ZcAEI42HY+uighy5GdKQRHMoTT1OzyDG90ABjggQqDGW+zXzyIDAQAB",'
114    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
115    '},"status":"ENABLED","keyId":482168993,"outputPrefixType":"TINK"}]}')
116
117RS256_JWK_SET_KID = (
118    '{"keys":[{"kty":"RSA",'
119    '"n":"AJLKZN-5Rgal5jz6tgi-SnQ3kce8RYk2naS943OJ12qn7QraTOqhMX63NiS2iLJ8KcHxj'
120    'ApX3v2pSLNhq0_X6TPKA3gnHLwt_Q82YbEhZwBC4IIt4Z1jSkS30ldFCcwSPuYWeon1LL_FvJk'
121    'hypbFTJrznwtj-fpe9qk8Dei3t4cugsRaebPacNNdQeydz1OubLcuhiPbHoQdgf5-534lsPWDe'
122    'fvqX8MqIrc6DKFSjjqY-3xavPH_AK6Qu5EdUgU3ttAbdQJqWQ09g5n5pW_0NVBY4_xdwu-zQjU'
123    'N-OGXABCONh2ProoIcuRnSkERzKE09Ts8gxvdAAY4IEKgxlvs188",'
124    '"e":"AQAB","use":"sig","alg":"RS256","key_ops":["verify"],'
125    '"kid":"HL1QoQ"}]}')
126
127RS384_KEYSET = (
128    '{"primaryKeyId":333504275,"key":[{"keyData":{'
129    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PublicKey"'
130    ',"value":"EAIagQMAnlBY5WD7gVQjNKvrS2whLKzt0Eql72B6haZ17eKifNn4S49eGdBy9RLj'
131    '/mvHXAbacrngt9fzi0iv/WQ57jUmtO1b/wLt5LYk9APsBYjywDCIe+u9UouikP7c3SBqjjQijZ'
132    '50jgYbMY6cL7s2Gx5lI1vlGX3ZExLVYbNoI9VBFAWjSDefd6GugESxXQFnnO3p2GHOKryZLeDH'
133    '/KzVacTq2/pVXKVH/9/EQzcLB0oYUljZ4vYQ4HCAcwnUZbirsRwA0350Dz0Mlj+3+9sSAF8FPA'
134    '+F/wlIBkPqjJ26b80V5FU4mBTzvYoXGTjkD7+bxH9p28huJSU96P4WdG5PYVwI1VEYwGipkUIp'
135    'MWjJ7dXAtmltHzM9vkUt2bsBe9vyJjmRXyoC6mHSJbSyOm9Dd8BENobcUL9h+aBoxruY+mU49k'
136    'AHzzeAntn8C+vIrxN+X6N2EU9N8t9BF+mwYiBEsY54wx99RbRrY9yICfPBmQJGwXSxNCXBRrbJ'
137    'yxkIVuqvACP5IgMBAAE=",'
138    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
139    '},"status":"ENABLED","keyId":333504275,"outputPrefixType":"RAW"}]}')
140
141RS384_JWK_SET = (
142    '{"keys":[{"kty":"RSA",'
143    '"n":"AJ5QWOVg-4FUIzSr60tsISys7dBKpe9geoWmde3ionzZ-EuPXhnQcvUS4_5rx1wG2nK54'
144    'LfX84tIr_1kOe41JrTtW_8C7eS2JPQD7AWI8sAwiHvrvVKLopD-3N0gao40Io2edI4GGzGOnC-'
145    '7NhseZSNb5Rl92RMS1WGzaCPVQRQFo0g3n3ehroBEsV0BZ5zt6dhhziq8mS3gx_ys1WnE6tv6V'
146    'VylR__fxEM3CwdKGFJY2eL2EOBwgHMJ1GW4q7EcANN-dA89DJY_t_vbEgBfBTwPhf8JSAZD6oy'
147    'dum_NFeRVOJgU872KFxk45A-_m8R_advIbiUlPej-FnRuT2FcCNVRGMBoqZFCKTFoye3VwLZpb'
148    'R8zPb5FLdm7AXvb8iY5kV8qAuph0iW0sjpvQ3fARDaG3FC_YfmgaMa7mPplOPZAB883gJ7Z_Av'
149    'ryK8Tfl-jdhFPTfLfQRfpsGIgRLGOeMMffUW0a2PciAnzwZkCRsF0sTQlwUa2ycsZCFbq'
150    'rwAj-Q",'
151    '"e":"AQAB","use":"sig","alg":"RS384","key_ops":["verify"]}]}')
152
153RS512_KEYSET = (
154    '{"primaryKeyId":705596479,"key":[{"keyData":{'
155    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PublicKey"'
156    ',"value":"EAMagQQAkKxZ9IRzF56gh47RXLJzQ6lffcnBmQSwvxUDJ0wHpKZzfAawOn1uidbg'
157    'EoQ3XWOgtNvi7QeKLE4GjQa5bY0xdRnu8nKjFcsvH+eu1sV8oVoZ984J5mT1mhwU6nt26p4xKy'
158    'eapMhzYYNvKudQjQJ8SbpVOFpEiJ7j0ECMUd4Q8mCUqWsrXYE8+1CcHjprsIxdot+haCARc72R'
159    'Bj9cLuBIhJNzlFXNmsYh8yoSiEYr/auRvg/kIlNlnlOK/rJM/jMXbB6FuWdePrtqZ+ce2TVyAR'
160    'qjZJ0G0vZcPuvOhgS4LM7/Aeal84ZhIcHladSo/g8pK1eUhnRqRXJpsltwux+1XVJeg2a0FQ0B'
161    'N3Ft25uu5jhfvGWXeTkQOR7LbpbxKTI+vumSy9dmY4UrgAG37N8Xj5/NeqBT51L3qE6tk2ZLoO'
162    '7yjRjhADK5lnbb4iYWWvWd3kqyv0JVlxfDzjAaYtiduEUIdCe45MGk8DpCn9Lnjlunhm4QyQuf'
163    'K8k8UPiBbWNEODI8pjTSEjs0wyMqhegBKAvtVEhr029bg3Lv7YjN9FDvx4usuWGc16bXkTqNgC'
164    'K4KzPG7PwV120r6IVGflfpSkd5rrkzDY01fsP0mW57QCHA67bxqLUECr2dAfNzz6ddS9pqXQyX'
165    'ZWCyWKcvTFsGrr1oECwDOmW+nUIHGklr9Q0iAwEAAQ==",'
166    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
167    '},"status":"ENABLED","keyId":705596479,"outputPrefixType":"RAW"}]}')
168
169RS512_JWK_SET = (
170    '{"keys":[{"kty":"RSA",'
171    '"n":"AJCsWfSEcxeeoIeO0Vyyc0OpX33JwZkEsL8VAydMB6Smc3wGsDp9bonW4BKEN11joLTb4'
172    'u0HiixOBo0GuW2NMXUZ7vJyoxXLLx_nrtbFfKFaGffOCeZk9ZocFOp7duqeMSsnmqTIc2GDbyr'
173    'nUI0CfEm6VThaRIie49BAjFHeEPJglKlrK12BPPtQnB46a7CMXaLfoWggEXO9kQY_XC7gSISTc'
174    '5RVzZrGIfMqEohGK_2rkb4P5CJTZZ5Tiv6yTP4zF2wehblnXj67amfnHtk1cgEao2SdBtL2XD7'
175    'rzoYEuCzO_wHmpfOGYSHB5WnUqP4PKStXlIZ0akVyabJbcLsftV1SXoNmtBUNATdxbdubruY4X'
176    '7xll3k5EDkey26W8SkyPr7pksvXZmOFK4ABt-zfF4-fzXqgU-dS96hOrZNmS6Du8o0Y4QAyuZZ'
177    '22-ImFlr1nd5Ksr9CVZcXw84wGmLYnbhFCHQnuOTBpPA6Qp_S545bp4ZuEMkLnyvJPFD4gW1jR'
178    'DgyPKY00hI7NMMjKoXoASgL7VRIa9NvW4Ny7-2IzfRQ78eLrLlhnNem15E6jYAiuCszxuz8Fdd'
179    'tK-iFRn5X6UpHea65Mw2NNX7D9Jlue0AhwOu28ai1BAq9nQHzc8-nXUvaal0Ml2VgslinL0xbB'
180    'q69aBAsAzplvp1CBxpJa_UN",'
181    '"e":"AQAB","use":"sig","alg":"RS512","key_ops":["verify"]}]}')
182
183PRIVATEKEY_KEYSET = (
184    '{"primaryKeyId":152493399,"key":[{"keyData":{'
185    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtEcdsaPrivateKey",'
186    '"value":"EkYQARogaHkaakArEB51RyZ236S5x3BxaNTFycWuXIGZF8adZ2UiIFlZT7MFogZ'
187    '8ARbS1URIAPcpw8A0g2uwAHRkBqGUiCU2GiBI4jtU/59Zajohgeezi2BXB13O8IJh8V3b0it'
188    'q5zyy5Q==",'
189    '"keyMaterialType":"ASYMMETRIC_PRIVATE"'
190    '},"status":"ENABLED","keyId":152493399,"outputPrefixType":"RAW"}]}')
191
192KEYSET_WITH_DISABLED_KEY = (
193    '{"primaryKeyId":282600252,"key":['
194    '{"keyData":{'
195    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",'
196    '"value":"EAEaIBDPI66hjLHvjxmUJ2nyHIBDmdOtQ4gPsvWgYYgZ0gygIiBTEK0rTACpAb97m'
197    '+mvtJKAk0'
198    'q3mHjPcUZm0C4EueDW4Q==",'
199    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
200    '},"status":"ENABLED","keyId":282600252,"outputPrefixType":"RAW"},'
201    '{"keyData":{'
202    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PublicKey"'
203    ','
204    '"value":"EAEagQIAkspk37lGBqXmPPq2CL5KdDeRx7xFiTadpL3jc4nXaqftCtpM6qExfrc2J'
205    'LaIsnwpwfGMClfe/alIs2GrT9fpM8oDeCccvC39DzZhsSFnAELggi3hnWNKRLfSV0UJzBI+5hZ'
206    '6ifUsv8W8mSHKlsVMmvOfC2P5+l72qTwN6Le3hy6CxFp5s9pw011B7J3PU65sty6GI9sehB2B/'
207    'n7nfiWw9YN5++pfwyoitzoMoVKOOpj7fFq88f8ArpC7kR1SBTe20Bt1AmpZDT2Dmfmlb/Q1UFj'
208    'j/F3C77NCNQ344ZcAEI42HY+uighy5GdKQRHMoTT1OzyDG90ABjggQqDGW+zXzyIDAQAB",'
209    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
210    '},"status":"DISABLED","keyId":482168993,"outputPrefixType":"RAW"}]}')
211
212PS256_KEYSET = (
213    '{"primaryKeyId":1508587714,"key":[{"keyData":{'
214    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPssPublicKey",'
215    '"value":"EAEagQMAj7Eud2n5G11qsdtjpgGWjW4cAKalSE1atm7d+Cp8biRX9wbmLJRMUvoO2'
216    'j7Sp9Szx1TMmksY2Ugf/7+Nv9fY7vBbmxOiBQVTvikWn0FgPwhFTXTz+9fhGjM6E6sdSOUzjM6'
217    'nsPulKqOQ8Aed+TLIlgvwuSTF4B5d6QkZWBymq7My6vV+epzWnoLpVDzCHh+c35r81Pyrj6tiT'
218    'PQzPLN2ixeanclMjx8deNwlak3vwBdMDgwQ63rVCo2eWDS/BYK4rG22luSTDVfQVHU1NXlwXEn'
219    'b/eONFSF6ZbD6JXFMT3uHT4okTOrX4Kd34stbPIUtZFUy3XiSeCGtghBXLMf/ge113Q9WDJ+RN'
220    '1Xa4vgHJCO0+VO+cAugVkiu9UgsPP8o/r7tA2aP/Ps8EHYa1IaZg75vnrMZPvsTH7WG2SjSgW9'
221    'GLLsbNJLFFqLFMwPuZPe8BbgvimPdStXasX/PN6DLKoK2PaT0I+iLK9mRi1Z4OjFbl9KAZXXEl'
222    'hAQTzrEI2adIgMBAAE=",'
223    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
224    '},"status":"ENABLED","keyId":1508587714,"outputPrefixType":"RAW"}]}')
225
226PS256_JWK_SET = (
227    '{"keys":[{"kty":"RSA",'
228    '"n":"AI-xLndp-RtdarHbY6YBlo1uHACmpUhNWrZu3fgqfG4kV_cG5iyUTFL6Dto-0qfUs8dUz'
229    'JpLGNlIH_-_jb_X2O7wW5sTogUFU74pFp9BYD8IRU108_vX4RozOhOrHUjlM4zOp7D7pSqjkPA'
230    'HnfkyyJYL8LkkxeAeXekJGVgcpquzMur1fnqc1p6C6VQ8wh4fnN-a_NT8q4-rYkz0MzyzdosXm'
231    'p3JTI8fHXjcJWpN78AXTA4MEOt61QqNnlg0vwWCuKxttpbkkw1X0FR1NTV5cFxJ2_3jjRUhemW'
232    'w-iVxTE97h0-KJEzq1-Cnd-LLWzyFLWRVMt14knghrYIQVyzH_4Htdd0PVgyfkTdV2uL4ByQjt'
233    'PlTvnALoFZIrvVILDz_KP6-7QNmj_z7PBB2GtSGmYO-b56zGT77Ex-1htko0oFvRiy7GzSSxRa'
234    'ixTMD7mT3vAW4L4pj3UrV2rF_zzegyyqCtj2k9CPoiyvZkYtWeDoxW5fSgGV1xJYQEE86xCNmn'
235    'Q",'
236    '"e":"AQAB","use":"sig","alg":"PS256","key_ops":["verify"]}]}')
237
238PS256_KEYSET_TINK = (
239    '{"primaryKeyId":1508587714,"key":[{"keyData":{'
240    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPssPublicKey",'
241    '"value":"EAEagQMAj7Eud2n5G11qsdtjpgGWjW4cAKalSE1atm7d+Cp8biRX9wbmLJRMUvoO2'
242    'j7Sp9Szx1TMmksY2Ugf/7+Nv9fY7vBbmxOiBQVTvikWn0FgPwhFTXTz+9fhGjM6E6sdSOUzjM6'
243    'nsPulKqOQ8Aed+TLIlgvwuSTF4B5d6QkZWBymq7My6vV+epzWnoLpVDzCHh+c35r81Pyrj6tiT'
244    'PQzPLN2ixeanclMjx8deNwlak3vwBdMDgwQ63rVCo2eWDS/BYK4rG22luSTDVfQVHU1NXlwXEn'
245    'b/eONFSF6ZbD6JXFMT3uHT4okTOrX4Kd34stbPIUtZFUy3XiSeCGtghBXLMf/ge113Q9WDJ+RN'
246    '1Xa4vgHJCO0+VO+cAugVkiu9UgsPP8o/r7tA2aP/Ps8EHYa1IaZg75vnrMZPvsTH7WG2SjSgW9'
247    'GLLsbNJLFFqLFMwPuZPe8BbgvimPdStXasX/PN6DLKoK2PaT0I+iLK9mRi1Z4OjFbl9KAZXXEl'
248    'hAQTzrEI2adIgMBAAE=",'
249    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
250    '},"status":"ENABLED","keyId":1508587714,"outputPrefixType":"TINK"}]}')
251
252PS256_JWK_SET_KID = (
253    '{"keys":[{"kty":"RSA",'
254    '"n":"AI-xLndp-RtdarHbY6YBlo1uHACmpUhNWrZu3fgqfG4kV_cG5iyUTFL6Dto-0qfUs8dUz'
255    'JpLGNlIH_-_jb_X2O7wW5sTogUFU74pFp9BYD8IRU108_vX4RozOhOrHUjlM4zOp7D7pSqjkPA'
256    'HnfkyyJYL8LkkxeAeXekJGVgcpquzMur1fnqc1p6C6VQ8wh4fnN-a_NT8q4-rYkz0MzyzdosXm'
257    'p3JTI8fHXjcJWpN78AXTA4MEOt61QqNnlg0vwWCuKxttpbkkw1X0FR1NTV5cFxJ2_3jjRUhemW'
258    'w-iVxTE97h0-KJEzq1-Cnd-LLWzyFLWRVMt14knghrYIQVyzH_4Htdd0PVgyfkTdV2uL4ByQjt'
259    'PlTvnALoFZIrvVILDz_KP6-7QNmj_z7PBB2GtSGmYO-b56zGT77Ex-1htko0oFvRiy7GzSSxRa'
260    'ixTMD7mT3vAW4L4pj3UrV2rF_zzegyyqCtj2k9CPoiyvZkYtWeDoxW5fSgGV1xJYQEE86xCNmn'
261    'Q",'
262    '"e":"AQAB","use":"sig","alg":"PS256","key_ops":["verify"],'
263    '"kid":"Wes4wg"}]}')
264
265PS384_KEYSET = (
266    '{"primaryKeyId":1042230435,"key":[{"keyData":{'
267    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPssPublicKey",'
268    '"value":"EAIagQMAv6a0OergWYmY1k6l6vx6Of5+RxCeeQ9jMTXQyvO0GCgMDExxtqVS8S25e'
269    'hZ5LNDIiGjhE3v2++D7QEjnzOC5UqI1ZwPxUBSrOaf5oDbJ9vBc2c7wDyJhRV8UobQSpzunD4k'
270    'XypVhytjwRdiP61vG0C/eL0x+LijtM/XVee1Y+5mWrypVrB6EHKtdkMx2WIYNpsFOForFrr6Jz'
271    'LbWfDRWoqbCXKYivnw+CSE38ddW1XsrAT76E2Vf+womuwyBbkjLaiWvNxNFBTap2IaBLKAni6x'
272    '7pqYCeu1n9eMUi41oz9QM8xfOvpH+wubc2PjwyTsb1FDTLnhV36tQLTVGdQdCDMF2Z8Agrnio3'
273    'n1SFjSbYgFyVtpCwFKM2Z0zfO7k9jVbYYkzglzkJfp/lQrsuWqe4CVJjFE1H4BxcU7L0j8755k'
274    'GJI08h1b7LPgqJcPgtHjcqbxHFU2yOf7mNGlW7YTnoQBO0StzQUk7kEw3X0+niEwX/L8j'
275    'qW4YMbxrGdAfkTnPIgMBAAE=",'
276    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
277    '},"status":"ENABLED","keyId":1042230435,"outputPrefixType":"RAW"}]}')
278
279PS384_JWK_SET = (
280    '{"keys":[{"kty":"RSA",'
281    '"n":"AL-mtDnq4FmJmNZOper8ejn-fkcQnnkPYzE10MrztBgoDAxMcbalUvEtuXoWeSzQyIho4'
282    'RN79vvg-0BI58zguVKiNWcD8VAUqzmn-aA2yfbwXNnO8A8iYUVfFKG0Eqc7pw-JF8qVYcrY8EX'
283    'Yj-tbxtAv3i9Mfi4o7TP11XntWPuZlq8qVawehByrXZDMdliGDabBThaKxa6-icy21nw0VqKmw'
284    'lymIr58PgkhN_HXVtV7KwE--hNlX_sKJrsMgW5Iy2olrzcTRQU2qdiGgSygJ4use6amAnrtZ_X'
285    'jFIuNaM_UDPMXzr6R_sLm3Nj48Mk7G9RQ0y54Vd-rUC01RnUHQgzBdmfAIK54qN59UhY0m2IBc'
286    'lbaQsBSjNmdM3zu5PY1W2GJM4Jc5CX6f5UK7LlqnuAlSYxRNR-AcXFOy9I_O-eZBiSNPIdW-yz'
287    '4KiXD4LR43Km8RxVNsjn-5jRpVu2E56EATtErc0FJO5BMN19Pp4hMF_y_I6luGDG8axnQH5E5z'
288    'w",'
289    '"e":"AQAB","use":"sig","alg":"PS384","key_ops":["verify"]}]}')
290
291PS512_KEYSET = (
292    '{"primaryKeyId":257081135,"key":[{"keyData":{'
293    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPssPublicKey",'
294    '"value":"EAMagQQAnOUQvBwNRgeI3zlzIhVo4NzFVCsQn9hd2EIclz6cWBRMFr4EX5lXLK0St'
295    'SIB7EQP4ciHa+vr59sOgMFMC2kiXRUXNtl99QhGwH0YjbWeDC50PKEAjH1hhhPgSw2dFcUVs4j'
296    'bScDrwNn1sQ8rkgSNczvQNpV1MtBhS/CC1PxVF88JaejG2zr+unoFlw7xnqxBWMzNrMHZHwqga'
297    '2vL3inSbvA/RGQjnE2DzQSwZkXthGSwYBjOYbGawMN4onkAx/myHMyTg/TLAqG9GUyB0DVelvV'
298    'oGZG/QJBY2Fp2FlpOQRKeBr6pC7Lk8zZL4GJk264KoOpG8v1t7PveN+STIdTE2D548K+GDOvsv'
299    'rO4ZhofS/iqN9xLucuU1HkqKUqyLvMxsWum8Zhp7zinFdBnDOgeheOHUgN/iwjupk6u1Svt+RW'
300    'NJsfb2l0jrvzf0cRMbPeLZRmpDwBxBvXWo61u6uaBEVb+ooZ6K5+hx3Rld7wXktjYIZzHqUr39'
301    'P5yTw28b8Y2dPFWR4vwr2/0zBxcDmTRRtQ7vPOtZPD0/LVIXkgbBiLILpycnucWt9Lq9Hc62KF'
302    'iTQOAuuOxz7ObBegXjnFupiZZ9PyzO5WgT9lRpH7U7tzGLAjV+AUpjH6HA1o6bRLKOHFBPS+I9'
303    'IqAYb/RpF6M/6hCmC2Rz64yYzR3y4vHKGMiAwEAAQ==",'
304    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
305    '},"status":"ENABLED","keyId":257081135,"outputPrefixType":"RAW"}]}')
306
307PS512_JWK_SET = (
308    '{"keys":[{"kty":"RSA",'
309    '"n":"AJzlELwcDUYHiN85cyIVaODcxVQrEJ_YXdhCHJc-nFgUTBa-BF-ZVyytErUiAexED-HIh'
310    '2vr6-fbDoDBTAtpIl0VFzbZffUIRsB9GI21ngwudDyhAIx9YYYT4EsNnRXFFbOI20nA68DZ9bE'
311    'PK5IEjXM70DaVdTLQYUvwgtT8VRfPCWnoxts6_rp6BZcO8Z6sQVjMzazB2R8KoGtry94p0m7wP'
312    '0RkI5xNg80EsGZF7YRksGAYzmGxmsDDeKJ5AMf5shzMk4P0ywKhvRlMgdA1Xpb1aBmRv0CQWNh'
313    'adhZaTkESnga-qQuy5PM2S-BiZNuuCqDqRvL9bez73jfkkyHUxNg-ePCvhgzr7L6zuGYaH0v4q'
314    'jfcS7nLlNR5KilKsi7zMbFrpvGYae84pxXQZwzoHoXjh1IDf4sI7qZOrtUr7fkVjSbH29pdI67'
315    '839HETGz3i2UZqQ8AcQb11qOtburmgRFW_qKGeiufocd0ZXe8F5LY2CGcx6lK9_T-ck8NvG_GN'
316    'nTxVkeL8K9v9MwcXA5k0UbUO7zzrWTw9Py1SF5IGwYiyC6cnJ7nFrfS6vR3OtihYk0DgLrjsc-'
317    'zmwXoF45xbqYmWfT8szuVoE_ZUaR-1O7cxiwI1fgFKYx-hwNaOm0SyjhxQT0viPSKgGG_0aRej'
318    'P-oQpgtkc-uMmM0d8uLxyhj",'
319    '"e":"AQAB","use":"sig","alg":"PS512","key_ops":["verify"]}]}')
320
321HS256_KEYSET = """
322    {
323      "primaryKeyId": 872908418,
324      "key": [
325        {
326          "keyData": {
327            "typeUrl": "type.googleapis.com/google.crypto.tink.JwtHmacKey",
328            "value": "GiA2qUishZ7cDwH/j2a9xcqqusSg1jKRnPux6XRxc5rvdRAB",
329            "keyMaterialType": "SYMMETRIC"
330          },
331          "status": "ENABLED",
332          "keyId": 872908418,
333          "outputPrefixType": "TINK"
334        }
335      ]
336    }"""
337
338KEYSET_WITH_TWO_KEYS = (
339    '{"primaryKeyId":282600252,"key":['
340    '{"keyData":{'
341    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtEcdsaPublicKey",'
342    '"value":"EAEaIBDPI66hjLHvjxmUJ2nyHIBDmdOtQ4gPsvWgYYgZ0gygIiBTEK0rTACpAb97m'
343    '+mvtJKAk0'
344    'q3mHjPcUZm0C4EueDW4Q==",'
345    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
346    '},"status":"ENABLED","keyId":282600252,"outputPrefixType":"RAW"},'
347    '{"keyData":{'
348    '"typeUrl":"type.googleapis.com/google.crypto.tink.JwtRsaSsaPkcs1PublicKey"'
349    ',"value":"EAEagQIAkspk37lGBqXmPPq2CL5KdDeRx7xFiTadpL3jc4nXaqftCtpM6qExfrc2'
350    'JLaIsnwpwfGMClfe/alIs2GrT9fpM8oDeCccvC39DzZhsSFnAELggi3hnWNKRLfSV0UJzBI+5h'
351    'Z6ifUsv8W8mSHKlsVMmvOfC2P5+l72qTwN6Le3hy6CxFp5s9pw011B7J3PU65sty6GI9sehB2B'
352    '/n7nfiWw9YN5++pfwyoitzoMoVKOOpj7fFq88f8ArpC7kR1SBTe20Bt1AmpZDT2Dmfmlb/Q1UF'
353    'jj/F3C77NCNQ344ZcAEI42HY+uighy5GdKQRHMoTT1OzyDG90ABjggQqDGW+zXzyIDAQAB",'
354    '"keyMaterialType":"ASYMMETRIC_PUBLIC"'
355    '},"status":"ENABLED","keyId":482168993,"outputPrefixType":"RAW"}]}')
356
357JWK_SET_WITH_TWO_KEYS = (
358    '{"keys":[{'
359    '"kty":"EC",'
360    '"crv":"P-256",'
361    '"x":"EM8jrqGMse-PGZQnafIcgEOZ061DiA-y9aBhiBnSDKA",'
362    '"y":"UxCtK0wAqQG_e5vpr7SSgJNKt5h4z3FGZtAuBLng1uE",'
363    '"use":"sig","alg":"ES256","key_ops":["verify"]},'
364    '{"kty":"RSA",'
365    '"n":"AJLKZN-5Rgal5jz6tgi-SnQ3kce8RYk2naS943OJ12qn7QraTOqhMX63NiS2iLJ8KcHxj'
366    'ApX3v2pSLNhq0_X6TPKA3gnHLwt_Q82YbEhZwBC4IIt4Z1jSkS30ldFCcwSPuYWeon1LL_FvJk'
367    'hypbFTJrznwtj-fpe9qk8Dei3t4cugsRaebPacNNdQeydz1OubLcuhiPbHoQdgf5-534lsPWDe'
368    'fvqX8MqIrc6DKFSjjqY-3xavPH_AK6Qu5EdUgU3ttAbdQJqWQ09g5n5pW_0NVBY4_xdwu-zQjU'
369    'N-OGXABCONh2ProoIcuRnSkERzKE09Ts8gxvdAAY4IEKgxlvs188",'
370    '"e":"AQAB","use":"sig","alg":"RS256","key_ops":["verify"]}]}')
371
372
373class JwkSetConverterTest(parameterized.TestCase):
374
375  @parameterized.named_parameters([
376      ('ES256_RAW', ES256_KEYSET, ES256_JWK_SET),
377      ('ES384_RAW', ES384_KEYSET, ES384_JWK_SET),
378      ('ES512_RAW', ES512_KEYSET, ES512_JWK_SET),
379      ('WITH_DISABLED_KEY', KEYSET_WITH_DISABLED_KEY, ES256_JWK_SET),
380      ('ES256_TINK', ES256_KEYSET_TINK, ES256_JWK_SET_KID),
381      ('RS256_RAW', RS256_KEYSET, RS256_JWK_SET),
382      ('RS384_RAW', RS384_KEYSET, RS384_JWK_SET),
383      ('RS512_RAW', RS512_KEYSET, RS512_JWK_SET),
384      ('RS256_TINK', RS256_KEYSET_TINK, RS256_JWK_SET_KID),
385      ('PS256_RAW', PS256_KEYSET, PS256_JWK_SET),
386      ('PS384_RAW', PS384_KEYSET, PS384_JWK_SET),
387      ('PS512_RAW', PS512_KEYSET, PS512_JWK_SET),
388      ('PS256_TINK', PS256_KEYSET_TINK, PS256_JWK_SET_KID),
389      ('TWO_KEYS', KEYSET_WITH_TWO_KEYS, JWK_SET_WITH_TWO_KEYS)
390  ])
391  def test_convert_from_jwt_key(self, tink_keyset, expected_jwk_set):
392    reader = tink.JsonKeysetReader(tink_keyset)
393    keyset_handle = cleartext_keyset_handle.read(reader)
394    jwk_set = jwt.jwk_set_from_public_keyset_handle(keyset_handle)
395    self.assertEqual(jwk_set, expected_jwk_set)
396
397  @parameterized.named_parameters([('ES256_RAW', ES256_JWK_SET),
398                                   ('ES384_RAW', ES384_JWK_SET),
399                                   ('ES512_RAW', ES512_JWK_SET),
400                                   ('ES256_TINK', ES256_JWK_SET_KID),
401                                   ('RS256_RAW', RS256_JWK_SET),
402                                   ('RS384_RAW', RS384_JWK_SET),
403                                   ('RS512_RAW', RS512_JWK_SET),
404                                   ('RS256_TINK', RS256_JWK_SET_KID),
405                                   ('PS256_RAW', RS256_JWK_SET),
406                                   ('PS384_RAW', RS384_JWK_SET),
407                                   ('PS512_RAW', RS512_JWK_SET),
408                                   ('PS256_TINK', RS256_JWK_SET_KID)])
409  def test_convert_jwk_set_to_public_keyset_handle_and_back(self, jwk_set):
410    keyset_handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
411    output_jwk_set = jwt.jwk_set_from_public_keyset_handle(keyset_handle)
412    self.assertEqual(output_jwk_set, jwk_set)
413    # check that all keys are raw.
414    for key in keyset_handle._keyset.key:
415      self.assertEqual(key.output_prefix_type, tink_pb2.RAW)
416
417    # test deprecated to/from keyset_handle functions.
418    self.assertEqual(
419        jwt.jwk_set_from_keyset_handle(jwt.jwk_set_to_keyset_handle(jwk_set)),
420        jwk_set)
421
422  def test_es_conserves_empty_kid(self):
423    jwk_set_with_empty_kid = ES256_JWK_SET_KID.replace('"ENgjPA"', '""')
424    keyset_handle = jwt.jwk_set_to_public_keyset_handle(jwk_set_with_empty_kid)
425    output_jwk_set = jwt.jwk_set_from_public_keyset_handle(keyset_handle)
426    self.assertEqual(output_jwk_set, jwk_set_with_empty_kid)
427
428  def test_primary_key_id_missing_success(self):
429    keyset = ES256_KEYSET.replace('"primaryKeyId":282600252,', '')
430    reader = tink.JsonKeysetReader(keyset)
431    keyset_handle = cleartext_keyset_handle.read(reader)
432    jwk_set = jwt.jwk_set_from_public_keyset_handle(keyset_handle)
433    self.assertEqual(jwk_set, ES256_JWK_SET)
434
435  @parameterized.named_parameters([
436      ('ES256_RAW', ES256_KEYSET),
437      ('RS256_RAW', RS256_KEYSET),
438      ('PS256_RAW', PS256_KEYSET)
439  ])
440  def test_from_legacy_ecdsa_keyset_fails(self, keyset):
441    legacy_keyset = keyset.replace('RAW', 'LEGACY')
442    reader = tink.JsonKeysetReader(legacy_keyset)
443    keyset_handle = cleartext_keyset_handle.read(reader)
444    with self.assertRaises(tink.TinkError):
445      jwt.jwk_set_from_public_keyset_handle(keyset_handle)
446
447  @parameterized.named_parameters([
448      ('ES256_RAW', ES256_KEYSET),
449      ('RS256_RAW', RS256_KEYSET),
450      ('PS256_RAW', RS256_KEYSET)
451  ])
452  def test_from_crunchy_ecdsa_keyset_fails(self, keyset):
453    crunchy_keyset = keyset.replace('RAW', 'CRUNCHY')
454    reader = tink.JsonKeysetReader(crunchy_keyset)
455    keyset_handle = cleartext_keyset_handle.read(reader)
456    with self.assertRaises(tink.TinkError):
457      jwt.jwk_set_from_public_keyset_handle(keyset_handle)
458
459  def test_from_hs256_keyset_fails(self):
460    reader = tink.JsonKeysetReader(HS256_KEYSET)
461    keyset_handle = cleartext_keyset_handle.read(reader)
462    with self.assertRaises(tink.TinkError):
463      jwt.jwk_set_from_public_keyset_handle(keyset_handle)
464
465  def test_from_private_keyset_fails(self):
466    reader = tink.JsonKeysetReader(PRIVATEKEY_KEYSET)
467    keyset_handle = cleartext_keyset_handle.read(reader)
468    with self.assertRaises(tink.TinkError):
469      jwt.jwk_set_from_public_keyset_handle(keyset_handle)
470
471  def test_ecdsa_without_use_or_key_ops_to_public_keyset_handle_success(self):
472    jwk_set = """{"keys":[
473        {
474           "kty":"EC",
475           "crv":"P-256",
476           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
477           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
478           "alg":"ES256"
479        }]}"""
480    # ignore returned value, we only test that it worked.
481    jwt.jwk_set_to_public_keyset_handle(jwk_set)
482
483  def test_ecdsa_private_key_to_public_keyset_handle_fails(self):
484    # Example from https://datatracker.ietf.org/doc/html/rfc7517#appendix-A.2
485    jwk_set = """{"keys":[
486        {
487           "kty":"EC",
488           "crv":"P-256",
489           "x":"MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4",
490           "y":"4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM",
491           "d":"870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE",
492           "alg":"ES256"
493        }]}"""
494    with self.assertRaises(tink.TinkError):
495      jwt.jwk_set_to_public_keyset_handle(jwk_set)
496
497  def test_ecdsa_key_with_unknown_field_to_public_keyset_handle_success(self):
498    jwk_set = """{"keys":[
499        {
500           "kty":"EC",
501           "crv":"P-256",
502           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
503           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
504           "alg":"ES256",
505           "unknown":1234,
506           "use":"sig",
507           "key_ops":["verify"]
508        }]}"""
509    jwt.jwk_set_to_public_keyset_handle(jwk_set)
510
511  def test_ecdsa_key_without_alg_to_public_keyset_handle_fails(self):
512    jwk_set = """{"keys":[
513        {
514           "kty":"EC",
515           "crv":"P-256",
516           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
517           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
518           "use":"sig",
519           "key_ops":["verify"]
520        }]}"""
521    with self.assertRaises(tink.TinkError):
522      jwt.jwk_set_to_public_keyset_handle(jwk_set)
523
524  def test_ecdsa_key_without_kty_to_public_keyset_handle_fails(self):
525    jwk_set = """{"keys":[
526        {
527           "crv":"P-256",
528           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
529           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
530           "alg":"ES256",
531           "use":"sig",
532           "key_ops":["verify"]
533        }]}"""
534    with self.assertRaises(tink.TinkError):
535      jwt.jwk_set_to_public_keyset_handle(jwk_set)
536
537  def test_ecdsa_key_without_crv_to_public_keyset_handle_fails(self):
538    jwk_set = """{"keys":[
539        {
540           "kty":"EC",
541           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
542           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
543           "alg":"ES256",
544           "use":"sig",
545           "key_ops":["verify"]
546        }]}"""
547    with self.assertRaises(tink.TinkError):
548      jwt.jwk_set_to_public_keyset_handle(jwk_set)
549
550  def test_ecdsa_key_with_small_x_primitive_fails(self):
551    jwk_set = """{"keys":[
552        {
553           "kty":"EC",
554           "crv":"P-256",
555           "x":"AAAwOQ",
556           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
557           "alg":"ES256",
558           "use":"sig",
559           "key_ops":["verify"]
560        }]}"""
561    handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
562    with self.assertRaises(tink.TinkError):
563      handle.primitive(jwt.JwtPublicKeyVerify)
564
565  def test_ecdsa_key_with_small_y_primitive_fails(self):
566    jwk_set = """{"keys":[
567        {
568           "kty":"EC",
569           "crv":"P-256",
570           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
571           "y":"AAAwOQ",
572           "alg":"ES256",
573           "use":"sig",
574           "key_ops":["verify"]
575        }]}"""
576    handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
577    with self.assertRaises(tink.TinkError):
578      handle.primitive(jwt.JwtPublicKeyVerify)
579
580  def test_ecdsa_key_with_invalid_kty_to_public_keyset_handle_fails(self):
581    jwk_set = """{"keys":[
582        {
583           "kty":"RSA",
584           "crv":"P-256",
585           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
586           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
587           "alg":"ES256",
588           "use":"sig",
589           "key_ops":["verify"]
590        }]}"""
591    with self.assertRaises(tink.TinkError):
592      jwt.jwk_set_to_public_keyset_handle(jwk_set)
593
594  def test_ecdsa_key_with_invalid_crv_to_public_keyset_handle_fails(self):
595    jwk_set = """{"keys":[
596        {
597           "kty":"EC",
598           "crv":"P-384",
599           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
600           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
601           "alg":"ES256",
602           "use":"sig",
603           "key_ops":["verify"]
604        }]}"""
605    with self.assertRaises(tink.TinkError):
606      jwt.jwk_set_to_public_keyset_handle(jwk_set)
607
608  def test_ecdsa_key_with_invalid_use_to_public_keyset_handle_fails(self):
609    jwk_set = """{"keys":[
610        {
611           "kty":"EC",
612           "crv":"P-256",
613           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
614           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
615           "alg":"ES256",
616           "use":"invalid",
617           "key_ops":["verify"]
618        }]}"""
619    with self.assertRaises(tink.TinkError):
620      jwt.jwk_set_to_public_keyset_handle(jwk_set)
621
622  def test_ecdsa_key_with_invalid_key_ops_to_public_keyset_handle_fails(self):
623    jwk_set = """{"keys":[
624        {
625           "kty":"EC",
626           "crv":"P-256",
627           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
628           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
629           "alg":"ES256",
630           "use":"sig",
631           "key_ops":["invalid"]
632        }]}"""
633    with self.assertRaises(tink.TinkError):
634      jwt.jwk_set_to_public_keyset_handle(jwk_set)
635
636  def test_ecdsa_key_with_string_key_ops_to_public_keyset_handle_fails(self):
637    jwk_set = """{"keys":[
638        {
639           "kty":"EC",
640           "crv":"P-256",
641           "x":"KUPydf4k4cS5EGS82npjEUxKIiBfUGP3wlN49A2GxTY",
642           "y":"b22m_Y4sT-jUJSxBVqjrW_DxWyBLopxYHTuFVfx70ZI",
643           "alg":"ES256",
644           "use":"sig",
645           "key_ops":"verify"
646        }]}"""
647    with self.assertRaises(tink.TinkError):
648      jwt.jwk_set_to_public_keyset_handle(jwk_set)
649
650  def test_rsa_ssa_pkcs1_without_use_and_key_ops_to_keyset_handle_success(self):
651    jwk_set = RS256_JWK_SET.replace(',"use":"sig"',
652                                    '').replace(',"key_ops":["verify"]', '')
653    keyset_handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
654    output_jwk_set = jwt.jwk_set_from_public_keyset_handle(keyset_handle)
655    self.assertEqual(output_jwk_set, RS256_JWK_SET)
656
657  def test_rsa_ssa_pss_without_use_and_key_ops_to_keyset_handle_success(self):
658    jwk_set = PS256_JWK_SET.replace(',"use":"sig"',
659                                    '').replace(',"key_ops":["verify"]', '')
660    keyset_handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
661    output_jwk_set = jwt.jwk_set_from_public_keyset_handle(keyset_handle)
662    self.assertEqual(output_jwk_set, PS256_JWK_SET)
663
664  def test_rsa_ssa_pkcs1_with_unknown_property_keyset_handle_success(self):
665    jwk_set = RS256_JWK_SET.replace(',"use":"sig"',
666                                    ',"use":"sig","unknown":1234')
667    keyset_handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
668    output_jwk_set = jwt.jwk_set_from_public_keyset_handle(keyset_handle)
669    self.assertEqual(output_jwk_set, RS256_JWK_SET)
670
671  def test_rsa_ssa_pss_with_unknown_property_keyset_handle_success(self):
672    jwk_set = PS256_JWK_SET.replace(',"use":"sig"',
673                                    ',"use":"sig","unknown":1234')
674    keyset_handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
675    output_jwk_set = jwt.jwk_set_from_public_keyset_handle(keyset_handle)
676    self.assertEqual(output_jwk_set, PS256_JWK_SET)
677
678  def test_rsa_private_key_to_public_keyset_handle_fails(self):
679    # Example from https://datatracker.ietf.org/doc/html/rfc7517#appendix-A.2
680    jwk_set = """
681     {"keys":
682       [
683         {"kty":"RSA",
684          "n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2aiAFbWhM78LhWx4
685     cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCiFV4n3oknjhMst
686     n64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65YGjQR0_FDW2Q
687     vzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n91CbOpbIS
688     D08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_xBniIqbw
689     0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
690          "e":"AQAB",
691          "d":"X4cTteJY_gn4FYPsXB8rdXix5vwsg1FLN5E3EaG6RJoVH-HLLKD9
692     M7dx5oo7GURknchnrRweUkC7hT5fJLM0WbFAKNLWY2vv7B6NqXSzUvxT0_YSfqij
693     wp3RTzlBaCxWp4doFk5N2o8Gy_nHNKroADIkJ46pRUohsXywbReAdYaMwFs9tv8d
694     _cPVY3i07a3t8MN6TNwm0dSawm9v47UiCl3Sk5ZiG7xojPLu4sbg1U2jx4IBTNBz
695     nbJSzFHK66jT8bgkuqsk0GjskDJk19Z4qwjwbsnn4j2WBii3RL-Us2lGVkY8fkFz
696     me1z0HbIkfz0Y6mqnOYtqc0X4jfcKoAC8Q",
697          "p":"83i-7IvMGXoMXCskv73TKr8637FiO7Z27zv8oj6pbWUQyLPQBQxtPV
698     nwD20R-60eTDmD2ujnMt5PoqMrm8RfmNhVWDtjjMmCMjOpSXicFHj7XOuVIYQyqV
699     WlWEh6dN36GVZYk93N8Bc9vY41xy8B9RzzOGVQzXvNEvn7O0nVbfs",
700          "q":"3dfOR9cuYq-0S-mkFLzgItgMEfFzB2q3hWehMuG0oCuqnb3vobLyum
701     qjVZQO1dIrdwgTnCdpYzBcOfW5r370AFXjiWft_NGEiovonizhKpo9VVS78TzFgx
702     kIdrecRezsZ-1kYd_s1qDbxtkDEgfAITAG9LUnADun4vIcb6yelxk",
703          "dp":"G4sPXkc6Ya9y8oJW9_ILj4xuppu0lzi_H7VTkS8xj5SdX3coE0oim
704     YwxIi2emTAue0UOa5dpgFGyBJ4c8tQ2VF402XRugKDTP8akYhFo5tAA77Qe_Nmtu
705     YZc3C3m3I24G2GvR5sSDxUyAN2zq8Lfn9EUms6rY3Ob8YeiKkTiBj0",
706          "dq":"s9lAH9fggBsoFR8Oac2R_E2gw282rT2kGOAhvIllETE1efrA6huUU
707     vMfBcMpn8lqeW6vzznYY5SSQF7pMdC_agI3nG8Ibp1BUb0JUiraRNqUfLhcQb_d9
708     GF4Dh7e74WbRsobRonujTYN1xCaP6TO61jvWrX-L18txXw494Q_cgk",
709          "qi":"GyM_p6JrXySiz1toFgKbWV-JdI3jQ4ypu9rbMWx3rQJBfmt0FoYzg
710     UIZEVFEcOqwemRN81zoDAaa-Bk0KWNGDjJHZDdDmFhW3AN7lI-puxk_mHZGJ11rx
711     yR8O55XLSe3SPmRfKwZI6yU24ZxvQKFYItdldUKGzO6Ia6zTKhAVRU",
712          "alg":"RS256",
713          "kid":"2011-04-29"}
714       ]
715     }"""
716    # remove spaces and line breaks
717    jwk_set = jwk_set.replace(' ', '').replace('\n', '')
718    # PKCS1
719    with self.assertRaises(tink.TinkError):
720      jwt.jwk_set_to_public_keyset_handle(jwk_set)
721    # PSS
722    jwk_set = jwk_set.replace('"alg":"RS256"', '"alg":"PS256"')
723    with self.assertRaises(tink.TinkError):
724      jwt.jwk_set_to_public_keyset_handle(jwk_set)
725
726  def test_rsa_without_alg_fails(self):
727    jwk_set = RS256_JWK_SET.replace(',"alg":"RS256"', '')
728    with self.assertRaises(tink.TinkError):
729      jwt.jwk_set_to_public_keyset_handle(jwk_set)
730
731  def test_rsa_without_kty_fails(self):
732    jwk_set = RS256_JWK_SET.replace('"kty":"RSA",', '')
733    # PKCS1
734    with self.assertRaises(tink.TinkError):
735      jwt.jwk_set_to_public_keyset_handle(jwk_set)
736    # PSS
737    jwk_set = jwk_set.replace('"alg":"RS256"', '"alg":"PS256"')
738    with self.assertRaises(tink.TinkError):
739      jwt.jwk_set_to_public_keyset_handle(jwk_set)
740
741  def test_rsa_with_small_n_primitive_fails(self):
742    jwk_set = """{"keys":[{
743        "kty":"RSA",
744        "n":"AAAwOQ",
745        "e":"AQAB",
746        "use":"sig",
747        "alg":"RS256",
748        "key_ops":["verify"]}]}"""
749    # PKCS1
750    handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
751    with self.assertRaises(tink.TinkError):
752      handle.primitive(jwt.JwtPublicKeyVerify)
753    # test PSS
754    jwk_set = jwk_set.replace('"alg":"RS256"', '"alg":"PS256"')
755    handle = jwt.jwk_set_to_public_keyset_handle(jwk_set)
756    with self.assertRaises(tink.TinkError):
757      handle.primitive(jwt.JwtPublicKeyVerify)
758
759  def test_rsa_with_invalid_kty_fails(self):
760    jwk_set = RS256_JWK_SET.replace('"kty":"RSA"', '"kty":"EC"')
761    # PKCS1
762    with self.assertRaises(tink.TinkError):
763      jwt.jwk_set_to_public_keyset_handle(jwk_set)
764    # PSS
765    jwk_set = jwk_set.replace('"alg":"RS256"', '"alg":"PS256"')
766    with self.assertRaises(tink.TinkError):
767      jwt.jwk_set_to_public_keyset_handle(jwk_set)
768
769  def test_rsa_with_invalid_use_fails(self):
770    jwk_set = RS256_JWK_SET.replace('"use":"sig"', '"use":"invalid"')
771    # PKCS1
772    with self.assertRaises(tink.TinkError):
773      jwt.jwk_set_to_public_keyset_handle(jwk_set)
774    # PSS
775    jwk_set = jwk_set.replace('"alg":"RS256"', '"alg":"PS256"')
776    with self.assertRaises(tink.TinkError):
777      jwt.jwk_set_to_public_keyset_handle(jwk_set)
778
779  def test_rsa_with_invalid_key_ops_fails(self):
780    jwk_set = RS256_JWK_SET.replace('"key_ops":["verify"]',
781                                    '"key_ops":["invalid"]')
782    # PKCS1
783    with self.assertRaises(tink.TinkError):
784      jwt.jwk_set_to_public_keyset_handle(jwk_set)
785    # PSS
786    jwk_set = jwk_set.replace('"alg":"RS256"', '"alg":"PS256"')
787    with self.assertRaises(tink.TinkError):
788      jwt.jwk_set_to_public_keyset_handle(jwk_set)
789
790  def test_rsa_with_string_key_ops_fails(self):
791    jwk_set = RS256_JWK_SET.replace('"key_ops":["verify"]',
792                                    '"key_ops":"verify"')
793    # PKCS1
794    with self.assertRaises(tink.TinkError):
795      jwt.jwk_set_to_public_keyset_handle(jwk_set)
796    # PSS
797    jwk_set = jwk_set.replace('"alg":"RS256"', '"alg":"PS256"')
798    with self.assertRaises(tink.TinkError):
799      jwt.jwk_set_to_public_keyset_handle(jwk_set)
800
801  def test_jwk_set_to_public_keyset_handle_with_invalid_json_raises_tink_error(
802      self):
803    with self.assertRaises(tink.TinkError):
804      jwt.jwk_set_to_public_keyset_handle('invalid')
805
806if __name__ == '__main__':
807  absltest.main()
808