|
|
@@ -261,13 +261,18 @@ bool picopass_device_save(PicopassDevice* dev, const char* dev_name) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-bool picopass_hex_str_to_uint8(const char* value_str, uint8_t* value) {
|
|
|
+bool picopass_hex_str_to_uint8(const char* value_str, size_t max, uint8_t* value) {
|
|
|
furi_check(value_str);
|
|
|
furi_check(value);
|
|
|
|
|
|
bool parse_success = false;
|
|
|
- while(*value_str && value_str[1]) {
|
|
|
- parse_success = hex_char_to_uint8(*value_str, value_str[1], value++);
|
|
|
+ size_t count = 0;
|
|
|
+ while(value_str[0] && value_str[1]) {
|
|
|
+ if(count++ >= max) {
|
|
|
+ parse_success = true;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ parse_success = hex_char_to_uint8(value_str[0], value_str[1], value++);
|
|
|
if(!parse_success) break;
|
|
|
value_str += 3;
|
|
|
}
|
|
|
@@ -315,7 +320,8 @@ static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, boo
|
|
|
memset(card_data[i].data, 0, PICOPASS_BLOCK_LEN);
|
|
|
} else {
|
|
|
FURI_LOG_D(TAG, "Block %i: %s (hex)", i, furi_string_get_cstr(block_str));
|
|
|
- if(!picopass_hex_str_to_uint8(furi_string_get_cstr(block_str), card_data[i].data)) {
|
|
|
+ if(!picopass_hex_str_to_uint8(
|
|
|
+ furi_string_get_cstr(block_str), PICOPASS_BLOCK_LEN, card_data[i].data)) {
|
|
|
block_read = false;
|
|
|
break;
|
|
|
}
|
|
|
@@ -323,6 +329,23 @@ static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, boo
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // Check if legacy or SE
|
|
|
+ PicopassBlock temp_block = {};
|
|
|
+ memset(temp_block.data, 0xff, PICOPASS_BLOCK_LEN);
|
|
|
+ pacs->legacy =
|
|
|
+ (memcmp(
|
|
|
+ card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data,
|
|
|
+ temp_block.data,
|
|
|
+ PICOPASS_BLOCK_LEN) == 0);
|
|
|
+
|
|
|
+ temp_block.data[3] = 0x00;
|
|
|
+ temp_block.data[4] = 0x06;
|
|
|
+ pacs->se_enabled =
|
|
|
+ (memcmp(
|
|
|
+ card_data[PICOPASS_SECURE_AIA_BLOCK_INDEX].data,
|
|
|
+ temp_block.data,
|
|
|
+ PICOPASS_BLOCK_LEN) == 0);
|
|
|
+
|
|
|
size_t app_limit = card_data[PICOPASS_CONFIG_BLOCK_INDEX].data[0];
|
|
|
// Fix for unpersonalized cards that have app_limit set to 0xFF
|
|
|
if(app_limit > PICOPASS_MAX_APP_LIMIT) app_limit = PICOPASS_MAX_APP_LIMIT;
|
|
|
@@ -338,7 +361,8 @@ static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, boo
|
|
|
memset(card_data[i].data, 0, PICOPASS_BLOCK_LEN);
|
|
|
} else {
|
|
|
FURI_LOG_D(TAG, "Block %i: %s (hex)", i, furi_string_get_cstr(block_str));
|
|
|
- if(!picopass_hex_str_to_uint8(furi_string_get_cstr(block_str), card_data[i].data)) {
|
|
|
+ if(!picopass_hex_str_to_uint8(
|
|
|
+ furi_string_get_cstr(block_str), PICOPASS_BLOCK_LEN, card_data[i].data)) {
|
|
|
block_read = false;
|
|
|
break;
|
|
|
}
|
|
|
@@ -347,7 +371,9 @@ static bool picopass_device_load_data(PicopassDevice* dev, FuriString* path, boo
|
|
|
}
|
|
|
if(!block_read) break;
|
|
|
|
|
|
- if(card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].valid) {
|
|
|
+ if(pacs->se_enabled) {
|
|
|
+ FURI_LOG_D(TAG, "Skipping parsing: SE enabled");
|
|
|
+ } else if(card_data[PICOPASS_ICLASS_PACS_CFG_BLOCK_INDEX].valid) {
|
|
|
picopass_device_parse_credential(card_data, pacs);
|
|
|
picopass_device_parse_wiegand(pacs);
|
|
|
}
|