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