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:
parent
1b988af695
commit
4737789ede
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue