security/nss/lib/ckfw/object.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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 * object.c
michael@0 7 *
michael@0 8 * This file implements the NSSCKFWObject 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 * NSSCKFWObject
michael@0 17 *
michael@0 18 * -- create/destroy --
michael@0 19 * nssCKFWObject_Create
michael@0 20 * nssCKFWObject_Finalize
michael@0 21 * nssCKFWObject_Destroy
michael@0 22 *
michael@0 23 * -- public accessors --
michael@0 24 * NSSCKFWObject_GetMDObject
michael@0 25 * NSSCKFWObject_GetArena
michael@0 26 * NSSCKFWObject_IsTokenObject
michael@0 27 * NSSCKFWObject_GetAttributeCount
michael@0 28 * NSSCKFWObject_GetAttributeTypes
michael@0 29 * NSSCKFWObject_GetAttributeSize
michael@0 30 * NSSCKFWObject_GetAttribute
michael@0 31 * NSSCKFWObject_SetAttribute
michael@0 32 * NSSCKFWObject_GetObjectSize
michael@0 33 *
michael@0 34 * -- implement public accessors --
michael@0 35 * nssCKFWObject_GetMDObject
michael@0 36 * nssCKFWObject_GetArena
michael@0 37 *
michael@0 38 * -- private accessors --
michael@0 39 * nssCKFWObject_SetHandle
michael@0 40 * nssCKFWObject_GetHandle
michael@0 41 *
michael@0 42 * -- module fronts --
michael@0 43 * nssCKFWObject_IsTokenObject
michael@0 44 * nssCKFWObject_GetAttributeCount
michael@0 45 * nssCKFWObject_GetAttributeTypes
michael@0 46 * nssCKFWObject_GetAttributeSize
michael@0 47 * nssCKFWObject_GetAttribute
michael@0 48 * nssCKFWObject_SetAttribute
michael@0 49 * nssCKFWObject_GetObjectSize
michael@0 50 */
michael@0 51
michael@0 52 struct NSSCKFWObjectStr {
michael@0 53 NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */
michael@0 54 NSSArena *arena;
michael@0 55 NSSCKMDObject *mdObject;
michael@0 56 NSSCKMDSession *mdSession;
michael@0 57 NSSCKFWSession *fwSession;
michael@0 58 NSSCKMDToken *mdToken;
michael@0 59 NSSCKFWToken *fwToken;
michael@0 60 NSSCKMDInstance *mdInstance;
michael@0 61 NSSCKFWInstance *fwInstance;
michael@0 62 CK_OBJECT_HANDLE hObject;
michael@0 63 };
michael@0 64
michael@0 65 #ifdef DEBUG
michael@0 66 /*
michael@0 67 * But first, the pointer-tracking stuff.
michael@0 68 *
michael@0 69 * NOTE: the pointer-tracking support in NSS/base currently relies
michael@0 70 * upon NSPR's CallOnce support. That, however, relies upon NSPR's
michael@0 71 * locking, which is tied into the runtime. We need a pointer-tracker
michael@0 72 * implementation that uses the locks supplied through C_Initialize.
michael@0 73 * That support, however, can be filled in later. So for now, I'll
michael@0 74 * just do this routines as no-ops.
michael@0 75 */
michael@0 76
michael@0 77 static CK_RV
michael@0 78 object_add_pointer
michael@0 79 (
michael@0 80 const NSSCKFWObject *fwObject
michael@0 81 )
michael@0 82 {
michael@0 83 return CKR_OK;
michael@0 84 }
michael@0 85
michael@0 86 static CK_RV
michael@0 87 object_remove_pointer
michael@0 88 (
michael@0 89 const NSSCKFWObject *fwObject
michael@0 90 )
michael@0 91 {
michael@0 92 return CKR_OK;
michael@0 93 }
michael@0 94
michael@0 95 NSS_IMPLEMENT CK_RV
michael@0 96 nssCKFWObject_verifyPointer
michael@0 97 (
michael@0 98 const NSSCKFWObject *fwObject
michael@0 99 )
michael@0 100 {
michael@0 101 return CKR_OK;
michael@0 102 }
michael@0 103
michael@0 104 #endif /* DEBUG */
michael@0 105
michael@0 106
michael@0 107 /*
michael@0 108 * nssCKFWObject_Create
michael@0 109 *
michael@0 110 */
michael@0 111 NSS_IMPLEMENT NSSCKFWObject *
michael@0 112 nssCKFWObject_Create
michael@0 113 (
michael@0 114 NSSArena *arena,
michael@0 115 NSSCKMDObject *mdObject,
michael@0 116 NSSCKFWSession *fwSession,
michael@0 117 NSSCKFWToken *fwToken,
michael@0 118 NSSCKFWInstance *fwInstance,
michael@0 119 CK_RV *pError
michael@0 120 )
michael@0 121 {
michael@0 122 NSSCKFWObject *fwObject;
michael@0 123 nssCKFWHash *mdObjectHash;
michael@0 124
michael@0 125 #ifdef NSSDEBUG
michael@0 126 if (!pError) {
michael@0 127 return (NSSCKFWObject *)NULL;
michael@0 128 }
michael@0 129
michael@0 130 if( PR_SUCCESS != nssArena_verifyPointer(arena) ) {
michael@0 131 *pError = CKR_ARGUMENTS_BAD;
michael@0 132 return (NSSCKFWObject *)NULL;
michael@0 133 }
michael@0 134 #endif /* NSSDEBUG */
michael@0 135
michael@0 136 if (!fwToken) {
michael@0 137 *pError = CKR_ARGUMENTS_BAD;
michael@0 138 return (NSSCKFWObject *)NULL;
michael@0 139 }
michael@0 140 mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken);
michael@0 141 if (!mdObjectHash) {
michael@0 142 *pError = CKR_GENERAL_ERROR;
michael@0 143 return (NSSCKFWObject *)NULL;
michael@0 144 }
michael@0 145
michael@0 146 if( nssCKFWHash_Exists(mdObjectHash, mdObject) ) {
michael@0 147 fwObject = nssCKFWHash_Lookup(mdObjectHash, mdObject);
michael@0 148 return fwObject;
michael@0 149 }
michael@0 150
michael@0 151 fwObject = nss_ZNEW(arena, NSSCKFWObject);
michael@0 152 if (!fwObject) {
michael@0 153 *pError = CKR_HOST_MEMORY;
michael@0 154 return (NSSCKFWObject *)NULL;
michael@0 155 }
michael@0 156
michael@0 157 fwObject->arena = arena;
michael@0 158 fwObject->mdObject = mdObject;
michael@0 159 fwObject->fwSession = fwSession;
michael@0 160
michael@0 161 if (fwSession) {
michael@0 162 fwObject->mdSession = nssCKFWSession_GetMDSession(fwSession);
michael@0 163 }
michael@0 164
michael@0 165 fwObject->fwToken = fwToken;
michael@0 166 fwObject->mdToken = nssCKFWToken_GetMDToken(fwToken);
michael@0 167 fwObject->fwInstance = fwInstance;
michael@0 168 fwObject->mdInstance = nssCKFWInstance_GetMDInstance(fwInstance);
michael@0 169 fwObject->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError);
michael@0 170 if (!fwObject->mutex) {
michael@0 171 if( CKR_OK == *pError ) {
michael@0 172 *pError = CKR_GENERAL_ERROR;
michael@0 173 }
michael@0 174 return (NSSCKFWObject *)NULL;
michael@0 175 }
michael@0 176
michael@0 177 *pError = nssCKFWHash_Add(mdObjectHash, mdObject, fwObject);
michael@0 178 if( CKR_OK != *pError ) {
michael@0 179 nss_ZFreeIf(fwObject);
michael@0 180 return (NSSCKFWObject *)NULL;
michael@0 181 }
michael@0 182
michael@0 183 #ifdef DEBUG
michael@0 184 *pError = object_add_pointer(fwObject);
michael@0 185 if( CKR_OK != *pError ) {
michael@0 186 nssCKFWHash_Remove(mdObjectHash, mdObject);
michael@0 187 nss_ZFreeIf(fwObject);
michael@0 188 return (NSSCKFWObject *)NULL;
michael@0 189 }
michael@0 190 #endif /* DEBUG */
michael@0 191
michael@0 192 *pError = CKR_OK;
michael@0 193 return fwObject;
michael@0 194 }
michael@0 195
michael@0 196 /*
michael@0 197 * nssCKFWObject_Finalize
michael@0 198 *
michael@0 199 */
michael@0 200 NSS_IMPLEMENT void
michael@0 201 nssCKFWObject_Finalize
michael@0 202 (
michael@0 203 NSSCKFWObject *fwObject,
michael@0 204 PRBool removeFromHash
michael@0 205 )
michael@0 206 {
michael@0 207 nssCKFWHash *mdObjectHash;
michael@0 208
michael@0 209 #ifdef NSSDEBUG
michael@0 210 if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
michael@0 211 return;
michael@0 212 }
michael@0 213 #endif /* NSSDEBUG */
michael@0 214
michael@0 215 (void)nssCKFWMutex_Destroy(fwObject->mutex);
michael@0 216
michael@0 217 if (fwObject->mdObject->Finalize) {
michael@0 218 fwObject->mdObject->Finalize(fwObject->mdObject, fwObject,
michael@0 219 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 220 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
michael@0 221 }
michael@0 222
michael@0 223 if (removeFromHash) {
michael@0 224 mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
michael@0 225 if (mdObjectHash) {
michael@0 226 nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
michael@0 227 }
michael@0 228 }
michael@0 229
michael@0 230 if (fwObject->fwSession) {
michael@0 231 nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
michael@0 232 }
michael@0 233 nss_ZFreeIf(fwObject);
michael@0 234
michael@0 235 #ifdef DEBUG
michael@0 236 (void)object_remove_pointer(fwObject);
michael@0 237 #endif /* DEBUG */
michael@0 238
michael@0 239 return;
michael@0 240 }
michael@0 241
michael@0 242 /*
michael@0 243 * nssCKFWObject_Destroy
michael@0 244 *
michael@0 245 */
michael@0 246 NSS_IMPLEMENT void
michael@0 247 nssCKFWObject_Destroy
michael@0 248 (
michael@0 249 NSSCKFWObject *fwObject
michael@0 250 )
michael@0 251 {
michael@0 252 nssCKFWHash *mdObjectHash;
michael@0 253
michael@0 254 #ifdef NSSDEBUG
michael@0 255 if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
michael@0 256 return;
michael@0 257 }
michael@0 258 #endif /* NSSDEBUG */
michael@0 259
michael@0 260 (void)nssCKFWMutex_Destroy(fwObject->mutex);
michael@0 261
michael@0 262 if (fwObject->mdObject->Destroy) {
michael@0 263 fwObject->mdObject->Destroy(fwObject->mdObject, fwObject,
michael@0 264 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 265 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
michael@0 266 }
michael@0 267
michael@0 268 mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken);
michael@0 269 if (mdObjectHash) {
michael@0 270 nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject);
michael@0 271 }
michael@0 272
michael@0 273 if (fwObject->fwSession) {
michael@0 274 nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
michael@0 275 }
michael@0 276 nss_ZFreeIf(fwObject);
michael@0 277
michael@0 278 #ifdef DEBUG
michael@0 279 (void)object_remove_pointer(fwObject);
michael@0 280 #endif /* DEBUG */
michael@0 281
michael@0 282 return;
michael@0 283 }
michael@0 284
michael@0 285 /*
michael@0 286 * nssCKFWObject_GetMDObject
michael@0 287 *
michael@0 288 */
michael@0 289 NSS_IMPLEMENT NSSCKMDObject *
michael@0 290 nssCKFWObject_GetMDObject
michael@0 291 (
michael@0 292 NSSCKFWObject *fwObject
michael@0 293 )
michael@0 294 {
michael@0 295 #ifdef NSSDEBUG
michael@0 296 if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
michael@0 297 return (NSSCKMDObject *)NULL;
michael@0 298 }
michael@0 299 #endif /* NSSDEBUG */
michael@0 300
michael@0 301 return fwObject->mdObject;
michael@0 302 }
michael@0 303
michael@0 304 /*
michael@0 305 * nssCKFWObject_GetArena
michael@0 306 *
michael@0 307 */
michael@0 308 NSS_IMPLEMENT NSSArena *
michael@0 309 nssCKFWObject_GetArena
michael@0 310 (
michael@0 311 NSSCKFWObject *fwObject,
michael@0 312 CK_RV *pError
michael@0 313 )
michael@0 314 {
michael@0 315 #ifdef NSSDEBUG
michael@0 316 if (!pError) {
michael@0 317 return (NSSArena *)NULL;
michael@0 318 }
michael@0 319
michael@0 320 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 321 if( CKR_OK != *pError ) {
michael@0 322 return (NSSArena *)NULL;
michael@0 323 }
michael@0 324 #endif /* NSSDEBUG */
michael@0 325
michael@0 326 return fwObject->arena;
michael@0 327 }
michael@0 328
michael@0 329 /*
michael@0 330 * nssCKFWObject_SetHandle
michael@0 331 *
michael@0 332 */
michael@0 333 NSS_IMPLEMENT CK_RV
michael@0 334 nssCKFWObject_SetHandle
michael@0 335 (
michael@0 336 NSSCKFWObject *fwObject,
michael@0 337 CK_OBJECT_HANDLE hObject
michael@0 338 )
michael@0 339 {
michael@0 340 #ifdef NSSDEBUG
michael@0 341 CK_RV error = CKR_OK;
michael@0 342 #endif /* NSSDEBUG */
michael@0 343
michael@0 344 #ifdef NSSDEBUG
michael@0 345 error = nssCKFWObject_verifyPointer(fwObject);
michael@0 346 if( CKR_OK != error ) {
michael@0 347 return error;
michael@0 348 }
michael@0 349 #endif /* NSSDEBUG */
michael@0 350
michael@0 351 if( (CK_OBJECT_HANDLE)0 != fwObject->hObject ) {
michael@0 352 return CKR_GENERAL_ERROR;
michael@0 353 }
michael@0 354
michael@0 355 fwObject->hObject = hObject;
michael@0 356
michael@0 357 return CKR_OK;
michael@0 358 }
michael@0 359
michael@0 360 /*
michael@0 361 * nssCKFWObject_GetHandle
michael@0 362 *
michael@0 363 */
michael@0 364 NSS_IMPLEMENT CK_OBJECT_HANDLE
michael@0 365 nssCKFWObject_GetHandle
michael@0 366 (
michael@0 367 NSSCKFWObject *fwObject
michael@0 368 )
michael@0 369 {
michael@0 370 #ifdef NSSDEBUG
michael@0 371 if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
michael@0 372 return (CK_OBJECT_HANDLE)0;
michael@0 373 }
michael@0 374 #endif /* NSSDEBUG */
michael@0 375
michael@0 376 return fwObject->hObject;
michael@0 377 }
michael@0 378
michael@0 379 /*
michael@0 380 * nssCKFWObject_IsTokenObject
michael@0 381 *
michael@0 382 */
michael@0 383 NSS_IMPLEMENT CK_BBOOL
michael@0 384 nssCKFWObject_IsTokenObject
michael@0 385 (
michael@0 386 NSSCKFWObject *fwObject
michael@0 387 )
michael@0 388 {
michael@0 389 CK_BBOOL b = CK_FALSE;
michael@0 390
michael@0 391 #ifdef NSSDEBUG
michael@0 392 if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
michael@0 393 return CK_FALSE;
michael@0 394 }
michael@0 395 #endif /* NSSDEBUG */
michael@0 396
michael@0 397 if (!fwObject->mdObject->IsTokenObject) {
michael@0 398 NSSItem item;
michael@0 399 NSSItem *pItem;
michael@0 400 CK_RV rv = CKR_OK;
michael@0 401
michael@0 402 item.data = (void *)&b;
michael@0 403 item.size = sizeof(b);
michael@0 404
michael@0 405 pItem = nssCKFWObject_GetAttribute(fwObject, CKA_TOKEN, &item,
michael@0 406 (NSSArena *)NULL, &rv);
michael@0 407 if (!pItem) {
michael@0 408 /* Error of some type */
michael@0 409 b = CK_FALSE;
michael@0 410 goto done;
michael@0 411 }
michael@0 412
michael@0 413 goto done;
michael@0 414 }
michael@0 415
michael@0 416 b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject,
michael@0 417 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 418 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance);
michael@0 419
michael@0 420 done:
michael@0 421 return b;
michael@0 422 }
michael@0 423
michael@0 424 /*
michael@0 425 * nssCKFWObject_GetAttributeCount
michael@0 426 *
michael@0 427 */
michael@0 428 NSS_IMPLEMENT CK_ULONG
michael@0 429 nssCKFWObject_GetAttributeCount
michael@0 430 (
michael@0 431 NSSCKFWObject *fwObject,
michael@0 432 CK_RV *pError
michael@0 433 )
michael@0 434 {
michael@0 435 CK_ULONG rv;
michael@0 436
michael@0 437 #ifdef NSSDEBUG
michael@0 438 if (!pError) {
michael@0 439 return (CK_ULONG)0;
michael@0 440 }
michael@0 441
michael@0 442 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 443 if( CKR_OK != *pError ) {
michael@0 444 return (CK_ULONG)0;
michael@0 445 }
michael@0 446 #endif /* NSSDEBUG */
michael@0 447
michael@0 448 if (!fwObject->mdObject->GetAttributeCount) {
michael@0 449 *pError = CKR_GENERAL_ERROR;
michael@0 450 return (CK_ULONG)0;
michael@0 451 }
michael@0 452
michael@0 453 *pError = nssCKFWMutex_Lock(fwObject->mutex);
michael@0 454 if( CKR_OK != *pError ) {
michael@0 455 return (CK_ULONG)0;
michael@0 456 }
michael@0 457
michael@0 458 rv = fwObject->mdObject->GetAttributeCount(fwObject->mdObject, fwObject,
michael@0 459 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 460 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
michael@0 461 pError);
michael@0 462
michael@0 463 (void)nssCKFWMutex_Unlock(fwObject->mutex);
michael@0 464 return rv;
michael@0 465 }
michael@0 466
michael@0 467 /*
michael@0 468 * nssCKFWObject_GetAttributeTypes
michael@0 469 *
michael@0 470 */
michael@0 471 NSS_IMPLEMENT CK_RV
michael@0 472 nssCKFWObject_GetAttributeTypes
michael@0 473 (
michael@0 474 NSSCKFWObject *fwObject,
michael@0 475 CK_ATTRIBUTE_TYPE_PTR typeArray,
michael@0 476 CK_ULONG ulCount
michael@0 477 )
michael@0 478 {
michael@0 479 CK_RV error = CKR_OK;
michael@0 480
michael@0 481 #ifdef NSSDEBUG
michael@0 482 error = nssCKFWObject_verifyPointer(fwObject);
michael@0 483 if( CKR_OK != error ) {
michael@0 484 return error;
michael@0 485 }
michael@0 486
michael@0 487 if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) {
michael@0 488 return CKR_ARGUMENTS_BAD;
michael@0 489 }
michael@0 490 #endif /* NSSDEBUG */
michael@0 491
michael@0 492 if (!fwObject->mdObject->GetAttributeTypes) {
michael@0 493 return CKR_GENERAL_ERROR;
michael@0 494 }
michael@0 495
michael@0 496 error = nssCKFWMutex_Lock(fwObject->mutex);
michael@0 497 if( CKR_OK != error ) {
michael@0 498 return error;
michael@0 499 }
michael@0 500
michael@0 501 error = fwObject->mdObject->GetAttributeTypes(fwObject->mdObject, fwObject,
michael@0 502 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 503 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
michael@0 504 typeArray, ulCount);
michael@0 505
michael@0 506 (void)nssCKFWMutex_Unlock(fwObject->mutex);
michael@0 507 return error;
michael@0 508 }
michael@0 509
michael@0 510 /*
michael@0 511 * nssCKFWObject_GetAttributeSize
michael@0 512 *
michael@0 513 */
michael@0 514 NSS_IMPLEMENT CK_ULONG
michael@0 515 nssCKFWObject_GetAttributeSize
michael@0 516 (
michael@0 517 NSSCKFWObject *fwObject,
michael@0 518 CK_ATTRIBUTE_TYPE attribute,
michael@0 519 CK_RV *pError
michael@0 520 )
michael@0 521 {
michael@0 522 CK_ULONG rv;
michael@0 523
michael@0 524 #ifdef NSSDEBUG
michael@0 525 if (!pError) {
michael@0 526 return (CK_ULONG)0;
michael@0 527 }
michael@0 528
michael@0 529 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 530 if( CKR_OK != *pError ) {
michael@0 531 return (CK_ULONG)0;
michael@0 532 }
michael@0 533 #endif /* NSSDEBUG */
michael@0 534
michael@0 535 if (!fwObject->mdObject->GetAttributeSize) {
michael@0 536 *pError = CKR_GENERAL_ERROR;
michael@0 537 return (CK_ULONG )0;
michael@0 538 }
michael@0 539
michael@0 540 *pError = nssCKFWMutex_Lock(fwObject->mutex);
michael@0 541 if( CKR_OK != *pError ) {
michael@0 542 return (CK_ULONG)0;
michael@0 543 }
michael@0 544
michael@0 545 rv = fwObject->mdObject->GetAttributeSize(fwObject->mdObject, fwObject,
michael@0 546 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 547 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
michael@0 548 attribute, pError);
michael@0 549
michael@0 550 (void)nssCKFWMutex_Unlock(fwObject->mutex);
michael@0 551 return rv;
michael@0 552 }
michael@0 553
michael@0 554 /*
michael@0 555 * nssCKFWObject_GetAttribute
michael@0 556 *
michael@0 557 * Usual NSS allocation rules:
michael@0 558 * If itemOpt is not NULL, it will be returned; otherwise an NSSItem
michael@0 559 * will be allocated. If itemOpt is not NULL but itemOpt->data is,
michael@0 560 * the buffer will be allocated; otherwise, the buffer will be used.
michael@0 561 * Any allocations will come from the optional arena, if one is
michael@0 562 * specified.
michael@0 563 */
michael@0 564 NSS_IMPLEMENT NSSItem *
michael@0 565 nssCKFWObject_GetAttribute
michael@0 566 (
michael@0 567 NSSCKFWObject *fwObject,
michael@0 568 CK_ATTRIBUTE_TYPE attribute,
michael@0 569 NSSItem *itemOpt,
michael@0 570 NSSArena *arenaOpt,
michael@0 571 CK_RV *pError
michael@0 572 )
michael@0 573 {
michael@0 574 NSSItem *rv = (NSSItem *)NULL;
michael@0 575 NSSCKFWItem mdItem;
michael@0 576
michael@0 577 #ifdef NSSDEBUG
michael@0 578 if (!pError) {
michael@0 579 return (NSSItem *)NULL;
michael@0 580 }
michael@0 581
michael@0 582 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 583 if( CKR_OK != *pError ) {
michael@0 584 return (NSSItem *)NULL;
michael@0 585 }
michael@0 586 #endif /* NSSDEBUG */
michael@0 587
michael@0 588 if (!fwObject->mdObject->GetAttribute) {
michael@0 589 *pError = CKR_GENERAL_ERROR;
michael@0 590 return (NSSItem *)NULL;
michael@0 591 }
michael@0 592
michael@0 593 *pError = nssCKFWMutex_Lock(fwObject->mutex);
michael@0 594 if( CKR_OK != *pError ) {
michael@0 595 return (NSSItem *)NULL;
michael@0 596 }
michael@0 597
michael@0 598 mdItem = fwObject->mdObject->GetAttribute(fwObject->mdObject, fwObject,
michael@0 599 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 600 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
michael@0 601 attribute, pError);
michael@0 602
michael@0 603 if (!mdItem.item) {
michael@0 604 if( CKR_OK == *pError ) {
michael@0 605 *pError = CKR_GENERAL_ERROR;
michael@0 606 }
michael@0 607
michael@0 608 goto done;
michael@0 609 }
michael@0 610
michael@0 611 if (!itemOpt) {
michael@0 612 rv = nss_ZNEW(arenaOpt, NSSItem);
michael@0 613 if (!rv) {
michael@0 614 *pError = CKR_HOST_MEMORY;
michael@0 615 goto done;
michael@0 616 }
michael@0 617 } else {
michael@0 618 rv = itemOpt;
michael@0 619 }
michael@0 620
michael@0 621 if (!rv->data) {
michael@0 622 rv->size = mdItem.item->size;
michael@0 623 rv->data = nss_ZAlloc(arenaOpt, rv->size);
michael@0 624 if (!rv->data) {
michael@0 625 *pError = CKR_HOST_MEMORY;
michael@0 626 if (!itemOpt) {
michael@0 627 nss_ZFreeIf(rv);
michael@0 628 }
michael@0 629 rv = (NSSItem *)NULL;
michael@0 630 goto done;
michael@0 631 }
michael@0 632 } else {
michael@0 633 if( rv->size >= mdItem.item->size ) {
michael@0 634 rv->size = mdItem.item->size;
michael@0 635 } else {
michael@0 636 *pError = CKR_BUFFER_TOO_SMALL;
michael@0 637 /* Should we set rv->size to mdItem->size? */
michael@0 638 /* rv can't have been allocated */
michael@0 639 rv = (NSSItem *)NULL;
michael@0 640 goto done;
michael@0 641 }
michael@0 642 }
michael@0 643
michael@0 644 (void)nsslibc_memcpy(rv->data, mdItem.item->data, rv->size);
michael@0 645
michael@0 646 if (PR_TRUE == mdItem.needsFreeing) {
michael@0 647 PR_ASSERT(fwObject->mdObject->FreeAttribute);
michael@0 648 if (fwObject->mdObject->FreeAttribute) {
michael@0 649 *pError = fwObject->mdObject->FreeAttribute(&mdItem);
michael@0 650 }
michael@0 651 }
michael@0 652
michael@0 653 done:
michael@0 654 (void)nssCKFWMutex_Unlock(fwObject->mutex);
michael@0 655 return rv;
michael@0 656 }
michael@0 657
michael@0 658 /*
michael@0 659 * nssCKFWObject_SetAttribute
michael@0 660 *
michael@0 661 */
michael@0 662 NSS_IMPLEMENT CK_RV
michael@0 663 nssCKFWObject_SetAttribute
michael@0 664 (
michael@0 665 NSSCKFWObject *fwObject,
michael@0 666 NSSCKFWSession *fwSession,
michael@0 667 CK_ATTRIBUTE_TYPE attribute,
michael@0 668 NSSItem *value
michael@0 669 )
michael@0 670 {
michael@0 671 CK_RV error = CKR_OK;
michael@0 672
michael@0 673 #ifdef NSSDEBUG
michael@0 674 error = nssCKFWObject_verifyPointer(fwObject);
michael@0 675 if( CKR_OK != error ) {
michael@0 676 return error;
michael@0 677 }
michael@0 678 #endif /* NSSDEBUG */
michael@0 679
michael@0 680 if( CKA_TOKEN == attribute ) {
michael@0 681 /*
michael@0 682 * We're changing from a session object to a token object or
michael@0 683 * vice-versa.
michael@0 684 */
michael@0 685
michael@0 686 CK_ATTRIBUTE a;
michael@0 687 NSSCKFWObject *newFwObject;
michael@0 688 NSSCKFWObject swab;
michael@0 689
michael@0 690 a.type = CKA_TOKEN;
michael@0 691 a.pValue = value->data;
michael@0 692 a.ulValueLen = value->size;
michael@0 693
michael@0 694 newFwObject = nssCKFWSession_CopyObject(fwSession, fwObject,
michael@0 695 &a, 1, &error);
michael@0 696 if (!newFwObject) {
michael@0 697 if( CKR_OK == error ) {
michael@0 698 error = CKR_GENERAL_ERROR;
michael@0 699 }
michael@0 700 return error;
michael@0 701 }
michael@0 702
michael@0 703 /*
michael@0 704 * Actually, I bet the locking is worse than this.. this part of
michael@0 705 * the code could probably use some scrutiny and reworking.
michael@0 706 */
michael@0 707 error = nssCKFWMutex_Lock(fwObject->mutex);
michael@0 708 if( CKR_OK != error ) {
michael@0 709 nssCKFWObject_Destroy(newFwObject);
michael@0 710 return error;
michael@0 711 }
michael@0 712
michael@0 713 error = nssCKFWMutex_Lock(newFwObject->mutex);
michael@0 714 if( CKR_OK != error ) {
michael@0 715 nssCKFWMutex_Unlock(fwObject->mutex);
michael@0 716 nssCKFWObject_Destroy(newFwObject);
michael@0 717 return error;
michael@0 718 }
michael@0 719
michael@0 720 /*
michael@0 721 * Now, we have our new object, but it has a new fwObject pointer,
michael@0 722 * while we have to keep the existing one. So quick swap the contents.
michael@0 723 */
michael@0 724 swab = *fwObject;
michael@0 725 *fwObject = *newFwObject;
michael@0 726 *newFwObject = swab;
michael@0 727
michael@0 728 /* But keep the mutexes the same */
michael@0 729 swab.mutex = fwObject->mutex;
michael@0 730 fwObject->mutex = newFwObject->mutex;
michael@0 731 newFwObject->mutex = swab.mutex;
michael@0 732
michael@0 733 (void)nssCKFWMutex_Unlock(newFwObject->mutex);
michael@0 734 (void)nssCKFWMutex_Unlock(fwObject->mutex);
michael@0 735
michael@0 736 /*
michael@0 737 * Either remove or add this to the list of session objects
michael@0 738 */
michael@0 739
michael@0 740 if( CK_FALSE == *(CK_BBOOL *)value->data ) {
michael@0 741 /*
michael@0 742 * New one is a session object, except since we "stole" the fwObject, it's
michael@0 743 * not in the list. Add it.
michael@0 744 */
michael@0 745 nssCKFWSession_RegisterSessionObject(fwSession, fwObject);
michael@0 746 } else {
michael@0 747 /*
michael@0 748 * New one is a token object, except since we "stole" the fwObject, it's
michael@0 749 * in the list. Remove it.
michael@0 750 */
michael@0 751 if (fwObject->fwSession) {
michael@0 752 nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject);
michael@0 753 }
michael@0 754 }
michael@0 755
michael@0 756 /*
michael@0 757 * Now delete the old object. Remember the names have changed.
michael@0 758 */
michael@0 759 nssCKFWObject_Destroy(newFwObject);
michael@0 760
michael@0 761 return CKR_OK;
michael@0 762 } else {
michael@0 763 /*
michael@0 764 * An "ordinary" change.
michael@0 765 */
michael@0 766 if (!fwObject->mdObject->SetAttribute) {
michael@0 767 /* We could fake it with copying, like above.. later */
michael@0 768 return CKR_ATTRIBUTE_READ_ONLY;
michael@0 769 }
michael@0 770
michael@0 771 error = nssCKFWMutex_Lock(fwObject->mutex);
michael@0 772 if( CKR_OK != error ) {
michael@0 773 return error;
michael@0 774 }
michael@0 775
michael@0 776 error = fwObject->mdObject->SetAttribute(fwObject->mdObject, fwObject,
michael@0 777 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 778 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
michael@0 779 attribute, value);
michael@0 780
michael@0 781 (void)nssCKFWMutex_Unlock(fwObject->mutex);
michael@0 782
michael@0 783 return error;
michael@0 784 }
michael@0 785 }
michael@0 786
michael@0 787 /*
michael@0 788 * nssCKFWObject_GetObjectSize
michael@0 789 *
michael@0 790 */
michael@0 791 NSS_IMPLEMENT CK_ULONG
michael@0 792 nssCKFWObject_GetObjectSize
michael@0 793 (
michael@0 794 NSSCKFWObject *fwObject,
michael@0 795 CK_RV *pError
michael@0 796 )
michael@0 797 {
michael@0 798 CK_ULONG rv;
michael@0 799
michael@0 800 #ifdef NSSDEBUG
michael@0 801 if (!pError) {
michael@0 802 return (CK_ULONG)0;
michael@0 803 }
michael@0 804
michael@0 805 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 806 if( CKR_OK != *pError ) {
michael@0 807 return (CK_ULONG)0;
michael@0 808 }
michael@0 809 #endif /* NSSDEBUG */
michael@0 810
michael@0 811 if (!fwObject->mdObject->GetObjectSize) {
michael@0 812 *pError = CKR_INFORMATION_SENSITIVE;
michael@0 813 return (CK_ULONG)0;
michael@0 814 }
michael@0 815
michael@0 816 *pError = nssCKFWMutex_Lock(fwObject->mutex);
michael@0 817 if( CKR_OK != *pError ) {
michael@0 818 return (CK_ULONG)0;
michael@0 819 }
michael@0 820
michael@0 821 rv = fwObject->mdObject->GetObjectSize(fwObject->mdObject, fwObject,
michael@0 822 fwObject->mdSession, fwObject->fwSession, fwObject->mdToken,
michael@0 823 fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance,
michael@0 824 pError);
michael@0 825
michael@0 826 (void)nssCKFWMutex_Unlock(fwObject->mutex);
michael@0 827 return rv;
michael@0 828 }
michael@0 829
michael@0 830 /*
michael@0 831 * NSSCKFWObject_GetMDObject
michael@0 832 *
michael@0 833 */
michael@0 834 NSS_IMPLEMENT NSSCKMDObject *
michael@0 835 NSSCKFWObject_GetMDObject
michael@0 836 (
michael@0 837 NSSCKFWObject *fwObject
michael@0 838 )
michael@0 839 {
michael@0 840 #ifdef DEBUG
michael@0 841 if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
michael@0 842 return (NSSCKMDObject *)NULL;
michael@0 843 }
michael@0 844 #endif /* DEBUG */
michael@0 845
michael@0 846 return nssCKFWObject_GetMDObject(fwObject);
michael@0 847 }
michael@0 848
michael@0 849 /*
michael@0 850 * NSSCKFWObject_GetArena
michael@0 851 *
michael@0 852 */
michael@0 853 NSS_IMPLEMENT NSSArena *
michael@0 854 NSSCKFWObject_GetArena
michael@0 855 (
michael@0 856 NSSCKFWObject *fwObject,
michael@0 857 CK_RV *pError
michael@0 858 )
michael@0 859 {
michael@0 860 #ifdef DEBUG
michael@0 861 if (!pError) {
michael@0 862 return (NSSArena *)NULL;
michael@0 863 }
michael@0 864
michael@0 865 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 866 if( CKR_OK != *pError ) {
michael@0 867 return (NSSArena *)NULL;
michael@0 868 }
michael@0 869 #endif /* DEBUG */
michael@0 870
michael@0 871 return nssCKFWObject_GetArena(fwObject, pError);
michael@0 872 }
michael@0 873
michael@0 874 /*
michael@0 875 * NSSCKFWObject_IsTokenObject
michael@0 876 *
michael@0 877 */
michael@0 878 NSS_IMPLEMENT CK_BBOOL
michael@0 879 NSSCKFWObject_IsTokenObject
michael@0 880 (
michael@0 881 NSSCKFWObject *fwObject
michael@0 882 )
michael@0 883 {
michael@0 884 #ifdef DEBUG
michael@0 885 if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) {
michael@0 886 return CK_FALSE;
michael@0 887 }
michael@0 888 #endif /* DEBUG */
michael@0 889
michael@0 890 return nssCKFWObject_IsTokenObject(fwObject);
michael@0 891 }
michael@0 892
michael@0 893 /*
michael@0 894 * NSSCKFWObject_GetAttributeCount
michael@0 895 *
michael@0 896 */
michael@0 897 NSS_IMPLEMENT CK_ULONG
michael@0 898 NSSCKFWObject_GetAttributeCount
michael@0 899 (
michael@0 900 NSSCKFWObject *fwObject,
michael@0 901 CK_RV *pError
michael@0 902 )
michael@0 903 {
michael@0 904 #ifdef DEBUG
michael@0 905 if (!pError) {
michael@0 906 return (CK_ULONG)0;
michael@0 907 }
michael@0 908
michael@0 909 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 910 if( CKR_OK != *pError ) {
michael@0 911 return (CK_ULONG)0;
michael@0 912 }
michael@0 913 #endif /* DEBUG */
michael@0 914
michael@0 915 return nssCKFWObject_GetAttributeCount(fwObject, pError);
michael@0 916 }
michael@0 917
michael@0 918 /*
michael@0 919 * NSSCKFWObject_GetAttributeTypes
michael@0 920 *
michael@0 921 */
michael@0 922 NSS_IMPLEMENT CK_RV
michael@0 923 NSSCKFWObject_GetAttributeTypes
michael@0 924 (
michael@0 925 NSSCKFWObject *fwObject,
michael@0 926 CK_ATTRIBUTE_TYPE_PTR typeArray,
michael@0 927 CK_ULONG ulCount
michael@0 928 )
michael@0 929 {
michael@0 930 #ifdef DEBUG
michael@0 931 CK_RV error = CKR_OK;
michael@0 932
michael@0 933 error = nssCKFWObject_verifyPointer(fwObject);
michael@0 934 if( CKR_OK != error ) {
michael@0 935 return error;
michael@0 936 }
michael@0 937
michael@0 938 if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) {
michael@0 939 return CKR_ARGUMENTS_BAD;
michael@0 940 }
michael@0 941 #endif /* DEBUG */
michael@0 942
michael@0 943 return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount);
michael@0 944 }
michael@0 945
michael@0 946 /*
michael@0 947 * NSSCKFWObject_GetAttributeSize
michael@0 948 *
michael@0 949 */
michael@0 950 NSS_IMPLEMENT CK_ULONG
michael@0 951 NSSCKFWObject_GetAttributeSize
michael@0 952 (
michael@0 953 NSSCKFWObject *fwObject,
michael@0 954 CK_ATTRIBUTE_TYPE attribute,
michael@0 955 CK_RV *pError
michael@0 956 )
michael@0 957 {
michael@0 958 #ifdef DEBUG
michael@0 959 if (!pError) {
michael@0 960 return (CK_ULONG)0;
michael@0 961 }
michael@0 962
michael@0 963 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 964 if( CKR_OK != *pError ) {
michael@0 965 return (CK_ULONG)0;
michael@0 966 }
michael@0 967 #endif /* DEBUG */
michael@0 968
michael@0 969 return nssCKFWObject_GetAttributeSize(fwObject, attribute, pError);
michael@0 970 }
michael@0 971
michael@0 972 /*
michael@0 973 * NSSCKFWObject_GetAttribute
michael@0 974 *
michael@0 975 */
michael@0 976 NSS_IMPLEMENT NSSItem *
michael@0 977 NSSCKFWObject_GetAttribute
michael@0 978 (
michael@0 979 NSSCKFWObject *fwObject,
michael@0 980 CK_ATTRIBUTE_TYPE attribute,
michael@0 981 NSSItem *itemOpt,
michael@0 982 NSSArena *arenaOpt,
michael@0 983 CK_RV *pError
michael@0 984 )
michael@0 985 {
michael@0 986 #ifdef DEBUG
michael@0 987 if (!pError) {
michael@0 988 return (NSSItem *)NULL;
michael@0 989 }
michael@0 990
michael@0 991 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 992 if( CKR_OK != *pError ) {
michael@0 993 return (NSSItem *)NULL;
michael@0 994 }
michael@0 995 #endif /* DEBUG */
michael@0 996
michael@0 997 return nssCKFWObject_GetAttribute(fwObject, attribute, itemOpt, arenaOpt, pError);
michael@0 998 }
michael@0 999
michael@0 1000 /*
michael@0 1001 * NSSCKFWObject_GetObjectSize
michael@0 1002 *
michael@0 1003 */
michael@0 1004 NSS_IMPLEMENT CK_ULONG
michael@0 1005 NSSCKFWObject_GetObjectSize
michael@0 1006 (
michael@0 1007 NSSCKFWObject *fwObject,
michael@0 1008 CK_RV *pError
michael@0 1009 )
michael@0 1010 {
michael@0 1011 #ifdef DEBUG
michael@0 1012 if (!pError) {
michael@0 1013 return (CK_ULONG)0;
michael@0 1014 }
michael@0 1015
michael@0 1016 *pError = nssCKFWObject_verifyPointer(fwObject);
michael@0 1017 if( CKR_OK != *pError ) {
michael@0 1018 return (CK_ULONG)0;
michael@0 1019 }
michael@0 1020 #endif /* DEBUG */
michael@0 1021
michael@0 1022 return nssCKFWObject_GetObjectSize(fwObject, pError);
michael@0 1023 }

mercurial