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