## Coverage Report

#### Created: 2023-09-23 17:42

    /libfido2/src/dev.c

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