Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: nss/lib/ckfw/session.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nss/lib/ckfw/object.c ('k') | nss/lib/ckfw/sessobj.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 }
OLDNEW
« no previous file with comments | « nss/lib/ckfw/object.c ('k') | nss/lib/ckfw/sessobj.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698