Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2018-2021 Yubico AB. All rights reserved. |
3 | | * Use of this source code is governed by a BSD-style |
4 | | * license that can be found in the LICENSE file. |
5 | | */ |
6 | | |
7 | | #include "fido.h" |
8 | | |
9 | | static int |
10 | | decode_string(const cbor_item_t *item, void *arg) |
11 | 40.4k | { |
12 | 40.4k | fido_str_array_t *a = arg; |
13 | 40.4k | const size_t i = a->len; |
14 | 40.4k | |
15 | 40.4k | /* keep ptr[x] and len consistent */ |
16 | 40.4k | if (cbor_string_copy(item, &a->ptr[i]) < 0) { |
17 | 106 | fido_log_debug("%s: cbor_string_copy", __func__); |
18 | 106 | return (-1); |
19 | 106 | } |
20 | 40.3k | |
21 | 40.3k | a->len++; |
22 | 40.3k | |
23 | 40.3k | return (0); |
24 | 40.3k | } |
25 | | |
26 | | static int |
27 | | decode_string_array(const cbor_item_t *item, fido_str_array_t *v) |
28 | 16.2k | { |
29 | 16.2k | v->ptr = NULL; |
30 | 16.2k | v->len = 0; |
31 | 16.2k | |
32 | 16.2k | if (cbor_isa_array(item) == false || |
33 | 16.2k | cbor_array_is_definite(item) == false) { |
34 | 78 | fido_log_debug("%s: cbor type", __func__); |
35 | 78 | return (-1); |
36 | 78 | } |
37 | 16.2k | |
38 | 16.2k | v->ptr = calloc(cbor_array_size(item), sizeof(char *)); |
39 | 16.2k | if (v->ptr == NULL) |
40 | 16.2k | return (-1); |
41 | 16.1k | |
42 | 16.1k | if (cbor_array_iter(item, v, decode_string) < 0) { |
43 | 121 | fido_log_debug("%s: decode_string", __func__); |
44 | 121 | return (-1); |
45 | 121 | } |
46 | 16.0k | |
47 | 16.0k | return (0); |
48 | 16.0k | } |
49 | | |
50 | | static int |
51 | | decode_aaguid(const cbor_item_t *item, unsigned char *aaguid, size_t aaguid_len) |
52 | 7.50k | { |
53 | 7.50k | if (cbor_isa_bytestring(item) == false || |
54 | 7.50k | cbor_bytestring_is_definite(item) == false || |
55 | 7.50k | cbor_bytestring_length(item) != aaguid_len) { |
56 | 126 | fido_log_debug("%s: cbor type", __func__); |
57 | 126 | return (-1); |
58 | 126 | } |
59 | 7.37k | |
60 | 7.37k | memcpy(aaguid, cbor_bytestring_handle(item), aaguid_len); |
61 | 7.37k | |
62 | 7.37k | return (0); |
63 | 7.37k | } |
64 | | |
65 | | static int |
66 | | decode_option(const cbor_item_t *key, const cbor_item_t *val, void *arg) |
67 | 41.1k | { |
68 | 41.1k | fido_opt_array_t *o = arg; |
69 | 41.1k | const size_t i = o->len; |
70 | 41.1k | |
71 | 41.1k | if (cbor_isa_float_ctrl(val) == false || |
72 | 41.1k | cbor_float_get_width(val) != CBOR_FLOAT_0 || |
73 | 41.1k | cbor_is_bool(val) == false) { |
74 | 2.34k | fido_log_debug("%s: cbor type", __func__); |
75 | 2.34k | return (0); /* ignore */ |
76 | 2.34k | } |
77 | 38.8k | |
78 | 38.8k | if (cbor_string_copy(key, &o->name[i]) < 0) { |
79 | 204 | fido_log_debug("%s: cbor_string_copy", __func__); |
80 | 204 | return (0); /* ignore */ |
81 | 204 | } |
82 | 38.6k | |
83 | 38.6k | /* keep name/value and len consistent */ |
84 | 38.6k | o->value[i] = cbor_ctrl_value(val) == CBOR_CTRL_TRUE; |
85 | 38.6k | o->len++; |
86 | 38.6k | |
87 | 38.6k | return (0); |
88 | 38.6k | } |
89 | | |
90 | | static int |
91 | | decode_options(const cbor_item_t *item, fido_opt_array_t *o) |
92 | 7.22k | { |
93 | 7.22k | o->name = NULL; |
94 | 7.22k | o->value = NULL; |
95 | 7.22k | o->len = 0; |
96 | 7.22k | |
97 | 7.22k | if (cbor_isa_map(item) == false || |
98 | 7.22k | cbor_map_is_definite(item) == false) { |
99 | 41 | fido_log_debug("%s: cbor type", __func__); |
100 | 41 | return (-1); |
101 | 41 | } |
102 | 7.18k | |
103 | 7.18k | o->name = calloc(cbor_map_size(item), sizeof(char *)); |
104 | 7.18k | o->value = calloc(cbor_map_size(item), sizeof(bool)); |
105 | 7.18k | if (o->name == NULL || o->value == NULL) |
106 | 7.18k | return (-1); |
107 | 7.15k | |
108 | 7.15k | return (cbor_map_iter(item, o, decode_option)); |
109 | 7.15k | } |
110 | | |
111 | | static int |
112 | | decode_protocol(const cbor_item_t *item, void *arg) |
113 | 8.98k | { |
114 | 8.98k | fido_byte_array_t *p = arg; |
115 | 8.98k | const size_t i = p->len; |
116 | 8.98k | |
117 | 8.98k | if (cbor_isa_uint(item) == false || |
118 | 8.98k | cbor_int_get_width(item) != CBOR_INT_8) { |
119 | 87 | fido_log_debug("%s: cbor type", __func__); |
120 | 87 | return (-1); |
121 | 87 | } |
122 | 8.89k | |
123 | 8.89k | /* keep ptr[x] and len consistent */ |
124 | 8.89k | p->ptr[i] = cbor_get_uint8(item); |
125 | 8.89k | p->len++; |
126 | 8.89k | |
127 | 8.89k | return (0); |
128 | 8.89k | } |
129 | | |
130 | | static int |
131 | | decode_protocols(const cbor_item_t *item, fido_byte_array_t *p) |
132 | 7.02k | { |
133 | 7.02k | p->ptr = NULL; |
134 | 7.02k | p->len = 0; |
135 | 7.02k | |
136 | 7.02k | if (cbor_isa_array(item) == false || |
137 | 7.02k | cbor_array_is_definite(item) == false) { |
138 | 48 | fido_log_debug("%s: cbor type", __func__); |
139 | 48 | return (-1); |
140 | 48 | } |
141 | 6.97k | |
142 | 6.97k | p->ptr = calloc(cbor_array_size(item), sizeof(uint8_t)); |
143 | 6.97k | if (p->ptr == NULL) |
144 | 6.97k | return (-1); |
145 | 6.96k | |
146 | 6.96k | if (cbor_array_iter(item, p, decode_protocol) < 0) { |
147 | 94 | fido_log_debug("%s: decode_protocol", __func__); |
148 | 94 | return (-1); |
149 | 94 | } |
150 | 6.86k | |
151 | 6.86k | return (0); |
152 | 6.86k | } |
153 | | |
154 | | static int |
155 | | decode_algorithm_entry(const cbor_item_t *key, const cbor_item_t *val, |
156 | | void *arg) |
157 | 19.5k | { |
158 | 19.5k | fido_algo_t *alg = arg; |
159 | 19.5k | char *name = NULL; |
160 | 19.5k | int ok = -1; |
161 | 19.5k | |
162 | 19.5k | if (cbor_string_copy(key, &name) < 0) { |
163 | 127 | fido_log_debug("%s: cbor type", __func__); |
164 | 127 | ok = 0; /* ignore */ |
165 | 127 | goto out; |
166 | 127 | } |
167 | 19.3k | |
168 | 19.3k | if (!strcmp(name, "alg")) { |
169 | 8.75k | if (cbor_isa_negint(val) == false || |
170 | 8.75k | cbor_get_int(val) > INT_MAX || alg->cose != 0) { |
171 | 388 | fido_log_debug("%s: alg", __func__); |
172 | 388 | goto out; |
173 | 388 | } |
174 | 8.37k | alg->cose = -(int)cbor_get_int(val) - 1; |
175 | 10.6k | } else if (!strcmp(name, "type")) { |
176 | 7.30k | if (cbor_string_copy(val, &alg->type) < 0) { |
177 | 32 | fido_log_debug("%s: type", __func__); |
178 | 32 | goto out; |
179 | 32 | } |
180 | 18.9k | } |
181 | 18.9k | |
182 | 18.9k | ok = 0; |
183 | 19.5k | out: |
184 | 19.5k | free(name); |
185 | 19.5k | |
186 | 19.5k | return (ok); |
187 | 18.9k | } |
188 | | |
189 | | static void |
190 | | free_algo(fido_algo_t *a) |
191 | 10.3k | { |
192 | 10.3k | free(a->type); |
193 | 10.3k | a->type = NULL; |
194 | 10.3k | a->cose = 0; |
195 | 10.3k | } |
196 | | |
197 | | static int |
198 | | decode_algorithm(const cbor_item_t *item, void *arg) |
199 | 10.4k | { |
200 | 10.4k | fido_algo_array_t *aa = arg; |
201 | 10.4k | const size_t i = aa->len; |
202 | 10.4k | |
203 | 10.4k | if (cbor_isa_map(item) == false || |
204 | 10.4k | cbor_map_is_definite(item) == false) { |
205 | 112 | fido_log_debug("%s: cbor type", __func__); |
206 | 112 | return (-1); |
207 | 112 | } |
208 | 10.3k | |
209 | 10.3k | memset(&aa->ptr[i], 0, sizeof(aa->ptr[i])); |
210 | 10.3k | |
211 | 10.3k | if (cbor_map_iter(item, &aa->ptr[i], decode_algorithm_entry) < 0) { |
212 | 655 | fido_log_debug("%s: decode_algorithm_entry", __func__); |
213 | 655 | free_algo(&aa->ptr[i]); |
214 | 655 | return (-1); |
215 | 655 | } |
216 | 9.66k | |
217 | 9.66k | /* keep ptr[x] and len consistent */ |
218 | 9.66k | aa->len++; |
219 | 9.66k | |
220 | 9.66k | return (0); |
221 | 9.66k | } |
222 | | |
223 | | static int |
224 | | decode_algorithms(const cbor_item_t *item, fido_algo_array_t *aa) |
225 | 5.37k | { |
226 | 5.37k | aa->ptr = NULL; |
227 | 5.37k | aa->len = 0; |
228 | 5.37k | |
229 | 5.37k | if (cbor_isa_array(item) == false || |
230 | 5.37k | cbor_array_is_definite(item) == false) { |
231 | 52 | fido_log_debug("%s: cbor type", __func__); |
232 | 52 | return (-1); |
233 | 52 | } |
234 | 5.32k | |
235 | 5.32k | aa->ptr = calloc(cbor_array_size(item), sizeof(fido_algo_t)); |
236 | 5.32k | if (aa->ptr == NULL) |
237 | 5.32k | return (-1); |
238 | 5.30k | |
239 | 5.30k | if (cbor_array_iter(item, aa, decode_algorithm) < 0) { |
240 | 768 | fido_log_debug("%s: decode_algorithm", __func__); |
241 | 768 | return (-1); |
242 | 768 | } |
243 | 4.54k | |
244 | 4.54k | return (0); |
245 | 4.54k | } |
246 | | |
247 | | static int |
248 | | parse_reply_element(const cbor_item_t *key, const cbor_item_t *val, void *arg) |
249 | 73.0k | { |
250 | 73.0k | fido_cbor_info_t *ci = arg; |
251 | 73.0k | |
252 | 73.0k | if (cbor_isa_uint(key) == false || |
253 | 73.0k | cbor_int_get_width(key) != CBOR_INT_8) { |
254 | 2.95k | fido_log_debug("%s: cbor type", __func__); |
255 | 2.95k | return (0); /* ignore */ |
256 | 2.95k | } |
257 | 70.0k | |
258 | 70.0k | switch (cbor_get_uint8(key)) { |
259 | 7.52k | case 1: /* versions */ |
260 | 7.52k | return (decode_string_array(val, &ci->versions)); |
261 | 8.14k | case 2: /* extensions */ |
262 | 8.14k | return (decode_string_array(val, &ci->extensions)); |
263 | 7.50k | case 3: /* aaguid */ |
264 | 7.50k | return (decode_aaguid(val, ci->aaguid, sizeof(ci->aaguid))); |
265 | 7.22k | case 4: /* options */ |
266 | 7.22k | return (decode_options(val, &ci->options)); |
267 | 7.32k | case 5: /* maxMsgSize */ |
268 | 7.32k | return (cbor_decode_uint64(val, &ci->maxmsgsiz)); |
269 | 7.02k | case 6: /* pinProtocols */ |
270 | 7.02k | return (decode_protocols(val, &ci->protocols)); |
271 | 6.67k | case 7: /* maxCredentialCountInList */ |
272 | 6.67k | return (cbor_decode_uint64(val, &ci->maxcredcntlst)); |
273 | 6.62k | case 8: /* maxCredentialIdLength */ |
274 | 6.62k | return (cbor_decode_uint64(val, &ci->maxcredidlen)); |
275 | 629 | case 9: /* transports */ |
276 | 629 | return (decode_string_array(val, &ci->transports)); |
277 | 5.37k | case 10: /* algorithms */ |
278 | 5.37k | return (decode_algorithms(val, &ci->algorithms)); |
279 | 553 | case 14: /* fwVersion */ |
280 | 553 | return (cbor_decode_uint64(val, &ci->fwversion)); |
281 | 528 | case 15: /* maxCredBlobLen */ |
282 | 528 | return (cbor_decode_uint64(val, &ci->maxcredbloblen)); |
283 | 4.96k | default: /* ignore */ |
284 | 4.96k | fido_log_debug("%s: cbor type", __func__); |
285 | 4.96k | return (0); |
286 | 70.0k | } |
287 | 70.0k | } |
288 | | |
289 | | static int |
290 | | fido_dev_get_cbor_info_tx(fido_dev_t *dev) |
291 | 16.7k | { |
292 | 16.7k | const unsigned char cbor[] = { CTAP_CBOR_GETINFO }; |
293 | 16.7k | |
294 | 16.7k | fido_log_debug("%s: dev=%p", __func__, (void *)dev); |
295 | 16.7k | |
296 | 16.7k | if (fido_tx(dev, CTAP_CMD_CBOR, cbor, sizeof(cbor)) < 0) { |
297 | 155 | fido_log_debug("%s: fido_tx", __func__); |
298 | 155 | return (FIDO_ERR_TX); |
299 | 155 | } |
300 | 16.6k | |
301 | 16.6k | return (FIDO_OK); |
302 | 16.6k | } |
303 | | |
304 | | static int |
305 | | fido_dev_get_cbor_info_rx(fido_dev_t *dev, fido_cbor_info_t *ci, int ms) |
306 | 16.6k | { |
307 | 16.6k | unsigned char reply[FIDO_MAXMSG]; |
308 | 16.6k | int reply_len; |
309 | 16.6k | |
310 | 16.6k | fido_log_debug("%s: dev=%p, ci=%p, ms=%d", __func__, (void *)dev, |
311 | 16.6k | (void *)ci, ms); |
312 | 16.6k | |
313 | 16.6k | fido_cbor_info_reset(ci); |
314 | 16.6k | |
315 | 16.6k | if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), |
316 | 16.6k | ms)) < 0) { |
317 | 3.65k | fido_log_debug("%s: fido_rx", __func__); |
318 | 3.65k | return (FIDO_ERR_RX); |
319 | 3.65k | } |
320 | 12.9k | |
321 | 12.9k | return (cbor_parse_reply(reply, (size_t)reply_len, ci, |
322 | 12.9k | parse_reply_element)); |
323 | 12.9k | } |
324 | | |
325 | | int |
326 | | fido_dev_get_cbor_info_wait(fido_dev_t *dev, fido_cbor_info_t *ci, int ms) |
327 | 16.7k | { |
328 | 16.7k | int r; |
329 | 16.7k | |
330 | | #ifdef USE_WINHELLO |
331 | | if (dev->flags & FIDO_DEV_WINHELLO) |
332 | | return (fido_winhello_get_cbor_info(dev, ci)); |
333 | | #endif |
334 | 16.7k | if ((r = fido_dev_get_cbor_info_tx(dev)) != FIDO_OK || |
335 | 16.7k | (r = fido_dev_get_cbor_info_rx(dev, ci, ms)) != FIDO_OK) |
336 | 16.7k | return (r); |
337 | 7.04k | |
338 | 7.04k | return (FIDO_OK); |
339 | 7.04k | } |
340 | | |
341 | | int |
342 | | fido_dev_get_cbor_info(fido_dev_t *dev, fido_cbor_info_t *ci) |
343 | 305 | { |
344 | 305 | return (fido_dev_get_cbor_info_wait(dev, ci, -1)); |
345 | 305 | } |
346 | | |
347 | | /* |
348 | | * get/set functions for fido_cbor_info_t; always at the end of the file |
349 | | */ |
350 | | |
351 | | fido_cbor_info_t * |
352 | | fido_cbor_info_new(void) |
353 | 16.8k | { |
354 | 16.8k | return (calloc(1, sizeof(fido_cbor_info_t))); |
355 | 16.8k | } |
356 | | |
357 | | static void |
358 | | free_str_array(fido_str_array_t *sa) |
359 | 100k | { |
360 | 140k | for (size_t i = 0; i < sa->len; i++) |
361 | 40.3k | free(sa->ptr[i]); |
362 | 100k | |
363 | 100k | free(sa->ptr); |
364 | 100k | sa->ptr = NULL; |
365 | 100k | sa->len = 0; |
366 | 100k | } |
367 | | |
368 | | static void |
369 | | free_opt_array(fido_opt_array_t *oa) |
370 | 33.4k | { |
371 | 72.0k | for (size_t i = 0; i < oa->len; i++) |
372 | 38.6k | free(oa->name[i]); |
373 | 33.4k | |
374 | 33.4k | free(oa->name); |
375 | 33.4k | free(oa->value); |
376 | 33.4k | oa->name = NULL; |
377 | 33.4k | oa->value = NULL; |
378 | 33.4k | } |
379 | | |
380 | | static void |
381 | | free_byte_array(fido_byte_array_t *ba) |
382 | 33.4k | { |
383 | 33.4k | free(ba->ptr); |
384 | 33.4k | |
385 | 33.4k | ba->ptr = NULL; |
386 | 33.4k | ba->len = 0; |
387 | 33.4k | } |
388 | | |
389 | | static void |
390 | | free_algo_array(fido_algo_array_t *aa) |
391 | 33.4k | { |
392 | 43.0k | for (size_t i = 0; i < aa->len; i++) |
393 | 9.66k | free_algo(&aa->ptr[i]); |
394 | 33.4k | |
395 | 33.4k | free(aa->ptr); |
396 | 33.4k | aa->ptr = NULL; |
397 | 33.4k | aa->len = 0; |
398 | 33.4k | } |
399 | | |
400 | | void |
401 | | fido_cbor_info_reset(fido_cbor_info_t *ci) |
402 | 33.4k | { |
403 | 33.4k | free_str_array(&ci->versions); |
404 | 33.4k | free_str_array(&ci->extensions); |
405 | 33.4k | free_str_array(&ci->transports); |
406 | 33.4k | free_opt_array(&ci->options); |
407 | 33.4k | free_byte_array(&ci->protocols); |
408 | 33.4k | free_algo_array(&ci->algorithms); |
409 | 33.4k | } |
410 | | |
411 | | void |
412 | | fido_cbor_info_free(fido_cbor_info_t **ci_p) |
413 | 53.6k | { |
414 | 53.6k | fido_cbor_info_t *ci; |
415 | 53.6k | |
416 | 53.6k | if (ci_p == NULL || (ci = *ci_p) == NULL) |
417 | 53.6k | return; |
418 | 16.7k | fido_cbor_info_reset(ci); |
419 | 16.7k | free(ci); |
420 | 16.7k | *ci_p = NULL; |
421 | 16.7k | } |
422 | | |
423 | | char ** |
424 | | fido_cbor_info_versions_ptr(const fido_cbor_info_t *ci) |
425 | 374 | { |
426 | 374 | return (ci->versions.ptr); |
427 | 374 | } |
428 | | |
429 | | size_t |
430 | | fido_cbor_info_versions_len(const fido_cbor_info_t *ci) |
431 | 679 | { |
432 | 679 | return (ci->versions.len); |
433 | 679 | } |
434 | | |
435 | | char ** |
436 | | fido_cbor_info_extensions_ptr(const fido_cbor_info_t *ci) |
437 | 7.15k | { |
438 | 7.15k | return (ci->extensions.ptr); |
439 | 7.15k | } |
440 | | |
441 | | size_t |
442 | | fido_cbor_info_extensions_len(const fido_cbor_info_t *ci) |
443 | 7.46k | { |
444 | 7.46k | return (ci->extensions.len); |
445 | 7.46k | } |
446 | | |
447 | | char ** |
448 | | fido_cbor_info_transports_ptr(const fido_cbor_info_t *ci) |
449 | 84 | { |
450 | 84 | return (ci->transports.ptr); |
451 | 84 | } |
452 | | |
453 | | size_t |
454 | | fido_cbor_info_transports_len(const fido_cbor_info_t *ci) |
455 | 389 | { |
456 | 389 | return (ci->transports.len); |
457 | 389 | } |
458 | | |
459 | | const unsigned char * |
460 | | fido_cbor_info_aaguid_ptr(const fido_cbor_info_t *ci) |
461 | 305 | { |
462 | 305 | return (ci->aaguid); |
463 | 305 | } |
464 | | |
465 | | size_t |
466 | | fido_cbor_info_aaguid_len(const fido_cbor_info_t *ci) |
467 | 305 | { |
468 | 305 | return (sizeof(ci->aaguid)); |
469 | 305 | } |
470 | | |
471 | | char ** |
472 | | fido_cbor_info_options_name_ptr(const fido_cbor_info_t *ci) |
473 | 7.18k | { |
474 | 7.18k | return (ci->options.name); |
475 | 7.18k | } |
476 | | |
477 | | const bool * |
478 | | fido_cbor_info_options_value_ptr(const fido_cbor_info_t *ci) |
479 | 7.18k | { |
480 | 7.18k | return (ci->options.value); |
481 | 7.18k | } |
482 | | |
483 | | size_t |
484 | | fido_cbor_info_options_len(const fido_cbor_info_t *ci) |
485 | 7.49k | { |
486 | 7.49k | return (ci->options.len); |
487 | 7.49k | } |
488 | | |
489 | | uint64_t |
490 | | fido_cbor_info_maxcredbloblen(const fido_cbor_info_t *ci) |
491 | 305 | { |
492 | 305 | return (ci->maxcredbloblen); |
493 | 305 | } |
494 | | |
495 | | uint64_t |
496 | | fido_cbor_info_maxmsgsiz(const fido_cbor_info_t *ci) |
497 | 7.33k | { |
498 | 7.33k | return (ci->maxmsgsiz); |
499 | 7.33k | } |
500 | | |
501 | | uint64_t |
502 | | fido_cbor_info_maxcredcntlst(const fido_cbor_info_t *ci) |
503 | 305 | { |
504 | 305 | return (ci->maxcredcntlst); |
505 | 305 | } |
506 | | |
507 | | uint64_t |
508 | | fido_cbor_info_maxcredidlen(const fido_cbor_info_t *ci) |
509 | 305 | { |
510 | 305 | return (ci->maxcredidlen); |
511 | 305 | } |
512 | | |
513 | | uint64_t |
514 | | fido_cbor_info_fwversion(const fido_cbor_info_t *ci) |
515 | 305 | { |
516 | 305 | return (ci->fwversion); |
517 | 305 | } |
518 | | |
519 | | const uint8_t * |
520 | | fido_cbor_info_protocols_ptr(const fido_cbor_info_t *ci) |
521 | 7.33k | { |
522 | 7.33k | return (ci->protocols.ptr); |
523 | 7.33k | } |
524 | | |
525 | | size_t |
526 | | fido_cbor_info_protocols_len(const fido_cbor_info_t *ci) |
527 | 7.33k | { |
528 | 7.33k | return (ci->protocols.len); |
529 | 7.33k | } |
530 | | |
531 | | size_t |
532 | | fido_cbor_info_algorithm_count(const fido_cbor_info_t *ci) |
533 | 633 | { |
534 | 633 | return (ci->algorithms.len); |
535 | 633 | } |
536 | | |
537 | | const char * |
538 | | fido_cbor_info_algorithm_type(const fido_cbor_info_t *ci, size_t idx) |
539 | 328 | { |
540 | 328 | if (idx >= ci->algorithms.len) |
541 | 305 | return (NULL); |
542 | 23 | |
543 | 23 | return (ci->algorithms.ptr[idx].type); |
544 | 23 | } |
545 | | |
546 | | int |
547 | | fido_cbor_info_algorithm_cose(const fido_cbor_info_t *ci, size_t idx) |
548 | 328 | { |
549 | 328 | if (idx >= ci->algorithms.len) |
550 | 305 | return (0); |
551 | 23 | |
552 | 23 | return (ci->algorithms.ptr[idx].cose); |
553 | 23 | } |