diff options
Diffstat (limited to 'examples/info.c')
-rw-r--r-- | examples/info.c | 216 |
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 | */ | ||
22 | static void | ||
23 | format_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; | ||
52 | toolong: | ||
53 | strlcpy(ret, "toolong", retlen); | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Print a FIDO device's attributes on stdout. | ||
58 | */ | ||
59 | static void | ||
60 | print_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 | */ | ||
76 | static void | ||
77 | print_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 | */ | ||
93 | static void | ||
94 | print_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 | */ | ||
112 | static void | ||
113 | print_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 | */ | ||
127 | static void | ||
128 | print_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 | */ | ||
136 | static void | ||
137 | print_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 | |||
150 | static void | ||
151 | getinfo(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); | ||
198 | end: | ||
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 | |||
205 | int | ||
206 | main(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 | } | ||