Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libfido2/src/credman.c
39478 views
1
/*
2
* Copyright (c) 2019-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 <openssl/sha.h>
9
10
#include "fido.h"
11
#include "fido/credman.h"
12
#include "fido/es256.h"
13
14
#define CMD_CRED_METADATA 0x01
15
#define CMD_RP_BEGIN 0x02
16
#define CMD_RP_NEXT 0x03
17
#define CMD_RK_BEGIN 0x04
18
#define CMD_RK_NEXT 0x05
19
#define CMD_DELETE_CRED 0x06
20
#define CMD_UPDATE_CRED 0x07
21
22
static int
23
credman_grow_array(void **ptr, size_t *n_alloc, const size_t *n_rx, size_t n,
24
size_t size)
25
{
26
void *new_ptr;
27
28
#ifdef FIDO_FUZZ
29
if (n > UINT8_MAX) {
30
fido_log_debug("%s: n > UINT8_MAX", __func__);
31
return (-1);
32
}
33
#endif
34
35
if (n < *n_alloc)
36
return (0);
37
38
/* sanity check */
39
if (*n_rx > 0 || *n_rx > *n_alloc || n < *n_alloc) {
40
fido_log_debug("%s: n=%zu, n_rx=%zu, n_alloc=%zu", __func__, n,
41
*n_rx, *n_alloc);
42
return (-1);
43
}
44
45
if ((new_ptr = recallocarray(*ptr, *n_alloc, n, size)) == NULL)
46
return (-1);
47
48
*ptr = new_ptr;
49
*n_alloc = n;
50
51
return (0);
52
}
53
54
static int
55
credman_prepare_hmac(uint8_t cmd, const void *body, cbor_item_t **param,
56
fido_blob_t *hmac_data)
57
{
58
cbor_item_t *param_cbor[3];
59
const fido_cred_t *cred;
60
size_t n;
61
int ok = -1;
62
63
memset(&param_cbor, 0, sizeof(param_cbor));
64
65
if (body == NULL)
66
return (fido_blob_set(hmac_data, &cmd, sizeof(cmd)));
67
68
switch (cmd) {
69
case CMD_RK_BEGIN:
70
n = 1;
71
if ((param_cbor[0] = fido_blob_encode(body)) == NULL) {
72
fido_log_debug("%s: cbor encode", __func__);
73
goto fail;
74
}
75
break;
76
case CMD_DELETE_CRED:
77
n = 2;
78
if ((param_cbor[1] = cbor_encode_pubkey(body)) == NULL) {
79
fido_log_debug("%s: cbor encode", __func__);
80
goto fail;
81
}
82
break;
83
case CMD_UPDATE_CRED:
84
n = 3;
85
cred = body;
86
param_cbor[1] = cbor_encode_pubkey(&cred->attcred.id);
87
param_cbor[2] = cbor_encode_user_entity(&cred->user);
88
if (param_cbor[1] == NULL || param_cbor[2] == NULL) {
89
fido_log_debug("%s: cbor encode", __func__);
90
goto fail;
91
}
92
break;
93
default:
94
fido_log_debug("%s: unknown cmd=0x%02x", __func__, cmd);
95
return (-1);
96
}
97
98
if ((*param = cbor_flatten_vector(param_cbor, n)) == NULL) {
99
fido_log_debug("%s: cbor_flatten_vector", __func__);
100
goto fail;
101
}
102
if (cbor_build_frame(cmd, param_cbor, n, hmac_data) < 0) {
103
fido_log_debug("%s: cbor_build_frame", __func__);
104
goto fail;
105
}
106
107
ok = 0;
108
fail:
109
cbor_vector_free(param_cbor, nitems(param_cbor));
110
111
return (ok);
112
}
113
114
static int
115
credman_tx(fido_dev_t *dev, uint8_t subcmd, const void *param, const char *pin,
116
const char *rp_id, fido_opt_t uv, int *ms)
117
{
118
fido_blob_t f;
119
fido_blob_t *ecdh = NULL;
120
fido_blob_t hmac;
121
es256_pk_t *pk = NULL;
122
cbor_item_t *argv[4];
123
const uint8_t cmd = CTAP_CBOR_CRED_MGMT_PRE;
124
int r = FIDO_ERR_INTERNAL;
125
126
memset(&f, 0, sizeof(f));
127
memset(&hmac, 0, sizeof(hmac));
128
memset(&argv, 0, sizeof(argv));
129
130
if (fido_dev_is_fido2(dev) == false) {
131
fido_log_debug("%s: fido_dev_is_fido2", __func__);
132
r = FIDO_ERR_INVALID_COMMAND;
133
goto fail;
134
}
135
136
/* subCommand */
137
if ((argv[0] = cbor_build_uint8(subcmd)) == NULL) {
138
fido_log_debug("%s: cbor encode", __func__);
139
goto fail;
140
}
141
142
/* pinProtocol, pinAuth */
143
if (pin != NULL || uv == FIDO_OPT_TRUE) {
144
if (credman_prepare_hmac(subcmd, param, &argv[1], &hmac) < 0) {
145
fido_log_debug("%s: credman_prepare_hmac", __func__);
146
goto fail;
147
}
148
if ((r = fido_do_ecdh(dev, &pk, &ecdh, ms)) != FIDO_OK) {
149
fido_log_debug("%s: fido_do_ecdh", __func__);
150
goto fail;
151
}
152
if ((r = cbor_add_uv_params(dev, cmd, &hmac, pk, ecdh, pin,
153
rp_id, &argv[3], &argv[2], ms)) != FIDO_OK) {
154
fido_log_debug("%s: cbor_add_uv_params", __func__);
155
goto fail;
156
}
157
}
158
159
/* framing and transmission */
160
if (cbor_build_frame(cmd, argv, nitems(argv), &f) < 0 ||
161
fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) {
162
fido_log_debug("%s: fido_tx", __func__);
163
r = FIDO_ERR_TX;
164
goto fail;
165
}
166
167
r = FIDO_OK;
168
fail:
169
es256_pk_free(&pk);
170
fido_blob_free(&ecdh);
171
cbor_vector_free(argv, nitems(argv));
172
free(f.ptr);
173
free(hmac.ptr);
174
175
return (r);
176
}
177
178
static int
179
credman_parse_metadata(const cbor_item_t *key, const cbor_item_t *val,
180
void *arg)
181
{
182
fido_credman_metadata_t *metadata = arg;
183
184
if (cbor_isa_uint(key) == false ||
185
cbor_int_get_width(key) != CBOR_INT_8) {
186
fido_log_debug("%s: cbor type", __func__);
187
return (0); /* ignore */
188
}
189
190
switch (cbor_get_uint8(key)) {
191
case 1:
192
return (cbor_decode_uint64(val, &metadata->rk_existing));
193
case 2:
194
return (cbor_decode_uint64(val, &metadata->rk_remaining));
195
default:
196
fido_log_debug("%s: cbor type", __func__);
197
return (0); /* ignore */
198
}
199
}
200
201
static int
202
credman_rx_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata, int *ms)
203
{
204
unsigned char *msg;
205
int msglen;
206
int r;
207
208
memset(metadata, 0, sizeof(*metadata));
209
210
if ((msg = malloc(FIDO_MAXMSG)) == NULL) {
211
r = FIDO_ERR_INTERNAL;
212
goto out;
213
}
214
215
if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) {
216
fido_log_debug("%s: fido_rx", __func__);
217
r = FIDO_ERR_RX;
218
goto out;
219
}
220
221
if ((r = cbor_parse_reply(msg, (size_t)msglen, metadata,
222
credman_parse_metadata)) != FIDO_OK) {
223
fido_log_debug("%s: credman_parse_metadata", __func__);
224
goto out;
225
}
226
227
r = FIDO_OK;
228
out:
229
freezero(msg, FIDO_MAXMSG);
230
231
return (r);
232
}
233
234
static int
235
credman_get_metadata_wait(fido_dev_t *dev, fido_credman_metadata_t *metadata,
236
const char *pin, int *ms)
237
{
238
int r;
239
240
if ((r = credman_tx(dev, CMD_CRED_METADATA, NULL, pin, NULL,
241
FIDO_OPT_TRUE, ms)) != FIDO_OK ||
242
(r = credman_rx_metadata(dev, metadata, ms)) != FIDO_OK)
243
return (r);
244
245
return (FIDO_OK);
246
}
247
248
int
249
fido_credman_get_dev_metadata(fido_dev_t *dev, fido_credman_metadata_t *metadata,
250
const char *pin)
251
{
252
int ms = dev->timeout_ms;
253
254
return (credman_get_metadata_wait(dev, metadata, pin, &ms));
255
}
256
257
static int
258
credman_parse_rk(const cbor_item_t *key, const cbor_item_t *val, void *arg)
259
{
260
fido_cred_t *cred = arg;
261
uint64_t prot;
262
263
if (cbor_isa_uint(key) == false ||
264
cbor_int_get_width(key) != CBOR_INT_8) {
265
fido_log_debug("%s: cbor type", __func__);
266
return (0); /* ignore */
267
}
268
269
switch (cbor_get_uint8(key)) {
270
case 6:
271
return (cbor_decode_user(val, &cred->user));
272
case 7:
273
return (cbor_decode_cred_id(val, &cred->attcred.id));
274
case 8:
275
if (cbor_decode_pubkey(val, &cred->attcred.type,
276
&cred->attcred.pubkey) < 0)
277
return (-1);
278
cred->type = cred->attcred.type; /* XXX */
279
return (0);
280
case 10:
281
if (cbor_decode_uint64(val, &prot) < 0 || prot > INT_MAX ||
282
fido_cred_set_prot(cred, (int)prot) != FIDO_OK)
283
return (-1);
284
return (0);
285
case 11:
286
return (fido_blob_decode(val, &cred->largeblob_key));
287
default:
288
fido_log_debug("%s: cbor type", __func__);
289
return (0); /* ignore */
290
}
291
}
292
293
static void
294
credman_reset_rk(fido_credman_rk_t *rk)
295
{
296
for (size_t i = 0; i < rk->n_alloc; i++) {
297
fido_cred_reset_tx(&rk->ptr[i]);
298
fido_cred_reset_rx(&rk->ptr[i]);
299
}
300
301
free(rk->ptr);
302
rk->ptr = NULL;
303
memset(rk, 0, sizeof(*rk));
304
}
305
306
static int
307
credman_parse_rk_count(const cbor_item_t *key, const cbor_item_t *val,
308
void *arg)
309
{
310
fido_credman_rk_t *rk = arg;
311
uint64_t n;
312
313
/* totalCredentials */
314
if (cbor_isa_uint(key) == false ||
315
cbor_int_get_width(key) != CBOR_INT_8 ||
316
cbor_get_uint8(key) != 9) {
317
fido_log_debug("%s: cbor_type", __func__);
318
return (0); /* ignore */
319
}
320
321
if (cbor_decode_uint64(val, &n) < 0 || n > SIZE_MAX) {
322
fido_log_debug("%s: cbor_decode_uint64", __func__);
323
return (-1);
324
}
325
326
if (credman_grow_array((void **)&rk->ptr, &rk->n_alloc, &rk->n_rx,
327
(size_t)n, sizeof(*rk->ptr)) < 0) {
328
fido_log_debug("%s: credman_grow_array", __func__);
329
return (-1);
330
}
331
332
return (0);
333
}
334
335
static int
336
credman_rx_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int *ms)
337
{
338
unsigned char *msg;
339
int msglen;
340
int r;
341
342
credman_reset_rk(rk);
343
344
if ((msg = malloc(FIDO_MAXMSG)) == NULL) {
345
r = FIDO_ERR_INTERNAL;
346
goto out;
347
}
348
349
if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) {
350
fido_log_debug("%s: fido_rx", __func__);
351
r = FIDO_ERR_RX;
352
goto out;
353
}
354
355
/* adjust as needed */
356
if ((r = cbor_parse_reply(msg, (size_t)msglen, rk,
357
credman_parse_rk_count)) != FIDO_OK) {
358
fido_log_debug("%s: credman_parse_rk_count", __func__);
359
goto out;
360
}
361
362
if (rk->n_alloc == 0) {
363
fido_log_debug("%s: n_alloc=0", __func__);
364
r = FIDO_OK;
365
goto out;
366
}
367
368
/* parse the first rk */
369
if ((r = cbor_parse_reply(msg, (size_t)msglen, &rk->ptr[0],
370
credman_parse_rk)) != FIDO_OK) {
371
fido_log_debug("%s: credman_parse_rk", __func__);
372
goto out;
373
}
374
rk->n_rx = 1;
375
376
r = FIDO_OK;
377
out:
378
freezero(msg, FIDO_MAXMSG);
379
380
return (r);
381
}
382
383
static int
384
credman_rx_next_rk(fido_dev_t *dev, fido_credman_rk_t *rk, int *ms)
385
{
386
unsigned char *msg;
387
int msglen;
388
int r;
389
390
if ((msg = malloc(FIDO_MAXMSG)) == NULL) {
391
r = FIDO_ERR_INTERNAL;
392
goto out;
393
}
394
395
if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) {
396
fido_log_debug("%s: fido_rx", __func__);
397
r = FIDO_ERR_RX;
398
goto out;
399
}
400
401
/* sanity check */
402
if (rk->n_rx >= rk->n_alloc) {
403
fido_log_debug("%s: n_rx=%zu, n_alloc=%zu", __func__, rk->n_rx,
404
rk->n_alloc);
405
r = FIDO_ERR_INTERNAL;
406
goto out;
407
}
408
409
if ((r = cbor_parse_reply(msg, (size_t)msglen, &rk->ptr[rk->n_rx],
410
credman_parse_rk)) != FIDO_OK) {
411
fido_log_debug("%s: credman_parse_rk", __func__);
412
goto out;
413
}
414
415
r = FIDO_OK;
416
out:
417
freezero(msg, FIDO_MAXMSG);
418
419
return (r);
420
}
421
422
static int
423
credman_get_rk_wait(fido_dev_t *dev, const char *rp_id, fido_credman_rk_t *rk,
424
const char *pin, int *ms)
425
{
426
fido_blob_t rp_dgst;
427
uint8_t dgst[SHA256_DIGEST_LENGTH];
428
int r;
429
430
if (SHA256((const unsigned char *)rp_id, strlen(rp_id), dgst) != dgst) {
431
fido_log_debug("%s: sha256", __func__);
432
return (FIDO_ERR_INTERNAL);
433
}
434
435
rp_dgst.ptr = dgst;
436
rp_dgst.len = sizeof(dgst);
437
438
if ((r = credman_tx(dev, CMD_RK_BEGIN, &rp_dgst, pin, rp_id,
439
FIDO_OPT_TRUE, ms)) != FIDO_OK ||
440
(r = credman_rx_rk(dev, rk, ms)) != FIDO_OK)
441
return (r);
442
443
while (rk->n_rx < rk->n_alloc) {
444
if ((r = credman_tx(dev, CMD_RK_NEXT, NULL, NULL, NULL,
445
FIDO_OPT_FALSE, ms)) != FIDO_OK ||
446
(r = credman_rx_next_rk(dev, rk, ms)) != FIDO_OK)
447
return (r);
448
rk->n_rx++;
449
}
450
451
return (FIDO_OK);
452
}
453
454
int
455
fido_credman_get_dev_rk(fido_dev_t *dev, const char *rp_id,
456
fido_credman_rk_t *rk, const char *pin)
457
{
458
int ms = dev->timeout_ms;
459
460
return (credman_get_rk_wait(dev, rp_id, rk, pin, &ms));
461
}
462
463
static int
464
credman_del_rk_wait(fido_dev_t *dev, const unsigned char *cred_id,
465
size_t cred_id_len, const char *pin, int *ms)
466
{
467
fido_blob_t cred;
468
int r;
469
470
memset(&cred, 0, sizeof(cred));
471
472
if (fido_blob_set(&cred, cred_id, cred_id_len) < 0)
473
return (FIDO_ERR_INVALID_ARGUMENT);
474
475
if ((r = credman_tx(dev, CMD_DELETE_CRED, &cred, pin, NULL,
476
FIDO_OPT_TRUE, ms)) != FIDO_OK ||
477
(r = fido_rx_cbor_status(dev, ms)) != FIDO_OK)
478
goto fail;
479
480
r = FIDO_OK;
481
fail:
482
free(cred.ptr);
483
484
return (r);
485
}
486
487
int
488
fido_credman_del_dev_rk(fido_dev_t *dev, const unsigned char *cred_id,
489
size_t cred_id_len, const char *pin)
490
{
491
int ms = dev->timeout_ms;
492
493
return (credman_del_rk_wait(dev, cred_id, cred_id_len, pin, &ms));
494
}
495
496
static int
497
credman_parse_rp(const cbor_item_t *key, const cbor_item_t *val, void *arg)
498
{
499
struct fido_credman_single_rp *rp = arg;
500
501
if (cbor_isa_uint(key) == false ||
502
cbor_int_get_width(key) != CBOR_INT_8) {
503
fido_log_debug("%s: cbor type", __func__);
504
return (0); /* ignore */
505
}
506
507
switch (cbor_get_uint8(key)) {
508
case 3:
509
return (cbor_decode_rp_entity(val, &rp->rp_entity));
510
case 4:
511
return (fido_blob_decode(val, &rp->rp_id_hash));
512
default:
513
fido_log_debug("%s: cbor type", __func__);
514
return (0); /* ignore */
515
}
516
}
517
518
static void
519
credman_reset_rp(fido_credman_rp_t *rp)
520
{
521
for (size_t i = 0; i < rp->n_alloc; i++) {
522
free(rp->ptr[i].rp_entity.id);
523
free(rp->ptr[i].rp_entity.name);
524
rp->ptr[i].rp_entity.id = NULL;
525
rp->ptr[i].rp_entity.name = NULL;
526
fido_blob_reset(&rp->ptr[i].rp_id_hash);
527
}
528
529
free(rp->ptr);
530
rp->ptr = NULL;
531
memset(rp, 0, sizeof(*rp));
532
}
533
534
static int
535
credman_parse_rp_count(const cbor_item_t *key, const cbor_item_t *val,
536
void *arg)
537
{
538
fido_credman_rp_t *rp = arg;
539
uint64_t n;
540
541
/* totalRPs */
542
if (cbor_isa_uint(key) == false ||
543
cbor_int_get_width(key) != CBOR_INT_8 ||
544
cbor_get_uint8(key) != 5) {
545
fido_log_debug("%s: cbor_type", __func__);
546
return (0); /* ignore */
547
}
548
549
if (cbor_decode_uint64(val, &n) < 0 || n > SIZE_MAX) {
550
fido_log_debug("%s: cbor_decode_uint64", __func__);
551
return (-1);
552
}
553
554
if (credman_grow_array((void **)&rp->ptr, &rp->n_alloc, &rp->n_rx,
555
(size_t)n, sizeof(*rp->ptr)) < 0) {
556
fido_log_debug("%s: credman_grow_array", __func__);
557
return (-1);
558
}
559
560
return (0);
561
}
562
563
static int
564
credman_rx_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int *ms)
565
{
566
unsigned char *msg;
567
int msglen;
568
int r;
569
570
credman_reset_rp(rp);
571
572
if ((msg = malloc(FIDO_MAXMSG)) == NULL) {
573
r = FIDO_ERR_INTERNAL;
574
goto out;
575
}
576
577
if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) {
578
fido_log_debug("%s: fido_rx", __func__);
579
r = FIDO_ERR_RX;
580
goto out;
581
}
582
583
/* adjust as needed */
584
if ((r = cbor_parse_reply(msg, (size_t)msglen, rp,
585
credman_parse_rp_count)) != FIDO_OK) {
586
fido_log_debug("%s: credman_parse_rp_count", __func__);
587
goto out;
588
}
589
590
if (rp->n_alloc == 0) {
591
fido_log_debug("%s: n_alloc=0", __func__);
592
r = FIDO_OK;
593
goto out;
594
}
595
596
/* parse the first rp */
597
if ((r = cbor_parse_reply(msg, (size_t)msglen, &rp->ptr[0],
598
credman_parse_rp)) != FIDO_OK) {
599
fido_log_debug("%s: credman_parse_rp", __func__);
600
goto out;
601
}
602
rp->n_rx = 1;
603
604
r = FIDO_OK;
605
out:
606
freezero(msg, FIDO_MAXMSG);
607
608
return (r);
609
}
610
611
static int
612
credman_rx_next_rp(fido_dev_t *dev, fido_credman_rp_t *rp, int *ms)
613
{
614
unsigned char *msg;
615
int msglen;
616
int r;
617
618
if ((msg = malloc(FIDO_MAXMSG)) == NULL) {
619
r = FIDO_ERR_INTERNAL;
620
goto out;
621
}
622
623
if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) {
624
fido_log_debug("%s: fido_rx", __func__);
625
r = FIDO_ERR_RX;
626
goto out;
627
}
628
629
/* sanity check */
630
if (rp->n_rx >= rp->n_alloc) {
631
fido_log_debug("%s: n_rx=%zu, n_alloc=%zu", __func__, rp->n_rx,
632
rp->n_alloc);
633
r = FIDO_ERR_INTERNAL;
634
goto out;
635
}
636
637
if ((r = cbor_parse_reply(msg, (size_t)msglen, &rp->ptr[rp->n_rx],
638
credman_parse_rp)) != FIDO_OK) {
639
fido_log_debug("%s: credman_parse_rp", __func__);
640
goto out;
641
}
642
643
r = FIDO_OK;
644
out:
645
freezero(msg, FIDO_MAXMSG);
646
647
return (r);
648
}
649
650
static int
651
credman_get_rp_wait(fido_dev_t *dev, fido_credman_rp_t *rp, const char *pin,
652
int *ms)
653
{
654
int r;
655
656
if ((r = credman_tx(dev, CMD_RP_BEGIN, NULL, pin, NULL,
657
FIDO_OPT_TRUE, ms)) != FIDO_OK ||
658
(r = credman_rx_rp(dev, rp, ms)) != FIDO_OK)
659
return (r);
660
661
while (rp->n_rx < rp->n_alloc) {
662
if ((r = credman_tx(dev, CMD_RP_NEXT, NULL, NULL, NULL,
663
FIDO_OPT_FALSE, ms)) != FIDO_OK ||
664
(r = credman_rx_next_rp(dev, rp, ms)) != FIDO_OK)
665
return (r);
666
rp->n_rx++;
667
}
668
669
return (FIDO_OK);
670
}
671
672
int
673
fido_credman_get_dev_rp(fido_dev_t *dev, fido_credman_rp_t *rp, const char *pin)
674
{
675
int ms = dev->timeout_ms;
676
677
return (credman_get_rp_wait(dev, rp, pin, &ms));
678
}
679
680
static int
681
credman_set_dev_rk_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin,
682
int *ms)
683
{
684
int r;
685
686
if ((r = credman_tx(dev, CMD_UPDATE_CRED, cred, pin, NULL,
687
FIDO_OPT_TRUE, ms)) != FIDO_OK ||
688
(r = fido_rx_cbor_status(dev, ms)) != FIDO_OK)
689
return (r);
690
691
return (FIDO_OK);
692
}
693
694
int
695
fido_credman_set_dev_rk(fido_dev_t *dev, fido_cred_t *cred, const char *pin)
696
{
697
int ms = dev->timeout_ms;
698
699
return (credman_set_dev_rk_wait(dev, cred, pin, &ms));
700
}
701
702
fido_credman_rk_t *
703
fido_credman_rk_new(void)
704
{
705
return (calloc(1, sizeof(fido_credman_rk_t)));
706
}
707
708
void
709
fido_credman_rk_free(fido_credman_rk_t **rk_p)
710
{
711
fido_credman_rk_t *rk;
712
713
if (rk_p == NULL || (rk = *rk_p) == NULL)
714
return;
715
716
credman_reset_rk(rk);
717
free(rk);
718
*rk_p = NULL;
719
}
720
721
size_t
722
fido_credman_rk_count(const fido_credman_rk_t *rk)
723
{
724
return (rk->n_rx);
725
}
726
727
const fido_cred_t *
728
fido_credman_rk(const fido_credman_rk_t *rk, size_t idx)
729
{
730
if (idx >= rk->n_alloc)
731
return (NULL);
732
733
return (&rk->ptr[idx]);
734
}
735
736
fido_credman_metadata_t *
737
fido_credman_metadata_new(void)
738
{
739
return (calloc(1, sizeof(fido_credman_metadata_t)));
740
}
741
742
void
743
fido_credman_metadata_free(fido_credman_metadata_t **metadata_p)
744
{
745
fido_credman_metadata_t *metadata;
746
747
if (metadata_p == NULL || (metadata = *metadata_p) == NULL)
748
return;
749
750
free(metadata);
751
*metadata_p = NULL;
752
}
753
754
uint64_t
755
fido_credman_rk_existing(const fido_credman_metadata_t *metadata)
756
{
757
return (metadata->rk_existing);
758
}
759
760
uint64_t
761
fido_credman_rk_remaining(const fido_credman_metadata_t *metadata)
762
{
763
return (metadata->rk_remaining);
764
}
765
766
fido_credman_rp_t *
767
fido_credman_rp_new(void)
768
{
769
return (calloc(1, sizeof(fido_credman_rp_t)));
770
}
771
772
void
773
fido_credman_rp_free(fido_credman_rp_t **rp_p)
774
{
775
fido_credman_rp_t *rp;
776
777
if (rp_p == NULL || (rp = *rp_p) == NULL)
778
return;
779
780
credman_reset_rp(rp);
781
free(rp);
782
*rp_p = NULL;
783
}
784
785
size_t
786
fido_credman_rp_count(const fido_credman_rp_t *rp)
787
{
788
return (rp->n_rx);
789
}
790
791
const char *
792
fido_credman_rp_id(const fido_credman_rp_t *rp, size_t idx)
793
{
794
if (idx >= rp->n_alloc)
795
return (NULL);
796
797
return (rp->ptr[idx].rp_entity.id);
798
}
799
800
const char *
801
fido_credman_rp_name(const fido_credman_rp_t *rp, size_t idx)
802
{
803
if (idx >= rp->n_alloc)
804
return (NULL);
805
806
return (rp->ptr[idx].rp_entity.name);
807
}
808
809
size_t
810
fido_credman_rp_id_hash_len(const fido_credman_rp_t *rp, size_t idx)
811
{
812
if (idx >= rp->n_alloc)
813
return (0);
814
815
return (rp->ptr[idx].rp_id_hash.len);
816
}
817
818
const unsigned char *
819
fido_credman_rp_id_hash_ptr(const fido_credman_rp_t *rp, size_t idx)
820
{
821
if (idx >= rp->n_alloc)
822
return (NULL);
823
824
return (rp->ptr[idx].rp_id_hash.ptr);
825
}
826
827