summaryrefslogtreecommitdiff
path: root/src/pin.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/pin.c')
-rw-r--r--src/pin.c126
1 files changed, 112 insertions, 14 deletions
diff --git a/src/pin.c b/src/pin.c
index 1ed555c..36acbe4 100644
--- a/src/pin.c
+++ b/src/pin.c
@@ -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
28static int
29parse_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
26static int 35static int
27fido_dev_get_pin_token_tx(fido_dev_t *dev, const char *pin, 36fido_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
80static int
81fido_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;
106fail:
107 cbor_vector_free(argv, nitems(argv));
108 free(f.ptr);
109
110 return (r);
111}
112#endif /* FIDO_UVTOKEN */
113
70static int 114static int
71fido_dev_get_pin_token_rx(fido_dev_t *dev, const fido_blob_t *ecdh, 115fido_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
155static int
156fido_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;
189fail:
190 fido_blob_free(&aes_token);
191
192 return (r);
193}
194#endif /* FIDO_UVTOKEN */
195
110static int 196static int
111fido_dev_get_pin_token_wait(fido_dev_t *dev, const char *pin, 197fido_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:
356static int 454static int
357fido_dev_get_retry_count_rx(fido_dev_t *dev, int *retries, int ms) 455fido_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 }