1 /*!
2 *
3 */
4
5 #include "check_cjose.h"
6
7 #include <stdlib.h>
8 #include <openssl/evp.h>
9 #include <jansson.h>
10 #include <check.h>
11 #include <cjose/jwk.h>
12 #include <cjose/base64.h>
13 #include <cjose/util.h>
14 #include "include/jwk_int.h"
15
16 /**
17 * Convenience function for comparing multiple string attributes of two
18 * json objects.
19 *
20 * \param left_json a json object to be compared.
21 * \param right_json a json object to be compared.
22 * \param null terminated array of attribute names.
23 * \returns true if string values of all named attributes are identical in both
24 * json objects or are both missing from each, false otherwise.
25 */
_match_string_attrs(json_t * left_json,json_t * right_json,const char ** attrs)26 static bool _match_string_attrs(json_t *left_json, json_t *right_json, const char **attrs)
27 {
28 for (int i = 0; NULL != attrs[i]; ++i)
29 {
30 const char *left_attr_str = NULL;
31 json_t *left_attr_json = NULL;
32 left_attr_json = json_object_get(left_json, attrs[i]);
33 if (NULL != left_attr_json)
34 {
35 left_attr_str = json_string_value(left_attr_json);
36 }
37
38 const char *right_attr_str = NULL;
39 json_t *right_attr_json = json_object_get(right_json, attrs[i]);
40 if (NULL != right_attr_json)
41 {
42 right_attr_str = json_string_value(right_attr_json);
43 }
44
45 // return false if strings don't match (consider NULL==NULL a match)
46 if ((left_attr_str != right_attr_str)
47 && (left_attr_str == NULL || right_attr_str == NULL || strcmp(left_attr_str, right_attr_str) != 0))
48 {
49 return false;
50 }
51 }
52 return true;
53 }
54
START_TEST(test_cjose_jwk_name_for_kty)55 START_TEST(test_cjose_jwk_name_for_kty)
56 {
57 cjose_err err;
58 ck_assert_str_eq("RSA", cjose_jwk_name_for_kty(CJOSE_JWK_KTY_RSA, &err));
59 ck_assert_str_eq("EC", cjose_jwk_name_for_kty(CJOSE_JWK_KTY_EC, &err));
60 ck_assert_str_eq("oct", cjose_jwk_name_for_kty(CJOSE_JWK_KTY_OCT, &err));
61 ck_assert(NULL == cjose_jwk_name_for_kty(0, &err));
62 ck_assert(NULL == cjose_jwk_name_for_kty(99, &err));
63 }
64 END_TEST
65
66 const char *RSA_e = "AQAB";
67 const char *RSA_n = "2Rgbvu_cGMpvVl8DE6aGGX7IE2lKn5c9ZtexriFrCLqBbKt2TBOZkoCn_AbcDjUVk23CxsIj9Z1VfsL_0UeVA_AeOLUWw0F5-"
68 "JhoK6NBeLpYZOz7HYieTOSJjSxYhoCYtVbLKI27e3NEvckxTs-90CdKl71P7YwrdSrY59hR-u2etyNCRGAPcoDH5xYJxrG2p5FH_Dh_"
69 "MQ0ugDnJY2_b_-w9NS2Y2atIkzXZDjtcSpjImKpL0eIFF69ptiF8vd4q2j-"
70 "ougipFBGP9U5bSVzeZ7FyGkJ5Qa2DYc0osYi1QFs3YZKzkKfcblx14u-yZYhUkZHlb_jbfulnUHxDdO_r8Q";
71 const char *RSA_d = "P9N6tNRIXXGG8lnUyb43xt8ja7GVIv6QKuBXeN6SXWqYCp8OlKdei1gQC2To5bRtt36ZuV3yvI-ZRz-"
72 "Ffr4Q7at29y0mmBl0BsaoOcwxv5Dp1CJoYfJ8uBao6jyTelfsjcQKzs18xXrKRxIT0Rv6rmwe3iXmjeycCkKiqudKkv8m9RtbvdWH8AFd2ZsCL"
73 "NblVRrOZ9ZPQQCMVJLf65pF_cBfux-Zz_CJCfq93gFcN3h1tPFLX8UPBMqvqkBZzDx8PGoYgrydz-T8tcqtkDriyEL3mGYe9b2uH_"
74 "8JnzMMNMFheVPDdNBhyQQVOmQqPj7idv7677eSle4LJZANUYZdwQ";
75 const char *RSA_p = "8Yhaq4UMiFptSuUMcLUqOJdZ9Jr0z2KG_ZrPaaHIX8gfbtp5DGjhXEE--SwoX9ukEzR6vCewSFcEl20wnT0uTwrVs-Bf2J1L-"
76 "5tKKeiiwLQxXtk1cG5-PI-ECkqX0AP2K2Xa0wpIjldBE5SBR0S7whANpKxhVFMtNgKog4xNvxU";
77 const char *RSA_q = "5hkENNaWQSJ5qWXVJYh0LAHddr1NXwkKIfKNjK8vCYfOHXDgKxW4UbAIu7wIU9iZcVjTdN2UcaJMe5fBQR9ZEP8bcuY9ZpeUCkv-"
78 "g9IGw69HUXE7ERBz1es_lZOuJzENwL85Al7jOtVJ2y26g4r30q4jqaL7CcgUZjBKAytjUG0";
79 const char *RSA_dp = "pAn1epQsRNcVb05Muqdv-2tfnu824TqLb-YahCVqjxK9tm4O1EzO8fcmK9i_uwrTTm_QA8X4xcjDx4xS_"
80 "he1Qd2b8kSrE9UQ69s17WygTLyU41QmJSwF9F-MT-kFXjOylxrgGYDccj_0ZLXxb1PRKSX5_iNNHxY2mH4JsP4zN1k";
81 const char *RSA_dq = "gTTxAL6y9vZl_PKa4w2htoiBlMiuJryLvQ5X3_ULY72nxy54Ipl6vBwue0UWJAcP-u8XJpu6XKj3a7uGoIv61ql5_2Y8elyJm9Kao-"
82 "kPNVk6oggEVAu6EBiext57v7Qy9dYrLCKeVI4qf_JIts8VZG-2xO4pK4_3rH5XQTpe9W0";
83 const char *RSA_qi = "xTJ_ON_6kc9g3ZbunSSt_oqJBguxH2x8HVl2KQXafW-F0_DOv09P1e0fbSdOLhR-V9lLjq8DxOcvCMxkpQr2G8lTaBRVTF_-szu9adi9bgb_-"
84 "egvc_NAvRkuGE9fUmB2_nAyU-j4VUh1MMSP5qqQhMYvFdAF5y36MpI-pV1SLFQ";
START_TEST(test_cjose_jwk_create_RSA_spec)85 START_TEST(test_cjose_jwk_create_RSA_spec)
86 {
87 cjose_err err;
88 cjose_jwk_rsa_keyspec specPub;
89 cjose_jwk_rsa_keyspec specPriv;
90
91 memset(&specPriv, 0, sizeof(cjose_jwk_rsa_keyspec));
92 cjose_base64url_decode(RSA_e, strlen(RSA_e), &specPriv.e, &specPriv.elen, &err);
93 cjose_base64url_decode(RSA_n, strlen(RSA_n), &specPriv.n, &specPriv.nlen, &err);
94 cjose_base64url_decode(RSA_d, strlen(RSA_d), &specPriv.d, &specPriv.dlen, &err);
95 cjose_base64url_decode(RSA_p, strlen(RSA_p), &specPriv.p, &specPriv.plen, &err);
96 cjose_base64url_decode(RSA_q, strlen(RSA_q), &specPriv.q, &specPriv.qlen, &err);
97 cjose_base64url_decode(RSA_dp, strlen(RSA_dp), &specPriv.dp, &specPriv.dplen, &err);
98 cjose_base64url_decode(RSA_dq, strlen(RSA_dq), &specPriv.dq, &specPriv.dqlen, &err);
99 cjose_base64url_decode(RSA_qi, strlen(RSA_qi), &specPriv.qi, &specPriv.qilen, &err);
100
101 // everything
102 cjose_jwk_t *jwk = NULL;
103 jwk = cjose_jwk_create_RSA_spec(&specPriv, &err);
104 ck_assert(NULL != jwk);
105 ck_assert(1 == jwk->retained);
106 ck_assert(CJOSE_JWK_KTY_RSA == jwk->kty);
107 ck_assert(2048 == jwk->keysize);
108 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
109 ck_assert(NULL != jwk->keydata);
110 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
111 cjose_jwk_release(jwk);
112
113 // only private is not possible after the OpenSSL 1.1.x changes because e & n always need to be set
114
115 // minimal private
116 cjose_get_dealloc()(specPriv.p);
117 specPriv.p = NULL;
118 cjose_get_dealloc()(specPriv.q);
119 specPriv.q = NULL;
120 cjose_get_dealloc()(specPriv.dp);
121 specPriv.dp = NULL;
122 cjose_get_dealloc()(specPriv.dq);
123 specPriv.dq = NULL;
124 cjose_get_dealloc()(specPriv.qi);
125 specPriv.qi = NULL;
126 jwk = cjose_jwk_create_RSA_spec(&specPriv, &err);
127 ck_assert(NULL != jwk);
128 ck_assert(1 == jwk->retained);
129 ck_assert(CJOSE_JWK_KTY_RSA == jwk->kty);
130 ck_assert(2048 == jwk->keysize);
131 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
132 ck_assert(NULL != jwk->keydata);
133 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
134 cjose_jwk_release(jwk);
135
136 cjose_get_dealloc()(specPriv.n);
137 specPriv.n = NULL;
138 cjose_get_dealloc()(specPriv.d);
139 specPriv.d = NULL;
140 cjose_get_dealloc()(specPriv.e);
141 specPriv.e = NULL;
142
143 // public only
144 memset(&specPub, 0, sizeof(cjose_jwk_rsa_keyspec));
145 cjose_base64url_decode(RSA_e, strlen(RSA_e), &specPub.e, &specPub.elen, &err);
146 cjose_base64url_decode(RSA_n, strlen(RSA_n), &specPub.n, &specPub.nlen, &err);
147
148 jwk = cjose_jwk_create_RSA_spec(&specPub, &err);
149 ck_assert(NULL != jwk);
150 ck_assert(1 == jwk->retained);
151 ck_assert(CJOSE_JWK_KTY_RSA == jwk->kty);
152 ck_assert(2048 == jwk->keysize);
153 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
154 ck_assert(NULL != jwk->keydata);
155 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
156 cjose_jwk_release(jwk);
157
158 cjose_get_dealloc()(specPub.n);
159 specPub.n = NULL;
160 cjose_get_dealloc()(specPub.e);
161 specPub.e = NULL;
162 }
163 END_TEST
164
START_TEST(test_cjose_jwk_create_RSA_random)165 START_TEST(test_cjose_jwk_create_RSA_random)
166 {
167 cjose_err err;
168 cjose_jwk_t *jwk = NULL;
169 uint8_t *e = NULL;
170 size_t elen = 0;
171
172 e = (uint8_t *)"\x01\x00\x01";
173 elen = 3;
174 jwk = cjose_jwk_create_RSA_random(2048, e, elen, &err);
175 ck_assert(NULL != jwk);
176 ck_assert(1 == jwk->retained);
177 ck_assert(CJOSE_JWK_KTY_RSA == jwk->kty);
178 ck_assert(2048 == jwk->keysize);
179 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
180 ck_assert(NULL != jwk->keydata);
181 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
182
183 cjose_jwk_release(jwk);
184
185 e = NULL;
186 elen = 0;
187 jwk = cjose_jwk_create_RSA_random(2048, e, elen, &err);
188 ck_assert(NULL != jwk);
189 ck_assert(1 == jwk->retained);
190 ck_assert(CJOSE_JWK_KTY_RSA == jwk->kty);
191 ck_assert(2048 == jwk->keysize);
192 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
193 ck_assert(NULL != jwk->keydata);
194 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
195
196 cjose_jwk_release(jwk);
197 }
198 END_TEST
199
200 const char *EC_P256_d = "RSSjcBQW_EBxm1gzYhejCdWtj3Id_GuwldwEgSuKCEM";
201 const char *EC_P256_x = "ii8jCnvs4FLc0rteSWxanup22pNDhzizmlGN-bfTcFk";
202 const char *EC_P256_y = "KbkZ7r_DQ-t67pnxPnFDHObTLBqn44BSjcqn0STUkaM";
START_TEST(test_cjose_jwk_create_EC_P256_spec)203 START_TEST(test_cjose_jwk_create_EC_P256_spec)
204 {
205 cjose_err err;
206 cjose_jwk_t *jwk = NULL;
207 cjose_jwk_ec_keyspec spec;
208
209 memset(&spec, 0, sizeof(cjose_jwk_ec_keyspec));
210 spec.crv = CJOSE_JWK_EC_P_256;
211 cjose_base64url_decode(EC_P256_d, strlen(EC_P256_d), &spec.d, &spec.dlen, &err);
212 cjose_base64url_decode(EC_P256_x, strlen(EC_P256_x), &spec.x, &spec.xlen, &err);
213 cjose_base64url_decode(EC_P256_y, strlen(EC_P256_y), &spec.y, &spec.ylen, &err);
214
215 jwk = cjose_jwk_create_EC_spec(&spec, &err);
216 ck_assert(NULL != jwk);
217 ck_assert(1 == jwk->retained);
218 ck_assert(CJOSE_JWK_KTY_EC == jwk->kty);
219 ck_assert(256 == jwk->keysize);
220 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
221 ck_assert(NULL != jwk->keydata);
222 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
223 ck_assert(CJOSE_JWK_EC_P_256 == cjose_jwk_EC_get_curve(jwk, &err));
224 cjose_get_dealloc()(spec.d);
225 cjose_get_dealloc()(spec.x);
226 cjose_get_dealloc()(spec.y);
227
228 // cleanup
229 cjose_jwk_release(jwk);
230 }
231 END_TEST
START_TEST(test_cjose_jwk_create_EC_P256_random)232 START_TEST(test_cjose_jwk_create_EC_P256_random)
233 {
234 cjose_err err;
235 cjose_jwk_t *jwk = NULL;
236
237 jwk = cjose_jwk_create_EC_random(CJOSE_JWK_EC_P_256, &err);
238 ck_assert(1 == jwk->retained);
239 ck_assert(CJOSE_JWK_KTY_EC == jwk->kty);
240 ck_assert(256 == jwk->keysize);
241 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
242 ck_assert(NULL != jwk->keydata);
243 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
244 ck_assert(CJOSE_JWK_EC_P_256 == cjose_jwk_EC_get_curve(jwk, &err));
245
246 // cleanup
247 cjose_jwk_release(jwk);
248 }
249 END_TEST
250
251 const char *EC_384_d = "vpwFfxYfV7Ftm3fuidQsK-l_tGxqqnUUG6R5QZStJAeZy7qQiHAo7rZumFslws38";
252 const char *EC_384_x = "ulIwcMpG6gbi9Bo_CeVFDIu7RT-AFxu5NRiH9Wm39lYQOAcZTlHJM8Tz4Fwbtu-0";
253 const char *EC_384_y = "WOZtl6a6x_ukWquJbd_sF18zivwVq26HhJbnmwEKuab7zvZ3sGzOX7LJCHl4zmXa";
START_TEST(test_cjose_jwk_create_EC_P384_spec)254 START_TEST(test_cjose_jwk_create_EC_P384_spec)
255 {
256 cjose_err err;
257 cjose_jwk_t *jwk = NULL;
258 cjose_jwk_ec_keyspec spec;
259
260 memset(&spec, 0, sizeof(cjose_jwk_ec_keyspec));
261 spec.crv = CJOSE_JWK_EC_P_384;
262 cjose_base64url_decode(EC_384_d, strlen(EC_384_d), &spec.d, &spec.dlen, &err);
263 cjose_base64url_decode(EC_384_x, strlen(EC_384_x), &spec.x, &spec.xlen, &err);
264 cjose_base64url_decode(EC_384_y, strlen(EC_384_y), &spec.y, &spec.ylen, &err);
265
266 jwk = cjose_jwk_create_EC_spec(&spec, &err);
267 ck_assert(NULL != jwk);
268 ck_assert(1 == jwk->retained);
269 ck_assert(CJOSE_JWK_KTY_EC == jwk->kty);
270 ck_assert(384 == jwk->keysize);
271 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
272 ck_assert(NULL != jwk->keydata);
273 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
274 ck_assert(CJOSE_JWK_EC_P_384 == cjose_jwk_EC_get_curve(jwk, &err));
275 cjose_get_dealloc()(spec.d);
276 cjose_get_dealloc()(spec.x);
277 cjose_get_dealloc()(spec.y);
278
279 // cleanup
280 cjose_jwk_release(jwk);
281 }
282 END_TEST
START_TEST(test_cjose_jwk_create_EC_P384_random)283 START_TEST(test_cjose_jwk_create_EC_P384_random)
284 {
285 cjose_err err;
286 cjose_jwk_t *jwk = NULL;
287
288 jwk = cjose_jwk_create_EC_random(CJOSE_JWK_EC_P_384, &err);
289 ck_assert(1 == jwk->retained);
290 ck_assert(CJOSE_JWK_KTY_EC == jwk->kty);
291 ck_assert(384 == jwk->keysize);
292 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
293 ck_assert(NULL != jwk->keydata);
294 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
295 ck_assert(CJOSE_JWK_EC_P_384 == cjose_jwk_EC_get_curve(jwk, &err));
296
297 // cleanup
298 cjose_jwk_release(jwk);
299 }
300 END_TEST
301
302 const char *EC_521_d = "E-0dXEk-bh2Fb08ge8_kNCiSSLiWu7zAR-4SVxH_SfqX2vPimGlF8cU-RFxb64zjW599vsULwvE62MzFWtK63Y4";
303 const char *EC_521_x = "C3LEPuVWTeIQ7KGNibjAdUyHYyapCE6GAQ_oEs7P49yA8AWyJhxIVGWuc1punIsi5WjzHRoNhj0TqEBN4LsW0-g";
304 const char *EC_521_y = "AeMjLFBhdk-lBiaFc8QKYZYziRIS_8q-3ziwXm5zfREdzVv9GUm-l-APSv4gIq-0-G0oSyFf6j6oh7KTf4aYGTV6";
START_TEST(test_cjose_jwk_create_EC_P521_spec)305 START_TEST(test_cjose_jwk_create_EC_P521_spec)
306 {
307 cjose_err err;
308 cjose_jwk_t *jwk = NULL;
309 cjose_jwk_ec_keyspec spec;
310
311 memset(&spec, 0, sizeof(cjose_jwk_ec_keyspec));
312 spec.crv = CJOSE_JWK_EC_P_521;
313 cjose_base64url_decode(EC_521_d, strlen(EC_521_d), &spec.d, &spec.dlen, &err);
314 cjose_base64url_decode(EC_521_x, strlen(EC_521_x), &spec.x, &spec.xlen, &err);
315 cjose_base64url_decode(EC_521_y, strlen(EC_521_y), &spec.y, &spec.ylen, &err);
316
317 jwk = cjose_jwk_create_EC_spec(&spec, &err);
318 ck_assert(NULL != jwk);
319 ck_assert(1 == jwk->retained);
320 ck_assert(CJOSE_JWK_KTY_EC == jwk->kty);
321 ck_assert(521 == jwk->keysize);
322 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
323 ck_assert(NULL != jwk->keydata);
324 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
325 ck_assert(CJOSE_JWK_EC_P_521 == cjose_jwk_EC_get_curve(jwk, &err));
326 free(spec.d);
327 free(spec.x);
328 free(spec.y);
329
330 // cleanup
331 cjose_jwk_release(jwk);
332 }
333 END_TEST
START_TEST(test_cjose_jwk_create_EC_P521_random)334 START_TEST(test_cjose_jwk_create_EC_P521_random)
335 {
336 cjose_err err;
337 cjose_jwk_t *jwk = NULL;
338
339 jwk = cjose_jwk_create_EC_random(CJOSE_JWK_EC_P_521, &err);
340 ck_assert(1 == jwk->retained);
341 ck_assert(CJOSE_JWK_KTY_EC == jwk->kty);
342 ck_assert(521 == jwk->keysize);
343 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
344 ck_assert(NULL != jwk->keydata);
345 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
346 ck_assert(CJOSE_JWK_EC_P_521 == cjose_jwk_EC_get_curve(jwk, &err));
347
348 // cleanup
349 cjose_jwk_release(jwk);
350 }
351 END_TEST
352
353 const uint8_t *OCT_KEY = "pKE-eSbyFqPdtA5WzazKFg";
START_TEST(test_cjose_jwk_create_oct_spec)354 START_TEST(test_cjose_jwk_create_oct_spec)
355 {
356 cjose_err err;
357 cjose_jwk_t *jwk = NULL;
358 uint8_t *k = NULL;
359 size_t klen = 0;
360
361 cjose_base64url_decode(OCT_KEY, strlen(OCT_KEY), &k, &klen, &err);
362
363 jwk = cjose_jwk_create_oct_spec(k, klen, &err);
364 ck_assert(1 == jwk->retained);
365 ck_assert(CJOSE_JWK_KTY_OCT == jwk->kty);
366 ck_assert(klen * 8 == jwk->keysize);
367 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
368 ck_assert(NULL != jwk->keydata);
369 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
370 ck_assert_bin_eq(k, jwk->keydata, klen);
371 cjose_get_dealloc()(k);
372
373 // cleanup
374 cjose_jwk_release(jwk);
375 }
376 END_TEST
START_TEST(test_cjose_jwk_create_oct_random)377 START_TEST(test_cjose_jwk_create_oct_random)
378 {
379 cjose_err err;
380 cjose_jwk_t *jwk = NULL;
381
382 jwk = cjose_jwk_create_oct_random(128, &err);
383 ck_assert(1 == jwk->retained);
384 ck_assert(CJOSE_JWK_KTY_OCT == jwk->kty);
385 ck_assert(128 == jwk->keysize);
386 ck_assert(cjose_jwk_get_keysize(jwk, &err) == jwk->keysize);
387 ck_assert(NULL != jwk->keydata);
388 ck_assert(cjose_jwk_get_keydata(jwk, &err) == jwk->keydata);
389
390 // cleanup
391 cjose_jwk_release(jwk);
392 }
393 END_TEST
START_TEST(test_cjose_jwk_create_oct_random_inval)394 START_TEST(test_cjose_jwk_create_oct_random_inval)
395 {
396 cjose_err err;
397 cjose_jwk_t *jwk = NULL;
398
399 jwk = cjose_jwk_create_oct_random(0, &err);
400 ck_assert(NULL == jwk);
401 ck_assert(CJOSE_ERR_INVALID_ARG == err.code);
402 }
403 END_TEST
404
START_TEST(test_cjose_jwk_retain_release)405 START_TEST(test_cjose_jwk_retain_release)
406 {
407 cjose_err err;
408 // create some type of key
409 cjose_jwk_t *jwk = cjose_jwk_create_oct_random(128, &err);
410 ck_assert(1 == jwk->retained);
411
412 cjose_jwk_t *retained = NULL;
413 retained = cjose_jwk_retain(jwk, &err);
414 ck_assert(jwk == retained);
415 ck_assert(2 == jwk->retained);
416
417 bool result = false;
418 result = cjose_jwk_release(jwk);
419 ck_assert(result);
420 ck_assert(1 == jwk->retained);
421
422 retained = cjose_jwk_retain(jwk, &err);
423 ck_assert(jwk == retained);
424 ck_assert(2 == jwk->retained);
425
426 result = cjose_jwk_release(jwk);
427 ck_assert(result);
428 ck_assert(1 == jwk->retained);
429
430 result = cjose_jwk_release(jwk);
431 ck_assert(!result);
432
433 result = cjose_jwk_release(NULL);
434 ck_assert(!result);
435
436 retained = cjose_jwk_retain(NULL, &err);
437 ck_assert(retained == NULL);
438 }
439 END_TEST
440
START_TEST(test_cjose_jwk_get_kty)441 START_TEST(test_cjose_jwk_get_kty)
442 {
443 cjose_err err;
444 cjose_jwk_t *jwk = NULL;
445 jwk = cjose_jwk_create_oct_random(128, &err);
446 ck_assert(CJOSE_JWK_KTY_OCT == cjose_jwk_get_kty(jwk, &err));
447 cjose_jwk_release(jwk);
448
449 jwk = cjose_jwk_create_EC_random(CJOSE_JWK_EC_P_256, &err);
450 ck_assert(CJOSE_JWK_KTY_EC == cjose_jwk_get_kty(jwk, &err));
451 cjose_jwk_release(jwk);
452 }
453 END_TEST
454
START_TEST(test_cjose_jwk_to_json_oct)455 START_TEST(test_cjose_jwk_to_json_oct)
456 {
457 cjose_err err;
458 cjose_jwk_t *jwk = NULL;
459 uint8_t *k = NULL;
460 size_t klen = 0;
461
462 cjose_base64url_decode(OCT_KEY, strlen(OCT_KEY), &k, &klen, &err);
463 jwk = cjose_jwk_create_oct_spec(k, klen, &err);
464 cjose_get_dealloc()(k);
465
466 char *json;
467 json = cjose_jwk_to_json(jwk, false, &err);
468 ck_assert(NULL != json);
469 ck_assert_str_eq("{\"kty\":\"oct\"}", json);
470 free(json);
471
472 json = cjose_jwk_to_json(jwk, true, &err);
473 ck_assert(NULL != json);
474 ck_assert_str_eq("{\"kty\":\"oct\",\"k\":\"pKE-eSbyFqPdtA5WzazKFg\"}", json);
475 free(json);
476
477 cjose_jwk_release(jwk);
478 }
479 END_TEST
START_TEST(test_cjose_jwk_to_json_ec)480 START_TEST(test_cjose_jwk_to_json_ec)
481 {
482 cjose_err err;
483 cjose_jwk_t *jwk = NULL;
484 cjose_jwk_ec_keyspec spec;
485
486 memset(&spec, 0, sizeof(cjose_jwk_ec_keyspec));
487 spec.crv = CJOSE_JWK_EC_P_256;
488 cjose_base64url_decode(EC_P256_d, strlen(EC_P256_d), &spec.d, &spec.dlen, &err);
489 cjose_base64url_decode(EC_P256_x, strlen(EC_P256_x), &spec.x, &spec.xlen, &err);
490 cjose_base64url_decode(EC_P256_y, strlen(EC_P256_y), &spec.y, &spec.ylen, &err);
491
492 jwk = cjose_jwk_create_EC_spec(&spec, &err);
493 cjose_get_dealloc()(spec.d);
494 cjose_get_dealloc()(spec.x);
495 cjose_get_dealloc()(spec.y);
496
497 char *json;
498 json = cjose_jwk_to_json(jwk, false, &err);
499 ck_assert(NULL != json);
500 ck_assert_str_eq("{\"kty\":\"EC\",\"crv\":\"P-256\""
501 ",\"x\":\"ii8jCnvs4FLc0rteSWxanup22pNDhzizmlGN-bfTcFk\""
502 ",\"y\":\"KbkZ7r_DQ-t67pnxPnFDHObTLBqn44BSjcqn0STUkaM\"}",
503 json);
504 free(json);
505
506 json = cjose_jwk_to_json(jwk, true, &err);
507 ck_assert(NULL != json);
508 ck_assert_str_eq("{\"kty\":\"EC\",\"crv\":\"P-256\""
509 ",\"x\":\"ii8jCnvs4FLc0rteSWxanup22pNDhzizmlGN-bfTcFk\""
510 ",\"y\":\"KbkZ7r_DQ-t67pnxPnFDHObTLBqn44BSjcqn0STUkaM\""
511 ",\"d\":\"RSSjcBQW_EBxm1gzYhejCdWtj3Id_GuwldwEgSuKCEM\"}",
512 json);
513 free(json);
514
515 cjose_jwk_release(jwk);
516 }
517 END_TEST
518
519 const char *RSA_PUBLIC_JSON = "{\"kty\":\"RSA\","
520 "\"e\":\"AQAB\""
521 ",\"n\":\"2Rgbvu_cGMpvVl8DE6aGGX7IE2lKn5c9ZtexriFrCLqBbKt2TBOZkoCn_AbcDjUVk23CxsIj9Z1VfsL_0UeVA_"
522 "AeOLUWw0F5-JhoK6NBeLpYZOz7HYieTOSJjSxYhoCYtVbLKI27e3NEvckxTs-90CdKl71P7YwrdSrY59hR-"
523 "u2etyNCRGAPcoDH5xYJxrG2p5FH_Dh_MQ0ugDnJY2_b_-w9NS2Y2atIkzXZDjtcSpjImKpL0eIFF69ptiF8vd4q2j-"
524 "ougipFBGP9U5bSVzeZ7FyGkJ5Qa2DYc0osYi1QFs3YZKzkKfcblx14u-yZYhUkZHlb_jbfulnUHxDdO_r8Q\""
525 "}";
START_TEST(test_cjose_jwk_to_json_rsa)526 START_TEST(test_cjose_jwk_to_json_rsa)
527 {
528 cjose_err err;
529 cjose_jwk_t *jwk = NULL;
530 cjose_jwk_rsa_keyspec spec;
531
532 memset(&spec, 0, sizeof(cjose_jwk_rsa_keyspec));
533 cjose_base64url_decode(RSA_e, strlen(RSA_e), &spec.e, &spec.elen, &err);
534 cjose_base64url_decode(RSA_n, strlen(RSA_n), &spec.n, &spec.nlen, &err);
535 cjose_base64url_decode(RSA_d, strlen(RSA_d), &spec.d, &spec.dlen, &err);
536 cjose_base64url_decode(RSA_p, strlen(RSA_p), &spec.p, &spec.plen, &err);
537 cjose_base64url_decode(RSA_q, strlen(RSA_q), &spec.q, &spec.qlen, &err);
538 cjose_base64url_decode(RSA_dp, strlen(RSA_dp), &spec.dp, &spec.dplen, &err);
539 cjose_base64url_decode(RSA_dq, strlen(RSA_dq), &spec.dq, &spec.dqlen, &err);
540 cjose_base64url_decode(RSA_qi, strlen(RSA_qi), &spec.qi, &spec.qilen, &err);
541
542 jwk = cjose_jwk_create_RSA_spec(&spec, &err);
543 cjose_get_dealloc()(spec.e);
544 cjose_get_dealloc()(spec.n);
545 cjose_get_dealloc()(spec.d);
546 cjose_get_dealloc()(spec.p);
547 cjose_get_dealloc()(spec.q);
548 cjose_get_dealloc()(spec.dp);
549 cjose_get_dealloc()(spec.dq);
550 cjose_get_dealloc()(spec.qi);
551
552 char *json;
553 json = cjose_jwk_to_json(jwk, false, &err);
554 ck_assert(NULL != json);
555 ck_assert_str_eq(RSA_PUBLIC_JSON, json);
556 free(json);
557
558 json = cjose_jwk_to_json(jwk, true, &err);
559 ck_assert(NULL != json);
560 ck_assert_str_eq("{\"kty\":\"RSA\",\"e\":\"AQAB\""
561 ",\"n\":\"2Rgbvu_cGMpvVl8DE6aGGX7IE2lKn5c9ZtexriFrCLqBbKt2TBOZkoCn_AbcDjUVk23CxsIj9Z1VfsL_0UeVA_AeOLUWw0F5-"
562 "JhoK6NBeLpYZOz7HYieTOSJjSxYhoCYtVbLKI27e3NEvckxTs-90CdKl71P7YwrdSrY59hR-u2etyNCRGAPcoDH5xYJxrG2p5FH_Dh_"
563 "MQ0ugDnJY2_b_-w9NS2Y2atIkzXZDjtcSpjImKpL0eIFF69ptiF8vd4q2j-"
564 "ougipFBGP9U5bSVzeZ7FyGkJ5Qa2DYc0osYi1QFs3YZKzkKfcblx14u-yZYhUkZHlb_jbfulnUHxDdO_r8Q\""
565 ",\"d\":\"P9N6tNRIXXGG8lnUyb43xt8ja7GVIv6QKuBXeN6SXWqYCp8OlKdei1gQC2To5bRtt36ZuV3yvI-ZRz-"
566 "Ffr4Q7at29y0mmBl0BsaoOcwxv5Dp1CJoYfJ8uBao6jyTelfsjcQKzs18xXrKRxIT0Rv6rmwe3iXmjeycCkKiqudKkv8m9RtbvdWH8AFd2ZsC"
567 "LNblVRrOZ9ZPQQCMVJLf65pF_cBfux-Zz_CJCfq93gFcN3h1tPFLX8UPBMqvqkBZzDx8PGoYgrydz-T8tcqtkDriyEL3mGYe9b2uH_"
568 "8JnzMMNMFheVPDdNBhyQQVOmQqPj7idv7677eSle4LJZANUYZdwQ\""
569 ",\"p\":\"8Yhaq4UMiFptSuUMcLUqOJdZ9Jr0z2KG_ZrPaaHIX8gfbtp5DGjhXEE--SwoX9ukEzR6vCewSFcEl20wnT0uTwrVs-Bf2J1L-"
570 "5tKKeiiwLQxXtk1cG5-PI-ECkqX0AP2K2Xa0wpIjldBE5SBR0S7whANpKxhVFMtNgKog4xNvxU\""
571 ",\"q\":\"5hkENNaWQSJ5qWXVJYh0LAHddr1NXwkKIfKNjK8vCYfOHXDgKxW4UbAIu7wIU9iZcVjTdN2UcaJMe5fBQR9ZEP8bcuY9ZpeUCkv-"
572 "g9IGw69HUXE7ERBz1es_lZOuJzENwL85Al7jOtVJ2y26g4r30q4jqaL7CcgUZjBKAytjUG0\""
573 ",\"dp\":\"pAn1epQsRNcVb05Muqdv-2tfnu824TqLb-YahCVqjxK9tm4O1EzO8fcmK9i_uwrTTm_QA8X4xcjDx4xS_"
574 "he1Qd2b8kSrE9UQ69s17WygTLyU41QmJSwF9F-MT-kFXjOylxrgGYDccj_0ZLXxb1PRKSX5_iNNHxY2mH4JsP4zN1k\""
575 ",\"dq\":\"gTTxAL6y9vZl_PKa4w2htoiBlMiuJryLvQ5X3_ULY72nxy54Ipl6vBwue0UWJAcP-u8XJpu6XKj3a7uGoIv61ql5_"
576 "2Y8elyJm9Kao-kPNVk6oggEVAu6EBiext57v7Qy9dYrLCKeVI4qf_JIts8VZG-2xO4pK4_3rH5XQTpe9W0\""
577 ",\"qi\":\"xTJ_ON_6kc9g3ZbunSSt_oqJBguxH2x8HVl2KQXafW-F0_DOv09P1e0fbSdOLhR-V9lLjq8DxOcvCMxkpQr2G8lTaBRVTF_-"
578 "szu9adi9bgb_-egvc_NAvRkuGE9fUmB2_nAyU-j4VUh1MMSP5qqQhMYvFdAF5y36MpI-pV1SLFQ\""
579 "}",
580 json);
581 free(json);
582
583 cjose_jwk_release(jwk);
584 }
585 END_TEST
586
START_TEST(test_cjose_jwk_import_json_valid)587 START_TEST(test_cjose_jwk_import_json_valid)
588 {
589 cjose_err err;
590 static const char *JWK[] = {
591 // EC P-256
592 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
593 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
594 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
595 "\"kid\": \"4E34BAFD-E5D9-479C-964D-009C419C38DB\" }",
596
597 // EC P-256, attributes rearranged
598 "{ \"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
599 "\"kid\": \"05A9BE36-CBBD-43F4-ACC2-8C7823B2DE23\", "
600 "\"kty\": \"EC\", \"crv\": \"P-256\", "
601 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\"}",
602
603 // EC P-256, no 'kid'
604 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
605 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
606 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\"}",
607
608 // EC P-256, empty 'kid'
609 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
610 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
611 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
612 "\"kid\": \"\" }",
613
614 // EC P-256, empty 'kid'
615 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
616 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
617 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
618 "\"kid\": null }",
619
620 // EC P-256 with private key 'd'
621 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
622 "\"x\": \"ccXrxIe0aS32y9kBkZFfAh6f7UvdcowtGH5uxCIo7eY\", "
623 "\"y\": \"GGQACnDgoiQvdQTsv1KxNUzOjZgnNoO4wQe_F75-bb0\", "
624 "\"kid\": \"F2BF329A-151B-4066-AB92-1CCA0C0F9DB5\", "
625 "\"d\": \"hWdoUQvCWta1UQhC0nkTG0fHLFjWpDLv5wucVyq4-HY\" }",
626
627 // EC P-384
628 "{ \"kty\": \"EC\", \"crv\": \"P-384\", "
629 "\"x\": \"pO1SWmH7uOJfrtU1ibqVVK7VHffbpZtGfPYMPP_5KLQO9Dtsy41UEkMlL3BWHJDH\", "
630 "\"y\": \"RdBNoaV42bRE55V8PJR3Toeo8omQAIHPboOa7LlbQSGPYp6H6zW0tKroPquJYr3w\", "
631 "\"kid\": \"55680752-989A-4C5C-BC6E-48602489865C\" }",
632
633 // EC P-521
634 "{ \"kty\": \"EC\", \"crv\": \"P-521\", "
635 "\"x\": \"AC8xogZa6uKAPU8086yAlG_inL3BaRyTB0pQUIJMENsPV_4S32DxIEEellMzQ_ts1Egp6OyS3ewjCUKHv5CTF7IV\", "
636 "\"y\": \"AIR1I2rUew5WyetOHYC-arEDDk2R30Yto6TTot92l4aY0DL8pSYxPVwv9beFUJEl95o_1Vv5y1453nFZW1Ca0uUj\", "
637 "\"kid\": \"A3EAB438-EBF8-4FEC-B605-A67C3A0D2313\" }",
638
639 // RSA 2048 public params only
640 "{ \"kty\": \"RSA\", "
641 "\"e\": \"AQAB\", "
642 "\"n\": "
643 "\"zSNO12-ydrm-bheszVm2ZvycKrSV2CN0xqQHPxB4yT8MFlWfopMA2Imt4EkILfPfZPeUYV6lElCjoY_4GBtQOy_"
644 "e4RvDSMC0pqt5X4e6mjQvLsaAClkBmhhCYd-Vn9XIC3rSeAmBpSJDuwq_RTweXSG0hb_bn5FHf1Bl_"
645 "ekEBUsm0Xq4p6N5DjC0ImNP74G0qxBVJzu07qsCJzYpifYYoEYkwIY7S4jqyHv55wiuMt89VTl37y8VFR3ll6RPiPFa4Raiminw5wKNJEmrGEukabibspiC0Xv"
646 "WEMXj_zk0YnVTGAGdZeDPwnjYY6JUOJ9KgcYkiQYb9SXetsjSbyheZw\", "
647 "\"kid\": \"05F24DC3-59F4-4AC5-9849-F2F5EA8A6F3E\" }",
648
649 // RSA 2048 public and private params with CRT params
650 "{ \"kty\": \"RSA\", "
651 "\"e\": \"AQAB\", "
652 "\"n\": "
653 "\"zSNO12-ydrm-bheszVm2ZvycKrSV2CN0xqQHPxB4yT8MFlWfopMA2Imt4EkILfPfZPeUYV6lElCjoY_4GBtQOy_"
654 "e4RvDSMC0pqt5X4e6mjQvLsaAClkBmhhCYd-Vn9XIC3rSeAmBpSJDuwq_RTweXSG0hb_bn5FHf1Bl_"
655 "ekEBUsm0Xq4p6N5DjC0ImNP74G0qxBVJzu07qsCJzYpifYYoEYkwIY7S4jqyHv55wiuMt89VTl37y8VFR3ll6RPiPFa4Raiminw5wKNJEmrGEukabibspiC0Xv"
656 "WEMXj_zk0YnVTGAGdZeDPwnjYY6JUOJ9KgcYkiQYb9SXetsjSbyheZw\", "
657 "\"kid\": \"F7D90C71-6671-4064-A0AA-379AD1862D19\", "
658 "\"d\": "
659 "\"bixuZapp0PYFXp98gXWTT1CQlycR61lvmFf0RFyWYo9n8H7gE7KcG7AmIHVY3UVDT7jgikMIqQOCPn1SI7BXsNIPBBujEGnfHDywHSyKfdNVG-"
660 "wkTGptP9OTo3kvpP5uSCwY6btBU-1JLyWggJC_RgmaKNNYIyUlny0Q-gOx0x0I-6ipWyLQVdKZBkw6erSODM244sPU9qEmyzVW7Nbmo5PKC1U4w-"
661 "Dt4nBe19TIUHG-ggN_UDRauljbegIIcnEWWeXdJZDdPUHgmIRa2ODN0mfSKl1CB4LJ2eyKlmddGLFiHys44OVwA8LVzrodUixIQP6wQ02AUwlaYU_"
662 "BWLEVoQ\", "
663 "\"p\": "
664 "\"9GRrzfmxrL_WgSKXexO6uc2hWh-lV9bPfBU735uHUFBS2_OOUjtQSYSqm-HK2ND1EIlPZBEEu9ccdshaEVYx79eP5fRnpF8EKEo1W-eeinmn7pQsfR-"
665 "6kFzkKmdBVhUyfpZvWtNuIwNZLu-HEvF2eIVVauQtJCPnjeYFbDyveqk\", "
666 "\"q\": "
667 "\"1uGXUwk052ayLvpYx3-L272X5srOyme3PCS2W1AZBXnXK06jqFp_KqUDpPnL3MNYZlfoYW5HIQBNpGCcZaTwfdLnSZroSbkQk-"
668 "9w3zfsOiJplDbZb77mG6xbw7m7AqcNQA6szoGlCrxluE74apKg4dUOg5rEx8-LOeK90rz-So8\", "
669 "\"dp\": "
670 "\"D36KYy2weQ5UkC1cQz5V-U-zKh6VggMpdml2OVAH_SyKhE1luYrvJSoXEvj2vlZJIzpBYUu-7BXQRSugoja_xb_57I9ZPs-"
671 "TWOaTiXce0xKxdevJAknPrzVkddfECawgXmw1NSHweqHMtrAS9T1_0FZLuxIqVn88P__UWi9ixLk\", "
672 "\"dq\": "
673 "\"J733d-MXBslGoUuqCdO8MTsCkivmTScbi6Mamw7YYdvkAN19hVCffmqgnu2YV89FVUBi-UolG6Rrt8AqjN4RoKPWJRXiamgw-"
674 "btqO86jASmGL2RpmLJM6sdY_X0nalktKTDNoy_1L2QiyBDK_yL5YGtAUPTZ-j6XeHBIPWa4_V8\", "
675 "\"qi\": "
676 "\"DJcZFEvdjynkwHEOrTSXLezReXT8bj73eo7Yoadtbln27nD_8q5yAobHVOO9ZzrwSoDCeepW_fVotgMuqxdGIBXZB_"
677 "DboRvjWW0QuBZ7Lg2SwwQqi9Ve8w31Z36gvOr1fR-Bd12B5STepC4SYBn1u5uMG5AIgfgzoa-FXEEBgB8\" }",
678
679 // RSA 4096 public and private params, without CRT params
680 "{ \"kty\": \"RSA\", "
681 "\"e\": \"AQAB\", "
682 "\"n\": "
683 "\"vlbWUA9HUDHB5MDotmXObtE_Y4zKtGNtmPHUy_xkp_fSr0BxNdSOUzvzoAhK3sxTqpzVujKC245RHJ84Hhbl-KDj-"
684 "n7Ee8EV3nKpnsqiBgHyc3rBpxpIi0J8kYmpiPGXu7k4xnCWCeiu_gfFGzvPdLHzlV7WOfYIHvymtbS7WOyTQLBgDjUKfHdJzH75vogy35h_mEcS-pde-"
685 "EIi7u4OqD3bNW7iLbf2JVLtSNUYNCMMu23GsOEcBAsdf4QMq5gU-AEFK4Aib8mSPi_tXoohembr-"
686 "JkzByRAkHbdzoGXssj0EHESt4reDfY8enVo5ACKmzbqlIJ1jmPVV6EKPBPzcQiN9dUA43xei2gmRAswdUKnexVPAPFPfKMpLqr24h1e7jHFBQL23-QqZX-"
687 "gASbEDiYa9GusSY4kRn80hZRqCq4sgIRVEiu3ofjVdo4YzzESAkmfgFayUThhakqP82_wr9_Uc2vw3ZtlaTC_"
688 "0LY70ne9yTy3SD3yEOa649nOTBfSh156YGtxvaHHidFojVHpPHBmjGAlak--mONHXHn00l_CVivUcuBqIGcZXRfiO6YwVDH_4ZTVzAkDov1C-"
689 "4SNJK0XKeIwvGSspaSQrTmH_pT66L7tIhdZLTMVMh2ahnInVZP2G_-motugLq-x962JLQuLLeuh_r_Rk4VHZYhOgoc\", "
690 "\"kid\": \"2940921e-3646-451c-8510-971552754e74\", "
691 "\"d\": "
692 "\"oMyvxXcC4icHDQBEGUOswEYabTmWTgrpnho_kg0p5BUjclbYzYdCreKqEPqwdcTcsfhJP0JI9r8mmy2PtSvXINKbhxXtXDdlCEaKMdIySyz97L06OLelrbB_"
693 "mFxaU4z2iOsToeGff8OJgqaByF4hBw8HH5u9E75cYgFDvaJv29IRHMdkftwkfb4xJIfo6SQbBnbI5Ja22-"
694 "lhnA4TgRKwY0XOmTeR8NnHIwUJ3UvZZMJvkTBOeUPT7T6OrxmZsqWKoXILMhLQBOyfldXbjNDZM5UbqSuTxmbD_"
695 "MfO3xTwWWQXfIRqMZEpw1XRBguGj4g9kJ82Ujxcn-yLYbp08QhR0ijBY13HzFVMZ2jxqckrvp3uYgfJjcCN9QXZ6qlv40s_"
696 "vJRRgv4wxdDc035eoymqGQby0UnDTmhijRV_-eAJQvdl3bv-R5dH9IzhxoJA8xAqZfVtlehPuGaXDAsa4pIWSg9hZkMdDEjW15g3zTQi3ba8_"
697 "MfmnKuDe4GXYBjrH69z7epxbhnTmKQ-fZIxboA9sYuJHj6pEGT8D485QmrnmLjvqmQUzcxnpU6E3awksTp_"
698 "HeBYLLbmrv4DPGNyVri2yPPTTRrNBtbWkuvEGVnMhvL2ed9uqLSnH8zOfgWqstqjxadxKADidYEZzmiYfEjYTDZGd9VDIUdKNGHWGFRB7UE\", "
699 "\"p\": "
700 "\"6VtjaNMD_VKTbs7sUQk-qjPTn6mCI8_3loqrOOy32b1G0HfIzCijuV-"
701 "L7g7RxmMszEEfEILxRpJnOZRehN8etsIEuCdhU6VAdhBsBH5hIA9ZtX8GIs0sPrhc4kzPiwJ6JcLytUc6HCTICf2FIU7SI8I17-"
702 "p53d35VItYiC1sGLZ2yN61VoKYNTncUSwboP2zXmGv4FPB5wQogryA_bEn-"
703 "1U12FFSRd75Ku9GAEVxbTk3OaQqYgqfo9LnAWvunTDu31D4uyC6rze77NCo8UguqCpFjvF0ihOryQI6C3d0e8kxcM1vJbMvZNfrDN65btzqWi4m-"
704 "CnqGYkl6BXQtS5UVw\", "
705 "\"q\": "
706 "\"0M7h_gtxoVoNPLRjYA5zBUD8qmyWiAzjloFOrDRLJwiD4OPHgImUx2WPTiSCjouvGqwfJh1jEEryJV_d0e4iVGyKYbFeXfzadwYXXR2jK4QwO1V_"
707 "JDHI7HUYwNl6qzZqATi2zNKunPgIwY55gWBKjP2aUvPUBAcTeCsUPvrN_SajPVfc2wSlA2TvEnjmweNvgSTNqtBlMpmpwvEb9WXfv4pl3BfRvoTk3VR4icyvl-"
708 "PLFedp2y0Fs0aQ4LRQ2ZMKWyGQEam_uAoa1tXrRJ_yQRvtWm1K8GpRZGKwN3TvtAg649PxQ7tJ8cvh3BwQROJyQBZDrlR04wqvDK4SNezlUQ\" }",
709
710 // oct 256
711 "{ \"kty\": \"oct\", "
712 "\"kid\": \"b779034d-2e9b-44a8-8334-55d6b7a0ef59\", "
713 "\"k\": \"wsL6R8uXG4RnsckLggj9Lg-kE5MMSJ8luzIBA8j7WXE\" }",
714
715 // oct 512
716 "{ \"kty\": \"oct\", "
717 "\"kid\": \"0c17c6d8-307d-4e4a-a860-a14788ee1110\", "
718 "\"k\": \"qKcFDl6VSS7CgMpdF9we9JFEenMQniO-8lQ0DvFI1jzfTb93H2Gc0YzO4iNEZ7VPN6p0l-PyA4vlOrn0hPS5qA\" }",
719
720 // oct 1024
721 "{ \"kty\": \"oct\", "
722 "\"kid\": \"3dfc3c58-74fd-4b8a-88d6-5321b30b554c\", "
723 "\"k\": "
724 "\"dCDW6NH5DkKtH6dTsRm_yJchQtrVxD_ZjDob3UquMBoAwdtVIjKvMztbP4XQE7Gf_QjzEa58_UrI80QzBxG_UpFxzpjTOBfWz8Do1BHZak_"
725 "W1KBWDyfnEqc8RtxZmc4yE1dko5B8GUyfplMrEFa2tO899hnGe7pqRVdiwFF5QkY\" }",
726
727 NULL,
728 };
729
730 cjose_jwk_t *jwk = NULL;
731 for (int i = 0; JWK[i] != NULL; ++i)
732 {
733 // get json representation of "before"
734 json_t *left_json = json_loads(JWK[i], 0, NULL);
735 ck_assert(NULL != left_json);
736
737 // do import
738 jwk = cjose_jwk_import_json((cjose_header_t *)left_json, &err);
739 ck_assert_msg(NULL != jwk,
740 "expected a cjose_jwk_t, but got NULL (%s) : "
741 "%s, file: %s, function: %s, line: %ld",
742 JWK[i], err.message, err.file, err.function, err.line);
743
744 // get json representation of "after"
745 char *jwk_str = cjose_jwk_to_json(jwk, true, &err);
746 json_t *right_json = json_loads(jwk_str, 0, NULL);
747 ck_assert(NULL != right_json);
748
749 // check that cooresponding attributes match up
750 const char *attrs[] = { "kty", "crv", "x", "y", "d", "kid", "e", "n", "p", "q", "dp", "dq", "qi", NULL };
751 if (!_match_string_attrs(left_json, right_json, attrs))
752 {
753 ck_assert_str_eq(JWK[i], jwk_str);
754 }
755
756 free(jwk_str);
757 json_decref(left_json);
758 json_decref(right_json);
759 cjose_jwk_release(jwk);
760 }
761 }
762 END_TEST
763
START_TEST(test_cjose_jwk_import_json_invalid)764 START_TEST(test_cjose_jwk_import_json_invalid)
765 {
766 cjose_err err;
767 static const char *JWK[] = {
768 // EC P-256 invalid 'kty'
769 "{ \"kty\": \"EMC\", \"crv\": \"P-256\", "
770 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
771 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
772 "\"kid\": \"0406E98B-CE84-4C78-965A-84C53BA73A1E\" }",
773
774 // EC P-256 missing 'kty'
775 "{ \"crv\": \"P-256\", "
776 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
777 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
778 "\"kid\": \"EE05B07C-22ED-4059-A50B-4AD0A48E28D4\" }",
779
780 // EC P-256 invalid 'crv'
781 "{ \"kty\": \"EC\", \"crv\": \"P-257\", "
782 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
783 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
784 "\"kid\": \"BB70E4BD-9547-4566-9195-1C45777D368B\" }",
785
786 // EC P-256 missing 'crv'
787 "{ \"kty\": \"EC\", "
788 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
789 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
790 "\"kid\": \"928D103F-8DF2-41D5-A42B-7A72508FC70E\" }",
791
792 // EC P-256 invalid 'x' (truncated)
793 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
794 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20\", "
795 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
796 "\"kid\": \"685A7314-EBE1-4E1A-A81D-8AB4A1B56452\" }",
797
798 // EC P-256 invalid 'x' (a number)
799 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
800 "\"x\": 42, "
801 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
802 "\"kid\": \"5B3F3AB3-E716-4D85-8E4A-4BAC0D7D64E8\" }",
803
804 // EC P-256 missing 'x'
805 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
806 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
807 "\"kid\": \"9354D170-5FA4-46B5-901D-38098716E28A\" }",
808
809 // EC P-256 invalid 'y' (truncated)
810 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
811 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
812 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRg\", "
813 "\"kid\": \"262DDF7E-1AB5-43D1-91EA-13B99779DF16\" }",
814
815 // EC P-256 invalid 'y' (an object)
816 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
817 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
818 "\"y\": {}, "
819 "\"kid\": \"1BEFD34C-A86E-4512-B206-7A2B94D82D27\" }",
820
821 // EC P-256 missing 'y'
822 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
823 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
824 "\"kid\": \"CBA61EED-3C61-45B3-9A35-9DE03F247720\" }",
825
826 // EC P-384 invalid 'x' (truncated)
827 "{ \"kty\": \"EC\", \"crv\": \"P-384\", "
828 "\"x\": \"pO1SWmH7uOJfrtU1ibqVVK7VHffbpZtGfPYMPP_5KLQO9Dtsy41UEkMlL3BWHJD\", "
829 "\"y\": \"RdBNoaV42bRE55V8PJR3Toeo8omQAIHPboOa7LlbQSGPYp6H6zW0tKroPquJYr3w\", "
830 "\"kid\": \"FFC23684-88C8-4783-BBA3-ABF29971943B\" }",
831
832 // EC P-521 invalid 'x' (truncated)
833 "{ \"kty\": \"EC\", \"crv\": \"P-521\", "
834 "\"x\": \"AVq9Y0jEvSINQJzcExSIUWYjo73cJcVTz_QHXCU7p9rbmC8chFdACiGLKDKlzdgW6lhZzA5qnp8mkpS2qJO_EVxU\", "
835 "\"y\": \"AQHcQF8s_dhS_84CKLll0vkr0xCqWLp5XXdb79coYWI7Ev9SwZ4UZZVPxgu7ZGyp_2WdtaWw68uYeUVU4WiyKfP\", "
836 "\"kid\": \"3930AC1C-C02F-46DA-9730-87785F405FE8\" }",
837
838 // RSA 2048 missing 'n' (needed for both public and private)
839 "{ \"kty\": \"RSA\", "
840 "\"e\": \"AQAB\", "
841 "\"kid\": \"05F24DC3-59F4-4AC5-9849-F2F5EA8A6F3E\" }",
842
843 // empty object
844 "{}",
845
846 // empty string
847 "\"\"",
848
849 // a number
850 "5",
851
852 // null JWK
853 "null",
854
855 NULL,
856 };
857
858 cjose_jwk_t *jwk = NULL;
859 for (int i = 0; JWK[i] != NULL; ++i)
860 {
861 json_t *left_json = json_loads(JWK[i], 0, NULL);
862 jwk = cjose_jwk_import_json((cjose_header_t *)left_json, &err);
863 ck_assert_msg(NULL == jwk, "expected NULL, received a cjose_jwk_t");
864 ck_assert_int_eq(err.code, CJOSE_ERR_INVALID_ARG);
865 cjose_jwk_release(jwk);
866 }
867 }
868 END_TEST
869
START_TEST(test_cjose_jwk_import_valid)870 START_TEST(test_cjose_jwk_import_valid)
871 {
872 cjose_err err;
873 static const char *JWK[] = {
874 // EC P-256
875 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
876 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
877 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
878 "\"kid\": \"4E34BAFD-E5D9-479C-964D-009C419C38DB\" }",
879
880 // EC P-256, attributes rearranged
881 "{ \"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
882 "\"kid\": \"05A9BE36-CBBD-43F4-ACC2-8C7823B2DE23\", "
883 "\"kty\": \"EC\", \"crv\": \"P-256\", "
884 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\"}",
885
886 // EC P-256, no 'kid'
887 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
888 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
889 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\"}",
890
891 // EC P-256, empty 'kid'
892 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
893 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
894 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
895 "\"kid\": \"\" }",
896
897 // EC P-256, empty 'kid'
898 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
899 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
900 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
901 "\"kid\": null }",
902
903 // EC P-256 with private key 'd'
904 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
905 "\"x\": \"ccXrxIe0aS32y9kBkZFfAh6f7UvdcowtGH5uxCIo7eY\", "
906 "\"y\": \"GGQACnDgoiQvdQTsv1KxNUzOjZgnNoO4wQe_F75-bb0\", "
907 "\"kid\": \"F2BF329A-151B-4066-AB92-1CCA0C0F9DB5\", "
908 "\"d\": \"hWdoUQvCWta1UQhC0nkTG0fHLFjWpDLv5wucVyq4-HY\" }",
909
910 // EC P-384
911 "{ \"kty\": \"EC\", \"crv\": \"P-384\", "
912 "\"x\": \"pO1SWmH7uOJfrtU1ibqVVK7VHffbpZtGfPYMPP_5KLQO9Dtsy41UEkMlL3BWHJDH\", "
913 "\"y\": \"RdBNoaV42bRE55V8PJR3Toeo8omQAIHPboOa7LlbQSGPYp6H6zW0tKroPquJYr3w\", "
914 "\"kid\": \"55680752-989A-4C5C-BC6E-48602489865C\" }",
915
916 // EC P-521
917 "{ \"kty\": \"EC\", \"crv\": \"P-521\", "
918 "\"x\": \"AC8xogZa6uKAPU8086yAlG_inL3BaRyTB0pQUIJMENsPV_4S32DxIEEellMzQ_ts1Egp6OyS3ewjCUKHv5CTF7IV\", "
919 "\"y\": \"AIR1I2rUew5WyetOHYC-arEDDk2R30Yto6TTot92l4aY0DL8pSYxPVwv9beFUJEl95o_1Vv5y1453nFZW1Ca0uUj\", "
920 "\"kid\": \"A3EAB438-EBF8-4FEC-B605-A67C3A0D2313\" }",
921
922 // RSA 2048 public params only
923 "{ \"kty\": \"RSA\", "
924 "\"e\": \"AQAB\", "
925 "\"n\": "
926 "\"zSNO12-ydrm-bheszVm2ZvycKrSV2CN0xqQHPxB4yT8MFlWfopMA2Imt4EkILfPfZPeUYV6lElCjoY_4GBtQOy_"
927 "e4RvDSMC0pqt5X4e6mjQvLsaAClkBmhhCYd-Vn9XIC3rSeAmBpSJDuwq_RTweXSG0hb_bn5FHf1Bl_"
928 "ekEBUsm0Xq4p6N5DjC0ImNP74G0qxBVJzu07qsCJzYpifYYoEYkwIY7S4jqyHv55wiuMt89VTl37y8VFR3ll6RPiPFa4Raiminw5wKNJEmrGEukabibspiC0Xv"
929 "WEMXj_zk0YnVTGAGdZeDPwnjYY6JUOJ9KgcYkiQYb9SXetsjSbyheZw\", "
930 "\"kid\": \"05F24DC3-59F4-4AC5-9849-F2F5EA8A6F3E\" }",
931
932 // RSA 2048 public and private params with CRT params
933 "{ \"kty\": \"RSA\", "
934 "\"e\": \"AQAB\", "
935 "\"n\": "
936 "\"zSNO12-ydrm-bheszVm2ZvycKrSV2CN0xqQHPxB4yT8MFlWfopMA2Imt4EkILfPfZPeUYV6lElCjoY_4GBtQOy_"
937 "e4RvDSMC0pqt5X4e6mjQvLsaAClkBmhhCYd-Vn9XIC3rSeAmBpSJDuwq_RTweXSG0hb_bn5FHf1Bl_"
938 "ekEBUsm0Xq4p6N5DjC0ImNP74G0qxBVJzu07qsCJzYpifYYoEYkwIY7S4jqyHv55wiuMt89VTl37y8VFR3ll6RPiPFa4Raiminw5wKNJEmrGEukabibspiC0Xv"
939 "WEMXj_zk0YnVTGAGdZeDPwnjYY6JUOJ9KgcYkiQYb9SXetsjSbyheZw\", "
940 "\"kid\": \"F7D90C71-6671-4064-A0AA-379AD1862D19\", "
941 "\"d\": "
942 "\"bixuZapp0PYFXp98gXWTT1CQlycR61lvmFf0RFyWYo9n8H7gE7KcG7AmIHVY3UVDT7jgikMIqQOCPn1SI7BXsNIPBBujEGnfHDywHSyKfdNVG-"
943 "wkTGptP9OTo3kvpP5uSCwY6btBU-1JLyWggJC_RgmaKNNYIyUlny0Q-gOx0x0I-6ipWyLQVdKZBkw6erSODM244sPU9qEmyzVW7Nbmo5PKC1U4w-"
944 "Dt4nBe19TIUHG-ggN_UDRauljbegIIcnEWWeXdJZDdPUHgmIRa2ODN0mfSKl1CB4LJ2eyKlmddGLFiHys44OVwA8LVzrodUixIQP6wQ02AUwlaYU_"
945 "BWLEVoQ\", "
946 "\"p\": "
947 "\"9GRrzfmxrL_WgSKXexO6uc2hWh-lV9bPfBU735uHUFBS2_OOUjtQSYSqm-HK2ND1EIlPZBEEu9ccdshaEVYx79eP5fRnpF8EKEo1W-eeinmn7pQsfR-"
948 "6kFzkKmdBVhUyfpZvWtNuIwNZLu-HEvF2eIVVauQtJCPnjeYFbDyveqk\", "
949 "\"q\": "
950 "\"1uGXUwk052ayLvpYx3-L272X5srOyme3PCS2W1AZBXnXK06jqFp_KqUDpPnL3MNYZlfoYW5HIQBNpGCcZaTwfdLnSZroSbkQk-"
951 "9w3zfsOiJplDbZb77mG6xbw7m7AqcNQA6szoGlCrxluE74apKg4dUOg5rEx8-LOeK90rz-So8\", "
952 "\"dp\": "
953 "\"D36KYy2weQ5UkC1cQz5V-U-zKh6VggMpdml2OVAH_SyKhE1luYrvJSoXEvj2vlZJIzpBYUu-7BXQRSugoja_xb_57I9ZPs-"
954 "TWOaTiXce0xKxdevJAknPrzVkddfECawgXmw1NSHweqHMtrAS9T1_0FZLuxIqVn88P__UWi9ixLk\", "
955 "\"dq\": "
956 "\"J733d-MXBslGoUuqCdO8MTsCkivmTScbi6Mamw7YYdvkAN19hVCffmqgnu2YV89FVUBi-UolG6Rrt8AqjN4RoKPWJRXiamgw-"
957 "btqO86jASmGL2RpmLJM6sdY_X0nalktKTDNoy_1L2QiyBDK_yL5YGtAUPTZ-j6XeHBIPWa4_V8\", "
958 "\"qi\": "
959 "\"DJcZFEvdjynkwHEOrTSXLezReXT8bj73eo7Yoadtbln27nD_8q5yAobHVOO9ZzrwSoDCeepW_fVotgMuqxdGIBXZB_"
960 "DboRvjWW0QuBZ7Lg2SwwQqi9Ve8w31Z36gvOr1fR-Bd12B5STepC4SYBn1u5uMG5AIgfgzoa-FXEEBgB8\" }",
961
962 // RSA 4096 public and private params, without CRT params
963 "{ \"kty\": \"RSA\", "
964 "\"e\": \"AQAB\", "
965 "\"n\": "
966 "\"vlbWUA9HUDHB5MDotmXObtE_Y4zKtGNtmPHUy_xkp_fSr0BxNdSOUzvzoAhK3sxTqpzVujKC245RHJ84Hhbl-KDj-"
967 "n7Ee8EV3nKpnsqiBgHyc3rBpxpIi0J8kYmpiPGXu7k4xnCWCeiu_gfFGzvPdLHzlV7WOfYIHvymtbS7WOyTQLBgDjUKfHdJzH75vogy35h_mEcS-pde-"
968 "EIi7u4OqD3bNW7iLbf2JVLtSNUYNCMMu23GsOEcBAsdf4QMq5gU-AEFK4Aib8mSPi_tXoohembr-"
969 "JkzByRAkHbdzoGXssj0EHESt4reDfY8enVo5ACKmzbqlIJ1jmPVV6EKPBPzcQiN9dUA43xei2gmRAswdUKnexVPAPFPfKMpLqr24h1e7jHFBQL23-QqZX-"
970 "gASbEDiYa9GusSY4kRn80hZRqCq4sgIRVEiu3ofjVdo4YzzESAkmfgFayUThhakqP82_wr9_Uc2vw3ZtlaTC_"
971 "0LY70ne9yTy3SD3yEOa649nOTBfSh156YGtxvaHHidFojVHpPHBmjGAlak--mONHXHn00l_CVivUcuBqIGcZXRfiO6YwVDH_4ZTVzAkDov1C-"
972 "4SNJK0XKeIwvGSspaSQrTmH_pT66L7tIhdZLTMVMh2ahnInVZP2G_-motugLq-x962JLQuLLeuh_r_Rk4VHZYhOgoc\", "
973 "\"kid\": \"2940921e-3646-451c-8510-971552754e74\", "
974 "\"d\": "
975 "\"oMyvxXcC4icHDQBEGUOswEYabTmWTgrpnho_kg0p5BUjclbYzYdCreKqEPqwdcTcsfhJP0JI9r8mmy2PtSvXINKbhxXtXDdlCEaKMdIySyz97L06OLelrbB_"
976 "mFxaU4z2iOsToeGff8OJgqaByF4hBw8HH5u9E75cYgFDvaJv29IRHMdkftwkfb4xJIfo6SQbBnbI5Ja22-"
977 "lhnA4TgRKwY0XOmTeR8NnHIwUJ3UvZZMJvkTBOeUPT7T6OrxmZsqWKoXILMhLQBOyfldXbjNDZM5UbqSuTxmbD_"
978 "MfO3xTwWWQXfIRqMZEpw1XRBguGj4g9kJ82Ujxcn-yLYbp08QhR0ijBY13HzFVMZ2jxqckrvp3uYgfJjcCN9QXZ6qlv40s_"
979 "vJRRgv4wxdDc035eoymqGQby0UnDTmhijRV_-eAJQvdl3bv-R5dH9IzhxoJA8xAqZfVtlehPuGaXDAsa4pIWSg9hZkMdDEjW15g3zTQi3ba8_"
980 "MfmnKuDe4GXYBjrH69z7epxbhnTmKQ-fZIxboA9sYuJHj6pEGT8D485QmrnmLjvqmQUzcxnpU6E3awksTp_"
981 "HeBYLLbmrv4DPGNyVri2yPPTTRrNBtbWkuvEGVnMhvL2ed9uqLSnH8zOfgWqstqjxadxKADidYEZzmiYfEjYTDZGd9VDIUdKNGHWGFRB7UE\", "
982 "\"p\": "
983 "\"6VtjaNMD_VKTbs7sUQk-qjPTn6mCI8_3loqrOOy32b1G0HfIzCijuV-"
984 "L7g7RxmMszEEfEILxRpJnOZRehN8etsIEuCdhU6VAdhBsBH5hIA9ZtX8GIs0sPrhc4kzPiwJ6JcLytUc6HCTICf2FIU7SI8I17-"
985 "p53d35VItYiC1sGLZ2yN61VoKYNTncUSwboP2zXmGv4FPB5wQogryA_bEn-"
986 "1U12FFSRd75Ku9GAEVxbTk3OaQqYgqfo9LnAWvunTDu31D4uyC6rze77NCo8UguqCpFjvF0ihOryQI6C3d0e8kxcM1vJbMvZNfrDN65btzqWi4m-"
987 "CnqGYkl6BXQtS5UVw\", "
988 "\"q\": "
989 "\"0M7h_gtxoVoNPLRjYA5zBUD8qmyWiAzjloFOrDRLJwiD4OPHgImUx2WPTiSCjouvGqwfJh1jEEryJV_d0e4iVGyKYbFeXfzadwYXXR2jK4QwO1V_"
990 "JDHI7HUYwNl6qzZqATi2zNKunPgIwY55gWBKjP2aUvPUBAcTeCsUPvrN_SajPVfc2wSlA2TvEnjmweNvgSTNqtBlMpmpwvEb9WXfv4pl3BfRvoTk3VR4icyvl-"
991 "PLFedp2y0Fs0aQ4LRQ2ZMKWyGQEam_uAoa1tXrRJ_yQRvtWm1K8GpRZGKwN3TvtAg649PxQ7tJ8cvh3BwQROJyQBZDrlR04wqvDK4SNezlUQ\" }",
992
993 // oct 256
994 "{ \"kty\": \"oct\", "
995 "\"kid\": \"b779034d-2e9b-44a8-8334-55d6b7a0ef59\", "
996 "\"k\": \"wsL6R8uXG4RnsckLggj9Lg-kE5MMSJ8luzIBA8j7WXE\" }",
997
998 // oct 512
999 "{ \"kty\": \"oct\", "
1000 "\"kid\": \"0c17c6d8-307d-4e4a-a860-a14788ee1110\", "
1001 "\"k\": \"qKcFDl6VSS7CgMpdF9we9JFEenMQniO-8lQ0DvFI1jzfTb93H2Gc0YzO4iNEZ7VPN6p0l-PyA4vlOrn0hPS5qA\" }",
1002
1003 // oct 1024
1004 "{ \"kty\": \"oct\", "
1005 "\"kid\": \"3dfc3c58-74fd-4b8a-88d6-5321b30b554c\", "
1006 "\"k\": "
1007 "\"dCDW6NH5DkKtH6dTsRm_yJchQtrVxD_ZjDob3UquMBoAwdtVIjKvMztbP4XQE7Gf_QjzEa58_UrI80QzBxG_UpFxzpjTOBfWz8Do1BHZak_"
1008 "W1KBWDyfnEqc8RtxZmc4yE1dko5B8GUyfplMrEFa2tO899hnGe7pqRVdiwFF5QkY\" }",
1009
1010 NULL,
1011 };
1012
1013 cjose_jwk_t *jwk = NULL;
1014 for (int i = 0; JWK[i] != NULL; ++i)
1015 {
1016 // do import
1017 jwk = cjose_jwk_import(JWK[i], strlen(JWK[i]), &err);
1018 ck_assert_msg(NULL != jwk, "expected a cjose_jwk_t, but got NULL (%s) : "
1019 "%s, file: %s, function: %s, line: %ld",
1020 JWK[i], err.message, err.file, err.function, err.line);
1021
1022 // get json representation of "before"
1023 json_t *left_json = json_loads(JWK[i], 0, NULL);
1024 ck_assert(NULL != left_json);
1025
1026 // get json representation of "after"
1027 char *jwk_str = cjose_jwk_to_json(jwk, true, &err);
1028 json_t *right_json = json_loads(jwk_str, 0, NULL);
1029 ck_assert(NULL != right_json);
1030
1031 // check that cooresponding attributes match up
1032 const char *attrs[] = { "kty", "crv", "x", "y", "d", "kid", "e", "n", "p", "q", "dp", "dq", "qi", NULL };
1033 if (!_match_string_attrs(left_json, right_json, attrs))
1034 {
1035 ck_assert_str_eq(JWK[i], jwk_str);
1036 }
1037
1038 free(jwk_str);
1039 json_decref(left_json);
1040 json_decref(right_json);
1041 cjose_jwk_release(jwk);
1042 }
1043 }
1044 END_TEST
1045
START_TEST(test_cjose_jwk_import_invalid)1046 START_TEST(test_cjose_jwk_import_invalid)
1047 {
1048 cjose_err err;
1049 static const char *JWK[] = {
1050 // EC P-256 invalid 'kty'
1051 "{ \"kty\": \"EMC\", \"crv\": \"P-256\", "
1052 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1053 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1054 "\"kid\": \"0406E98B-CE84-4C78-965A-84C53BA73A1E\" }",
1055
1056 // EC P-256 missing 'kty'
1057 "{ \"crv\": \"P-256\", "
1058 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1059 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1060 "\"kid\": \"EE05B07C-22ED-4059-A50B-4AD0A48E28D4\" }",
1061
1062 // EC P-256 invalid 'crv'
1063 "{ \"kty\": \"EC\", \"crv\": \"P-257\", "
1064 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1065 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1066 "\"kid\": \"BB70E4BD-9547-4566-9195-1C45777D368B\" }",
1067
1068 // EC P-256 missing 'crv'
1069 "{ \"kty\": \"EC\", "
1070 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1071 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1072 "\"kid\": \"928D103F-8DF2-41D5-A42B-7A72508FC70E\" }",
1073
1074 // EC P-256 invalid 'x' (truncated)
1075 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1076 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20\", "
1077 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1078 "\"kid\": \"685A7314-EBE1-4E1A-A81D-8AB4A1B56452\" }",
1079
1080 // EC P-256 invalid 'x' (a number)
1081 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1082 "\"x\": 42, "
1083 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1084 "\"kid\": \"5B3F3AB3-E716-4D85-8E4A-4BAC0D7D64E8\" }",
1085
1086 // EC P-256 missing 'x'
1087 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1088 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1089 "\"kid\": \"9354D170-5FA4-46B5-901D-38098716E28A\" }",
1090
1091 // EC P-256 invalid 'y' (truncated)
1092 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1093 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1094 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRg\", "
1095 "\"kid\": \"262DDF7E-1AB5-43D1-91EA-13B99779DF16\" }",
1096
1097 // EC P-256 invalid 'y' (an object)
1098 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1099 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1100 "\"y\": {}, "
1101 "\"kid\": \"1BEFD34C-A86E-4512-B206-7A2B94D82D27\" }",
1102
1103 // EC P-256 missing 'y'
1104 "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1105 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1106 "\"kid\": \"CBA61EED-3C61-45B3-9A35-9DE03F247720\" }",
1107
1108 // EC P-384 invalid 'x' (truncated)
1109 "{ \"kty\": \"EC\", \"crv\": \"P-384\", "
1110 "\"x\": \"pO1SWmH7uOJfrtU1ibqVVK7VHffbpZtGfPYMPP_5KLQO9Dtsy41UEkMlL3BWHJD\", "
1111 "\"y\": \"RdBNoaV42bRE55V8PJR3Toeo8omQAIHPboOa7LlbQSGPYp6H6zW0tKroPquJYr3w\", "
1112 "\"kid\": \"FFC23684-88C8-4783-BBA3-ABF29971943B\" }",
1113
1114 // EC P-521 invalid 'x' (truncated)
1115 "{ \"kty\": \"EC\", \"crv\": \"P-521\", "
1116 "\"x\": \"AVq9Y0jEvSINQJzcExSIUWYjo73cJcVTz_QHXCU7p9rbmC8chFdACiGLKDKlzdgW6lhZzA5qnp8mkpS2qJO_EVxU\", "
1117 "\"y\": \"AQHcQF8s_dhS_84CKLll0vkr0xCqWLp5XXdb79coYWI7Ev9SwZ4UZZVPxgu7ZGyp_2WdtaWw68uYeUVU4WiyKfP\", "
1118 "\"kid\": \"3930AC1C-C02F-46DA-9730-87785F405FE8\" }",
1119
1120 // RSA 2048 missing 'n' (needed for both public and private)
1121 "{ \"kty\": \"RSA\", "
1122 "\"e\": \"AQAB\", "
1123 "\"kid\": \"05F24DC3-59F4-4AC5-9849-F2F5EA8A6F3E\" }",
1124
1125 // empty object
1126 "{}",
1127
1128 // empty string
1129 "\"\"",
1130
1131 // null JWK
1132 "null",
1133
1134 // a number
1135 "5",
1136
1137 // nothing
1138 "",
1139
1140 // junk
1141 "!@#$%^&*()",
1142
1143 NULL,
1144 };
1145
1146 cjose_jwk_t *jwk = NULL;
1147 for (int i = 0; JWK[i] != NULL; ++i)
1148 {
1149 jwk = cjose_jwk_import(JWK[i], strlen(JWK[i]), &err);
1150 ck_assert_msg(NULL == jwk, "expected NULL, received a cjose_jwk_t");
1151 ck_assert_int_eq(err.code, CJOSE_ERR_INVALID_ARG);
1152 cjose_jwk_release(jwk);
1153 }
1154 }
1155 END_TEST
1156
START_TEST(test_cjose_jwk_import_underflow_length)1157 START_TEST(test_cjose_jwk_import_underflow_length)
1158 {
1159 cjose_err err;
1160 static const char *JWK = "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1161 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1162 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1163 "\"kid\": \"CF21823B-D7C3-4C7F-BBE9-F11745E6BD21\" }";
1164
1165 cjose_jwk_t *jwk = NULL;
1166
1167 // test zero json doc length
1168 jwk = cjose_jwk_import(JWK, 0, &err);
1169 ck_assert_msg(NULL == jwk, "expected NULL, received a cjose_jwk_t");
1170 cjose_jwk_release(jwk);
1171
1172 // test truncated length
1173 jwk = cjose_jwk_import(JWK, 10, &err);
1174 ck_assert_msg(NULL == jwk, "expected NULL, received a cjose_jwk_t");
1175 cjose_jwk_release(jwk);
1176 }
1177 END_TEST
1178
START_TEST(test_cjose_jwk_import_no_zero_termination)1179 START_TEST(test_cjose_jwk_import_no_zero_termination)
1180 {
1181 cjose_err err;
1182 static const char *JWK = "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1183 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1184 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1185 "\"kid\": \"7CD876ED-6404-443A-8BBD-D4C1C99B6F71\" }, "
1186 "{ \"kty\": \"EC\", \"crv\": \"P-384\", "
1187 "\"x\": \"pO1SWmH7uOJfrtU1ibqVVK7VHffbpZtGfPYMPP_5KLQO9Dtsy41UEkMlL3BWHJD\", "
1188 "\"y\": \"RdBNoaV42bRE55V8PJR3Toeo8omQAIHPboOa7LlbQSGPYp6H6zW0tKroPquJYr3w\", "
1189 "\"kid\": \"7CD876ED-6404-443A-8BBD-D4C1C99B6F71\" }";
1190
1191 cjose_jwk_t *jwk = NULL;
1192
1193 // do import providing length of just the first key (which is length 182)
1194 jwk = cjose_jwk_import(JWK, 182, &err);
1195 ck_assert_msg(NULL != jwk, "expected a cjose_jwk_t, but got NULL");
1196
1197 // get json representation of "before"
1198 json_t *left_json = json_loads(JWK, JSON_DISABLE_EOF_CHECK, NULL);
1199 ck_assert(NULL != left_json);
1200
1201 // get json representation of "after"
1202 char *jwk_str = cjose_jwk_to_json(jwk, true, &err);
1203 json_t *right_json = json_loads(jwk_str, 0, NULL);
1204 ck_assert(NULL != right_json);
1205
1206 // check that cooresponding attributes match up
1207 const char *attrs[] = { "kty", "crv", "x", "y", "d", "kid", NULL };
1208 if (!_match_string_attrs(left_json, right_json, attrs))
1209 {
1210 ck_assert_str_eq(JWK, jwk_str);
1211 }
1212
1213 free(jwk_str);
1214 json_decref(left_json);
1215 json_decref(right_json);
1216 cjose_jwk_release(jwk);
1217 }
1218 END_TEST
1219
START_TEST(test_cjose_jwk_import_with_base64url_padding)1220 START_TEST(test_cjose_jwk_import_with_base64url_padding)
1221 {
1222 cjose_err err;
1223 static const char *JWK_IN = "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1224 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M=\", "
1225 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ=\", "
1226 "\"kid\": \"BEB14BFF-1D35-4AC0-9D0A-3FD44D1C834D\" }";
1227
1228 static const char *JWK_OUT = "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1229 "\"x\": \"VoFkf6Wk5kDQ1ob6csBmiMPHU8jALwdtaap35Fsj20M\", "
1230 "\"y\": \"XymwN6u2PmsKbIPy5iij6qZ-mIyej5dvZWB_75lnRgQ\", "
1231 "\"kid\": \"BEB14BFF-1D35-4AC0-9D0A-3FD44D1C834D\" }";
1232
1233 cjose_jwk_t *jwk = NULL;
1234
1235 // do import
1236 jwk = cjose_jwk_import(JWK_IN, strlen(JWK_IN), &err);
1237 ck_assert_msg(NULL != jwk, "expected a cjose_jwk_t, but got NULL");
1238
1239 // get json representation of "expected" (i.e. no padding)
1240 json_t *left_json = json_loads(JWK_OUT, 0, NULL);
1241 ck_assert(NULL != left_json);
1242
1243 // get json representation of "actual" (i.e. reserialized original)
1244 char *jwk_str = cjose_jwk_to_json(jwk, true, &err);
1245 json_t *right_json = json_loads(jwk_str, 0, NULL);
1246 ck_assert(NULL != right_json);
1247
1248 // check that cooresponding attributes match up
1249 const char *attrs[] = { "kty", "crv", "x", "y", "d", "kid", NULL };
1250 if (!_match_string_attrs(left_json, right_json, attrs))
1251 {
1252 ck_assert_str_eq(JWK_OUT, jwk_str);
1253 }
1254
1255 free(jwk_str);
1256 json_decref(left_json);
1257 json_decref(right_json);
1258 cjose_jwk_release(jwk);
1259 }
1260 END_TEST
1261
START_TEST(test_cjose_jwk_EC_import_with_priv_export_with_pub)1262 START_TEST(test_cjose_jwk_EC_import_with_priv_export_with_pub)
1263 {
1264 cjose_err err;
1265 static const char *JWK_IN = "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1266 "\"kid\": \"7302734F-A854-40BC-A44F-93F6F72B0D34\", "
1267 "\"d\": \"hWdoUQvCWta1UQhC0nkTG0fHLFjWpDLv5wucVyq4-HY\" }";
1268
1269 static const char *JWK_OUT = "{ \"kty\": \"EC\", \"crv\": \"P-256\", "
1270 "\"x\": \"ccXrxIe0aS32y9kBkZFfAh6f7UvdcowtGH5uxCIo7eY\", "
1271 "\"y\": \"GGQACnDgoiQvdQTsv1KxNUzOjZgnNoO4wQe_F75-bb0\", "
1272 "\"kid\": \"7302734F-A854-40BC-A44F-93F6F72B0D34\", "
1273 "\"d\": \"hWdoUQvCWta1UQhC0nkTG0fHLFjWpDLv5wucVyq4-HY\" }";
1274
1275 cjose_jwk_t *jwk = NULL;
1276
1277 // do import which includes just the private key 'd'
1278 jwk = cjose_jwk_import(JWK_IN, strlen(JWK_IN), &err);
1279 ck_assert_msg(NULL != jwk, "expected a cjose_jwk_t, but got NULL");
1280
1281 // get json representation of "expected" (i.e. includes 'x' and 'y')
1282 json_t *left_json = json_loads(JWK_OUT, 0, NULL);
1283 ck_assert(NULL != left_json);
1284
1285 // get json representation of "actual" (i.e. reserialized original)
1286 char *jwk_str = cjose_jwk_to_json(jwk, true, &err);
1287 json_t *right_json = json_loads(jwk_str, 0, NULL);
1288 ck_assert(NULL != right_json);
1289
1290 // check that cooresponding attributes match up
1291 const char *attrs[] = { "kty", "crv", "x", "y", "d", "kid", NULL };
1292 if (!_match_string_attrs(left_json, right_json, attrs))
1293 {
1294 ck_assert_str_eq(JWK_OUT, jwk_str);
1295 }
1296
1297 free(jwk_str);
1298 json_decref(left_json);
1299 json_decref(right_json);
1300 cjose_jwk_release(jwk);
1301 }
1302 END_TEST
1303
START_TEST(test_cjose_jwk_hkdf)1304 START_TEST(test_cjose_jwk_hkdf)
1305 {
1306 cjose_err err;
1307
1308 const char *ikm = "source key material";
1309 size_t ikm_len = strlen(ikm);
1310
1311 size_t ephemeral_key_len = 32;
1312 uint8_t *ephemeral_key = (uint8_t *)malloc(ephemeral_key_len);
1313 bool ok
1314 = cjose_jwk_hkdf(EVP_sha256(), (uint8_t *)"", 0, (uint8_t *)"", 0, ikm, ikm_len, ephemeral_key, ephemeral_key_len, &err);
1315 ck_assert_msg(ok, "Failed to compute HKDF");
1316
1317 // the following is the expected output of HKDF with the ikm given above,
1318 // SHA256, no salt, no info, and an extend length of 256 bits, as provided
1319 // by the Ruby impl. of HKDF found here: https://github.com/jtdowney/hkdf
1320 const uint8_t expected[] = { 0x0C, 0x23, 0xF4, 0x62, 0x98, 0x9B, 0x7F, 0x77, 0x3E, 0x7C, 0x2F, 0x7C, 0x6B, 0xF4, 0x6B, 0xB7,
1321 0xB9, 0x11, 0x65, 0xC5, 0x92, 0xD1, 0x0C, 0x48, 0xFD, 0x47, 0x94, 0x76, 0x74, 0xB4, 0x14, 0xCE };
1322 for (int i = 0; i < ephemeral_key_len; i++)
1323 {
1324 ck_assert_msg(ephemeral_key[i] == expected[i], "HKDF failed on byte: %d", i);
1325 }
1326 free(ephemeral_key);
1327 }
1328 END_TEST
1329
START_TEST(test_cjose_jwk_get_and_set_kid)1330 START_TEST(test_cjose_jwk_get_and_set_kid)
1331 {
1332 cjose_err err;
1333
1334 const char *oldKid = "725cad72-23c6-4bf7-84c3-4583a6cf5fe9";
1335 const char *newKid = "aec1cebf-ddec-4d5f-8a61-f29e2f68dc41";
1336
1337 static const char *JWK_BEFORE[] = { // OCT key
1338 "{\"kty\":\"oct\","
1339 "\"kid\":\"725cad72-23c6-4bf7-84c3-4583a6cf5fe9\","
1340 "\"k\":\"wsL6R8uXG4RnsckLggj9Lg-kE5MMSJ8luzIBA8j7WXE\"}",
1341
1342 // EC key
1343 "{\"kty\":\"EC\","
1344 "\"kid\":\"725cad72-23c6-4bf7-84c3-4583a6cf5fe9\","
1345 "\"crv\":\"P-256\","
1346 "\"x\":\"ccXrxIe0aS32y9kBkZFfAh6f7UvdcowtGH5uxCIo7eY\","
1347 "\"y\":\"GGQACnDgoiQvdQTsv1KxNUzOjZgnNoO4wQe_F75-bb0\","
1348 "\"d\":\"hWdoUQvCWta1UQhC0nkTG0fHLFjWpDLv5wucVyq4-HY\"}",
1349
1350 // RSA key
1351 "{\"kty\":\"RSA\","
1352 "\"kid\":\"725cad72-23c6-4bf7-84c3-4583a6cf5fe9\","
1353 "\"e\":\"AQAB\","
1354 "\"n\":\"zSNO12-ydrm-bheszVm2ZvycKrSV2CN0xqQHPxB4yT8MFlWfopMA2Im"
1355 "t4EkILfPfZPeUYV6lElCjoY_4GBtQOy_e4RvDSMC0pqt5X4e6mjQvLsaAClkBmh"
1356 "hCYd-Vn9XIC3rSeAmBpSJDuwq_RTweXSG0hb_bn5FHf1Bl_ekEBUsm0Xq4p6N5D"
1357 "jC0ImNP74G0qxBVJzu07qsCJzYpifYYoEYkwIY7S4jqyHv55wiuMt89VTl37y8V"
1358 "FR3ll6RPiPFa4Raiminw5wKNJEmrGEukabibspiC0XvWEMXj_zk0YnVTGAGdZeD"
1359 "PwnjYY6JUOJ9KgcYkiQYb9SXetsjSbyheZw\"}",
1360
1361 NULL
1362
1363 };
1364
1365 static const char *JWK_AFTER[] = { // OCT key
1366 "{\"kty\":\"oct\","
1367 "\"kid\":\"aec1cebf-ddec-4d5f-8a61-f29e2f68dc41\","
1368 "\"k\":\"wsL6R8uXG4RnsckLggj9Lg-kE5MMSJ8luzIBA8j7WXE\"}",
1369
1370 // EC key
1371 "{\"kty\":\"EC\","
1372 "\"kid\":\"aec1cebf-ddec-4d5f-8a61-f29e2f68dc41\","
1373 "\"crv\":\"P-256\","
1374 "\"x\":\"ccXrxIe0aS32y9kBkZFfAh6f7UvdcowtGH5uxCIo7eY\","
1375 "\"y\":\"GGQACnDgoiQvdQTsv1KxNUzOjZgnNoO4wQe_F75-bb0\","
1376 "\"d\":\"hWdoUQvCWta1UQhC0nkTG0fHLFjWpDLv5wucVyq4-HY\"}",
1377
1378 // RSA key
1379 "{\"kty\":\"RSA\","
1380 "\"kid\":\"aec1cebf-ddec-4d5f-8a61-f29e2f68dc41\","
1381 "\"e\":\"AQAB\","
1382 "\"n\":\"zSNO12-ydrm-bheszVm2ZvycKrSV2CN0xqQHPxB4yT8MFlWfopMA2Im"
1383 "t4EkILfPfZPeUYV6lElCjoY_4GBtQOy_e4RvDSMC0pqt5X4e6mjQvLsaAClkBmh"
1384 "hCYd-Vn9XIC3rSeAmBpSJDuwq_RTweXSG0hb_bn5FHf1Bl_ekEBUsm0Xq4p6N5D"
1385 "jC0ImNP74G0qxBVJzu07qsCJzYpifYYoEYkwIY7S4jqyHv55wiuMt89VTl37y8V"
1386 "FR3ll6RPiPFa4Raiminw5wKNJEmrGEukabibspiC0XvWEMXj_zk0YnVTGAGdZeD"
1387 "PwnjYY6JUOJ9KgcYkiQYb9SXetsjSbyheZw\"}",
1388
1389 NULL
1390 };
1391
1392 // because stuff happens
1393 ck_assert(sizeof(JWK_BEFORE) == sizeof(JWK_AFTER));
1394
1395 const char *kid = NULL;
1396 char *json = NULL;
1397 for (int i = 0; JWK_BEFORE[i] != NULL; ++i)
1398 {
1399 // import the before state
1400 cjose_jwk_t *jwk = cjose_jwk_import(JWK_BEFORE[i], strlen(JWK_BEFORE[i]), &err);
1401 ck_assert_msg(NULL != jwk, "expected a cjose_jwk_t, but got NULL");
1402
1403 // check that kid was imported correctly
1404 kid = cjose_jwk_get_kid(jwk, &err);
1405 ck_assert_msg(!strcmp(kid, oldKid), "match on imported JWK kid failed: %d", i);
1406
1407 // change the kid
1408 ck_assert(cjose_jwk_set_kid(jwk, newKid, strlen(newKid), &err));
1409
1410 // check that the kid was changed
1411 kid = cjose_jwk_get_kid(jwk, &err);
1412 ck_assert_msg(!strcmp(kid, newKid), "match on modified JWK kid failed: %d", i);
1413
1414 // check that the kid is exported correctly
1415 json = cjose_jwk_to_json(jwk, true, &err);
1416 ck_assert_msg(!strcmp(json, JWK_AFTER[i]), "match on modified JWK JSON failed: %d", i);
1417
1418 // freedom!
1419 cjose_jwk_release(jwk);
1420 free(json);
1421 }
1422 }
1423 END_TEST
1424
cjose_jwk_suite()1425 Suite *cjose_jwk_suite()
1426 {
1427 Suite *suite = suite_create("jwk");
1428
1429 TCase *tc_jwk = tcase_create("core");
1430 tcase_set_timeout(tc_jwk, 120.0);
1431 tcase_add_test(tc_jwk, test_cjose_jwk_name_for_kty);
1432 tcase_add_test(tc_jwk, test_cjose_jwk_create_RSA_spec);
1433 tcase_add_test(tc_jwk, test_cjose_jwk_create_RSA_random);
1434 tcase_add_test(tc_jwk, test_cjose_jwk_create_EC_P256_spec);
1435 tcase_add_test(tc_jwk, test_cjose_jwk_create_EC_P256_random);
1436 tcase_add_test(tc_jwk, test_cjose_jwk_create_EC_P384_spec);
1437 tcase_add_test(tc_jwk, test_cjose_jwk_create_EC_P384_random);
1438 tcase_add_test(tc_jwk, test_cjose_jwk_create_EC_P521_spec);
1439 tcase_add_test(tc_jwk, test_cjose_jwk_create_EC_P521_random);
1440 tcase_add_test(tc_jwk, test_cjose_jwk_create_oct_spec);
1441 tcase_add_test(tc_jwk, test_cjose_jwk_create_oct_random);
1442 tcase_add_test(tc_jwk, test_cjose_jwk_create_oct_random_inval);
1443 tcase_add_test(tc_jwk, test_cjose_jwk_retain_release);
1444 tcase_add_test(tc_jwk, test_cjose_jwk_get_kty);
1445 tcase_add_test(tc_jwk, test_cjose_jwk_to_json_oct);
1446 tcase_add_test(tc_jwk, test_cjose_jwk_to_json_ec);
1447 tcase_add_test(tc_jwk, test_cjose_jwk_to_json_rsa);
1448 tcase_add_test(tc_jwk, test_cjose_jwk_import_json_valid);
1449 tcase_add_test(tc_jwk, test_cjose_jwk_import_json_invalid);
1450 tcase_add_test(tc_jwk, test_cjose_jwk_import_valid);
1451 tcase_add_test(tc_jwk, test_cjose_jwk_import_invalid);
1452 tcase_add_test(tc_jwk, test_cjose_jwk_import_underflow_length);
1453 tcase_add_test(tc_jwk, test_cjose_jwk_import_no_zero_termination);
1454 tcase_add_test(tc_jwk, test_cjose_jwk_import_with_base64url_padding);
1455 tcase_add_test(tc_jwk, test_cjose_jwk_EC_import_with_priv_export_with_pub);
1456 tcase_add_test(tc_jwk, test_cjose_jwk_hkdf);
1457 tcase_add_test(tc_jwk, test_cjose_jwk_get_and_set_kid);
1458 suite_add_tcase(suite, tc_jwk);
1459
1460 return suite;
1461 }
1462