~ubuntu-branches/ubuntu/trusty/xulrunner/trusty

« back to all changes in this revision

Viewing changes to security/nss-fips/lib/ckfw/session.c

  • Committer: Bazaar Package Importer
  • Author(s): Devid Antonio Filoni
  • Date: 2008-08-25 13:04:18 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20080825130418-ck1i2ms384tzb9m0
Tags: 1.8.1.16+nobinonly-0ubuntu1
* New upstream release (taken from upstream CVS), LP: #254618.
* Fix MFSA 2008-35, MFSA 2008-34, MFSA 2008-33, MFSA 2008-32, MFSA 2008-31,
  MFSA 2008-30, MFSA 2008-29, MFSA 2008-28, MFSA 2008-27, MFSA 2008-25,
  MFSA 2008-24, MFSA 2008-23, MFSA 2008-22, MFSA 2008-21, MFSA 2008-26 also
  known as CVE-2008-2933, CVE-2008-2785, CVE-2008-2811, CVE-2008-2810,
  CVE-2008-2809, CVE-2008-2808, CVE-2008-2807, CVE-2008-2806, CVE-2008-2805,
  CVE-2008-2803, CVE-2008-2802, CVE-2008-2801, CVE-2008-2800, CVE-2008-2798.
* Drop 89_bz419350_attachment_306066 patch, merged upstream.
* Bump Standards-Version to 3.8.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
3
 *
 
4
 * The contents of this file are subject to the Mozilla Public License Version
 
5
 * 1.1 (the "License"); you may not use this file except in compliance with
 
6
 * the License. You may obtain a copy of the License at
 
7
 * http://www.mozilla.org/MPL/
 
8
 *
 
9
 * Software distributed under the License is distributed on an "AS IS" basis,
 
10
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
11
 * for the specific language governing rights and limitations under the
 
12
 * License.
 
13
 *
 
14
 * The Original Code is the Netscape security libraries.
 
15
 *
 
16
 * The Initial Developer of the Original Code is
 
17
 * Netscape Communications Corporation.
 
18
 * Portions created by the Initial Developer are Copyright (C) 1994-2000
 
19
 * the Initial Developer. All Rights Reserved.
 
20
 *
 
21
 * Contributor(s):
 
22
 *
 
23
 * Alternatively, the contents of this file may be used under the terms of
 
24
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
25
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
26
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
27
 * of those above. If you wish to allow use of your version of this file only
 
28
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
29
 * use your version of this file under the terms of the MPL, indicate your
 
30
 * decision by deleting the provisions above and replace them with the notice
 
31
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
32
 * the provisions above, a recipient may use your version of this file under
 
33
 * the terms of any one of the MPL, the GPL or the LGPL.
 
34
 *
 
35
 * ***** END LICENSE BLOCK ***** */
 
36
 
 
37
#ifdef DEBUG
 
38
static const char CVS_ID[] = "@(#) $RCSfile: session.c,v $ $Revision: 1.8.28.1 $ $Date: 2006/04/19 23:49:53 $";
 
39
#endif /* DEBUG */
 
40
 
 
41
/*
 
42
 * session.c
 
43
 *
 
44
 * This file implements the NSSCKFWSession type and methods.
 
45
 */
 
46
 
 
47
#ifndef CK_T
 
48
#include "ck.h"
 
49
#endif /* CK_T */
 
50
 
 
51
/*
 
52
 * NSSCKFWSession
 
53
 *
 
54
 *  -- create/destroy --
 
55
 *  nssCKFWSession_Create
 
56
 *  nssCKFWSession_Destroy
 
57
 *
 
58
 *  -- public accessors --
 
59
 *  NSSCKFWSession_GetMDSession
 
60
 *  NSSCKFWSession_GetArena
 
61
 *  NSSCKFWSession_CallNotification
 
62
 *  NSSCKFWSession_IsRWSession
 
63
 *  NSSCKFWSession_IsSO
 
64
 *
 
65
 *  -- implement public accessors --
 
66
 *  nssCKFWSession_GetMDSession
 
67
 *  nssCKFWSession_GetArena
 
68
 *  nssCKFWSession_CallNotification
 
69
 *  nssCKFWSession_IsRWSession
 
70
 *  nssCKFWSession_IsSO
 
71
 *
 
72
 *  -- private accessors --
 
73
 *  nssCKFWSession_GetSlot
 
74
 *  nssCKFWSession_GetSessionState
 
75
 *  nssCKFWSession_SetFWFindObjects
 
76
 *  nssCKFWSession_GetFWFindObjects
 
77
 *  nssCKFWSession_SetMDSession
 
78
 *  nssCKFWSession_SetHandle
 
79
 *  nssCKFWSession_GetHandle
 
80
 *  nssCKFWSession_RegisterSessionObject
 
81
 *  nssCKFWSession_DeegisterSessionObject
 
82
 *
 
83
 *  -- module fronts --
 
84
 *  nssCKFWSession_GetDeviceError
 
85
 *  nssCKFWSession_Login
 
86
 *  nssCKFWSession_Logout
 
87
 *  nssCKFWSession_InitPIN
 
88
 *  nssCKFWSession_SetPIN
 
89
 *  nssCKFWSession_GetOperationStateLen
 
90
 *  nssCKFWSession_GetOperationState
 
91
 *  nssCKFWSession_SetOperationState
 
92
 *  nssCKFWSession_CreateObject
 
93
 *  nssCKFWSession_CopyObject
 
94
 *  nssCKFWSession_FindObjectsInit
 
95
 *  nssCKFWSession_SeedRandom
 
96
 *  nssCKFWSession_GetRandom
 
97
 */
 
98
 
 
99
struct NSSCKFWSessionStr {
 
100
  NSSArena *arena;
 
101
  NSSCKMDSession *mdSession;
 
102
  NSSCKFWToken *fwToken;
 
103
  NSSCKMDToken *mdToken;
 
104
  NSSCKFWInstance *fwInstance;
 
105
  NSSCKMDInstance *mdInstance;
 
106
  CK_VOID_PTR pApplication;
 
107
  CK_NOTIFY Notify;
 
108
 
 
109
  /*
 
110
   * Everything above is set at creation time, and then not modified.
 
111
   * The items below are atomic.  No locking required.  If we fear
 
112
   * about pointer-copies being nonatomic, we'll lock fwFindObjects.
 
113
   */
 
114
 
 
115
  CK_BBOOL rw;
 
116
  NSSCKFWFindObjects *fwFindObjects;
 
117
  nssCKFWHash *sessionObjectHash;
 
118
  CK_SESSION_HANDLE hSession;
 
119
};
 
120
 
 
121
#ifdef DEBUG
 
122
/*
 
123
 * But first, the pointer-tracking stuff.
 
124
 *
 
125
 * NOTE: the pointer-tracking support in NSS/base currently relies
 
126
 * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
 
127
 * locking, which is tied into the runtime.  We need a pointer-tracker
 
128
 * implementation that uses the locks supplied through C_Initialize.
 
129
 * That support, however, can be filled in later.  So for now, I'll
 
130
 * just do this routines as no-ops.
 
131
 */
 
132
 
 
133
static CK_RV
 
134
session_add_pointer
 
135
(
 
136
  const NSSCKFWSession *fwSession
 
137
)
 
138
{
 
139
  return CKR_OK;
 
140
}
 
141
 
 
142
static CK_RV
 
143
session_remove_pointer
 
144
(
 
145
  const NSSCKFWSession *fwSession
 
146
)
 
147
{
 
148
  return CKR_OK;
 
149
}
 
150
 
 
151
NSS_IMPLEMENT CK_RV
 
152
nssCKFWSession_verifyPointer
 
153
(
 
154
  const NSSCKFWSession *fwSession
 
155
)
 
156
{
 
157
  return CKR_OK;
 
158
}
 
159
 
 
160
#endif /* DEBUG */
 
161
 
 
162
/*
 
163
 * nssCKFWSession_Create
 
164
 *
 
165
 */
 
166
NSS_IMPLEMENT NSSCKFWSession *
 
167
nssCKFWSession_Create
 
168
(
 
169
  NSSCKFWToken *fwToken,
 
170
  CK_BBOOL rw,
 
171
  CK_VOID_PTR pApplication,
 
172
  CK_NOTIFY Notify,
 
173
  CK_RV *pError
 
174
)
 
175
{
 
176
  NSSArena *arena = (NSSArena *)NULL;
 
177
  NSSCKFWSession *fwSession;
 
178
  NSSCKFWSlot *fwSlot;
 
179
 
 
180
#ifdef NSSDEBUG
 
181
  if( (CK_RV *)NULL == pError ) {
 
182
    return (NSSCKFWSession *)NULL;
 
183
  }
 
184
 
 
185
  *pError = nssCKFWToken_verifyPointer(fwToken);
 
186
  if( CKR_OK != *pError ) {
 
187
    return (NSSCKFWSession *)NULL;
 
188
  }
 
189
#endif /* NSSDEBUG */
 
190
 
 
191
  arena = NSSArena_Create();
 
192
  if( (NSSArena *)NULL == arena ) {
 
193
    *pError = CKR_HOST_MEMORY;
 
194
    return (NSSCKFWSession *)NULL;
 
195
  }
 
196
 
 
197
  fwSession = nss_ZNEW(arena, NSSCKFWSession);
 
198
  if( (NSSCKFWSession *)NULL == fwSession ) {
 
199
    *pError = CKR_HOST_MEMORY;
 
200
    goto loser;
 
201
  }
 
202
 
 
203
  fwSession->arena = arena;
 
204
  fwSession->mdSession = (NSSCKMDSession *)NULL; /* set later */
 
205
  fwSession->fwToken = fwToken;
 
206
  fwSession->mdToken = nssCKFWToken_GetMDToken(fwToken);
 
207
 
 
208
  fwSlot = nssCKFWToken_GetFWSlot(fwToken);
 
209
  fwSession->fwInstance = nssCKFWSlot_GetFWInstance(fwSlot);
 
210
  fwSession->mdInstance = nssCKFWSlot_GetMDInstance(fwSlot);
 
211
 
 
212
  fwSession->rw = rw;
 
213
  fwSession->pApplication = pApplication;
 
214
  fwSession->Notify = Notify;
 
215
 
 
216
  fwSession->fwFindObjects = (NSSCKFWFindObjects *)NULL;
 
217
 
 
218
  fwSession->sessionObjectHash = nssCKFWHash_Create(fwSession->fwInstance, arena, pError);
 
219
  if( (nssCKFWHash *)NULL == fwSession->sessionObjectHash ) {
 
220
    if( CKR_OK == *pError ) {
 
221
      *pError = CKR_GENERAL_ERROR;
 
222
    }
 
223
    goto loser;
 
224
  }
 
225
 
 
226
#ifdef DEBUG
 
227
  *pError = session_add_pointer(fwSession);
 
228
  if( CKR_OK != *pError ) {
 
229
    goto loser;
 
230
  }
 
231
#endif /* DEBUG */
 
232
 
 
233
  return fwSession;
 
234
 
 
235
 loser:
 
236
  if( (NSSArena *)NULL != arena ) {
 
237
    if( fwSession && (nssCKFWHash *)NULL != fwSession->sessionObjectHash ) {
 
238
      (void)nssCKFWHash_Destroy(fwSession->sessionObjectHash);
 
239
    }
 
240
    NSSArena_Destroy(arena);
 
241
  }
 
242
 
 
243
  return (NSSCKFWSession *)NULL;
 
244
}
 
245
 
 
246
static void
 
247
nss_ckfw_session_object_destroy_iterator
 
248
(
 
249
  const void *key,
 
250
  void *value,
 
251
  void *closure
 
252
)
 
253
{
 
254
  NSSCKFWObject *fwObject = (NSSCKFWObject *)value;
 
255
  nssCKFWObject_Finalize(fwObject);
 
256
}
 
257
 
 
258
/*
 
259
 * nssCKFWSession_Destroy
 
260
 *
 
261
 */
 
262
NSS_IMPLEMENT CK_RV
 
263
nssCKFWSession_Destroy
 
264
(
 
265
  NSSCKFWSession *fwSession,
 
266
  CK_BBOOL removeFromTokenHash
 
267
)
 
268
{
 
269
  CK_RV error = CKR_OK;
 
270
  nssCKFWHash *sessionObjectHash;
 
271
 
 
272
#ifdef NSSDEBUG
 
273
  error = nssCKFWSession_verifyPointer(fwSession);
 
274
  if( CKR_OK != error ) {
 
275
    return error;
 
276
  }
 
277
#endif /* NSSDEBUG */
 
278
 
 
279
  if( removeFromTokenHash ) {
 
280
    error = nssCKFWToken_RemoveSession(fwSession->fwToken, fwSession);
 
281
  }
 
282
 
 
283
  /*
 
284
   * Invalidate session objects
 
285
   */
 
286
 
 
287
  sessionObjectHash = fwSession->sessionObjectHash;
 
288
  fwSession->sessionObjectHash = (nssCKFWHash *)NULL;
 
289
 
 
290
  nssCKFWHash_Iterate(sessionObjectHash, 
 
291
                      nss_ckfw_session_object_destroy_iterator, 
 
292
                      (void *)NULL);
 
293
 
 
294
#ifdef DEBUG
 
295
  (void)session_remove_pointer(fwSession);
 
296
#endif /* DEBUG */
 
297
  (void)nssCKFWHash_Destroy(sessionObjectHash);
 
298
  NSSArena_Destroy(fwSession->arena);
 
299
 
 
300
  return error;
 
301
}
 
302
 
 
303
/*
 
304
 * nssCKFWSession_GetMDSession
 
305
 *
 
306
 */
 
307
NSS_IMPLEMENT NSSCKMDSession *
 
308
nssCKFWSession_GetMDSession
 
309
(
 
310
  NSSCKFWSession *fwSession
 
311
)
 
312
{
 
313
#ifdef NSSDEBUG
 
314
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
315
    return (NSSCKMDSession *)NULL;
 
316
  }
 
317
#endif /* NSSDEBUG */
 
318
 
 
319
  return fwSession->mdSession;
 
320
}
 
321
 
 
322
/*
 
323
 * nssCKFWSession_GetArena
 
324
 *
 
325
 */
 
326
NSS_IMPLEMENT NSSArena *
 
327
nssCKFWSession_GetArena
 
328
(
 
329
  NSSCKFWSession *fwSession,
 
330
  CK_RV *pError
 
331
)
 
332
{
 
333
#ifdef NSSDEBUG
 
334
  if( (CK_RV *)NULL == pError ) {
 
335
    return (NSSArena *)NULL;
 
336
  }
 
337
 
 
338
  *pError = nssCKFWSession_verifyPointer(fwSession);
 
339
  if( CKR_OK != *pError ) {
 
340
    return (NSSArena *)NULL;
 
341
  }
 
342
#endif /* NSSDEBUG */
 
343
 
 
344
  return fwSession->arena;
 
345
}
 
346
 
 
347
/*
 
348
 * nssCKFWSession_CallNotification
 
349
 *
 
350
 */
 
351
NSS_IMPLEMENT CK_RV
 
352
nssCKFWSession_CallNotification
 
353
(
 
354
  NSSCKFWSession *fwSession,
 
355
  CK_NOTIFICATION event
 
356
)
 
357
{
 
358
  CK_RV error = CKR_OK;
 
359
  CK_SESSION_HANDLE handle;
 
360
 
 
361
#ifdef NSSDEBUG
 
362
  error = nssCKFWSession_verifyPointer(fwSession);
 
363
  if( CKR_OK != error ) {
 
364
    return error;
 
365
  }
 
366
#endif /* NSSDEBUG */
 
367
 
 
368
  if( (CK_NOTIFY)NULL == fwSession->Notify ) {
 
369
    return CKR_OK;
 
370
  }
 
371
 
 
372
  handle = nssCKFWInstance_FindSessionHandle(fwSession->fwInstance, fwSession);
 
373
  if( (CK_SESSION_HANDLE)0 == handle ) {
 
374
    return CKR_GENERAL_ERROR;
 
375
  }
 
376
 
 
377
  error = fwSession->Notify(handle, event, fwSession->pApplication);
 
378
 
 
379
  return error;
 
380
}
 
381
 
 
382
/*
 
383
 * nssCKFWSession_IsRWSession
 
384
 *
 
385
 */
 
386
NSS_IMPLEMENT CK_BBOOL
 
387
nssCKFWSession_IsRWSession
 
388
(
 
389
  NSSCKFWSession *fwSession
 
390
)
 
391
{
 
392
#ifdef NSSDEBUG
 
393
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
394
    return CK_FALSE;
 
395
  }
 
396
#endif /* NSSDEBUG */
 
397
 
 
398
  return fwSession->rw;
 
399
}
 
400
 
 
401
/*
 
402
 * nssCKFWSession_IsSO
 
403
 *
 
404
 */
 
405
NSS_IMPLEMENT CK_BBOOL
 
406
nssCKFWSession_IsSO
 
407
(
 
408
  NSSCKFWSession *fwSession
 
409
)
 
410
{
 
411
  CK_STATE state;
 
412
 
 
413
#ifdef NSSDEBUG
 
414
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
415
    return CK_FALSE;
 
416
  }
 
417
#endif /* NSSDEBUG */
 
418
 
 
419
  state = nssCKFWToken_GetSessionState(fwSession->fwToken);
 
420
  switch( state ) {
 
421
  case CKS_RO_PUBLIC_SESSION:
 
422
  case CKS_RO_USER_FUNCTIONS:
 
423
  case CKS_RW_PUBLIC_SESSION:
 
424
  case CKS_RW_USER_FUNCTIONS:
 
425
    return CK_FALSE;
 
426
  case CKS_RW_SO_FUNCTIONS:
 
427
    return CK_TRUE;
 
428
  default:
 
429
    return CK_FALSE;
 
430
  }
 
431
}
 
432
 
 
433
/*
 
434
 * nssCKFWSession_GetFWSlot
 
435
 *
 
436
 */
 
437
NSS_IMPLEMENT NSSCKFWSlot *
 
438
nssCKFWSession_GetFWSlot
 
439
(
 
440
  NSSCKFWSession *fwSession
 
441
)
 
442
{
 
443
#ifdef NSSDEBUG
 
444
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
445
    return (NSSCKFWSlot *)NULL;
 
446
  }
 
447
#endif /* NSSDEBUG */
 
448
 
 
449
  return nssCKFWToken_GetFWSlot(fwSession->fwToken);
 
450
}
 
451
 
 
452
/*
 
453
 * nssCFKWSession_GetSessionState
 
454
 *
 
455
 */
 
456
NSS_IMPLEMENT CK_STATE
 
457
nssCKFWSession_GetSessionState
 
458
(
 
459
  NSSCKFWSession *fwSession
 
460
)
 
461
{
 
462
#ifdef NSSDEBUG
 
463
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
464
    return CKS_RO_PUBLIC_SESSION; /* whatever */
 
465
  }
 
466
#endif /* NSSDEBUG */
 
467
 
 
468
  return nssCKFWToken_GetSessionState(fwSession->fwToken);
 
469
}
 
470
 
 
471
/*
 
472
 * nssCKFWSession_SetFWFindObjects
 
473
 *
 
474
 */
 
475
NSS_IMPLEMENT CK_RV
 
476
nssCKFWSession_SetFWFindObjects
 
477
(
 
478
  NSSCKFWSession *fwSession,
 
479
  NSSCKFWFindObjects *fwFindObjects
 
480
)
 
481
{
 
482
#ifdef NSSDEBUG
 
483
  CK_RV error = CKR_OK;
 
484
#endif /* NSSDEBUG */
 
485
 
 
486
#ifdef NSSDEBUG
 
487
  error = nssCKFWSession_verifyPointer(fwSession);
 
488
  if( CKR_OK != error ) {
 
489
    return error;
 
490
  }
 
491
 
 
492
  /* fwFindObjects may be null */
 
493
#endif /* NSSDEBUG */
 
494
 
 
495
  if( ((NSSCKFWFindObjects *)NULL != fwSession->fwFindObjects) &&
 
496
      ((NSSCKFWFindObjects *)NULL != fwFindObjects) ) {
 
497
    return CKR_OPERATION_ACTIVE;
 
498
  }
 
499
 
 
500
  fwSession->fwFindObjects = fwFindObjects;
 
501
 
 
502
  return CKR_OK;
 
503
}
 
504
 
 
505
/*
 
506
 * nssCKFWSession_GetFWFindObjects
 
507
 *
 
508
 */
 
509
NSS_IMPLEMENT NSSCKFWFindObjects *
 
510
nssCKFWSession_GetFWFindObjects
 
511
(
 
512
  NSSCKFWSession *fwSession,
 
513
  CK_RV *pError
 
514
)
 
515
{
 
516
#ifdef NSSDEBUG
 
517
  if( (CK_RV *)NULL == pError ) {
 
518
    return (NSSCKFWFindObjects *)NULL;
 
519
  }
 
520
 
 
521
  *pError = nssCKFWSession_verifyPointer(fwSession);
 
522
  if( CKR_OK != *pError ) {
 
523
    return (NSSCKFWFindObjects *)NULL;
 
524
  }
 
525
#endif /* NSSDEBUG */
 
526
 
 
527
  if( (NSSCKFWFindObjects *)NULL == fwSession->fwFindObjects ) {
 
528
    *pError = CKR_OPERATION_NOT_INITIALIZED;
 
529
    return (NSSCKFWFindObjects *)NULL;
 
530
  }
 
531
 
 
532
  return fwSession->fwFindObjects;
 
533
}
 
534
 
 
535
/*
 
536
 * nssCKFWSession_SetMDSession
 
537
 *
 
538
 */
 
539
NSS_IMPLEMENT CK_RV
 
540
nssCKFWSession_SetMDSession
 
541
(
 
542
  NSSCKFWSession *fwSession,
 
543
  NSSCKMDSession *mdSession
 
544
)
 
545
{
 
546
#ifdef NSSDEBUG
 
547
  CK_RV error = CKR_OK;
 
548
#endif /* NSSDEBUG */
 
549
 
 
550
#ifdef NSSDEBUG
 
551
  error = nssCKFWSession_verifyPointer(fwSession);
 
552
  if( CKR_OK != error ) {
 
553
    return error;
 
554
  }
 
555
 
 
556
  if( (NSSCKMDSession *)NULL == mdSession ) {
 
557
    return CKR_ARGUMENTS_BAD;
 
558
  }
 
559
#endif /* NSSDEBUG */
 
560
 
 
561
  if( (NSSCKMDSession *)NULL != fwSession->mdSession ) {
 
562
    return CKR_GENERAL_ERROR;
 
563
  }
 
564
 
 
565
  fwSession->mdSession = mdSession;
 
566
 
 
567
  return CKR_OK;
 
568
}
 
569
 
 
570
/*
 
571
 * nssCKFWSession_SetHandle
 
572
 *
 
573
 */
 
574
NSS_IMPLEMENT CK_RV
 
575
nssCKFWSession_SetHandle
 
576
(
 
577
  NSSCKFWSession *fwSession,
 
578
  CK_SESSION_HANDLE hSession
 
579
)
 
580
{
 
581
#ifdef NSSDEBUG
 
582
  CK_RV error = CKR_OK;
 
583
#endif /* NSSDEBUG */
 
584
 
 
585
#ifdef NSSDEBUG
 
586
  error = nssCKFWSession_verifyPointer(fwSession);
 
587
  if( CKR_OK != error ) {
 
588
    return error;
 
589
  }
 
590
#endif /* NSSDEBUG */
 
591
 
 
592
  if( (CK_SESSION_HANDLE)0 != fwSession->hSession ) {
 
593
    return CKR_GENERAL_ERROR;
 
594
  }
 
595
 
 
596
  fwSession->hSession = hSession;
 
597
 
 
598
  return CKR_OK;
 
599
}
 
600
 
 
601
/*
 
602
 * nssCKFWSession_GetHandle
 
603
 *
 
604
 */
 
605
NSS_IMPLEMENT CK_SESSION_HANDLE
 
606
nssCKFWSession_GetHandle
 
607
(
 
608
  NSSCKFWSession *fwSession
 
609
)
 
610
{
 
611
#ifdef NSSDEBUG
 
612
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
613
    return NULL;
 
614
  }
 
615
#endif /* NSSDEBUG */
 
616
 
 
617
  return fwSession->hSession;
 
618
}
 
619
 
 
620
/*
 
621
 * nssCKFWSession_RegisterSessionObject
 
622
 *
 
623
 */
 
624
NSS_IMPLEMENT CK_RV
 
625
nssCKFWSession_RegisterSessionObject
 
626
(
 
627
  NSSCKFWSession *fwSession,
 
628
  NSSCKFWObject *fwObject
 
629
)
 
630
{
 
631
  CK_RV rv = CKR_OK;
 
632
 
 
633
#ifdef NSSDEBUG
 
634
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
635
    return CKR_GENERAL_ERROR;
 
636
  }
 
637
#endif /* NSSDEBUG */
 
638
 
 
639
  if( (nssCKFWHash *)NULL != fwSession->sessionObjectHash ) {
 
640
    rv = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
 
641
  }
 
642
 
 
643
  return rv;
 
644
}
 
645
 
 
646
/*
 
647
 * nssCKFWSession_DeregisterSessionObject
 
648
 *
 
649
 */
 
650
NSS_IMPLEMENT CK_RV
 
651
nssCKFWSession_DeregisterSessionObject
 
652
(
 
653
  NSSCKFWSession *fwSession,
 
654
  NSSCKFWObject *fwObject
 
655
)
 
656
{
 
657
#ifdef NSSDEBUG
 
658
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
659
    return CKR_GENERAL_ERROR;
 
660
  }
 
661
#endif /* NSSDEBUG */
 
662
 
 
663
  if( (nssCKFWHash *)NULL != fwSession->sessionObjectHash ) {
 
664
    nssCKFWHash_Remove(fwSession->sessionObjectHash, fwObject);
 
665
  }
 
666
 
 
667
  return CKR_OK;
 
668
}
 
669
 
 
670
/*
 
671
 * nssCKFWSession_GetDeviceError
 
672
 *
 
673
 */
 
674
NSS_IMPLEMENT CK_ULONG
 
675
nssCKFWSession_GetDeviceError
 
676
(
 
677
  NSSCKFWSession *fwSession
 
678
)
 
679
{
 
680
#ifdef NSSDEBUG
 
681
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
682
    return (CK_ULONG)0;
 
683
  }
 
684
 
 
685
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
686
    return (CK_ULONG)0;
 
687
  }
 
688
#endif /* NSSDEBUG */
 
689
 
 
690
  if( (void *)NULL == (void *)fwSession->mdSession->GetDeviceError ) {
 
691
    return (CK_ULONG)0;
 
692
  }
 
693
 
 
694
  return fwSession->mdSession->GetDeviceError(fwSession->mdSession, 
 
695
    fwSession, fwSession->mdToken, fwSession->fwToken, 
 
696
    fwSession->mdInstance, fwSession->fwInstance);
 
697
}
 
698
 
 
699
/*
 
700
 * nssCKFWSession_Login
 
701
 *
 
702
 */
 
703
NSS_IMPLEMENT CK_RV
 
704
nssCKFWSession_Login
 
705
(
 
706
  NSSCKFWSession *fwSession,
 
707
  CK_USER_TYPE userType,
 
708
  NSSItem *pin
 
709
)
 
710
{
 
711
  CK_RV error = CKR_OK;
 
712
  CK_STATE oldState;
 
713
  CK_STATE newState;
 
714
 
 
715
#ifdef NSSDEBUG
 
716
  error = nssCKFWSession_verifyPointer(fwSession);
 
717
  if( CKR_OK != error ) {
 
718
    return error;
 
719
  }
 
720
 
 
721
  switch( userType ) {
 
722
  case CKU_SO:
 
723
  case CKU_USER:
 
724
    break;
 
725
  default:
 
726
    return CKR_USER_TYPE_INVALID;
 
727
  }
 
728
 
 
729
  if( (NSSItem *)NULL == pin ) {
 
730
    if( CK_TRUE != nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken) ) {
 
731
      return CKR_ARGUMENTS_BAD;
 
732
    }
 
733
  }
 
734
 
 
735
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
736
    return CKR_GENERAL_ERROR;
 
737
  }
 
738
#endif /* NSSDEBUG */
 
739
 
 
740
  oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
 
741
 
 
742
  /*
 
743
   * It's not clear what happens when you're already logged in.
 
744
   * I'll just fail; but if we decide to change, the logic is
 
745
   * all right here.
 
746
   */
 
747
 
 
748
  if( CKU_SO == userType ) {
 
749
    switch( oldState ) {
 
750
    case CKS_RO_PUBLIC_SESSION:      
 
751
      /*
 
752
       * There's no such thing as a read-only security officer
 
753
       * session, so fail.  The error should be CKR_SESSION_READ_ONLY,
 
754
       * except that C_Login isn't defined to return that.  So we'll
 
755
       * do CKR_SESSION_READ_ONLY_EXISTS, which is what is documented.
 
756
       */
 
757
      return CKR_SESSION_READ_ONLY_EXISTS;
 
758
    case CKS_RO_USER_FUNCTIONS:
 
759
      return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
 
760
    case CKS_RW_PUBLIC_SESSION:
 
761
      newState = CKS_RW_SO_FUNCTIONS;
 
762
      break;
 
763
    case CKS_RW_USER_FUNCTIONS:
 
764
      return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
 
765
    case CKS_RW_SO_FUNCTIONS:
 
766
      return CKR_USER_ALREADY_LOGGED_IN;
 
767
    default:
 
768
      return CKR_GENERAL_ERROR;
 
769
    }
 
770
  } else /* CKU_USER == userType */ {
 
771
    switch( oldState ) {
 
772
    case CKS_RO_PUBLIC_SESSION:      
 
773
      newState = CKS_RO_USER_FUNCTIONS;
 
774
      break;
 
775
    case CKS_RO_USER_FUNCTIONS:
 
776
      return CKR_USER_ALREADY_LOGGED_IN;
 
777
    case CKS_RW_PUBLIC_SESSION:
 
778
      newState = CKS_RW_USER_FUNCTIONS;
 
779
      break;
 
780
    case CKS_RW_USER_FUNCTIONS:
 
781
      return CKR_USER_ALREADY_LOGGED_IN;
 
782
    case CKS_RW_SO_FUNCTIONS:
 
783
      return CKR_USER_ANOTHER_ALREADY_LOGGED_IN;
 
784
    default:
 
785
      return CKR_GENERAL_ERROR;
 
786
    }
 
787
  }
 
788
 
 
789
  /*
 
790
   * So now we're in one of three cases:
 
791
   *
 
792
   * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_SO_FUNCTIONS;
 
793
   * Old == CKS_RW_PUBLIC_SESSION, New == CKS_RW_USER_FUNCTIONS;
 
794
   * Old == CKS_RO_PUBLIC_SESSION, New == CKS_RO_USER_FUNCTIONS;
 
795
   */
 
796
 
 
797
  if( (void *)NULL == (void *)fwSession->mdSession->Login ) {
 
798
    /*
 
799
     * The Module doesn't want to be informed (or check the pin)
 
800
     * it'll just rely on the Framework as needed.
 
801
     */
 
802
    ;
 
803
  } else {
 
804
    error = fwSession->mdSession->Login(fwSession->mdSession, fwSession,
 
805
      fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
 
806
      fwSession->fwInstance, userType, pin, oldState, newState);
 
807
    if( CKR_OK != error ) {
 
808
      return error;
 
809
    }
 
810
  }
 
811
 
 
812
  (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
 
813
  return CKR_OK;
 
814
}
 
815
 
 
816
/*
 
817
 * nssCKFWSession_Logout
 
818
 *
 
819
 */
 
820
NSS_IMPLEMENT CK_RV
 
821
nssCKFWSession_Logout
 
822
(
 
823
  NSSCKFWSession *fwSession
 
824
)
 
825
{
 
826
  CK_RV error = CKR_OK;
 
827
  CK_STATE oldState;
 
828
  CK_STATE newState;
 
829
 
 
830
#ifdef NSSDEBUG
 
831
  error = nssCKFWSession_verifyPointer(fwSession);
 
832
  if( CKR_OK != error ) {
 
833
    return error;
 
834
  }
 
835
 
 
836
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
837
    return CKR_GENERAL_ERROR;
 
838
  }
 
839
#endif /* NSSDEBUG */
 
840
 
 
841
  oldState = nssCKFWToken_GetSessionState(fwSession->fwToken);
 
842
 
 
843
  switch( oldState ) {
 
844
  case CKS_RO_PUBLIC_SESSION:
 
845
    return CKR_USER_NOT_LOGGED_IN;
 
846
  case CKS_RO_USER_FUNCTIONS:
 
847
    newState = CKS_RO_PUBLIC_SESSION;
 
848
    break;
 
849
  case CKS_RW_PUBLIC_SESSION:
 
850
    return CKR_USER_NOT_LOGGED_IN;
 
851
  case CKS_RW_USER_FUNCTIONS:
 
852
    newState = CKS_RW_PUBLIC_SESSION;
 
853
    break;
 
854
  case CKS_RW_SO_FUNCTIONS:
 
855
    newState = CKS_RW_PUBLIC_SESSION;
 
856
    break;
 
857
  default:
 
858
    return CKR_GENERAL_ERROR;
 
859
  }
 
860
 
 
861
  /*
 
862
   * So now we're in one of three cases:
 
863
   *
 
864
   * Old == CKS_RW_SO_FUNCTIONS,   New == CKS_RW_PUBLIC_SESSION;
 
865
   * Old == CKS_RW_USER_FUNCTIONS, New == CKS_RW_PUBLIC_SESSION;
 
866
   * Old == CKS_RO_USER_FUNCTIONS, New == CKS_RO_PUBLIC_SESSION;
 
867
   */
 
868
 
 
869
  if( (void *)NULL == (void *)fwSession->mdSession->Logout ) {
 
870
    /*
 
871
     * The Module doesn't want to be informed.  Okay.
 
872
     */
 
873
    ;
 
874
  } else {
 
875
    error = fwSession->mdSession->Logout(fwSession->mdSession, fwSession,
 
876
      fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
 
877
      fwSession->fwInstance, oldState, newState);
 
878
    if( CKR_OK != error ) {
 
879
      /*
 
880
       * Now what?!  A failure really should end up with the Framework
 
881
       * considering it logged out, right?
 
882
       */
 
883
      ;
 
884
    }
 
885
  }
 
886
 
 
887
  (void)nssCKFWToken_SetSessionState(fwSession->fwToken, newState);
 
888
  return error;
 
889
}
 
890
 
 
891
/*
 
892
 * nssCKFWSession_InitPIN
 
893
 *
 
894
 */
 
895
NSS_IMPLEMENT CK_RV
 
896
nssCKFWSession_InitPIN
 
897
(
 
898
  NSSCKFWSession *fwSession,
 
899
  NSSItem *pin
 
900
)
 
901
{
 
902
  CK_RV error = CKR_OK;
 
903
  CK_STATE state;
 
904
 
 
905
#ifdef NSSDEBUG
 
906
  error = nssCKFWSession_verifyPointer(fwSession);
 
907
  if( CKR_OK != error ) {
 
908
    return error;
 
909
  }
 
910
 
 
911
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
912
    return CKR_GENERAL_ERROR;
 
913
  }
 
914
#endif /* NSSDEBUG */
 
915
 
 
916
  state = nssCKFWToken_GetSessionState(fwSession->fwToken);
 
917
  if( CKS_RW_SO_FUNCTIONS != state ) {
 
918
    return CKR_USER_NOT_LOGGED_IN;
 
919
  }
 
920
 
 
921
  if( (NSSItem *)NULL == pin ) {
 
922
    CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
 
923
    if( CK_TRUE != has ) {
 
924
      return CKR_ARGUMENTS_BAD;
 
925
    }
 
926
  }
 
927
 
 
928
  if( (void *)NULL == (void *)fwSession->mdSession->InitPIN ) {
 
929
    return CKR_TOKEN_WRITE_PROTECTED;
 
930
  }
 
931
 
 
932
  error = fwSession->mdSession->InitPIN(fwSession->mdSession, fwSession,
 
933
    fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
 
934
    fwSession->fwInstance, pin);
 
935
 
 
936
  return error;
 
937
}
 
938
 
 
939
/*
 
940
 * nssCKFWSession_SetPIN
 
941
 *
 
942
 */
 
943
NSS_IMPLEMENT CK_RV
 
944
nssCKFWSession_SetPIN
 
945
(
 
946
  NSSCKFWSession *fwSession,
 
947
  NSSItem *newPin,
 
948
  NSSItem *oldPin
 
949
)
 
950
{
 
951
  CK_RV error = CKR_OK;
 
952
  CK_STATE state;
 
953
 
 
954
#ifdef NSSDEBUG
 
955
  error = nssCKFWSession_verifyPointer(fwSession);
 
956
  if( CKR_OK != error ) {
 
957
    return error;
 
958
  }
 
959
 
 
960
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
961
    return CKR_GENERAL_ERROR;
 
962
  }
 
963
#endif /* NSSDEBUG */
 
964
 
 
965
  state = nssCKFWToken_GetSessionState(fwSession->fwToken);
 
966
  if( (CKS_RW_SO_FUNCTIONS != state) &&
 
967
      (CKS_RW_USER_FUNCTIONS != state) ) {
 
968
    return CKR_USER_NOT_LOGGED_IN;
 
969
  }
 
970
 
 
971
  if( (NSSItem *)NULL == newPin ) {
 
972
    CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
 
973
    if( CK_TRUE != has ) {
 
974
      return CKR_ARGUMENTS_BAD;
 
975
    }
 
976
  }
 
977
 
 
978
  if( (NSSItem *)NULL == oldPin ) {
 
979
    CK_BBOOL has = nssCKFWToken_GetHasProtectedAuthenticationPath(fwSession->fwToken);
 
980
    if( CK_TRUE != has ) {
 
981
      return CKR_ARGUMENTS_BAD;
 
982
    }
 
983
  }
 
984
 
 
985
  if( (void *)NULL == (void *)fwSession->mdSession->SetPIN ) {
 
986
    return CKR_TOKEN_WRITE_PROTECTED;
 
987
  }
 
988
 
 
989
  error = fwSession->mdSession->SetPIN(fwSession->mdSession, fwSession,
 
990
    fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
 
991
    fwSession->fwInstance, newPin, oldPin);
 
992
 
 
993
  return error;
 
994
}
 
995
 
 
996
/*
 
997
 * nssCKFWSession_GetOperationStateLen
 
998
 *
 
999
 */
 
1000
NSS_IMPLEMENT CK_ULONG
 
1001
nssCKFWSession_GetOperationStateLen
 
1002
(
 
1003
  NSSCKFWSession *fwSession,
 
1004
  CK_RV *pError
 
1005
)
 
1006
{
 
1007
  CK_ULONG mdAmt;
 
1008
  CK_ULONG fwAmt;
 
1009
 
 
1010
#ifdef NSSDEBUG
 
1011
  if( (CK_RV *)NULL == pError ) {
 
1012
    return (CK_ULONG)0;
 
1013
  }
 
1014
 
 
1015
  *pError = nssCKFWSession_verifyPointer(fwSession);
 
1016
  if( CKR_OK != *pError ) {
 
1017
    return (CK_ULONG)0;
 
1018
  }
 
1019
 
 
1020
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
1021
    *pError = CKR_GENERAL_ERROR;
 
1022
    return (CK_ULONG)0;
 
1023
  }
 
1024
#endif /* NSSDEBUG */
 
1025
 
 
1026
  if( (void *)NULL == (void *)fwSession->mdSession->GetOperationStateLen ) {
 
1027
    *pError = CKR_STATE_UNSAVEABLE;
 
1028
  }
 
1029
 
 
1030
  /*
 
1031
   * We could check that the session is actually in some state..
 
1032
   */
 
1033
 
 
1034
  mdAmt = fwSession->mdSession->GetOperationStateLen(fwSession->mdSession,
 
1035
    fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
 
1036
    fwSession->fwInstance, pError);
 
1037
 
 
1038
  if( ((CK_ULONG)0 == mdAmt) && (CKR_OK != *pError) ) {
 
1039
    return (CK_ULONG)0;
 
1040
  }
 
1041
 
 
1042
  /*
 
1043
   * Add a bit of sanity-checking
 
1044
   */
 
1045
  fwAmt = mdAmt + 2*sizeof(CK_ULONG);
 
1046
 
 
1047
  return fwAmt;
 
1048
}
 
1049
 
 
1050
/*
 
1051
 * nssCKFWSession_GetOperationState
 
1052
 *
 
1053
 */
 
1054
NSS_IMPLEMENT CK_RV
 
1055
nssCKFWSession_GetOperationState
 
1056
(
 
1057
  NSSCKFWSession *fwSession,
 
1058
  NSSItem *buffer
 
1059
)
 
1060
{
 
1061
  CK_RV error = CKR_OK;
 
1062
  CK_ULONG fwAmt;
 
1063
  CK_ULONG *ulBuffer;
 
1064
  NSSItem i2;
 
1065
  CK_ULONG n, i;
 
1066
 
 
1067
#ifdef NSSDEBUG
 
1068
  error = nssCKFWSession_verifyPointer(fwSession);
 
1069
  if( CKR_OK != error ) {
 
1070
    return error;
 
1071
  }
 
1072
 
 
1073
  if( (NSSItem *)NULL == buffer ) {
 
1074
    return CKR_ARGUMENTS_BAD;
 
1075
  }
 
1076
 
 
1077
  if( (void *)NULL == buffer->data ) {
 
1078
    return CKR_ARGUMENTS_BAD;
 
1079
  }
 
1080
 
 
1081
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
1082
    return CKR_GENERAL_ERROR;
 
1083
  }
 
1084
#endif /* NSSDEBUG */
 
1085
 
 
1086
  if( (void *)NULL == (void *)fwSession->mdSession->GetOperationState ) {
 
1087
    return CKR_STATE_UNSAVEABLE;
 
1088
  }
 
1089
 
 
1090
  /*
 
1091
   * Sanity-check the caller's buffer.
 
1092
   */
 
1093
 
 
1094
  error = CKR_OK;
 
1095
  fwAmt = nssCKFWSession_GetOperationStateLen(fwSession, &error);
 
1096
  if( ((CK_ULONG)0 == fwAmt) && (CKR_OK != error) ) {
 
1097
    return error;
 
1098
  }
 
1099
 
 
1100
  if( buffer->size < fwAmt ) {
 
1101
    return CKR_BUFFER_TOO_SMALL;
 
1102
  }
 
1103
 
 
1104
  ulBuffer = (CK_ULONG *)buffer->data;
 
1105
 
 
1106
  i2.size = buffer->size - 2*sizeof(CK_ULONG);
 
1107
  i2.data = (void *)&ulBuffer[2];
 
1108
 
 
1109
  error = fwSession->mdSession->GetOperationState(fwSession->mdSession,
 
1110
    fwSession, fwSession->mdToken, fwSession->fwToken, 
 
1111
    fwSession->mdInstance, fwSession->fwInstance, &i2);
 
1112
 
 
1113
  if( CKR_OK != error ) {
 
1114
    return error;
 
1115
  }
 
1116
 
 
1117
  /*
 
1118
   * Add a little integrety/identity check.  
 
1119
   * NOTE: right now, it's pretty stupid.  
 
1120
   * A CRC or something would be better.
 
1121
   */
 
1122
 
 
1123
  ulBuffer[0] = 0x434b4657; /* CKFW */
 
1124
  ulBuffer[1] = 0;
 
1125
  n = i2.size/sizeof(CK_ULONG);
 
1126
  for( i = 0; i < n; i++ ) {
 
1127
    ulBuffer[1] ^= ulBuffer[2+i];
 
1128
  }
 
1129
 
 
1130
  return CKR_OK;
 
1131
}
 
1132
 
 
1133
/*
 
1134
 * nssCKFWSession_SetOperationState
 
1135
 *
 
1136
 */
 
1137
NSS_IMPLEMENT CK_RV
 
1138
nssCKFWSession_SetOperationState
 
1139
(
 
1140
  NSSCKFWSession *fwSession,
 
1141
  NSSItem *state,
 
1142
  NSSCKFWObject *encryptionKey,
 
1143
  NSSCKFWObject *authenticationKey
 
1144
)
 
1145
{
 
1146
  CK_RV error = CKR_OK;
 
1147
  CK_ULONG *ulBuffer;
 
1148
  CK_ULONG n, i;
 
1149
  CK_ULONG x;
 
1150
  NSSItem s;
 
1151
  NSSCKMDObject *mdek;
 
1152
  NSSCKMDObject *mdak;
 
1153
 
 
1154
#ifdef NSSDEBUG
 
1155
  error = nssCKFWSession_verifyPointer(fwSession);
 
1156
  if( CKR_OK != error ) {
 
1157
    return error;
 
1158
  }
 
1159
 
 
1160
  if( (NSSItem *)NULL == state ) {
 
1161
    return CKR_ARGUMENTS_BAD;
 
1162
  }
 
1163
 
 
1164
  if( (void *)NULL == state->data ) {
 
1165
    return CKR_ARGUMENTS_BAD;
 
1166
  }
 
1167
 
 
1168
  if( (NSSCKFWObject *)NULL != encryptionKey ) {
 
1169
    error = nssCKFWObject_verifyPointer(encryptionKey);
 
1170
    if( CKR_OK != error ) {
 
1171
      return error;
 
1172
    }
 
1173
  }
 
1174
 
 
1175
  if( (NSSCKFWObject *)NULL != authenticationKey ) {
 
1176
    error = nssCKFWObject_verifyPointer(authenticationKey);
 
1177
    if( CKR_OK != error ) {
 
1178
      return error;
 
1179
    }
 
1180
  }
 
1181
 
 
1182
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
1183
    return CKR_GENERAL_ERROR;
 
1184
  }
 
1185
#endif /* NSSDEBUG */
 
1186
 
 
1187
  ulBuffer = (CK_ULONG *)state->data;
 
1188
  if( 0x43b4657 != ulBuffer[0] ) {
 
1189
    return CKR_SAVED_STATE_INVALID;
 
1190
  }
 
1191
  n = (state->size / sizeof(CK_ULONG)) - 2;
 
1192
  x = (CK_ULONG)0;
 
1193
  for( i = 0; i < n; i++ ) {
 
1194
    x ^= ulBuffer[2+i];
 
1195
  }
 
1196
 
 
1197
  if( x != ulBuffer[1] ) {
 
1198
    return CKR_SAVED_STATE_INVALID;
 
1199
  }
 
1200
 
 
1201
  if( (void *)NULL == (void *)fwSession->mdSession->SetOperationState ) {
 
1202
    return CKR_GENERAL_ERROR;
 
1203
  }
 
1204
 
 
1205
  s.size = state->size - 2*sizeof(CK_ULONG);
 
1206
  s.data = (void *)&ulBuffer[2];
 
1207
 
 
1208
  if( (NSSCKFWObject *)NULL != encryptionKey ) {
 
1209
    mdek = nssCKFWObject_GetMDObject(encryptionKey);
 
1210
  } else {
 
1211
    mdek = (NSSCKMDObject *)NULL;
 
1212
  }
 
1213
 
 
1214
  if( (NSSCKFWObject *)NULL != authenticationKey ) {
 
1215
    mdak = nssCKFWObject_GetMDObject(authenticationKey);
 
1216
  } else {
 
1217
    mdak = (NSSCKMDObject *)NULL;
 
1218
  }
 
1219
 
 
1220
  error = fwSession->mdSession->SetOperationState(fwSession->mdSession, 
 
1221
    fwSession, fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
 
1222
    fwSession->fwInstance, &s, mdek, encryptionKey, mdak, authenticationKey);
 
1223
 
 
1224
  if( CKR_OK != error ) {
 
1225
    return error;
 
1226
  }
 
1227
 
 
1228
  /*
 
1229
   * Here'd we restore any session data
 
1230
   */
 
1231
  
 
1232
  return CKR_OK;
 
1233
}
 
1234
 
 
1235
static CK_BBOOL
 
1236
nss_attributes_form_token_object
 
1237
(
 
1238
  CK_ATTRIBUTE_PTR pTemplate,
 
1239
  CK_ULONG ulAttributeCount
 
1240
)
 
1241
{
 
1242
  CK_ULONG i;
 
1243
  CK_BBOOL rv;
 
1244
 
 
1245
  for( i = 0; i < ulAttributeCount; i++ ) {
 
1246
    if( CKA_TOKEN == pTemplate[i].type ) {
 
1247
      /* If we sanity-check, we can remove this sizeof check */
 
1248
      if( sizeof(CK_BBOOL) == pTemplate[i].ulValueLen ) {
 
1249
        (void)nsslibc_memcpy(&rv, pTemplate[i].pValue, sizeof(CK_BBOOL));
 
1250
        return rv;
 
1251
      } else {
 
1252
        return CK_FALSE;
 
1253
      }
 
1254
    }
 
1255
  }
 
1256
 
 
1257
  return CK_FALSE;
 
1258
}
 
1259
 
 
1260
/*
 
1261
 * nssCKFWSession_CreateObject
 
1262
 *
 
1263
 */
 
1264
NSS_IMPLEMENT NSSCKFWObject *
 
1265
nssCKFWSession_CreateObject
 
1266
(
 
1267
  NSSCKFWSession *fwSession,
 
1268
  CK_ATTRIBUTE_PTR pTemplate,
 
1269
  CK_ULONG ulAttributeCount,
 
1270
  CK_RV *pError
 
1271
)
 
1272
{
 
1273
  NSSArena *arena;
 
1274
  NSSCKMDObject *mdObject;
 
1275
  NSSCKFWObject *fwObject;
 
1276
  CK_BBOOL isTokenObject;
 
1277
 
 
1278
#ifdef NSSDEBUG
 
1279
  if( (CK_RV *)NULL == pError ) {
 
1280
    return (NSSCKFWObject *)NULL;
 
1281
  }
 
1282
 
 
1283
  *pError = nssCKFWSession_verifyPointer(fwSession);
 
1284
  if( CKR_OK != pError ) {
 
1285
    return (NSSCKFWObject *)NULL;
 
1286
  }
 
1287
 
 
1288
  if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
 
1289
    *pError = CKR_ARGUMENTS_BAD;
 
1290
    return (NSSCKFWObject *)NULL;
 
1291
  }
 
1292
 
 
1293
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
1294
    *pError = CKR_GENERAL_ERROR;
 
1295
    return (NSSCKFWObject *)NULL;
 
1296
  }
 
1297
#endif /* NSSDEBUG */
 
1298
 
 
1299
  /*
 
1300
   * Here would be an excellent place to sanity-check the object.
 
1301
   */
 
1302
 
 
1303
  isTokenObject = nss_attributes_form_token_object(pTemplate, ulAttributeCount);
 
1304
  if( CK_TRUE == isTokenObject ) {
 
1305
    /* === TOKEN OBJECT === */
 
1306
 
 
1307
    if( (void *)NULL == (void *)fwSession->mdSession->CreateObject ) {
 
1308
      *pError = CKR_TOKEN_WRITE_PROTECTED;
 
1309
      return (NSSCKFWObject *)NULL;
 
1310
    }
 
1311
 
 
1312
    arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
 
1313
    if( (NSSArena *)NULL == arena ) {
 
1314
      if( CKR_OK == *pError ) {
 
1315
        *pError = CKR_GENERAL_ERROR;
 
1316
      }
 
1317
      return (NSSCKFWObject *)NULL;
 
1318
    }
 
1319
 
 
1320
    goto callmdcreateobject;
 
1321
  } else {
 
1322
    /* === SESSION OBJECT === */
 
1323
 
 
1324
    arena = nssCKFWSession_GetArena(fwSession, pError);
 
1325
    if( (NSSArena *)NULL == arena ) {
 
1326
      if( CKR_OK == *pError ) {
 
1327
        *pError = CKR_GENERAL_ERROR;
 
1328
      }
 
1329
      return (NSSCKFWObject *)NULL;
 
1330
    }
 
1331
 
 
1332
    if( CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
 
1333
                     fwSession->fwInstance) ) {
 
1334
      /* --- module handles the session object -- */
 
1335
 
 
1336
      if( (void *)NULL == (void *)fwSession->mdSession->CreateObject ) {
 
1337
        *pError = CKR_GENERAL_ERROR;
 
1338
        return (NSSCKFWObject *)NULL;
 
1339
      }
 
1340
      
 
1341
      goto callmdcreateobject;
 
1342
    } else {
 
1343
      /* --- framework handles the session object -- */
 
1344
      mdObject = nssCKMDSessionObject_Create(fwSession->fwToken, 
 
1345
        arena, pTemplate, ulAttributeCount, pError);
 
1346
      goto gotmdobject;
 
1347
    }
 
1348
  }
 
1349
 
 
1350
 callmdcreateobject:
 
1351
  mdObject = fwSession->mdSession->CreateObject(fwSession->mdSession,
 
1352
    fwSession, fwSession->mdToken, fwSession->fwToken,
 
1353
    fwSession->mdInstance, fwSession->fwInstance, arena, pTemplate,
 
1354
    ulAttributeCount, pError);
 
1355
 
 
1356
 gotmdobject:
 
1357
  if( (NSSCKMDObject *)NULL == mdObject ) {
 
1358
    if( CKR_OK == *pError ) {
 
1359
      *pError = CKR_GENERAL_ERROR;
 
1360
    }
 
1361
    return (NSSCKFWObject *)NULL;
 
1362
  }
 
1363
 
 
1364
  fwObject = nssCKFWObject_Create(arena, mdObject, fwSession, 
 
1365
    fwSession->fwToken, fwSession->fwInstance, pError);
 
1366
  if( (NSSCKFWObject *)NULL == fwObject ) {
 
1367
    if( CKR_OK == *pError ) {
 
1368
      *pError = CKR_GENERAL_ERROR;
 
1369
    }
 
1370
    
 
1371
    if( (void *)NULL != (void *)mdObject->Destroy ) {
 
1372
      (void)mdObject->Destroy(mdObject, (NSSCKFWObject *)NULL,
 
1373
        fwSession->mdSession, fwSession, fwSession->mdToken,
 
1374
        fwSession->fwToken, fwSession->mdInstance, fwSession->fwInstance);
 
1375
    }
 
1376
    
 
1377
    return (NSSCKFWObject *)NULL;
 
1378
  }
 
1379
 
 
1380
  if( CK_FALSE == isTokenObject ) {
 
1381
    if( CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, fwObject) ) {
 
1382
      *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, fwObject, fwObject);
 
1383
      if( CKR_OK != *pError ) {
 
1384
        nssCKFWObject_Finalize(fwObject);
 
1385
        return (NSSCKFWObject *)NULL;
 
1386
      }
 
1387
    }
 
1388
  }
 
1389
  
 
1390
  return fwObject;
 
1391
}
 
1392
 
 
1393
/*
 
1394
 * nssCKFWSession_CopyObject
 
1395
 *
 
1396
 */
 
1397
NSS_IMPLEMENT NSSCKFWObject *
 
1398
nssCKFWSession_CopyObject
 
1399
(
 
1400
  NSSCKFWSession *fwSession,
 
1401
  NSSCKFWObject *fwObject,
 
1402
  CK_ATTRIBUTE_PTR pTemplate,
 
1403
  CK_ULONG ulAttributeCount,
 
1404
  CK_RV *pError
 
1405
)
 
1406
{
 
1407
  CK_BBOOL oldIsToken;
 
1408
  CK_BBOOL newIsToken;
 
1409
  CK_ULONG i;
 
1410
  NSSCKFWObject *rv;
 
1411
 
 
1412
#ifdef NSSDEBUG
 
1413
  if( (CK_RV *)NULL == pError ) {
 
1414
    return (NSSCKFWObject *)NULL;
 
1415
  }
 
1416
 
 
1417
  *pError = nssCKFWSession_verifyPointer(fwSession);
 
1418
  if( CKR_OK != *pError ) {
 
1419
    return (NSSCKFWObject *)NULL;
 
1420
  }
 
1421
 
 
1422
  *pError = nssCKFWObject_verifyPointer(fwObject);
 
1423
  if( CKR_OK != *pError ) {
 
1424
    return (NSSCKFWObject *)NULL;
 
1425
  }
 
1426
 
 
1427
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
1428
    *pError = CKR_GENERAL_ERROR;
 
1429
    return (NSSCKFWObject *)NULL;
 
1430
  }
 
1431
#endif /* NSSDEBUG */
 
1432
 
 
1433
  /*
 
1434
   * Sanity-check object
 
1435
   */
 
1436
 
 
1437
  oldIsToken = nssCKFWObject_IsTokenObject(fwObject);
 
1438
 
 
1439
  newIsToken = oldIsToken;
 
1440
  for( i = 0; i < ulAttributeCount; i++ ) {
 
1441
    if( CKA_TOKEN == pTemplate[i].type ) {
 
1442
      /* Since we sanity-checked the object, we know this is the right size. */
 
1443
      (void)nsslibc_memcpy(&newIsToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
 
1444
      break;
 
1445
    }
 
1446
  }
 
1447
 
 
1448
  /*
 
1449
   * If the Module handles its session objects, or if both the new
 
1450
   * and old object are token objects, use CopyObject if it exists.
 
1451
   */
 
1452
 
 
1453
  if( ((void *)NULL != (void *)fwSession->mdSession->CopyObject) &&
 
1454
      (((CK_TRUE == oldIsToken) && (CK_TRUE == newIsToken)) ||
 
1455
       (CK_TRUE == nssCKFWInstance_GetModuleHandlesSessionObjects(
 
1456
                     fwSession->fwInstance))) ) {
 
1457
    /* use copy object */
 
1458
    NSSArena *arena;
 
1459
    NSSCKMDObject *mdOldObject;
 
1460
    NSSCKMDObject *mdObject;
 
1461
 
 
1462
    mdOldObject = nssCKFWObject_GetMDObject(fwObject);
 
1463
 
 
1464
    if( CK_TRUE == newIsToken ) {
 
1465
      arena = nssCKFWToken_GetArena(fwSession->fwToken, pError);
 
1466
    } else {
 
1467
      arena = nssCKFWSession_GetArena(fwSession, pError);
 
1468
    }
 
1469
    if( (NSSArena *)NULL == arena ) {
 
1470
      if( CKR_OK == *pError ) {
 
1471
        *pError = CKR_GENERAL_ERROR;
 
1472
      }
 
1473
      return (NSSCKFWObject *)NULL;
 
1474
    }
 
1475
 
 
1476
    mdObject = fwSession->mdSession->CopyObject(fwSession->mdSession,
 
1477
      fwSession, fwSession->mdToken, fwSession->fwToken,
 
1478
      fwSession->mdInstance, fwSession->fwInstance, mdOldObject,
 
1479
      fwObject, arena, pTemplate, ulAttributeCount, pError);
 
1480
    if( (NSSCKMDObject *)NULL == mdObject ) {
 
1481
      if( CKR_OK == *pError ) {
 
1482
        *pError = CKR_GENERAL_ERROR;
 
1483
      }
 
1484
      return (NSSCKFWObject *)NULL;
 
1485
    }
 
1486
 
 
1487
    rv = nssCKFWObject_Create(arena, mdObject, fwSession,
 
1488
      fwSession->fwToken, fwSession->fwInstance, pError);
 
1489
    if( (NSSCKFWObject *)NULL == fwObject ) {
 
1490
      if( CKR_OK == *pError ) {
 
1491
        *pError = CKR_GENERAL_ERROR;
 
1492
      }
 
1493
 
 
1494
      if( (void *)NULL != (void *)mdObject->Destroy ) {
 
1495
        (void)mdObject->Destroy(mdObject, (NSSCKFWObject *)NULL,
 
1496
          fwSession->mdSession, fwSession, fwSession->mdToken,
 
1497
          fwSession->fwToken, fwSession->mdInstance, fwSession->fwInstance);
 
1498
      }
 
1499
    
 
1500
      return (NSSCKFWObject *)NULL;
 
1501
    }
 
1502
 
 
1503
    if( CK_FALSE == newIsToken ) {
 
1504
      if( CK_FALSE == nssCKFWHash_Exists(fwSession->sessionObjectHash, rv) ) {
 
1505
        *pError = nssCKFWHash_Add(fwSession->sessionObjectHash, rv, rv);
 
1506
        if( CKR_OK != *pError ) {
 
1507
          nssCKFWObject_Finalize(rv);
 
1508
          return (NSSCKFWObject *)NULL;
 
1509
        }
 
1510
      }
 
1511
    }
 
1512
 
 
1513
    return rv;
 
1514
  } else {
 
1515
    /* use create object */
 
1516
    NSSArena *tmpArena;
 
1517
    CK_ATTRIBUTE_PTR newTemplate;
 
1518
    CK_ULONG i, j, n, newLength, k;
 
1519
    CK_ATTRIBUTE_TYPE_PTR oldTypes;
 
1520
    NSSCKFWObject *rv;
 
1521
    
 
1522
    tmpArena = NSSArena_Create();
 
1523
    if( (NSSArena *)NULL == tmpArena ) {
 
1524
      *pError = CKR_HOST_MEMORY;
 
1525
      return (NSSCKFWObject *)NULL;
 
1526
    }
 
1527
 
 
1528
    n = nssCKFWObject_GetAttributeCount(fwObject, pError);
 
1529
    if( (0 == n) && (CKR_OK != *pError) ) {
 
1530
      return (NSSCKFWObject *)NULL;
 
1531
    }
 
1532
 
 
1533
    oldTypes = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE_TYPE, n);
 
1534
    if( (CK_ATTRIBUTE_TYPE_PTR)NULL == oldTypes ) {
 
1535
      NSSArena_Destroy(tmpArena);
 
1536
      *pError = CKR_HOST_MEMORY;
 
1537
      return (NSSCKFWObject *)NULL;
 
1538
    }
 
1539
 
 
1540
    *pError = nssCKFWObject_GetAttributeTypes(fwObject, oldTypes, n);
 
1541
    if( CKR_OK != *pError ) {
 
1542
      NSSArena_Destroy(tmpArena);
 
1543
      return (NSSCKFWObject *)NULL;
 
1544
    }
 
1545
 
 
1546
    newLength = n;
 
1547
    for( i = 0; i < ulAttributeCount; i++ ) {
 
1548
      for( j = 0; j < n; j++ ) {
 
1549
        if( oldTypes[j] == pTemplate[i].type ) {
 
1550
          if( (CK_VOID_PTR)NULL == pTemplate[i].pValue ) {
 
1551
            /* Removing the attribute */
 
1552
            newLength--;
 
1553
          }
 
1554
          break;
 
1555
        }
 
1556
      }
 
1557
      if( j == n ) {
 
1558
        /* Not found */
 
1559
        newLength++;
 
1560
      }
 
1561
    }
 
1562
 
 
1563
    newTemplate = nss_ZNEWARRAY(tmpArena, CK_ATTRIBUTE, newLength);
 
1564
    if( (CK_ATTRIBUTE_PTR)NULL == newTemplate ) {
 
1565
      NSSArena_Destroy(tmpArena);
 
1566
      *pError = CKR_HOST_MEMORY;
 
1567
      return (NSSCKFWObject *)NULL;
 
1568
    }
 
1569
 
 
1570
    k = 0;
 
1571
    for( j = 0; j < n; j++ ) {
 
1572
      for( i = 0; i < ulAttributeCount; i++ ) {
 
1573
        if( oldTypes[j] == pTemplate[i].type ) {
 
1574
          if( (CK_VOID_PTR)NULL == pTemplate[i].pValue ) {
 
1575
            /* This attribute is being deleted */
 
1576
            ;
 
1577
          } else {
 
1578
            /* This attribute is being replaced */
 
1579
            newTemplate[k].type = pTemplate[i].type;
 
1580
            newTemplate[k].pValue = pTemplate[i].pValue;
 
1581
            newTemplate[k].ulValueLen = pTemplate[i].ulValueLen;
 
1582
            k++;
 
1583
          }
 
1584
          break;
 
1585
        }
 
1586
      }
 
1587
      if( i == ulAttributeCount ) {
 
1588
        /* This attribute is being copied over from the old object */
 
1589
        NSSItem item, *it;
 
1590
        item.size = 0;
 
1591
        item.data = (void *)NULL;
 
1592
        it = nssCKFWObject_GetAttribute(fwObject, oldTypes[j],
 
1593
          &item, tmpArena, pError);
 
1594
        if( (NSSItem *)NULL == it ) {
 
1595
          if( CKR_OK == *pError ) {
 
1596
            *pError = CKR_GENERAL_ERROR;
 
1597
          }
 
1598
          NSSArena_Destroy(tmpArena);
 
1599
          return (NSSCKFWObject *)NULL;
 
1600
        }
 
1601
        newTemplate[k].type = oldTypes[j];
 
1602
        newTemplate[k].pValue = it->data;
 
1603
        newTemplate[k].ulValueLen = it->size;
 
1604
        k++;
 
1605
      }
 
1606
    }
 
1607
    /* assert that k == newLength */
 
1608
 
 
1609
    rv = nssCKFWSession_CreateObject(fwSession, newTemplate, newLength, pError);
 
1610
    if( (NSSCKFWObject *)NULL == rv ) {
 
1611
      if( CKR_OK == *pError ) {
 
1612
        *pError = CKR_GENERAL_ERROR;
 
1613
      }
 
1614
      NSSArena_Destroy(tmpArena);
 
1615
      return (NSSCKFWObject *)NULL;
 
1616
    }
 
1617
 
 
1618
    NSSArena_Destroy(tmpArena);
 
1619
    return rv;
 
1620
  }
 
1621
}
 
1622
 
 
1623
/*
 
1624
 * nssCKFWSession_FindObjectsInit
 
1625
 *
 
1626
 */
 
1627
NSS_IMPLEMENT NSSCKFWFindObjects *
 
1628
nssCKFWSession_FindObjectsInit
 
1629
(
 
1630
  NSSCKFWSession *fwSession,
 
1631
  CK_ATTRIBUTE_PTR pTemplate,
 
1632
  CK_ULONG ulAttributeCount,
 
1633
  CK_RV *pError
 
1634
)
 
1635
{
 
1636
  NSSCKMDFindObjects *mdfo1 = (NSSCKMDFindObjects *)NULL;
 
1637
  NSSCKMDFindObjects *mdfo2 = (NSSCKMDFindObjects *)NULL;
 
1638
 
 
1639
#ifdef NSSDEBUG
 
1640
  if( (CK_RV *)NULL == pError ) {
 
1641
    return (NSSCKFWFindObjects *)NULL;
 
1642
  }
 
1643
 
 
1644
  *pError = nssCKFWSession_verifyPointer(fwSession);
 
1645
  if( CKR_OK != *pError ) {
 
1646
    return (NSSCKFWFindObjects *)NULL;
 
1647
  }
 
1648
 
 
1649
  if( ((CK_ATTRIBUTE_PTR)NULL == pTemplate) && (ulAttributeCount != 0) ) {
 
1650
    *pError = CKR_ARGUMENTS_BAD;
 
1651
    return (NSSCKFWFindObjects *)NULL;
 
1652
  }
 
1653
 
 
1654
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
1655
    *pError = CKR_GENERAL_ERROR;
 
1656
    return (NSSCKFWFindObjects *)NULL;
 
1657
  }
 
1658
#endif /* NSSDEBUG */
 
1659
 
 
1660
  if( CK_TRUE != nssCKFWInstance_GetModuleHandlesSessionObjects(
 
1661
                   fwSession->fwInstance) ) {
 
1662
    CK_ULONG i;
 
1663
 
 
1664
    /*
 
1665
     * Does the search criteria restrict us to token or session
 
1666
     * objects?
 
1667
     */
 
1668
 
 
1669
    for( i = 0; i < ulAttributeCount; i++ ) {
 
1670
      if( CKA_TOKEN == pTemplate[i].type ) {
 
1671
        /* Yes, it does. */
 
1672
        CK_BBOOL isToken;
 
1673
        if( sizeof(CK_BBOOL) != pTemplate[i].ulValueLen ) {
 
1674
          *pError = CKR_ATTRIBUTE_VALUE_INVALID;
 
1675
          return (NSSCKFWFindObjects *)NULL;
 
1676
        }
 
1677
        (void)nsslibc_memcpy(&isToken, pTemplate[i].pValue, sizeof(CK_BBOOL));
 
1678
 
 
1679
        if( CK_TRUE == isToken ) {
 
1680
          /* Pass it on to the module's search routine */
 
1681
          if( (void *)NULL == (void *)fwSession->mdSession->FindObjectsInit ) {
 
1682
            goto wrap;
 
1683
          }
 
1684
 
 
1685
          mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
 
1686
                    fwSession, fwSession->mdToken, fwSession->fwToken,
 
1687
                    fwSession->mdInstance, fwSession->fwInstance, 
 
1688
                    pTemplate, ulAttributeCount, pError);
 
1689
        } else {
 
1690
          /* Do the search ourselves */
 
1691
          mdfo1 = nssCKMDFindSessionObjects_Create(fwSession->fwToken, 
 
1692
                    pTemplate, ulAttributeCount, pError);
 
1693
        }
 
1694
 
 
1695
        if( (NSSCKMDFindObjects *)NULL == mdfo1 ) {
 
1696
          if( CKR_OK == *pError ) {
 
1697
            *pError = CKR_GENERAL_ERROR;
 
1698
          }
 
1699
          return (NSSCKFWFindObjects *)NULL;
 
1700
        }
 
1701
        
 
1702
        goto wrap;
 
1703
      }
 
1704
    }
 
1705
 
 
1706
    if( i == ulAttributeCount ) {
 
1707
      /* No, it doesn't.  Do a hybrid search. */
 
1708
      mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
 
1709
                fwSession, fwSession->mdToken, fwSession->fwToken,
 
1710
                fwSession->mdInstance, fwSession->fwInstance, 
 
1711
                pTemplate, ulAttributeCount, pError);
 
1712
 
 
1713
      if( (NSSCKMDFindObjects *)NULL == mdfo1 ) {
 
1714
        if( CKR_OK == *pError ) {
 
1715
          *pError = CKR_GENERAL_ERROR;
 
1716
        }
 
1717
        return (NSSCKFWFindObjects *)NULL;
 
1718
      }
 
1719
 
 
1720
      mdfo2 = nssCKMDFindSessionObjects_Create(fwSession->fwToken,
 
1721
                pTemplate, ulAttributeCount, pError);
 
1722
      if( (NSSCKMDFindObjects *)NULL == mdfo2 ) {
 
1723
        if( CKR_OK == *pError ) {
 
1724
          *pError = CKR_GENERAL_ERROR;
 
1725
        }
 
1726
        if( (void *)NULL != (void *)mdfo1->Final ) {
 
1727
          mdfo1->Final(mdfo1, (NSSCKFWFindObjects *)NULL, fwSession->mdSession,
 
1728
            fwSession, fwSession->mdToken, fwSession->fwToken, 
 
1729
            fwSession->mdInstance, fwSession->fwInstance);
 
1730
        }
 
1731
        return (NSSCKFWFindObjects *)NULL;
 
1732
      }
 
1733
 
 
1734
      goto wrap;
 
1735
    }
 
1736
    /*NOTREACHED*/
 
1737
  } else {
 
1738
    /* Module handles all its own objects.  Pass on to module's search */
 
1739
    mdfo1 = fwSession->mdSession->FindObjectsInit(fwSession->mdSession,
 
1740
              fwSession, fwSession->mdToken, fwSession->fwToken,
 
1741
              fwSession->mdInstance, fwSession->fwInstance, 
 
1742
              pTemplate, ulAttributeCount, pError);
 
1743
 
 
1744
    if( (NSSCKMDFindObjects *)NULL == mdfo1 ) {
 
1745
      if( CKR_OK == *pError ) {
 
1746
        *pError = CKR_GENERAL_ERROR;
 
1747
      }
 
1748
      return (NSSCKFWFindObjects *)NULL;
 
1749
    }
 
1750
 
 
1751
    goto wrap;
 
1752
  }
 
1753
 
 
1754
 wrap:
 
1755
  return nssCKFWFindObjects_Create(fwSession, fwSession->fwToken,
 
1756
           fwSession->fwInstance, mdfo1, mdfo2, pError);
 
1757
}
 
1758
 
 
1759
/*
 
1760
 * nssCKFWSession_SeedRandom
 
1761
 *
 
1762
 */
 
1763
NSS_IMPLEMENT CK_RV
 
1764
nssCKFWSession_SeedRandom
 
1765
(
 
1766
  NSSCKFWSession *fwSession,
 
1767
  NSSItem *seed
 
1768
)
 
1769
{
 
1770
  CK_RV error = CKR_OK;
 
1771
 
 
1772
#ifdef NSSDEBUG
 
1773
  error = nssCKFWSession_verifyPointer(fwSession);
 
1774
  if( CKR_OK != error ) {
 
1775
    return error;
 
1776
  }
 
1777
 
 
1778
  if( (NSSItem *)NULL == seed ) {
 
1779
    return CKR_ARGUMENTS_BAD;
 
1780
  }
 
1781
 
 
1782
  if( (void *)NULL == seed->data ) {
 
1783
    return CKR_ARGUMENTS_BAD;
 
1784
  }
 
1785
 
 
1786
  if( 0 == seed->size ) {
 
1787
    return CKR_ARGUMENTS_BAD;
 
1788
  }
 
1789
 
 
1790
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
1791
    return CKR_GENERAL_ERROR;
 
1792
  }
 
1793
#endif /* NSSDEBUG */
 
1794
 
 
1795
  if( (void *)NULL == (void *)fwSession->mdSession->SeedRandom ) {
 
1796
    return CKR_RANDOM_SEED_NOT_SUPPORTED;
 
1797
  }
 
1798
 
 
1799
  error = fwSession->mdSession->SeedRandom(fwSession->mdSession, fwSession,
 
1800
    fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
 
1801
    fwSession->fwInstance, seed);
 
1802
 
 
1803
  return error;
 
1804
}
 
1805
 
 
1806
/*
 
1807
 * nssCKFWSession_GetRandom
 
1808
 *
 
1809
 */
 
1810
NSS_IMPLEMENT CK_RV
 
1811
nssCKFWSession_GetRandom
 
1812
(
 
1813
  NSSCKFWSession *fwSession,
 
1814
  NSSItem *buffer
 
1815
)
 
1816
{
 
1817
  CK_RV error = CKR_OK;
 
1818
 
 
1819
#ifdef NSSDEBUG
 
1820
  error = nssCKFWSession_verifyPointer(fwSession);
 
1821
  if( CKR_OK != error ) {
 
1822
    return error;
 
1823
  }
 
1824
 
 
1825
  if( (NSSItem *)NULL == buffer ) {
 
1826
    return CKR_ARGUMENTS_BAD;
 
1827
  }
 
1828
 
 
1829
  if( (void *)NULL == buffer->data ) {
 
1830
    return CKR_ARGUMENTS_BAD;
 
1831
  }
 
1832
 
 
1833
  if( (NSSCKMDSession *)NULL == fwSession->mdSession ) {
 
1834
    return CKR_GENERAL_ERROR;
 
1835
  }
 
1836
#endif /* NSSDEBUG */
 
1837
 
 
1838
  if( (void *)NULL == (void *)fwSession->mdSession->GetRandom ) {
 
1839
    if( CK_TRUE == nssCKFWToken_GetHasRNG(fwSession->fwToken) ) {
 
1840
      return CKR_GENERAL_ERROR;
 
1841
    } else {
 
1842
      return CKR_RANDOM_NO_RNG;
 
1843
    }
 
1844
  }
 
1845
 
 
1846
  if( 0 == buffer->size ) {
 
1847
    return CKR_OK;
 
1848
  }
 
1849
 
 
1850
  error = fwSession->mdSession->GetRandom(fwSession->mdSession, fwSession,
 
1851
    fwSession->mdToken, fwSession->fwToken, fwSession->mdInstance,
 
1852
    fwSession->fwInstance, buffer);
 
1853
 
 
1854
  return error;
 
1855
}
 
1856
 
 
1857
/*
 
1858
 * NSSCKFWSession_GetMDSession
 
1859
 *
 
1860
 */
 
1861
 
 
1862
NSS_IMPLEMENT NSSCKMDSession *
 
1863
NSSCKFWSession_GetMDSession
 
1864
(
 
1865
  NSSCKFWSession *fwSession
 
1866
)
 
1867
{
 
1868
#ifdef DEBUG
 
1869
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
1870
    return (NSSCKMDSession *)NULL;
 
1871
  }
 
1872
#endif /* DEBUG */
 
1873
 
 
1874
  return nssCKFWSession_GetMDSession(fwSession);
 
1875
}
 
1876
 
 
1877
/*
 
1878
 * NSSCKFWSession_GetArena
 
1879
 *
 
1880
 */
 
1881
 
 
1882
NSS_IMPLEMENT NSSArena *
 
1883
NSSCKFWSession_GetArena
 
1884
(
 
1885
  NSSCKFWSession *fwSession,
 
1886
  CK_RV *pError
 
1887
)
 
1888
{
 
1889
#ifdef DEBUG
 
1890
  if( (CK_RV *)NULL == pError ) {
 
1891
    return (NSSArena *)NULL;
 
1892
  }
 
1893
 
 
1894
  *pError = nssCKFWSession_verifyPointer(fwSession);
 
1895
  if( CKR_OK != *pError ) {
 
1896
    return (NSSArena *)NULL;
 
1897
  }
 
1898
#endif /* DEBUG */
 
1899
 
 
1900
  return nssCKFWSession_GetArena(fwSession, pError);
 
1901
}
 
1902
 
 
1903
/*
 
1904
 * NSSCKFWSession_CallNotification
 
1905
 *
 
1906
 */
 
1907
 
 
1908
NSS_IMPLEMENT CK_RV
 
1909
NSSCKFWSession_CallNotification
 
1910
(
 
1911
  NSSCKFWSession *fwSession,
 
1912
  CK_NOTIFICATION event
 
1913
)
 
1914
{
 
1915
#ifdef DEBUG
 
1916
  CK_RV error = CKR_OK;
 
1917
 
 
1918
  error = nssCKFWSession_verifyPointer(fwSession);
 
1919
  if( CKR_OK != error ) {
 
1920
    return error;
 
1921
  }
 
1922
#endif /* DEBUG */
 
1923
 
 
1924
  return nssCKFWSession_CallNotification(fwSession, event);
 
1925
}
 
1926
 
 
1927
/*
 
1928
 * NSSCKFWSession_IsRWSession
 
1929
 *
 
1930
 */
 
1931
 
 
1932
NSS_IMPLEMENT CK_BBOOL
 
1933
NSSCKFWSession_IsRWSession
 
1934
(
 
1935
  NSSCKFWSession *fwSession
 
1936
)
 
1937
{
 
1938
#ifdef DEBUG
 
1939
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
1940
    return CK_FALSE;
 
1941
  }
 
1942
#endif /* DEBUG */
 
1943
 
 
1944
  return nssCKFWSession_IsRWSession(fwSession);
 
1945
}
 
1946
 
 
1947
/*
 
1948
 * NSSCKFWSession_IsSO
 
1949
 *
 
1950
 */
 
1951
 
 
1952
NSS_IMPLEMENT CK_BBOOL
 
1953
NSSCKFWSession_IsSO
 
1954
(
 
1955
  NSSCKFWSession *fwSession
 
1956
)
 
1957
{
 
1958
#ifdef DEBUG
 
1959
  if( CKR_OK != nssCKFWSession_verifyPointer(fwSession) ) {
 
1960
    return CK_FALSE;
 
1961
  }
 
1962
#endif /* DEBUG */
 
1963
 
 
1964
  return nssCKFWSession_IsSO(fwSession);
 
1965
}