xref: /freebsd-src/contrib/libfido2/tools/config.c (revision 2ccfa855b2fc331819953e3de1b1c15ce5b95a7e)
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