mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
Fixed data asn1
- now handles bad input better by doing correct root free of obj
This commit is contained in:
parent
906e3f4c32
commit
2e8bacb00f
4 changed files with 66 additions and 34 deletions
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
||||||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||||
|
|
||||||
## [unreleased][unreleased]
|
## [unreleased][unreleased]
|
||||||
|
- Fixed `data asn1` - now handles bad input better (@iceman1001)
|
||||||
- Added new public key for signature MIFARE Plus Troika (@iceman100)
|
- Added new public key for signature MIFARE Plus Troika (@iceman100)
|
||||||
- Fixed the client build on Android (@wh201906)
|
- Fixed the client build on Android (@wh201906)
|
||||||
- Added TCP connection support on Windows (@wh201906)
|
- Added TCP connection support on Windows (@wh201906)
|
||||||
|
|
|
@ -576,7 +576,8 @@ static int PivGetData(Iso7816CommandChannel channel, const uint8_t tag[], size_t
|
||||||
struct tlvdb_root *new_root = realloc(root, sizeof(*root) + capacity);
|
struct tlvdb_root *new_root = realloc(root, sizeof(*root) + capacity);
|
||||||
if (new_root == NULL) {
|
if (new_root == NULL) {
|
||||||
PrintAndLogEx(FAILED, "Running out of memory while re-allocating buffer");
|
PrintAndLogEx(FAILED, "Running out of memory while re-allocating buffer");
|
||||||
free(root);
|
//free(root);
|
||||||
|
tlvdb_root_free(root);
|
||||||
return PM3_EMALLOC;
|
return PM3_EMALLOC;
|
||||||
}
|
}
|
||||||
root = new_root;
|
root = new_root;
|
||||||
|
|
|
@ -177,7 +177,7 @@ bool TLVPrintFromBuffer(uint8_t *data, int datalen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLVPrintFromTLVLev(struct tlvdb *tlv, int level) {
|
void TLVPrintFromTLVLev(struct tlvdb *tlv, int level) {
|
||||||
if (!tlv)
|
if (tlv == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
tlvdb_visit(tlv, emv_print_cb, NULL, level);
|
tlvdb_visit(tlv, emv_print_cb, NULL, level);
|
||||||
|
@ -193,15 +193,16 @@ void TLVPrintAIDlistFromSelectTLV(struct tlvdb *tlv) {
|
||||||
PrintAndLogEx(INFO, "|------------------+--------+-------------------------|");
|
PrintAndLogEx(INFO, "|------------------+--------+-------------------------|");
|
||||||
|
|
||||||
struct tlvdb *ttmp = tlvdb_find(tlv, 0x6f);
|
struct tlvdb *ttmp = tlvdb_find(tlv, 0x6f);
|
||||||
if (!ttmp)
|
if (ttmp == NULL)
|
||||||
PrintAndLogEx(INFO, "| none |");
|
PrintAndLogEx(INFO, "| none |");
|
||||||
|
|
||||||
while (ttmp) {
|
while (ttmp) {
|
||||||
const struct tlv *tgAID = tlvdb_get_inchild(ttmp, 0x84, NULL);
|
const struct tlv *tgAID = tlvdb_get_inchild(ttmp, 0x84, NULL);
|
||||||
const struct tlv *tgName = tlvdb_get_inchild(ttmp, 0x50, NULL);
|
const struct tlv *tgName = tlvdb_get_inchild(ttmp, 0x50, NULL);
|
||||||
const struct tlv *tgPrio = tlvdb_get_inchild(ttmp, 0x87, NULL);
|
const struct tlv *tgPrio = tlvdb_get_inchild(ttmp, 0x87, NULL);
|
||||||
if (!tgAID)
|
if (!tgAID) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
PrintAndLogEx(INFO, "| %s| %s | %s|",
|
PrintAndLogEx(INFO, "| %s| %s | %s|",
|
||||||
sprint_hex_inrow_ex(tgAID->value, tgAID->len, 17),
|
sprint_hex_inrow_ex(tgAID->value, tgAID->len, 17),
|
||||||
(tgPrio) ? sprint_hex(tgPrio->value, 1) : " ",
|
(tgPrio) ? sprint_hex(tgPrio->value, 1) : " ",
|
||||||
|
|
|
@ -197,9 +197,7 @@ struct tlvdb *tlvdb_parse(const unsigned char *buf, size_t len) {
|
||||||
return &root->db;
|
return &root->db;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
tlvdb_free(&root->db);
|
tlvdb_root_free(root);
|
||||||
|
|
||||||
free(root);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,22 +206,32 @@ struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len) {
|
||||||
const unsigned char *tmp;
|
const unsigned char *tmp;
|
||||||
size_t left;
|
size_t left;
|
||||||
|
|
||||||
if (!len || !buf)
|
if (len == 0 || buf == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
root = calloc(1, sizeof(*root) + len);
|
root = calloc(1, sizeof(*root) + len);
|
||||||
|
if (root == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
root->len = len;
|
root->len = len;
|
||||||
memcpy(root->buf, buf, len);
|
memcpy(root->buf, buf, len);
|
||||||
|
|
||||||
tmp = root->buf;
|
tmp = root->buf;
|
||||||
left = len;
|
left = len;
|
||||||
|
|
||||||
if (!tlvdb_parse_one(&root->db, NULL, &tmp, &left))
|
if (tlvdb_parse_one(&root->db, NULL, &tmp, &left) == false) {
|
||||||
goto err;
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
while (left != 0) {
|
while (left != 0) {
|
||||||
struct tlvdb *db = calloc(1, sizeof(*db));
|
struct tlvdb *db = calloc(1, sizeof(*db));
|
||||||
if (!tlvdb_parse_one(db, NULL, &tmp, &left)) {
|
if (db == NULL ) {
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tlvdb_parse_one(db, NULL, &tmp, &left) == false) {
|
||||||
free(db);
|
free(db);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -234,9 +242,7 @@ struct tlvdb *tlvdb_parse_multi(const unsigned char *buf, size_t len) {
|
||||||
return &root->db;
|
return &root->db;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
tlvdb_free(&root->db);
|
tlvdb_root_free(root);
|
||||||
|
|
||||||
free(root);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,8 +319,9 @@ struct tlvdb *tlvdb_external(tlv_tag_t tag, size_t len, const unsigned char *val
|
||||||
void tlvdb_free(struct tlvdb *tlvdb) {
|
void tlvdb_free(struct tlvdb *tlvdb) {
|
||||||
struct tlvdb *next = NULL;
|
struct tlvdb *next = NULL;
|
||||||
|
|
||||||
if (!tlvdb)
|
if (tlvdb == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (; tlvdb; tlvdb = next) {
|
for (; tlvdb; tlvdb = next) {
|
||||||
next = tlvdb->next;
|
next = tlvdb->next;
|
||||||
|
@ -339,38 +346,44 @@ void tlvdb_root_free(struct tlvdb_root *root) {
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tlvdb *tlvdb_find_next(struct tlvdb *tlvdb, tlv_tag_t tag) {
|
struct tlvdb *tlvdb_find_next(struct tlvdb *tlvdb, tlv_tag_t tag) {
|
||||||
if (!tlvdb)
|
if (tlvdb == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return tlvdb_find(tlvdb->next, tag);
|
return tlvdb_find(tlvdb->next, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tlvdb *tlvdb_find(struct tlvdb *tlvdb, tlv_tag_t tag) {
|
struct tlvdb *tlvdb_find(struct tlvdb *tlvdb, tlv_tag_t tag) {
|
||||||
if (!tlvdb)
|
if (tlvdb == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (; tlvdb; tlvdb = tlvdb->next) {
|
for (; tlvdb; tlvdb = tlvdb->next) {
|
||||||
if (tlvdb->tag.tag == tag)
|
if (tlvdb->tag.tag == tag) {
|
||||||
return tlvdb;
|
return tlvdb;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tlvdb *tlvdb_find_full(struct tlvdb *tlvdb, tlv_tag_t tag) {
|
struct tlvdb *tlvdb_find_full(struct tlvdb *tlvdb, tlv_tag_t tag) {
|
||||||
if (!tlvdb)
|
if (tlvdb == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (; tlvdb; tlvdb = tlvdb->next) {
|
for (; tlvdb; tlvdb = tlvdb->next) {
|
||||||
if (tlvdb->tag.tag == tag)
|
if (tlvdb->tag.tag == tag) {
|
||||||
return tlvdb;
|
return tlvdb;
|
||||||
|
}
|
||||||
|
|
||||||
if (tlvdb->children) {
|
if (tlvdb->children) {
|
||||||
struct tlvdb *ch = tlvdb_find_full(tlvdb->children, tag);
|
struct tlvdb *ch = tlvdb_find_full(tlvdb->children, tag);
|
||||||
if (ch)
|
if (ch) {
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -391,12 +404,14 @@ 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) {
|
||||||
if (tlvdb == other)
|
if (tlvdb == other) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
while (tlvdb->next) {
|
while (tlvdb->next) {
|
||||||
if (tlvdb->next == other)
|
if (tlvdb->next == other) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tlvdb = tlvdb->next;
|
tlvdb = tlvdb->next;
|
||||||
}
|
}
|
||||||
|
@ -405,17 +420,21 @@ void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other) {
|
||||||
}
|
}
|
||||||
|
|
||||||
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_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
|
||||||
struct tlvdb *elm = tlvdb_fixed(tag, len, value);
|
struct tlvdb *elm = tlvdb_fixed(tag, len, value);
|
||||||
tlvdb_add(tlvdb, elm);
|
tlvdb_add(tlvdb, elm);
|
||||||
if (tlvdb_elm)
|
if (tlvdb_elm) {
|
||||||
*tlvdb_elm = 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)) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// replace tlv element
|
// replace tlv element
|
||||||
struct tlvdb *tnewelm = tlvdb_fixed(tag, len, value);
|
struct tlvdb *tnewelm = tlvdb_fixed(tag, len, value);
|
||||||
|
@ -434,8 +453,9 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len,
|
||||||
// elm in root
|
// elm in root
|
||||||
struct tlvdb *celm = tlvdb;
|
struct tlvdb *celm = tlvdb;
|
||||||
// elm in child list of node
|
// elm in child list of node
|
||||||
if (telm->parent && telm->parent->children)
|
if (telm->parent && telm->parent->children) {
|
||||||
celm = telm->parent->children;
|
celm = telm->parent->children;
|
||||||
|
}
|
||||||
|
|
||||||
// find previous element
|
// find previous element
|
||||||
for (; celm; celm = celm->next) {
|
for (; celm; celm = celm->next) {
|
||||||
|
@ -455,6 +475,7 @@ void tlvdb_change_or_add_node_ex(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len,
|
||||||
*tlvdb_elm = tnewelm;
|
*tlvdb_elm = tnewelm;
|
||||||
tnewelm_linked = true;
|
tnewelm_linked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tnewelm_linked) {
|
if (!tnewelm_linked) {
|
||||||
tlvdb_free(tnewelm);
|
tlvdb_free(tnewelm);
|
||||||
}
|
}
|
||||||
|
@ -470,8 +491,9 @@ void tlvdb_change_or_add_node(struct tlvdb *tlvdb, tlv_tag_t tag, size_t len, co
|
||||||
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;
|
||||||
|
|
||||||
if (!tlvdb)
|
if (tlvdb == NULL) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (; tlvdb; tlvdb = next) {
|
for (; tlvdb; tlvdb = next) {
|
||||||
next = tlvdb->next;
|
next = tlvdb->next;
|
||||||
|
@ -481,12 +503,14 @@ void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct tlvdb *tlvdb_next(const struct tlvdb *tlvdb) {
|
static const struct tlvdb *tlvdb_next(const struct tlvdb *tlvdb) {
|
||||||
if (tlvdb->children)
|
if (tlvdb->children) {
|
||||||
return tlvdb->children;
|
return tlvdb->children;
|
||||||
|
}
|
||||||
|
|
||||||
while (tlvdb) {
|
while (tlvdb) {
|
||||||
if (tlvdb->next)
|
if (tlvdb->next) {
|
||||||
return tlvdb->next;
|
return tlvdb->next;
|
||||||
|
}
|
||||||
|
|
||||||
tlvdb = tlvdb->parent;
|
tlvdb = tlvdb->parent;
|
||||||
}
|
}
|
||||||
|
@ -502,8 +526,9 @@ const struct tlv *tlvdb_get(const struct tlvdb *tlvdb, tlv_tag_t tag, const stru
|
||||||
|
|
||||||
|
|
||||||
while (tlvdb) {
|
while (tlvdb) {
|
||||||
if (tlvdb->tag.tag == tag)
|
if (tlvdb->tag.tag == tag) {
|
||||||
return &tlvdb->tag;
|
return &tlvdb->tag;
|
||||||
|
}
|
||||||
|
|
||||||
tlvdb = tlvdb_next(tlvdb);
|
tlvdb = tlvdb_next(tlvdb);
|
||||||
}
|
}
|
||||||
|
@ -570,11 +595,13 @@ bool tlv_is_constructed(const struct tlv *tlv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool tlv_equal(const struct tlv *a, const struct tlv *b) {
|
bool tlv_equal(const struct tlv *a, const struct tlv *b) {
|
||||||
if (!a && !b)
|
if (a == NULL && b == NULL) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!a || !b)
|
if (a == NULL || b == NULL) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return a->tag == b->tag && a->len == b->len && !memcmp(a->value, b->value, a->len);
|
return a->tag == b->tag && a->len == b->len && !memcmp(a->value, b->value, a->len);
|
||||||
}
|
}
|
||||||
|
@ -599,8 +626,9 @@ bool tlvdb_get_uint8(struct tlvdb *tlvRoot, tlv_tag_t tag, uint8_t *value) {
|
||||||
bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value) {
|
bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value) {
|
||||||
*value = 0;
|
*value = 0;
|
||||||
if (etlv) {
|
if (etlv) {
|
||||||
if (etlv->len == 0)
|
if (etlv->len == 0) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (etlv->len == 1) {
|
if (etlv->len == 1) {
|
||||||
*value = etlv->value[0];
|
*value = etlv->value[0];
|
||||||
|
@ -613,8 +641,9 @@ bool tlv_get_uint8(const struct tlv *etlv, uint8_t *value) {
|
||||||
bool tlv_get_int(const struct tlv *etlv, int *value) {
|
bool tlv_get_int(const struct tlv *etlv, int *value) {
|
||||||
*value = 0;
|
*value = 0;
|
||||||
if (etlv) {
|
if (etlv) {
|
||||||
if (etlv->len == 0)
|
if (etlv->len == 0) {
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (etlv->len <= 4) {
|
if (etlv->len <= 4) {
|
||||||
for (int i = 0; i < etlv->len; i++) {
|
for (int i = 0; i < etlv->len; i++) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue