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