Skip to content

Commit

Permalink
picopass: Add wiegand parsing plugin (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
bettse committed Apr 26, 2024
1 parent ae4ce84 commit 9cc6fb0
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 1 deletion.
12 changes: 12 additions & 0 deletions application.fam
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ App(
apptype=FlipperAppType.EXTERNAL,
targets=["f7"],
entry_point="picopass_app",
sources=[
"*.c", "!plugin/*.c",
],
requires=[
"storage",
"gui",
Expand All @@ -23,3 +26,12 @@ App(
fap_icon_assets="icons",
fap_file_assets="files",
)

App(
appid="plugin_wiegand",
apptype=FlipperAppType.PLUGIN,
entry_point="plugin_wiegand_ep",
requires=["picopass"],
sources=["plugin/wiegand.c"],
fal_embedded=True,
)
23 changes: 23 additions & 0 deletions picopass.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,27 @@ Picopass* picopass_alloc() {
view_dispatcher_add_view(
picopass->view_dispatcher, PicopassViewLoclass, loclass_get_view(picopass->loclass));

picopass->plugin_manager =
plugin_manager_alloc(PLUGIN_APP_ID, PLUGIN_API_VERSION, firmware_api_interface);

picopass->plugin_wiegand = NULL;
if(plugin_manager_load_all(picopass->plugin_manager, APP_DATA_PATH("plugins")) !=
PluginManagerErrorNone) {
FURI_LOG_E(TAG, "Failed to load all libs");
} else {
uint32_t plugin_count = plugin_manager_get_count(picopass->plugin_manager);
FURI_LOG_I(TAG, "Loaded %lu plugin(s)", plugin_count);

for(uint32_t i = 0; i < plugin_count; i++) {
const PluginWiegand* plugin = plugin_manager_get_ep(picopass->plugin_manager, i);
FURI_LOG_I(TAG, "plugin name: %s", plugin->name);
if(strcmp(plugin->name, "Plugin Wiegand") == 0) {
// Have to cast to drop "const" qualifier
picopass->plugin_wiegand = (PluginWiegand*)plugin;
}
}
}

return picopass;
}

Expand Down Expand Up @@ -158,6 +179,8 @@ void picopass_free(Picopass* picopass) {
furi_record_close(RECORD_NOTIFICATION);
picopass->notifications = NULL;

plugin_manager_free(picopass->plugin_manager);

free(picopass);
}

Expand Down
8 changes: 8 additions & 0 deletions picopass_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
#include "protocol/picopass_poller.h"
#include "protocol/picopass_listener.h"

#include "plugin/interface.h"
#include <flipper_application/flipper_application.h>
#include <flipper_application/plugins/plugin_manager.h>
#include <loader/firmware_api/firmware_api.h>

#define PICOPASS_TEXT_STORE_SIZE 129

#define PICOPASS_ICLASS_ELITE_DICT_FLIPPER_NAME APP_ASSETS_PATH("iclass_elite_dict.txt")
Expand Down Expand Up @@ -107,6 +112,9 @@ struct Picopass {
DictAttack* dict_attack;
Loclass* loclass;

PluginManager* plugin_manager;
PluginWiegand* plugin_wiegand;

PicopassDictAttackContext dict_attack_ctx;
PicopassWriteKeyContext write_key_context;
PicopassLoclassContext loclass_context;
Expand Down
1 change: 1 addition & 0 deletions plugin
Submodule plugin added at 30d5c4
24 changes: 24 additions & 0 deletions scenes/picopass_scene_card_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ enum SubmenuIndex {
SubmenuIndexSave,
SubmenuIndexSaveAsLF,
SubmenuIndexSaveAsSeader,
SubmenuIndexParse,
SubmenuIndexChangeKey,
SubmenuIndexWrite,
SubmenuIndexEmulate,
Expand All @@ -22,6 +23,7 @@ void picopass_scene_card_menu_on_enter(void* context) {
PicopassPacs* pacs = &picopass->dev->dev_data.pacs;
PicopassBlock* card_data = picopass->dev->dev_data.card_data;
PicopassDeviceAuthMethod auth = picopass->dev->dev_data.auth;
PluginWiegand* plugin = picopass->plugin_wiegand;

bool SE = card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].valid &&
0x30 == card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].data[0];
Expand Down Expand Up @@ -59,6 +61,23 @@ void picopass_scene_card_menu_on_enter(void* context) {
SubmenuIndexSaveAsLF,
picopass_scene_card_menu_submenu_callback,
picopass);

if(plugin) {
// Convert from byte array to uint64_t
uint64_t credential = 0;
memcpy(&credential, pacs->credential, sizeof(uint64_t));
credential = __builtin_bswap64(credential);

size_t format_count = plugin->count(pacs->bitLength, credential);
if(format_count > 0) {
submenu_add_item(
submenu,
"Parse",
SubmenuIndexParse,
picopass_scene_card_menu_submenu_callback,
picopass);
}
}
}

if(auth == PicopassDeviceAuthMethodNone || auth == PicopassDeviceAuthMethodKey) {
Expand Down Expand Up @@ -131,6 +150,11 @@ bool picopass_scene_card_menu_on_event(void* context, SceneManagerEvent event) {
picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexChangeKey);
scene_manager_next_scene(picopass->scene_manager, PicopassSceneKeyMenu);
consumed = true;
} else if(event.event == SubmenuIndexParse) {
scene_manager_set_scene_state(
picopass->scene_manager, PicopassSceneCardMenu, SubmenuIndexParse);
scene_manager_next_scene(picopass->scene_manager, PicopassSceneFormats);
consumed = true;
}
} else if(event.type == SceneManagerEventTypeBack) {
consumed = scene_manager_search_and_switch_to_previous_scene(
Expand Down
1 change: 1 addition & 0 deletions scenes/picopass_scene_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ ADD_SCENE(picopass, loclass, Loclass)
ADD_SCENE(picopass, key_input, KeyInput)
ADD_SCENE(picopass, nr_mac_saved, NrMacSaved)
ADD_SCENE(picopass, more_info, MoreInfo)
ADD_SCENE(picopass, formats, Formats)
23 changes: 22 additions & 1 deletion scenes/picopass_scene_device_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ void picopass_scene_device_info_on_enter(void* context) {
// Setup view
PicopassBlock* card_data = picopass->dev->dev_data.card_data;
PicopassPacs* pacs = &picopass->dev->dev_data.pacs;
PluginWiegand* plugin = picopass->plugin_wiegand;
Widget* widget = picopass->widget;

uint8_t csn[PICOPASS_BLOCK_LEN] = {0};
Expand Down Expand Up @@ -77,10 +78,27 @@ void picopass_scene_device_info_on_enter(void* context) {
"Back",
picopass_scene_device_info_widget_callback,
picopass);

if(plugin) {
// Convert from byte array to uint64_t
uint64_t credential = 0;
memcpy(&credential, pacs->credential, sizeof(uint64_t));
credential = __builtin_bswap64(credential);

size_t format_count = plugin->count(pacs->bitLength, credential);
if(format_count > 0) {
widget_add_button_element(
picopass->widget,
GuiButtonTypeCenter,
"Parse",
picopass_scene_device_info_widget_callback,
picopass);
}
}
widget_add_button_element(
picopass->widget,
GuiButtonTypeRight,
"More",
"Raw",
picopass_scene_device_info_widget_callback,
picopass);

Expand All @@ -97,6 +115,9 @@ bool picopass_scene_device_info_on_event(void* context, SceneManagerEvent event)
} else if(event.event == GuiButtonTypeRight) {
scene_manager_next_scene(picopass->scene_manager, PicopassSceneMoreInfo);
consumed = true;
} else if(event.event == GuiButtonTypeCenter) {
scene_manager_next_scene(picopass->scene_manager, PicopassSceneFormats);
consumed = true;
} else if(event.event == PicopassCustomEventViewExit) {
view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewWidget);
consumed = true;
Expand Down
54 changes: 54 additions & 0 deletions scenes/picopass_scene_formats.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "../picopass_i.h"
#include <dolphin/dolphin.h>

void picopass_scene_formats_on_enter(void* context) {
Picopass* picopass = context;
PluginWiegand* plugin = picopass->plugin_wiegand;
PicopassDevice* dev = picopass->dev;
PicopassDeviceData dev_data = dev->dev_data;
PicopassPacs pacs = dev_data.pacs;

FuriString* str = picopass->text_box_store;
furi_string_reset(str);

// Convert from byte array to uint64_t
uint64_t credential = 0;
memcpy(&credential, pacs.credential, sizeof(pacs.credential));
credential = __builtin_bswap64(credential);

if(plugin) {
FuriString* description = furi_string_alloc();
size_t format_count = plugin->count(pacs.bitLength, credential);
for(size_t i = 0; i < format_count; i++) {
plugin->description(pacs.bitLength, credential, i, description);

furi_string_cat_printf(str, "%s\n", furi_string_get_cstr(description));
}
furi_string_free(description);
}

text_box_set_font(picopass->text_box, TextBoxFontHex);
text_box_set_text(picopass->text_box, furi_string_get_cstr(picopass->text_box_store));
view_dispatcher_switch_to_view(picopass->view_dispatcher, PicopassViewTextBox);
}

bool picopass_scene_formats_on_event(void* context, SceneManagerEvent event) {
Picopass* picopass = context;
bool consumed = false;

if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeLeft) {
consumed = scene_manager_previous_scene(picopass->scene_manager);
}
} else if(event.type == SceneManagerEventTypeBack) {
consumed = scene_manager_previous_scene(picopass->scene_manager);
}
return consumed;
}

void picopass_scene_formats_on_exit(void* context) {
Picopass* picopass = context;

// Clear views
text_box_reset(picopass->text_box);
}

0 comments on commit 9cc6fb0

Please sign in to comment.