xref: /aosp_15_r20/external/libwebsockets/include/libwebsockets/lws-jws.h (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 - 2019 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 
25*1c60b9acSAndroid Build Coastguard Worker /*! \defgroup jws JSON Web Signature
26*1c60b9acSAndroid Build Coastguard Worker  * ## JSON Web Signature API
27*1c60b9acSAndroid Build Coastguard Worker  *
28*1c60b9acSAndroid Build Coastguard Worker  * Lws provides an API to check and create RFC7515 JSON Web Signatures
29*1c60b9acSAndroid Build Coastguard Worker  *
30*1c60b9acSAndroid Build Coastguard Worker  * SHA256/384/512 HMAC, and RSA 256/384/512 are supported.
31*1c60b9acSAndroid Build Coastguard Worker  *
32*1c60b9acSAndroid Build Coastguard Worker  * The API uses your TLS library crypto, but works exactly the same no matter
33*1c60b9acSAndroid Build Coastguard Worker  * what your TLS backend is.
34*1c60b9acSAndroid Build Coastguard Worker  */
35*1c60b9acSAndroid Build Coastguard Worker ///@{
36*1c60b9acSAndroid Build Coastguard Worker 
37*1c60b9acSAndroid Build Coastguard Worker /*
38*1c60b9acSAndroid Build Coastguard Worker  * The maps are built to work with both JWS (LJWS_) and JWE (LJWE_), and are
39*1c60b9acSAndroid Build Coastguard Worker  * sized to the slightly larger JWE case.
40*1c60b9acSAndroid Build Coastguard Worker  */
41*1c60b9acSAndroid Build Coastguard Worker 
42*1c60b9acSAndroid Build Coastguard Worker enum enum_jws_sig_elements {
43*1c60b9acSAndroid Build Coastguard Worker 
44*1c60b9acSAndroid Build Coastguard Worker 	/* JWS block namespace */
45*1c60b9acSAndroid Build Coastguard Worker 	LJWS_JOSE,
46*1c60b9acSAndroid Build Coastguard Worker 	LJWS_PYLD,
47*1c60b9acSAndroid Build Coastguard Worker 	LJWS_SIG,
48*1c60b9acSAndroid Build Coastguard Worker 	LJWS_UHDR,
49*1c60b9acSAndroid Build Coastguard Worker 
50*1c60b9acSAndroid Build Coastguard Worker 	/* JWE block namespace */
51*1c60b9acSAndroid Build Coastguard Worker 	LJWE_JOSE = 0,
52*1c60b9acSAndroid Build Coastguard Worker 	LJWE_EKEY,
53*1c60b9acSAndroid Build Coastguard Worker 	LJWE_IV,
54*1c60b9acSAndroid Build Coastguard Worker 	LJWE_CTXT,
55*1c60b9acSAndroid Build Coastguard Worker 	LJWE_ATAG,
56*1c60b9acSAndroid Build Coastguard Worker 	LJWE_AAD,
57*1c60b9acSAndroid Build Coastguard Worker 
58*1c60b9acSAndroid Build Coastguard Worker 	LWS_JWS_MAX_COMPACT_BLOCKS
59*1c60b9acSAndroid Build Coastguard Worker };
60*1c60b9acSAndroid Build Coastguard Worker 
61*1c60b9acSAndroid Build Coastguard Worker struct lws_jws_map {
62*1c60b9acSAndroid Build Coastguard Worker 	const char *buf[LWS_JWS_MAX_COMPACT_BLOCKS];
63*1c60b9acSAndroid Build Coastguard Worker 	uint32_t len[LWS_JWS_MAX_COMPACT_BLOCKS];
64*1c60b9acSAndroid Build Coastguard Worker };
65*1c60b9acSAndroid Build Coastguard Worker 
66*1c60b9acSAndroid Build Coastguard Worker #define LWS_JWS_MAX_SIGS 3
67*1c60b9acSAndroid Build Coastguard Worker 
68*1c60b9acSAndroid Build Coastguard Worker struct lws_jws {
69*1c60b9acSAndroid Build Coastguard Worker 	struct lws_jwk *jwk; /* the struct lws_jwk containing the signing key */
70*1c60b9acSAndroid Build Coastguard Worker 	struct lws_context *context; /* the lws context (used to get random) */
71*1c60b9acSAndroid Build Coastguard Worker 	struct lws_jws_map map, map_b64;
72*1c60b9acSAndroid Build Coastguard Worker };
73*1c60b9acSAndroid Build Coastguard Worker 
74*1c60b9acSAndroid Build Coastguard Worker /* jws EC signatures do not have ASN.1 in them, meaning they're incompatible
75*1c60b9acSAndroid Build Coastguard Worker  * with generic signatures.
76*1c60b9acSAndroid Build Coastguard Worker  */
77*1c60b9acSAndroid Build Coastguard Worker 
78*1c60b9acSAndroid Build Coastguard Worker /**
79*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_init() - initialize a jws for use
80*1c60b9acSAndroid Build Coastguard Worker  *
81*1c60b9acSAndroid Build Coastguard Worker  * \param jws: pointer to the jws to initialize
82*1c60b9acSAndroid Build Coastguard Worker  * \param jwk: the jwk to use with this jws
83*1c60b9acSAndroid Build Coastguard Worker  * \param context: the lws_context to use
84*1c60b9acSAndroid Build Coastguard Worker  */
85*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN void
86*1c60b9acSAndroid Build Coastguard Worker lws_jws_init(struct lws_jws *jws, struct lws_jwk *jwk,
87*1c60b9acSAndroid Build Coastguard Worker 	     struct lws_context *context);
88*1c60b9acSAndroid Build Coastguard Worker 
89*1c60b9acSAndroid Build Coastguard Worker /**
90*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_destroy() - scrub a jws
91*1c60b9acSAndroid Build Coastguard Worker  *
92*1c60b9acSAndroid Build Coastguard Worker  * \param jws: pointer to the jws to destroy
93*1c60b9acSAndroid Build Coastguard Worker  *
94*1c60b9acSAndroid Build Coastguard Worker  * Call before the jws goes out of scope.
95*1c60b9acSAndroid Build Coastguard Worker  *
96*1c60b9acSAndroid Build Coastguard Worker  * Elements defined in the jws are zeroed.
97*1c60b9acSAndroid Build Coastguard Worker  */
98*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN void
99*1c60b9acSAndroid Build Coastguard Worker lws_jws_destroy(struct lws_jws *jws);
100*1c60b9acSAndroid Build Coastguard Worker 
101*1c60b9acSAndroid Build Coastguard Worker /**
102*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_sig_confirm_compact() - check signature
103*1c60b9acSAndroid Build Coastguard Worker  *
104*1c60b9acSAndroid Build Coastguard Worker  * \param map: pointers and lengths for each of the unencoded JWS elements
105*1c60b9acSAndroid Build Coastguard Worker  * \param jwk: public key
106*1c60b9acSAndroid Build Coastguard Worker  * \param context: lws_context
107*1c60b9acSAndroid Build Coastguard Worker  * \param temp: scratchpad
108*1c60b9acSAndroid Build Coastguard Worker  * \param temp_len: length of scratchpad
109*1c60b9acSAndroid Build Coastguard Worker  *
110*1c60b9acSAndroid Build Coastguard Worker  * Confirms the signature on a JWS.  Use if you have non-b64 plain JWS elements
111*1c60b9acSAndroid Build Coastguard Worker  * in a map... it'll make a temp b64 version needed for comparison.  See below
112*1c60b9acSAndroid Build Coastguard Worker  * for other variants.
113*1c60b9acSAndroid Build Coastguard Worker  *
114*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 on match, else nonzero.
115*1c60b9acSAndroid Build Coastguard Worker  */
116*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
117*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm_compact(struct lws_jws_map *map, struct lws_jwk *jwk,
118*1c60b9acSAndroid Build Coastguard Worker 			    struct lws_context *context,
119*1c60b9acSAndroid Build Coastguard Worker 			    char *temp, int *temp_len);
120*1c60b9acSAndroid Build Coastguard Worker 
121*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
122*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm_compact_b64_map(struct lws_jws_map *map_b64,
123*1c60b9acSAndroid Build Coastguard Worker 				    struct lws_jwk *jwk,
124*1c60b9acSAndroid Build Coastguard Worker 			            struct lws_context *context,
125*1c60b9acSAndroid Build Coastguard Worker 			            char *temp, int *temp_len);
126*1c60b9acSAndroid Build Coastguard Worker 
127*1c60b9acSAndroid Build Coastguard Worker /**
128*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_sig_confirm_compact_b64() - check signature on b64 compact JWS
129*1c60b9acSAndroid Build Coastguard Worker  *
130*1c60b9acSAndroid Build Coastguard Worker  * \param in: pointer to b64 jose.payload[.hdr].sig
131*1c60b9acSAndroid Build Coastguard Worker  * \param len: bytes available at \p in
132*1c60b9acSAndroid Build Coastguard Worker  * \param map: map to take decoded non-b64 content
133*1c60b9acSAndroid Build Coastguard Worker  * \param jwk: public key
134*1c60b9acSAndroid Build Coastguard Worker  * \param context: lws_context
135*1c60b9acSAndroid Build Coastguard Worker  * \param temp: scratchpad
136*1c60b9acSAndroid Build Coastguard Worker  * \param temp_len: size of scratchpad
137*1c60b9acSAndroid Build Coastguard Worker  *
138*1c60b9acSAndroid Build Coastguard Worker  * Confirms the signature on a JWS.  Use if you have you have b64 compact layout
139*1c60b9acSAndroid Build Coastguard Worker  * (jose.payload.hdr.sig) as an aggregated string... it'll make a temp plain
140*1c60b9acSAndroid Build Coastguard Worker  * version needed for comparison.
141*1c60b9acSAndroid Build Coastguard Worker  *
142*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 on match, else nonzero.
143*1c60b9acSAndroid Build Coastguard Worker  */
144*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
145*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm_compact_b64(const char *in, size_t len,
146*1c60b9acSAndroid Build Coastguard Worker 				struct lws_jws_map *map,
147*1c60b9acSAndroid Build Coastguard Worker 				struct lws_jwk *jwk,
148*1c60b9acSAndroid Build Coastguard Worker 				struct lws_context *context,
149*1c60b9acSAndroid Build Coastguard Worker 				char *temp, int *temp_len);
150*1c60b9acSAndroid Build Coastguard Worker 
151*1c60b9acSAndroid Build Coastguard Worker /**
152*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_sig_confirm() - check signature on plain + b64 JWS elements
153*1c60b9acSAndroid Build Coastguard Worker  *
154*1c60b9acSAndroid Build Coastguard Worker  * \param map_b64: pointers and lengths for each of the b64-encoded JWS elements
155*1c60b9acSAndroid Build Coastguard Worker  * \param map: pointers and lengths for each of the unencoded JWS elements
156*1c60b9acSAndroid Build Coastguard Worker  * \param jwk: public key
157*1c60b9acSAndroid Build Coastguard Worker  * \param context: lws_context
158*1c60b9acSAndroid Build Coastguard Worker  *
159*1c60b9acSAndroid Build Coastguard Worker  * Confirms the signature on a JWS.  Use if you have you already have both b64
160*1c60b9acSAndroid Build Coastguard Worker  * compact layout (jose.payload.hdr.sig) and decoded JWS elements in maps.
161*1c60b9acSAndroid Build Coastguard Worker  *
162*1c60b9acSAndroid Build Coastguard Worker  * If you had the b64 string and called lws_jws_compact_decode() on it, you
163*1c60b9acSAndroid Build Coastguard Worker  * will end up with both maps, and can use this api version, saving needlessly
164*1c60b9acSAndroid Build Coastguard Worker  * regenerating any temp map.
165*1c60b9acSAndroid Build Coastguard Worker  *
166*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 on match, else nonzero.
167*1c60b9acSAndroid Build Coastguard Worker  */
168*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
169*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm(struct lws_jws_map *map_b64, /* b64-encoded */
170*1c60b9acSAndroid Build Coastguard Worker 		    struct lws_jws_map *map,	/* non-b64 */
171*1c60b9acSAndroid Build Coastguard Worker 		    struct lws_jwk *jwk, struct lws_context *context);
172*1c60b9acSAndroid Build Coastguard Worker 
173*1c60b9acSAndroid Build Coastguard Worker /**
174*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_sign_from_b64() - add b64 sig to b64 hdr + payload
175*1c60b9acSAndroid Build Coastguard Worker  *
176*1c60b9acSAndroid Build Coastguard Worker  * \param jose: jose header information
177*1c60b9acSAndroid Build Coastguard Worker  * \param jws: information to include in the signature
178*1c60b9acSAndroid Build Coastguard Worker  * \param b64_sig: output buffer for b64 signature
179*1c60b9acSAndroid Build Coastguard Worker  * \param sig_len: size of \p b64_sig output buffer
180*1c60b9acSAndroid Build Coastguard Worker  *
181*1c60b9acSAndroid Build Coastguard Worker  * This adds a b64-coded JWS signature of the b64-encoded protected header
182*1c60b9acSAndroid Build Coastguard Worker  * and b64-encoded payload, at \p b64_sig.  The signature will be as large
183*1c60b9acSAndroid Build Coastguard Worker  * as the N element of the RSA key when the RSA key is used, eg, 512 bytes for
184*1c60b9acSAndroid Build Coastguard Worker  * a 4096-bit key, and then b64-encoding on top.
185*1c60b9acSAndroid Build Coastguard Worker  *
186*1c60b9acSAndroid Build Coastguard Worker  * In some special cases, there is only payload to sign and no header, in that
187*1c60b9acSAndroid Build Coastguard Worker  * case \p b64_hdr may be NULL, and only the payload will be hashed before
188*1c60b9acSAndroid Build Coastguard Worker  * signing.
189*1c60b9acSAndroid Build Coastguard Worker  *
190*1c60b9acSAndroid Build Coastguard Worker  * If successful, returns the length of the encoded signature written to
191*1c60b9acSAndroid Build Coastguard Worker  * \p b64_sig.  If the jose signing type is unknown, 0 is returned.  Otherwise
192*1c60b9acSAndroid Build Coastguard Worker  * -1 indicates failure.
193*1c60b9acSAndroid Build Coastguard Worker  */
194*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
195*1c60b9acSAndroid Build Coastguard Worker lws_jws_sign_from_b64(struct lws_jose *jose, struct lws_jws *jws, char *b64_sig,
196*1c60b9acSAndroid Build Coastguard Worker 			size_t sig_len);
197*1c60b9acSAndroid Build Coastguard Worker 
198*1c60b9acSAndroid Build Coastguard Worker /**
199*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_compact_decode() - converts and maps compact serialization b64 sections
200*1c60b9acSAndroid Build Coastguard Worker  *
201*1c60b9acSAndroid Build Coastguard Worker  * \param in: the incoming compact serialized b64
202*1c60b9acSAndroid Build Coastguard Worker  * \param len: the length of the incoming compact serialized b64
203*1c60b9acSAndroid Build Coastguard Worker  * \param map: pointer to the results structure
204*1c60b9acSAndroid Build Coastguard Worker  * \param map_b64: NULL, or pointer to a second results structure taking block
205*1c60b9acSAndroid Build Coastguard Worker  *		   information about the undecoded b64
206*1c60b9acSAndroid Build Coastguard Worker  * \param out: buffer to hold decoded results
207*1c60b9acSAndroid Build Coastguard Worker  * \param out_len: size of out in bytes
208*1c60b9acSAndroid Build Coastguard Worker  *
209*1c60b9acSAndroid Build Coastguard Worker  * Returns number of sections (2 if "none", else 3), or -1 if illegal.
210*1c60b9acSAndroid Build Coastguard Worker  *
211*1c60b9acSAndroid Build Coastguard Worker  * map is set to point to the start and hold the length of each decoded block.
212*1c60b9acSAndroid Build Coastguard Worker  * If map_b64 is non-NULL, then it's set with information about the input b64
213*1c60b9acSAndroid Build Coastguard Worker  * blocks.
214*1c60b9acSAndroid Build Coastguard Worker  */
215*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
216*1c60b9acSAndroid Build Coastguard Worker lws_jws_compact_decode(const char *in, int len, struct lws_jws_map *map,
217*1c60b9acSAndroid Build Coastguard Worker 		struct lws_jws_map *map_b64, char *out, int *out_len);
218*1c60b9acSAndroid Build Coastguard Worker 
219*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
220*1c60b9acSAndroid Build Coastguard Worker lws_jws_compact_encode(struct lws_jws_map *map_b64, /* b64-encoded */
221*1c60b9acSAndroid Build Coastguard Worker 		       const struct lws_jws_map *map,	/* non-b64 */
222*1c60b9acSAndroid Build Coastguard Worker 		       char *buf, int *out_len);
223*1c60b9acSAndroid Build Coastguard Worker 
224*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
225*1c60b9acSAndroid Build Coastguard Worker lws_jws_sig_confirm_json(const char *in, size_t len,
226*1c60b9acSAndroid Build Coastguard Worker 			 struct lws_jws *jws, struct lws_jwk *jwk,
227*1c60b9acSAndroid Build Coastguard Worker 			 struct lws_context *context,
228*1c60b9acSAndroid Build Coastguard Worker 			 char *temp, int *temp_len);
229*1c60b9acSAndroid Build Coastguard Worker 
230*1c60b9acSAndroid Build Coastguard Worker /**
231*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_write_flattened_json() - create flattened JSON sig
232*1c60b9acSAndroid Build Coastguard Worker  *
233*1c60b9acSAndroid Build Coastguard Worker  * \param jws: information to include in the signature
234*1c60b9acSAndroid Build Coastguard Worker  * \param flattened: output buffer for JSON
235*1c60b9acSAndroid Build Coastguard Worker  * \param len: size of \p flattened output buffer
236*1c60b9acSAndroid Build Coastguard Worker  *
237*1c60b9acSAndroid Build Coastguard Worker  */
238*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
239*1c60b9acSAndroid Build Coastguard Worker lws_jws_write_flattened_json(struct lws_jws *jws, char *flattened, size_t len);
240*1c60b9acSAndroid Build Coastguard Worker 
241*1c60b9acSAndroid Build Coastguard Worker /**
242*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_write_compact() - create flattened JSON sig
243*1c60b9acSAndroid Build Coastguard Worker  *
244*1c60b9acSAndroid Build Coastguard Worker  * \param jws: information to include in the signature
245*1c60b9acSAndroid Build Coastguard Worker  * \param compact: output buffer for compact format
246*1c60b9acSAndroid Build Coastguard Worker  * \param len: size of \p flattened output buffer
247*1c60b9acSAndroid Build Coastguard Worker  *
248*1c60b9acSAndroid Build Coastguard Worker  */
249*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
250*1c60b9acSAndroid Build Coastguard Worker lws_jws_write_compact(struct lws_jws *jws, char *compact, size_t len);
251*1c60b9acSAndroid Build Coastguard Worker 
252*1c60b9acSAndroid Build Coastguard Worker 
253*1c60b9acSAndroid Build Coastguard Worker 
254*1c60b9acSAndroid Build Coastguard Worker /*
255*1c60b9acSAndroid Build Coastguard Worker  * below apis are not normally needed if dealing with whole JWS... they're
256*1c60b9acSAndroid Build Coastguard Worker  * useful for creating from scratch
257*1c60b9acSAndroid Build Coastguard Worker  */
258*1c60b9acSAndroid Build Coastguard Worker 
259*1c60b9acSAndroid Build Coastguard Worker 
260*1c60b9acSAndroid Build Coastguard Worker /**
261*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_dup_element() - allocate space for an element and copy data into it
262*1c60b9acSAndroid Build Coastguard Worker  *
263*1c60b9acSAndroid Build Coastguard Worker  * \param map: map to create the element in
264*1c60b9acSAndroid Build Coastguard Worker  * \param idx: index of element in the map to create
265*1c60b9acSAndroid Build Coastguard Worker  * \param temp: space to allocate in
266*1c60b9acSAndroid Build Coastguard Worker  * \param temp_len: available space at temp
267*1c60b9acSAndroid Build Coastguard Worker  * \param in: data to duplicate into element
268*1c60b9acSAndroid Build Coastguard Worker  * \param in_len: length of data to duplicate
269*1c60b9acSAndroid Build Coastguard Worker  * \param actual_alloc: 0 for same as in_len, else actual allocation size
270*1c60b9acSAndroid Build Coastguard Worker  *
271*1c60b9acSAndroid Build Coastguard Worker  * Copies in_len from in to temp, if temp_len is sufficient.
272*1c60b9acSAndroid Build Coastguard Worker  *
273*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 or -1 if not enough space in temp / temp_len.
274*1c60b9acSAndroid Build Coastguard Worker  *
275*1c60b9acSAndroid Build Coastguard Worker  * Over-allocation can be acheived by setting actual_alloc to the real
276*1c60b9acSAndroid Build Coastguard Worker  * allocation desired... in_len will be copied into it.
277*1c60b9acSAndroid Build Coastguard Worker  *
278*1c60b9acSAndroid Build Coastguard Worker  * *temp_len is reduced by actual_alloc if successful.
279*1c60b9acSAndroid Build Coastguard Worker  */
280*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
281*1c60b9acSAndroid Build Coastguard Worker lws_jws_dup_element(struct lws_jws_map *map, int idx,
282*1c60b9acSAndroid Build Coastguard Worker 		    char *temp, int *temp_len, const void *in, size_t in_len,
283*1c60b9acSAndroid Build Coastguard Worker 		    size_t actual_alloc);
284*1c60b9acSAndroid Build Coastguard Worker 
285*1c60b9acSAndroid Build Coastguard Worker /**
286*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_randomize_element() - create an element and fill with random
287*1c60b9acSAndroid Build Coastguard Worker  *
288*1c60b9acSAndroid Build Coastguard Worker  * \param context: lws_context used for random
289*1c60b9acSAndroid Build Coastguard Worker  * \param map: map to create the element in
290*1c60b9acSAndroid Build Coastguard Worker  * \param idx: index of element in the map to create
291*1c60b9acSAndroid Build Coastguard Worker  * \param temp: space to allocate in
292*1c60b9acSAndroid Build Coastguard Worker  * \param temp_len: available space at temp
293*1c60b9acSAndroid Build Coastguard Worker  * \param random_len: length of data to fill with random
294*1c60b9acSAndroid Build Coastguard Worker  * \param actual_alloc: 0 for same as random_len, else actual allocation size
295*1c60b9acSAndroid Build Coastguard Worker  *
296*1c60b9acSAndroid Build Coastguard Worker  * Randomize random_len bytes at temp, if temp_len is sufficient.
297*1c60b9acSAndroid Build Coastguard Worker  *
298*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 or -1 if not enough space in temp / temp_len.
299*1c60b9acSAndroid Build Coastguard Worker  *
300*1c60b9acSAndroid Build Coastguard Worker  * Over-allocation can be acheived by setting actual_alloc to the real
301*1c60b9acSAndroid Build Coastguard Worker  * allocation desired... the first random_len will be filled with random.
302*1c60b9acSAndroid Build Coastguard Worker  *
303*1c60b9acSAndroid Build Coastguard Worker  * *temp_len is reduced by actual_alloc if successful.
304*1c60b9acSAndroid Build Coastguard Worker  */
305*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
306*1c60b9acSAndroid Build Coastguard Worker lws_jws_randomize_element(struct lws_context *context,
307*1c60b9acSAndroid Build Coastguard Worker 			  struct lws_jws_map *map,
308*1c60b9acSAndroid Build Coastguard Worker 			  int idx, char *temp, int *temp_len, size_t random_len,
309*1c60b9acSAndroid Build Coastguard Worker 			  size_t actual_alloc);
310*1c60b9acSAndroid Build Coastguard Worker 
311*1c60b9acSAndroid Build Coastguard Worker /**
312*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_alloc_element() - create an element and reserve space for content
313*1c60b9acSAndroid Build Coastguard Worker  *
314*1c60b9acSAndroid Build Coastguard Worker  * \param map: map to create the element in
315*1c60b9acSAndroid Build Coastguard Worker  * \param idx: index of element in the map to create
316*1c60b9acSAndroid Build Coastguard Worker  * \param temp: space to allocate in
317*1c60b9acSAndroid Build Coastguard Worker  * \param temp_len: available space at temp
318*1c60b9acSAndroid Build Coastguard Worker  * \param len: logical length of element
319*1c60b9acSAndroid Build Coastguard Worker  * \param actual_alloc: 0 for same as len, else actual allocation size
320*1c60b9acSAndroid Build Coastguard Worker  *
321*1c60b9acSAndroid Build Coastguard Worker  * Allocate len bytes at temp, if temp_len is sufficient.
322*1c60b9acSAndroid Build Coastguard Worker  *
323*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 or -1 if not enough space in temp / temp_len.
324*1c60b9acSAndroid Build Coastguard Worker  *
325*1c60b9acSAndroid Build Coastguard Worker  * Over-allocation can be acheived by setting actual_alloc to the real
326*1c60b9acSAndroid Build Coastguard Worker  * allocation desired... the element logical length will be set to len.
327*1c60b9acSAndroid Build Coastguard Worker  *
328*1c60b9acSAndroid Build Coastguard Worker  * *temp_len is reduced by actual_alloc if successful.
329*1c60b9acSAndroid Build Coastguard Worker  */
330*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
331*1c60b9acSAndroid Build Coastguard Worker lws_jws_alloc_element(struct lws_jws_map *map, int idx, char *temp,
332*1c60b9acSAndroid Build Coastguard Worker 		      int *temp_len, size_t len, size_t actual_alloc);
333*1c60b9acSAndroid Build Coastguard Worker 
334*1c60b9acSAndroid Build Coastguard Worker /**
335*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_encode_b64_element() - create an b64-encoded element
336*1c60b9acSAndroid Build Coastguard Worker  *
337*1c60b9acSAndroid Build Coastguard Worker  * \param map: map to create the element in
338*1c60b9acSAndroid Build Coastguard Worker  * \param idx: index of element in the map to create
339*1c60b9acSAndroid Build Coastguard Worker  * \param temp: space to allocate in
340*1c60b9acSAndroid Build Coastguard Worker  * \param temp_len: available space at temp
341*1c60b9acSAndroid Build Coastguard Worker  * \param in: pointer to unencoded input
342*1c60b9acSAndroid Build Coastguard Worker  * \param in_len: length of unencoded input
343*1c60b9acSAndroid Build Coastguard Worker  *
344*1c60b9acSAndroid Build Coastguard Worker  * Allocate len bytes at temp, if temp_len is sufficient.
345*1c60b9acSAndroid Build Coastguard Worker  *
346*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 or -1 if not enough space in temp / temp_len.
347*1c60b9acSAndroid Build Coastguard Worker  *
348*1c60b9acSAndroid Build Coastguard Worker  * Over-allocation can be acheived by setting actual_alloc to the real
349*1c60b9acSAndroid Build Coastguard Worker  * allocation desired... the element logical length will be set to len.
350*1c60b9acSAndroid Build Coastguard Worker  *
351*1c60b9acSAndroid Build Coastguard Worker  * *temp_len is reduced by actual_alloc if successful.
352*1c60b9acSAndroid Build Coastguard Worker  */
353*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
354*1c60b9acSAndroid Build Coastguard Worker lws_jws_encode_b64_element(struct lws_jws_map *map, int idx,
355*1c60b9acSAndroid Build Coastguard Worker 			   char *temp, int *temp_len, const void *in,
356*1c60b9acSAndroid Build Coastguard Worker 			   size_t in_len);
357*1c60b9acSAndroid Build Coastguard Worker 
358*1c60b9acSAndroid Build Coastguard Worker 
359*1c60b9acSAndroid Build Coastguard Worker /**
360*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_b64_compact_map() - find block starts and lengths in compact b64
361*1c60b9acSAndroid Build Coastguard Worker  *
362*1c60b9acSAndroid Build Coastguard Worker  * \param in: pointer to b64 jose.payload[.hdr].sig
363*1c60b9acSAndroid Build Coastguard Worker  * \param len: bytes available at \p in
364*1c60b9acSAndroid Build Coastguard Worker  * \param map: output struct with pointers and lengths for each JWS element
365*1c60b9acSAndroid Build Coastguard Worker  *
366*1c60b9acSAndroid Build Coastguard Worker  * Scans a jose.payload[.hdr].sig b64 string and notes where the blocks start
367*1c60b9acSAndroid Build Coastguard Worker  * and their length into \p map.
368*1c60b9acSAndroid Build Coastguard Worker  *
369*1c60b9acSAndroid Build Coastguard Worker  * Returns number of blocks if OK.  May return <0 if malformed.
370*1c60b9acSAndroid Build Coastguard Worker  * May not fill all map entries.
371*1c60b9acSAndroid Build Coastguard Worker  */
372*1c60b9acSAndroid Build Coastguard Worker 
373*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
374*1c60b9acSAndroid Build Coastguard Worker lws_jws_b64_compact_map(const char *in, int len, struct lws_jws_map *map);
375*1c60b9acSAndroid Build Coastguard Worker 
376*1c60b9acSAndroid Build Coastguard Worker 
377*1c60b9acSAndroid Build Coastguard Worker /**
378*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_base64_enc() - encode input data into b64url data
379*1c60b9acSAndroid Build Coastguard Worker  *
380*1c60b9acSAndroid Build Coastguard Worker  * \param in: the incoming plaintext
381*1c60b9acSAndroid Build Coastguard Worker  * \param in_len: the length of the incoming plaintext in bytes
382*1c60b9acSAndroid Build Coastguard Worker  * \param out: the buffer to store the b64url encoded data to
383*1c60b9acSAndroid Build Coastguard Worker  * \param out_max: the length of \p out in bytes
384*1c60b9acSAndroid Build Coastguard Worker  *
385*1c60b9acSAndroid Build Coastguard Worker  * Returns either -1 if problems, or the number of bytes written to \p out.
386*1c60b9acSAndroid Build Coastguard Worker  */
387*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
388*1c60b9acSAndroid Build Coastguard Worker lws_jws_base64_enc(const char *in, size_t in_len, char *out, size_t out_max);
389*1c60b9acSAndroid Build Coastguard Worker 
390*1c60b9acSAndroid Build Coastguard Worker /**
391*1c60b9acSAndroid Build Coastguard Worker  * lws_jws_encode_section() - encode input data into b64url data,
392*1c60b9acSAndroid Build Coastguard Worker  *				prepending . if not first
393*1c60b9acSAndroid Build Coastguard Worker  *
394*1c60b9acSAndroid Build Coastguard Worker  * \param in: the incoming plaintext
395*1c60b9acSAndroid Build Coastguard Worker  * \param in_len: the length of the incoming plaintext in bytes
396*1c60b9acSAndroid Build Coastguard Worker  * \param first: nonzero if the first section
397*1c60b9acSAndroid Build Coastguard Worker  * \param p: the buffer to store the b64url encoded data to
398*1c60b9acSAndroid Build Coastguard Worker  * \param end: just past the end of p
399*1c60b9acSAndroid Build Coastguard Worker  *
400*1c60b9acSAndroid Build Coastguard Worker  * Returns either -1 if problems, or the number of bytes written to \p out.
401*1c60b9acSAndroid Build Coastguard Worker  * If the section is not the first one, '.' is prepended.
402*1c60b9acSAndroid Build Coastguard Worker  */
403*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
404*1c60b9acSAndroid Build Coastguard Worker lws_jws_encode_section(const char *in, size_t in_len, int first, char **p,
405*1c60b9acSAndroid Build Coastguard Worker 		       char *end);
406*1c60b9acSAndroid Build Coastguard Worker 
407*1c60b9acSAndroid Build Coastguard Worker /**
408*1c60b9acSAndroid Build Coastguard Worker  * lws_jwt_signed_validate() - check a compact JWT against a key and alg
409*1c60b9acSAndroid Build Coastguard Worker  *
410*1c60b9acSAndroid Build Coastguard Worker  * \param ctx: the lws_context
411*1c60b9acSAndroid Build Coastguard Worker  * \param jwk: the key for checking the signature
412*1c60b9acSAndroid Build Coastguard Worker  * \param alg_list: the expected alg name, like "ES512"
413*1c60b9acSAndroid Build Coastguard Worker  * \param com: the compact JWT
414*1c60b9acSAndroid Build Coastguard Worker  * \param len: the length of com
415*1c60b9acSAndroid Build Coastguard Worker  * \param temp: a temp scratchpad
416*1c60b9acSAndroid Build Coastguard Worker  * \param tl: available length of temp scratchpad
417*1c60b9acSAndroid Build Coastguard Worker  * \param out: the output buffer to hold the validated plaintext
418*1c60b9acSAndroid Build Coastguard Worker  * \param out_len: on entry, max length of out; on exit, used length of out
419*1c60b9acSAndroid Build Coastguard Worker  *
420*1c60b9acSAndroid Build Coastguard Worker  * Returns nonzero if the JWT cannot be validated or the plaintext can't fit the
421*1c60b9acSAndroid Build Coastguard Worker  * provided output buffer, or 0 if it is validated as being signed by the
422*1c60b9acSAndroid Build Coastguard Worker  * provided jwk.
423*1c60b9acSAndroid Build Coastguard Worker  *
424*1c60b9acSAndroid Build Coastguard Worker  * If validated, the plaintext in the JWT is copied into out and out_len set to
425*1c60b9acSAndroid Build Coastguard Worker  * the used length.
426*1c60b9acSAndroid Build Coastguard Worker  *
427*1c60b9acSAndroid Build Coastguard Worker  * temp can be discarded or reused after the call returned, it's used to hold
428*1c60b9acSAndroid Build Coastguard Worker  * transformations of the B64 JWS in the JWT.
429*1c60b9acSAndroid Build Coastguard Worker  */
430*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
431*1c60b9acSAndroid Build Coastguard Worker lws_jwt_signed_validate(struct lws_context *ctx, struct lws_jwk *jwk,
432*1c60b9acSAndroid Build Coastguard Worker 			const char *alg_list, const char *com, size_t len,
433*1c60b9acSAndroid Build Coastguard Worker 			char *temp, int tl, char *out, size_t *out_len);
434*1c60b9acSAndroid Build Coastguard Worker 
435*1c60b9acSAndroid Build Coastguard Worker /**
436*1c60b9acSAndroid Build Coastguard Worker  * lws_jwt_sign_compact() - generate a compact JWT using a key and alg
437*1c60b9acSAndroid Build Coastguard Worker  *
438*1c60b9acSAndroid Build Coastguard Worker  * \param ctx: the lws_context
439*1c60b9acSAndroid Build Coastguard Worker  * \param jwk: the signing key
440*1c60b9acSAndroid Build Coastguard Worker  * \param alg: the signing alg name, like "ES512"
441*1c60b9acSAndroid Build Coastguard Worker  * \param out: the output buffer to hold the signed JWT in compact form
442*1c60b9acSAndroid Build Coastguard Worker  * \param out_len: on entry, the length of out; on exit, the used amount of out
443*1c60b9acSAndroid Build Coastguard Worker  * \param temp: a temp scratchpad
444*1c60b9acSAndroid Build Coastguard Worker  * \param tl: available length of temp scratchpad
445*1c60b9acSAndroid Build Coastguard Worker  * \param format: a printf style format specification
446*1c60b9acSAndroid Build Coastguard Worker  * \param ...: zero or more args for the format specification
447*1c60b9acSAndroid Build Coastguard Worker  *
448*1c60b9acSAndroid Build Coastguard Worker  * Creates a JWT in a single step, from the format string and args through to
449*1c60b9acSAndroid Build Coastguard Worker  * outputting a well-formed compact JWT representation in out.
450*1c60b9acSAndroid Build Coastguard Worker  *
451*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 if all is well and *out_len is the amount of data in out, else
452*1c60b9acSAndroid Build Coastguard Worker  * nonzero if failed.  Temp must be large enough to hold various intermediate
453*1c60b9acSAndroid Build Coastguard Worker  * representations.
454*1c60b9acSAndroid Build Coastguard Worker  */
455*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
456*1c60b9acSAndroid Build Coastguard Worker lws_jwt_sign_compact(struct lws_context *ctx, struct lws_jwk *jwk,
457*1c60b9acSAndroid Build Coastguard Worker 		     const char *alg, char *out, size_t *out_len, char *temp,
458*1c60b9acSAndroid Build Coastguard Worker 		     int tl, const char *format, ...) LWS_FORMAT(8);
459*1c60b9acSAndroid Build Coastguard Worker 
460*1c60b9acSAndroid Build Coastguard Worker struct lws_jwt_sign_info {
461*1c60b9acSAndroid Build Coastguard Worker 	const char *alg;
462*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: signing alg name, like "RS256" */
463*1c60b9acSAndroid Build Coastguard Worker 	const char *jose_hdr;
464*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: optional JOSE hdr; if present, alg field is ignored; instead the
465*1c60b9acSAndroid Build Coastguard Worker 	 *          whole claim object has to be provided in this parameter */
466*1c60b9acSAndroid Build Coastguard Worker 	size_t jose_hdr_len;
467*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: if jose_hdr is not NULL, JOSE header length without terminating '\0' */
468*1c60b9acSAndroid Build Coastguard Worker 	char *out;
469*1c60b9acSAndroid Build Coastguard Worker 	/**< exit: signed JWT in compact form*/
470*1c60b9acSAndroid Build Coastguard Worker 	size_t *out_len;
471*1c60b9acSAndroid Build Coastguard Worker 	/**< entry,exit: buffer size of out; actual size of JWT on exit */
472*1c60b9acSAndroid Build Coastguard Worker 	char *temp;
473*1c60b9acSAndroid Build Coastguard Worker 	/**< exit undefined content, used by the function as a temporary scratchpad; MUST
474*1c60b9acSAndroid Build Coastguard Worker 	 * be large enogh to store various intermediate representations */
475*1c60b9acSAndroid Build Coastguard Worker 	int tl;
476*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: size of temp buffer */
477*1c60b9acSAndroid Build Coastguard Worker };
478*1c60b9acSAndroid Build Coastguard Worker 
479*1c60b9acSAndroid Build Coastguard Worker /**
480*1c60b9acSAndroid Build Coastguard Worker  * lws_jwt_sign_compact() - generate a compact JWT using a key and JOSE header
481*1c60b9acSAndroid Build Coastguard Worker  *
482*1c60b9acSAndroid Build Coastguard Worker  * \param ctx: the lws_context
483*1c60b9acSAndroid Build Coastguard Worker  * \param jwk: the signing key
484*1c60b9acSAndroid Build Coastguard Worker  * \param info: info describing the JWT's content and output/temp buffers
485*1c60b9acSAndroid Build Coastguard Worker  * \param format: a printf style format specification of the claims object
486*1c60b9acSAndroid Build Coastguard Worker  * \param ...: zero or more args for the format specification
487*1c60b9acSAndroid Build Coastguard Worker  *
488*1c60b9acSAndroid Build Coastguard Worker  * Creates a JWT in a single step, from the format string and args through to
489*1c60b9acSAndroid Build Coastguard Worker  * outputting a well-formed compact JWT representation in out. The provided
490*1c60b9acSAndroid Build Coastguard Worker  * JOSE header's syntax is checked before it is added to the JWT.
491*1c60b9acSAndroid Build Coastguard Worker  *
492*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 if all is well and *out_len is the amount of data in out, else
493*1c60b9acSAndroid Build Coastguard Worker  * nonzero if failed.  Temp must be large enough to hold various intermediate
494*1c60b9acSAndroid Build Coastguard Worker  * representations.
495*1c60b9acSAndroid Build Coastguard Worker  */
496*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
497*1c60b9acSAndroid Build Coastguard Worker lws_jwt_sign_via_info(struct lws_context *ctx, struct lws_jwk *jwk,
498*1c60b9acSAndroid Build Coastguard Worker          const struct lws_jwt_sign_info *info, const char *format, ...) LWS_FORMAT(4);
499*1c60b9acSAndroid Build Coastguard Worker 
500*1c60b9acSAndroid Build Coastguard Worker /**
501*1c60b9acSAndroid Build Coastguard Worker  * lws_jwt_token_sanity() - check a validated jwt payload for sanity
502*1c60b9acSAndroid Build Coastguard Worker  *
503*1c60b9acSAndroid Build Coastguard Worker  * \param in: the JWT payload
504*1c60b9acSAndroid Build Coastguard Worker  * \param in_len: the length of the JWT payload
505*1c60b9acSAndroid Build Coastguard Worker  * \param iss: the expected issuer of the token
506*1c60b9acSAndroid Build Coastguard Worker  * \param aud: the expected audience of the token
507*1c60b9acSAndroid Build Coastguard Worker  * \param csrf_in: NULL, or the csrf token that came in on a URL
508*1c60b9acSAndroid Build Coastguard Worker  * \param sub: a buffer to hold the subject name in the JWT (eg, account name)
509*1c60b9acSAndroid Build Coastguard Worker  * \param sub_len: the max length of the sub buffer
510*1c60b9acSAndroid Build Coastguard Worker  * \param secs_left: set to the number of seconds of valid auth left if valid
511*1c60b9acSAndroid Build Coastguard Worker  *
512*1c60b9acSAndroid Build Coastguard Worker  * This performs some generic sanity tests on validated JWT payload...
513*1c60b9acSAndroid Build Coastguard Worker  *
514*1c60b9acSAndroid Build Coastguard Worker  *  - the issuer is as expected
515*1c60b9acSAndroid Build Coastguard Worker  *  - the audience is us
516*1c60b9acSAndroid Build Coastguard Worker  *  - current time is OK for nbf ("not before") in the token
517*1c60b9acSAndroid Build Coastguard Worker  *  - current time is OK for exp ("expiry") in the token
518*1c60b9acSAndroid Build Coastguard Worker  *  - if csrf_in is not NULL, that the JWK has a csrf and it matches it
519*1c60b9acSAndroid Build Coastguard Worker  *  - if sub is not NULL, that the JWK provides a subject (and copies it to sub)
520*1c60b9acSAndroid Build Coastguard Worker  *
521*1c60b9acSAndroid Build Coastguard Worker  * If the tests pass, *secs_left is set to the number of remaining seconds the
522*1c60b9acSAndroid Build Coastguard Worker  * auth is valid.
523*1c60b9acSAndroid Build Coastguard Worker  *
524*1c60b9acSAndroid Build Coastguard Worker  * Returns 0 if no inconsistency, else nonzero.
525*1c60b9acSAndroid Build Coastguard Worker  */
526*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
527*1c60b9acSAndroid Build Coastguard Worker lws_jwt_token_sanity(const char *in, size_t in_len,
528*1c60b9acSAndroid Build Coastguard Worker 		     const char *iss, const char *aud, const char *csrf_in,
529*1c60b9acSAndroid Build Coastguard Worker 		     char *sub, size_t sub_len, unsigned long *exp_unix_time);
530*1c60b9acSAndroid Build Coastguard Worker 
531*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
532*1c60b9acSAndroid Build Coastguard Worker 
533*1c60b9acSAndroid Build Coastguard Worker struct lws_jwt_sign_set_cookie {
534*1c60b9acSAndroid Build Coastguard Worker 	struct lws_jwk			*jwk;
535*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: required signing key */
536*1c60b9acSAndroid Build Coastguard Worker 	const char			*alg;
537*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: required signing alg, eg, "ES512" */
538*1c60b9acSAndroid Build Coastguard Worker 	const char 			*iss;
539*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: issuer name to use */
540*1c60b9acSAndroid Build Coastguard Worker 	const char			*aud;
541*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: audience */
542*1c60b9acSAndroid Build Coastguard Worker 	const char			*cookie_name;
543*1c60b9acSAndroid Build Coastguard Worker 	/**< entry: the name of the cookie */
544*1c60b9acSAndroid Build Coastguard Worker 	char				sub[33];
545*1c60b9acSAndroid Build Coastguard Worker 	/**< sign-entry, validate-exit: subject */
546*1c60b9acSAndroid Build Coastguard Worker 	const char			*extra_json;
547*1c60b9acSAndroid Build Coastguard Worker 	/**< sign-entry, validate-exit:
548*1c60b9acSAndroid Build Coastguard Worker 	 * optional "ext" JSON object contents for the JWT */
549*1c60b9acSAndroid Build Coastguard Worker 	size_t				extra_json_len;
550*1c60b9acSAndroid Build Coastguard Worker 	/**< validate-exit:
551*1c60b9acSAndroid Build Coastguard Worker 	 * length of optional "ext" JSON object contents for the JWT */
552*1c60b9acSAndroid Build Coastguard Worker 	const char			*csrf_in;
553*1c60b9acSAndroid Build Coastguard Worker 	/**< validate-entry:
554*1c60b9acSAndroid Build Coastguard Worker 	 * NULL, or an external CSRF token to check against what is in the JWT */
555*1c60b9acSAndroid Build Coastguard Worker 	unsigned long			expiry_unix_time;
556*1c60b9acSAndroid Build Coastguard Worker 	/**< sign-entry: seconds the JWT and cookie may live,
557*1c60b9acSAndroid Build Coastguard Worker 	 * validate-exit: expiry unix time */
558*1c60b9acSAndroid Build Coastguard Worker };
559*1c60b9acSAndroid Build Coastguard Worker 
560*1c60b9acSAndroid Build Coastguard Worker /**
561*1c60b9acSAndroid Build Coastguard Worker  * lws_jwt_sign_token_set_http_cookie() - creates sets a JWT in a wsi cookie
562*1c60b9acSAndroid Build Coastguard Worker  *
563*1c60b9acSAndroid Build Coastguard Worker  * \param wsi: the wsi to create the cookie header on
564*1c60b9acSAndroid Build Coastguard Worker  * \param i: structure describing what should be in the JWT
565*1c60b9acSAndroid Build Coastguard Worker  * \param p: wsi headers area
566*1c60b9acSAndroid Build Coastguard Worker  * \param end: end of wsi headers area
567*1c60b9acSAndroid Build Coastguard Worker  *
568*1c60b9acSAndroid Build Coastguard Worker  * Creates a JWT specified \p i, and attaches it to the outgoing headers on
569*1c60b9acSAndroid Build Coastguard Worker  * wsi.  Returns 0 if successful.
570*1c60b9acSAndroid Build Coastguard Worker  *
571*1c60b9acSAndroid Build Coastguard Worker  * Best-practice security restrictions are applied to the cookie set action,
572*1c60b9acSAndroid Build Coastguard Worker  * including forcing httponly, and __Host- prefix.  As required by __Host-, the
573*1c60b9acSAndroid Build Coastguard Worker  * cookie Path is set to /.  __Host- is applied by the function, the cookie_name
574*1c60b9acSAndroid Build Coastguard Worker  * should just be "xyz" for "__Host-xyz".
575*1c60b9acSAndroid Build Coastguard Worker  *
576*1c60b9acSAndroid Build Coastguard Worker  * \p extra_json should just be the bare JSON, a { } is provided around it by
577*1c60b9acSAndroid Build Coastguard Worker  * the function if it's non-NULL.  For example, "\"authorization\": 1".
578*1c60b9acSAndroid Build Coastguard Worker  *
579*1c60b9acSAndroid Build Coastguard Worker  * It's recommended the secs parameter is kept as small as consistent with one
580*1c60b9acSAndroid Build Coastguard Worker  * user session on the site if possible, eg, 10 minutes or 20 minutes.  At the
581*1c60b9acSAndroid Build Coastguard Worker  * server, it can determine how much time is left in the auth and inform the
582*1c60b9acSAndroid Build Coastguard Worker  * client; if the JWT validity expires, the page should reload so the UI always
583*1c60b9acSAndroid Build Coastguard Worker  * reflects what's possible to do with the authorization state correctly.  If
584*1c60b9acSAndroid Build Coastguard Worker  * the JWT expires, the user can log back in using credentials usually stored in
585*1c60b9acSAndroid Build Coastguard Worker  * the browser and auto-filled-in, so this is not very inconvenient.
586*1c60b9acSAndroid Build Coastguard Worker  *
587*1c60b9acSAndroid Build Coastguard Worker  * This is a helper on top of the other JOSE and JWT apis that somewhat crosses
588*1c60b9acSAndroid Build Coastguard Worker  * over between JWT and HTTP, since it knows about cookies.  So it is only built
589*1c60b9acSAndroid Build Coastguard Worker  * if both LWS_WITH_JOSE and one of the http-related roles enabled.
590*1c60b9acSAndroid Build Coastguard Worker  */
591*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
592*1c60b9acSAndroid Build Coastguard Worker lws_jwt_sign_token_set_http_cookie(struct lws *wsi,
593*1c60b9acSAndroid Build Coastguard Worker 				   const struct lws_jwt_sign_set_cookie *i,
594*1c60b9acSAndroid Build Coastguard Worker 				   uint8_t **p, uint8_t *end);
595*1c60b9acSAndroid Build Coastguard Worker LWS_VISIBLE LWS_EXTERN int
596*1c60b9acSAndroid Build Coastguard Worker lws_jwt_get_http_cookie_validate_jwt(struct lws *wsi,
597*1c60b9acSAndroid Build Coastguard Worker 				     struct lws_jwt_sign_set_cookie *i,
598*1c60b9acSAndroid Build Coastguard Worker 				     char *out, size_t *out_len);
599*1c60b9acSAndroid Build Coastguard Worker #endif
600*1c60b9acSAndroid Build Coastguard Worker 
601*1c60b9acSAndroid Build Coastguard Worker ///@}
602