pkcs11testmodule.cpp (28509B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* This Source Code Form is subject to the terms of the Mozilla Public 3 * License, v. 2.0. If a copy of the MPL was not distributed with this 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 5 6 // This is a testing PKCS #11 module that simulates a token being inserted and 7 // removed from a slot every 50ms. This is achieved mainly in 8 // Test_C_WaitForSlotEvent. If the application that loaded this module calls 9 // C_WaitForSlotEvent, this module waits for 50ms and returns, having changed 10 // its internal state to report that the token has either been inserted or 11 // removed, as appropriate. 12 // This module also provides an alternate token that is always present for tests 13 // that don't want the cyclic behavior described above. 14 15 #include <assert.h> 16 #include <string.h> 17 18 #ifdef _WIN32 19 # include <windows.h> // for Sleep 20 #else 21 # include <unistd.h> // for usleep 22 #endif 23 24 #include "pkcs11t.h" 25 26 #undef CK_DECLARE_FUNCTION 27 28 #ifdef _WIN32 29 #define CK_DECLARE_FUNCTION(rtype, func) extern rtype __declspec(dllexport) func 30 #else 31 #define CK_DECLARE_FUNCTION(rtype, func) extern rtype func 32 #endif 33 34 #include "pkcs11.h" 35 36 #if __cplusplus < 201103L 37 # include <prtypes.h> 38 # define static_assert(condition, message) PR_STATIC_ASSERT(condition) 39 #endif 40 41 CK_RV Test_C_Initialize(CK_VOID_PTR) { return CKR_OK; } 42 43 CK_RV Test_C_Finalize(CK_VOID_PTR) { return CKR_OK; } 44 45 static const CK_VERSION CryptokiVersion = {2, 2}; 46 static const CK_VERSION TestLibraryVersion = {0, 0}; 47 static const char TestLibraryDescription[] = "Test PKCS11 Library"; 48 static const char TestManufacturerID[] = "Test PKCS11 Manufacturer ID"; 49 50 /* The dest buffer is one in the CK_INFO or CK_TOKEN_INFO structs. 51 * Those buffers are padded with spaces. DestSize corresponds to the declared 52 * size for those buffers (e.g. 32 for `char foo[32]`). 53 * The src buffer is a string literal. SrcSize includes the string 54 * termination character (e.g. 4 for `const char foo[] = "foo"` */ 55 template <size_t DestSize, size_t SrcSize> 56 void CopyString(unsigned char (&dest)[DestSize], const char (&src)[SrcSize]) { 57 static_assert(DestSize >= SrcSize - 1, "DestSize >= SrcSize - 1"); 58 memcpy(dest, src, SrcSize - 1); 59 memset(dest + SrcSize - 1, ' ', DestSize - SrcSize + 1); 60 } 61 62 CK_RV Test_C_GetInfo(CK_INFO_PTR pInfo) { 63 if (!pInfo) { 64 return CKR_ARGUMENTS_BAD; 65 } 66 67 pInfo->cryptokiVersion = CryptokiVersion; 68 CopyString(pInfo->manufacturerID, TestManufacturerID); 69 pInfo->flags = 0; // must be 0 70 CopyString(pInfo->libraryDescription, TestLibraryDescription); 71 pInfo->libraryVersion = TestLibraryVersion; 72 return CKR_OK; 73 } 74 75 CK_RV Test_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR) { return CKR_OK; } 76 77 static int tokenPresent = 0; 78 79 // The token in slot 4 has 4 objects: 80 // 1. CKO_PROFILE with CKP_PUBLIC_CERTIFICATES_TOKEN 81 // 2. CKO_PROFILE with CKP_BASELINE_PROVIDER 82 // 3. CKO_CERTIFICATE with CKA_ID "\x00..\x0f" 83 // 4. CKO_CERTIFICATE with CKA_ID "\x10..\x1f" 84 static bool readingProfile = false; 85 static const CK_PROFILE_ID profiles[] = {CKP_PUBLIC_CERTIFICATES_TOKEN, 86 CKP_BASELINE_PROVIDER}; 87 static int profileIndex = 0; 88 89 static bool readingCert = false; 90 static const unsigned char certId1[] = { 91 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 92 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f 93 }; 94 static const char *certLabel1 = "cert1"; 95 static const unsigned char certId2[] = { 96 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 97 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f 98 }; 99 static const char *certLabel2 = "cert2"; 100 101 static const unsigned char certValue[] = { 102 0x30, 0x82, 0x01, 0x54, 0x30, 0x81, 0xfc, 0xa0, 0x03, 0x02, 0x01, 0x02, 103 0x02, 0x02, 0x0e, 0x42, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 104 0x3d, 0x04, 0x03, 0x02, 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 105 0x55, 0x04, 0x03, 0x13, 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 106 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x30, 0x31, 0x32, 0x31, 107 0x39, 0x30, 0x39, 0x30, 0x32, 0x34, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x31, 108 0x30, 0x33, 0x31, 0x39, 0x30, 0x39, 0x30, 0x32, 0x34, 0x39, 0x5a, 0x30, 109 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x0a, 110 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41, 0x30, 0x59, 111 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 112 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 113 0x04, 0x24, 0xd1, 0x96, 0xcc, 0x72, 0x36, 0xbb, 0xd6, 0x04, 0x36, 0x14, 114 0x59, 0x9a, 0x27, 0x24, 0x6b, 0x03, 0x7c, 0x02, 0x69, 0x68, 0x50, 0x70, 115 0x52, 0xe5, 0x5f, 0xe1, 0xf1, 0xd4, 0x0a, 0x00, 0x18, 0x76, 0x14, 0xa3, 116 0xed, 0x7d, 0xc5, 0x0a, 0xfe, 0xe4, 0x6f, 0x09, 0xf8, 0xcd, 0xe8, 0x5a, 117 0x39, 0x81, 0xf4, 0xcc, 0x25, 0xbe, 0x26, 0x76, 0xe1, 0x23, 0x52, 0x09, 118 0x6f, 0xbd, 0xf1, 0x75, 0xbe, 0xa3, 0x3c, 0x30, 0x3a, 0x30, 0x14, 0x06, 119 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x01, 0x01, 120 0xff, 0x04, 0x04, 0x03, 0x02, 0x02, 0x04, 0x30, 0x12, 0x06, 0x03, 0x55, 121 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 122 0x02, 0x01, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 123 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x0a, 0x06, 0x08, 0x2a, 124 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 125 0x02, 0x20, 0x76, 0x56, 0x09, 0xe9, 0x79, 0xc2, 0x62, 0x28, 0xfc, 0x48, 126 0xf8, 0xac, 0x73, 0xbb, 0xe1, 0xe5, 0x79, 0x93, 0x78, 0x05, 0x4b, 0x45, 127 0x08, 0xcf, 0x10, 0x9f, 0x0d, 0xb9, 0x50, 0x7d, 0x70, 0x24, 0x02, 0x20, 128 0x27, 0x52, 0xe7, 0x9e, 0x42, 0xe3, 0xb2, 0x4d, 0xbb, 0x7d, 0xa3, 0x81, 129 0x5f, 0x7f, 0x0f, 0x3a, 0x55, 0x34, 0xfa, 0x86, 0x35, 0xcb, 0x68, 0x4f, 130 0xad, 0x67, 0x67, 0x05, 0x36, 0xcb, 0x11, 0x4d 131 }; 132 static const unsigned char certSerial[] = { 133 0x02, 0x02, 0x0e, 0x42 134 }; 135 static const unsigned char certIssuer[] = { 136 0x30, 0x15, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 137 0x0a, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x41 138 }; 139 140 static const struct cert { 141 const unsigned char *id; 142 size_t idLen; 143 const char *label; 144 } certs[] = { 145 { certId1, sizeof(certId1), certLabel1 }, 146 { certId2, sizeof(certId2), certLabel2 } 147 }; 148 static int certIndex = 0; 149 static CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE; 150 static bool certIdGiven = false; 151 152 CK_RV Test_C_GetSlotList(CK_BBOOL limitToTokensPresent, 153 CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { 154 if (!pulCount) { 155 return CKR_ARGUMENTS_BAD; 156 } 157 158 CK_SLOT_ID slots[4]; 159 CK_ULONG slotCount = 0; 160 161 // We always return slot 2 and 4. 162 slots[slotCount++] = 2; 163 slots[slotCount++] = 4; 164 165 // Slot 1 is a removable slot where a token is present if 166 // tokenPresent = CK_TRUE. 167 if (tokenPresent || !limitToTokensPresent) { 168 slots[slotCount++] = 1; 169 } 170 171 // Slot 3 is a removable slot which never has a token. 172 if (!limitToTokensPresent) { 173 slots[slotCount++] = 3; 174 } 175 176 if (pSlotList) { 177 if (*pulCount < slotCount) { 178 return CKR_BUFFER_TOO_SMALL; 179 } 180 memcpy(pSlotList, slots, sizeof(CK_SLOT_ID) * slotCount); 181 } 182 183 *pulCount = slotCount; 184 return CKR_OK; 185 } 186 187 static const char TestSlotDescription[] = "Test PKCS11 Slot"; 188 static const char TestSlot2Description[] = "Test PKCS11 Slot 二"; 189 static const char TestSlot3Description[] = "Empty PKCS11 Slot"; 190 static const char TestSlot4Description[] = "Test PKCS11 Public Certs Slot"; 191 192 CK_RV Test_C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { 193 if (!pInfo) { 194 return CKR_ARGUMENTS_BAD; 195 } 196 197 switch (slotID) { 198 case 1: 199 CopyString(pInfo->slotDescription, TestSlotDescription); 200 pInfo->flags = 201 (tokenPresent ? CKF_TOKEN_PRESENT : 0) | CKF_REMOVABLE_DEVICE; 202 break; 203 case 2: 204 CopyString(pInfo->slotDescription, TestSlot2Description); 205 pInfo->flags = CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE; 206 break; 207 case 3: 208 CopyString(pInfo->slotDescription, TestSlot3Description); 209 pInfo->flags = CKF_REMOVABLE_DEVICE; 210 break; 211 case 4: 212 CopyString(pInfo->slotDescription, TestSlot4Description); 213 pInfo->flags = CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE; 214 break; 215 default: 216 return CKR_ARGUMENTS_BAD; 217 } 218 219 CopyString(pInfo->manufacturerID, TestManufacturerID); 220 pInfo->hardwareVersion = TestLibraryVersion; 221 pInfo->firmwareVersion = TestLibraryVersion; 222 return CKR_OK; 223 } 224 225 // Deliberately include énye to ensure we're handling encoding correctly. 226 // The PKCS #11 base specification v2.20 specifies that strings be encoded 227 // as UTF-8. 228 static const char TestTokenLabel[] = "Test PKCS11 Tokeñ Label"; 229 static const char TestToken2Label[] = "Test PKCS11 Tokeñ 2 Label"; 230 static const char TestToken4Label[] = "Test PKCS11 Public Certs Token"; 231 static const char TestTokenModel[] = "Test Model"; 232 233 CK_RV Test_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { 234 if (!pInfo) { 235 return CKR_ARGUMENTS_BAD; 236 } 237 238 switch (slotID) { 239 case 1: 240 CopyString(pInfo->label, TestTokenLabel); 241 break; 242 case 2: 243 CopyString(pInfo->label, TestToken2Label); 244 break; 245 case 4: 246 CopyString(pInfo->label, TestToken4Label); 247 break; 248 default: 249 return CKR_ARGUMENTS_BAD; 250 } 251 252 CopyString(pInfo->manufacturerID, TestManufacturerID); 253 CopyString(pInfo->model, TestTokenModel); 254 memset(pInfo->serialNumber, 0, sizeof(pInfo->serialNumber)); 255 pInfo->flags = CKF_TOKEN_INITIALIZED; 256 pInfo->ulMaxSessionCount = 1; 257 pInfo->ulSessionCount = 0; 258 pInfo->ulMaxRwSessionCount = 1; 259 pInfo->ulRwSessionCount = 0; 260 pInfo->ulMaxPinLen = 4; 261 pInfo->ulMinPinLen = 4; 262 pInfo->ulTotalPublicMemory = 1024; 263 pInfo->ulFreePublicMemory = 1024; 264 pInfo->ulTotalPrivateMemory = 1024; 265 pInfo->ulFreePrivateMemory = 1024; 266 pInfo->hardwareVersion = TestLibraryVersion; 267 pInfo->firmwareVersion = TestLibraryVersion; 268 memset(pInfo->utcTime, 0, sizeof(pInfo->utcTime)); 269 return CKR_OK; 270 } 271 272 CK_RV Test_C_GetMechanismList(CK_SLOT_ID, CK_MECHANISM_TYPE_PTR, 273 CK_ULONG_PTR pulCount) { 274 if (!pulCount) { 275 return CKR_ARGUMENTS_BAD; 276 } 277 278 *pulCount = 0; 279 return CKR_OK; 280 } 281 282 CK_RV Test_C_GetMechanismInfo(CK_SLOT_ID, CK_MECHANISM_TYPE, 283 CK_MECHANISM_INFO_PTR) { 284 return CKR_OK; 285 } 286 287 CK_RV Test_C_InitToken(CK_SLOT_ID, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR) { 288 return CKR_OK; 289 } 290 291 CK_RV Test_C_InitPIN(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG) { 292 return CKR_FUNCTION_NOT_SUPPORTED; 293 } 294 295 CK_RV Test_C_SetPIN(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG, 296 CK_UTF8CHAR_PTR, CK_ULONG) { 297 return CKR_FUNCTION_NOT_SUPPORTED; 298 } 299 300 CK_RV Test_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY, 301 CK_SESSION_HANDLE_PTR phSession) { 302 switch (slotID) { 303 case 1: 304 *phSession = 1; 305 break; 306 case 2: 307 *phSession = 2; 308 break; 309 case 4: 310 *phSession = 4; 311 break; 312 default: 313 return CKR_ARGUMENTS_BAD; 314 } 315 316 return CKR_OK; 317 } 318 319 CK_RV Test_C_CloseSession(CK_SESSION_HANDLE) { return CKR_OK; } 320 321 CK_RV Test_C_CloseAllSessions(CK_SLOT_ID) { return CKR_OK; } 322 323 CK_RV Test_C_GetSessionInfo(CK_SESSION_HANDLE hSession, 324 CK_SESSION_INFO_PTR pInfo) { 325 if (!pInfo) { 326 return CKR_ARGUMENTS_BAD; 327 } 328 329 switch (hSession) { 330 case 1: 331 pInfo->slotID = 1; 332 break; 333 case 2: 334 pInfo->slotID = 2; 335 break; 336 case 4: 337 pInfo->slotID = 4; 338 break; 339 default: 340 return CKR_ARGUMENTS_BAD; 341 } 342 343 pInfo->state = CKS_RO_PUBLIC_SESSION; 344 pInfo->flags = CKF_SERIAL_SESSION; 345 return CKR_OK; 346 } 347 348 CK_RV Test_C_GetOperationState(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { 349 return CKR_FUNCTION_NOT_SUPPORTED; 350 } 351 352 CK_RV Test_C_SetOperationState(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, 353 CK_OBJECT_HANDLE, CK_OBJECT_HANDLE) { 354 return CKR_FUNCTION_NOT_SUPPORTED; 355 } 356 357 CK_RV Test_C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG) { 358 return CKR_FUNCTION_NOT_SUPPORTED; 359 } 360 361 CK_RV Test_C_Logout(CK_SESSION_HANDLE) { return CKR_FUNCTION_NOT_SUPPORTED; } 362 363 CK_RV Test_C_CreateObject(CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, 364 CK_OBJECT_HANDLE_PTR) { 365 return CKR_FUNCTION_NOT_SUPPORTED; 366 } 367 368 CK_RV Test_C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, 369 CK_ULONG, CK_OBJECT_HANDLE_PTR) { 370 return CKR_FUNCTION_NOT_SUPPORTED; 371 } 372 373 CK_RV Test_C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) { 374 return CKR_FUNCTION_NOT_SUPPORTED; 375 } 376 377 CK_RV Test_C_GetObjectSize(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR) { 378 return CKR_FUNCTION_NOT_SUPPORTED; 379 } 380 381 CK_RV Test_C_GetAttributeValue(CK_SESSION_HANDLE hSession, 382 CK_OBJECT_HANDLE hObject, 383 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { 384 if (hSession == 4) { 385 switch (hObject) { 386 case 1: 387 case 2: 388 for (CK_ULONG count = 0; count < ulCount; count++) { 389 if (pTemplate[count].type == CKA_PROFILE_ID) { 390 if (pTemplate[count].pValue) { 391 assert(pTemplate[count].ulValueLen == sizeof(CK_ULONG)); 392 CK_ULONG value = profiles[hObject - 1]; 393 memcpy(pTemplate[count].pValue, &value, sizeof(value)); 394 } else { 395 pTemplate[count].ulValueLen = sizeof(CK_ULONG); 396 } 397 } else { 398 pTemplate[count].ulValueLen = (CK_ULONG)-1; 399 } 400 } 401 return CKR_OK; 402 case 3: 403 case 4: 404 for (CK_ULONG count = 0; count < ulCount; count++) { 405 switch (pTemplate[count].type) { 406 case CKA_TOKEN: 407 if (pTemplate[count].pValue) { 408 assert(pTemplate[count].ulValueLen == sizeof(CK_BBOOL)); 409 CK_BBOOL value = true; 410 memcpy(pTemplate[count].pValue, &value, sizeof(value)); 411 } else { 412 pTemplate[count].ulValueLen = sizeof(CK_BBOOL); 413 } 414 break; 415 416 case CKA_LABEL: { 417 const char *label = certs[hObject - 3].label; 418 size_t labelLen = strlen(label); 419 if (pTemplate[count].pValue) { 420 if (pTemplate[count].ulValueLen >= labelLen) { 421 memcpy(pTemplate[count].pValue, label, labelLen); 422 } else { 423 pTemplate[count].ulValueLen = CK_UNAVAILABLE_INFORMATION; 424 } 425 } else { 426 pTemplate[count].ulValueLen = labelLen; 427 } 428 break; 429 } 430 431 #define BYTEARRAY_CASE(label, array) \ 432 case label: \ 433 if (pTemplate[count].pValue) { \ 434 if (pTemplate[count].ulValueLen >= sizeof(array)) { \ 435 memcpy(pTemplate[count].pValue, array, sizeof(array)); \ 436 } else { \ 437 pTemplate[count].ulValueLen = CK_UNAVAILABLE_INFORMATION; \ 438 } \ 439 } else { \ 440 pTemplate[count].ulValueLen = sizeof(array); \ 441 } \ 442 break; 443 444 BYTEARRAY_CASE(CKA_VALUE, certValue) 445 BYTEARRAY_CASE(CKA_SERIAL_NUMBER, certSerial) 446 BYTEARRAY_CASE(CKA_ISSUER, certIssuer) 447 448 default: 449 pTemplate[count].ulValueLen = CK_UNAVAILABLE_INFORMATION; 450 break; 451 } 452 } 453 return CKR_OK; 454 default: 455 break; 456 } 457 } 458 return CKR_FUNCTION_NOT_SUPPORTED; 459 } 460 461 CK_RV Test_C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, 462 CK_ATTRIBUTE_PTR, CK_ULONG) { 463 return CKR_FUNCTION_NOT_SUPPORTED; 464 } 465 466 CK_RV Test_C_FindObjectsInit(CK_SESSION_HANDLE hSession, 467 CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { 468 // Slot 4 469 if (hSession == 4) { 470 CK_OBJECT_CLASS objectClass = CKO_DATA; 471 CK_BYTE *id = NULL; 472 CK_ULONG idLen = 0; 473 for (CK_ULONG count = 0; count < ulCount; count++) { 474 CK_ATTRIBUTE attribute = pTemplate[count]; 475 switch (attribute.type) { 476 case CKA_CLASS: 477 assert(attribute.ulValueLen == sizeof(CK_OBJECT_CLASS)); 478 479 memcpy(&objectClass, attribute.pValue, attribute.ulValueLen); 480 break; 481 case CKA_ID: 482 id = (CK_BYTE *)attribute.pValue; 483 idLen = attribute.ulValueLen; 484 break; 485 default: 486 break; 487 } 488 } 489 490 switch (objectClass) { 491 case CKO_PROFILE: 492 readingProfile = true; 493 profileIndex = 0; 494 break; 495 case CKO_CERTIFICATE: 496 readingCert = true; 497 certIndex = 0; 498 if (id) { 499 certIdGiven = true; 500 for (size_t count = 0; count < sizeof(certs) / sizeof(certs[0]); count++) { 501 if (certs[count].idLen == idLen && 502 memcmp(certs[count].id, id, idLen) == 0) { 503 certHandle = count + 3; 504 break; 505 } 506 } 507 } 508 break; 509 default: 510 break; 511 } 512 } 513 return CKR_OK; 514 } 515 516 CK_RV Test_C_FindObjects(CK_SESSION_HANDLE hSession, 517 CK_OBJECT_HANDLE_PTR phObject, 518 CK_ULONG ulMaxObjectCount, 519 CK_ULONG_PTR pulObjectCount) { 520 if (readingProfile) { 521 assert(hSession == 4); 522 CK_ULONG count = ulMaxObjectCount; 523 size_t remaining = sizeof(profiles) / sizeof(profiles[0]) - profileIndex; 524 if (count > remaining) { 525 count = remaining; 526 } 527 for (CK_ULONG i = 0; i < count; i++) { 528 phObject[i] = i + 1; 529 } 530 profileIndex += count; 531 *pulObjectCount = count; 532 } else if (readingCert) { 533 assert(hSession == 4); 534 if (!certIdGiven) { 535 CK_ULONG count = ulMaxObjectCount; 536 size_t remaining = sizeof(certs) / sizeof(certs[0]) - certIndex; 537 if (count > remaining) { 538 count = remaining; 539 } 540 for (CK_ULONG i = 0; i < count; i++) { 541 phObject[i] = i + 3; 542 } 543 *pulObjectCount = count; 544 certIndex += count; 545 } else if (certHandle != CK_INVALID_HANDLE) { 546 if (certIndex == 0 && ulMaxObjectCount > 0) { 547 phObject[0] = certHandle; 548 *pulObjectCount = 1; 549 certIndex = 1; 550 } else { 551 *pulObjectCount = 0; 552 } 553 } else { 554 *pulObjectCount = 0; 555 } 556 } else { 557 *pulObjectCount = 0; 558 } 559 return CKR_OK; 560 } 561 562 CK_RV Test_C_FindObjectsFinal(CK_SESSION_HANDLE hSession) { 563 readingProfile = false; 564 readingCert = false; 565 certHandle = CK_INVALID_HANDLE; 566 certIdGiven = false; 567 return CKR_OK; 568 } 569 570 CK_RV Test_C_EncryptInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, 571 CK_OBJECT_HANDLE) { 572 return CKR_FUNCTION_NOT_SUPPORTED; 573 } 574 575 CK_RV Test_C_Encrypt(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, 576 CK_ULONG_PTR) { 577 return CKR_FUNCTION_NOT_SUPPORTED; 578 } 579 580 CK_RV Test_C_EncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, 581 CK_BYTE_PTR, CK_ULONG_PTR) { 582 return CKR_FUNCTION_NOT_SUPPORTED; 583 } 584 585 CK_RV Test_C_EncryptFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { 586 return CKR_FUNCTION_NOT_SUPPORTED; 587 } 588 589 CK_RV Test_C_DecryptInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, 590 CK_OBJECT_HANDLE) { 591 return CKR_FUNCTION_NOT_SUPPORTED; 592 } 593 594 CK_RV Test_C_Decrypt(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, 595 CK_ULONG_PTR) { 596 return CKR_FUNCTION_NOT_SUPPORTED; 597 } 598 599 CK_RV Test_C_DecryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, 600 CK_BYTE_PTR, CK_ULONG_PTR) { 601 return CKR_FUNCTION_NOT_SUPPORTED; 602 } 603 604 CK_RV Test_C_DecryptFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { 605 return CKR_FUNCTION_NOT_SUPPORTED; 606 } 607 608 CK_RV Test_C_DigestInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR) { 609 return CKR_FUNCTION_NOT_SUPPORTED; 610 } 611 612 CK_RV Test_C_Digest(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, 613 CK_ULONG_PTR) { 614 return CKR_FUNCTION_NOT_SUPPORTED; 615 } 616 617 CK_RV Test_C_DigestUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { 618 return CKR_FUNCTION_NOT_SUPPORTED; 619 } 620 621 CK_RV Test_C_DigestKey(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) { 622 return CKR_FUNCTION_NOT_SUPPORTED; 623 } 624 625 CK_RV Test_C_DigestFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { 626 return CKR_FUNCTION_NOT_SUPPORTED; 627 } 628 629 CK_RV Test_C_SignInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE) { 630 return CKR_FUNCTION_NOT_SUPPORTED; 631 } 632 633 CK_RV Test_C_Sign(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, 634 CK_ULONG_PTR) { 635 return CKR_FUNCTION_NOT_SUPPORTED; 636 } 637 638 CK_RV Test_C_SignUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { 639 return CKR_FUNCTION_NOT_SUPPORTED; 640 } 641 642 CK_RV Test_C_SignFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { 643 return CKR_FUNCTION_NOT_SUPPORTED; 644 } 645 646 CK_RV Test_C_SignRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, 647 CK_OBJECT_HANDLE) { 648 return CKR_FUNCTION_NOT_SUPPORTED; 649 } 650 651 CK_RV Test_C_SignRecover(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, 652 CK_ULONG_PTR) { 653 return CKR_FUNCTION_NOT_SUPPORTED; 654 } 655 656 CK_RV Test_C_VerifyInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE) { 657 return CKR_FUNCTION_NOT_SUPPORTED; 658 } 659 660 CK_RV Test_C_Verify(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, 661 CK_ULONG) { 662 return CKR_FUNCTION_NOT_SUPPORTED; 663 } 664 665 CK_RV Test_C_VerifyUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { 666 return CKR_FUNCTION_NOT_SUPPORTED; 667 } 668 669 CK_RV Test_C_VerifyFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { 670 return CKR_FUNCTION_NOT_SUPPORTED; 671 } 672 673 CK_RV Test_C_VerifyRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, 674 CK_OBJECT_HANDLE) { 675 return CKR_FUNCTION_NOT_SUPPORTED; 676 } 677 678 CK_RV Test_C_VerifyRecover(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, 679 CK_BYTE_PTR, CK_ULONG_PTR) { 680 return CKR_FUNCTION_NOT_SUPPORTED; 681 } 682 683 CK_RV Test_C_DigestEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, 684 CK_BYTE_PTR, CK_ULONG_PTR) { 685 return CKR_FUNCTION_NOT_SUPPORTED; 686 } 687 688 CK_RV Test_C_DecryptDigestUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, 689 CK_BYTE_PTR, CK_ULONG_PTR) { 690 return CKR_FUNCTION_NOT_SUPPORTED; 691 } 692 693 CK_RV Test_C_SignEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, 694 CK_BYTE_PTR, CK_ULONG_PTR) { 695 return CKR_FUNCTION_NOT_SUPPORTED; 696 } 697 698 CK_RV Test_C_DecryptVerifyUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, 699 CK_BYTE_PTR, CK_ULONG_PTR) { 700 return CKR_FUNCTION_NOT_SUPPORTED; 701 } 702 703 CK_RV Test_C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, 704 CK_ULONG, CK_OBJECT_HANDLE_PTR) { 705 return CKR_FUNCTION_NOT_SUPPORTED; 706 } 707 708 CK_RV Test_C_GenerateKeyPair(CK_SESSION_HANDLE, CK_MECHANISM_PTR, 709 CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, 710 CK_ULONG, CK_OBJECT_HANDLE_PTR, 711 CK_OBJECT_HANDLE_PTR) { 712 return CKR_FUNCTION_NOT_SUPPORTED; 713 } 714 715 CK_RV Test_C_WrapKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, 716 CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { 717 return CKR_FUNCTION_NOT_SUPPORTED; 718 } 719 720 CK_RV Test_C_UnwrapKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, 721 CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, 722 CK_OBJECT_HANDLE_PTR) { 723 return CKR_FUNCTION_NOT_SUPPORTED; 724 } 725 726 CK_RV Test_C_DeriveKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, 727 CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR) { 728 return CKR_FUNCTION_NOT_SUPPORTED; 729 } 730 731 CK_RV Test_C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { 732 return CKR_FUNCTION_NOT_SUPPORTED; 733 } 734 735 CK_RV Test_C_GenerateRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { 736 return CKR_FUNCTION_NOT_SUPPORTED; 737 } 738 739 CK_RV Test_C_GetFunctionStatus(CK_SESSION_HANDLE) { 740 return CKR_FUNCTION_NOT_SUPPORTED; 741 } 742 743 CK_RV Test_C_CancelFunction(CK_SESSION_HANDLE) { 744 return CKR_FUNCTION_NOT_SUPPORTED; 745 } 746 747 CK_RV Test_C_WaitForSlotEvent(CK_FLAGS, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR) { 748 #ifdef _WIN32 749 Sleep(50); // Sleep takes the duration argument as milliseconds 750 #else 751 usleep(50000); // usleep takes the duration argument as microseconds 752 #endif 753 *pSlot = 1; 754 tokenPresent = !tokenPresent; 755 return CKR_OK; 756 } 757 758 static CK_FUNCTION_LIST FunctionList = {{2, 2}, 759 Test_C_Initialize, 760 Test_C_Finalize, 761 Test_C_GetInfo, 762 Test_C_GetFunctionList, 763 Test_C_GetSlotList, 764 Test_C_GetSlotInfo, 765 Test_C_GetTokenInfo, 766 Test_C_GetMechanismList, 767 Test_C_GetMechanismInfo, 768 Test_C_InitToken, 769 Test_C_InitPIN, 770 Test_C_SetPIN, 771 Test_C_OpenSession, 772 Test_C_CloseSession, 773 Test_C_CloseAllSessions, 774 Test_C_GetSessionInfo, 775 Test_C_GetOperationState, 776 Test_C_SetOperationState, 777 Test_C_Login, 778 Test_C_Logout, 779 Test_C_CreateObject, 780 Test_C_CopyObject, 781 Test_C_DestroyObject, 782 Test_C_GetObjectSize, 783 Test_C_GetAttributeValue, 784 Test_C_SetAttributeValue, 785 Test_C_FindObjectsInit, 786 Test_C_FindObjects, 787 Test_C_FindObjectsFinal, 788 Test_C_EncryptInit, 789 Test_C_Encrypt, 790 Test_C_EncryptUpdate, 791 Test_C_EncryptFinal, 792 Test_C_DecryptInit, 793 Test_C_Decrypt, 794 Test_C_DecryptUpdate, 795 Test_C_DecryptFinal, 796 Test_C_DigestInit, 797 Test_C_Digest, 798 Test_C_DigestUpdate, 799 Test_C_DigestKey, 800 Test_C_DigestFinal, 801 Test_C_SignInit, 802 Test_C_Sign, 803 Test_C_SignUpdate, 804 Test_C_SignFinal, 805 Test_C_SignRecoverInit, 806 Test_C_SignRecover, 807 Test_C_VerifyInit, 808 Test_C_Verify, 809 Test_C_VerifyUpdate, 810 Test_C_VerifyFinal, 811 Test_C_VerifyRecoverInit, 812 Test_C_VerifyRecover, 813 Test_C_DigestEncryptUpdate, 814 Test_C_DecryptDigestUpdate, 815 Test_C_SignEncryptUpdate, 816 Test_C_DecryptVerifyUpdate, 817 Test_C_GenerateKey, 818 Test_C_GenerateKeyPair, 819 Test_C_WrapKey, 820 Test_C_UnwrapKey, 821 Test_C_DeriveKey, 822 Test_C_SeedRandom, 823 Test_C_GenerateRandom, 824 Test_C_GetFunctionStatus, 825 Test_C_CancelFunction, 826 Test_C_WaitForSlotEvent}; 827 828 #ifdef _WIN32 829 __declspec(dllexport) 830 #endif 831 832 CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) { 833 *ppFunctionList = &FunctionList; 834 return CKR_OK; 835 }