mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
AC Response Format1
This commit is contained in:
parent
70744d2cbb
commit
607bef7ffd
3 changed files with 64 additions and 5 deletions
|
@ -38,6 +38,9 @@ void ParamLoadDefaults(struct tlvdb *tlvRoot) {
|
||||||
TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
|
TLV_ADD(0x9F6A, "\x01\x02\x03\x04");
|
||||||
//9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
|
//9F66:(Terminal Transaction Qualifiers (TTQ)) len:4
|
||||||
TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
|
TLV_ADD(0x9F66, "\x26\x00\x00\x00"); // qVSDC
|
||||||
|
//95:(Terminal Verification Results) len:5
|
||||||
|
// all OK TVR
|
||||||
|
TLV_ADD(0x95, "\x00\x00\x00\x00\x00");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintChannel(EMVCommandChannel channel) {
|
void PrintChannel(EMVCommandChannel channel) {
|
||||||
|
@ -685,6 +688,50 @@ void ProcessGPOResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProcessACResponseFormat1(struct tlvdb *tlvRoot, uint8_t *buf, size_t len, bool decodeTLV) {
|
||||||
|
if (buf[0] == 0x80) {
|
||||||
|
if (decodeTLV){
|
||||||
|
PrintAndLog("GPO response format1:");
|
||||||
|
TLVPrintFromBuffer(buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t elmlen = len - 2; // wo 0x80XX
|
||||||
|
|
||||||
|
if (len < 4 + 2 || (elmlen - 2) % 4 || elmlen != buf[1]) {
|
||||||
|
PrintAndLogEx(ERR, "GPO response format1 parsing error. length=%d", len);
|
||||||
|
} else {
|
||||||
|
struct tlvdb *tlvElm = NULL;
|
||||||
|
if (decodeTLV)
|
||||||
|
PrintAndLog("\n------------ Format1 decoded ------------");
|
||||||
|
|
||||||
|
// CID (Cryptogram Information Data)
|
||||||
|
tlvdb_change_or_add_node_ex(tlvRoot, 0x9f27, 1, &buf[2], &tlvElm);
|
||||||
|
if (decodeTLV)
|
||||||
|
TLVPrintFromTLV(tlvElm);
|
||||||
|
|
||||||
|
// ATC (Application Transaction Counter)
|
||||||
|
tlvdb_change_or_add_node_ex(tlvRoot, 0x9f36, 2, &buf[3], &tlvElm);
|
||||||
|
if (decodeTLV)
|
||||||
|
TLVPrintFromTLV(tlvElm);
|
||||||
|
|
||||||
|
// AC (Application Cryptogram)
|
||||||
|
tlvdb_change_or_add_node_ex(tlvRoot, 0x9f26, min(8, elmlen - 3), &buf[5], &tlvElm);
|
||||||
|
if (decodeTLV)
|
||||||
|
TLVPrintFromTLV(tlvElm);
|
||||||
|
|
||||||
|
// IAD (Issuer Application Data) - optional
|
||||||
|
if (len > 11 + 2) {
|
||||||
|
tlvdb_change_or_add_node_ex(tlvRoot, 0x9f10, elmlen - 11, &buf[13], &tlvElm);
|
||||||
|
if (decodeTLV)
|
||||||
|
TLVPrintFromTLV(tlvElm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (decodeTLV)
|
||||||
|
TLVPrintFromBuffer(buf, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int CmdEMVExec(const char *cmd) {
|
int CmdEMVExec(const char *cmd) {
|
||||||
uint8_t buf[APDU_RES_LEN] = {0};
|
uint8_t buf[APDU_RES_LEN] = {0};
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
@ -1151,9 +1198,9 @@ int CmdEMVExec(const char *cmd) {
|
||||||
PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw);
|
PrintAndLogEx(NORMAL, "AC1 error(%d): %4x. Exit...", res, sw);
|
||||||
dreturn(7);
|
dreturn(7);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decodeTLV)
|
// process Format1 (0x80) anf print Format2 (0x77)
|
||||||
TLVPrintFromBuffer(buf, len);
|
ProcessACResponseFormat1(tlvRoot, buf, len, decodeTLV);
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "\n* * Processing online request\n");
|
PrintAndLogEx(NORMAL, "\n* * Processing online request\n");
|
||||||
|
|
||||||
|
|
|
@ -359,12 +359,15 @@ void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other)
|
||||||
tlvdb->next = other;
|
tlvdb->next = other;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value)
|
void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value, struct tlvdb **tlvdb_elm)
|
||||||
{
|
{
|
||||||
struct tlvdb *telm = tlvdb_find_full(tlvdb, tag);
|
struct tlvdb *telm = tlvdb_find_full(tlvdb, tag);
|
||||||
if (telm == NULL) {
|
if (telm == NULL) {
|
||||||
// new tlv element
|
// new tlv element
|
||||||
tlvdb_add(tlvdb, tlvdb_fixed(tag, len, value));
|
struct tlvdb *elm = tlvdb_fixed(tag, len, value);
|
||||||
|
tlvdb_add(tlvdb, elm);
|
||||||
|
if (tlvdb_elm)
|
||||||
|
*tlvdb_elm = elm;
|
||||||
} else {
|
} else {
|
||||||
// the same tlv structure
|
// the same tlv structure
|
||||||
if (telm->tag.tag == tag && telm->tag.len == len && !memcmp(telm->tag.value, value, len))
|
if (telm->tag.tag == tag && telm->tag.len == len && !memcmp(telm->tag.value, value, len))
|
||||||
|
@ -400,11 +403,19 @@ void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, co
|
||||||
// free old element with childrens
|
// free old element with childrens
|
||||||
telm->next = NULL;
|
telm->next = NULL;
|
||||||
tlvdb_free(telm);
|
tlvdb_free(telm);
|
||||||
|
|
||||||
|
if (tlvdb_elm)
|
||||||
|
*tlvdb_elm = tnewelm;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value)
|
||||||
|
{
|
||||||
|
tlvdb_change_or_add_node_ex(tlvdb, tag, len, value, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level)
|
void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level)
|
||||||
{
|
{
|
||||||
struct tlvdb *next = NULL;
|
struct tlvdb *next = NULL;
|
||||||
|
|
|
@ -50,6 +50,7 @@ struct tlvdb *tlvdb_find_path(struct tlvdb *tlvdb, tlv_tag_t tag[]);
|
||||||
|
|
||||||
void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other);
|
void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other);
|
||||||
void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value);
|
void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value);
|
||||||
|
void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, const unsigned char *value, struct tlvdb **tlvdb_elm);
|
||||||
|
|
||||||
void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level);
|
void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level);
|
||||||
const struct tlv *tlvdb_get(const struct tlvdb *tlvdb, tlv_tag_t tag, const struct tlv *prev);
|
const struct tlv *tlvdb_get(const struct tlvdb *tlvdb, tlv_tag_t tag, const struct tlv *prev);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue