diff --git a/ctap.c b/ctap.c index 0335f4b..173d3f9 100644 --- a/ctap.c +++ b/ctap.c @@ -18,11 +18,49 @@ static void check_ret(CborError ret) } } +void ctap_get_info(CborEncoder * encoder) +{ + int ret; + CborEncoder array; + CborEncoder map; -void ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) + const int number_of_map_items = 2; + const int number_of_versions = 2; + + ret = cbor_encoder_create_map(encoder, &map, number_of_map_items); + check_ret(ret); + { + + ret = cbor_encode_uint(&map, 0x01); // versions key + check_ret(ret); + { + ret = cbor_encoder_create_array(&map, &array, number_of_versions); + check_ret(ret); + ret = cbor_encode_text_stringz(&array, "1.0"); + check_ret(ret); + ret = cbor_encode_text_stringz(&array, "2.0"); + check_ret(ret); + ret = cbor_encoder_close_container(&map, &array); + check_ret(ret); + } + + ret = cbor_encode_uint(&map, 0x03); // aaguid key + check_ret(ret); + { + ret = cbor_encode_byte_string(&map, CTAP_AAGUID, 16); + check_ret(ret); + } + + } + ret = cbor_encoder_close_container(encoder, &map); + check_ret(ret); + + +} + +uint8_t ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) { uint8_t cmd = *pkt_raw; - int ret; pkt_raw++; @@ -33,7 +71,8 @@ void ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) resp->length = 0; CborEncoder encoder; - CborEncoder array; + cbor_encoder_init(&encoder, buf, sizeof(buf), 0); + switch(cmd) { @@ -48,20 +87,7 @@ void ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) break; case CTAP_GET_INFO: printf("CTAP_GET_INFO\n"); - - cbor_encoder_init(&encoder, buf, sizeof(buf), 0); - - ret = cbor_encoder_create_array(&encoder, &array, 2); - check_ret(ret); - - ret = cbor_encode_text_stringz(&array, "1.0"); - check_ret(ret); - ret = cbor_encode_text_stringz(&array, "2.0"); - check_ret(ret); - - ret = cbor_encoder_close_container(&encoder, &array); - check_ret(ret); - + ctap_get_info(&encoder); dump_hex(buf, cbor_encoder_get_buffer_size(&encoder, buf)); resp->length = cbor_encoder_get_buffer_size(&encoder, buf); @@ -81,4 +107,5 @@ void ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp) } printf("cbor structure: %d bytes\n", length - 1); + return 0; } diff --git a/ctap.h b/ctap.h index 0626233..5c51fe1 100644 --- a/ctap.h +++ b/ctap.h @@ -11,6 +11,8 @@ #define CTAP_VENDOR_FIRST 0x40 #define CTAP_VENDOR_LAST 0xBF +#define CTAP_AAGUID ((uint8_t*)"\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff") + typedef struct { uint8_t * data; @@ -18,7 +20,7 @@ typedef struct } CTAP_RESPONSE; -void ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp); +uint8_t ctap_handle_packet(uint8_t * pkt_raw, int length, CTAP_RESPONSE * resp); // Must be implemented by application // data is HID_MESSAGE_SIZE long in bytes diff --git a/ctaphid.c b/ctaphid.c index f090d5f..a4f8cae 100644 --- a/ctaphid.c +++ b/ctaphid.c @@ -37,14 +37,14 @@ static int ctap_packet_seq; static uint32_t _next_cid = 0; +static void buffer_reset(); + void ctaphid_init() { state = IDLE; active_cid = 0; + buffer_reset(); active_cid_timestamp = millis(); - ctap_buffer_bcnt = 0; - ctap_buffer_offset = 0; - ctap_packet_seq = 0; ctap_write(NULL, -1); } @@ -79,7 +79,7 @@ static int is_init_pkt(CTAPHID_PACKET * pkt) static int is_cont_pkt(CTAPHID_PACKET * pkt) { - return (pkt->pkt.init.cmd == CTAPHID_INIT); + return !(pkt->pkt.init.cmd & CTAPHID_INIT); } static int is_active_cid(CTAPHID_PACKET * pkt) @@ -128,6 +128,13 @@ static int buffer_packet(CTAPHID_PACKET * pkt) return SUCESS; } +static void buffer_reset() +{ + ctap_buffer_bcnt = 0; + ctap_buffer_offset = 0; + ctap_packet_seq = 0; +} + static int buffer_status() { if (ctap_buffer_bcnt == 0) @@ -178,6 +185,8 @@ void ctaphid_handle_packet(uint8_t * pkt_raw) printf(" length: %d\n", ctaphid_packet_len(pkt)); int ret; + uint8_t status; + uint32_t oldcid; static CTAPHID_INIT_RESPONSE init_resp; static CTAPHID_RESPONSE resp; @@ -242,9 +251,10 @@ start_over: } else if (is_timed_out()) { - ctaphid_init(); printf("dropping last channel -- timeout"); - ctaphid_send_error(pkt->cid, ERR_MSG_TIMEOUT); + oldcid = active_cid; + ctaphid_init(); + ctaphid_send_error(active_cid, ERR_MSG_TIMEOUT); goto start_over; } else @@ -350,14 +360,15 @@ start_over: return; } - ctap_handle_packet(ctap_buffer, buffer_len(), &ctap_resp); + status = ctap_handle_packet(ctap_buffer, buffer_len(), &ctap_resp); resp.cid = active_cid; - resp.cmd = CTAPHID_MSG; - resp.bcntl = (ctap_resp.length & 0x00ff) >> 0; - resp.bcnth = (ctap_resp.length & 0xff00) >> 8; + resp.cmd = CTAPHID_CBOR; + resp.bcntl = ((ctap_resp.length+1) & 0x00ff) >> 0; + resp.bcnth = ((ctap_resp.length+1) & 0xff00) >> 8; ctap_write(&resp,sizeof(CTAPHID_RESPONSE)); + ctap_write(&status, 1); ctap_write(ctap_resp.data, ctap_resp.length); ctap_write(NULL, 0); @@ -368,6 +379,8 @@ start_over: printf("error, unimplemented HID cmd: %02x\r\n", buffer_cmd()); break; } + + buffer_reset(); break; default: