Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2018 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 <openssl/ec.h> |
8 | | #include <openssl/evp.h> |
9 | | #include <openssl/sha.h> |
10 | | #include <openssl/x509.h> |
11 | | |
12 | | #include <string.h> |
13 | | #include "fido.h" |
14 | | #include "fido/es256.h" |
15 | | |
16 | | static int |
17 | | parse_makecred_reply(const cbor_item_t *key, const cbor_item_t *val, void *arg) |
18 | 989 | { |
19 | 989 | fido_cred_t *cred = arg; |
20 | 989 | |
21 | 989 | if (cbor_isa_uint(key) == false || |
22 | 989 | cbor_int_get_width(key) != CBOR_INT_8) { |
23 | 15 | fido_log_debug("%s: cbor type", __func__); |
24 | 15 | return (0); /* ignore */ |
25 | 15 | } |
26 | 974 | |
27 | 974 | switch (cbor_get_uint8(key)) { |
28 | 408 | case 1: /* fmt */ |
29 | 408 | return (cbor_decode_fmt(val, &cred->fmt)); |
30 | 372 | case 2: /* authdata */ |
31 | 372 | if (fido_blob_decode(val, &cred->authdata_raw) < 0) { |
32 | 1 | fido_log_debug("%s: fido_blob_decode", __func__); |
33 | 1 | return (-1); |
34 | 1 | } |
35 | 371 | return (cbor_decode_cred_authdata(val, cred->type, |
36 | 371 | &cred->authdata_cbor, &cred->authdata, &cred->attcred, |
37 | 371 | &cred->authdata_ext)); |
38 | 371 | case 3: /* attestation statement */ |
39 | 183 | return (cbor_decode_attstmt(val, &cred->attstmt)); |
40 | 371 | default: /* ignore */ |
41 | 11 | fido_log_debug("%s: cbor type", __func__); |
42 | 11 | return (0); |
43 | 974 | } |
44 | 974 | } |
45 | | |
46 | | static int |
47 | | fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin) |
48 | 867 | { |
49 | 867 | fido_blob_t f; |
50 | 867 | fido_blob_t *ecdh = NULL; |
51 | 867 | es256_pk_t *pk = NULL; |
52 | 867 | cbor_item_t *argv[9]; |
53 | 867 | int r; |
54 | 867 | |
55 | 867 | memset(&f, 0, sizeof(f)); |
56 | 867 | memset(argv, 0, sizeof(argv)); |
57 | 867 | |
58 | 867 | if (cred->cdh.ptr == NULL || cred->type == 0) { |
59 | 2 | fido_log_debug("%s: cdh=%p, type=%d", __func__, |
60 | 2 | (void *)cred->cdh.ptr, cred->type); |
61 | 2 | r = FIDO_ERR_INVALID_ARGUMENT; |
62 | 2 | goto fail; |
63 | 2 | } |
64 | 865 | |
65 | 865 | if ((argv[0] = fido_blob_encode(&cred->cdh)) == NULL || |
66 | 865 | (argv[1] = cbor_encode_rp_entity(&cred->rp)) == NULL || |
67 | 865 | (argv[2] = cbor_encode_user_entity(&cred->user)) == NULL || |
68 | 865 | (argv[3] = cbor_encode_pubkey_param(cred->type)) == NULL) { |
69 | 40 | fido_log_debug("%s: cbor encode", __func__); |
70 | 40 | r = FIDO_ERR_INTERNAL; |
71 | 40 | goto fail; |
72 | 40 | } |
73 | 825 | |
74 | 825 | /* excluded credentials */ |
75 | 825 | if (cred->excl.len) |
76 | 564 | if ((argv[4] = cbor_encode_pubkey_list(&cred->excl)) == NULL) { |
77 | 41 | fido_log_debug("%s: cbor_encode_pubkey_list", __func__); |
78 | 41 | r = FIDO_ERR_INTERNAL; |
79 | 41 | goto fail; |
80 | 41 | } |
81 | 784 | |
82 | 784 | /* extensions */ |
83 | 784 | if (cred->ext.mask) |
84 | 440 | if ((argv[5] = cbor_encode_extensions(&cred->ext)) == NULL) { |
85 | 5 | fido_log_debug("%s: cbor_encode_extensions", __func__); |
86 | 5 | r = FIDO_ERR_INTERNAL; |
87 | 5 | goto fail; |
88 | 5 | } |
89 | 779 | |
90 | 779 | /* options */ |
91 | 779 | if (cred->rk != FIDO_OPT_OMIT || cred->uv != FIDO_OPT_OMIT) |
92 | 436 | if ((argv[6] = cbor_encode_options(cred->rk, |
93 | 436 | cred->uv)) == NULL) { |
94 | 4 | fido_log_debug("%s: cbor_encode_options", __func__); |
95 | 4 | r = FIDO_ERR_INTERNAL; |
96 | 4 | goto fail; |
97 | 4 | } |
98 | 775 | |
99 | 775 | /* pin authentication */ |
100 | 775 | if (pin) { |
101 | 639 | if ((r = fido_do_ecdh(dev, &pk, &ecdh)) != FIDO_OK) { |
102 | 172 | fido_log_debug("%s: fido_do_ecdh", __func__); |
103 | 172 | goto fail; |
104 | 172 | } |
105 | 467 | if ((r = cbor_add_pin_params(dev, &cred->cdh, pk, ecdh, pin, |
106 | 467 | &argv[7], &argv[8])) != FIDO_OK) { |
107 | 82 | fido_log_debug("%s: cbor_add_pin_params", __func__); |
108 | 82 | goto fail; |
109 | 82 | } |
110 | 521 | } |
111 | 521 | |
112 | 521 | /* framing and transmission */ |
113 | 521 | if (cbor_build_frame(CTAP_CBOR_MAKECRED, argv, nitems(argv), &f) < 0 || |
114 | 521 | fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { |
115 | 61 | fido_log_debug("%s: fido_tx", __func__); |
116 | 61 | r = FIDO_ERR_TX; |
117 | 61 | goto fail; |
118 | 61 | } |
119 | 460 | |
120 | 460 | r = FIDO_OK; |
121 | 867 | fail: |
122 | 867 | es256_pk_free(&pk); |
123 | 867 | fido_blob_free(&ecdh); |
124 | 867 | cbor_vector_free(argv, nitems(argv)); |
125 | 867 | free(f.ptr); |
126 | 867 | |
127 | 867 | return (r); |
128 | 460 | } |
129 | | |
130 | | static int |
131 | | fido_dev_make_cred_rx(fido_dev_t *dev, fido_cred_t *cred, int ms) |
132 | 460 | { |
133 | 460 | unsigned char reply[FIDO_MAXMSG]; |
134 | 460 | int reply_len; |
135 | 460 | int r; |
136 | 460 | |
137 | 460 | fido_cred_reset_rx(cred); |
138 | 460 | |
139 | 460 | if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), |
140 | 460 | ms)) < 0) { |
141 | 32 | fido_log_debug("%s: fido_rx", __func__); |
142 | 32 | return (FIDO_ERR_RX); |
143 | 32 | } |
144 | 428 | |
145 | 428 | if ((r = cbor_parse_reply(reply, (size_t)reply_len, cred, |
146 | 428 | parse_makecred_reply)) != FIDO_OK) { |
147 | 288 | fido_log_debug("%s: parse_makecred_reply", __func__); |
148 | 288 | return (r); |
149 | 288 | } |
150 | 140 | |
151 | 140 | if (cred->fmt == NULL || fido_blob_is_empty(&cred->authdata_cbor) || |
152 | 140 | fido_blob_is_empty(&cred->attcred.id) || |
153 | 140 | fido_blob_is_empty(&cred->attstmt.sig)) { |
154 | 30 | fido_cred_reset_rx(cred); |
155 | 30 | return (FIDO_ERR_INVALID_CBOR); |
156 | 30 | } |
157 | 110 | |
158 | 110 | return (FIDO_OK); |
159 | 110 | } |
160 | | |
161 | | static int |
162 | | fido_dev_make_cred_wait(fido_dev_t *dev, fido_cred_t *cred, const char *pin, int ms) |
163 | 867 | { |
164 | 867 | int r; |
165 | 867 | |
166 | 867 | if ((r = fido_dev_make_cred_tx(dev, cred, pin)) != FIDO_OK || |
167 | 867 | (r = fido_dev_make_cred_rx(dev, cred, ms)) != FIDO_OK) |
168 | 867 | return (r); |
169 | 110 | |
170 | 110 | return (FIDO_OK); |
171 | 110 | } |
172 | | |
173 | | int |
174 | | fido_dev_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin) |
175 | 1.57k | { |
176 | 1.57k | if (fido_dev_is_fido2(dev) == false) { |
177 | 709 | if (pin != NULL || cred->rk == FIDO_OPT_TRUE || |
178 | 709 | cred->ext.mask != 0) |
179 | 410 | return (FIDO_ERR_UNSUPPORTED_OPTION); |
180 | 299 | return (u2f_register(dev, cred, -1)); |
181 | 299 | } |
182 | 867 | |
183 | 867 | return (fido_dev_make_cred_wait(dev, cred, pin, -1)); |
184 | 867 | } |
185 | | |
186 | | static int |
187 | | check_extensions(const fido_cred_ext_t *authdata_ext, const fido_cred_ext_t *ext) |
188 | 91 | { |
189 | 91 | return (timingsafe_bcmp(authdata_ext, ext, sizeof(*authdata_ext))); |
190 | 91 | } |
191 | | |
192 | | int |
193 | | fido_check_rp_id(const char *id, const unsigned char *obtained_hash) |
194 | 500 | { |
195 | 500 | unsigned char expected_hash[SHA256_DIGEST_LENGTH]; |
196 | 500 | |
197 | 500 | explicit_bzero(expected_hash, sizeof(expected_hash)); |
198 | 500 | |
199 | 500 | if (SHA256((const unsigned char *)id, strlen(id), |
200 | 500 | expected_hash) != expected_hash) { |
201 | 14 | fido_log_debug("%s: sha256", __func__); |
202 | 14 | return (-1); |
203 | 14 | } |
204 | 486 | |
205 | 486 | return (timingsafe_bcmp(expected_hash, obtained_hash, |
206 | 486 | SHA256_DIGEST_LENGTH)); |
207 | 486 | } |
208 | | |
209 | | static int |
210 | | get_signed_hash_u2f(fido_blob_t *dgst, const unsigned char *rp_id, |
211 | | size_t rp_id_len, const fido_blob_t *clientdata, const fido_blob_t *id, |
212 | | const es256_pk_t *pk) |
213 | 24 | { |
214 | 24 | const uint8_t zero = 0; |
215 | 24 | const uint8_t four = 4; /* uncompressed point */ |
216 | 24 | SHA256_CTX ctx; |
217 | 24 | |
218 | 24 | if (dgst->len != SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 || |
219 | 24 | SHA256_Update(&ctx, &zero, sizeof(zero)) == 0 || |
220 | 24 | SHA256_Update(&ctx, rp_id, rp_id_len) == 0 || |
221 | 24 | SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 || |
222 | 24 | SHA256_Update(&ctx, id->ptr, id->len) == 0 || |
223 | 24 | SHA256_Update(&ctx, &four, sizeof(four)) == 0 || |
224 | 24 | SHA256_Update(&ctx, pk->x, sizeof(pk->x)) == 0 || |
225 | 24 | SHA256_Update(&ctx, pk->y, sizeof(pk->y)) == 0 || |
226 | 24 | SHA256_Final(dgst->ptr, &ctx) == 0) { |
227 | 10 | fido_log_debug("%s: sha256", __func__); |
228 | 10 | return (-1); |
229 | 10 | } |
230 | 14 | |
231 | 14 | return (0); |
232 | 14 | } |
233 | | |
234 | | static int |
235 | | verify_sig(const fido_blob_t *dgst, const fido_blob_t *x5c, |
236 | | const fido_blob_t *sig) |
237 | 22 | { |
238 | 22 | BIO *rawcert = NULL; |
239 | 22 | X509 *cert = NULL; |
240 | 22 | EVP_PKEY *pkey = NULL; |
241 | 22 | EC_KEY *ec; |
242 | 22 | int ok = -1; |
243 | 22 | |
244 | 22 | /* openssl needs ints */ |
245 | 22 | if (dgst->len > INT_MAX || x5c->len > INT_MAX || sig->len > INT_MAX) { |
246 | 0 | fido_log_debug("%s: dgst->len=%zu, x5c->len=%zu, sig->len=%zu", |
247 | 0 | __func__, dgst->len, x5c->len, sig->len); |
248 | 0 | return (-1); |
249 | 0 | } |
250 | 22 | |
251 | 22 | /* fetch key from x509 */ |
252 | 22 | if ((rawcert = BIO_new_mem_buf(x5c->ptr, (int)x5c->len)) == NULL || |
253 | 22 | (cert = d2i_X509_bio(rawcert, NULL)) == NULL || |
254 | 22 | (pkey = X509_get_pubkey(cert)) == NULL || |
255 | 22 | (ec = EVP_PKEY_get0_EC_KEY(pkey)) == NULL) { |
256 | 10 | fido_log_debug("%s: x509 key", __func__); |
257 | 10 | goto fail; |
258 | 10 | } |
259 | 12 | |
260 | 12 | if (ECDSA_verify(0, dgst->ptr, (int)dgst->len, sig->ptr, |
261 | 12 | (int)sig->len, ec) != 1) { |
262 | 12 | fido_log_debug("%s: ECDSA_verify", __func__); |
263 | 12 | goto fail; |
264 | 12 | } |
265 | 0 | |
266 | 0 | ok = 0; |
267 | 22 | fail: |
268 | 22 | if (rawcert != NULL) |
269 | 22 | BIO_free(rawcert); |
270 | 22 | if (cert != NULL) |
271 | 22 | X509_free(cert); |
272 | 22 | if (pkey != NULL) |
273 | 22 | EVP_PKEY_free(pkey); |
274 | 22 | |
275 | 22 | return (ok); |
276 | 0 | } |
277 | | |
278 | | int |
279 | | fido_cred_verify(const fido_cred_t *cred) |
280 | 1.68k | { |
281 | 1.68k | unsigned char buf[SHA256_DIGEST_LENGTH]; |
282 | 1.68k | fido_blob_t dgst; |
283 | 1.68k | int r; |
284 | 1.68k | |
285 | 1.68k | dgst.ptr = buf; |
286 | 1.68k | dgst.len = sizeof(buf); |
287 | 1.68k | |
288 | 1.68k | /* do we have everything we need? */ |
289 | 1.68k | if (cred->cdh.ptr == NULL || cred->authdata_cbor.ptr == NULL || |
290 | 1.68k | cred->attstmt.x5c.ptr == NULL || cred->attstmt.sig.ptr == NULL || |
291 | 1.68k | cred->fmt == NULL || cred->attcred.id.ptr == NULL || |
292 | 1.68k | cred->rp.id == NULL) { |
293 | 1.61k | fido_log_debug("%s: cdh=%p, authdata=%p, x5c=%p, sig=%p, " |
294 | 1.61k | "fmt=%p id=%p, rp.id=%s", __func__, (void *)cred->cdh.ptr, |
295 | 1.61k | (void *)cred->authdata_cbor.ptr, |
296 | 1.61k | (void *)cred->attstmt.x5c.ptr, |
297 | 1.61k | (void *)cred->attstmt.sig.ptr, (void *)cred->fmt, |
298 | 1.61k | (void *)cred->attcred.id.ptr, cred->rp.id); |
299 | 1.61k | r = FIDO_ERR_INVALID_ARGUMENT; |
300 | 1.61k | goto out; |
301 | 1.61k | } |
302 | 70 | |
303 | 70 | if (fido_check_rp_id(cred->rp.id, cred->authdata.rp_id_hash) != 0) { |
304 | 35 | fido_log_debug("%s: fido_check_rp_id", __func__); |
305 | 35 | r = FIDO_ERR_INVALID_PARAM; |
306 | 35 | goto out; |
307 | 35 | } |
308 | 35 | |
309 | 35 | if (fido_check_flags(cred->authdata.flags, FIDO_OPT_TRUE, |
310 | 35 | cred->uv) < 0) { |
311 | 2 | fido_log_debug("%s: fido_check_flags", __func__); |
312 | 2 | r = FIDO_ERR_INVALID_PARAM; |
313 | 2 | goto out; |
314 | 2 | } |
315 | 33 | |
316 | 33 | if (check_extensions(&cred->authdata_ext, &cred->ext) != 0) { |
317 | 1 | fido_log_debug("%s: check_extensions", __func__); |
318 | 1 | r = FIDO_ERR_INVALID_PARAM; |
319 | 1 | goto out; |
320 | 1 | } |
321 | 32 | |
322 | 32 | if (!strcmp(cred->fmt, "packed")) { |
323 | 9 | if (fido_get_signed_hash(COSE_ES256, &dgst, &cred->cdh, |
324 | 9 | &cred->authdata_cbor) < 0) { |
325 | 1 | fido_log_debug("%s: fido_get_signed_hash", __func__); |
326 | 1 | r = FIDO_ERR_INTERNAL; |
327 | 1 | goto out; |
328 | 1 | } |
329 | 23 | } else { |
330 | 23 | if (get_signed_hash_u2f(&dgst, cred->authdata.rp_id_hash, |
331 | 23 | sizeof(cred->authdata.rp_id_hash), &cred->cdh, |
332 | 23 | &cred->attcred.id, &cred->attcred.pubkey.es256) < 0) { |
333 | 9 | fido_log_debug("%s: get_signed_hash_u2f", __func__); |
334 | 9 | r = FIDO_ERR_INTERNAL; |
335 | 9 | goto out; |
336 | 9 | } |
337 | 22 | } |
338 | 22 | |
339 | 22 | if (verify_sig(&dgst, &cred->attstmt.x5c, &cred->attstmt.sig) < 0) { |
340 | 22 | fido_log_debug("%s: verify_sig", __func__); |
341 | 22 | r = FIDO_ERR_INVALID_SIG; |
342 | 22 | goto out; |
343 | 22 | } |
344 | 0 | |
345 | 0 | r = FIDO_OK; |
346 | 1.68k | out: |
347 | 1.68k | explicit_bzero(buf, sizeof(buf)); |
348 | 1.68k | |
349 | 1.68k | return (r); |
350 | 0 | } |
351 | | |
352 | | int |
353 | | fido_cred_verify_self(const fido_cred_t *cred) |
354 | 1.68k | { |
355 | 1.68k | unsigned char buf[1024]; /* XXX */ |
356 | 1.68k | fido_blob_t dgst; |
357 | 1.68k | int ok = -1; |
358 | 1.68k | int r; |
359 | 1.68k | |
360 | 1.68k | dgst.ptr = buf; |
361 | 1.68k | dgst.len = sizeof(buf); |
362 | 1.68k | |
363 | 1.68k | /* do we have everything we need? */ |
364 | 1.68k | if (cred->cdh.ptr == NULL || cred->authdata_cbor.ptr == NULL || |
365 | 1.68k | cred->attstmt.x5c.ptr != NULL || cred->attstmt.sig.ptr == NULL || |
366 | 1.68k | cred->fmt == NULL || cred->attcred.id.ptr == NULL || |
367 | 1.68k | cred->rp.id == NULL) { |
368 | 1.60k | fido_log_debug("%s: cdh=%p, authdata=%p, x5c=%p, sig=%p, " |
369 | 1.60k | "fmt=%p id=%p, rp.id=%s", __func__, (void *)cred->cdh.ptr, |
370 | 1.60k | (void *)cred->authdata_cbor.ptr, |
371 | 1.60k | (void *)cred->attstmt.x5c.ptr, |
372 | 1.60k | (void *)cred->attstmt.sig.ptr, (void *)cred->fmt, |
373 | 1.60k | (void *)cred->attcred.id.ptr, cred->rp.id); |
374 | 1.60k | r = FIDO_ERR_INVALID_ARGUMENT; |
375 | 1.60k | goto out; |
376 | 1.60k | } |
377 | 77 | |
378 | 77 | if (fido_check_rp_id(cred->rp.id, cred->authdata.rp_id_hash) != 0) { |
379 | 18 | fido_log_debug("%s: fido_check_rp_id", __func__); |
380 | 18 | r = FIDO_ERR_INVALID_PARAM; |
381 | 18 | goto out; |
382 | 18 | } |
383 | 59 | |
384 | 59 | if (fido_check_flags(cred->authdata.flags, FIDO_OPT_TRUE, |
385 | 59 | cred->uv) < 0) { |
386 | 1 | fido_log_debug("%s: fido_check_flags", __func__); |
387 | 1 | r = FIDO_ERR_INVALID_PARAM; |
388 | 1 | goto out; |
389 | 1 | } |
390 | 58 | |
391 | 58 | if (check_extensions(&cred->authdata_ext, &cred->ext) != 0) { |
392 | 1 | fido_log_debug("%s: check_extensions", __func__); |
393 | 1 | r = FIDO_ERR_INVALID_PARAM; |
394 | 1 | goto out; |
395 | 1 | } |
396 | 57 | |
397 | 57 | if (!strcmp(cred->fmt, "packed")) { |
398 | 56 | if (fido_get_signed_hash(cred->attcred.type, &dgst, &cred->cdh, |
399 | 56 | &cred->authdata_cbor) < 0) { |
400 | 5 | fido_log_debug("%s: fido_get_signed_hash", __func__); |
401 | 5 | r = FIDO_ERR_INTERNAL; |
402 | 5 | goto out; |
403 | 5 | } |
404 | 1 | } else { |
405 | 1 | if (get_signed_hash_u2f(&dgst, cred->authdata.rp_id_hash, |
406 | 1 | sizeof(cred->authdata.rp_id_hash), &cred->cdh, |
407 | 1 | &cred->attcred.id, &cred->attcred.pubkey.es256) < 0) { |
408 | 1 | fido_log_debug("%s: get_signed_hash_u2f", __func__); |
409 | 1 | r = FIDO_ERR_INTERNAL; |
410 | 1 | goto out; |
411 | 1 | } |
412 | 51 | } |
413 | 51 | |
414 | 51 | switch (cred->attcred.type) { |
415 | 9 | case COSE_ES256: |
416 | 9 | ok = fido_verify_sig_es256(&dgst, &cred->attcred.pubkey.es256, |
417 | 9 | &cred->attstmt.sig); |
418 | 9 | break; |
419 | 17 | case COSE_RS256: |
420 | 17 | ok = fido_verify_sig_rs256(&dgst, &cred->attcred.pubkey.rs256, |
421 | 17 | &cred->attstmt.sig); |
422 | 17 | break; |
423 | 25 | case COSE_EDDSA: |
424 | 25 | ok = fido_verify_sig_eddsa(&dgst, &cred->attcred.pubkey.eddsa, |
425 | 25 | &cred->attstmt.sig); |
426 | 25 | break; |
427 | 0 | default: |
428 | 0 | fido_log_debug("%s: unsupported cose_alg %d", __func__, |
429 | 0 | cred->attcred.type); |
430 | 0 | r = FIDO_ERR_UNSUPPORTED_OPTION; |
431 | 0 | goto out; |
432 | 51 | } |
433 | 51 | |
434 | 51 | if (ok < 0) |
435 | 51 | r = FIDO_ERR_INVALID_SIG; |
436 | 51 | else |
437 | 51 | r = FIDO_OK; |
438 | 51 | |
439 | 1.68k | out: |
440 | 1.68k | explicit_bzero(buf, sizeof(buf)); |
441 | 1.68k | |
442 | 1.68k | return (r); |
443 | 51 | } |
444 | | |
445 | | fido_cred_t * |
446 | | fido_cred_new(void) |
447 | 3.41k | { |
448 | 3.41k | return (calloc(1, sizeof(fido_cred_t))); |
449 | 3.41k | } |
450 | | |
451 | | static void |
452 | | fido_cred_clean_authdata(fido_cred_t *cred) |
453 | 23.9k | { |
454 | 23.9k | free(cred->authdata_cbor.ptr); |
455 | 23.9k | free(cred->authdata_raw.ptr); |
456 | 23.9k | free(cred->attcred.id.ptr); |
457 | 23.9k | |
458 | 23.9k | memset(&cred->authdata_ext, 0, sizeof(cred->authdata_ext)); |
459 | 23.9k | memset(&cred->authdata_cbor, 0, sizeof(cred->authdata_cbor)); |
460 | 23.9k | memset(&cred->authdata_raw, 0, sizeof(cred->authdata_raw)); |
461 | 23.9k | memset(&cred->authdata, 0, sizeof(cred->authdata)); |
462 | 23.9k | memset(&cred->attcred, 0, sizeof(cred->attcred)); |
463 | 23.9k | } |
464 | | |
465 | | void |
466 | | fido_cred_reset_tx(fido_cred_t *cred) |
467 | 11.0k | { |
468 | 11.0k | free(cred->cdh.ptr); |
469 | 11.0k | free(cred->rp.id); |
470 | 11.0k | free(cred->rp.name); |
471 | 11.0k | free(cred->user.id.ptr); |
472 | 11.0k | free(cred->user.icon); |
473 | 11.0k | free(cred->user.name); |
474 | 11.0k | free(cred->user.display_name); |
475 | 11.0k | fido_free_blob_array(&cred->excl); |
476 | 11.0k | |
477 | 11.0k | memset(&cred->cdh, 0, sizeof(cred->cdh)); |
478 | 11.0k | memset(&cred->rp, 0, sizeof(cred->rp)); |
479 | 11.0k | memset(&cred->user, 0, sizeof(cred->user)); |
480 | 11.0k | memset(&cred->excl, 0, sizeof(cred->excl)); |
481 | 11.0k | memset(&cred->ext, 0, sizeof(cred->ext)); |
482 | 11.0k | |
483 | 11.0k | cred->type = 0; |
484 | 11.0k | cred->rk = FIDO_OPT_OMIT; |
485 | 11.0k | cred->uv = FIDO_OPT_OMIT; |
486 | 11.0k | } |
487 | | |
488 | | static void |
489 | | fido_cred_clean_x509(fido_cred_t *cred) |
490 | 14.9k | { |
491 | 14.9k | free(cred->attstmt.x5c.ptr); |
492 | 14.9k | cred->attstmt.x5c.ptr = NULL; |
493 | 14.9k | cred->attstmt.x5c.len = 0; |
494 | 14.9k | } |
495 | | |
496 | | static void |
497 | | fido_cred_clean_sig(fido_cred_t *cred) |
498 | 14.9k | { |
499 | 14.9k | free(cred->attstmt.sig.ptr); |
500 | 14.9k | cred->attstmt.sig.ptr = NULL; |
501 | 14.9k | cred->attstmt.sig.len = 0; |
502 | 14.9k | } |
503 | | |
504 | | void |
505 | | fido_cred_reset_rx(fido_cred_t *cred) |
506 | 11.5k | { |
507 | 11.5k | free(cred->fmt); |
508 | 11.5k | cred->fmt = NULL; |
509 | 11.5k | |
510 | 11.5k | fido_cred_clean_authdata(cred); |
511 | 11.5k | fido_cred_clean_x509(cred); |
512 | 11.5k | fido_cred_clean_sig(cred); |
513 | 11.5k | } |
514 | | |
515 | | void |
516 | | fido_cred_free(fido_cred_t **cred_p) |
517 | 3.38k | { |
518 | 3.38k | fido_cred_t *cred; |
519 | 3.38k | |
520 | 3.38k | if (cred_p == NULL || (cred = *cred_p) == NULL) |
521 | 3.38k | return; |
522 | 3.38k | |
523 | 3.38k | fido_cred_reset_tx(cred); |
524 | 3.38k | fido_cred_reset_rx(cred); |
525 | 3.38k | |
526 | 3.38k | free(cred); |
527 | 3.38k | |
528 | 3.38k | *cred_p = NULL; |
529 | 3.38k | } |
530 | | |
531 | | int |
532 | | fido_cred_set_authdata(fido_cred_t *cred, const unsigned char *ptr, size_t len) |
533 | 3.40k | { |
534 | 3.40k | cbor_item_t *item = NULL; |
535 | 3.40k | struct cbor_load_result cbor; |
536 | 3.40k | int r = FIDO_ERR_INVALID_ARGUMENT; |
537 | 3.40k | |
538 | 3.40k | fido_cred_clean_authdata(cred); |
539 | 3.40k | |
540 | 3.40k | if (ptr == NULL || len == 0) |
541 | 2.65k | goto fail; |
542 | 743 | |
543 | 743 | if ((item = cbor_load(ptr, len, &cbor)) == NULL) { |
544 | 19 | fido_log_debug("%s: cbor_load", __func__); |
545 | 19 | goto fail; |
546 | 19 | } |
547 | 724 | |
548 | 724 | if (fido_blob_decode(item, &cred->authdata_raw) < 0) { |
549 | 15 | fido_log_debug("%s: fido_blob_decode", __func__); |
550 | 15 | goto fail; |
551 | 15 | } |
552 | 709 | |
553 | 709 | if (cbor_decode_cred_authdata(item, cred->type, &cred->authdata_cbor, |
554 | 709 | &cred->authdata, &cred->attcred, &cred->authdata_ext) < 0) { |
555 | 298 | fido_log_debug("%s: cbor_decode_cred_authdata", __func__); |
556 | 298 | goto fail; |
557 | 298 | } |
558 | 411 | |
559 | 411 | r = FIDO_OK; |
560 | 3.40k | fail: |
561 | 3.40k | if (item != NULL) |
562 | 3.40k | cbor_decref(&item); |
563 | 3.40k | |
564 | 3.40k | if (r != FIDO_OK) |
565 | 3.40k | fido_cred_clean_authdata(cred); |
566 | 3.40k | |
567 | 3.40k | return (r); |
568 | 411 | |
569 | 411 | } |
570 | | |
571 | | int |
572 | | fido_cred_set_authdata_raw(fido_cred_t *cred, const unsigned char *ptr, |
573 | | size_t len) |
574 | 2.98k | { |
575 | 2.98k | cbor_item_t *item = NULL; |
576 | 2.98k | int r = FIDO_ERR_INVALID_ARGUMENT; |
577 | 2.98k | |
578 | 2.98k | fido_cred_clean_authdata(cred); |
579 | 2.98k | |
580 | 2.98k | if (ptr == NULL || len == 0) |
581 | 2.64k | goto fail; |
582 | 343 | |
583 | 343 | if (fido_blob_set(&cred->authdata_raw, ptr, len) < 0) { |
584 | 7 | fido_log_debug("%s: fido_blob_set", __func__); |
585 | 7 | r = FIDO_ERR_INTERNAL; |
586 | 7 | goto fail; |
587 | 7 | } |
588 | 336 | |
589 | 336 | if ((item = cbor_build_bytestring(ptr, len)) == NULL) { |
590 | 6 | fido_log_debug("%s: cbor_build_bytestring", __func__); |
591 | 6 | r = FIDO_ERR_INTERNAL; |
592 | 6 | goto fail; |
593 | 6 | } |
594 | 330 | |
595 | 330 | if (cbor_decode_cred_authdata(item, cred->type, &cred->authdata_cbor, |
596 | 330 | &cred->authdata, &cred->attcred, &cred->authdata_ext) < 0) { |
597 | 314 | fido_log_debug("%s: cbor_decode_cred_authdata", __func__); |
598 | 314 | goto fail; |
599 | 314 | } |
600 | 16 | |
601 | 16 | r = FIDO_OK; |
602 | 2.98k | fail: |
603 | 2.98k | if (item != NULL) |
604 | 2.98k | cbor_decref(&item); |
605 | 2.98k | |
606 | 2.98k | if (r != FIDO_OK) |
607 | 2.98k | fido_cred_clean_authdata(cred); |
608 | 2.98k | |
609 | 2.98k | return (r); |
610 | 16 | |
611 | 16 | } |
612 | | |
613 | | int |
614 | | fido_cred_set_x509(fido_cred_t *cred, const unsigned char *ptr, size_t len) |
615 | 3.39k | { |
616 | 3.39k | unsigned char *x509; |
617 | 3.39k | |
618 | 3.39k | fido_cred_clean_x509(cred); |
619 | 3.39k | |
620 | 3.39k | if (ptr == NULL || len == 0) |
621 | 3.18k | return (FIDO_ERR_INVALID_ARGUMENT); |
622 | 211 | if ((x509 = malloc(len)) == NULL) |
623 | 211 | return (FIDO_ERR_INTERNAL); |
624 | 200 | |
625 | 200 | memcpy(x509, ptr, len); |
626 | 200 | cred->attstmt.x5c.ptr = x509; |
627 | 200 | cred->attstmt.x5c.len = len; |
628 | 200 | |
629 | 200 | return (FIDO_OK); |
630 | 200 | } |
631 | | |
632 | | int |
633 | | fido_cred_set_sig(fido_cred_t *cred, const unsigned char *ptr, size_t len) |
634 | 3.39k | { |
635 | 3.39k | unsigned char *sig; |
636 | 3.39k | |
637 | 3.39k | fido_cred_clean_sig(cred); |
638 | 3.39k | |
639 | 3.39k | if (ptr == NULL || len == 0) |
640 | 3.04k | return (FIDO_ERR_INVALID_ARGUMENT); |
641 | 354 | if ((sig = malloc(len)) == NULL) |
642 | 354 | return (FIDO_ERR_INTERNAL); |
643 | 349 | |
644 | 349 | memcpy(sig, ptr, len); |
645 | 349 | cred->attstmt.sig.ptr = sig; |
646 | 349 | cred->attstmt.sig.len = len; |
647 | 349 | |
648 | 349 | return (FIDO_OK); |
649 | 349 | } |
650 | | |
651 | | int |
652 | | fido_cred_exclude(fido_cred_t *cred, const unsigned char *id_ptr, size_t id_len) |
653 | 65.5k | { |
654 | 65.5k | fido_blob_t id_blob; |
655 | 65.5k | fido_blob_t *list_ptr; |
656 | 65.5k | |
657 | 65.5k | memset(&id_blob, 0, sizeof(id_blob)); |
658 | 65.5k | |
659 | 65.5k | if (fido_blob_set(&id_blob, id_ptr, id_len) < 0) |
660 | 211 | return (FIDO_ERR_INVALID_ARGUMENT); |
661 | 65.3k | |
662 | 65.3k | if (cred->excl.len == SIZE_MAX) { |
663 | 0 | free(id_blob.ptr); |
664 | 0 | return (FIDO_ERR_INVALID_ARGUMENT); |
665 | 0 | } |
666 | 65.3k | |
667 | 65.3k | if ((list_ptr = recallocarray(cred->excl.ptr, cred->excl.len, |
668 | 65.3k | cred->excl.len + 1, sizeof(fido_blob_t))) == NULL) { |
669 | 188 | free(id_blob.ptr); |
670 | 188 | return (FIDO_ERR_INTERNAL); |
671 | 188 | } |
672 | 65.1k | |
673 | 65.1k | list_ptr[cred->excl.len++] = id_blob; |
674 | 65.1k | cred->excl.ptr = list_ptr; |
675 | 65.1k | |
676 | 65.1k | return (FIDO_OK); |
677 | 65.1k | } |
678 | | |
679 | | int |
680 | | fido_cred_set_clientdata_hash(fido_cred_t *cred, const unsigned char *hash, |
681 | | size_t hash_len) |
682 | 4.83k | { |
683 | 4.83k | if (fido_blob_set(&cred->cdh, hash, hash_len) < 0) |
684 | 142 | return (FIDO_ERR_INVALID_ARGUMENT); |
685 | 4.69k | |
686 | 4.69k | return (FIDO_OK); |
687 | 4.69k | } |
688 | | |
689 | | int |
690 | | fido_cred_set_rp(fido_cred_t *cred, const char *id, const char *name) |
691 | 4.83k | { |
692 | 4.83k | fido_rp_t *rp = &cred->rp; |
693 | 4.83k | |
694 | 4.83k | if (rp->id != NULL) { |
695 | 1.55k | free(rp->id); |
696 | 1.55k | rp->id = NULL; |
697 | 1.55k | } |
698 | 4.83k | if (rp->name != NULL) { |
699 | 1.55k | free(rp->name); |
700 | 1.55k | rp->name = NULL; |
701 | 1.55k | } |
702 | 4.83k | |
703 | 4.83k | if (id != NULL && (rp->id = strdup(id)) == NULL) |
704 | 4.83k | goto fail; |
705 | 4.81k | if (name != NULL && (rp->name = strdup(name)) == NULL) |
706 | 4.81k | goto fail; |
707 | 4.78k | |
708 | 4.78k | return (FIDO_OK); |
709 | 52 | fail: |
710 | 52 | free(rp->id); |
711 | 52 | free(rp->name); |
712 | 52 | rp->id = NULL; |
713 | 52 | rp->name = NULL; |
714 | 52 | |
715 | 52 | return (FIDO_ERR_INTERNAL); |
716 | 4.78k | } |
717 | | |
718 | | int |
719 | | fido_cred_set_user(fido_cred_t *cred, const unsigned char *user_id, |
720 | | size_t user_id_len, const char *name, const char *display_name, |
721 | | const char *icon) |
722 | 3.15k | { |
723 | 3.15k | fido_user_t *up = &cred->user; |
724 | 3.15k | |
725 | 3.15k | if (up->id.ptr != NULL) { |
726 | 1.53k | free(up->id.ptr); |
727 | 1.53k | up->id.ptr = NULL; |
728 | 1.53k | up->id.len = 0; |
729 | 1.53k | } |
730 | 3.15k | if (up->name != NULL) { |
731 | 1.53k | free(up->name); |
732 | 1.53k | up->name = NULL; |
733 | 1.53k | } |
734 | 3.15k | if (up->display_name != NULL) { |
735 | 1.53k | free(up->display_name); |
736 | 1.53k | up->display_name = NULL; |
737 | 1.53k | } |
738 | 3.15k | if (up->icon != NULL) { |
739 | 1.53k | free(up->icon); |
740 | 1.53k | up->icon = NULL; |
741 | 1.53k | } |
742 | 3.15k | |
743 | 3.15k | if (user_id != NULL) { |
744 | 3.15k | if ((up->id.ptr = malloc(user_id_len)) == NULL) |
745 | 3.15k | goto fail; |
746 | 3.13k | memcpy(up->id.ptr, user_id, user_id_len); |
747 | 3.13k | up->id.len = user_id_len; |
748 | 3.13k | } |
749 | 3.15k | if (name != NULL && (up->name = strdup(name)) == NULL) |
750 | 3.13k | goto fail; |
751 | 3.11k | if (display_name != NULL && |
752 | 3.11k | (up->display_name = strdup(display_name)) == NULL) |
753 | 3.11k | goto fail; |
754 | 3.10k | if (icon != NULL && (up->icon = strdup(icon)) == NULL) |
755 | 3.10k | goto fail; |
756 | 3.08k | |
757 | 3.08k | return (FIDO_OK); |
758 | 64 | fail: |
759 | 64 | free(up->id.ptr); |
760 | 64 | free(up->name); |
761 | 64 | free(up->display_name); |
762 | 64 | free(up->icon); |
763 | 64 | |
764 | 64 | up->id.ptr = NULL; |
765 | 64 | up->id.len = 0; |
766 | 64 | up->name = NULL; |
767 | 64 | up->display_name = NULL; |
768 | 64 | up->icon = NULL; |
769 | 64 | |
770 | 64 | return (FIDO_ERR_INTERNAL); |
771 | 3.08k | } |
772 | | |
773 | | int |
774 | | fido_cred_set_extensions(fido_cred_t *cred, int ext) |
775 | 3.25k | { |
776 | 3.25k | if (ext == 0) |
777 | 184 | cred->ext.mask = 0; |
778 | 3.07k | else { |
779 | 3.07k | if (ext != FIDO_EXT_HMAC_SECRET && |
780 | 3.07k | ext != FIDO_EXT_CRED_PROTECT) |
781 | 3.07k | return (FIDO_ERR_INVALID_ARGUMENT); |
782 | 32 | cred->ext.mask |= ext; |
783 | 32 | } |
784 | 3.25k | |
785 | 3.25k | return (FIDO_OK); |
786 | 3.25k | } |
787 | | |
788 | | int |
789 | | fido_cred_set_options(fido_cred_t *cred, bool rk, bool uv) |
790 | 0 | { |
791 | 0 | cred->rk = rk ? FIDO_OPT_TRUE : FIDO_OPT_FALSE; |
792 | 0 | cred->uv = uv ? FIDO_OPT_TRUE : FIDO_OPT_FALSE; |
793 | 0 |
|
794 | 0 | return (FIDO_OK); |
795 | 0 | } |
796 | | |
797 | | int |
798 | | fido_cred_set_rk(fido_cred_t *cred, fido_opt_t rk) |
799 | 1.08k | { |
800 | 1.08k | cred->rk = rk; |
801 | 1.08k | |
802 | 1.08k | return (FIDO_OK); |
803 | 1.08k | } |
804 | | |
805 | | int |
806 | | fido_cred_set_uv(fido_cred_t *cred, fido_opt_t uv) |
807 | 1.03k | { |
808 | 1.03k | cred->uv = uv; |
809 | 1.03k | |
810 | 1.03k | return (FIDO_OK); |
811 | 1.03k | } |
812 | | |
813 | | int |
814 | | fido_cred_set_prot(fido_cred_t *cred, int prot) |
815 | 3.81k | { |
816 | 3.81k | if (prot == 0) { |
817 | 1.66k | cred->ext.mask &= ~FIDO_EXT_CRED_PROTECT; |
818 | 1.66k | cred->ext.prot = 0; |
819 | 2.14k | } else { |
820 | 2.14k | if (prot != FIDO_CRED_PROT_UV_OPTIONAL && |
821 | 2.14k | prot != FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID && |
822 | 2.14k | prot != FIDO_CRED_PROT_UV_REQUIRED) |
823 | 2.14k | return (FIDO_ERR_INVALID_ARGUMENT); |
824 | 2.08k | |
825 | 2.08k | cred->ext.mask |= FIDO_EXT_CRED_PROTECT; |
826 | 2.08k | cred->ext.prot = prot; |
827 | 2.08k | } |
828 | 3.81k | |
829 | 3.81k | return (FIDO_OK); |
830 | 3.81k | } |
831 | | |
832 | | int |
833 | | fido_cred_set_fmt(fido_cred_t *cred, const char *fmt) |
834 | 407 | { |
835 | 407 | free(cred->fmt); |
836 | 407 | cred->fmt = NULL; |
837 | 407 | |
838 | 407 | if (fmt == NULL) |
839 | 407 | return (FIDO_ERR_INVALID_ARGUMENT); |
840 | 407 | |
841 | 407 | if (strcmp(fmt, "packed") && strcmp(fmt, "fido-u2f")) |
842 | 0 | return (FIDO_ERR_INVALID_ARGUMENT); |
843 | 407 | |
844 | 407 | if ((cred->fmt = strdup(fmt)) == NULL) |
845 | 407 | return (FIDO_ERR_INTERNAL); |
846 | 404 | |
847 | 404 | return (FIDO_OK); |
848 | 404 | } |
849 | | |
850 | | int |
851 | | fido_cred_set_type(fido_cred_t *cred, int cose_alg) |
852 | 4.83k | { |
853 | 4.83k | if ((cose_alg != COSE_ES256 && cose_alg != COSE_RS256 && |
854 | 4.83k | cose_alg != COSE_EDDSA) || cred->type != 0) |
855 | 1.57k | return (FIDO_ERR_INVALID_ARGUMENT); |
856 | 3.25k | |
857 | 3.25k | cred->type = cose_alg; |
858 | 3.25k | |
859 | 3.25k | return (FIDO_OK); |
860 | 3.25k | } |
861 | | |
862 | | int |
863 | | fido_cred_type(const fido_cred_t *cred) |
864 | 2.93k | { |
865 | 2.93k | return (cred->type); |
866 | 2.93k | } |
867 | | |
868 | | uint8_t |
869 | | fido_cred_flags(const fido_cred_t *cred) |
870 | 1.68k | { |
871 | 1.68k | return (cred->authdata.flags); |
872 | 1.68k | } |
873 | | |
874 | | uint32_t |
875 | | fido_cred_sigcount(const fido_cred_t *cred) |
876 | 1.68k | { |
877 | 1.68k | return (cred->authdata.sigcount); |
878 | 1.68k | } |
879 | | |
880 | | const unsigned char * |
881 | | fido_cred_clientdata_hash_ptr(const fido_cred_t *cred) |
882 | 1.70k | { |
883 | 1.70k | return (cred->cdh.ptr); |
884 | 1.70k | } |
885 | | |
886 | | size_t |
887 | | fido_cred_clientdata_hash_len(const fido_cred_t *cred) |
888 | 1.70k | { |
889 | 1.70k | return (cred->cdh.len); |
890 | 1.70k | } |
891 | | |
892 | | const unsigned char * |
893 | | fido_cred_x5c_ptr(const fido_cred_t *cred) |
894 | 1.70k | { |
895 | 1.70k | return (cred->attstmt.x5c.ptr); |
896 | 1.70k | } |
897 | | |
898 | | size_t |
899 | | fido_cred_x5c_len(const fido_cred_t *cred) |
900 | 1.70k | { |
901 | 1.70k | return (cred->attstmt.x5c.len); |
902 | 1.70k | } |
903 | | |
904 | | const unsigned char * |
905 | | fido_cred_sig_ptr(const fido_cred_t *cred) |
906 | 1.70k | { |
907 | 1.70k | return (cred->attstmt.sig.ptr); |
908 | 1.70k | } |
909 | | |
910 | | size_t |
911 | | fido_cred_sig_len(const fido_cred_t *cred) |
912 | 1.70k | { |
913 | 1.70k | return (cred->attstmt.sig.len); |
914 | 1.70k | } |
915 | | |
916 | | const unsigned char * |
917 | | fido_cred_authdata_ptr(const fido_cred_t *cred) |
918 | 1.70k | { |
919 | 1.70k | return (cred->authdata_cbor.ptr); |
920 | 1.70k | } |
921 | | |
922 | | size_t |
923 | | fido_cred_authdata_len(const fido_cred_t *cred) |
924 | 1.70k | { |
925 | 1.70k | return (cred->authdata_cbor.len); |
926 | 1.70k | } |
927 | | |
928 | | const unsigned char * |
929 | | fido_cred_authdata_raw_ptr(const fido_cred_t *cred) |
930 | 1.70k | { |
931 | 1.70k | return (cred->authdata_raw.ptr); |
932 | 1.70k | } |
933 | | |
934 | | size_t |
935 | | fido_cred_authdata_raw_len(const fido_cred_t *cred) |
936 | 1.70k | { |
937 | 1.70k | return (cred->authdata_raw.len); |
938 | 1.70k | } |
939 | | |
940 | | const unsigned char * |
941 | | fido_cred_pubkey_ptr(const fido_cred_t *cred) |
942 | 2.93k | { |
943 | 2.93k | const void *ptr; |
944 | 2.93k | |
945 | 2.93k | switch (cred->attcred.type) { |
946 | 724 | case COSE_ES256: |
947 | 724 | ptr = &cred->attcred.pubkey.es256; |
948 | 724 | break; |
949 | 21 | case COSE_RS256: |
950 | 21 | ptr = &cred->attcred.pubkey.rs256; |
951 | 21 | break; |
952 | 102 | case COSE_EDDSA: |
953 | 102 | ptr = &cred->attcred.pubkey.eddsa; |
954 | 102 | break; |
955 | 2.09k | default: |
956 | 2.09k | ptr = NULL; |
957 | 2.09k | break; |
958 | 2.93k | } |
959 | 2.93k | |
960 | 2.93k | return (ptr); |
961 | 2.93k | } |
962 | | |
963 | | size_t |
964 | | fido_cred_pubkey_len(const fido_cred_t *cred) |
965 | 2.93k | { |
966 | 2.93k | size_t len; |
967 | 2.93k | |
968 | 2.93k | switch (cred->attcred.type) { |
969 | 724 | case COSE_ES256: |
970 | 724 | len = sizeof(cred->attcred.pubkey.es256); |
971 | 724 | break; |
972 | 21 | case COSE_RS256: |
973 | 21 | len = sizeof(cred->attcred.pubkey.rs256); |
974 | 21 | break; |
975 | 102 | case COSE_EDDSA: |
976 | 102 | len = sizeof(cred->attcred.pubkey.eddsa); |
977 | 102 | break; |
978 | 2.09k | default: |
979 | 2.09k | len = 0; |
980 | 2.09k | break; |
981 | 2.93k | } |
982 | 2.93k | |
983 | 2.93k | return (len); |
984 | 2.93k | } |
985 | | |
986 | | const unsigned char * |
987 | | fido_cred_id_ptr(const fido_cred_t *cred) |
988 | 2.93k | { |
989 | 2.93k | return (cred->attcred.id.ptr); |
990 | 2.93k | } |
991 | | |
992 | | size_t |
993 | | fido_cred_id_len(const fido_cred_t *cred) |
994 | 2.93k | { |
995 | 2.93k | return (cred->attcred.id.len); |
996 | 2.93k | } |
997 | | |
998 | | const unsigned char * |
999 | | fido_cred_aaguid_ptr(const fido_cred_t *cred) |
1000 | 1.68k | { |
1001 | 1.68k | return (cred->attcred.aaguid); |
1002 | 1.68k | } |
1003 | | |
1004 | | size_t |
1005 | | fido_cred_aaguid_len(const fido_cred_t *cred) |
1006 | 1.68k | { |
1007 | 1.68k | return (sizeof(cred->attcred.aaguid)); |
1008 | 1.68k | } |
1009 | | |
1010 | | int |
1011 | | fido_cred_prot(const fido_cred_t *cred) |
1012 | 2.95k | { |
1013 | 2.95k | return (cred->ext.prot); |
1014 | 2.95k | } |
1015 | | |
1016 | | const char * |
1017 | | fido_cred_fmt(const fido_cred_t *cred) |
1018 | 1.70k | { |
1019 | 1.70k | return (cred->fmt); |
1020 | 1.70k | } |
1021 | | |
1022 | | const char * |
1023 | | fido_cred_rp_id(const fido_cred_t *cred) |
1024 | 1.70k | { |
1025 | 1.70k | return (cred->rp.id); |
1026 | 1.70k | } |
1027 | | |
1028 | | const char * |
1029 | | fido_cred_rp_name(const fido_cred_t *cred) |
1030 | 1.70k | { |
1031 | 1.70k | return (cred->rp.name); |
1032 | 1.70k | } |
1033 | | |
1034 | | const char * |
1035 | | fido_cred_user_name(const fido_cred_t *cred) |
1036 | 5.87k | { |
1037 | 5.87k | return (cred->user.name); |
1038 | 5.87k | } |
1039 | | |
1040 | | const char * |
1041 | | fido_cred_display_name(const fido_cred_t *cred) |
1042 | 5.87k | { |
1043 | 5.87k | return (cred->user.display_name); |
1044 | 5.87k | } |
1045 | | |
1046 | | const unsigned char * |
1047 | | fido_cred_user_id_ptr(const fido_cred_t *cred) |
1048 | 2.93k | { |
1049 | 2.93k | return (cred->user.id.ptr); |
1050 | 2.93k | } |
1051 | | |
1052 | | size_t |
1053 | | fido_cred_user_id_len(const fido_cred_t *cred) |
1054 | 2.93k | { |
1055 | 2.93k | return (cred->user.id.len); |
1056 | 2.93k | } |