xref: /netbsd-src/external/bsd/libfido2/dist/tools/credman.c (revision 82d56013d7b633d116a93943de88e08335357a7c)
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 <stdbool.h>
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[1024];
26 	int r;
27 
28 	if ((metadata = fido_credman_metadata_new()) == NULL)
29 		errx(1, "fido_credman_metadata_new");
30 
31 	read_pin(path, pin, sizeof(pin));
32 	r = fido_credman_get_dev_metadata(dev, metadata, pin);
33 	explicit_bzero(pin, sizeof(pin));
34 
35 	if (r != FIDO_OK)
36 		errx(1, "fido_credman_get_dev_metadata: %s", fido_strerr(r));
37 
38 	printf("existing rk(s): %u\n",
39 	    (unsigned)fido_credman_rk_existing(metadata));
40 	printf("remaining rk(s): %u\n",
41 	    (unsigned)fido_credman_rk_remaining(metadata));
42 
43 	fido_credman_metadata_free(&metadata);
44 	fido_dev_close(dev);
45 	fido_dev_free(&dev);
46 
47 	exit(0);
48 }
49 
50 static void
51 print_rp(fido_credman_rp_t *rp, size_t idx)
52 {
53 	char *rp_id_hash = NULL;
54 
55 	if (base64_encode(fido_credman_rp_id_hash_ptr(rp, idx),
56 	    fido_credman_rp_id_hash_len(rp, idx), &rp_id_hash) < 0)
57 		errx(1, "output error");
58 
59 	printf("%02u: %s %s\n", (unsigned)idx, rp_id_hash,
60 	    fido_credman_rp_id(rp, idx));
61 
62 	free(rp_id_hash);
63 	rp_id_hash = NULL;
64 }
65 
66 int
67 credman_list_rp(char *path)
68 {
69 	fido_dev_t *dev = NULL;
70 	fido_credman_rp_t *rp = NULL;
71 	char pin[1024];
72 	int r;
73 
74 	if (path == NULL)
75 		usage();
76 	if ((rp = fido_credman_rp_new()) == NULL)
77 		errx(1, "fido_credman_rp_new");
78 
79 	dev = open_dev(path);
80 	read_pin(path, pin, sizeof(pin));
81 	r = fido_credman_get_dev_rp(dev, rp, pin);
82 	explicit_bzero(pin, sizeof(pin));
83 
84 	if (r != FIDO_OK)
85 		errx(1, "fido_credman_get_dev_rp: %s", fido_strerr(r));
86 
87 	for (size_t i = 0; i < fido_credman_rp_count(rp); i++)
88 		print_rp(rp, i);
89 
90 	fido_credman_rp_free(&rp);
91 	fido_dev_close(dev);
92 	fido_dev_free(&dev);
93 
94 	exit(0);
95 }
96 
97 static void
98 print_rk(const fido_credman_rk_t *rk, size_t idx)
99 {
100 	const fido_cred_t *cred;
101 	char *id = NULL;
102 	char *user_id = NULL;
103 	const char *type;
104 	const char *prot;
105 
106 	if ((cred = fido_credman_rk(rk, idx)) == NULL)
107 		errx(1, "fido_credman_rk");
108 	if (base64_encode(fido_cred_id_ptr(cred), fido_cred_id_len(cred),
109 	    &id) < 0 || base64_encode(fido_cred_user_id_ptr(cred),
110 	    fido_cred_user_id_len(cred), &user_id) < 0)
111 		errx(1, "output error");
112 
113 	type = cose_string(fido_cred_type(cred));
114 	prot = prot_string(fido_cred_prot(cred));
115 
116 	printf("%02u: %s %s %s %s %s\n", (unsigned)idx, id,
117 	    fido_cred_display_name(cred), user_id, type, prot);
118 
119 	free(user_id);
120 	free(id);
121 	user_id = NULL;
122 	id = NULL;
123 }
124 
125 int
126 credman_list_rk(char *path, const char *rp_id)
127 {
128 	fido_dev_t *dev = NULL;
129 	fido_credman_rk_t *rk = NULL;
130 	char pin[1024];
131 	int r;
132 
133 	if (path == NULL)
134 		usage();
135 	if ((rk = fido_credman_rk_new()) == NULL)
136 		errx(1, "fido_credman_rk_new");
137 
138 	dev = open_dev(path);
139 	read_pin(path, pin, sizeof(pin));
140 	r = fido_credman_get_dev_rk(dev, rp_id, rk, pin);
141 	explicit_bzero(pin, sizeof(pin));
142 
143 	if (r != FIDO_OK)
144 		errx(1, "fido_credman_get_dev_rk: %s", fido_strerr(r));
145 	for (size_t i = 0; i < fido_credman_rk_count(rk); i++)
146 		print_rk(rk, i);
147 
148 	fido_credman_rk_free(&rk);
149 	fido_dev_close(dev);
150 	fido_dev_free(&dev);
151 
152 	exit(0);
153 }
154 
155 int
156 credman_print_rk(fido_dev_t *dev, const char *path, char *rp_id, char *cred_id)
157 {
158 	const fido_cred_t *cred = NULL;
159 	fido_credman_rk_t *rk = NULL;
160 	char pin[1024];
161 	void *cred_id_ptr = NULL;
162 	size_t cred_id_len = 0;
163 	int r;
164 
165 	if ((rk = fido_credman_rk_new()) == NULL)
166 		errx(1, "fido_credman_rk_new");
167 	if (base64_decode(cred_id, &cred_id_ptr, &cred_id_len) < 0)
168 		errx(1, "base64_decode");
169 
170 	read_pin(path, pin, sizeof(pin));
171 	r = fido_credman_get_dev_rk(dev, rp_id, rk, pin);
172 	explicit_bzero(pin, sizeof(pin));
173 
174 	if (r != FIDO_OK)
175 		errx(1, "fido_credman_get_dev_rk: %s", fido_strerr(r));
176 
177 	for (size_t i = 0; i < fido_credman_rk_count(rk); i++) {
178 		if ((cred = fido_credman_rk(rk, i)) == NULL ||
179 		    fido_cred_id_ptr(cred) == NULL)
180 			errx(1, "output error");
181 		if (cred_id_len != fido_cred_id_len(cred) ||
182 		    memcmp(cred_id_ptr, fido_cred_id_ptr(cred), cred_id_len))
183 			continue;
184 		print_cred(stdout, fido_cred_type(cred), cred);
185 		goto out;
186 	}
187 
188 	errx(1, "credential not found");
189 
190 out:
191 	free(cred_id_ptr);
192 	cred_id_ptr = NULL;
193 
194 	fido_credman_rk_free(&rk);
195 	fido_dev_close(dev);
196 	fido_dev_free(&dev);
197 
198 	exit(0);
199 }
200 
201 int
202 credman_delete_rk(fido_dev_t *dev, const char *path, char *id)
203 {
204 	char pin[1024];
205 	void *id_ptr = NULL;
206 	size_t id_len = 0;
207 	int r;
208 
209 	if (base64_decode(id, &id_ptr, &id_len) < 0)
210 		errx(1, "base64_decode");
211 
212 	read_pin(path, pin, sizeof(pin));
213 	r = fido_credman_del_dev_rk(dev, id_ptr, id_len, pin);
214 	explicit_bzero(pin, sizeof(pin));
215 
216 	if (r != FIDO_OK)
217 		errx(1, "fido_credman_del_dev_rk: %s", fido_strerr(r));
218 
219 	free(id_ptr);
220 	id_ptr = NULL;
221 
222 	fido_dev_close(dev);
223 	fido_dev_free(&dev);
224 
225 	exit(0);
226 }
227