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: session.c,v $ $Revision: 1.15 $ $Da
te: 2012/04/25 14:49:28 $"; | |
7 #endif /* DEBUG */ | |
8 | |
9 /* | |
10 * session.c | |
11 * | |
12 * This file implements the NSSCKFWSession type and methods. | |
13 */ | |
14 | |
15 #ifndef CK_T | |
16 #include "ck.h" | |
17 #endif /* CK_T */ | |
18 | |
19 /* | |
20 * NSSCKFWSession | |
21 * | |
22 * -- create/destroy -- | |
23 * nssCKFWSession_Create | |
24 * nssCKFWSession_Destroy | |
25 * | |
26 * -- public accessors -- | |
27 * NSSCKFWSession_GetMDSession | |
28 * NSSCKFWSession_GetArena | |
29 * NSSCKFWSession_CallNotification | |
30 * NSSCKFWSession_IsRWSession | |
31 * NSSCKFWSession_IsSO | |
32 * | |
33 * -- implement public accessors -- | |
34 * nssCKFWSession_GetMDSession | |
35 * nssCKFWSession_GetArena | |
36 * nssCKFWSession_CallNotification | |
37 * nssCKFWSession_IsRWSession | |
38 * nssCKFWSession_IsSO | |
39 * | |
40 * -- private accessors -- | |
41 * nssCKFWSession_GetSlot | |
42 * nssCKFWSession_GetSessionState | |
43 * nssCKFWSession_SetFWFindObjects | |
44 * nssCKFWSession_GetFWFindObjects | |
45 * nssCKFWSession_SetMDSession | |
46 * nssCKFWSession_SetHandle | |
47 * nssCKFWSession_GetHandle | |
48 * nssCKFWSession_RegisterSessionObject | |
49 * nssCKFWSession_DeegisterSessionObject | |
50 * | |
51 * -- module fronts -- | |
52 * nssCKFWSession_GetDeviceError | |
53 * nssCKFWSession_Login | |
54 * nssCKFWSession_Logout | |
55 * nssCKFWSession_InitPIN | |
56 * nssCKFWSession_SetPIN | |
57 * nssCKFWSession_GetOperationStateLen | |
58 * nssCKFWSession_GetOperationState | |
59 * nssCKFWSession_SetOperationState | |
60 * nssCKFWSession_CreateObject | |
61 * nssCKFWSession_CopyObject | |
62 * nssCKFWSession_FindObjectsInit | |
63 * nssCKFWSession_SeedRandom | |
64 * nssCKFWSession_GetRandom | |
65 */ | |
66 | |
67 struct NSSCKFWSessionStr { | |
68 NSSArena *arena; | |
69 NSSCKMDSession *mdSession; | |
70 NSSCKFWToken *fwToken; | |
71 NSSCKMDToken *mdToken; | |
72 NSSCKFWInstance *fwInstance; | |
73 NSSCKMDInstance *mdInstance; | |
74 CK_VOID_PTR pApplication; | |
75 CK_NOTIFY Notify; | |
76 | |
77 /* | |
78 * Everything above is set at creation time, and then not modified. | |
79 * The items below are atomic. No locking required. If we fear | |
80 * about pointer-copies being nonatomic, we'll lock fwFindObjects. | |
81 */ | |
82 | |
83 CK_BBOOL rw; | |
84 NSSCKFWFindObjects *fwFindObjects; | |
85 NSSCKFWCryptoOperation *fwOperationArray[NSSCKFWCryptoOperationState_Max]; | |
86 nssCKFWHash *sessionObjectHash; | |
87 CK_SESSION_HANDLE hSession; | |
88 }; | |
89 | |
90 #ifdef DEBUG | |
91 /* | |
92 * But first, the pointer-tracking stuff. | |
93 * | |
94 * NOTE: the pointer-tracking support in NSS/base currently relies | |
95 * upon NSPR's CallOnce support. That, however, relies upon NSPR's | |
96 * locking, which is tied into the runtime. We need a pointer-tracker | |
97 * implementation that uses the locks supplied through C_Initialize. | |
98 * That support, however, can be filled in later. So for now, I'll | |
99 * just do this routines as no-ops. | |
100 */ | |
101 | |
102 static CK_RV | |
103 session_add_pointer | |
104 ( | |
105 const NSSCKFWSession *fwSession | |
106 ) | |
107 { | |
108 return CKR_OK; | |
109 } | |
110 | |
111 static CK_RV | |
112 session_remove_pointer | |
113 ( | |
114 const NSSCKFWSession *fwSession | |
115 ) | |
116 { | |
117 return CKR_OK; | |
118 } | |
119 | |
120 NSS_IMPLEMENT CK_RV | |
121 nssCKFWSession_verifyPointer | |
122 ( | |
123 const NSSCKFWSession *fwSession | |
124 ) | |
125 { | |
126 return CKR_OK; | |
127 } | |
128 | |
129 #endif /* DEBUG */ | |
130 | |
131 /* | |
132 * nssCKFWSession_Create | |
133 * | |
134 */ | |
135 NSS_IMPLEMENT NSSCKFWSession * | |
136 nssCKFWSession_Create | |
137 ( | |
138 NSSCKFWToken *fwToken, | |
139 CK_BBOOL rw, | |
140 CK_VOID_PTR pApplication, | |
141 CK_NOTIFY Notify, | |
142 CK_RV *pError | |
143 ) | |
144 { | |
145 NSSArena *arena = (NSSArena *)NULL; | |
146 NSSCKFWSession *fwSession; | |
147 NSSCKFWSlot *fwSlot; | |
148 | |
149 #ifdef NSSDEBUG | |
150 if (!pError) { | |
151 return (NSSCKFWSession *)NULL; | |
152 } | |
153 | |
154 *pError = nssCKFWToken_verifyPointer(fwToken); | |
155 if( CKR_OK != *pError ) { | |
156 return (NSSCKFWSession *)NULL; | |
157 } | |
158 #endif /* NSSDEBUG */ | |
159 | |
160 arena = NSSArena_Create(); | |
161 if (!arena) { | |
162 *pError = CKR_HOST_MEMORY; | |
163 return (NSSCKFWSession *)NULL; | |
164 } | |
165 | |
166 fwSession = nss_ZNEW(arena, NSSCKFWSession); | |
167 if (!fwSession) { | |
168 *pError = CKR_HOST_MEMORY; | |
169 goto loser; | |
170 } | |
171 | |
172 fwSession->arena = arena; | |
173 fwSession->mdSession = (NSSCKMDSession *)NULL; /* set later */ | |
174 fwSession->fwToken = fwToken; | |
175 fwSession->mdToken = nssCKFWToken_GetMDToken(fwToken); | |
176 | |
177 fwSlot = nssCKFWToken_GetFWSlot(fwToken); | |
178 fwSession->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot); | |
179 fwSession->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot); | |
180 | |
181 fwSession->rw = rw; | |
182 fwSession->pApplication = pApplication; | |
183 fwSession->Notify = Notify; | |
184 | |
185 fwSession->fwFindObjects = (NSSCKFWFindObjects *)NULL; | |
186 | |
187 fwSession->sessionObjectHash = nssCKFWHash_Create(fwSession->fwInstance, arena
, pError); | |
188 if (!fwSession->sessionObjectHash) { | |
189 if( CKR_OK == *pError ) { | |
190 *pError = CKR_GENERAL_ERROR; | |
191 } | |
192 goto loser; | |
193 } | |
194 | |
195 #ifdef DEBUG | |
196 *pError = session_add_pointer(fwSession); | |
197 if( CKR_OK != *pError ) { | |
198 goto loser; | |
199 } | |
200 #endif /* DEBUG */ | |
201 | |
202 return fwSession; | |
203 | |
204 loser: | |
205 if (arena) { | |
206 if (fwSession && fwSession->sessionObjectHash) { | |
207 (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash); | |
208 } | |
209 NSSArena_Destroy(arena); | |
210 } | |
211 | |
212 return (NSSCKFWSession *)NULL; | |
213 } | |
214 | |
215 static void | |
216 nss_ckfw_session_object_destroy_iterator | |
217 ( | |
218 const void *key, | |
219 void *value, | |
220 void *closure | |
221 ) | |
222 { | |
223 NSSCKFWObject *fwObject = (NSSCKFWObject *)value; | |
224 nssCKFWObject_Finalize(fwObject, PR_TRUE); | |
225 } | |
226 | |
227 /* | |
228 * nssCKFWSession_Destroy | |
229 * | |
230 */ | |
231 NSS_IMPLEMENT CK_RV | |
232 nssCKFWSession_Destroy | |
233 ( | |
234 NSSCKFWSession *fwSession, | |
235 CK_BBOOL removeFromTokenHash | |
236 ) | |
237 { | |
238 CK_RV error = CKR_OK; | |
239 nssCKFWHash *sessionObjectHash; | |
240 NSSCKFWCryptoOperationState i; | |
241 | |
242 #ifdef NSSDEBUG | |
243 error = nssCKFWSession_verifyPointer(fwSession); | |
244 if( CKR_OK != error ) { | |
245 return error; | |
246 } | |
247 #endif /* NSSDEBUG */ | |
248 | |
249 if( removeFromTokenHash ) { | |
250 error = nssCKFWToken_RemoveSession(fwSession->fwToken, fwSession); | |
251 } | |
252 | |
253 /* | |
254 * Invalidate session objects | |
255 */ | |
256 | |
257 sessionObjectHash = fwSession->sessionObjectHash; | |
258 fwSession->sessionObjectHash = (nssCKFWHash *)NULL; | |
259 | |
260 nssCKFWHash_Iterate(sessionObjectHash, | |
261 nss_ckfw_session_object_destroy_iterator, | |
262 (void *)NULL); | |
263 | |
264 for (i=0; i < NSSCKFWCryptoOperationState_Max; i++) { | |
265 if (fwSession->fwOperationArray[i]) { | |
266 nssCKFWCryptoOperation_Destroy(fwSession->fwOperationArray[i]); | |
267 } | |
268 } | |
269 | |
270 #ifdef DEBUG | |
271 (void)session_remove_pointer(fwSession); | |
272 #endif /* DEBUG */ | |
273 (void)nssCKFWHash_Destroy(sessionObjectHash); | |
274 NSSArena_Destroy(fwSession->arena); | |
275 | |
276 return error; | |
277 } | |
278 | |
279 /* | |
280 * nssCKFWSession_GetMDSession | |
281 * | |
282 */ | |
283 NSS_IMPLEMENT NSSCKMDSession * | |
284 nssCKFWSession_GetMDSession | |
285 ( | |
286 NSSCKFWSession *fwSession | |
287 ) | |
288 { | |
289 #ifdef NSSDEBUG | |
290 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
291 return (NSSCKMDSession *)NULL; | |
292 } | |
293 #endif /* NSSDEBUG */ | |
294 | |
295 return fwSession->mdSession; | |
296 } | |
297 | |
298 /* | |
299 * nssCKFWSession_GetArena | |
300 * | |
301 */ | |
302 NSS_IMPLEMENT NSSArena * | |
303 nssCKFWSession_GetArena | |
304 ( | |
305 NSSCKFWSession *fwSession, | |
306 CK_RV *pError | |
307 ) | |
308 { | |
309 #ifdef NSSDEBUG | |
310 if (!pError) { | |
311 return (NSSArena *)NULL; | |
312 } | |
313 | |
314 *pError = nssCKFWSession_verifyPointer(fwSession); | |
315 if( CKR_OK != *pError ) { | |
316 return (NSSArena *)NULL; | |
317 } | |
318 #endif /* NSSDEBUG */ | |
319 | |
320 return fwSession->arena; | |
321 } | |
322 | |
323 /* | |
324 * nssCKFWSession_CallNotification | |
325 * | |
326 */ | |
327 NSS_IMPLEMENT CK_RV | |
328 nssCKFWSession_CallNotification | |
329 ( | |
330 NSSCKFWSession *fwSession, | |
331 CK_NOTIFICATION event | |
332 ) | |
333 { | |
334 CK_RV error = CKR_OK; | |
335 CK_SESSION_HANDLE handle; | |
336 | |
337 #ifdef NSSDEBUG | |
338 error = nssCKFWSession_verifyPointer(fwSession); | |
339 if( CKR_OK != error ) { | |
340 return error; | |
341 } | |
342 #endif /* NSSDEBUG */ | |
343 | |
344 if( (CK_NOTIFY)NULL == fwSession->Notify ) { | |
345 return CKR_OK; | |
346 } | |
347 | |
348 handle = nssCKFWInstance_FindSessionHandle(fwSession->fwInstance, fwSession); | |
349 if( (CK_SESSION_HANDLE)0 == handle ) { | |
350 return CKR_GENERAL_ERROR; | |
351 } | |
352 | |
353 error = fwSession->Notify(handle, event, fwSession->pApplication); | |
354 | |
355 return error; | |
356 } | |
357 | |
358 /* | |
359 * nssCKFWSession_IsRWSession | |
360 * | |
361 */ | |
362 NSS_IMPLEMENT CK_BBOOL | |
363 nssCKFWSession_IsRWSession | |
364 ( | |
365 NSSCKFWSession *fwSession | |
366 ) | |
367 { | |
368 #ifdef NSSDEBUG | |
369 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
370 return CK_FALSE; | |
371 } | |
372 #endif /* NSSDEBUG */ | |
373 | |
374 return fwSession->rw; | |
375 } | |
376 | |
377 /* | |
378 * nssCKFWSession_IsSO | |
379 * | |
380 */ | |
381 NSS_IMPLEMENT CK_BBOOL | |
382 nssCKFWSession_IsSO | |
383 ( | |
384 NSSCKFWSession *fwSession | |
385 ) | |
386 { | |
387 CK_STATE state; | |
388 | |
389 #ifdef NSSDEBUG | |
390 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
391 return CK_FALSE; | |
392 } | |
393 #endif /* NSSDEBUG */ | |
394 | |
395 state = nssCKFWToken_GetSessionState(fwSession->fwToken); | |
396 switch( state ) { | |
397 case CKS_RO_PUBLIC_SESSION: | |
398 case CKS_RO_USER_FUNCTIONS: | |
399 case CKS_RW_PUBLIC_SESSION: | |
400 case CKS_RW_USER_FUNCTIONS: | |
401 return CK_FALSE; | |
402 case CKS_RW_SO_FUNCTIONS: | |
403 return CK_TRUE; | |
404 default: | |
405 return CK_FALSE; | |
406 } | |
407 } | |
408 | |
409 /* | |
410 * nssCKFWSession_GetFWSlot | |
411 * | |
412 */ | |
413 NSS_IMPLEMENT NSSCKFWSlot * | |
414 nssCKFWSession_GetFWSlot | |
415 ( | |
416 NSSCKFWSession *fwSession | |
417 ) | |
418 { | |
419 #ifdef NSSDEBUG | |
420 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
421 return (NSSCKFWSlot *)NULL; | |
422 } | |
423 #endif /* NSSDEBUG */ | |
424 | |
425 return nssCKFWToken_GetFWSlot(fwSession->fwToken); | |
426 } | |
427 | |
428 /* | |
429 * nssCFKWSession_GetSessionState | |
430 * | |
431 */ | |
432 NSS_IMPLEMENT CK_STATE | |
433 nssCKFWSession_GetSessionState | |
434 ( | |
435 NSSCKFWSession *fwSession | |
436 ) | |
437 { | |
438 #ifdef NSSDEBUG | |
439 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
440 return CKS_RO_PUBLIC_SESSION; /* whatever */ | |
441 } | |
442 #endif /* NSSDEBUG */ | |
443 | |
444 return nssCKFWToken_GetSessionState(fwSession->fwToken); | |
445 } | |
446 | |
447 /* | |
448 * nssCKFWSession_SetFWFindObjects | |
449 * | |
450 */ | |
451 NSS_IMPLEMENT CK_RV | |
452 nssCKFWSession_SetFWFindObjects | |
453 ( | |
454 NSSCKFWSession *fwSession, | |
455 NSSCKFWFindObjects *fwFindObjects | |
456 ) | |
457 { | |
458 #ifdef NSSDEBUG | |
459 CK_RV error = CKR_OK; | |
460 #endif /* NSSDEBUG */ | |
461 | |
462 #ifdef NSSDEBUG | |
463 error = nssCKFWSession_verifyPointer(fwSession); | |
464 if( CKR_OK != error ) { | |
465 return error; | |
466 } | |
467 | |
468 /* fwFindObjects may be null */ | |
469 #endif /* NSSDEBUG */ | |
470 | |
471 if ((fwSession->fwFindObjects) && | |
472 (fwFindObjects)) { | |
473 return CKR_OPERATION_ACTIVE; | |
474 } | |
475 | |
476 fwSession->fwFindObjects = fwFindObjects; | |
477 | |
478 return CKR_OK; | |
479 } | |
480 | |
481 /* | |
482 * nssCKFWSession_GetFWFindObjects | |
483 * | |
484 */ | |
485 NSS_IMPLEMENT NSSCKFWFindObjects * | |
486 nssCKFWSession_GetFWFindObjects | |
487 ( | |
488 NSSCKFWSession *fwSession, | |
489 CK_RV *pError | |
490 ) | |
491 { | |
492 #ifdef NSSDEBUG | |
493 if (!pError) { | |
494 return (NSSCKFWFindObjects *)NULL; | |
495 } | |
496 | |
497 *pError = nssCKFWSession_verifyPointer(fwSession); | |
498 if( CKR_OK != *pError ) { | |
499 return (NSSCKFWFindObjects *)NULL; | |
500 } | |
501 #endif /* NSSDEBUG */ | |
502 | |
503 if (!fwSession->fwFindObjects) { | |
504 *pError = CKR_OPERATION_NOT_INITIALIZED; | |
505 return (NSSCKFWFindObjects *)NULL; | |
506 } | |
507 | |
508 return fwSession->fwFindObjects; | |
509 } | |
510 | |
511 /* | |
512 * nssCKFWSession_SetMDSession | |
513 * | |
514 */ | |
515 NSS_IMPLEMENT CK_RV | |
516 nssCKFWSession_SetMDSession | |
517 ( | |
518 NSSCKFWSession *fwSession, | |
519 NSSCKMDSession *mdSession | |
520 ) | |
521 { | |
522 #ifdef NSSDEBUG | |
523 CK_RV error = CKR_OK; | |
524 #endif /* NSSDEBUG */ | |
525 | |
526 #ifdef NSSDEBUG | |
527 error = nssCKFWSession_verifyPointer(fwSession); | |
528 if( CKR_OK != error ) { | |
529 return error; | |
530 } | |
531 | |
532 if (!mdSession) { | |
533 return CKR_ARGUMENTS_BAD; | |
534 } | |
535 #endif /* NSSDEBUG */ | |
536 | |
537 if (fwSession->mdSession) { | |
538 return CKR_GENERAL_ERROR; | |
539 } | |
540 | |
541 fwSession->mdSession = mdSession; | |
542 | |
543 return CKR_OK; | |
544 } | |
545 | |
546 /* | |
547 * nssCKFWSession_SetHandle | |
548 * | |
549 */ | |
550 NSS_IMPLEMENT CK_RV | |
551 nssCKFWSession_SetHandle | |
552 ( | |
553 NSSCKFWSession *fwSession, | |
554 CK_SESSION_HANDLE hSession | |
555 ) | |
556 { | |
557 #ifdef NSSDEBUG | |
558 CK_RV error = CKR_OK; | |
559 #endif /* NSSDEBUG */ | |
560 | |
561 #ifdef NSSDEBUG | |
562 error = nssCKFWSession_verifyPointer(fwSession); | |
563 if( CKR_OK != error ) { | |
564 return error; | |
565 } | |
566 #endif /* NSSDEBUG */ | |
567 | |
568 if( (CK_SESSION_HANDLE)0 != fwSession->hSession ) { | |
569 return CKR_GENERAL_ERROR; | |
570 } | |
571 | |
572 fwSession->hSession = hSession; | |
573 | |
574 return CKR_OK; | |
575 } | |
576 | |
577 /* | |
578 * nssCKFWSession_GetHandle | |
579 * | |
580 */ | |
581 NSS_IMPLEMENT CK_SESSION_HANDLE | |
582 nssCKFWSession_GetHandle | |
583 ( | |
584 NSSCKFWSession *fwSession | |
585 ) | |
586 { | |
587 #ifdef NSSDEBUG | |
588 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
589 return NULL; | |
590 } | |
591 #endif /* NSSDEBUG */ | |
592 | |
593 return fwSession->hSession; | |
594 } | |
595 | |
596 /* | |
597 * nssCKFWSession_RegisterSessionObject | |
598 * | |
599 */ | |
600 NSS_IMPLEMENT CK_RV | |
601 nssCKFWSession_RegisterSessionObject | |
602 ( | |
603 NSSCKFWSession *fwSession, | |
604 NSSCKFWObject *fwObject | |
605 ) | |
606 { | |
607 CK_RV rv = CKR_OK; | |
608 | |
609 #ifdef NSSDEBUG | |
610 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
611 return CKR_GENERAL_ERROR; | |
612 } | |
613 #endif /* NSSDEBUG */ | |
614 | |
615 if (fwSession->sessionObjectHash) { | |
616 rv = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject); | |
617 } | |
618 | |
619 return rv; | |
620 } | |
621 | |
622 /* | |
623 * nssCKFWSession_DeregisterSessionObject | |
624 * | |
625 */ | |
626 NSS_IMPLEMENT CK_RV | |
627 nssCKFWSession_DeregisterSessionObject | |
628 ( | |
629 NSSCKFWSession *fwSession, | |
630 NSSCKFWObject *fwObject | |
631 ) | |
632 { | |
633 #ifdef NSSDEBUG | |
634 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
635 return CKR_GENERAL_ERROR; | |
636 } | |
637 #endif /* NSSDEBUG */ | |
638 | |
639 if (fwSession->sessionObjectHash) { | |
640 nssCKFWHash_Remove(fwSession->sessionObjectHash, fwObject); | |
641 } | |
642 | |
643 return CKR_OK; | |
644 } | |
645 | |
646 /* | |
647 * nssCKFWSession_GetDeviceError | |
648 * | |
649 */ | |
650 NSS_IMPLEMENT CK_ULONG | |
651 nssCKFWSession_GetDeviceError | |
652 ( | |
653 NSSCKFWSession *fwSession | |
654 ) | |
655 { | |
656 #ifdef NSSDEBUG | |
657 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
658 return (CK_ULONG)0; | |
659 } | |
660 | |
661 if (!fwSession->mdSession) { | |
662 return (CK_ULONG)0; | |
663 } | |
664 #endif /* NSSDEBUG */ | |
665 | |
666 if (!fwSession->mdSession->GetDeviceError) { | |
667 return (CK_ULONG)0; | |
668 } | |
669 | |
670 return fwSession->mdSession->GetDeviceError(fwSession->mdSession, | |
671 fwSession, fwSession->mdToken, fwSession->fwToken, | |
672 fwSession->mdInstance, fwSession->fwInstance); | |
673 } | |
674 | |
675 /* | |
676 * nssCKFWSession_Login | |
677 * | |
678 */ | |
679 NSS_IMPLEMENT CK_RV | |
680 nssCKFWSession_Login | |
681 ( | |
682 NSSCKFWSession *fwSession, | |
683 CK_USER_TYPE userType, | |
684 NSSItem *pin | |
685 ) | |
686 { | |
687 CK_RV error = CKR_OK; | |
688 CK_STATE oldState; | |
689 CK_STATE newState; | |
690 | |
691 #ifdef NSSDEBUG | |
692 error = nssCKFWSession_verifyPointer(fwSession); | |
693 if( CKR_OK != error ) { | |
694 return error; | |
695 } | |
696 | |
697 switch( userType ) { | |
698 case CKU_SO: | |
699 case CKU_USER: | |
700 break; | |
701 default: | |
702 return CKR_USER_TYPE_INVALID; | |
703 } | |
704 | |
705 if (!pin) { | |
706 if( CK_TRUE != nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwT
oken) ) { | |
707 return CKR_ARGUMENTS_BAD; | |
708 } | |
709 } | |
710 | |
711 if (!fwSession->mdSession) { | |
712 return CKR_GENERAL_ERROR; | |
713 } | |
714 #endif /* NSSDEBUG */ | |
715 | |
716 oldState = nssCKFWToken_GetSessionState(fwSession->fwToken); | |
717 | |
718 /* | |
719 * It's not clear what happens when you're already logged in. | |
720 * I'll just fail; but if we decide to change, the logic is | |
721 * all right here. | |
722 */ | |
723 | |
724 if( CKU_SO == userType ) { | |
725 switch( oldState ) { | |
726 case CKS_RO_PUBLIC_SESSION: | |
727 /* | |
728 * There's no such thing as a read-only security officer | |
729 * session, so fail. The error should be CKR_SESSION_READ_ONLY, | |
730 * except that C_Login isn't defined to return that. So we'll | |
731 * do CKR_SESSION_READ_ONLY_EXISTS, which is what is documented. | |
732 */ | |
733 return CKR_SESSION_READ_ONLY_EXISTS; | |
734 case CKS_RO_USER_FUNCTIONS: | |
735 return CKR_USER_ANOTHER_ALREADY_LOGGED_IN; | |
736 case CKS_RW_PUBLIC_SESSION: | |
737 newState = CKS_RW_SO_FUNCTIONS; | |
738 break; | |
739 case CKS_RW_USER_FUNCTIONS: | |
740 return CKR_USER_ANOTHER_ALREADY_LOGGED_IN; | |
741 case CKS_RW_SO_FUNCTIONS: | |
742 return CKR_USER_ALREADY_LOGGED_IN; | |
743 default: | |
744 return CKR_GENERAL_ERROR; | |
745 } | |
746 } else /* CKU_USER == userType */ { | |
747 switch( oldState ) { | |
748 case CKS_RO_PUBLIC_SESSION: | |
749 newState = CKS_RO_USER_FUNCTIONS; | |
750 break; | |
751 case CKS_RO_USER_FUNCTIONS: | |
752 return CKR_USER_ALREADY_LOGGED_IN; | |
753 case CKS_RW_PUBLIC_SESSION: | |
754 newState = CKS_RW_USER_FUNCTIONS; | |
755 break; | |
756 case CKS_RW_USER_FUNCTIONS: | |
757 return CKR_USER_ALREADY_LOGGED_IN; | |
758 case CKS_RW_SO_FUNCTIONS: | |
759 return CKR_USER_ANOTHER_ALREADY_LOGGED_IN; | |
760 default: | |
761 return CKR_GENERAL_ERROR; | |
762 } | |
763 } | |
764 | |
765 /* | |
766 * So now we're in one of three cases: | |
767 * | |
768 * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_SO_FUNCTIONS; | |
769 * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_USER_FUNCTIONS; | |
770 * Old == CKS_RO_PUBLIC_SESSION, New == CKS_RO_USER_FUNCTIONS; | |
771 */ | |
772 | |
773 if (!fwSession->mdSession->Login) { | |
774 /* | |
775 * The Module doesn't want to be informed (or check the pin) | |
776 * it'll just rely on the Framework as needed. | |
777 */ | |
778 ; | |
779 } else { | |
780 error = fwSession->mdSession->Login(fwSession->mdSession, fwSession, | |
781 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance, | |
782 fwSession->fwInstance, userType, pin, oldState, newState); | |
783 if( CKR_OK != error ) { | |
784 return error; | |
785 } | |
786 } | |
787 | |
788 (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState); | |
789 return CKR_OK; | |
790 } | |
791 | |
792 /* | |
793 * nssCKFWSession_Logout | |
794 * | |
795 */ | |
796 NSS_IMPLEMENT CK_RV | |
797 nssCKFWSession_Logout | |
798 ( | |
799 NSSCKFWSession *fwSession | |
800 ) | |
801 { | |
802 CK_RV error = CKR_OK; | |
803 CK_STATE oldState; | |
804 CK_STATE newState; | |
805 | |
806 #ifdef NSSDEBUG | |
807 error = nssCKFWSession_verifyPointer(fwSession); | |
808 if( CKR_OK != error ) { | |
809 return error; | |
810 } | |
811 | |
812 if (!fwSession->mdSession) { | |
813 return CKR_GENERAL_ERROR; | |
814 } | |
815 #endif /* NSSDEBUG */ | |
816 | |
817 oldState = nssCKFWToken_GetSessionState(fwSession->fwToken); | |
818 | |
819 switch( oldState ) { | |
820 case CKS_RO_PUBLIC_SESSION: | |
821 return CKR_USER_NOT_LOGGED_IN; | |
822 case CKS_RO_USER_FUNCTIONS: | |
823 newState = CKS_RO_PUBLIC_SESSION; | |
824 break; | |
825 case CKS_RW_PUBLIC_SESSION: | |
826 return CKR_USER_NOT_LOGGED_IN; | |
827 case CKS_RW_USER_FUNCTIONS: | |
828 newState = CKS_RW_PUBLIC_SESSION; | |
829 break; | |
830 case CKS_RW_SO_FUNCTIONS: | |
831 newState = CKS_RW_PUBLIC_SESSION; | |
832 break; | |
833 default: | |
834 return CKR_GENERAL_ERROR; | |
835 } | |
836 | |
837 /* | |
838 * So now we're in one of three cases: | |
839 * | |
840 * Old == CKS_RW_SO_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION; | |
841 * Old == CKS_RW_USER_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION; | |
842 * Old == CKS_RO_USER_FUNCTIONS, New == CKS_RO_PUBLIC_SESSION; | |
843 */ | |
844 | |
845 if (!fwSession->mdSession->Logout) { | |
846 /* | |
847 * The Module doesn't want to be informed. Okay. | |
848 */ | |
849 ; | |
850 } else { | |
851 error = fwSession->mdSession->Logout(fwSession->mdSession, fwSession, | |
852 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance, | |
853 fwSession->fwInstance, oldState, newState); | |
854 if( CKR_OK != error ) { | |
855 /* | |
856 * Now what?! A failure really should end up with the Framework | |
857 * considering it logged out, right? | |
858 */ | |
859 ; | |
860 } | |
861 } | |
862 | |
863 (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState); | |
864 return error; | |
865 } | |
866 | |
867 /* | |
868 * nssCKFWSession_InitPIN | |
869 * | |
870 */ | |
871 NSS_IMPLEMENT CK_RV | |
872 nssCKFWSession_InitPIN | |
873 ( | |
874 NSSCKFWSession *fwSession, | |
875 NSSItem *pin | |
876 ) | |
877 { | |
878 CK_RV error = CKR_OK; | |
879 CK_STATE state; | |
880 | |
881 #ifdef NSSDEBUG | |
882 error = nssCKFWSession_verifyPointer(fwSession); | |
883 if( CKR_OK != error ) { | |
884 return error; | |
885 } | |
886 | |
887 if (!fwSession->mdSession) { | |
888 return CKR_GENERAL_ERROR; | |
889 } | |
890 #endif /* NSSDEBUG */ | |
891 | |
892 state = nssCKFWToken_GetSessionState(fwSession->fwToken); | |
893 if( CKS_RW_SO_FUNCTIONS != state ) { | |
894 return CKR_USER_NOT_LOGGED_IN; | |
895 } | |
896 | |
897 if (!pin) { | |
898 CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwT
oken); | |
899 if( CK_TRUE != has ) { | |
900 return CKR_ARGUMENTS_BAD; | |
901 } | |
902 } | |
903 | |
904 if (!fwSession->mdSession->InitPIN) { | |
905 return CKR_TOKEN_WRITE_PROTECTED; | |
906 } | |
907 | |
908 error = fwSession->mdSession->InitPIN(fwSession->mdSession, fwSession, | |
909 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance, | |
910 fwSession->fwInstance, pin); | |
911 | |
912 return error; | |
913 } | |
914 | |
915 /* | |
916 * nssCKFWSession_SetPIN | |
917 * | |
918 */ | |
919 NSS_IMPLEMENT CK_RV | |
920 nssCKFWSession_SetPIN | |
921 ( | |
922 NSSCKFWSession *fwSession, | |
923 NSSItem *newPin, | |
924 NSSItem *oldPin | |
925 ) | |
926 { | |
927 CK_RV error = CKR_OK; | |
928 | |
929 #ifdef NSSDEBUG | |
930 error = nssCKFWSession_verifyPointer(fwSession); | |
931 if( CKR_OK != error ) { | |
932 return error; | |
933 } | |
934 | |
935 if (!fwSession->mdSession) { | |
936 return CKR_GENERAL_ERROR; | |
937 } | |
938 #endif /* NSSDEBUG */ | |
939 | |
940 if (!newPin) { | |
941 CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwT
oken); | |
942 if( CK_TRUE != has ) { | |
943 return CKR_ARGUMENTS_BAD; | |
944 } | |
945 } | |
946 | |
947 if (!oldPin) { | |
948 CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwT
oken); | |
949 if( CK_TRUE != has ) { | |
950 return CKR_ARGUMENTS_BAD; | |
951 } | |
952 } | |
953 | |
954 if (!fwSession->mdSession->SetPIN) { | |
955 return CKR_TOKEN_WRITE_PROTECTED; | |
956 } | |
957 | |
958 error = fwSession->mdSession->SetPIN(fwSession->mdSession, fwSession, | |
959 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance, | |
960 fwSession->fwInstance, newPin, oldPin); | |
961 | |
962 return error; | |
963 } | |
964 | |
965 /* | |
966 * nssCKFWSession_GetOperationStateLen | |
967 * | |
968 */ | |
969 NSS_IMPLEMENT CK_ULONG | |
970 nssCKFWSession_GetOperationStateLen | |
971 ( | |
972 NSSCKFWSession *fwSession, | |
973 CK_RV *pError | |
974 ) | |
975 { | |
976 CK_ULONG mdAmt; | |
977 CK_ULONG fwAmt; | |
978 | |
979 #ifdef NSSDEBUG | |
980 if (!pError) { | |
981 return (CK_ULONG)0; | |
982 } | |
983 | |
984 *pError = nssCKFWSession_verifyPointer(fwSession); | |
985 if( CKR_OK != *pError ) { | |
986 return (CK_ULONG)0; | |
987 } | |
988 | |
989 if (!fwSession->mdSession) { | |
990 *pError = CKR_GENERAL_ERROR; | |
991 return (CK_ULONG)0; | |
992 } | |
993 #endif /* NSSDEBUG */ | |
994 | |
995 if (!fwSession->mdSession->GetOperationStateLen) { | |
996 *pError = CKR_STATE_UNSAVEABLE; | |
997 return (CK_ULONG)0; | |
998 } | |
999 | |
1000 /* | |
1001 * We could check that the session is actually in some state.. | |
1002 */ | |
1003 | |
1004 mdAmt = fwSession->mdSession->GetOperationStateLen(fwSession->mdSession, | |
1005 fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance, | |
1006 fwSession->fwInstance, pError); | |
1007 | |
1008 if( ((CK_ULONG)0 == mdAmt) && (CKR_OK != *pError) ) { | |
1009 return (CK_ULONG)0; | |
1010 } | |
1011 | |
1012 /* | |
1013 * Add a bit of sanity-checking | |
1014 */ | |
1015 fwAmt = mdAmt + 2*sizeof(CK_ULONG); | |
1016 | |
1017 return fwAmt; | |
1018 } | |
1019 | |
1020 /* | |
1021 * nssCKFWSession_GetOperationState | |
1022 * | |
1023 */ | |
1024 NSS_IMPLEMENT CK_RV | |
1025 nssCKFWSession_GetOperationState | |
1026 ( | |
1027 NSSCKFWSession *fwSession, | |
1028 NSSItem *buffer | |
1029 ) | |
1030 { | |
1031 CK_RV error = CKR_OK; | |
1032 CK_ULONG fwAmt; | |
1033 CK_ULONG *ulBuffer; | |
1034 NSSItem i2; | |
1035 CK_ULONG n, i; | |
1036 | |
1037 #ifdef NSSDEBUG | |
1038 error = nssCKFWSession_verifyPointer(fwSession); | |
1039 if( CKR_OK != error ) { | |
1040 return error; | |
1041 } | |
1042 | |
1043 if (!buffer) { | |
1044 return CKR_ARGUMENTS_BAD; | |
1045 } | |
1046 | |
1047 if (!buffer->data) { | |
1048 return CKR_ARGUMENTS_BAD; | |
1049 } | |
1050 | |
1051 if (!fwSession->mdSession) { | |
1052 return CKR_GENERAL_ERROR; | |
1053 } | |
1054 #endif /* NSSDEBUG */ | |
1055 | |
1056 if (!fwSession->mdSession->GetOperationState) { | |
1057 return CKR_STATE_UNSAVEABLE; | |
1058 } | |
1059 | |
1060 /* | |
1061 * Sanity-check the caller's buffer. | |
1062 */ | |
1063 | |
1064 error = CKR_OK; | |
1065 fwAmt = nssCKFWSession_GetOperationStateLen(fwSession, &error); | |
1066 if( ((CK_ULONG)0 == fwAmt) && (CKR_OK != error) ) { | |
1067 return error; | |
1068 } | |
1069 | |
1070 if( buffer->size < fwAmt ) { | |
1071 return CKR_BUFFER_TOO_SMALL; | |
1072 } | |
1073 | |
1074 ulBuffer = (CK_ULONG *)buffer->data; | |
1075 | |
1076 i2.size = buffer->size - 2*sizeof(CK_ULONG); | |
1077 i2.data = (void *)&ulBuffer[2]; | |
1078 | |
1079 error = fwSession->mdSession->GetOperationState(fwSession->mdSession, | |
1080 fwSession, fwSession->mdToken, fwSession->fwToken, | |
1081 fwSession->mdInstance, fwSession->fwInstance, &i2); | |
1082 | |
1083 if( CKR_OK != error ) { | |
1084 return error; | |
1085 } | |
1086 | |
1087 /* | |
1088 * Add a little integrety/identity check. | |
1089 * NOTE: right now, it's pretty stupid. | |
1090 * A CRC or something would be better. | |
1091 */ | |
1092 | |
1093 ulBuffer[0] = 0x434b4657; /* CKFW */ | |
1094 ulBuffer[1] = 0; | |
1095 n = i2.size/sizeof(CK_ULONG); | |
1096 for( i = 0; i < n; i++ ) { | |
1097 ulBuffer[1] ^= ulBuffer[2+i]; | |
1098 } | |
1099 | |
1100 return CKR_OK; | |
1101 } | |
1102 | |
1103 /* | |
1104 * nssCKFWSession_SetOperationState | |
1105 * | |
1106 */ | |
1107 NSS_IMPLEMENT CK_RV | |
1108 nssCKFWSession_SetOperationState | |
1109 ( | |
1110 NSSCKFWSession *fwSession, | |
1111 NSSItem *state, | |
1112 NSSCKFWObject *encryptionKey, | |
1113 NSSCKFWObject *authenticationKey | |
1114 ) | |
1115 { | |
1116 CK_RV error = CKR_OK; | |
1117 CK_ULONG *ulBuffer; | |
1118 CK_ULONG n, i; | |
1119 CK_ULONG x; | |
1120 NSSItem s; | |
1121 NSSCKMDObject *mdek; | |
1122 NSSCKMDObject *mdak; | |
1123 | |
1124 #ifdef NSSDEBUG | |
1125 error = nssCKFWSession_verifyPointer(fwSession); | |
1126 if( CKR_OK != error ) { | |
1127 return error; | |
1128 } | |
1129 | |
1130 if (!state) { | |
1131 return CKR_ARGUMENTS_BAD; | |
1132 } | |
1133 | |
1134 if (!state->data) { | |
1135 return CKR_ARGUMENTS_BAD; | |
1136 } | |
1137 | |
1138 if (encryptionKey) { | |
1139 error = nssCKFWObject_verifyPointer(encryptionKey); | |
1140 if( CKR_OK != error ) { | |
1141 return error; | |
1142 } | |
1143 } | |
1144 | |
1145 if (authenticationKey) { | |
1146 error = nssCKFWObject_verifyPointer(authenticationKey); | |
1147 if( CKR_OK != error ) { | |
1148 return error; | |
1149 } | |
1150 } | |
1151 | |
1152 if (!fwSession->mdSession) { | |
1153 return CKR_GENERAL_ERROR; | |
1154 } | |
1155 #endif /* NSSDEBUG */ | |
1156 | |
1157 ulBuffer = (CK_ULONG *)state->data; | |
1158 if( 0x43b4657 != ulBuffer[0] ) { | |
1159 return CKR_SAVED_STATE_INVALID; | |
1160 } | |
1161 n = (state->size / sizeof(CK_ULONG)) - 2; | |
1162 x = (CK_ULONG)0; | |
1163 for( i = 0; i < n; i++ ) { | |
1164 x ^= ulBuffer[2+i]; | |
1165 } | |
1166 | |
1167 if( x != ulBuffer[1] ) { | |
1168 return CKR_SAVED_STATE_INVALID; | |
1169 } | |
1170 | |
1171 if (!fwSession->mdSession->SetOperationState) { | |
1172 return CKR_GENERAL_ERROR; | |
1173 } | |
1174 | |
1175 s.size = state->size - 2*sizeof(CK_ULONG); | |
1176 s.data = (void *)&ulBuffer[2]; | |
1177 | |
1178 if (encryptionKey) { | |
1179 mdek = nssCKFWObject_GetMDObject(encryptionKey); | |
1180 } else { | |
1181 mdek = (NSSCKMDObject *)NULL; | |
1182 } | |
1183 | |
1184 if (authenticationKey) { | |
1185 mdak = nssCKFWObject_GetMDObject(authenticationKey); | |
1186 } else { | |
1187 mdak = (NSSCKMDObject *)NULL; | |
1188 } | |
1189 | |
1190 error = fwSession->mdSession->SetOperationState(fwSession->mdSession, | |
1191 fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance, | |
1192 fwSession->fwInstance, &s, mdek, encryptionKey, mdak, authenticationKey); | |
1193 | |
1194 if( CKR_OK != error ) { | |
1195 return error; | |
1196 } | |
1197 | |
1198 /* | |
1199 * Here'd we restore any session data | |
1200 */ | |
1201 | |
1202 return CKR_OK; | |
1203 } | |
1204 | |
1205 static CK_BBOOL | |
1206 nss_attributes_form_token_object | |
1207 ( | |
1208 CK_ATTRIBUTE_PTR pTemplate, | |
1209 CK_ULONG ulAttributeCount | |
1210 ) | |
1211 { | |
1212 CK_ULONG i; | |
1213 CK_BBOOL rv; | |
1214 | |
1215 for( i = 0; i < ulAttributeCount; i++ ) { | |
1216 if( CKA_TOKEN == pTemplate[i].type ) { | |
1217 /* If we sanity-check, we can remove this sizeof check */ | |
1218 if( sizeof(CK_BBOOL) == pTemplate[i].ulValueLen ) { | |
1219 (void)nsslibc_memcpy(&rv, pTemplate[i].pValue, sizeof(CK_BBOOL)); | |
1220 return rv; | |
1221 } else { | |
1222 return CK_FALSE; | |
1223 } | |
1224 } | |
1225 } | |
1226 | |
1227 return CK_FALSE; | |
1228 } | |
1229 | |
1230 /* | |
1231 * nssCKFWSession_CreateObject | |
1232 * | |
1233 */ | |
1234 NSS_IMPLEMENT NSSCKFWObject * | |
1235 nssCKFWSession_CreateObject | |
1236 ( | |
1237 NSSCKFWSession *fwSession, | |
1238 CK_ATTRIBUTE_PTR pTemplate, | |
1239 CK_ULONG ulAttributeCount, | |
1240 CK_RV *pError | |
1241 ) | |
1242 { | |
1243 NSSArena *arena; | |
1244 NSSCKMDObject *mdObject; | |
1245 NSSCKFWObject *fwObject; | |
1246 CK_BBOOL isTokenObject; | |
1247 | |
1248 #ifdef NSSDEBUG | |
1249 if (!pError) { | |
1250 return (NSSCKFWObject *)NULL; | |
1251 } | |
1252 | |
1253 *pError = nssCKFWSession_verifyPointer(fwSession); | |
1254 if( CKR_OK != pError ) { | |
1255 return (NSSCKFWObject *)NULL; | |
1256 } | |
1257 | |
1258 if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) { | |
1259 *pError = CKR_ARGUMENTS_BAD; | |
1260 return (NSSCKFWObject *)NULL; | |
1261 } | |
1262 | |
1263 if (!fwSession->mdSession) { | |
1264 *pError = CKR_GENERAL_ERROR; | |
1265 return (NSSCKFWObject *)NULL; | |
1266 } | |
1267 #endif /* NSSDEBUG */ | |
1268 | |
1269 /* | |
1270 * Here would be an excellent place to sanity-check the object. | |
1271 */ | |
1272 | |
1273 isTokenObject = nss_attributes_form_token_object(pTemplate, ulAttributeCount); | |
1274 if( CK_TRUE == isTokenObject ) { | |
1275 /* === TOKEN OBJECT === */ | |
1276 | |
1277 if (!fwSession->mdSession->CreateObject) { | |
1278 *pError = CKR_TOKEN_WRITE_PROTECTED; | |
1279 return (NSSCKFWObject *)NULL; | |
1280 } | |
1281 | |
1282 arena = nssCKFWToken_GetArena(fwSession->fwToken, pError); | |
1283 if (!arena) { | |
1284 if( CKR_OK == *pError ) { | |
1285 *pError = CKR_GENERAL_ERROR; | |
1286 } | |
1287 return (NSSCKFWObject *)NULL; | |
1288 } | |
1289 | |
1290 goto callmdcreateobject; | |
1291 } else { | |
1292 /* === SESSION OBJECT === */ | |
1293 | |
1294 arena = nssCKFWSession_GetArena(fwSession, pError); | |
1295 if (!arena) { | |
1296 if( CKR_OK == *pError ) { | |
1297 *pError = CKR_GENERAL_ERROR; | |
1298 } | |
1299 return (NSSCKFWObject *)NULL; | |
1300 } | |
1301 | |
1302 if( CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects( | |
1303 fwSession->fwInstance) ) { | |
1304 /* --- module handles the session object -- */ | |
1305 | |
1306 if (!fwSession->mdSession->CreateObject) { | |
1307 *pError = CKR_GENERAL_ERROR; | |
1308 return (NSSCKFWObject *)NULL; | |
1309 } | |
1310 | |
1311 goto callmdcreateobject; | |
1312 } else { | |
1313 /* --- framework handles the session object -- */ | |
1314 mdObject = nssCKMDSessionObject_Create(fwSession->fwToken, | |
1315 arena, pTemplate, ulAttributeCount, pError); | |
1316 goto gotmdobject; | |
1317 } | |
1318 } | |
1319 | |
1320 callmdcreateobject: | |
1321 mdObject = fwSession->mdSession->CreateObject(fwSession->mdSession, | |
1322 fwSession, fwSession->mdToken, fwSession->fwToken, | |
1323 fwSession->mdInstance, fwSession->fwInstance, arena, pTemplate, | |
1324 ulAttributeCount, pError); | |
1325 | |
1326 gotmdobject: | |
1327 if (!mdObject) { | |
1328 if( CKR_OK == *pError ) { | |
1329 *pError = CKR_GENERAL_ERROR; | |
1330 } | |
1331 return (NSSCKFWObject *)NULL; | |
1332 } | |
1333 | |
1334 fwObject = nssCKFWObject_Create(arena, mdObject, | |
1335 isTokenObject ? NULL : fwSession, | |
1336 fwSession->fwToken, fwSession->fwInstance, pError); | |
1337 if (!fwObject) { | |
1338 if( CKR_OK == *pError ) { | |
1339 *pError = CKR_GENERAL_ERROR; | |
1340 } | |
1341 | |
1342 if (mdObject->Destroy) { | |
1343 (void)mdObject->Destroy(mdObject, (NSSCKFWObject *)NULL, | |
1344 fwSession->mdSession, fwSession, fwSession->mdToken, | |
1345 fwSession->fwToken, fwSession->mdInstance, fwSession->fwInstance); | |
1346 } | |
1347 | |
1348 return (NSSCKFWObject *)NULL; | |
1349 } | |
1350 | |
1351 if( CK_FALSE == isTokenObject ) { | |
1352 if( CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, fwObject) )
{ | |
1353 *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject
); | |
1354 if( CKR_OK != *pError ) { | |
1355 nssCKFWObject_Finalize(fwObject, PR_TRUE); | |
1356 return (NSSCKFWObject *)NULL; | |
1357 } | |
1358 } | |
1359 } | |
1360 | |
1361 return fwObject; | |
1362 } | |
1363 | |
1364 /* | |
1365 * nssCKFWSession_CopyObject | |
1366 * | |
1367 */ | |
1368 NSS_IMPLEMENT NSSCKFWObject * | |
1369 nssCKFWSession_CopyObject | |
1370 ( | |
1371 NSSCKFWSession *fwSession, | |
1372 NSSCKFWObject *fwObject, | |
1373 CK_ATTRIBUTE_PTR pTemplate, | |
1374 CK_ULONG ulAttributeCount, | |
1375 CK_RV *pError | |
1376 ) | |
1377 { | |
1378 CK_BBOOL oldIsToken; | |
1379 CK_BBOOL newIsToken; | |
1380 CK_ULONG i; | |
1381 NSSCKFWObject *rv; | |
1382 | |
1383 #ifdef NSSDEBUG | |
1384 if (!pError) { | |
1385 return (NSSCKFWObject *)NULL; | |
1386 } | |
1387 | |
1388 *pError = nssCKFWSession_verifyPointer(fwSession); | |
1389 if( CKR_OK != *pError ) { | |
1390 return (NSSCKFWObject *)NULL; | |
1391 } | |
1392 | |
1393 *pError = nssCKFWObject_verifyPointer(fwObject); | |
1394 if( CKR_OK != *pError ) { | |
1395 return (NSSCKFWObject *)NULL; | |
1396 } | |
1397 | |
1398 if (!fwSession->mdSession) { | |
1399 *pError = CKR_GENERAL_ERROR; | |
1400 return (NSSCKFWObject *)NULL; | |
1401 } | |
1402 #endif /* NSSDEBUG */ | |
1403 | |
1404 /* | |
1405 * Sanity-check object | |
1406 */ | |
1407 | |
1408 if (!fwObject) { | |
1409 *pError = CKR_ARGUMENTS_BAD; | |
1410 return (NSSCKFWObject *)NULL; | |
1411 } | |
1412 | |
1413 oldIsToken = nssCKFWObject_IsTokenObject(fwObject); | |
1414 | |
1415 newIsToken = oldIsToken; | |
1416 for( i = 0; i < ulAttributeCount; i++ ) { | |
1417 if( CKA_TOKEN == pTemplate[i].type ) { | |
1418 /* Since we sanity-checked the object, we know this is the right size. */ | |
1419 (void)nsslibc_memcpy(&newIsToken, pTemplate[i].pValue, sizeof(CK_BBOOL)); | |
1420 break; | |
1421 } | |
1422 } | |
1423 | |
1424 /* | |
1425 * If the Module handles its session objects, or if both the new | |
1426 * and old object are token objects, use CopyObject if it exists. | |
1427 */ | |
1428 | |
1429 if ((fwSession->mdSession->CopyObject) && | |
1430 (((CK_TRUE == oldIsToken) && (CK_TRUE == newIsToken)) || | |
1431 (CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects( | |
1432 fwSession->fwInstance))) ) { | |
1433 /* use copy object */ | |
1434 NSSArena *arena; | |
1435 NSSCKMDObject *mdOldObject; | |
1436 NSSCKMDObject *mdObject; | |
1437 | |
1438 mdOldObject = nssCKFWObject_GetMDObject(fwObject); | |
1439 | |
1440 if( CK_TRUE == newIsToken ) { | |
1441 arena = nssCKFWToken_GetArena(fwSession->fwToken, pError); | |
1442 } else { | |
1443 arena = nssCKFWSession_GetArena(fwSession, pError); | |
1444 } | |
1445 if (!arena) { | |
1446 if( CKR_OK == *pError ) { | |
1447 *pError = CKR_GENERAL_ERROR; | |
1448 } | |
1449 return (NSSCKFWObject *)NULL; | |
1450 } | |
1451 | |
1452 mdObject = fwSession->mdSession->CopyObject(fwSession->mdSession, | |
1453 fwSession, fwSession->mdToken, fwSession->fwToken, | |
1454 fwSession->mdInstance, fwSession->fwInstance, mdOldObject, | |
1455 fwObject, arena, pTemplate, ulAttributeCount, pError); | |
1456 if (!mdObject) { | |
1457 if( CKR_OK == *pError ) { | |
1458 *pError = CKR_GENERAL_ERROR; | |
1459 } | |
1460 return (NSSCKFWObject *)NULL; | |
1461 } | |
1462 | |
1463 rv = nssCKFWObject_Create(arena, mdObject, | |
1464 newIsToken ? NULL : fwSession, | |
1465 fwSession->fwToken, fwSession->fwInstance, pError); | |
1466 | |
1467 if( CK_FALSE == newIsToken ) { | |
1468 if( CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, rv) ) { | |
1469 *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, rv, rv); | |
1470 if( CKR_OK != *pError ) { | |
1471 nssCKFWObject_Finalize(rv, PR_TRUE); | |
1472 return (NSSCKFWObject *)NULL; | |
1473 } | |
1474 } | |
1475 } | |
1476 | |
1477 return rv; | |
1478 } else { | |
1479 /* use create object */ | |
1480 NSSArena *tmpArena; | |
1481 CK_ATTRIBUTE_PTR newTemplate; | |
1482 CK_ULONG i, j, n, newLength, k; | |
1483 CK_ATTRIBUTE_TYPE_PTR oldTypes; | |
1484 NSSCKFWObject *rv; | |
1485 | |
1486 n = nssCKFWObject_GetAttributeCount(fwObject, pError); | |
1487 if( (0 == n) && (CKR_OK != *pError) ) { | |
1488 return (NSSCKFWObject *)NULL; | |
1489 } | |
1490 | |
1491 tmpArena = NSSArena_Create(); | |
1492 if (!tmpArena) { | |
1493 *pError = CKR_HOST_MEMORY; | |
1494 return (NSSCKFWObject *)NULL; | |
1495 } | |
1496 | |
1497 oldTypes = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE_TYPE, n); | |
1498 if( (CK_ATTRIBUTE_TYPE_PTR)NULL == oldTypes ) { | |
1499 NSSArena_Destroy(tmpArena); | |
1500 *pError = CKR_HOST_MEMORY; | |
1501 return (NSSCKFWObject *)NULL; | |
1502 } | |
1503 | |
1504 *pError = nssCKFWObject_GetAttributeTypes(fwObject, oldTypes, n); | |
1505 if( CKR_OK != *pError ) { | |
1506 NSSArena_Destroy(tmpArena); | |
1507 return (NSSCKFWObject *)NULL; | |
1508 } | |
1509 | |
1510 newLength = n; | |
1511 for( i = 0; i < ulAttributeCount; i++ ) { | |
1512 for( j = 0; j < n; j++ ) { | |
1513 if( oldTypes[j] == pTemplate[i].type ) { | |
1514 if( (CK_VOID_PTR)NULL == pTemplate[i].pValue ) { | |
1515 /* Removing the attribute */ | |
1516 newLength--; | |
1517 } | |
1518 break; | |
1519 } | |
1520 } | |
1521 if( j == n ) { | |
1522 /* Not found */ | |
1523 newLength++; | |
1524 } | |
1525 } | |
1526 | |
1527 newTemplate = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE, newLength); | |
1528 if( (CK_ATTRIBUTE_PTR)NULL == newTemplate ) { | |
1529 NSSArena_Destroy(tmpArena); | |
1530 *pError = CKR_HOST_MEMORY; | |
1531 return (NSSCKFWObject *)NULL; | |
1532 } | |
1533 | |
1534 k = 0; | |
1535 for( j = 0; j < n; j++ ) { | |
1536 for( i = 0; i < ulAttributeCount; i++ ) { | |
1537 if( oldTypes[j] == pTemplate[i].type ) { | |
1538 if( (CK_VOID_PTR)NULL == pTemplate[i].pValue ) { | |
1539 /* This attribute is being deleted */ | |
1540 ; | |
1541 } else { | |
1542 /* This attribute is being replaced */ | |
1543 newTemplate[k].type = pTemplate[i].type; | |
1544 newTemplate[k].pValue = pTemplate[i].pValue; | |
1545 newTemplate[k].ulValueLen = pTemplate[i].ulValueLen; | |
1546 k++; | |
1547 } | |
1548 break; | |
1549 } | |
1550 } | |
1551 if( i == ulAttributeCount ) { | |
1552 /* This attribute is being copied over from the old object */ | |
1553 NSSItem item, *it; | |
1554 item.size = 0; | |
1555 item.data = (void *)NULL; | |
1556 it = nssCKFWObject_GetAttribute(fwObject, oldTypes[j], | |
1557 &item, tmpArena, pError); | |
1558 if (!it) { | |
1559 if( CKR_OK == *pError ) { | |
1560 *pError = CKR_GENERAL_ERROR; | |
1561 } | |
1562 NSSArena_Destroy(tmpArena); | |
1563 return (NSSCKFWObject *)NULL; | |
1564 } | |
1565 newTemplate[k].type = oldTypes[j]; | |
1566 newTemplate[k].pValue = it->data; | |
1567 newTemplate[k].ulValueLen = it->size; | |
1568 k++; | |
1569 } | |
1570 } | |
1571 /* assert that k == newLength */ | |
1572 | |
1573 rv = nssCKFWSession_CreateObject(fwSession, newTemplate, newLength, pError); | |
1574 if (!rv) { | |
1575 if( CKR_OK == *pError ) { | |
1576 *pError = CKR_GENERAL_ERROR; | |
1577 } | |
1578 NSSArena_Destroy(tmpArena); | |
1579 return (NSSCKFWObject *)NULL; | |
1580 } | |
1581 | |
1582 NSSArena_Destroy(tmpArena); | |
1583 return rv; | |
1584 } | |
1585 } | |
1586 | |
1587 /* | |
1588 * nssCKFWSession_FindObjectsInit | |
1589 * | |
1590 */ | |
1591 NSS_IMPLEMENT NSSCKFWFindObjects * | |
1592 nssCKFWSession_FindObjectsInit | |
1593 ( | |
1594 NSSCKFWSession *fwSession, | |
1595 CK_ATTRIBUTE_PTR pTemplate, | |
1596 CK_ULONG ulAttributeCount, | |
1597 CK_RV *pError | |
1598 ) | |
1599 { | |
1600 NSSCKMDFindObjects *mdfo1 = (NSSCKMDFindObjects *)NULL; | |
1601 NSSCKMDFindObjects *mdfo2 = (NSSCKMDFindObjects *)NULL; | |
1602 | |
1603 #ifdef NSSDEBUG | |
1604 if (!pError) { | |
1605 return (NSSCKFWFindObjects *)NULL; | |
1606 } | |
1607 | |
1608 *pError = nssCKFWSession_verifyPointer(fwSession); | |
1609 if( CKR_OK != *pError ) { | |
1610 return (NSSCKFWFindObjects *)NULL; | |
1611 } | |
1612 | |
1613 if( ((CK_ATTRIBUTE_PTR)NULL == pTemplate) && (ulAttributeCount != 0) ) { | |
1614 *pError = CKR_ARGUMENTS_BAD; | |
1615 return (NSSCKFWFindObjects *)NULL; | |
1616 } | |
1617 | |
1618 if (!fwSession->mdSession) { | |
1619 *pError = CKR_GENERAL_ERROR; | |
1620 return (NSSCKFWFindObjects *)NULL; | |
1621 } | |
1622 #endif /* NSSDEBUG */ | |
1623 | |
1624 if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects( | |
1625 fwSession->fwInstance) ) { | |
1626 CK_ULONG i; | |
1627 | |
1628 /* | |
1629 * Does the search criteria restrict us to token or session | |
1630 * objects? | |
1631 */ | |
1632 | |
1633 for( i = 0; i < ulAttributeCount; i++ ) { | |
1634 if( CKA_TOKEN == pTemplate[i].type ) { | |
1635 /* Yes, it does. */ | |
1636 CK_BBOOL isToken; | |
1637 if( sizeof(CK_BBOOL) != pTemplate[i].ulValueLen ) { | |
1638 *pError = CKR_ATTRIBUTE_VALUE_INVALID; | |
1639 return (NSSCKFWFindObjects *)NULL; | |
1640 } | |
1641 (void)nsslibc_memcpy(&isToken, pTemplate[i].pValue, sizeof(CK_BBOOL)); | |
1642 | |
1643 if( CK_TRUE == isToken ) { | |
1644 /* Pass it on to the module's search routine */ | |
1645 if (!fwSession->mdSession->FindObjectsInit) { | |
1646 goto wrap; | |
1647 } | |
1648 | |
1649 mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession, | |
1650 fwSession, fwSession->mdToken, fwSession->fwToken, | |
1651 fwSession->mdInstance, fwSession->fwInstance, | |
1652 pTemplate, ulAttributeCount, pError); | |
1653 } else { | |
1654 /* Do the search ourselves */ | |
1655 mdfo1 = nssCKMDFindSessionObjects_Create(fwSession->fwToken, | |
1656 pTemplate, ulAttributeCount, pError); | |
1657 } | |
1658 | |
1659 if (!mdfo1) { | |
1660 if( CKR_OK == *pError ) { | |
1661 *pError = CKR_GENERAL_ERROR; | |
1662 } | |
1663 return (NSSCKFWFindObjects *)NULL; | |
1664 } | |
1665 | |
1666 goto wrap; | |
1667 } | |
1668 } | |
1669 | |
1670 if( i == ulAttributeCount ) { | |
1671 /* No, it doesn't. Do a hybrid search. */ | |
1672 mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession, | |
1673 fwSession, fwSession->mdToken, fwSession->fwToken, | |
1674 fwSession->mdInstance, fwSession->fwInstance, | |
1675 pTemplate, ulAttributeCount, pError); | |
1676 | |
1677 if (!mdfo1) { | |
1678 if( CKR_OK == *pError ) { | |
1679 *pError = CKR_GENERAL_ERROR; | |
1680 } | |
1681 return (NSSCKFWFindObjects *)NULL; | |
1682 } | |
1683 | |
1684 mdfo2 = nssCKMDFindSessionObjects_Create(fwSession->fwToken, | |
1685 pTemplate, ulAttributeCount, pError); | |
1686 if (!mdfo2) { | |
1687 if( CKR_OK == *pError ) { | |
1688 *pError = CKR_GENERAL_ERROR; | |
1689 } | |
1690 if (mdfo1->Final) { | |
1691 mdfo1->Final(mdfo1, (NSSCKFWFindObjects *)NULL, fwSession->mdSession, | |
1692 fwSession, fwSession->mdToken, fwSession->fwToken, | |
1693 fwSession->mdInstance, fwSession->fwInstance); | |
1694 } | |
1695 return (NSSCKFWFindObjects *)NULL; | |
1696 } | |
1697 | |
1698 goto wrap; | |
1699 } | |
1700 /*NOTREACHED*/ | |
1701 } else { | |
1702 /* Module handles all its own objects. Pass on to module's search */ | |
1703 mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession, | |
1704 fwSession, fwSession->mdToken, fwSession->fwToken, | |
1705 fwSession->mdInstance, fwSession->fwInstance, | |
1706 pTemplate, ulAttributeCount, pError); | |
1707 | |
1708 if (!mdfo1) { | |
1709 if( CKR_OK == *pError ) { | |
1710 *pError = CKR_GENERAL_ERROR; | |
1711 } | |
1712 return (NSSCKFWFindObjects *)NULL; | |
1713 } | |
1714 | |
1715 goto wrap; | |
1716 } | |
1717 | |
1718 wrap: | |
1719 return nssCKFWFindObjects_Create(fwSession, fwSession->fwToken, | |
1720 fwSession->fwInstance, mdfo1, mdfo2, pError); | |
1721 } | |
1722 | |
1723 /* | |
1724 * nssCKFWSession_SeedRandom | |
1725 * | |
1726 */ | |
1727 NSS_IMPLEMENT CK_RV | |
1728 nssCKFWSession_SeedRandom | |
1729 ( | |
1730 NSSCKFWSession *fwSession, | |
1731 NSSItem *seed | |
1732 ) | |
1733 { | |
1734 CK_RV error = CKR_OK; | |
1735 | |
1736 #ifdef NSSDEBUG | |
1737 error = nssCKFWSession_verifyPointer(fwSession); | |
1738 if( CKR_OK != error ) { | |
1739 return error; | |
1740 } | |
1741 | |
1742 if (!seed) { | |
1743 return CKR_ARGUMENTS_BAD; | |
1744 } | |
1745 | |
1746 if (!seed->data) { | |
1747 return CKR_ARGUMENTS_BAD; | |
1748 } | |
1749 | |
1750 if( 0 == seed->size ) { | |
1751 return CKR_ARGUMENTS_BAD; | |
1752 } | |
1753 | |
1754 if (!fwSession->mdSession) { | |
1755 return CKR_GENERAL_ERROR; | |
1756 } | |
1757 #endif /* NSSDEBUG */ | |
1758 | |
1759 if (!fwSession->mdSession->SeedRandom) { | |
1760 return CKR_RANDOM_SEED_NOT_SUPPORTED; | |
1761 } | |
1762 | |
1763 error = fwSession->mdSession->SeedRandom(fwSession->mdSession, fwSession, | |
1764 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance, | |
1765 fwSession->fwInstance, seed); | |
1766 | |
1767 return error; | |
1768 } | |
1769 | |
1770 /* | |
1771 * nssCKFWSession_GetRandom | |
1772 * | |
1773 */ | |
1774 NSS_IMPLEMENT CK_RV | |
1775 nssCKFWSession_GetRandom | |
1776 ( | |
1777 NSSCKFWSession *fwSession, | |
1778 NSSItem *buffer | |
1779 ) | |
1780 { | |
1781 CK_RV error = CKR_OK; | |
1782 | |
1783 #ifdef NSSDEBUG | |
1784 error = nssCKFWSession_verifyPointer(fwSession); | |
1785 if( CKR_OK != error ) { | |
1786 return error; | |
1787 } | |
1788 | |
1789 if (!buffer) { | |
1790 return CKR_ARGUMENTS_BAD; | |
1791 } | |
1792 | |
1793 if (!buffer->data) { | |
1794 return CKR_ARGUMENTS_BAD; | |
1795 } | |
1796 | |
1797 if (!fwSession->mdSession) { | |
1798 return CKR_GENERAL_ERROR; | |
1799 } | |
1800 #endif /* NSSDEBUG */ | |
1801 | |
1802 if (!fwSession->mdSession->GetRandom) { | |
1803 if( CK_TRUE == nssCKFWToken_GetHasRNG(fwSession->fwToken) ) { | |
1804 return CKR_GENERAL_ERROR; | |
1805 } else { | |
1806 return CKR_RANDOM_NO_RNG; | |
1807 } | |
1808 } | |
1809 | |
1810 if( 0 == buffer->size ) { | |
1811 return CKR_OK; | |
1812 } | |
1813 | |
1814 error = fwSession->mdSession->GetRandom(fwSession->mdSession, fwSession, | |
1815 fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance, | |
1816 fwSession->fwInstance, buffer); | |
1817 | |
1818 return error; | |
1819 } | |
1820 | |
1821 | |
1822 /* | |
1823 * nssCKFWSession_SetCurrentCryptoOperation | |
1824 */ | |
1825 NSS_IMPLEMENT void | |
1826 nssCKFWSession_SetCurrentCryptoOperation | |
1827 ( | |
1828 NSSCKFWSession *fwSession, | |
1829 NSSCKFWCryptoOperation * fwOperation, | |
1830 NSSCKFWCryptoOperationState state | |
1831 ) | |
1832 { | |
1833 #ifdef NSSDEBUG | |
1834 CK_RV error = CKR_OK; | |
1835 error = nssCKFWSession_verifyPointer(fwSession); | |
1836 if( CKR_OK != error ) { | |
1837 return; | |
1838 } | |
1839 | |
1840 if ( state >= NSSCKFWCryptoOperationState_Max) { | |
1841 return; | |
1842 } | |
1843 | |
1844 if (!fwSession->mdSession) { | |
1845 return; | |
1846 } | |
1847 #endif /* NSSDEBUG */ | |
1848 fwSession->fwOperationArray[state] = fwOperation; | |
1849 return; | |
1850 } | |
1851 | |
1852 /* | |
1853 * nssCKFWSession_GetCurrentCryptoOperation | |
1854 */ | |
1855 NSS_IMPLEMENT NSSCKFWCryptoOperation * | |
1856 nssCKFWSession_GetCurrentCryptoOperation | |
1857 ( | |
1858 NSSCKFWSession *fwSession, | |
1859 NSSCKFWCryptoOperationState state | |
1860 ) | |
1861 { | |
1862 #ifdef NSSDEBUG | |
1863 CK_RV error = CKR_OK; | |
1864 error = nssCKFWSession_verifyPointer(fwSession); | |
1865 if( CKR_OK != error ) { | |
1866 return (NSSCKFWCryptoOperation *)NULL; | |
1867 } | |
1868 | |
1869 if ( state >= NSSCKFWCryptoOperationState_Max) { | |
1870 return (NSSCKFWCryptoOperation *)NULL; | |
1871 } | |
1872 | |
1873 if (!fwSession->mdSession) { | |
1874 return (NSSCKFWCryptoOperation *)NULL; | |
1875 } | |
1876 #endif /* NSSDEBUG */ | |
1877 return fwSession->fwOperationArray[state]; | |
1878 } | |
1879 | |
1880 /* | |
1881 * nssCKFWSession_Final | |
1882 */ | |
1883 NSS_IMPLEMENT CK_RV | |
1884 nssCKFWSession_Final | |
1885 ( | |
1886 NSSCKFWSession *fwSession, | |
1887 NSSCKFWCryptoOperationType type, | |
1888 NSSCKFWCryptoOperationState state, | |
1889 CK_BYTE_PTR outBuf, | |
1890 CK_ULONG_PTR outBufLen | |
1891 ) | |
1892 { | |
1893 NSSCKFWCryptoOperation *fwOperation; | |
1894 NSSItem outputBuffer; | |
1895 CK_RV error = CKR_OK; | |
1896 | |
1897 #ifdef NSSDEBUG | |
1898 error = nssCKFWSession_verifyPointer(fwSession); | |
1899 if( CKR_OK != error ) { | |
1900 return error; | |
1901 } | |
1902 | |
1903 if (!fwSession->mdSession) { | |
1904 return CKR_GENERAL_ERROR; | |
1905 } | |
1906 #endif /* NSSDEBUG */ | |
1907 | |
1908 /* make sure we have a valid operation initialized */ | |
1909 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state); | |
1910 if (!fwOperation) { | |
1911 return CKR_OPERATION_NOT_INITIALIZED; | |
1912 } | |
1913 | |
1914 /* make sure it's the correct type */ | |
1915 if (type != nssCKFWCryptoOperation_GetType(fwOperation)) { | |
1916 return CKR_OPERATION_NOT_INITIALIZED; | |
1917 } | |
1918 | |
1919 /* handle buffer issues, note for Verify, the type is an input buffer. */ | |
1920 if (NSSCKFWCryptoOperationType_Verify == type) { | |
1921 if ((CK_BYTE_PTR)NULL == outBuf) { | |
1922 error = CKR_ARGUMENTS_BAD; | |
1923 goto done; | |
1924 } | |
1925 } else { | |
1926 CK_ULONG len = nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error); | |
1927 CK_ULONG maxBufLen = *outBufLen; | |
1928 | |
1929 if (CKR_OK != error) { | |
1930 goto done; | |
1931 } | |
1932 *outBufLen = len; | |
1933 if ((CK_BYTE_PTR)NULL == outBuf) { | |
1934 return CKR_OK; | |
1935 } | |
1936 | |
1937 if (len > maxBufLen) { | |
1938 return CKR_BUFFER_TOO_SMALL; | |
1939 } | |
1940 } | |
1941 outputBuffer.data = outBuf; | |
1942 outputBuffer.size = *outBufLen; | |
1943 | |
1944 error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer); | |
1945 done: | |
1946 if (CKR_BUFFER_TOO_SMALL == error) { | |
1947 return error; | |
1948 } | |
1949 /* clean up our state */ | |
1950 nssCKFWCryptoOperation_Destroy(fwOperation); | |
1951 nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state); | |
1952 return error; | |
1953 } | |
1954 | |
1955 /* | |
1956 * nssCKFWSession_Update | |
1957 */ | |
1958 NSS_IMPLEMENT CK_RV | |
1959 nssCKFWSession_Update | |
1960 ( | |
1961 NSSCKFWSession *fwSession, | |
1962 NSSCKFWCryptoOperationType type, | |
1963 NSSCKFWCryptoOperationState state, | |
1964 CK_BYTE_PTR inBuf, | |
1965 CK_ULONG inBufLen, | |
1966 CK_BYTE_PTR outBuf, | |
1967 CK_ULONG_PTR outBufLen | |
1968 ) | |
1969 { | |
1970 NSSCKFWCryptoOperation *fwOperation; | |
1971 NSSItem inputBuffer; | |
1972 NSSItem outputBuffer; | |
1973 CK_ULONG len; | |
1974 CK_ULONG maxBufLen; | |
1975 CK_RV error = CKR_OK; | |
1976 | |
1977 #ifdef NSSDEBUG | |
1978 error = nssCKFWSession_verifyPointer(fwSession); | |
1979 if( CKR_OK != error ) { | |
1980 return error; | |
1981 } | |
1982 | |
1983 if (!fwSession->mdSession) { | |
1984 return CKR_GENERAL_ERROR; | |
1985 } | |
1986 #endif /* NSSDEBUG */ | |
1987 | |
1988 /* make sure we have a valid operation initialized */ | |
1989 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state); | |
1990 if (!fwOperation) { | |
1991 return CKR_OPERATION_NOT_INITIALIZED; | |
1992 } | |
1993 | |
1994 /* make sure it's the correct type */ | |
1995 if (type != nssCKFWCryptoOperation_GetType(fwOperation)) { | |
1996 return CKR_OPERATION_NOT_INITIALIZED; | |
1997 } | |
1998 | |
1999 inputBuffer.data = inBuf; | |
2000 inputBuffer.size = inBufLen; | |
2001 | |
2002 /* handle buffer issues, note for Verify, the type is an input buffer. */ | |
2003 len = nssCKFWCryptoOperation_GetOperationLength(fwOperation, &inputBuffer, | |
2004 &error); | |
2005 if (CKR_OK != error) { | |
2006 return error; | |
2007 } | |
2008 maxBufLen = *outBufLen; | |
2009 | |
2010 *outBufLen = len; | |
2011 if ((CK_BYTE_PTR)NULL == outBuf) { | |
2012 return CKR_OK; | |
2013 } | |
2014 | |
2015 if (len > maxBufLen) { | |
2016 return CKR_BUFFER_TOO_SMALL; | |
2017 } | |
2018 outputBuffer.data = outBuf; | |
2019 outputBuffer.size = *outBufLen; | |
2020 | |
2021 return nssCKFWCryptoOperation_Update(fwOperation, | |
2022 &inputBuffer, &outputBuffer); | |
2023 } | |
2024 | |
2025 /* | |
2026 * nssCKFWSession_DigestUpdate | |
2027 */ | |
2028 NSS_IMPLEMENT CK_RV | |
2029 nssCKFWSession_DigestUpdate | |
2030 ( | |
2031 NSSCKFWSession *fwSession, | |
2032 NSSCKFWCryptoOperationType type, | |
2033 NSSCKFWCryptoOperationState state, | |
2034 CK_BYTE_PTR inBuf, | |
2035 CK_ULONG inBufLen | |
2036 ) | |
2037 { | |
2038 NSSCKFWCryptoOperation *fwOperation; | |
2039 NSSItem inputBuffer; | |
2040 CK_RV error = CKR_OK; | |
2041 | |
2042 #ifdef NSSDEBUG | |
2043 error = nssCKFWSession_verifyPointer(fwSession); | |
2044 if( CKR_OK != error ) { | |
2045 return error; | |
2046 } | |
2047 | |
2048 if (!fwSession->mdSession) { | |
2049 return CKR_GENERAL_ERROR; | |
2050 } | |
2051 #endif /* NSSDEBUG */ | |
2052 | |
2053 /* make sure we have a valid operation initialized */ | |
2054 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state); | |
2055 if (!fwOperation) { | |
2056 return CKR_OPERATION_NOT_INITIALIZED; | |
2057 } | |
2058 | |
2059 /* make sure it's the correct type */ | |
2060 if (type != nssCKFWCryptoOperation_GetType(fwOperation)) { | |
2061 return CKR_OPERATION_NOT_INITIALIZED; | |
2062 } | |
2063 | |
2064 inputBuffer.data = inBuf; | |
2065 inputBuffer.size = inBufLen; | |
2066 | |
2067 | |
2068 error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer); | |
2069 return error; | |
2070 } | |
2071 | |
2072 /* | |
2073 * nssCKFWSession_DigestUpdate | |
2074 */ | |
2075 NSS_IMPLEMENT CK_RV | |
2076 nssCKFWSession_DigestKey | |
2077 ( | |
2078 NSSCKFWSession *fwSession, | |
2079 NSSCKFWObject *fwKey | |
2080 ) | |
2081 { | |
2082 NSSCKFWCryptoOperation *fwOperation; | |
2083 NSSItem *inputBuffer; | |
2084 CK_RV error = CKR_OK; | |
2085 | |
2086 #ifdef NSSDEBUG | |
2087 error = nssCKFWSession_verifyPointer(fwSession); | |
2088 if( CKR_OK != error ) { | |
2089 return error; | |
2090 } | |
2091 | |
2092 if (!fwSession->mdSession) { | |
2093 return CKR_GENERAL_ERROR; | |
2094 } | |
2095 #endif /* NSSDEBUG */ | |
2096 | |
2097 /* make sure we have a valid operation initialized */ | |
2098 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, | |
2099 NSSCKFWCryptoOperationState_Digest); | |
2100 if (!fwOperation) { | |
2101 return CKR_OPERATION_NOT_INITIALIZED; | |
2102 } | |
2103 | |
2104 /* make sure it's the correct type */ | |
2105 if (NSSCKFWCryptoOperationType_Digest != | |
2106 nssCKFWCryptoOperation_GetType(fwOperation)) { | |
2107 return CKR_OPERATION_NOT_INITIALIZED; | |
2108 } | |
2109 | |
2110 error = nssCKFWCryptoOperation_DigestKey(fwOperation, fwKey); | |
2111 if (CKR_FUNCTION_FAILED != error) { | |
2112 return error; | |
2113 } | |
2114 | |
2115 /* no machine depended way for this to happen, do it by hand */ | |
2116 inputBuffer=nssCKFWObject_GetAttribute(fwKey, CKA_VALUE, NULL, NULL, &error); | |
2117 if (!inputBuffer) { | |
2118 /* couldn't get the value, just fail then */ | |
2119 return error; | |
2120 } | |
2121 error = nssCKFWCryptoOperation_DigestUpdate(fwOperation, inputBuffer); | |
2122 nssItem_Destroy(inputBuffer); | |
2123 return error; | |
2124 } | |
2125 | |
2126 /* | |
2127 * nssCKFWSession_UpdateFinal | |
2128 */ | |
2129 NSS_IMPLEMENT CK_RV | |
2130 nssCKFWSession_UpdateFinal | |
2131 ( | |
2132 NSSCKFWSession *fwSession, | |
2133 NSSCKFWCryptoOperationType type, | |
2134 NSSCKFWCryptoOperationState state, | |
2135 CK_BYTE_PTR inBuf, | |
2136 CK_ULONG inBufLen, | |
2137 CK_BYTE_PTR outBuf, | |
2138 CK_ULONG_PTR outBufLen | |
2139 ) | |
2140 { | |
2141 NSSCKFWCryptoOperation *fwOperation; | |
2142 NSSItem inputBuffer; | |
2143 NSSItem outputBuffer; | |
2144 PRBool isEncryptDecrypt; | |
2145 CK_RV error = CKR_OK; | |
2146 | |
2147 #ifdef NSSDEBUG | |
2148 error = nssCKFWSession_verifyPointer(fwSession); | |
2149 if( CKR_OK != error ) { | |
2150 return error; | |
2151 } | |
2152 | |
2153 if (!fwSession->mdSession) { | |
2154 return CKR_GENERAL_ERROR; | |
2155 } | |
2156 #endif /* NSSDEBUG */ | |
2157 | |
2158 /* make sure we have a valid operation initialized */ | |
2159 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, state); | |
2160 if (!fwOperation) { | |
2161 return CKR_OPERATION_NOT_INITIALIZED; | |
2162 } | |
2163 | |
2164 /* make sure it's the correct type */ | |
2165 if (type != nssCKFWCryptoOperation_GetType(fwOperation)) { | |
2166 return CKR_OPERATION_NOT_INITIALIZED; | |
2167 } | |
2168 | |
2169 inputBuffer.data = inBuf; | |
2170 inputBuffer.size = inBufLen; | |
2171 isEncryptDecrypt = (PRBool) ((NSSCKFWCryptoOperationType_Encrypt == type) || | |
2172 (NSSCKFWCryptoOperationType_Decrypt == type)) ; | |
2173 | |
2174 /* handle buffer issues, note for Verify, the type is an input buffer. */ | |
2175 if (NSSCKFWCryptoOperationType_Verify == type) { | |
2176 if ((CK_BYTE_PTR)NULL == outBuf) { | |
2177 error = CKR_ARGUMENTS_BAD; | |
2178 goto done; | |
2179 } | |
2180 } else { | |
2181 CK_ULONG maxBufLen = *outBufLen; | |
2182 CK_ULONG len; | |
2183 | |
2184 len = (isEncryptDecrypt) ? | |
2185 nssCKFWCryptoOperation_GetOperationLength(fwOperation, | |
2186 &inputBuffer, &error) : | |
2187 nssCKFWCryptoOperation_GetFinalLength(fwOperation, &error); | |
2188 | |
2189 if (CKR_OK != error) { | |
2190 goto done; | |
2191 } | |
2192 | |
2193 *outBufLen = len; | |
2194 if ((CK_BYTE_PTR)NULL == outBuf) { | |
2195 return CKR_OK; | |
2196 } | |
2197 | |
2198 if (len > maxBufLen) { | |
2199 return CKR_BUFFER_TOO_SMALL; | |
2200 } | |
2201 } | |
2202 outputBuffer.data = outBuf; | |
2203 outputBuffer.size = *outBufLen; | |
2204 | |
2205 error = nssCKFWCryptoOperation_UpdateFinal(fwOperation, | |
2206 &inputBuffer, &outputBuffer); | |
2207 | |
2208 /* UpdateFinal isn't support, manually use Update and Final */ | |
2209 if (CKR_FUNCTION_FAILED == error) { | |
2210 error = isEncryptDecrypt ? | |
2211 nssCKFWCryptoOperation_Update(fwOperation, &inputBuffer, &outputBuffer) : | |
2212 nssCKFWCryptoOperation_DigestUpdate(fwOperation, &inputBuffer); | |
2213 | |
2214 if (CKR_OK == error) { | |
2215 error = nssCKFWCryptoOperation_Final(fwOperation, &outputBuffer); | |
2216 } | |
2217 } | |
2218 | |
2219 | |
2220 done: | |
2221 if (CKR_BUFFER_TOO_SMALL == error) { | |
2222 /* if we return CKR_BUFFER_TOO_SMALL, we the caller is not expecting. | |
2223 * the crypto state to be freed */ | |
2224 return error; | |
2225 } | |
2226 | |
2227 /* clean up our state */ | |
2228 nssCKFWCryptoOperation_Destroy(fwOperation); | |
2229 nssCKFWSession_SetCurrentCryptoOperation(fwSession, NULL, state); | |
2230 return error; | |
2231 } | |
2232 | |
2233 NSS_IMPLEMENT CK_RV | |
2234 nssCKFWSession_UpdateCombo | |
2235 ( | |
2236 NSSCKFWSession *fwSession, | |
2237 NSSCKFWCryptoOperationType encryptType, | |
2238 NSSCKFWCryptoOperationType digestType, | |
2239 NSSCKFWCryptoOperationState digestState, | |
2240 CK_BYTE_PTR inBuf, | |
2241 CK_ULONG inBufLen, | |
2242 CK_BYTE_PTR outBuf, | |
2243 CK_ULONG_PTR outBufLen | |
2244 ) | |
2245 { | |
2246 NSSCKFWCryptoOperation *fwOperation; | |
2247 NSSCKFWCryptoOperation *fwPeerOperation; | |
2248 NSSItem inputBuffer; | |
2249 NSSItem outputBuffer; | |
2250 CK_ULONG maxBufLen = *outBufLen; | |
2251 CK_ULONG len; | |
2252 CK_RV error = CKR_OK; | |
2253 | |
2254 #ifdef NSSDEBUG | |
2255 error = nssCKFWSession_verifyPointer(fwSession); | |
2256 if( CKR_OK != error ) { | |
2257 return error; | |
2258 } | |
2259 | |
2260 if (!fwSession->mdSession) { | |
2261 return CKR_GENERAL_ERROR; | |
2262 } | |
2263 #endif /* NSSDEBUG */ | |
2264 | |
2265 /* make sure we have a valid operation initialized */ | |
2266 fwOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, | |
2267 NSSCKFWCryptoOperationState_EncryptDecrypt); | |
2268 if (!fwOperation) { | |
2269 return CKR_OPERATION_NOT_INITIALIZED; | |
2270 } | |
2271 | |
2272 /* make sure it's the correct type */ | |
2273 if (encryptType != nssCKFWCryptoOperation_GetType(fwOperation)) { | |
2274 return CKR_OPERATION_NOT_INITIALIZED; | |
2275 } | |
2276 /* make sure we have a valid operation initialized */ | |
2277 fwPeerOperation = nssCKFWSession_GetCurrentCryptoOperation(fwSession, | |
2278 digestState); | |
2279 if (!fwPeerOperation) { | |
2280 return CKR_OPERATION_NOT_INITIALIZED; | |
2281 } | |
2282 | |
2283 /* make sure it's the correct type */ | |
2284 if (digestType != nssCKFWCryptoOperation_GetType(fwOperation)) { | |
2285 return CKR_OPERATION_NOT_INITIALIZED; | |
2286 } | |
2287 | |
2288 inputBuffer.data = inBuf; | |
2289 inputBuffer.size = inBufLen; | |
2290 len = nssCKFWCryptoOperation_GetOperationLength(fwOperation, | |
2291 &inputBuffer, &error); | |
2292 if (CKR_OK != error) { | |
2293 return error; | |
2294 } | |
2295 | |
2296 *outBufLen = len; | |
2297 if ((CK_BYTE_PTR)NULL == outBuf) { | |
2298 return CKR_OK; | |
2299 } | |
2300 | |
2301 if (len > maxBufLen) { | |
2302 return CKR_BUFFER_TOO_SMALL; | |
2303 } | |
2304 | |
2305 outputBuffer.data = outBuf; | |
2306 outputBuffer.size = *outBufLen; | |
2307 | |
2308 error = nssCKFWCryptoOperation_UpdateCombo(fwOperation, fwPeerOperation, | |
2309 &inputBuffer, &outputBuffer); | |
2310 if (CKR_FUNCTION_FAILED == error) { | |
2311 PRBool isEncrypt = | |
2312 (PRBool) (NSSCKFWCryptoOperationType_Encrypt == encryptType); | |
2313 | |
2314 if (isEncrypt) { | |
2315 error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation, | |
2316 &inputBuffer); | |
2317 if (CKR_OK != error) { | |
2318 return error; | |
2319 } | |
2320 } | |
2321 error = nssCKFWCryptoOperation_Update(fwOperation, | |
2322 &inputBuffer, &outputBuffer); | |
2323 if (CKR_OK != error) { | |
2324 return error; | |
2325 } | |
2326 if (!isEncrypt) { | |
2327 error = nssCKFWCryptoOperation_DigestUpdate(fwPeerOperation, | |
2328 &outputBuffer); | |
2329 } | |
2330 } | |
2331 return error; | |
2332 } | |
2333 | |
2334 | |
2335 /* | |
2336 * NSSCKFWSession_GetMDSession | |
2337 * | |
2338 */ | |
2339 | |
2340 NSS_IMPLEMENT NSSCKMDSession * | |
2341 NSSCKFWSession_GetMDSession | |
2342 ( | |
2343 NSSCKFWSession *fwSession | |
2344 ) | |
2345 { | |
2346 #ifdef DEBUG | |
2347 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
2348 return (NSSCKMDSession *)NULL; | |
2349 } | |
2350 #endif /* DEBUG */ | |
2351 | |
2352 return nssCKFWSession_GetMDSession(fwSession); | |
2353 } | |
2354 | |
2355 /* | |
2356 * NSSCKFWSession_GetArena | |
2357 * | |
2358 */ | |
2359 | |
2360 NSS_IMPLEMENT NSSArena * | |
2361 NSSCKFWSession_GetArena | |
2362 ( | |
2363 NSSCKFWSession *fwSession, | |
2364 CK_RV *pError | |
2365 ) | |
2366 { | |
2367 #ifdef DEBUG | |
2368 if (!pError) { | |
2369 return (NSSArena *)NULL; | |
2370 } | |
2371 | |
2372 *pError = nssCKFWSession_verifyPointer(fwSession); | |
2373 if( CKR_OK != *pError ) { | |
2374 return (NSSArena *)NULL; | |
2375 } | |
2376 #endif /* DEBUG */ | |
2377 | |
2378 return nssCKFWSession_GetArena(fwSession, pError); | |
2379 } | |
2380 | |
2381 /* | |
2382 * NSSCKFWSession_CallNotification | |
2383 * | |
2384 */ | |
2385 | |
2386 NSS_IMPLEMENT CK_RV | |
2387 NSSCKFWSession_CallNotification | |
2388 ( | |
2389 NSSCKFWSession *fwSession, | |
2390 CK_NOTIFICATION event | |
2391 ) | |
2392 { | |
2393 #ifdef DEBUG | |
2394 CK_RV error = CKR_OK; | |
2395 | |
2396 error = nssCKFWSession_verifyPointer(fwSession); | |
2397 if( CKR_OK != error ) { | |
2398 return error; | |
2399 } | |
2400 #endif /* DEBUG */ | |
2401 | |
2402 return nssCKFWSession_CallNotification(fwSession, event); | |
2403 } | |
2404 | |
2405 /* | |
2406 * NSSCKFWSession_IsRWSession | |
2407 * | |
2408 */ | |
2409 | |
2410 NSS_IMPLEMENT CK_BBOOL | |
2411 NSSCKFWSession_IsRWSession | |
2412 ( | |
2413 NSSCKFWSession *fwSession | |
2414 ) | |
2415 { | |
2416 #ifdef DEBUG | |
2417 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
2418 return CK_FALSE; | |
2419 } | |
2420 #endif /* DEBUG */ | |
2421 | |
2422 return nssCKFWSession_IsRWSession(fwSession); | |
2423 } | |
2424 | |
2425 /* | |
2426 * NSSCKFWSession_IsSO | |
2427 * | |
2428 */ | |
2429 | |
2430 NSS_IMPLEMENT CK_BBOOL | |
2431 NSSCKFWSession_IsSO | |
2432 ( | |
2433 NSSCKFWSession *fwSession | |
2434 ) | |
2435 { | |
2436 #ifdef DEBUG | |
2437 if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) { | |
2438 return CK_FALSE; | |
2439 } | |
2440 #endif /* DEBUG */ | |
2441 | |
2442 return nssCKFWSession_IsSO(fwSession); | |
2443 } | |
2444 | |
2445 NSS_IMPLEMENT NSSCKFWCryptoOperation * | |
2446 NSSCKFWSession_GetCurrentCryptoOperation | |
2447 ( | |
2448 NSSCKFWSession *fwSession, | |
2449 NSSCKFWCryptoOperationState state | |
2450 ) | |
2451 { | |
2452 #ifdef DEBUG | |
2453 CK_RV error = CKR_OK; | |
2454 error = nssCKFWSession_verifyPointer(fwSession); | |
2455 if( CKR_OK != error ) { | |
2456 return (NSSCKFWCryptoOperation *)NULL; | |
2457 } | |
2458 | |
2459 if ( state >= NSSCKFWCryptoOperationState_Max) { | |
2460 return (NSSCKFWCryptoOperation *)NULL; | |
2461 } | |
2462 #endif /* DEBUG */ | |
2463 return nssCKFWSession_GetCurrentCryptoOperation(fwSession, state); | |
2464 } | |
OLD | NEW |