Changed ASN1 calls for easier calls.
Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
caddf87c23
commit
f88e786c04
4 changed files with 82 additions and 35 deletions
55
src/asn1.c
55
src/asn1.c
|
|
@ -15,8 +15,40 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "pico_keys.h"
|
||||
#include "asn1.h"
|
||||
|
||||
int asn1_ctx_init(uint8_t *data, uint16_t len, asn1_ctx_t *ctx) {
|
||||
if (!ctx) {
|
||||
return CCID_ERR_NULL_PARAM;
|
||||
}
|
||||
ctx->data = data;
|
||||
ctx->len = 0;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
int asn1_ctx_clear(asn1_ctx_t *ctx) {
|
||||
ctx->data = NULL;
|
||||
ctx->len = 0;
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
uint16_t asn1_len(asn1_ctx_t *ctx) {
|
||||
if (ctx->data && ctx->len > 0) {
|
||||
return ctx->len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t asn1_get_uint(asn1_ctx_t *ctx) {
|
||||
uint32_t d = ctx->data[0];
|
||||
for (uint8_t lt = 1; lt < ctx->len; lt++) {
|
||||
d <<= 8;
|
||||
d |= ctx->data[lt];
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
uint16_t asn1_len_tag(uint16_t tag, uint16_t len) {
|
||||
uint16_t ret = 1 + format_tlv_len(len, NULL) + len;
|
||||
if (tag > 0x00ff) {
|
||||
|
|
@ -47,8 +79,7 @@ uint8_t format_tlv_len(uint16_t len, uint8_t *out) {
|
|||
return 3;
|
||||
}
|
||||
|
||||
int walk_tlv(const uint8_t *cdata,
|
||||
uint16_t cdata_len,
|
||||
int walk_tlv(const asn1_ctx_t *ctxi,
|
||||
uint8_t **p,
|
||||
uint16_t *tag,
|
||||
uint16_t *tag_len,
|
||||
|
|
@ -57,9 +88,9 @@ int walk_tlv(const uint8_t *cdata,
|
|||
return 0;
|
||||
}
|
||||
if (!*p) {
|
||||
*p = (uint8_t *) cdata;
|
||||
*p = (uint8_t *) ctxi->data;
|
||||
}
|
||||
if (*p - cdata >= cdata_len) {
|
||||
if (*p - ctxi->data >= ctxi->len) {
|
||||
return 0;
|
||||
}
|
||||
uint16_t tg = 0x0;
|
||||
|
|
@ -90,22 +121,18 @@ int walk_tlv(const uint8_t *cdata,
|
|||
return 1;
|
||||
}
|
||||
|
||||
bool asn1_find_tag(const uint8_t *data,
|
||||
uint16_t data_len,
|
||||
bool asn1_find_tag(const asn1_ctx_t *ctxi,
|
||||
uint16_t itag,
|
||||
uint16_t *tag_len,
|
||||
uint8_t **tag_data) {
|
||||
asn1_ctx_t *ctxo) {
|
||||
uint16_t tag = 0x0;
|
||||
uint8_t *p = NULL;
|
||||
uint8_t *tdata = NULL;
|
||||
uint16_t tlen = 0;
|
||||
while (walk_tlv(data, data_len, &p, &tag, &tlen, &tdata)) {
|
||||
while (walk_tlv(ctxi, &p, &tag, &tlen, &tdata)) {
|
||||
if (itag == tag) {
|
||||
if (tag_data != NULL) {
|
||||
*tag_data = tdata;
|
||||
}
|
||||
if (tag_len != NULL) {
|
||||
*tag_len = tlen;
|
||||
if (ctxo != NULL) {
|
||||
ctxo->data = tdata;
|
||||
ctxo->len = tlen;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
19
src/asn1.h
19
src/asn1.h
|
|
@ -26,18 +26,25 @@
|
|||
#include <stdbool.h>
|
||||
#endif
|
||||
|
||||
extern int walk_tlv(const uint8_t *cdata,
|
||||
uint16_t cdata_len,
|
||||
typedef struct asn1_ctx {
|
||||
uint8_t *data;
|
||||
uint16_t len;
|
||||
} asn1_ctx_t;
|
||||
|
||||
extern int asn1_ctx_init(uint8_t *, uint16_t, asn1_ctx_t *);
|
||||
extern int asn1_ctx_clear(asn1_ctx_t *ctx);
|
||||
extern uint16_t asn1_len(asn1_ctx_t *ctx);
|
||||
extern uint32_t asn1_get_uint(asn1_ctx_t *ctx);
|
||||
|
||||
extern int walk_tlv(const asn1_ctx_t *ctxi,
|
||||
uint8_t **p,
|
||||
uint16_t *tag,
|
||||
uint16_t *tag_len,
|
||||
uint8_t **data);
|
||||
extern uint8_t format_tlv_len(uint16_t len, uint8_t *out);
|
||||
extern bool asn1_find_tag(const uint8_t *data,
|
||||
uint16_t data_len,
|
||||
extern bool asn1_find_tag(const asn1_ctx_t *ctxi,
|
||||
uint16_t itag,
|
||||
uint16_t *tag_len,
|
||||
uint8_t **tag_data);
|
||||
asn1_ctx_t *ctxo);
|
||||
extern uint16_t asn1_len_tag(uint16_t tag, uint16_t len);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
13
src/eac.c
13
src/eac.c
|
|
@ -113,7 +113,10 @@ int sm_unwrap() {
|
|||
uint16_t tag = 0x0;
|
||||
uint8_t *tag_data = NULL, *p = NULL;
|
||||
uint16_t tag_len = 0;
|
||||
while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) {
|
||||
asn1_ctx_t ctxi;
|
||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data))
|
||||
{
|
||||
if (tag == 0x87 || tag == 0x85) {
|
||||
body = tag_data;
|
||||
body_size = tag_len;
|
||||
|
|
@ -209,7 +212,9 @@ uint16_t sm_get_le() {
|
|||
uint16_t tag = 0x0;
|
||||
uint8_t *tag_data = NULL, *p = NULL;
|
||||
uint16_t tag_len = 0;
|
||||
while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) {
|
||||
asn1_ctx_t ctxi;
|
||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) {
|
||||
if (tag == 0x97) {
|
||||
uint16_t le = 0;
|
||||
for (uint16_t t = 1; t <= tag_len; t++) {
|
||||
|
|
@ -266,7 +271,9 @@ int sm_verify() {
|
|||
uint16_t tag = 0x0;
|
||||
uint8_t *tag_data = NULL, *p = NULL;
|
||||
uint16_t tag_len = 0;
|
||||
while (walk_tlv(apdu.data, (uint16_t)apdu.nc, &p, &tag, &tag_len, &tag_data)) {
|
||||
asn1_ctx_t ctxi;
|
||||
asn1_ctx_init(apdu.data, (uint16_t)apdu.nc, &ctxi);
|
||||
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) {
|
||||
if (tag & 0x1) {
|
||||
input[input_len++] = (uint8_t)tag;
|
||||
uint8_t tlen = format_tlv_len(tag_len, input + input_len);
|
||||
|
|
|
|||
|
|
@ -358,9 +358,11 @@ uint16_t meta_find(uint16_t fid, uint8_t **out) {
|
|||
return 0;
|
||||
}
|
||||
uint16_t tag = 0x0;
|
||||
uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef);
|
||||
uint16_t tag_len = 0, data_len = file_get_size(ef);
|
||||
while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) {
|
||||
uint8_t *tag_data = NULL, *p = NULL;
|
||||
uint16_t tag_len = 0;
|
||||
asn1_ctx_t ctxi;
|
||||
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
||||
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) {
|
||||
if (tag_len < 2) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -380,27 +382,29 @@ int meta_delete(uint16_t fid) {
|
|||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
}
|
||||
uint16_t tag = 0x0;
|
||||
uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef);
|
||||
uint16_t tag_len = 0, data_len = file_get_size(ef);
|
||||
uint8_t *tag_data = NULL, *p = NULL;
|
||||
uint16_t tag_len = 0;
|
||||
uint8_t *fdata = NULL;
|
||||
while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) {
|
||||
asn1_ctx_t ctxi;
|
||||
asn1_ctx_init(file_get_data(ef), file_get_size(ef), &ctxi);
|
||||
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) {
|
||||
uint8_t *tpos = p - tag_len - format_tlv_len(tag_len, NULL) - 1;
|
||||
if (tag_len < 2) {
|
||||
continue;
|
||||
}
|
||||
uint16_t cfid = (tag_data[0] << 8 | tag_data[1]);
|
||||
if (cfid == fid) {
|
||||
uint16_t new_len = data_len - 1 - tag_len - format_tlv_len(tag_len, NULL);
|
||||
uint16_t new_len = ctxi.len - 1 - tag_len - format_tlv_len(tag_len, NULL);
|
||||
if (new_len == 0) {
|
||||
flash_clear_file(ef);
|
||||
}
|
||||
else {
|
||||
fdata = (uint8_t *) calloc(1, new_len);
|
||||
if (tpos > data) {
|
||||
memcpy(fdata, data, tpos - data);
|
||||
if (tpos > ctxi.data) {
|
||||
memcpy(fdata, ctxi.data, tpos - ctxi.data);
|
||||
}
|
||||
if (data + data_len > p) {
|
||||
memcpy(fdata + (tpos - data), p, data + data_len - p);
|
||||
if (ctxi.data + ctxi.len > p) {
|
||||
memcpy(fdata + (tpos - ctxi.data), p, ctxi.data + ctxi.len - p);
|
||||
}
|
||||
int r = flash_write_data_to_file(ef, fdata, new_len);
|
||||
free(fdata);
|
||||
|
|
@ -426,7 +430,9 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
|||
uint16_t tag = 0x0;
|
||||
uint8_t *tag_data = NULL, *p = NULL;
|
||||
uint16_t tag_len = 0;
|
||||
while (walk_tlv(fdata, ef_size, &p, &tag, &tag_len, &tag_data)) {
|
||||
asn1_ctx_t ctxi;
|
||||
asn1_ctx_init(fdata, ef_size, &ctxi);
|
||||
while (walk_tlv(&ctxi, &p, &tag, &tag_len, &tag_data)) {
|
||||
if (tag_len < 2) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue