Line | Count | Source |
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 "fido.h" |
8 | | |
9 | | static int |
10 | | parse_authkey(const cbor_item_t *key, const cbor_item_t *val, void *arg) |
11 | 4.10k | { |
12 | 4.10k | es256_pk_t *authkey = arg; |
13 | 4.10k | |
14 | 4.10k | if (cbor_isa_uint(key) == false || |
15 | 4.10k | cbor_int_get_width(key) != CBOR_INT_8 || |
16 | 4.10k | cbor_get_uint8(key) != 1) { |
17 | 294 | fido_log_debug("%s: cbor type", __func__); |
18 | 294 | return (0); /* ignore */ |
19 | 294 | } |
20 | 3.80k | |
21 | 3.80k | return (es256_pk_decode(val, authkey)); |
22 | 3.80k | } |
23 | | |
24 | | static int |
25 | | fido_dev_authkey_tx(fido_dev_t *dev) |
26 | 5.65k | { |
27 | 5.65k | fido_blob_t f; |
28 | 5.65k | cbor_item_t *argv[2]; |
29 | 5.65k | int r; |
30 | 5.65k | |
31 | 5.65k | fido_log_debug("%s: dev=%p", __func__, (void *)dev); |
32 | 5.65k | |
33 | 5.65k | memset(&f, 0, sizeof(f)); |
34 | 5.65k | memset(argv, 0, sizeof(argv)); |
35 | 5.65k | |
36 | 5.65k | /* add command parameters */ |
37 | 5.65k | if ((argv[0] = cbor_encode_pin_opt(dev)) == NULL || |
38 | 5.65k | (argv[1] = cbor_build_uint8(2)) == NULL) { |
39 | 1.26k | fido_log_debug("%s: cbor_build", __func__); |
40 | 1.26k | r = FIDO_ERR_INTERNAL; |
41 | 1.26k | goto fail; |
42 | 1.26k | } |
43 | 4.39k | |
44 | 4.39k | /* frame and transmit */ |
45 | 4.39k | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), |
46 | 4.39k | &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { |
47 | 52 | fido_log_debug("%s: fido_tx", __func__); |
48 | 52 | r = FIDO_ERR_TX; |
49 | 52 | goto fail; |
50 | 52 | } |
51 | 4.34k | |
52 | 4.34k | r = FIDO_OK; |
53 | 5.65k | fail: |
54 | 5.65k | cbor_vector_free(argv, nitems(argv)); |
55 | 5.65k | free(f.ptr); |
56 | 5.65k | |
57 | 5.65k | return (r); |
58 | 4.34k | } |
59 | | |
60 | | static int |
61 | | fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int ms) |
62 | 4.34k | { |
63 | 4.34k | unsigned char reply[FIDO_MAXMSG]; |
64 | 4.34k | int reply_len; |
65 | 4.34k | |
66 | 4.34k | fido_log_debug("%s: dev=%p, authkey=%p, ms=%d", __func__, (void *)dev, |
67 | 4.34k | (void *)authkey, ms); |
68 | 4.34k | |
69 | 4.34k | memset(authkey, 0, sizeof(*authkey)); |
70 | 4.34k | |
71 | 4.34k | if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), |
72 | 4.34k | ms)) < 0) { |
73 | 303 | fido_log_debug("%s: fido_rx", __func__); |
74 | 303 | return (FIDO_ERR_RX); |
75 | 303 | } |
76 | 4.03k | |
77 | 4.03k | return (cbor_parse_reply(reply, (size_t)reply_len, authkey, |
78 | 4.03k | parse_authkey)); |
79 | 4.03k | } |
80 | | |
81 | | static int |
82 | | fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int ms) |
83 | 5.65k | { |
84 | 5.65k | int r; |
85 | 5.65k | |
86 | 5.65k | if ((r = fido_dev_authkey_tx(dev)) != FIDO_OK || |
87 | 5.65k | (r = fido_dev_authkey_rx(dev, authkey, ms)) != FIDO_OK) |
88 | 5.65k | return (r); |
89 | 3.73k | |
90 | 3.73k | return (FIDO_OK); |
91 | 3.73k | } |
92 | | |
93 | | int |
94 | | fido_dev_authkey(fido_dev_t *dev, es256_pk_t *authkey) |
95 | 5.65k | { |
96 | 5.65k | return (fido_dev_authkey_wait(dev, authkey, -1)); |
97 | 5.65k | } |