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