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