Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libfido2/tools/bio.c
39536 views
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
* SPDX-License-Identifier: BSD-2-Clause
6
*/
7
8
#include <fido.h>
9
#include <fido/bio.h>
10
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
21
static int
22
print_template(const fido_bio_template_array_t *ta, size_t idx)
23
{
24
const fido_bio_template_t *t = NULL;
25
char *id = NULL;
26
27
if ((t = fido_bio_template(ta, idx)) == NULL) {
28
warnx("fido_bio_template");
29
return -1;
30
}
31
if (base64_encode(fido_bio_template_id_ptr(t),
32
fido_bio_template_id_len(t), &id) < 0) {
33
warnx("output error");
34
return -1;
35
}
36
37
printf("%02u: %s %s\n", (unsigned)idx, id, fido_bio_template_name(t));
38
free(id);
39
40
return 0;
41
}
42
43
int
44
bio_list(const char *path)
45
{
46
fido_bio_template_array_t *ta = NULL;
47
fido_dev_t *dev = NULL;
48
char *pin = NULL;
49
int r, ok = 1;
50
51
if ((ta = fido_bio_template_array_new()) == NULL)
52
errx(1, "fido_bio_template_array_new");
53
dev = open_dev(path);
54
if ((pin = get_pin(path)) == NULL)
55
goto out;
56
r = fido_bio_dev_get_template_array(dev, ta, pin);
57
freezero(pin, PINBUF_LEN);
58
pin = NULL;
59
if (r != FIDO_OK) {
60
warnx("fido_bio_dev_get_template_array: %s", fido_strerr(r));
61
goto out;
62
}
63
for (size_t i = 0; i < fido_bio_template_array_count(ta); i++)
64
if (print_template(ta, i) < 0)
65
goto out;
66
67
ok = 0;
68
out:
69
fido_bio_template_array_free(&ta);
70
fido_dev_close(dev);
71
fido_dev_free(&dev);
72
73
exit(ok);
74
}
75
76
int
77
bio_set_name(const char *path, const char *id, const char *name)
78
{
79
fido_bio_template_t *t = NULL;
80
fido_dev_t *dev = NULL;
81
char *pin = NULL;
82
void *id_blob_ptr = NULL;
83
size_t id_blob_len = 0;
84
int r, ok = 1;
85
86
if ((t = fido_bio_template_new()) == NULL)
87
errx(1, "fido_bio_template_new");
88
if (base64_decode(id, &id_blob_ptr, &id_blob_len) < 0)
89
errx(1, "base64_decode");
90
if ((r = fido_bio_template_set_name(t, name)) != FIDO_OK)
91
errx(1, "fido_bio_template_set_name: %s", fido_strerr(r));
92
if ((r = fido_bio_template_set_id(t, id_blob_ptr,
93
id_blob_len)) != FIDO_OK)
94
errx(1, "fido_bio_template_set_id: %s", fido_strerr(r));
95
96
dev = open_dev(path);
97
if ((pin = get_pin(path)) == NULL)
98
goto out;
99
r = fido_bio_dev_set_template_name(dev, t, pin);
100
freezero(pin, PINBUF_LEN);
101
pin = NULL;
102
if (r != FIDO_OK) {
103
warnx("fido_bio_dev_set_template_name: %s", fido_strerr(r));
104
goto out;
105
}
106
107
ok = 0;
108
out:
109
free(id_blob_ptr);
110
fido_bio_template_free(&t);
111
fido_dev_close(dev);
112
fido_dev_free(&dev);
113
114
exit(ok);
115
}
116
117
static const char *
118
enroll_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
156
int
157
bio_enroll(const char *path)
158
{
159
fido_bio_template_t *t = NULL;
160
fido_bio_enroll_t *e = NULL;
161
fido_dev_t *dev = NULL;
162
char *pin = NULL;
163
int r, ok = 1;
164
165
if ((t = fido_bio_template_new()) == NULL)
166
errx(1, "fido_bio_template_new");
167
if ((e = fido_bio_enroll_new()) == NULL)
168
errx(1, "fido_bio_enroll_new");
169
170
dev = open_dev(path);
171
if ((pin = get_pin(path)) == NULL)
172
goto out;
173
printf("Touch your security key.\n");
174
r = fido_bio_dev_enroll_begin(dev, t, e, 10000, pin);
175
freezero(pin, PINBUF_LEN);
176
pin = NULL;
177
if (r != FIDO_OK) {
178
warnx("fido_bio_dev_enroll_begin: %s", fido_strerr(r));
179
goto out;
180
}
181
printf("%s.\n", enroll_strerr(fido_bio_enroll_last_status(e)));
182
183
while (fido_bio_enroll_remaining_samples(e) > 0) {
184
printf("Touch your security key (%u sample%s left).\n",
185
(unsigned)fido_bio_enroll_remaining_samples(e),
186
plural(fido_bio_enroll_remaining_samples(e)));
187
if ((r = fido_bio_dev_enroll_continue(dev, t, e,
188
10000)) != FIDO_OK) {
189
fido_dev_cancel(dev);
190
warnx("fido_bio_dev_enroll_continue: %s",
191
fido_strerr(r));
192
goto out;
193
}
194
printf("%s.\n", enroll_strerr(fido_bio_enroll_last_status(e)));
195
}
196
197
ok = 0;
198
out:
199
fido_bio_template_free(&t);
200
fido_bio_enroll_free(&e);
201
fido_dev_close(dev);
202
fido_dev_free(&dev);
203
204
exit(ok);
205
}
206
207
int
208
bio_delete(const char *path, const char *id)
209
{
210
fido_bio_template_t *t = NULL;
211
fido_dev_t *dev = NULL;
212
char *pin = NULL;
213
void *id_blob_ptr = NULL;
214
size_t id_blob_len = 0;
215
int r, ok = 1;
216
217
if ((t = fido_bio_template_new()) == NULL)
218
errx(1, "fido_bio_template_new");
219
if (base64_decode(id, &id_blob_ptr, &id_blob_len) < 0)
220
errx(1, "base64_decode");
221
if ((r = fido_bio_template_set_id(t, id_blob_ptr,
222
id_blob_len)) != FIDO_OK)
223
errx(1, "fido_bio_template_set_id: %s", fido_strerr(r));
224
225
dev = open_dev(path);
226
if ((pin = get_pin(path)) == NULL)
227
goto out;
228
r = fido_bio_dev_enroll_remove(dev, t, pin);
229
freezero(pin, PINBUF_LEN);
230
pin = NULL;
231
if (r != FIDO_OK) {
232
warnx("fido_bio_dev_enroll_remove: %s", fido_strerr(r));
233
goto out;
234
}
235
236
ok = 0;
237
out:
238
free(id_blob_ptr);
239
fido_bio_template_free(&t);
240
fido_dev_close(dev);
241
fido_dev_free(&dev);
242
243
exit(ok);
244
}
245
246
static const char *
247
type_str(uint8_t t)
248
{
249
switch (t) {
250
case 1:
251
return "touch";
252
case 2:
253
return "swipe";
254
default:
255
return "unknown";
256
}
257
}
258
259
void
260
bio_info(fido_dev_t *dev)
261
{
262
fido_bio_info_t *i = NULL;
263
264
if ((i = fido_bio_info_new()) == NULL) {
265
warnx("fido_bio_info_new");
266
return;
267
}
268
if (fido_bio_dev_get_info(dev, i) != FIDO_OK) {
269
fido_bio_info_free(&i);
270
return;
271
}
272
273
printf("sensor type: %u (%s)\n", (unsigned)fido_bio_info_type(i),
274
type_str(fido_bio_info_type(i)));
275
printf("max samples: %u\n", (unsigned)fido_bio_info_max_samples(i));
276
277
fido_bio_info_free(&i);
278
}
279
280