Skip to content

Commit

Permalink
libopensc: APDU 'allocate & copy'and 'free' procedures
Browse files Browse the repository at this point in the history
  • Loading branch information
viktorTarasov committed Jan 6, 2013
1 parent 8d7c773 commit 6a4de6d
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 18 deletions.
62 changes: 60 additions & 2 deletions src/libopensc/card.c
Expand Up @@ -61,6 +61,55 @@ void sc_format_apdu(sc_card_t *card, sc_apdu_t *apdu,
apdu->p2 = (u8) p2;
}

struct sc_apdu *
sc_allocate_apdu(struct sc_apdu *copy_from, unsigned flags)
{
struct sc_apdu *apdu = NULL;

assert(copy_from != NULL);
apdu = (struct sc_apdu *)malloc(sizeof(struct sc_apdu));
if (!copy_from || !apdu)
return apdu;
memcpy(apdu, copy_from, sizeof(struct sc_apdu));
apdu->data = apdu->resp = NULL;
apdu->next = NULL;
apdu->datalen = apdu->resplen = 0;
apdu->allocation_flags = SC_APDU_ALLOCATE_FLAG;

if ((flags & SC_APDU_ALLOCATE_FLAG_DATA) && copy_from->data && copy_from->datalen) {
apdu->data = malloc(copy_from->datalen);
if (!apdu->data)
return NULL;
memcpy(apdu->data, copy_from->data, copy_from->datalen);
apdu->datalen = copy_from->datalen;
apdu->allocation_flags |= SC_APDU_ALLOCATE_FLAG_DATA;
}

if ((flags & SC_APDU_ALLOCATE_FLAG_RESP) && copy_from->resp && copy_from->resplen) {
apdu->resp = malloc(copy_from->resplen);
if (!apdu->resp)
return NULL;
memcpy(apdu->resp, copy_from->resp, copy_from->resplen);
apdu->resplen = copy_from->resplen;
apdu->allocation_flags |= SC_APDU_ALLOCATE_FLAG_RESP;
}
return apdu;
}

void
sc_free_apdu(struct sc_apdu *apdu)
{
if (!apdu)
return;
if (apdu->allocation_flags & SC_APDU_ALLOCATE_FLAG_DATA)
free (apdu->data);
if (apdu->allocation_flags & SC_APDU_ALLOCATE_FLAG_RESP)
free (apdu->resp);
if (apdu->allocation_flags & SC_APDU_ALLOCATE_FLAG)
free (apdu);
}


static sc_card_t * sc_card_new(sc_context_t *ctx)
{
sc_card_t *card;
Expand Down Expand Up @@ -968,32 +1017,40 @@ int _sc_add_atr(sc_context_t *ctx, struct sc_card_driver *driver, struct sc_atr_
if (!map)
return SC_ERROR_OUT_OF_MEMORY;
driver->atr_map = map;

dst = &driver->atr_map[driver->natrs++];
memset(dst, 0, sizeof(*dst));
memset(&driver->atr_map[driver->natrs], 0, sizeof(struct sc_atr_table));
dst->atr = strdup(src->atr);
if (!dst->atr)
return SC_ERROR_OUT_OF_MEMORY;

if (src->atrmask) {
dst->atrmask = strdup(src->atrmask);
if (!dst->atrmask)
return SC_ERROR_OUT_OF_MEMORY;
} else {
}
else {
dst->atrmask = NULL;
}

if (src->name) {
dst->name = strdup(src->name);
if (!dst->name)
return SC_ERROR_OUT_OF_MEMORY;
} else {
}
else {
dst->name = NULL;
}

dst->type = src->type;
dst->flags = src->flags;
dst->card_atr = src->card_atr;

return SC_SUCCESS;
}


int _sc_free_atr(sc_context_t *ctx, struct sc_card_driver *driver)
{
unsigned int i;
Expand Down Expand Up @@ -1197,6 +1254,7 @@ sc_card_sm_check(struct sc_card *card)
int rv, ii;

SC_FUNC_CALLED(ctx, SC_LOG_DEBUG_NORMAL);
sc_log(ctx, "card->sm_ctx.ops.open %p", card->sm_ctx.ops.open);

/* get the name of card specific SM configuration section */
atrblock = _sc_match_atr_block(ctx, card->driver, &card->atr);
Expand Down
3 changes: 3 additions & 0 deletions src/libopensc/libopensc.exports
Expand Up @@ -99,6 +99,8 @@ sc_file_set_sec_attr
sc_file_set_type_attr
sc_file_valid
sc_format_apdu
sc_allocate_apdu
sc_free_apdu
sc_bytes2apdu
sc_format_asn1_entry
sc_format_oid
Expand Down Expand Up @@ -300,6 +302,7 @@ sc_pkcs15init_verify_secret
sc_pkcs15init_sanity_check
sc_pkcs15init_finalize_profile
sc_card_find_rsa_alg
sc_check_apdu
sc_print_cache
sc_find_app
sc_remote_data_init
Expand Down
12 changes: 8 additions & 4 deletions src/libopensc/opensc.h
Expand Up @@ -166,7 +166,7 @@ typedef struct sc_security_env {

unsigned int algorithm_ref;
struct sc_path file_ref;
u8 key_ref[8];
unsigned char key_ref[8];
size_t key_ref_len;

struct sc_supported_algo_info supported_algos[SC_MAX_SUPPORTED_ALGORITHMS];
Expand Down Expand Up @@ -719,10 +719,14 @@ typedef struct sc_context {
* @param apdu sc_apdu_t object of the APDU to be send
* @return SC_SUCCESS on succcess and an error code otherwise
*/
int sc_transmit_apdu(struct sc_card *card, sc_apdu_t *apdu);
int sc_transmit_apdu(struct sc_card *, struct sc_apdu *);

void sc_format_apdu(struct sc_card *card, sc_apdu_t *apdu, int cse, int ins,
int p1, int p2);
void sc_format_apdu(struct sc_card *, struct sc_apdu *, int, int, int, int);

int sc_check_apdu(struct sc_card *, const struct sc_apdu *);

struct sc_apdu *sc_allocate_apdu(struct sc_apdu *, unsigned);
void sc_free_apdu(struct sc_apdu *);

/** Transforms an APDU from binary to its @c sc_apdu_t representation
* @param ctx sc_context_t object (used for logging)
Expand Down
32 changes: 20 additions & 12 deletions src/libopensc/types.h
Expand Up @@ -174,8 +174,11 @@ struct sc_crt {
#define SC_AC_OP_WRITE 24
#define SC_AC_OP_RESIZE 25
#define SC_AC_OP_GENERATE 26
#define SC_AC_OP_CREATE_EF 27
#define SC_AC_OP_CREATE_DF 28
#define SC_AC_OP_ADMIN 29
/* If you add more OPs here, make sure you increase SC_MAX_AC_OPS*/
#define SC_MAX_AC_OPS 27
#define SC_MAX_AC_OPS 30

/* the use of SC_AC_OP_ERASE is deprecated, SC_AC_OP_DELETE should be used
* instead */
Expand Down Expand Up @@ -263,18 +266,23 @@ typedef struct sc_file {
*/
#define SC_APDU_FLAGS_NO_RETRY_WL 0x00000004UL

#define SC_APDU_ALLOCATE_FLAG 0x01
#define SC_APDU_ALLOCATE_FLAG_DATA 0x02
#define SC_APDU_ALLOCATE_FLAG_RESP 0x04

typedef struct sc_apdu {
int cse; /* APDU case */
u8 cla, ins, p1, p2; /* CLA, INS, P1 and P2 bytes */
size_t lc, le; /* Lc and Le bytes */
const u8 *data; /* C-APDU data */
size_t datalen; /* length of data in C-APDU */
u8 *resp; /* R-APDU data buffer */
size_t resplen; /* in: size of R-APDU buffer,
* out: length of data returned in R-APDU */
u8 control; /* Set if APDU should go to the reader */

unsigned int sw1, sw2; /* Status words returned in R-APDU */
int cse; /* APDU case */
unsigned char cla, ins, p1, p2; /* CLA, INS, P1 and P2 bytes */
size_t lc, le; /* Lc and Le bytes */
unsigned char *data; /* C-APDU data */
size_t datalen; /* length of data in C-APDU */
unsigned char *resp; /* R-APDU data buffer */
size_t resplen; /* in: size of R-APDU buffer,
* out: length of data returned in R-APDU */
unsigned char control; /* Set if APDU should go to the reader */
unsigned allocation_flags; /* APDU allocation flags */

unsigned int sw1, sw2; /* Status words returned in R-APDU */
unsigned char mac[8];
size_t mac_len;

Expand Down

0 comments on commit 6a4de6d

Please sign in to comment.