From 729c70385b5979d119b04b35528209dd94bc49bb Mon Sep 17 00:00:00 2001 From: Emerson Lin Date: Thu, 25 May 2017 13:16:32 -0700 Subject: [PATCH 1/4] bump openssl to 1.0.2l OpenSSL just released a new version and 1.0.2k no longer works --- mac.mk | 2 +- windows.mk | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mac.mk b/mac.mk index e77683c..7fff5da 100644 --- a/mac.mk +++ b/mac.mk @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. PACKAGE=yubico-piv-tool -OPENSSLVERSION=1.0.2k +OPENSSLVERSION=1.0.2l CFLAGS="-mmacosx-version-min=10.6" all: usage mac diff --git a/windows.mk b/windows.mk index 7aba4a2..baf29c0 100644 --- a/windows.mk +++ b/windows.mk @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. PACKAGE=yubico-piv-tool -OPENSSLVERSION=1.0.2k +OPENSSLVERSION=1.0.2l all: usage 32bit 64bit From c05d87996836ffd8955262806d39c5dbdc53e899 Mon Sep 17 00:00:00 2001 From: emersonl Date: Thu, 25 May 2017 21:38:08 -0700 Subject: [PATCH 2/4] Fix issue #88 and #102 --- lib/internal.h | 1 + lib/ykpiv.c | 112 +++++++++++++++++++++++++++++++++++-------------- 2 files changed, 81 insertions(+), 32 deletions(-) diff --git a/lib/internal.h b/lib/internal.h index 218d7ee..d05436c 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -49,6 +49,7 @@ struct ykpiv_state { SCARDCONTEXT context; SCARDHANDLE card; int verbose; + char *pin; }; union u_APDU { diff --git a/lib/ykpiv.c b/lib/ykpiv.c index 96a5a90..7cf63e6 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -102,6 +102,7 @@ ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose) { return YKPIV_MEMORY_ERROR; } memset(s, 0, sizeof(ykpiv_state)); + s->pin = NULL; s->verbose = verbose; s->context = SCARD_E_INVALID_HANDLE; *state = s; @@ -110,6 +111,7 @@ ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose) { ykpiv_rc ykpiv_done(ykpiv_state *state) { ykpiv_disconnect(state); + free(state->pin); free(state); return YKPIV_OK; } @@ -128,6 +130,34 @@ ykpiv_rc ykpiv_disconnect(ykpiv_state *state) { return YKPIV_OK; } +static ykpiv_rc _select_application(ykpiv_state *state) { + APDU apdu; + unsigned char data[0xff]; + unsigned long recv_len = sizeof(data); + int sw; + ykpiv_rc res; + + memset(apdu.raw, 0, sizeof(apdu)); + apdu.st.ins = 0xa4; + apdu.st.p1 = 0x04; + apdu.st.lc = sizeof(aid); + memcpy(apdu.st.data, aid, sizeof(aid)); + + if((res = send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) { + if(state->verbose) { + fprintf(stderr, "Failed communicating with card: '%s'\n", ykpiv_strerror(res)); + } + return res; + } else if(sw == SW_SUCCESS) { + return YKPIV_OK; + } else { + if(state->verbose) { + fprintf(stderr, "Failed selecting application: %04x\n", sw); + } + return YKPIV_GENERIC_ERROR; + } +} + ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) { unsigned long active_protocol; char reader_buf[2048]; @@ -154,40 +184,15 @@ 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; } - - { - APDU apdu; - unsigned char data[0xff]; - unsigned long recv_len = sizeof(data); - int sw; - ykpiv_rc res; - - memset(apdu.raw, 0, sizeof(apdu)); - apdu.st.ins = 0xa4; - apdu.st.p1 = 0x04; - apdu.st.lc = sizeof(aid); - memcpy(apdu.st.data, aid, sizeof(aid)); - - if((res = send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) { - if(state->verbose) { - fprintf(stderr, "Failed communicating with card: '%s'\n", ykpiv_strerror(res)); - } - continue; - } else if(sw == SW_SUCCESS) { - return YKPIV_OK; - } else { - if(state->verbose) { - fprintf(stderr, "Failed selecting application: %04x\n", sw); - } - } - } + if (_select_application(state) != YKPIV_OK) + continue; + return YKPIV_OK; } if(*reader_ptr == '\0') { @@ -202,6 +207,30 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) { return YKPIV_GENERIC_ERROR; } +static ykpiv_rc _reconnect(ykpiv_state *state) { + unsigned long active_protocol; + long rc; + ykpiv_rc res; + int tries; + + if(state->verbose) { + fprintf(stderr, "trying to reconnect to current reader.\n"); + } + rc = SCardReconnect(state->card, SCARD_SHARE_SHARED, + SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &active_protocol); + if(rc != SCARD_S_SUCCESS) { + if(state->verbose) { + fprintf(stderr, "SCardReconnect failed, rc=%08lx\n", rc); + } + return YKPIV_PCSC_ERROR; + } + if ((res = _select_application(state)) != YKPIV_OK) + return res; + if (state->pin) + return ykpiv_verify(state, state->pin, &tries); + return YKPIV_OK; +} + ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) { unsigned long num_readers = 0; long rc; @@ -231,8 +260,7 @@ 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); } @@ -254,8 +282,17 @@ 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); + 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); @@ -704,6 +741,11 @@ ykpiv_rc ykpiv_verify(ykpiv_state *state, const char *pin, int *tries) { if((res = send_data(state, &apdu, data, &recv_len, &sw)) != YKPIV_OK) { return res; } else if(sw == SW_SUCCESS) { + if (pin) { + free(state->pin); + state->pin = malloc(len * sizeof(char) + 1); + strcpy(state->pin, pin); + } return YKPIV_OK; } else if((sw >> 8) == 0x63) { *tries = (sw & 0xf); @@ -767,7 +809,13 @@ static ykpiv_rc _change_pin_internal(ykpiv_state *state, int action, const char } ykpiv_rc ykpiv_change_pin(ykpiv_state *state, const char * current_pin, size_t current_pin_len, const char * new_pin, size_t new_pin_len, int *tries) { - return _change_pin_internal(state, CHREF_ACT_CHANGE_PIN, current_pin, current_pin_len, new_pin, new_pin_len, tries); + ykpiv_rc res = _change_pin_internal(state, CHREF_ACT_CHANGE_PIN, current_pin, current_pin_len, new_pin, new_pin_len, tries); + if (res == YKPIV_OK && new_pin != NULL) { + free(state->pin); + state->pin = malloc(new_pin_len * sizeof(char) + 1); + strcpy(state->pin, new_pin); + } + return res; } ykpiv_rc ykpiv_change_puk(ykpiv_state *state, const char * current_puk, size_t current_puk_len, const char * new_puk, size_t new_puk_len, int *tries) { From 6882bc5c7ccbdc3ee0d3e7df39ce6f06a6a70ecb Mon Sep 17 00:00:00 2001 From: emersonl Date: Fri, 26 May 2017 15:34:03 -0700 Subject: [PATCH 3/4] Fix issue #116 --- lib/ykpiv.c | 173 ++++++++++++++++++++++++++++------------------------ 1 file changed, 94 insertions(+), 79 deletions(-) diff --git a/lib/ykpiv.c b/lib/ykpiv.c index 7cf63e6..c6a40a1 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -274,24 +274,16 @@ ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) { 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) { - const unsigned char *in_ptr = in_data; - unsigned long max_out = *out_len; - ykpiv_rc res; +static ykpiv_rc _begin_transaction(ykpiv_state *state) { long rc; - *out_len = 0; - unsigned long active_protocol; + ykpiv_rc res; -BeginTransaction: rc = SCardBeginTransaction(state->card); if((rc & 0xFFFFFFFF) == SCARD_W_RESET_CARD) { - res = _reconnect(state); - if(res != YKPIV_OK) { + if((res = _reconnect(state)) != YKPIV_OK) { return res; } - goto BeginTransaction; + return _begin_transaction(state); } if(rc != SCARD_S_SUCCESS) { if(state->verbose) { @@ -299,79 +291,102 @@ BeginTransaction: } return YKPIV_PCSC_ERROR; } - do { - size_t this_size = 0xff; - unsigned char data[261]; - unsigned long recv_len = sizeof(data); - APDU apdu; + return YKPIV_OK; +} - 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) { - return res; - } else if(*sw != SW_SUCCESS && *sw >> 8 != 0x61) { - 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); - } - 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); - } - - memset(apdu.raw, 0, sizeof(apdu.raw)); - apdu.st.ins = 0xc0; - res = send_data(state, &apdu, data, &recv_len, sw); - if(res != YKPIV_OK) { - return res; - } else if(*sw != SW_SUCCESS && *sw >> 8 != 0x61) { - 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; - } - } - 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); - } +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) { + 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; + + 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); + + 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); +} + static ykpiv_rc send_data(ykpiv_state *state, APDU *apdu, unsigned char *data, unsigned long *recv_len, int *sw) { long rc; From d1db8eb282276a68bcfbe78bbeda9ff3e5a09d1c Mon Sep 17 00:00:00 2001 From: emersonl Date: Mon, 29 May 2017 04:19:49 -0700 Subject: [PATCH 4/4] Improve the style based on comments from Klas --- lib/ykpiv.c | 185 +++++++++++++++++++++++++++------------------------- 1 file changed, 97 insertions(+), 88 deletions(-) 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;