Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libfido2/examples/info.c
39483 views
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
#include <stdbool.h>
10
#include <stdint.h>
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <string.h>
14
15
#include "../openbsd-compat/openbsd-compat.h"
16
17
/*
18
* Pretty-print a device's capabilities flags and return the result.
19
*/
20
static void
21
format_flags(char *ret, size_t retlen, uint8_t flags)
22
{
23
memset(ret, 0, retlen);
24
25
if (flags & FIDO_CAP_WINK) {
26
if (strlcat(ret, "wink,", retlen) >= retlen)
27
goto toolong;
28
} else {
29
if (strlcat(ret, "nowink,", retlen) >= retlen)
30
goto toolong;
31
}
32
33
if (flags & FIDO_CAP_CBOR) {
34
if (strlcat(ret, " cbor,", retlen) >= retlen)
35
goto toolong;
36
} else {
37
if (strlcat(ret, " nocbor,", retlen) >= retlen)
38
goto toolong;
39
}
40
41
if (flags & FIDO_CAP_NMSG) {
42
if (strlcat(ret, " nomsg", retlen) >= retlen)
43
goto toolong;
44
} else {
45
if (strlcat(ret, " msg", retlen) >= retlen)
46
goto toolong;
47
}
48
49
return;
50
toolong:
51
strlcpy(ret, "toolong", retlen);
52
}
53
54
/*
55
* Print a FIDO device's attributes on stdout.
56
*/
57
static void
58
print_attr(const fido_dev_t *dev)
59
{
60
char flags_txt[128];
61
62
printf("proto: 0x%02x\n", fido_dev_protocol(dev));
63
printf("major: 0x%02x\n", fido_dev_major(dev));
64
printf("minor: 0x%02x\n", fido_dev_minor(dev));
65
printf("build: 0x%02x\n", fido_dev_build(dev));
66
67
format_flags(flags_txt, sizeof(flags_txt), fido_dev_flags(dev));
68
printf("caps: 0x%02x (%s)\n", fido_dev_flags(dev), flags_txt);
69
}
70
71
/*
72
* Auxiliary function to print an array of strings on stdout.
73
*/
74
static void
75
print_str_array(const char *label, char * const *sa, size_t len)
76
{
77
if (len == 0)
78
return;
79
80
printf("%s strings: ", label);
81
82
for (size_t i = 0; i < len; i++)
83
printf("%s%s", i > 0 ? ", " : "", sa[i]);
84
85
printf("\n");
86
}
87
88
/*
89
* Auxiliary function to print (char *, bool) pairs on stdout.
90
*/
91
static void
92
print_opt_array(const char *label, char * const *name, const bool *value,
93
size_t len)
94
{
95
if (len == 0)
96
return;
97
98
printf("%s: ", label);
99
100
for (size_t i = 0; i < len; i++)
101
printf("%s%s%s", i > 0 ? ", " : "",
102
value[i] ? "" : "no", name[i]);
103
104
printf("\n");
105
}
106
107
/*
108
* Auxiliary function to print (char *, uint64_t) pairs on stdout.
109
*/
110
static void
111
print_cert_array(const char *label, char * const *name, const uint64_t *value,
112
size_t len)
113
{
114
if (len == 0)
115
return;
116
117
printf("%s: ", label);
118
119
for (size_t i = 0; i < len; i++)
120
printf("%s%s %llu", i > 0 ? ", " : "", name[i],
121
(unsigned long long)value[i]);
122
123
printf("\n");
124
}
125
126
/*
127
* Auxiliary function to print a list of supported COSE algorithms on stdout.
128
*/
129
static void
130
print_algorithms(const fido_cbor_info_t *ci)
131
{
132
const char *cose, *type;
133
size_t len;
134
135
if ((len = fido_cbor_info_algorithm_count(ci)) == 0)
136
return;
137
138
printf("algorithms: ");
139
140
for (size_t i = 0; i < len; i++) {
141
cose = type = "unknown";
142
switch (fido_cbor_info_algorithm_cose(ci, i)) {
143
case COSE_ES256:
144
cose = "es256";
145
break;
146
case COSE_ES384:
147
cose = "es384";
148
break;
149
case COSE_RS256:
150
cose = "rs256";
151
break;
152
case COSE_EDDSA:
153
cose = "eddsa";
154
break;
155
}
156
if (fido_cbor_info_algorithm_type(ci, i) != NULL)
157
type = fido_cbor_info_algorithm_type(ci, i);
158
printf("%s%s (%s)", i > 0 ? ", " : "", cose, type);
159
}
160
161
printf("\n");
162
}
163
164
/*
165
* Auxiliary function to print an authenticator's AAGUID on stdout.
166
*/
167
static void
168
print_aaguid(const unsigned char *buf, size_t buflen)
169
{
170
printf("aaguid: ");
171
172
while (buflen--)
173
printf("%02x", *buf++);
174
175
printf("\n");
176
}
177
178
/*
179
* Auxiliary function to print an authenticator's maximum message size on
180
* stdout.
181
*/
182
static void
183
print_maxmsgsiz(uint64_t maxmsgsiz)
184
{
185
printf("maxmsgsiz: %d\n", (int)maxmsgsiz);
186
}
187
188
/*
189
* Auxiliary function to print an authenticator's maximum number of credentials
190
* in a credential list on stdout.
191
*/
192
static void
193
print_maxcredcntlst(uint64_t maxcredcntlst)
194
{
195
printf("maxcredcntlst: %d\n", (int)maxcredcntlst);
196
}
197
198
/*
199
* Auxiliary function to print an authenticator's maximum credential ID length
200
* on stdout.
201
*/
202
static void
203
print_maxcredidlen(uint64_t maxcredidlen)
204
{
205
printf("maxcredlen: %d\n", (int)maxcredidlen);
206
}
207
208
/*
209
* Auxiliary function to print the maximum size of an authenticator's
210
* serialized largeBlob array.
211
*/
212
static void
213
print_maxlargeblob(uint64_t maxlargeblob)
214
{
215
printf("maxlargeblob: %d\n", (int)maxlargeblob);
216
}
217
218
/*
219
* Auxiliary function to print the authenticator's estimated number of
220
* remaining resident credentials.
221
*/
222
static void
223
print_rk_remaining(int64_t rk_remaining)
224
{
225
printf("remaining rk(s): ");
226
227
if (rk_remaining == -1)
228
printf("undefined\n");
229
else
230
printf("%d\n", (int)rk_remaining);
231
}
232
233
/*
234
* Auxiliary function to print the minimum pin length observed by the
235
* authenticator.
236
*/
237
static void
238
print_minpinlen(uint64_t minpinlen)
239
{
240
printf("minpinlen: %d\n", (int)minpinlen);
241
}
242
243
/*
244
* Auxiliary function to print the authenticator's preferred (platform)
245
* UV attempts.
246
*/
247
static void
248
print_uv_attempts(uint64_t uv_attempts)
249
{
250
printf("platform uv attempt(s): %d\n", (int)uv_attempts);
251
}
252
253
/*
254
* Auxiliary function to print an authenticator's firmware version on stdout.
255
*/
256
static void
257
print_fwversion(uint64_t fwversion)
258
{
259
printf("fwversion: 0x%x\n", (int)fwversion);
260
}
261
262
/*
263
* Auxiliary function to print an array of bytes on stdout.
264
*/
265
static void
266
print_byte_array(const char *label, const uint8_t *ba, size_t len)
267
{
268
if (len == 0)
269
return;
270
271
printf("%s: ", label);
272
273
for (size_t i = 0; i < len; i++)
274
printf("%s%u", i > 0 ? ", " : "", (unsigned)ba[i]);
275
276
printf("\n");
277
}
278
279
static void
280
getinfo(const char *path)
281
{
282
fido_dev_t *dev;
283
fido_cbor_info_t *ci;
284
int r;
285
286
fido_init(0);
287
288
if ((dev = fido_dev_new()) == NULL)
289
errx(1, "fido_dev_new");
290
if ((r = fido_dev_open(dev, path)) != FIDO_OK)
291
errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r);
292
293
print_attr(dev);
294
295
if (fido_dev_is_fido2(dev) == false)
296
goto end;
297
if ((ci = fido_cbor_info_new()) == NULL)
298
errx(1, "fido_cbor_info_new");
299
if ((r = fido_dev_get_cbor_info(dev, ci)) != FIDO_OK)
300
errx(1, "fido_dev_get_cbor_info: %s (0x%x)", fido_strerr(r), r);
301
302
/* print supported protocol versions */
303
print_str_array("version", fido_cbor_info_versions_ptr(ci),
304
fido_cbor_info_versions_len(ci));
305
306
/* print supported extensions */
307
print_str_array("extension", fido_cbor_info_extensions_ptr(ci),
308
fido_cbor_info_extensions_len(ci));
309
310
/* print supported transports */
311
print_str_array("transport", fido_cbor_info_transports_ptr(ci),
312
fido_cbor_info_transports_len(ci));
313
314
/* print supported algorithms */
315
print_algorithms(ci);
316
317
/* print aaguid */
318
print_aaguid(fido_cbor_info_aaguid_ptr(ci),
319
fido_cbor_info_aaguid_len(ci));
320
321
/* print supported options */
322
print_opt_array("options", fido_cbor_info_options_name_ptr(ci),
323
fido_cbor_info_options_value_ptr(ci),
324
fido_cbor_info_options_len(ci));
325
326
/* print certifications */
327
print_cert_array("certifications", fido_cbor_info_certs_name_ptr(ci),
328
fido_cbor_info_certs_value_ptr(ci),
329
fido_cbor_info_certs_len(ci));
330
331
/* print firmware version */
332
print_fwversion(fido_cbor_info_fwversion(ci));
333
334
/* print maximum message size */
335
print_maxmsgsiz(fido_cbor_info_maxmsgsiz(ci));
336
337
/* print maximum number of credentials allowed in credential lists */
338
print_maxcredcntlst(fido_cbor_info_maxcredcntlst(ci));
339
340
/* print maximum length of a credential ID */
341
print_maxcredidlen(fido_cbor_info_maxcredidlen(ci));
342
343
/* print maximum length of largeBlob array */
344
print_maxlargeblob(fido_cbor_info_maxlargeblob(ci));
345
346
/* print number of remaining resident credentials */
347
print_rk_remaining(fido_cbor_info_rk_remaining(ci));
348
349
/* print minimum pin length */
350
print_minpinlen(fido_cbor_info_minpinlen(ci));
351
352
/* print supported pin protocols */
353
print_byte_array("pin protocols", fido_cbor_info_protocols_ptr(ci),
354
fido_cbor_info_protocols_len(ci));
355
356
/* print whether a new pin is required */
357
printf("pin change required: %s\n",
358
fido_cbor_info_new_pin_required(ci) ? "true" : "false");
359
360
/* print platform uv attempts */
361
print_uv_attempts(fido_cbor_info_uv_attempts(ci));
362
363
fido_cbor_info_free(&ci);
364
end:
365
if ((r = fido_dev_close(dev)) != FIDO_OK)
366
errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r);
367
368
fido_dev_free(&dev);
369
}
370
371
int
372
main(int argc, char **argv)
373
{
374
if (argc != 2) {
375
fprintf(stderr, "usage: info <device>\n");
376
exit(EXIT_FAILURE);
377
}
378
379
getinfo(argv[1]);
380
381
exit(0);
382
}
383
384