diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index 8799dc12e..c99c4b939 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1957,16 +1957,18 @@ int infoHF_EMRTD_offline(const char *path) { uint8_t *data; size_t datalen = 0; char *filepath = calloc(strlen(path) + 100, sizeof(char)); - if (filepath == NULL) + if (filepath == NULL) { return PM3_EMALLOC; + } strcpy(filepath, path); strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_COM].filename); - if (loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Failed to read EF_COM."); - free(filepath); - return PM3_ESOFT; + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) { + PrintAndLogEx(ERR, "Failed to read EF_COM"); + free(filepath); + return PM3_ESOFT; } int res = emrtd_print_ef_com_info(data, datalen); @@ -1996,21 +1998,23 @@ int infoHF_EMRTD_offline(const char *path) { strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_CardAccess].filename); - if (loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) { - emrtd_print_ef_cardaccess_info(data, datalen); - free(data); + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) || + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) { + emrtd_print_ef_cardaccess_info(data, datalen); + free(data); } else { - PrintAndLogEx(HINT, "The error above this is normal. It just means that your eMRTD lacks PACE."); + PrintAndLogEx(HINT, "The error above this is normal. It just means that your eMRTD lacks PACE"); } strcpy(filepath, path); strncat(filepath, PATHSEP, 2); strcat(filepath, dg_table[EF_SOD].filename); - if (loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Failed to read EF_SOD."); - free(filepath); - return PM3_ESOFT; + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS) && + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) != PM3_SUCCESS)) { + PrintAndLogEx(ERR, "Failed to read EF_SOD"); + free(filepath); + return PM3_ESOFT; } // coverity scan CID 395630, @@ -2020,7 +2024,7 @@ int infoHF_EMRTD_offline(const char *path) { res = emrtd_parse_ef_sod_hashes(data, datalen, *dg_hashes_sod, &hash_algo); if (res != PM3_SUCCESS) { - PrintAndLogEx(ERR, "Failed to read hash list from EF_SOD. Hash checks will fail."); + PrintAndLogEx(ERR, "Failed to read hash list from EF_SOD. Hash checks will fail"); } free(data); @@ -2035,10 +2039,12 @@ int infoHF_EMRTD_offline(const char *path) { strcpy(filepath, path); strncat(filepath, PATHSEP, 2); strcat(filepath, dg->filename); - if (loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) { + if ((loadFile_safeEx(filepath, ".BIN", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS) || + (loadFile_safeEx(filepath, ".bin", (void **)&data, (size_t *)&datalen, false) == PM3_SUCCESS)) { // we won't halt on parsing errors - if (dg->parser != NULL) + if (dg->parser != NULL) { dg->parser(data, datalen); + } PrintAndLogEx(DEBUG, "EF_DG%i hash algo: %i", dg->dgnum, hash_algo); // Check file hash @@ -2058,13 +2064,6 @@ int infoHF_EMRTD_offline(const char *path) { return PM3_SUCCESS; } -static void text_to_upper(uint8_t *data, int datalen) { - // Loop over text to make lowercase text uppercase - for (int i = 0; i < datalen; i++) { - data[i] = toupper(data[i]); - } -} - static bool validate_date(uint8_t *data, int datalen) { // Date has to be 6 chars if (datalen != 6) { @@ -2085,7 +2084,9 @@ static int CmdHFeMRTDDump(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf emrtd dump", "Dump all files on an eMRTD", - "hf emrtd dump" + "hf emrtd dump\n" + "hf emrtd dump --dir ../dump\n" + "hf emrtd dump -n 123456789 -d 19890101 -e 20250401" ); void *argtable[] = { @@ -2094,7 +2095,7 @@ static int CmdHFeMRTDDump(const char *Cmd) { arg_str0("d", "dateofbirth", "", "date of birth in YYMMDD format"), arg_str0("e", "expiry", "", "expiry in YYMMDD format"), arg_str0("m", "mrz", "<[0-9A-Z<]>", "2nd line of MRZ, 44 chars"), - arg_str0(NULL, "path", "", "save dump to the given dirpath"), + arg_str0(NULL, "dir", "", "save dump to the given dirpath"), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -2110,7 +2111,7 @@ static int CmdHFeMRTDDump(const char *Cmd) { if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) { BAC = false; } else { - text_to_upper(docnum, slen); + strn_upper((char*)docnum, slen); if (slen != 9) { // Pad to 9 with < memset(docnum + slen, '<', 9 - slen); @@ -2143,7 +2144,7 @@ static int CmdHFeMRTDDump(const char *Cmd) { error = true; } else { BAC = true; - text_to_upper(mrz, slen); + strn_upper((char*)mrz, slen); memcpy(docnum, &mrz[0], 9); memcpy(dob, &mrz[13], 6); memcpy(expiry, &mrz[21], 6); @@ -2183,7 +2184,10 @@ static int CmdHFeMRTDInfo(const char *Cmd) { CLIParserContext *ctx; CLIParserInit(&ctx, "hf emrtd info", "Display info about an eMRTD", - "hf emrtd info" + "hf emrtd info\n" + "hf emrtd info --dir ../dumps\n" + "hf emrtd info -n 123456789 -d 19890101 -e 20250401\n" + "hf emrtd info -n 123456789 -d 19890101 -e 20250401 -i" ); void *argtable[] = { @@ -2192,7 +2196,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { arg_str0("d", "dateofbirth", "", "date of birth in YYMMDD format"), arg_str0("e", "expiry", "", "expiry in YYMMDD format"), arg_str0("m", "mrz", "<[0-9A-Z<]>", "2nd line of MRZ, 44 chars (passports only)"), - arg_str0(NULL, "path", "", "display info from offline dump stored in dirpath"), + arg_str0(NULL, "dir", "", "display info from offline dump stored in dirpath"), arg_lit0("i", "images", "show images"), arg_param_end }; @@ -2209,7 +2213,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) { BAC = false; } else { - text_to_upper(docnum, slen); + strn_upper((char*)docnum, slen); if (slen != 9) { memset(docnum + slen, '<', 9 - slen); } @@ -2241,7 +2245,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { error = true; } else { BAC = true; - text_to_upper(mrz, slen); + strn_upper((char*)mrz, slen); memcpy(docnum, &mrz[0], 9); memcpy(dob, &mrz[13], 6); memcpy(expiry, &mrz[21], 6); @@ -2262,7 +2266,7 @@ static int CmdHFeMRTDInfo(const char *Cmd) { bool is_offline = CLIParamStrToBuf(arg_get_str(ctx, 5), path, sizeof(path), &slen) == 0 && slen > 0; bool show_images = arg_get_lit(ctx, 6); CLIParserFree(ctx); - if ((! IfPm3Iso14443()) && (! is_offline)) { + if ((IfPm3Iso14443() == false) && (is_offline == false)) { PrintAndLogEx(WARNING, "Only offline mode is available"); error = true; } diff --git a/client/src/util.c b/client/src/util.c index 56eb3164a..dc58eef2c 100644 --- a/client/src/util.c +++ b/client/src/util.c @@ -1088,6 +1088,14 @@ void str_lower(char *s) { s[i] = tolower(s[i]); } +void str_upper(char *s) { + strn_upper(s, strlen(s)); +} + +void strn_upper(char *s, size_t n) { + for (size_t i = 0; i < n; i++) + s[i] = toupper(s[i]); +} // check for prefix in string bool str_startswith(const char *s, const char *pre) { return strncmp(pre, s, strlen(pre)) == 0; diff --git a/client/src/util.h b/client/src/util.h index 616272c84..d831a750b 100644 --- a/client/src/util.h +++ b/client/src/util.h @@ -129,6 +129,9 @@ uint64_t HornerScheme(uint64_t num, uint64_t divider, uint64_t factor); int num_CPUs(void); // number of logical CPUs void str_lower(char *s); // converts string to lower case +void str_upper(char *s); // converts string to UPPER case +void strn_upper(char *s, size_t n); + bool str_startswith(const char *s, const char *pre); // check for prefix in string bool str_endswith(const char *s, const char *suffix); // check for suffix in string void clean_ascii(unsigned char *buf, size_t len);