OLD | NEW |
| (Empty) |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
4 | |
5 #ifdef DEBUG | |
6 static const char CVS_ID[] = "@(#) $RCSfile: token.c,v $ $Revision: 1.17 $ $Date
: 2012/04/25 14:49:28 $"; | |
7 #endif /* DEBUG */ | |
8 | |
9 /* | |
10 * token.c | |
11 * | |
12 * This file implements the NSSCKFWToken type and methods. | |
13 */ | |
14 | |
15 #ifndef CK_T | |
16 #include "ck.h" | |
17 #endif /* CK_T */ | |
18 | |
19 /* | |
20 * NSSCKFWToken | |
21 * | |
22 * -- create/destroy -- | |
23 * nssCKFWToken_Create | |
24 * nssCKFWToken_Destroy | |
25 * | |
26 * -- public accessors -- | |
27 * NSSCKFWToken_GetMDToken | |
28 * NSSCKFWToken_GetFWSlot | |
29 * NSSCKFWToken_GetMDSlot | |
30 * NSSCKFWToken_GetSessionState | |
31 * | |
32 * -- implement public accessors -- | |
33 * nssCKFWToken_GetMDToken | |
34 * nssCKFWToken_GetFWSlot | |
35 * nssCKFWToken_GetMDSlot | |
36 * nssCKFWToken_GetSessionState | |
37 * nssCKFWToken_SetSessionState | |
38 * | |
39 * -- private accessors -- | |
40 * nssCKFWToken_SetSessionState | |
41 * nssCKFWToken_RemoveSession | |
42 * nssCKFWToken_CloseAllSessions | |
43 * nssCKFWToken_GetSessionCount | |
44 * nssCKFWToken_GetRwSessionCount | |
45 * nssCKFWToken_GetRoSessionCount | |
46 * nssCKFWToken_GetSessionObjectHash | |
47 * nssCKFWToken_GetMDObjectHash | |
48 * nssCKFWToken_GetObjectHandleHash | |
49 * | |
50 * -- module fronts -- | |
51 * nssCKFWToken_InitToken | |
52 * nssCKFWToken_GetLabel | |
53 * nssCKFWToken_GetManufacturerID | |
54 * nssCKFWToken_GetModel | |
55 * nssCKFWToken_GetSerialNumber | |
56 * nssCKFWToken_GetHasRNG | |
57 * nssCKFWToken_GetIsWriteProtected | |
58 * nssCKFWToken_GetLoginRequired | |
59 * nssCKFWToken_GetUserPinInitialized | |
60 * nssCKFWToken_GetRestoreKeyNotNeeded | |
61 * nssCKFWToken_GetHasClockOnToken | |
62 * nssCKFWToken_GetHasProtectedAuthenticationPath | |
63 * nssCKFWToken_GetSupportsDualCryptoOperations | |
64 * nssCKFWToken_GetMaxSessionCount | |
65 * nssCKFWToken_GetMaxRwSessionCount | |
66 * nssCKFWToken_GetMaxPinLen | |
67 * nssCKFWToken_GetMinPinLen | |
68 * nssCKFWToken_GetTotalPublicMemory | |
69 * nssCKFWToken_GetFreePublicMemory | |
70 * nssCKFWToken_GetTotalPrivateMemory | |
71 * nssCKFWToken_GetFreePrivateMemory | |
72 * nssCKFWToken_GetHardwareVersion | |
73 * nssCKFWToken_GetFirmwareVersion | |
74 * nssCKFWToken_GetUTCTime | |
75 * nssCKFWToken_OpenSession | |
76 * nssCKFWToken_GetMechanismCount | |
77 * nssCKFWToken_GetMechanismTypes | |
78 * nssCKFWToken_GetMechanism | |
79 */ | |
80 | |
81 struct NSSCKFWTokenStr { | |
82 NSSCKFWMutex *mutex; | |
83 NSSArena *arena; | |
84 NSSCKMDToken *mdToken; | |
85 NSSCKFWSlot *fwSlot; | |
86 NSSCKMDSlot *mdSlot; | |
87 NSSCKFWInstance *fwInstance; | |
88 NSSCKMDInstance *mdInstance; | |
89 | |
90 /* | |
91 * Everything above is set at creation time, and then not modified. | |
92 * The invariants the mutex protects are: | |
93 * | |
94 * 1) Each of the cached descriptions (versions, etc.) are in an | |
95 * internally consistant state. | |
96 * | |
97 * 2) The session counts and hashes are consistant. | |
98 * | |
99 * 3) The object hashes are consistant. | |
100 * | |
101 * Note that the calls accessing the cached descriptions will call | |
102 * the NSSCKMDToken methods with the mutex locked. Those methods | |
103 * may then call the public NSSCKFWToken routines. Those public | |
104 * routines only access the constant data above and the atomic | |
105 * CK_STATE session state variable below, so there's no problem. | |
106 * But be careful if you add to this object; mutexes are in | |
107 * general not reentrant, so don't create deadlock situations. | |
108 */ | |
109 | |
110 NSSUTF8 *label; | |
111 NSSUTF8 *manufacturerID; | |
112 NSSUTF8 *model; | |
113 NSSUTF8 *serialNumber; | |
114 CK_VERSION hardwareVersion; | |
115 CK_VERSION firmwareVersion; | |
116 | |
117 CK_ULONG sessionCount; | |
118 CK_ULONG rwSessionCount; | |
119 nssCKFWHash *sessions; | |
120 nssCKFWHash *sessionObjectHash; | |
121 nssCKFWHash *mdObjectHash; | |
122 nssCKFWHash *mdMechanismHash; | |
123 | |
124 CK_STATE state; | |
125 }; | |
126 | |
127 #ifdef DEBUG | |
128 /* | |
129 * But first, the pointer-tracking stuff. | |
130 * | |
131 * NOTE: the pointer-tracking support in NSS/base currently relies | |
132 * upon NSPR's CallOnce support. That, however, relies upon NSPR's | |
133 * locking, which is tied into the runtime. We need a pointer-tracker | |
134 * implementation that uses the locks supplied through C_Initialize. | |
135 * That support, however, can be filled in later. So for now, I'll | |
136 * just do this routines as no-ops. | |
137 */ | |
138 | |
139 static CK_RV | |
140 token_add_pointer | |
141 ( | |
142 const NSSCKFWToken *fwToken | |
143 ) | |
144 { | |
145 return CKR_OK; | |
146 } | |
147 | |
148 static CK_RV | |
149 token_remove_pointer | |
150 ( | |
151 const NSSCKFWToken *fwToken | |
152 ) | |
153 { | |
154 return CKR_OK; | |
155 } | |
156 | |
157 NSS_IMPLEMENT CK_RV | |
158 nssCKFWToken_verifyPointer | |
159 ( | |
160 const NSSCKFWToken *fwToken | |
161 ) | |
162 { | |
163 return CKR_OK; | |
164 } | |
165 | |
166 #endif /* DEBUG */ | |
167 | |
168 /* | |
169 * nssCKFWToken_Create | |
170 * | |
171 */ | |
172 NSS_IMPLEMENT NSSCKFWToken * | |
173 nssCKFWToken_Create | |
174 ( | |
175 NSSCKFWSlot *fwSlot, | |
176 NSSCKMDToken *mdToken, | |
177 CK_RV *pError | |
178 ) | |
179 { | |
180 NSSArena *arena = (NSSArena *)NULL; | |
181 NSSCKFWToken *fwToken = (NSSCKFWToken *)NULL; | |
182 CK_BBOOL called_setup = CK_FALSE; | |
183 | |
184 /* | |
185 * We have already verified the arguments in nssCKFWSlot_GetToken. | |
186 */ | |
187 | |
188 arena = NSSArena_Create(); | |
189 if (!arena) { | |
190 *pError = CKR_HOST_MEMORY; | |
191 goto loser; | |
192 } | |
193 | |
194 fwToken = nss_ZNEW(arena, NSSCKFWToken); | |
195 if (!fwToken) { | |
196 *pError = CKR_HOST_MEMORY; | |
197 goto loser; | |
198 } | |
199 | |
200 fwToken->arena = arena; | |
201 fwToken->mdToken = mdToken; | |
202 fwToken->fwSlot = fwSlot; | |
203 fwToken->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot); | |
204 fwToken->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot); | |
205 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */ | |
206 fwToken->sessionCount = 0; | |
207 fwToken->rwSessionCount = 0; | |
208 | |
209 fwToken->mutex = nssCKFWInstance_CreateMutex(fwToken->fwInstance, arena, pErro
r); | |
210 if (!fwToken->mutex) { | |
211 if( CKR_OK == *pError ) { | |
212 *pError = CKR_GENERAL_ERROR; | |
213 } | |
214 goto loser; | |
215 } | |
216 | |
217 fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, arena, pError); | |
218 if (!fwToken->sessions) { | |
219 if( CKR_OK == *pError ) { | |
220 *pError = CKR_GENERAL_ERROR; | |
221 } | |
222 goto loser; | |
223 } | |
224 | |
225 if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects( | |
226 fwToken->fwInstance) ) { | |
227 fwToken->sessionObjectHash = nssCKFWHash_Create(fwToken->fwInstance, | |
228 arena, pError); | |
229 if (!fwToken->sessionObjectHash) { | |
230 if( CKR_OK == *pError ) { | |
231 *pError = CKR_GENERAL_ERROR; | |
232 } | |
233 goto loser; | |
234 } | |
235 } | |
236 | |
237 fwToken->mdObjectHash = nssCKFWHash_Create(fwToken->fwInstance, | |
238 arena, pError); | |
239 if (!fwToken->mdObjectHash) { | |
240 if( CKR_OK == *pError ) { | |
241 *pError = CKR_GENERAL_ERROR; | |
242 } | |
243 goto loser; | |
244 } | |
245 | |
246 fwToken->mdMechanismHash = nssCKFWHash_Create(fwToken->fwInstance, | |
247 arena, pError); | |
248 if (!fwToken->mdMechanismHash) { | |
249 if( CKR_OK == *pError ) { | |
250 *pError = CKR_GENERAL_ERROR; | |
251 } | |
252 goto loser; | |
253 } | |
254 | |
255 /* More here */ | |
256 | |
257 if (mdToken->Setup) { | |
258 *pError = mdToken->Setup(mdToken, fwToken, fwToken->mdInstance, fwToken->fwI
nstance); | |
259 if( CKR_OK != *pError ) { | |
260 goto loser; | |
261 } | |
262 } | |
263 | |
264 called_setup = CK_TRUE; | |
265 | |
266 #ifdef DEBUG | |
267 *pError = token_add_pointer(fwToken); | |
268 if( CKR_OK != *pError ) { | |
269 goto loser; | |
270 } | |
271 #endif /* DEBUG */ | |
272 | |
273 *pError = CKR_OK; | |
274 return fwToken; | |
275 | |
276 loser: | |
277 | |
278 if( CK_TRUE == called_setup ) { | |
279 if (mdToken->Invalidate) { | |
280 mdToken->Invalidate(mdToken, fwToken, fwToken->mdInstance, fwToken->fwInst
ance); | |
281 } | |
282 } | |
283 | |
284 if (arena) { | |
285 (void)NSSArena_Destroy(arena); | |
286 } | |
287 | |
288 return (NSSCKFWToken *)NULL; | |
289 } | |
290 | |
291 static void | |
292 nss_ckfwtoken_session_iterator | |
293 ( | |
294 const void *key, | |
295 void *value, | |
296 void *closure | |
297 ) | |
298 { | |
299 /* | |
300 * Remember that the fwToken->mutex is locked | |
301 */ | |
302 NSSCKFWSession *fwSession = (NSSCKFWSession *)value; | |
303 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); | |
304 return; | |
305 } | |
306 | |
307 static void | |
308 nss_ckfwtoken_object_iterator | |
309 ( | |
310 const void *key, | |
311 void *value, | |
312 void *closure | |
313 ) | |
314 { | |
315 /* | |
316 * Remember that the fwToken->mutex is locked | |
317 */ | |
318 NSSCKFWObject *fwObject = (NSSCKFWObject *)value; | |
319 (void)nssCKFWObject_Finalize(fwObject, CK_FALSE); | |
320 return; | |
321 } | |
322 | |
323 /* | |
324 * nssCKFWToken_Destroy | |
325 * | |
326 */ | |
327 NSS_IMPLEMENT CK_RV | |
328 nssCKFWToken_Destroy | |
329 ( | |
330 NSSCKFWToken *fwToken | |
331 ) | |
332 { | |
333 CK_RV error = CKR_OK; | |
334 | |
335 #ifdef NSSDEBUG | |
336 error = nssCKFWToken_verifyPointer(fwToken); | |
337 if( CKR_OK != error ) { | |
338 return error; | |
339 } | |
340 #endif /* NSSDEBUG */ | |
341 | |
342 (void)nssCKFWMutex_Destroy(fwToken->mutex); | |
343 | |
344 if (fwToken->mdToken->Invalidate) { | |
345 fwToken->mdToken->Invalidate(fwToken->mdToken, fwToken, | |
346 fwToken->mdInstance, fwToken->fwInstance); | |
347 } | |
348 /* we can destroy the list without locking now because no one else is | |
349 * referencing us (or _Destroy was invalidly called!) | |
350 */ | |
351 nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, | |
352 (void *)NULL); | |
353 nssCKFWHash_Destroy(fwToken->sessions); | |
354 | |
355 /* session objects go away when their sessions are removed */ | |
356 if (fwToken->sessionObjectHash) { | |
357 nssCKFWHash_Destroy(fwToken->sessionObjectHash); | |
358 } | |
359 | |
360 /* free up the token objects */ | |
361 if (fwToken->mdObjectHash) { | |
362 nssCKFWHash_Iterate(fwToken->mdObjectHash, nss_ckfwtoken_object_iterator, | |
363 (void *)NULL); | |
364 nssCKFWHash_Destroy(fwToken->mdObjectHash); | |
365 } | |
366 if (fwToken->mdMechanismHash) { | |
367 nssCKFWHash_Destroy(fwToken->mdMechanismHash); | |
368 } | |
369 | |
370 nssCKFWSlot_ClearToken(fwToken->fwSlot); | |
371 | |
372 #ifdef DEBUG | |
373 error = token_remove_pointer(fwToken); | |
374 #endif /* DEBUG */ | |
375 | |
376 (void)NSSArena_Destroy(fwToken->arena); | |
377 return error; | |
378 } | |
379 | |
380 /* | |
381 * nssCKFWToken_GetMDToken | |
382 * | |
383 */ | |
384 NSS_IMPLEMENT NSSCKMDToken * | |
385 nssCKFWToken_GetMDToken | |
386 ( | |
387 NSSCKFWToken *fwToken | |
388 ) | |
389 { | |
390 #ifdef NSSDEBUG | |
391 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
392 return (NSSCKMDToken *)NULL; | |
393 } | |
394 #endif /* NSSDEBUG */ | |
395 | |
396 return fwToken->mdToken; | |
397 } | |
398 | |
399 /* | |
400 * nssCKFWToken_GetArena | |
401 * | |
402 */ | |
403 NSS_IMPLEMENT NSSArena * | |
404 nssCKFWToken_GetArena | |
405 ( | |
406 NSSCKFWToken *fwToken, | |
407 CK_RV *pError | |
408 ) | |
409 { | |
410 #ifdef NSSDEBUG | |
411 if (!pError) { | |
412 return (NSSArena *)NULL; | |
413 } | |
414 | |
415 *pError = nssCKFWToken_verifyPointer(fwToken); | |
416 if( CKR_OK != *pError ) { | |
417 return (NSSArena *)NULL; | |
418 } | |
419 #endif /* NSSDEBUG */ | |
420 | |
421 return fwToken->arena; | |
422 } | |
423 | |
424 /* | |
425 * nssCKFWToken_GetFWSlot | |
426 * | |
427 */ | |
428 NSS_IMPLEMENT NSSCKFWSlot * | |
429 nssCKFWToken_GetFWSlot | |
430 ( | |
431 NSSCKFWToken *fwToken | |
432 ) | |
433 { | |
434 #ifdef NSSDEBUG | |
435 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
436 return (NSSCKFWSlot *)NULL; | |
437 } | |
438 #endif /* NSSDEBUG */ | |
439 | |
440 return fwToken->fwSlot; | |
441 } | |
442 | |
443 /* | |
444 * nssCKFWToken_GetMDSlot | |
445 * | |
446 */ | |
447 NSS_IMPLEMENT NSSCKMDSlot * | |
448 nssCKFWToken_GetMDSlot | |
449 ( | |
450 NSSCKFWToken *fwToken | |
451 ) | |
452 { | |
453 #ifdef NSSDEBUG | |
454 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
455 return (NSSCKMDSlot *)NULL; | |
456 } | |
457 #endif /* NSSDEBUG */ | |
458 | |
459 return fwToken->mdSlot; | |
460 } | |
461 | |
462 /* | |
463 * nssCKFWToken_GetSessionState | |
464 * | |
465 */ | |
466 NSS_IMPLEMENT CK_STATE | |
467 nssCKFWToken_GetSessionState | |
468 ( | |
469 NSSCKFWToken *fwToken | |
470 ) | |
471 { | |
472 #ifdef NSSDEBUG | |
473 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
474 return CKS_RO_PUBLIC_SESSION; /* whatever */ | |
475 } | |
476 #endif /* NSSDEBUG */ | |
477 | |
478 /* | |
479 * BTW, do not lock the token in this method. | |
480 */ | |
481 | |
482 /* | |
483 * Theoretically, there is no state if there aren't any | |
484 * sessions open. But then we'd need to worry about | |
485 * reporting an error, etc. What the heck-- let's just | |
486 * revert to CKR_RO_PUBLIC_SESSION as the "default." | |
487 */ | |
488 | |
489 return fwToken->state; | |
490 } | |
491 | |
492 /* | |
493 * nssCKFWToken_InitToken | |
494 * | |
495 */ | |
496 NSS_IMPLEMENT CK_RV | |
497 nssCKFWToken_InitToken | |
498 ( | |
499 NSSCKFWToken *fwToken, | |
500 NSSItem *pin, | |
501 NSSUTF8 *label | |
502 ) | |
503 { | |
504 CK_RV error; | |
505 | |
506 #ifdef NSSDEBUG | |
507 error = nssCKFWToken_verifyPointer(fwToken); | |
508 if( CKR_OK != error ) { | |
509 return CKR_ARGUMENTS_BAD; | |
510 } | |
511 #endif /* NSSDEBUG */ | |
512 | |
513 error = nssCKFWMutex_Lock(fwToken->mutex); | |
514 if( CKR_OK != error ) { | |
515 return error; | |
516 } | |
517 | |
518 if( fwToken->sessionCount > 0 ) { | |
519 error = CKR_SESSION_EXISTS; | |
520 goto done; | |
521 } | |
522 | |
523 if (!fwToken->mdToken->InitToken) { | |
524 error = CKR_DEVICE_ERROR; | |
525 goto done; | |
526 } | |
527 | |
528 if (!pin) { | |
529 if( nssCKFWToken_GetHasProtectedAuthenticationPath(fwToken) ) { | |
530 ; /* okay */ | |
531 } else { | |
532 error = CKR_PIN_INCORRECT; | |
533 goto done; | |
534 } | |
535 } | |
536 | |
537 if (!label) { | |
538 label = (NSSUTF8 *) ""; | |
539 } | |
540 | |
541 error = fwToken->mdToken->InitToken(fwToken->mdToken, fwToken, | |
542 fwToken->mdInstance, fwToken->fwInstance, pin, label); | |
543 | |
544 done: | |
545 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
546 return error; | |
547 } | |
548 | |
549 /* | |
550 * nssCKFWToken_GetLabel | |
551 * | |
552 */ | |
553 NSS_IMPLEMENT CK_RV | |
554 nssCKFWToken_GetLabel | |
555 ( | |
556 NSSCKFWToken *fwToken, | |
557 CK_CHAR label[32] | |
558 ) | |
559 { | |
560 CK_RV error = CKR_OK; | |
561 | |
562 #ifdef NSSDEBUG | |
563 if( (CK_CHAR_PTR)NULL == label ) { | |
564 return CKR_ARGUMENTS_BAD; | |
565 } | |
566 | |
567 error = nssCKFWToken_verifyPointer(fwToken); | |
568 if( CKR_OK != error ) { | |
569 return error; | |
570 } | |
571 #endif /* NSSDEBUG */ | |
572 | |
573 error = nssCKFWMutex_Lock(fwToken->mutex); | |
574 if( CKR_OK != error ) { | |
575 return error; | |
576 } | |
577 | |
578 if (!fwToken->label) { | |
579 if (fwToken->mdToken->GetLabel) { | |
580 fwToken->label = fwToken->mdToken->GetLabel(fwToken->mdToken, fwToken, | |
581 fwToken->mdInstance, fwToken->fwInstance, &error); | |
582 if ((!fwToken->label) && (CKR_OK != error)) { | |
583 goto done; | |
584 } | |
585 } else { | |
586 fwToken->label = (NSSUTF8 *) ""; | |
587 } | |
588 } | |
589 | |
590 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->label, (char *)label, 32, ' '); | |
591 error = CKR_OK; | |
592 | |
593 done: | |
594 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
595 return error; | |
596 } | |
597 | |
598 /* | |
599 * nssCKFWToken_GetManufacturerID | |
600 * | |
601 */ | |
602 NSS_IMPLEMENT CK_RV | |
603 nssCKFWToken_GetManufacturerID | |
604 ( | |
605 NSSCKFWToken *fwToken, | |
606 CK_CHAR manufacturerID[32] | |
607 ) | |
608 { | |
609 CK_RV error = CKR_OK; | |
610 | |
611 #ifdef NSSDEBUG | |
612 if( (CK_CHAR_PTR)NULL == manufacturerID ) { | |
613 return CKR_ARGUMENTS_BAD; | |
614 } | |
615 | |
616 error = nssCKFWToken_verifyPointer(fwToken); | |
617 if( CKR_OK != error ) { | |
618 return error; | |
619 } | |
620 #endif /* NSSDEBUG */ | |
621 | |
622 error = nssCKFWMutex_Lock(fwToken->mutex); | |
623 if( CKR_OK != error ) { | |
624 return error; | |
625 } | |
626 | |
627 if (!fwToken->manufacturerID) { | |
628 if (fwToken->mdToken->GetManufacturerID) { | |
629 fwToken->manufacturerID = fwToken->mdToken->GetManufacturerID(fwToken->mdT
oken, | |
630 fwToken, fwToken->mdInstance, fwToken->fwInstance, &error); | |
631 if ((!fwToken->manufacturerID) && (CKR_OK != error)) { | |
632 goto done; | |
633 } | |
634 } else { | |
635 fwToken->manufacturerID = (NSSUTF8 *)""; | |
636 } | |
637 } | |
638 | |
639 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->manufacturerID, (char *)manufacture
rID, 32, ' '); | |
640 error = CKR_OK; | |
641 | |
642 done: | |
643 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
644 return error; | |
645 } | |
646 | |
647 /* | |
648 * nssCKFWToken_GetModel | |
649 * | |
650 */ | |
651 NSS_IMPLEMENT CK_RV | |
652 nssCKFWToken_GetModel | |
653 ( | |
654 NSSCKFWToken *fwToken, | |
655 CK_CHAR model[16] | |
656 ) | |
657 { | |
658 CK_RV error = CKR_OK; | |
659 | |
660 #ifdef NSSDEBUG | |
661 if( (CK_CHAR_PTR)NULL == model ) { | |
662 return CKR_ARGUMENTS_BAD; | |
663 } | |
664 | |
665 error = nssCKFWToken_verifyPointer(fwToken); | |
666 if( CKR_OK != error ) { | |
667 return error; | |
668 } | |
669 #endif /* NSSDEBUG */ | |
670 | |
671 error = nssCKFWMutex_Lock(fwToken->mutex); | |
672 if( CKR_OK != error ) { | |
673 return error; | |
674 } | |
675 | |
676 if (!fwToken->model) { | |
677 if (fwToken->mdToken->GetModel) { | |
678 fwToken->model = fwToken->mdToken->GetModel(fwToken->mdToken, fwToken, | |
679 fwToken->mdInstance, fwToken->fwInstance, &error); | |
680 if ((!fwToken->model) && (CKR_OK != error)) { | |
681 goto done; | |
682 } | |
683 } else { | |
684 fwToken->model = (NSSUTF8 *)""; | |
685 } | |
686 } | |
687 | |
688 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->model, (char *)model, 16, ' '); | |
689 error = CKR_OK; | |
690 | |
691 done: | |
692 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
693 return error; | |
694 } | |
695 | |
696 /* | |
697 * nssCKFWToken_GetSerialNumber | |
698 * | |
699 */ | |
700 NSS_IMPLEMENT CK_RV | |
701 nssCKFWToken_GetSerialNumber | |
702 ( | |
703 NSSCKFWToken *fwToken, | |
704 CK_CHAR serialNumber[16] | |
705 ) | |
706 { | |
707 CK_RV error = CKR_OK; | |
708 | |
709 #ifdef NSSDEBUG | |
710 if( (CK_CHAR_PTR)NULL == serialNumber ) { | |
711 return CKR_ARGUMENTS_BAD; | |
712 } | |
713 | |
714 error = nssCKFWToken_verifyPointer(fwToken); | |
715 if( CKR_OK != error ) { | |
716 return error; | |
717 } | |
718 #endif /* NSSDEBUG */ | |
719 | |
720 error = nssCKFWMutex_Lock(fwToken->mutex); | |
721 if( CKR_OK != error ) { | |
722 return error; | |
723 } | |
724 | |
725 if (!fwToken->serialNumber) { | |
726 if (fwToken->mdToken->GetSerialNumber) { | |
727 fwToken->serialNumber = fwToken->mdToken->GetSerialNumber(fwToken->mdToken
, | |
728 fwToken, fwToken->mdInstance, fwToken->fwInstance, &error); | |
729 if ((!fwToken->serialNumber) && (CKR_OK != error)) { | |
730 goto done; | |
731 } | |
732 } else { | |
733 fwToken->serialNumber = (NSSUTF8 *)""; | |
734 } | |
735 } | |
736 | |
737 (void)nssUTF8_CopyIntoFixedBuffer(fwToken->serialNumber, (char *)serialNumber,
16, ' '); | |
738 error = CKR_OK; | |
739 | |
740 done: | |
741 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
742 return error; | |
743 } | |
744 | |
745 | |
746 /* | |
747 * nssCKFWToken_GetHasRNG | |
748 * | |
749 */ | |
750 NSS_IMPLEMENT CK_BBOOL | |
751 nssCKFWToken_GetHasRNG | |
752 ( | |
753 NSSCKFWToken *fwToken | |
754 ) | |
755 { | |
756 #ifdef NSSDEBUG | |
757 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
758 return CK_FALSE; | |
759 } | |
760 #endif /* NSSDEBUG */ | |
761 | |
762 if (!fwToken->mdToken->GetHasRNG) { | |
763 return CK_FALSE; | |
764 } | |
765 | |
766 return fwToken->mdToken->GetHasRNG(fwToken->mdToken, fwToken, | |
767 fwToken->mdInstance, fwToken->fwInstance); | |
768 } | |
769 | |
770 /* | |
771 * nssCKFWToken_GetIsWriteProtected | |
772 * | |
773 */ | |
774 NSS_IMPLEMENT CK_BBOOL | |
775 nssCKFWToken_GetIsWriteProtected | |
776 ( | |
777 NSSCKFWToken *fwToken | |
778 ) | |
779 { | |
780 #ifdef NSSDEBUG | |
781 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
782 return CK_FALSE; | |
783 } | |
784 #endif /* NSSDEBUG */ | |
785 | |
786 if (!fwToken->mdToken->GetIsWriteProtected) { | |
787 return CK_FALSE; | |
788 } | |
789 | |
790 return fwToken->mdToken->GetIsWriteProtected(fwToken->mdToken, fwToken, | |
791 fwToken->mdInstance, fwToken->fwInstance); | |
792 } | |
793 | |
794 /* | |
795 * nssCKFWToken_GetLoginRequired | |
796 * | |
797 */ | |
798 NSS_IMPLEMENT CK_BBOOL | |
799 nssCKFWToken_GetLoginRequired | |
800 ( | |
801 NSSCKFWToken *fwToken | |
802 ) | |
803 { | |
804 #ifdef NSSDEBUG | |
805 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
806 return CK_FALSE; | |
807 } | |
808 #endif /* NSSDEBUG */ | |
809 | |
810 if (!fwToken->mdToken->GetLoginRequired) { | |
811 return CK_FALSE; | |
812 } | |
813 | |
814 return fwToken->mdToken->GetLoginRequired(fwToken->mdToken, fwToken, | |
815 fwToken->mdInstance, fwToken->fwInstance); | |
816 } | |
817 | |
818 /* | |
819 * nssCKFWToken_GetUserPinInitialized | |
820 * | |
821 */ | |
822 NSS_IMPLEMENT CK_BBOOL | |
823 nssCKFWToken_GetUserPinInitialized | |
824 ( | |
825 NSSCKFWToken *fwToken | |
826 ) | |
827 { | |
828 #ifdef NSSDEBUG | |
829 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
830 return CK_FALSE; | |
831 } | |
832 #endif /* NSSDEBUG */ | |
833 | |
834 if (!fwToken->mdToken->GetUserPinInitialized) { | |
835 return CK_FALSE; | |
836 } | |
837 | |
838 return fwToken->mdToken->GetUserPinInitialized(fwToken->mdToken, fwToken, | |
839 fwToken->mdInstance, fwToken->fwInstance); | |
840 } | |
841 | |
842 /* | |
843 * nssCKFWToken_GetRestoreKeyNotNeeded | |
844 * | |
845 */ | |
846 NSS_IMPLEMENT CK_BBOOL | |
847 nssCKFWToken_GetRestoreKeyNotNeeded | |
848 ( | |
849 NSSCKFWToken *fwToken | |
850 ) | |
851 { | |
852 #ifdef NSSDEBUG | |
853 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
854 return CK_FALSE; | |
855 } | |
856 #endif /* NSSDEBUG */ | |
857 | |
858 if (!fwToken->mdToken->GetRestoreKeyNotNeeded) { | |
859 return CK_FALSE; | |
860 } | |
861 | |
862 return fwToken->mdToken->GetRestoreKeyNotNeeded(fwToken->mdToken, fwToken, | |
863 fwToken->mdInstance, fwToken->fwInstance); | |
864 } | |
865 | |
866 /* | |
867 * nssCKFWToken_GetHasClockOnToken | |
868 * | |
869 */ | |
870 NSS_IMPLEMENT CK_BBOOL | |
871 nssCKFWToken_GetHasClockOnToken | |
872 ( | |
873 NSSCKFWToken *fwToken | |
874 ) | |
875 { | |
876 #ifdef NSSDEBUG | |
877 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
878 return CK_FALSE; | |
879 } | |
880 #endif /* NSSDEBUG */ | |
881 | |
882 if (!fwToken->mdToken->GetHasClockOnToken) { | |
883 return CK_FALSE; | |
884 } | |
885 | |
886 return fwToken->mdToken->GetHasClockOnToken(fwToken->mdToken, fwToken, | |
887 fwToken->mdInstance, fwToken->fwInstance); | |
888 } | |
889 | |
890 /* | |
891 * nssCKFWToken_GetHasProtectedAuthenticationPath | |
892 * | |
893 */ | |
894 NSS_IMPLEMENT CK_BBOOL | |
895 nssCKFWToken_GetHasProtectedAuthenticationPath | |
896 ( | |
897 NSSCKFWToken *fwToken | |
898 ) | |
899 { | |
900 #ifdef NSSDEBUG | |
901 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
902 return CK_FALSE; | |
903 } | |
904 #endif /* NSSDEBUG */ | |
905 | |
906 if (!fwToken->mdToken->GetHasProtectedAuthenticationPath) { | |
907 return CK_FALSE; | |
908 } | |
909 | |
910 return fwToken->mdToken->GetHasProtectedAuthenticationPath(fwToken->mdToken, | |
911 fwToken, fwToken->mdInstance, fwToken->fwInstance); | |
912 } | |
913 | |
914 /* | |
915 * nssCKFWToken_GetSupportsDualCryptoOperations | |
916 * | |
917 */ | |
918 NSS_IMPLEMENT CK_BBOOL | |
919 nssCKFWToken_GetSupportsDualCryptoOperations | |
920 ( | |
921 NSSCKFWToken *fwToken | |
922 ) | |
923 { | |
924 #ifdef NSSDEBUG | |
925 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
926 return CK_FALSE; | |
927 } | |
928 #endif /* NSSDEBUG */ | |
929 | |
930 if (!fwToken->mdToken->GetSupportsDualCryptoOperations) { | |
931 return CK_FALSE; | |
932 } | |
933 | |
934 return fwToken->mdToken->GetSupportsDualCryptoOperations(fwToken->mdToken, | |
935 fwToken, fwToken->mdInstance, fwToken->fwInstance); | |
936 } | |
937 | |
938 /* | |
939 * nssCKFWToken_GetMaxSessionCount | |
940 * | |
941 */ | |
942 NSS_IMPLEMENT CK_ULONG | |
943 nssCKFWToken_GetMaxSessionCount | |
944 ( | |
945 NSSCKFWToken *fwToken | |
946 ) | |
947 { | |
948 #ifdef NSSDEBUG | |
949 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
950 return CK_UNAVAILABLE_INFORMATION; | |
951 } | |
952 #endif /* NSSDEBUG */ | |
953 | |
954 if (!fwToken->mdToken->GetMaxSessionCount) { | |
955 return CK_UNAVAILABLE_INFORMATION; | |
956 } | |
957 | |
958 return fwToken->mdToken->GetMaxSessionCount(fwToken->mdToken, fwToken, | |
959 fwToken->mdInstance, fwToken->fwInstance); | |
960 } | |
961 | |
962 /* | |
963 * nssCKFWToken_GetMaxRwSessionCount | |
964 * | |
965 */ | |
966 NSS_IMPLEMENT CK_ULONG | |
967 nssCKFWToken_GetMaxRwSessionCount | |
968 ( | |
969 NSSCKFWToken *fwToken | |
970 ) | |
971 { | |
972 #ifdef NSSDEBUG | |
973 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
974 return CK_UNAVAILABLE_INFORMATION; | |
975 } | |
976 #endif /* NSSDEBUG */ | |
977 | |
978 if (!fwToken->mdToken->GetMaxRwSessionCount) { | |
979 return CK_UNAVAILABLE_INFORMATION; | |
980 } | |
981 | |
982 return fwToken->mdToken->GetMaxRwSessionCount(fwToken->mdToken, fwToken, | |
983 fwToken->mdInstance, fwToken->fwInstance); | |
984 } | |
985 | |
986 /* | |
987 * nssCKFWToken_GetMaxPinLen | |
988 * | |
989 */ | |
990 NSS_IMPLEMENT CK_ULONG | |
991 nssCKFWToken_GetMaxPinLen | |
992 ( | |
993 NSSCKFWToken *fwToken | |
994 ) | |
995 { | |
996 #ifdef NSSDEBUG | |
997 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
998 return CK_UNAVAILABLE_INFORMATION; | |
999 } | |
1000 #endif /* NSSDEBUG */ | |
1001 | |
1002 if (!fwToken->mdToken->GetMaxPinLen) { | |
1003 return CK_UNAVAILABLE_INFORMATION; | |
1004 } | |
1005 | |
1006 return fwToken->mdToken->GetMaxPinLen(fwToken->mdToken, fwToken, | |
1007 fwToken->mdInstance, fwToken->fwInstance); | |
1008 } | |
1009 | |
1010 /* | |
1011 * nssCKFWToken_GetMinPinLen | |
1012 * | |
1013 */ | |
1014 NSS_IMPLEMENT CK_ULONG | |
1015 nssCKFWToken_GetMinPinLen | |
1016 ( | |
1017 NSSCKFWToken *fwToken | |
1018 ) | |
1019 { | |
1020 #ifdef NSSDEBUG | |
1021 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1022 return CK_UNAVAILABLE_INFORMATION; | |
1023 } | |
1024 #endif /* NSSDEBUG */ | |
1025 | |
1026 if (!fwToken->mdToken->GetMinPinLen) { | |
1027 return CK_UNAVAILABLE_INFORMATION; | |
1028 } | |
1029 | |
1030 return fwToken->mdToken->GetMinPinLen(fwToken->mdToken, fwToken, | |
1031 fwToken->mdInstance, fwToken->fwInstance); | |
1032 } | |
1033 | |
1034 /* | |
1035 * nssCKFWToken_GetTotalPublicMemory | |
1036 * | |
1037 */ | |
1038 NSS_IMPLEMENT CK_ULONG | |
1039 nssCKFWToken_GetTotalPublicMemory | |
1040 ( | |
1041 NSSCKFWToken *fwToken | |
1042 ) | |
1043 { | |
1044 #ifdef NSSDEBUG | |
1045 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1046 return CK_UNAVAILABLE_INFORMATION; | |
1047 } | |
1048 #endif /* NSSDEBUG */ | |
1049 | |
1050 if (!fwToken->mdToken->GetTotalPublicMemory) { | |
1051 return CK_UNAVAILABLE_INFORMATION; | |
1052 } | |
1053 | |
1054 return fwToken->mdToken->GetTotalPublicMemory(fwToken->mdToken, fwToken, | |
1055 fwToken->mdInstance, fwToken->fwInstance); | |
1056 } | |
1057 | |
1058 /* | |
1059 * nssCKFWToken_GetFreePublicMemory | |
1060 * | |
1061 */ | |
1062 NSS_IMPLEMENT CK_ULONG | |
1063 nssCKFWToken_GetFreePublicMemory | |
1064 ( | |
1065 NSSCKFWToken *fwToken | |
1066 ) | |
1067 { | |
1068 #ifdef NSSDEBUG | |
1069 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1070 return CK_UNAVAILABLE_INFORMATION; | |
1071 } | |
1072 #endif /* NSSDEBUG */ | |
1073 | |
1074 if (!fwToken->mdToken->GetFreePublicMemory) { | |
1075 return CK_UNAVAILABLE_INFORMATION; | |
1076 } | |
1077 | |
1078 return fwToken->mdToken->GetFreePublicMemory(fwToken->mdToken, fwToken, | |
1079 fwToken->mdInstance, fwToken->fwInstance); | |
1080 } | |
1081 | |
1082 /* | |
1083 * nssCKFWToken_GetTotalPrivateMemory | |
1084 * | |
1085 */ | |
1086 NSS_IMPLEMENT CK_ULONG | |
1087 nssCKFWToken_GetTotalPrivateMemory | |
1088 ( | |
1089 NSSCKFWToken *fwToken | |
1090 ) | |
1091 { | |
1092 #ifdef NSSDEBUG | |
1093 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1094 return CK_UNAVAILABLE_INFORMATION; | |
1095 } | |
1096 #endif /* NSSDEBUG */ | |
1097 | |
1098 if (!fwToken->mdToken->GetTotalPrivateMemory) { | |
1099 return CK_UNAVAILABLE_INFORMATION; | |
1100 } | |
1101 | |
1102 return fwToken->mdToken->GetTotalPrivateMemory(fwToken->mdToken, fwToken, | |
1103 fwToken->mdInstance, fwToken->fwInstance); | |
1104 } | |
1105 | |
1106 /* | |
1107 * nssCKFWToken_GetFreePrivateMemory | |
1108 * | |
1109 */ | |
1110 NSS_IMPLEMENT CK_ULONG | |
1111 nssCKFWToken_GetFreePrivateMemory | |
1112 ( | |
1113 NSSCKFWToken *fwToken | |
1114 ) | |
1115 { | |
1116 #ifdef NSSDEBUG | |
1117 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1118 return CK_UNAVAILABLE_INFORMATION; | |
1119 } | |
1120 #endif /* NSSDEBUG */ | |
1121 | |
1122 if (!fwToken->mdToken->GetFreePrivateMemory) { | |
1123 return CK_UNAVAILABLE_INFORMATION; | |
1124 } | |
1125 | |
1126 return fwToken->mdToken->GetFreePrivateMemory(fwToken->mdToken, fwToken, | |
1127 fwToken->mdInstance, fwToken->fwInstance); | |
1128 } | |
1129 | |
1130 /* | |
1131 * nssCKFWToken_GetHardwareVersion | |
1132 * | |
1133 */ | |
1134 NSS_IMPLEMENT CK_VERSION | |
1135 nssCKFWToken_GetHardwareVersion | |
1136 ( | |
1137 NSSCKFWToken *fwToken | |
1138 ) | |
1139 { | |
1140 CK_VERSION rv; | |
1141 | |
1142 #ifdef NSSDEBUG | |
1143 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1144 rv.major = rv.minor = 0; | |
1145 return rv; | |
1146 } | |
1147 #endif /* NSSDEBUG */ | |
1148 | |
1149 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) { | |
1150 rv.major = rv.minor = 0; | |
1151 return rv; | |
1152 } | |
1153 | |
1154 if( (0 != fwToken->hardwareVersion.major) || | |
1155 (0 != fwToken->hardwareVersion.minor) ) { | |
1156 rv = fwToken->hardwareVersion; | |
1157 goto done; | |
1158 } | |
1159 | |
1160 if (fwToken->mdToken->GetHardwareVersion) { | |
1161 fwToken->hardwareVersion = fwToken->mdToken->GetHardwareVersion( | |
1162 fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); | |
1163 } else { | |
1164 fwToken->hardwareVersion.major = 0; | |
1165 fwToken->hardwareVersion.minor = 1; | |
1166 } | |
1167 | |
1168 rv = fwToken->hardwareVersion; | |
1169 | |
1170 done: | |
1171 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1172 return rv; | |
1173 } | |
1174 | |
1175 /* | |
1176 * nssCKFWToken_GetFirmwareVersion | |
1177 * | |
1178 */ | |
1179 NSS_IMPLEMENT CK_VERSION | |
1180 nssCKFWToken_GetFirmwareVersion | |
1181 ( | |
1182 NSSCKFWToken *fwToken | |
1183 ) | |
1184 { | |
1185 CK_VERSION rv; | |
1186 | |
1187 #ifdef NSSDEBUG | |
1188 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1189 rv.major = rv.minor = 0; | |
1190 return rv; | |
1191 } | |
1192 #endif /* NSSDEBUG */ | |
1193 | |
1194 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) { | |
1195 rv.major = rv.minor = 0; | |
1196 return rv; | |
1197 } | |
1198 | |
1199 if( (0 != fwToken->firmwareVersion.major) || | |
1200 (0 != fwToken->firmwareVersion.minor) ) { | |
1201 rv = fwToken->firmwareVersion; | |
1202 goto done; | |
1203 } | |
1204 | |
1205 if (fwToken->mdToken->GetFirmwareVersion) { | |
1206 fwToken->firmwareVersion = fwToken->mdToken->GetFirmwareVersion( | |
1207 fwToken->mdToken, fwToken, fwToken->mdInstance, fwToken->fwInstance); | |
1208 } else { | |
1209 fwToken->firmwareVersion.major = 0; | |
1210 fwToken->firmwareVersion.minor = 1; | |
1211 } | |
1212 | |
1213 rv = fwToken->firmwareVersion; | |
1214 | |
1215 done: | |
1216 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1217 return rv; | |
1218 } | |
1219 | |
1220 /* | |
1221 * nssCKFWToken_GetUTCTime | |
1222 * | |
1223 */ | |
1224 NSS_IMPLEMENT CK_RV | |
1225 nssCKFWToken_GetUTCTime | |
1226 ( | |
1227 NSSCKFWToken *fwToken, | |
1228 CK_CHAR utcTime[16] | |
1229 ) | |
1230 { | |
1231 CK_RV error = CKR_OK; | |
1232 | |
1233 #ifdef NSSDEBUG | |
1234 error = nssCKFWToken_verifyPointer(fwToken); | |
1235 if( CKR_OK != error ) { | |
1236 return error; | |
1237 } | |
1238 | |
1239 if( (CK_CHAR_PTR)NULL == utcTime ) { | |
1240 return CKR_ARGUMENTS_BAD; | |
1241 } | |
1242 #endif /* DEBUG */ | |
1243 | |
1244 if( CK_TRUE != nssCKFWToken_GetHasClockOnToken(fwToken) ) { | |
1245 /* return CKR_DEVICE_ERROR; */ | |
1246 (void)nssUTF8_CopyIntoFixedBuffer((NSSUTF8 *)NULL, (char *)utcTime, 16, ' ')
; | |
1247 return CKR_OK; | |
1248 } | |
1249 | |
1250 if (!fwToken->mdToken->GetUTCTime) { | |
1251 /* It said it had one! */ | |
1252 return CKR_GENERAL_ERROR; | |
1253 } | |
1254 | |
1255 error = fwToken->mdToken->GetUTCTime(fwToken->mdToken, fwToken, | |
1256 fwToken->mdInstance, fwToken->fwInstance, utcTime); | |
1257 if( CKR_OK != error ) { | |
1258 return error; | |
1259 } | |
1260 | |
1261 /* Sanity-check the data */ | |
1262 { | |
1263 /* Format is YYYYMMDDhhmmss00 */ | |
1264 int i; | |
1265 int Y, M, D, h, m, s, z; | |
1266 static int dims[] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; | |
1267 | |
1268 for( i = 0; i < 16; i++ ) { | |
1269 if( (utcTime[i] < '0') || (utcTime[i] > '9') ) { | |
1270 goto badtime; | |
1271 } | |
1272 } | |
1273 | |
1274 Y = ((utcTime[ 0] - '0') * 1000) + ((utcTime[1] - '0') * 100) + | |
1275 ((utcTime[ 2] - '0') * 10) + (utcTime[ 3] - '0'); | |
1276 M = ((utcTime[ 4] - '0') * 10) + (utcTime[ 5] - '0'); | |
1277 D = ((utcTime[ 6] - '0') * 10) + (utcTime[ 7] - '0'); | |
1278 h = ((utcTime[ 8] - '0') * 10) + (utcTime[ 9] - '0'); | |
1279 m = ((utcTime[10] - '0') * 10) + (utcTime[11] - '0'); | |
1280 s = ((utcTime[12] - '0') * 10) + (utcTime[13] - '0'); | |
1281 z = ((utcTime[14] - '0') * 10) + (utcTime[15] - '0'); | |
1282 | |
1283 if( (Y < 1990) || (Y > 3000) ) goto badtime; /* Y3K problem. heh heh heh */ | |
1284 if( (M < 1) || (M > 12) ) goto badtime; | |
1285 if( (D < 1) || (D > 31) ) goto badtime; | |
1286 | |
1287 if( D > dims[M-1] ) goto badtime; /* per-month check */ | |
1288 if( (2 == M) && (((Y%4)||!(Y%100))&&(Y%400)) && (D > 28) ) goto badtime; /*
leap years */ | |
1289 | |
1290 if( (h < 0) || (h > 23) ) goto badtime; | |
1291 if( (m < 0) || (m > 60) ) goto badtime; | |
1292 if( (s < 0) || (s > 61) ) goto badtime; | |
1293 | |
1294 /* 60m and 60 or 61s is only allowed for leap seconds. */ | |
1295 if( (60 == m) || (s >= 60) ) { | |
1296 if( (23 != h) || (60 != m) || (s < 60) ) goto badtime; | |
1297 /* leap seconds can only happen on June 30 or Dec 31.. I think */ | |
1298 /* if( ((6 != M) || (30 != D)) && ((12 != M) || (31 != D)) ) goto badtime;
*/ | |
1299 } | |
1300 } | |
1301 | |
1302 return CKR_OK; | |
1303 | |
1304 badtime: | |
1305 return CKR_GENERAL_ERROR; | |
1306 } | |
1307 | |
1308 /* | |
1309 * nssCKFWToken_OpenSession | |
1310 * | |
1311 */ | |
1312 NSS_IMPLEMENT NSSCKFWSession * | |
1313 nssCKFWToken_OpenSession | |
1314 ( | |
1315 NSSCKFWToken *fwToken, | |
1316 CK_BBOOL rw, | |
1317 CK_VOID_PTR pApplication, | |
1318 CK_NOTIFY Notify, | |
1319 CK_RV *pError | |
1320 ) | |
1321 { | |
1322 NSSCKFWSession *fwSession = (NSSCKFWSession *)NULL; | |
1323 NSSCKMDSession *mdSession; | |
1324 | |
1325 #ifdef NSSDEBUG | |
1326 if (!pError) { | |
1327 return (NSSCKFWSession *)NULL; | |
1328 } | |
1329 | |
1330 *pError = nssCKFWToken_verifyPointer(fwToken); | |
1331 if( CKR_OK != *pError ) { | |
1332 return (NSSCKFWSession *)NULL; | |
1333 } | |
1334 | |
1335 switch( rw ) { | |
1336 case CK_TRUE: | |
1337 case CK_FALSE: | |
1338 break; | |
1339 default: | |
1340 *pError = CKR_ARGUMENTS_BAD; | |
1341 return (NSSCKFWSession *)NULL; | |
1342 } | |
1343 #endif /* NSSDEBUG */ | |
1344 | |
1345 *pError = nssCKFWMutex_Lock(fwToken->mutex); | |
1346 if( CKR_OK != *pError ) { | |
1347 return (NSSCKFWSession *)NULL; | |
1348 } | |
1349 | |
1350 if( CK_TRUE == rw ) { | |
1351 /* Read-write session desired */ | |
1352 if( CK_TRUE == nssCKFWToken_GetIsWriteProtected(fwToken) ) { | |
1353 *pError = CKR_TOKEN_WRITE_PROTECTED; | |
1354 goto done; | |
1355 } | |
1356 } else { | |
1357 /* Read-only session desired */ | |
1358 if( CKS_RW_SO_FUNCTIONS == nssCKFWToken_GetSessionState(fwToken) ) { | |
1359 *pError = CKR_SESSION_READ_WRITE_SO_EXISTS; | |
1360 goto done; | |
1361 } | |
1362 } | |
1363 | |
1364 /* We could compare sesion counts to any limits we know of, I guess.. */ | |
1365 | |
1366 if (!fwToken->mdToken->OpenSession) { | |
1367 /* | |
1368 * I'm not sure that the Module actually needs to implement | |
1369 * mdSessions -- the Framework can keep track of everything | |
1370 * needed, really. But I'll sort out that detail later.. | |
1371 */ | |
1372 *pError = CKR_GENERAL_ERROR; | |
1373 goto done; | |
1374 } | |
1375 | |
1376 fwSession = nssCKFWSession_Create(fwToken, rw, pApplication, Notify, pError); | |
1377 if (!fwSession) { | |
1378 if( CKR_OK == *pError ) { | |
1379 *pError = CKR_GENERAL_ERROR; | |
1380 } | |
1381 goto done; | |
1382 } | |
1383 | |
1384 mdSession = fwToken->mdToken->OpenSession(fwToken->mdToken, fwToken, | |
1385 fwToken->mdInstance, fwToken->fwInstance, fwSession, | |
1386 rw, pError); | |
1387 if (!mdSession) { | |
1388 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); | |
1389 if( CKR_OK == *pError ) { | |
1390 *pError = CKR_GENERAL_ERROR; | |
1391 } | |
1392 goto done; | |
1393 } | |
1394 | |
1395 *pError = nssCKFWSession_SetMDSession(fwSession, mdSession); | |
1396 if( CKR_OK != *pError ) { | |
1397 if (mdSession->Close) { | |
1398 mdSession->Close(mdSession, fwSession, fwToken->mdToken, fwToken, | |
1399 fwToken->mdInstance, fwToken->fwInstance); | |
1400 } | |
1401 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); | |
1402 goto done; | |
1403 } | |
1404 | |
1405 *pError = nssCKFWHash_Add(fwToken->sessions, fwSession, fwSession); | |
1406 if( CKR_OK != *pError ) { | |
1407 (void)nssCKFWSession_Destroy(fwSession, CK_FALSE); | |
1408 fwSession = (NSSCKFWSession *)NULL; | |
1409 goto done; | |
1410 } | |
1411 | |
1412 done: | |
1413 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1414 return fwSession; | |
1415 } | |
1416 | |
1417 /* | |
1418 * nssCKFWToken_GetMechanismCount | |
1419 * | |
1420 */ | |
1421 NSS_IMPLEMENT CK_ULONG | |
1422 nssCKFWToken_GetMechanismCount | |
1423 ( | |
1424 NSSCKFWToken *fwToken | |
1425 ) | |
1426 { | |
1427 #ifdef NSSDEBUG | |
1428 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1429 return 0; | |
1430 } | |
1431 #endif /* NSSDEBUG */ | |
1432 | |
1433 if (!fwToken->mdToken->GetMechanismCount) { | |
1434 return 0; | |
1435 } | |
1436 | |
1437 return fwToken->mdToken->GetMechanismCount(fwToken->mdToken, fwToken, | |
1438 fwToken->mdInstance, fwToken->fwInstance); | |
1439 } | |
1440 | |
1441 /* | |
1442 * nssCKFWToken_GetMechanismTypes | |
1443 * | |
1444 */ | |
1445 NSS_IMPLEMENT CK_RV | |
1446 nssCKFWToken_GetMechanismTypes | |
1447 ( | |
1448 NSSCKFWToken *fwToken, | |
1449 CK_MECHANISM_TYPE types[] | |
1450 ) | |
1451 { | |
1452 #ifdef NSSDEBUG | |
1453 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1454 return CKR_ARGUMENTS_BAD; | |
1455 } | |
1456 | |
1457 if (!types) { | |
1458 return CKR_ARGUMENTS_BAD; | |
1459 } | |
1460 #endif /* NSSDEBUG */ | |
1461 | |
1462 if (!fwToken->mdToken->GetMechanismTypes) { | |
1463 /* | |
1464 * This should only be called with a sufficiently-large | |
1465 * "types" array, which can only be done if GetMechanismCount | |
1466 * is implemented. If that's implemented (and returns nonzero), | |
1467 * then this should be too. So return an error. | |
1468 */ | |
1469 return CKR_GENERAL_ERROR; | |
1470 } | |
1471 | |
1472 return fwToken->mdToken->GetMechanismTypes(fwToken->mdToken, fwToken, | |
1473 fwToken->mdInstance, fwToken->fwInstance, types); | |
1474 } | |
1475 | |
1476 | |
1477 /* | |
1478 * nssCKFWToken_GetMechanism | |
1479 * | |
1480 */ | |
1481 NSS_IMPLEMENT NSSCKFWMechanism * | |
1482 nssCKFWToken_GetMechanism | |
1483 ( | |
1484 NSSCKFWToken *fwToken, | |
1485 CK_MECHANISM_TYPE which, | |
1486 CK_RV *pError | |
1487 ) | |
1488 { | |
1489 NSSCKMDMechanism *mdMechanism; | |
1490 if (!fwToken->mdMechanismHash) { | |
1491 *pError = CKR_GENERAL_ERROR; | |
1492 return (NSSCKFWMechanism *)NULL; | |
1493 } | |
1494 | |
1495 if (!fwToken->mdToken->GetMechanism) { | |
1496 /* | |
1497 * If we don't implement any GetMechanism function, then we must | |
1498 * not support any. | |
1499 */ | |
1500 *pError = CKR_MECHANISM_INVALID; | |
1501 return (NSSCKFWMechanism *)NULL; | |
1502 } | |
1503 | |
1504 /* lookup in hash table */ | |
1505 mdMechanism = fwToken->mdToken->GetMechanism(fwToken->mdToken, fwToken, | |
1506 fwToken->mdInstance, fwToken->fwInstance, which, pError); | |
1507 if (!mdMechanism) { | |
1508 return (NSSCKFWMechanism *) NULL; | |
1509 } | |
1510 /* store in hash table */ | |
1511 return nssCKFWMechanism_Create(mdMechanism, fwToken->mdToken, fwToken, | |
1512 fwToken->mdInstance, fwToken->fwInstance); | |
1513 } | |
1514 | |
1515 NSS_IMPLEMENT CK_RV | |
1516 nssCKFWToken_SetSessionState | |
1517 ( | |
1518 NSSCKFWToken *fwToken, | |
1519 CK_STATE newState | |
1520 ) | |
1521 { | |
1522 CK_RV error = CKR_OK; | |
1523 | |
1524 #ifdef NSSDEBUG | |
1525 error = nssCKFWToken_verifyPointer(fwToken); | |
1526 if( CKR_OK != error ) { | |
1527 return error; | |
1528 } | |
1529 | |
1530 switch( newState ) { | |
1531 case CKS_RO_PUBLIC_SESSION: | |
1532 case CKS_RO_USER_FUNCTIONS: | |
1533 case CKS_RW_PUBLIC_SESSION: | |
1534 case CKS_RW_USER_FUNCTIONS: | |
1535 case CKS_RW_SO_FUNCTIONS: | |
1536 break; | |
1537 default: | |
1538 return CKR_ARGUMENTS_BAD; | |
1539 } | |
1540 #endif /* NSSDEBUG */ | |
1541 | |
1542 error = nssCKFWMutex_Lock(fwToken->mutex); | |
1543 if( CKR_OK != error ) { | |
1544 return error; | |
1545 } | |
1546 | |
1547 fwToken->state = newState; | |
1548 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1549 return CKR_OK; | |
1550 } | |
1551 | |
1552 /* | |
1553 * nssCKFWToken_RemoveSession | |
1554 * | |
1555 */ | |
1556 NSS_IMPLEMENT CK_RV | |
1557 nssCKFWToken_RemoveSession | |
1558 ( | |
1559 NSSCKFWToken *fwToken, | |
1560 NSSCKFWSession *fwSession | |
1561 ) | |
1562 { | |
1563 CK_RV error = CKR_OK; | |
1564 | |
1565 #ifdef NSSDEBUG | |
1566 error = nssCKFWToken_verifyPointer(fwToken); | |
1567 if( CKR_OK != error ) { | |
1568 return error; | |
1569 } | |
1570 | |
1571 error = nssCKFWSession_verifyPointer(fwSession); | |
1572 if( CKR_OK != error ) { | |
1573 return error; | |
1574 } | |
1575 #endif /* NSSDEBUG */ | |
1576 | |
1577 error = nssCKFWMutex_Lock(fwToken->mutex); | |
1578 if( CKR_OK != error ) { | |
1579 return error; | |
1580 } | |
1581 | |
1582 if( CK_TRUE != nssCKFWHash_Exists(fwToken->sessions, fwSession) ) { | |
1583 error = CKR_SESSION_HANDLE_INVALID; | |
1584 goto done; | |
1585 } | |
1586 | |
1587 nssCKFWHash_Remove(fwToken->sessions, fwSession); | |
1588 fwToken->sessionCount--; | |
1589 | |
1590 if( nssCKFWSession_IsRWSession(fwSession) ) { | |
1591 fwToken->rwSessionCount--; | |
1592 } | |
1593 | |
1594 if( 0 == fwToken->sessionCount ) { | |
1595 fwToken->rwSessionCount = 0; /* sanity */ | |
1596 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */ | |
1597 } | |
1598 | |
1599 error = CKR_OK; | |
1600 | |
1601 done: | |
1602 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1603 return error; | |
1604 } | |
1605 | |
1606 | |
1607 /* | |
1608 * nssCKFWToken_CloseAllSessions | |
1609 * | |
1610 */ | |
1611 NSS_IMPLEMENT CK_RV | |
1612 nssCKFWToken_CloseAllSessions | |
1613 ( | |
1614 NSSCKFWToken *fwToken | |
1615 ) | |
1616 { | |
1617 CK_RV error = CKR_OK; | |
1618 | |
1619 #ifdef NSSDEBUG | |
1620 error = nssCKFWToken_verifyPointer(fwToken); | |
1621 if( CKR_OK != error ) { | |
1622 return error; | |
1623 } | |
1624 #endif /* NSSDEBUG */ | |
1625 | |
1626 error = nssCKFWMutex_Lock(fwToken->mutex); | |
1627 if( CKR_OK != error ) { | |
1628 return error; | |
1629 } | |
1630 | |
1631 nssCKFWHash_Iterate(fwToken->sessions, nss_ckfwtoken_session_iterator, (void *
)NULL); | |
1632 | |
1633 nssCKFWHash_Destroy(fwToken->sessions); | |
1634 | |
1635 fwToken->sessions = nssCKFWHash_Create(fwToken->fwInstance, fwToken->arena, &e
rror); | |
1636 if (!fwToken->sessions) { | |
1637 if( CKR_OK == error ) { | |
1638 error = CKR_GENERAL_ERROR; | |
1639 } | |
1640 goto done; | |
1641 } | |
1642 | |
1643 fwToken->state = CKS_RO_PUBLIC_SESSION; /* some default */ | |
1644 fwToken->sessionCount = 0; | |
1645 fwToken->rwSessionCount = 0; | |
1646 | |
1647 error = CKR_OK; | |
1648 | |
1649 done: | |
1650 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1651 return error; | |
1652 } | |
1653 | |
1654 /* | |
1655 * nssCKFWToken_GetSessionCount | |
1656 * | |
1657 */ | |
1658 NSS_IMPLEMENT CK_ULONG | |
1659 nssCKFWToken_GetSessionCount | |
1660 ( | |
1661 NSSCKFWToken *fwToken | |
1662 ) | |
1663 { | |
1664 CK_ULONG rv; | |
1665 | |
1666 #ifdef NSSDEBUG | |
1667 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1668 return (CK_ULONG)0; | |
1669 } | |
1670 #endif /* NSSDEBUG */ | |
1671 | |
1672 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) { | |
1673 return (CK_ULONG)0; | |
1674 } | |
1675 | |
1676 rv = fwToken->sessionCount; | |
1677 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1678 return rv; | |
1679 } | |
1680 | |
1681 /* | |
1682 * nssCKFWToken_GetRwSessionCount | |
1683 * | |
1684 */ | |
1685 NSS_IMPLEMENT CK_ULONG | |
1686 nssCKFWToken_GetRwSessionCount | |
1687 ( | |
1688 NSSCKFWToken *fwToken | |
1689 ) | |
1690 { | |
1691 CK_ULONG rv; | |
1692 | |
1693 #ifdef NSSDEBUG | |
1694 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1695 return (CK_ULONG)0; | |
1696 } | |
1697 #endif /* NSSDEBUG */ | |
1698 | |
1699 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) { | |
1700 return (CK_ULONG)0; | |
1701 } | |
1702 | |
1703 rv = fwToken->rwSessionCount; | |
1704 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1705 return rv; | |
1706 } | |
1707 | |
1708 /* | |
1709 * nssCKFWToken_GetRoSessionCount | |
1710 * | |
1711 */ | |
1712 NSS_IMPLEMENT CK_ULONG | |
1713 nssCKFWToken_GetRoSessionCount | |
1714 ( | |
1715 NSSCKFWToken *fwToken | |
1716 ) | |
1717 { | |
1718 CK_ULONG rv; | |
1719 | |
1720 #ifdef NSSDEBUG | |
1721 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1722 return (CK_ULONG)0; | |
1723 } | |
1724 #endif /* NSSDEBUG */ | |
1725 | |
1726 if( CKR_OK != nssCKFWMutex_Lock(fwToken->mutex) ) { | |
1727 return (CK_ULONG)0; | |
1728 } | |
1729 | |
1730 rv = fwToken->sessionCount - fwToken->rwSessionCount; | |
1731 (void)nssCKFWMutex_Unlock(fwToken->mutex); | |
1732 return rv; | |
1733 } | |
1734 | |
1735 /* | |
1736 * nssCKFWToken_GetSessionObjectHash | |
1737 * | |
1738 */ | |
1739 NSS_IMPLEMENT nssCKFWHash * | |
1740 nssCKFWToken_GetSessionObjectHash | |
1741 ( | |
1742 NSSCKFWToken *fwToken | |
1743 ) | |
1744 { | |
1745 #ifdef NSSDEBUG | |
1746 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1747 return (nssCKFWHash *)NULL; | |
1748 } | |
1749 #endif /* NSSDEBUG */ | |
1750 | |
1751 return fwToken->sessionObjectHash; | |
1752 } | |
1753 | |
1754 /* | |
1755 * nssCKFWToken_GetMDObjectHash | |
1756 * | |
1757 */ | |
1758 NSS_IMPLEMENT nssCKFWHash * | |
1759 nssCKFWToken_GetMDObjectHash | |
1760 ( | |
1761 NSSCKFWToken *fwToken | |
1762 ) | |
1763 { | |
1764 #ifdef NSSDEBUG | |
1765 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1766 return (nssCKFWHash *)NULL; | |
1767 } | |
1768 #endif /* NSSDEBUG */ | |
1769 | |
1770 return fwToken->mdObjectHash; | |
1771 } | |
1772 | |
1773 /* | |
1774 * nssCKFWToken_GetObjectHandleHash | |
1775 * | |
1776 */ | |
1777 NSS_IMPLEMENT nssCKFWHash * | |
1778 nssCKFWToken_GetObjectHandleHash | |
1779 ( | |
1780 NSSCKFWToken *fwToken | |
1781 ) | |
1782 { | |
1783 #ifdef NSSDEBUG | |
1784 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1785 return (nssCKFWHash *)NULL; | |
1786 } | |
1787 #endif /* NSSDEBUG */ | |
1788 | |
1789 return fwToken->mdObjectHash; | |
1790 } | |
1791 | |
1792 /* | |
1793 * NSSCKFWToken_GetMDToken | |
1794 * | |
1795 */ | |
1796 | |
1797 NSS_IMPLEMENT NSSCKMDToken * | |
1798 NSSCKFWToken_GetMDToken | |
1799 ( | |
1800 NSSCKFWToken *fwToken | |
1801 ) | |
1802 { | |
1803 #ifdef DEBUG | |
1804 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1805 return (NSSCKMDToken *)NULL; | |
1806 } | |
1807 #endif /* DEBUG */ | |
1808 | |
1809 return nssCKFWToken_GetMDToken(fwToken); | |
1810 } | |
1811 | |
1812 /* | |
1813 * NSSCKFWToken_GetArena | |
1814 * | |
1815 */ | |
1816 | |
1817 NSS_IMPLEMENT NSSArena * | |
1818 NSSCKFWToken_GetArena | |
1819 ( | |
1820 NSSCKFWToken *fwToken, | |
1821 CK_RV *pError | |
1822 ) | |
1823 { | |
1824 #ifdef DEBUG | |
1825 if (!pError) { | |
1826 return (NSSArena *)NULL; | |
1827 } | |
1828 | |
1829 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1830 *pError = CKR_ARGUMENTS_BAD; | |
1831 return (NSSArena *)NULL; | |
1832 } | |
1833 #endif /* DEBUG */ | |
1834 | |
1835 return nssCKFWToken_GetArena(fwToken, pError); | |
1836 } | |
1837 | |
1838 /* | |
1839 * NSSCKFWToken_GetFWSlot | |
1840 * | |
1841 */ | |
1842 | |
1843 NSS_IMPLEMENT NSSCKFWSlot * | |
1844 NSSCKFWToken_GetFWSlot | |
1845 ( | |
1846 NSSCKFWToken *fwToken | |
1847 ) | |
1848 { | |
1849 #ifdef DEBUG | |
1850 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1851 return (NSSCKFWSlot *)NULL; | |
1852 } | |
1853 #endif /* DEBUG */ | |
1854 | |
1855 return nssCKFWToken_GetFWSlot(fwToken); | |
1856 } | |
1857 | |
1858 /* | |
1859 * NSSCKFWToken_GetMDSlot | |
1860 * | |
1861 */ | |
1862 | |
1863 NSS_IMPLEMENT NSSCKMDSlot * | |
1864 NSSCKFWToken_GetMDSlot | |
1865 ( | |
1866 NSSCKFWToken *fwToken | |
1867 ) | |
1868 { | |
1869 #ifdef DEBUG | |
1870 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1871 return (NSSCKMDSlot *)NULL; | |
1872 } | |
1873 #endif /* DEBUG */ | |
1874 | |
1875 return nssCKFWToken_GetMDSlot(fwToken); | |
1876 } | |
1877 | |
1878 /* | |
1879 * NSSCKFWToken_GetSessionState | |
1880 * | |
1881 */ | |
1882 | |
1883 NSS_IMPLEMENT CK_STATE | |
1884 NSSCKFWSession_GetSessionState | |
1885 ( | |
1886 NSSCKFWToken *fwToken | |
1887 ) | |
1888 { | |
1889 #ifdef DEBUG | |
1890 if( CKR_OK != nssCKFWToken_verifyPointer(fwToken) ) { | |
1891 return CKS_RO_PUBLIC_SESSION; | |
1892 } | |
1893 #endif /* DEBUG */ | |
1894 | |
1895 return nssCKFWToken_GetSessionState(fwToken); | |
1896 } | |
OLD | NEW |