|
|
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.