diff options
Diffstat (limited to 'src/pin.c')
-rw-r--r-- | src/pin.c | 126 |
1 files changed, 112 insertions, 14 deletions
@@ -5,6 +5,7 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <string.h> | 7 | #include <string.h> |
8 | |||
8 | #include "fido.h" | 9 | #include "fido.h" |
9 | #include "fido/es256.h" | 10 | #include "fido/es256.h" |
10 | 11 | ||
@@ -23,6 +24,14 @@ parse_pintoken(const cbor_item_t *key, const cbor_item_t *val, void *arg) | |||
23 | return (fido_blob_decode(val, token)); | 24 | return (fido_blob_decode(val, token)); |
24 | } | 25 | } |
25 | 26 | ||
27 | #ifdef FIDO_UVTOKEN | ||
28 | static int | ||
29 | parse_uvtoken(const cbor_item_t *key, const cbor_item_t *val, void *arg) | ||
30 | { | ||
31 | return (parse_pintoken(key, val, arg)); | ||
32 | } | ||
33 | #endif /* FIDO_UVTOKEN */ | ||
34 | |||
26 | static int | 35 | static int |
27 | fido_dev_get_pin_token_tx(fido_dev_t *dev, const char *pin, | 36 | fido_dev_get_pin_token_tx(fido_dev_t *dev, const char *pin, |
28 | const fido_blob_t *ecdh, const es256_pk_t *pk) | 37 | const fido_blob_t *ecdh, const es256_pk_t *pk) |
@@ -51,8 +60,8 @@ fido_dev_get_pin_token_tx(fido_dev_t *dev, const char *pin, | |||
51 | goto fail; | 60 | goto fail; |
52 | } | 61 | } |
53 | 62 | ||
54 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, 6, &f) < 0 || | 63 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), |
55 | fido_tx(dev, CTAP_FRAME_INIT | CTAP_CMD_CBOR, f.ptr, f.len) < 0) { | 64 | &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { |
56 | fido_log_debug("%s: fido_tx", __func__); | 65 | fido_log_debug("%s: fido_tx", __func__); |
57 | r = FIDO_ERR_TX; | 66 | r = FIDO_ERR_TX; |
58 | goto fail; | 67 | goto fail; |
@@ -67,13 +76,47 @@ fail: | |||
67 | return (r); | 76 | return (r); |
68 | } | 77 | } |
69 | 78 | ||
79 | #ifdef FIDO_UVTOKEN | ||
80 | static int | ||
81 | fido_dev_get_uv_token_tx(fido_dev_t *dev, const es256_pk_t *pk) | ||
82 | { | ||
83 | fido_blob_t f; | ||
84 | cbor_item_t *argv[3]; | ||
85 | int r; | ||
86 | |||
87 | memset(&f, 0, sizeof(f)); | ||
88 | memset(argv, 0, sizeof(argv)); | ||
89 | |||
90 | if ((argv[0] = cbor_build_uint8(1)) == NULL || | ||
91 | (argv[1] = cbor_build_uint8(6)) == NULL || | ||
92 | (argv[2] = es256_pk_encode(pk, 0)) == NULL) { | ||
93 | fido_log_debug("%s: cbor encode", __func__); | ||
94 | r = FIDO_ERR_INTERNAL; | ||
95 | goto fail; | ||
96 | } | ||
97 | |||
98 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), | ||
99 | &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { | ||
100 | fido_log_debug("%s: fido_tx", __func__); | ||
101 | r = FIDO_ERR_TX; | ||
102 | goto fail; | ||
103 | } | ||
104 | |||
105 | r = FIDO_OK; | ||
106 | fail: | ||
107 | cbor_vector_free(argv, nitems(argv)); | ||
108 | free(f.ptr); | ||
109 | |||
110 | return (r); | ||
111 | } | ||
112 | #endif /* FIDO_UVTOKEN */ | ||
113 | |||
70 | static int | 114 | static int |
71 | fido_dev_get_pin_token_rx(fido_dev_t *dev, const fido_blob_t *ecdh, | 115 | fido_dev_get_pin_token_rx(fido_dev_t *dev, const fido_blob_t *ecdh, |
72 | fido_blob_t *token, int ms) | 116 | fido_blob_t *token, int ms) |
73 | { | 117 | { |
74 | const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_CBOR; | ||
75 | fido_blob_t *aes_token = NULL; | 118 | fido_blob_t *aes_token = NULL; |
76 | unsigned char reply[2048]; | 119 | unsigned char reply[FIDO_MAXMSG]; |
77 | int reply_len; | 120 | int reply_len; |
78 | int r; | 121 | int r; |
79 | 122 | ||
@@ -82,7 +125,8 @@ fido_dev_get_pin_token_rx(fido_dev_t *dev, const fido_blob_t *ecdh, | |||
82 | goto fail; | 125 | goto fail; |
83 | } | 126 | } |
84 | 127 | ||
85 | if ((reply_len = fido_rx(dev, cmd, &reply, sizeof(reply), ms)) < 0) { | 128 | if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), |
129 | ms)) < 0) { | ||
86 | fido_log_debug("%s: fido_rx", __func__); | 130 | fido_log_debug("%s: fido_rx", __func__); |
87 | r = FIDO_ERR_RX; | 131 | r = FIDO_ERR_RX; |
88 | goto fail; | 132 | goto fail; |
@@ -107,15 +151,69 @@ fail: | |||
107 | return (r); | 151 | return (r); |
108 | } | 152 | } |
109 | 153 | ||
154 | #ifdef FIDO_UVTOKEN | ||
155 | static int | ||
156 | fido_dev_get_uv_token_rx(fido_dev_t *dev, const fido_blob_t *ecdh, | ||
157 | fido_blob_t *token, int ms) | ||
158 | { | ||
159 | fido_blob_t *aes_token = NULL; | ||
160 | unsigned char reply[FIDO_MAXMSG]; | ||
161 | int reply_len; | ||
162 | int r; | ||
163 | |||
164 | if ((aes_token = fido_blob_new()) == NULL) { | ||
165 | r = FIDO_ERR_INTERNAL; | ||
166 | goto fail; | ||
167 | } | ||
168 | |||
169 | if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), | ||
170 | ms)) < 0) { | ||
171 | fido_log_debug("%s: fido_rx", __func__); | ||
172 | r = FIDO_ERR_RX; | ||
173 | goto fail; | ||
174 | } | ||
175 | |||
176 | if ((r = cbor_parse_reply(reply, (size_t)reply_len, aes_token, | ||
177 | parse_uvtoken)) != FIDO_OK) { | ||
178 | fido_log_debug("%s: parse_uvtoken", __func__); | ||
179 | goto fail; | ||
180 | } | ||
181 | |||
182 | if (aes256_cbc_dec(ecdh, aes_token, token) < 0) { | ||
183 | fido_log_debug("%s: aes256_cbc_dec", __func__); | ||
184 | r = FIDO_ERR_RX; | ||
185 | goto fail; | ||
186 | } | ||
187 | |||
188 | r = FIDO_OK; | ||
189 | fail: | ||
190 | fido_blob_free(&aes_token); | ||
191 | |||
192 | return (r); | ||
193 | } | ||
194 | #endif /* FIDO_UVTOKEN */ | ||
195 | |||
110 | static int | 196 | static int |
111 | fido_dev_get_pin_token_wait(fido_dev_t *dev, const char *pin, | 197 | fido_dev_get_pin_token_wait(fido_dev_t *dev, const char *pin, |
112 | const fido_blob_t *ecdh, const es256_pk_t *pk, fido_blob_t *token, int ms) | 198 | const fido_blob_t *ecdh, const es256_pk_t *pk, fido_blob_t *token, int ms) |
113 | { | 199 | { |
114 | int r; | 200 | int r; |
115 | 201 | ||
202 | #ifdef FIDO_UVTOKEN | ||
203 | if (getenv("FIDO_UVTOKEN") != NULL) { | ||
204 | if ((r = fido_dev_get_uv_token_tx(dev, pk)) != FIDO_OK || | ||
205 | (r = fido_dev_get_uv_token_rx(dev, ecdh, token, ms)) != FIDO_OK) | ||
206 | return (r); | ||
207 | } else { | ||
208 | if ((r = fido_dev_get_pin_token_tx(dev, pin, ecdh, pk)) != FIDO_OK || | ||
209 | (r = fido_dev_get_pin_token_rx(dev, ecdh, token, ms)) != FIDO_OK) | ||
210 | return (r); | ||
211 | } | ||
212 | #else | ||
116 | if ((r = fido_dev_get_pin_token_tx(dev, pin, ecdh, pk)) != FIDO_OK || | 213 | if ((r = fido_dev_get_pin_token_tx(dev, pin, ecdh, pk)) != FIDO_OK || |
117 | (r = fido_dev_get_pin_token_rx(dev, ecdh, token, ms)) != FIDO_OK) | 214 | (r = fido_dev_get_pin_token_rx(dev, ecdh, token, ms)) != FIDO_OK) |
118 | return (r); | 215 | return (r); |
216 | #endif | ||
119 | 217 | ||
120 | return (FIDO_OK); | 218 | return (FIDO_OK); |
121 | } | 219 | } |
@@ -196,8 +294,8 @@ fido_dev_change_pin_tx(fido_dev_t *dev, const char *pin, const char *oldpin) | |||
196 | goto fail; | 294 | goto fail; |
197 | } | 295 | } |
198 | 296 | ||
199 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, 6, &f) < 0 || | 297 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), |
200 | fido_tx(dev, CTAP_FRAME_INIT | CTAP_CMD_CBOR, f.ptr, f.len) < 0) { | 298 | &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { |
201 | fido_log_debug("%s: fido_tx", __func__); | 299 | fido_log_debug("%s: fido_tx", __func__); |
202 | r = FIDO_ERR_TX; | 300 | r = FIDO_ERR_TX; |
203 | goto fail; | 301 | goto fail; |
@@ -249,8 +347,8 @@ fido_dev_set_pin_tx(fido_dev_t *dev, const char *pin) | |||
249 | goto fail; | 347 | goto fail; |
250 | } | 348 | } |
251 | 349 | ||
252 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, 5, &f) < 0 || | 350 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), |
253 | fido_tx(dev, CTAP_FRAME_INIT | CTAP_CMD_CBOR, f.ptr, f.len) < 0) { | 351 | &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { |
254 | fido_log_debug("%s: fido_tx", __func__); | 352 | fido_log_debug("%s: fido_tx", __func__); |
255 | r = FIDO_ERR_TX; | 353 | r = FIDO_ERR_TX; |
256 | goto fail; | 354 | goto fail; |
@@ -338,8 +436,8 @@ fido_dev_get_retry_count_tx(fido_dev_t *dev) | |||
338 | goto fail; | 436 | goto fail; |
339 | } | 437 | } |
340 | 438 | ||
341 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, 2, &f) < 0 || | 439 | if (cbor_build_frame(CTAP_CBOR_CLIENT_PIN, argv, nitems(argv), |
342 | fido_tx(dev, CTAP_FRAME_INIT | CTAP_CMD_CBOR, f.ptr, f.len) < 0) { | 440 | &f) < 0 || fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { |
343 | fido_log_debug("%s: fido_tx", __func__); | 441 | fido_log_debug("%s: fido_tx", __func__); |
344 | r = FIDO_ERR_TX; | 442 | r = FIDO_ERR_TX; |
345 | goto fail; | 443 | goto fail; |
@@ -356,14 +454,14 @@ fail: | |||
356 | static int | 454 | static int |
357 | fido_dev_get_retry_count_rx(fido_dev_t *dev, int *retries, int ms) | 455 | fido_dev_get_retry_count_rx(fido_dev_t *dev, int *retries, int ms) |
358 | { | 456 | { |
359 | const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_CBOR; | 457 | unsigned char reply[FIDO_MAXMSG]; |
360 | unsigned char reply[512]; | ||
361 | int reply_len; | 458 | int reply_len; |
362 | int r; | 459 | int r; |
363 | 460 | ||
364 | *retries = 0; | 461 | *retries = 0; |
365 | 462 | ||
366 | if ((reply_len = fido_rx(dev, cmd, &reply, sizeof(reply), ms)) < 0) { | 463 | if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), |
464 | ms)) < 0) { | ||
367 | fido_log_debug("%s: fido_rx", __func__); | 465 | fido_log_debug("%s: fido_rx", __func__); |
368 | return (FIDO_ERR_RX); | 466 | return (FIDO_ERR_RX); |
369 | } | 467 | } |