1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/ckfw/sessobj.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1075 @@ 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 + * sessobj.c 1.10 + * 1.11 + * This file contains an NSSCKMDObject implementation for session 1.12 + * objects. The framework uses this implementation to manage 1.13 + * session objects when a Module doesn't wish to be bothered. 1.14 + */ 1.15 + 1.16 +#ifndef CK_T 1.17 +#include "ck.h" 1.18 +#endif /* CK_T */ 1.19 + 1.20 +/* 1.21 + * nssCKMDSessionObject 1.22 + * 1.23 + * -- create -- 1.24 + * nssCKMDSessionObject_Create 1.25 + * 1.26 + * -- EPV calls -- 1.27 + * nss_ckmdSessionObject_Finalize 1.28 + * nss_ckmdSessionObject_IsTokenObject 1.29 + * nss_ckmdSessionObject_GetAttributeCount 1.30 + * nss_ckmdSessionObject_GetAttributeTypes 1.31 + * nss_ckmdSessionObject_GetAttributeSize 1.32 + * nss_ckmdSessionObject_GetAttribute 1.33 + * nss_ckmdSessionObject_SetAttribute 1.34 + * nss_ckmdSessionObject_GetObjectSize 1.35 + */ 1.36 + 1.37 +struct nssCKMDSessionObjectStr { 1.38 + CK_ULONG n; 1.39 + NSSArena *arena; 1.40 + NSSItem *attributes; 1.41 + CK_ATTRIBUTE_TYPE_PTR types; 1.42 + nssCKFWHash *hash; 1.43 +}; 1.44 +typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject; 1.45 + 1.46 +#ifdef DEBUG 1.47 +/* 1.48 + * But first, the pointer-tracking stuff. 1.49 + * 1.50 + * NOTE: the pointer-tracking support in NSS/base currently relies 1.51 + * upon NSPR's CallOnce support. That, however, relies upon NSPR's 1.52 + * locking, which is tied into the runtime. We need a pointer-tracker 1.53 + * implementation that uses the locks supplied through C_Initialize. 1.54 + * That support, however, can be filled in later. So for now, I'll 1.55 + * just do this routines as no-ops. 1.56 + */ 1.57 + 1.58 +static CK_RV 1.59 +nss_ckmdSessionObject_add_pointer 1.60 +( 1.61 + const NSSCKMDObject *mdObject 1.62 +) 1.63 +{ 1.64 + return CKR_OK; 1.65 +} 1.66 + 1.67 +static CK_RV 1.68 +nss_ckmdSessionObject_remove_pointer 1.69 +( 1.70 + const NSSCKMDObject *mdObject 1.71 +) 1.72 +{ 1.73 + return CKR_OK; 1.74 +} 1.75 + 1.76 +#ifdef NSS_DEBUG 1.77 +static CK_RV 1.78 +nss_ckmdSessionObject_verifyPointer 1.79 +( 1.80 + const NSSCKMDObject *mdObject 1.81 +) 1.82 +{ 1.83 + return CKR_OK; 1.84 +} 1.85 +#endif 1.86 + 1.87 +#endif /* DEBUG */ 1.88 + 1.89 +/* 1.90 + * We must forward-declare these routines 1.91 + */ 1.92 +static void 1.93 +nss_ckmdSessionObject_Finalize 1.94 +( 1.95 + NSSCKMDObject *mdObject, 1.96 + NSSCKFWObject *fwObject, 1.97 + NSSCKMDSession *mdSession, 1.98 + NSSCKFWSession *fwSession, 1.99 + NSSCKMDToken *mdToken, 1.100 + NSSCKFWToken *fwToken, 1.101 + NSSCKMDInstance *mdInstance, 1.102 + NSSCKFWInstance *fwInstance 1.103 +); 1.104 + 1.105 +static CK_RV 1.106 +nss_ckmdSessionObject_Destroy 1.107 +( 1.108 + NSSCKMDObject *mdObject, 1.109 + NSSCKFWObject *fwObject, 1.110 + NSSCKMDSession *mdSession, 1.111 + NSSCKFWSession *fwSession, 1.112 + NSSCKMDToken *mdToken, 1.113 + NSSCKFWToken *fwToken, 1.114 + NSSCKMDInstance *mdInstance, 1.115 + NSSCKFWInstance *fwInstance 1.116 +); 1.117 + 1.118 +static CK_BBOOL 1.119 +nss_ckmdSessionObject_IsTokenObject 1.120 +( 1.121 + NSSCKMDObject *mdObject, 1.122 + NSSCKFWObject *fwObject, 1.123 + NSSCKMDSession *mdSession, 1.124 + NSSCKFWSession *fwSession, 1.125 + NSSCKMDToken *mdToken, 1.126 + NSSCKFWToken *fwToken, 1.127 + NSSCKMDInstance *mdInstance, 1.128 + NSSCKFWInstance *fwInstance 1.129 +); 1.130 + 1.131 +static CK_ULONG 1.132 +nss_ckmdSessionObject_GetAttributeCount 1.133 +( 1.134 + NSSCKMDObject *mdObject, 1.135 + NSSCKFWObject *fwObject, 1.136 + NSSCKMDSession *mdSession, 1.137 + NSSCKFWSession *fwSession, 1.138 + NSSCKMDToken *mdToken, 1.139 + NSSCKFWToken *fwToken, 1.140 + NSSCKMDInstance *mdInstance, 1.141 + NSSCKFWInstance *fwInstance, 1.142 + CK_RV *pError 1.143 +); 1.144 + 1.145 +static CK_RV 1.146 +nss_ckmdSessionObject_GetAttributeTypes 1.147 +( 1.148 + NSSCKMDObject *mdObject, 1.149 + NSSCKFWObject *fwObject, 1.150 + NSSCKMDSession *mdSession, 1.151 + NSSCKFWSession *fwSession, 1.152 + NSSCKMDToken *mdToken, 1.153 + NSSCKFWToken *fwToken, 1.154 + NSSCKMDInstance *mdInstance, 1.155 + NSSCKFWInstance *fwInstance, 1.156 + CK_ATTRIBUTE_TYPE_PTR typeArray, 1.157 + CK_ULONG ulCount 1.158 +); 1.159 + 1.160 +static CK_ULONG 1.161 +nss_ckmdSessionObject_GetAttributeSize 1.162 +( 1.163 + NSSCKMDObject *mdObject, 1.164 + NSSCKFWObject *fwObject, 1.165 + NSSCKMDSession *mdSession, 1.166 + NSSCKFWSession *fwSession, 1.167 + NSSCKMDToken *mdToken, 1.168 + NSSCKFWToken *fwToken, 1.169 + NSSCKMDInstance *mdInstance, 1.170 + NSSCKFWInstance *fwInstance, 1.171 + CK_ATTRIBUTE_TYPE attribute, 1.172 + CK_RV *pError 1.173 +); 1.174 + 1.175 +static NSSCKFWItem 1.176 +nss_ckmdSessionObject_GetAttribute 1.177 +( 1.178 + NSSCKMDObject *mdObject, 1.179 + NSSCKFWObject *fwObject, 1.180 + NSSCKMDSession *mdSession, 1.181 + NSSCKFWSession *fwSession, 1.182 + NSSCKMDToken *mdToken, 1.183 + NSSCKFWToken *fwToken, 1.184 + NSSCKMDInstance *mdInstance, 1.185 + NSSCKFWInstance *fwInstance, 1.186 + CK_ATTRIBUTE_TYPE attribute, 1.187 + CK_RV *pError 1.188 +); 1.189 + 1.190 +static CK_RV 1.191 +nss_ckmdSessionObject_SetAttribute 1.192 +( 1.193 + NSSCKMDObject *mdObject, 1.194 + NSSCKFWObject *fwObject, 1.195 + NSSCKMDSession *mdSession, 1.196 + NSSCKFWSession *fwSession, 1.197 + NSSCKMDToken *mdToken, 1.198 + NSSCKFWToken *fwToken, 1.199 + NSSCKMDInstance *mdInstance, 1.200 + NSSCKFWInstance *fwInstance, 1.201 + CK_ATTRIBUTE_TYPE attribute, 1.202 + NSSItem *value 1.203 +); 1.204 + 1.205 +static CK_ULONG 1.206 +nss_ckmdSessionObject_GetObjectSize 1.207 +( 1.208 + NSSCKMDObject *mdObject, 1.209 + NSSCKFWObject *fwObject, 1.210 + NSSCKMDSession *mdSession, 1.211 + NSSCKFWSession *fwSession, 1.212 + NSSCKMDToken *mdToken, 1.213 + NSSCKFWToken *fwToken, 1.214 + NSSCKMDInstance *mdInstance, 1.215 + NSSCKFWInstance *fwInstance, 1.216 + CK_RV *pError 1.217 +); 1.218 + 1.219 +/* 1.220 + * nssCKMDSessionObject_Create 1.221 + * 1.222 + */ 1.223 +NSS_IMPLEMENT NSSCKMDObject * 1.224 +nssCKMDSessionObject_Create 1.225 +( 1.226 + NSSCKFWToken *fwToken, 1.227 + NSSArena *arena, 1.228 + CK_ATTRIBUTE_PTR attributes, 1.229 + CK_ULONG ulCount, 1.230 + CK_RV *pError 1.231 +) 1.232 +{ 1.233 + NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL; 1.234 + nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL; 1.235 + CK_ULONG i; 1.236 + nssCKFWHash *hash; 1.237 + 1.238 + *pError = CKR_OK; 1.239 + 1.240 + mdso = nss_ZNEW(arena, nssCKMDSessionObject); 1.241 + if (!mdso) { 1.242 + goto loser; 1.243 + } 1.244 + 1.245 + mdso->arena = arena; 1.246 + mdso->n = ulCount; 1.247 + mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount); 1.248 + if (!mdso->attributes) { 1.249 + goto loser; 1.250 + } 1.251 + 1.252 + mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount); 1.253 + if (!mdso->types) { 1.254 + goto loser; 1.255 + } 1.256 + for( i = 0; i < ulCount; i++ ) { 1.257 + mdso->types[i] = attributes[i].type; 1.258 + mdso->attributes[i].size = attributes[i].ulValueLen; 1.259 + mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen); 1.260 + if (!mdso->attributes[i].data) { 1.261 + goto loser; 1.262 + } 1.263 + (void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue, 1.264 + attributes[i].ulValueLen); 1.265 + } 1.266 + 1.267 + mdObject = nss_ZNEW(arena, NSSCKMDObject); 1.268 + if (!mdObject) { 1.269 + goto loser; 1.270 + } 1.271 + 1.272 + mdObject->etc = (void *)mdso; 1.273 + mdObject->Finalize = nss_ckmdSessionObject_Finalize; 1.274 + mdObject->Destroy = nss_ckmdSessionObject_Destroy; 1.275 + mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject; 1.276 + mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount; 1.277 + mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes; 1.278 + mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize; 1.279 + mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute; 1.280 + mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute; 1.281 + mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize; 1.282 + 1.283 + hash = nssCKFWToken_GetSessionObjectHash(fwToken); 1.284 + if (!hash) { 1.285 + *pError = CKR_GENERAL_ERROR; 1.286 + goto loser; 1.287 + } 1.288 + 1.289 + mdso->hash = hash; 1.290 + 1.291 + *pError = nssCKFWHash_Add(hash, mdObject, mdObject); 1.292 + if( CKR_OK != *pError ) { 1.293 + goto loser; 1.294 + } 1.295 + 1.296 +#ifdef DEBUG 1.297 + if(( *pError = nss_ckmdSessionObject_add_pointer(mdObject)) != CKR_OK ) { 1.298 + goto loser; 1.299 + } 1.300 +#endif /* DEBUG */ 1.301 + 1.302 + return mdObject; 1.303 + 1.304 + loser: 1.305 + if (mdso) { 1.306 + if (mdso->attributes) { 1.307 + for( i = 0; i < ulCount; i++ ) { 1.308 + nss_ZFreeIf(mdso->attributes[i].data); 1.309 + } 1.310 + nss_ZFreeIf(mdso->attributes); 1.311 + } 1.312 + nss_ZFreeIf(mdso->types); 1.313 + nss_ZFreeIf(mdso); 1.314 + } 1.315 + 1.316 + nss_ZFreeIf(mdObject); 1.317 + if (*pError == CKR_OK) { 1.318 + *pError = CKR_HOST_MEMORY; 1.319 + } 1.320 + return (NSSCKMDObject *)NULL; 1.321 +} 1.322 + 1.323 +/* 1.324 + * nss_ckmdSessionObject_Finalize 1.325 + * 1.326 + */ 1.327 +static void 1.328 +nss_ckmdSessionObject_Finalize 1.329 +( 1.330 + NSSCKMDObject *mdObject, 1.331 + NSSCKFWObject *fwObject, 1.332 + NSSCKMDSession *mdSession, 1.333 + NSSCKFWSession *fwSession, 1.334 + NSSCKMDToken *mdToken, 1.335 + NSSCKFWToken *fwToken, 1.336 + NSSCKMDInstance *mdInstance, 1.337 + NSSCKFWInstance *fwInstance 1.338 +) 1.339 +{ 1.340 + /* This shouldn't ever be called */ 1.341 + return; 1.342 +} 1.343 + 1.344 +/* 1.345 + * nss_ckmdSessionObject_Destroy 1.346 + * 1.347 + */ 1.348 + 1.349 +static CK_RV 1.350 +nss_ckmdSessionObject_Destroy 1.351 +( 1.352 + NSSCKMDObject *mdObject, 1.353 + NSSCKFWObject *fwObject, 1.354 + NSSCKMDSession *mdSession, 1.355 + NSSCKFWSession *fwSession, 1.356 + NSSCKMDToken *mdToken, 1.357 + NSSCKFWToken *fwToken, 1.358 + NSSCKMDInstance *mdInstance, 1.359 + NSSCKFWInstance *fwInstance 1.360 +) 1.361 +{ 1.362 +#ifdef NSSDEBUG 1.363 + CK_RV error = CKR_OK; 1.364 +#endif /* NSSDEBUG */ 1.365 + nssCKMDSessionObject *mdso; 1.366 + CK_ULONG i; 1.367 + 1.368 +#ifdef NSSDEBUG 1.369 + error = nss_ckmdSessionObject_verifyPointer(mdObject); 1.370 + if( CKR_OK != error ) { 1.371 + return error; 1.372 + } 1.373 +#endif /* NSSDEBUG */ 1.374 + 1.375 + mdso = (nssCKMDSessionObject *)mdObject->etc; 1.376 + 1.377 + nssCKFWHash_Remove(mdso->hash, mdObject); 1.378 + 1.379 + for( i = 0; i < mdso->n; i++ ) { 1.380 + nss_ZFreeIf(mdso->attributes[i].data); 1.381 + } 1.382 + nss_ZFreeIf(mdso->attributes); 1.383 + nss_ZFreeIf(mdso->types); 1.384 + nss_ZFreeIf(mdso); 1.385 + nss_ZFreeIf(mdObject); 1.386 + 1.387 +#ifdef DEBUG 1.388 + (void)nss_ckmdSessionObject_remove_pointer(mdObject); 1.389 +#endif /* DEBUG */ 1.390 + 1.391 + return CKR_OK; 1.392 +} 1.393 + 1.394 +/* 1.395 + * nss_ckmdSessionObject_IsTokenObject 1.396 + * 1.397 + */ 1.398 + 1.399 +static CK_BBOOL 1.400 +nss_ckmdSessionObject_IsTokenObject 1.401 +( 1.402 + NSSCKMDObject *mdObject, 1.403 + NSSCKFWObject *fwObject, 1.404 + NSSCKMDSession *mdSession, 1.405 + NSSCKFWSession *fwSession, 1.406 + NSSCKMDToken *mdToken, 1.407 + NSSCKFWToken *fwToken, 1.408 + NSSCKMDInstance *mdInstance, 1.409 + NSSCKFWInstance *fwInstance 1.410 +) 1.411 +{ 1.412 +#ifdef NSSDEBUG 1.413 + if( CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject) ) { 1.414 + return CK_FALSE; 1.415 + } 1.416 +#endif /* NSSDEBUG */ 1.417 + 1.418 + /* 1.419 + * This implementation is only ever used for session objects. 1.420 + */ 1.421 + return CK_FALSE; 1.422 +} 1.423 + 1.424 +/* 1.425 + * nss_ckmdSessionObject_GetAttributeCount 1.426 + * 1.427 + */ 1.428 +static CK_ULONG 1.429 +nss_ckmdSessionObject_GetAttributeCount 1.430 +( 1.431 + NSSCKMDObject *mdObject, 1.432 + NSSCKFWObject *fwObject, 1.433 + NSSCKMDSession *mdSession, 1.434 + NSSCKFWSession *fwSession, 1.435 + NSSCKMDToken *mdToken, 1.436 + NSSCKFWToken *fwToken, 1.437 + NSSCKMDInstance *mdInstance, 1.438 + NSSCKFWInstance *fwInstance, 1.439 + CK_RV *pError 1.440 +) 1.441 +{ 1.442 + nssCKMDSessionObject *obj; 1.443 + 1.444 +#ifdef NSSDEBUG 1.445 + if (!pError) { 1.446 + return 0; 1.447 + } 1.448 + 1.449 + *pError = nss_ckmdSessionObject_verifyPointer(mdObject); 1.450 + if( CKR_OK != *pError ) { 1.451 + return 0; 1.452 + } 1.453 + 1.454 + /* We could even check all the other arguments, for sanity. */ 1.455 +#endif /* NSSDEBUG */ 1.456 + 1.457 + obj = (nssCKMDSessionObject *)mdObject->etc; 1.458 + 1.459 + return obj->n; 1.460 +} 1.461 + 1.462 +/* 1.463 + * nss_ckmdSessionObject_GetAttributeTypes 1.464 + * 1.465 + */ 1.466 +static CK_RV 1.467 +nss_ckmdSessionObject_GetAttributeTypes 1.468 +( 1.469 + NSSCKMDObject *mdObject, 1.470 + NSSCKFWObject *fwObject, 1.471 + NSSCKMDSession *mdSession, 1.472 + NSSCKFWSession *fwSession, 1.473 + NSSCKMDToken *mdToken, 1.474 + NSSCKFWToken *fwToken, 1.475 + NSSCKMDInstance *mdInstance, 1.476 + NSSCKFWInstance *fwInstance, 1.477 + CK_ATTRIBUTE_TYPE_PTR typeArray, 1.478 + CK_ULONG ulCount 1.479 +) 1.480 +{ 1.481 +#ifdef NSSDEBUG 1.482 + CK_RV error = CKR_OK; 1.483 +#endif /* NSSDEBUG */ 1.484 + nssCKMDSessionObject *obj; 1.485 + 1.486 +#ifdef NSSDEBUG 1.487 + error = nss_ckmdSessionObject_verifyPointer(mdObject); 1.488 + if( CKR_OK != error ) { 1.489 + return error; 1.490 + } 1.491 + 1.492 + /* We could even check all the other arguments, for sanity. */ 1.493 +#endif /* NSSDEBUG */ 1.494 + 1.495 + obj = (nssCKMDSessionObject *)mdObject->etc; 1.496 + 1.497 + if( ulCount < obj->n ) { 1.498 + return CKR_BUFFER_TOO_SMALL; 1.499 + } 1.500 + 1.501 + (void)nsslibc_memcpy(typeArray, obj->types, 1.502 + sizeof(CK_ATTRIBUTE_TYPE) * obj->n); 1.503 + 1.504 + return CKR_OK; 1.505 +} 1.506 + 1.507 +/* 1.508 + * nss_ckmdSessionObject_GetAttributeSize 1.509 + * 1.510 + */ 1.511 +static CK_ULONG 1.512 +nss_ckmdSessionObject_GetAttributeSize 1.513 +( 1.514 + NSSCKMDObject *mdObject, 1.515 + NSSCKFWObject *fwObject, 1.516 + NSSCKMDSession *mdSession, 1.517 + NSSCKFWSession *fwSession, 1.518 + NSSCKMDToken *mdToken, 1.519 + NSSCKFWToken *fwToken, 1.520 + NSSCKMDInstance *mdInstance, 1.521 + NSSCKFWInstance *fwInstance, 1.522 + CK_ATTRIBUTE_TYPE attribute, 1.523 + CK_RV *pError 1.524 +) 1.525 +{ 1.526 + nssCKMDSessionObject *obj; 1.527 + CK_ULONG i; 1.528 + 1.529 +#ifdef NSSDEBUG 1.530 + if (!pError) { 1.531 + return 0; 1.532 + } 1.533 + 1.534 + *pError = nss_ckmdSessionObject_verifyPointer(mdObject); 1.535 + if( CKR_OK != *pError ) { 1.536 + return 0; 1.537 + } 1.538 + 1.539 + /* We could even check all the other arguments, for sanity. */ 1.540 +#endif /* NSSDEBUG */ 1.541 + 1.542 + obj = (nssCKMDSessionObject *)mdObject->etc; 1.543 + 1.544 + for( i = 0; i < obj->n; i++ ) { 1.545 + if( attribute == obj->types[i] ) { 1.546 + return (CK_ULONG)(obj->attributes[i].size); 1.547 + } 1.548 + } 1.549 + 1.550 + *pError = CKR_ATTRIBUTE_TYPE_INVALID; 1.551 + return 0; 1.552 +} 1.553 + 1.554 +/* 1.555 + * nss_ckmdSessionObject_GetAttribute 1.556 + * 1.557 + */ 1.558 +static NSSCKFWItem 1.559 +nss_ckmdSessionObject_GetAttribute 1.560 +( 1.561 + NSSCKMDObject *mdObject, 1.562 + NSSCKFWObject *fwObject, 1.563 + NSSCKMDSession *mdSession, 1.564 + NSSCKFWSession *fwSession, 1.565 + NSSCKMDToken *mdToken, 1.566 + NSSCKFWToken *fwToken, 1.567 + NSSCKMDInstance *mdInstance, 1.568 + NSSCKFWInstance *fwInstance, 1.569 + CK_ATTRIBUTE_TYPE attribute, 1.570 + CK_RV *pError 1.571 +) 1.572 +{ 1.573 + NSSCKFWItem item; 1.574 + nssCKMDSessionObject *obj; 1.575 + CK_ULONG i; 1.576 + 1.577 + item.needsFreeing = PR_FALSE; 1.578 + item.item = NULL; 1.579 +#ifdef NSSDEBUG 1.580 + if (!pError) { 1.581 + return item; 1.582 + } 1.583 + 1.584 + *pError = nss_ckmdSessionObject_verifyPointer(mdObject); 1.585 + if( CKR_OK != *pError ) { 1.586 + return item; 1.587 + } 1.588 + 1.589 + /* We could even check all the other arguments, for sanity. */ 1.590 +#endif /* NSSDEBUG */ 1.591 + 1.592 + obj = (nssCKMDSessionObject *)mdObject->etc; 1.593 + 1.594 + for( i = 0; i < obj->n; i++ ) { 1.595 + if( attribute == obj->types[i] ) { 1.596 + item.item = &obj->attributes[i]; 1.597 + return item; 1.598 + } 1.599 + } 1.600 + 1.601 + *pError = CKR_ATTRIBUTE_TYPE_INVALID; 1.602 + return item; 1.603 +} 1.604 + 1.605 +/* 1.606 + * nss_ckmdSessionObject_SetAttribute 1.607 + * 1.608 + */ 1.609 + 1.610 +/* 1.611 + * Okay, so this implementation sucks. It doesn't support removing 1.612 + * an attribute (if value == NULL), and could be more graceful about 1.613 + * memory. It should allow "blank" slots in the arrays, with some 1.614 + * invalid attribute type, and then it could support removal much 1.615 + * more easily. Do this later. 1.616 + */ 1.617 +static CK_RV 1.618 +nss_ckmdSessionObject_SetAttribute 1.619 +( 1.620 + NSSCKMDObject *mdObject, 1.621 + NSSCKFWObject *fwObject, 1.622 + NSSCKMDSession *mdSession, 1.623 + NSSCKFWSession *fwSession, 1.624 + NSSCKMDToken *mdToken, 1.625 + NSSCKFWToken *fwToken, 1.626 + NSSCKMDInstance *mdInstance, 1.627 + NSSCKFWInstance *fwInstance, 1.628 + CK_ATTRIBUTE_TYPE attribute, 1.629 + NSSItem *value 1.630 +) 1.631 +{ 1.632 + nssCKMDSessionObject *obj; 1.633 + CK_ULONG i; 1.634 + NSSItem n; 1.635 + NSSItem *ra; 1.636 + CK_ATTRIBUTE_TYPE_PTR rt; 1.637 +#ifdef NSSDEBUG 1.638 + CK_RV error; 1.639 +#endif /* NSSDEBUG */ 1.640 + 1.641 +#ifdef NSSDEBUG 1.642 + error = nss_ckmdSessionObject_verifyPointer(mdObject); 1.643 + if( CKR_OK != error ) { 1.644 + return 0; 1.645 + } 1.646 + 1.647 + /* We could even check all the other arguments, for sanity. */ 1.648 +#endif /* NSSDEBUG */ 1.649 + 1.650 + obj = (nssCKMDSessionObject *)mdObject->etc; 1.651 + 1.652 + n.size = value->size; 1.653 + n.data = nss_ZAlloc(obj->arena, n.size); 1.654 + if (!n.data) { 1.655 + return CKR_HOST_MEMORY; 1.656 + } 1.657 + (void)nsslibc_memcpy(n.data, value->data, n.size); 1.658 + 1.659 + for( i = 0; i < obj->n; i++ ) { 1.660 + if( attribute == obj->types[i] ) { 1.661 + nss_ZFreeIf(obj->attributes[i].data); 1.662 + obj->attributes[i] = n; 1.663 + return CKR_OK; 1.664 + } 1.665 + } 1.666 + 1.667 + /* 1.668 + * It's new. 1.669 + */ 1.670 + 1.671 + ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1)); 1.672 + if (!ra) { 1.673 + nss_ZFreeIf(n.data); 1.674 + return CKR_HOST_MEMORY; 1.675 + } 1.676 + obj->attributes = ra; 1.677 + 1.678 + rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types, 1.679 + sizeof(CK_ATTRIBUTE_TYPE) * (obj->n + 1)); 1.680 + if (!rt) { 1.681 + nss_ZFreeIf(n.data); 1.682 + return CKR_HOST_MEMORY; 1.683 + } 1.684 + 1.685 + obj->types = rt; 1.686 + obj->attributes[obj->n] = n; 1.687 + obj->types[obj->n] = attribute; 1.688 + obj->n++; 1.689 + 1.690 + return CKR_OK; 1.691 +} 1.692 + 1.693 +/* 1.694 + * nss_ckmdSessionObject_GetObjectSize 1.695 + * 1.696 + */ 1.697 +static CK_ULONG 1.698 +nss_ckmdSessionObject_GetObjectSize 1.699 +( 1.700 + NSSCKMDObject *mdObject, 1.701 + NSSCKFWObject *fwObject, 1.702 + NSSCKMDSession *mdSession, 1.703 + NSSCKFWSession *fwSession, 1.704 + NSSCKMDToken *mdToken, 1.705 + NSSCKFWToken *fwToken, 1.706 + NSSCKMDInstance *mdInstance, 1.707 + NSSCKFWInstance *fwInstance, 1.708 + CK_RV *pError 1.709 +) 1.710 +{ 1.711 + nssCKMDSessionObject *obj; 1.712 + CK_ULONG i; 1.713 + CK_ULONG rv = (CK_ULONG)0; 1.714 + 1.715 +#ifdef NSSDEBUG 1.716 + if (!pError) { 1.717 + return 0; 1.718 + } 1.719 + 1.720 + *pError = nss_ckmdSessionObject_verifyPointer(mdObject); 1.721 + if( CKR_OK != *pError ) { 1.722 + return 0; 1.723 + } 1.724 + 1.725 + /* We could even check all the other arguments, for sanity. */ 1.726 +#endif /* NSSDEBUG */ 1.727 + 1.728 + obj = (nssCKMDSessionObject *)mdObject->etc; 1.729 + 1.730 + for( i = 0; i < obj->n; i++ ) { 1.731 + rv += obj->attributes[i].size; 1.732 + } 1.733 + 1.734 + rv += sizeof(NSSItem) * obj->n; 1.735 + rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n; 1.736 + rv += sizeof(nssCKMDSessionObject); 1.737 + 1.738 + return rv; 1.739 +} 1.740 + 1.741 +/* 1.742 + * nssCKMDFindSessionObjects 1.743 + * 1.744 + * -- create -- 1.745 + * nssCKMDFindSessionObjects_Create 1.746 + * 1.747 + * -- EPV calls -- 1.748 + * nss_ckmdFindSessionObjects_Final 1.749 + * nss_ckmdFindSessionObjects_Next 1.750 + */ 1.751 + 1.752 +struct nodeStr { 1.753 + struct nodeStr *next; 1.754 + NSSCKMDObject *mdObject; 1.755 +}; 1.756 + 1.757 +struct nssCKMDFindSessionObjectsStr { 1.758 + NSSArena *arena; 1.759 + CK_RV error; 1.760 + CK_ATTRIBUTE_PTR pTemplate; 1.761 + CK_ULONG ulCount; 1.762 + struct nodeStr *list; 1.763 + nssCKFWHash *hash; 1.764 + 1.765 +}; 1.766 +typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects; 1.767 + 1.768 +#ifdef DEBUG 1.769 +/* 1.770 + * But first, the pointer-tracking stuff. 1.771 + * 1.772 + * NOTE: the pointer-tracking support in NSS/base currently relies 1.773 + * upon NSPR's CallOnce support. That, however, relies upon NSPR's 1.774 + * locking, which is tied into the runtime. We need a pointer-tracker 1.775 + * implementation that uses the locks supplied through C_Initialize. 1.776 + * That support, however, can be filled in later. So for now, I'll 1.777 + * just do this routines as no-ops. 1.778 + */ 1.779 + 1.780 +static CK_RV 1.781 +nss_ckmdFindSessionObjects_add_pointer 1.782 +( 1.783 + const NSSCKMDFindObjects *mdFindObjects 1.784 +) 1.785 +{ 1.786 + return CKR_OK; 1.787 +} 1.788 + 1.789 +static CK_RV 1.790 +nss_ckmdFindSessionObjects_remove_pointer 1.791 +( 1.792 + const NSSCKMDFindObjects *mdFindObjects 1.793 +) 1.794 +{ 1.795 + return CKR_OK; 1.796 +} 1.797 + 1.798 +#ifdef NSS_DEBUG 1.799 +static CK_RV 1.800 +nss_ckmdFindSessionObjects_verifyPointer 1.801 +( 1.802 + const NSSCKMDFindObjects *mdFindObjects 1.803 +) 1.804 +{ 1.805 + return CKR_OK; 1.806 +} 1.807 +#endif 1.808 + 1.809 +#endif /* DEBUG */ 1.810 + 1.811 +/* 1.812 + * We must forward-declare these routines. 1.813 + */ 1.814 +static void 1.815 +nss_ckmdFindSessionObjects_Final 1.816 +( 1.817 + NSSCKMDFindObjects *mdFindObjects, 1.818 + NSSCKFWFindObjects *fwFindObjects, 1.819 + NSSCKMDSession *mdSession, 1.820 + NSSCKFWSession *fwSession, 1.821 + NSSCKMDToken *mdToken, 1.822 + NSSCKFWToken *fwToken, 1.823 + NSSCKMDInstance *mdInstance, 1.824 + NSSCKFWInstance *fwInstance 1.825 +); 1.826 + 1.827 +static NSSCKMDObject * 1.828 +nss_ckmdFindSessionObjects_Next 1.829 +( 1.830 + NSSCKMDFindObjects *mdFindObjects, 1.831 + NSSCKFWFindObjects *fwFindObjects, 1.832 + NSSCKMDSession *mdSession, 1.833 + NSSCKFWSession *fwSession, 1.834 + NSSCKMDToken *mdToken, 1.835 + NSSCKFWToken *fwToken, 1.836 + NSSCKMDInstance *mdInstance, 1.837 + NSSCKFWInstance *fwInstance, 1.838 + NSSArena *arena, 1.839 + CK_RV *pError 1.840 +); 1.841 + 1.842 +static CK_BBOOL 1.843 +items_match 1.844 +( 1.845 + NSSItem *a, 1.846 + CK_VOID_PTR pValue, 1.847 + CK_ULONG ulValueLen 1.848 +) 1.849 +{ 1.850 + if( a->size != ulValueLen ) { 1.851 + return CK_FALSE; 1.852 + } 1.853 + 1.854 + if( PR_TRUE == nsslibc_memequal(a->data, pValue, ulValueLen, (PRStatus *)NULL) ) { 1.855 + return CK_TRUE; 1.856 + } else { 1.857 + return CK_FALSE; 1.858 + } 1.859 +} 1.860 + 1.861 +/* 1.862 + * Our hashtable iterator 1.863 + */ 1.864 +static void 1.865 +findfcn 1.866 +( 1.867 + const void *key, 1.868 + void *value, 1.869 + void *closure 1.870 +) 1.871 +{ 1.872 + NSSCKMDObject *mdObject = (NSSCKMDObject *)value; 1.873 + nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)mdObject->etc; 1.874 + nssCKMDFindSessionObjects *mdfso = (nssCKMDFindSessionObjects *)closure; 1.875 + CK_ULONG i, j; 1.876 + struct nodeStr *node; 1.877 + 1.878 + if( CKR_OK != mdfso->error ) { 1.879 + return; 1.880 + } 1.881 + 1.882 + for( i = 0; i < mdfso->ulCount; i++ ) { 1.883 + CK_ATTRIBUTE_PTR p = &mdfso->pTemplate[i]; 1.884 + 1.885 + for( j = 0; j < mdso->n; j++ ) { 1.886 + if( mdso->types[j] == p->type ) { 1.887 + if( !items_match(&mdso->attributes[j], p->pValue, p->ulValueLen) ) { 1.888 + return; 1.889 + } else { 1.890 + break; 1.891 + } 1.892 + } 1.893 + } 1.894 + 1.895 + if( j == mdso->n ) { 1.896 + /* Attribute not found */ 1.897 + return; 1.898 + } 1.899 + } 1.900 + 1.901 + /* Matches */ 1.902 + node = nss_ZNEW(mdfso->arena, struct nodeStr); 1.903 + if( (struct nodeStr *)NULL == node ) { 1.904 + mdfso->error = CKR_HOST_MEMORY; 1.905 + return; 1.906 + } 1.907 + 1.908 + node->mdObject = mdObject; 1.909 + node->next = mdfso->list; 1.910 + mdfso->list = node; 1.911 + 1.912 + return; 1.913 +} 1.914 + 1.915 +/* 1.916 + * nssCKMDFindSessionObjects_Create 1.917 + * 1.918 + */ 1.919 +NSS_IMPLEMENT NSSCKMDFindObjects * 1.920 +nssCKMDFindSessionObjects_Create 1.921 +( 1.922 + NSSCKFWToken *fwToken, 1.923 + CK_ATTRIBUTE_PTR pTemplate, 1.924 + CK_ULONG ulCount, 1.925 + CK_RV *pError 1.926 +) 1.927 +{ 1.928 + NSSArena *arena; 1.929 + nssCKMDFindSessionObjects *mdfso; 1.930 + nssCKFWHash *hash; 1.931 + NSSCKMDFindObjects *rv; 1.932 + 1.933 +#ifdef NSSDEBUG 1.934 + if (!pError) { 1.935 + return (NSSCKMDFindObjects *)NULL; 1.936 + } 1.937 + 1.938 + *pError = nssCKFWToken_verifyPointer(fwToken); 1.939 + if( CKR_OK != *pError ) { 1.940 + return (NSSCKMDFindObjects *)NULL; 1.941 + } 1.942 + 1.943 + if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) { 1.944 + *pError = CKR_ARGUMENTS_BAD; 1.945 + return (NSSCKMDFindObjects *)NULL; 1.946 + } 1.947 +#endif /* NSSDEBUG */ 1.948 + 1.949 + *pError = CKR_OK; 1.950 + 1.951 + hash = nssCKFWToken_GetSessionObjectHash(fwToken); 1.952 + if (!hash) { 1.953 + *pError= CKR_GENERAL_ERROR; 1.954 + return (NSSCKMDFindObjects *)NULL; 1.955 + } 1.956 + 1.957 + arena = NSSArena_Create(); 1.958 + if (!arena) { 1.959 + *pError = CKR_HOST_MEMORY; 1.960 + return (NSSCKMDFindObjects *)NULL; 1.961 + } 1.962 + 1.963 + mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects); 1.964 + if (!mdfso) { 1.965 + goto loser; 1.966 + } 1.967 + 1.968 + rv = nss_ZNEW(arena, NSSCKMDFindObjects); 1.969 + if(rv == NULL) { 1.970 + goto loser; 1.971 + } 1.972 + 1.973 + mdfso->error = CKR_OK; 1.974 + mdfso->pTemplate = pTemplate; 1.975 + mdfso->ulCount = ulCount; 1.976 + mdfso->hash = hash; 1.977 + 1.978 + nssCKFWHash_Iterate(hash, findfcn, mdfso); 1.979 + 1.980 + if( CKR_OK != mdfso->error ) { 1.981 + goto loser; 1.982 + } 1.983 + 1.984 + rv->etc = (void *)mdfso; 1.985 + rv->Final = nss_ckmdFindSessionObjects_Final; 1.986 + rv->Next = nss_ckmdFindSessionObjects_Next; 1.987 + 1.988 +#ifdef DEBUG 1.989 + if( (*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK ) { 1.990 + goto loser; 1.991 + } 1.992 +#endif /* DEBUG */ 1.993 + mdfso->arena = arena; 1.994 + 1.995 + return rv; 1.996 + 1.997 +loser: 1.998 + if (arena) { 1.999 + NSSArena_Destroy(arena); 1.1000 + } 1.1001 + if (*pError == CKR_OK) { 1.1002 + *pError = CKR_HOST_MEMORY; 1.1003 + } 1.1004 + return NULL; 1.1005 +} 1.1006 + 1.1007 +static void 1.1008 +nss_ckmdFindSessionObjects_Final 1.1009 +( 1.1010 + NSSCKMDFindObjects *mdFindObjects, 1.1011 + NSSCKFWFindObjects *fwFindObjects, 1.1012 + NSSCKMDSession *mdSession, 1.1013 + NSSCKFWSession *fwSession, 1.1014 + NSSCKMDToken *mdToken, 1.1015 + NSSCKFWToken *fwToken, 1.1016 + NSSCKMDInstance *mdInstance, 1.1017 + NSSCKFWInstance *fwInstance 1.1018 +) 1.1019 +{ 1.1020 + nssCKMDFindSessionObjects *mdfso; 1.1021 + 1.1022 +#ifdef NSSDEBUG 1.1023 + if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) { 1.1024 + return; 1.1025 + } 1.1026 +#endif /* NSSDEBUG */ 1.1027 + 1.1028 + mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc; 1.1029 + if (mdfso->arena) NSSArena_Destroy(mdfso->arena); 1.1030 + 1.1031 +#ifdef DEBUG 1.1032 + (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects); 1.1033 +#endif /* DEBUG */ 1.1034 + 1.1035 + return; 1.1036 +} 1.1037 + 1.1038 +static NSSCKMDObject * 1.1039 +nss_ckmdFindSessionObjects_Next 1.1040 +( 1.1041 + NSSCKMDFindObjects *mdFindObjects, 1.1042 + NSSCKFWFindObjects *fwFindObjects, 1.1043 + NSSCKMDSession *mdSession, 1.1044 + NSSCKFWSession *fwSession, 1.1045 + NSSCKMDToken *mdToken, 1.1046 + NSSCKFWToken *fwToken, 1.1047 + NSSCKMDInstance *mdInstance, 1.1048 + NSSCKFWInstance *fwInstance, 1.1049 + NSSArena *arena, 1.1050 + CK_RV *pError 1.1051 +) 1.1052 +{ 1.1053 + nssCKMDFindSessionObjects *mdfso; 1.1054 + NSSCKMDObject *rv = (NSSCKMDObject *)NULL; 1.1055 + 1.1056 +#ifdef NSSDEBUG 1.1057 + if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) { 1.1058 + return (NSSCKMDObject *)NULL; 1.1059 + } 1.1060 +#endif /* NSSDEBUG */ 1.1061 + 1.1062 + mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc; 1.1063 + 1.1064 + while (!rv) { 1.1065 + if( (struct nodeStr *)NULL == mdfso->list ) { 1.1066 + *pError = CKR_OK; 1.1067 + return (NSSCKMDObject *)NULL; 1.1068 + } 1.1069 + 1.1070 + if( nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject) ) { 1.1071 + rv = mdfso->list->mdObject; 1.1072 + } 1.1073 + 1.1074 + mdfso->list = mdfso->list->next; 1.1075 + } 1.1076 + 1.1077 + return rv; 1.1078 +}