Add meta functions for manipulating meta data.
Added meta_add(), meta_delete() and meta_find(). It conveys this meta data throught tag A5 of FCP. Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
parent
1a58422cd8
commit
6c90ce3361
2 changed files with 87 additions and 17 deletions
|
|
@ -23,6 +23,7 @@
|
|||
extern const uintptr_t end_data_pool;
|
||||
extern const uintptr_t start_data_pool;
|
||||
extern int flash_write_data_to_file(file_t *file, const uint8_t *data, uint16_t len);
|
||||
extern int flash_write_data_to_file_offset(file_t *file, const uint8_t *data, uint16_t len, uint16_t offset);
|
||||
extern int flash_program_halfword (uintptr_t addr, uint16_t data);
|
||||
extern int flash_program_word (uintptr_t addr, uint32_t data);
|
||||
extern int flash_program_uintptr (uintptr_t addr, uintptr_t data);
|
||||
|
|
@ -84,6 +85,13 @@ void process_fci(const file_t *pe) {
|
|||
}
|
||||
memcpy(res_APDU+res_APDU_size, "\x8A\x01\x05", 3); //life-cycle (5 -> activated)
|
||||
res_APDU_size += 3;
|
||||
uint8_t meta_size = meta_find(pe->fid, res_APDU+res_APDU_size+3, 256);
|
||||
if (meta_size) {
|
||||
res_APDU[res_APDU_size++] = 0xA5;
|
||||
res_APDU[res_APDU_size++] = 0x81;
|
||||
res_APDU[res_APDU_size++] = meta_size;
|
||||
res_APDU_size += meta_size;
|
||||
}
|
||||
res_APDU[1] = res_APDU_size-2;
|
||||
res_APDU[3] = res_APDU_size-4;
|
||||
}
|
||||
|
|
@ -184,15 +192,6 @@ bool authenticate_action(const file_t *ef, uint8_t op) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void initialize_chain(file_chain_t **chain) {
|
||||
file_chain_t *next;
|
||||
for (file_chain_t *f = *chain; f; f = next) {
|
||||
next = f->next;
|
||||
free(f);
|
||||
}
|
||||
*chain = NULL;
|
||||
}
|
||||
|
||||
void initialize_flash(bool hard) {
|
||||
if (hard) {
|
||||
const uint8_t empty[8] = { 0 };
|
||||
|
|
@ -300,3 +299,77 @@ file_t *file_new(uint16_t fid) {
|
|||
//memset((uint8_t *)f->acl, 0x90, sizeof(f->acl));
|
||||
return f;
|
||||
}
|
||||
int meta_find(uint16_t fid, uint8_t *out, size_t out_len) {
|
||||
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
|
||||
if (!ef)
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
uint8_t tag = 0x0, *tag_data = NULL, *p = NULL, *data = file_get_data(ef);
|
||||
size_t tag_len = 0, data_len = file_get_size(ef);
|
||||
while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) {
|
||||
if (tag_len < 2)
|
||||
continue;
|
||||
uint16_t cfid = (tag_data[0] << 8 | tag_data[1]);
|
||||
if (cfid == fid) {
|
||||
if (out) {
|
||||
if (out_len < tag_len-2)
|
||||
return CCID_ERR_NO_MEMORY;
|
||||
memcpy(out, tag_data+2, tag_len-2);
|
||||
}
|
||||
return tag_len-2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
int meta_delete(uint16_t fid) {
|
||||
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
|
||||
if (!ef)
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
uint8_t tag = 0x0, *tag_data = NULL, *p = NULL, *data = file_get_data(ef);
|
||||
size_t tag_len = 0, data_len = file_get_size(ef);
|
||||
uint8_t *fdata = NULL;
|
||||
while (walk_tlv(data, data_len, &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) {
|
||||
size_t new_len = data_len-1-tag_len-format_tlv_len(tag_len, NULL);
|
||||
fdata = (uint8_t *)calloc(1, new_len);
|
||||
if (tpos > data) {
|
||||
memcpy(fdata, data, tpos-data);
|
||||
}
|
||||
if (data+data_len > p) {
|
||||
memcpy(fdata+(tpos-data), p, data+data_len-p);
|
||||
}
|
||||
int r = flash_write_data_to_file(ef, fdata, new_len);
|
||||
free(fdata);
|
||||
if (r != CCID_OK)
|
||||
return CCID_EXEC_ERROR;
|
||||
low_flash_available();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return CCID_OK;
|
||||
}
|
||||
int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
|
||||
int r;
|
||||
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
|
||||
if (!ef)
|
||||
return CCID_ERR_FILE_NOT_FOUND;
|
||||
if ((r = meta_delete(fid)) != CCID_OK)
|
||||
return r;
|
||||
size_t fdata_len = 1+format_tlv_len(len+2, NULL)+len+2;
|
||||
uint8_t *fdata = (uint8_t *)calloc(1, fdata_len), *f = fdata;
|
||||
*f++ = fid & 0xff;
|
||||
f += format_tlv_len(len, f);
|
||||
*f++ = fid >> 8;
|
||||
*f++ = fid & 0xff;
|
||||
memcpy(f, data, len);
|
||||
r = flash_write_data_to_file(ef, fdata, fdata_len);
|
||||
free(fdata);
|
||||
if (r != CCID_OK)
|
||||
return CCID_EXEC_ERROR;
|
||||
low_flash_available();
|
||||
return CCID_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@
|
|||
#define EF_AODFS 0x6043
|
||||
#define EF_DODFS 0x6044
|
||||
#define EF_SKDFS 0x6045
|
||||
#define EF_META 0xE010
|
||||
|
||||
#define MAX_DEPTH 4
|
||||
|
||||
|
|
@ -73,12 +74,6 @@ typedef struct file
|
|||
const uint8_t acl[7];
|
||||
} __attribute__((packed)) file_t;
|
||||
|
||||
typedef struct file_chain
|
||||
{
|
||||
file_t *file;
|
||||
struct file_chain *next;
|
||||
} file_chain_t;
|
||||
|
||||
extern file_t *currentEF;
|
||||
extern file_t *currentDF;
|
||||
extern const file_t *selected_applet;
|
||||
|
|
@ -116,9 +111,11 @@ extern file_t dynamic_file[];
|
|||
extern file_t *search_dynamic_file(uint16_t);
|
||||
extern int delete_dynamic_file(file_t *f);
|
||||
|
||||
extern file_chain_t *add_file_to_chain(file_t *file, file_chain_t **chain);
|
||||
extern file_t *search_file_chain(uint16_t fid, file_chain_t *chain);
|
||||
extern bool isUserAuthenticated;
|
||||
|
||||
extern int meta_find(uint16_t, uint8_t *out, size_t out_len);
|
||||
extern int meta_delete(uint16_t fid);
|
||||
extern int meta_add(uint16_t fid, const uint8_t *data, uint16_t len);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue