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 | } |