summaryrefslogtreecommitdiff
path: root/tools/bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/bio.c')
-rw-r--r--tools/bio.c270
1 files changed, 270 insertions, 0 deletions
diff --git a/tools/bio.c b/tools/bio.c
new file mode 100644
index 0000000..b8f9b38
--- /dev/null
+++ b/tools/bio.c
@@ -0,0 +1,270 @@
1/*
2 * Copyright (c) 2019 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 <fido.h>
8#include <fido/bio.h>
9
10#include <stdbool.h>
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#ifdef HAVE_UNISTD_H
15#include <unistd.h>
16#endif
17
18#include "../openbsd-compat/openbsd-compat.h"
19#include "extern.h"
20
21static void
22print_template(const fido_bio_template_array_t *ta, size_t idx)
23{
24 char *id = NULL;
25 const fido_bio_template_t *t = NULL;
26
27 if ((t = fido_bio_template(ta, idx)) == NULL)
28 errx(1, "fido_bio_template");
29
30 if (base64_encode(fido_bio_template_id_ptr(t),
31 fido_bio_template_id_len(t), &id) < 0)
32 errx(1, "output error");
33
34 printf("%02u: %s %s\n", (unsigned)idx, id, fido_bio_template_name(t));
35
36 free(id);
37}
38
39int
40bio_list(char *path)
41{
42 char pin[1024];
43 fido_bio_template_array_t *ta = NULL;
44 fido_dev_t *dev = NULL;
45 int r;
46
47 if (path == NULL)
48 usage();
49 if ((ta = fido_bio_template_array_new()) == NULL)
50 errx(1, "fido_bio_template_array_new");
51
52 dev = open_dev(path);
53 read_pin(path, pin, sizeof(pin));
54 r = fido_bio_dev_get_template_array(dev, ta, pin);
55 explicit_bzero(pin, sizeof(pin));
56
57 if (r != FIDO_OK)
58 errx(1, "fido_bio_dev_get_template_array: %s", fido_strerr(r));
59 for (size_t i = 0; i < fido_bio_template_array_count(ta); i++)
60 print_template(ta, i);
61
62 fido_bio_template_array_free(&ta);
63 fido_dev_close(dev);
64 fido_dev_free(&dev);
65
66 exit(0);
67}
68
69int
70bio_set_name(char *path, char *id, char *name)
71{
72 char pin[1024];
73 fido_bio_template_t *t = NULL;
74 fido_dev_t *dev = NULL;
75 int r;
76 size_t id_blob_len = 0;
77 void *id_blob_ptr = NULL;
78
79 if (path == NULL)
80 usage();
81 if ((t = fido_bio_template_new()) == NULL)
82 errx(1, "fido_bio_template_new");
83
84 if (base64_decode(id, &id_blob_ptr, &id_blob_len) < 0)
85 errx(1, "base64_decode");
86
87 if ((r = fido_bio_template_set_name(t, name)) != FIDO_OK)
88 errx(1, "fido_bio_template_set_name: %s", fido_strerr(r));
89 if ((r = fido_bio_template_set_id(t, id_blob_ptr,
90 id_blob_len)) != FIDO_OK)
91 errx(1, "fido_bio_template_set_id: %s", fido_strerr(r));
92
93 dev = open_dev(path);
94 read_pin(path, pin, sizeof(pin));
95 r = fido_bio_dev_set_template_name(dev, t, pin);
96 explicit_bzero(pin, sizeof(pin));
97
98 if (r != FIDO_OK)
99 errx(1, "fido_bio_dev_set_template_name: %s", fido_strerr(r));
100
101 free(id_blob_ptr);
102 fido_bio_template_free(&t);
103 fido_dev_close(dev);
104 fido_dev_free(&dev);
105
106 exit(0);
107}
108
109static const char *
110plural(uint8_t n)
111{
112 if (n == 1)
113 return "";
114 return "s";
115}
116
117static const char *
118enroll_strerr(uint8_t n)
119{
120 switch (n) {
121 case FIDO_BIO_ENROLL_FP_GOOD:
122 return "Sample ok";
123 case FIDO_BIO_ENROLL_FP_TOO_HIGH:
124 return "Sample too high";
125 case FIDO_BIO_ENROLL_FP_TOO_LOW:
126 return "Sample too low";
127 case FIDO_BIO_ENROLL_FP_TOO_LEFT:
128 return "Sample too left";
129 case FIDO_BIO_ENROLL_FP_TOO_RIGHT:
130 return "Sample too right";
131 case FIDO_BIO_ENROLL_FP_TOO_FAST:
132 return "Sample too fast";
133 case FIDO_BIO_ENROLL_FP_TOO_SLOW:
134 return "Sample too slow";
135 case FIDO_BIO_ENROLL_FP_POOR_QUALITY:
136 return "Poor quality sample";
137 case FIDO_BIO_ENROLL_FP_TOO_SKEWED:
138 return "Sample too skewed";
139 case FIDO_BIO_ENROLL_FP_TOO_SHORT:
140 return "Sample too short";
141 case FIDO_BIO_ENROLL_FP_MERGE_FAILURE:
142 return "Sample merge failure";
143 case FIDO_BIO_ENROLL_FP_EXISTS:
144 return "Sample exists";
145 case FIDO_BIO_ENROLL_FP_DATABASE_FULL:
146 return "Fingerprint database full";
147 case FIDO_BIO_ENROLL_NO_USER_ACTIVITY:
148 return "No user activity";
149 case FIDO_BIO_ENROLL_NO_USER_PRESENCE_TRANSITION:
150 return "No user presence transition";
151 default:
152 return "Unknown error";
153 }
154}
155
156int
157bio_enroll(char *path)
158{
159 char pin[1024];
160 fido_bio_enroll_t *e = NULL;
161 fido_bio_template_t *t = NULL;
162 fido_dev_t *dev = NULL;
163 int r;
164
165 if (path == NULL)
166 usage();
167 if ((t = fido_bio_template_new()) == NULL)
168 errx(1, "fido_bio_template_new");
169 if ((e = fido_bio_enroll_new()) == NULL)
170 errx(1, "fido_bio_enroll_new");
171
172 dev = open_dev(path);
173 read_pin(path, pin, sizeof(pin));
174
175 printf("Touch your security key.\n");
176
177 r = fido_bio_dev_enroll_begin(dev, t, e, 10000, pin);
178 explicit_bzero(pin, sizeof(pin));
179 if (r != FIDO_OK)
180 errx(1, "fido_bio_dev_enroll_begin: %s", fido_strerr(r));
181
182 printf("%s.\n", enroll_strerr(fido_bio_enroll_last_status(e)));
183
184 while (fido_bio_enroll_remaining_samples(e) > 0) {
185 printf("Touch your security key (%u sample%s left).\n",
186 (unsigned)fido_bio_enroll_remaining_samples(e),
187 plural(fido_bio_enroll_remaining_samples(e)));
188 if ((r = fido_bio_dev_enroll_continue(dev, t, e,
189 10000)) != FIDO_OK) {
190 errx(1, "fido_bio_dev_enroll_continue: %s",
191 fido_strerr(r));
192 }
193 printf("%s.\n", enroll_strerr(fido_bio_enroll_last_status(e)));
194 }
195
196 fido_bio_template_free(&t);
197 fido_bio_enroll_free(&e);
198 fido_dev_close(dev);
199 fido_dev_free(&dev);
200
201 exit(0);
202}
203
204int
205bio_delete(fido_dev_t *dev, char *path, char *id)
206{
207 char pin[1024];
208 fido_bio_template_t *t = NULL;
209 int r;
210 size_t id_blob_len = 0;
211 void *id_blob_ptr = NULL;
212
213 if (path == NULL)
214 usage();
215 if ((t = fido_bio_template_new()) == NULL)
216 errx(1, "fido_bio_template_new");
217
218 if (base64_decode(id, &id_blob_ptr, &id_blob_len) < 0)
219 errx(1, "base64_decode");
220 if ((r = fido_bio_template_set_id(t, id_blob_ptr,
221 id_blob_len)) != FIDO_OK)
222 errx(1, "fido_bio_template_set_id: %s", fido_strerr(r));
223
224 read_pin(path, pin, sizeof(pin));
225 r = fido_bio_dev_enroll_remove(dev, t, pin);
226 explicit_bzero(pin, sizeof(pin));
227
228 if (r != FIDO_OK)
229 errx(1, "fido_bio_dev_enroll_remove: %s", fido_strerr(r));
230
231 free(id_blob_ptr);
232 fido_bio_template_free(&t);
233 fido_dev_close(dev);
234 fido_dev_free(&dev);
235
236 exit(0);
237}
238
239static const char *
240type_str(uint8_t t)
241{
242 switch (t) {
243 case 1:
244 return "touch";
245 case 2:
246 return "swipe";
247 default:
248 return "unknown";
249 }
250}
251
252void
253bio_info(fido_dev_t *dev)
254{
255 fido_bio_info_t *i = NULL;
256 int r;
257
258 if ((i = fido_bio_info_new()) == NULL)
259 errx(1, "fido_bio_info_new");
260 if ((r = fido_bio_dev_get_info(dev, i)) != FIDO_OK) {
261 fido_bio_info_free(&i);
262 return;
263 }
264
265 printf("sensor type: %u (%s)\n", (unsigned)fido_bio_info_type(i),
266 type_str(fido_bio_info_type(i)));
267 printf("max samples: %u\n", (unsigned)fido_bio_info_max_samples(i));
268
269 fido_bio_info_free(&i);
270}