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 * cose_sign handling
25*1c60b9acSAndroid Build Coastguard Worker *
26*1c60b9acSAndroid Build Coastguard Worker * Validation:
27*1c60b9acSAndroid Build Coastguard Worker *
28*1c60b9acSAndroid Build Coastguard Worker * - we put all our pieces and results in an lwsac in the parse state object
29*1c60b9acSAndroid Build Coastguard Worker *
30*1c60b9acSAndroid Build Coastguard Worker * - we collect pieces needed for sig validation into lwsac elements
31*1c60b9acSAndroid Build Coastguard Worker *
32*1c60b9acSAndroid Build Coastguard Worker * - we go through each signature making discrete results in the lwsac for
33*1c60b9acSAndroid Build Coastguard Worker * the user code to assess
34*1c60b9acSAndroid Build Coastguard Worker */
35*1c60b9acSAndroid Build Coastguard Worker
36*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
37*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-cose.h"
38*1c60b9acSAndroid Build Coastguard Worker
39*1c60b9acSAndroid Build Coastguard Worker const uint8_t *sig_mctx[] = { (uint8_t *)"",
40*1c60b9acSAndroid Build Coastguard Worker (uint8_t *)"\x85\x69""Signature",
41*1c60b9acSAndroid Build Coastguard Worker (uint8_t *)"\x84\x6a""Signature1",
42*1c60b9acSAndroid Build Coastguard Worker (uint8_t *)"\x85\x6f""CounterSignature",
43*1c60b9acSAndroid Build Coastguard Worker (uint8_t *)"\x84\x63""MAC",
44*1c60b9acSAndroid Build Coastguard Worker (uint8_t *)"\x84\x64""MAC0",
45*1c60b9acSAndroid Build Coastguard Worker };
46*1c60b9acSAndroid Build Coastguard Worker uint8_t sig_mctx_len[] = { 0, 11, 12, 17, 5, 6 };
47*1c60b9acSAndroid Build Coastguard Worker
48*1c60b9acSAndroid Build Coastguard Worker struct alg_names {
49*1c60b9acSAndroid Build Coastguard Worker const char *name;
50*1c60b9acSAndroid Build Coastguard Worker cose_param_t alg;
51*1c60b9acSAndroid Build Coastguard Worker } alg_names[] = {
52*1c60b9acSAndroid Build Coastguard Worker { "ES256", LWSCOSE_WKAECDSA_ALG_ES256 },
53*1c60b9acSAndroid Build Coastguard Worker { "ES384", LWSCOSE_WKAECDSA_ALG_ES384 },
54*1c60b9acSAndroid Build Coastguard Worker { "ES512", LWSCOSE_WKAECDSA_ALG_ES512 },
55*1c60b9acSAndroid Build Coastguard Worker { "HS256_64", LWSCOSE_WKAHMAC_256_64 },
56*1c60b9acSAndroid Build Coastguard Worker { "HS256", LWSCOSE_WKAHMAC_256_256 },
57*1c60b9acSAndroid Build Coastguard Worker { "HS384", LWSCOSE_WKAHMAC_384_384 },
58*1c60b9acSAndroid Build Coastguard Worker { "HS512", LWSCOSE_WKAHMAC_512_512 },
59*1c60b9acSAndroid Build Coastguard Worker { "RS256", LWSCOSE_WKARSA_ALG_RS256 },
60*1c60b9acSAndroid Build Coastguard Worker { "RS384", LWSCOSE_WKARSA_ALG_RS384 },
61*1c60b9acSAndroid Build Coastguard Worker { "RS512", LWSCOSE_WKARSA_ALG_RS512 },
62*1c60b9acSAndroid Build Coastguard Worker };
63*1c60b9acSAndroid Build Coastguard Worker
64*1c60b9acSAndroid Build Coastguard Worker /*
65*1c60b9acSAndroid Build Coastguard Worker * The Sig_structure plaintext is new temp CBOR made up from pieces from the
66*1c60b9acSAndroid Build Coastguard Worker * cose_sign, cose_signature, and payload in a specific order
67*1c60b9acSAndroid Build Coastguard Worker *
68*1c60b9acSAndroid Build Coastguard Worker * tstr context string
69*1c60b9acSAndroid Build Coastguard Worker * bstr 0-len or protected body headers
70*1c60b9acSAndroid Build Coastguard Worker * bstr (Missing for sign1) 0-len or protected signer headers
71*1c60b9acSAndroid Build Coastguard Worker * bstr 0-len or protected application part
72*1c60b9acSAndroid Build Coastguard Worker * bstr the payload
73*1c60b9acSAndroid Build Coastguard Worker *
74*1c60b9acSAndroid Build Coastguard Worker * We are getting CBOR with an optional outer tag and then an array of exactly
75*1c60b9acSAndroid Build Coastguard Worker * 4 items in a fixed order
76*1c60b9acSAndroid Build Coastguard Worker *
77*1c60b9acSAndroid Build Coastguard Worker * [
78*1c60b9acSAndroid Build Coastguard Worker * protected headers: bstr containing a map (captured as CBOR in cps->ph[])
79*1c60b9acSAndroid Build Coastguard Worker * unprotected: map: for sign1, eg, the alg (!?), the kid
80*1c60b9acSAndroid Build Coastguard Worker * payload: bstr
81*1c60b9acSAndroid Build Coastguard Worker * if sign: signatures: [ cose_signature struct array,
82*1c60b9acSAndroid Build Coastguard Worker * each is a 3-element array
83*1c60b9acSAndroid Build Coastguard Worker * [
84*1c60b9acSAndroid Build Coastguard Worker * protected: bstr containing a map: (eg, the alg) (captured as CBOR)
85*1c60b9acSAndroid Build Coastguard Worker * unprotected: map: (eg, the kid)
86*1c60b9acSAndroid Build Coastguard Worker * signature: bstr
87*1c60b9acSAndroid Build Coastguard Worker * ]
88*1c60b9acSAndroid Build Coastguard Worker * if sign1: bstr containing signature
89*1c60b9acSAndroid Build Coastguard Worker * ]
90*1c60b9acSAndroid Build Coastguard Worker *
91*1c60b9acSAndroid Build Coastguard Worker * The last signatures field may be an array of signatures, or a single
92*1c60b9acSAndroid Build Coastguard Worker * cose_signature object for cose_sign1.
93*1c60b9acSAndroid Build Coastguard Worker *
94*1c60b9acSAndroid Build Coastguard Worker * For cose_sign1, we know the signature alg before the payload and can do it
95*1c60b9acSAndroid Build Coastguard Worker * in a single pass. But for sign, we do not know the signature algs until
96*1c60b9acSAndroid Build Coastguard Worker * after the payload, which is an unfortunate oversight in cose_sign, meaning we
97*1c60b9acSAndroid Build Coastguard Worker * cannot hash the payload one or more ways in a single pass.
98*1c60b9acSAndroid Build Coastguard Worker */
99*1c60b9acSAndroid Build Coastguard Worker
100*1c60b9acSAndroid Build Coastguard Worker #if defined(VERBOSE)
101*1c60b9acSAndroid Build Coastguard Worker const char *cose_sections[] = {
102*1c60b9acSAndroid Build Coastguard Worker "ST_UNKNOWN",
103*1c60b9acSAndroid Build Coastguard Worker
104*1c60b9acSAndroid Build Coastguard Worker "ST_OUTER_PROTECTED",
105*1c60b9acSAndroid Build Coastguard Worker "ST_OUTER_UNPROTECTED",
106*1c60b9acSAndroid Build Coastguard Worker "ST_OUTER_PAYLOAD",
107*1c60b9acSAndroid Build Coastguard Worker "ST_OUTER_SIGN1_SIGNATURE",
108*1c60b9acSAndroid Build Coastguard Worker
109*1c60b9acSAndroid Build Coastguard Worker "ST_OUTER_SIGN_SIGARRAY",
110*1c60b9acSAndroid Build Coastguard Worker
111*1c60b9acSAndroid Build Coastguard Worker "ST_OUTER_MACTAG",
112*1c60b9acSAndroid Build Coastguard Worker
113*1c60b9acSAndroid Build Coastguard Worker "ST_INNER_PROTECTED",
114*1c60b9acSAndroid Build Coastguard Worker "ST_INNER_UNPROTECTED",
115*1c60b9acSAndroid Build Coastguard Worker "ST_INNER_SIGNATURE",
116*1c60b9acSAndroid Build Coastguard Worker
117*1c60b9acSAndroid Build Coastguard Worker "ST_INNER_EXCESS",
118*1c60b9acSAndroid Build Coastguard Worker };
119*1c60b9acSAndroid Build Coastguard Worker #endif
120*1c60b9acSAndroid Build Coastguard Worker
121*1c60b9acSAndroid Build Coastguard Worker const char *
lws_cose_alg_to_name(cose_param_t alg)122*1c60b9acSAndroid Build Coastguard Worker lws_cose_alg_to_name(cose_param_t alg)
123*1c60b9acSAndroid Build Coastguard Worker {
124*1c60b9acSAndroid Build Coastguard Worker size_t n;
125*1c60b9acSAndroid Build Coastguard Worker
126*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < LWS_ARRAY_SIZE(alg_names); n++)
127*1c60b9acSAndroid Build Coastguard Worker if (alg_names[n].alg == alg)
128*1c60b9acSAndroid Build Coastguard Worker return alg_names[n].name;
129*1c60b9acSAndroid Build Coastguard Worker
130*1c60b9acSAndroid Build Coastguard Worker return "unknown_alg";
131*1c60b9acSAndroid Build Coastguard Worker }
132*1c60b9acSAndroid Build Coastguard Worker
133*1c60b9acSAndroid Build Coastguard Worker cose_param_t
lws_cose_name_to_alg(const char * name)134*1c60b9acSAndroid Build Coastguard Worker lws_cose_name_to_alg(const char *name)
135*1c60b9acSAndroid Build Coastguard Worker {
136*1c60b9acSAndroid Build Coastguard Worker size_t n;
137*1c60b9acSAndroid Build Coastguard Worker
138*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < LWS_ARRAY_SIZE(alg_names); n++)
139*1c60b9acSAndroid Build Coastguard Worker if (!strcmp(alg_names[n].name, name))
140*1c60b9acSAndroid Build Coastguard Worker return alg_names[n].alg;
141*1c60b9acSAndroid Build Coastguard Worker
142*1c60b9acSAndroid Build Coastguard Worker return 0;
143*1c60b9acSAndroid Build Coastguard Worker }
144*1c60b9acSAndroid Build Coastguard Worker
145*1c60b9acSAndroid Build Coastguard Worker static size_t
bstr_len(uint8_t * t,size_t buflen,uint8_t opcode,uint64_t len)146*1c60b9acSAndroid Build Coastguard Worker bstr_len(uint8_t *t, size_t buflen, uint8_t opcode, uint64_t len)
147*1c60b9acSAndroid Build Coastguard Worker {
148*1c60b9acSAndroid Build Coastguard Worker uint8_t *ot = t;
149*1c60b9acSAndroid Build Coastguard Worker
150*1c60b9acSAndroid Build Coastguard Worker if (buflen < 9)
151*1c60b9acSAndroid Build Coastguard Worker return 0;
152*1c60b9acSAndroid Build Coastguard Worker
153*1c60b9acSAndroid Build Coastguard Worker if (len < 24) {
154*1c60b9acSAndroid Build Coastguard Worker *t = (uint8_t)(opcode | len);
155*1c60b9acSAndroid Build Coastguard Worker
156*1c60b9acSAndroid Build Coastguard Worker return 1;
157*1c60b9acSAndroid Build Coastguard Worker }
158*1c60b9acSAndroid Build Coastguard Worker if (len < 256) {
159*1c60b9acSAndroid Build Coastguard Worker *t++ = opcode | LWS_CBOR_1;
160*1c60b9acSAndroid Build Coastguard Worker goto b;
161*1c60b9acSAndroid Build Coastguard Worker }
162*1c60b9acSAndroid Build Coastguard Worker if (len < 65536) {
163*1c60b9acSAndroid Build Coastguard Worker *t++ = opcode | LWS_CBOR_2;
164*1c60b9acSAndroid Build Coastguard Worker goto b1;
165*1c60b9acSAndroid Build Coastguard Worker }
166*1c60b9acSAndroid Build Coastguard Worker if (len < 0xffffffffu) {
167*1c60b9acSAndroid Build Coastguard Worker *t++ = opcode | LWS_CBOR_4;
168*1c60b9acSAndroid Build Coastguard Worker goto b2;
169*1c60b9acSAndroid Build Coastguard Worker }
170*1c60b9acSAndroid Build Coastguard Worker
171*1c60b9acSAndroid Build Coastguard Worker *t++ = opcode | LWS_CBOR_8;
172*1c60b9acSAndroid Build Coastguard Worker
173*1c60b9acSAndroid Build Coastguard Worker *t++ = (uint8_t)(len >> 56);
174*1c60b9acSAndroid Build Coastguard Worker *t++ = (uint8_t)(len >> 48);
175*1c60b9acSAndroid Build Coastguard Worker *t++ = (uint8_t)(len >> 40);
176*1c60b9acSAndroid Build Coastguard Worker *t++ = (uint8_t)(len >> 32);
177*1c60b9acSAndroid Build Coastguard Worker
178*1c60b9acSAndroid Build Coastguard Worker b2:
179*1c60b9acSAndroid Build Coastguard Worker *t++ = (uint8_t)(len >> 24);
180*1c60b9acSAndroid Build Coastguard Worker *t++ = (uint8_t)(len >> 16);
181*1c60b9acSAndroid Build Coastguard Worker b1:
182*1c60b9acSAndroid Build Coastguard Worker *t++ = (uint8_t)(len >> 8);
183*1c60b9acSAndroid Build Coastguard Worker b:
184*1c60b9acSAndroid Build Coastguard Worker *t++ = (uint8_t)len;
185*1c60b9acSAndroid Build Coastguard Worker
186*1c60b9acSAndroid Build Coastguard Worker return lws_ptr_diff_size_t(t, ot);
187*1c60b9acSAndroid Build Coastguard Worker }
188*1c60b9acSAndroid Build Coastguard Worker
189*1c60b9acSAndroid Build Coastguard Worker static int
apply_external(struct lws_cose_validate_context * cps)190*1c60b9acSAndroid Build Coastguard Worker apply_external(struct lws_cose_validate_context *cps)
191*1c60b9acSAndroid Build Coastguard Worker {
192*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t *alg;
193*1c60b9acSAndroid Build Coastguard Worker uint8_t t[9];
194*1c60b9acSAndroid Build Coastguard Worker
195*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(cps->algs.head, lws_cose_sig_alg_t, list);
196*1c60b9acSAndroid Build Coastguard Worker if (!alg)
197*1c60b9acSAndroid Build Coastguard Worker /* expected if no key */
198*1c60b9acSAndroid Build Coastguard Worker return 0;
199*1c60b9acSAndroid Build Coastguard Worker
200*1c60b9acSAndroid Build Coastguard Worker /* get the external payload first, if any indicated */
201*1c60b9acSAndroid Build Coastguard Worker
202*1c60b9acSAndroid Build Coastguard Worker if (cps->info.ext_len) {
203*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_ext_pay_t ex;
204*1c60b9acSAndroid Build Coastguard Worker size_t s;
205*1c60b9acSAndroid Build Coastguard Worker
206*1c60b9acSAndroid Build Coastguard Worker s = bstr_len(t, sizeof(t), LWS_CBOR_MAJTYP_BSTR,
207*1c60b9acSAndroid Build Coastguard Worker cps->info.ext_len);
208*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_val_alg_hash(alg, t, s))
209*1c60b9acSAndroid Build Coastguard Worker return 1;
210*1c60b9acSAndroid Build Coastguard Worker
211*1c60b9acSAndroid Build Coastguard Worker memset(&ex, 0, sizeof(ex));
212*1c60b9acSAndroid Build Coastguard Worker ex.cps = cps;
213*1c60b9acSAndroid Build Coastguard Worker
214*1c60b9acSAndroid Build Coastguard Worker do {
215*1c60b9acSAndroid Build Coastguard Worker int n;
216*1c60b9acSAndroid Build Coastguard Worker
217*1c60b9acSAndroid Build Coastguard Worker ex.xl = 0;
218*1c60b9acSAndroid Build Coastguard Worker n = cps->info.ext_cb(&ex);
219*1c60b9acSAndroid Build Coastguard Worker
220*1c60b9acSAndroid Build Coastguard Worker if (ex.xl &&
221*1c60b9acSAndroid Build Coastguard Worker lws_cose_val_alg_hash(alg, ex.ext, ex.xl))
222*1c60b9acSAndroid Build Coastguard Worker return 1;
223*1c60b9acSAndroid Build Coastguard Worker
224*1c60b9acSAndroid Build Coastguard Worker if (n == LCOSESIGEXTCB_RET_ERROR)
225*1c60b9acSAndroid Build Coastguard Worker return 1;
226*1c60b9acSAndroid Build Coastguard Worker
227*1c60b9acSAndroid Build Coastguard Worker if (n == LCOSESIGEXTCB_RET_FINISHED)
228*1c60b9acSAndroid Build Coastguard Worker break;
229*1c60b9acSAndroid Build Coastguard Worker } while (1);
230*1c60b9acSAndroid Build Coastguard Worker }
231*1c60b9acSAndroid Build Coastguard Worker
232*1c60b9acSAndroid Build Coastguard Worker return 0;
233*1c60b9acSAndroid Build Coastguard Worker }
234*1c60b9acSAndroid Build Coastguard Worker
235*1c60b9acSAndroid Build Coastguard Worker static int
create_alg(struct lecp_ctx * ctx,struct lws_cose_validate_context * cps)236*1c60b9acSAndroid Build Coastguard Worker create_alg(struct lecp_ctx *ctx, struct lws_cose_validate_context *cps)
237*1c60b9acSAndroid Build Coastguard Worker {
238*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_param_stack_t *sl = &cps->st[cps->sp], *sl0 = &cps->st[0];
239*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_res_t *res;
240*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t *alg;
241*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_t *ck;
242*1c60b9acSAndroid Build Coastguard Worker uint8_t *p;
243*1c60b9acSAndroid Build Coastguard Worker size_t s;
244*1c60b9acSAndroid Build Coastguard Worker
245*1c60b9acSAndroid Build Coastguard Worker /* with sign1, we can hash the payload in a
246*1c60b9acSAndroid Build Coastguard Worker * single pass */
247*1c60b9acSAndroid Build Coastguard Worker
248*1c60b9acSAndroid Build Coastguard Worker ck = lws_cose_key_from_set(cps->info.keyset, sl->kid.buf, sl->kid.len);
249*1c60b9acSAndroid Build Coastguard Worker if (!ck) {
250*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: no key\n", __func__);
251*1c60b9acSAndroid Build Coastguard Worker lwsl_hexdump_notice(sl->kid.buf, sl->kid.len);
252*1c60b9acSAndroid Build Coastguard Worker goto no_key_or_alg;
253*1c60b9acSAndroid Build Coastguard Worker }
254*1c60b9acSAndroid Build Coastguard Worker
255*1c60b9acSAndroid Build Coastguard Worker // lwsl_notice("%s: cps->alg %d\n", __func__, (int)cps->alg);
256*1c60b9acSAndroid Build Coastguard Worker
257*1c60b9acSAndroid Build Coastguard Worker alg = lws_cose_val_alg_create(cps->info.cx, ck, cps->st[0].alg,
258*1c60b9acSAndroid Build Coastguard Worker LWSCOSE_WKKO_VERIFY);
259*1c60b9acSAndroid Build Coastguard Worker if (!alg) {
260*1c60b9acSAndroid Build Coastguard Worker lwsl_info("%s: no alg\n", __func__);
261*1c60b9acSAndroid Build Coastguard Worker
262*1c60b9acSAndroid Build Coastguard Worker no_key_or_alg:
263*1c60b9acSAndroid Build Coastguard Worker /*
264*1c60b9acSAndroid Build Coastguard Worker * We can't create the alg then, so we can't normally
265*1c60b9acSAndroid Build Coastguard Worker * create a result object. Create one especially for this
266*1c60b9acSAndroid Build Coastguard Worker * case and continue on
267*1c60b9acSAndroid Build Coastguard Worker */
268*1c60b9acSAndroid Build Coastguard Worker
269*1c60b9acSAndroid Build Coastguard Worker res = lws_zalloc(sizeof(*res), __func__);
270*1c60b9acSAndroid Build Coastguard Worker if (res) {
271*1c60b9acSAndroid Build Coastguard Worker res->result = -1001;
272*1c60b9acSAndroid Build Coastguard Worker
273*1c60b9acSAndroid Build Coastguard Worker lws_dll2_add_tail(&res->list, &cps->results);
274*1c60b9acSAndroid Build Coastguard Worker }
275*1c60b9acSAndroid Build Coastguard Worker
276*1c60b9acSAndroid Build Coastguard Worker return 0;
277*1c60b9acSAndroid Build Coastguard Worker }
278*1c60b9acSAndroid Build Coastguard Worker
279*1c60b9acSAndroid Build Coastguard Worker lws_dll2_add_tail(&alg->list, &cps->algs);
280*1c60b9acSAndroid Build Coastguard Worker
281*1c60b9acSAndroid Build Coastguard Worker /*
282*1c60b9acSAndroid Build Coastguard Worker * Hash step 1: The first hash content depends on
283*1c60b9acSAndroid Build Coastguard Worker * sign/sign1/csign/mac/mac0 constant bstr
284*1c60b9acSAndroid Build Coastguard Worker */
285*1c60b9acSAndroid Build Coastguard Worker
286*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_val_alg_hash(alg, sig_mctx[cps->info.sigtype],
287*1c60b9acSAndroid Build Coastguard Worker sig_mctx_len[cps->info.sigtype]))
288*1c60b9acSAndroid Build Coastguard Worker goto bail;
289*1c60b9acSAndroid Build Coastguard Worker
290*1c60b9acSAndroid Build Coastguard Worker /*
291*1c60b9acSAndroid Build Coastguard Worker * Hash step 2: A zero-length bstr, or a copy of the
292*1c60b9acSAndroid Build Coastguard Worker * OUTER protected headers
293*1c60b9acSAndroid Build Coastguard Worker *
294*1c60b9acSAndroid Build Coastguard Worker * A zero-entry map alone becomes a zero-
295*1c60b9acSAndroid Build Coastguard Worker * length bstr
296*1c60b9acSAndroid Build Coastguard Worker */
297*1c60b9acSAndroid Build Coastguard Worker
298*1c60b9acSAndroid Build Coastguard Worker if (sl0->ph_pos[0] < 2) {
299*1c60b9acSAndroid Build Coastguard Worker /* nothing to speak of */
300*1c60b9acSAndroid Build Coastguard Worker sl0->ph[0][0] = LWS_CBOR_MAJTYP_BSTR;
301*1c60b9acSAndroid Build Coastguard Worker p = &sl0->ph[0][0];
302*1c60b9acSAndroid Build Coastguard Worker s = 1;
303*1c60b9acSAndroid Build Coastguard Worker } else {
304*1c60b9acSAndroid Build Coastguard Worker if (sl0->ph_pos[0] < 24) {
305*1c60b9acSAndroid Build Coastguard Worker sl0->ph[0][2] = (uint8_t)
306*1c60b9acSAndroid Build Coastguard Worker (LWS_CBOR_MAJTYP_BSTR | sl0->ph_pos[0]);
307*1c60b9acSAndroid Build Coastguard Worker p = &sl0->ph[0][2];
308*1c60b9acSAndroid Build Coastguard Worker s = (size_t)sl0->ph_pos[0] + 1;
309*1c60b9acSAndroid Build Coastguard Worker } else {
310*1c60b9acSAndroid Build Coastguard Worker sl0->ph[0][1] = LWS_CBOR_MAJTYP_BSTR |
311*1c60b9acSAndroid Build Coastguard Worker LWS_CBOR_1;
312*1c60b9acSAndroid Build Coastguard Worker sl0->ph[0][2] = (uint8_t)sl0->ph_pos[0];
313*1c60b9acSAndroid Build Coastguard Worker p = &sl0->ph[0][1];
314*1c60b9acSAndroid Build Coastguard Worker s = (size_t)sl0->ph_pos[0] + 2;
315*1c60b9acSAndroid Build Coastguard Worker }
316*1c60b9acSAndroid Build Coastguard Worker }
317*1c60b9acSAndroid Build Coastguard Worker
318*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_val_alg_hash(alg, p, s))
319*1c60b9acSAndroid Build Coastguard Worker goto bail;
320*1c60b9acSAndroid Build Coastguard Worker
321*1c60b9acSAndroid Build Coastguard Worker /*
322*1c60b9acSAndroid Build Coastguard Worker * Hash step 3: Protected signer headers (Elided for sign1)
323*1c60b9acSAndroid Build Coastguard Worker */
324*1c60b9acSAndroid Build Coastguard Worker
325*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype == SIGTYPE_MULTI) {
326*1c60b9acSAndroid Build Coastguard Worker if (sl->ph_pos[2] < 2) {
327*1c60b9acSAndroid Build Coastguard Worker /* nothing to speak of */
328*1c60b9acSAndroid Build Coastguard Worker sl->ph[2][0] = LWS_CBOR_MAJTYP_BSTR;
329*1c60b9acSAndroid Build Coastguard Worker p = &sl->ph[2][0];
330*1c60b9acSAndroid Build Coastguard Worker s = 1;
331*1c60b9acSAndroid Build Coastguard Worker } else {
332*1c60b9acSAndroid Build Coastguard Worker if (sl->ph_pos[2] < 24) {
333*1c60b9acSAndroid Build Coastguard Worker sl->ph[2][2] = (uint8_t)
334*1c60b9acSAndroid Build Coastguard Worker (LWS_CBOR_MAJTYP_BSTR | sl->ph_pos[2]);
335*1c60b9acSAndroid Build Coastguard Worker p = &sl->ph[2][2];
336*1c60b9acSAndroid Build Coastguard Worker s = (size_t)sl->ph_pos[2] + 1;
337*1c60b9acSAndroid Build Coastguard Worker } else {
338*1c60b9acSAndroid Build Coastguard Worker sl->ph[2][1] = LWS_CBOR_MAJTYP_BSTR |
339*1c60b9acSAndroid Build Coastguard Worker LWS_CBOR_1;
340*1c60b9acSAndroid Build Coastguard Worker sl->ph[2][2] = (uint8_t)sl->ph_pos[2];
341*1c60b9acSAndroid Build Coastguard Worker p = &sl->ph[2][1];
342*1c60b9acSAndroid Build Coastguard Worker s = (size_t)sl->ph_pos[2] + 2;
343*1c60b9acSAndroid Build Coastguard Worker }
344*1c60b9acSAndroid Build Coastguard Worker }
345*1c60b9acSAndroid Build Coastguard Worker
346*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_val_alg_hash(alg, p, s))
347*1c60b9acSAndroid Build Coastguard Worker goto bail;
348*1c60b9acSAndroid Build Coastguard Worker }
349*1c60b9acSAndroid Build Coastguard Worker
350*1c60b9acSAndroid Build Coastguard Worker /* Hash step 4: bstr for applictation protected pieces
351*1c60b9acSAndroid Build Coastguard Worker * empty for now
352*1c60b9acSAndroid Build Coastguard Worker */
353*1c60b9acSAndroid Build Coastguard Worker
354*1c60b9acSAndroid Build Coastguard Worker if (!cps->info.ext_len) { /* ie, if no app data */
355*1c60b9acSAndroid Build Coastguard Worker uint8_t u = LWS_CBOR_MAJTYP_BSTR;
356*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_val_alg_hash(alg, &u, 1))
357*1c60b9acSAndroid Build Coastguard Worker goto bail;
358*1c60b9acSAndroid Build Coastguard Worker }
359*1c60b9acSAndroid Build Coastguard Worker
360*1c60b9acSAndroid Build Coastguard Worker /*
361*1c60b9acSAndroid Build Coastguard Worker * The final part is the payload in its own bstr, as
362*1c60b9acSAndroid Build Coastguard Worker * we get it if sign1, else replayed from a cache in heap
363*1c60b9acSAndroid Build Coastguard Worker */
364*1c60b9acSAndroid Build Coastguard Worker
365*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype == SIGTYPE_SINGLE)
366*1c60b9acSAndroid Build Coastguard Worker return 0;
367*1c60b9acSAndroid Build Coastguard Worker
368*1c60b9acSAndroid Build Coastguard Worker if (!cps->payload_stash) {
369*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: no payload stash\n", __func__);
370*1c60b9acSAndroid Build Coastguard Worker goto bail;
371*1c60b9acSAndroid Build Coastguard Worker }
372*1c60b9acSAndroid Build Coastguard Worker
373*1c60b9acSAndroid Build Coastguard Worker apply_external(cps);
374*1c60b9acSAndroid Build Coastguard Worker
375*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_val_alg_hash(alg, cps->payload_stash, cps->payload_pos))
376*1c60b9acSAndroid Build Coastguard Worker goto bail;
377*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("a %d\n", (int)cps->sig_agg_pos);
378*1c60b9acSAndroid Build Coastguard Worker
379*1c60b9acSAndroid Build Coastguard Worker lws_cose_val_alg_destroy(cps, &alg, (const uint8_t *)cps->sig_agg,
380*1c60b9acSAndroid Build Coastguard Worker cps->sig_agg_pos);
381*1c60b9acSAndroid Build Coastguard Worker
382*1c60b9acSAndroid Build Coastguard Worker return 0;
383*1c60b9acSAndroid Build Coastguard Worker
384*1c60b9acSAndroid Build Coastguard Worker bail:
385*1c60b9acSAndroid Build Coastguard Worker return 1;
386*1c60b9acSAndroid Build Coastguard Worker }
387*1c60b9acSAndroid Build Coastguard Worker
388*1c60b9acSAndroid Build Coastguard Worker #if defined(VERBOSE)
389*1c60b9acSAndroid Build Coastguard Worker static const char * const reason_names[] = {
390*1c60b9acSAndroid Build Coastguard Worker "LECPCB_CONSTRUCTED",
391*1c60b9acSAndroid Build Coastguard Worker "LECPCB_DESTRUCTED",
392*1c60b9acSAndroid Build Coastguard Worker "LECPCB_START",
393*1c60b9acSAndroid Build Coastguard Worker "LECPCB_COMPLETE",
394*1c60b9acSAndroid Build Coastguard Worker "LECPCB_FAILED",
395*1c60b9acSAndroid Build Coastguard Worker "LECPCB_PAIR_NAME",
396*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_TRUE",
397*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_FALSE",
398*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_NULL",
399*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_NUM_INT",
400*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_RESERVED", /* float in lejp */
401*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_STR_START",
402*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_STR_CHUNK",
403*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_STR_END",
404*1c60b9acSAndroid Build Coastguard Worker "LECPCB_ARRAY_START",
405*1c60b9acSAndroid Build Coastguard Worker "LECPCB_ARRAY_END",
406*1c60b9acSAndroid Build Coastguard Worker "LECPCB_OBJECT_START",
407*1c60b9acSAndroid Build Coastguard Worker "LECPCB_OBJECT_END",
408*1c60b9acSAndroid Build Coastguard Worker "LECPCB_TAG_START",
409*1c60b9acSAndroid Build Coastguard Worker "LECPCB_TAG_END",
410*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_NUM_UINT",
411*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_UNDEFINED",
412*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_FLOAT16",
413*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_FLOAT32",
414*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_FLOAT64",
415*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_SIMPLE",
416*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_BLOB_START",
417*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_BLOB_CHUNK",
418*1c60b9acSAndroid Build Coastguard Worker "LECPCB_VAL_BLOB_END",
419*1c60b9acSAndroid Build Coastguard Worker "LECPCB_ARRAY_ITEM_START",
420*1c60b9acSAndroid Build Coastguard Worker "LECPCB_ARRAY_ITEM_END",
421*1c60b9acSAndroid Build Coastguard Worker "LECPCB_LITERAL_CBOR"
422*1c60b9acSAndroid Build Coastguard Worker };
423*1c60b9acSAndroid Build Coastguard Worker #endif
424*1c60b9acSAndroid Build Coastguard Worker
425*1c60b9acSAndroid Build Coastguard Worker static int
ph_index(struct lws_cose_validate_context * cps)426*1c60b9acSAndroid Build Coastguard Worker ph_index(struct lws_cose_validate_context *cps)
427*1c60b9acSAndroid Build Coastguard Worker {
428*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
429*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PROTECTED:
430*1c60b9acSAndroid Build Coastguard Worker return 0;
431*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_UNPROTECTED:
432*1c60b9acSAndroid Build Coastguard Worker return 1;
433*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_PROTECTED:
434*1c60b9acSAndroid Build Coastguard Worker return 2;
435*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_UNPROTECTED:
436*1c60b9acSAndroid Build Coastguard Worker return 3;
437*1c60b9acSAndroid Build Coastguard Worker }
438*1c60b9acSAndroid Build Coastguard Worker
439*1c60b9acSAndroid Build Coastguard Worker assert(0);
440*1c60b9acSAndroid Build Coastguard Worker return 0;
441*1c60b9acSAndroid Build Coastguard Worker }
442*1c60b9acSAndroid Build Coastguard Worker
443*1c60b9acSAndroid Build Coastguard Worker static signed char
cb_cose_sig(struct lecp_ctx * ctx,char reason)444*1c60b9acSAndroid Build Coastguard Worker cb_cose_sig(struct lecp_ctx *ctx, char reason)
445*1c60b9acSAndroid Build Coastguard Worker {
446*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_validate_context *cps =
447*1c60b9acSAndroid Build Coastguard Worker (struct lws_cose_validate_context *)ctx->user;
448*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_param_stack_t *sl;
449*1c60b9acSAndroid Build Coastguard Worker struct lws_gencrypto_keyelem *ke;
450*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t *alg;
451*1c60b9acSAndroid Build Coastguard Worker uint8_t t[9];
452*1c60b9acSAndroid Build Coastguard Worker size_t s;
453*1c60b9acSAndroid Build Coastguard Worker int hi;
454*1c60b9acSAndroid Build Coastguard Worker
455*1c60b9acSAndroid Build Coastguard Worker #if defined(VERBOSE)
456*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: %s, tli %s, sub %d, ppos %d, sp %d\n", __func__,
457*1c60b9acSAndroid Build Coastguard Worker reason_names[reason & 0x1f], cose_sections[cps->tli],
458*1c60b9acSAndroid Build Coastguard Worker cps->sub, ctx->pst[ctx->pst_sp].ppos, cps->sp);
459*1c60b9acSAndroid Build Coastguard Worker #endif
460*1c60b9acSAndroid Build Coastguard Worker
461*1c60b9acSAndroid Build Coastguard Worker switch (reason) {
462*1c60b9acSAndroid Build Coastguard Worker case LECPCB_CONSTRUCTED:
463*1c60b9acSAndroid Build Coastguard Worker break;
464*1c60b9acSAndroid Build Coastguard Worker
465*1c60b9acSAndroid Build Coastguard Worker case LECPCB_TAG_START:
466*1c60b9acSAndroid Build Coastguard Worker
467*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: tag sigtype %d\n", __func__, cps->info.sigtype);
468*1c60b9acSAndroid Build Coastguard Worker
469*1c60b9acSAndroid Build Coastguard Worker switch (cps->info.sigtype) {
470*1c60b9acSAndroid Build Coastguard Worker default:
471*1c60b9acSAndroid Build Coastguard Worker assert(0);
472*1c60b9acSAndroid Build Coastguard Worker break;
473*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_UNKNOWN:
474*1c60b9acSAndroid Build Coastguard Worker /* it means use the tag value to set the type */
475*1c60b9acSAndroid Build Coastguard Worker switch (ctx->item.u.u64) {
476*1c60b9acSAndroid Build Coastguard Worker case LWSCOAP_CONTENTFORMAT_COSE_SIGN:
477*1c60b9acSAndroid Build Coastguard Worker cps->info.sigtype = SIGTYPE_MULTI;
478*1c60b9acSAndroid Build Coastguard Worker break;
479*1c60b9acSAndroid Build Coastguard Worker case LWSCOAP_CONTENTFORMAT_COSE_SIGN1:
480*1c60b9acSAndroid Build Coastguard Worker cps->info.sigtype = SIGTYPE_SINGLE;
481*1c60b9acSAndroid Build Coastguard Worker break;
482*1c60b9acSAndroid Build Coastguard Worker // case LWSCOAP_CONTENTFORMAT_COSE_SIGN__:
483*1c60b9acSAndroid Build Coastguard Worker // cps->info.sigtype = SIGTYPE_COUNTERSIGNED;
484*1c60b9acSAndroid Build Coastguard Worker // break;
485*1c60b9acSAndroid Build Coastguard Worker case LWSCOAP_CONTENTFORMAT_COSE_MAC0:
486*1c60b9acSAndroid Build Coastguard Worker cps->info.sigtype = SIGTYPE_MAC0;
487*1c60b9acSAndroid Build Coastguard Worker break;
488*1c60b9acSAndroid Build Coastguard Worker case LWSCOAP_CONTENTFORMAT_COSE_MAC:
489*1c60b9acSAndroid Build Coastguard Worker cps->info.sigtype = SIGTYPE_MAC;
490*1c60b9acSAndroid Build Coastguard Worker break;
491*1c60b9acSAndroid Build Coastguard Worker default:
492*1c60b9acSAndroid Build Coastguard Worker goto unexpected_tag;
493*1c60b9acSAndroid Build Coastguard Worker }
494*1c60b9acSAndroid Build Coastguard Worker break;
495*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MULTI:
496*1c60b9acSAndroid Build Coastguard Worker if (ctx->item.u.u64 != LWSCOAP_CONTENTFORMAT_COSE_SIGN)
497*1c60b9acSAndroid Build Coastguard Worker goto unexpected_tag;
498*1c60b9acSAndroid Build Coastguard Worker break;
499*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_SINGLE:
500*1c60b9acSAndroid Build Coastguard Worker if (ctx->item.u.u64 != LWSCOAP_CONTENTFORMAT_COSE_SIGN1)
501*1c60b9acSAndroid Build Coastguard Worker goto unexpected_tag;
502*1c60b9acSAndroid Build Coastguard Worker break;
503*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_COUNTERSIGNED:
504*1c60b9acSAndroid Build Coastguard Worker if (ctx->item.u.u64 != LWSCOAP_CONTENTFORMAT_COSE_SIGN)
505*1c60b9acSAndroid Build Coastguard Worker goto unexpected_tag;
506*1c60b9acSAndroid Build Coastguard Worker break;
507*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC0:
508*1c60b9acSAndroid Build Coastguard Worker if (ctx->item.u.u64 != LWSCOAP_CONTENTFORMAT_COSE_MAC0)
509*1c60b9acSAndroid Build Coastguard Worker goto unexpected_tag;
510*1c60b9acSAndroid Build Coastguard Worker break;
511*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC:
512*1c60b9acSAndroid Build Coastguard Worker if (ctx->item.u.u64 != LWSCOAP_CONTENTFORMAT_COSE_MAC) {
513*1c60b9acSAndroid Build Coastguard Worker unexpected_tag:
514*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unexpected tag %d\n", __func__,
515*1c60b9acSAndroid Build Coastguard Worker (int)ctx->item.u.u64);
516*1c60b9acSAndroid Build Coastguard Worker goto bail;
517*1c60b9acSAndroid Build Coastguard Worker }
518*1c60b9acSAndroid Build Coastguard Worker break;
519*1c60b9acSAndroid Build Coastguard Worker }
520*1c60b9acSAndroid Build Coastguard Worker
521*1c60b9acSAndroid Build Coastguard Worker cps->depth++;
522*1c60b9acSAndroid Build Coastguard Worker break;
523*1c60b9acSAndroid Build Coastguard Worker
524*1c60b9acSAndroid Build Coastguard Worker case LECPCB_ARRAY_ITEM_START:
525*1c60b9acSAndroid Build Coastguard Worker
526*1c60b9acSAndroid Build Coastguard Worker if (cps->sub)
527*1c60b9acSAndroid Build Coastguard Worker break;
528*1c60b9acSAndroid Build Coastguard Worker
529*1c60b9acSAndroid Build Coastguard Worker if (ctx->pst[ctx->pst_sp].ppos == 4 ||
530*1c60b9acSAndroid Build Coastguard Worker ctx->pst[ctx->pst_sp].ppos == 6) {
531*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
532*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_UNPROTECTED:
533*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_PROTECTED:
534*1c60b9acSAndroid Build Coastguard Worker hi = ph_index(cps);
535*1c60b9acSAndroid Build Coastguard Worker sl = &cps->st[cps->sp];
536*1c60b9acSAndroid Build Coastguard Worker sl->ph_pos[hi] = 0;
537*1c60b9acSAndroid Build Coastguard Worker lecp_parse_report_raw(ctx, 1);
538*1c60b9acSAndroid Build Coastguard Worker break;
539*1c60b9acSAndroid Build Coastguard Worker default:
540*1c60b9acSAndroid Build Coastguard Worker break;
541*1c60b9acSAndroid Build Coastguard Worker }
542*1c60b9acSAndroid Build Coastguard Worker break;
543*1c60b9acSAndroid Build Coastguard Worker }
544*1c60b9acSAndroid Build Coastguard Worker
545*1c60b9acSAndroid Build Coastguard Worker if (ctx->pst[ctx->pst_sp].ppos != 2)
546*1c60b9acSAndroid Build Coastguard Worker break;
547*1c60b9acSAndroid Build Coastguard Worker
548*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
549*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_UNPROTECTED:
550*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PROTECTED:
551*1c60b9acSAndroid Build Coastguard Worker /*
552*1c60b9acSAndroid Build Coastguard Worker * Holy type confusion, Batman... this is a CBOR bstr
553*1c60b9acSAndroid Build Coastguard Worker * containing valid CBOR that must also be parsed as
554*1c60b9acSAndroid Build Coastguard Worker * part of the containing array... we need to collect
555*1c60b9acSAndroid Build Coastguard Worker * it anyway since it is part of the signing plaintext
556*1c60b9acSAndroid Build Coastguard Worker * in bstr form, let's get it and then parse it at the
557*1c60b9acSAndroid Build Coastguard Worker * END of the bstr.
558*1c60b9acSAndroid Build Coastguard Worker */
559*1c60b9acSAndroid Build Coastguard Worker lecp_parse_report_raw(ctx, 1);
560*1c60b9acSAndroid Build Coastguard Worker break;
561*1c60b9acSAndroid Build Coastguard Worker
562*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PAYLOAD:
563*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype != SIGTYPE_SINGLE)
564*1c60b9acSAndroid Build Coastguard Worker break;
565*1c60b9acSAndroid Build Coastguard Worker
566*1c60b9acSAndroid Build Coastguard Worker if (create_alg(ctx, cps))
567*1c60b9acSAndroid Build Coastguard Worker goto bail;
568*1c60b9acSAndroid Build Coastguard Worker
569*1c60b9acSAndroid Build Coastguard Worker break;
570*1c60b9acSAndroid Build Coastguard Worker
571*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_SIGN_SIGARRAY:
572*1c60b9acSAndroid Build Coastguard Worker cps->tli = ST_INNER_PROTECTED;
573*1c60b9acSAndroid Build Coastguard Worker break;
574*1c60b9acSAndroid Build Coastguard Worker }
575*1c60b9acSAndroid Build Coastguard Worker break;
576*1c60b9acSAndroid Build Coastguard Worker
577*1c60b9acSAndroid Build Coastguard Worker case LECPCB_ARRAY_ITEM_END:
578*1c60b9acSAndroid Build Coastguard Worker
579*1c60b9acSAndroid Build Coastguard Worker if (cps->sub)
580*1c60b9acSAndroid Build Coastguard Worker break;
581*1c60b9acSAndroid Build Coastguard Worker
582*1c60b9acSAndroid Build Coastguard Worker if (ctx->pst[ctx->pst_sp].ppos == 2) {
583*1c60b9acSAndroid Build Coastguard Worker sl = &cps->st[cps->sp];
584*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
585*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_UNPROTECTED:
586*1c60b9acSAndroid Build Coastguard Worker break;
587*1c60b9acSAndroid Build Coastguard Worker /* fallthru */
588*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PROTECTED:
589*1c60b9acSAndroid Build Coastguard Worker lecp_parse_report_raw(ctx, 0);
590*1c60b9acSAndroid Build Coastguard Worker
591*1c60b9acSAndroid Build Coastguard Worker hi = ph_index(cps);
592*1c60b9acSAndroid Build Coastguard Worker
593*1c60b9acSAndroid Build Coastguard Worker if (!sl->ph_pos[hi] || cps->sub)
594*1c60b9acSAndroid Build Coastguard Worker break;
595*1c60b9acSAndroid Build Coastguard Worker
596*1c60b9acSAndroid Build Coastguard Worker cps->sub = 1;
597*1c60b9acSAndroid Build Coastguard Worker s = (size_t)sl->ph_pos[hi];
598*1c60b9acSAndroid Build Coastguard Worker
599*1c60b9acSAndroid Build Coastguard Worker if (lecp_parse_subtree(&cps->ctx,
600*1c60b9acSAndroid Build Coastguard Worker sl->ph[hi] + 3, s) !=
601*1c60b9acSAndroid Build Coastguard Worker LECP_CONTINUE)
602*1c60b9acSAndroid Build Coastguard Worker goto bail;
603*1c60b9acSAndroid Build Coastguard Worker cps->sub = 0;
604*1c60b9acSAndroid Build Coastguard Worker break;
605*1c60b9acSAndroid Build Coastguard Worker
606*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PAYLOAD:
607*1c60b9acSAndroid Build Coastguard Worker switch (cps->info.sigtype) {
608*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MULTI:
609*1c60b9acSAndroid Build Coastguard Worker cps->tli = ST_OUTER_SIGN_SIGARRAY - 1;
610*1c60b9acSAndroid Build Coastguard Worker break;
611*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC:
612*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_MAC0:
613*1c60b9acSAndroid Build Coastguard Worker cps->tli = ST_OUTER_MACTAG - 1;
614*1c60b9acSAndroid Build Coastguard Worker break;
615*1c60b9acSAndroid Build Coastguard Worker case SIGTYPE_COUNTERSIGNED:
616*1c60b9acSAndroid Build Coastguard Worker break;
617*1c60b9acSAndroid Build Coastguard Worker default:
618*1c60b9acSAndroid Build Coastguard Worker break;
619*1c60b9acSAndroid Build Coastguard Worker }
620*1c60b9acSAndroid Build Coastguard Worker break;
621*1c60b9acSAndroid Build Coastguard Worker
622*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_SIGN1_SIGNATURE:
623*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_MACTAG:
624*1c60b9acSAndroid Build Coastguard Worker cps->sp++;
625*1c60b9acSAndroid Build Coastguard Worker cps->tli = ST_INNER_PROTECTED - 1;
626*1c60b9acSAndroid Build Coastguard Worker break;
627*1c60b9acSAndroid Build Coastguard Worker
628*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_UNPROTECTED:
629*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("ST_INNER_UNPROTECTED end\n");
630*1c60b9acSAndroid Build Coastguard Worker break;
631*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_PROTECTED:
632*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("ST_INNER_PROTECTED end\n");
633*1c60b9acSAndroid Build Coastguard Worker break;
634*1c60b9acSAndroid Build Coastguard Worker
635*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_EXCESS:
636*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_SIGN_SIGARRAY:
637*1c60b9acSAndroid Build Coastguard Worker cps->tli--; /* so no change */
638*1c60b9acSAndroid Build Coastguard Worker break;
639*1c60b9acSAndroid Build Coastguard Worker }
640*1c60b9acSAndroid Build Coastguard Worker if (!cps->sub)
641*1c60b9acSAndroid Build Coastguard Worker cps->tli++;
642*1c60b9acSAndroid Build Coastguard Worker }
643*1c60b9acSAndroid Build Coastguard Worker
644*1c60b9acSAndroid Build Coastguard Worker if (ctx->pst[ctx->pst_sp].ppos >= 4) {
645*1c60b9acSAndroid Build Coastguard Worker uint8_t *p;
646*1c60b9acSAndroid Build Coastguard Worker uint8_t u;
647*1c60b9acSAndroid Build Coastguard Worker size_t s1;
648*1c60b9acSAndroid Build Coastguard Worker
649*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
650*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_UNPROTECTED:
651*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_PROTECTED:
652*1c60b9acSAndroid Build Coastguard Worker
653*1c60b9acSAndroid Build Coastguard Worker hi = ph_index(cps);
654*1c60b9acSAndroid Build Coastguard Worker sl = &cps->st[cps->sp];
655*1c60b9acSAndroid Build Coastguard Worker p = sl->ph[hi] + 3;
656*1c60b9acSAndroid Build Coastguard Worker lecp_parse_report_raw(ctx, 0);
657*1c60b9acSAndroid Build Coastguard Worker
658*1c60b9acSAndroid Build Coastguard Worker if (!sl->ph_pos[hi] || cps->sub) {
659*1c60b9acSAndroid Build Coastguard Worker if (!cps->sub)
660*1c60b9acSAndroid Build Coastguard Worker cps->tli++;
661*1c60b9acSAndroid Build Coastguard Worker break;
662*1c60b9acSAndroid Build Coastguard Worker }
663*1c60b9acSAndroid Build Coastguard Worker
664*1c60b9acSAndroid Build Coastguard Worker cps->sub = 1;
665*1c60b9acSAndroid Build Coastguard Worker s = (size_t)sl->ph_pos[hi];
666*1c60b9acSAndroid Build Coastguard Worker
667*1c60b9acSAndroid Build Coastguard Worker /*
668*1c60b9acSAndroid Build Coastguard Worker * somehow the raw captures the
669*1c60b9acSAndroid Build Coastguard Worker * initial BSTR container length,
670*1c60b9acSAndroid Build Coastguard Worker * let's strip it
671*1c60b9acSAndroid Build Coastguard Worker */
672*1c60b9acSAndroid Build Coastguard Worker
673*1c60b9acSAndroid Build Coastguard Worker u = (*p) & LWS_CBOR_SUBMASK;
674*1c60b9acSAndroid Build Coastguard Worker if (((*p) & LWS_CBOR_MAJTYP_MASK) ==
675*1c60b9acSAndroid Build Coastguard Worker LWS_CBOR_MAJTYP_BSTR) {
676*1c60b9acSAndroid Build Coastguard Worker s1 = 1;
677*1c60b9acSAndroid Build Coastguard Worker if (u == LWS_CBOR_1)
678*1c60b9acSAndroid Build Coastguard Worker s1 = 2;
679*1c60b9acSAndroid Build Coastguard Worker else if (u == LWS_CBOR_2)
680*1c60b9acSAndroid Build Coastguard Worker s1 = 3;
681*1c60b9acSAndroid Build Coastguard Worker else if (u == LWS_CBOR_4)
682*1c60b9acSAndroid Build Coastguard Worker s1 = 5;
683*1c60b9acSAndroid Build Coastguard Worker else if (u == LWS_CBOR_8)
684*1c60b9acSAndroid Build Coastguard Worker s1 = 9;
685*1c60b9acSAndroid Build Coastguard Worker
686*1c60b9acSAndroid Build Coastguard Worker if (s1 > s)
687*1c60b9acSAndroid Build Coastguard Worker goto bail;
688*1c60b9acSAndroid Build Coastguard Worker
689*1c60b9acSAndroid Build Coastguard Worker sl->ph_pos[hi] = (int)
690*1c60b9acSAndroid Build Coastguard Worker (sl->ph_pos[hi] - (ssize_t)s1);
691*1c60b9acSAndroid Build Coastguard Worker s = s - s1;
692*1c60b9acSAndroid Build Coastguard Worker memmove(p, p + s1, s);
693*1c60b9acSAndroid Build Coastguard Worker }
694*1c60b9acSAndroid Build Coastguard Worker
695*1c60b9acSAndroid Build Coastguard Worker if (lecp_parse_subtree(&cps->ctx, p, s) !=
696*1c60b9acSAndroid Build Coastguard Worker LECP_CONTINUE)
697*1c60b9acSAndroid Build Coastguard Worker goto bail;
698*1c60b9acSAndroid Build Coastguard Worker
699*1c60b9acSAndroid Build Coastguard Worker cps->sub = 0;
700*1c60b9acSAndroid Build Coastguard Worker
701*1c60b9acSAndroid Build Coastguard Worker if (!cps->sub)
702*1c60b9acSAndroid Build Coastguard Worker cps->tli++;
703*1c60b9acSAndroid Build Coastguard Worker break;
704*1c60b9acSAndroid Build Coastguard Worker
705*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_SIGNATURE:
706*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype == SIGTYPE_MAC) {
707*1c60b9acSAndroid Build Coastguard Worker // lwsl_err("Y: alg %d\n", (int)cps->alg);
708*1c60b9acSAndroid Build Coastguard Worker if (create_alg(ctx, cps))
709*1c60b9acSAndroid Build Coastguard Worker goto bail;
710*1c60b9acSAndroid Build Coastguard Worker }
711*1c60b9acSAndroid Build Coastguard Worker cps->tli++;
712*1c60b9acSAndroid Build Coastguard Worker break;
713*1c60b9acSAndroid Build Coastguard Worker default:
714*1c60b9acSAndroid Build Coastguard Worker break;
715*1c60b9acSAndroid Build Coastguard Worker }
716*1c60b9acSAndroid Build Coastguard Worker }
717*1c60b9acSAndroid Build Coastguard Worker
718*1c60b9acSAndroid Build Coastguard Worker break;
719*1c60b9acSAndroid Build Coastguard Worker
720*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_NUM_INT:
721*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_NUM_UINT:
722*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
723*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_PROTECTED:
724*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_UNPROTECTED:
725*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_SIGNATURE:
726*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PROTECTED:
727*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_UNPROTECTED:
728*1c60b9acSAndroid Build Coastguard Worker if (lecp_parse_map_is_key(ctx)) {
729*1c60b9acSAndroid Build Coastguard Worker cps->map_key = ctx->item.u.i64;
730*1c60b9acSAndroid Build Coastguard Worker // lwsl_notice("%s: key %d\n", __func__, (int)cps->map_key);
731*1c60b9acSAndroid Build Coastguard Worker break;
732*1c60b9acSAndroid Build Coastguard Worker }
733*1c60b9acSAndroid Build Coastguard Worker
734*1c60b9acSAndroid Build Coastguard Worker // lwsl_notice("%s: key %d val %d\n", __func__, (int)cps->map_key, (int)ctx->item.u.i64);
735*1c60b9acSAndroid Build Coastguard Worker
736*1c60b9acSAndroid Build Coastguard Worker if (cps->map_key == LWSCOSE_WKL_ALG) {
737*1c60b9acSAndroid Build Coastguard Worker sl = &cps->st[cps->sp];
738*1c60b9acSAndroid Build Coastguard Worker cps->map_key = 0;
739*1c60b9acSAndroid Build Coastguard Worker if (cps->tli == ST_INNER_PROTECTED ||
740*1c60b9acSAndroid Build Coastguard Worker cps->tli == ST_INNER_UNPROTECTED ||
741*1c60b9acSAndroid Build Coastguard Worker cps->tli == ST_INNER_SIGNATURE) {
742*1c60b9acSAndroid Build Coastguard Worker sl->alg = ctx->item.u.i64;
743*1c60b9acSAndroid Build Coastguard Worker if (!cps->st[0].alg)
744*1c60b9acSAndroid Build Coastguard Worker cps->st[0].alg = sl->alg;
745*1c60b9acSAndroid Build Coastguard Worker } else
746*1c60b9acSAndroid Build Coastguard Worker sl->alg = ctx->item.u.i64;
747*1c60b9acSAndroid Build Coastguard Worker break;
748*1c60b9acSAndroid Build Coastguard Worker }
749*1c60b9acSAndroid Build Coastguard Worker break;
750*1c60b9acSAndroid Build Coastguard Worker }
751*1c60b9acSAndroid Build Coastguard Worker break;
752*1c60b9acSAndroid Build Coastguard Worker
753*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_STR_END:
754*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
755*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_UNPROTECTED:
756*1c60b9acSAndroid Build Coastguard Worker break;
757*1c60b9acSAndroid Build Coastguard Worker }
758*1c60b9acSAndroid Build Coastguard Worker break;
759*1c60b9acSAndroid Build Coastguard Worker
760*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_BLOB_START:
761*1c60b9acSAndroid Build Coastguard Worker
762*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: blob size %d\n", __func__, (int)ctx->item.u.u64);
763*1c60b9acSAndroid Build Coastguard Worker
764*1c60b9acSAndroid Build Coastguard Worker if (cps->tli == ST_OUTER_SIGN1_SIGNATURE ||
765*1c60b9acSAndroid Build Coastguard Worker cps->tli == ST_INNER_SIGNATURE) {
766*1c60b9acSAndroid Build Coastguard Worker if (ctx->item.u.u64 > sizeof(cps->sig_agg))
767*1c60b9acSAndroid Build Coastguard Worker goto bail;
768*1c60b9acSAndroid Build Coastguard Worker cps->sig_agg_pos = 0;
769*1c60b9acSAndroid Build Coastguard Worker break;
770*1c60b9acSAndroid Build Coastguard Worker }
771*1c60b9acSAndroid Build Coastguard Worker
772*1c60b9acSAndroid Build Coastguard Worker if (cps->tli != ST_OUTER_PAYLOAD)
773*1c60b9acSAndroid Build Coastguard Worker break;
774*1c60b9acSAndroid Build Coastguard Worker
775*1c60b9acSAndroid Build Coastguard Worker if (apply_external(cps)) {
776*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: ext\n", __func__);
777*1c60b9acSAndroid Build Coastguard Worker goto bail;
778*1c60b9acSAndroid Build Coastguard Worker }
779*1c60b9acSAndroid Build Coastguard Worker
780*1c60b9acSAndroid Build Coastguard Worker s = bstr_len(t, sizeof(t), LWS_CBOR_MAJTYP_BSTR,
781*1c60b9acSAndroid Build Coastguard Worker ctx->item.u.u64);
782*1c60b9acSAndroid Build Coastguard Worker
783*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype == SIGTYPE_SINGLE) {
784*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(cps->algs.head,
785*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
786*1c60b9acSAndroid Build Coastguard Worker if (!alg)
787*1c60b9acSAndroid Build Coastguard Worker /* expected if no key */
788*1c60b9acSAndroid Build Coastguard Worker break;
789*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_val_alg_hash(alg, t, s)) {
790*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: hash failed\n", __func__);
791*1c60b9acSAndroid Build Coastguard Worker goto bail;
792*1c60b9acSAndroid Build Coastguard Worker }
793*1c60b9acSAndroid Build Coastguard Worker
794*1c60b9acSAndroid Build Coastguard Worker break;
795*1c60b9acSAndroid Build Coastguard Worker }
796*1c60b9acSAndroid Build Coastguard Worker
797*1c60b9acSAndroid Build Coastguard Worker cps->payload_stash_size = (size_t)(ctx->item.u.u64 + s);
798*1c60b9acSAndroid Build Coastguard Worker cps->payload_stash = lws_malloc(cps->payload_stash_size,
799*1c60b9acSAndroid Build Coastguard Worker __func__);
800*1c60b9acSAndroid Build Coastguard Worker if (!cps->payload_stash) {
801*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: oom\n", __func__);
802*1c60b9acSAndroid Build Coastguard Worker goto bail;
803*1c60b9acSAndroid Build Coastguard Worker }
804*1c60b9acSAndroid Build Coastguard Worker
805*1c60b9acSAndroid Build Coastguard Worker memcpy(cps->payload_stash, t, s);
806*1c60b9acSAndroid Build Coastguard Worker cps->payload_pos = s;
807*1c60b9acSAndroid Build Coastguard Worker
808*1c60b9acSAndroid Build Coastguard Worker break;
809*1c60b9acSAndroid Build Coastguard Worker
810*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_BLOB_CHUNK:
811*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
812*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PAYLOAD:
813*1c60b9acSAndroid Build Coastguard Worker
814*1c60b9acSAndroid Build Coastguard Worker if (cps->info.pay_cb && ctx->npos)
815*1c60b9acSAndroid Build Coastguard Worker cps->info.pay_cb(cps, cps->info.pay_opaque,
816*1c60b9acSAndroid Build Coastguard Worker (uint8_t *)ctx->buf, ctx->npos);
817*1c60b9acSAndroid Build Coastguard Worker
818*1c60b9acSAndroid Build Coastguard Worker if (cps->payload_stash) {
819*1c60b9acSAndroid Build Coastguard Worker if (cps->payload_pos + ctx->npos >
820*1c60b9acSAndroid Build Coastguard Worker cps->payload_stash_size)
821*1c60b9acSAndroid Build Coastguard Worker goto bail;
822*1c60b9acSAndroid Build Coastguard Worker memcpy(cps->payload_stash + cps->payload_pos,
823*1c60b9acSAndroid Build Coastguard Worker ctx->buf, ctx->npos);
824*1c60b9acSAndroid Build Coastguard Worker cps->payload_pos += ctx->npos;
825*1c60b9acSAndroid Build Coastguard Worker break;
826*1c60b9acSAndroid Build Coastguard Worker }
827*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(cps->algs.head,
828*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
829*1c60b9acSAndroid Build Coastguard Worker if (!alg)
830*1c60b9acSAndroid Build Coastguard Worker /* expected if no key */
831*1c60b9acSAndroid Build Coastguard Worker break;
832*1c60b9acSAndroid Build Coastguard Worker if (ctx->npos &&
833*1c60b9acSAndroid Build Coastguard Worker lws_cose_val_alg_hash(alg, (uint8_t *)ctx->buf,
834*1c60b9acSAndroid Build Coastguard Worker ctx->npos)) {
835*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: chunk fail\n", __func__);
836*1c60b9acSAndroid Build Coastguard Worker goto bail;
837*1c60b9acSAndroid Build Coastguard Worker }
838*1c60b9acSAndroid Build Coastguard Worker break;
839*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_SIGNATURE:
840*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_SIGN1_SIGNATURE:
841*1c60b9acSAndroid Build Coastguard Worker /* the sig is big compared to ctx->buf... we need to
842*1c60b9acSAndroid Build Coastguard Worker * stash it then */
843*1c60b9acSAndroid Build Coastguard Worker memcpy(cps->sig_agg + cps->sig_agg_pos, ctx->buf,
844*1c60b9acSAndroid Build Coastguard Worker ctx->npos);
845*1c60b9acSAndroid Build Coastguard Worker cps->sig_agg_pos = cps->sig_agg_pos + ctx->npos;
846*1c60b9acSAndroid Build Coastguard Worker break;
847*1c60b9acSAndroid Build Coastguard Worker }
848*1c60b9acSAndroid Build Coastguard Worker break;
849*1c60b9acSAndroid Build Coastguard Worker
850*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_BLOB_END:
851*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
852*1c60b9acSAndroid Build Coastguard Worker
853*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_SIGNATURE:
854*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype == SIGTYPE_MULTI) {
855*1c60b9acSAndroid Build Coastguard Worker memcpy(cps->sig_agg + cps->sig_agg_pos, ctx->buf,
856*1c60b9acSAndroid Build Coastguard Worker ctx->npos);
857*1c60b9acSAndroid Build Coastguard Worker cps->sig_agg_pos = cps->sig_agg_pos + ctx->npos;
858*1c60b9acSAndroid Build Coastguard Worker // lwsl_err("Y: alg %d\n", (int)cps->alg);
859*1c60b9acSAndroid Build Coastguard Worker if (create_alg(ctx, cps))
860*1c60b9acSAndroid Build Coastguard Worker goto bail;
861*1c60b9acSAndroid Build Coastguard Worker break;
862*1c60b9acSAndroid Build Coastguard Worker }
863*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype != SIGTYPE_MAC)
864*1c60b9acSAndroid Build Coastguard Worker break;
865*1c60b9acSAndroid Build Coastguard Worker /* fallthru */
866*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PROTECTED:
867*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_UNPROTECTED:
868*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_PROTECTED:
869*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_UNPROTECTED:
870*1c60b9acSAndroid Build Coastguard Worker if (cps->map_key == LWSCOSE_WKL_KID) {
871*1c60b9acSAndroid Build Coastguard Worker sl = &cps->st[cps->sp];
872*1c60b9acSAndroid Build Coastguard Worker ke = &sl->kid;
873*1c60b9acSAndroid Build Coastguard Worker if (ke->buf)
874*1c60b9acSAndroid Build Coastguard Worker lws_free(ke->buf);
875*1c60b9acSAndroid Build Coastguard Worker ke->buf = lws_malloc(ctx->npos, __func__);
876*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf)
877*1c60b9acSAndroid Build Coastguard Worker goto bail;
878*1c60b9acSAndroid Build Coastguard Worker ke->len = ctx->npos;
879*1c60b9acSAndroid Build Coastguard Worker memcpy(ke->buf, ctx->buf, ctx->npos);
880*1c60b9acSAndroid Build Coastguard Worker cps->map_key = 0;
881*1c60b9acSAndroid Build Coastguard Worker }
882*1c60b9acSAndroid Build Coastguard Worker break;
883*1c60b9acSAndroid Build Coastguard Worker
884*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PAYLOAD:
885*1c60b9acSAndroid Build Coastguard Worker if (cps->info.pay_cb && ctx->npos)
886*1c60b9acSAndroid Build Coastguard Worker cps->info.pay_cb(cps, cps->info.pay_opaque,
887*1c60b9acSAndroid Build Coastguard Worker (uint8_t *)ctx->buf, ctx->npos);
888*1c60b9acSAndroid Build Coastguard Worker if (cps->payload_stash) {
889*1c60b9acSAndroid Build Coastguard Worker if (cps->payload_pos + ctx->npos >
890*1c60b9acSAndroid Build Coastguard Worker cps->payload_stash_size)
891*1c60b9acSAndroid Build Coastguard Worker goto bail;
892*1c60b9acSAndroid Build Coastguard Worker memcpy(cps->payload_stash + cps->payload_pos,
893*1c60b9acSAndroid Build Coastguard Worker ctx->buf, ctx->npos);
894*1c60b9acSAndroid Build Coastguard Worker cps->payload_pos += ctx->npos;
895*1c60b9acSAndroid Build Coastguard Worker break;
896*1c60b9acSAndroid Build Coastguard Worker }
897*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(cps->algs.head,
898*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
899*1c60b9acSAndroid Build Coastguard Worker if (!alg)
900*1c60b9acSAndroid Build Coastguard Worker /* expected if no key */
901*1c60b9acSAndroid Build Coastguard Worker break;
902*1c60b9acSAndroid Build Coastguard Worker
903*1c60b9acSAndroid Build Coastguard Worker if (ctx->npos &&
904*1c60b9acSAndroid Build Coastguard Worker lws_cose_val_alg_hash(alg, (uint8_t *)ctx->buf,
905*1c60b9acSAndroid Build Coastguard Worker ctx->npos))
906*1c60b9acSAndroid Build Coastguard Worker goto bail;
907*1c60b9acSAndroid Build Coastguard Worker break;
908*1c60b9acSAndroid Build Coastguard Worker
909*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_SIGN1_SIGNATURE:
910*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype == SIGTYPE_MULTI)
911*1c60b9acSAndroid Build Coastguard Worker break;
912*1c60b9acSAndroid Build Coastguard Worker
913*1c60b9acSAndroid Build Coastguard Worker memcpy(cps->sig_agg + cps->sig_agg_pos, ctx->buf,
914*1c60b9acSAndroid Build Coastguard Worker ctx->npos);
915*1c60b9acSAndroid Build Coastguard Worker cps->sig_agg_pos += ctx->npos;
916*1c60b9acSAndroid Build Coastguard Worker
917*1c60b9acSAndroid Build Coastguard Worker alg = lws_container_of(cps->algs.head,
918*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
919*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("b\n");
920*1c60b9acSAndroid Build Coastguard Worker if (alg)
921*1c60b9acSAndroid Build Coastguard Worker lws_cose_val_alg_destroy(cps, &alg,
922*1c60b9acSAndroid Build Coastguard Worker cps->sig_agg,
923*1c60b9acSAndroid Build Coastguard Worker cps->sig_agg_pos);
924*1c60b9acSAndroid Build Coastguard Worker break;
925*1c60b9acSAndroid Build Coastguard Worker
926*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_MACTAG:
927*1c60b9acSAndroid Build Coastguard Worker if (cps->mac_pos + ctx->npos > sizeof(cps->mac))
928*1c60b9acSAndroid Build Coastguard Worker goto bail;
929*1c60b9acSAndroid Build Coastguard Worker memcpy(cps->mac + cps->mac_pos, ctx->buf, ctx->npos);
930*1c60b9acSAndroid Build Coastguard Worker cps->mac_pos += ctx->npos;
931*1c60b9acSAndroid Build Coastguard Worker
932*1c60b9acSAndroid Build Coastguard Worker if (cps->info.sigtype == SIGTYPE_MAC0) {
933*1c60b9acSAndroid Build Coastguard Worker if (create_alg(ctx, cps))
934*1c60b9acSAndroid Build Coastguard Worker goto bail;
935*1c60b9acSAndroid Build Coastguard Worker }
936*1c60b9acSAndroid Build Coastguard Worker
937*1c60b9acSAndroid Build Coastguard Worker break;
938*1c60b9acSAndroid Build Coastguard Worker }
939*1c60b9acSAndroid Build Coastguard Worker break;
940*1c60b9acSAndroid Build Coastguard Worker
941*1c60b9acSAndroid Build Coastguard Worker case LECPCB_LITERAL_CBOR:
942*1c60b9acSAndroid Build Coastguard Worker /* only used for protected headers */
943*1c60b9acSAndroid Build Coastguard Worker switch (cps->tli) {
944*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_PROTECTED:
945*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_PROTECTED:
946*1c60b9acSAndroid Build Coastguard Worker case ST_INNER_UNPROTECTED:
947*1c60b9acSAndroid Build Coastguard Worker case ST_OUTER_UNPROTECTED:
948*1c60b9acSAndroid Build Coastguard Worker sl = &cps->st[cps->sp];
949*1c60b9acSAndroid Build Coastguard Worker hi = ph_index(cps);
950*1c60b9acSAndroid Build Coastguard Worker if (sl->ph_pos[hi] + 3 + ctx->cbor_pos >
951*1c60b9acSAndroid Build Coastguard Worker (int)sizeof(sl->ph[hi]) - 3)
952*1c60b9acSAndroid Build Coastguard Worker /* more protected cbor than we can handle */
953*1c60b9acSAndroid Build Coastguard Worker goto bail;
954*1c60b9acSAndroid Build Coastguard Worker memcpy(sl->ph[hi] + 3 + sl->ph_pos[hi], ctx->cbor,
955*1c60b9acSAndroid Build Coastguard Worker ctx->cbor_pos);
956*1c60b9acSAndroid Build Coastguard Worker sl->ph_pos[hi] += ctx->cbor_pos;
957*1c60b9acSAndroid Build Coastguard Worker break;
958*1c60b9acSAndroid Build Coastguard Worker }
959*1c60b9acSAndroid Build Coastguard Worker }
960*1c60b9acSAndroid Build Coastguard Worker
961*1c60b9acSAndroid Build Coastguard Worker return 0;
962*1c60b9acSAndroid Build Coastguard Worker
963*1c60b9acSAndroid Build Coastguard Worker bail:
964*1c60b9acSAndroid Build Coastguard Worker
965*1c60b9acSAndroid Build Coastguard Worker return -1;
966*1c60b9acSAndroid Build Coastguard Worker }
967*1c60b9acSAndroid Build Coastguard Worker
968*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_validate_context *
lws_cose_validate_create(const lws_cose_validate_create_info_t * info)969*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_create(const lws_cose_validate_create_info_t *info)
970*1c60b9acSAndroid Build Coastguard Worker {
971*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_validate_context *cps;
972*1c60b9acSAndroid Build Coastguard Worker
973*1c60b9acSAndroid Build Coastguard Worker /* you have to provide at least one key in a cose_keyset */
974*1c60b9acSAndroid Build Coastguard Worker assert(info->keyset);
975*1c60b9acSAndroid Build Coastguard Worker /* you have to provide an lws_context (for crypto random) */
976*1c60b9acSAndroid Build Coastguard Worker assert(info->cx);
977*1c60b9acSAndroid Build Coastguard Worker
978*1c60b9acSAndroid Build Coastguard Worker cps = lws_zalloc(sizeof(*cps), __func__);
979*1c60b9acSAndroid Build Coastguard Worker if (!cps)
980*1c60b9acSAndroid Build Coastguard Worker return NULL;
981*1c60b9acSAndroid Build Coastguard Worker
982*1c60b9acSAndroid Build Coastguard Worker cps->info = *info;
983*1c60b9acSAndroid Build Coastguard Worker cps->tli = ST_OUTER_PROTECTED;
984*1c60b9acSAndroid Build Coastguard Worker
985*1c60b9acSAndroid Build Coastguard Worker lecp_construct(&cps->ctx, cb_cose_sig, cps, NULL, 0);
986*1c60b9acSAndroid Build Coastguard Worker
987*1c60b9acSAndroid Build Coastguard Worker return cps;
988*1c60b9acSAndroid Build Coastguard Worker }
989*1c60b9acSAndroid Build Coastguard Worker
990*1c60b9acSAndroid Build Coastguard Worker int
lws_cose_validate_chunk(struct lws_cose_validate_context * cps,const uint8_t * in,size_t in_len,size_t * used_in)991*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_chunk(struct lws_cose_validate_context *cps,
992*1c60b9acSAndroid Build Coastguard Worker const uint8_t *in, size_t in_len, size_t *used_in)
993*1c60b9acSAndroid Build Coastguard Worker {
994*1c60b9acSAndroid Build Coastguard Worker int n;
995*1c60b9acSAndroid Build Coastguard Worker
996*1c60b9acSAndroid Build Coastguard Worker n = lecp_parse(&cps->ctx, in, in_len);
997*1c60b9acSAndroid Build Coastguard Worker if (used_in)
998*1c60b9acSAndroid Build Coastguard Worker *used_in = cps->ctx.used_in;
999*1c60b9acSAndroid Build Coastguard Worker
1000*1c60b9acSAndroid Build Coastguard Worker if (n == LECP_CONTINUE)
1001*1c60b9acSAndroid Build Coastguard Worker return LECP_CONTINUE;
1002*1c60b9acSAndroid Build Coastguard Worker
1003*1c60b9acSAndroid Build Coastguard Worker lecp_destruct(&cps->ctx);
1004*1c60b9acSAndroid Build Coastguard Worker
1005*1c60b9acSAndroid Build Coastguard Worker return n;
1006*1c60b9acSAndroid Build Coastguard Worker }
1007*1c60b9acSAndroid Build Coastguard Worker
1008*1c60b9acSAndroid Build Coastguard Worker lws_dll2_owner_t *
lws_cose_validate_results(struct lws_cose_validate_context * cps)1009*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_results(struct lws_cose_validate_context *cps)
1010*1c60b9acSAndroid Build Coastguard Worker {
1011*1c60b9acSAndroid Build Coastguard Worker return &cps->results;
1012*1c60b9acSAndroid Build Coastguard Worker }
1013*1c60b9acSAndroid Build Coastguard Worker
1014*1c60b9acSAndroid Build Coastguard Worker void
lws_cose_validate_destroy(struct lws_cose_validate_context ** _cps)1015*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_destroy(struct lws_cose_validate_context **_cps)
1016*1c60b9acSAndroid Build Coastguard Worker {
1017*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_validate_context *cps = *_cps;
1018*1c60b9acSAndroid Build Coastguard Worker
1019*1c60b9acSAndroid Build Coastguard Worker if (!cps)
1020*1c60b9acSAndroid Build Coastguard Worker return;
1021*1c60b9acSAndroid Build Coastguard Worker
1022*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
1023*1c60b9acSAndroid Build Coastguard Worker lws_dll2_get_head(&cps->algs)) {
1024*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t *alg = lws_container_of(p,
1025*1c60b9acSAndroid Build Coastguard Worker lws_cose_sig_alg_t, list);
1026*1c60b9acSAndroid Build Coastguard Worker
1027*1c60b9acSAndroid Build Coastguard Worker lws_dll2_remove(p);
1028*1c60b9acSAndroid Build Coastguard Worker lws_cose_val_alg_destroy(cps, &alg, NULL, 0);
1029*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll_safe(p, tp);
1030*1c60b9acSAndroid Build Coastguard Worker
1031*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
1032*1c60b9acSAndroid Build Coastguard Worker lws_dll2_get_head(&cps->results)) {
1033*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_res_t *res = lws_container_of(p,
1034*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_res_t, list);
1035*1c60b9acSAndroid Build Coastguard Worker
1036*1c60b9acSAndroid Build Coastguard Worker lws_dll2_remove(p);
1037*1c60b9acSAndroid Build Coastguard Worker lws_free(res);
1038*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll_safe(p, tp);
1039*1c60b9acSAndroid Build Coastguard Worker
1040*1c60b9acSAndroid Build Coastguard Worker lws_free_set_NULL(cps->payload_stash);
1041*1c60b9acSAndroid Build Coastguard Worker
1042*1c60b9acSAndroid Build Coastguard Worker lwsac_free(&cps->ac);
1043*1c60b9acSAndroid Build Coastguard Worker
1044*1c60b9acSAndroid Build Coastguard Worker while (cps->sp >= 0) {
1045*1c60b9acSAndroid Build Coastguard Worker if (cps->st[cps->sp].kid.buf)
1046*1c60b9acSAndroid Build Coastguard Worker lws_free(cps->st[cps->sp].kid.buf);
1047*1c60b9acSAndroid Build Coastguard Worker cps->sp--;
1048*1c60b9acSAndroid Build Coastguard Worker }
1049*1c60b9acSAndroid Build Coastguard Worker
1050*1c60b9acSAndroid Build Coastguard Worker lws_free_set_NULL(*_cps);
1051*1c60b9acSAndroid Build Coastguard Worker }
1052