Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/libfido2/tools/cred_make.c
39507 views
1
/*
2
* Copyright (c) 2018-2023 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 <stdio.h>
10
#include <stdlib.h>
11
#include <string.h>
12
#ifdef HAVE_UNISTD_H
13
#include <unistd.h>
14
#endif
15
16
#include "../openbsd-compat/openbsd-compat.h"
17
#include "extern.h"
18
19
static fido_cred_t *
20
prepare_cred(FILE *in_f, int type, int flags)
21
{
22
fido_cred_t *cred = NULL;
23
struct blob cdh;
24
struct blob uid;
25
char *rpid = NULL;
26
char *uname = NULL;
27
int r;
28
29
memset(&cdh, 0, sizeof(cdh));
30
memset(&uid, 0, sizeof(uid));
31
32
r = base64_read(in_f, &cdh);
33
r |= string_read(in_f, &rpid);
34
r |= string_read(in_f, &uname);
35
r |= base64_read(in_f, &uid);
36
if (r < 0)
37
errx(1, "input error");
38
39
if (flags & FLAG_DEBUG) {
40
fprintf(stderr, "client data%s:\n",
41
flags & FLAG_CD ? "" : " hash");
42
xxd(cdh.ptr, cdh.len);
43
fprintf(stderr, "relying party id: %s\n", rpid);
44
fprintf(stderr, "user name: %s\n", uname);
45
fprintf(stderr, "user id:\n");
46
xxd(uid.ptr, uid.len);
47
}
48
49
if ((cred = fido_cred_new()) == NULL)
50
errx(1, "fido_cred_new");
51
52
53
if (flags & FLAG_CD)
54
r = fido_cred_set_clientdata(cred, cdh.ptr, cdh.len);
55
else
56
r = fido_cred_set_clientdata_hash(cred, cdh.ptr, cdh.len);
57
58
if (r != FIDO_OK || (r = fido_cred_set_type(cred, type)) != FIDO_OK ||
59
(r = fido_cred_set_rp(cred, rpid, NULL)) != FIDO_OK ||
60
(r = fido_cred_set_user(cred, uid.ptr, uid.len, uname, NULL,
61
NULL)) != FIDO_OK)
62
errx(1, "fido_cred_set: %s", fido_strerr(r));
63
64
if (flags & FLAG_RK) {
65
if ((r = fido_cred_set_rk(cred, FIDO_OPT_TRUE)) != FIDO_OK)
66
errx(1, "fido_cred_set_rk: %s", fido_strerr(r));
67
}
68
if (flags & FLAG_UV) {
69
if ((r = fido_cred_set_uv(cred, FIDO_OPT_TRUE)) != FIDO_OK)
70
errx(1, "fido_cred_set_uv: %s", fido_strerr(r));
71
}
72
if (flags & FLAG_HMAC) {
73
if ((r = fido_cred_set_extensions(cred,
74
FIDO_EXT_HMAC_SECRET)) != FIDO_OK)
75
errx(1, "fido_cred_set_extensions: %s", fido_strerr(r));
76
}
77
if (flags & FLAG_LARGEBLOB) {
78
if ((r = fido_cred_set_extensions(cred,
79
FIDO_EXT_LARGEBLOB_KEY)) != FIDO_OK)
80
errx(1, "fido_cred_set_extensions: %s", fido_strerr(r));
81
}
82
83
free(cdh.ptr);
84
free(uid.ptr);
85
free(rpid);
86
free(uname);
87
88
return (cred);
89
}
90
91
static void
92
print_attcred(FILE *out_f, const fido_cred_t *cred)
93
{
94
char *cdh = NULL;
95
char *authdata = NULL;
96
char *id = NULL;
97
char *sig = NULL;
98
char *x5c = NULL;
99
char *key = NULL;
100
int r;
101
102
r = base64_encode(fido_cred_clientdata_hash_ptr(cred),
103
fido_cred_clientdata_hash_len(cred), &cdh);
104
r |= base64_encode(fido_cred_authdata_ptr(cred),
105
fido_cred_authdata_len(cred), &authdata);
106
r |= base64_encode(fido_cred_id_ptr(cred), fido_cred_id_len(cred),
107
&id);
108
r |= base64_encode(fido_cred_sig_ptr(cred), fido_cred_sig_len(cred),
109
&sig);
110
if (fido_cred_x5c_ptr(cred) != NULL)
111
r |= base64_encode(fido_cred_x5c_ptr(cred),
112
fido_cred_x5c_len(cred), &x5c);
113
if (fido_cred_largeblob_key_ptr(cred) != NULL)
114
r |= base64_encode(fido_cred_largeblob_key_ptr(cred),
115
fido_cred_largeblob_key_len(cred), &key);
116
if (r < 0)
117
errx(1, "output error");
118
119
fprintf(out_f, "%s\n", cdh);
120
fprintf(out_f, "%s\n", fido_cred_rp_id(cred));
121
fprintf(out_f, "%s\n", fido_cred_fmt(cred));
122
fprintf(out_f, "%s\n", authdata);
123
fprintf(out_f, "%s\n", id);
124
fprintf(out_f, "%s\n", sig);
125
if (x5c != NULL)
126
fprintf(out_f, "%s\n", x5c);
127
if (key != NULL) {
128
fprintf(out_f, "%s\n", key);
129
explicit_bzero(key, strlen(key));
130
}
131
132
free(cdh);
133
free(authdata);
134
free(id);
135
free(sig);
136
free(x5c);
137
free(key);
138
}
139
140
int
141
cred_make(int argc, char **argv)
142
{
143
fido_dev_t *dev = NULL;
144
fido_cred_t *cred = NULL;
145
char prompt[1024];
146
char pin[128];
147
char *in_path = NULL;
148
char *out_path = NULL;
149
FILE *in_f = NULL;
150
FILE *out_f = NULL;
151
int type = COSE_ES256;
152
int flags = 0;
153
int cred_protect = -1;
154
int ch;
155
int r;
156
157
while ((ch = getopt(argc, argv, "bc:dhi:o:qruvw")) != -1) {
158
switch (ch) {
159
case 'b':
160
flags |= FLAG_LARGEBLOB;
161
break;
162
case 'c':
163
if ((cred_protect = base10(optarg)) < 0)
164
errx(1, "-c: invalid argument '%s'", optarg);
165
break;
166
case 'd':
167
flags |= FLAG_DEBUG;
168
break;
169
case 'h':
170
flags |= FLAG_HMAC;
171
break;
172
case 'i':
173
in_path = optarg;
174
break;
175
case 'o':
176
out_path = optarg;
177
break;
178
case 'q':
179
flags |= FLAG_QUIET;
180
break;
181
case 'r':
182
flags |= FLAG_RK;
183
break;
184
case 'u':
185
flags |= FLAG_U2F;
186
break;
187
case 'v':
188
flags |= FLAG_UV;
189
break;
190
case 'w':
191
flags |= FLAG_CD;
192
break;
193
default:
194
usage();
195
}
196
}
197
198
argc -= optind;
199
argv += optind;
200
201
if (argc < 1 || argc > 2)
202
usage();
203
204
in_f = open_read(in_path);
205
out_f = open_write(out_path);
206
207
if (argc > 1 && cose_type(argv[1], &type) < 0)
208
errx(1, "unknown type %s", argv[1]);
209
210
fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0);
211
212
cred = prepare_cred(in_f, type, flags);
213
214
dev = open_dev(argv[0]);
215
if (flags & FLAG_U2F)
216
fido_dev_force_u2f(dev);
217
218
if (cred_protect > 0) {
219
r = fido_cred_set_prot(cred, cred_protect);
220
if (r != FIDO_OK) {
221
errx(1, "fido_cred_set_prot: %s", fido_strerr(r));
222
}
223
}
224
225
r = fido_dev_make_cred(dev, cred, NULL);
226
if (r == FIDO_ERR_PIN_REQUIRED && !(flags & FLAG_QUIET)) {
227
r = snprintf(prompt, sizeof(prompt), "Enter PIN for %s: ",
228
argv[0]);
229
if (r < 0 || (size_t)r >= sizeof(prompt))
230
errx(1, "snprintf");
231
if (!readpassphrase(prompt, pin, sizeof(pin), RPP_ECHO_OFF))
232
errx(1, "readpassphrase");
233
if (strlen(pin) < 4 || strlen(pin) > 63) {
234
explicit_bzero(pin, sizeof(pin));
235
errx(1, "invalid PIN length");
236
}
237
r = fido_dev_make_cred(dev, cred, pin);
238
}
239
240
explicit_bzero(pin, sizeof(pin));
241
if (r != FIDO_OK)
242
errx(1, "fido_dev_make_cred: %s", fido_strerr(r));
243
print_attcred(out_f, cred);
244
245
fido_dev_close(dev);
246
fido_dev_free(&dev);
247
fido_cred_free(&cred);
248
249
fclose(in_f);
250
fclose(out_f);
251
in_f = NULL;
252
out_f = NULL;
253
254
exit(0);
255
}
256
257