diff options
Diffstat (limited to 'src/authkey.c')
-rw-r--r-- | src/authkey.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/authkey.c b/src/authkey.c new file mode 100644 index 0000000..9de37f1 --- /dev/null +++ b/src/authkey.c | |||
@@ -0,0 +1,98 @@ | |||
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 <string.h> | ||
8 | #include "fido.h" | ||
9 | |||
10 | static int | ||
11 | parse_authkey(const cbor_item_t *key, const cbor_item_t *val, void *arg) | ||
12 | { | ||
13 | es256_pk_t *authkey = arg; | ||
14 | |||
15 | if (cbor_isa_uint(key) == false || | ||
16 | cbor_int_get_width(key) != CBOR_INT_8 || | ||
17 | cbor_get_uint8(key) != 1) { | ||
18 | fido_log_debug("%s: cbor type", __func__); | ||
19 | return (0); /* ignore */ | ||
20 | } | ||
21 | |||
22 | return (es256_pk_decode(val, authkey)); | ||
23 | } | ||
24 | |||
25 | static int | ||
26 | fido_dev_authkey_tx(fido_dev_t *dev) | ||
27 | { | ||
28 | fido_blob_t f; | ||
29 | cbor_item_t *argv[2]; | ||
30 | int r; | ||
31 | |||
32 | fido_log_debug("%s: dev=%p", __func__, (void *)dev); | ||
33 | |||
34 | memset(&f, 0, sizeof(f)); | ||
35 | memset(argv, 0, sizeof(argv)); | ||
36 | |||
37 | /* add command parameters */ | ||
38 | if ((argv[0] = cbor_build_uint8(1)) == NULL || | ||
39 | (argv[1] = cbor_build_uint8(2)) == NULL) { | ||
40 | fido_log_debug("%s: cbor_build", __func__); | ||
41 | r = FIDO_ERR_INTERNAL; | ||
42 | goto fail; | ||
43 | } | ||
44 | |||
45 | /* frame and transmit */ | ||
46 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, 2, &f) < 0 || | ||
47 | fido_tx(dev, CTAP_FRAME_INIT | CTAP_CMD_CBOR, f.ptr, f.len) < 0) { | ||
48 | fido_log_debug("%s: fido_tx", __func__); | ||
49 | r = FIDO_ERR_TX; | ||
50 | goto fail; | ||
51 | } | ||
52 | |||
53 | r = FIDO_OK; | ||
54 | fail: | ||
55 | cbor_vector_free(argv, nitems(argv)); | ||
56 | free(f.ptr); | ||
57 | |||
58 | return (r); | ||
59 | } | ||
60 | |||
61 | static int | ||
62 | fido_dev_authkey_rx(fido_dev_t *dev, es256_pk_t *authkey, int ms) | ||
63 | { | ||
64 | const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_CBOR; | ||
65 | unsigned char reply[2048]; | ||
66 | int reply_len; | ||
67 | |||
68 | fido_log_debug("%s: dev=%p, authkey=%p, ms=%d", __func__, (void *)dev, | ||
69 | (void *)authkey, ms); | ||
70 | |||
71 | memset(authkey, 0, sizeof(*authkey)); | ||
72 | |||
73 | if ((reply_len = fido_rx(dev, cmd, &reply, sizeof(reply), ms)) < 0) { | ||
74 | fido_log_debug("%s: fido_rx", __func__); | ||
75 | return (FIDO_ERR_RX); | ||
76 | } | ||
77 | |||
78 | return (cbor_parse_reply(reply, (size_t)reply_len, authkey, | ||
79 | parse_authkey)); | ||
80 | } | ||
81 | |||
82 | static int | ||
83 | fido_dev_authkey_wait(fido_dev_t *dev, es256_pk_t *authkey, int ms) | ||
84 | { | ||
85 | int r; | ||
86 | |||
87 | if ((r = fido_dev_authkey_tx(dev)) != FIDO_OK || | ||
88 | (r = fido_dev_authkey_rx(dev, authkey, ms)) != FIDO_OK) | ||
89 | return (r); | ||
90 | |||
91 | return (FIDO_OK); | ||
92 | } | ||
93 | |||
94 | int | ||
95 | fido_dev_authkey(fido_dev_t *dev, es256_pk_t *authkey) | ||
96 | { | ||
97 | return (fido_dev_authkey_wait(dev, authkey, -1)); | ||
98 | } | ||