security/nss/lib/ckfw/session.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial