148 lines
4.1 KiB
C
148 lines
4.1 KiB
C
/*
|
|
* p11test_loader.c: Library loader for PKCS#11 test suite
|
|
*
|
|
* Copyright (C) 2016 Martin Strhársky <strharsky.martin@gmail.com>
|
|
* Copyright (C) 2016, 2017 Red Hat, Inc.
|
|
*
|
|
* Author: Jakub Jelen <jjelen@redhat.com>
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "p11test_loader.h"
|
|
|
|
void *pkcs11_so;
|
|
|
|
int get_slot_with_card(token_info_t * info)
|
|
{
|
|
CK_SLOT_ID_PTR slot_list;
|
|
CK_SLOT_ID slot_id;
|
|
CK_ULONG slot_count = 0;
|
|
CK_RV rv;
|
|
int error = 0;
|
|
unsigned int i;
|
|
|
|
CK_FUNCTION_LIST_PTR function_pointer = info->function_pointer;
|
|
|
|
/* Get slot list for memory allocation */
|
|
rv = function_pointer->C_GetSlotList(0, NULL_PTR, &slot_count);
|
|
|
|
if ((rv == CKR_OK) && (slot_count > 0)) {
|
|
slot_list = malloc(slot_count * sizeof (CK_SLOT_ID));
|
|
|
|
if (slot_list == NULL) {
|
|
fprintf(stderr, "System error: unable to allocate memory\n");
|
|
return 1;
|
|
}
|
|
|
|
/* Get the slot list for processing */
|
|
rv = function_pointer->C_GetSlotList(0, slot_list, &slot_count);
|
|
if (rv != CKR_OK) {
|
|
fprintf(stderr, "GetSlotList failed: unable to get slot count.\n");
|
|
error = 1;
|
|
goto cleanup;
|
|
}
|
|
} else {
|
|
fprintf(stderr, "GetSlotList failed: unable to get slot list.\n");
|
|
return 1;
|
|
}
|
|
|
|
/* Find a slot capable of specified mechanism */
|
|
for (i = 0; i < slot_count; i++) {
|
|
CK_SLOT_INFO slot_info;
|
|
slot_id = slot_list[i];
|
|
|
|
rv = function_pointer->C_GetSlotInfo(slot_id, &slot_info);
|
|
if (rv != CKR_OK)
|
|
continue;
|
|
|
|
if (info->slot_id == slot_id) {
|
|
if (info->slot_id == slot_list[i]) { /* explicitly specified slot */
|
|
debug_print("Manually selected slot %lu (%s a token)\n", info->slot_id,
|
|
((slot_info.flags & CKF_TOKEN_PRESENT) ? "with" : "without"));
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
if (slot_info.flags & CKF_TOKEN_PRESENT) {
|
|
/* first found slot if not specified */
|
|
if (info->slot_id == (unsigned long) -1) {
|
|
info->slot_id = slot_id;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
}
|
|
error = 1;
|
|
fprintf(stderr, "No slot with card inserted or the selected slot does not exist\n");
|
|
|
|
cleanup:
|
|
if (slot_list) {
|
|
free(slot_list);
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
int load_pkcs11_module(token_info_t * info, const char* path_to_pkcs11_library) {
|
|
CK_RV rv;
|
|
CK_RV (*C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR) = 0;
|
|
|
|
if(strlen(path_to_pkcs11_library) == 0) {
|
|
fprintf(stderr, "You have to specify path to PKCS#11 library.");
|
|
return 1;
|
|
}
|
|
|
|
pkcs11_so = dlopen(path_to_pkcs11_library, RTLD_NOW);
|
|
|
|
if (!pkcs11_so) {
|
|
fprintf(stderr, "Error loading pkcs#11 so: %s\n", dlerror());
|
|
return 1;
|
|
}
|
|
|
|
C_GetFunctionList = (CK_RV (*)(CK_FUNCTION_LIST_PTR_PTR)) dlsym(pkcs11_so, "C_GetFunctionList");
|
|
|
|
if (!C_GetFunctionList) {
|
|
fprintf(stderr, "Could not get function list: %s\n", dlerror());
|
|
return 1;
|
|
}
|
|
|
|
rv = C_GetFunctionList(&info->function_pointer);
|
|
if (CKR_OK != rv) {
|
|
fprintf(stderr, "C_GetFunctionList call failed: 0x%.8lX", rv);
|
|
return 1;
|
|
}
|
|
|
|
rv = info->function_pointer->C_Initialize(NULL_PTR);
|
|
|
|
if (rv != CKR_OK) {
|
|
fprintf(stderr, "C_Initialize: Error = 0x%.8lX\n", rv);
|
|
return 1;
|
|
}
|
|
|
|
if (get_slot_with_card(info)) {
|
|
fprintf(stderr, "There is no card present in reader.\n");
|
|
info->function_pointer->C_Finalize(NULL_PTR);
|
|
return 1;
|
|
}
|
|
|
|
info->function_pointer->C_Finalize(NULL_PTR);
|
|
return 0;
|
|
}
|
|
|
|
void close_pkcs11_module() {
|
|
if(pkcs11_so)
|
|
dlclose(pkcs11_so);
|
|
}
|
|
|