diff --git a/lib/ykpiv.c b/lib/ykpiv.c index aac931b..30c3ba3 100644 --- a/lib/ykpiv.c +++ b/lib/ykpiv.c @@ -228,9 +228,8 @@ ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted) { return YKPIV_GENERIC_ERROR; } -ykpiv_rc ykpiv_list_readers(ykpiv_state *state, unsigned char **readers, unsigned long *len) { +ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len) { unsigned long num_readers = 0; - char reader_buf[1024]; long rc; if(SCardIsValidContext(state->context) != SCARD_S_SUCCESS) { @@ -252,11 +251,11 @@ ykpiv_rc ykpiv_list_readers(ykpiv_state *state, unsigned char **readers, unsigne return YKPIV_PCSC_ERROR; } - if (num_readers > sizeof(reader_buf)) { - num_readers = sizeof(reader_buf); + if (num_readers > *len) { + num_readers = *len; } - rc = SCardListReaders(state->context, NULL, reader_buf, &num_readers); + rc = SCardListReaders(state->context, NULL, readers, &num_readers); if (rc != SCARD_S_SUCCESS) { if(state->verbose) { @@ -266,16 +265,6 @@ ykpiv_rc ykpiv_list_readers(ykpiv_state *state, unsigned char **readers, unsigne return YKPIV_PCSC_ERROR; } - // Save available readers (aka PKCS11 slots) - *readers = malloc(sizeof(char) * num_readers); - if (*readers == NULL) { - if(state->verbose) { - fprintf (stderr, "error: malloc failed"); - } - SCardReleaseContext(state->context); - return YKPIV_MEMORY_ERROR; - } - memcpy(*readers, reader_buf, num_readers); *len = num_readers; return YKPIV_OK; diff --git a/lib/ykpiv.h b/lib/ykpiv.h index d832283..ffbee83 100644 --- a/lib/ykpiv.h +++ b/lib/ykpiv.h @@ -65,7 +65,7 @@ extern "C" ykpiv_rc ykpiv_init(ykpiv_state **state, int verbose); ykpiv_rc ykpiv_done(ykpiv_state *state); ykpiv_rc ykpiv_connect(ykpiv_state *state, const char *wanted); - ykpiv_rc ykpiv_list_readers(ykpiv_state *state, unsigned char **readers, unsigned long *len); + ykpiv_rc ykpiv_list_readers(ykpiv_state *state, char *readers, size_t *len); ykpiv_rc ykpiv_disconnect(ykpiv_state *state); ykpiv_rc ykpiv_transfer_data(ykpiv_state *state, const unsigned char *templ, const unsigned char *in_data, long in_len, diff --git a/tool/cmdline.ggo b/tool/cmdline.ggo index d777748..bdd2a7e 100644 --- a/tool/cmdline.ggo +++ b/tool/cmdline.ggo @@ -32,7 +32,7 @@ option "action" a "Action to take" values="version","generate","set-mgm-key", "reset","pin-retries","import-key","import-certificate","set-chuid", "request-certificate","verify-pin","change-pin","change-puk","unblock-pin", "selfsign-certificate","delete-certificate","read-certificate","status", - "test-signature","test-decipher" enum multiple + "test-signature","test-decipher","list-readers" enum multiple text " Multiple actions may be given at once and will be executed in order for example --action=verify-pin --action=request-certificate\n" diff --git a/tool/yubico-piv-tool.c b/tool/yubico-piv-tool.c index 1fcbb25..e916be1 100644 --- a/tool/yubico-piv-tool.c +++ b/tool/yubico-piv-tool.c @@ -1569,6 +1569,21 @@ decipher_out: return ret; } +static bool list_readers(ykpiv_state *state) { + char readers[2048]; + char *reader_ptr; + size_t len = sizeof(readers); + ykpiv_rc rc = ykpiv_list_readers(state, readers, &len); + if(rc != YKPIV_OK) { + fprintf(stderr, "Failed listing readers.\n"); + return false; + } + for(reader_ptr = readers; *reader_ptr != '\0'; reader_ptr += strlen(reader_ptr) + 1) { + printf("%s\n", reader_ptr); + } + return true; +} + int main(int argc, char *argv[]) { struct gengetopt_args_info args_info; ykpiv_state *state; @@ -1622,6 +1637,7 @@ int main(int argc, char *argv[]) { case action_arg_version: case action_arg_reset: case action_arg_status: + case action_arg_listMINUS_readers: case action__NULL: default: continue; @@ -1666,6 +1682,7 @@ int main(int argc, char *argv[]) { case action_arg_status: case action_arg_testMINUS_signature: case action_arg_testMINUS_decipher: + case action_arg_listMINUS_readers: case action__NULL: default: if(verbosity) { @@ -1850,6 +1867,11 @@ int main(int argc, char *argv[]) { ret = EXIT_FAILURE; } break; + case action_arg_listMINUS_readers: + if(list_readers(state) == false) { + ret = EXIT_FAILURE; + } + break; case action__NULL: default: fprintf(stderr, "Wrong action. %d.\n", action); diff --git a/ykcs11/ykcs11.c b/ykcs11/ykcs11.c index 4997329..a4e6b94 100644 --- a/ykcs11/ykcs11.c +++ b/ykcs11/ykcs11.c @@ -47,8 +47,8 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)( ) { DIN; - CK_CHAR_PTR readers; - CK_ULONG len; + char readers[2048]; + CK_ULONG len = sizeof(readers); // TODO: check for locks and mutexes @@ -60,7 +60,7 @@ CK_DEFINE_FUNCTION(CK_RV, C_Initialize)( return CKR_FUNCTION_FAILED; // TODO: better error? } - if (ykpiv_list_readers(piv_state, &readers, &len) != YKPIV_OK) { + if (ykpiv_list_readers(piv_state, readers, &len) != YKPIV_OK) { DBG(("Unable to list readers")); return CKR_FUNCTION_FAILED; }