diff --git a/client/src/cmdhfemrtd.c b/client/src/cmdhfemrtd.c index e6875fc63..389d10f53 100644 --- a/client/src/cmdhfemrtd.c +++ b/client/src/cmdhfemrtd.c @@ -1154,15 +1154,28 @@ static void emrtd_print_name(char *mrz, int offset, int max_length, bool localiz } } -static void emrtd_mrz_convert_date(char *mrz, int offset, char *final_date, bool is_expiry, bool is_full) { +static void emrtd_mrz_convert_date(char *mrz, int offset, char *final_date, bool is_expiry, bool is_full, bool is_ascii) { + char work_date[9] = { 0x00 }; + int len = is_full ? 8 : 6; + + // Copy the data to a working array in the right format + if (!is_ascii) { + memcpy(work_date, sprint_hex_inrow((uint8_t *)mrz + offset, len / 2), len); + } else { + memcpy(work_date, mrz + offset, len); + } + + // Set offset to 0 as we've now copied data. + offset = 0; + if (is_full) { // If we get the full date, use the first two characters from that for year - memcpy(final_date, mrz, 2); + memcpy(final_date, work_date, 2); // and do + 2 on offset so that rest of code uses the right data offset += 2; } else { char temp_year[3] = { 0x00 }; - memcpy(temp_year, mrz + offset, 2); + memcpy(temp_year, work_date, 2); // If it's > 20, assume 19xx. if (strtol(temp_year, NULL, 10) < 20 || is_expiry) { final_date[0] = '2'; @@ -1173,16 +1186,16 @@ static void emrtd_mrz_convert_date(char *mrz, int offset, char *final_date, bool } } - memcpy(final_date + 2, mrz + offset, 2); + memcpy(final_date + 2, work_date + offset, 2); final_date[4] = '-'; - memcpy(final_date + 5, mrz + offset + 2, 2); + memcpy(final_date + 5, work_date + offset + 2, 2); final_date[7] = '-'; - memcpy(final_date + 8, mrz + offset + 4, 2); + memcpy(final_date + 8, work_date + offset + 4, 2); } -static void emrtd_print_dob(char *mrz, int offset, bool full) { +static void emrtd_print_dob(char *mrz, int offset, bool full, bool ascii) { char final_date[12] = { 0x00 }; - emrtd_mrz_convert_date(mrz, offset, final_date, false, full); + emrtd_mrz_convert_date(mrz, offset, final_date, false, full, ascii); PrintAndLogEx(SUCCESS, "Date of birth.........: " _YELLOW_("%s"), final_date); @@ -1193,7 +1206,7 @@ static void emrtd_print_dob(char *mrz, int offset, bool full) { static void emrtd_print_expiry(char *mrz, int offset) { char final_date[12] = { 0x00 }; - emrtd_mrz_convert_date(mrz, offset, final_date, true, false); + emrtd_mrz_convert_date(mrz, offset, final_date, true, false, true); PrintAndLogEx(SUCCESS, "Date of expiry........: " _YELLOW_("%s"), final_date); @@ -1202,9 +1215,9 @@ static void emrtd_print_expiry(char *mrz, int offset) { } } -static void emrtd_print_issuance(char *data) { +static void emrtd_print_issuance(char *data, bool ascii) { char final_date[12] = { 0x00 }; - emrtd_mrz_convert_date(data, 0, final_date, true, true); + emrtd_mrz_convert_date(data, 0, final_date, true, true, ascii); PrintAndLogEx(SUCCESS, "Date of issue.........: " _YELLOW_("%s"), final_date); } @@ -1268,7 +1281,7 @@ static bool emrtd_print_ef_dg1_info(uint8_t *response, int resplen) { PrintAndLogEx(SUCCESS, "Nationality...........: " _YELLOW_("%.3s"), mrz + 44 + 10); emrtd_print_name(mrz, 5, 38, false); emrtd_print_document_number(mrz, 44); - emrtd_print_dob(mrz, 44 + 13, false); + emrtd_print_dob(mrz, 44 + 13, false, true); emrtd_print_legal_sex(&mrz[44 + 20]); emrtd_print_expiry(mrz, 44 + 21); emrtd_print_optional_elements(mrz, 44 + 28, 14, true); @@ -1287,7 +1300,7 @@ static bool emrtd_print_ef_dg1_info(uint8_t *response, int resplen) { PrintAndLogEx(SUCCESS, "Nationality...........: " _YELLOW_("%.3s"), mrz + 30 + 15); emrtd_print_name(mrz, 60, 30, false); emrtd_print_document_number(mrz, 5); - emrtd_print_dob(mrz, 30, false); + emrtd_print_dob(mrz, 30, false, true); emrtd_print_legal_sex(&mrz[30 + 7]); emrtd_print_expiry(mrz, 30 + 8); emrtd_print_optional_elements(mrz, 15, 15, false); @@ -1324,6 +1337,9 @@ static bool emrtd_print_ef_dg11_info(uint8_t *response, int resplen) { case 0x0e: emrtd_print_name((char *) tagdata, 0, tagdatalen, true); break; + case 0x0f: + emrtd_print_name((char *) tagdata, 0, tagdatalen, false); + break; case 0x10: PrintAndLogEx(SUCCESS, "Personal Number.......: " _YELLOW_("%.*s"), tagdatalen, tagdata); break; @@ -1358,7 +1374,7 @@ static bool emrtd_print_ef_dg11_info(uint8_t *response, int resplen) { PrintAndLogEx(SUCCESS, "Custody Information...: " _YELLOW_("%.*s"), tagdatalen, tagdata); break; case 0x2b: - emrtd_print_dob((char *) tagdata, 0, true); + emrtd_print_dob((char *) tagdata, 0, true, tagdatalen != 4); break; default: PrintAndLogEx(SUCCESS, "Unknown Field %02X%02X....: %s", taglist[i], taglist[i + 1], sprint_hex_inrow(tagdata, tagdatalen)); @@ -1399,7 +1415,7 @@ static bool emrtd_print_ef_dg12_info(uint8_t *response, int resplen) { PrintAndLogEx(SUCCESS, "Issuing Authority.....: " _YELLOW_("%.*s"), tagdatalen, tagdata); break; case 0x26: - emrtd_print_issuance((char *) tagdata); + emrtd_print_issuance((char *) tagdata, tagdatalen != 4); break; case 0x1b: PrintAndLogEx(SUCCESS, "Endorsements & Observations: " _YELLOW_("%.*s"), tagdatalen, tagdata);