1*1c60b9acSAndroid Build Coastguard Worker /*
2*1c60b9acSAndroid Build Coastguard Worker * lws-minimal-crypto-cose-sign
3*1c60b9acSAndroid Build Coastguard Worker *
4*1c60b9acSAndroid Build Coastguard Worker * Written in 2010-2021 by Andy Green <[email protected]>
5*1c60b9acSAndroid Build Coastguard Worker *
6*1c60b9acSAndroid Build Coastguard Worker * This file is made available under the Creative Commons CC0 1.0
7*1c60b9acSAndroid Build Coastguard Worker * Universal Public Domain Dedication.
8*1c60b9acSAndroid Build Coastguard Worker */
9*1c60b9acSAndroid Build Coastguard Worker
10*1c60b9acSAndroid Build Coastguard Worker #include <libwebsockets.h>
11*1c60b9acSAndroid Build Coastguard Worker #include <sys/types.h>
12*1c60b9acSAndroid Build Coastguard Worker #include <fcntl.h>
13*1c60b9acSAndroid Build Coastguard Worker
14*1c60b9acSAndroid Build Coastguard Worker static int fdin = 0, fdout = 1;
15*1c60b9acSAndroid Build Coastguard Worker static uint8_t extra[4096];
16*1c60b9acSAndroid Build Coastguard Worker static size_t ext_len;
17*1c60b9acSAndroid Build Coastguard Worker
18*1c60b9acSAndroid Build Coastguard Worker int
_alloc_file(struct lws_context * context,const char * filename,uint8_t ** buf,size_t * amount)19*1c60b9acSAndroid Build Coastguard Worker _alloc_file(struct lws_context *context, const char *filename, uint8_t **buf,
20*1c60b9acSAndroid Build Coastguard Worker size_t *amount)
21*1c60b9acSAndroid Build Coastguard Worker {
22*1c60b9acSAndroid Build Coastguard Worker FILE *f;
23*1c60b9acSAndroid Build Coastguard Worker size_t s;
24*1c60b9acSAndroid Build Coastguard Worker ssize_t m;
25*1c60b9acSAndroid Build Coastguard Worker int n = 0;
26*1c60b9acSAndroid Build Coastguard Worker
27*1c60b9acSAndroid Build Coastguard Worker f = fopen(filename, "rb");
28*1c60b9acSAndroid Build Coastguard Worker if (f == NULL) {
29*1c60b9acSAndroid Build Coastguard Worker n = 1;
30*1c60b9acSAndroid Build Coastguard Worker goto bail;
31*1c60b9acSAndroid Build Coastguard Worker }
32*1c60b9acSAndroid Build Coastguard Worker
33*1c60b9acSAndroid Build Coastguard Worker if (fseek(f, 0, SEEK_END) != 0) {
34*1c60b9acSAndroid Build Coastguard Worker n = 1;
35*1c60b9acSAndroid Build Coastguard Worker goto bail;
36*1c60b9acSAndroid Build Coastguard Worker }
37*1c60b9acSAndroid Build Coastguard Worker
38*1c60b9acSAndroid Build Coastguard Worker m = ftell(f);
39*1c60b9acSAndroid Build Coastguard Worker if (m == -1l) {
40*1c60b9acSAndroid Build Coastguard Worker n = 1;
41*1c60b9acSAndroid Build Coastguard Worker goto bail;
42*1c60b9acSAndroid Build Coastguard Worker }
43*1c60b9acSAndroid Build Coastguard Worker s = (size_t)m;
44*1c60b9acSAndroid Build Coastguard Worker
45*1c60b9acSAndroid Build Coastguard Worker if (fseek(f, 0, SEEK_SET) != 0) {
46*1c60b9acSAndroid Build Coastguard Worker n = 1;
47*1c60b9acSAndroid Build Coastguard Worker goto bail;
48*1c60b9acSAndroid Build Coastguard Worker }
49*1c60b9acSAndroid Build Coastguard Worker
50*1c60b9acSAndroid Build Coastguard Worker *buf = malloc(s + 1);
51*1c60b9acSAndroid Build Coastguard Worker if (!*buf) {
52*1c60b9acSAndroid Build Coastguard Worker n = 2;
53*1c60b9acSAndroid Build Coastguard Worker goto bail;
54*1c60b9acSAndroid Build Coastguard Worker }
55*1c60b9acSAndroid Build Coastguard Worker
56*1c60b9acSAndroid Build Coastguard Worker if (fread(*buf, s, 1, f) != 1) {
57*1c60b9acSAndroid Build Coastguard Worker free(*buf);
58*1c60b9acSAndroid Build Coastguard Worker n = 1;
59*1c60b9acSAndroid Build Coastguard Worker goto bail;
60*1c60b9acSAndroid Build Coastguard Worker }
61*1c60b9acSAndroid Build Coastguard Worker
62*1c60b9acSAndroid Build Coastguard Worker *amount = s;
63*1c60b9acSAndroid Build Coastguard Worker
64*1c60b9acSAndroid Build Coastguard Worker bail:
65*1c60b9acSAndroid Build Coastguard Worker if (f)
66*1c60b9acSAndroid Build Coastguard Worker fclose(f);
67*1c60b9acSAndroid Build Coastguard Worker
68*1c60b9acSAndroid Build Coastguard Worker return n;
69*1c60b9acSAndroid Build Coastguard Worker
70*1c60b9acSAndroid Build Coastguard Worker }
71*1c60b9acSAndroid Build Coastguard Worker
72*1c60b9acSAndroid Build Coastguard Worker static int
extra_cb(lws_cose_sig_ext_pay_t * x)73*1c60b9acSAndroid Build Coastguard Worker extra_cb(lws_cose_sig_ext_pay_t *x)
74*1c60b9acSAndroid Build Coastguard Worker {
75*1c60b9acSAndroid Build Coastguard Worker x->ext = extra;
76*1c60b9acSAndroid Build Coastguard Worker x->xl = ext_len;
77*1c60b9acSAndroid Build Coastguard Worker
78*1c60b9acSAndroid Build Coastguard Worker // lwsl_hexdump_notice(extra, ext_len);
79*1c60b9acSAndroid Build Coastguard Worker
80*1c60b9acSAndroid Build Coastguard Worker return 0;
81*1c60b9acSAndroid Build Coastguard Worker }
82*1c60b9acSAndroid Build Coastguard Worker
83*1c60b9acSAndroid Build Coastguard Worker int
pay_cb(struct lws_cose_validate_context * cps,void * opaque,const uint8_t * paychunk,size_t paychunk_len)84*1c60b9acSAndroid Build Coastguard Worker pay_cb(struct lws_cose_validate_context *cps, void *opaque,
85*1c60b9acSAndroid Build Coastguard Worker const uint8_t *paychunk, size_t paychunk_len)
86*1c60b9acSAndroid Build Coastguard Worker {
87*1c60b9acSAndroid Build Coastguard Worker write(fdout, paychunk, paychunk_len);
88*1c60b9acSAndroid Build Coastguard Worker
89*1c60b9acSAndroid Build Coastguard Worker return 0;
90*1c60b9acSAndroid Build Coastguard Worker }
91*1c60b9acSAndroid Build Coastguard Worker
main(int argc,const char ** argv)92*1c60b9acSAndroid Build Coastguard Worker int main(int argc, const char **argv)
93*1c60b9acSAndroid Build Coastguard Worker {
94*1c60b9acSAndroid Build Coastguard Worker uint8_t *ks, temp[256], *kid = NULL, ktmp[4096], sbuf[512];
95*1c60b9acSAndroid Build Coastguard Worker int n, m, sign = 0, result = 1,
96*1c60b9acSAndroid Build Coastguard Worker logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
97*1c60b9acSAndroid Build Coastguard Worker enum lws_cose_sig_types sigtype = SIGTYPE_UNKNOWN;
98*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_validate_context *cps = NULL;
99*1c60b9acSAndroid Build Coastguard Worker struct lws_cose_sign_context *csc = NULL;
100*1c60b9acSAndroid Build Coastguard Worker const struct lws_gencrypto_keyelem *ke;
101*1c60b9acSAndroid Build Coastguard Worker struct lws_context_creation_info info;
102*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_create_info_t vi;
103*1c60b9acSAndroid Build Coastguard Worker struct lws_buflist *paybuf = NULL;
104*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_create_info_t i;
105*1c60b9acSAndroid Build Coastguard Worker struct lws_context *context;
106*1c60b9acSAndroid Build Coastguard Worker size_t ks_len, kid_len = 0;
107*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_t *ck = NULL;
108*1c60b9acSAndroid Build Coastguard Worker lws_dll2_owner_t *o, set;
109*1c60b9acSAndroid Build Coastguard Worker lws_lec_pctx_t lec;
110*1c60b9acSAndroid Build Coastguard Worker cose_param_t alg;
111*1c60b9acSAndroid Build Coastguard Worker const char *p;
112*1c60b9acSAndroid Build Coastguard Worker
113*1c60b9acSAndroid Build Coastguard Worker if ((p = lws_cmdline_option(argc, argv, "-d")))
114*1c60b9acSAndroid Build Coastguard Worker logs = atoi(p);
115*1c60b9acSAndroid Build Coastguard Worker
116*1c60b9acSAndroid Build Coastguard Worker lws_set_log_level(logs, NULL);
117*1c60b9acSAndroid Build Coastguard Worker
118*1c60b9acSAndroid Build Coastguard Worker lwsl_user("LWS cose-sign example tool -k keyset [-s alg-name kid ]\n");
119*1c60b9acSAndroid Build Coastguard Worker
120*1c60b9acSAndroid Build Coastguard Worker memset(&info, 0, sizeof info); /* otherwise uninitialized garbage */
121*1c60b9acSAndroid Build Coastguard Worker #if defined(LWS_WITH_NETWORK)
122*1c60b9acSAndroid Build Coastguard Worker info.port = CONTEXT_PORT_NO_LISTEN;
123*1c60b9acSAndroid Build Coastguard Worker #endif
124*1c60b9acSAndroid Build Coastguard Worker
125*1c60b9acSAndroid Build Coastguard Worker context = lws_create_context(&info);
126*1c60b9acSAndroid Build Coastguard Worker if (!context) {
127*1c60b9acSAndroid Build Coastguard Worker lwsl_err("lws init failed\n");
128*1c60b9acSAndroid Build Coastguard Worker return 1;
129*1c60b9acSAndroid Build Coastguard Worker }
130*1c60b9acSAndroid Build Coastguard Worker
131*1c60b9acSAndroid Build Coastguard Worker if ((p = lws_cmdline_option(argc, argv, "--stdin"))) {
132*1c60b9acSAndroid Build Coastguard Worker fdin = open(p, LWS_O_RDONLY, 0);
133*1c60b9acSAndroid Build Coastguard Worker if (fdin < 0) {
134*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: unable to open stdin file\n", __func__);
135*1c60b9acSAndroid Build Coastguard Worker return 1;
136*1c60b9acSAndroid Build Coastguard Worker }
137*1c60b9acSAndroid Build Coastguard Worker }
138*1c60b9acSAndroid Build Coastguard Worker
139*1c60b9acSAndroid Build Coastguard Worker if ((p = lws_cmdline_option(argc, argv, "--stdout"))) {
140*1c60b9acSAndroid Build Coastguard Worker fdout = open(p, LWS_O_WRONLY | LWS_O_CREAT | LWS_O_TRUNC, 0600);
141*1c60b9acSAndroid Build Coastguard Worker if (fdout < 0) {
142*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: unable to open stdout file\n", __func__);
143*1c60b9acSAndroid Build Coastguard Worker goto bail_early;
144*1c60b9acSAndroid Build Coastguard Worker }
145*1c60b9acSAndroid Build Coastguard Worker }
146*1c60b9acSAndroid Build Coastguard Worker
147*1c60b9acSAndroid Build Coastguard Worker /*
148*1c60b9acSAndroid Build Coastguard Worker * If no tag, you can tell it the signature type, otherwise it will
149*1c60b9acSAndroid Build Coastguard Worker * use the tag to select the right type without these
150*1c60b9acSAndroid Build Coastguard Worker */
151*1c60b9acSAndroid Build Coastguard Worker
152*1c60b9acSAndroid Build Coastguard Worker if (lws_cmdline_option(argc, argv, "--cose-sign"))
153*1c60b9acSAndroid Build Coastguard Worker sigtype = SIGTYPE_MULTI;
154*1c60b9acSAndroid Build Coastguard Worker
155*1c60b9acSAndroid Build Coastguard Worker if (lws_cmdline_option(argc, argv, "--cose-sign1"))
156*1c60b9acSAndroid Build Coastguard Worker sigtype = SIGTYPE_SINGLE;
157*1c60b9acSAndroid Build Coastguard Worker
158*1c60b9acSAndroid Build Coastguard Worker if (lws_cmdline_option(argc, argv, "--cose-mac"))
159*1c60b9acSAndroid Build Coastguard Worker sigtype = SIGTYPE_MAC;
160*1c60b9acSAndroid Build Coastguard Worker
161*1c60b9acSAndroid Build Coastguard Worker if (lws_cmdline_option(argc, argv, "--cose-mac0"))
162*1c60b9acSAndroid Build Coastguard Worker sigtype = SIGTYPE_MAC0;
163*1c60b9acSAndroid Build Coastguard Worker
164*1c60b9acSAndroid Build Coastguard Worker /* if signing, set the ciphers */
165*1c60b9acSAndroid Build Coastguard Worker
166*1c60b9acSAndroid Build Coastguard Worker if (lws_cmdline_option(argc, argv, "-s"))
167*1c60b9acSAndroid Build Coastguard Worker sign = 1;
168*1c60b9acSAndroid Build Coastguard Worker
169*1c60b9acSAndroid Build Coastguard Worker if ((p = lws_cmdline_option(argc, argv, "--kid"))) {
170*1c60b9acSAndroid Build Coastguard Worker kid = (uint8_t *)p;
171*1c60b9acSAndroid Build Coastguard Worker kid_len = strlen(p);
172*1c60b9acSAndroid Build Coastguard Worker //lwsl_hexdump_notice(kid, kid_len);
173*1c60b9acSAndroid Build Coastguard Worker }
174*1c60b9acSAndroid Build Coastguard Worker
175*1c60b9acSAndroid Build Coastguard Worker if ((p = lws_cmdline_option(argc, argv, "--kid-hex"))) {
176*1c60b9acSAndroid Build Coastguard Worker kid_len = (size_t)lws_hex_to_byte_array(p, ktmp, sizeof(ktmp));
177*1c60b9acSAndroid Build Coastguard Worker kid = (uint8_t *)ktmp;
178*1c60b9acSAndroid Build Coastguard Worker }
179*1c60b9acSAndroid Build Coastguard Worker
180*1c60b9acSAndroid Build Coastguard Worker if ((p = lws_cmdline_option(argc, argv, "--extra"))) {
181*1c60b9acSAndroid Build Coastguard Worker ext_len = (size_t)lws_hex_to_byte_array(p, extra, sizeof(extra));
182*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%llu\n", (unsigned long long)ext_len);
183*1c60b9acSAndroid Build Coastguard Worker if (ext_len == (size_t)-1ll)
184*1c60b9acSAndroid Build Coastguard Worker ext_len = 0;
185*1c60b9acSAndroid Build Coastguard Worker }
186*1c60b9acSAndroid Build Coastguard Worker
187*1c60b9acSAndroid Build Coastguard Worker /* grab the key */
188*1c60b9acSAndroid Build Coastguard Worker
189*1c60b9acSAndroid Build Coastguard Worker if (!(p = lws_cmdline_option(argc, argv, "-k"))) {
190*1c60b9acSAndroid Build Coastguard Worker lwsl_err("-k <key set file> is required\n");
191*1c60b9acSAndroid Build Coastguard Worker goto bail;
192*1c60b9acSAndroid Build Coastguard Worker }
193*1c60b9acSAndroid Build Coastguard Worker
194*1c60b9acSAndroid Build Coastguard Worker if (_alloc_file(context, p, &ks, &ks_len)) {
195*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: unable to load %s\n", __func__, p);
196*1c60b9acSAndroid Build Coastguard Worker goto bail;
197*1c60b9acSAndroid Build Coastguard Worker }
198*1c60b9acSAndroid Build Coastguard Worker
199*1c60b9acSAndroid Build Coastguard Worker lws_dll2_owner_clear(&set);
200*1c60b9acSAndroid Build Coastguard Worker if (!lws_cose_key_import(&set, NULL, NULL, ks, ks_len)) {
201*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: key import fail\n", __func__);
202*1c60b9acSAndroid Build Coastguard Worker free(ks);
203*1c60b9acSAndroid Build Coastguard Worker goto bail2;
204*1c60b9acSAndroid Build Coastguard Worker }
205*1c60b9acSAndroid Build Coastguard Worker
206*1c60b9acSAndroid Build Coastguard Worker free(ks);
207*1c60b9acSAndroid Build Coastguard Worker
208*1c60b9acSAndroid Build Coastguard Worker if (!fdin) {
209*1c60b9acSAndroid Build Coastguard Worker struct timeval timeout;
210*1c60b9acSAndroid Build Coastguard Worker fd_set fds;
211*1c60b9acSAndroid Build Coastguard Worker
212*1c60b9acSAndroid Build Coastguard Worker FD_ZERO(&fds);
213*1c60b9acSAndroid Build Coastguard Worker FD_SET(0, &fds);
214*1c60b9acSAndroid Build Coastguard Worker
215*1c60b9acSAndroid Build Coastguard Worker timeout.tv_sec = 0;
216*1c60b9acSAndroid Build Coastguard Worker timeout.tv_usec = 1000;
217*1c60b9acSAndroid Build Coastguard Worker
218*1c60b9acSAndroid Build Coastguard Worker if (select(fdin + 1, &fds, NULL, NULL, &timeout) < 0 ||
219*1c60b9acSAndroid Build Coastguard Worker !FD_ISSET(0, &fds)) {
220*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: pass cose_sign or plaintext "
221*1c60b9acSAndroid Build Coastguard Worker "on stdin or --stdin\n", __func__);
222*1c60b9acSAndroid Build Coastguard Worker goto bail2;
223*1c60b9acSAndroid Build Coastguard Worker }
224*1c60b9acSAndroid Build Coastguard Worker }
225*1c60b9acSAndroid Build Coastguard Worker
226*1c60b9acSAndroid Build Coastguard Worker if (sign) {
227*1c60b9acSAndroid Build Coastguard Worker uint8_t *ppay;
228*1c60b9acSAndroid Build Coastguard Worker size_t s;
229*1c60b9acSAndroid Build Coastguard Worker
230*1c60b9acSAndroid Build Coastguard Worker p = lws_cmdline_option(argc, argv, "--alg");
231*1c60b9acSAndroid Build Coastguard Worker if (!p) {
232*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: need to specify alg (eg, ES256) "
233*1c60b9acSAndroid Build Coastguard Worker "when signing\n", __func__);
234*1c60b9acSAndroid Build Coastguard Worker goto bail2;
235*1c60b9acSAndroid Build Coastguard Worker }
236*1c60b9acSAndroid Build Coastguard Worker alg = lws_cose_name_to_alg(p);
237*1c60b9acSAndroid Build Coastguard Worker
238*1c60b9acSAndroid Build Coastguard Worker lws_lec_init(&lec, sbuf, sizeof(sbuf));
239*1c60b9acSAndroid Build Coastguard Worker memset(&i, 0, sizeof(i));
240*1c60b9acSAndroid Build Coastguard Worker i.cx = context;
241*1c60b9acSAndroid Build Coastguard Worker i.keyset = &set;
242*1c60b9acSAndroid Build Coastguard Worker i.lec = &lec;
243*1c60b9acSAndroid Build Coastguard Worker i.flags = LCSC_FL_ADD_CBOR_TAG |
244*1c60b9acSAndroid Build Coastguard Worker LCSC_FL_ADD_CBOR_PREFER_MAC0;
245*1c60b9acSAndroid Build Coastguard Worker i.sigtype = sigtype;
246*1c60b9acSAndroid Build Coastguard Worker
247*1c60b9acSAndroid Build Coastguard Worker /*
248*1c60b9acSAndroid Build Coastguard Worker * Unfortunately, with COSE we must know the payload length
249*1c60b9acSAndroid Build Coastguard Worker * before we have seen the payload. It's illegal to use
250*1c60b9acSAndroid Build Coastguard Worker * indeterminite lengths inside COSE objects.
251*1c60b9acSAndroid Build Coastguard Worker */
252*1c60b9acSAndroid Build Coastguard Worker
253*1c60b9acSAndroid Build Coastguard Worker do {
254*1c60b9acSAndroid Build Coastguard Worker n = (int)read(fdin, temp, sizeof(temp));
255*1c60b9acSAndroid Build Coastguard Worker if (n < 0)
256*1c60b9acSAndroid Build Coastguard Worker goto bail3;
257*1c60b9acSAndroid Build Coastguard Worker if (!n)
258*1c60b9acSAndroid Build Coastguard Worker break;
259*1c60b9acSAndroid Build Coastguard Worker
260*1c60b9acSAndroid Build Coastguard Worker s = (size_t)n;
261*1c60b9acSAndroid Build Coastguard Worker
262*1c60b9acSAndroid Build Coastguard Worker if (lws_buflist_append_segment(&paybuf, temp, s) < 0)
263*1c60b9acSAndroid Build Coastguard Worker goto bail3;
264*1c60b9acSAndroid Build Coastguard Worker i.inline_payload_len += s;
265*1c60b9acSAndroid Build Coastguard Worker
266*1c60b9acSAndroid Build Coastguard Worker } while (1);
267*1c60b9acSAndroid Build Coastguard Worker
268*1c60b9acSAndroid Build Coastguard Worker // lwsl_notice("%s: inline_payload_len %llu\n", __func__,
269*1c60b9acSAndroid Build Coastguard Worker // (unsigned long long)i.inline_payload_len);
270*1c60b9acSAndroid Build Coastguard Worker
271*1c60b9acSAndroid Build Coastguard Worker csc = lws_cose_sign_create(&i);
272*1c60b9acSAndroid Build Coastguard Worker if (!csc)
273*1c60b9acSAndroid Build Coastguard Worker goto bail2;
274*1c60b9acSAndroid Build Coastguard Worker ck = lws_cose_key_from_set(&set, kid, kid_len);
275*1c60b9acSAndroid Build Coastguard Worker if (!ck)
276*1c60b9acSAndroid Build Coastguard Worker goto bail2;
277*1c60b9acSAndroid Build Coastguard Worker
278*1c60b9acSAndroid Build Coastguard Worker if (lws_cose_sign_add(csc, alg, ck))
279*1c60b9acSAndroid Build Coastguard Worker goto bail2;
280*1c60b9acSAndroid Build Coastguard Worker
281*1c60b9acSAndroid Build Coastguard Worker do {
282*1c60b9acSAndroid Build Coastguard Worker s = lws_buflist_next_segment_len(&paybuf, &ppay);
283*1c60b9acSAndroid Build Coastguard Worker if (!s)
284*1c60b9acSAndroid Build Coastguard Worker break;
285*1c60b9acSAndroid Build Coastguard Worker
286*1c60b9acSAndroid Build Coastguard Worker do {
287*1c60b9acSAndroid Build Coastguard Worker m = (int)lws_cose_sign_payload_chunk(csc,
288*1c60b9acSAndroid Build Coastguard Worker ppay, s);
289*1c60b9acSAndroid Build Coastguard Worker if (lec.used) {
290*1c60b9acSAndroid Build Coastguard Worker // lwsl_hexdump_err(sbuf, lec.used);
291*1c60b9acSAndroid Build Coastguard Worker write(fdout, sbuf, lec.used);
292*1c60b9acSAndroid Build Coastguard Worker lws_lec_setbuf(&lec, sbuf, sizeof(sbuf));
293*1c60b9acSAndroid Build Coastguard Worker }
294*1c60b9acSAndroid Build Coastguard Worker } while (m == LCOSESIGEXTCB_RET_AGAIN);
295*1c60b9acSAndroid Build Coastguard Worker
296*1c60b9acSAndroid Build Coastguard Worker if (m == LWS_LECPCTX_RET_FAIL)
297*1c60b9acSAndroid Build Coastguard Worker goto bail2;
298*1c60b9acSAndroid Build Coastguard Worker
299*1c60b9acSAndroid Build Coastguard Worker if (lec.used) {
300*1c60b9acSAndroid Build Coastguard Worker write(fdout, sbuf, lec.used);
301*1c60b9acSAndroid Build Coastguard Worker lws_lec_setbuf(&lec, sbuf, sizeof(sbuf));
302*1c60b9acSAndroid Build Coastguard Worker }
303*1c60b9acSAndroid Build Coastguard Worker
304*1c60b9acSAndroid Build Coastguard Worker lws_buflist_use_segment(&paybuf, s);
305*1c60b9acSAndroid Build Coastguard Worker } while(1);
306*1c60b9acSAndroid Build Coastguard Worker
307*1c60b9acSAndroid Build Coastguard Worker } else {
308*1c60b9acSAndroid Build Coastguard Worker memset(&vi, 0, sizeof(vi));
309*1c60b9acSAndroid Build Coastguard Worker
310*1c60b9acSAndroid Build Coastguard Worker vi.cx = context;
311*1c60b9acSAndroid Build Coastguard Worker vi.keyset = &set;
312*1c60b9acSAndroid Build Coastguard Worker vi.sigtype = sigtype;
313*1c60b9acSAndroid Build Coastguard Worker vi.ext_cb = extra_cb;
314*1c60b9acSAndroid Build Coastguard Worker vi.ext_opaque = extra;
315*1c60b9acSAndroid Build Coastguard Worker vi.ext_len = ext_len;
316*1c60b9acSAndroid Build Coastguard Worker vi.pay_cb = pay_cb;
317*1c60b9acSAndroid Build Coastguard Worker
318*1c60b9acSAndroid Build Coastguard Worker cps = lws_cose_validate_create(&vi);
319*1c60b9acSAndroid Build Coastguard Worker if (!cps) {
320*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: sign_val_create fail\n", __func__);
321*1c60b9acSAndroid Build Coastguard Worker goto bail;
322*1c60b9acSAndroid Build Coastguard Worker }
323*1c60b9acSAndroid Build Coastguard Worker
324*1c60b9acSAndroid Build Coastguard Worker do {
325*1c60b9acSAndroid Build Coastguard Worker n = (int)read(fdin, temp, sizeof(temp));
326*1c60b9acSAndroid Build Coastguard Worker if (n < 0)
327*1c60b9acSAndroid Build Coastguard Worker goto bail3;
328*1c60b9acSAndroid Build Coastguard Worker if (!n)
329*1c60b9acSAndroid Build Coastguard Worker break;
330*1c60b9acSAndroid Build Coastguard Worker
331*1c60b9acSAndroid Build Coastguard Worker n = lws_cose_validate_chunk(cps, temp, (size_t)n, NULL);
332*1c60b9acSAndroid Build Coastguard Worker if (n && n != LECP_CONTINUE) {
333*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: chunk validation failed: %d\n",
334*1c60b9acSAndroid Build Coastguard Worker __func__, n);
335*1c60b9acSAndroid Build Coastguard Worker goto bail2;
336*1c60b9acSAndroid Build Coastguard Worker }
337*1c60b9acSAndroid Build Coastguard Worker } while (1);
338*1c60b9acSAndroid Build Coastguard Worker }
339*1c60b9acSAndroid Build Coastguard Worker
340*1c60b9acSAndroid Build Coastguard Worker bail3:
341*1c60b9acSAndroid Build Coastguard Worker
342*1c60b9acSAndroid Build Coastguard Worker result = 0;
343*1c60b9acSAndroid Build Coastguard Worker
344*1c60b9acSAndroid Build Coastguard Worker if (!sign) {
345*1c60b9acSAndroid Build Coastguard Worker char buf[2048];
346*1c60b9acSAndroid Build Coastguard Worker int os;
347*1c60b9acSAndroid Build Coastguard Worker
348*1c60b9acSAndroid Build Coastguard Worker o = lws_cose_validate_results(cps);
349*1c60b9acSAndroid Build Coastguard Worker if (!o)
350*1c60b9acSAndroid Build Coastguard Worker result = 1;
351*1c60b9acSAndroid Build Coastguard Worker else {
352*1c60b9acSAndroid Build Coastguard Worker os = lws_snprintf(buf, sizeof(buf),
353*1c60b9acSAndroid Build Coastguard Worker "\nresults count %d\n", o->count);
354*1c60b9acSAndroid Build Coastguard Worker write(fdout, buf, (size_t)os);
355*1c60b9acSAndroid Build Coastguard Worker
356*1c60b9acSAndroid Build Coastguard Worker if (!o->count)
357*1c60b9acSAndroid Build Coastguard Worker result = 1;
358*1c60b9acSAndroid Build Coastguard Worker }
359*1c60b9acSAndroid Build Coastguard Worker
360*1c60b9acSAndroid Build Coastguard Worker lws_start_foreach_dll_safe(struct lws_dll2 *, p, tp,
361*1c60b9acSAndroid Build Coastguard Worker lws_dll2_get_head(o)) {
362*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_res_t *res = lws_container_of(p,
363*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_res_t, list);
364*1c60b9acSAndroid Build Coastguard Worker char khr[256];
365*1c60b9acSAndroid Build Coastguard Worker
366*1c60b9acSAndroid Build Coastguard Worker khr[0] = '\0';
367*1c60b9acSAndroid Build Coastguard Worker if (res->cose_key) {
368*1c60b9acSAndroid Build Coastguard Worker ke = &res->cose_key->meta[COSEKEY_META_KID];
369*1c60b9acSAndroid Build Coastguard Worker if (ke && ke->buf)
370*1c60b9acSAndroid Build Coastguard Worker lws_hex_from_byte_array(ke->buf, ke->len,
371*1c60b9acSAndroid Build Coastguard Worker khr, sizeof(khr));
372*1c60b9acSAndroid Build Coastguard Worker }
373*1c60b9acSAndroid Build Coastguard Worker os = lws_snprintf(buf, sizeof(buf),
374*1c60b9acSAndroid Build Coastguard Worker " result: %d (alg %s, kid %s)\n",
375*1c60b9acSAndroid Build Coastguard Worker res->result,
376*1c60b9acSAndroid Build Coastguard Worker lws_cose_alg_to_name(res->cose_alg), khr);
377*1c60b9acSAndroid Build Coastguard Worker write(fdout, buf, (size_t)os);
378*1c60b9acSAndroid Build Coastguard Worker result |= res->result;
379*1c60b9acSAndroid Build Coastguard Worker } lws_end_foreach_dll_safe(p, tp);
380*1c60b9acSAndroid Build Coastguard Worker }
381*1c60b9acSAndroid Build Coastguard Worker
382*1c60b9acSAndroid Build Coastguard Worker bail2:
383*1c60b9acSAndroid Build Coastguard Worker if (!sign)
384*1c60b9acSAndroid Build Coastguard Worker lws_cose_validate_destroy(&cps);
385*1c60b9acSAndroid Build Coastguard Worker else {
386*1c60b9acSAndroid Build Coastguard Worker lws_buflist_destroy_all_segments(&paybuf);
387*1c60b9acSAndroid Build Coastguard Worker lws_cose_sign_destroy(&csc);
388*1c60b9acSAndroid Build Coastguard Worker }
389*1c60b9acSAndroid Build Coastguard Worker //bail1:
390*1c60b9acSAndroid Build Coastguard Worker lws_cose_key_set_destroy(&set);
391*1c60b9acSAndroid Build Coastguard Worker bail:
392*1c60b9acSAndroid Build Coastguard Worker lws_context_destroy(context);
393*1c60b9acSAndroid Build Coastguard Worker
394*1c60b9acSAndroid Build Coastguard Worker if (result)
395*1c60b9acSAndroid Build Coastguard Worker lwsl_err("%s: FAIL: %d\n", __func__, result);
396*1c60b9acSAndroid Build Coastguard Worker else
397*1c60b9acSAndroid Build Coastguard Worker lwsl_notice("%s: PASS\n", __func__);
398*1c60b9acSAndroid Build Coastguard Worker
399*1c60b9acSAndroid Build Coastguard Worker bail_early:
400*1c60b9acSAndroid Build Coastguard Worker if (fdin > 0)
401*1c60b9acSAndroid Build Coastguard Worker close(fdin);
402*1c60b9acSAndroid Build Coastguard Worker if (fdout != 1 && fdout >= 0)
403*1c60b9acSAndroid Build Coastguard Worker close(fdout);
404*1c60b9acSAndroid Build Coastguard Worker
405*1c60b9acSAndroid Build Coastguard Worker return result;
406*1c60b9acSAndroid Build Coastguard Worker }
407