From c79050aa44b8836d836c5dd22a383a073c28b74b Mon Sep 17 00:00:00 2001 From: nicoo Date: Wed, 12 Feb 2020 13:42:22 +0100 Subject: Import upstream release 1.3.0 Closes: #951184 --- tools/bio.c | 270 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 tools/bio.c (limited to 'tools/bio.c') 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 @@ +/* + * Copyright (c) 2019 Yubico AB. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +#include +#include + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "../openbsd-compat/openbsd-compat.h" +#include "extern.h" + +static void +print_template(const fido_bio_template_array_t *ta, size_t idx) +{ + char *id = NULL; + const fido_bio_template_t *t = NULL; + + if ((t = fido_bio_template(ta, idx)) == NULL) + errx(1, "fido_bio_template"); + + if (base64_encode(fido_bio_template_id_ptr(t), + fido_bio_template_id_len(t), &id) < 0) + errx(1, "output error"); + + printf("%02u: %s %s\n", (unsigned)idx, id, fido_bio_template_name(t)); + + free(id); +} + +int +bio_list(char *path) +{ + char pin[1024]; + fido_bio_template_array_t *ta = NULL; + fido_dev_t *dev = NULL; + int r; + + if (path == NULL) + usage(); + if ((ta = fido_bio_template_array_new()) == NULL) + errx(1, "fido_bio_template_array_new"); + + dev = open_dev(path); + read_pin(path, pin, sizeof(pin)); + r = fido_bio_dev_get_template_array(dev, ta, pin); + explicit_bzero(pin, sizeof(pin)); + + if (r != FIDO_OK) + errx(1, "fido_bio_dev_get_template_array: %s", fido_strerr(r)); + for (size_t i = 0; i < fido_bio_template_array_count(ta); i++) + print_template(ta, i); + + fido_bio_template_array_free(&ta); + fido_dev_close(dev); + fido_dev_free(&dev); + + exit(0); +} + +int +bio_set_name(char *path, char *id, char *name) +{ + char pin[1024]; + fido_bio_template_t *t = NULL; + fido_dev_t *dev = NULL; + int r; + size_t id_blob_len = 0; + void *id_blob_ptr = NULL; + + if (path == NULL) + usage(); + if ((t = fido_bio_template_new()) == NULL) + errx(1, "fido_bio_template_new"); + + if (base64_decode(id, &id_blob_ptr, &id_blob_len) < 0) + errx(1, "base64_decode"); + + if ((r = fido_bio_template_set_name(t, name)) != FIDO_OK) + errx(1, "fido_bio_template_set_name: %s", fido_strerr(r)); + if ((r = fido_bio_template_set_id(t, id_blob_ptr, + id_blob_len)) != FIDO_OK) + errx(1, "fido_bio_template_set_id: %s", fido_strerr(r)); + + dev = open_dev(path); + read_pin(path, pin, sizeof(pin)); + r = fido_bio_dev_set_template_name(dev, t, pin); + explicit_bzero(pin, sizeof(pin)); + + if (r != FIDO_OK) + errx(1, "fido_bio_dev_set_template_name: %s", fido_strerr(r)); + + free(id_blob_ptr); + fido_bio_template_free(&t); + fido_dev_close(dev); + fido_dev_free(&dev); + + exit(0); +} + +static const char * +plural(uint8_t n) +{ + if (n == 1) + return ""; + return "s"; +} + +static const char * +enroll_strerr(uint8_t n) +{ + switch (n) { + case FIDO_BIO_ENROLL_FP_GOOD: + return "Sample ok"; + case FIDO_BIO_ENROLL_FP_TOO_HIGH: + return "Sample too high"; + case FIDO_BIO_ENROLL_FP_TOO_LOW: + return "Sample too low"; + case FIDO_BIO_ENROLL_FP_TOO_LEFT: + return "Sample too left"; + case FIDO_BIO_ENROLL_FP_TOO_RIGHT: + return "Sample too right"; + case FIDO_BIO_ENROLL_FP_TOO_FAST: + return "Sample too fast"; + case FIDO_BIO_ENROLL_FP_TOO_SLOW: + return "Sample too slow"; + case FIDO_BIO_ENROLL_FP_POOR_QUALITY: + return "Poor quality sample"; + case FIDO_BIO_ENROLL_FP_TOO_SKEWED: + return "Sample too skewed"; + case FIDO_BIO_ENROLL_FP_TOO_SHORT: + return "Sample too short"; + case FIDO_BIO_ENROLL_FP_MERGE_FAILURE: + return "Sample merge failure"; + case FIDO_BIO_ENROLL_FP_EXISTS: + return "Sample exists"; + case FIDO_BIO_ENROLL_FP_DATABASE_FULL: + return "Fingerprint database full"; + case FIDO_BIO_ENROLL_NO_USER_ACTIVITY: + return "No user activity"; + case FIDO_BIO_ENROLL_NO_USER_PRESENCE_TRANSITION: + return "No user presence transition"; + default: + return "Unknown error"; + } +} + +int +bio_enroll(char *path) +{ + char pin[1024]; + fido_bio_enroll_t *e = NULL; + fido_bio_template_t *t = NULL; + fido_dev_t *dev = NULL; + int r; + + if (path == NULL) + usage(); + if ((t = fido_bio_template_new()) == NULL) + errx(1, "fido_bio_template_new"); + if ((e = fido_bio_enroll_new()) == NULL) + errx(1, "fido_bio_enroll_new"); + + dev = open_dev(path); + read_pin(path, pin, sizeof(pin)); + + printf("Touch your security key.\n"); + + r = fido_bio_dev_enroll_begin(dev, t, e, 10000, pin); + explicit_bzero(pin, sizeof(pin)); + if (r != FIDO_OK) + errx(1, "fido_bio_dev_enroll_begin: %s", fido_strerr(r)); + + printf("%s.\n", enroll_strerr(fido_bio_enroll_last_status(e))); + + while (fido_bio_enroll_remaining_samples(e) > 0) { + printf("Touch your security key (%u sample%s left).\n", + (unsigned)fido_bio_enroll_remaining_samples(e), + plural(fido_bio_enroll_remaining_samples(e))); + if ((r = fido_bio_dev_enroll_continue(dev, t, e, + 10000)) != FIDO_OK) { + errx(1, "fido_bio_dev_enroll_continue: %s", + fido_strerr(r)); + } + printf("%s.\n", enroll_strerr(fido_bio_enroll_last_status(e))); + } + + fido_bio_template_free(&t); + fido_bio_enroll_free(&e); + fido_dev_close(dev); + fido_dev_free(&dev); + + exit(0); +} + +int +bio_delete(fido_dev_t *dev, char *path, char *id) +{ + char pin[1024]; + fido_bio_template_t *t = NULL; + int r; + size_t id_blob_len = 0; + void *id_blob_ptr = NULL; + + if (path == NULL) + usage(); + if ((t = fido_bio_template_new()) == NULL) + errx(1, "fido_bio_template_new"); + + if (base64_decode(id, &id_blob_ptr, &id_blob_len) < 0) + errx(1, "base64_decode"); + if ((r = fido_bio_template_set_id(t, id_blob_ptr, + id_blob_len)) != FIDO_OK) + errx(1, "fido_bio_template_set_id: %s", fido_strerr(r)); + + read_pin(path, pin, sizeof(pin)); + r = fido_bio_dev_enroll_remove(dev, t, pin); + explicit_bzero(pin, sizeof(pin)); + + if (r != FIDO_OK) + errx(1, "fido_bio_dev_enroll_remove: %s", fido_strerr(r)); + + free(id_blob_ptr); + fido_bio_template_free(&t); + fido_dev_close(dev); + fido_dev_free(&dev); + + exit(0); +} + +static const char * +type_str(uint8_t t) +{ + switch (t) { + case 1: + return "touch"; + case 2: + return "swipe"; + default: + return "unknown"; + } +} + +void +bio_info(fido_dev_t *dev) +{ + fido_bio_info_t *i = NULL; + int r; + + if ((i = fido_bio_info_new()) == NULL) + errx(1, "fido_bio_info_new"); + if ((r = fido_bio_dev_get_info(dev, i)) != FIDO_OK) { + fido_bio_info_free(&i); + return; + } + + printf("sensor type: %u (%s)\n", (unsigned)fido_bio_info_type(i), + type_str(fido_bio_info_type(i))); + printf("max samples: %u\n", (unsigned)fido_bio_info_max_samples(i)); + + fido_bio_info_free(&i); +} -- cgit v1.2.3