1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ckfw/object.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1023 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 + 1.8 +/* 1.9 + * object.c 1.10 + * 1.11 + * This file implements the NSSCKFWObject type and methods. 1.12 + */ 1.13 + 1.14 +#ifndef CK_T 1.15 +#include "ck.h" 1.16 +#endif /* CK_T */ 1.17 + 1.18 +/* 1.19 + * NSSCKFWObject 1.20 + * 1.21 + * -- create/destroy -- 1.22 + * nssCKFWObject_Create 1.23 + * nssCKFWObject_Finalize 1.24 + * nssCKFWObject_Destroy 1.25 + * 1.26 + * -- public accessors -- 1.27 + * NSSCKFWObject_GetMDObject 1.28 + * NSSCKFWObject_GetArena 1.29 + * NSSCKFWObject_IsTokenObject 1.30 + * NSSCKFWObject_GetAttributeCount 1.31 + * NSSCKFWObject_GetAttributeTypes 1.32 + * NSSCKFWObject_GetAttributeSize 1.33 + * NSSCKFWObject_GetAttribute 1.34 + * NSSCKFWObject_SetAttribute 1.35 + * NSSCKFWObject_GetObjectSize 1.36 + * 1.37 + * -- implement public accessors -- 1.38 + * nssCKFWObject_GetMDObject 1.39 + * nssCKFWObject_GetArena 1.40 + * 1.41 + * -- private accessors -- 1.42 + * nssCKFWObject_SetHandle 1.43 + * nssCKFWObject_GetHandle 1.44 + * 1.45 + * -- module fronts -- 1.46 + * nssCKFWObject_IsTokenObject 1.47 + * nssCKFWObject_GetAttributeCount 1.48 + * nssCKFWObject_GetAttributeTypes 1.49 + * nssCKFWObject_GetAttributeSize 1.50 + * nssCKFWObject_GetAttribute 1.51 + * nssCKFWObject_SetAttribute 1.52 + * nssCKFWObject_GetObjectSize 1.53 + */ 1.54 + 1.55 +struct NSSCKFWObjectStr { 1.56 + NSSCKFWMutex *mutex; /* merely to serialise the MDObject calls */ 1.57 + NSSArena *arena; 1.58 + NSSCKMDObject *mdObject; 1.59 + NSSCKMDSession *mdSession; 1.60 + NSSCKFWSession *fwSession; 1.61 + NSSCKMDToken *mdToken; 1.62 + NSSCKFWToken *fwToken; 1.63 + NSSCKMDInstance *mdInstance; 1.64 + NSSCKFWInstance *fwInstance; 1.65 + CK_OBJECT_HANDLE hObject; 1.66 +}; 1.67 + 1.68 +#ifdef DEBUG 1.69 +/* 1.70 + * But first, the pointer-tracking stuff. 1.71 + * 1.72 + * NOTE: the pointer-tracking support in NSS/base currently relies 1.73 + * upon NSPR's CallOnce support. That, however, relies upon NSPR's 1.74 + * locking, which is tied into the runtime. We need a pointer-tracker 1.75 + * implementation that uses the locks supplied through C_Initialize. 1.76 + * That support, however, can be filled in later. So for now, I'll 1.77 + * just do this routines as no-ops. 1.78 + */ 1.79 + 1.80 +static CK_RV 1.81 +object_add_pointer 1.82 +( 1.83 + const NSSCKFWObject *fwObject 1.84 +) 1.85 +{ 1.86 + return CKR_OK; 1.87 +} 1.88 + 1.89 +static CK_RV 1.90 +object_remove_pointer 1.91 +( 1.92 + const NSSCKFWObject *fwObject 1.93 +) 1.94 +{ 1.95 + return CKR_OK; 1.96 +} 1.97 + 1.98 +NSS_IMPLEMENT CK_RV 1.99 +nssCKFWObject_verifyPointer 1.100 +( 1.101 + const NSSCKFWObject *fwObject 1.102 +) 1.103 +{ 1.104 + return CKR_OK; 1.105 +} 1.106 + 1.107 +#endif /* DEBUG */ 1.108 + 1.109 + 1.110 +/* 1.111 + * nssCKFWObject_Create 1.112 + * 1.113 + */ 1.114 +NSS_IMPLEMENT NSSCKFWObject * 1.115 +nssCKFWObject_Create 1.116 +( 1.117 + NSSArena *arena, 1.118 + NSSCKMDObject *mdObject, 1.119 + NSSCKFWSession *fwSession, 1.120 + NSSCKFWToken *fwToken, 1.121 + NSSCKFWInstance *fwInstance, 1.122 + CK_RV *pError 1.123 +) 1.124 +{ 1.125 + NSSCKFWObject *fwObject; 1.126 + nssCKFWHash *mdObjectHash; 1.127 + 1.128 +#ifdef NSSDEBUG 1.129 + if (!pError) { 1.130 + return (NSSCKFWObject *)NULL; 1.131 + } 1.132 + 1.133 + if( PR_SUCCESS != nssArena_verifyPointer(arena) ) { 1.134 + *pError = CKR_ARGUMENTS_BAD; 1.135 + return (NSSCKFWObject *)NULL; 1.136 + } 1.137 +#endif /* NSSDEBUG */ 1.138 + 1.139 + if (!fwToken) { 1.140 + *pError = CKR_ARGUMENTS_BAD; 1.141 + return (NSSCKFWObject *)NULL; 1.142 + } 1.143 + mdObjectHash = nssCKFWToken_GetMDObjectHash(fwToken); 1.144 + if (!mdObjectHash) { 1.145 + *pError = CKR_GENERAL_ERROR; 1.146 + return (NSSCKFWObject *)NULL; 1.147 + } 1.148 + 1.149 + if( nssCKFWHash_Exists(mdObjectHash, mdObject) ) { 1.150 + fwObject = nssCKFWHash_Lookup(mdObjectHash, mdObject); 1.151 + return fwObject; 1.152 + } 1.153 + 1.154 + fwObject = nss_ZNEW(arena, NSSCKFWObject); 1.155 + if (!fwObject) { 1.156 + *pError = CKR_HOST_MEMORY; 1.157 + return (NSSCKFWObject *)NULL; 1.158 + } 1.159 + 1.160 + fwObject->arena = arena; 1.161 + fwObject->mdObject = mdObject; 1.162 + fwObject->fwSession = fwSession; 1.163 + 1.164 + if (fwSession) { 1.165 + fwObject->mdSession = nssCKFWSession_GetMDSession(fwSession); 1.166 + } 1.167 + 1.168 + fwObject->fwToken = fwToken; 1.169 + fwObject->mdToken = nssCKFWToken_GetMDToken(fwToken); 1.170 + fwObject->fwInstance = fwInstance; 1.171 + fwObject->mdInstance = nssCKFWInstance_GetMDInstance(fwInstance); 1.172 + fwObject->mutex = nssCKFWInstance_CreateMutex(fwInstance, arena, pError); 1.173 + if (!fwObject->mutex) { 1.174 + if( CKR_OK == *pError ) { 1.175 + *pError = CKR_GENERAL_ERROR; 1.176 + } 1.177 + return (NSSCKFWObject *)NULL; 1.178 + } 1.179 + 1.180 + *pError = nssCKFWHash_Add(mdObjectHash, mdObject, fwObject); 1.181 + if( CKR_OK != *pError ) { 1.182 + nss_ZFreeIf(fwObject); 1.183 + return (NSSCKFWObject *)NULL; 1.184 + } 1.185 + 1.186 +#ifdef DEBUG 1.187 + *pError = object_add_pointer(fwObject); 1.188 + if( CKR_OK != *pError ) { 1.189 + nssCKFWHash_Remove(mdObjectHash, mdObject); 1.190 + nss_ZFreeIf(fwObject); 1.191 + return (NSSCKFWObject *)NULL; 1.192 + } 1.193 +#endif /* DEBUG */ 1.194 + 1.195 + *pError = CKR_OK; 1.196 + return fwObject; 1.197 +} 1.198 + 1.199 +/* 1.200 + * nssCKFWObject_Finalize 1.201 + * 1.202 + */ 1.203 +NSS_IMPLEMENT void 1.204 +nssCKFWObject_Finalize 1.205 +( 1.206 + NSSCKFWObject *fwObject, 1.207 + PRBool removeFromHash 1.208 +) 1.209 +{ 1.210 + nssCKFWHash *mdObjectHash; 1.211 + 1.212 +#ifdef NSSDEBUG 1.213 + if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { 1.214 + return; 1.215 + } 1.216 +#endif /* NSSDEBUG */ 1.217 + 1.218 + (void)nssCKFWMutex_Destroy(fwObject->mutex); 1.219 + 1.220 + if (fwObject->mdObject->Finalize) { 1.221 + fwObject->mdObject->Finalize(fwObject->mdObject, fwObject, 1.222 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.223 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance); 1.224 + } 1.225 + 1.226 + if (removeFromHash) { 1.227 + mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken); 1.228 + if (mdObjectHash) { 1.229 + nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject); 1.230 + } 1.231 + } 1.232 + 1.233 + if (fwObject->fwSession) { 1.234 + nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject); 1.235 + } 1.236 + nss_ZFreeIf(fwObject); 1.237 + 1.238 +#ifdef DEBUG 1.239 + (void)object_remove_pointer(fwObject); 1.240 +#endif /* DEBUG */ 1.241 + 1.242 + return; 1.243 +} 1.244 + 1.245 +/* 1.246 + * nssCKFWObject_Destroy 1.247 + * 1.248 + */ 1.249 +NSS_IMPLEMENT void 1.250 +nssCKFWObject_Destroy 1.251 +( 1.252 + NSSCKFWObject *fwObject 1.253 +) 1.254 +{ 1.255 + nssCKFWHash *mdObjectHash; 1.256 + 1.257 +#ifdef NSSDEBUG 1.258 + if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { 1.259 + return; 1.260 + } 1.261 +#endif /* NSSDEBUG */ 1.262 + 1.263 + (void)nssCKFWMutex_Destroy(fwObject->mutex); 1.264 + 1.265 + if (fwObject->mdObject->Destroy) { 1.266 + fwObject->mdObject->Destroy(fwObject->mdObject, fwObject, 1.267 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.268 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance); 1.269 + } 1.270 + 1.271 + mdObjectHash = nssCKFWToken_GetMDObjectHash(fwObject->fwToken); 1.272 + if (mdObjectHash) { 1.273 + nssCKFWHash_Remove(mdObjectHash, fwObject->mdObject); 1.274 + } 1.275 + 1.276 + if (fwObject->fwSession) { 1.277 + nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject); 1.278 + } 1.279 + nss_ZFreeIf(fwObject); 1.280 + 1.281 +#ifdef DEBUG 1.282 + (void)object_remove_pointer(fwObject); 1.283 +#endif /* DEBUG */ 1.284 + 1.285 + return; 1.286 +} 1.287 + 1.288 +/* 1.289 + * nssCKFWObject_GetMDObject 1.290 + * 1.291 + */ 1.292 +NSS_IMPLEMENT NSSCKMDObject * 1.293 +nssCKFWObject_GetMDObject 1.294 +( 1.295 + NSSCKFWObject *fwObject 1.296 +) 1.297 +{ 1.298 +#ifdef NSSDEBUG 1.299 + if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { 1.300 + return (NSSCKMDObject *)NULL; 1.301 + } 1.302 +#endif /* NSSDEBUG */ 1.303 + 1.304 + return fwObject->mdObject; 1.305 +} 1.306 + 1.307 +/* 1.308 + * nssCKFWObject_GetArena 1.309 + * 1.310 + */ 1.311 +NSS_IMPLEMENT NSSArena * 1.312 +nssCKFWObject_GetArena 1.313 +( 1.314 + NSSCKFWObject *fwObject, 1.315 + CK_RV *pError 1.316 +) 1.317 +{ 1.318 +#ifdef NSSDEBUG 1.319 + if (!pError) { 1.320 + return (NSSArena *)NULL; 1.321 + } 1.322 + 1.323 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.324 + if( CKR_OK != *pError ) { 1.325 + return (NSSArena *)NULL; 1.326 + } 1.327 +#endif /* NSSDEBUG */ 1.328 + 1.329 + return fwObject->arena; 1.330 +} 1.331 + 1.332 +/* 1.333 + * nssCKFWObject_SetHandle 1.334 + * 1.335 + */ 1.336 +NSS_IMPLEMENT CK_RV 1.337 +nssCKFWObject_SetHandle 1.338 +( 1.339 + NSSCKFWObject *fwObject, 1.340 + CK_OBJECT_HANDLE hObject 1.341 +) 1.342 +{ 1.343 +#ifdef NSSDEBUG 1.344 + CK_RV error = CKR_OK; 1.345 +#endif /* NSSDEBUG */ 1.346 + 1.347 +#ifdef NSSDEBUG 1.348 + error = nssCKFWObject_verifyPointer(fwObject); 1.349 + if( CKR_OK != error ) { 1.350 + return error; 1.351 + } 1.352 +#endif /* NSSDEBUG */ 1.353 + 1.354 + if( (CK_OBJECT_HANDLE)0 != fwObject->hObject ) { 1.355 + return CKR_GENERAL_ERROR; 1.356 + } 1.357 + 1.358 + fwObject->hObject = hObject; 1.359 + 1.360 + return CKR_OK; 1.361 +} 1.362 + 1.363 +/* 1.364 + * nssCKFWObject_GetHandle 1.365 + * 1.366 + */ 1.367 +NSS_IMPLEMENT CK_OBJECT_HANDLE 1.368 +nssCKFWObject_GetHandle 1.369 +( 1.370 + NSSCKFWObject *fwObject 1.371 +) 1.372 +{ 1.373 +#ifdef NSSDEBUG 1.374 + if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { 1.375 + return (CK_OBJECT_HANDLE)0; 1.376 + } 1.377 +#endif /* NSSDEBUG */ 1.378 + 1.379 + return fwObject->hObject; 1.380 +} 1.381 + 1.382 +/* 1.383 + * nssCKFWObject_IsTokenObject 1.384 + * 1.385 + */ 1.386 +NSS_IMPLEMENT CK_BBOOL 1.387 +nssCKFWObject_IsTokenObject 1.388 +( 1.389 + NSSCKFWObject *fwObject 1.390 +) 1.391 +{ 1.392 + CK_BBOOL b = CK_FALSE; 1.393 + 1.394 +#ifdef NSSDEBUG 1.395 + if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { 1.396 + return CK_FALSE; 1.397 + } 1.398 +#endif /* NSSDEBUG */ 1.399 + 1.400 + if (!fwObject->mdObject->IsTokenObject) { 1.401 + NSSItem item; 1.402 + NSSItem *pItem; 1.403 + CK_RV rv = CKR_OK; 1.404 + 1.405 + item.data = (void *)&b; 1.406 + item.size = sizeof(b); 1.407 + 1.408 + pItem = nssCKFWObject_GetAttribute(fwObject, CKA_TOKEN, &item, 1.409 + (NSSArena *)NULL, &rv); 1.410 + if (!pItem) { 1.411 + /* Error of some type */ 1.412 + b = CK_FALSE; 1.413 + goto done; 1.414 + } 1.415 + 1.416 + goto done; 1.417 + } 1.418 + 1.419 + b = fwObject->mdObject->IsTokenObject(fwObject->mdObject, fwObject, 1.420 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.421 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance); 1.422 + 1.423 + done: 1.424 + return b; 1.425 +} 1.426 + 1.427 +/* 1.428 + * nssCKFWObject_GetAttributeCount 1.429 + * 1.430 + */ 1.431 +NSS_IMPLEMENT CK_ULONG 1.432 +nssCKFWObject_GetAttributeCount 1.433 +( 1.434 + NSSCKFWObject *fwObject, 1.435 + CK_RV *pError 1.436 +) 1.437 +{ 1.438 + CK_ULONG rv; 1.439 + 1.440 +#ifdef NSSDEBUG 1.441 + if (!pError) { 1.442 + return (CK_ULONG)0; 1.443 + } 1.444 + 1.445 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.446 + if( CKR_OK != *pError ) { 1.447 + return (CK_ULONG)0; 1.448 + } 1.449 +#endif /* NSSDEBUG */ 1.450 + 1.451 + if (!fwObject->mdObject->GetAttributeCount) { 1.452 + *pError = CKR_GENERAL_ERROR; 1.453 + return (CK_ULONG)0; 1.454 + } 1.455 + 1.456 + *pError = nssCKFWMutex_Lock(fwObject->mutex); 1.457 + if( CKR_OK != *pError ) { 1.458 + return (CK_ULONG)0; 1.459 + } 1.460 + 1.461 + rv = fwObject->mdObject->GetAttributeCount(fwObject->mdObject, fwObject, 1.462 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.463 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, 1.464 + pError); 1.465 + 1.466 + (void)nssCKFWMutex_Unlock(fwObject->mutex); 1.467 + return rv; 1.468 +} 1.469 + 1.470 +/* 1.471 + * nssCKFWObject_GetAttributeTypes 1.472 + * 1.473 + */ 1.474 +NSS_IMPLEMENT CK_RV 1.475 +nssCKFWObject_GetAttributeTypes 1.476 +( 1.477 + NSSCKFWObject *fwObject, 1.478 + CK_ATTRIBUTE_TYPE_PTR typeArray, 1.479 + CK_ULONG ulCount 1.480 +) 1.481 +{ 1.482 + CK_RV error = CKR_OK; 1.483 + 1.484 +#ifdef NSSDEBUG 1.485 + error = nssCKFWObject_verifyPointer(fwObject); 1.486 + if( CKR_OK != error ) { 1.487 + return error; 1.488 + } 1.489 + 1.490 + if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) { 1.491 + return CKR_ARGUMENTS_BAD; 1.492 + } 1.493 +#endif /* NSSDEBUG */ 1.494 + 1.495 + if (!fwObject->mdObject->GetAttributeTypes) { 1.496 + return CKR_GENERAL_ERROR; 1.497 + } 1.498 + 1.499 + error = nssCKFWMutex_Lock(fwObject->mutex); 1.500 + if( CKR_OK != error ) { 1.501 + return error; 1.502 + } 1.503 + 1.504 + error = fwObject->mdObject->GetAttributeTypes(fwObject->mdObject, fwObject, 1.505 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.506 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, 1.507 + typeArray, ulCount); 1.508 + 1.509 + (void)nssCKFWMutex_Unlock(fwObject->mutex); 1.510 + return error; 1.511 +} 1.512 + 1.513 +/* 1.514 + * nssCKFWObject_GetAttributeSize 1.515 + * 1.516 + */ 1.517 +NSS_IMPLEMENT CK_ULONG 1.518 +nssCKFWObject_GetAttributeSize 1.519 +( 1.520 + NSSCKFWObject *fwObject, 1.521 + CK_ATTRIBUTE_TYPE attribute, 1.522 + CK_RV *pError 1.523 +) 1.524 +{ 1.525 + CK_ULONG rv; 1.526 + 1.527 +#ifdef NSSDEBUG 1.528 + if (!pError) { 1.529 + return (CK_ULONG)0; 1.530 + } 1.531 + 1.532 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.533 + if( CKR_OK != *pError ) { 1.534 + return (CK_ULONG)0; 1.535 + } 1.536 +#endif /* NSSDEBUG */ 1.537 + 1.538 + if (!fwObject->mdObject->GetAttributeSize) { 1.539 + *pError = CKR_GENERAL_ERROR; 1.540 + return (CK_ULONG )0; 1.541 + } 1.542 + 1.543 + *pError = nssCKFWMutex_Lock(fwObject->mutex); 1.544 + if( CKR_OK != *pError ) { 1.545 + return (CK_ULONG)0; 1.546 + } 1.547 + 1.548 + rv = fwObject->mdObject->GetAttributeSize(fwObject->mdObject, fwObject, 1.549 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.550 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, 1.551 + attribute, pError); 1.552 + 1.553 + (void)nssCKFWMutex_Unlock(fwObject->mutex); 1.554 + return rv; 1.555 +} 1.556 + 1.557 +/* 1.558 + * nssCKFWObject_GetAttribute 1.559 + * 1.560 + * Usual NSS allocation rules: 1.561 + * If itemOpt is not NULL, it will be returned; otherwise an NSSItem 1.562 + * will be allocated. If itemOpt is not NULL but itemOpt->data is, 1.563 + * the buffer will be allocated; otherwise, the buffer will be used. 1.564 + * Any allocations will come from the optional arena, if one is 1.565 + * specified. 1.566 + */ 1.567 +NSS_IMPLEMENT NSSItem * 1.568 +nssCKFWObject_GetAttribute 1.569 +( 1.570 + NSSCKFWObject *fwObject, 1.571 + CK_ATTRIBUTE_TYPE attribute, 1.572 + NSSItem *itemOpt, 1.573 + NSSArena *arenaOpt, 1.574 + CK_RV *pError 1.575 +) 1.576 +{ 1.577 + NSSItem *rv = (NSSItem *)NULL; 1.578 + NSSCKFWItem mdItem; 1.579 + 1.580 +#ifdef NSSDEBUG 1.581 + if (!pError) { 1.582 + return (NSSItem *)NULL; 1.583 + } 1.584 + 1.585 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.586 + if( CKR_OK != *pError ) { 1.587 + return (NSSItem *)NULL; 1.588 + } 1.589 +#endif /* NSSDEBUG */ 1.590 + 1.591 + if (!fwObject->mdObject->GetAttribute) { 1.592 + *pError = CKR_GENERAL_ERROR; 1.593 + return (NSSItem *)NULL; 1.594 + } 1.595 + 1.596 + *pError = nssCKFWMutex_Lock(fwObject->mutex); 1.597 + if( CKR_OK != *pError ) { 1.598 + return (NSSItem *)NULL; 1.599 + } 1.600 + 1.601 + mdItem = fwObject->mdObject->GetAttribute(fwObject->mdObject, fwObject, 1.602 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.603 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, 1.604 + attribute, pError); 1.605 + 1.606 + if (!mdItem.item) { 1.607 + if( CKR_OK == *pError ) { 1.608 + *pError = CKR_GENERAL_ERROR; 1.609 + } 1.610 + 1.611 + goto done; 1.612 + } 1.613 + 1.614 + if (!itemOpt) { 1.615 + rv = nss_ZNEW(arenaOpt, NSSItem); 1.616 + if (!rv) { 1.617 + *pError = CKR_HOST_MEMORY; 1.618 + goto done; 1.619 + } 1.620 + } else { 1.621 + rv = itemOpt; 1.622 + } 1.623 + 1.624 + if (!rv->data) { 1.625 + rv->size = mdItem.item->size; 1.626 + rv->data = nss_ZAlloc(arenaOpt, rv->size); 1.627 + if (!rv->data) { 1.628 + *pError = CKR_HOST_MEMORY; 1.629 + if (!itemOpt) { 1.630 + nss_ZFreeIf(rv); 1.631 + } 1.632 + rv = (NSSItem *)NULL; 1.633 + goto done; 1.634 + } 1.635 + } else { 1.636 + if( rv->size >= mdItem.item->size ) { 1.637 + rv->size = mdItem.item->size; 1.638 + } else { 1.639 + *pError = CKR_BUFFER_TOO_SMALL; 1.640 + /* Should we set rv->size to mdItem->size? */ 1.641 + /* rv can't have been allocated */ 1.642 + rv = (NSSItem *)NULL; 1.643 + goto done; 1.644 + } 1.645 + } 1.646 + 1.647 + (void)nsslibc_memcpy(rv->data, mdItem.item->data, rv->size); 1.648 + 1.649 + if (PR_TRUE == mdItem.needsFreeing) { 1.650 + PR_ASSERT(fwObject->mdObject->FreeAttribute); 1.651 + if (fwObject->mdObject->FreeAttribute) { 1.652 + *pError = fwObject->mdObject->FreeAttribute(&mdItem); 1.653 + } 1.654 + } 1.655 + 1.656 + done: 1.657 + (void)nssCKFWMutex_Unlock(fwObject->mutex); 1.658 + return rv; 1.659 +} 1.660 + 1.661 +/* 1.662 + * nssCKFWObject_SetAttribute 1.663 + * 1.664 + */ 1.665 +NSS_IMPLEMENT CK_RV 1.666 +nssCKFWObject_SetAttribute 1.667 +( 1.668 + NSSCKFWObject *fwObject, 1.669 + NSSCKFWSession *fwSession, 1.670 + CK_ATTRIBUTE_TYPE attribute, 1.671 + NSSItem *value 1.672 +) 1.673 +{ 1.674 + CK_RV error = CKR_OK; 1.675 + 1.676 +#ifdef NSSDEBUG 1.677 + error = nssCKFWObject_verifyPointer(fwObject); 1.678 + if( CKR_OK != error ) { 1.679 + return error; 1.680 + } 1.681 +#endif /* NSSDEBUG */ 1.682 + 1.683 + if( CKA_TOKEN == attribute ) { 1.684 + /* 1.685 + * We're changing from a session object to a token object or 1.686 + * vice-versa. 1.687 + */ 1.688 + 1.689 + CK_ATTRIBUTE a; 1.690 + NSSCKFWObject *newFwObject; 1.691 + NSSCKFWObject swab; 1.692 + 1.693 + a.type = CKA_TOKEN; 1.694 + a.pValue = value->data; 1.695 + a.ulValueLen = value->size; 1.696 + 1.697 + newFwObject = nssCKFWSession_CopyObject(fwSession, fwObject, 1.698 + &a, 1, &error); 1.699 + if (!newFwObject) { 1.700 + if( CKR_OK == error ) { 1.701 + error = CKR_GENERAL_ERROR; 1.702 + } 1.703 + return error; 1.704 + } 1.705 + 1.706 + /* 1.707 + * Actually, I bet the locking is worse than this.. this part of 1.708 + * the code could probably use some scrutiny and reworking. 1.709 + */ 1.710 + error = nssCKFWMutex_Lock(fwObject->mutex); 1.711 + if( CKR_OK != error ) { 1.712 + nssCKFWObject_Destroy(newFwObject); 1.713 + return error; 1.714 + } 1.715 + 1.716 + error = nssCKFWMutex_Lock(newFwObject->mutex); 1.717 + if( CKR_OK != error ) { 1.718 + nssCKFWMutex_Unlock(fwObject->mutex); 1.719 + nssCKFWObject_Destroy(newFwObject); 1.720 + return error; 1.721 + } 1.722 + 1.723 + /* 1.724 + * Now, we have our new object, but it has a new fwObject pointer, 1.725 + * while we have to keep the existing one. So quick swap the contents. 1.726 + */ 1.727 + swab = *fwObject; 1.728 + *fwObject = *newFwObject; 1.729 + *newFwObject = swab; 1.730 + 1.731 + /* But keep the mutexes the same */ 1.732 + swab.mutex = fwObject->mutex; 1.733 + fwObject->mutex = newFwObject->mutex; 1.734 + newFwObject->mutex = swab.mutex; 1.735 + 1.736 + (void)nssCKFWMutex_Unlock(newFwObject->mutex); 1.737 + (void)nssCKFWMutex_Unlock(fwObject->mutex); 1.738 + 1.739 + /* 1.740 + * Either remove or add this to the list of session objects 1.741 + */ 1.742 + 1.743 + if( CK_FALSE == *(CK_BBOOL *)value->data ) { 1.744 + /* 1.745 + * New one is a session object, except since we "stole" the fwObject, it's 1.746 + * not in the list. Add it. 1.747 + */ 1.748 + nssCKFWSession_RegisterSessionObject(fwSession, fwObject); 1.749 + } else { 1.750 + /* 1.751 + * New one is a token object, except since we "stole" the fwObject, it's 1.752 + * in the list. Remove it. 1.753 + */ 1.754 + if (fwObject->fwSession) { 1.755 + nssCKFWSession_DeregisterSessionObject(fwObject->fwSession, fwObject); 1.756 + } 1.757 + } 1.758 + 1.759 + /* 1.760 + * Now delete the old object. Remember the names have changed. 1.761 + */ 1.762 + nssCKFWObject_Destroy(newFwObject); 1.763 + 1.764 + return CKR_OK; 1.765 + } else { 1.766 + /* 1.767 + * An "ordinary" change. 1.768 + */ 1.769 + if (!fwObject->mdObject->SetAttribute) { 1.770 + /* We could fake it with copying, like above.. later */ 1.771 + return CKR_ATTRIBUTE_READ_ONLY; 1.772 + } 1.773 + 1.774 + error = nssCKFWMutex_Lock(fwObject->mutex); 1.775 + if( CKR_OK != error ) { 1.776 + return error; 1.777 + } 1.778 + 1.779 + error = fwObject->mdObject->SetAttribute(fwObject->mdObject, fwObject, 1.780 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.781 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, 1.782 + attribute, value); 1.783 + 1.784 + (void)nssCKFWMutex_Unlock(fwObject->mutex); 1.785 + 1.786 + return error; 1.787 + } 1.788 +} 1.789 + 1.790 +/* 1.791 + * nssCKFWObject_GetObjectSize 1.792 + * 1.793 + */ 1.794 +NSS_IMPLEMENT CK_ULONG 1.795 +nssCKFWObject_GetObjectSize 1.796 +( 1.797 + NSSCKFWObject *fwObject, 1.798 + CK_RV *pError 1.799 +) 1.800 +{ 1.801 + CK_ULONG rv; 1.802 + 1.803 +#ifdef NSSDEBUG 1.804 + if (!pError) { 1.805 + return (CK_ULONG)0; 1.806 + } 1.807 + 1.808 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.809 + if( CKR_OK != *pError ) { 1.810 + return (CK_ULONG)0; 1.811 + } 1.812 +#endif /* NSSDEBUG */ 1.813 + 1.814 + if (!fwObject->mdObject->GetObjectSize) { 1.815 + *pError = CKR_INFORMATION_SENSITIVE; 1.816 + return (CK_ULONG)0; 1.817 + } 1.818 + 1.819 + *pError = nssCKFWMutex_Lock(fwObject->mutex); 1.820 + if( CKR_OK != *pError ) { 1.821 + return (CK_ULONG)0; 1.822 + } 1.823 + 1.824 + rv = fwObject->mdObject->GetObjectSize(fwObject->mdObject, fwObject, 1.825 + fwObject->mdSession, fwObject->fwSession, fwObject->mdToken, 1.826 + fwObject->fwToken, fwObject->mdInstance, fwObject->fwInstance, 1.827 + pError); 1.828 + 1.829 + (void)nssCKFWMutex_Unlock(fwObject->mutex); 1.830 + return rv; 1.831 +} 1.832 + 1.833 +/* 1.834 + * NSSCKFWObject_GetMDObject 1.835 + * 1.836 + */ 1.837 +NSS_IMPLEMENT NSSCKMDObject * 1.838 +NSSCKFWObject_GetMDObject 1.839 +( 1.840 + NSSCKFWObject *fwObject 1.841 +) 1.842 +{ 1.843 +#ifdef DEBUG 1.844 + if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { 1.845 + return (NSSCKMDObject *)NULL; 1.846 + } 1.847 +#endif /* DEBUG */ 1.848 + 1.849 + return nssCKFWObject_GetMDObject(fwObject); 1.850 +} 1.851 + 1.852 +/* 1.853 + * NSSCKFWObject_GetArena 1.854 + * 1.855 + */ 1.856 +NSS_IMPLEMENT NSSArena * 1.857 +NSSCKFWObject_GetArena 1.858 +( 1.859 + NSSCKFWObject *fwObject, 1.860 + CK_RV *pError 1.861 +) 1.862 +{ 1.863 +#ifdef DEBUG 1.864 + if (!pError) { 1.865 + return (NSSArena *)NULL; 1.866 + } 1.867 + 1.868 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.869 + if( CKR_OK != *pError ) { 1.870 + return (NSSArena *)NULL; 1.871 + } 1.872 +#endif /* DEBUG */ 1.873 + 1.874 + return nssCKFWObject_GetArena(fwObject, pError); 1.875 +} 1.876 + 1.877 +/* 1.878 + * NSSCKFWObject_IsTokenObject 1.879 + * 1.880 + */ 1.881 +NSS_IMPLEMENT CK_BBOOL 1.882 +NSSCKFWObject_IsTokenObject 1.883 +( 1.884 + NSSCKFWObject *fwObject 1.885 +) 1.886 +{ 1.887 +#ifdef DEBUG 1.888 + if( CKR_OK != nssCKFWObject_verifyPointer(fwObject) ) { 1.889 + return CK_FALSE; 1.890 + } 1.891 +#endif /* DEBUG */ 1.892 + 1.893 + return nssCKFWObject_IsTokenObject(fwObject); 1.894 +} 1.895 + 1.896 +/* 1.897 + * NSSCKFWObject_GetAttributeCount 1.898 + * 1.899 + */ 1.900 +NSS_IMPLEMENT CK_ULONG 1.901 +NSSCKFWObject_GetAttributeCount 1.902 +( 1.903 + NSSCKFWObject *fwObject, 1.904 + CK_RV *pError 1.905 +) 1.906 +{ 1.907 +#ifdef DEBUG 1.908 + if (!pError) { 1.909 + return (CK_ULONG)0; 1.910 + } 1.911 + 1.912 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.913 + if( CKR_OK != *pError ) { 1.914 + return (CK_ULONG)0; 1.915 + } 1.916 +#endif /* DEBUG */ 1.917 + 1.918 + return nssCKFWObject_GetAttributeCount(fwObject, pError); 1.919 +} 1.920 + 1.921 +/* 1.922 + * NSSCKFWObject_GetAttributeTypes 1.923 + * 1.924 + */ 1.925 +NSS_IMPLEMENT CK_RV 1.926 +NSSCKFWObject_GetAttributeTypes 1.927 +( 1.928 + NSSCKFWObject *fwObject, 1.929 + CK_ATTRIBUTE_TYPE_PTR typeArray, 1.930 + CK_ULONG ulCount 1.931 +) 1.932 +{ 1.933 +#ifdef DEBUG 1.934 + CK_RV error = CKR_OK; 1.935 + 1.936 + error = nssCKFWObject_verifyPointer(fwObject); 1.937 + if( CKR_OK != error ) { 1.938 + return error; 1.939 + } 1.940 + 1.941 + if( (CK_ATTRIBUTE_TYPE_PTR)NULL == typeArray ) { 1.942 + return CKR_ARGUMENTS_BAD; 1.943 + } 1.944 +#endif /* DEBUG */ 1.945 + 1.946 + return nssCKFWObject_GetAttributeTypes(fwObject, typeArray, ulCount); 1.947 +} 1.948 + 1.949 +/* 1.950 + * NSSCKFWObject_GetAttributeSize 1.951 + * 1.952 + */ 1.953 +NSS_IMPLEMENT CK_ULONG 1.954 +NSSCKFWObject_GetAttributeSize 1.955 +( 1.956 + NSSCKFWObject *fwObject, 1.957 + CK_ATTRIBUTE_TYPE attribute, 1.958 + CK_RV *pError 1.959 +) 1.960 +{ 1.961 +#ifdef DEBUG 1.962 + if (!pError) { 1.963 + return (CK_ULONG)0; 1.964 + } 1.965 + 1.966 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.967 + if( CKR_OK != *pError ) { 1.968 + return (CK_ULONG)0; 1.969 + } 1.970 +#endif /* DEBUG */ 1.971 + 1.972 + return nssCKFWObject_GetAttributeSize(fwObject, attribute, pError); 1.973 +} 1.974 + 1.975 +/* 1.976 + * NSSCKFWObject_GetAttribute 1.977 + * 1.978 + */ 1.979 +NSS_IMPLEMENT NSSItem * 1.980 +NSSCKFWObject_GetAttribute 1.981 +( 1.982 + NSSCKFWObject *fwObject, 1.983 + CK_ATTRIBUTE_TYPE attribute, 1.984 + NSSItem *itemOpt, 1.985 + NSSArena *arenaOpt, 1.986 + CK_RV *pError 1.987 +) 1.988 +{ 1.989 +#ifdef DEBUG 1.990 + if (!pError) { 1.991 + return (NSSItem *)NULL; 1.992 + } 1.993 + 1.994 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.995 + if( CKR_OK != *pError ) { 1.996 + return (NSSItem *)NULL; 1.997 + } 1.998 +#endif /* DEBUG */ 1.999 + 1.1000 + return nssCKFWObject_GetAttribute(fwObject, attribute, itemOpt, arenaOpt, pError); 1.1001 +} 1.1002 + 1.1003 +/* 1.1004 + * NSSCKFWObject_GetObjectSize 1.1005 + * 1.1006 + */ 1.1007 +NSS_IMPLEMENT CK_ULONG 1.1008 +NSSCKFWObject_GetObjectSize 1.1009 +( 1.1010 + NSSCKFWObject *fwObject, 1.1011 + CK_RV *pError 1.1012 +) 1.1013 +{ 1.1014 +#ifdef DEBUG 1.1015 + if (!pError) { 1.1016 + return (CK_ULONG)0; 1.1017 + } 1.1018 + 1.1019 + *pError = nssCKFWObject_verifyPointer(fwObject); 1.1020 + if( CKR_OK != *pError ) { 1.1021 + return (CK_ULONG)0; 1.1022 + } 1.1023 +#endif /* DEBUG */ 1.1024 + 1.1025 + return nssCKFWObject_GetObjectSize(fwObject, pError); 1.1026 +}