Implemented the get_response card operation, is now explicitely called by sc_transmit_apdu()

git-svn-id: https://www.opensc-project.org/svnp/opensc/trunk@1246 c6295689-39f2-0310-b995-f0e70906c6a9
This commit is contained in:
sth 2003-07-10 11:38:02 +00:00
parent 1b988af695
commit 4737789ede
3 changed files with 34 additions and 34 deletions

View File

@ -213,9 +213,7 @@ int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
}
}
if (apdu->sw1 == 0x61 && apdu->resplen == 0) {
struct sc_apdu rspapdu;
unsigned int le;
u8 rsp[SC_MAX_APDU_BUFFER_SIZE];
if (orig_resplen == 0) {
apdu->sw1 = 0x90; /* FIXME: should we do this? */
@ -226,39 +224,13 @@ int sc_transmit_apdu(struct sc_card *card, struct sc_apdu *apdu)
le = apdu->sw2? (size_t) apdu->sw2 : 256;
sc_format_apdu(card, &rspapdu, SC_APDU_CASE_2_SHORT,
0xC0, 0, 0);
rspapdu.le = le;
rspapdu.resp = rsp;
rspapdu.resplen = le;
r = sc_transceive(card, &rspapdu);
if (r != 0) {
error(card->ctx, "error while getting response: %s\n",
sc_strerror(r));
if (card->ops->get_response == NULL) {
sc_unlock(card);
return r;
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_NOT_SUPPORTED);
}
if (card->ctx->debug >= 5) {
char buf[2048];
buf[0] = 0;
if (rspapdu.resplen) {
sc_hex_dump(card->ctx, rspapdu.resp,
rspapdu.resplen,
buf, sizeof(buf));
}
debug(card->ctx, "Response %d bytes (SW1=%02X SW2=%02X)\n%s",
rspapdu.resplen, rspapdu.sw1, rspapdu.sw2, buf);
}
if (rspapdu.resplen) {
size_t c = rspapdu.resplen;
if (c > orig_resplen)
c = orig_resplen;
memcpy(apdu->resp, rspapdu.resp, c);
apdu->resplen = c;
}
apdu->sw1 = rspapdu.sw1;
apdu->sw2 = rspapdu.sw2;
r = card->ops->get_response(card, apdu, le);
sc_unlock(card);
return r;
}
sc_unlock(card);
return 0;

View File

@ -557,6 +557,33 @@ static int iso7816_create_file(struct sc_card *card, struct sc_file *file)
return sc_check_sw(card, apdu.sw1, apdu.sw2);
}
static int iso7816_get_response(struct sc_card *card, sc_apdu_t *orig_apdu, size_t count)
{
struct sc_apdu apdu;
u8 recvbuf[SC_MAX_APDU_BUFFER_SIZE];
int r;
sc_format_apdu(card, &apdu, SC_APDU_CASE_2_SHORT, 0xC0, 0x00, 0x00);
apdu.le = count;
apdu.resplen = count;
apdu.resp = orig_apdu->resp;
r = sc_transmit_apdu(card, &apdu);
SC_TEST_RET(card->ctx, r, "APDU transmit failed");
if (apdu.resplen == 0)
SC_FUNC_RETURN(card->ctx, 2, sc_check_sw(card, apdu.sw1, apdu.sw2));
if (apdu.resplen != count) {
SC_FUNC_RETURN(card->ctx, 2, SC_ERROR_WRONG_LENGTH);
}
orig_apdu->resplen = apdu.resplen;
orig_apdu->sw1 = 0x90;
orig_apdu->sw2 = 0x00;
SC_FUNC_RETURN(card->ctx, 3, apdu.resplen);
}
static int iso7816_delete_file(struct sc_card *card, const struct sc_path *path)
{
int r;
@ -931,6 +958,7 @@ struct sc_card_driver * sc_get_iso7816_driver(void)
iso_ops.select_file = iso7816_select_file;
iso_ops.get_challenge = iso7816_get_challenge;
iso_ops.create_file = iso7816_create_file;
iso_ops.get_response = iso7816_get_response;
iso_ops.delete_file = iso7816_delete_file;
iso_ops.set_security_env = iso7816_set_security_env;
iso_ops.restore_security_env = iso7816_restore_security_env;

View File

@ -493,7 +493,7 @@ struct sc_card_operations {
* <file>, if not NULL. */
int (*select_file)(struct sc_card *card, const struct sc_path *path,
struct sc_file **file_out);
int (*get_response)(struct sc_card *card, u8 * buf, size_t count);
int (*get_response)(struct sc_card *card, sc_apdu_t *orig_apdu, size_t count);
int (*get_challenge)(struct sc_card *card, u8 * buf, size_t count);
/*