summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/CMakeLists.txt16
-rw-r--r--examples/README.adoc9
-rw-r--r--examples/assert.c15
-rw-r--r--examples/cred.c15
-rw-r--r--examples/extern.h1
-rw-r--r--examples/info.c31
-rw-r--r--examples/manifest.c5
-rw-r--r--examples/reset.c9
-rw-r--r--examples/retries.c5
-rw-r--r--examples/select.c215
-rw-r--r--examples/setpin.c5
-rw-r--r--examples/util.c3
12 files changed, 289 insertions, 40 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 1203592..7228860 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -3,6 +3,7 @@
3# license that can be found in the LICENSE file. 3# license that can be found in the LICENSE file.
4 4
5list(APPEND COMPAT_SOURCES 5list(APPEND COMPAT_SOURCES
6 ../openbsd-compat/clock_gettime.c
6 ../openbsd-compat/getopt_long.c 7 ../openbsd-compat/getopt_long.c
7 ../openbsd-compat/strlcat.c 8 ../openbsd-compat/strlcat.c
8 ../openbsd-compat/strlcpy.c 9 ../openbsd-compat/strlcpy.c
@@ -15,6 +16,13 @@ endif()
15# drop -rdynamic 16# drop -rdynamic
16set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "") 17set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
17 18
19# enable -Wconversion -Wsign-conversion
20if(NOT MSVC)
21 set_source_files_properties(assert.c cred.c info.c manifest.c reset.c
22 retries.c setpin.c util.c PROPERTIES COMPILE_FLAGS
23 "-Wconversion -Wsign-conversion")
24endif()
25
18# manifest 26# manifest
19add_executable(manifest manifest.c ${COMPAT_SOURCES}) 27add_executable(manifest manifest.c ${COMPAT_SOURCES})
20target_link_libraries(manifest fido2) 28target_link_libraries(manifest fido2)
@@ -42,3 +50,11 @@ target_link_libraries(setpin fido2)
42# retries 50# retries
43add_executable(retries retries.c ${COMPAT_SOURCES}) 51add_executable(retries retries.c ${COMPAT_SOURCES})
44target_link_libraries(retries fido2) 52target_link_libraries(retries fido2)
53
54# select
55add_executable(select select.c ${COMPAT_SOURCES})
56target_link_libraries(select fido2)
57if(MINGW)
58 # needed for nanosleep() in mingw
59 target_link_libraries(select winpthread)
60endif()
diff --git a/examples/README.adoc b/examples/README.adoc
index 091c6bc..b7b73d8 100644
--- a/examples/README.adoc
+++ b/examples/README.adoc
@@ -77,5 +77,14 @@ The following examples are provided:
77- retries <device> 77- retries <device>
78 Get the number of PIN attempts left on <device> before lockout. 78 Get the number of PIN attempts left on <device> before lockout.
79 79
80- select
81
82 Enumerates available FIDO devices and, if more than one is present,
83 simultaneously requests touch on all of them, printing information
84 about the device touched.
85
80Debugging is possible through the use of the FIDO_DEBUG environment variable. 86Debugging is possible through the use of the FIDO_DEBUG environment variable.
81If set, libfido2 will produce a log of its transactions with the authenticator. 87If set, libfido2 will produce a log of its transactions with the authenticator.
88
89Additionally, an example of a WebAuthn client using libfido2 is available at
90https://github.com/martelletto/fido2-webauthn-client.
diff --git a/examples/assert.c b/examples/assert.c
index a421a51..a18d8af 100644
--- a/examples/assert.c
+++ b/examples/assert.c
@@ -14,17 +14,12 @@
14#include <unistd.h> 14#include <unistd.h>
15#endif 15#endif
16 16
17#include "../openbsd-compat/openbsd-compat.h"
18
19#include "fido.h" 17#include "fido.h"
20#include "fido/es256.h" 18#include "fido/es256.h"
21#include "fido/rs256.h" 19#include "fido/rs256.h"
22#include "fido/eddsa.h" 20#include "fido/eddsa.h"
23#include "extern.h" 21#include "extern.h"
24 22#include "../openbsd-compat/openbsd-compat.h"
25#ifdef SIGNAL_EXAMPLE
26extern volatile sig_atomic_t got_signal;
27#endif
28 23
29static const unsigned char cdh[32] = { 24static const unsigned char cdh[32] = {
30 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7, 25 0xec, 0x8d, 0x8f, 0x78, 0x42, 0x4a, 0x2b, 0xb7,
@@ -188,13 +183,15 @@ main(int argc, char **argv)
188 break; 183 break;
189 case 'T': 184 case 'T':
190#ifndef SIGNAL_EXAMPLE 185#ifndef SIGNAL_EXAMPLE
186 (void)seconds;
191 errx(1, "-T not supported"); 187 errx(1, "-T not supported");
192#endif 188#else
193 if (base10(optarg, &seconds) < 0) 189 if (base10(optarg, &seconds) < 0)
194 errx(1, "base10: %s", optarg); 190 errx(1, "base10: %s", optarg);
195 if (seconds <= 0 || seconds > 30) 191 if (seconds <= 0 || seconds > 30)
196 errx(1, "-T: %s must be in (0,30]", optarg); 192 errx(1, "-T: %s must be in (0,30]", optarg);
197 break; 193 break;
194#endif
198 case 'a': 195 case 'a':
199 if (read_blob(optarg, &body, &len) < 0) 196 if (read_blob(optarg, &body, &len) < 0)
200 errx(1, "read_blob: %s", optarg); 197 errx(1, "read_blob: %s", optarg);
@@ -312,6 +309,10 @@ main(int argc, char **argv)
312 errx(1, "fido_assert_count: %d signatures returned", 309 errx(1, "fido_assert_count: %d signatures returned",
313 (int)fido_assert_count(assert)); 310 (int)fido_assert_count(assert));
314 311
312 /* when verifying, pin implies uv */
313 if (pin)
314 uv = true;
315
315 verify_assert(type, fido_assert_authdata_ptr(assert, 0), 316 verify_assert(type, fido_assert_authdata_ptr(assert, 0),
316 fido_assert_authdata_len(assert, 0), fido_assert_sig_ptr(assert, 0), 317 fido_assert_authdata_len(assert, 0), fido_assert_sig_ptr(assert, 0),
317 fido_assert_sig_len(assert, 0), up, uv, ext, argv[0]); 318 fido_assert_sig_len(assert, 0), up, uv, ext, argv[0]);
diff --git a/examples/cred.c b/examples/cred.c
index 3e0a30f..6bd0faf 100644
--- a/examples/cred.c
+++ b/examples/cred.c
@@ -16,14 +16,9 @@
16#include <unistd.h> 16#include <unistd.h>
17#endif 17#endif
18 18
19#include "../openbsd-compat/openbsd-compat.h"
20
21#include "fido.h" 19#include "fido.h"
22#include "extern.h" 20#include "extern.h"
23 21#include "../openbsd-compat/openbsd-compat.h"
24#ifdef SIGNAL_EXAMPLE
25extern volatile sig_atomic_t got_signal;
26#endif
27 22
28static const unsigned char cdh[32] = { 23static const unsigned char cdh[32] = {
29 0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb, 24 0xf9, 0x64, 0x57, 0xe7, 0x2d, 0x97, 0xf6, 0xbb,
@@ -192,13 +187,15 @@ main(int argc, char **argv)
192 break; 187 break;
193 case 'T': 188 case 'T':
194#ifndef SIGNAL_EXAMPLE 189#ifndef SIGNAL_EXAMPLE
190 (void)seconds;
195 errx(1, "-T not supported"); 191 errx(1, "-T not supported");
196#endif 192#else
197 if (base10(optarg, &seconds) < 0) 193 if (base10(optarg, &seconds) < 0)
198 errx(1, "base10: %s", optarg); 194 errx(1, "base10: %s", optarg);
199 if (seconds <= 0 || seconds > 30) 195 if (seconds <= 0 || seconds > 30)
200 errx(1, "-T: %s must be in (0,30]", optarg); 196 errx(1, "-T: %s must be in (0,30]", optarg);
201 break; 197 break;
198#endif
202 case 'e': 199 case 'e':
203 if (read_blob(optarg, &body, &len) < 0) 200 if (read_blob(optarg, &body, &len) < 0)
204 errx(1, "read_blob: %s", optarg); 201 errx(1, "read_blob: %s", optarg);
@@ -318,6 +315,10 @@ main(int argc, char **argv)
318 315
319 fido_dev_free(&dev); 316 fido_dev_free(&dev);
320 317
318 /* when verifying, pin implies uv */
319 if (pin)
320 uv = true;
321
321 verify_cred(type, fido_cred_fmt(cred), fido_cred_authdata_ptr(cred), 322 verify_cred(type, fido_cred_fmt(cred), fido_cred_authdata_ptr(cred),
322 fido_cred_authdata_len(cred), fido_cred_x5c_ptr(cred), 323 fido_cred_authdata_len(cred), fido_cred_x5c_ptr(cred),
323 fido_cred_x5c_len(cred), fido_cred_sig_ptr(cred), 324 fido_cred_x5c_len(cred), fido_cred_sig_ptr(cred),
diff --git a/examples/extern.h b/examples/extern.h
index 578b8c4..0ea68c4 100644
--- a/examples/extern.h
+++ b/examples/extern.h
@@ -27,6 +27,7 @@ int write_rsa_pubkey(const char *, const void *, size_t);
27int write_eddsa_pubkey(const char *, const void *, size_t); 27int write_eddsa_pubkey(const char *, const void *, size_t);
28#ifdef SIGNAL_EXAMPLE 28#ifdef SIGNAL_EXAMPLE
29void prepare_signal_handler(int); 29void prepare_signal_handler(int);
30extern volatile sig_atomic_t got_signal;
30#endif 31#endif
31 32
32#endif /* _EXTERN_H_ */ 33#endif /* _EXTERN_H_ */
diff --git a/examples/info.c b/examples/info.c
index ef0d97e..d81de85 100644
--- a/examples/info.c
+++ b/examples/info.c
@@ -4,17 +4,14 @@
4 * license that can be found in the LICENSE file. 4 * license that can be found in the LICENSE file.
5 */ 5 */
6 6
7#include <openssl/ec.h>
8
9#include <stdbool.h> 7#include <stdbool.h>
10#include <stdint.h> 8#include <stdint.h>
11#include <stdio.h> 9#include <stdio.h>
12#include <stdlib.h> 10#include <stdlib.h>
13#include <string.h> 11#include <string.h>
14 12
15#include "../openbsd-compat/openbsd-compat.h"
16
17#include "fido.h" 13#include "fido.h"
14#include "../openbsd-compat/openbsd-compat.h"
18 15
19/* 16/*
20 * Pretty-print a device's capabilities flags and return the result. 17 * Pretty-print a device's capabilities flags and return the result.
@@ -131,6 +128,26 @@ print_maxmsgsiz(uint64_t maxmsgsiz)
131} 128}
132 129
133/* 130/*
131 * Auxiliary function to print an authenticator's maximum number of credentials
132 * in a credential list on stdout.
133 */
134static void
135print_maxcredcntlst(uint64_t maxcredcntlst)
136{
137 printf("maxcredcntlst: %d\n", (int)maxcredcntlst);
138}
139
140/*
141 * Auxiliary function to print an authenticator's maximum credential ID length
142 * on stdout.
143 */
144static void
145print_maxcredidlen(uint64_t maxcredidlen)
146{
147 printf("maxcredlen: %d\n", (int)maxcredidlen);
148}
149
150/*
134 * Auxiliary function to print an authenticator's firmware version on stdout. 151 * Auxiliary function to print an authenticator's firmware version on stdout.
135 */ 152 */
136static void 153static void
@@ -199,6 +216,12 @@ getinfo(const char *path)
199 /* print maximum message size */ 216 /* print maximum message size */
200 print_maxmsgsiz(fido_cbor_info_maxmsgsiz(ci)); 217 print_maxmsgsiz(fido_cbor_info_maxmsgsiz(ci));
201 218
219 /* print maximum number of credentials allowed in credential lists */
220 print_maxcredcntlst(fido_cbor_info_maxcredcntlst(ci));
221
222 /* print maximum length of a credential ID */
223 print_maxcredidlen(fido_cbor_info_maxcredidlen(ci));
224
202 /* print firmware version */ 225 /* print firmware version */
203 print_fwversion(fido_cbor_info_fwversion(ci)); 226 print_fwversion(fido_cbor_info_fwversion(ci));
204 227
diff --git a/examples/manifest.c b/examples/manifest.c
index 895447a..d5ebda2 100644
--- a/examples/manifest.c
+++ b/examples/manifest.c
@@ -4,15 +4,12 @@
4 * license that can be found in the LICENSE file. 4 * license that can be found in the LICENSE file.
5 */ 5 */
6 6
7#include <openssl/ec.h>
8
9#include <stdbool.h> 7#include <stdbool.h>
10#include <stdio.h> 8#include <stdio.h>
11#include <stdlib.h> 9#include <stdlib.h>
12 10
13#include "../openbsd-compat/openbsd-compat.h"
14
15#include "fido.h" 11#include "fido.h"
12#include "../openbsd-compat/openbsd-compat.h"
16 13
17int 14int
18main(void) 15main(void)
diff --git a/examples/reset.c b/examples/reset.c
index 36a7de2..3e715c4 100644
--- a/examples/reset.c
+++ b/examples/reset.c
@@ -8,21 +8,14 @@
8 * Perform a factory reset on a given authenticator. 8 * Perform a factory reset on a given authenticator.
9 */ 9 */
10 10
11#include <openssl/ec.h>
12
13#include <stdbool.h> 11#include <stdbool.h>
14#include <stdint.h> 12#include <stdint.h>
15#include <stdio.h> 13#include <stdio.h>
16#include <stdlib.h> 14#include <stdlib.h>
17 15
18#include "../openbsd-compat/openbsd-compat.h"
19
20#include "fido.h" 16#include "fido.h"
21#include "extern.h" 17#include "extern.h"
22 18#include "../openbsd-compat/openbsd-compat.h"
23#ifdef SIGNAL_EXAMPLE
24extern volatile sig_atomic_t got_signal;
25#endif
26 19
27int 20int
28main(int argc, char **argv) 21main(int argc, char **argv)
diff --git a/examples/retries.c b/examples/retries.c
index 3ed7558..5cc116c 100644
--- a/examples/retries.c
+++ b/examples/retries.c
@@ -8,15 +8,12 @@
8 * Get an authenticator's number of PIN attempts left. 8 * Get an authenticator's number of PIN attempts left.
9 */ 9 */
10 10
11#include <openssl/ec.h>
12
13#include <stdbool.h> 11#include <stdbool.h>
14#include <stdio.h> 12#include <stdio.h>
15#include <stdlib.h> 13#include <stdlib.h>
16 14
17#include "../openbsd-compat/openbsd-compat.h"
18
19#include "fido.h" 15#include "fido.h"
16#include "../openbsd-compat/openbsd-compat.h"
20 17
21int 18int
22main(int argc, char **argv) 19main(int argc, char **argv)
diff --git a/examples/select.c b/examples/select.c
new file mode 100644
index 0000000..1fb2960
--- /dev/null
+++ b/examples/select.c
@@ -0,0 +1,215 @@
1/*
2 * Copyright (c) 2020 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 <errno.h>
8#include <stdbool.h>
9#include <stdio.h>
10#include <stdlib.h>
11#include <time.h>
12
13#include "fido.h"
14#include "../openbsd-compat/openbsd-compat.h"
15
16#define FIDO_POLL_MS 50
17
18#if defined(_MSC_VER)
19static int
20nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
21{
22 if (rmtp != NULL) {
23 errno = EINVAL;
24 return (-1);
25 }
26
27 Sleep(rqtp->tv_nsec / 1000000);
28
29 return (0);
30}
31#endif
32
33static fido_dev_t *
34open_dev(const fido_dev_info_t *di)
35{
36 fido_dev_t *dev;
37 int r;
38
39 if ((dev = fido_dev_new()) == NULL) {
40 warnx("%s: fido_dev_new", __func__);
41 return (NULL);
42 }
43
44 if ((r = fido_dev_open(dev, fido_dev_info_path(di))) != FIDO_OK) {
45 warnx("%s: fido_dev_open %s: %s", __func__,
46 fido_dev_info_path(di), fido_strerr(r));
47 fido_dev_free(&dev);
48 return (NULL);
49 }
50
51 printf("%s (0x%04x:0x%04x) is %s\n", fido_dev_info_path(di),
52 fido_dev_info_vendor(di), fido_dev_info_product(di),
53 fido_dev_is_fido2(dev) ? "fido2" : "u2f");
54
55 return (dev);
56}
57
58static int
59select_dev(const fido_dev_info_t *devlist, size_t ndevs, fido_dev_t **dev,
60 size_t *idx, int secs)
61{
62 const fido_dev_info_t *di;
63 fido_dev_t **devtab;
64 struct timespec ts_start;
65 struct timespec ts_now;
66 struct timespec ts_delta;
67 struct timespec ts_pause;
68 size_t nopen = 0;
69 int touched;
70 int r;
71 long ms_remain;
72
73 *dev = NULL;
74 *idx = 0;
75
76 printf("%u authenticator(s) detected\n", (unsigned)ndevs);
77
78 if (ndevs == 0)
79 return (0); /* nothing to do */
80
81 if ((devtab = calloc(ndevs, sizeof(*devtab))) == NULL) {
82 warn("%s: calloc", __func__);
83 return (-1);
84 }
85
86 for (size_t i = 0; i < ndevs; i++) {
87 di = fido_dev_info_ptr(devlist, i);
88 if ((devtab[i] = open_dev(di)) != NULL) {
89 *idx = i;
90 nopen++;
91 }
92 }
93
94 printf("%u authenticator(s) opened\n", (unsigned)nopen);
95
96 if (nopen < 2) {
97 if (nopen == 1)
98 *dev = devtab[*idx]; /* single candidate */
99 r = 0;
100 goto out;
101 }
102
103 for (size_t i = 0; i < ndevs; i++) {
104 di = fido_dev_info_ptr(devlist, i);
105 if (devtab[i] == NULL)
106 continue; /* failed to open */
107 if ((r = fido_dev_get_touch_begin(devtab[i])) != FIDO_OK) {
108 warnx("%s: fido_dev_get_touch_begin %s: %s", __func__,
109 fido_dev_info_path(di), fido_strerr(r));
110 r = -1;
111 goto out;
112 }
113 }
114
115 if (clock_gettime(CLOCK_MONOTONIC, &ts_start) != 0) {
116 warn("%s: clock_gettime", __func__);
117 r = -1;
118 goto out;
119 }
120
121 ts_pause.tv_sec = 0;
122 ts_pause.tv_nsec = 200000000; /* 200ms */
123
124 do {
125 nanosleep(&ts_pause, NULL);
126
127 for (size_t i = 0; i < ndevs; i++) {
128 di = fido_dev_info_ptr(devlist, i);
129 if (devtab[i] == NULL) {
130 /* failed to open or discarded */
131 continue;
132 }
133 if ((r = fido_dev_get_touch_status(devtab[i], &touched,
134 FIDO_POLL_MS)) != FIDO_OK) {
135 warnx("%s: fido_dev_get_touch_status %s: %s",
136 __func__, fido_dev_info_path(di),
137 fido_strerr(r));
138 fido_dev_close(devtab[i]);
139 fido_dev_free(&devtab[i]);
140 continue; /* discard */
141 }
142 if (touched) {
143 *dev = devtab[i];
144 *idx = i;
145 r = 0;
146 goto out;
147 }
148 }
149
150 if (clock_gettime(CLOCK_MONOTONIC, &ts_now) != 0) {
151 warn("%s: clock_gettime", __func__);
152 r = -1;
153 goto out;
154 }
155
156 timespecsub(&ts_now, &ts_start, &ts_delta);
157 ms_remain = (secs * 1000) - ((long)ts_delta.tv_sec * 1000) +
158 ((long)ts_delta.tv_nsec / 1000000);
159 } while (ms_remain > FIDO_POLL_MS);
160
161 printf("timeout after %d seconds\n", secs);
162 r = -1;
163out:
164 if (r != 0) {
165 *dev = NULL;
166 *idx = 0;
167 }
168
169 for (size_t i = 0; i < ndevs; i++) {
170 if (devtab[i] && devtab[i] != *dev) {
171 fido_dev_cancel(devtab[i]);
172 fido_dev_close(devtab[i]);
173 fido_dev_free(&devtab[i]);
174 }
175 }
176
177 free(devtab);
178
179 return (r);
180}
181
182int
183main(void)
184{
185 const fido_dev_info_t *di;
186 fido_dev_info_t *devlist;
187 fido_dev_t *dev;
188 size_t idx;
189 size_t ndevs;
190 int r;
191
192 fido_init(0);
193
194 if ((devlist = fido_dev_info_new(64)) == NULL)
195 errx(1, "fido_dev_info_new");
196
197 if ((r = fido_dev_info_manifest(devlist, 64, &ndevs)) != FIDO_OK)
198 errx(1, "fido_dev_info_manifest: %s (0x%x)", fido_strerr(r), r);
199 if (select_dev(devlist, ndevs, &dev, &idx, 15) != 0)
200 errx(1, "select_dev");
201 if (dev == NULL)
202 errx(1, "no authenticator found");
203
204 di = fido_dev_info_ptr(devlist, idx);
205 printf("%s: %s by %s (PIN %sset)\n", fido_dev_info_path(di),
206 fido_dev_info_product_string(di),
207 fido_dev_info_manufacturer_string(di),
208 fido_dev_has_pin(dev) ? "" : "un");
209
210 fido_dev_close(dev);
211 fido_dev_free(&dev);
212 fido_dev_info_free(&devlist, ndevs);
213
214 exit(0);
215}
diff --git a/examples/setpin.c b/examples/setpin.c
index 75d3d4a..5413bf9 100644
--- a/examples/setpin.c
+++ b/examples/setpin.c
@@ -8,16 +8,13 @@
8 * Configure a PIN on a given authenticator. 8 * Configure a PIN on a given authenticator.
9 */ 9 */
10 10
11#include <openssl/ec.h>
12
13#include <stdbool.h> 11#include <stdbool.h>
14#include <stdint.h> 12#include <stdint.h>
15#include <stdio.h> 13#include <stdio.h>
16#include <stdlib.h> 14#include <stdlib.h>
17 15
18#include "../openbsd-compat/openbsd-compat.h"
19
20#include "fido.h" 16#include "fido.h"
17#include "../openbsd-compat/openbsd-compat.h"
21 18
22static void 19static void
23setpin(const char *path, const char *pin, const char *oldpin) 20setpin(const char *path, const char *pin, const char *oldpin)
diff --git a/examples/util.c b/examples/util.c
index 2f6a845..5291cd8 100644
--- a/examples/util.c
+++ b/examples/util.c
@@ -27,13 +27,12 @@
27#include "../openbsd-compat/posix_win.h" 27#include "../openbsd-compat/posix_win.h"
28#endif 28#endif
29 29
30#include "../openbsd-compat/openbsd-compat.h"
31
32#include "fido.h" 30#include "fido.h"
33#include "fido/es256.h" 31#include "fido/es256.h"
34#include "fido/rs256.h" 32#include "fido/rs256.h"
35#include "fido/eddsa.h" 33#include "fido/eddsa.h"
36#include "extern.h" 34#include "extern.h"
35#include "../openbsd-compat/openbsd-compat.h"
37 36
38#ifdef SIGNAL_EXAMPLE 37#ifdef SIGNAL_EXAMPLE
39volatile sig_atomic_t got_signal = 0; 38volatile sig_atomic_t got_signal = 0;