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