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_key code
25*1c60b9acSAndroid Build Coastguard Worker */
26*1c60b9acSAndroid Build Coastguard Worker
27*1c60b9acSAndroid Build Coastguard Worker #include "private-lib-core.h"
28*1c60b9acSAndroid Build Coastguard Worker //#include "private-lib-jose.h"
29*1c60b9acSAndroid Build Coastguard Worker
30*1c60b9acSAndroid Build Coastguard Worker #define lwsl_cose lwsl_notice
31*1c60b9acSAndroid Build Coastguard Worker #define lwsl_hexdump_cose lwsl_hexdump_notice
32*1c60b9acSAndroid Build Coastguard Worker
33*1c60b9acSAndroid Build Coastguard Worker // #define VERBOSE 1
34*1c60b9acSAndroid Build Coastguard Worker
35*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_key_parse_state {
36*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_key *ck;
37*1c60b9acSAndroid Build Coastguard Worker /**< single key created here if pkey_set is NULL */
38*1c60b9acSAndroid Build Coastguard Worker char buf[(8192 / 8) + 1];
39*1c60b9acSAndroid Build Coastguard Worker /**< enough for 8Kb key, only needed during parse */
40*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_import_callback per_key_cb;
41*1c60b9acSAndroid Build Coastguard Worker lws_dll2_owner_t *pkey_set;
42*1c60b9acSAndroid Build Coastguard Worker /**< if non-NULL, expects a [ key set ], else single key */
43*1c60b9acSAndroid Build Coastguard Worker void *user;
44*1c60b9acSAndroid Build Coastguard Worker size_t pos;
45*1c60b9acSAndroid Build Coastguard Worker int cose_state;
46*1c60b9acSAndroid Build Coastguard Worker cose_param_t seen[16];
47*1c60b9acSAndroid Build Coastguard Worker int seen_count;
48*1c60b9acSAndroid Build Coastguard Worker int gencrypto_eidx;
49*1c60b9acSAndroid Build Coastguard Worker int meta_idx;
50*1c60b9acSAndroid Build Coastguard Worker unsigned short possible;
51*1c60b9acSAndroid Build Coastguard Worker };
52*1c60b9acSAndroid Build Coastguard Worker
53*1c60b9acSAndroid Build Coastguard Worker /*
54*1c60b9acSAndroid Build Coastguard Worker * A COSE key representation is a CBOR map with a specified structure. The
55*1c60b9acSAndroid Build Coastguard Worker * keys are
56*1c60b9acSAndroid Build Coastguard Worker *
57*1c60b9acSAndroid Build Coastguard Worker * LWSCOSE_WKK_KTY MUST int / tstr
58*1c60b9acSAndroid Build Coastguard Worker * LWSCOSE_WKK_KID OPT bstr
59*1c60b9acSAndroid Build Coastguard Worker * LWSCOSE_WKK_ALG OPT int / tstr
60*1c60b9acSAndroid Build Coastguard Worker * LWSCOSE_WKK_KEY_OPS OPT [ + (int / tstr) ]
61*1c60b9acSAndroid Build Coastguard Worker * LWSCOSE_WKK_BASE_IV OPT bstr
62*1c60b9acSAndroid Build Coastguard Worker */
63*1c60b9acSAndroid Build Coastguard Worker
64*1c60b9acSAndroid Build Coastguard Worker #if defined(_DEBUG)
65*1c60b9acSAndroid Build Coastguard Worker
66*1c60b9acSAndroid Build Coastguard Worker static const char *meta_names[] = {
67*1c60b9acSAndroid Build Coastguard Worker "kty", "kid", "use", "key_ops", "base_iv", "alg"
68*1c60b9acSAndroid Build Coastguard Worker };
69*1c60b9acSAndroid Build Coastguard Worker
70*1c60b9acSAndroid Build Coastguard Worker static const char *oct_names[] = {
71*1c60b9acSAndroid Build Coastguard Worker "k"
72*1c60b9acSAndroid Build Coastguard Worker };
73*1c60b9acSAndroid Build Coastguard Worker
74*1c60b9acSAndroid Build Coastguard Worker static const char *rsa_names[] = {
75*1c60b9acSAndroid Build Coastguard Worker "e", "n", "d", "p", "q", "dp", "dq", "qi", "other", "ri", "di", "ti"
76*1c60b9acSAndroid Build Coastguard Worker };
77*1c60b9acSAndroid Build Coastguard Worker
78*1c60b9acSAndroid Build Coastguard Worker static const char *ec_names[] = {
79*1c60b9acSAndroid Build Coastguard Worker "crv", "x", "d", "y",
80*1c60b9acSAndroid Build Coastguard Worker };
81*1c60b9acSAndroid Build Coastguard Worker
82*1c60b9acSAndroid Build Coastguard Worker void
lws_cose_key_dump(const struct lws_cose_key * ck)83*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_dump(const struct lws_cose_key *ck)
84*1c60b9acSAndroid Build Coastguard Worker {
85*1c60b9acSAndroid Build Coastguard Worker const char **enames;
86*1c60b9acSAndroid Build Coastguard Worker char hex[2048];
87*1c60b9acSAndroid Build Coastguard Worker int elems;
88*1c60b9acSAndroid Build Coastguard Worker int n;
89*1c60b9acSAndroid Build Coastguard Worker
90*1c60b9acSAndroid Build Coastguard Worker (void)enames;
91*1c60b9acSAndroid Build Coastguard Worker (void)meta_names;
92*1c60b9acSAndroid Build Coastguard Worker
93*1c60b9acSAndroid Build Coastguard Worker switch (ck->gencrypto_kty) {
94*1c60b9acSAndroid Build Coastguard Worker
95*1c60b9acSAndroid Build Coastguard Worker case LWS_GENCRYPTO_KTY_OCT:
96*1c60b9acSAndroid Build Coastguard Worker elems = LWS_GENCRYPTO_OCT_KEYEL_COUNT;
97*1c60b9acSAndroid Build Coastguard Worker enames = oct_names;
98*1c60b9acSAndroid Build Coastguard Worker break;
99*1c60b9acSAndroid Build Coastguard Worker case LWS_GENCRYPTO_KTY_RSA:
100*1c60b9acSAndroid Build Coastguard Worker elems = LWS_GENCRYPTO_RSA_KEYEL_COUNT;
101*1c60b9acSAndroid Build Coastguard Worker enames = rsa_names;
102*1c60b9acSAndroid Build Coastguard Worker break;
103*1c60b9acSAndroid Build Coastguard Worker case LWS_GENCRYPTO_KTY_EC:
104*1c60b9acSAndroid Build Coastguard Worker elems = LWS_GENCRYPTO_EC_KEYEL_COUNT;
105*1c60b9acSAndroid Build Coastguard Worker enames = ec_names;
106*1c60b9acSAndroid Build Coastguard Worker break;
107*1c60b9acSAndroid Build Coastguard Worker
108*1c60b9acSAndroid Build Coastguard Worker default:
109*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: jwk %p: unknown type\n", __func__, ck);
110*1c60b9acSAndroid Build Coastguard Worker
111*1c60b9acSAndroid Build Coastguard Worker return;
112*1c60b9acSAndroid Build Coastguard Worker }
113*1c60b9acSAndroid Build Coastguard Worker
114*1c60b9acSAndroid Build Coastguard Worker lwsl_cose("%s: cose_key %p, kty: %lld (gc %d)\n", __func__, ck,
115*1c60b9acSAndroid Build Coastguard Worker (long long)ck->kty, ck->gencrypto_kty);
116*1c60b9acSAndroid Build Coastguard Worker
117*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < LWS_COUNT_COSE_KEY_ELEMENTS; n++) {
118*1c60b9acSAndroid Build Coastguard Worker if (ck->meta[n].buf) {
119*1c60b9acSAndroid Build Coastguard Worker lws_hex_from_byte_array(ck->meta[n].buf, ck->meta[n].len,
120*1c60b9acSAndroid Build Coastguard Worker hex, sizeof(hex));
121*1c60b9acSAndroid Build Coastguard Worker lwsl_cose(" meta: %s: %s\n", meta_names[n], hex);
122*1c60b9acSAndroid Build Coastguard Worker }
123*1c60b9acSAndroid Build Coastguard Worker }
124*1c60b9acSAndroid Build Coastguard Worker
125*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < elems; n++) {
126*1c60b9acSAndroid Build Coastguard Worker if (ck->e[n].buf) {
127*1c60b9acSAndroid Build Coastguard Worker lws_hex_from_byte_array(ck->e[n].buf, ck->e[n].len,
128*1c60b9acSAndroid Build Coastguard Worker hex, sizeof(hex));
129*1c60b9acSAndroid Build Coastguard Worker lwsl_cose(" e: %s: %s\n", enames[n], hex);
130*1c60b9acSAndroid Build Coastguard Worker }
131*1c60b9acSAndroid Build Coastguard Worker }
132*1c60b9acSAndroid Build Coastguard Worker }
133*1c60b9acSAndroid Build Coastguard Worker #endif
134*1c60b9acSAndroid Build Coastguard Worker
135*1c60b9acSAndroid Build Coastguard Worker static const char * const kty_strings[] = { NULL,
136*1c60b9acSAndroid Build Coastguard Worker "OKP", "EC2", "RSA", "SYMMETRIC", "HSS_LMS", "WALNUTDSA"
137*1c60b9acSAndroid Build Coastguard Worker };
138*1c60b9acSAndroid Build Coastguard Worker
139*1c60b9acSAndroid Build Coastguard Worker int
lws_cose_key_checks(const lws_cose_key_t * key,int64_t kty,cose_param_t alg,int key_op,const char * crv)140*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_checks(const lws_cose_key_t *key, int64_t kty, cose_param_t alg,
141*1c60b9acSAndroid Build Coastguard Worker int key_op, const char *crv)
142*1c60b9acSAndroid Build Coastguard Worker {
143*1c60b9acSAndroid Build Coastguard Worker const struct lws_gencrypto_keyelem *ke;
144*1c60b9acSAndroid Build Coastguard Worker
145*1c60b9acSAndroid Build Coastguard Worker /*
146*1c60b9acSAndroid Build Coastguard Worker * we ourselves have to have a very clear idea what we need, even if
147*1c60b9acSAndroid Build Coastguard Worker * matches are optional in the key itself
148*1c60b9acSAndroid Build Coastguard Worker */
149*1c60b9acSAndroid Build Coastguard Worker assert(key);
150*1c60b9acSAndroid Build Coastguard Worker assert(kty);
151*1c60b9acSAndroid Build Coastguard Worker assert(alg);
152*1c60b9acSAndroid Build Coastguard Worker assert(key_op);
153*1c60b9acSAndroid Build Coastguard Worker assert((kty != LWSCOSE_WKKTV_OKP && kty != LWSCOSE_WKKTV_EC2) || crv);
154*1c60b9acSAndroid Build Coastguard Worker
155*1c60b9acSAndroid Build Coastguard Worker /* RFC8152 8.1:
156*1c60b9acSAndroid Build Coastguard Worker *
157*1c60b9acSAndroid Build Coastguard Worker * The 'kty' field MUST be present, and it MUST be '...'.
158*1c60b9acSAndroid Build Coastguard Worker *
159*1c60b9acSAndroid Build Coastguard Worker * But kty can come as an int or a string, but we convert well-known
160*1c60b9acSAndroid Build Coastguard Worker * kty ints to the corresponding string representation at key import
161*1c60b9acSAndroid Build Coastguard Worker */
162*1c60b9acSAndroid Build Coastguard Worker if (!kty || kty >= (int)LWS_ARRAY_SIZE(kty_strings)) {
163*1c60b9acSAndroid Build Coastguard Worker /* we don't understand it */
164*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: unknown kty %d\n", __func__, (int)kty);
165*1c60b9acSAndroid Build Coastguard Worker goto bail;
166*1c60b9acSAndroid Build Coastguard Worker }
167*1c60b9acSAndroid Build Coastguard Worker
168*1c60b9acSAndroid Build Coastguard Worker ke = &key->meta[COSEKEY_META_KTY];
169*1c60b9acSAndroid Build Coastguard Worker if (ke->buf && (strlen(kty_strings[kty]) != ke->len ||
170*1c60b9acSAndroid Build Coastguard Worker memcmp(kty_strings[kty], ke->buf, ke->len))) {
171*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: key is of wrong kty\n", __func__);
172*1c60b9acSAndroid Build Coastguard Worker lwsl_hexdump_notice(ke->buf, ke->len);
173*1c60b9acSAndroid Build Coastguard Worker goto bail;
174*1c60b9acSAndroid Build Coastguard Worker }
175*1c60b9acSAndroid Build Coastguard Worker
176*1c60b9acSAndroid Build Coastguard Worker /* ...
177*1c60b9acSAndroid Build Coastguard Worker * If the 'alg' field is present, it MUST match the ... signature
178*1c60b9acSAndroid Build Coastguard Worker * algorithm being used.
179*1c60b9acSAndroid Build Coastguard Worker *
180*1c60b9acSAndroid Build Coastguard Worker * We attempt to convert key alg text representations to a well-known
181*1c60b9acSAndroid Build Coastguard Worker * index, if we can't, then we don't know the alg anyway and should fail
182*1c60b9acSAndroid Build Coastguard Worker * it
183*1c60b9acSAndroid Build Coastguard Worker */
184*1c60b9acSAndroid Build Coastguard Worker
185*1c60b9acSAndroid Build Coastguard Worker if (!key->cose_alg && key->meta[COSEKEY_META_ALG].buf) {
186*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: alg fail 1\n", __func__);
187*1c60b9acSAndroid Build Coastguard Worker goto bail;
188*1c60b9acSAndroid Build Coastguard Worker }
189*1c60b9acSAndroid Build Coastguard Worker
190*1c60b9acSAndroid Build Coastguard Worker if (key->cose_alg && /* accept it being absent altogether */
191*1c60b9acSAndroid Build Coastguard Worker key->cose_alg != alg) {
192*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: alg fail 2\n", __func__);
193*1c60b9acSAndroid Build Coastguard Worker
194*1c60b9acSAndroid Build Coastguard Worker goto bail;
195*1c60b9acSAndroid Build Coastguard Worker }
196*1c60b9acSAndroid Build Coastguard Worker
197*1c60b9acSAndroid Build Coastguard Worker /* ...
198*1c60b9acSAndroid Build Coastguard Worker * If the 'key_ops' field is present, it MUST include 'sign' / 'verify'
199*1c60b9acSAndroid Build Coastguard Worker * when creating /verifying an ... signature.
200*1c60b9acSAndroid Build Coastguard Worker */
201*1c60b9acSAndroid Build Coastguard Worker
202*1c60b9acSAndroid Build Coastguard Worker ke = &key->meta[COSEKEY_META_KEY_OPS];
203*1c60b9acSAndroid Build Coastguard Worker if (ke->buf && ke->len) {
204*1c60b9acSAndroid Build Coastguard Worker uint32_t n;
205*1c60b9acSAndroid Build Coastguard Worker
206*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < ke->len; n++)
207*1c60b9acSAndroid Build Coastguard Worker if (ke->buf[n] == key_op)
208*1c60b9acSAndroid Build Coastguard Worker break;
209*1c60b9acSAndroid Build Coastguard Worker
210*1c60b9acSAndroid Build Coastguard Worker if (n == ke->len)
211*1c60b9acSAndroid Build Coastguard Worker goto bail;
212*1c60b9acSAndroid Build Coastguard Worker }
213*1c60b9acSAndroid Build Coastguard Worker
214*1c60b9acSAndroid Build Coastguard Worker /*
215*1c60b9acSAndroid Build Coastguard Worker * If it's related to EC, check there is a curve associated with the
216*1c60b9acSAndroid Build Coastguard Worker * key, and check it is what we expect
217*1c60b9acSAndroid Build Coastguard Worker */
218*1c60b9acSAndroid Build Coastguard Worker
219*1c60b9acSAndroid Build Coastguard Worker if (kty == LWSCOSE_WKKTV_OKP || kty == LWSCOSE_WKKTV_EC2) {
220*1c60b9acSAndroid Build Coastguard Worker ke = &key->e[LWS_GENCRYPTO_EC_KEYEL_CRV];
221*1c60b9acSAndroid Build Coastguard Worker
222*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf)
223*1c60b9acSAndroid Build Coastguard Worker goto bail;
224*1c60b9acSAndroid Build Coastguard Worker if (ke->len != strlen(crv))
225*1c60b9acSAndroid Build Coastguard Worker goto bail;
226*1c60b9acSAndroid Build Coastguard Worker if (memcmp(ke->buf, crv, ke->len))
227*1c60b9acSAndroid Build Coastguard Worker goto bail;
228*1c60b9acSAndroid Build Coastguard Worker }
229*1c60b9acSAndroid Build Coastguard Worker
230*1c60b9acSAndroid Build Coastguard Worker /* We're willing to use this key for this operation */
231*1c60b9acSAndroid Build Coastguard Worker
232*1c60b9acSAndroid Build Coastguard Worker return 0;
233*1c60b9acSAndroid Build Coastguard Worker
234*1c60b9acSAndroid Build Coastguard Worker bail:
235*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: key rejected\n", __func__);
236*1c60b9acSAndroid Build Coastguard Worker
237*1c60b9acSAndroid Build Coastguard Worker return 1;
238*1c60b9acSAndroid Build Coastguard Worker }
239*1c60b9acSAndroid Build Coastguard Worker
240*1c60b9acSAndroid Build Coastguard Worker
241*1c60b9acSAndroid Build Coastguard Worker static int
lws_ck_set_el(struct lws_gencrypto_keyelem * e,char * in,size_t len)242*1c60b9acSAndroid Build Coastguard Worker lws_ck_set_el(struct lws_gencrypto_keyelem *e, char *in, size_t len)
243*1c60b9acSAndroid Build Coastguard Worker {
244*1c60b9acSAndroid Build Coastguard Worker e->buf = lws_malloc(len + 1, "ck");
245*1c60b9acSAndroid Build Coastguard Worker if (!e->buf)
246*1c60b9acSAndroid Build Coastguard Worker return -1;
247*1c60b9acSAndroid Build Coastguard Worker
248*1c60b9acSAndroid Build Coastguard Worker memcpy(e->buf, in, len);
249*1c60b9acSAndroid Build Coastguard Worker e->buf[len] = '\0';
250*1c60b9acSAndroid Build Coastguard Worker e->len = (uint32_t)len;
251*1c60b9acSAndroid Build Coastguard Worker
252*1c60b9acSAndroid Build Coastguard Worker return 0;
253*1c60b9acSAndroid Build Coastguard Worker }
254*1c60b9acSAndroid Build Coastguard Worker
255*1c60b9acSAndroid Build Coastguard Worker static struct {
256*1c60b9acSAndroid Build Coastguard Worker const char *curve;
257*1c60b9acSAndroid Build Coastguard Worker cose_param_t cose_id;
258*1c60b9acSAndroid Build Coastguard Worker } cose_curves[] = {
259*1c60b9acSAndroid Build Coastguard Worker { "P-256", LWSCOSE_WKEC_P256 },
260*1c60b9acSAndroid Build Coastguard Worker { "P-384", LWSCOSE_WKEC_P384 },
261*1c60b9acSAndroid Build Coastguard Worker { "P-521", LWSCOSE_WKEC_P521 },
262*1c60b9acSAndroid Build Coastguard Worker { "X25519", LWSCOSE_WKEC_X25519 },
263*1c60b9acSAndroid Build Coastguard Worker { "X448", LWSCOSE_WKEC_X448 },
264*1c60b9acSAndroid Build Coastguard Worker { "ED25519", LWSCOSE_WKEC_ED25519 },
265*1c60b9acSAndroid Build Coastguard Worker { "ED448", LWSCOSE_WKEC_ED448 },
266*1c60b9acSAndroid Build Coastguard Worker { "SECP256K1", LWSCOSE_WKEC_SECP256K1 },
267*1c60b9acSAndroid Build Coastguard Worker };
268*1c60b9acSAndroid Build Coastguard Worker
269*1c60b9acSAndroid Build Coastguard Worker /* 0 means failed */
270*1c60b9acSAndroid Build Coastguard Worker
271*1c60b9acSAndroid Build Coastguard Worker static cose_param_t
lws_cose_curve_name_to_id(const char * curve)272*1c60b9acSAndroid Build Coastguard Worker lws_cose_curve_name_to_id(const char *curve)
273*1c60b9acSAndroid Build Coastguard Worker {
274*1c60b9acSAndroid Build Coastguard Worker int n;
275*1c60b9acSAndroid Build Coastguard Worker
276*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(cose_curves); n++)
277*1c60b9acSAndroid Build Coastguard Worker if (!strcmp(cose_curves[n].curve, curve))
278*1c60b9acSAndroid Build Coastguard Worker return cose_curves[n].cose_id;
279*1c60b9acSAndroid Build Coastguard Worker
280*1c60b9acSAndroid Build Coastguard Worker return 0;
281*1c60b9acSAndroid Build Coastguard Worker }
282*1c60b9acSAndroid Build Coastguard Worker
283*1c60b9acSAndroid Build Coastguard Worker static const char *
lws_cose_curve_id_to_name(cose_param_t id)284*1c60b9acSAndroid Build Coastguard Worker lws_cose_curve_id_to_name(cose_param_t id)
285*1c60b9acSAndroid Build Coastguard Worker {
286*1c60b9acSAndroid Build Coastguard Worker int n;
287*1c60b9acSAndroid Build Coastguard Worker
288*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(cose_curves); n++)
289*1c60b9acSAndroid Build Coastguard Worker if (cose_curves[n].cose_id == id)
290*1c60b9acSAndroid Build Coastguard Worker return cose_curves[n].curve;
291*1c60b9acSAndroid Build Coastguard Worker
292*1c60b9acSAndroid Build Coastguard Worker return 0;
293*1c60b9acSAndroid Build Coastguard Worker }
294*1c60b9acSAndroid Build Coastguard Worker
295*1c60b9acSAndroid Build Coastguard Worker static const char * const wk_algs[] = {
296*1c60b9acSAndroid Build Coastguard Worker "ES256", "ES384", "ES512"
297*1c60b9acSAndroid Build Coastguard Worker };
298*1c60b9acSAndroid Build Coastguard Worker static signed char wk_alg_indexes[] = {
299*1c60b9acSAndroid Build Coastguard Worker LWSCOSE_WKAECDSA_ALG_ES256,
300*1c60b9acSAndroid Build Coastguard Worker LWSCOSE_WKAECDSA_ALG_ES384,
301*1c60b9acSAndroid Build Coastguard Worker LWSCOSE_WKAECDSA_ALG_ES512,
302*1c60b9acSAndroid Build Coastguard Worker };
303*1c60b9acSAndroid Build Coastguard Worker
304*1c60b9acSAndroid Build Coastguard Worker static signed char
cb_cose_key(struct lecp_ctx * ctx,char reason)305*1c60b9acSAndroid Build Coastguard Worker cb_cose_key(struct lecp_ctx *ctx, char reason)
306*1c60b9acSAndroid Build Coastguard Worker {
307*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_key_parse_state *cps =
308*1c60b9acSAndroid Build Coastguard Worker (struct lws_cose_key_parse_state *)ctx->user;
309*1c60b9acSAndroid Build Coastguard Worker struct lws_gencrypto_keyelem *ke = NULL;
310*1c60b9acSAndroid Build Coastguard Worker const char *p;
311*1c60b9acSAndroid Build Coastguard Worker int n;
312*1c60b9acSAndroid Build Coastguard Worker
313*1c60b9acSAndroid Build Coastguard Worker #if defined(VERBOSE)
314*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: reason %d, path %s, ord %u, ppos %d\n", __func__,
315*1c60b9acSAndroid Build Coastguard Worker reason & 0x3f,
316*1c60b9acSAndroid Build Coastguard Worker ctx->path, ctx->st[ctx->sp - 1].ordinal,
317*1c60b9acSAndroid Build Coastguard Worker ctx->pst[ctx->pst_sp].ppos);
318*1c60b9acSAndroid Build Coastguard Worker #endif
319*1c60b9acSAndroid Build Coastguard Worker
320*1c60b9acSAndroid Build Coastguard Worker switch (reason) {
321*1c60b9acSAndroid Build Coastguard Worker case LECPCB_OBJECT_START:
322*1c60b9acSAndroid Build Coastguard Worker if (cps->ck)
323*1c60b9acSAndroid Build Coastguard Worker break;
324*1c60b9acSAndroid Build Coastguard Worker goto ak;
325*1c60b9acSAndroid Build Coastguard Worker case LECPCB_ARRAY_ITEM_START:
326*1c60b9acSAndroid Build Coastguard Worker if (cps->pkey_set && ctx->pst[ctx->pst_sp].ppos == 2) {
327*1c60b9acSAndroid Build Coastguard Worker ak:
328*1c60b9acSAndroid Build Coastguard Worker cps->ck = lws_zalloc(sizeof(*cps->ck), __func__);
329*1c60b9acSAndroid Build Coastguard Worker if (!cps->ck)
330*1c60b9acSAndroid Build Coastguard Worker goto bail;
331*1c60b9acSAndroid Build Coastguard Worker cps->cose_state = 0;
332*1c60b9acSAndroid Build Coastguard Worker cps->meta_idx = -1;
333*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx = -1;
334*1c60b9acSAndroid Build Coastguard Worker cps->seen_count = 0;
335*1c60b9acSAndroid Build Coastguard Worker
336*1c60b9acSAndroid Build Coastguard Worker if (cps->pkey_set)
337*1c60b9acSAndroid Build Coastguard Worker lws_dll2_add_tail(&cps->ck->list, cps->pkey_set);
338*1c60b9acSAndroid Build Coastguard Worker }
339*1c60b9acSAndroid Build Coastguard Worker break;
340*1c60b9acSAndroid Build Coastguard Worker case LECPCB_ARRAY_ITEM_END:
341*1c60b9acSAndroid Build Coastguard Worker if (cps->pkey_set && ctx->pst[ctx->pst_sp].ppos == 2) {
342*1c60b9acSAndroid Build Coastguard Worker if (cps->per_key_cb)
343*1c60b9acSAndroid Build Coastguard Worker cps->per_key_cb(cps->ck, cps->user);
344*1c60b9acSAndroid Build Coastguard Worker }
345*1c60b9acSAndroid Build Coastguard Worker break;
346*1c60b9acSAndroid Build Coastguard Worker case LECPCB_TAG_START:
347*1c60b9acSAndroid Build Coastguard Worker if (ctx->item.u.u64 != LWSCOAP_CONTENTFORMAT_COSE_KEY) {
348*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unexpected tag\n", __func__);
349*1c60b9acSAndroid Build Coastguard Worker goto bail;
350*1c60b9acSAndroid Build Coastguard Worker }
351*1c60b9acSAndroid Build Coastguard Worker break;
352*1c60b9acSAndroid Build Coastguard Worker
353*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_NUM_INT:
354*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_NUM_UINT:
355*1c60b9acSAndroid Build Coastguard Worker if (!ctx->sp) {
356*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unexpected uint %d, ppos %d\n",
357*1c60b9acSAndroid Build Coastguard Worker __func__, ctx->sp, ctx->pst[ctx->sp].ppos);
358*1c60b9acSAndroid Build Coastguard Worker goto bail;
359*1c60b9acSAndroid Build Coastguard Worker }
360*1c60b9acSAndroid Build Coastguard Worker
361*1c60b9acSAndroid Build Coastguard Worker if (!lecp_parse_map_is_key(ctx)) {
362*1c60b9acSAndroid Build Coastguard Worker const char *kty_str;
363*1c60b9acSAndroid Build Coastguard Worker
364*1c60b9acSAndroid Build Coastguard Worker /* value part of map */
365*1c60b9acSAndroid Build Coastguard Worker
366*1c60b9acSAndroid Build Coastguard Worker switch (cps->cose_state) {
367*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKK_KTY:
368*1c60b9acSAndroid Build Coastguard Worker assert(cps->ck);
369*1c60b9acSAndroid Build Coastguard Worker cps->ck->kty = (int)ctx->item.u.u64;
370*1c60b9acSAndroid Build Coastguard Worker
371*1c60b9acSAndroid Build Coastguard Worker /* convert the cose key type to gencrypto one */
372*1c60b9acSAndroid Build Coastguard Worker switch (ctx->item.u.u64) {
373*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_OKP:
374*1c60b9acSAndroid Build Coastguard Worker cps->ck->gencrypto_kty =
375*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_KTY_EC;
376*1c60b9acSAndroid Build Coastguard Worker kty_str = "OKP";
377*1c60b9acSAndroid Build Coastguard Worker break;
378*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_EC2:
379*1c60b9acSAndroid Build Coastguard Worker kty_str = "EC2";
380*1c60b9acSAndroid Build Coastguard Worker cps->ck->gencrypto_kty =
381*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_KTY_EC;
382*1c60b9acSAndroid Build Coastguard Worker break;
383*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_RSA:
384*1c60b9acSAndroid Build Coastguard Worker kty_str = "RSA";
385*1c60b9acSAndroid Build Coastguard Worker cps->ck->gencrypto_kty =
386*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_KTY_RSA;
387*1c60b9acSAndroid Build Coastguard Worker break;
388*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_SYMMETRIC:
389*1c60b9acSAndroid Build Coastguard Worker kty_str = "SYMMETRIC";
390*1c60b9acSAndroid Build Coastguard Worker cps->ck->gencrypto_kty =
391*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_KTY_OCT;
392*1c60b9acSAndroid Build Coastguard Worker break;
393*1c60b9acSAndroid Build Coastguard Worker // case LWSCOSE_WKKTV_HSS_LMS:
394*1c60b9acSAndroid Build Coastguard Worker // case LWSCOSE_WKKTV_WALNUTDSA:
395*1c60b9acSAndroid Build Coastguard Worker default:
396*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unknown kty\n", __func__);
397*1c60b9acSAndroid Build Coastguard Worker goto bail;
398*1c60b9acSAndroid Build Coastguard Worker }
399*1c60b9acSAndroid Build Coastguard Worker
400*1c60b9acSAndroid Build Coastguard Worker /* store the string version of the key type */
401*1c60b9acSAndroid Build Coastguard Worker
402*1c60b9acSAndroid Build Coastguard Worker ke = &cps->ck->meta[COSEKEY_META_KTY];
403*1c60b9acSAndroid Build Coastguard Worker ke->len = (uint32_t)strlen(kty_str);
404*1c60b9acSAndroid Build Coastguard Worker ke->buf = lws_malloc(ke->len + 1, __func__);
405*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf)
406*1c60b9acSAndroid Build Coastguard Worker goto bail;
407*1c60b9acSAndroid Build Coastguard Worker memcpy(ke->buf, kty_str, ke->len + 1);
408*1c60b9acSAndroid Build Coastguard Worker break;
409*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKK_ALG:
410*1c60b9acSAndroid Build Coastguard Worker /*
411*1c60b9acSAndroid Build Coastguard Worker * He can tie the key to a cose alg code
412*1c60b9acSAndroid Build Coastguard Worker */
413*1c60b9acSAndroid Build Coastguard Worker cps->ck->cose_alg = (int)ctx->item.u.u64;
414*1c60b9acSAndroid Build Coastguard Worker break;
415*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKK_KEY_OPS:
416*1c60b9acSAndroid Build Coastguard Worker if (!cps->pkey_set &&
417*1c60b9acSAndroid Build Coastguard Worker (ctx->pst[ctx->sp].ppos != 3 ||
418*1c60b9acSAndroid Build Coastguard Worker strcmp(ctx->path, ".[]"))) {
419*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unexpected kops\n",
420*1c60b9acSAndroid Build Coastguard Worker __func__);
421*1c60b9acSAndroid Build Coastguard Worker goto bail;
422*1c60b9acSAndroid Build Coastguard Worker }
423*1c60b9acSAndroid Build Coastguard Worker if (cps->pkey_set &&
424*1c60b9acSAndroid Build Coastguard Worker (ctx->pst[ctx->sp].ppos != 5 ||
425*1c60b9acSAndroid Build Coastguard Worker strcmp(ctx->path, "[].[]"))) {
426*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unexpected kops\n",
427*1c60b9acSAndroid Build Coastguard Worker __func__);
428*1c60b9acSAndroid Build Coastguard Worker goto bail;
429*1c60b9acSAndroid Build Coastguard Worker }
430*1c60b9acSAndroid Build Coastguard Worker break;
431*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKOKP_CRV:
432*1c60b9acSAndroid Build Coastguard Worker cps->ck->cose_curve = (int)ctx->item.u.u64;
433*1c60b9acSAndroid Build Coastguard Worker p = lws_cose_curve_id_to_name(cps->ck->cose_curve);
434*1c60b9acSAndroid Build Coastguard Worker if (p) {
435*1c60b9acSAndroid Build Coastguard Worker ke = &cps->ck->e[LWS_GENCRYPTO_EC_KEYEL_CRV];
436*1c60b9acSAndroid Build Coastguard Worker ke->len = (uint32_t)strlen(p);
437*1c60b9acSAndroid Build Coastguard Worker ke->buf = lws_malloc(ke->len + 1, __func__);
438*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf)
439*1c60b9acSAndroid Build Coastguard Worker goto bail;
440*1c60b9acSAndroid Build Coastguard Worker memcpy(ke->buf, p, ke->len);
441*1c60b9acSAndroid Build Coastguard Worker ke->buf[ke->len] = '\0';
442*1c60b9acSAndroid Build Coastguard Worker }
443*1c60b9acSAndroid Build Coastguard Worker break;
444*1c60b9acSAndroid Build Coastguard Worker default:
445*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: uint not allowed in state %d\n",
446*1c60b9acSAndroid Build Coastguard Worker __func__, cps->cose_state);
447*1c60b9acSAndroid Build Coastguard Worker /* int not allowed in this state */
448*1c60b9acSAndroid Build Coastguard Worker goto bail;
449*1c60b9acSAndroid Build Coastguard Worker }
450*1c60b9acSAndroid Build Coastguard Worker
451*1c60b9acSAndroid Build Coastguard Worker cps->cose_state = 0;
452*1c60b9acSAndroid Build Coastguard Worker break;
453*1c60b9acSAndroid Build Coastguard Worker }
454*1c60b9acSAndroid Build Coastguard Worker
455*1c60b9acSAndroid Build Coastguard Worker /* key part of map pair */
456*1c60b9acSAndroid Build Coastguard Worker
457*1c60b9acSAndroid Build Coastguard Worker /*
458*1c60b9acSAndroid Build Coastguard Worker * Disallow any of these coming more than once
459*1c60b9acSAndroid Build Coastguard Worker */
460*1c60b9acSAndroid Build Coastguard Worker cps->cose_state = (int)ctx->item.u.u64;
461*1c60b9acSAndroid Build Coastguard Worker for (n = 0 ; n < cps->seen_count; n++)
462*1c60b9acSAndroid Build Coastguard Worker if (cps->seen[n] == cps->cose_state) {
463*1c60b9acSAndroid Build Coastguard Worker /* dupe */
464*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: duplicate map name %d\n",
465*1c60b9acSAndroid Build Coastguard Worker __func__, cps->cose_state);
466*1c60b9acSAndroid Build Coastguard Worker goto bail;
467*1c60b9acSAndroid Build Coastguard Worker }
468*1c60b9acSAndroid Build Coastguard Worker
469*1c60b9acSAndroid Build Coastguard Worker if (cps->seen_count >= (int)LWS_ARRAY_SIZE(cps->seen))
470*1c60b9acSAndroid Build Coastguard Worker goto bail;
471*1c60b9acSAndroid Build Coastguard Worker cps->seen[cps->seen_count++] = cps->cose_state;
472*1c60b9acSAndroid Build Coastguard Worker
473*1c60b9acSAndroid Build Coastguard Worker cps->meta_idx = -1;
474*1c60b9acSAndroid Build Coastguard Worker switch ((int)ctx->item.u.u64) {
475*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKK_KTY:
476*1c60b9acSAndroid Build Coastguard Worker cps->meta_idx = COSEKEY_META_KTY;
477*1c60b9acSAndroid Build Coastguard Worker break;
478*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKK_KID:
479*1c60b9acSAndroid Build Coastguard Worker cps->meta_idx = COSEKEY_META_KID;
480*1c60b9acSAndroid Build Coastguard Worker break;
481*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKK_ALG:
482*1c60b9acSAndroid Build Coastguard Worker cps->meta_idx = COSEKEY_META_ALG;
483*1c60b9acSAndroid Build Coastguard Worker break;
484*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKK_KEY_OPS:
485*1c60b9acSAndroid Build Coastguard Worker cps->meta_idx = COSEKEY_META_KEY_OPS;
486*1c60b9acSAndroid Build Coastguard Worker break;
487*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKK_BASE_IV:
488*1c60b9acSAndroid Build Coastguard Worker cps->meta_idx = COSEKEY_META_BASE_IV;
489*1c60b9acSAndroid Build Coastguard Worker break;
490*1c60b9acSAndroid Build Coastguard Worker
491*1c60b9acSAndroid Build Coastguard Worker default:
492*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx = -1;
493*1c60b9acSAndroid Build Coastguard Worker
494*1c60b9acSAndroid Build Coastguard Worker switch (cps->ck->kty) {
495*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_OKP:
496*1c60b9acSAndroid Build Coastguard Worker switch ((int)ctx->item.u.u64) {
497*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKOKP_CRV:
498*1c60b9acSAndroid Build Coastguard Worker cps->cose_state = LWSCOSE_WKOKP_CRV;
499*1c60b9acSAndroid Build Coastguard Worker break;
500*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKOKP_X:
501*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
502*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_EC_KEYEL_X;
503*1c60b9acSAndroid Build Coastguard Worker break;
504*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKOKP_D:
505*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
506*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_EC_KEYEL_D;
507*1c60b9acSAndroid Build Coastguard Worker break;
508*1c60b9acSAndroid Build Coastguard Worker default:
509*1c60b9acSAndroid Build Coastguard Worker goto bail;
510*1c60b9acSAndroid Build Coastguard Worker }
511*1c60b9acSAndroid Build Coastguard Worker break;
512*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_EC2:
513*1c60b9acSAndroid Build Coastguard Worker switch ((int)ctx->item.u.u64) {
514*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKECKP_CRV:
515*1c60b9acSAndroid Build Coastguard Worker cps->cose_state = LWSCOSE_WKOKP_CRV;
516*1c60b9acSAndroid Build Coastguard Worker break;
517*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKECKP_X:
518*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
519*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_EC_KEYEL_X;
520*1c60b9acSAndroid Build Coastguard Worker break;
521*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKECKP_Y:
522*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
523*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_EC_KEYEL_Y;
524*1c60b9acSAndroid Build Coastguard Worker break;
525*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKECKP_D:
526*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
527*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_EC_KEYEL_D;
528*1c60b9acSAndroid Build Coastguard Worker break;
529*1c60b9acSAndroid Build Coastguard Worker default:
530*1c60b9acSAndroid Build Coastguard Worker goto bail;
531*1c60b9acSAndroid Build Coastguard Worker }
532*1c60b9acSAndroid Build Coastguard Worker break;
533*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_RSA:
534*1c60b9acSAndroid Build Coastguard Worker switch ((int)ctx->item.u.u64) {
535*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_N:
536*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
537*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_N;
538*1c60b9acSAndroid Build Coastguard Worker break;
539*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_E:
540*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
541*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_E;
542*1c60b9acSAndroid Build Coastguard Worker break;
543*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_D:
544*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
545*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_D;
546*1c60b9acSAndroid Build Coastguard Worker break;
547*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_P:
548*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
549*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_P;
550*1c60b9acSAndroid Build Coastguard Worker break;
551*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_Q:
552*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
553*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_Q;
554*1c60b9acSAndroid Build Coastguard Worker break;
555*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_DP:
556*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
557*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_DP;
558*1c60b9acSAndroid Build Coastguard Worker break;
559*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_DQ:
560*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
561*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_DQ;
562*1c60b9acSAndroid Build Coastguard Worker break;
563*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_QINV:
564*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
565*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_QI;
566*1c60b9acSAndroid Build Coastguard Worker break;
567*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_OTHER:
568*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
569*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_OTHER;
570*1c60b9acSAndroid Build Coastguard Worker break;
571*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_RI:
572*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
573*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_RI;
574*1c60b9acSAndroid Build Coastguard Worker break;
575*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_DI:
576*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
577*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_DI;
578*1c60b9acSAndroid Build Coastguard Worker break;
579*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKPRSA_TI:
580*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx =
581*1c60b9acSAndroid Build Coastguard Worker LWS_GENCRYPTO_RSA_KEYEL_TI;
582*1c60b9acSAndroid Build Coastguard Worker break;
583*1c60b9acSAndroid Build Coastguard Worker default:
584*1c60b9acSAndroid Build Coastguard Worker goto bail;
585*1c60b9acSAndroid Build Coastguard Worker }
586*1c60b9acSAndroid Build Coastguard Worker break;
587*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_SYMMETRIC:
588*1c60b9acSAndroid Build Coastguard Worker if (ctx->item.u.i64 != -1 &&
589*1c60b9acSAndroid Build Coastguard Worker ctx->item.u.u64 != LWSCOSE_WKSYMKP_KEY_VALUE)
590*1c60b9acSAndroid Build Coastguard Worker goto bail;
591*1c60b9acSAndroid Build Coastguard Worker
592*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx = LWS_GENCRYPTO_OCT_KEYEL_K;
593*1c60b9acSAndroid Build Coastguard Worker break;
594*1c60b9acSAndroid Build Coastguard Worker default:
595*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unknown kty\n", __func__);
596*1c60b9acSAndroid Build Coastguard Worker goto bail;
597*1c60b9acSAndroid Build Coastguard Worker }
598*1c60b9acSAndroid Build Coastguard Worker break;
599*1c60b9acSAndroid Build Coastguard Worker }
600*1c60b9acSAndroid Build Coastguard Worker break;
601*1c60b9acSAndroid Build Coastguard Worker
602*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_BLOB_START:
603*1c60b9acSAndroid Build Coastguard Worker if (!ctx->sp || !(ctx->st[ctx->sp - 1].ordinal & 1)) {
604*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: unexpected blob\n", __func__);
605*1c60b9acSAndroid Build Coastguard Worker goto bail;
606*1c60b9acSAndroid Build Coastguard Worker }
607*1c60b9acSAndroid Build Coastguard Worker
608*1c60b9acSAndroid Build Coastguard Worker if (cps->cose_state == COSEKEY_META_KID)
609*1c60b9acSAndroid Build Coastguard Worker break;
610*1c60b9acSAndroid Build Coastguard Worker
611*1c60b9acSAndroid Build Coastguard Worker /*
612*1c60b9acSAndroid Build Coastguard Worker * Validate the association of the blob now, collect it into
613*1c60b9acSAndroid Build Coastguard Worker * the temp buf in cps and then alloc and copy it into the
614*1c60b9acSAndroid Build Coastguard Worker * related key element when it's at the end and the size known
615*1c60b9acSAndroid Build Coastguard Worker */
616*1c60b9acSAndroid Build Coastguard Worker
617*1c60b9acSAndroid Build Coastguard Worker cps->pos = 0;
618*1c60b9acSAndroid Build Coastguard Worker if (cps->gencrypto_eidx >= 0) {
619*1c60b9acSAndroid Build Coastguard Worker if (cps->ck->e[cps->gencrypto_eidx].buf) {
620*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: e[%d] set twice %d\n", __func__,
621*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx,
622*1c60b9acSAndroid Build Coastguard Worker cps->ck->e[cps->gencrypto_eidx].len);
623*1c60b9acSAndroid Build Coastguard Worker /* key elements must only come at most once */
624*1c60b9acSAndroid Build Coastguard Worker goto bail;
625*1c60b9acSAndroid Build Coastguard Worker }
626*1c60b9acSAndroid Build Coastguard Worker break;
627*1c60b9acSAndroid Build Coastguard Worker }
628*1c60b9acSAndroid Build Coastguard Worker if (cps->meta_idx >= 0)
629*1c60b9acSAndroid Build Coastguard Worker break;
630*1c60b9acSAndroid Build Coastguard Worker
631*1c60b9acSAndroid Build Coastguard Worker goto bail;
632*1c60b9acSAndroid Build Coastguard Worker
633*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_BLOB_CHUNK:
634*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_BLOB_END:
635*1c60b9acSAndroid Build Coastguard Worker if (cps->pos + ctx->npos > sizeof(cps->buf)) {
636*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: oversize blob\n", __func__);
637*1c60b9acSAndroid Build Coastguard Worker goto bail;
638*1c60b9acSAndroid Build Coastguard Worker }
639*1c60b9acSAndroid Build Coastguard Worker memcpy(cps->buf + cps->pos, ctx->buf, ctx->npos);
640*1c60b9acSAndroid Build Coastguard Worker cps->pos += ctx->npos;
641*1c60b9acSAndroid Build Coastguard Worker
642*1c60b9acSAndroid Build Coastguard Worker if (reason == LECPCB_VAL_BLOB_CHUNK)
643*1c60b9acSAndroid Build Coastguard Worker break;
644*1c60b9acSAndroid Build Coastguard Worker
645*1c60b9acSAndroid Build Coastguard Worker /* we have the key element data, let's make the ck element */
646*1c60b9acSAndroid Build Coastguard Worker if (cps->gencrypto_eidx >= 0) {
647*1c60b9acSAndroid Build Coastguard Worker
648*1c60b9acSAndroid Build Coastguard Worker if (cps->ck->e[cps->gencrypto_eidx].buf)
649*1c60b9acSAndroid Build Coastguard Worker break;
650*1c60b9acSAndroid Build Coastguard Worker
651*1c60b9acSAndroid Build Coastguard Worker lws_ck_set_el(&cps->ck->e[cps->gencrypto_eidx],
652*1c60b9acSAndroid Build Coastguard Worker (char *)cps->buf, cps->pos);
653*1c60b9acSAndroid Build Coastguard Worker cps->gencrypto_eidx = -1;
654*1c60b9acSAndroid Build Coastguard Worker break;
655*1c60b9acSAndroid Build Coastguard Worker }
656*1c60b9acSAndroid Build Coastguard Worker
657*1c60b9acSAndroid Build Coastguard Worker
658*1c60b9acSAndroid Build Coastguard Worker if (cps->meta_idx >= 0) {
659*1c60b9acSAndroid Build Coastguard Worker lws_ck_set_el(&cps->ck->meta[cps->meta_idx],
660*1c60b9acSAndroid Build Coastguard Worker (char *)cps->buf, cps->pos);
661*1c60b9acSAndroid Build Coastguard Worker cps->meta_idx = -1;
662*1c60b9acSAndroid Build Coastguard Worker }
663*1c60b9acSAndroid Build Coastguard Worker cps->pos = 0;
664*1c60b9acSAndroid Build Coastguard Worker break;
665*1c60b9acSAndroid Build Coastguard Worker case LECPCB_VAL_STR_END:
666*1c60b9acSAndroid Build Coastguard Worker if (cps->cose_state == LWSCOSE_WKOKP_CRV) {
667*1c60b9acSAndroid Build Coastguard Worker cps->ck->cose_curve = lws_cose_curve_name_to_id(ctx->buf);
668*1c60b9acSAndroid Build Coastguard Worker ke = &cps->ck->e[LWS_GENCRYPTO_EC_KEYEL_CRV];
669*1c60b9acSAndroid Build Coastguard Worker ke->len = ctx->npos;
670*1c60b9acSAndroid Build Coastguard Worker ke->buf = lws_malloc(ctx->npos, __func__);
671*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf)
672*1c60b9acSAndroid Build Coastguard Worker goto bail;
673*1c60b9acSAndroid Build Coastguard Worker memcpy(ke->buf, ctx->buf, ctx->npos);
674*1c60b9acSAndroid Build Coastguard Worker }
675*1c60b9acSAndroid Build Coastguard Worker
676*1c60b9acSAndroid Build Coastguard Worker if (!lecp_parse_map_is_key(ctx) &&
677*1c60b9acSAndroid Build Coastguard Worker cps->cose_state == LWSCOSE_WKK_ALG) {
678*1c60b9acSAndroid Build Coastguard Worker size_t n;
679*1c60b9acSAndroid Build Coastguard Worker
680*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < LWS_ARRAY_SIZE(wk_algs); n++)
681*1c60b9acSAndroid Build Coastguard Worker if (ctx->npos == strlen(wk_algs[n]) &&
682*1c60b9acSAndroid Build Coastguard Worker !memcmp(ctx->buf, wk_algs[n], ctx->npos)) {
683*1c60b9acSAndroid Build Coastguard Worker cps->ck->cose_alg = wk_alg_indexes[n];
684*1c60b9acSAndroid Build Coastguard Worker break;
685*1c60b9acSAndroid Build Coastguard Worker }
686*1c60b9acSAndroid Build Coastguard Worker
687*1c60b9acSAndroid Build Coastguard Worker if (n == LWS_ARRAY_SIZE(wk_algs))
688*1c60b9acSAndroid Build Coastguard Worker /* key is for an alg we don't understand */
689*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: key for unknown alg %.*s\n",
690*1c60b9acSAndroid Build Coastguard Worker __func__, (int)ctx->npos, ctx->buf);
691*1c60b9acSAndroid Build Coastguard Worker
692*1c60b9acSAndroid Build Coastguard Worker ke = &cps->ck->meta[COSEKEY_META_ALG];
693*1c60b9acSAndroid Build Coastguard Worker ke->len = ctx->npos;
694*1c60b9acSAndroid Build Coastguard Worker ke->buf = lws_malloc(ctx->npos, __func__);
695*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf)
696*1c60b9acSAndroid Build Coastguard Worker goto bail;
697*1c60b9acSAndroid Build Coastguard Worker memcpy(ke->buf, ctx->buf, ctx->npos);
698*1c60b9acSAndroid Build Coastguard Worker }
699*1c60b9acSAndroid Build Coastguard Worker
700*1c60b9acSAndroid Build Coastguard Worker break;
701*1c60b9acSAndroid Build Coastguard Worker }
702*1c60b9acSAndroid Build Coastguard Worker
703*1c60b9acSAndroid Build Coastguard Worker return 0;
704*1c60b9acSAndroid Build Coastguard Worker
705*1c60b9acSAndroid Build Coastguard Worker bail:
706*1c60b9acSAndroid Build Coastguard Worker lwsl_warn("%s: bail\n", __func__);
707*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_destroy(&cps->ck);
708*1c60b9acSAndroid Build Coastguard Worker
709*1c60b9acSAndroid Build Coastguard Worker if (cps->pkey_set) {
710*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_set_destroy(cps->pkey_set);
711*1c60b9acSAndroid Build Coastguard Worker cps->pkey_set = NULL;
712*1c60b9acSAndroid Build Coastguard Worker }
713*1c60b9acSAndroid Build Coastguard Worker
714*1c60b9acSAndroid Build Coastguard Worker return -1;
715*1c60b9acSAndroid Build Coastguard Worker }
716*1c60b9acSAndroid Build Coastguard Worker
717*1c60b9acSAndroid Build Coastguard Worker void
lws_cose_key_destroy_elements(struct lws_gencrypto_keyelem * el,int m)718*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_destroy_elements(struct lws_gencrypto_keyelem *el, int m)
719*1c60b9acSAndroid Build Coastguard Worker {
720*1c60b9acSAndroid Build Coastguard Worker int n;
721*1c60b9acSAndroid Build Coastguard Worker
722*1c60b9acSAndroid Build Coastguard Worker if (!el)
723*1c60b9acSAndroid Build Coastguard Worker return;
724*1c60b9acSAndroid Build Coastguard Worker
725*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < m; n++)
726*1c60b9acSAndroid Build Coastguard Worker if (el[n].buf) {
727*1c60b9acSAndroid Build Coastguard Worker /* wipe all key material when it goes out of scope */
728*1c60b9acSAndroid Build Coastguard Worker lws_explicit_bzero(el[n].buf, el[n].len);
729*1c60b9acSAndroid Build Coastguard Worker lws_free_set_NULL(el[n].buf);
730*1c60b9acSAndroid Build Coastguard Worker el[n].len = 0;
731*1c60b9acSAndroid Build Coastguard Worker }
732*1c60b9acSAndroid Build Coastguard Worker }
733*1c60b9acSAndroid Build Coastguard Worker
734*1c60b9acSAndroid Build Coastguard Worker void
lws_cose_key_destroy(struct lws_cose_key ** pck)735*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_destroy(struct lws_cose_key **pck)
736*1c60b9acSAndroid Build Coastguard Worker {
737*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_key *ck = *pck;
738*1c60b9acSAndroid Build Coastguard Worker
739*1c60b9acSAndroid Build Coastguard Worker if (!ck)
740*1c60b9acSAndroid Build Coastguard Worker return;
741*1c60b9acSAndroid Build Coastguard Worker
742*1c60b9acSAndroid Build Coastguard Worker lws_dll2_remove(&ck->list);
743*1c60b9acSAndroid Build Coastguard Worker
744*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_destroy_elements(ck->e, LWS_ARRAY_SIZE(ck->e));
745*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_destroy_elements(ck->meta, LWS_ARRAY_SIZE(ck->meta));
746*1c60b9acSAndroid Build Coastguard Worker
747*1c60b9acSAndroid Build Coastguard Worker lws_free_set_NULL(*pck);
748*1c60b9acSAndroid Build Coastguard Worker }
749*1c60b9acSAndroid Build Coastguard Worker
750*1c60b9acSAndroid Build Coastguard Worker static int
lws_cose_key_set_memb_remove(struct lws_dll2 * d,void * user)751*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_set_memb_remove(struct lws_dll2 *d, void *user)
752*1c60b9acSAndroid Build Coastguard Worker {
753*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_t *ck = lws_container_of(d, lws_cose_key_t, list);
754*1c60b9acSAndroid Build Coastguard Worker
755*1c60b9acSAndroid Build Coastguard Worker lws_dll2_remove(d);
756*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_destroy(&ck);
757*1c60b9acSAndroid Build Coastguard Worker
758*1c60b9acSAndroid Build Coastguard Worker return 0;
759*1c60b9acSAndroid Build Coastguard Worker }
760*1c60b9acSAndroid Build Coastguard Worker
761*1c60b9acSAndroid Build Coastguard Worker void
lws_cose_key_set_destroy(lws_dll2_owner_t * o)762*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_set_destroy(lws_dll2_owner_t *o)
763*1c60b9acSAndroid Build Coastguard Worker {
764*1c60b9acSAndroid Build Coastguard Worker lws_dll2_foreach_safe(o, NULL, lws_cose_key_set_memb_remove);
765*1c60b9acSAndroid Build Coastguard Worker }
766*1c60b9acSAndroid Build Coastguard Worker
767*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_t *
lws_cose_key_from_set(lws_dll2_owner_t * set,const uint8_t * kid,size_t kl)768*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_from_set(lws_dll2_owner_t *set, const uint8_t *kid, size_t kl)
769*1c60b9acSAndroid Build Coastguard Worker {
770*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll(struct lws_dll2 *, p, lws_dll2_get_head(set)) {
771*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_t *ck = lws_container_of(p, lws_cose_key_t, list);
772*1c60b9acSAndroid Build Coastguard Worker struct lws_gencrypto_keyelem *ke = &ck->meta[COSEKEY_META_KID];
773*1c60b9acSAndroid Build Coastguard Worker
774*1c60b9acSAndroid Build Coastguard Worker if (!kid) /* always the first then */
775*1c60b9acSAndroid Build Coastguard Worker return ck;
776*1c60b9acSAndroid Build Coastguard Worker
777*1c60b9acSAndroid Build Coastguard Worker if (ke->buf && ke->len == (uint32_t)kl &&
778*1c60b9acSAndroid Build Coastguard Worker !memcmp(ke->buf, kid, ke->len))
779*1c60b9acSAndroid Build Coastguard Worker return ck;
780*1c60b9acSAndroid Build Coastguard Worker
781*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll(p);
782*1c60b9acSAndroid Build Coastguard Worker
783*1c60b9acSAndroid Build Coastguard Worker return NULL;
784*1c60b9acSAndroid Build Coastguard Worker }
785*1c60b9acSAndroid Build Coastguard Worker
786*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_t *
lws_cose_key_generate(struct lws_context * context,cose_param_t cose_kty,int use_mask,int bits,const char * curve,const uint8_t * kid,size_t kl)787*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_generate(struct lws_context *context, cose_param_t cose_kty,
788*1c60b9acSAndroid Build Coastguard Worker int use_mask, int bits, const char *curve,
789*1c60b9acSAndroid Build Coastguard Worker const uint8_t *kid, size_t kl)
790*1c60b9acSAndroid Build Coastguard Worker {
791*1c60b9acSAndroid Build Coastguard Worker struct lws_gencrypto_keyelem *ke;
792*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_t *ck;
793*1c60b9acSAndroid Build Coastguard Worker size_t sn;
794*1c60b9acSAndroid Build Coastguard Worker int n;
795*1c60b9acSAndroid Build Coastguard Worker
796*1c60b9acSAndroid Build Coastguard Worker ck = lws_zalloc(sizeof(*ck), __func__);
797*1c60b9acSAndroid Build Coastguard Worker if (!ck)
798*1c60b9acSAndroid Build Coastguard Worker return NULL;
799*1c60b9acSAndroid Build Coastguard Worker
800*1c60b9acSAndroid Build Coastguard Worker ck->kty = cose_kty;
801*1c60b9acSAndroid Build Coastguard Worker ck->private_key = 1;
802*1c60b9acSAndroid Build Coastguard Worker
803*1c60b9acSAndroid Build Coastguard Worker if (use_mask & 0xfffe) {
804*1c60b9acSAndroid Build Coastguard Worker int count = 0;
805*1c60b9acSAndroid Build Coastguard Worker
806*1c60b9acSAndroid Build Coastguard Worker for (n = 1; n < 15; n++)
807*1c60b9acSAndroid Build Coastguard Worker if (use_mask & (1 << n))
808*1c60b9acSAndroid Build Coastguard Worker count++;
809*1c60b9acSAndroid Build Coastguard Worker ke = &ck->meta[COSEKEY_META_KEY_OPS];
810*1c60b9acSAndroid Build Coastguard Worker ke->buf = lws_malloc((size_t)count, __func__);
811*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf)
812*1c60b9acSAndroid Build Coastguard Worker goto fail;
813*1c60b9acSAndroid Build Coastguard Worker ke->len = (uint32_t)count;
814*1c60b9acSAndroid Build Coastguard Worker count = 0;
815*1c60b9acSAndroid Build Coastguard Worker for (n = 1; n < 15; n++)
816*1c60b9acSAndroid Build Coastguard Worker if (use_mask & (1 << n))
817*1c60b9acSAndroid Build Coastguard Worker ke->buf[count++] = (uint8_t)n;
818*1c60b9acSAndroid Build Coastguard Worker }
819*1c60b9acSAndroid Build Coastguard Worker
820*1c60b9acSAndroid Build Coastguard Worker if (kid) {
821*1c60b9acSAndroid Build Coastguard Worker ke = &ck->meta[COSEKEY_META_KID];
822*1c60b9acSAndroid Build Coastguard Worker ke->buf = lws_malloc(kl, __func__);
823*1c60b9acSAndroid Build Coastguard Worker ke->len = (uint32_t)kl;
824*1c60b9acSAndroid Build Coastguard Worker memcpy(ke->buf, kid, ke->len);
825*1c60b9acSAndroid Build Coastguard Worker }
826*1c60b9acSAndroid Build Coastguard Worker
827*1c60b9acSAndroid Build Coastguard Worker switch (cose_kty) {
828*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_RSA:
829*1c60b9acSAndroid Build Coastguard Worker {
830*1c60b9acSAndroid Build Coastguard Worker struct lws_genrsa_ctx ctx;
831*1c60b9acSAndroid Build Coastguard Worker
832*1c60b9acSAndroid Build Coastguard Worker memset(&ctx, 0, sizeof(ctx));
833*1c60b9acSAndroid Build Coastguard Worker ck->gencrypto_kty = LWS_GENCRYPTO_KTY_RSA;
834*1c60b9acSAndroid Build Coastguard Worker
835*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: generating %d bit RSA key\n",
836*1c60b9acSAndroid Build Coastguard Worker __func__, bits);
837*1c60b9acSAndroid Build Coastguard Worker n = lws_genrsa_new_keypair(context, &ctx,
838*1c60b9acSAndroid Build Coastguard Worker LGRSAM_PKCS1_1_5,
839*1c60b9acSAndroid Build Coastguard Worker ck->e, bits);
840*1c60b9acSAndroid Build Coastguard Worker lws_genrsa_destroy(&ctx);
841*1c60b9acSAndroid Build Coastguard Worker if (n) {
842*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: problem generating RSA key\n",
843*1c60b9acSAndroid Build Coastguard Worker __func__);
844*1c60b9acSAndroid Build Coastguard Worker goto fail;
845*1c60b9acSAndroid Build Coastguard Worker }
846*1c60b9acSAndroid Build Coastguard Worker }
847*1c60b9acSAndroid Build Coastguard Worker break;
848*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_SYMMETRIC:
849*1c60b9acSAndroid Build Coastguard Worker
850*1c60b9acSAndroid Build Coastguard Worker ck->gencrypto_kty = LWS_GENCRYPTO_KTY_OCT;
851*1c60b9acSAndroid Build Coastguard Worker sn = (unsigned int)lws_gencrypto_bits_to_bytes(bits);
852*1c60b9acSAndroid Build Coastguard Worker ke = &ck->e[LWS_GENCRYPTO_OCT_KEYEL_K];
853*1c60b9acSAndroid Build Coastguard Worker ke->buf = lws_malloc(sn, "oct");
854*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf)
855*1c60b9acSAndroid Build Coastguard Worker goto fail;
856*1c60b9acSAndroid Build Coastguard Worker ke->len = (uint32_t)sn;
857*1c60b9acSAndroid Build Coastguard Worker if (lws_get_random(context, ke->buf, sn) != sn) {
858*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: problem getting random\n", __func__);
859*1c60b9acSAndroid Build Coastguard Worker goto fail;
860*1c60b9acSAndroid Build Coastguard Worker }
861*1c60b9acSAndroid Build Coastguard Worker break;
862*1c60b9acSAndroid Build Coastguard Worker
863*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_OKP:
864*1c60b9acSAndroid Build Coastguard Worker case LWSCOSE_WKKTV_EC2:
865*1c60b9acSAndroid Build Coastguard Worker {
866*1c60b9acSAndroid Build Coastguard Worker struct lws_genec_ctx ctx;
867*1c60b9acSAndroid Build Coastguard Worker
868*1c60b9acSAndroid Build Coastguard Worker ck->gencrypto_kty = LWS_GENCRYPTO_KTY_EC;
869*1c60b9acSAndroid Build Coastguard Worker
870*1c60b9acSAndroid Build Coastguard Worker if (!curve) {
871*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: must have a named curve\n", __func__);
872*1c60b9acSAndroid Build Coastguard Worker
873*1c60b9acSAndroid Build Coastguard Worker goto fail;
874*1c60b9acSAndroid Build Coastguard Worker }
875*1c60b9acSAndroid Build Coastguard Worker
876*1c60b9acSAndroid Build Coastguard Worker if (lws_genecdsa_create(&ctx, context, NULL))
877*1c60b9acSAndroid Build Coastguard Worker goto fail;
878*1c60b9acSAndroid Build Coastguard Worker
879*1c60b9acSAndroid Build Coastguard Worker ctx.genec_alg = LEGENEC_ECDSA;
880*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: generating ECDSA key on curve %s\n", __func__,
881*1c60b9acSAndroid Build Coastguard Worker curve);
882*1c60b9acSAndroid Build Coastguard Worker
883*1c60b9acSAndroid Build Coastguard Worker n = lws_genecdsa_new_keypair(&ctx, curve, ck->e);
884*1c60b9acSAndroid Build Coastguard Worker lws_genec_destroy(&ctx);
885*1c60b9acSAndroid Build Coastguard Worker if (n) {
886*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: problem generating ECDSA key\n", __func__);
887*1c60b9acSAndroid Build Coastguard Worker goto fail;
888*1c60b9acSAndroid Build Coastguard Worker }
889*1c60b9acSAndroid Build Coastguard Worker /* trim the trailing NUL */
890*1c60b9acSAndroid Build Coastguard Worker ck->e[LWS_GENCRYPTO_EC_KEYEL_CRV].len = (uint32_t)strlen(curve);
891*1c60b9acSAndroid Build Coastguard Worker }
892*1c60b9acSAndroid Build Coastguard Worker break;
893*1c60b9acSAndroid Build Coastguard Worker
894*1c60b9acSAndroid Build Coastguard Worker default:
895*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: unknown kty\n", __func__);
896*1c60b9acSAndroid Build Coastguard Worker goto fail;
897*1c60b9acSAndroid Build Coastguard Worker }
898*1c60b9acSAndroid Build Coastguard Worker
899*1c60b9acSAndroid Build Coastguard Worker return ck;
900*1c60b9acSAndroid Build Coastguard Worker
901*1c60b9acSAndroid Build Coastguard Worker fail:
902*1c60b9acSAndroid Build Coastguard Worker lws_free_set_NULL(ck);
903*1c60b9acSAndroid Build Coastguard Worker
904*1c60b9acSAndroid Build Coastguard Worker return NULL;
905*1c60b9acSAndroid Build Coastguard Worker }
906*1c60b9acSAndroid Build Coastguard Worker
907*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_key *
lws_cose_key_import(lws_dll2_owner_t * pkey_set,lws_cose_key_import_callback cb,void * user,const uint8_t * in,size_t len)908*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_import(lws_dll2_owner_t *pkey_set, lws_cose_key_import_callback cb,
909*1c60b9acSAndroid Build Coastguard Worker void *user, const uint8_t *in, size_t len)
910*1c60b9acSAndroid Build Coastguard Worker {
911*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_key_parse_state cps;
912*1c60b9acSAndroid Build Coastguard Worker struct lecp_ctx ctx;
913*1c60b9acSAndroid Build Coastguard Worker int m;
914*1c60b9acSAndroid Build Coastguard Worker
915*1c60b9acSAndroid Build Coastguard Worker memset(&cps, 0, sizeof(cps));
916*1c60b9acSAndroid Build Coastguard Worker
917*1c60b9acSAndroid Build Coastguard Worker cps.per_key_cb = cb;
918*1c60b9acSAndroid Build Coastguard Worker cps.user = user;
919*1c60b9acSAndroid Build Coastguard Worker cps.pkey_set = pkey_set;
920*1c60b9acSAndroid Build Coastguard Worker cps.gencrypto_eidx = -1;
921*1c60b9acSAndroid Build Coastguard Worker
922*1c60b9acSAndroid Build Coastguard Worker lecp_construct(&ctx, cb_cose_key, &cps, NULL, 0);
923*1c60b9acSAndroid Build Coastguard Worker m = lecp_parse(&ctx, in, len);
924*1c60b9acSAndroid Build Coastguard Worker lecp_destruct(&ctx);
925*1c60b9acSAndroid Build Coastguard Worker
926*1c60b9acSAndroid Build Coastguard Worker if (m < 0) {
927*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: parse got %d\n", __func__, m);
928*1c60b9acSAndroid Build Coastguard Worker if (cps.pkey_set)
929*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_set_destroy(cps.pkey_set);
930*1c60b9acSAndroid Build Coastguard Worker
931*1c60b9acSAndroid Build Coastguard Worker return NULL;
932*1c60b9acSAndroid Build Coastguard Worker }
933*1c60b9acSAndroid Build Coastguard Worker
934*1c60b9acSAndroid Build Coastguard Worker switch (cps.ck->gencrypto_kty) {
935*1c60b9acSAndroid Build Coastguard Worker case LWS_GENCRYPTO_KTY_UNKNOWN:
936*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: missing or unknown ktys\n", __func__);
937*1c60b9acSAndroid Build Coastguard Worker goto bail;
938*1c60b9acSAndroid Build Coastguard Worker default:
939*1c60b9acSAndroid Build Coastguard Worker break;
940*1c60b9acSAndroid Build Coastguard Worker }
941*1c60b9acSAndroid Build Coastguard Worker
942*1c60b9acSAndroid Build Coastguard Worker return cps.ck;
943*1c60b9acSAndroid Build Coastguard Worker
944*1c60b9acSAndroid Build Coastguard Worker bail:
945*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_destroy(&cps.ck);
946*1c60b9acSAndroid Build Coastguard Worker return NULL;
947*1c60b9acSAndroid Build Coastguard Worker }
948*1c60b9acSAndroid Build Coastguard Worker
949*1c60b9acSAndroid Build Coastguard Worker /* gencrypto element orering -> cose key parameters */
950*1c60b9acSAndroid Build Coastguard Worker
951*1c60b9acSAndroid Build Coastguard Worker static const signed char ckp[3][12] = {
952*1c60b9acSAndroid Build Coastguard Worker { /* LWS_GENCRYPTO_KTY_OCT (1) */
953*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_OCT_KEYEL_K */ LWSCOSE_WKSYMKP_KEY_VALUE,
954*1c60b9acSAndroid Build Coastguard Worker },
955*1c60b9acSAndroid Build Coastguard Worker { /* LWS_GENCRYPTO_KTY_RSA (2) */
956*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_E */ LWSCOSE_WKKPRSA_E,
957*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_N */ LWSCOSE_WKKPRSA_N,
958*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_D */ LWSCOSE_WKKPRSA_D,
959*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_P */ LWSCOSE_WKKPRSA_P,
960*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_Q */ LWSCOSE_WKKPRSA_Q,
961*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_DP */ LWSCOSE_WKKPRSA_DP,
962*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_DQ */ LWSCOSE_WKKPRSA_DQ,
963*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_QT */ LWSCOSE_WKKPRSA_QINV,
964*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_OTHER */ LWSCOSE_WKKPRSA_OTHER,
965*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_RI */ LWSCOSE_WKKPRSA_RI,
966*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_DI */ LWSCOSE_WKKPRSA_DI,
967*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_RSA_KEYEL_TI */ LWSCOSE_WKKPRSA_TI,
968*1c60b9acSAndroid Build Coastguard Worker },
969*1c60b9acSAndroid Build Coastguard Worker { /* LWS_GENCRYPTO_KTY_EC (3) */
970*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_EC_KEYEL_CRV */ LWSCOSE_WKECKP_CRV,
971*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_EC_KEYEL_X */ LWSCOSE_WKECKP_X,
972*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_EC_KEYEL_D */ LWSCOSE_WKECKP_D,
973*1c60b9acSAndroid Build Coastguard Worker /* LWS_GENCRYPTO_EC_KEYEL_Y */ LWSCOSE_WKECKP_Y,
974*1c60b9acSAndroid Build Coastguard Worker }
975*1c60b9acSAndroid Build Coastguard Worker };
976*1c60b9acSAndroid Build Coastguard Worker
977*1c60b9acSAndroid Build Coastguard Worker enum lws_lec_pctx_ret
lws_cose_key_export(lws_cose_key_t * ck,lws_lec_pctx_t * ctx,int flags)978*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_export(lws_cose_key_t *ck, lws_lec_pctx_t *ctx, int flags)
979*1c60b9acSAndroid Build Coastguard Worker {
980*1c60b9acSAndroid Build Coastguard Worker cose_param_t pa = 0;
981*1c60b9acSAndroid Build Coastguard Worker int n;
982*1c60b9acSAndroid Build Coastguard Worker
983*1c60b9acSAndroid Build Coastguard Worker if (!ctx->opaque[0]) {
984*1c60b9acSAndroid Build Coastguard Worker
985*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[0] = 1; /* map pair count */
986*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[1] = 1; /* element index */
987*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[2] = 0; /* public mask */
988*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[3] = 0; /* doing AGAIN */
989*1c60b9acSAndroid Build Coastguard Worker
990*1c60b9acSAndroid Build Coastguard Worker switch (ck->gencrypto_kty) {
991*1c60b9acSAndroid Build Coastguard Worker case LWS_GENCRYPTO_KTY_OCT:
992*1c60b9acSAndroid Build Coastguard Worker /* nothing to differentiate */
993*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[2] = 1 << LWS_GENCRYPTO_OCT_KEYEL_K;
994*1c60b9acSAndroid Build Coastguard Worker break;
995*1c60b9acSAndroid Build Coastguard Worker case LWS_GENCRYPTO_KTY_RSA:
996*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[2] = 1 << LWS_GENCRYPTO_RSA_KEYEL_E;
997*1c60b9acSAndroid Build Coastguard Worker break;
998*1c60b9acSAndroid Build Coastguard Worker case LWS_GENCRYPTO_KTY_EC:
999*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[2] = (1 << LWS_GENCRYPTO_EC_KEYEL_X) |
1000*1c60b9acSAndroid Build Coastguard Worker (1 << LWS_GENCRYPTO_EC_KEYEL_Y);
1001*1c60b9acSAndroid Build Coastguard Worker break;
1002*1c60b9acSAndroid Build Coastguard Worker default:
1003*1c60b9acSAndroid Build Coastguard Worker goto fail;
1004*1c60b9acSAndroid Build Coastguard Worker }
1005*1c60b9acSAndroid Build Coastguard Worker
1006*1c60b9acSAndroid Build Coastguard Worker if (flags & LWSJWKF_EXPORT_PRIVATE)
1007*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[2] = 0xffff;
1008*1c60b9acSAndroid Build Coastguard Worker
1009*1c60b9acSAndroid Build Coastguard Worker /*
1010*1c60b9acSAndroid Build Coastguard Worker * We first need to find out how many CBOR map pairs we are
1011*1c60b9acSAndroid Build Coastguard Worker * planning to create, so we can set a fixed length map of the
1012*1c60b9acSAndroid Build Coastguard Worker * right size.
1013*1c60b9acSAndroid Build Coastguard Worker */
1014*1c60b9acSAndroid Build Coastguard Worker
1015*1c60b9acSAndroid Build Coastguard Worker for (n = 0; n < (int)LWS_ARRAY_SIZE(ck->e); n++)
1016*1c60b9acSAndroid Build Coastguard Worker if ((ctx->opaque[2] & (1 << n)) && ck->e[n].buf)
1017*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[0]++;
1018*1c60b9acSAndroid Build Coastguard Worker
1019*1c60b9acSAndroid Build Coastguard Worker /*
1020*1c60b9acSAndroid Build Coastguard Worker * We always issue kty, others may be
1021*1c60b9acSAndroid Build Coastguard Worker *
1022*1c60b9acSAndroid Build Coastguard Worker * KID / ALG / KEY_OPS / BASE_IV
1023*1c60b9acSAndroid Build Coastguard Worker */
1024*1c60b9acSAndroid Build Coastguard Worker
1025*1c60b9acSAndroid Build Coastguard Worker if (ck->meta[COSEKEY_META_KID].buf)
1026*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[0]++;
1027*1c60b9acSAndroid Build Coastguard Worker if (ck->meta[COSEKEY_META_ALG].buf)
1028*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[0]++;
1029*1c60b9acSAndroid Build Coastguard Worker if (ck->meta[COSEKEY_META_KEY_OPS].buf)
1030*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[0]++;
1031*1c60b9acSAndroid Build Coastguard Worker if (ck->meta[COSEKEY_META_BASE_IV].buf)
1032*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[0]++;
1033*1c60b9acSAndroid Build Coastguard Worker
1034*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(ctx, LWS_CBOR_MAJTYP_MAP, 0, (uint64_t)ctx->opaque[0]);
1035*1c60b9acSAndroid Build Coastguard Worker lws_lec_signed(ctx, LWSCOSE_WKK_KTY);
1036*1c60b9acSAndroid Build Coastguard Worker lws_lec_signed(ctx, (int64_t)ck->kty);
1037*1c60b9acSAndroid Build Coastguard Worker
1038*1c60b9acSAndroid Build Coastguard Worker if (ck->gencrypto_kty == LWS_GENCRYPTO_KTY_EC) {
1039*1c60b9acSAndroid Build Coastguard Worker struct lws_gencrypto_keyelem *ke =
1040*1c60b9acSAndroid Build Coastguard Worker &ck->e[LWS_GENCRYPTO_EC_KEYEL_CRV];
1041*1c60b9acSAndroid Build Coastguard Worker
1042*1c60b9acSAndroid Build Coastguard Worker if (!ke->buf ||
1043*1c60b9acSAndroid Build Coastguard Worker ck->e[LWS_GENCRYPTO_EC_KEYEL_CRV].len > 10) {
1044*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: no curve type\n", __func__);
1045*1c60b9acSAndroid Build Coastguard Worker goto fail;
1046*1c60b9acSAndroid Build Coastguard Worker }
1047*1c60b9acSAndroid Build Coastguard Worker
1048*1c60b9acSAndroid Build Coastguard Worker pa = lws_cose_curve_name_to_id((const char *)ke->buf);
1049*1c60b9acSAndroid Build Coastguard Worker lws_lec_signed(ctx, LWSCOSE_WKECKP_CRV);
1050*1c60b9acSAndroid Build Coastguard Worker if (pa)
1051*1c60b9acSAndroid Build Coastguard Worker lws_lec_signed(ctx, pa);
1052*1c60b9acSAndroid Build Coastguard Worker else
1053*1c60b9acSAndroid Build Coastguard Worker lws_lec_printf(ctx, "%.*s",
1054*1c60b9acSAndroid Build Coastguard Worker (int)ke->len, ke->buf);
1055*1c60b9acSAndroid Build Coastguard Worker }
1056*1c60b9acSAndroid Build Coastguard Worker
1057*1c60b9acSAndroid Build Coastguard Worker
1058*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[1] = COSEKEY_META_KID;
1059*1c60b9acSAndroid Build Coastguard Worker }
1060*1c60b9acSAndroid Build Coastguard Worker
1061*1c60b9acSAndroid Build Coastguard Worker /*
1062*1c60b9acSAndroid Build Coastguard Worker * Start from the second key meta, then do any elements that are set
1063*1c60b9acSAndroid Build Coastguard Worker */
1064*1c60b9acSAndroid Build Coastguard Worker
1065*1c60b9acSAndroid Build Coastguard Worker while (ctx->buf != ctx->end) {
1066*1c60b9acSAndroid Build Coastguard Worker struct lws_gencrypto_keyelem *ke = NULL;
1067*1c60b9acSAndroid Build Coastguard Worker int cose_key_param = 0;
1068*1c60b9acSAndroid Build Coastguard Worker
1069*1c60b9acSAndroid Build Coastguard Worker if (lws_lec_scratch(ctx))
1070*1c60b9acSAndroid Build Coastguard Worker break;
1071*1c60b9acSAndroid Build Coastguard Worker
1072*1c60b9acSAndroid Build Coastguard Worker if (ctx->opaque[1] == LWS_ARRAY_SIZE(ck->e) +
1073*1c60b9acSAndroid Build Coastguard Worker LWS_COUNT_COSE_KEY_ELEMENTS)
1074*1c60b9acSAndroid Build Coastguard Worker break;
1075*1c60b9acSAndroid Build Coastguard Worker
1076*1c60b9acSAndroid Build Coastguard Worker if (ctx->opaque[1] >= LWS_COUNT_COSE_KEY_ELEMENTS) {
1077*1c60b9acSAndroid Build Coastguard Worker n = ctx->opaque[1] - LWS_COUNT_COSE_KEY_ELEMENTS;
1078*1c60b9acSAndroid Build Coastguard Worker
1079*1c60b9acSAndroid Build Coastguard Worker if (ck->gencrypto_kty != LWS_GENCRYPTO_KTY_EC ||
1080*1c60b9acSAndroid Build Coastguard Worker n != LWS_GENCRYPTO_EC_KEYEL_CRV) {
1081*1c60b9acSAndroid Build Coastguard Worker /* we didn't already encode his curve */
1082*1c60b9acSAndroid Build Coastguard Worker
1083*1c60b9acSAndroid Build Coastguard Worker if ((ctx->opaque[2] & (1 << n)) &&
1084*1c60b9acSAndroid Build Coastguard Worker ck->e[n].buf && ck->e[n].len) {
1085*1c60b9acSAndroid Build Coastguard Worker ke = &ck->e[n];
1086*1c60b9acSAndroid Build Coastguard Worker cose_key_param = ckp[ck->gencrypto_kty - 1][n];
1087*1c60b9acSAndroid Build Coastguard Worker }
1088*1c60b9acSAndroid Build Coastguard Worker }
1089*1c60b9acSAndroid Build Coastguard Worker } else
1090*1c60b9acSAndroid Build Coastguard Worker
1091*1c60b9acSAndroid Build Coastguard Worker switch (ctx->opaque[1]) {
1092*1c60b9acSAndroid Build Coastguard Worker
1093*1c60b9acSAndroid Build Coastguard Worker case COSEKEY_META_KID: /* bstr */
1094*1c60b9acSAndroid Build Coastguard Worker if (ck->meta[COSEKEY_META_KID].buf) {
1095*1c60b9acSAndroid Build Coastguard Worker ke = &ck->meta[COSEKEY_META_KID];
1096*1c60b9acSAndroid Build Coastguard Worker cose_key_param = LWSCOSE_WKK_KID;
1097*1c60b9acSAndroid Build Coastguard Worker // lwsl_hexdump_notice(ke->buf, ke->len);
1098*1c60b9acSAndroid Build Coastguard Worker }
1099*1c60b9acSAndroid Build Coastguard Worker break;
1100*1c60b9acSAndroid Build Coastguard Worker
1101*1c60b9acSAndroid Build Coastguard Worker case COSEKEY_META_ALG: /* int, tstr */
1102*1c60b9acSAndroid Build Coastguard Worker if (ck->meta[COSEKEY_META_ALG].buf) {
1103*1c60b9acSAndroid Build Coastguard Worker ke = &ck->meta[COSEKEY_META_ALG];
1104*1c60b9acSAndroid Build Coastguard Worker cose_key_param = LWSCOSE_WKK_ALG;
1105*1c60b9acSAndroid Build Coastguard Worker }
1106*1c60b9acSAndroid Build Coastguard Worker break;
1107*1c60b9acSAndroid Build Coastguard Worker
1108*1c60b9acSAndroid Build Coastguard Worker case COSEKEY_META_KEY_OPS: /* [ int ] */
1109*1c60b9acSAndroid Build Coastguard Worker if (!ck->meta[COSEKEY_META_KEY_OPS].buf)
1110*1c60b9acSAndroid Build Coastguard Worker break;
1111*1c60b9acSAndroid Build Coastguard Worker ke = &ck->meta[COSEKEY_META_KEY_OPS];
1112*1c60b9acSAndroid Build Coastguard Worker
1113*1c60b9acSAndroid Build Coastguard Worker n = (int)ke->len;
1114*1c60b9acSAndroid Build Coastguard Worker if (n > 10)
1115*1c60b9acSAndroid Build Coastguard Worker n = 10;
1116*1c60b9acSAndroid Build Coastguard Worker
1117*1c60b9acSAndroid Build Coastguard Worker /*
1118*1c60b9acSAndroid Build Coastguard Worker * We copy this array into scratch by hand now we
1119*1c60b9acSAndroid Build Coastguard Worker * made sure it will fit, we will never need AGAIN
1120*1c60b9acSAndroid Build Coastguard Worker */
1121*1c60b9acSAndroid Build Coastguard Worker
1122*1c60b9acSAndroid Build Coastguard Worker lws_lec_signed(ctx, LWSCOSE_WKK_KEY_OPS);
1123*1c60b9acSAndroid Build Coastguard Worker lws_lec_int(ctx, LWS_CBOR_MAJTYP_ARRAY, 0, (uint64_t)n);
1124*1c60b9acSAndroid Build Coastguard Worker memcpy(&ctx->scratch[ctx->scratch_len], ke->buf,
1125*1c60b9acSAndroid Build Coastguard Worker (size_t)n);
1126*1c60b9acSAndroid Build Coastguard Worker ctx->scratch_len = (uint8_t)(ctx->scratch_len + (uint8_t)n);
1127*1c60b9acSAndroid Build Coastguard Worker ke = NULL;
1128*1c60b9acSAndroid Build Coastguard Worker break;
1129*1c60b9acSAndroid Build Coastguard Worker
1130*1c60b9acSAndroid Build Coastguard Worker case COSEKEY_META_BASE_IV: /* bstr */
1131*1c60b9acSAndroid Build Coastguard Worker if (ck->meta[COSEKEY_META_BASE_IV].buf) {
1132*1c60b9acSAndroid Build Coastguard Worker ke = &ck->meta[COSEKEY_META_BASE_IV];
1133*1c60b9acSAndroid Build Coastguard Worker cose_key_param = LWSCOSE_WKK_BASE_IV;
1134*1c60b9acSAndroid Build Coastguard Worker }
1135*1c60b9acSAndroid Build Coastguard Worker break;
1136*1c60b9acSAndroid Build Coastguard Worker
1137*1c60b9acSAndroid Build Coastguard Worker default:
1138*1c60b9acSAndroid Build Coastguard Worker break;
1139*1c60b9acSAndroid Build Coastguard Worker }
1140*1c60b9acSAndroid Build Coastguard Worker
1141*1c60b9acSAndroid Build Coastguard Worker if (ke && ke->buf && ke->len) {
1142*1c60b9acSAndroid Build Coastguard Worker
1143*1c60b9acSAndroid Build Coastguard Worker if (!ctx->opaque[3])
1144*1c60b9acSAndroid Build Coastguard Worker lws_lec_signed(ctx, cose_key_param);
1145*1c60b9acSAndroid Build Coastguard Worker
1146*1c60b9acSAndroid Build Coastguard Worker /* binary string or text string? */
1147*1c60b9acSAndroid Build Coastguard Worker if (ctx->opaque[1] == COSEKEY_META_KID ||
1148*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[1] == COSEKEY_META_BASE_IV ||
1149*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[1] >= LWS_COUNT_COSE_KEY_ELEMENTS)
1150*1c60b9acSAndroid Build Coastguard Worker n = (int)lws_lec_printf(ctx, "%.*b",
1151*1c60b9acSAndroid Build Coastguard Worker (int)ke->len, ke->buf);
1152*1c60b9acSAndroid Build Coastguard Worker else
1153*1c60b9acSAndroid Build Coastguard Worker n = (int)lws_lec_printf(ctx, "%.*s",
1154*1c60b9acSAndroid Build Coastguard Worker (int)ke->len, ke->buf);
1155*1c60b9acSAndroid Build Coastguard Worker
1156*1c60b9acSAndroid Build Coastguard Worker switch (n) {
1157*1c60b9acSAndroid Build Coastguard Worker case LWS_LECPCTX_RET_AGAIN:
1158*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[3] = 1;
1159*1c60b9acSAndroid Build Coastguard Worker /* dump what we have and come back */
1160*1c60b9acSAndroid Build Coastguard Worker continue;
1161*1c60b9acSAndroid Build Coastguard Worker case LWS_LECPCTX_RET_FAIL:
1162*1c60b9acSAndroid Build Coastguard Worker goto fail;
1163*1c60b9acSAndroid Build Coastguard Worker case LWS_LECPCTX_RET_FINISHED:
1164*1c60b9acSAndroid Build Coastguard Worker break;
1165*1c60b9acSAndroid Build Coastguard Worker }
1166*1c60b9acSAndroid Build Coastguard Worker }
1167*1c60b9acSAndroid Build Coastguard Worker
1168*1c60b9acSAndroid Build Coastguard Worker /* move on if we finished that guy */
1169*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[1]++;
1170*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[3] = 0;
1171*1c60b9acSAndroid Build Coastguard Worker }
1172*1c60b9acSAndroid Build Coastguard Worker
1173*1c60b9acSAndroid Build Coastguard Worker ctx->used = lws_ptr_diff_size_t(ctx->buf, ctx->start);
1174*1c60b9acSAndroid Build Coastguard Worker
1175*1c60b9acSAndroid Build Coastguard Worker if (ctx->buf == ctx->end || ctx->scratch_len)
1176*1c60b9acSAndroid Build Coastguard Worker return LWS_LECPCTX_RET_AGAIN;
1177*1c60b9acSAndroid Build Coastguard Worker
1178*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[0] = 0;
1179*1c60b9acSAndroid Build Coastguard Worker
1180*1c60b9acSAndroid Build Coastguard Worker return LWS_LECPCTX_RET_FINISHED;
1181*1c60b9acSAndroid Build Coastguard Worker
1182*1c60b9acSAndroid Build Coastguard Worker fail:
1183*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: failed\n", __func__);
1184*1c60b9acSAndroid Build Coastguard Worker
1185*1c60b9acSAndroid Build Coastguard Worker ctx->opaque[0] = 0;
1186*1c60b9acSAndroid Build Coastguard Worker
1187*1c60b9acSAndroid Build Coastguard Worker return LWS_LECPCTX_RET_FAIL;
1188*1c60b9acSAndroid Build Coastguard Worker }
1189