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