diff --git a/lib/internal.h b/lib/internal.h index 2aef554..20968de 100644 --- a/lib/internal.h +++ b/lib/internal.h @@ -44,6 +44,12 @@ #endif #endif +// Typedef DWORD (defined by pcsc lib) to pcsc_word to make it clear that this +// is not the Windows meaning of DWORD, but the PCSC library's meaning. This +// differs: Windows defines a DWORD as 32-bits, but pcsclite defines it as +// 'unsigned long' on x86_64 Linux, which is often 64-bits. +typedef DWORD pcsc_word; + #ifdef __cplusplus extern "C" { diff --git a/lib/tests/Makefile.am b/lib/tests/Makefile.am index 858cf1f..46264f4 100644 --- a/lib/tests/Makefile.am +++ b/lib/tests/Makefile.am @@ -26,7 +26,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. AM_CFLAGS = $(WARN_CFLAGS) @CHECK_CFLAGS@ $(OPENSSL_CFLAGS) -AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_builddir)/lib $(OPENSSL_CFLAGS) +AM_CPPFLAGS = -I$(top_srcdir)/lib -I$(top_builddir)/lib $(OPENSSL_CFLAGS) $(PCSC_CFLAGS) AM_LDFLAGS = @CHECK_LIBS@ diff --git a/lib/tests/api.c b/lib/tests/api.c index d7bf972..81ec279 100644 --- a/lib/tests/api.c +++ b/lib/tests/api.c @@ -40,6 +40,14 @@ int destruction_confirmed(void); +// only defined in libcheck 0.11+ (linux distros still shipping 0.10) +#ifndef ck_assert_ptr_nonnull +#define ck_assert_ptr_nonnull(a) ck_assert((a) != NULL) +#endif +#ifndef ck_assert_mem_eq +#define ck_assert_mem_eq(a,b,n) ck_assert(memcmp((a), (b), (n)) == 0) +#endif + ykpiv_state *g_state; const uint8_t g_cert[] = { "0123456789ABCDEFGHIK0123456789ABCDEFGHIK0123456789ABCDEFGHIK0123456789ABCDEFGHIK" @@ -97,12 +105,12 @@ START_TEST(test_devicemodel) { ck_assert_int_eq(res, YKPIV_OK); ck_assert_int_gt(num_readers, 0); if (model == DEVTYPE_YK4) { - ck_assert_ptr_nonnull(strnstr(reader_buf, "Yubikey 4", strlen(reader_buf))); + ck_assert_ptr_nonnull(strstr(reader_buf, "Yubikey 4")); ck_assert(version[0] == '4'); // Verify app version 4.x ck_assert(version[1] == '.'); } else { - ck_assert_ptr_nonnull(strnstr(reader_buf, "Yubikey NEO", strlen(reader_buf))); + ck_assert_ptr_nonnull(strstr(reader_buf, "Yubikey NEO")); ck_assert(version[0] == '1'); // Verify app version 1.x ck_assert(version[1] == '.'); } diff --git a/lib/ykpiv.c b/lib/ykpiv.c index 50c7340..b6d0a05 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -259,9 +259,9 @@ static ykpiv_rc _ykpiv_connect(ykpiv_state *state, uintptr_t context, uintptr_t // if card handle has changed, determine if handle is valid (less efficient, but complete) if ((card != state->card)) { char reader[CB_BUF_MAX]; - uint32_t reader_len = (uint32_t)sizeof(reader); + pcsc_word reader_len = sizeof(reader); uint8_t atr[CB_ATR_MAX]; - uint32_t atr_len = (uint32_t)sizeof(atr); + pcsc_word atr_len = sizeof(atr); // Cannot set the reader len to NULL. Confirmed in OSX 10.10, so we have to retrieve it even though we don't need it. if (SCARD_S_SUCCESS != SCardStatus(card, reader, &reader_len, NULL, NULL, atr, &atr_len)) { @@ -291,7 +291,7 @@ ykpiv_rc ykpiv_connect_with_external_card(ykpiv_state *state, uintptr_t context, } ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) { - uint32_t active_protocol; + pcsc_word active_protocol; char reader_buf[2048]; size_t num_readers = sizeof(reader_buf); long rc; @@ -316,7 +316,7 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) { fprintf(stderr, "trying to connect to reader '%s'.\n", reader_ptr); } rc = SCardConnect(state->context, reader_ptr, SCARD_SHARE_SHARED, - SCARD_PROTOCOL_T1, &card, &active_protocol); + SCARD_PROTOCOL_T1, &card, &active_protocol); if(rc != SCARD_S_SUCCESS) { if(state->verbose) { @@ -352,7 +352,7 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) { } static ykpiv_rc reconnect(ykpiv_state *state) { - uint32_t active_protocol; + pcsc_word active_protocol; long rc; ykpiv_rc res; int tries; @@ -360,7 +360,7 @@ static ykpiv_rc reconnect(ykpiv_state *state) { fprintf(stderr, "trying to reconnect to current reader.\n"); } rc = SCardReconnect(state->card, SCARD_SHARE_SHARED, - SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &active_protocol); + SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &active_protocol); if(rc != SCARD_S_SUCCESS) { if(state->verbose) { fprintf(stderr, "SCardReconnect failed, rc=%08lx\n", rc); @@ -377,7 +377,7 @@ static ykpiv_rc reconnect(ykpiv_state *state) { } ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) { - uint32_t num_readers = 0; + pcsc_word num_readers = 0; long rc; if(SCardIsValidContext(state->context) != SCARD_S_SUCCESS) { @@ -531,19 +531,21 @@ static ykpiv_rc _send_data(ykpiv_state *state, APDU *apdu, unsigned char *data, uint32_t *recv_len, int *sw) { long rc; unsigned int send_len = (unsigned int)apdu->st.lc + 5; + pcsc_word tmp_len = *recv_len; if(state->verbose > 1) { fprintf(stderr, "> "); dump_hex(apdu->raw, send_len); fprintf(stderr, "\n"); } - rc = SCardTransmit(state->card, SCARD_PCI_T1, apdu->raw, send_len, NULL, data, recv_len); + rc = SCardTransmit(state->card, SCARD_PCI_T1, apdu->raw, send_len, NULL, data, &tmp_len); if(rc != SCARD_S_SUCCESS) { if(state->verbose) { fprintf (stderr, "error: SCardTransmit failed, rc=%08lx\n", rc); } return YKPIV_PCSC_ERROR; } + *recv_len = (uint32_t)tmp_len; if(state->verbose > 1) { fprintf(stderr, "< "); diff --git a/lib/ykpiv.map b/lib/ykpiv.map index 4f013aa..5381cb7 100644 --- a/lib/ykpiv.map +++ b/lib/ykpiv.map @@ -79,37 +79,37 @@ global: YKPIV_1.5.0 { global: - ykpiv_attest - ykpiv_auth_getchallenge - ykpiv_auth_verifyresponse - ykpiv_connect_with_external_card - ykpiv_done_with_external_card - ykpiv_get_pin_retries - ykpiv_init_with_allocator - ykpiv_set_pin_retries - ykpiv_util_block_puk - ykpiv_util_delete_cert - ykpiv_util_devicemodel - ykpiv_util_free - ykpiv_util_generate_key - ykpiv_util_get_cardid - ykpiv_util_get_cccid - ykpiv_util_get_config - ykpiv_util_get_derived_mgm - ykpiv_util_get_protected_mgm - ykpiv_util_list_keys - ykpiv_util_list_keys.SLOTS - ykpiv_util_read_cert - ykpiv_util_read_mscmap - ykpiv_util_read_msroots - ykpiv_util_reset - ykpiv_util_set_cardid - ykpiv_util_set_cccid - ykpiv_util_set_pin_last_changed - ykpiv_util_set_protected_mgm - ykpiv_util_slot_object - ykpiv_util_write_cert - ykpiv_util_write_mscmap - ykpiv_util_write_msroots - ykpiv_verify_select -} YKPIV_1.5.0; + ykpiv_attest; + ykpiv_auth_getchallenge; + ykpiv_auth_verifyresponse; + ykpiv_connect_with_external_card; + ykpiv_done_with_external_card; + ykpiv_get_pin_retries; + ykpiv_init_with_allocator; + ykpiv_set_pin_retries; + ykpiv_util_block_puk; + ykpiv_util_delete_cert; + ykpiv_util_devicemodel; + ykpiv_util_free; + ykpiv_util_generate_key; + ykpiv_util_get_cardid; + ykpiv_util_get_cccid; + ykpiv_util_get_config; + ykpiv_util_get_derived_mgm; + ykpiv_util_get_protected_mgm; + ykpiv_util_list_keys; + ykpiv_util_list_keys; + ykpiv_util_read_cert; + ykpiv_util_read_mscmap; + ykpiv_util_read_msroots; + ykpiv_util_reset; + ykpiv_util_set_cardid; + ykpiv_util_set_cccid; + ykpiv_util_set_pin_last_changed; + ykpiv_util_set_protected_mgm; + ykpiv_util_slot_object; + ykpiv_util_write_cert; + ykpiv_util_write_mscmap; + ykpiv_util_write_msroots; + ykpiv_verify_select; +} YKPIV_1.3.0;