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
config_entattest(char * path)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
config_always_uv(char * path,int toggle)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
config_pin_minlen(char * path,const char * pinlen)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
config_force_pin_change(char * path)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
config_pin_minlen_rpid(char * path,const char * rpids)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