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