Merge pull request #1123 from aveao/emrtd

hf emrtd info: EF_DG12 support + coverity fixes
This commit is contained in:
Philippe Teuwen 2020-12-18 23:47:16 +01:00 committed by GitHub
commit 2e50237373
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1183,6 +1183,22 @@ static void emrtd_print_expiry(char *mrz, int offset) {
}
}
static void emrtd_print_issuance(char *data) {
char final_date[12] = { 0x00 };
emrtd_mrz_convert_date(data, 0, final_date, true, true);
PrintAndLogEx(SUCCESS, "Date of issue.........: " _YELLOW_("%s"), final_date);
}
static void emrtd_print_personalization_timestamp(uint8_t *data) {
char str_date[0x0F] = { 0x00 };
strcpy(str_date, sprint_hex_inrow(data, 0x0E));
char final_date[20] = { 0x00 };
sprintf(final_date, "%.4s-%.2s-%.2s %.2s:%.2s:%.2s", str_date, str_date + 4, str_date + 6, str_date + 8, str_date + 10, str_date + 12);
PrintAndLogEx(SUCCESS, "Personalization at....: " _YELLOW_("%s"), final_date);
}
static bool emrtd_print_ef_dg1_info(uint8_t *response, int resplen) {
int td_variant = 0;
@ -1339,6 +1355,65 @@ static bool emrtd_print_ef_dg11_info(uint8_t *response, int resplen) {
return true;
}
static bool emrtd_print_ef_dg12_info(uint8_t *response, int resplen) {
uint8_t taglist[100] = { 0x00 };
int taglistlen = 0;
uint8_t tagdata[1000] = { 0x00 };
int tagdatalen = 0;
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "-------------------- " _CYAN_("EF_DG12") " -------------------");
if (!emrtd_lds_get_data_by_tag(response, &resplen, taglist, &taglistlen, 0x5c, 0x00, false)) {
PrintAndLogEx(ERR, "Failed to read file list from EF_DG12.");
return false;
}
for (int i = 0; i < taglistlen; i++) {
emrtd_lds_get_data_by_tag(response, &resplen, tagdata, &tagdatalen, taglist[i], taglist[i + 1], taglist[i] == 0x5f);
// Special behavior for two char tags
if (taglist[i] == 0x5f) {
// Several things here are longer than the rest but I can't think of a way to shorten them
// ...and I doubt many states are using them.
switch (taglist[i + 1]) {
case 0x19:
PrintAndLogEx(SUCCESS, "Issuing Authority.....: " _YELLOW_("%.*s"), tagdatalen, tagdata);
break;
case 0x26:
emrtd_print_issuance((char *) tagdata);
break;
case 0x1b:
PrintAndLogEx(SUCCESS, "Endorsements & Observations: " _YELLOW_("%.*s"), tagdatalen, tagdata);
break;
case 0x1c:
PrintAndLogEx(SUCCESS, "Tax/Exit Requirements.: " _YELLOW_("%.*s"), tagdatalen, tagdata);
break;
case 0x1d:
saveFile("FrontOfDocument", ".jpg", tagdata, tagdatalen);
break;
case 0x1e:
saveFile("BackOfDocument", ".jpg", tagdata, tagdatalen);
break;
case 0x55:
emrtd_print_personalization_timestamp(tagdata);
break;
case 0x56:
PrintAndLogEx(SUCCESS, "Serial of Personalization System: " _YELLOW_("%.*s"), tagdatalen, tagdata);
break;
default:
PrintAndLogEx(SUCCESS, "Unknown Field %02X%02X....: %s", taglist[i], taglist[i + 1], sprint_hex_inrow(tagdata, tagdatalen));
break;
}
i += 1;
} else {
// TODO: Account for A0
PrintAndLogEx(SUCCESS, "Unknown Field %02X......: %s", taglist[i], sprint_hex_inrow(tagdata, tagdatalen));
}
}
return true;
}
int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_available) {
uint8_t response[EMRTD_MAX_FILE_SIZE] = { 0x00 };
int resplen = 0;
@ -1396,6 +1471,8 @@ int infoHF_EMRTD(char *documentnumber, char *dob, char *expiry, bool BAC_availab
emrtd_print_ef_dg1_info(response, resplen);
} else if (strcmp(file_name, "EF_DG11") == 0 && emrtd_select_and_read(response, &resplen, EMRTD_EF_DG11, ks_enc, ks_mac, ssc, BAC, use_14b)) {
emrtd_print_ef_dg11_info(response, resplen);
} else if (strcmp(file_name, "EF_DG12") == 0 && emrtd_select_and_read(response, &resplen, EMRTD_EF_DG12, ks_enc, ks_mac, ssc, BAC, use_14b)) {
emrtd_print_ef_dg12_info(response, resplen);
}
}
@ -1446,7 +1523,8 @@ static int cmd_hf_emrtd_dump(const char *Cmd) {
uint8_t dob[7] = { 0x00 };
uint8_t expiry[7] = { 0x00 };
bool BAC = true;
int slen = 0; // unused
bool error = false;
int slen = 0;
// Go through all args, if even one isn't supplied, mark BAC as unavailable
if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) {
BAC = false;
@ -1464,7 +1542,7 @@ static int cmd_hf_emrtd_dump(const char *Cmd) {
if (!validate_date(dob, slen)) {
PrintAndLogEx(ERR, "Date of birth date format is incorrect, cannot continue.");
PrintAndLogEx(HINT, "Use the format YYMMDD.");
return PM3_ESOFT;
error = true;
}
}
@ -1474,11 +1552,14 @@ static int cmd_hf_emrtd_dump(const char *Cmd) {
if (!validate_date(expiry, slen)) {
PrintAndLogEx(ERR, "Expiry date format is incorrect, cannot continue.");
PrintAndLogEx(HINT, "Use the format YYMMDD.");
return PM3_ESOFT;
error = true;
}
}
CLIParserFree(ctx);
if (error) {
return PM3_ESOFT;
}
return dumpHF_EMRTD((char *)docnum, (char *)dob, (char *)expiry, BAC);
}
@ -1502,7 +1583,8 @@ static int cmd_hf_emrtd_info(const char *Cmd) {
uint8_t dob[7] = { 0x00 };
uint8_t expiry[7] = { 0x00 };
bool BAC = true;
int slen = 0; // unused
bool error = false;
int slen = 0;
// Go through all args, if even one isn't supplied, mark BAC as unavailable
if (CLIParamStrToBuf(arg_get_str(ctx, 1), docnum, 9, &slen) != 0 || slen == 0) {
BAC = false;
@ -1519,7 +1601,7 @@ static int cmd_hf_emrtd_info(const char *Cmd) {
if (!validate_date(dob, slen)) {
PrintAndLogEx(ERR, "Date of birth date format is incorrect, cannot continue.");
PrintAndLogEx(HINT, "Use the format YYMMDD.");
return PM3_ESOFT;
error = true;
}
}
@ -1529,11 +1611,14 @@ static int cmd_hf_emrtd_info(const char *Cmd) {
if (!validate_date(expiry, slen)) {
PrintAndLogEx(ERR, "Expiry date format is incorrect, cannot continue.");
PrintAndLogEx(HINT, "Use the format YYMMDD.");
return PM3_ESOFT;
error = true;
}
}
CLIParserFree(ctx);
if (error) {
return PM3_ESOFT;
}
return infoHF_EMRTD((char *)docnum, (char *)dob, (char *)expiry, BAC);
}