[FL-3701] NFC fixes (#3264)

* nfc app: fix unlock with manual password crash
* nfc app: preserve card detected state
* nfc app: fix mf keys scene switch
* nfc app: fix multiple protocol tag detect notification
* nfc plugin: fix retrun in function body in aime parser
* iso14443-3b poller: rework ATTRIB response check
* nfc app: fix navigation after file load failur
* iso14443-3b poller: fix PVS warning
* mfc listener: add crutch in mfc emulation
This commit is contained in:
gornekich 2023-12-05 17:40:06 +04:00 committed by GitHub
parent c477d1321a
commit 82baf1e923
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 38 additions and 20 deletions

View file

@ -400,15 +400,16 @@ bool nfc_load_from_file_select(NfcApp* instance) {
browser_options.base_path = NFC_APP_FOLDER; browser_options.base_path = NFC_APP_FOLDER;
browser_options.hide_dot_files = true; browser_options.hide_dot_files = true;
// Input events and views are managed by file_browser bool success = false;
bool result = dialog_file_browser_show( do {
instance->dialogs, instance->file_path, instance->file_path, &browser_options); // Input events and views are managed by file_browser
if(!dialog_file_browser_show(
instance->dialogs, instance->file_path, instance->file_path, &browser_options))
break;
success = nfc_load_file(instance, instance->file_path, true);
} while(!success);
if(result) { return success;
result = nfc_load_file(instance, instance->file_path, true);
}
return result;
} }
void nfc_show_loading_popup(void* context, bool show) { void nfc_show_loading_popup(void* context, bool show) {

View file

@ -120,10 +120,15 @@ static bool aime_parse(const NfcDevice* device, FuriString* parsed_data) {
aime_accesscode[9]); aime_accesscode[9]);
// validate decimal hex representation // validate decimal hex representation
bool code_is_hex = true;
for(int i = 0; i < 24; i++) { for(int i = 0; i < 24; i++) {
if(aime_accesscode_str[i] == ' ') continue; if(aime_accesscode_str[i] == ' ') continue;
if(aime_accesscode_str[i] < '0' || aime_accesscode_str[i] > '9') return false; if(aime_accesscode_str[i] < '0' || aime_accesscode_str[i] > '9') {
code_is_hex = false;
break;
}
} }
if(!code_is_hex) break;
// Note: Aime access code has some other self-check algorithms that are not public. // Note: Aime access code has some other self-check algorithms that are not public.
// This parser does not try to verify the number. // This parser does not try to verify the number.

View file

@ -37,6 +37,7 @@ bool nfc_scene_detect_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == NfcCustomEventWorkerExit) { if(event.event == NfcCustomEventWorkerExit) {
if(instance->protocols_detected_num > 1) { if(instance->protocols_detected_num > 1) {
notification_message(instance->notifications, &sequence_single_vibro);
scene_manager_next_scene(instance->scene_manager, NfcSceneSelectProtocol); scene_manager_next_scene(instance->scene_manager, NfcSceneSelectProtocol);
} else { } else {
scene_manager_next_scene(instance->scene_manager, NfcSceneRead); scene_manager_next_scene(instance->scene_manager, NfcSceneRead);

View file

@ -45,11 +45,7 @@ bool nfc_scene_extra_actions_on_event(void* context, SceneManagerEvent event) {
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexMfClassicKeys) { if(event.event == SubmenuIndexMfClassicKeys) {
if(nfc_dict_check_presence(NFC_APP_MF_CLASSIC_DICT_USER_PATH)) { scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicKeys);
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicKeys);
} else {
scene_manager_previous_scene(instance->scene_manager);
}
consumed = true; consumed = true;
} else if(event.event == SubmenuIndexMfUltralightUnlock) { } else if(event.event == SubmenuIndexMfUltralightUnlock) {
mf_ultralight_auth_reset(instance->mf_ul_auth); mf_ultralight_auth_reset(instance->mf_ul_auth);

View file

@ -52,11 +52,12 @@ bool nfc_scene_mf_ultralight_unlock_warn_on_event(void* context, SceneManagerEve
bool consumed = false; bool consumed = false;
nfc->protocols_detected[0] = nfc_device_get_protocol(nfc->nfc_device);
MfUltralightAuthType type = nfc->mf_ul_auth->type; MfUltralightAuthType type = nfc->mf_ul_auth->type;
if((type == MfUltralightAuthTypeReader) || (type == MfUltralightAuthTypeManual)) { if((type == MfUltralightAuthTypeReader) || (type == MfUltralightAuthTypeManual)) {
if(event.type == SceneManagerEventTypeCustom) { if(event.type == SceneManagerEventTypeCustom) {
if(event.event == DialogExResultRight) { if(event.event == DialogExResultRight) {
const NfcProtocol mfu_protocol[] = {NfcProtocolMfUltralight};
nfc_app_set_detected_protocols(nfc, mfu_protocol, COUNT_OF(mfu_protocol));
scene_manager_next_scene(nfc->scene_manager, NfcSceneRead); scene_manager_next_scene(nfc->scene_manager, NfcSceneRead);
dolphin_deed(DolphinDeedNfcRead); dolphin_deed(DolphinDeedNfcRead);
consumed = true; consumed = true;

View file

@ -21,7 +21,6 @@ void nfc_scene_select_protocol_on_enter(void* context) {
} else { } else {
prefix = "Read as"; prefix = "Read as";
submenu_set_header(submenu, "Multi-protocol card"); submenu_set_header(submenu, "Multi-protocol card");
notification_message(instance->notifications, &sequence_single_vibro);
} }
for(uint32_t i = 0; i < instance->protocols_detected_num; i++) { for(uint32_t i = 0; i < instance->protocols_detected_num; i++) {

View file

@ -125,7 +125,6 @@ void dict_attack_reset(DictAttack* instance) {
instance->view, instance->view,
DictAttackViewModel * model, DictAttackViewModel * model,
{ {
model->card_detected = false;
model->sectors_total = 0; model->sectors_total = 0;
model->sectors_read = 0; model->sectors_read = 0;
model->current_sector = 0; model->current_sector = 0;

View file

@ -131,9 +131,18 @@ Iso14443_3bError iso14443_3b_poller_activate(Iso14443_3bPoller* instance, Iso144
break; break;
} }
if(bit_buffer_get_size_bytes(instance->rx_buffer) != 1 || if(bit_buffer_get_size_bytes(instance->rx_buffer) != 1) {
bit_buffer_get_byte(instance->rx_buffer, 0) != 0) { FURI_LOG_W(
FURI_LOG_D(TAG, "Unexpected ATTRIB response"); TAG,
"Unexpected ATTRIB response length: %zu",
bit_buffer_get_size_bytes(instance->rx_buffer));
}
if(bit_buffer_get_byte(instance->rx_buffer, 0) != 0) {
FURI_LOG_D(
TAG,
"Incorrect CID in ATTRIB response: %02X",
bit_buffer_get_byte(instance->rx_buffer, 0));
instance->state = Iso14443_3bPollerStateActivationFailed; instance->state = Iso14443_3bPollerStateActivationFailed;
ret = Iso14443_3bErrorCommunication; ret = Iso14443_3bErrorCommunication;
break; break;

View file

@ -481,6 +481,13 @@ static const MfClassicListenerCmd mf_classic_listener_cmd_handlers[] = {
.command_num = COUNT_OF(mf_classic_listener_halt_handlers), .command_num = COUNT_OF(mf_classic_listener_halt_handlers),
.handler = mf_classic_listener_halt_handlers, .handler = mf_classic_listener_halt_handlers,
}, },
{
// This crutch is necessary since some devices (like Pixel) send 15-bit "HALT" command ...
.cmd_start_byte = MF_CLASSIC_CMD_HALT_MSB,
.cmd_len_bits = 15,
.command_num = COUNT_OF(mf_classic_listener_halt_handlers),
.handler = mf_classic_listener_halt_handlers,
},
{ {
.cmd_start_byte = MF_CLASSIC_CMD_AUTH_KEY_A, .cmd_start_byte = MF_CLASSIC_CMD_AUTH_KEY_A,
.cmd_len_bits = 2 * 8, .cmd_len_bits = 2 * 8,