Back to index

lightning-sunbird  0.9+nobinonly
sessobj.c
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 #ifdef DEBUG
00038 static const char CVS_ID[] = "@(#) $RCSfile: sessobj.c,v $ $Revision: 1.12 $ $Date: 2005/01/20 02:25:45 $";
00039 #endif /* DEBUG */
00040 
00041 /*
00042  * sessobj.c
00043  *
00044  * This file contains an NSSCKMDObject implementation for session 
00045  * objects.  The framework uses this implementation to manage
00046  * session objects when a Module doesn't wish to be bothered.
00047  */
00048 
00049 #ifndef CK_T
00050 #include "ck.h"
00051 #endif /* CK_T */
00052 
00053 /*
00054  * nssCKMDSessionObject
00055  *
00056  *  -- create --
00057  *  nssCKMDSessionObject_Create
00058  *
00059  *  -- EPV calls --
00060  *  nss_ckmdSessionObject_Finalize
00061  *  nss_ckmdSessionObject_IsTokenObject
00062  *  nss_ckmdSessionObject_GetAttributeCount
00063  *  nss_ckmdSessionObject_GetAttributeTypes
00064  *  nss_ckmdSessionObject_GetAttributeSize
00065  *  nss_ckmdSessionObject_GetAttribute
00066  *  nss_ckmdSessionObject_SetAttribute
00067  *  nss_ckmdSessionObject_GetObjectSize
00068  */
00069 
00070 struct nssCKMDSessionObjectStr {
00071   CK_ULONG n;
00072   NSSArena *arena;
00073   NSSItem *attributes;
00074   CK_ATTRIBUTE_TYPE_PTR types;
00075   nssCKFWHash *hash;
00076 };
00077 typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject;
00078 
00079 #ifdef DEBUG
00080 /*
00081  * But first, the pointer-tracking stuff.
00082  *
00083  * NOTE: the pointer-tracking support in NSS/base currently relies
00084  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
00085  * locking, which is tied into the runtime.  We need a pointer-tracker
00086  * implementation that uses the locks supplied through C_Initialize.
00087  * That support, however, can be filled in later.  So for now, I'll
00088  * just do this routines as no-ops.
00089  */
00090 
00091 static CK_RV
00092 nss_ckmdSessionObject_add_pointer
00093 (
00094   const NSSCKMDObject *mdObject
00095 )
00096 {
00097   return CKR_OK;
00098 }
00099 
00100 static CK_RV
00101 nss_ckmdSessionObject_remove_pointer
00102 (
00103   const NSSCKMDObject *mdObject
00104 )
00105 {
00106   return CKR_OK;
00107 }
00108 
00109 #ifdef NSS_DEBUG
00110 static CK_RV
00111 nss_ckmdSessionObject_verifyPointer
00112 (
00113   const NSSCKMDObject *mdObject
00114 )
00115 {
00116   return CKR_OK;
00117 }
00118 #endif
00119 
00120 #endif /* DEBUG */
00121 
00122 /*
00123  * We must forward-declare these routines
00124  */
00125 static void
00126 nss_ckmdSessionObject_Finalize
00127 (
00128   NSSCKMDObject *mdObject,
00129   NSSCKFWObject *fwObject,
00130   NSSCKMDSession *mdSession,
00131   NSSCKFWSession *fwSession,
00132   NSSCKMDToken *mdToken,
00133   NSSCKFWToken *fwToken,
00134   NSSCKMDInstance *mdInstance,
00135   NSSCKFWInstance *fwInstance
00136 );
00137 
00138 static CK_RV
00139 nss_ckmdSessionObject_Destroy
00140 (
00141   NSSCKMDObject *mdObject,
00142   NSSCKFWObject *fwObject,
00143   NSSCKMDSession *mdSession,
00144   NSSCKFWSession *fwSession,
00145   NSSCKMDToken *mdToken,
00146   NSSCKFWToken *fwToken,
00147   NSSCKMDInstance *mdInstance,
00148   NSSCKFWInstance *fwInstance
00149 );
00150 
00151 static CK_BBOOL
00152 nss_ckmdSessionObject_IsTokenObject
00153 (
00154   NSSCKMDObject *mdObject,
00155   NSSCKFWObject *fwObject,
00156   NSSCKMDSession *mdSession,
00157   NSSCKFWSession *fwSession,
00158   NSSCKMDToken *mdToken,
00159   NSSCKFWToken *fwToken,
00160   NSSCKMDInstance *mdInstance,
00161   NSSCKFWInstance *fwInstance
00162 );
00163 
00164 static CK_ULONG
00165 nss_ckmdSessionObject_GetAttributeCount
00166 (
00167   NSSCKMDObject *mdObject,
00168   NSSCKFWObject *fwObject,
00169   NSSCKMDSession *mdSession,
00170   NSSCKFWSession *fwSession,
00171   NSSCKMDToken *mdToken,
00172   NSSCKFWToken *fwToken,
00173   NSSCKMDInstance *mdInstance,
00174   NSSCKFWInstance *fwInstance,
00175   CK_RV *pError
00176 );
00177 
00178 static CK_RV
00179 nss_ckmdSessionObject_GetAttributeTypes
00180 (
00181   NSSCKMDObject *mdObject,
00182   NSSCKFWObject *fwObject,
00183   NSSCKMDSession *mdSession,
00184   NSSCKFWSession *fwSession,
00185   NSSCKMDToken *mdToken,
00186   NSSCKFWToken *fwToken,
00187   NSSCKMDInstance *mdInstance,
00188   NSSCKFWInstance *fwInstance,
00189   CK_ATTRIBUTE_TYPE_PTR typeArray,
00190   CK_ULONG ulCount
00191 );
00192 
00193 static CK_ULONG
00194 nss_ckmdSessionObject_GetAttributeSize
00195 (
00196   NSSCKMDObject *mdObject,
00197   NSSCKFWObject *fwObject,
00198   NSSCKMDSession *mdSession,
00199   NSSCKFWSession *fwSession,
00200   NSSCKMDToken *mdToken,
00201   NSSCKFWToken *fwToken,
00202   NSSCKMDInstance *mdInstance,
00203   NSSCKFWInstance *fwInstance,
00204   CK_ATTRIBUTE_TYPE attribute,
00205   CK_RV *pError
00206 );
00207 
00208 static NSSCKFWItem
00209 nss_ckmdSessionObject_GetAttribute
00210 (
00211   NSSCKMDObject *mdObject,
00212   NSSCKFWObject *fwObject,
00213   NSSCKMDSession *mdSession,
00214   NSSCKFWSession *fwSession,
00215   NSSCKMDToken *mdToken,
00216   NSSCKFWToken *fwToken,
00217   NSSCKMDInstance *mdInstance,
00218   NSSCKFWInstance *fwInstance,
00219   CK_ATTRIBUTE_TYPE attribute,
00220   CK_RV *pError
00221 );
00222 
00223 static CK_RV
00224 nss_ckmdSessionObject_SetAttribute
00225 (
00226   NSSCKMDObject *mdObject,
00227   NSSCKFWObject *fwObject,
00228   NSSCKMDSession *mdSession,
00229   NSSCKFWSession *fwSession,
00230   NSSCKMDToken *mdToken,
00231   NSSCKFWToken *fwToken,
00232   NSSCKMDInstance *mdInstance,
00233   NSSCKFWInstance *fwInstance,
00234   CK_ATTRIBUTE_TYPE attribute,
00235   NSSItem *value
00236 );
00237 
00238 static CK_ULONG
00239 nss_ckmdSessionObject_GetObjectSize
00240 (
00241   NSSCKMDObject *mdObject,
00242   NSSCKFWObject *fwObject,
00243   NSSCKMDSession *mdSession,
00244   NSSCKFWSession *fwSession,
00245   NSSCKMDToken *mdToken,
00246   NSSCKFWToken *fwToken,
00247   NSSCKMDInstance *mdInstance,
00248   NSSCKFWInstance *fwInstance,
00249   CK_RV *pError
00250 );
00251 
00252 /*
00253  * nssCKMDSessionObject_Create
00254  *
00255  */
00256 NSS_IMPLEMENT NSSCKMDObject *
00257 nssCKMDSessionObject_Create
00258 (
00259   NSSCKFWToken *fwToken,
00260   NSSArena *arena,
00261   CK_ATTRIBUTE_PTR attributes,
00262   CK_ULONG ulCount,
00263   CK_RV *pError
00264 )
00265 {
00266   NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL;
00267   nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL;
00268   CK_ULONG i;
00269   nssCKFWHash *hash;
00270 
00271   mdso = nss_ZNEW(arena, nssCKMDSessionObject);
00272   if( (nssCKMDSessionObject *)NULL == mdso ) {
00273     goto loser;
00274   }
00275 
00276   mdso->arena = arena;
00277   mdso->n = ulCount;
00278   mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount);
00279   if( (NSSItem *)NULL == mdso->attributes ) {
00280     goto loser;
00281   }
00282 
00283   mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount);
00284 
00285   for( i = 0; i < ulCount; i++ ) {
00286     mdso->types[i] = attributes[i].type;
00287     mdso->attributes[i].size = attributes[i].ulValueLen;
00288     mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen);
00289     if( (void *)NULL == mdso->attributes[i].data ) {
00290       goto loser;
00291     }
00292     (void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue,
00293       attributes[i].ulValueLen);
00294   }
00295 
00296   mdObject = nss_ZNEW(arena, NSSCKMDObject);
00297   if( (NSSCKMDObject *)NULL == mdObject ) {
00298     goto loser;
00299   }
00300 
00301   mdObject->etc = (void *)mdso;
00302   mdObject->Finalize = nss_ckmdSessionObject_Finalize;
00303   mdObject->Destroy = nss_ckmdSessionObject_Destroy;
00304   mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject;
00305   mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount;
00306   mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes;
00307   mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize;
00308   mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute;
00309   mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute;
00310   mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize;
00311 
00312   hash = nssCKFWToken_GetSessionObjectHash(fwToken);
00313   if( (nssCKFWHash *)NULL == hash ) {
00314     *pError = CKR_GENERAL_ERROR;
00315     goto loser;
00316   }
00317 
00318   mdso->hash = hash;
00319 
00320   *pError = nssCKFWHash_Add(hash, mdObject, mdObject);
00321   if( CKR_OK != *pError ) {
00322     goto loser;
00323   }
00324 
00325 #ifdef DEBUG
00326   if( CKR_OK != nss_ckmdSessionObject_add_pointer(mdObject) ) {
00327     goto loser;
00328   }
00329 #endif /* DEBUG */
00330 
00331   *pError = CKR_OK;
00332   return mdObject;
00333 
00334  loser:
00335   if( (nssCKMDSessionObject *)NULL != mdso ) {
00336     if( (NSSItem *)NULL != mdso->attributes ) {
00337       for( i = 0; i < ulCount; i++ ) {
00338         nss_ZFreeIf(mdso->attributes[i].data);
00339       }
00340 
00341       nss_ZFreeIf(mdso->attributes);
00342     }
00343 
00344     nss_ZFreeIf(mdso->types);
00345     nss_ZFreeIf(mdso);
00346   }
00347 
00348   nss_ZFreeIf(mdObject);
00349   *pError = CKR_HOST_MEMORY;
00350   return (NSSCKMDObject *)NULL;
00351 }
00352 
00353 /*
00354  * nss_ckmdSessionObject_Finalize
00355  *
00356  */
00357 static void
00358 nss_ckmdSessionObject_Finalize
00359 (
00360   NSSCKMDObject *mdObject,
00361   NSSCKFWObject *fwObject,
00362   NSSCKMDSession *mdSession,
00363   NSSCKFWSession *fwSession,
00364   NSSCKMDToken *mdToken,
00365   NSSCKFWToken *fwToken,
00366   NSSCKMDInstance *mdInstance,
00367   NSSCKFWInstance *fwInstance
00368 )
00369 {
00370   /* This shouldn't ever be called */
00371   return;
00372 }
00373 
00374 /*
00375  * nss_ckmdSessionObject_Destroy
00376  *
00377  */
00378 
00379 static CK_RV
00380 nss_ckmdSessionObject_Destroy
00381 (
00382   NSSCKMDObject *mdObject,
00383   NSSCKFWObject *fwObject,
00384   NSSCKMDSession *mdSession,
00385   NSSCKFWSession *fwSession,
00386   NSSCKMDToken *mdToken,
00387   NSSCKFWToken *fwToken,
00388   NSSCKMDInstance *mdInstance,
00389   NSSCKFWInstance *fwInstance
00390 )
00391 {
00392 #ifdef NSSDEBUG
00393   CK_RV error = CKR_OK;
00394 #endif /* NSSDEBUG */
00395   nssCKMDSessionObject *mdso;
00396   CK_ULONG i;
00397 
00398 #ifdef NSSDEBUG
00399   error = nss_ckmdSessionObject_verifyPointer(mdObject);
00400   if( CKR_OK != error ) {
00401     return error;
00402   }
00403 #endif /* NSSDEBUG */
00404 
00405   mdso = (nssCKMDSessionObject *)mdObject->etc;
00406 
00407   nssCKFWHash_Remove(mdso->hash, mdObject);
00408 
00409   for( i = 0; i < mdso->n; i++ ) {
00410     nss_ZFreeIf(mdso->attributes[i].data);
00411   }
00412   nss_ZFreeIf(mdso->attributes);
00413   nss_ZFreeIf(mdso->types);
00414   nss_ZFreeIf(mdso);
00415   nss_ZFreeIf(mdObject);
00416 
00417 #ifdef DEBUG
00418   (void)nss_ckmdSessionObject_remove_pointer(mdObject);
00419 #endif /* DEBUG */
00420 
00421   return CKR_OK;
00422 }
00423 
00424 /*
00425  * nss_ckmdSessionObject_IsTokenObject
00426  *
00427  */
00428 
00429 static CK_BBOOL
00430 nss_ckmdSessionObject_IsTokenObject
00431 (
00432   NSSCKMDObject *mdObject,
00433   NSSCKFWObject *fwObject,
00434   NSSCKMDSession *mdSession,
00435   NSSCKFWSession *fwSession,
00436   NSSCKMDToken *mdToken,
00437   NSSCKFWToken *fwToken,
00438   NSSCKMDInstance *mdInstance,
00439   NSSCKFWInstance *fwInstance
00440 )
00441 {
00442 #ifdef NSSDEBUG
00443   if( CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject) ) {
00444     return CK_FALSE;
00445   }
00446 #endif /* NSSDEBUG */
00447 
00448   /*
00449    * This implementation is only ever used for session objects.
00450    */
00451   return CK_FALSE;
00452 }
00453 
00454 /*
00455  * nss_ckmdSessionObject_GetAttributeCount
00456  *
00457  */
00458 static CK_ULONG
00459 nss_ckmdSessionObject_GetAttributeCount
00460 (
00461   NSSCKMDObject *mdObject,
00462   NSSCKFWObject *fwObject,
00463   NSSCKMDSession *mdSession,
00464   NSSCKFWSession *fwSession,
00465   NSSCKMDToken *mdToken,
00466   NSSCKFWToken *fwToken,
00467   NSSCKMDInstance *mdInstance,
00468   NSSCKFWInstance *fwInstance,
00469   CK_RV *pError
00470 )
00471 {
00472   nssCKMDSessionObject *obj;
00473 
00474 #ifdef NSSDEBUG
00475   if( (CK_RV *)NULL == pError ) {
00476     return 0;
00477   }
00478 
00479   *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
00480   if( CKR_OK != *pError ) {
00481     return 0;
00482   }
00483 
00484   /* We could even check all the other arguments, for sanity. */
00485 #endif /* NSSDEBUG */
00486 
00487   obj = (nssCKMDSessionObject *)mdObject->etc;
00488 
00489   return obj->n;
00490 }
00491 
00492 /*
00493  * nss_ckmdSessionObject_GetAttributeTypes
00494  *
00495  */
00496 static CK_RV
00497 nss_ckmdSessionObject_GetAttributeTypes
00498 (
00499   NSSCKMDObject *mdObject,
00500   NSSCKFWObject *fwObject,
00501   NSSCKMDSession *mdSession,
00502   NSSCKFWSession *fwSession,
00503   NSSCKMDToken *mdToken,
00504   NSSCKFWToken *fwToken,
00505   NSSCKMDInstance *mdInstance,
00506   NSSCKFWInstance *fwInstance,
00507   CK_ATTRIBUTE_TYPE_PTR typeArray,
00508   CK_ULONG ulCount
00509 )
00510 {
00511 #ifdef NSSDEBUG
00512   CK_RV error = CKR_OK;
00513 #endif /* NSSDEBUG */
00514   nssCKMDSessionObject *obj;
00515 
00516 #ifdef NSSDEBUG
00517   error = nss_ckmdSessionObject_verifyPointer(mdObject);
00518   if( CKR_OK != error ) {
00519     return error;
00520   }
00521 
00522   /* We could even check all the other arguments, for sanity. */
00523 #endif /* NSSDEBUG */
00524 
00525   obj = (nssCKMDSessionObject *)mdObject->etc;
00526 
00527   if( ulCount < obj->n ) {
00528     return CKR_BUFFER_TOO_SMALL;
00529   }
00530 
00531   (void)nsslibc_memcpy(typeArray, obj->types, 
00532     sizeof(CK_ATTRIBUTE_TYPE) * obj->n);
00533 
00534   return CKR_OK;
00535 }
00536 
00537 /*
00538  * nss_ckmdSessionObject_GetAttributeSize
00539  *
00540  */
00541 static CK_ULONG
00542 nss_ckmdSessionObject_GetAttributeSize
00543 (
00544   NSSCKMDObject *mdObject,
00545   NSSCKFWObject *fwObject,
00546   NSSCKMDSession *mdSession,
00547   NSSCKFWSession *fwSession,
00548   NSSCKMDToken *mdToken,
00549   NSSCKFWToken *fwToken,
00550   NSSCKMDInstance *mdInstance,
00551   NSSCKFWInstance *fwInstance,
00552   CK_ATTRIBUTE_TYPE attribute,
00553   CK_RV *pError
00554 )
00555 {
00556   nssCKMDSessionObject *obj;
00557   CK_ULONG i;
00558 
00559 #ifdef NSSDEBUG
00560   if( (CK_RV *)NULL == pError ) {
00561     return 0;
00562   }
00563 
00564   *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
00565   if( CKR_OK != *pError ) {
00566     return 0;
00567   }
00568 
00569   /* We could even check all the other arguments, for sanity. */
00570 #endif /* NSSDEBUG */
00571 
00572   obj = (nssCKMDSessionObject *)mdObject->etc;
00573 
00574   for( i = 0; i < obj->n; i++ ) {
00575     if( attribute == obj->types[i] ) {
00576       return (CK_ULONG)(obj->attributes[i].size);
00577     }
00578   }
00579 
00580   *pError = CKR_ATTRIBUTE_TYPE_INVALID;
00581   return 0;
00582 }
00583 
00584 /*
00585  * nss_ckmdSessionObject_GetAttribute
00586  *
00587  */
00588 static NSSCKFWItem
00589 nss_ckmdSessionObject_GetAttribute
00590 (
00591   NSSCKMDObject *mdObject,
00592   NSSCKFWObject *fwObject,
00593   NSSCKMDSession *mdSession,
00594   NSSCKFWSession *fwSession,
00595   NSSCKMDToken *mdToken,
00596   NSSCKFWToken *fwToken,
00597   NSSCKMDInstance *mdInstance,
00598   NSSCKFWInstance *fwInstance,
00599   CK_ATTRIBUTE_TYPE attribute,
00600   CK_RV *pError
00601 )
00602 {
00603   NSSCKFWItem item;
00604   nssCKMDSessionObject *obj;
00605   CK_ULONG i;
00606 
00607   item.needsFreeing = PR_FALSE;
00608   item.item = NULL;
00609 #ifdef NSSDEBUG
00610   if( (CK_RV *)NULL == pError ) {
00611     return item;
00612   }
00613 
00614   *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
00615   if( CKR_OK != *pError ) {
00616     return item;
00617   }
00618 
00619   /* We could even check all the other arguments, for sanity. */
00620 #endif /* NSSDEBUG */
00621 
00622   obj = (nssCKMDSessionObject *)mdObject->etc;
00623 
00624   for( i = 0; i < obj->n; i++ ) {
00625     if( attribute == obj->types[i] ) {
00626       item.item = &obj->attributes[i];
00627       return item;
00628     }
00629   }
00630 
00631   *pError = CKR_ATTRIBUTE_TYPE_INVALID;
00632   return item;
00633 }
00634 
00635 /*
00636  * nss_ckmdSessionObject_SetAttribute
00637  *
00638  */
00639 
00640 /*
00641  * Okay, so this implementation sucks.  It doesn't support removing
00642  * an attribute (if value == NULL), and could be more graceful about
00643  * memory.  It should allow "blank" slots in the arrays, with some
00644  * invalid attribute type, and then it could support removal much
00645  * more easily.  Do this later.
00646  */
00647 static CK_RV
00648 nss_ckmdSessionObject_SetAttribute
00649 (
00650   NSSCKMDObject *mdObject,
00651   NSSCKFWObject *fwObject,
00652   NSSCKMDSession *mdSession,
00653   NSSCKFWSession *fwSession,
00654   NSSCKMDToken *mdToken,
00655   NSSCKFWToken *fwToken,
00656   NSSCKMDInstance *mdInstance,
00657   NSSCKFWInstance *fwInstance,
00658   CK_ATTRIBUTE_TYPE attribute,
00659   NSSItem *value
00660 )
00661 {
00662   nssCKMDSessionObject *obj;
00663   CK_ULONG i;
00664   NSSItem n;
00665   NSSItem *ra;
00666   CK_ATTRIBUTE_TYPE_PTR rt;
00667 #ifdef NSSDEBUG
00668   CK_RV error;
00669 #endif /* NSSDEBUG */
00670 
00671 #ifdef NSSDEBUG
00672   error = nss_ckmdSessionObject_verifyPointer(mdObject);
00673   if( CKR_OK != error ) {
00674     return 0;
00675   }
00676 
00677   /* We could even check all the other arguments, for sanity. */
00678 #endif /* NSSDEBUG */
00679 
00680   obj = (nssCKMDSessionObject *)mdObject->etc;
00681 
00682   n.size = value->size;
00683   n.data = nss_ZAlloc(obj->arena, n.size);
00684   if( (void *)NULL == n.data ) {
00685     return CKR_HOST_MEMORY;
00686   }
00687   (void)nsslibc_memcpy(n.data, value->data, n.size);
00688 
00689   for( i = 0; i < obj->n; i++ ) {
00690     if( attribute == obj->types[i] ) {
00691       nss_ZFreeIf(obj->attributes[i].data);
00692       obj->attributes[i] = n;
00693       return CKR_OK;
00694     }
00695   }
00696 
00697   /*
00698    * It's new.
00699    */
00700 
00701   ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1));
00702   if( (NSSItem *)NULL == ra ) {
00703     nss_ZFreeIf(n.data);
00704     return CKR_HOST_MEMORY;
00705   }
00706 
00707   rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types, (obj->n + 1));
00708   if( (CK_ATTRIBUTE_TYPE_PTR)NULL == rt ) {
00709     nss_ZFreeIf(n.data);
00710     obj->attributes = (NSSItem *)nss_ZRealloc(ra, sizeof(NSSItem) * obj->n);
00711     if( (NSSItem *)NULL == obj->attributes ) {
00712       return CKR_GENERAL_ERROR;
00713     }
00714     return CKR_HOST_MEMORY;
00715   }
00716 
00717   obj->attributes = ra;
00718   obj->types = rt;
00719   obj->attributes[obj->n] = n;
00720   obj->types[obj->n] = attribute;
00721   obj->n++;
00722 
00723   return CKR_OK;
00724 }
00725 
00726 /*
00727  * nss_ckmdSessionObject_GetObjectSize
00728  *
00729  */
00730 static CK_ULONG
00731 nss_ckmdSessionObject_GetObjectSize
00732 (
00733   NSSCKMDObject *mdObject,
00734   NSSCKFWObject *fwObject,
00735   NSSCKMDSession *mdSession,
00736   NSSCKFWSession *fwSession,
00737   NSSCKMDToken *mdToken,
00738   NSSCKFWToken *fwToken,
00739   NSSCKMDInstance *mdInstance,
00740   NSSCKFWInstance *fwInstance,
00741   CK_RV *pError
00742 )
00743 {
00744   nssCKMDSessionObject *obj;
00745   CK_ULONG i;
00746   CK_ULONG rv = (CK_ULONG)0;
00747 
00748 #ifdef NSSDEBUG
00749   if( (CK_RV *)NULL == pError ) {
00750     return 0;
00751   }
00752 
00753   *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
00754   if( CKR_OK != *pError ) {
00755     return 0;
00756   }
00757 
00758   /* We could even check all the other arguments, for sanity. */
00759 #endif /* NSSDEBUG */
00760 
00761   obj = (nssCKMDSessionObject *)mdObject->etc;
00762 
00763   for( i = 0; i < obj->n; i++ ) {
00764     rv += obj->attributes[i].size;
00765   }
00766 
00767   rv += sizeof(NSSItem) * obj->n;
00768   rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n;
00769   rv += sizeof(nssCKMDSessionObject);
00770 
00771   return rv;
00772 }
00773 
00774 /*
00775  * nssCKMDFindSessionObjects
00776  *
00777  *  -- create --
00778  *  nssCKMDFindSessionObjects_Create
00779  *
00780  *  -- EPV calls --
00781  *  nss_ckmdFindSessionObjects_Final
00782  *  nss_ckmdFindSessionObjects_Next
00783  */
00784 
00785 struct nodeStr {
00786   struct nodeStr *next;
00787   NSSCKMDObject *mdObject;
00788 };
00789 
00790 struct nssCKMDFindSessionObjectsStr {
00791   NSSArena *arena;
00792   CK_RV error;
00793   CK_ATTRIBUTE_PTR pTemplate;
00794   CK_ULONG ulCount;
00795   struct nodeStr *list;
00796   nssCKFWHash *hash;
00797 
00798 };
00799 typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects;
00800 
00801 #ifdef DEBUG
00802 /*
00803  * But first, the pointer-tracking stuff.
00804  *
00805  * NOTE: the pointer-tracking support in NSS/base currently relies
00806  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
00807  * locking, which is tied into the runtime.  We need a pointer-tracker
00808  * implementation that uses the locks supplied through C_Initialize.
00809  * That support, however, can be filled in later.  So for now, I'll
00810  * just do this routines as no-ops.
00811  */
00812 
00813 static CK_RV
00814 nss_ckmdFindSessionObjects_add_pointer
00815 (
00816   const NSSCKMDFindObjects *mdFindObjects
00817 )
00818 {
00819   return CKR_OK;
00820 }
00821 
00822 static CK_RV
00823 nss_ckmdFindSessionObjects_remove_pointer
00824 (
00825   const NSSCKMDFindObjects *mdFindObjects
00826 )
00827 {
00828   return CKR_OK;
00829 }
00830 
00831 #ifdef NSS_DEBUG
00832 static CK_RV
00833 nss_ckmdFindSessionObjects_verifyPointer
00834 (
00835   const NSSCKMDFindObjects *mdFindObjects
00836 )
00837 {
00838   return CKR_OK;
00839 }
00840 #endif
00841 
00842 #endif /* DEBUG */
00843 
00844 /*
00845  * We must forward-declare these routines.
00846  */
00847 static void
00848 nss_ckmdFindSessionObjects_Final
00849 (
00850   NSSCKMDFindObjects *mdFindObjects,
00851   NSSCKFWFindObjects *fwFindObjects,
00852   NSSCKMDSession *mdSession,
00853   NSSCKFWSession *fwSession,
00854   NSSCKMDToken *mdToken,
00855   NSSCKFWToken *fwToken,
00856   NSSCKMDInstance *mdInstance,
00857   NSSCKFWInstance *fwInstance
00858 );
00859 
00860 static NSSCKMDObject *
00861 nss_ckmdFindSessionObjects_Next
00862 (
00863   NSSCKMDFindObjects *mdFindObjects,
00864   NSSCKFWFindObjects *fwFindObjects,
00865   NSSCKMDSession *mdSession,
00866   NSSCKFWSession *fwSession,
00867   NSSCKMDToken *mdToken,
00868   NSSCKFWToken *fwToken,
00869   NSSCKMDInstance *mdInstance,
00870   NSSCKFWInstance *fwInstance,
00871   NSSArena *arena,
00872   CK_RV *pError
00873 );
00874 
00875 static CK_BBOOL
00876 items_match
00877 (
00878   NSSItem *a,
00879   CK_VOID_PTR pValue,
00880   CK_ULONG ulValueLen
00881 )
00882 {
00883   if( a->size != ulValueLen ) {
00884     return CK_FALSE;
00885   }
00886 
00887   if( PR_TRUE == nsslibc_memequal(a->data, pValue, ulValueLen, (PRStatus *)NULL) ) {
00888     return CK_TRUE;
00889   } else {
00890     return CK_FALSE;
00891   }
00892 }
00893 
00894 /*
00895  * Our hashtable iterator
00896  */
00897 static void
00898 findfcn
00899 (
00900   const void *key,
00901   void *value,
00902   void *closure
00903 )
00904 {
00905   NSSCKMDObject *mdObject = (NSSCKMDObject *)value;
00906   nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)mdObject->etc;
00907   nssCKMDFindSessionObjects *mdfso = (nssCKMDFindSessionObjects *)closure;
00908   CK_ULONG i, j;
00909   struct nodeStr *node;
00910 
00911   if( CKR_OK != mdfso->error ) {
00912     return;
00913   }
00914 
00915   for( i = 0; i < mdfso->ulCount; i++ ) {
00916     CK_ATTRIBUTE_PTR p = &mdfso->pTemplate[i];
00917 
00918     for( j = 0; j < mdso->n; j++ ) {
00919       if( mdso->types[j] == p->type ) {
00920         if( !items_match(&mdso->attributes[j], p->pValue, p->ulValueLen) ) {
00921           return;
00922         } else {
00923           break;
00924         }
00925       }
00926     }
00927 
00928     if( j == mdso->n ) {
00929       /* Attribute not found */
00930       return;
00931     }
00932   }
00933 
00934   /* Matches */
00935   node = nss_ZNEW(mdfso->arena, struct nodeStr);
00936   if( (struct nodeStr *)NULL == node ) {
00937     mdfso->error = CKR_HOST_MEMORY;
00938     return;
00939   }
00940 
00941   node->mdObject = mdObject;
00942   node->next = mdfso->list;
00943   mdfso->list = node;
00944 
00945   return;
00946 }
00947 
00948 /*
00949  * nssCKMDFindSessionObjects_Create
00950  *
00951  */
00952 NSS_IMPLEMENT NSSCKMDFindObjects *
00953 nssCKMDFindSessionObjects_Create
00954 (
00955   NSSCKFWToken *fwToken,
00956   CK_ATTRIBUTE_PTR pTemplate,
00957   CK_ULONG ulCount,
00958   CK_RV *pError
00959 )
00960 {
00961   NSSArena *arena;
00962   nssCKMDFindSessionObjects *mdfso;
00963   nssCKFWHash *hash;
00964   NSSCKMDFindObjects *rv;
00965 
00966 #ifdef NSSDEBUG
00967   if( (CK_RV *)NULL == pError ) {
00968     return (NSSCKMDFindObjects *)NULL;
00969   }
00970 
00971   *pError = nssCKFWToken_verifyPointer(fwToken);
00972   if( CKR_OK != *pError ) {
00973     return (NSSCKMDFindObjects *)NULL;
00974   }
00975 
00976   if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
00977     *pError = CKR_ARGUMENTS_BAD;
00978     return (NSSCKMDFindObjects *)NULL;
00979   }
00980 #endif /* NSSDEBUG */
00981 
00982   hash = nssCKFWToken_GetSessionObjectHash(fwToken);
00983   if( (nssCKFWHash *)NULL == hash ) {
00984     *pError= CKR_GENERAL_ERROR;
00985     return (NSSCKMDFindObjects *)NULL;
00986   }
00987 
00988   arena = NSSArena_Create();
00989   if( (NSSArena *)NULL == arena ) {
00990     *pError = CKR_HOST_MEMORY;
00991     return (NSSCKMDFindObjects *)NULL;
00992   }
00993 
00994   mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects);
00995   if( (nssCKMDFindSessionObjects *)NULL == mdfso ) {
00996     NSSArena_Destroy(arena);
00997     *pError = CKR_HOST_MEMORY;
00998     return (NSSCKMDFindObjects *)NULL;
00999   }
01000 
01001   rv = nss_ZNEW(arena, NSSCKMDFindObjects);
01002 
01003   mdfso->error = CKR_OK;
01004   mdfso->pTemplate = pTemplate;
01005   mdfso->ulCount = ulCount;
01006   mdfso->hash = hash;
01007 
01008   nssCKFWHash_Iterate(hash, findfcn, mdfso);
01009 
01010   if( CKR_OK != mdfso->error ) {
01011     NSSArena_Destroy(arena);
01012     *pError = CKR_HOST_MEMORY;
01013     return (NSSCKMDFindObjects *)NULL;
01014   }
01015 
01016   rv->etc = (void *)mdfso;
01017   rv->Final = nss_ckmdFindSessionObjects_Final;
01018   rv->Next = nss_ckmdFindSessionObjects_Next;
01019 
01020 #ifdef DEBUG
01021   if( (*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK ) {
01022     NSSArena_Destroy(arena);
01023     return (NSSCKMDFindObjects *)NULL;
01024   }
01025 #endif /* DEBUG */    
01026   mdfso->arena = arena;
01027 
01028   return rv;
01029 }
01030 
01031 static void
01032 nss_ckmdFindSessionObjects_Final
01033 (
01034   NSSCKMDFindObjects *mdFindObjects,
01035   NSSCKFWFindObjects *fwFindObjects,
01036   NSSCKMDSession *mdSession,
01037   NSSCKFWSession *fwSession,
01038   NSSCKMDToken *mdToken,
01039   NSSCKFWToken *fwToken,
01040   NSSCKMDInstance *mdInstance,
01041   NSSCKFWInstance *fwInstance
01042 )
01043 {
01044   nssCKMDFindSessionObjects *mdfso;
01045 
01046 #ifdef NSSDEBUG
01047   if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
01048     return;
01049   }
01050 #endif /* NSSDEBUG */
01051 
01052   mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
01053   if (mdfso->arena) NSSArena_Destroy(mdfso->arena);
01054 
01055 #ifdef DEBUG
01056   (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects);
01057 #endif /* DEBUG */
01058 
01059   return;
01060 }
01061 
01062 static NSSCKMDObject *
01063 nss_ckmdFindSessionObjects_Next
01064 (
01065   NSSCKMDFindObjects *mdFindObjects,
01066   NSSCKFWFindObjects *fwFindObjects,
01067   NSSCKMDSession *mdSession,
01068   NSSCKFWSession *fwSession,
01069   NSSCKMDToken *mdToken,
01070   NSSCKFWToken *fwToken,
01071   NSSCKMDInstance *mdInstance,
01072   NSSCKFWInstance *fwInstance,
01073   NSSArena *arena,
01074   CK_RV *pError
01075 )
01076 {
01077   nssCKMDFindSessionObjects *mdfso;
01078   NSSCKMDObject *rv = (NSSCKMDObject *)NULL;
01079 
01080 #ifdef NSSDEBUG
01081   if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
01082     return (NSSCKMDObject *)NULL;
01083   }
01084 #endif /* NSSDEBUG */
01085 
01086   mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
01087 
01088   while( (NSSCKMDObject *)NULL == rv ) {
01089     if( (struct nodeStr *)NULL == mdfso->list ) {
01090       *pError = CKR_OK;
01091       return (NSSCKMDObject *)NULL;
01092     }
01093 
01094     if( nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject) ) {
01095       rv = mdfso->list->mdObject;
01096     }
01097 
01098     mdfso->list = mdfso->list->next;
01099   }
01100 
01101   return rv;
01102 }