- renamed sc_asn1_parse to sc_asn1_decode

- added capabilities and flags fields to struct sc_card
- added a mutex to sc_context for future use


git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@148 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
jey 2002-01-07 18:23:34 +00:00
parent 4d2599a923
commit 9197babe53
12 changed files with 101 additions and 45 deletions

View File

@ -721,3 +721,37 @@ int sc_asn1_parse_choice(struct sc_context *ctx, struct sc_asn1_struct *asn1,
{
return asn1_parse(ctx, asn1, in, len, newp, len_left, 1, 0);
}
int sc_asn1_encode(struct sc_context *ctx, const struct sc_asn1_struct *asn1,
u8 *buf, size_t bufleft, size_t *objsize_out)
{
#if 0
int r, idx = 0;
const u8 *p = buf;
const struct sc_asn1_struct *entry = asn1;
size_t total = 0, objsize;
if (ctx->debug >= 3)
debug(ctx, "called, depth %d\n", depth);
if (left < 2)
return SC_ERROR_ASN1_END_OF_CONTENTS;
for (idx = 0; asn1[idx].name != NULL; idx++) {
entry = &asn1[idx];
if (!(entry->flags & SC_ASN1_PRESENT))
continue;
r = asn1_encode_entry(ctx, entry, p, bufleft, &objsize);
if (r)
return r;
total += objsize;
p += objsize;
assert(bufleft >= objsize);
bufleft -= objsize;
}
if (objsize_out != NULL)
*objsize_out = total;
SC_FUNC_RETURN(ctx, 3, 0);
#else
return SC_ERROR_NOT_SUPPORTED;
#endif
}

View File

@ -42,10 +42,12 @@ struct sc_pkcs15_object {
/* DER tag and length parsing */
int sc_asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, size_t len, const u8 **newp, size_t *left);
int sc_asn1_parse_choice(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, size_t len, const u8 **newp, size_t *left);
int sc_asn1_decode(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, size_t len, const u8 **newp, size_t *left);
int sc_asn1_decode_choice(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, size_t len, const u8 **newp, size_t *left);
int sc_asn1_encode(struct sc_context *ctx, const struct sc_asn1_struct *asn1,
u8 *buf, size_t bufsize, size_t *obj_size);
const u8 *sc_asn1_find_tag(struct sc_context *ctx, const u8 * buf,
size_t buflen, unsigned int tag, size_t *taglen);

View File

@ -583,15 +583,10 @@ int sc_read_binary(struct sc_card *card, unsigned int idx,
assert(card != NULL && card->ops != NULL && buf != NULL);
if (card->ctx->debug >= 2)
debug(card->ctx, "sc_read_binary: %d bytes at index %d\n", count, idx);
if (count > RB_BUF_SIZE) {
if (count > RB_BUF_SIZE && !(card->caps & SC_CARD_CAP_APDU_EXT)) {
int bytes_read = 0;
unsigned char *p = buf;
if (card->ops->read_binary_large != NULL) {
r = card->ops->read_binary_large(card, idx, buf, count, flags);
SC_FUNC_RETURN(card->ctx, 2, r);
}
/* no read_binary_large support... */
r = sc_lock(card);
SC_TEST_RET(card->ctx, r, "sc_lock() failed");
while (count > 0) {
@ -617,6 +612,7 @@ int sc_read_binary(struct sc_card *card, unsigned int idx,
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
r = card->ops->read_binary(card, idx, buf, count, flags);
SC_FUNC_RETURN(card->ctx, 2, r);
#undef RB_BUF_SIZE
}
int sc_select_file(struct sc_card *card,

View File

@ -66,8 +66,10 @@ void do_log2(struct sc_context *ctx, int type, const char *file,
const char *terms[] = { "linux", "xterm", "Eterm" };
int term_count = sizeof(terms)/sizeof(terms[0]);
int left, r;
struct timeval tv;
assert(ctx != NULL);
gettimeofday(&tv, NULL);
if (ctx->use_std_output) {
switch (type) {
case SC_LOG_TYPE_ERROR:
@ -115,11 +117,6 @@ void do_log2(struct sc_context *ctx, int type, const char *file,
case SC_LOG_TYPE_ERROR:
color_pfx = "\33[01;31m";
break;
#if 0
case SC_LOG_TYPE_NORMAL:
color_pfx = "\33[01;33m";
break;
#endif
case SC_LOG_TYPE_DEBUG:
color_pfx = "\33[00;32m";
break;

View File

@ -182,6 +182,7 @@ struct sc_file {
#define SC_SEC_OPERATION_DECIPHER 0
#define SC_SEC_OPERATION_SIGN 1
struct sc_security_env {
int algorithm_ref;
struct sc_path key_file_id;
@ -189,12 +190,31 @@ struct sc_security_env {
int key_ref;
};
/*
* Card capabilities
*/
/* SC_CARD_APDU_EXT: Card can handle large (> 256 bytes) buffers in
* calls to read_binary, write_binary and update_binary; if not,
* several successive calls to the corresponding function is made. */
#define SC_CARD_CAP_APDU_EXT 0x00000001
/* SC_CARD_CAP_EMV: Card can handle operations specified in the
* EMV 4.0 standard. */
#define SC_CARD_CAP_EMV 0x00000002
/*
* Card flags
*/
/* none yet */
struct sc_card {
int cla;
struct sc_context *ctx;
SCARDHANDLE pcsc_card;
int reader;
unsigned long caps, flags;
int cla;
u8 atr[SC_MAX_ATR_SIZE];
size_t atr_len;
@ -232,14 +252,6 @@ struct sc_card_operations {
const u8 * buf, size_t count, unsigned long flags);
int (*erase_binary)(struct sc_card *card, unsigned int idx,
size_t count, unsigned long flags);
/* These may be left NULL. If not present, multiple calls
* to read_binary et al. will be made. */
int (*read_binary_large)(struct sc_card *card, unsigned int idx,
u8 * buf, size_t count, unsigned long flags);
int (*write_binary_large)(struct sc_card *card, unsigned int idx,
const u8 * buf, size_t count, unsigned long flags);
int (*update_binary_large)(struct sc_card *card, unsigned int idx,
const u8 * buf, size_t count, unsigned long flags);
int (*read_record)(struct sc_card *card, unsigned int rec_nr,
u8 * buf, size_t count, unsigned long flags);
@ -251,7 +263,13 @@ struct sc_card_operations {
int (*get_response)(struct sc_card *card, u8 * buf, size_t count);
int (*get_challenge)(struct sc_card *card, u8 * buf, size_t count);
/* ISO 7816-8 */
/*
* ISO 7816-8 functions
*/
/* verify: Verifies reference data identified by <ref_qualifier>.
* If <tries_left> is not NULL, number of verify tries left is
* saved in case of verification failure.
int (*verify)(struct sc_card *card, int ref_qualifier,
const u8 *data, size_t data_len, int *tries_left);
@ -266,8 +284,13 @@ struct sc_card_operations {
* card. If se_num <= 0, the environment will not be stored. */
int (*set_security_env)(struct sc_card *card,
const struct sc_security_env *env, int se_num);
/* decipher: Engages the deciphering operation. Card will use the
* security environment set in a call to set_security_env or
* restore_security_env. */
int (*decipher)(struct sc_card *card, const u8 * crgram,
size_t crgram_len, u8 * out, size_t outlen);
/* compute_signature: Generates a digital signature on the card. Similiar
* to the function decipher. */
int (*compute_signature)(struct sc_card *card, const u8 * data,
size_t data_len, u8 * out, size_t outlen);
int (*change_reference_data)(struct sc_card *card, int ref_qualifier,
@ -293,7 +316,8 @@ struct sc_context {
int debug;
int use_std_output, use_cache;
const struct sc_card_driver *card_drivers[SC_MAX_CARD_DRIVERS+1];
const struct sc_card_driver *card_drivers[SC_MAX_CARD_DRIVERS+1];
pthread_mutex_t mutex;
};
struct sc_apdu {
@ -373,7 +397,7 @@ inline int sc_file_valid(const struct sc_file *file);
void sc_format_path(const char *path_in, struct sc_path *path_out);
int sc_hex_to_bin(const char *in, u8 *out, size_t *outlen);
/* Possibly only on Setec cards */
/* Possibly only valid on Setec cards */
int sc_list_files(struct sc_card *card, u8 * buf, int buflen);
const char *sc_strerror(int error);

View File

@ -48,7 +48,7 @@ static int parse_rsa_pubkey(struct sc_context *ctx, struct sc_pkcs15_rsa_pubkey
error(ctx, "RSA public key not found\n");
return SC_ERROR_INVALID_ASN1_OBJECT;
}
r = sc_asn1_parse(ctx, asn1_rsa_pubkey, obj, objlen, NULL, NULL);
r = sc_asn1_decode(ctx, asn1_rsa_pubkey, obj, objlen, NULL, NULL);
SC_TEST_RET(ctx, r, "ASN.1 parsing failed");
return 0;
@ -69,7 +69,7 @@ static int parse_algorithm_id(struct sc_context *ctx, void *arg, const u8 *obj,
};
int r;
r = sc_asn1_parse(ctx, asn1_alg_id, obj, objlen, NULL, NULL);
r = sc_asn1_decode(ctx, asn1_alg_id, obj, objlen, NULL, NULL);
SC_TEST_RET(ctx, r, "ASN.1 parsing failed");
return 0;
@ -117,7 +117,7 @@ static int parse_x509_cert(struct sc_context *ctx, const u8 *buf, size_t buflen,
return SC_ERROR_INVALID_ASN1_OBJECT;
}
cert->data_len = objlen + (obj - buf);
r = sc_asn1_parse(ctx, asn1_cert, obj, objlen, NULL, NULL);
r = sc_asn1_decode(ctx, asn1_cert, obj, objlen, NULL, NULL);
SC_TEST_RET(ctx, r, "ASN.1 parsing failed");
cert->version++;
@ -311,7 +311,7 @@ static int parse_x509_cert_info(struct sc_context *ctx,
{ NULL }
};
r = sc_asn1_parse(ctx, asn1_cert, *buf, *buflen, buf, buflen);
r = sc_asn1_decode(ctx, asn1_cert, *buf, *buflen, buf, buflen);
return r;
}

View File

@ -65,7 +65,7 @@ static int parse_pin_info(struct sc_context *ctx,
memset(pin, 0, sizeof(*pin));
r = sc_asn1_parse(ctx, asn1_pin, *buf, *buflen, buf, buflen);
r = sc_asn1_decode(ctx, asn1_pin, *buf, *buflen, buf, buflen);
if (r == 0)
pin->magic = SC_PKCS15_PIN_MAGIC;

View File

@ -87,7 +87,7 @@ static int parse_rsa_prkey_info(struct sc_context *ctx,
prkey->key_reference = -1;
prkey->native = 1;
r = sc_asn1_parse(ctx, asn1_prkey, *buf, *buflen, buf, buflen);
r = sc_asn1_decode(ctx, asn1_prkey, *buf, *buflen, buf, buflen);
return r;
}

View File

@ -81,7 +81,7 @@ void parse_tokeninfo(struct sc_pkcs15_card *card, const u8 * buf, size_t buflen)
error(card->card->ctx, "invalid EF(TokenInfo)\n");
goto err;
}
r = sc_asn1_parse(card->card->ctx, asn1_tokeninfo, buf, buflen, NULL, NULL);
r = sc_asn1_decode(card->card->ctx, asn1_tokeninfo, buf, buflen, NULL, NULL);
if (r) {
error(card->card->ctx, "ASN.1 parsing failed: %s\n", sc_strerror(r));
goto err;
@ -139,7 +139,7 @@ static int parse_dir(const u8 * buf, size_t buflen, struct sc_pkcs15_card *card)
error(card->card->ctx, "No [APPLICATION 1] tag in EF(DIR)\n");
return -1;
}
r = sc_asn1_parse(card->card->ctx, asn1_dir, buf, buflen, NULL, NULL);
r = sc_asn1_decode(card->card->ctx, asn1_dir, buf, buflen, NULL, NULL);
if (r) {
error(card->card->ctx, "EF(DIR) parsing failed: %s\n",
sc_strerror(r));
@ -180,7 +180,7 @@ static int parse_odf(const u8 * buf, int buflen, struct sc_pkcs15_card *card)
};
while (left > 0) {
r = sc_asn1_parse_choice(card->card->ctx, asn1_odf, p, left, &p, &left);
r = sc_asn1_decode_choice(card->card->ctx, asn1_odf, p, left, &p, &left);
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
break;
if (r < 0)

View File

@ -42,10 +42,12 @@ struct sc_pkcs15_object {
/* DER tag and length parsing */
int sc_asn1_parse(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, size_t len, const u8 **newp, size_t *left);
int sc_asn1_parse_choice(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, size_t len, const u8 **newp, size_t *left);
int sc_asn1_decode(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, size_t len, const u8 **newp, size_t *left);
int sc_asn1_decode_choice(struct sc_context *ctx, struct sc_asn1_struct *asn1,
const u8 *in, size_t len, const u8 **newp, size_t *left);
int sc_asn1_encode(struct sc_context *ctx, const struct sc_asn1_struct *asn1,
u8 *buf, size_t bufsize, size_t *obj_size);
const u8 *sc_asn1_find_tag(struct sc_context *ctx, const u8 * buf,
size_t buflen, unsigned int tag, size_t *taglen);

View File

@ -172,6 +172,7 @@ int sc_establish_context(struct sc_context **ctx_out)
break;
} while (p < (reader_buf + reader_buf_size - 1));
free(reader_buf);
pthread_mutex_init(&ctx->mutex, NULL);
for (i = 0; i < SC_MAX_CARD_DRIVERS+1; i++)
ctx->card_drivers[i] = NULL;
i = 0;

View File

@ -616,10 +616,10 @@ int send_apdu(void)
struct sc_apdu apdu;
u8 buf[MAX_BUFFER_SIZE], sbuf[MAX_BUFFER_SIZE],
rbuf[MAX_BUFFER_SIZE], *p = buf;
size_t len = sizeof(buf), len0, r;
size_t len, len0 = sizeof(buf), r;
sc_hex_to_bin(opt_apdu, buf, &len0);
if (len < 4) {
if (len0 < 4) {
fprintf(stderr, "APDU too short (must be at least 4 bytes).\n");
return 2;
}
@ -639,12 +639,12 @@ int send_apdu(void)
memcpy(sbuf, p, apdu.lc);
apdu.data = sbuf;
apdu.datalen = apdu.lc;
len -= apdu.lc;
if (len < 0) {
if (len < apdu.lc) {
fprintf(stderr, "APDU too short (need %d bytes).\n",
-len);
apdu.lc-len);
return 2;
}
len -= apdu.lc;
if (len) {
apdu.le = *p++;
len--;