Coverage Report

Created: 2020-09-01 07:05

/libfido2/src/dev.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (c) 2018 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 <sys/types.h>
8
#include <sys/stat.h>
9
#ifdef HAVE_SYS_RANDOM_H
10
#include <sys/random.h>
11
#endif
12
13
#include <openssl/sha.h>
14
15
#include <fcntl.h>
16
#include <stdint.h>
17
#include <stdlib.h>
18
#include <string.h>
19
#ifdef HAVE_UNISTD_H
20
#include <unistd.h>
21
#endif
22
23
#include "fido.h"
24
25
#if defined(_WIN32)
26
#include <windows.h>
27
28
#include <winternl.h>
29
#include <winerror.h>
30
#include <stdio.h>
31
#include <bcrypt.h>
32
#include <sal.h>
33
34
static int
35
obtain_nonce(uint64_t *nonce)
36
{
37
        NTSTATUS status;
38
39
        status = BCryptGenRandom(NULL, (unsigned char *)nonce, sizeof(*nonce),
40
            BCRYPT_USE_SYSTEM_PREFERRED_RNG);
41
42
        if (!NT_SUCCESS(status))
43
                return (-1);
44
45
        return (0);
46
}
47
#elif defined(HAVE_ARC4RANDOM_BUF)
48
static int
49
obtain_nonce(uint64_t *nonce)
50
{
51
        arc4random_buf(nonce, sizeof(*nonce));
52
        return (0);
53
}
54
#elif defined(HAVE_GETRANDOM)
55
static int
56
obtain_nonce(uint64_t *nonce)
57
26.5k
{
58
26.5k
        if (getrandom(nonce, sizeof(*nonce), 0) < 0)
59
0
                return (-1);
60
26.5k
        return (0);
61
26.5k
}
62
#elif defined(HAVE_DEV_URANDOM)
63
static int
64
obtain_nonce(uint64_t *nonce)
65
{
66
        int     fd = -1;
67
        int     ok = -1;
68
        ssize_t r;
69
70
        if ((fd = open(FIDO_RANDOM_DEV, O_RDONLY)) < 0)
71
                goto fail;
72
        if ((r = read(fd, nonce, sizeof(*nonce))) < 0 ||
73
            (size_t)r != sizeof(*nonce))
74
                goto fail;
75
76
        ok = 0;
77
fail:
78
        if (fd != -1)
79
                close(fd);
80
81
        return (ok);
82
}
83
#else
84
#error "please provide an implementation of obtain_nonce() for your platform"
85
#endif /* _WIN32 */
86
87
#ifndef TLS
88
#define TLS
89
#endif
90
91
typedef struct dev_manifest_func_node {
92
        dev_manifest_func_t manifest_func;
93
        struct dev_manifest_func_node *next;
94
} dev_manifest_func_node_t;
95
96
static TLS dev_manifest_func_node_t *manifest_funcs = NULL;
97
98
static void
99
find_manifest_func_node(dev_manifest_func_t f, dev_manifest_func_node_t **curr,
100
    dev_manifest_func_node_t **prev)
101
0
{
102
0
        *prev = NULL;
103
0
        *curr = manifest_funcs;
104
0
105
0
        while (*curr != NULL && (*curr)->manifest_func != f) {
106
0
                *prev = *curr;
107
0
                *curr = (*curr)->next;
108
0
        }
109
0
}
110
111
#ifdef FIDO_FUZZ
112
static void
113
set_random_report_len(fido_dev_t *dev)
114
26.5k
{
115
26.5k
        dev->rx_len = CTAP_MIN_REPORT_LEN +
116
26.5k
            uniform_random(CTAP_MAX_REPORT_LEN - CTAP_MIN_REPORT_LEN + 1);
117
26.5k
        dev->tx_len = CTAP_MIN_REPORT_LEN +
118
26.5k
            uniform_random(CTAP_MAX_REPORT_LEN - CTAP_MIN_REPORT_LEN + 1);
119
26.5k
}
120
#endif
121
122
static void
123
fido_dev_set_flags(fido_dev_t *dev, const fido_cbor_info_t *info)
124
3.40k
{
125
3.40k
        char * const    *ptr;
126
3.40k
        const bool      *val;
127
3.40k
        size_t           len;
128
3.40k
129
3.40k
        ptr = fido_cbor_info_extensions_ptr(info);
130
3.40k
        len = fido_cbor_info_extensions_len(info);
131
3.40k
132
9.91k
        for (size_t i = 0; i < len; i++)
133
6.51k
                if (strcmp(ptr[i], "credProtect") == 0)
134
1.86k
                        dev->flags |= FIDO_DEV_CRED_PROT;
135
3.40k
136
3.40k
        ptr = fido_cbor_info_options_name_ptr(info);
137
3.40k
        val = fido_cbor_info_options_value_ptr(info);
138
3.40k
        len = fido_cbor_info_options_len(info);
139
3.40k
140
18.5k
        for (size_t i = 0; i < len; i++)
141
15.1k
                if (strcmp(ptr[i], "clientPin") == 0) {
142
2.08k
                        if (val[i] == true)
143
2.08k
                                dev->flags |= FIDO_DEV_PIN_SET;
144
2.08k
                        else
145
2.08k
                                dev->flags |= FIDO_DEV_PIN_UNSET;
146
2.08k
                }
147
3.40k
}
148
149
static int
150
fido_dev_open_tx(fido_dev_t *dev, const char *path)
151
26.5k
{
152
26.5k
        const uint8_t   cmd = CTAP_CMD_INIT;
153
26.5k
        int             r;
154
26.5k
155
26.5k
        if (dev->io_handle != NULL) {
156
0
                fido_log_debug("%s: handle=%p", __func__, dev->io_handle);
157
0
                return (FIDO_ERR_INVALID_ARGUMENT);
158
0
        }
159
26.5k
160
26.5k
        if (dev->io.open == NULL || dev->io.close == NULL) {
161
0
                fido_log_debug("%s: NULL open/close", __func__);
162
0
                return (FIDO_ERR_INVALID_ARGUMENT);
163
0
        }
164
26.5k
165
26.5k
        if (obtain_nonce(&dev->nonce) < 0) {
166
0
                fido_log_debug("%s: obtain_nonce", __func__);
167
0
                return (FIDO_ERR_INTERNAL);
168
0
        }
169
26.5k
170
26.5k
        if ((dev->io_handle = dev->io.open(path)) == NULL) {
171
0
                fido_log_debug("%s: dev->io.open", __func__);
172
0
                return (FIDO_ERR_INTERNAL);
173
0
        }
174
26.5k
175
26.5k
        if (dev->io_own) {
176
26.5k
                dev->rx_len = CTAP_MAX_REPORT_LEN;
177
26.5k
                dev->tx_len = CTAP_MAX_REPORT_LEN;
178
26.5k
        } else {
179
0
                dev->rx_len = fido_hid_report_in_len(dev->io_handle);
180
0
                dev->tx_len = fido_hid_report_out_len(dev->io_handle);
181
0
        }
182
26.5k
183
26.5k
#ifdef FIDO_FUZZ
184
26.5k
        set_random_report_len(dev);
185
26.5k
#endif
186
26.5k
187
26.5k
        if (dev->rx_len < CTAP_MIN_REPORT_LEN ||
188
26.5k
            dev->rx_len > CTAP_MAX_REPORT_LEN) {
189
0
                fido_log_debug("%s: invalid rx_len %zu", __func__, dev->rx_len);
190
0
                r = FIDO_ERR_RX;
191
0
                goto fail;
192
0
        }
193
26.5k
194
26.5k
        if (dev->tx_len < CTAP_MIN_REPORT_LEN ||
195
26.5k
            dev->tx_len > CTAP_MAX_REPORT_LEN) {
196
0
                fido_log_debug("%s: invalid tx_len %zu", __func__, dev->tx_len);
197
0
                r = FIDO_ERR_TX;
198
0
                goto fail;
199
0
        }
200
26.5k
201
26.5k
        if (fido_tx(dev, cmd, &dev->nonce, sizeof(dev->nonce)) < 0) {
202
188
                fido_log_debug("%s: fido_tx", __func__);
203
188
                r = FIDO_ERR_TX;
204
188
                goto fail;
205
188
        }
206
26.3k
207
26.3k
        return (FIDO_OK);
208
188
fail:
209
188
        dev->io.close(dev->io_handle);
210
188
        dev->io_handle = NULL;
211
188
212
188
        return (r);
213
26.3k
}
214
215
static int
216
fido_dev_open_rx(fido_dev_t *dev, int ms)
217
26.3k
{
218
26.3k
        fido_cbor_info_t        *info = NULL;
219
26.3k
        int                      reply_len;
220
26.3k
        int                      r;
221
26.3k
222
26.3k
        if ((reply_len = fido_rx(dev, CTAP_CMD_INIT, &dev->attr,
223
26.3k
            sizeof(dev->attr), ms)) < 0) {
224
16.4k
                fido_log_debug("%s: fido_rx", __func__);
225
16.4k
                r = FIDO_ERR_RX;
226
16.4k
                goto fail;
227
16.4k
        }
228
9.90k
229
9.90k
#ifdef FIDO_FUZZ
230
9.90k
        dev->attr.nonce = dev->nonce;
231
9.90k
#endif
232
9.90k
233
9.90k
        if ((size_t)reply_len != sizeof(dev->attr) ||
234
9.90k
            dev->attr.nonce != dev->nonce) {
235
148
                fido_log_debug("%s: invalid nonce", __func__);
236
148
                r = FIDO_ERR_RX;
237
148
                goto fail;
238
148
        }
239
9.75k
240
9.75k
        dev->flags = 0;
241
9.75k
        dev->cid = dev->attr.cid;
242
9.75k
243
9.75k
        if (fido_dev_is_fido2(dev)) {
244
7.42k
                if ((info = fido_cbor_info_new()) == NULL) {
245
37
                        fido_log_debug("%s: fido_cbor_info_new", __func__);
246
37
                        r = FIDO_ERR_INTERNAL;
247
37
                        goto fail;
248
37
                }
249
7.38k
                if (fido_dev_get_cbor_info_wait(dev, info, ms) != FIDO_OK) {
250
3.97k
                        fido_log_debug("%s: falling back to u2f", __func__);
251
3.97k
                        fido_dev_force_u2f(dev);
252
3.97k
                } else {
253
3.40k
                        fido_dev_set_flags(dev, info);
254
3.40k
                }
255
7.38k
        }
256
9.75k
257
9.75k
        if (fido_dev_is_fido2(dev) && info != NULL) {
258
3.40k
                fido_log_debug("%s: FIDO_MAXMSG=%d, maxmsgsiz=%lu", __func__,
259
3.40k
                    FIDO_MAXMSG, (unsigned long)fido_cbor_info_maxmsgsiz(info));
260
3.40k
        }
261
9.72k
262
9.72k
        r = FIDO_OK;
263
26.3k
fail:
264
26.3k
        fido_cbor_info_free(&info);
265
26.3k
266
26.3k
        if (r != FIDO_OK) {
267
16.6k
                dev->io.close(dev->io_handle);
268
16.6k
                dev->io_handle = NULL;
269
16.6k
        }
270
26.3k
271
26.3k
        return (r);
272
9.72k
}
273
274
static int
275
fido_dev_open_wait(fido_dev_t *dev, const char *path, int ms)
276
26.5k
{
277
26.5k
        int r;
278
26.5k
279
26.5k
        if ((r = fido_dev_open_tx(dev, path)) != FIDO_OK ||
280
26.5k
            (r = fido_dev_open_rx(dev, ms)) != FIDO_OK)
281
26.5k
                return (r);
282
9.72k
283
9.72k
        return (FIDO_OK);
284
9.72k
}
285
286
int
287
fido_dev_register_manifest_func(const dev_manifest_func_t f)
288
0
{
289
0
        dev_manifest_func_node_t *prev, *curr, *n;
290
0
291
0
        find_manifest_func_node(f, &curr, &prev);
292
0
        if (curr != NULL)
293
0
                return (FIDO_OK);
294
0
295
0
        if ((n = calloc(1, sizeof(*n))) == NULL) {
296
0
                fido_log_debug("%s: calloc", __func__);
297
0
                return (FIDO_ERR_INTERNAL);
298
0
        }
299
0
300
0
        n->manifest_func = f;
301
0
        n->next = manifest_funcs;
302
0
        manifest_funcs = n;
303
0
304
0
        return (FIDO_OK);
305
0
}
306
307
void
308
fido_dev_unregister_manifest_func(const dev_manifest_func_t f)
309
0
{
310
0
        dev_manifest_func_node_t *prev, *curr;
311
0
312
0
        find_manifest_func_node(f, &curr, &prev);
313
0
        if (curr == NULL)
314
0
                return;
315
0
        if (prev != NULL)
316
0
                prev->next = curr->next;
317
0
        else
318
0
                manifest_funcs = curr->next;
319
0
320
0
        free(curr);
321
0
}
322
323
int
324
fido_dev_info_manifest(fido_dev_info_t *devlist, size_t ilen, size_t *olen)
325
0
{
326
0
        dev_manifest_func_node_t        *curr = NULL;
327
0
        dev_manifest_func_t              m_func;
328
0
        size_t                           curr_olen;
329
0
        int                              r;
330
0
331
0
        *olen = 0;
332
0
333
0
        if (fido_dev_register_manifest_func(fido_hid_manifest) != FIDO_OK)
334
0
                return (FIDO_ERR_INTERNAL);
335
0
336
0
        for (curr = manifest_funcs; curr != NULL; curr = curr->next) {
337
0
                curr_olen = 0;
338
0
                m_func = curr->manifest_func;
339
0
                r = m_func(devlist + *olen, ilen - *olen, &curr_olen);
340
0
                if (r != FIDO_OK)
341
0
                        return (r);
342
0
                *olen += curr_olen;
343
0
                if (*olen == ilen)
344
0
                        break;
345
0
        }
346
0
347
0
        return (FIDO_OK);
348
0
}
349
350
int
351
fido_dev_open_with_info(fido_dev_t *dev)
352
0
{
353
0
        if (dev->path == NULL)
354
0
                return (FIDO_ERR_INVALID_ARGUMENT);
355
0
356
0
        return (fido_dev_open_wait(dev, dev->path, -1));
357
0
}
358
359
int
360
fido_dev_open(fido_dev_t *dev, const char *path)
361
26.5k
{
362
26.5k
        return (fido_dev_open_wait(dev, path, -1));
363
26.5k
}
364
365
int
366
fido_dev_close(fido_dev_t *dev)
367
9.72k
{
368
9.72k
        if (dev->io_handle == NULL || dev->io.close == NULL)
369
9.72k
                return (FIDO_ERR_INVALID_ARGUMENT);
370
9.72k
371
9.72k
        dev->io.close(dev->io_handle);
372
9.72k
        dev->io_handle = NULL;
373
9.72k
374
9.72k
        return (FIDO_OK);
375
9.72k
}
376
377
int
378
fido_dev_cancel(fido_dev_t *dev)
379
4.25k
{
380
4.25k
        if (fido_dev_is_fido2(dev) == false)
381
4.25k
                return (FIDO_ERR_INVALID_ARGUMENT);
382
1.59k
383
1.59k
        if (fido_tx(dev, CTAP_CMD_CANCEL, NULL, 0) < 0)
384
15
                return (FIDO_ERR_TX);
385
1.57k
386
1.57k
        return (FIDO_OK);
387
1.57k
}
388
389
int
390
fido_dev_get_touch_begin(fido_dev_t *dev)
391
1.44k
{
392
1.44k
        fido_blob_t      f;
393
1.44k
        cbor_item_t     *argv[9];
394
1.44k
        const char      *clientdata = FIDO_DUMMY_CLIENTDATA;
395
1.44k
        const uint8_t    user_id = FIDO_DUMMY_USER_ID;
396
1.44k
        unsigned char    cdh[SHA256_DIGEST_LENGTH];
397
1.44k
        fido_rp_t        rp;
398
1.44k
        fido_user_t      user;
399
1.44k
        int              r = FIDO_ERR_INTERNAL;
400
1.44k
401
1.44k
        memset(&f, 0, sizeof(f));
402
1.44k
        memset(argv, 0, sizeof(argv));
403
1.44k
        memset(cdh, 0, sizeof(cdh));
404
1.44k
        memset(&rp, 0, sizeof(rp));
405
1.44k
        memset(&user, 0, sizeof(user));
406
1.44k
407
1.44k
        if (fido_dev_is_fido2(dev) == false)
408
1.44k
                return (u2f_get_touch_begin(dev));
409
109
410
109
        if (SHA256((const void *)clientdata, strlen(clientdata), cdh) != cdh) {
411
1
                fido_log_debug("%s: sha256", __func__);
412
1
                return (FIDO_ERR_INTERNAL);
413
1
        }
414
108
415
108
        if ((rp.id = strdup(FIDO_DUMMY_RP_ID)) == NULL ||
416
108
            (user.name = strdup(FIDO_DUMMY_USER_NAME)) == NULL) {
417
8
                fido_log_debug("%s: strdup", __func__);
418
8
                goto fail;
419
8
        }
420
100
421
100
        if (fido_blob_set(&user.id, &user_id, sizeof(user_id)) < 0) {
422
1
                fido_log_debug("%s: fido_blob_set", __func__);
423
1
                goto fail;
424
1
        }
425
99
426
99
        if ((argv[0] = cbor_build_bytestring(cdh, sizeof(cdh))) == NULL ||
427
99
            (argv[1] = cbor_encode_rp_entity(&rp)) == NULL ||
428
99
            (argv[2] = cbor_encode_user_entity(&user)) == NULL ||
429
99
            (argv[3] = cbor_encode_pubkey_param(COSE_ES256)) == NULL) {
430
21
                fido_log_debug("%s: cbor encode", __func__);
431
21
                goto fail;
432
21
        }
433
78
434
78
        if (fido_dev_supports_pin(dev)) {
435
75
                if ((argv[7] = cbor_new_definite_bytestring()) == NULL ||
436
75
                    (argv[8] = cbor_encode_pin_opt()) == NULL) {
437
1
                        fido_log_debug("%s: cbor encode", __func__);
438
1
                        goto fail;
439
1
                }
440
77
        }
441
77
442
77
        if (cbor_build_frame(CTAP_CBOR_MAKECRED, argv, nitems(argv), &f) < 0 ||
443
77
            fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) {
444
8
                fido_log_debug("%s: fido_tx", __func__);
445
8
                r = FIDO_ERR_TX;
446
8
                goto fail;
447
8
        }
448
69
449
69
        r = FIDO_OK;
450
108
fail:
451
108
        cbor_vector_free(argv, nitems(argv));
452
108
        free(f.ptr);
453
108
        free(rp.id);
454
108
        free(user.name);
455
108
        free(user.id.ptr);
456
108
457
108
        return (r);
458
69
}
459
460
int
461
fido_dev_get_touch_status(fido_dev_t *dev, int *touched, int ms)
462
1.44k
{
463
1.44k
        int r;
464
1.44k
465
1.44k
        *touched = 0;
466
1.44k
467
1.44k
        if (fido_dev_is_fido2(dev) == false)
468
1.44k
                return (u2f_get_touch_status(dev, touched, ms));
469
109
470
109
        switch ((r = fido_rx_cbor_status(dev, ms))) {
471
35
        case FIDO_ERR_PIN_AUTH_INVALID:
472
35
        case FIDO_ERR_PIN_INVALID:
473
35
        case FIDO_ERR_PIN_NOT_SET:
474
35
        case FIDO_ERR_SUCCESS:
475
35
                *touched = 1;
476
35
                break;
477
35
        case FIDO_ERR_RX:
478
26
                /* ignore */
479
26
                break;
480
48
        default:
481
48
                fido_log_debug("%s: fido_rx_cbor_status", __func__);
482
48
                return (r);
483
61
        }
484
61
485
61
        return (FIDO_OK);
486
61
}
487
488
int
489
fido_dev_set_io_functions(fido_dev_t *dev, const fido_dev_io_t *io)
490
26.5k
{
491
26.5k
        if (dev->io_handle != NULL) {
492
0
                fido_log_debug("%s: non-NULL handle", __func__);
493
0
                return (FIDO_ERR_INVALID_ARGUMENT);
494
0
        }
495
26.5k
496
26.5k
        if (io == NULL || io->open == NULL || io->close == NULL ||
497
26.5k
            io->read == NULL || io->write == NULL) {
498
0
                fido_log_debug("%s: NULL function", __func__);
499
0
                return (FIDO_ERR_INVALID_ARGUMENT);
500
0
        }
501
26.5k
502
26.5k
        dev->io = *io;
503
26.5k
        dev->io_own = true;
504
26.5k
505
26.5k
        return (FIDO_OK);
506
26.5k
}
507
508
int
509
fido_dev_set_transport_functions(fido_dev_t *dev, const fido_dev_transport_t *t)
510
0
{
511
0
        if (dev->io_handle != NULL) {
512
0
                fido_log_debug("%s: non-NULL handle", __func__);
513
0
                return (FIDO_ERR_INVALID_ARGUMENT);
514
0
        }
515
0
516
0
        dev->transport = *t;
517
0
        dev->io_own = true;
518
0
519
0
        return (FIDO_OK);
520
0
}
521
522
void
523
fido_init(int flags)
524
7.92k
{
525
7.92k
        if (flags & FIDO_DEBUG || getenv("FIDO_DEBUG") != NULL)
526
7.92k
                fido_log_init();
527
7.92k
}
528
529
fido_dev_t *
530
fido_dev_new(void)
531
26.6k
{
532
26.6k
        fido_dev_t *dev;
533
26.6k
534
26.6k
        if ((dev = calloc(1, sizeof(*dev))) == NULL)
535
26.6k
                return (NULL);
536
26.5k
537
26.5k
        dev->cid = CTAP_CID_BROADCAST;
538
26.5k
        dev->io = (fido_dev_io_t) {
539
26.5k
                &fido_hid_open,
540
26.5k
                &fido_hid_close,
541
26.5k
                &fido_hid_read,
542
26.5k
                &fido_hid_write,
543
26.5k
        };
544
26.5k
545
26.5k
        return (dev);
546
26.5k
}
547
548
fido_dev_t *
549
fido_dev_new_with_info(const fido_dev_info_t *di)
550
0
{
551
0
        fido_dev_t *dev;
552
0
553
0
        if ((dev = calloc(1, sizeof(*dev))) == NULL)
554
0
                return (NULL);
555
0
556
0
        dev->cid = CTAP_CID_BROADCAST;
557
0
558
0
        if (di->io.open == NULL || di->io.close == NULL ||
559
0
            di->io.read == NULL || di->io.write == NULL) {
560
0
                fido_log_debug("%s: NULL function", __func__);
561
0
                fido_dev_free(&dev);
562
0
                return (NULL);
563
0
        }
564
0
565
0
        dev->io = di->io;
566
0
        dev->transport = di->transport;
567
0
568
0
        if ((dev->path = strdup(di->path)) == NULL) {
569
0
                fido_log_debug("%s: strdup", __func__);
570
0
                fido_dev_free(&dev);
571
0
                return (NULL);
572
0
        }
573
0
574
0
        return (dev);
575
0
}
576
577
void
578
fido_dev_free(fido_dev_t **dev_p)
579
32.8k
{
580
32.8k
        fido_dev_t *dev;
581
32.8k
582
32.8k
        if (dev_p == NULL || (dev = *dev_p) == NULL)
583
32.8k
                return;
584
26.5k
585
26.5k
        free(dev->path);
586
26.5k
        free(dev);
587
26.5k
588
26.5k
        *dev_p = NULL;
589
26.5k
}
590
591
uint8_t
592
fido_dev_protocol(const fido_dev_t *dev)
593
247
{
594
247
        return (dev->attr.protocol);
595
247
}
596
597
uint8_t
598
fido_dev_major(const fido_dev_t *dev)
599
247
{
600
247
        return (dev->attr.major);
601
247
}
602
603
uint8_t
604
fido_dev_minor(const fido_dev_t *dev)
605
247
{
606
247
        return (dev->attr.minor);
607
247
}
608
609
uint8_t
610
fido_dev_build(const fido_dev_t *dev)
611
247
{
612
247
        return (dev->attr.build);
613
247
}
614
615
uint8_t
616
fido_dev_flags(const fido_dev_t *dev)
617
247
{
618
247
        return (dev->attr.flags);
619
247
}
620
621
bool
622
fido_dev_is_fido2(const fido_dev_t *dev)
623
35.5k
{
624
35.5k
        return (dev->attr.flags & FIDO_CAP_CBOR);
625
35.5k
}
626
627
bool
628
fido_dev_supports_pin(const fido_dev_t *dev)
629
2.17k
{
630
2.17k
        return (dev->flags & (FIDO_DEV_PIN_SET|FIDO_DEV_PIN_UNSET));
631
2.17k
}
632
633
bool
634
fido_dev_has_pin(const fido_dev_t *dev)
635
2.09k
{
636
2.09k
        return (dev->flags & FIDO_DEV_PIN_SET);
637
2.09k
}
638
639
bool
640
fido_dev_supports_cred_prot(const fido_dev_t *dev)
641
2.02k
{
642
2.02k
        return (dev->flags & FIDO_DEV_CRED_PROT);
643
2.02k
}
644
645
void
646
fido_dev_force_u2f(fido_dev_t *dev)
647
5.13k
{
648
5.13k
        dev->attr.flags &= (uint8_t)~FIDO_CAP_CBOR;
649
5.13k
        dev->flags = 0;
650
5.13k
}
651
652
void
653
fido_dev_force_fido2(fido_dev_t *dev)
654
0
{
655
0
        dev->attr.flags |= FIDO_CAP_CBOR;
656
0
}