| Line | Count | Source | 
| 1 |  | /* | 
| 2 |  |  * Copyright (c) 2018-2022 Yubico AB. All rights reserved. | 
| 3 |  |  * Use of this source code is governed by a BSD-style | 
| 4 |  |  * license that can be found in the LICENSE file. | 
| 5 |  |  * SPDX-License-Identifier: BSD-2-Clause | 
| 6 |  |  */ | 
| 7 |  |  | 
| 8 |  | #include "fido.h" | 
| 9 |  |  | 
| 10 |  | static int | 
| 11 |  | parse_authkey(const cbor_item_t *key, const cbor_item_t *val, void *arg) | 
| 12 | 7.56k | { | 
| 13 | 7.56k |         es256_pk_t *authkey = arg; | 
| 14 |  |  | 
| 15 | 7.56k |         if (cbor_isa_uint(key) == false || | 
| 16 | 7.56k |             cbor_int_get_width(key) != CBOR_INT_8 || | 
| 17 | 7.56k |             cbor_get_uint8(key) != 1) { | 
| 18 | 682 |                 fido_log_debug("%s: cbor type", __func__); | 
| 19 | 682 |                 return (0); /* ignore */ | 
| 20 | 682 |         } | 
| 21 |  |  | 
| 22 | 6.88k |         return (es256_pk_decode(val, authkey)); | 
| 23 | 7.56k | } | 
| 24 |  |  | 
| 25 |  | static int | 
| 26 |  | fido_dev_authkey_tx(fido_dev_t *dev, int *ms) | 
| 27 | 13.7k | { | 
| 28 | 13.7k |         fido_blob_t      f; | 
| 29 | 13.7k |         cbor_item_t     *argv[2]; | 
| 30 | 13.7k |         int              r; | 
| 31 |  |  | 
| 32 | 13.7k |         fido_log_debug("%s: dev=%p", __func__, (void *)dev); | 
| 33 |  |  | 
| 34 | 13.7k |         memset(&f, 0, sizeof(f)); | 
| 35 | 13.7k |         memset(argv, 0, sizeof(argv)); | 
| 36 |  |  | 
| 37 |  |         /* add command parameters */ | 
| 38 | 13.7k |         if ((argv[0] = cbor_encode_pin_opt(dev)) == NULL || | 
| 39 | 13.7k |             (argv[1] = cbor_build_uint8(2)) == NULL) { | 
| 40 | 5.83k |                 fido_log_debug("%s: cbor_build", __func__); | 
| 41 | 5.83k |                 r = FIDO_ERR_INTERNAL; | 
| 42 | 5.83k |                 goto fail; | 
| 43 | 5.83k |         } | 
| 44 |  |  | 
| 45 |  |         /* frame and transmit */ | 
| 46 | 7.89k |         if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), | 
| 47 | 7.89k |             &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len, ms) < 0) { | 
| 48 | 79 |                 fido_log_debug("%s: fido_tx", __func__); | 
| 49 | 79 |                 r = FIDO_ERR_TX; | 
| 50 | 79 |                 goto fail; | 
| 51 | 79 |         } | 
| 52 |  |  | 
| 53 | 7.81k |         r = FIDO_OK; | 
| 54 | 13.7k | fail: | 
| 55 | 13.7k |         cbor_vector_free(argv, nitems(argv)); | 
| 56 | 13.7k |         free(f.ptr); | 
| 57 |  |  | 
| 58 | 13.7k |         return (r); | 
| 59 | 7.81k | } | 
| 60 |  |  | 
| 61 |  | static int | 
| 62 |  | fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int *ms) | 
| 63 | 7.81k | { | 
| 64 | 7.81k |         unsigned char   *msg; | 
| 65 | 7.81k |         int              msglen; | 
| 66 | 7.81k |         int              r; | 
| 67 |  |  | 
| 68 | 7.81k |         fido_log_debug("%s: dev=%p, authkey=%p, ms=%d", __func__, (void *)dev, | 
| 69 | 7.81k |             (void *)authkey, *ms); | 
| 70 |  |  | 
| 71 | 7.81k |         memset(authkey, 0, sizeof(*authkey)); | 
| 72 |  |  | 
| 73 | 7.81k |         if ((msg = malloc(FIDO_MAXMSG)) == NULL) { | 
| 74 | 20 |                 r = FIDO_ERR_INTERNAL; | 
| 75 | 20 |                 goto out; | 
| 76 | 20 |         } | 
| 77 |  |  | 
| 78 | 7.79k |         if ((msglen = fido_rx(dev, CTAP_CMD_CBOR, msg, FIDO_MAXMSG, ms)) < 0) { | 
| 79 | 532 |                 fido_log_debug("%s: fido_rx", __func__); | 
| 80 | 532 |                 r = FIDO_ERR_RX; | 
| 81 | 532 |                 goto out; | 
| 82 | 532 |         } | 
| 83 |  |  | 
| 84 | 7.26k |         r = cbor_parse_reply(msg, (size_t)msglen, authkey, parse_authkey); | 
| 85 | 7.81k | out: | 
| 86 | 7.81k |         freezero(msg, FIDO_MAXMSG); | 
| 87 |  |  | 
| 88 | 7.81k |         return (r); | 
| 89 | 7.26k | } | 
| 90 |  |  | 
| 91 |  | static int | 
| 92 |  | fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int *ms) | 
| 93 | 13.7k | { | 
| 94 | 13.7k |         int r; | 
| 95 |  |  | 
| 96 | 13.7k |         if ((r = fido_dev_authkey_tx(dev, ms)) != FIDO_OK || | 
| 97 | 13.7k |             (r = fido_dev_authkey_rx(dev, authkey, ms)) != FIDO_OK) | 
| 98 | 6.99k |                 return (r); | 
| 99 |  |  | 
| 100 | 6.74k |         return (FIDO_OK); | 
| 101 | 13.7k | } | 
| 102 |  |  | 
| 103 |  | int | 
| 104 |  | fido_dev_authkey(fido_dev_t *dev, es256_pk_t *authkey, int *ms) | 
| 105 | 13.7k | { | 
| 106 | 13.7k |         return (fido_dev_authkey_wait(dev, authkey, ms)); | 
| 107 | 13.7k | } |