- 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:
parent
4d2599a923
commit
9197babe53
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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--;
|
||||
|
|
Loading…
Reference in New Issue