summaryrefslogtreecommitdiff
path: root/examples/info.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/info.c')
-rw-r--r--examples/info.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/examples/info.c b/examples/info.c
new file mode 100644
index 0000000..e79729c
--- /dev/null
+++ b/examples/info.c
@@ -0,0 +1,216 @@
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 <openssl/ec.h>
8
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#include "fido.h"
18
19/*
20 * Pretty-print a device's capabilities flags and return the result.
21 */
22static void
23format_flags(char *ret, size_t retlen, uint8_t flags)
24{
25 memset(ret, 0, retlen);
26
27 if (flags & FIDO_CAP_WINK) {
28 if (strlcat(ret, "wink,", retlen) >= retlen)
29 goto toolong;
30 } else {
31 if (strlcat(ret, "nowink,", retlen) >= retlen)
32 goto toolong;
33 }
34
35 if (flags & FIDO_CAP_CBOR) {
36 if (strlcat(ret, " cbor,", retlen) >= retlen)
37 goto toolong;
38 } else {
39 if (strlcat(ret, " nocbor,", retlen) >= retlen)
40 goto toolong;
41 }
42
43 if (flags & FIDO_CAP_NMSG) {
44 if (strlcat(ret, " nomsg", retlen) >= retlen)
45 goto toolong;
46 } else {
47 if (strlcat(ret, " msg", retlen) >= retlen)
48 goto toolong;
49 }
50
51 return;
52toolong:
53 strlcpy(ret, "toolong", retlen);
54}
55
56/*
57 * Print a FIDO device's attributes on stdout.
58 */
59static void
60print_attr(const fido_dev_t *dev)
61{
62 char flags_txt[128];
63
64 printf("proto: 0x%02x\n", fido_dev_protocol(dev));
65 printf("major: 0x%02x\n", fido_dev_major(dev));
66 printf("minor: 0x%02x\n", fido_dev_minor(dev));
67 printf("build: 0x%02x\n", fido_dev_build(dev));
68
69 format_flags(flags_txt, sizeof(flags_txt), fido_dev_flags(dev));
70 printf("caps: 0x%02x (%s)\n", fido_dev_flags(dev), flags_txt);
71}
72
73/*
74 * Auxiliary function to print an array of strings on stdout.
75 */
76static void
77print_str_array(const char *label, char * const *sa, size_t len)
78{
79 if (len == 0)
80 return;
81
82 printf("%s strings: ", label);
83
84 for (size_t i = 0; i < len; i++)
85 printf("%s%s", i > 0 ? ", " : "", sa[i]);
86
87 printf("\n");
88}
89
90/*
91 * Auxiliary function to print (char *, bool) pairs on stdout.
92 */
93static void
94print_opt_array(const char *label, char * const *name, const bool *value,
95 size_t len)
96{
97 if (len == 0)
98 return;
99
100 printf("%s: ", label);
101
102 for (size_t i = 0; i < len; i++)
103 printf("%s%s%s", i > 0 ? ", " : "",
104 value[i] ? "" : "no", name[i]);
105
106 printf("\n");
107}
108
109/*
110 * Auxiliary function to print an authenticator's AAGUID on stdout.
111 */
112static void
113print_aaguid(const unsigned char *buf, size_t buflen)
114{
115 printf("aaguid: ");
116
117 while (buflen--)
118 printf("%02x", *buf++);
119
120 printf("\n");
121}
122
123/*
124 * Auxiliary function to print an authenticator's maximum message size on
125 * stdout.
126 */
127static void
128print_maxmsgsiz(uint64_t maxmsgsiz)
129{
130 printf("maxmsgsiz: %d\n", (int)maxmsgsiz);
131}
132
133/*
134 * Auxiliary function to print an array of bytes on stdout.
135 */
136static void
137print_byte_array(const char *label, const uint8_t *ba, size_t len)
138{
139 if (len == 0)
140 return;
141
142 printf("%s: ", label);
143
144 for (size_t i = 0; i < len; i++)
145 printf("%s%u", i > 0 ? ", " : "", (unsigned)ba[i]);
146
147 printf("\n");
148}
149
150static void
151getinfo(const char *path)
152{
153 fido_dev_t *dev;
154 fido_cbor_info_t *ci;
155 int r;
156
157 fido_init(0);
158
159 if ((dev = fido_dev_new()) == NULL)
160 errx(1, "fido_dev_new");
161 if ((r = fido_dev_open(dev, path)) != FIDO_OK)
162 errx(1, "fido_dev_open: %s (0x%x)", fido_strerr(r), r);
163
164 print_attr(dev);
165
166 if (fido_dev_is_fido2(dev) == false)
167 goto end;
168 if ((ci = fido_cbor_info_new()) == NULL)
169 errx(1, "fido_cbor_info_new");
170 if ((r = fido_dev_get_cbor_info(dev, ci)) != FIDO_OK)
171 errx(1, "fido_dev_get_cbor_info: %s (0x%x)", fido_strerr(r), r);
172
173 /* print supported protocol versions */
174 print_str_array("version", fido_cbor_info_versions_ptr(ci),
175 fido_cbor_info_versions_len(ci));
176
177 /* print supported extensions */
178 print_str_array("extension", fido_cbor_info_extensions_ptr(ci),
179 fido_cbor_info_extensions_len(ci));
180
181 /* print aaguid */
182 print_aaguid(fido_cbor_info_aaguid_ptr(ci),
183 fido_cbor_info_aaguid_len(ci));
184
185 /* print supported options */
186 print_opt_array("options", fido_cbor_info_options_name_ptr(ci),
187 fido_cbor_info_options_value_ptr(ci),
188 fido_cbor_info_options_len(ci));
189
190 /* print maximum message size */
191 print_maxmsgsiz(fido_cbor_info_maxmsgsiz(ci));
192
193 /* print supported pin protocols */
194 print_byte_array("pin protocols", fido_cbor_info_protocols_ptr(ci),
195 fido_cbor_info_protocols_len(ci));
196
197 fido_cbor_info_free(&ci);
198end:
199 if ((r = fido_dev_close(dev)) != FIDO_OK)
200 errx(1, "fido_dev_close: %s (0x%x)", fido_strerr(r), r);
201
202 fido_dev_free(&dev);
203}
204
205int
206main(int argc, char **argv)
207{
208 if (argc != 2) {
209 fprintf(stderr, "usage: info <device>\n");
210 exit(EXIT_FAILURE);
211 }
212
213 getinfo(argv[1]);
214
215 exit(0);
216}