xref: /netbsd-src/external/bsd/libfido2/dist/tools/config.c (revision 2d40c4512a84c0d064ec30a492c5e2a14d230bc3)
195dbdf32Schristos /*
295dbdf32Schristos  * Copyright (c) 2020 Yubico AB. All rights reserved.
395dbdf32Schristos  * Use of this source code is governed by a BSD-style
495dbdf32Schristos  * license that can be found in the LICENSE file.
5*2d40c451Schristos  * SPDX-License-Identifier: BSD-2-Clause
695dbdf32Schristos  */
795dbdf32Schristos 
895dbdf32Schristos #include <stdio.h>
995dbdf32Schristos #include <stdlib.h>
1095dbdf32Schristos #include <string.h>
1195dbdf32Schristos 
1295dbdf32Schristos #include <fido.h>
1395dbdf32Schristos #include <fido/config.h>
1495dbdf32Schristos 
1595dbdf32Schristos #include "../openbsd-compat/openbsd-compat.h"
1695dbdf32Schristos #include "extern.h"
1795dbdf32Schristos 
1895dbdf32Schristos int
config_entattest(char * path)1995dbdf32Schristos config_entattest(char *path)
2095dbdf32Schristos {
2195dbdf32Schristos 	fido_dev_t *dev;
2295dbdf32Schristos 	char *pin = NULL;
2395dbdf32Schristos 	int r, ok = 1;
2495dbdf32Schristos 
2595dbdf32Schristos 	dev = open_dev(path);
2695dbdf32Schristos 	if ((r = fido_dev_enable_entattest(dev, NULL)) != FIDO_OK &&
2795dbdf32Schristos 	    should_retry_with_pin(dev, r)) {
2895dbdf32Schristos 		if ((pin = get_pin(path)) == NULL)
2995dbdf32Schristos 			goto out;
3095dbdf32Schristos 		r = fido_dev_enable_entattest(dev, pin);
3195dbdf32Schristos 		freezero(pin, PINBUF_LEN);
3295dbdf32Schristos 		pin = NULL;
3395dbdf32Schristos 	}
3495dbdf32Schristos 	if (r != FIDO_OK) {
3595dbdf32Schristos 		warnx("fido_dev_enable_entattest: %s (0x%x)",
3695dbdf32Schristos 		    fido_strerr(r), r);
3795dbdf32Schristos 		goto out;
3895dbdf32Schristos 	}
3995dbdf32Schristos 
4095dbdf32Schristos 	ok = 0;
4195dbdf32Schristos out:
4295dbdf32Schristos 	fido_dev_close(dev);
4395dbdf32Schristos 	fido_dev_free(&dev);
4495dbdf32Schristos 
4595dbdf32Schristos 	exit(ok);
4695dbdf32Schristos }
4795dbdf32Schristos 
4895dbdf32Schristos int
config_always_uv(char * path,int toggle)4995dbdf32Schristos config_always_uv(char *path, int toggle)
5095dbdf32Schristos {
5195dbdf32Schristos 	fido_dev_t *dev;
5295dbdf32Schristos 	char *pin = NULL;
5395dbdf32Schristos 	int v, r, ok = 1;
5495dbdf32Schristos 
5595dbdf32Schristos 	dev = open_dev(path);
5695dbdf32Schristos 	if (get_devopt(dev, "alwaysUv", &v) < 0) {
5795dbdf32Schristos 		warnx("%s: getdevopt", __func__);
5895dbdf32Schristos 		goto out;
5995dbdf32Schristos 	}
6095dbdf32Schristos 	if (v == -1) {
6195dbdf32Schristos 		warnx("%s: option not found", __func__);
6295dbdf32Schristos 		goto out;
6395dbdf32Schristos 	}
6495dbdf32Schristos 	if (v == toggle) {
6595dbdf32Schristos 		ok = 0;
6695dbdf32Schristos 		goto out;
6795dbdf32Schristos 	}
6895dbdf32Schristos 	if ((r = fido_dev_toggle_always_uv(dev, NULL)) != FIDO_OK &&
6995dbdf32Schristos 	    should_retry_with_pin(dev, r)) {
7095dbdf32Schristos 		if ((pin = get_pin(path)) == NULL)
7195dbdf32Schristos 			goto out;
7295dbdf32Schristos 		r = fido_dev_toggle_always_uv(dev, pin);
7395dbdf32Schristos 		freezero(pin, PINBUF_LEN);
7495dbdf32Schristos 		pin = NULL;
7595dbdf32Schristos 	}
7695dbdf32Schristos 	if (r != FIDO_OK) {
7795dbdf32Schristos 		warnx("fido_dev_toggle_always_uv: %s (0x%x)",
7895dbdf32Schristos 		    fido_strerr(r), r);
7995dbdf32Schristos 		goto out;
8095dbdf32Schristos 	}
8195dbdf32Schristos 
8295dbdf32Schristos 	ok = 0;
8395dbdf32Schristos out:
8495dbdf32Schristos 	fido_dev_close(dev);
8595dbdf32Schristos 	fido_dev_free(&dev);
8695dbdf32Schristos 
8795dbdf32Schristos 	exit(ok);
8895dbdf32Schristos }
8995dbdf32Schristos 
9095dbdf32Schristos int
config_pin_minlen(char * path,const char * pinlen)9195dbdf32Schristos config_pin_minlen(char *path, const char *pinlen)
9295dbdf32Schristos {
9395dbdf32Schristos 	fido_dev_t *dev;
9495dbdf32Schristos 	char *pin = NULL;
9595dbdf32Schristos 	int len, r, ok = 1;
9695dbdf32Schristos 
9795dbdf32Schristos 	dev = open_dev(path);
9895dbdf32Schristos 	if ((len = base10(pinlen)) < 0 || len > 63) {
9995dbdf32Schristos 		warnx("%s: len > 63", __func__);
10095dbdf32Schristos 		goto out;
10195dbdf32Schristos 	}
10295dbdf32Schristos 	if ((r = fido_dev_set_pin_minlen(dev, (size_t)len, NULL)) != FIDO_OK &&
10395dbdf32Schristos 	    should_retry_with_pin(dev, r)) {
10495dbdf32Schristos 		if ((pin = get_pin(path)) == NULL)
10595dbdf32Schristos 			goto out;
10695dbdf32Schristos 		r = fido_dev_set_pin_minlen(dev, (size_t)len, pin);
10795dbdf32Schristos 		freezero(pin, PINBUF_LEN);
10895dbdf32Schristos 		pin = NULL;
10995dbdf32Schristos 	}
11095dbdf32Schristos 	if (r != FIDO_OK) {
11195dbdf32Schristos 		warnx("fido_dev_set_pin_minlen: %s (0x%x)", fido_strerr(r), r);
11295dbdf32Schristos 		goto out;
11395dbdf32Schristos 	}
11495dbdf32Schristos 
11595dbdf32Schristos 	ok = 0;
11695dbdf32Schristos out:
11795dbdf32Schristos 	fido_dev_close(dev);
11895dbdf32Schristos 	fido_dev_free(&dev);
11995dbdf32Schristos 
12095dbdf32Schristos 	exit(ok);
12195dbdf32Schristos }
12295dbdf32Schristos 
12395dbdf32Schristos int
config_force_pin_change(char * path)12495dbdf32Schristos config_force_pin_change(char *path)
12595dbdf32Schristos {
12695dbdf32Schristos 	fido_dev_t *dev;
12795dbdf32Schristos 	char *pin = NULL;
12895dbdf32Schristos 	int r, ok = 1;
12995dbdf32Schristos 
13095dbdf32Schristos 	dev = open_dev(path);
13195dbdf32Schristos 	if ((r = fido_dev_force_pin_change(dev, NULL)) != FIDO_OK &&
13295dbdf32Schristos 	    should_retry_with_pin(dev, r)) {
13395dbdf32Schristos 		if ((pin = get_pin(path)) == NULL)
13495dbdf32Schristos 			goto out;
13595dbdf32Schristos 		r = fido_dev_force_pin_change(dev, pin);
13695dbdf32Schristos 		freezero(pin, PINBUF_LEN);
13795dbdf32Schristos 		pin = NULL;
13895dbdf32Schristos 	}
13995dbdf32Schristos 	if (r != FIDO_OK) {
14095dbdf32Schristos 		warnx("fido_dev_force_pin_change: %s (0x%x)", fido_strerr(r), r);
14195dbdf32Schristos 		goto out;
14295dbdf32Schristos 	}
14395dbdf32Schristos 
14495dbdf32Schristos 	ok = 0;
14595dbdf32Schristos out:
14695dbdf32Schristos 	fido_dev_close(dev);
14795dbdf32Schristos 	fido_dev_free(&dev);
14895dbdf32Schristos 
14995dbdf32Schristos 	exit(ok);
15095dbdf32Schristos }
151*2d40c451Schristos 
152*2d40c451Schristos int
config_pin_minlen_rpid(char * path,const char * rpids)153*2d40c451Schristos config_pin_minlen_rpid(char *path, const char *rpids)
154*2d40c451Schristos {
155*2d40c451Schristos 	fido_dev_t *dev;
156*2d40c451Schristos 	char *otmp, *tmp, *cp;
157*2d40c451Schristos 	char *pin = NULL, **rpid = NULL;
158*2d40c451Schristos 	int r, ok = 1;
159*2d40c451Schristos 	size_t n;
160*2d40c451Schristos 
161*2d40c451Schristos 	if ((tmp = strdup(rpids)) == NULL)
162*2d40c451Schristos 		err(1, "strdup");
163*2d40c451Schristos 	otmp = tmp;
164*2d40c451Schristos 	for (n = 0; (cp = strsep(&tmp, ",")) != NULL; n++) {
165*2d40c451Schristos 		if (n == SIZE_MAX || (rpid = recallocarray(rpid, n, n + 1,
166*2d40c451Schristos 		    sizeof(*rpid))) == NULL)
167*2d40c451Schristos 			err(1, "recallocarray");
168*2d40c451Schristos 		if ((rpid[n] = strdup(cp)) == NULL)
169*2d40c451Schristos 			err(1, "strdup");
170*2d40c451Schristos 		if (*rpid[n] == '\0')
171*2d40c451Schristos 			errx(1, "empty rpid");
172*2d40c451Schristos 	}
173*2d40c451Schristos 	free(otmp);
174*2d40c451Schristos 	if (rpid == NULL || n == 0)
175*2d40c451Schristos 		errx(1, "could not parse rp_id");
176*2d40c451Schristos 	dev = open_dev(path);
177*2d40c451Schristos 	if ((r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
178*2d40c451Schristos 	    n, NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
179*2d40c451Schristos 		if ((pin = get_pin(path)) == NULL)
180*2d40c451Schristos 			goto out;
181*2d40c451Schristos 		r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
182*2d40c451Schristos 		    n, pin);
183*2d40c451Schristos 		freezero(pin, PINBUF_LEN);
184*2d40c451Schristos 		pin = NULL;
185*2d40c451Schristos 	}
186*2d40c451Schristos 	if (r != FIDO_OK) {
187*2d40c451Schristos 		warnx("fido_dev_set_pin_minlen_rpid: %s (0x%x)",
188*2d40c451Schristos 		    fido_strerr(r), r);
189*2d40c451Schristos 		goto out;
190*2d40c451Schristos 	}
191*2d40c451Schristos 
192*2d40c451Schristos 	ok = 0;
193*2d40c451Schristos out:
194*2d40c451Schristos 	fido_dev_close(dev);
195*2d40c451Schristos 	fido_dev_free(&dev);
196*2d40c451Schristos 
197*2d40c451Schristos 	exit(ok);
198*2d40c451Schristos }
199