1
mirror of https://github.com/DarkFlippers/unleashed-firmware.git synced 2025-12-12 20:49:49 +04:00

CCID: App changes (#3837)

- Keep ccid_callback and buffer as private to the iso7816_handler
- set usb ccid callback from iso7816_handler (to ensure the right structure is being passed)
- make iso7816 related code independent from furi related code (goal is to make it independently testable)
- rename vars

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
Filipe Paz Rodrigues
2024-09-05 08:04:32 -07:00
committed by GitHub
parent fa2d611652
commit 4a58930247
5 changed files with 64 additions and 37 deletions

View File

@@ -105,7 +105,7 @@ void ccid_test_app_free(CcidTestApp* app) {
furi_record_close(RECORD_GUI); furi_record_close(RECORD_GUI);
app->gui = NULL; app->gui = NULL;
free(app->iso7816_handler); iso7816_handler_free(app->iso7816_handler);
// Free rest // Free rest
free(app); free(app);
@@ -121,8 +121,7 @@ int32_t ccid_test_app(void* p) {
furi_hal_usb_unlock(); furi_hal_usb_unlock();
furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true); furi_check(furi_hal_usb_set_config(&usb_ccid, &app->ccid_cfg) == true);
furi_hal_usb_ccid_set_callbacks( iso7816_handler_set_usb_ccid_callbacks();
(CcidCallbacks*)&app->iso7816_handler->ccid_callbacks, app->iso7816_handler);
furi_hal_usb_ccid_insert_smartcard(); furi_hal_usb_ccid_insert_smartcard();
//handle button events //handle button events
@@ -142,7 +141,7 @@ int32_t ccid_test_app(void* p) {
} }
//tear down USB //tear down USB
furi_hal_usb_ccid_set_callbacks(NULL, NULL); iso7816_handler_reset_usb_ccid_callbacks();
furi_hal_usb_set_config(usb_mode_prev, NULL); furi_hal_usb_set_config(usb_mode_prev, NULL);
//teardown view //teardown view

View File

@@ -6,11 +6,17 @@
#include <furi.h> #include <furi.h>
#include <furi_hal.h> #include <furi_hal.h>
#include "iso7816_handler.h"
#include "iso7816_t0_apdu.h" #include "iso7816_t0_apdu.h"
#include "iso7816_atr.h" #include "iso7816_atr.h"
#include "iso7816_handler.h"
#include "iso7816_response.h" #include "iso7816_response.h"
static Iso7816Handler* iso7816_handler;
static CcidCallbacks* ccid_callbacks;
static uint8_t* command_apdu_buffer;
static uint8_t* response_apdu_buffer;
void iso7816_icc_power_on_callback(uint8_t* atr_data, uint32_t* atr_data_len, void* context) { void iso7816_icc_power_on_callback(uint8_t* atr_data, uint32_t* atr_data_len, void* context) {
furi_check(context); furi_check(context);
@@ -40,12 +46,11 @@ void iso7816_xfr_datablock_callback(
Iso7816Handler* handler = (Iso7816Handler*)context; Iso7816Handler* handler = (Iso7816Handler*)context;
ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)&handler->response_apdu_buffer; ISO7816_Response_APDU* response_apdu = (ISO7816_Response_APDU*)response_apdu_buffer;
ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)command_apdu_buffer;
ISO7816_Command_APDU* command_apdu = (ISO7816_Command_APDU*)&handler->command_apdu_buffer;
uint8_t result = iso7816_read_command_apdu( uint8_t result = iso7816_read_command_apdu(
command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len); command_apdu, pc_to_reader_datablock, pc_to_reader_datablock_len, CCID_SHORT_APDU_SIZE);
if(result == ISO7816_READ_COMMAND_APDU_OK) { if(result == ISO7816_READ_COMMAND_APDU_OK) {
handler->iso7816_process_command(command_apdu, response_apdu); handler->iso7816_process_command(command_apdu, response_apdu);
@@ -61,8 +66,31 @@ void iso7816_xfr_datablock_callback(
} }
Iso7816Handler* iso7816_handler_alloc() { Iso7816Handler* iso7816_handler_alloc() {
Iso7816Handler* handler = malloc(sizeof(Iso7816Handler)); iso7816_handler = malloc(sizeof(Iso7816Handler));
handler->ccid_callbacks.icc_power_on_callback = iso7816_icc_power_on_callback;
handler->ccid_callbacks.xfr_datablock_callback = iso7816_xfr_datablock_callback; command_apdu_buffer = malloc(sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE);
return handler; response_apdu_buffer = malloc(sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE);
ccid_callbacks = malloc(sizeof(CcidCallbacks));
ccid_callbacks->icc_power_on_callback = iso7816_icc_power_on_callback;
ccid_callbacks->xfr_datablock_callback = iso7816_xfr_datablock_callback;
return iso7816_handler;
}
void iso7816_handler_set_usb_ccid_callbacks() {
furi_hal_usb_ccid_set_callbacks(ccid_callbacks, iso7816_handler);
}
void iso7816_handler_reset_usb_ccid_callbacks() {
furi_hal_usb_ccid_set_callbacks(NULL, NULL);
}
void iso7816_handler_free(Iso7816Handler* handler) {
free(ccid_callbacks);
free(command_apdu_buffer);
free(response_apdu_buffer);
free(handler);
} }

View File

@@ -5,14 +5,14 @@
#include "iso7816_t0_apdu.h" #include "iso7816_t0_apdu.h"
typedef struct { typedef struct {
CcidCallbacks ccid_callbacks;
void (*iso7816_answer_to_reset)(Iso7816Atr* atr); void (*iso7816_answer_to_reset)(Iso7816Atr* atr);
void (*iso7816_process_command)( void (*iso7816_process_command)(
const ISO7816_Command_APDU* command, const ISO7816_Command_APDU* command,
ISO7816_Response_APDU* response); ISO7816_Response_APDU* response);
uint8_t command_apdu_buffer[sizeof(ISO7816_Command_APDU) + CCID_SHORT_APDU_SIZE];
uint8_t response_apdu_buffer[sizeof(ISO7816_Response_APDU) + CCID_SHORT_APDU_SIZE];
} Iso7816Handler; } Iso7816Handler;
Iso7816Handler* iso7816_handler_alloc(); Iso7816Handler* iso7816_handler_alloc();
void iso7816_handler_free(Iso7816Handler* handler);
void iso7816_handler_set_usb_ccid_callbacks();
void iso7816_handler_reset_usb_ccid_callbacks();

View File

@@ -1,49 +1,48 @@
/* Implements rudimentary iso7816-3 support for APDU (T=0) */ /* Implements rudimentary iso7816-3 support for APDU (T=0) */
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include <furi.h>
#include <furi_hal.h>
#include "iso7816_t0_apdu.h" #include "iso7816_t0_apdu.h"
//reads dataBuffer with dataLen size, translate it into a ISO7816_Command_APDU type //reads pc_to_reader_datablock_len with pc_to_reader_datablock_len size, translate it into a ISO7816_Command_APDU type
//extra data will be pointed to commandDataBuffer //extra data will be pointed to commandDataBuffer
uint8_t iso7816_read_command_apdu( uint8_t iso7816_read_command_apdu(
ISO7816_Command_APDU* command, ISO7816_Command_APDU* command,
const uint8_t* dataBuffer, const uint8_t* pc_to_reader_datablock,
uint32_t dataLen) { uint32_t pc_to_reader_datablock_len,
command->CLA = dataBuffer[0]; uint32_t max_apdu_size) {
command->INS = dataBuffer[1]; command->CLA = pc_to_reader_datablock[0];
command->P1 = dataBuffer[2]; command->INS = pc_to_reader_datablock[1];
command->P2 = dataBuffer[3]; command->P1 = pc_to_reader_datablock[2];
command->P2 = pc_to_reader_datablock[3];
if(dataLen == 4) { if(pc_to_reader_datablock_len == 4) {
command->Lc = 0; command->Lc = 0;
command->Le = 0; command->Le = 0;
command->LePresent = false; command->LePresent = false;
return ISO7816_READ_COMMAND_APDU_OK; return ISO7816_READ_COMMAND_APDU_OK;
} else if(dataLen == 5) { } else if(pc_to_reader_datablock_len == 5) {
//short le //short le
command->Lc = 0; command->Lc = 0;
command->Le = dataBuffer[4]; command->Le = pc_to_reader_datablock[4];
command->LePresent = true; command->LePresent = true;
return ISO7816_READ_COMMAND_APDU_OK; return ISO7816_READ_COMMAND_APDU_OK;
} else if(dataLen > 5 && dataBuffer[4] != 0x00) { } else if(pc_to_reader_datablock_len > 5 && pc_to_reader_datablock[4] != 0x00) {
//short lc //short lc
command->Lc = dataBuffer[4]; command->Lc = pc_to_reader_datablock[4];
if(command->Lc > 0 && command->Lc < CCID_SHORT_APDU_SIZE) { //-V560 if(command->Lc > 0 && command->Lc < max_apdu_size) { //-V560
memcpy(command->Data, &dataBuffer[5], command->Lc); memcpy(command->Data, &pc_to_reader_datablock[5], command->Lc);
//does it have a short le too? //does it have a short le too?
if(dataLen == (uint32_t)(command->Lc + 5)) { if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 5)) {
command->Le = 0; command->Le = 0;
command->LePresent = false; command->LePresent = false;
return ISO7816_READ_COMMAND_APDU_OK; return ISO7816_READ_COMMAND_APDU_OK;
} else if(dataLen == (uint32_t)(command->Lc + 6)) { } else if(pc_to_reader_datablock_len == (uint32_t)(command->Lc + 6)) {
command->Le = dataBuffer[dataLen - 1]; command->Le = pc_to_reader_datablock[pc_to_reader_datablock_len - 1];
command->LePresent = true; command->LePresent = true;
return ISO7816_READ_COMMAND_APDU_OK; return ISO7816_READ_COMMAND_APDU_OK;

View File

@@ -34,7 +34,8 @@ typedef struct {
uint8_t iso7816_read_command_apdu( uint8_t iso7816_read_command_apdu(
ISO7816_Command_APDU* command, ISO7816_Command_APDU* command,
const uint8_t* pc_to_reader_datablock, const uint8_t* pc_to_reader_datablock,
uint32_t pc_to_reader_datablock_len); uint32_t pc_to_reader_datablock_len,
uint32_t max_apdu_size);
void iso7816_write_response_apdu( void iso7816_write_response_apdu(
const ISO7816_Response_APDU* response, const ISO7816_Response_APDU* response,
uint8_t* reader_to_pc_datablock, uint8_t* reader_to_pc_datablock,