diff --git a/lib/ykpiv.c b/lib/ykpiv.c index c6a40a1..493cb32 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -130,7 +130,7 @@ ykpiv_rc ykpiv_disconnect(ykpiv_state *state) { return YKPIV_OK; } -static ykpiv_rc _select_application(ykpiv_state *state) { +static ykpiv_rc select_application(ykpiv_state *state) { APDU apdu; unsigned char data[0xff]; unsigned long recv_len = sizeof(data); @@ -184,14 +184,16 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) { } rc = SCardConnect(state->context, reader_ptr, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T1, &state->card, &active_protocol); - if(rc != SCARD_S_SUCCESS) { + if(rc != SCARD_S_SUCCESS) + { if(state->verbose) { fprintf(stderr, "SCardConnect failed, rc=%08lx\n", rc); } continue; } - if (_select_application(state) != YKPIV_OK) + if (select_application(state) != YKPIV_OK) { continue; + } return YKPIV_OK; } @@ -207,7 +209,7 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) { return YKPIV_GENERIC_ERROR; } -static ykpiv_rc _reconnect(ykpiv_state *state) { +static ykpiv_rc reconnect(ykpiv_state *state) { unsigned long active_protocol; long rc; ykpiv_rc res; @@ -224,10 +226,12 @@ static ykpiv_rc _reconnect(ykpiv_state *state) { } return YKPIV_PCSC_ERROR; } - if ((res = _select_application(state)) != YKPIV_OK) + if ((res = select_application(state)) != YKPIV_OK) { return res; - if (state->pin) + } + if (state->pin) { return ykpiv_verify(state, state->pin, &tries); + } return YKPIV_OK; } @@ -260,7 +264,8 @@ ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) { } rc = SCardListReaders(state->context, NULL, readers, &num_readers); - if (rc != SCARD_S_SUCCESS) { + if (rc != SCARD_S_SUCCESS) + { if(state->verbose) { fprintf (stderr, "error: SCardListReaders failed, rc=%08lx\n", rc); } @@ -274,16 +279,16 @@ ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) { return YKPIV_OK; } -static ykpiv_rc _begin_transaction(ykpiv_state *state) { +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) { + if((res = reconnect(state)) != YKPIV_OK) { return res; } - return _begin_transaction(state); + rc = SCardBeginTransaction(state->card); } if(rc != SCARD_S_SUCCESS) { if(state->verbose) { @@ -294,7 +299,7 @@ static ykpiv_rc _begin_transaction(ykpiv_state *state) { return YKPIV_OK; } -static ykpiv_rc _end_transaction(ykpiv_state *state) { +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); @@ -304,87 +309,85 @@ static ykpiv_rc _end_transaction(ykpiv_state *state) { } 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) { - const unsigned char *in_ptr = in_data; - unsigned long max_out = *out_len; - ykpiv_rc res; - long rc; - *out_len = 0; + const unsigned char *in_data, long in_len, + unsigned char *out_data, unsigned long *out_len, int *sw) { + const unsigned char *in_ptr = in_data; + unsigned long max_out = *out_len; + ykpiv_rc res; + long rc; + *out_len = 0; - res = _begin_transaction(state); - if (res != YKPIV_OK) { - return res; - } - do { - size_t this_size = 0xff; - unsigned char data[261]; - unsigned long recv_len = sizeof(data); - APDU apdu; + res = begin_transaction(state); + if (res != YKPIV_OK) { + return res; + } + do { + size_t this_size = 0xff; + unsigned char data[261]; + unsigned long recv_len = sizeof(data); + APDU apdu; - memset(apdu.raw, 0, sizeof(apdu.raw)); - memcpy(apdu.raw, templ, 4); - if(in_ptr + 0xff < in_data + in_len) { - apdu.st.cla = 0x10; - } else { - this_size = (size_t)((in_data + in_len) - in_ptr); - } - if(state->verbose > 2) { - fprintf(stderr, "Going to send %lu bytes in this go.\n", (unsigned long)this_size); - } - apdu.st.lc = this_size; - 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) { - memcpy(out_data, data, recv_len - 2); - out_data += recv_len - 2; - *out_len += recv_len - 2; - } - in_ptr += this_size; - } while(in_ptr < in_data + in_len); - while(*sw >> 8 == 0x61) { - APDU apdu; - unsigned char data[261]; - unsigned long recv_len = sizeof(data); + memset(apdu.raw, 0, sizeof(apdu.raw)); + memcpy(apdu.raw, templ, 4); + if(in_ptr + 0xff < in_data + in_len) { + apdu.st.cla = 0x10; + } else { + this_size = (size_t)((in_data + in_len) - in_ptr); + } + if(state->verbose > 2) { + fprintf(stderr, "Going to send %lu bytes in this go.\n", (unsigned long)this_size); + } + apdu.st.lc = this_size; + 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) { + return end_transaction(state); + } + 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) { + memcpy(out_data, data, recv_len - 2); + out_data += recv_len - 2; + *out_len += recv_len - 2; + } + in_ptr += this_size; + } while(in_ptr < in_data + in_len); + while(*sw >> 8 == 0x61) { + APDU apdu; + unsigned char data[261]; + unsigned long recv_len = sizeof(data); - if(state->verbose > 2) { - fprintf(stderr, "The card indicates there is %d bytes more data for us.\n", *sw & 0xff); - } + if(state->verbose > 2) { + fprintf(stderr, "The card indicates there is %d bytes more data for us.\n", *sw & 0xff); + } - memset(apdu.raw, 0, sizeof(apdu.raw)); - 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) { - fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.", *out_len + recv_len - 2, max_out); - } - if(out_data) { - memcpy(out_data, data, recv_len - 2); - out_data += recv_len - 2; - *out_len += recv_len - 2; - } - } - return _end_transaction(state); + memset(apdu.raw, 0, sizeof(apdu.raw)); + 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) { + return end_transaction(state); + } + if(*out_len + recv_len - 2 > max_out) { + fprintf(stderr, "Output buffer to small, wanted to write %lu, max was %lu.", *out_len + recv_len - 2, max_out); + } + if(out_data) { + memcpy(out_data, data, recv_len - 2); + out_data += recv_len - 2; + *out_len += recv_len - 2; + } + } + return end_transaction(state); } static ykpiv_rc send_data(ykpiv_state *state, APDU *apdu, @@ -759,6 +762,9 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) { if (pin) { free(state->pin); state->pin = malloc(len * sizeof(char) + 1); + if (state->pin == NULL) { + return YKPIV_MEMORY_ERROR; + } strcpy(state->pin, pin); } return YKPIV_OK; @@ -828,6 +834,9 @@ ykpiv_rc ykpiv_change_pin(ykpiv_state *state, const char * current_pin, size_t c if (res == YKPIV_OK && new_pin != NULL) { free(state->pin); state->pin = malloc(new_pin_len * sizeof(char) + 1); + if (state->pin == NULL) { + return YKPIV_MEMORY_ERROR; + } strcpy(state->pin, new_pin); } return res;