xref: /aosp_15_r20/external/libwebsockets/lib/jose/jwk/jwk.c (revision 1c60b9aca93fdbc9b5f19b2d2194c91294b22281)
1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker  * libwebsockets - small server side websockets and web server implementation
3*1c60b9acSAndroid Build Coastguard Worker  *
4*1c60b9acSAndroid Build Coastguard Worker  * Copyright (C) 2010 - 2021 Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker  *
6*1c60b9acSAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*1c60b9acSAndroid Build Coastguard Worker  * of this software and associated documentation files (the "Software"), to
8*1c60b9acSAndroid Build Coastguard Worker  * deal in the Software without restriction, including without limitation the
9*1c60b9acSAndroid Build Coastguard Worker  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10*1c60b9acSAndroid Build Coastguard Worker  * sell copies of the Software, and to permit persons to whom the Software is
11*1c60b9acSAndroid Build Coastguard Worker  * furnished to do so, subject to the following conditions:
12*1c60b9acSAndroid Build Coastguard Worker  *
13*1c60b9acSAndroid Build Coastguard Worker  * The above copyright notice and this permission notice shall be included in
14*1c60b9acSAndroid Build Coastguard Worker  * all copies or substantial portions of the Software.
15*1c60b9acSAndroid Build Coastguard Worker  *
16*1c60b9acSAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*1c60b9acSAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*1c60b9acSAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19*1c60b9acSAndroid Build Coastguard Worker  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*1c60b9acSAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21*1c60b9acSAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22*1c60b9acSAndroid Build Coastguard Worker  * IN THE SOFTWARE.
23*1c60b9acSAndroid Build Coastguard Worker  *
24*1c60b9acSAndroid Build Coastguard Worker  * Shared JWK handling that's the same whether JOSE or COSE
25*1c60b9acSAndroid Build Coastguard Worker  */
26*1c60b9acSAndroid Build Coastguard Worker 
27*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
28*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-jose.h"
29*1c60b9acSAndroid Build Coastguard Worker 
30*1c60b9acSAndroid Build Coastguard Worker static const char *meta_names[] = {
31*1c60b9acSAndroid Build Coastguard Worker 	"kty", "kid", "use", "key_ops", "x5c", "alg"
32*1c60b9acSAndroid Build Coastguard Worker };
33*1c60b9acSAndroid Build Coastguard Worker 
34*1c60b9acSAndroid Build Coastguard Worker static const char meta_b64[] = { 0, 0, 0, 0, 1, 0 };
35*1c60b9acSAndroid Build Coastguard Worker 
36*1c60b9acSAndroid Build Coastguard Worker static const char *oct_names[] = {
37*1c60b9acSAndroid Build Coastguard Worker 	"k"
38*1c60b9acSAndroid Build Coastguard Worker };
39*1c60b9acSAndroid Build Coastguard Worker static const char oct_b64[] = { 1 };
40*1c60b9acSAndroid Build Coastguard Worker 
41*1c60b9acSAndroid Build Coastguard Worker static const char *rsa_names[] = {
42*1c60b9acSAndroid Build Coastguard Worker 	"e", "n", "d", "p", "q", "dp", "dq", "qi"
43*1c60b9acSAndroid Build Coastguard Worker };
44*1c60b9acSAndroid Build Coastguard Worker static const char rsa_b64[] = { 1, 1, 1, 1, 1, 1, 1, 1 };
45*1c60b9acSAndroid Build Coastguard Worker 
46*1c60b9acSAndroid Build Coastguard Worker static const char *ec_names[] = {
47*1c60b9acSAndroid Build Coastguard Worker 	"crv", "x", "d", "y",
48*1c60b9acSAndroid Build Coastguard Worker };
49*1c60b9acSAndroid Build Coastguard Worker static const char ec_b64[] = { 0, 1, 1, 1 };
50*1c60b9acSAndroid Build Coastguard Worker 
51*1c60b9acSAndroid Build Coastguard Worker int
lws_jwk_dump(struct lws_jwk * jwk)52*1c60b9acSAndroid Build Coastguard Worker lws_jwk_dump(struct lws_jwk *jwk)
53*1c60b9acSAndroid Build Coastguard Worker {
54*1c60b9acSAndroid Build Coastguard Worker 	const char **enames, *b64;
55*1c60b9acSAndroid Build Coastguard Worker 	int elems;
56*1c60b9acSAndroid Build Coastguard Worker 	int n;
57*1c60b9acSAndroid Build Coastguard Worker 
58*1c60b9acSAndroid Build Coastguard Worker 	(void)enames;
59*1c60b9acSAndroid Build Coastguard Worker 	(void)meta_names;
60*1c60b9acSAndroid Build Coastguard Worker 
61*1c60b9acSAndroid Build Coastguard Worker 	switch (jwk->kty) {
62*1c60b9acSAndroid Build Coastguard Worker 	default:
63*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GENCRYPTO_KTY_UNKNOWN:
64*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: jwk %p: unknown type\n", __func__, jwk);
65*1c60b9acSAndroid Build Coastguard Worker 
66*1c60b9acSAndroid Build Coastguard Worker 		return 1;
67*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GENCRYPTO_KTY_OCT:
68*1c60b9acSAndroid Build Coastguard Worker 		elems = LWS_GENCRYPTO_OCT_KEYEL_COUNT;
69*1c60b9acSAndroid Build Coastguard Worker 		enames = oct_names;
70*1c60b9acSAndroid Build Coastguard Worker 		b64 = oct_b64;
71*1c60b9acSAndroid Build Coastguard Worker 		break;
72*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GENCRYPTO_KTY_RSA:
73*1c60b9acSAndroid Build Coastguard Worker 		elems = LWS_GENCRYPTO_RSA_KEYEL_COUNT;
74*1c60b9acSAndroid Build Coastguard Worker 		enames = rsa_names;
75*1c60b9acSAndroid Build Coastguard Worker 		b64 = rsa_b64;
76*1c60b9acSAndroid Build Coastguard Worker 		break;
77*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GENCRYPTO_KTY_EC:
78*1c60b9acSAndroid Build Coastguard Worker 		elems = LWS_GENCRYPTO_EC_KEYEL_COUNT;
79*1c60b9acSAndroid Build Coastguard Worker 		enames = ec_names;
80*1c60b9acSAndroid Build Coastguard Worker 		b64 = ec_b64;
81*1c60b9acSAndroid Build Coastguard Worker 		break;
82*1c60b9acSAndroid Build Coastguard Worker 	}
83*1c60b9acSAndroid Build Coastguard Worker 
84*1c60b9acSAndroid Build Coastguard Worker 	lwsl_info("%s: jwk %p\n", __func__, jwk);
85*1c60b9acSAndroid Build Coastguard Worker 
86*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < LWS_COUNT_JWK_ELEMENTS; n++) {
87*1c60b9acSAndroid Build Coastguard Worker 		if (jwk->meta[n].buf && meta_b64[n]) {
88*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("  meta: %s\n", meta_names[n]);
89*1c60b9acSAndroid Build Coastguard Worker 			lwsl_hexdump_info(jwk->meta[n].buf, jwk->meta[n].len);
90*1c60b9acSAndroid Build Coastguard Worker 		}
91*1c60b9acSAndroid Build Coastguard Worker 		if (jwk->meta[n].buf && !meta_b64[n])
92*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("  meta: %s: '%s'\n", meta_names[n],
93*1c60b9acSAndroid Build Coastguard Worker 					jwk->meta[n].buf);
94*1c60b9acSAndroid Build Coastguard Worker 	}
95*1c60b9acSAndroid Build Coastguard Worker 
96*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < elems; n++) {
97*1c60b9acSAndroid Build Coastguard Worker 		if (jwk->e[n].buf && b64[n]) {
98*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("  e: %s\n", enames[n]);
99*1c60b9acSAndroid Build Coastguard Worker 			lwsl_hexdump_info(jwk->e[n].buf, jwk->e[n].len);
100*1c60b9acSAndroid Build Coastguard Worker 		}
101*1c60b9acSAndroid Build Coastguard Worker 		if (jwk->e[n].buf && !b64[n])
102*1c60b9acSAndroid Build Coastguard Worker 			lwsl_info("  e: %s: '%s'\n", enames[n], jwk->e[n].buf);
103*1c60b9acSAndroid Build Coastguard Worker 	}
104*1c60b9acSAndroid Build Coastguard Worker 
105*1c60b9acSAndroid Build Coastguard Worker 	return 0;
106*1c60b9acSAndroid Build Coastguard Worker }
107*1c60b9acSAndroid Build Coastguard Worker 
108*1c60b9acSAndroid Build Coastguard Worker int
_lws_jwk_set_el_jwk(struct lws_gencrypto_keyelem * e,char * in,size_t len)109*1c60b9acSAndroid Build Coastguard Worker _lws_jwk_set_el_jwk(struct lws_gencrypto_keyelem *e, char *in, size_t len)
110*1c60b9acSAndroid Build Coastguard Worker {
111*1c60b9acSAndroid Build Coastguard Worker 	e->buf = lws_malloc(len + 1, "jwk");
112*1c60b9acSAndroid Build Coastguard Worker 	if (!e->buf)
113*1c60b9acSAndroid Build Coastguard Worker 		return -1;
114*1c60b9acSAndroid Build Coastguard Worker 
115*1c60b9acSAndroid Build Coastguard Worker 	memcpy(e->buf, in, len);
116*1c60b9acSAndroid Build Coastguard Worker 	e->buf[len] = '\0';
117*1c60b9acSAndroid Build Coastguard Worker 	e->len = (uint32_t)len;
118*1c60b9acSAndroid Build Coastguard Worker 
119*1c60b9acSAndroid Build Coastguard Worker 	return 0;
120*1c60b9acSAndroid Build Coastguard Worker }
121*1c60b9acSAndroid Build Coastguard Worker 
122*1c60b9acSAndroid Build Coastguard Worker void
lws_jwk_destroy_elements(struct lws_gencrypto_keyelem * el,int m)123*1c60b9acSAndroid Build Coastguard Worker lws_jwk_destroy_elements(struct lws_gencrypto_keyelem *el, int m)
124*1c60b9acSAndroid Build Coastguard Worker {
125*1c60b9acSAndroid Build Coastguard Worker 	int n;
126*1c60b9acSAndroid Build Coastguard Worker 
127*1c60b9acSAndroid Build Coastguard Worker 	for (n = 0; n < m; n++)
128*1c60b9acSAndroid Build Coastguard Worker 		if (el[n].buf) {
129*1c60b9acSAndroid Build Coastguard Worker 			/* wipe all key material when it goes out of scope */
130*1c60b9acSAndroid Build Coastguard Worker 			lws_explicit_bzero(el[n].buf, el[n].len);
131*1c60b9acSAndroid Build Coastguard Worker 			lws_free_set_NULL(el[n].buf);
132*1c60b9acSAndroid Build Coastguard Worker 			el[n].len = 0;
133*1c60b9acSAndroid Build Coastguard Worker 		}
134*1c60b9acSAndroid Build Coastguard Worker }
135*1c60b9acSAndroid Build Coastguard Worker 
136*1c60b9acSAndroid Build Coastguard Worker void
lws_jwk_destroy(struct lws_jwk * jwk)137*1c60b9acSAndroid Build Coastguard Worker lws_jwk_destroy(struct lws_jwk *jwk)
138*1c60b9acSAndroid Build Coastguard Worker {
139*1c60b9acSAndroid Build Coastguard Worker 	lws_jwk_destroy_elements(jwk->e, LWS_ARRAY_SIZE(jwk->e));
140*1c60b9acSAndroid Build Coastguard Worker 	lws_jwk_destroy_elements(jwk->meta, LWS_ARRAY_SIZE(jwk->meta));
141*1c60b9acSAndroid Build Coastguard Worker }
142*1c60b9acSAndroid Build Coastguard Worker 
143*1c60b9acSAndroid Build Coastguard Worker void
lws_jwk_init_jps(struct lws_jwk_parse_state * jps,struct lws_jwk * jwk,lws_jwk_key_import_callback cb,void * user)144*1c60b9acSAndroid Build Coastguard Worker lws_jwk_init_jps(struct lws_jwk_parse_state *jps,
145*1c60b9acSAndroid Build Coastguard Worker 		 struct lws_jwk *jwk, lws_jwk_key_import_callback cb,
146*1c60b9acSAndroid Build Coastguard Worker 		 void *user)
147*1c60b9acSAndroid Build Coastguard Worker {
148*1c60b9acSAndroid Build Coastguard Worker 	if (jwk)
149*1c60b9acSAndroid Build Coastguard Worker 		memset(jwk, 0, sizeof(*jwk));
150*1c60b9acSAndroid Build Coastguard Worker 
151*1c60b9acSAndroid Build Coastguard Worker 	jps->jwk		= jwk;
152*1c60b9acSAndroid Build Coastguard Worker 	jps->possible		= F_RSA | F_EC | F_OCT;
153*1c60b9acSAndroid Build Coastguard Worker 	jps->per_key_cb		= cb;
154*1c60b9acSAndroid Build Coastguard Worker 	jps->user		= user;
155*1c60b9acSAndroid Build Coastguard Worker 	jps->pos		= 0;
156*1c60b9acSAndroid Build Coastguard Worker 	jps->seen		= 0;
157*1c60b9acSAndroid Build Coastguard Worker 	jps->cose_state		= 0;
158*1c60b9acSAndroid Build Coastguard Worker }
159*1c60b9acSAndroid Build Coastguard Worker 
160*1c60b9acSAndroid Build Coastguard Worker int
lws_jwk_dup_oct(struct lws_jwk * jwk,const void * key,int len)161*1c60b9acSAndroid Build Coastguard Worker lws_jwk_dup_oct(struct lws_jwk *jwk, const void *key, int len)
162*1c60b9acSAndroid Build Coastguard Worker {
163*1c60b9acSAndroid Build Coastguard Worker 	unsigned int ulen = (unsigned int)len;
164*1c60b9acSAndroid Build Coastguard Worker 
165*1c60b9acSAndroid Build Coastguard Worker 	jwk->e[LWS_GENCRYPTO_KTY_OCT].buf = lws_malloc(ulen, __func__);
166*1c60b9acSAndroid Build Coastguard Worker 	if (!jwk->e[LWS_GENCRYPTO_KTY_OCT].buf)
167*1c60b9acSAndroid Build Coastguard Worker 		return -1;
168*1c60b9acSAndroid Build Coastguard Worker 
169*1c60b9acSAndroid Build Coastguard Worker 	jwk->kty = LWS_GENCRYPTO_KTY_OCT;
170*1c60b9acSAndroid Build Coastguard Worker 	jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].len = ulen;
171*1c60b9acSAndroid Build Coastguard Worker 
172*1c60b9acSAndroid Build Coastguard Worker 	memcpy(jwk->e[LWS_GENCRYPTO_KTY_OCT].buf, key, ulen);
173*1c60b9acSAndroid Build Coastguard Worker 
174*1c60b9acSAndroid Build Coastguard Worker 	return 0;
175*1c60b9acSAndroid Build Coastguard Worker }
176*1c60b9acSAndroid Build Coastguard Worker 
177*1c60b9acSAndroid Build Coastguard Worker int
lws_jwk_generate(struct lws_context * context,struct lws_jwk * jwk,enum lws_gencrypto_kty kty,int bits,const char * curve)178*1c60b9acSAndroid Build Coastguard Worker lws_jwk_generate(struct lws_context *context, struct lws_jwk *jwk,
179*1c60b9acSAndroid Build Coastguard Worker 	         enum lws_gencrypto_kty kty, int bits, const char *curve)
180*1c60b9acSAndroid Build Coastguard Worker {
181*1c60b9acSAndroid Build Coastguard Worker 	size_t sn;
182*1c60b9acSAndroid Build Coastguard Worker 	int n;
183*1c60b9acSAndroid Build Coastguard Worker 
184*1c60b9acSAndroid Build Coastguard Worker 	memset(jwk, 0, sizeof(*jwk));
185*1c60b9acSAndroid Build Coastguard Worker 
186*1c60b9acSAndroid Build Coastguard Worker 	jwk->kty = (int)kty;
187*1c60b9acSAndroid Build Coastguard Worker 	jwk->private_key = 1;
188*1c60b9acSAndroid Build Coastguard Worker 
189*1c60b9acSAndroid Build Coastguard Worker 	switch (kty) {
190*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GENCRYPTO_KTY_RSA:
191*1c60b9acSAndroid Build Coastguard Worker 	{
192*1c60b9acSAndroid Build Coastguard Worker 		struct lws_genrsa_ctx ctx;
193*1c60b9acSAndroid Build Coastguard Worker 
194*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: generating %d bit RSA key\n", __func__, bits);
195*1c60b9acSAndroid Build Coastguard Worker 		n = lws_genrsa_new_keypair(context, &ctx, LGRSAM_PKCS1_1_5,
196*1c60b9acSAndroid Build Coastguard Worker 					    jwk->e, bits);
197*1c60b9acSAndroid Build Coastguard Worker 		lws_genrsa_destroy(&ctx);
198*1c60b9acSAndroid Build Coastguard Worker 		if (n) {
199*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: problem generating RSA key\n", __func__);
200*1c60b9acSAndroid Build Coastguard Worker 			return 1;
201*1c60b9acSAndroid Build Coastguard Worker 		}
202*1c60b9acSAndroid Build Coastguard Worker 	}
203*1c60b9acSAndroid Build Coastguard Worker 		break;
204*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GENCRYPTO_KTY_OCT:
205*1c60b9acSAndroid Build Coastguard Worker 		sn = (unsigned int)lws_gencrypto_bits_to_bytes(bits);
206*1c60b9acSAndroid Build Coastguard Worker 		jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].buf = lws_malloc(sn, "oct");
207*1c60b9acSAndroid Build Coastguard Worker 		if (!jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].buf)
208*1c60b9acSAndroid Build Coastguard Worker 			return 1;
209*1c60b9acSAndroid Build Coastguard Worker 		jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].len = (uint32_t)sn;
210*1c60b9acSAndroid Build Coastguard Worker 		if (lws_get_random(context,
211*1c60b9acSAndroid Build Coastguard Worker 			     jwk->e[LWS_GENCRYPTO_OCT_KEYEL_K].buf, sn) != sn) {
212*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: problem getting random\n", __func__);
213*1c60b9acSAndroid Build Coastguard Worker 			return 1;
214*1c60b9acSAndroid Build Coastguard Worker 		}
215*1c60b9acSAndroid Build Coastguard Worker 		break;
216*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GENCRYPTO_KTY_EC:
217*1c60b9acSAndroid Build Coastguard Worker 	{
218*1c60b9acSAndroid Build Coastguard Worker 		struct lws_genec_ctx ctx;
219*1c60b9acSAndroid Build Coastguard Worker 
220*1c60b9acSAndroid Build Coastguard Worker 		if (!curve) {
221*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: must have a named curve\n", __func__);
222*1c60b9acSAndroid Build Coastguard Worker 
223*1c60b9acSAndroid Build Coastguard Worker 			return 1;
224*1c60b9acSAndroid Build Coastguard Worker 		}
225*1c60b9acSAndroid Build Coastguard Worker 
226*1c60b9acSAndroid Build Coastguard Worker 		if (lws_genecdsa_create(&ctx, context, NULL))
227*1c60b9acSAndroid Build Coastguard Worker 			return 1;
228*1c60b9acSAndroid Build Coastguard Worker 
229*1c60b9acSAndroid Build Coastguard Worker 		lwsl_notice("%s: generating ECDSA key on curve %s\n", __func__,
230*1c60b9acSAndroid Build Coastguard Worker 				curve);
231*1c60b9acSAndroid Build Coastguard Worker 
232*1c60b9acSAndroid Build Coastguard Worker 		n = lws_genecdsa_new_keypair(&ctx, curve, jwk->e);
233*1c60b9acSAndroid Build Coastguard Worker 		lws_genec_destroy(&ctx);
234*1c60b9acSAndroid Build Coastguard Worker 		if (n) {
235*1c60b9acSAndroid Build Coastguard Worker 			lwsl_err("%s: problem generating ECDSA key\n", __func__);
236*1c60b9acSAndroid Build Coastguard Worker 			return 1;
237*1c60b9acSAndroid Build Coastguard Worker 		}
238*1c60b9acSAndroid Build Coastguard Worker 	}
239*1c60b9acSAndroid Build Coastguard Worker 		break;
240*1c60b9acSAndroid Build Coastguard Worker 
241*1c60b9acSAndroid Build Coastguard Worker 	case LWS_GENCRYPTO_KTY_UNKNOWN:
242*1c60b9acSAndroid Build Coastguard Worker 	default:
243*1c60b9acSAndroid Build Coastguard Worker 		lwsl_err("%s: unknown kty\n", __func__);
244*1c60b9acSAndroid Build Coastguard Worker 		return 1;
245*1c60b9acSAndroid Build Coastguard Worker 	}
246*1c60b9acSAndroid Build Coastguard Worker 
247*1c60b9acSAndroid Build Coastguard Worker 	return 0;
248*1c60b9acSAndroid Build Coastguard Worker }
249*1c60b9acSAndroid Build Coastguard Worker 
250*1c60b9acSAndroid Build Coastguard Worker int
lws_jwk_rfc7638_fingerprint(struct lws_jwk * jwk,char * digest32)251*1c60b9acSAndroid Build Coastguard Worker lws_jwk_rfc7638_fingerprint(struct lws_jwk *jwk, char *digest32)
252*1c60b9acSAndroid Build Coastguard Worker {
253*1c60b9acSAndroid Build Coastguard Worker 	struct lws_genhash_ctx hash_ctx;
254*1c60b9acSAndroid Build Coastguard Worker 	size_t tmpsize = 2536;
255*1c60b9acSAndroid Build Coastguard Worker 	char *tmp;
256*1c60b9acSAndroid Build Coastguard Worker 	int n, m = (int)tmpsize;
257*1c60b9acSAndroid Build Coastguard Worker 
258*1c60b9acSAndroid Build Coastguard Worker 	tmp = lws_malloc(tmpsize, "rfc7638 tmp");
259*1c60b9acSAndroid Build Coastguard Worker 
260*1c60b9acSAndroid Build Coastguard Worker 	n = lws_jwk_export(jwk, LWSJWKF_EXPORT_NOCRLF, tmp, &m);
261*1c60b9acSAndroid Build Coastguard Worker 	if (n < 0)
262*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
263*1c60b9acSAndroid Build Coastguard Worker 
264*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_init(&hash_ctx, LWS_GENHASH_TYPE_SHA256))
265*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
266*1c60b9acSAndroid Build Coastguard Worker 
267*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_update(&hash_ctx, tmp, (unsigned int)n)) {
268*1c60b9acSAndroid Build Coastguard Worker 		lws_genhash_destroy(&hash_ctx, NULL);
269*1c60b9acSAndroid Build Coastguard Worker 
270*1c60b9acSAndroid Build Coastguard Worker 		goto bail;
271*1c60b9acSAndroid Build Coastguard Worker 	}
272*1c60b9acSAndroid Build Coastguard Worker 	lws_free(tmp);
273*1c60b9acSAndroid Build Coastguard Worker 
274*1c60b9acSAndroid Build Coastguard Worker 	if (lws_genhash_destroy(&hash_ctx, digest32))
275*1c60b9acSAndroid Build Coastguard Worker 		return -1;
276*1c60b9acSAndroid Build Coastguard Worker 
277*1c60b9acSAndroid Build Coastguard Worker 	return 0;
278*1c60b9acSAndroid Build Coastguard Worker 
279*1c60b9acSAndroid Build Coastguard Worker bail:
280*1c60b9acSAndroid Build Coastguard Worker 	lws_free(tmp);
281*1c60b9acSAndroid Build Coastguard Worker 
282*1c60b9acSAndroid Build Coastguard Worker 	return -1;
283*1c60b9acSAndroid Build Coastguard Worker }
284*1c60b9acSAndroid Build Coastguard Worker 
285*1c60b9acSAndroid Build Coastguard Worker int
lws_jwk_strdup_meta(struct lws_jwk * jwk,enum enum_jwk_meta_tok idx,const char * in,int len)286*1c60b9acSAndroid Build Coastguard Worker lws_jwk_strdup_meta(struct lws_jwk *jwk, enum enum_jwk_meta_tok idx,
287*1c60b9acSAndroid Build Coastguard Worker 		    const char *in, int len)
288*1c60b9acSAndroid Build Coastguard Worker {
289*1c60b9acSAndroid Build Coastguard Worker 	jwk->meta[idx].buf = lws_malloc((unsigned int)len, __func__);
290*1c60b9acSAndroid Build Coastguard Worker 	if (!jwk->meta[idx].buf)
291*1c60b9acSAndroid Build Coastguard Worker 		return 1;
292*1c60b9acSAndroid Build Coastguard Worker 	jwk->meta[idx].len = (uint32_t)(unsigned int)len;
293*1c60b9acSAndroid Build Coastguard Worker 	memcpy(jwk->meta[idx].buf, in, (unsigned int)len);
294*1c60b9acSAndroid Build Coastguard Worker 
295*1c60b9acSAndroid Build Coastguard Worker 	return 0;
296*1c60b9acSAndroid Build Coastguard Worker }
297*1c60b9acSAndroid Build Coastguard Worker 
298