]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/libfido2/tools/credman.c
MFV: zlib 1.2.13.
[FreeBSD/FreeBSD.git] / contrib / libfido2 / tools / credman.c
1 /*
2  * Copyright (c) 2019 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 <fido.h>
8 #include <fido/credman.h>
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #ifdef HAVE_UNISTD_H
14 #include <unistd.h>
15 #endif
16
17 #include "../openbsd-compat/openbsd-compat.h"
18 #include "extern.h"
19
20 int
21 credman_get_metadata(fido_dev_t *dev, const char *path)
22 {
23         fido_credman_metadata_t *metadata = NULL;
24         char *pin = NULL;
25         int r, ok = 1;
26
27         if ((metadata = fido_credman_metadata_new()) == NULL) {
28                 warnx("fido_credman_metadata_new");
29                 goto out;
30         }
31         if ((r = fido_credman_get_dev_metadata(dev, metadata,
32             NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
33                 if ((pin = get_pin(path)) == NULL)
34                         goto out;
35                 r = fido_credman_get_dev_metadata(dev, metadata, pin);
36                 freezero(pin, PINBUF_LEN);
37                 pin = NULL;
38         }
39         if (r != FIDO_OK) {
40                 warnx("fido_credman_get_dev_metadata: %s", fido_strerr(r));
41                 goto out;
42         }
43
44         printf("existing rk(s): %u\n",
45             (unsigned)fido_credman_rk_existing(metadata));
46         printf("remaining rk(s): %u\n",
47             (unsigned)fido_credman_rk_remaining(metadata));
48
49         ok = 0;
50 out:
51         fido_credman_metadata_free(&metadata);
52         fido_dev_close(dev);
53         fido_dev_free(&dev);
54
55         exit(ok);
56 }
57
58 static int
59 print_rp(fido_credman_rp_t *rp, size_t idx)
60 {
61         char *rp_id_hash = NULL;
62
63         if (base64_encode(fido_credman_rp_id_hash_ptr(rp, idx),
64             fido_credman_rp_id_hash_len(rp, idx), &rp_id_hash) < 0) {
65                 warnx("output error");
66                 return -1;
67         }
68         printf("%02u: %s %s\n", (unsigned)idx, rp_id_hash,
69             fido_credman_rp_id(rp, idx));
70         free(rp_id_hash);
71
72         return 0;
73 }
74
75 int
76 credman_list_rp(const char *path)
77 {
78         fido_credman_rp_t *rp = NULL;
79         fido_dev_t *dev = NULL;
80         char *pin = NULL;
81         int r, ok = 1;
82
83         dev = open_dev(path);
84         if ((rp = fido_credman_rp_new()) == NULL) {
85                 warnx("fido_credman_rp_new");
86                 goto out;
87         }
88         if ((r = fido_credman_get_dev_rp(dev, rp, NULL)) != FIDO_OK &&
89             should_retry_with_pin(dev, r)) {
90                 if ((pin = get_pin(path)) == NULL)
91                         goto out;
92                 r = fido_credman_get_dev_rp(dev, rp, pin);
93                 freezero(pin, PINBUF_LEN);
94                 pin = NULL;
95         }
96         if (r != FIDO_OK) {
97                 warnx("fido_credman_get_dev_rp: %s", fido_strerr(r));
98                 goto out;
99         }
100         for (size_t i = 0; i < fido_credman_rp_count(rp); i++)
101                 if (print_rp(rp, i) < 0)
102                         goto out;
103
104         ok = 0;
105 out:
106         fido_credman_rp_free(&rp);
107         fido_dev_close(dev);
108         fido_dev_free(&dev);
109
110         exit(ok);
111 }
112
113 static int
114 print_rk(const fido_credman_rk_t *rk, size_t idx)
115 {
116         const fido_cred_t *cred;
117         char *id = NULL;
118         char *user_id = NULL;
119         const char *type;
120         const char *prot;
121
122         if ((cred = fido_credman_rk(rk, idx)) == NULL) {
123                 warnx("fido_credman_rk");
124                 return -1;
125         }
126         if (base64_encode(fido_cred_id_ptr(cred), fido_cred_id_len(cred),
127             &id) < 0 || base64_encode(fido_cred_user_id_ptr(cred),
128             fido_cred_user_id_len(cred), &user_id) < 0) {
129                 warnx("output error");
130                 return -1;
131         }
132
133         type = cose_string(fido_cred_type(cred));
134         prot = prot_string(fido_cred_prot(cred));
135
136         printf("%02u: %s %s %s %s %s\n", (unsigned)idx, id,
137             fido_cred_display_name(cred), user_id, type, prot);
138
139         free(user_id);
140         free(id);
141
142         return 0;
143 }
144
145 int
146 credman_list_rk(const char *path, const char *rp_id)
147 {
148         fido_dev_t *dev = NULL;
149         fido_credman_rk_t *rk = NULL;
150         char *pin = NULL;
151         int r, ok = 1;
152
153         dev = open_dev(path);
154         if ((rk = fido_credman_rk_new()) == NULL) {
155                 warnx("fido_credman_rk_new");
156                 goto out;
157         }
158         if ((r = fido_credman_get_dev_rk(dev, rp_id, rk, NULL)) != FIDO_OK &&
159             should_retry_with_pin(dev, r)) {
160                 if ((pin = get_pin(path)) == NULL)
161                         goto out;
162                 r = fido_credman_get_dev_rk(dev, rp_id, rk, pin);
163                 freezero(pin, PINBUF_LEN);
164                 pin = NULL;
165         }
166         if (r != FIDO_OK) {
167                 warnx("fido_credman_get_dev_rk: %s", fido_strerr(r));
168                 goto out;
169         }
170         for (size_t i = 0; i < fido_credman_rk_count(rk); i++)
171                 if (print_rk(rk, i) < 0)
172                         goto out;
173
174         ok = 0;
175 out:
176         fido_credman_rk_free(&rk);
177         fido_dev_close(dev);
178         fido_dev_free(&dev);
179
180         exit(ok);
181 }
182
183 int
184 credman_print_rk(fido_dev_t *dev, const char *path, const char *rp_id,
185     const char *cred_id)
186 {
187         fido_credman_rk_t *rk = NULL;
188         const fido_cred_t *cred = NULL;
189         char *pin = NULL;
190         void *cred_id_ptr = NULL;
191         size_t cred_id_len = 0;
192         int r, ok = 1;
193
194         if ((rk = fido_credman_rk_new()) == NULL) {
195                 warnx("fido_credman_rk_new");
196                 goto out;
197         }
198         if (base64_decode(cred_id, &cred_id_ptr, &cred_id_len) < 0) {
199                 warnx("base64_decode");
200                 goto out;
201         }
202         if ((r = fido_credman_get_dev_rk(dev, rp_id, rk, NULL)) != FIDO_OK &&
203             should_retry_with_pin(dev, r)) {
204                 if ((pin = get_pin(path)) == NULL)
205                         goto out;
206                 r = fido_credman_get_dev_rk(dev, rp_id, rk, pin);
207                 freezero(pin, PINBUF_LEN);
208                 pin = NULL;
209         }
210         if (r != FIDO_OK) {
211                 warnx("fido_credman_get_dev_rk: %s", fido_strerr(r));
212                 goto out;
213         }
214
215         for (size_t i = 0; i < fido_credman_rk_count(rk); i++) {
216                 if ((cred = fido_credman_rk(rk, i)) == NULL ||
217                     fido_cred_id_ptr(cred) == NULL) {
218                         warnx("output error");
219                         goto out;
220                 }
221                 if (cred_id_len != fido_cred_id_len(cred) ||
222                     memcmp(cred_id_ptr, fido_cred_id_ptr(cred), cred_id_len))
223                         continue;
224                 print_cred(stdout, fido_cred_type(cred), cred);
225                 ok = 0;
226                 goto out;
227         }
228
229         warnx("credential not found");
230 out:
231         free(cred_id_ptr);
232         fido_credman_rk_free(&rk);
233         fido_dev_close(dev);
234         fido_dev_free(&dev);
235
236         exit(ok);
237 }
238
239 int
240 credman_delete_rk(const char *path, const char *id)
241 {
242         fido_dev_t *dev = NULL;
243         char *pin = NULL;
244         void *id_ptr = NULL;
245         size_t id_len = 0;
246         int r, ok = 1;
247
248         dev = open_dev(path);
249         if (base64_decode(id, &id_ptr, &id_len) < 0) {
250                 warnx("base64_decode");
251                 goto out;
252         }
253         if ((r = fido_credman_del_dev_rk(dev, id_ptr, id_len,
254             NULL)) != FIDO_OK && should_retry_with_pin(dev, r)) {
255                 if ((pin = get_pin(path)) == NULL)
256                         goto out;
257                 r = fido_credman_del_dev_rk(dev, id_ptr, id_len, pin);
258                 freezero(pin, PINBUF_LEN);
259                 pin = NULL;
260         }
261         if (r != FIDO_OK) {
262                 warnx("fido_credman_del_dev_rk: %s", fido_strerr(r));
263                 goto out;
264         }
265
266         ok = 0;
267 out:
268         free(id_ptr);
269         fido_dev_close(dev);
270         fido_dev_free(&dev);
271
272         exit(ok);
273 }
274
275 int
276 credman_update_rk(const char *path, const char *user_id, const char *cred_id,
277     const char *name, const char *display_name)
278 {
279         fido_dev_t *dev = NULL;
280         fido_cred_t *cred = NULL;
281         char *pin = NULL;
282         void *user_id_ptr = NULL;
283         void *cred_id_ptr = NULL;
284         size_t user_id_len = 0;
285         size_t cred_id_len = 0;
286         int r, ok = 1;
287
288         dev = open_dev(path);
289         if (base64_decode(user_id, &user_id_ptr, &user_id_len) < 0 ||
290             base64_decode(cred_id, &cred_id_ptr, &cred_id_len) < 0) {
291                 warnx("base64_decode");
292                 goto out;
293         }
294         if ((cred = fido_cred_new()) == NULL) {
295                 warnx("fido_cred_new");
296                 goto out;
297         }
298         if ((r = fido_cred_set_id(cred, cred_id_ptr, cred_id_len)) != FIDO_OK) { 
299                 warnx("fido_cred_set_id: %s",  fido_strerr(r));
300                 goto out;
301         }
302         if ((r = fido_cred_set_user(cred, user_id_ptr, user_id_len, name,
303             display_name, NULL)) != FIDO_OK) {
304                 warnx("fido_cred_set_user: %s", fido_strerr(r));
305                 goto out;
306         }
307         if ((r = fido_credman_set_dev_rk(dev, cred, NULL)) != FIDO_OK &&
308             should_retry_with_pin(dev, r)) {
309                 if ((pin = get_pin(path)) == NULL)
310                         goto out;
311                 r = fido_credman_set_dev_rk(dev, cred, pin);
312                 freezero(pin, PINBUF_LEN);
313                 pin = NULL;
314         }
315         if (r != FIDO_OK) {
316                 warnx("fido_credman_set_dev_rk: %s", fido_strerr(r));
317                 goto out;
318         }
319
320         ok = 0;
321 out:
322         free(user_id_ptr);
323         free(cred_id_ptr);
324         fido_dev_close(dev);
325         fido_dev_free(&dev);
326         fido_cred_free(&cred);
327
328         exit(ok);
329 }