10afa8e06SEd Maste /*
20afa8e06SEd Maste * Copyright (c) 2020 Yubico AB. All rights reserved.
30afa8e06SEd Maste * Use of this source code is governed by a BSD-style
40afa8e06SEd Maste * license that can be found in the LICENSE file.
5*2ccfa855SEd Maste * SPDX-License-Identifier: BSD-2-Clause
60afa8e06SEd Maste */
70afa8e06SEd Maste
80afa8e06SEd Maste #include <stdio.h>
90afa8e06SEd Maste #include <stdlib.h>
100afa8e06SEd Maste #include <string.h>
110afa8e06SEd Maste
120afa8e06SEd Maste #include <fido.h>
130afa8e06SEd Maste #include <fido/config.h>
140afa8e06SEd Maste
150afa8e06SEd Maste #include "../openbsd-compat/openbsd-compat.h"
160afa8e06SEd Maste #include "extern.h"
170afa8e06SEd Maste
180afa8e06SEd Maste int
config_entattest(char * path)190afa8e06SEd Maste config_entattest(char *path)
200afa8e06SEd Maste {
210afa8e06SEd Maste fido_dev_t *dev;
220afa8e06SEd Maste char *pin = NULL;
230afa8e06SEd Maste int r, ok = 1;
240afa8e06SEd Maste
250afa8e06SEd Maste dev = open_dev(path);
260afa8e06SEd Maste if ((r = fido_dev_enable_entattest(dev, NULL)) != FIDO_OK &&
270afa8e06SEd Maste should_retry_with_pin(dev, r)) {
280afa8e06SEd Maste if ((pin = get_pin(path)) == NULL)
290afa8e06SEd Maste goto out;
300afa8e06SEd Maste r = fido_dev_enable_entattest(dev, pin);
310afa8e06SEd Maste freezero(pin, PINBUF_LEN);
320afa8e06SEd Maste pin = NULL;
330afa8e06SEd Maste }
340afa8e06SEd Maste if (r != FIDO_OK) {
350afa8e06SEd Maste warnx("fido_dev_enable_entattest: %s (0x%x)",
360afa8e06SEd Maste fido_strerr(r), r);
370afa8e06SEd Maste goto out;
380afa8e06SEd Maste }
390afa8e06SEd Maste
400afa8e06SEd Maste ok = 0;
410afa8e06SEd Maste out:
420afa8e06SEd Maste fido_dev_close(dev);
430afa8e06SEd Maste fido_dev_free(&dev);
440afa8e06SEd Maste
450afa8e06SEd Maste exit(ok);
460afa8e06SEd Maste }
470afa8e06SEd Maste
480afa8e06SEd Maste int
config_always_uv(char * path,int toggle)490afa8e06SEd Maste config_always_uv(char *path, int toggle)
500afa8e06SEd Maste {
510afa8e06SEd Maste fido_dev_t *dev;
520afa8e06SEd Maste char *pin = NULL;
530afa8e06SEd Maste int v, r, ok = 1;
540afa8e06SEd Maste
550afa8e06SEd Maste dev = open_dev(path);
560afa8e06SEd Maste if (get_devopt(dev, "alwaysUv", &v) < 0) {
570afa8e06SEd Maste warnx("%s: getdevopt", __func__);
580afa8e06SEd Maste goto out;
590afa8e06SEd Maste }
600afa8e06SEd Maste if (v == -1) {
610afa8e06SEd Maste warnx("%s: option not found", __func__);
620afa8e06SEd Maste goto out;
630afa8e06SEd Maste }
640afa8e06SEd Maste if (v == toggle) {
650afa8e06SEd Maste ok = 0;
660afa8e06SEd Maste goto out;
670afa8e06SEd Maste }
680afa8e06SEd Maste if ((r = fido_dev_toggle_always_uv(dev, NULL)) != FIDO_OK &&
690afa8e06SEd Maste should_retry_with_pin(dev, r)) {
700afa8e06SEd Maste if ((pin = get_pin(path)) == NULL)
710afa8e06SEd Maste goto out;
720afa8e06SEd Maste r = fido_dev_toggle_always_uv(dev, pin);
730afa8e06SEd Maste freezero(pin, PINBUF_LEN);
740afa8e06SEd Maste pin = NULL;
750afa8e06SEd Maste }
760afa8e06SEd Maste if (r != FIDO_OK) {
770afa8e06SEd Maste warnx("fido_dev_toggle_always_uv: %s (0x%x)",
780afa8e06SEd Maste fido_strerr(r), r);
790afa8e06SEd Maste goto out;
800afa8e06SEd Maste }
810afa8e06SEd Maste
820afa8e06SEd Maste ok = 0;
830afa8e06SEd Maste out:
840afa8e06SEd Maste fido_dev_close(dev);
850afa8e06SEd Maste fido_dev_free(&dev);
860afa8e06SEd Maste
870afa8e06SEd Maste exit(ok);
880afa8e06SEd Maste }
890afa8e06SEd Maste
900afa8e06SEd Maste int
config_pin_minlen(char * path,const char * pinlen)910afa8e06SEd Maste config_pin_minlen(char *path, const char *pinlen)
920afa8e06SEd Maste {
930afa8e06SEd Maste fido_dev_t *dev;
940afa8e06SEd Maste char *pin = NULL;
950afa8e06SEd Maste int len, r, ok = 1;
960afa8e06SEd Maste
970afa8e06SEd Maste dev = open_dev(path);
980afa8e06SEd Maste if ((len = base10(pinlen)) < 0 || len > 63) {
990afa8e06SEd Maste warnx("%s: len > 63", __func__);
1000afa8e06SEd Maste goto out;
1010afa8e06SEd Maste }
1020afa8e06SEd Maste if ((r = fido_dev_set_pin_minlen(dev, (size_t)len, NULL)) != FIDO_OK &&
1030afa8e06SEd Maste should_retry_with_pin(dev, r)) {
1040afa8e06SEd Maste if ((pin = get_pin(path)) == NULL)
1050afa8e06SEd Maste goto out;
1060afa8e06SEd Maste r = fido_dev_set_pin_minlen(dev, (size_t)len, pin);
1070afa8e06SEd Maste freezero(pin, PINBUF_LEN);
1080afa8e06SEd Maste pin = NULL;
1090afa8e06SEd Maste }
1100afa8e06SEd Maste if (r != FIDO_OK) {
1110afa8e06SEd Maste warnx("fido_dev_set_pin_minlen: %s (0x%x)", fido_strerr(r), r);
1120afa8e06SEd Maste goto out;
1130afa8e06SEd Maste }
1140afa8e06SEd Maste
1150afa8e06SEd Maste ok = 0;
1160afa8e06SEd Maste out:
1170afa8e06SEd Maste fido_dev_close(dev);
1180afa8e06SEd Maste fido_dev_free(&dev);
1190afa8e06SEd Maste
1200afa8e06SEd Maste exit(ok);
1210afa8e06SEd Maste }
1220afa8e06SEd Maste
1230afa8e06SEd Maste int
config_force_pin_change(char * path)1240afa8e06SEd Maste config_force_pin_change(char *path)
1250afa8e06SEd Maste {
1260afa8e06SEd Maste fido_dev_t *dev;
1270afa8e06SEd Maste char *pin = NULL;
1280afa8e06SEd Maste int r, ok = 1;
1290afa8e06SEd Maste
1300afa8e06SEd Maste dev = open_dev(path);
1310afa8e06SEd Maste if ((r = fido_dev_force_pin_change(dev, NULL)) != FIDO_OK &&
1320afa8e06SEd Maste should_retry_with_pin(dev, r)) {
1330afa8e06SEd Maste if ((pin = get_pin(path)) == NULL)
1340afa8e06SEd Maste goto out;
1350afa8e06SEd Maste r = fido_dev_force_pin_change(dev, pin);
1360afa8e06SEd Maste freezero(pin, PINBUF_LEN);
1370afa8e06SEd Maste pin = NULL;
1380afa8e06SEd Maste }
1390afa8e06SEd Maste if (r != FIDO_OK) {
1400afa8e06SEd Maste warnx("fido_dev_force_pin_change: %s (0x%x)", fido_strerr(r), r);
1410afa8e06SEd Maste goto out;
1420afa8e06SEd Maste }
1430afa8e06SEd Maste
1440afa8e06SEd Maste ok = 0;
1450afa8e06SEd Maste out:
1460afa8e06SEd Maste fido_dev_close(dev);
1470afa8e06SEd Maste fido_dev_free(&dev);
1480afa8e06SEd Maste
1490afa8e06SEd Maste exit(ok);
1500afa8e06SEd Maste }
151f540a430SEd Maste
152f540a430SEd Maste int
config_pin_minlen_rpid(char * path,const char * rpids)153f540a430SEd Maste config_pin_minlen_rpid(char *path, const char *rpids)
154f540a430SEd Maste {
155f540a430SEd Maste fido_dev_t *dev;
156f540a430SEd Maste char *otmp, *tmp, *cp;
157f540a430SEd Maste char *pin = NULL, **rpid = NULL;
158f540a430SEd Maste int r, ok = 1;
159f540a430SEd Maste size_t n;
160f540a430SEd Maste
161f540a430SEd Maste if ((tmp = strdup(rpids)) == NULL)
162f540a430SEd Maste err(1, "strdup");
163f540a430SEd Maste otmp = tmp;
164f540a430SEd Maste for (n = 0; (cp = strsep(&tmp, ",")) != NULL; n++) {
165f540a430SEd Maste if (n == SIZE_MAX || (rpid = recallocarray(rpid, n, n + 1,
166f540a430SEd Maste sizeof(*rpid))) == NULL)
167f540a430SEd Maste err(1, "recallocarray");
168f540a430SEd Maste if ((rpid[n] = strdup(cp)) == NULL)
169f540a430SEd Maste err(1, "strdup");
170f540a430SEd Maste if (*rpid[n] == '\0')
171f540a430SEd Maste errx(1, "empty rpid");
172f540a430SEd Maste }
173f540a430SEd Maste free(otmp);
174f540a430SEd Maste if (rpid == NULL || n == 0)
175f540a430SEd Maste errx(1, "could not parse rp_id");
176f540a430SEd Maste dev = open_dev(path);
177f540a430SEd Maste if ((r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
178f540a430SEd Maste n, NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
179f540a430SEd Maste if ((pin = get_pin(path)) == NULL)
180f540a430SEd Maste goto out;
181f540a430SEd Maste r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
182f540a430SEd Maste n, pin);
183f540a430SEd Maste freezero(pin, PINBUF_LEN);
184f540a430SEd Maste pin = NULL;
185f540a430SEd Maste }
186f540a430SEd Maste if (r != FIDO_OK) {
187f540a430SEd Maste warnx("fido_dev_set_pin_minlen_rpid: %s (0x%x)",
188f540a430SEd Maste fido_strerr(r), r);
189f540a430SEd Maste goto out;
190f540a430SEd Maste }
191f540a430SEd Maste
192f540a430SEd Maste ok = 0;
193f540a430SEd Maste out:
194f540a430SEd Maste fido_dev_close(dev);
195f540a430SEd Maste fido_dev_free(&dev);
196f540a430SEd Maste
197f540a430SEd Maste exit(ok);
198f540a430SEd Maste }
199