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