diff --git a/src/apdu.c b/src/apdu.c index c53a48f..c38fa0d 100644 --- a/src/apdu.c +++ b/src/apdu.c @@ -53,22 +53,8 @@ int process_apdu() { } } if (INS(apdu) == 0xA4 && P1(apdu) == 0x04 && (P2(apdu) == 0x00 || P2(apdu) == 0x4)) { //select by AID - for (int a = 0; a < num_apps; a++) { - if (!memcmp(apps[a].aid + 1, apdu.data, MIN(apdu.nc, apps[a].aid[0]))) { - if (current_app) { - if (current_app->aid && !memcmp(current_app->aid + 1, apdu.data, apdu.nc)) { - current_app->select_aid(current_app); - return SW_OK(); - } - if (current_app->unload) { - current_app->unload(); - } - } - current_app = &apps[a]; - if (current_app->select_aid(current_app) == CCID_OK) { - return SW_OK(); - } - } + if (select_app(apdu.data, apdu.nc) == CCID_OK) { + return SW_OK(); } return SW_FILE_NOT_FOUND(); } diff --git a/src/apdu.h b/src/apdu.h index e30e12b..ab141a9 100644 --- a/src/apdu.h +++ b/src/apdu.h @@ -34,6 +34,7 @@ typedef struct app { } app_t; extern int register_app(int (*)(app_t *), const uint8_t *); +extern int select_app(const uint8_t *aid, size_t aid_len); typedef struct cmd { uint8_t ins; diff --git a/src/main.c b/src/main.c index ad8866c..8147c92 100644 --- a/src/main.c +++ b/src/main.c @@ -114,6 +114,30 @@ int register_app(int (*select_aid)(app_t *), const uint8_t *aid) { return 0; } +int select_app(const uint8_t *aid, size_t aid_len) { + if (current_app && current_app->aid && (current_app->aid + 1 == aid || !memcmp(current_app->aid + 1, aid, aid_len))) { + return CCID_OK; + } + for (int a = 0; a < num_apps; a++) { + if (!memcmp(apps[a].aid + 1, aid, MIN(aid_len, apps[a].aid[0]))) { + if (current_app) { + if (current_app->aid && !memcmp(current_app->aid + 1, aid, aid_len)) { + current_app->select_aid(current_app); + return CCID_OK; + } + if (current_app->unload) { + current_app->unload(); + } + } + current_app = &apps[a]; + if (current_app->select_aid(current_app) == CCID_OK) { + return CCID_OK; + } + } + } + return CCID_ERR_FILE_NOT_FOUND; +} + int (*button_pressed_cb)(uint8_t) = NULL; static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; diff --git a/src/usb/hid/hid.c b/src/usb/hid/hid.c index 0136ad5..a087092 100644 --- a/src/usb/hid/hid.c +++ b/src/usb/hid/hid.c @@ -306,7 +306,7 @@ int driver_process_usb_nopacket_hid() { return 0; } -const uint8_t *fido_aid = NULL; +extern const uint8_t fido_aid[], u2f_aid[]; int driver_process_usb_packet_hid(uint16_t read) { int apdu_sent = 0; @@ -481,19 +481,10 @@ int driver_process_usb_packet_hid(uint16_t read) { (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { if (last_cmd == CTAPHID_OTP) { is_nitrokey = true; + select_app(fido_aid + 1, fido_aid[0]); } - - else if (current_app == NULL || - current_app->aid != fido_aid) { - if (current_app && current_app->unload) { - current_app->unload(); - } - for (int a = 0; a < num_apps; a++) { - if (!memcmp(apps[a].aid + 1, fido_aid + 1, MIN(fido_aid[0], apps[a].aid[0]))) { - current_app = &apps[a]; - current_app->select_aid(current_app); - } - } + else { + select_app(u2f_aid + 1, u2f_aid[0]); } //if (thread_type != 1) #ifndef ENABLE_EMULATION @@ -515,6 +506,7 @@ int driver_process_usb_packet_hid(uint16_t read) { (msg_packet.len == 0 || (msg_packet.len == msg_packet.current_len && msg_packet.len > 0))) { thread_type = 2; + select_app(fido_aid + 1, fido_aid[0]); if (cbor_process_cb) { if (msg_packet.current_len == msg_packet.len && msg_packet.len > 0) { apdu_sent = cbor_process_cb(last_cmd, msg_packet.data, msg_packet.len);