## Coverage Report

#### Created: 2025-03-01 02:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /libfido2/src/dev.c

    Line
    Count
    Source
    1
    /*
    2
     * Copyright (c) 2018-2022 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
     * SPDX-License-Identifier: BSD-2-Clause
    6
     */
    7
    8
    #include "fido.h"
    9
    10
    #ifndef TLS
    11
    #define TLS
    12
    #endif
    13
    14
    static TLS bool disable_u2f_fallback;
    15
    16
    #ifdef FIDO_FUZZ
    17
    static void
    18
    set_random_report_len(fido_dev_t *dev)
    19
    846k
    {
    20
    846k
            dev->rx_len = CTAP_MIN_REPORT_LEN +
    21
    846k
                uniform_random(CTAP_MAX_REPORT_LEN - CTAP_MIN_REPORT_LEN + 1);
    22
    846k
            dev->tx_len = CTAP_MIN_REPORT_LEN +
    23
    846k
                uniform_random(CTAP_MAX_REPORT_LEN - CTAP_MIN_REPORT_LEN + 1);
    24
    846k
    }
    25
    #endif
    26
    27
    static void
    28
    fido_dev_set_extension_flags(fido_dev_t *dev, const fido_cbor_info_t *info)
    29
    91.8k
    {
    30
    91.8k
            char * const    *ptr = fido_cbor_info_extensions_ptr(info);
    31
    91.8k
            size_t           len = fido_cbor_info_extensions_len(info);
    32
    33
    281k
            for (size_t i = 0; i < len; i++)
    34
    189k
                    if (strcmp(ptr[i], "credProtect") == 0)
    35
    30.1k
                            dev->flags |= FIDO_DEV_CRED_PROT;
    36
    91.8k
    }
    37
    38
    static void
    39
    fido_dev_set_option_flags(fido_dev_t *dev, const fido_cbor_info_t *info)
    40
    91.8k
    {
    41
    91.8k
            char * const    *ptr = fido_cbor_info_options_name_ptr(info);
    42
    91.8k
            const bool      *val = fido_cbor_info_options_value_ptr(info);
    43
    91.8k
            size_t           len = fido_cbor_info_options_len(info);
    44
    45
    555k
            for (size_t i = 0; i < len; i++)
    46
    463k
                    if (strcmp(ptr[i], "clientPin") == 0) {
    47
    30.8k
                            dev->flags |= val[i] ?
    48
    28.5k
                                FIDO_DEV_PIN_SET : FIDO_DEV_PIN_UNSET;
    49
    432k
                    } else if (strcmp(ptr[i], "credMgmt") == 0) {
    50
    1.09k
                            if (val[i])
    51
    967
                                    dev->flags |= FIDO_DEV_CREDMAN;
    52
    431k
                    } else if (strcmp(ptr[i], "credentialMgmtPreview") == 0) {
    53
    16.8k
                            if (val[i])
    54
    16.6k
                                    dev->flags |= FIDO_DEV_CREDMAN_PRE;
    55
    414k
                    } else if (strcmp(ptr[i], "uv") == 0) {
    56
    6.06k
                            dev->flags |= val[i] ?
    57
    5.86k
                                FIDO_DEV_UV_SET : FIDO_DEV_UV_UNSET;
    58
    408k
                    } else if (strcmp(ptr[i], "pinUvAuthToken") == 0) {
    59
    1.39k
                            if (val[i])
    60
    1.17k
                                    dev->flags |= FIDO_DEV_TOKEN_PERMS;
    61
    406k
                    } else if (strcmp(ptr[i], "bioEnroll") == 0) {
    62
    1.62k
                            dev->flags |= val[i] ?
    63
    1.14k
                                FIDO_DEV_BIO_SET : FIDO_DEV_BIO_UNSET;
    64
    1.62k
                    }
    65
    91.8k
    }
    66
    67
    static void
    68
    fido_dev_set_protocol_flags(fido_dev_t *dev, const fido_cbor_info_t *info)
    69
    91.8k
    {
    70
    91.8k
            const uint8_t   *ptr = fido_cbor_info_protocols_ptr(info);
    71
    91.8k
            size_t           len = fido_cbor_info_protocols_len(info);
    72
    73
    209k
            for (size_t i = 0; i < len; i++)
    74
    117k
                    switch (ptr[i]) {
    75
    84.3k
                    case CTAP_PIN_PROTOCOL1:
    76
    84.3k
                            dev->flags |= FIDO_DEV_PIN_PROTOCOL1;
    77
    84.3k
                            break;
    78
    19.5k
                    case CTAP_PIN_PROTOCOL2:
    79
    19.5k
                            dev->flags |= FIDO_DEV_PIN_PROTOCOL2;
    80
    19.5k
                            break;
    81
    13.5k
                    default:
    82
    13.5k
                            fido_log_debug("%s: unknown protocol %u", __func__,
    83
    13.5k
                                ptr[i]);
    84
    13.5k
                            break;
    85
    117k
                    }
    86
    91.8k
    }
    87
    88
    static void
    89
    fido_dev_set_flags(fido_dev_t *dev, const fido_cbor_info_t *info)
    90
    91.8k
    {
    91
    91.8k
            fido_dev_set_extension_flags(dev, info);
    92
    91.8k
            fido_dev_set_option_flags(dev, info);
    93
    91.8k
            fido_dev_set_protocol_flags(dev, info);
    94
    91.8k
    }
    95
    96
    static int
    97
    fido_dev_open_tx(fido_dev_t *dev, const char *path, int *ms)
    98
    3.34M
    {
    99
    3.34M
            int r;
    100
    101
    3.34M
            if (dev->io_handle != NULL) {
    102
    0
                    fido_log_debug("%s: handle=%p", __func__, dev->io_handle);
    103
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    104
    0
            }
    105
    106
    3.34M
            if (dev->io.open == NULL || dev->io.close == NULL) {
    107
    0
                    fido_log_debug("%s: NULL open/close", __func__);
    108
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    109
    0
            }
    110
    111
    3.34M
            if (dev->cid != CTAP_CID_BROADCAST) {
    112
    0
                    fido_log_debug("%s: cid=0x%x", __func__, dev->cid);
    113
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    114
    0
            }
    115
    116
    3.34M
            if (fido_get_random(&dev->nonce, sizeof(dev->nonce)) < 0) {
    117
    7.74k
                    fido_log_debug("%s: fido_get_random", __func__);
    118
    7.74k
                    return (FIDO_ERR_INTERNAL);
    119
    7.74k
            }
    120
    121
    3.33M
            if ((dev->io_handle = dev->io.open(path)) == NULL) {
    122
    2.49M
                    fido_log_debug("%s: dev->io.open", __func__);
    123
    2.49M
                    return (FIDO_ERR_INTERNAL);
    124
    2.49M
            }
    125
    126
    846k
            if (dev->io_own) {
    127
    846k
                    dev->rx_len = CTAP_MAX_REPORT_LEN;
    128
    846k
                    dev->tx_len = CTAP_MAX_REPORT_LEN;
    129
    846k
            } else {
    130
    0
                    dev->rx_len = fido_hid_report_in_len(dev->io_handle);
    131
    0
                    dev->tx_len = fido_hid_report_out_len(dev->io_handle);
    132
    0
            }
    133
    134
    846k
    #ifdef FIDO_FUZZ
    135
    846k
            set_random_report_len(dev);
    136
    846k
    #endif
    137
    138
    846k
            if (dev->rx_len < CTAP_MIN_REPORT_LEN ||
    139
    846k
                dev->rx_len > CTAP_MAX_REPORT_LEN) {
    140
    0
                    fido_log_debug("%s: invalid rx_len %zu", __func__, dev->rx_len);
    141
    0
                    r = FIDO_ERR_RX;
    142
    0
                    goto fail;
    143
    0
            }
    144
    145
    846k
            if (dev->tx_len < CTAP_MIN_REPORT_LEN ||
    146
    846k
                dev->tx_len > CTAP_MAX_REPORT_LEN) {
    147
    0
                    fido_log_debug("%s: invalid tx_len %zu", __func__, dev->tx_len);
    148
    0
                    r = FIDO_ERR_TX;
    149
    0
                    goto fail;
    150
    0
            }
    151
    152
    846k
            if (fido_tx(dev, CTAP_CMD_INIT, &dev->nonce, sizeof(dev->nonce),
    153
    846k
                ms) < 0) {
    154
    19.2k
                    fido_log_debug("%s: fido_tx", __func__);
    155
    19.2k
                    r = FIDO_ERR_TX;
    156
    19.2k
                    goto fail;
    157
    19.2k
            }
    158
    159
    826k
            return (FIDO_OK);
    160
    19.2k
    fail:
    161
    19.2k
            dev->io.close(dev->io_handle);
    162
    19.2k
            dev->io_handle = NULL;
    163
    164
    19.2k
            return (r);
    165
    846k
    }
    166
    167
    static int
    168
    fido_dev_open_rx(fido_dev_t *dev, int *ms)
    169
    826k
    {
    170
    826k
            fido_cbor_info_t        *info = NULL;
    171
    826k
            int                      reply_len;
    172
    826k
            int                      r;
    173
    174
    826k
            if ((reply_len = fido_rx(dev, CTAP_CMD_INIT, &dev->attr,
    175
    826k
                sizeof(dev->attr), ms)) < 0) {
    176
    516k
                    fido_log_debug("%s: fido_rx", __func__);
    177
    516k
                    r = FIDO_ERR_RX;
    178
    516k
                    goto fail;
    179
    516k
            }
    180
    181
    310k
    #ifdef FIDO_FUZZ
    182
    310k
            dev->attr.nonce = dev->nonce;
    183
    310k
    #endif
    184
    185
    310k
            if ((size_t)reply_len != sizeof(dev->attr) ||
    186
    310k
                dev->attr.nonce != dev->nonce) {
    187
    12.5k
                    fido_log_debug("%s: invalid nonce", __func__);
    188
    12.5k
                    r = FIDO_ERR_RX;
    189
    12.5k
                    goto fail;
    190
    12.5k
            }
    191
    192
    297k
            dev->flags = 0;
    193
    297k
            dev->cid = dev->attr.cid;
    194
    195
    297k
            if (fido_dev_is_fido2(dev)) {
    196
    236k
                    if ((info = fido_cbor_info_new()) == NULL) {
    197
    459
                            fido_log_debug("%s: fido_cbor_info_new", __func__);
    198
    459
                            r = FIDO_ERR_INTERNAL;
    199
    459
                            goto fail;
    200
    459
                    }
    201
    236k
                    if ((r = fido_dev_get_cbor_info_wait(dev, info,
    202
    236k
                        ms)) != FIDO_OK) {
    203
    144k
                            fido_log_debug("%s: fido_dev_cbor_info_wait: %d",
    204
    144k
                                __func__, r);
    205
    144k
                            if (disable_u2f_fallback)
    206
    0
                                    goto fail;
    207
    144k
                            fido_log_debug("%s: falling back to u2f", __func__);
    208
    144k
                            fido_dev_force_u2f(dev);
    209
    144k
                    } else {
    210
    91.8k
                            fido_dev_set_flags(dev, info);
    211
    91.8k
                    }
    212
    236k
            }
    213
    214
    297k
            if (fido_dev_is_fido2(dev) && info != NULL) {
    215
    91.8k
                    dev->maxmsgsize = fido_cbor_info_maxmsgsiz(info);
    216
    91.8k
                    fido_log_debug("%s: FIDO_MAXMSG=%d, maxmsgsiz=%lu", __func__,
    217
    91.8k
                        FIDO_MAXMSG, (unsigned long)dev->maxmsgsize);
    218
    91.8k
            }
    219
    220
    297k
            r = FIDO_OK;
    221
    826k
    fail:
    222
    826k
            fido_cbor_info_free(&info);
    223
    224
    826k
            if (r != FIDO_OK) {
    225
    529k
                    dev->io.close(dev->io_handle);
    226
    529k
                    dev->io_handle = NULL;
    227
    529k
            }
    228
    229
    826k
            return (r);
    230
    297k
    }
    231
    232
    static int
    233
    fido_dev_open_wait(fido_dev_t *dev, const char *path, int *ms)
    234
    3.34M
    {
    235
    3.34M
            int r;
    236
    237
    #ifdef USE_WINHELLO
    238
            if (strcmp(path, FIDO_WINHELLO_PATH) == 0)
    239
                    return (fido_winhello_open(dev));
    240
    #endif
    241
    3.34M
            if ((r = fido_dev_open_tx(dev, path, ms)) != FIDO_OK ||
    242
    3.34M
                (r = fido_dev_open_rx(dev, ms)) != FIDO_OK)
    243
    3.04M
                    return (r);
    244
    245
    297k
            return (FIDO_OK);
    246
    3.34M
    }
    247
    248
    static void
    249
    run_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen,
    250
        const char *type, int (*manifest)(fido_dev_info_t *, size_t, size_t *))
    251
    17.9k
    {
    252
    17.9k
            size_t ndevs = 0;
    253
    17.9k
            int r;
    254
    255
    17.9k
            if (*olen >= ilen) {
    256
    347
                    fido_log_debug("%s: skipping %s", __func__, type);
    257
    347
                    return;
    258
    347
            }
    259
    17.5k
            if ((r = manifest(devlist + *olen, ilen - *olen, &ndevs)) != FIDO_OK)
    260
    154
                    fido_log_debug("%s: %s: 0x%x", __func__, type, r);
    261
    17.5k
            fido_log_debug("%s: found %zu %s device%s", __func__, ndevs, type,
    262
    17.5k
                ndevs == 1 ? "" : "s");
    263
    17.5k
            *olen += ndevs;
    264
    17.5k
    }
    265
    266
    int
    267
    fido_dev_info_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
    268
    5.97k
    {
    269
    5.97k
            *olen = 0;
    270
    271
    5.97k
            run_manifest(devlist, ilen, olen, "hid", fido_hid_manifest);
    272
    5.97k
    #ifdef USE_NFC
    273
    5.97k
            run_manifest(devlist, ilen, olen, "nfc", fido_nfc_manifest);
    274
    5.97k
    #endif
    275
    5.97k
    #ifdef USE_PCSC
    276
    5.97k
            run_manifest(devlist, ilen, olen, "pcsc", fido_pcsc_manifest);
    277
    5.97k
    #endif
    278
    #ifdef USE_WINHELLO
    279
            run_manifest(devlist, ilen, olen, "winhello", fido_winhello_manifest);
    280
    #endif
    281
    282
    5.97k
            return (FIDO_OK);
    283
    5.97k
    }
    284
    285
    int
    286
    fido_dev_open_with_info(fido_dev_t *dev)
    287
    0
    {
    288
    0
            int ms = dev->timeout_ms;
    289
    290
    0
            if (dev->path == NULL)
    291
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    292
    293
    0
            return (fido_dev_open_wait(dev, dev->path, &ms));
    294
    0
    }
    295
    296
    int
    297
    fido_dev_open(fido_dev_t *dev, const char *path)
    298
    3.34M
    {
    299
    3.34M
            int ms = dev->timeout_ms;
    300
    301
    3.34M
    #ifdef USE_NFC
    302
    3.34M
            if (fido_is_nfc(path) && fido_dev_set_nfc(dev) < 0) {
    303
    0
                    fido_log_debug("%s: fido_dev_set_nfc", __func__);
    304
    0
                    return FIDO_ERR_INTERNAL;
    305
    0
            }
    306
    3.34M
    #endif
    307
    3.34M
    #ifdef USE_PCSC
    308
    3.34M
            if (fido_is_pcsc(path) && fido_dev_set_pcsc(dev) < 0) {
    309
    0
                    fido_log_debug("%s: fido_dev_set_pcsc", __func__);
    310
    0
                    return FIDO_ERR_INTERNAL;
    311
    0
            }
    312
    3.34M
    #endif
    313
    314
    3.34M
            return (fido_dev_open_wait(dev, path, &ms));
    315
    3.34M
    }
    316
    317
    int
    318
    fido_dev_close(fido_dev_t *dev)
    319
    297k
    {
    320
    #ifdef USE_WINHELLO
    321
            if (dev->flags & FIDO_DEV_WINHELLO)
    322
                    return (fido_winhello_close(dev));
    323
    #endif
    324
    297k
            if (dev->io_handle == NULL || dev->io.close == NULL)
    325
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    326
    327
    297k
            dev->io.close(dev->io_handle);
    328
    297k
            dev->io_handle = NULL;
    329
    297k
            dev->cid = CTAP_CID_BROADCAST;
    330
    331
    297k
            return (FIDO_OK);
    332
    297k
    }
    333
    334
    int
    335
    fido_dev_set_sigmask(fido_dev_t *dev, const fido_sigset_t *sigmask)
    336
    0
    {
    337
    0
            if (dev->io_handle == NULL || sigmask == NULL)
    338
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    339
    340
    0
    #ifdef USE_NFC
    341
    0
            if (dev->transport.rx == fido_nfc_rx && dev->io.read == fido_nfc_read)
    342
    0
                    return (fido_nfc_set_sigmask(dev->io_handle, sigmask));
    343
    0
    #endif
    344
    0
            if (dev->transport.rx == NULL && dev->io.read == fido_hid_read)
    345
    0
                    return (fido_hid_set_sigmask(dev->io_handle, sigmask));
    346
    347
    0
            return (FIDO_ERR_INVALID_ARGUMENT);
    348
    0
    }
    349
    350
    int
    351
    fido_dev_cancel(fido_dev_t *dev)
    352
    32.0k
    {
    353
    32.0k
            int ms = dev->timeout_ms;
    354
    355
    #ifdef USE_WINHELLO
    356
            if (dev->flags & FIDO_DEV_WINHELLO)
    357
                    return (fido_winhello_cancel(dev));
    358
    #endif
    359
    32.0k
            if (fido_dev_is_fido2(dev) == false)
    360
    20.3k
                    return (FIDO_ERR_INVALID_ARGUMENT);
    361
    11.6k
            if (fido_tx(dev, CTAP_CMD_CANCEL, NULL, 0, &ms) < 0)
    362
    242
                    return (FIDO_ERR_TX);
    363
    364
    11.4k
            return (FIDO_OK);
    365
    11.6k
    }
    366
    367
    int
    368
    fido_dev_set_io_functions(fido_dev_t *dev, const fido_dev_io_t *io)
    369
    831k
    {
    370
    831k
            if (dev->io_handle != NULL) {
    371
    0
                    fido_log_debug("%s: non-NULL handle", __func__);
    372
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    373
    0
            }
    374
    375
    831k
            if (io == NULL || io->open == NULL || io->close == NULL ||
    376
    831k
                io->read == NULL || io->write == NULL) {
    377
    0
                    fido_log_debug("%s: NULL function", __func__);
    378
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    379
    0
            }
    380
    381
    831k
            dev->io = *io;
    382
    831k
            dev->io_own = true;
    383
    384
    831k
            return (FIDO_OK);
    385
    831k
    }
    386
    387
    int
    388
    fido_dev_set_transport_functions(fido_dev_t *dev, const fido_dev_transport_t *t)
    389
    2.94k
    {
    390
    2.94k
            if (dev->io_handle != NULL) {
    391
    0
                    fido_log_debug("%s: non-NULL handle", __func__);
    392
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    393
    0
            }
    394
    395
    2.94k
            dev->transport = *t;
    396
    2.94k
            dev->io_own = true;
    397
    398
    2.94k
            return (FIDO_OK);
    399
    2.94k
    }
    400
    401
    void *
    402
    fido_dev_io_handle(const fido_dev_t *dev)
    403
    0
    {
    404
    405
    0
            return (dev->io_handle);
    406
    0
    }
    407
    408
    void
    409
    fido_init(int flags)
    410
    170k
    {
    411
    170k
            if (flags & FIDO_DEBUG || getenv("FIDO_DEBUG") != NULL)
    412
    170k
                    fido_log_init();
    413
    414
    170k
            disable_u2f_fallback = (flags & FIDO_DISABLE_U2F_FALLBACK);
    415
    170k
    }
    416
    417
    fido_dev_t *
    418
    fido_dev_new(void)
    419
    3.35M
    {
    420
    3.35M
            fido_dev_t *dev;
    421
    422
    3.35M
            if ((dev = calloc(1, sizeof(*dev))) == NULL)
    423
    9.89k
                    return (NULL);
    424
    425
    3.34M
            dev->cid = CTAP_CID_BROADCAST;
    426
    3.34M
            dev->timeout_ms = -1;
    427
    3.34M
            dev->io = (fido_dev_io_t) {
    428
    3.34M
                    &fido_hid_open,
    429
    3.34M
                    &fido_hid_close,
    430
    3.34M
                    &fido_hid_read,
    431
    3.34M
                    &fido_hid_write,
    432
    3.34M
            };
    433
    434
    3.34M
            return (dev);
    435
    3.35M
    }
    436
    437
    fido_dev_t *
    438
    fido_dev_new_with_info(const fido_dev_info_t *di)
    439
    0
    {
    440
    0
            fido_dev_t *dev;
    441
    442
    0
            if ((dev = calloc(1, sizeof(*dev))) == NULL)
    443
    0
                    return (NULL);
    444
    445
    #if 0
    446
            if (di->io.open == NULL || di->io.close == NULL ||
    447
                di->io.read == NULL || di->io.write == NULL) {
    448
                    fido_log_debug("%s: NULL function", __func__);
    449
                    fido_dev_free(&dev);
    450
                    return (NULL);
    451
            }
    452
    #endif
    453
    454
    0
            dev->io = di->io;
    455
    0
            dev->io_own = di->transport.tx != NULL || di->transport.rx != NULL;
    456
    0
            dev->transport = di->transport;
    457
    0
            dev->cid = CTAP_CID_BROADCAST;
    458
    0
            dev->timeout_ms = -1;
    459
    460
    0
            if ((dev->path = strdup(di->path)) == NULL) {
    461
    0
                    fido_log_debug("%s: strdup", __func__);
    462
    0
                    fido_dev_free(&dev);
    463
    0
                    return (NULL);
    464
    0
            }
    465
    466
    0
            return (dev);
    467
    0
    }
    468
    469
    void
    470
    fido_dev_free(fido_dev_t **dev_p)
    471
    3.47M
    {
    472
    3.47M
            fido_dev_t *dev;
    473
    474
    3.47M
            if (dev_p == NULL || (dev = *dev_p) == NULL)
    475
    133k
                    return;
    476
    477
    3.34M
            free(dev->path);
    478
    3.34M
            free(dev);
    479
    480
    3.34M
            *dev_p = NULL;
    481
    3.34M
    }
    482
    483
    uint8_t
    484
    fido_dev_protocol(const fido_dev_t *dev)
    485
    8.00k
    {
    486
    8.00k
            return (dev->attr.protocol);
    487
    8.00k
    }
    488
    489
    uint8_t
    490
    fido_dev_major(const fido_dev_t *dev)
    491
    8.00k
    {
    492
    8.00k
            return (dev->attr.major);
    493
    8.00k
    }
    494
    495
    uint8_t
    496
    fido_dev_minor(const fido_dev_t *dev)
    497
    8.00k
    {
    498
    8.00k
            return (dev->attr.minor);
    499
    8.00k
    }
    500
    501
    uint8_t
    502
    fido_dev_build(const fido_dev_t *dev)
    503
    8.00k
    {
    504
    8.00k
            return (dev->attr.build);
    505
    8.00k
    }
    506
    507
    uint8_t
    508
    fido_dev_flags(const fido_dev_t *dev)
    509
    8.00k
    {
    510
    8.00k
            return (dev->attr.flags);
    511
    8.00k
    }
    512
    513
    bool
    514
    fido_dev_is_fido2(const fido_dev_t *dev)
    515
    819k
    {
    516
    819k
            return (dev->attr.flags & FIDO_CAP_CBOR);
    517
    819k
    }
    518
    519
    bool
    520
    fido_dev_is_winhello(const fido_dev_t *dev)
    521
    0
    {
    522
    0
            return (dev->flags & FIDO_DEV_WINHELLO);
    523
    0
    }
    524
    525
    bool
    526
    fido_dev_supports_pin(const fido_dev_t *dev)
    527
    47.7k
    {
    528
    47.7k
            return (dev->flags & (FIDO_DEV_PIN_SET|FIDO_DEV_PIN_UNSET));
    529
    47.7k
    }
    530
    531
    bool
    532
    fido_dev_has_pin(const fido_dev_t *dev)
    533
    47.1k
    {
    534
    47.1k
            return (dev->flags & FIDO_DEV_PIN_SET);
    535
    47.1k
    }
    536
    537
    bool
    538
    fido_dev_supports_cred_prot(const fido_dev_t *dev)
    539
    46.1k
    {
    540
    46.1k
            return (dev->flags & FIDO_DEV_CRED_PROT);
    541
    46.1k
    }
    542
    543
    bool
    544
    fido_dev_supports_credman(const fido_dev_t *dev)
    545
    46.1k
    {
    546
    46.1k
            return (dev->flags & (FIDO_DEV_CREDMAN|FIDO_DEV_CREDMAN_PRE));
    547
    46.1k
    }
    548
    549
    bool
    550
    fido_dev_supports_uv(const fido_dev_t *dev)
    551
    47.1k
    {
    552
    47.1k
            return (dev->flags & (FIDO_DEV_UV_SET|FIDO_DEV_UV_UNSET));
    553
    47.1k
    }
    554
    555
    bool
    556
    fido_dev_has_uv(const fido_dev_t *dev)
    557
    47.5k
    {
    558
    47.5k
            return (dev->flags & FIDO_DEV_UV_SET);
    559
    47.5k
    }
    560
    561
    bool
    562
    fido_dev_supports_permissions(const fido_dev_t *dev)
    563
    43.4k
    {
    564
    43.4k
            return (dev->flags & FIDO_DEV_TOKEN_PERMS);
    565
    43.4k
    }
    566
    567
    void
    568
    fido_dev_force_u2f(fido_dev_t *dev)
    569
    153k
    {
    570
    153k
            dev->attr.flags &= (uint8_t)~FIDO_CAP_CBOR;
    571
    153k
            dev->flags = 0;
    572
    153k
    }
    573
    574
    void
    575
    fido_dev_force_fido2(fido_dev_t *dev)
    576
    0
    {
    577
    0
            dev->attr.flags |= FIDO_CAP_CBOR;
    578
    0
    }
    579
    580
    uint8_t
    581
    fido_dev_get_pin_protocol(const fido_dev_t *dev)
    582
    213k
    {
    583
    213k
            if (dev->flags & FIDO_DEV_PIN_PROTOCOL2)
    584
    22.8k
                    return (CTAP_PIN_PROTOCOL2);
    585
    190k
            else if (dev->flags & FIDO_DEV_PIN_PROTOCOL1)
    586
    149k
                    return (CTAP_PIN_PROTOCOL1);
    587
    588
    41.5k
            return (0);
    589
    213k
    }
    590
    591
    uint64_t
    592
    fido_dev_maxmsgsize(const fido_dev_t *dev)
    593
    39.1k
    {
    594
    39.1k
            return (dev->maxmsgsize);
    595
    39.1k
    }
    596
    597
    int
    598
    fido_dev_set_timeout(fido_dev_t *dev, int ms)
    599
    831k
    {
    600
    831k
            if (ms < -1)
    601
    0
                    return (FIDO_ERR_INVALID_ARGUMENT);
    602
    603
    831k
            dev->timeout_ms = ms;
    604
    605
    831k
            return (FIDO_OK);
    606
    831k
    }