#include "BiolibCommon.h" #include "Common.h"
#include <stdio.h> #include <stdlib.h>
int main(void) {
// Для работы с библиотекой PKCS#11
HMODULE modulePkcs; // Дискриптор загруженной библиотеки PKCS#11 CK_FUNCTION_LIST_PTR functionList= NULL; // Указатель на список функций PKCS#11, // хранящийся в структуре CK_FUNCTION_LIST
CK_C_GetFunctionList getFunctionList=NULL; // Указатель на функцию C_GetFunctionList CK_FUNCTION_LIST_EXTENDED_PTR functionListEx=NULL; // Указатель на список функций // расширения PKCS#11, хранящийся в структуре CK_FUNCTION_LIST_EXTENDED
CK_C_EX_GetFunctionListExtended getFunctionListEx=NULL; // Указатель на функцию // C_EX_GetFunctionListExtended CK_RV rv; // Код возврата. Могут быть возвращены только ошибки, определенные в PKCS#11
// Для работы с Biolib
HMODULE moduleBiolib = 0; // Дискриптор загруженной библиотеки Biolib
// Указатели на функции Biolib
BIO_RES_TYPE(BIO_CALL_CONV * initFunc) (CK_FUNCTION_LIST_PTR, CK_FUNCTION_LIST_EXTENDED_PTR, CK_BYTE) = NULL; // BIO_Initialize
BIO_RES_TYPE(BIO_CALL_CONV * getFPInfoFunc)(CK_SESSION_HANDLE, BIO_FINGERPRINT_INFO_PTR, BIO_FINGERPRINT_SCAN_PARAMS_PTR, CK_ULONG_PTR) = NULL; // BIO_GetFingerprintInfo
BIO_RES_TYPE(BIO_CALL_CONV * authFunc) (CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG, CK_ULONG, CK_BYTE) = NULL; // BIO_Authenticate
BIO_RES_TYPE(BIO_CALL_CONV * listScannersFunc) (BIO_SCANNER_INFO_PTR, CK_ULONG_PTR) = NULL; // BIO_ListScanners
BIO_RES_TYPE(BIO_CALL_CONV * setFPInitFunc) (CK_SESSION_HANDLE, BIO_FINGERPRINT_SCAN_PARAMS_PTR, CK_ULONG, BIO_FINGERPRINT_TYPE_PTR) = NULL; // BIO_SetFingerprintInit
BIO_RES_TYPE(BIO_CALL_CONV * setFPScan)(CK_SESSION_HANDLE, CK_ULONG, BIO_FINGERPRINT_TYPE_PTR) = NULL; // BIO_SetFingerprintScan
BIO_RES_TYPE(BIO_CALL_CONV * setFPStatus)(CK_SESSION_HANDLE, BIO_FINGERPRINT_SCAN_STATUS_PTR, CK_ULONG_PTR) = NULL; // BIO_SetFingerprintStatus
BIO_RES_TYPE(BIO_CALL_CONV * setFPFinal) (CK_SESSION_HANDLE, CK_ULONG_PTR) = NULL; // BIO_SetFingerprintFinal
BIO_RES_TYPE(BIO_CALL_CONV * finalizeFunc)() = NULL; // BIO_Finalize
BIO_RES_TYPE r = 0; // Код возврата для функций Biolib
int errorCode = 1; // Признак корректного завершения программы
/************************************************************************* * Загрузка функций PKCS#11 для инициализации Biolib * *************************************************************************/
printf("Initialization...\n");
modulePkcs=LoadLibrary(PKCS11ECP_LIBRARY_NAME); CHECK(" LoadLibrary", modulePkcs != NULL, exit);
getFunctionList= (CK_C_GetFunctionList)GetProcAddress(modulePkcs, "C_GetFunctionList"); CHECK(" GetProcAddress", getFunctionList != NULL, unloadPkcs);
rv = getFunctionList(&functionList); CHECK_AND_LOG(" Get function list", rv == CKR_OK, rvToStr(rv), unloadPkcs);
getFunctionListEx= (CK_C_EX_GetFunctionListExtended) GetProcAddress(modulePkcs, "C_EX_GetFunctionListExtended"); CHECK(" GetProcAddress", getFunctionListEx != NULL, unloadPkcs); rv = getFunctionListEx(&functionListEx); CHECK_AND_LOG(" Get extended function list", rv == CKR_OK, rvToStr(rv), unloadPkcs);
rv = functionList->C_Initialize(&initArgs); CHECK_AND_LOG(" C_Initialize", rv == CKR_OK, rvToStr(rv), unloadPkcs); printf("\nPKCS#11 loaded successfully! \n");
/************************************************************************* * Инициализация и загрузка функций Biolib * *************************************************************************/ moduleBiolib=LoadLibrary(BIOLIB_LIBRARY_NAME); CHECK(" LoadLibrary", moduleBiolib!=NULL, finalizePkcs);
initFunc = (BIO_RES_TYPE(BIO_CALL_CONV*)(CK_FUNCTION_LIST_PTR, CK_FUNCTION_LIST_EXTENDED_PTR, CK_BYTE))GetProcAddress(moduleBiolib, "BIO_Initialize");
finalizeFunc = (BIO_RES_TYPE(BIO_CALL_CONV*)())GetProcAddress(moduleBiolib, "BIO_Finalize"); authFunc = (BIO_RES_TYPE(BIO_CALL_CONV*)(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG, CK_ULONG timeout, CK_BYTE))GetProcAddress(moduleBiolib, "BIO_Authenticate");
listScannersFunc = (BIO_RES_TYPE(BIO_CALL_CONV*) (BIO_SCANNER_INFO_PTR, CK_ULONG_PTR))GetProcAddress(moduleBiolib, "BIO_ListScanners");
getFPInfoFunc = (BIO_RES_TYPE(BIO_CALL_CONV*)(CK_SESSION_HANDLE,BIO_FINGERPRINT_INFO_PTR, BIO_FINGERPRINT_SCAN_PARAMS_PTR,CK_ULONG_PTR)) GetProcAddress(moduleBiolib, "BIO_GetFingerprintInfo");
setFPInitFunc = (BIO_RES_TYPE(BIO_CALL_CONV*)(CK_SESSION_HANDLE,BIO_FINGERPRINT_SCAN_PARAMS_PTR, CK_ULONG, BIO_FINGERPRINT_TYPE_PTR)) GetProcAddress(moduleBiolib, "BIO_SetFingerprintInit");
setFPScan = (BIO_RES_TYPE(BIO_CALL_CONV*)(CK_SESSION_HANDLE, CK_ULONG, BIO_FINGERPRINT_TYPE_PTR))GetProcAddress(moduleBiolib, "BIO_SetFingerprintScan");
setFPStatus = (BIO_RES_TYPE(BIO_CALL_CONV*)(CK_SESSION_HANDLE, BIO_FINGERPRINT_SCAN_STATUS_PTR, CK_ULONG_PTR))GetProcAddress(moduleBiolib, "BIO_SetFingerprintStatus");
setFPFinal = (BIO_RES_TYPE(BIO_CALL_CONV*)(CK_SESSION_HANDLE, CK_ULONG_PTR))GetProcAddress( moduleBiolib, "BIO_SetFingerprintFinal");
CHECK_AND_LOG(" Load Biolib functions", initFunc && getFPInfoFunc && listScannersFunc && authFunc && finalizeFunc && setFPInitFunc && setFPScan && setFPStatus && setFPFinal, "", unloadBio);
/************************************************************************* * Инициализация Biolib * *************************************************************************/ r =initFunc(functionList, functionListEx, BIO_DEFAULT_INIT_FLAG); CHECK_AND_LOG(" BIO_Initialize", r == BIO_SUCCESS, bioRvToStr(r), unloadBio); printf("\nBiolib loaded successfully! \n");
/************************************************************************* * Установка отпечатка * *************************************************************************/
// Открываем сессию PKCS#11 в первом найденном слоте CK_SESSION_HANDLE session; CK_ULONG slotCount; CK_SLOT_ID_PTR slots;
rv = functionList->C_GetSlotList(CK_TRUE, NULL_PTR, &slotCount); CHECK_AND_LOG(" C_GetSlotList (number of slots)", rv == CKR_OK, rvToStr(rv), finalizeBio); CHECK_AND_LOG(" Checking available tokens", slotCount > 0, " No tokens available", finalizeBio); slots= (CK_SLOT_ID_PTR)malloc(slotCount *sizeof(CK_SLOT_ID)); CHECK(" Memory allocation for slots", slots!=NULL, finalizeBio); rv = functionList->C_GetSlotList(CK_TRUE, slots, &slotCount); CHECK_AND_LOG(" C_GetSlotList", rv == CKR_OK, rvToStr(rv), freeSlots); printf(" Slots available: %d\n", (int)slotCount); rv = functionList->C_OpenSession(slots[0], CKF_SERIAL_SESSION | CKF_RW_SESSION, NULL_PTR, NULL_PTR, &session); CHECK_AND_LOG(" C_OpenSession", rv == CKR_OK, rvToStr(rv), freeSlots);
// Логин от администратора
rv = functionList->C_Login(session, CKU_SO, SO_PIN, SO_PIN_LEN); CHECK_AND_LOG(" C_Login", rv == CKR_OK, rvToStr(rv), closeSession); printf("Initialization has been completed successfully.\n");
// Проверка наличия сканеров для начала работы CK_ULONG scannersCount =0; r =listScannersFunc(NULL, &scannersCount); CHECK_AND_LOG(" BIO_ListScanners", r == BIO_SUCCESS, bioRvToStr(r), closeSession);
if (scannersCount ==0) { printf("\n\nCan't set fingerprint without scanner. Sample will fe finished.\n\n"); goto closeSession; }
// Получение информации об отпечатке BIO_FINGERPRINT_INFO fpInfo; CK_ULONG fpCount; r =getFPInfoFunc(session, &fpInfo, NULL, &fpCount);
if (r != BIO_FINGERPRINT_NOT_FOUND) { printf("\n\nUpdating fingerprint\nAuthentication needed\n\n"); r =authFunc(session, 0, 0, 0, 0); CHECK_AND_LOG(" BIO_Authenticate", r == BIO_SUCCESS, bioRvToStr(r), logout); } else { printf("\n\nCreating new fingerprint \n\n"); }
// Создание или обновление отпечатка BIO_FINGERPRINT_SCAN_PARAMS scanParams[]= { { BIO_FT_LEFT_THUMB, 4 }, { BIO_FT_LEFT_INDEX, 4 }, { BIO_FT_LEFT_MIDDLE, 4 }, };
CK_ULONG scanParamsCount =sizeof(scanParams) /sizeof(BIO_FINGERPRINT_SCAN_PARAMS);
BIO_FINGERPRINT_SCAN_STATUS_PTR status = (BIO_FINGERPRINT_SCAN_STATUS_PTR) malloc(scanParamsCount *sizeof(BIO_FINGERPRINT_SCAN_STATUS)); CK_ULONG statusCount = scanParamsCount;
BIO_FINGERPRINT_TYPE nextToScan; r =setFPInitFunc(session, scanParams, scanParamsCount, &nextToScan); CHECK_AND_LOG(" BIO_SetFingerprintInit", r == BIO_SUCCESS, bioRvToStr(r), freeMemory);
while (1) { r =setFPStatus(session, status, &statusCount); CHECK_AND_LOG(" BIO_SetFingerprintStatus", r == BIO_SUCCESS, bioRvToStr(r), freeMemory);
printf("\nStatus:\n");
for (size_ti=0; i< statusCount; ++i) { printf("\nType %s: %lu / %lu\n", fingerprintTypeToString(status[i].type), status[i].currentScansCount, status[i].targetScansCount); }
if (nextToScan== BIO_FT_UNKNOWN) { break; }
printf("\nNext: %s\n", fingerprintTypeToString(nextToScan));
r =setFPScan(session, 0, &nextToScan); if (r == BIO_SUCCESS) { printf("successfully scanned\n"); } elseif (r == BIO_UNACCEPTABLE_FINGERPRINT) { printf("fingerprint not recognized. Try again\n"); } else { printf("BIO_SetFingerprintScan failed"); goto logout; } }
CK_ULONG fingerprintId =0; r =setFPFinal(session, &fingerprintId); CHECK_AND_LOG(" BIO_SetFingerprintFinal", r == BIO_SUCCESS, bioRvToStr(r), freeMemory); printf("\n\nFingerprint was set correctly, fingerprint id: %lu\n", fingerprintId);
/************************************************************************* * Освобождение ресурсов * *************************************************************************/
errorCode = 0; freeMemory: free(status); logout: rv = functionList->C_Logout(session); CHECK_RELEASE_AND_LOG(" C_Logout", rv == CKR_OK, rvToStr(rv), errorCode); closeSession: rv = functionList->C_CloseSession(session); CHECK_RELEASE_AND_LOG(" C_CloseSession", rv == CKR_OK, rvToStr(rv), errorCode); freeSlots: free(slots); finalizeBio: r = finalizeFunc(); CHECK_RELEASE(" BIO_Finalize", r == BIO_SUCCESS, errorCode); unloadBio: CHECK_RELEASE(" FreeLibrary", FreeLibrary(moduleBiolib), errorCode); finalizePkcs: rv = functionList->C_Finalize(NULL_PTR); CHECK_RELEASE_AND_LOG(" C_Finalize", rv == CKR_OK, rvToStr(rv), errorCode); unloadPkcs: CHECK_RELEASE(" FreeLibrary", FreeLibrary(modulePkcs), errorCode); exit: if (errorCode) { printf("\n\nSome error occurred. Sample failed.\n"); } else { printf("\n\nSample has been completed successfully.\n"); } return errorCode; } |