Home | History | Annotate | Line # | Download | only in tools
      1 /*
      2  * Copyright (c) 2020 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 <stdio.h>
      9 #include <stdlib.h>
     10 #include <string.h>
     11 
     12 #include <fido.h>
     13 #include <fido/config.h>
     14 
     15 #include "../openbsd-compat/openbsd-compat.h"
     16 #include "extern.h"
     17 
     18 int
     19 config_entattest(char *path)
     20 {
     21 	fido_dev_t *dev;
     22 	char *pin = NULL;
     23 	int r, ok = 1;
     24 
     25 	dev = open_dev(path);
     26 	if ((r = fido_dev_enable_entattest(dev, NULL)) != FIDO_OK &&
     27 	    should_retry_with_pin(dev, r)) {
     28 		if ((pin = get_pin(path)) == NULL)
     29 			goto out;
     30 		r = fido_dev_enable_entattest(dev, pin);
     31 		freezero(pin, PINBUF_LEN);
     32 		pin = NULL;
     33 	}
     34 	if (r != FIDO_OK) {
     35 		warnx("fido_dev_enable_entattest: %s (0x%x)",
     36 		    fido_strerr(r), r);
     37 		goto out;
     38 	}
     39 
     40 	ok = 0;
     41 out:
     42 	fido_dev_close(dev);
     43 	fido_dev_free(&dev);
     44 
     45 	exit(ok);
     46 }
     47 
     48 int
     49 config_always_uv(char *path, int toggle)
     50 {
     51 	fido_dev_t *dev;
     52 	char *pin = NULL;
     53 	int v, r, ok = 1;
     54 
     55 	dev = open_dev(path);
     56 	if (get_devopt(dev, "alwaysUv", &v) < 0) {
     57 		warnx("%s: getdevopt", __func__);
     58 		goto out;
     59 	}
     60 	if (v == -1) {
     61 		warnx("%s: option not found", __func__);
     62 		goto out;
     63 	}
     64 	if (v == toggle) {
     65 		ok = 0;
     66 		goto out;
     67 	}
     68 	if ((r = fido_dev_toggle_always_uv(dev, NULL)) != FIDO_OK &&
     69 	    should_retry_with_pin(dev, r)) {
     70 		if ((pin = get_pin(path)) == NULL)
     71 			goto out;
     72 		r = fido_dev_toggle_always_uv(dev, pin);
     73 		freezero(pin, PINBUF_LEN);
     74 		pin = NULL;
     75 	}
     76 	if (r != FIDO_OK) {
     77 		warnx("fido_dev_toggle_always_uv: %s (0x%x)",
     78 		    fido_strerr(r), r);
     79 		goto out;
     80 	}
     81 
     82 	ok = 0;
     83 out:
     84 	fido_dev_close(dev);
     85 	fido_dev_free(&dev);
     86 
     87 	exit(ok);
     88 }
     89 
     90 int
     91 config_pin_minlen(char *path, const char *pinlen)
     92 {
     93 	fido_dev_t *dev;
     94 	char *pin = NULL;
     95 	int len, r, ok = 1;
     96 
     97 	dev = open_dev(path);
     98 	if ((len = base10(pinlen)) < 0 || len > 63) {
     99 		warnx("%s: len > 63", __func__);
    100 		goto out;
    101 	}
    102 	if ((r = fido_dev_set_pin_minlen(dev, (size_t)len, NULL)) != FIDO_OK &&
    103 	    should_retry_with_pin(dev, r)) {
    104 		if ((pin = get_pin(path)) == NULL)
    105 			goto out;
    106 		r = fido_dev_set_pin_minlen(dev, (size_t)len, pin);
    107 		freezero(pin, PINBUF_LEN);
    108 		pin = NULL;
    109 	}
    110 	if (r != FIDO_OK) {
    111 		warnx("fido_dev_set_pin_minlen: %s (0x%x)", fido_strerr(r), r);
    112 		goto out;
    113 	}
    114 
    115 	ok = 0;
    116 out:
    117 	fido_dev_close(dev);
    118 	fido_dev_free(&dev);
    119 
    120 	exit(ok);
    121 }
    122 
    123 int
    124 config_force_pin_change(char *path)
    125 {
    126 	fido_dev_t *dev;
    127 	char *pin = NULL;
    128 	int r, ok = 1;
    129 
    130 	dev = open_dev(path);
    131 	if ((r = fido_dev_force_pin_change(dev, NULL)) != FIDO_OK &&
    132 	    should_retry_with_pin(dev, r)) {
    133 		if ((pin = get_pin(path)) == NULL)
    134 			goto out;
    135 		r = fido_dev_force_pin_change(dev, pin);
    136 		freezero(pin, PINBUF_LEN);
    137 		pin = NULL;
    138 	}
    139 	if (r != FIDO_OK) {
    140 		warnx("fido_dev_force_pin_change: %s (0x%x)", fido_strerr(r), r);
    141 		goto out;
    142 	}
    143 
    144 	ok = 0;
    145 out:
    146 	fido_dev_close(dev);
    147 	fido_dev_free(&dev);
    148 
    149 	exit(ok);
    150 }
    151 
    152 int
    153 config_pin_minlen_rpid(char *path, const char *rpids)
    154 {
    155 	fido_dev_t *dev;
    156 	char *otmp, *tmp, *cp;
    157 	char *pin = NULL, **rpid = NULL;
    158 	int r, ok = 1;
    159 	size_t n;
    160 
    161 	if ((tmp = strdup(rpids)) == NULL)
    162 		err(1, "strdup");
    163 	otmp = tmp;
    164 	for (n = 0; (cp = strsep(&tmp, ",")) != NULL; n++) {
    165 		if (n == SIZE_MAX || (rpid = recallocarray(rpid, n, n + 1,
    166 		    sizeof(*rpid))) == NULL)
    167 			err(1, "recallocarray");
    168 		if ((rpid[n] = strdup(cp)) == NULL)
    169 			err(1, "strdup");
    170 		if (*rpid[n] == '\0')
    171 			errx(1, "empty rpid");
    172 	}
    173 	free(otmp);
    174 	if (rpid == NULL || n == 0)
    175 		errx(1, "could not parse rp_id");
    176 	dev = open_dev(path);
    177 	if ((r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
    178 	    n, NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
    179 		if ((pin = get_pin(path)) == NULL)
    180 			goto out;
    181 		r = fido_dev_set_pin_minlen_rpid(dev, (const char * const *)rpid,
    182 		    n, pin);
    183 		freezero(pin, PINBUF_LEN);
    184 		pin = NULL;
    185 	}
    186 	if (r != FIDO_OK) {
    187 		warnx("fido_dev_set_pin_minlen_rpid: %s (0x%x)",
    188 		    fido_strerr(r), r);
    189 		goto out;
    190 	}
    191 
    192 	ok = 0;
    193 out:
    194 	fido_dev_close(dev);
    195 	fido_dev_free(&dev);
    196 
    197 	exit(ok);
    198 }
    199