|
|
1.1 ! root 1: /* ! 2: Copyright (c) 2008 TrueCrypt Foundation. All rights reserved. ! 3: ! 4: Governed by the TrueCrypt License 2.6 the full text of which is contained ! 5: in the file License.txt included in TrueCrypt binary and source code ! 6: distribution packages. ! 7: */ ! 8: ! 9: #include "Platform/Finally.h" ! 10: #include "Platform/ForEach.h" ! 11: ! 12: #if !defined (TC_WINDOWS) || defined (TC_PROTOTYPE) ! 13: # include "Platform/SerializerFactory.h" ! 14: # include "Platform/StringConverter.h" ! 15: # include "Platform/SystemException.h" ! 16: #else ! 17: # include "Dictionary.h" ! 18: # include "Language.h" ! 19: #endif ! 20: ! 21: #ifdef TC_UNIX ! 22: # include <dlfcn.h> ! 23: #endif ! 24: ! 25: #include "SecurityToken.h" ! 26: ! 27: #ifndef burn ! 28: # define burn Memory::Erase ! 29: #endif ! 30: ! 31: using namespace std; ! 32: ! 33: namespace TrueCrypt ! 34: { ! 35: SecurityTokenKeyfile::SecurityTokenKeyfile (const SecurityTokenKeyfilePath &path) ! 36: { ! 37: wstring pathStr = path; ! 38: unsigned long slotId; ! 39: ! 40: if (swscanf (pathStr.c_str(), TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/%lu", &slotId) != 1) ! 41: throw InvalidSecurityTokenKeyfilePath(); ! 42: ! 43: SlotId = slotId; ! 44: ! 45: size_t keyIdPos = pathStr.find (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/"); ! 46: if (keyIdPos == string::npos) ! 47: throw InvalidSecurityTokenKeyfilePath(); ! 48: ! 49: Id = pathStr.substr (keyIdPos + wstring (L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/").size()); ! 50: ! 51: vector <SecurityTokenKeyfile> keyfiles = SecurityToken::GetAvailableKeyfiles (&SlotId, Id); ! 52: ! 53: if (keyfiles.empty()) ! 54: throw SecurityTokenKeyfileNotFound(); ! 55: ! 56: *this = keyfiles.front(); ! 57: } ! 58: ! 59: SecurityTokenKeyfile::operator SecurityTokenKeyfilePath () const ! 60: { ! 61: wstringstream path; ! 62: path << TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX TC_SECURITY_TOKEN_KEYFILE_URL_SLOT L"/" << SlotId << L"/" TC_SECURITY_TOKEN_KEYFILE_URL_FILE L"/" << Id; ! 63: return path.str(); ! 64: } ! 65: ! 66: void SecurityToken::CheckLibraryStatus () ! 67: { ! 68: if (!Initialized) ! 69: throw SecurityTokenLibraryNotInitialized(); ! 70: } ! 71: ! 72: void SecurityToken::CloseLibrary () ! 73: { ! 74: if (Initialized) ! 75: { ! 76: CloseAllSessions(); ! 77: Pkcs11Functions->C_Finalize (NULL_PTR); ! 78: ! 79: #ifdef TC_WINDOWS ! 80: FreeLibrary (Pkcs11LibraryHandle); ! 81: #else ! 82: dlclose (Pkcs11LibraryHandle); ! 83: #endif ! 84: Initialized = false; ! 85: } ! 86: } ! 87: ! 88: void SecurityToken::CloseAllSessions () throw () ! 89: { ! 90: if (!Initialized) ! 91: return; ! 92: ! 93: typedef pair <CK_SLOT_ID, Pkcs11Session> SessionMapPair; ! 94: ! 95: foreach (SessionMapPair p, Sessions) ! 96: { ! 97: try ! 98: { ! 99: CloseSession (p.first); ! 100: } ! 101: catch (...) { } ! 102: } ! 103: } ! 104: ! 105: void SecurityToken::CloseSession (CK_SLOT_ID slotId) ! 106: { ! 107: if (Sessions.find (slotId) == Sessions.end()) ! 108: throw ParameterIncorrect (SRC_POS); ! 109: ! 110: Pkcs11Functions->C_CloseSession (Sessions[slotId].Handle); ! 111: Sessions.erase (Sessions.find (slotId)); ! 112: } ! 113: ! 114: void SecurityToken::CreateKeyfile (CK_SLOT_ID slotId, vector <byte> &keyfileData, const string &name) ! 115: { ! 116: if (name.empty()) ! 117: throw ParameterIncorrect (SRC_POS); ! 118: ! 119: LoginUserIfRequired (slotId); ! 120: ! 121: foreach (const SecurityTokenKeyfile &keyfile, GetAvailableKeyfiles (&slotId)) ! 122: { ! 123: if (keyfile.IdUtf8 == name) ! 124: throw SecurityTokenKeyfileAlreadyExists(); ! 125: } ! 126: ! 127: CK_OBJECT_CLASS dataClass = CKO_DATA; ! 128: CK_BBOOL trueVal = CK_TRUE; ! 129: ! 130: CK_ATTRIBUTE keyfileTemplate[] = ! 131: { ! 132: { CKA_CLASS, &dataClass, sizeof (dataClass) }, ! 133: { CKA_TOKEN, &trueVal, sizeof (trueVal) }, ! 134: { CKA_PRIVATE, &trueVal, sizeof (trueVal) }, ! 135: { CKA_LABEL, (CK_UTF8CHAR *) name.c_str(), name.size() }, ! 136: { CKA_VALUE, &keyfileData.front(), keyfileData.size() } ! 137: }; ! 138: ! 139: CK_OBJECT_HANDLE keyfileHandle; ! 140: ! 141: CK_RV status = Pkcs11Functions->C_CreateObject (Sessions[slotId].Handle, keyfileTemplate, array_capacity (keyfileTemplate), &keyfileHandle); ! 142: ! 143: switch (status) ! 144: { ! 145: case CKR_DATA_LEN_RANGE: ! 146: status = CKR_DEVICE_MEMORY; ! 147: break; ! 148: ! 149: case CKR_SESSION_READ_ONLY: ! 150: status = CKR_TOKEN_WRITE_PROTECTED; ! 151: break; ! 152: } ! 153: ! 154: if (status != CKR_OK) ! 155: throw Pkcs11Exception (status); ! 156: ! 157: // Some tokens report success even if the new object was truncated to fit in the available memory ! 158: vector <byte> objectData; ! 159: ! 160: GetObjectAttribute (slotId, keyfileHandle, CKA_VALUE, objectData); ! 161: finally_do_arg (vector <byte> *, &objectData, { burn (&finally_arg->front(), finally_arg->size()); }); ! 162: ! 163: if (objectData.size() != keyfileData.size()) ! 164: { ! 165: Pkcs11Functions->C_DestroyObject (Sessions[slotId].Handle, keyfileHandle); ! 166: throw Pkcs11Exception (CKR_DEVICE_MEMORY); ! 167: } ! 168: } ! 169: ! 170: void SecurityToken::DeleteKeyfile (const SecurityTokenKeyfile &keyfile) ! 171: { ! 172: LoginUserIfRequired (keyfile.SlotId); ! 173: ! 174: CK_RV status = Pkcs11Functions->C_DestroyObject (Sessions[keyfile.SlotId].Handle, keyfile.Handle); ! 175: if (status != CKR_OK) ! 176: throw Pkcs11Exception (status); ! 177: } ! 178: ! 179: vector <SecurityTokenKeyfile> SecurityToken::GetAvailableKeyfiles (CK_SLOT_ID *slotIdFilter, const wstring keyfileIdFilter) ! 180: { ! 181: bool unrecognizedTokenPresent = false; ! 182: vector <SecurityTokenKeyfile> keyfiles; ! 183: ! 184: foreach (const CK_SLOT_ID &slotId, GetTokenSlots()) ! 185: { ! 186: SecurityTokenInfo token; ! 187: ! 188: if (slotIdFilter && *slotIdFilter != slotId) ! 189: continue; ! 190: ! 191: try ! 192: { ! 193: LoginUserIfRequired (slotId); ! 194: token = GetTokenInfo (slotId); ! 195: } ! 196: catch (UserAbort &) ! 197: { ! 198: continue; ! 199: } ! 200: catch (Pkcs11Exception &e) ! 201: { ! 202: if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED) ! 203: { ! 204: unrecognizedTokenPresent = true; ! 205: continue; ! 206: } ! 207: ! 208: throw; ! 209: } ! 210: ! 211: foreach (const CK_OBJECT_HANDLE &dataHandle, GetObjects (slotId, CKO_DATA)) ! 212: { ! 213: SecurityTokenKeyfile keyfile; ! 214: keyfile.Handle = dataHandle; ! 215: keyfile.SlotId = slotId; ! 216: keyfile.Token = token; ! 217: ! 218: vector <byte> privateAttrib; ! 219: GetObjectAttribute (slotId, dataHandle, CKA_PRIVATE, privateAttrib); ! 220: ! 221: if (privateAttrib.size() == sizeof (CK_BBOOL) && *(CK_BBOOL *) &privateAttrib.front() != CK_TRUE) ! 222: continue; ! 223: ! 224: vector <byte> label; ! 225: GetObjectAttribute (slotId, dataHandle, CKA_LABEL, label); ! 226: label.push_back (0); ! 227: ! 228: keyfile.IdUtf8 = (char *) &label.front(); ! 229: ! 230: #if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE) ! 231: keyfile.Id = Utf8StringToWide ((const char *) &label.front()); ! 232: #else ! 233: keyfile.Id = StringConverter::ToWide ((const char *) &label.front()); ! 234: #endif ! 235: if (keyfile.Id.empty() || (!keyfileIdFilter.empty() && keyfileIdFilter != keyfile.Id)) ! 236: continue; ! 237: ! 238: keyfiles.push_back (keyfile); ! 239: ! 240: if (!keyfileIdFilter.empty()) ! 241: break; ! 242: } ! 243: } ! 244: ! 245: if (keyfiles.empty() && unrecognizedTokenPresent) ! 246: throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED); ! 247: ! 248: return keyfiles; ! 249: } ! 250: ! 251: list <SecurityTokenInfo> SecurityToken::GetAvailableTokens () ! 252: { ! 253: bool unrecognizedTokenPresent = false; ! 254: list <SecurityTokenInfo> tokens; ! 255: ! 256: foreach (const CK_SLOT_ID &slotId, GetTokenSlots()) ! 257: { ! 258: try ! 259: { ! 260: tokens.push_back (GetTokenInfo (slotId)); ! 261: } ! 262: catch (Pkcs11Exception &e) ! 263: { ! 264: if (e.GetErrorCode() == CKR_TOKEN_NOT_RECOGNIZED) ! 265: { ! 266: unrecognizedTokenPresent = true; ! 267: continue; ! 268: } ! 269: ! 270: throw; ! 271: } ! 272: } ! 273: ! 274: if (tokens.empty() && unrecognizedTokenPresent) ! 275: throw Pkcs11Exception (CKR_TOKEN_NOT_RECOGNIZED); ! 276: ! 277: return tokens; ! 278: } ! 279: ! 280: SecurityTokenInfo SecurityToken::GetTokenInfo (CK_SLOT_ID slotId) ! 281: { ! 282: CK_TOKEN_INFO info; ! 283: CK_RV status = Pkcs11Functions->C_GetTokenInfo (slotId, &info); ! 284: if (status != CKR_OK) ! 285: throw Pkcs11Exception (status); ! 286: ! 287: SecurityTokenInfo token; ! 288: token.SlotId = slotId; ! 289: token.Flags = info.flags; ! 290: ! 291: char label[sizeof (info.label) + 1]; ! 292: memset (label, 0, sizeof (label)); ! 293: memcpy (label, info.label, sizeof (info.label)); ! 294: ! 295: token.LabelUtf8 = label; ! 296: ! 297: size_t lastSpace = token.LabelUtf8.find_last_not_of (' '); ! 298: if (lastSpace == string::npos) ! 299: token.LabelUtf8.clear(); ! 300: else ! 301: token.LabelUtf8 = token.LabelUtf8.substr (0, lastSpace + 1); ! 302: ! 303: #if defined (TC_WINDOWS) && !defined (TC_PROTOTYPE) ! 304: token.Label = Utf8StringToWide (token.LabelUtf8); ! 305: #else ! 306: token.Label = StringConverter::ToWide (token.LabelUtf8); ! 307: #endif ! 308: return token; ! 309: } ! 310: ! 311: void SecurityToken::GetKeyfileData (const SecurityTokenKeyfile &keyfile, vector <byte> &keyfileData) ! 312: { ! 313: LoginUserIfRequired (keyfile.SlotId); ! 314: GetObjectAttribute (keyfile.SlotId, keyfile.Handle, CKA_VALUE, keyfileData); ! 315: } ! 316: ! 317: vector <CK_OBJECT_HANDLE> SecurityToken::GetObjects (CK_SLOT_ID slotId, CK_ATTRIBUTE_TYPE objectClass) ! 318: { ! 319: if (Sessions.find (slotId) == Sessions.end()) ! 320: throw ParameterIncorrect (SRC_POS); ! 321: ! 322: CK_ATTRIBUTE findTemplate; ! 323: findTemplate.type = CKA_CLASS; ! 324: findTemplate.pValue = &objectClass; ! 325: findTemplate.ulValueLen = sizeof (objectClass); ! 326: ! 327: CK_RV status = Pkcs11Functions->C_FindObjectsInit (Sessions[slotId].Handle, &findTemplate, 1); ! 328: if (status != CKR_OK) ! 329: throw Pkcs11Exception (status); ! 330: ! 331: finally_do_arg (CK_SLOT_ID, slotId, { Pkcs11Functions->C_FindObjectsFinal (Sessions[finally_arg].Handle); }); ! 332: ! 333: CK_ULONG objectCount; ! 334: vector <CK_OBJECT_HANDLE> objects; ! 335: ! 336: while (true) ! 337: { ! 338: CK_OBJECT_HANDLE object; ! 339: CK_RV status = Pkcs11Functions->C_FindObjects (Sessions[slotId].Handle, &object, 1, &objectCount); ! 340: if (status != CKR_OK) ! 341: throw Pkcs11Exception (status); ! 342: ! 343: if (objectCount != 1) ! 344: break; ! 345: ! 346: objects.push_back (object); ! 347: } ! 348: ! 349: return objects; ! 350: } ! 351: ! 352: void SecurityToken::GetObjectAttribute (CK_SLOT_ID slotId, CK_OBJECT_HANDLE tokenObject, CK_ATTRIBUTE_TYPE attributeType, vector <byte> &attributeValue) ! 353: { ! 354: attributeValue.clear(); ! 355: ! 356: if (Sessions.find (slotId) == Sessions.end()) ! 357: throw ParameterIncorrect (SRC_POS); ! 358: ! 359: CK_ATTRIBUTE attribute; ! 360: attribute.type = attributeType; ! 361: attribute.pValue = NULL_PTR; ! 362: ! 363: CK_RV status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1); ! 364: if (status != CKR_OK) ! 365: throw Pkcs11Exception (status); ! 366: ! 367: if (attribute.ulValueLen == 0) ! 368: return; ! 369: ! 370: attributeValue = vector <byte> (attribute.ulValueLen); ! 371: attribute.pValue = &attributeValue.front(); ! 372: ! 373: status = Pkcs11Functions->C_GetAttributeValue (Sessions[slotId].Handle, tokenObject, &attribute, 1); ! 374: if (status != CKR_OK) ! 375: throw Pkcs11Exception (status); ! 376: } ! 377: ! 378: list <CK_SLOT_ID> SecurityToken::GetTokenSlots () ! 379: { ! 380: CheckLibraryStatus(); ! 381: ! 382: list <CK_SLOT_ID> slots; ! 383: CK_ULONG slotCount; ! 384: ! 385: CK_RV status = Pkcs11Functions->C_GetSlotList (TRUE, NULL_PTR, &slotCount); ! 386: if (status != CKR_OK) ! 387: throw Pkcs11Exception (status); ! 388: ! 389: if (slotCount > 0) ! 390: { ! 391: vector <CK_SLOT_ID> slotArray (slotCount); ! 392: status = Pkcs11Functions->C_GetSlotList (TRUE, &slotArray.front(), &slotCount); ! 393: if (status != CKR_OK) ! 394: throw Pkcs11Exception (status); ! 395: ! 396: for (size_t i = 0; i < slotCount; i++) ! 397: { ! 398: CK_SLOT_INFO slotInfo; ! 399: status = Pkcs11Functions->C_GetSlotInfo (slotArray[i], &slotInfo); ! 400: ! 401: if (status != CKR_OK || !(slotInfo.flags & CKF_TOKEN_PRESENT)) ! 402: continue; ! 403: ! 404: slots.push_back (slotArray[i]); ! 405: } ! 406: } ! 407: ! 408: return slots; ! 409: } ! 410: ! 411: bool SecurityToken::IsKeyfilePathValid (const wstring &securityTokenKeyfilePath) ! 412: { ! 413: return securityTokenKeyfilePath.find (TC_SECURITY_TOKEN_KEYFILE_URL_PREFIX) == 0; ! 414: } ! 415: ! 416: void SecurityToken::Login (CK_SLOT_ID slotId, const string &pin) ! 417: { ! 418: if (Sessions.find (slotId) == Sessions.end()) ! 419: OpenSession (slotId); ! 420: else if (Sessions[slotId].UserLoggedIn) ! 421: return; ! 422: ! 423: CK_RV status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, (CK_CHAR_PTR) pin.c_str(), pin.size()); ! 424: ! 425: if (status != CKR_OK) ! 426: throw Pkcs11Exception (status); ! 427: ! 428: Sessions[slotId].UserLoggedIn = true; ! 429: } ! 430: ! 431: void SecurityToken::LoginUserIfRequired (CK_SLOT_ID slotId) ! 432: { ! 433: CheckLibraryStatus(); ! 434: CK_RV status; ! 435: ! 436: if (Sessions.find (slotId) == Sessions.end()) ! 437: { ! 438: OpenSession (slotId); ! 439: } ! 440: else ! 441: { ! 442: CK_SESSION_INFO sessionInfo; ! 443: status = Pkcs11Functions->C_GetSessionInfo (Sessions[slotId].Handle, &sessionInfo); ! 444: ! 445: if (status == CKR_OK) ! 446: { ! 447: Sessions[slotId].UserLoggedIn = (sessionInfo.state == CKS_RO_USER_FUNCTIONS || sessionInfo.state == CKS_RW_USER_FUNCTIONS); ! 448: } ! 449: else ! 450: { ! 451: try ! 452: { ! 453: CloseSession (slotId); ! 454: } ! 455: catch (...) { } ! 456: OpenSession (slotId); ! 457: } ! 458: } ! 459: ! 460: SecurityTokenInfo tokenInfo = GetTokenInfo (slotId); ! 461: ! 462: while (!Sessions[slotId].UserLoggedIn && (tokenInfo.Flags & CKF_LOGIN_REQUIRED)) ! 463: { ! 464: try ! 465: { ! 466: if (tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH) ! 467: { ! 468: status = Pkcs11Functions->C_Login (Sessions[slotId].Handle, CKU_USER, NULL_PTR, 0); ! 469: if (status != CKR_OK) ! 470: throw Pkcs11Exception (status); ! 471: } ! 472: else ! 473: { ! 474: string pin = tokenInfo.LabelUtf8; ! 475: if (tokenInfo.Label.empty()) ! 476: { ! 477: stringstream s; ! 478: s << "#" << slotId; ! 479: pin = s.str(); ! 480: } ! 481: ! 482: finally_do_arg (string*, &pin, { burn ((void *) finally_arg->c_str(), finally_arg->size()); }); ! 483: ! 484: (*PinCallback) (pin); ! 485: Login (slotId, pin); ! 486: } ! 487: ! 488: Sessions[slotId].UserLoggedIn = true; ! 489: } ! 490: catch (Pkcs11Exception &e) ! 491: { ! 492: CK_RV error = e.GetErrorCode(); ! 493: ! 494: if (error == CKR_USER_ALREADY_LOGGED_IN) ! 495: { ! 496: break; ! 497: } ! 498: else if (error == CKR_PIN_INCORRECT && !(tokenInfo.Flags & CKF_PROTECTED_AUTHENTICATION_PATH)) ! 499: { ! 500: (*WarningCallback) (Pkcs11Exception (CKR_PIN_INCORRECT)); ! 501: continue; ! 502: } ! 503: ! 504: throw; ! 505: } ! 506: } ! 507: } ! 508: ! 509: void SecurityToken::InitLibrary (const string &pkcs11LibraryPath, auto_ptr <GetPinFunctor> pinCallback, auto_ptr <SendExceptionFunctor> warningCallback) ! 510: { ! 511: if (Initialized) ! 512: CloseLibrary(); ! 513: ! 514: #ifdef TC_WINDOWS ! 515: Pkcs11LibraryHandle = LoadLibraryA (pkcs11LibraryPath.c_str()); ! 516: #else ! 517: Pkcs11LibraryHandle = dlopen (pkcs11LibraryPath.c_str(), RTLD_NOW | RTLD_LOCAL); ! 518: #endif ! 519: throw_sys_if (!Pkcs11LibraryHandle); ! 520: ! 521: typedef CK_RV (*C_GetFunctionList_t) (CK_FUNCTION_LIST_PTR_PTR ppFunctionList); ! 522: #ifdef TC_WINDOWS ! 523: C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) GetProcAddress (Pkcs11LibraryHandle, "C_GetFunctionList"); ! 524: #else ! 525: C_GetFunctionList_t C_GetFunctionList = (C_GetFunctionList_t) dlsym (Pkcs11LibraryHandle, "C_GetFunctionList"); ! 526: #endif ! 527: ! 528: if (!C_GetFunctionList) ! 529: throw SecurityTokenLibraryNotInitialized(); ! 530: ! 531: CK_RV status = C_GetFunctionList (&Pkcs11Functions); ! 532: if (status != CKR_OK) ! 533: throw Pkcs11Exception (status); ! 534: ! 535: status = Pkcs11Functions->C_Initialize (NULL_PTR); ! 536: if (status != CKR_OK) ! 537: throw Pkcs11Exception (status); ! 538: ! 539: PinCallback = pinCallback; ! 540: WarningCallback = warningCallback; ! 541: ! 542: Initialized = true; ! 543: } ! 544: ! 545: void SecurityToken::OpenSession (CK_SLOT_ID slotId) ! 546: { ! 547: if (Sessions.find (slotId) != Sessions.end()) ! 548: return; ! 549: ! 550: CK_SESSION_HANDLE session; ! 551: ! 552: CK_FLAGS flags = CKF_SERIAL_SESSION; ! 553: ! 554: if (!(GetTokenInfo (slotId).Flags & CKF_WRITE_PROTECTED)) ! 555: flags |= CKF_RW_SESSION; ! 556: ! 557: CK_RV status = Pkcs11Functions->C_OpenSession (slotId, flags, NULL_PTR, NULL_PTR, &session); ! 558: if (status != CKR_OK) ! 559: throw Pkcs11Exception (status); ! 560: ! 561: Sessions[slotId].Handle = session; ! 562: } ! 563: ! 564: Pkcs11Exception::operator string () const ! 565: { ! 566: #define TC_CASE_STR(CODE) case CODE : return #CODE ! 567: switch (ErrorCode) ! 568: { ! 569: case CKR_OK: return string(); ! 570: ! 571: TC_CASE_STR (CKR_CANCEL); ! 572: TC_CASE_STR (CKR_HOST_MEMORY); ! 573: TC_CASE_STR (CKR_SLOT_ID_INVALID); ! 574: TC_CASE_STR (CKR_GENERAL_ERROR); ! 575: TC_CASE_STR (CKR_FUNCTION_FAILED); ! 576: TC_CASE_STR (CKR_ARGUMENTS_BAD); ! 577: TC_CASE_STR (CKR_NO_EVENT); ! 578: TC_CASE_STR (CKR_NEED_TO_CREATE_THREADS); ! 579: TC_CASE_STR (CKR_CANT_LOCK); ! 580: TC_CASE_STR (CKR_ATTRIBUTE_READ_ONLY); ! 581: TC_CASE_STR (CKR_ATTRIBUTE_SENSITIVE); ! 582: TC_CASE_STR (CKR_ATTRIBUTE_TYPE_INVALID); ! 583: TC_CASE_STR (CKR_ATTRIBUTE_VALUE_INVALID); ! 584: TC_CASE_STR (CKR_DATA_INVALID); ! 585: TC_CASE_STR (CKR_DATA_LEN_RANGE); ! 586: TC_CASE_STR (CKR_DEVICE_ERROR); ! 587: TC_CASE_STR (CKR_DEVICE_MEMORY); ! 588: TC_CASE_STR (CKR_DEVICE_REMOVED); ! 589: TC_CASE_STR (CKR_ENCRYPTED_DATA_INVALID); ! 590: TC_CASE_STR (CKR_ENCRYPTED_DATA_LEN_RANGE); ! 591: TC_CASE_STR (CKR_FUNCTION_CANCELED); ! 592: TC_CASE_STR (CKR_FUNCTION_NOT_PARALLEL); ! 593: TC_CASE_STR (CKR_FUNCTION_NOT_SUPPORTED); ! 594: TC_CASE_STR (CKR_KEY_HANDLE_INVALID); ! 595: TC_CASE_STR (CKR_KEY_SIZE_RANGE); ! 596: TC_CASE_STR (CKR_KEY_TYPE_INCONSISTENT); ! 597: TC_CASE_STR (CKR_KEY_NOT_NEEDED); ! 598: TC_CASE_STR (CKR_KEY_CHANGED); ! 599: TC_CASE_STR (CKR_KEY_NEEDED); ! 600: TC_CASE_STR (CKR_KEY_INDIGESTIBLE); ! 601: TC_CASE_STR (CKR_KEY_FUNCTION_NOT_PERMITTED); ! 602: TC_CASE_STR (CKR_KEY_NOT_WRAPPABLE); ! 603: TC_CASE_STR (CKR_KEY_UNEXTRACTABLE); ! 604: TC_CASE_STR (CKR_MECHANISM_INVALID); ! 605: TC_CASE_STR (CKR_MECHANISM_PARAM_INVALID); ! 606: TC_CASE_STR (CKR_OBJECT_HANDLE_INVALID); ! 607: TC_CASE_STR (CKR_OPERATION_ACTIVE); ! 608: TC_CASE_STR (CKR_OPERATION_NOT_INITIALIZED); ! 609: TC_CASE_STR (CKR_PIN_INCORRECT); ! 610: TC_CASE_STR (CKR_PIN_INVALID); ! 611: TC_CASE_STR (CKR_PIN_LEN_RANGE); ! 612: TC_CASE_STR (CKR_PIN_EXPIRED); ! 613: TC_CASE_STR (CKR_PIN_LOCKED); ! 614: TC_CASE_STR (CKR_SESSION_CLOSED); ! 615: TC_CASE_STR (CKR_SESSION_COUNT); ! 616: TC_CASE_STR (CKR_SESSION_HANDLE_INVALID); ! 617: TC_CASE_STR (CKR_SESSION_PARALLEL_NOT_SUPPORTED); ! 618: TC_CASE_STR (CKR_SESSION_READ_ONLY); ! 619: TC_CASE_STR (CKR_SESSION_EXISTS); ! 620: TC_CASE_STR (CKR_SESSION_READ_ONLY_EXISTS); ! 621: TC_CASE_STR (CKR_SESSION_READ_WRITE_SO_EXISTS); ! 622: TC_CASE_STR (CKR_SIGNATURE_INVALID); ! 623: TC_CASE_STR (CKR_SIGNATURE_LEN_RANGE); ! 624: TC_CASE_STR (CKR_TEMPLATE_INCOMPLETE); ! 625: TC_CASE_STR (CKR_TEMPLATE_INCONSISTENT); ! 626: TC_CASE_STR (CKR_TOKEN_NOT_PRESENT); ! 627: TC_CASE_STR (CKR_TOKEN_NOT_RECOGNIZED); ! 628: TC_CASE_STR (CKR_TOKEN_WRITE_PROTECTED); ! 629: TC_CASE_STR (CKR_UNWRAPPING_KEY_HANDLE_INVALID); ! 630: TC_CASE_STR (CKR_UNWRAPPING_KEY_SIZE_RANGE); ! 631: TC_CASE_STR (CKR_UNWRAPPING_KEY_TYPE_INCONSISTENT); ! 632: TC_CASE_STR (CKR_USER_ALREADY_LOGGED_IN); ! 633: TC_CASE_STR (CKR_USER_NOT_LOGGED_IN); ! 634: TC_CASE_STR (CKR_USER_PIN_NOT_INITIALIZED); ! 635: TC_CASE_STR (CKR_USER_TYPE_INVALID); ! 636: TC_CASE_STR (CKR_USER_ANOTHER_ALREADY_LOGGED_IN); ! 637: TC_CASE_STR (CKR_USER_TOO_MANY_TYPES); ! 638: TC_CASE_STR (CKR_WRAPPED_KEY_INVALID); ! 639: TC_CASE_STR (CKR_WRAPPED_KEY_LEN_RANGE); ! 640: TC_CASE_STR (CKR_WRAPPING_KEY_HANDLE_INVALID); ! 641: TC_CASE_STR (CKR_WRAPPING_KEY_SIZE_RANGE); ! 642: TC_CASE_STR (CKR_WRAPPING_KEY_TYPE_INCONSISTENT); ! 643: TC_CASE_STR (CKR_RANDOM_SEED_NOT_SUPPORTED); ! 644: TC_CASE_STR (CKR_RANDOM_NO_RNG); ! 645: TC_CASE_STR (CKR_DOMAIN_PARAMS_INVALID); ! 646: TC_CASE_STR (CKR_BUFFER_TOO_SMALL); ! 647: TC_CASE_STR (CKR_SAVED_STATE_INVALID); ! 648: TC_CASE_STR (CKR_INFORMATION_SENSITIVE); ! 649: TC_CASE_STR (CKR_STATE_UNSAVEABLE); ! 650: TC_CASE_STR (CKR_CRYPTOKI_NOT_INITIALIZED); ! 651: TC_CASE_STR (CKR_CRYPTOKI_ALREADY_INITIALIZED); ! 652: TC_CASE_STR (CKR_MUTEX_BAD); ! 653: TC_CASE_STR (CKR_MUTEX_NOT_LOCKED); ! 654: TC_CASE_STR (CKR_NEW_PIN_MODE); ! 655: TC_CASE_STR (CKR_NEXT_OTP); ! 656: TC_CASE_STR (CKR_FUNCTION_REJECTED); ! 657: ! 658: default: ! 659: { ! 660: stringstream s; ! 661: s << "0x" << hex << ErrorCode; ! 662: return s.str(); ! 663: } ! 664: }; ! 665: ! 666: #undef TC_CASE_STR ! 667: } ! 668: ! 669: #ifdef TC_HEADER_Common_Exception ! 670: void Pkcs11Exception::Show (HWND parent) const ! 671: { ! 672: string errorString = string (*this); ! 673: ! 674: if (!errorString.empty()) ! 675: { ! 676: wstringstream subjectErrorCode; ! 677: if (SubjectErrorCodeValid) ! 678: subjectErrorCode << L": " << SubjectErrorCode; ! 679: ! 680: if (!GetDictionaryValue (errorString.c_str())) ! 681: { ! 682: if (errorString.find ("CKR_") == 0) ! 683: { ! 684: errorString = errorString.substr (4); ! 685: for (size_t i = 0; i < errorString.size(); ++i) ! 686: { ! 687: if (errorString[i] == '_') ! 688: errorString[i] = ' '; ! 689: } ! 690: } ! 691: wchar_t err[8192]; ! 692: wsprintfW (err, L"%s:\n\n%hs%s", GetString ("SECURITY_TOKEN_ERROR"), errorString.c_str(), subjectErrorCode.str().c_str()); ! 693: ErrorDirect (err); ! 694: } ! 695: else ! 696: { ! 697: wstring err = GetString (errorString.c_str()); ! 698: ! 699: if (SubjectErrorCodeValid) ! 700: err += L"\n\nError code" + subjectErrorCode.str(); ! 701: ! 702: ErrorDirect (err.c_str()); ! 703: } ! 704: } ! 705: } ! 706: #endif // TC_HEADER_Common_Exception ! 707: ! 708: auto_ptr <GetPinFunctor> SecurityToken::PinCallback; ! 709: auto_ptr <SendExceptionFunctor> SecurityToken::WarningCallback; ! 710: ! 711: bool SecurityToken::Initialized; ! 712: CK_FUNCTION_LIST_PTR SecurityToken::Pkcs11Functions; ! 713: map <CK_SLOT_ID, Pkcs11Session> SecurityToken::Sessions; ! 714: ! 715: #ifdef TC_WINDOWS ! 716: HMODULE SecurityToken::Pkcs11LibraryHandle; ! 717: #else ! 718: void *SecurityToken::Pkcs11LibraryHandle; ! 719: #endif ! 720: ! 721: #ifdef TC_HEADER_Platform_Exception ! 722: ! 723: void Pkcs11Exception::Deserialize (shared_ptr <Stream> stream) ! 724: { ! 725: Exception::Deserialize (stream); ! 726: Serializer sr (stream); ! 727: uint64 code; ! 728: sr.Deserialize ("ErrorCode", code); ! 729: sr.Deserialize ("SubjectErrorCodeValid", SubjectErrorCodeValid); ! 730: sr.Deserialize ("SubjectErrorCode", SubjectErrorCode); ! 731: ErrorCode = (CK_RV) code; ! 732: } ! 733: ! 734: void Pkcs11Exception::Serialize (shared_ptr <Stream> stream) const ! 735: { ! 736: Exception::Serialize (stream); ! 737: Serializer sr (stream); ! 738: sr.Serialize ("ErrorCode", (uint64) ErrorCode); ! 739: sr.Serialize ("SubjectErrorCodeValid", SubjectErrorCodeValid); ! 740: sr.Serialize ("SubjectErrorCode", SubjectErrorCode); ! 741: } ! 742: ! 743: # define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) ! 744: # undef TC_EXCEPTION_NODECL ! 745: # define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) ! 746: ! 747: TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (SecurityTokenException); ! 748: ! 749: #endif ! 750: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.