Fix issue #116
This commit is contained in:
+36
-21
@@ -274,6 +274,35 @@ ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) {
|
||||
return YKPIV_OK;
|
||||
}
|
||||
|
||||
static ykpiv_rc _begin_transaction(ykpiv_state *state) {
|
||||
long rc;
|
||||
ykpiv_rc res;
|
||||
|
||||
rc = SCardBeginTransaction(state->card);
|
||||
if((rc & 0xFFFFFFFF) == SCARD_W_RESET_CARD) {
|
||||
if((res = _reconnect(state)) != YKPIV_OK) {
|
||||
return res;
|
||||
}
|
||||
return _begin_transaction(state);
|
||||
}
|
||||
if(rc != SCARD_S_SUCCESS) {
|
||||
if(state->verbose) {
|
||||
fprintf(stderr, "error: Failed to begin pcsc transaction, rc=%08lx\n", rc);
|
||||
}
|
||||
return YKPIV_PCSC_ERROR;
|
||||
}
|
||||
return YKPIV_OK;
|
||||
}
|
||||
|
||||
static ykpiv_rc _end_transaction(ykpiv_state *state) {
|
||||
long rc = SCardEndTransaction(state->card, SCARD_LEAVE_CARD);
|
||||
if(rc != SCARD_S_SUCCESS && state->verbose) {
|
||||
fprintf(stderr, "error: Failed to end pcsc transaction, rc=%08lx\n", rc);
|
||||
return YKPIV_PCSC_ERROR;
|
||||
}
|
||||
return YKPIV_OK;
|
||||
}
|
||||
|
||||
ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
||||
const unsigned char *in_data, long in_len,
|
||||
unsigned char *out_data, unsigned long *out_len, int *sw) {
|
||||
@@ -282,23 +311,11 @@ ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ,
|
||||
ykpiv_rc res;
|
||||
long rc;
|
||||
*out_len = 0;
|
||||
unsigned long active_protocol;
|
||||
|
||||
BeginTransaction:
|
||||
rc = SCardBeginTransaction(state->card);
|
||||
if((rc & 0xFFFFFFFF) == SCARD_W_RESET_CARD) {
|
||||
res = _reconnect(state);
|
||||
res = _begin_transaction(state);
|
||||
if (res != YKPIV_OK) {
|
||||
return res;
|
||||
}
|
||||
goto BeginTransaction;
|
||||
}
|
||||
if(rc != SCARD_S_SUCCESS) {
|
||||
if(state->verbose) {
|
||||
fprintf(stderr, "error: Failed to begin pcsc transaction, rc=%08lx\n", rc);
|
||||
}
|
||||
return YKPIV_PCSC_ERROR;
|
||||
}
|
||||
do {
|
||||
size_t this_size = 0xff;
|
||||
unsigned char data[261];
|
||||
@@ -319,14 +336,17 @@ BeginTransaction:
|
||||
memcpy(apdu.st.data, in_ptr, this_size);
|
||||
res = send_data(state, &apdu, data, &recv_len, sw);
|
||||
if(res != YKPIV_OK) {
|
||||
_end_transaction(state);
|
||||
return res;
|
||||
} else if(*sw != SW_SUCCESS && *sw >> 8 != 0x61) {
|
||||
_end_transaction(state);
|
||||
return YKPIV_OK;
|
||||
}
|
||||
if(*out_len + recv_len - 2 > max_out) {
|
||||
if(state->verbose) {
|
||||
fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.\n", *out_len + recv_len - 2, max_out);
|
||||
}
|
||||
_end_transaction(state);
|
||||
return YKPIV_SIZE_ERROR;
|
||||
}
|
||||
if(out_data) {
|
||||
@@ -349,8 +369,10 @@ BeginTransaction:
|
||||
apdu.st.ins = 0xc0;
|
||||
res = send_data(state, &apdu, data, &recv_len, sw);
|
||||
if(res != YKPIV_OK) {
|
||||
_end_transaction(state);
|
||||
return res;
|
||||
} else if(*sw != SW_SUCCESS && *sw >> 8 != 0x61) {
|
||||
_end_transaction(state);
|
||||
return YKPIV_OK;
|
||||
}
|
||||
if(*out_len + recv_len - 2 > max_out) {
|
||||
@@ -362,14 +384,7 @@ BeginTransaction:
|
||||
*out_len += recv_len - 2;
|
||||
}
|
||||
}
|
||||
rc = SCardEndTransaction(state->card, SCARD_LEAVE_CARD);
|
||||
if(rc != SCARD_S_SUCCESS) {
|
||||
if(state->verbose) {
|
||||
fprintf(stderr, "error: Failed to end pcsc transaction, rc=%08lx\n", rc);
|
||||
}
|
||||
return YKPIV_PCSC_ERROR;
|
||||
}
|
||||
return YKPIV_OK;
|
||||
return _end_transaction(state);
|
||||
}
|
||||
|
||||
static ykpiv_rc send_data(ykpiv_state *state, APDU *apdu,
|
||||
|
||||
Reference in New Issue
Block a user