mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-22 06:13:27 -07:00
SDA works
This commit is contained in:
parent
8d9526f375
commit
667a1beafb
3 changed files with 48 additions and 22 deletions
|
@ -308,6 +308,8 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
uint16_t sw = 0;
|
||||
uint8_t AID[APDU_AID_LEN] = {0};
|
||||
size_t AIDlen = 0;
|
||||
uint8_t ODAiList[4096];
|
||||
size_t ODAiListLen = 0;
|
||||
|
||||
int res;
|
||||
|
||||
|
@ -568,9 +570,23 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
PrintAndLog("");
|
||||
}
|
||||
|
||||
// Build Input list for Offline Data Authentication
|
||||
// EMV 4.3 book3 10.3, page 96
|
||||
if (SFIoffline) {
|
||||
// here will be offline records storing...
|
||||
// dont foget: if (sfi < 11)
|
||||
if (SFI < 11) {
|
||||
const unsigned char *abuf = buf;
|
||||
size_t elmlen = len;
|
||||
struct tlv e;
|
||||
if (tlv_parse_tl(&abuf, &elmlen, &e)) {
|
||||
memcpy(&ODAiList[ODAiListLen], &buf[len - elmlen], elmlen);
|
||||
ODAiListLen += elmlen;
|
||||
} else {
|
||||
PrintAndLog("ERROR SFI[%02x]. Creating input list for Offline Data Authentication error.", SFI);
|
||||
}
|
||||
} else {
|
||||
memcpy(&ODAiList[ODAiListLen], buf, len);
|
||||
ODAiListLen += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -578,6 +594,13 @@ int CmdHFEMVExec(const char *cmd) {
|
|||
break;
|
||||
}
|
||||
|
||||
// copy Input list for Offline Data Authentication
|
||||
if (ODAiListLen) {
|
||||
struct tlvdb *oda = tlvdb_fixed(0x21, ODAiListLen, ODAiList); // not a standard tag
|
||||
tlvdb_add(tlvRoot, oda);
|
||||
PrintAndLog("* Input list for Offline Data Authentication added to TLV. len=%d \n", ODAiListLen);
|
||||
}
|
||||
|
||||
// get AIP
|
||||
const struct tlv *AIPtlv = tlvdb_get(tlvRoot, 0x82, NULL);
|
||||
uint16_t AIP = AIPtlv->value[0] + AIPtlv->value[1] * 0x100;
|
||||
|
|
|
@ -177,7 +177,7 @@ static const struct emv_tag emv_tags[] = {
|
|||
{ 0x01 , "", EMV_TAG_STRING }, // string for headers
|
||||
{ 0x02 , "Raw data", }, // data
|
||||
{ 0x20 , "Cardholder Verification Results (CVR)", EMV_TAG_CVR }, // not standard!
|
||||
{ 0x21 , "SDA data" }, // not standard! data for offline authentication from read records command
|
||||
{ 0x21 , "Input list for Offline Data Authentication" }, // not standard! data for "Offline Data Authentication" come from "read records" command. (EMV book3 10.3)
|
||||
|
||||
// EMV
|
||||
{ 0x41 , "Country code and national data" },
|
||||
|
|
|
@ -492,7 +492,7 @@ int trSDA(uint8_t *AID, size_t AIDlen, struct tlvdb *tlv) {
|
|||
|
||||
struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv);
|
||||
if (!issuer_pk) {
|
||||
PrintAndLog("ERROR: Issuer certificate found. Exit.");
|
||||
PrintAndLog("ERROR: Issuer certificate not found. Exit.");
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
@ -510,14 +510,14 @@ int trSDA(uint8_t *AID, size_t AIDlen, struct tlvdb *tlv) {
|
|||
|
||||
const struct tlv *sda_tlv = tlvdb_get(tlv, 0x21, NULL);
|
||||
if (!sda_tlv || sda_tlv->len < 1) {
|
||||
PrintAndLog("ERROR: Can't find dynamic authentication data. Exit.");
|
||||
PrintAndLog("ERROR: Can't find input list for Offline Data Authentication. Exit.");
|
||||
return 3;
|
||||
}
|
||||
|
||||
struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv);
|
||||
if (dac_db) {
|
||||
const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL);
|
||||
PrintAndLog("SDA verified OK (%02hhx:%02hhx)!\n", dac_tlv->value[0], dac_tlv->value[1]);
|
||||
PrintAndLog("SDA verified OK. (%02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]);
|
||||
tlvdb_add(tlv, dac_db);
|
||||
} else {
|
||||
PrintAndLog("ERROR: SSAD verify error");
|
||||
|
@ -538,27 +538,30 @@ int trDDA(uint8_t *AID, size_t AIDlen, struct tlvdb *tlv) {
|
|||
|
||||
const struct tlv *sda_tlv = tlvdb_get(tlv, 0x21, NULL);
|
||||
if (!sda_tlv || sda_tlv->len < 1) {
|
||||
PrintAndLog("ERROR: Can't find dynamic authentication data. Exit.");
|
||||
PrintAndLog("ERROR: Can't find input list for Offline Data Authentication. Exit.");
|
||||
return 3;
|
||||
}
|
||||
|
||||
struct emv_pk *issuer_pk = emv_pki_recover_issuer_cert(pk, tlv);
|
||||
if (issuer_pk)
|
||||
printf("Issuer PK recovered! RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
|
||||
issuer_pk->rid[0],
|
||||
issuer_pk->rid[1],
|
||||
issuer_pk->rid[2],
|
||||
issuer_pk->rid[3],
|
||||
issuer_pk->rid[4],
|
||||
issuer_pk->index,
|
||||
issuer_pk->serial[0],
|
||||
issuer_pk->serial[1],
|
||||
issuer_pk->serial[2]
|
||||
);
|
||||
if (!issuer_pk) {
|
||||
PrintAndLog("ERROR: Issuer certificate not found. Exit.");
|
||||
return 2;
|
||||
}
|
||||
printf("Issuer PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
|
||||
issuer_pk->rid[0],
|
||||
issuer_pk->rid[1],
|
||||
issuer_pk->rid[2],
|
||||
issuer_pk->rid[3],
|
||||
issuer_pk->rid[4],
|
||||
issuer_pk->index,
|
||||
issuer_pk->serial[0],
|
||||
issuer_pk->serial[1],
|
||||
issuer_pk->serial[2]
|
||||
);
|
||||
|
||||
struct emv_pk *icc_pk = emv_pki_recover_icc_cert(issuer_pk, tlv, sda_tlv);
|
||||
if (icc_pk)
|
||||
printf("ICC PK recovered! RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
|
||||
printf("ICC PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
|
||||
icc_pk->rid[0],
|
||||
icc_pk->rid[1],
|
||||
icc_pk->rid[2],
|
||||
|
@ -571,7 +574,7 @@ int trDDA(uint8_t *AID, size_t AIDlen, struct tlvdb *tlv) {
|
|||
);
|
||||
struct emv_pk *icc_pe_pk = emv_pki_recover_icc_pe_cert(issuer_pk, tlv);
|
||||
if (icc_pe_pk)
|
||||
printf("ICC PE PK recovered! RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
|
||||
printf("ICC PE PK recovered. RID %02hhx:%02hhx:%02hhx:%02hhx:%02hhx IDX %02hhx CSN %02hhx:%02hhx:%02hhx\n",
|
||||
icc_pe_pk->rid[0],
|
||||
icc_pe_pk->rid[1],
|
||||
icc_pe_pk->rid[2],
|
||||
|
@ -585,7 +588,7 @@ int trDDA(uint8_t *AID, size_t AIDlen, struct tlvdb *tlv) {
|
|||
struct tlvdb *dac_db = emv_pki_recover_dac(issuer_pk, tlv, sda_tlv);
|
||||
if (dac_db) {
|
||||
const struct tlv *dac_tlv = tlvdb_get(dac_db, 0x9f45, NULL);
|
||||
printf("SDA verified OK (%02hhx:%02hhx)!\n", dac_tlv->value[0], dac_tlv->value[1]);
|
||||
printf("SDA verified OK. (%02hhx:%02hhx)\n", dac_tlv->value[0], dac_tlv->value[1]);
|
||||
tlvdb_add(tlv, dac_db);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue