security/nss/lib/ckfw/sessobj.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

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 /*
     6  * sessobj.c
     7  *
     8  * This file contains an NSSCKMDObject implementation for session 
     9  * objects.  The framework uses this implementation to manage
    10  * session objects when a Module doesn't wish to be bothered.
    11  */
    13 #ifndef CK_T
    14 #include "ck.h"
    15 #endif /* CK_T */
    17 /*
    18  * nssCKMDSessionObject
    19  *
    20  *  -- create --
    21  *  nssCKMDSessionObject_Create
    22  *
    23  *  -- EPV calls --
    24  *  nss_ckmdSessionObject_Finalize
    25  *  nss_ckmdSessionObject_IsTokenObject
    26  *  nss_ckmdSessionObject_GetAttributeCount
    27  *  nss_ckmdSessionObject_GetAttributeTypes
    28  *  nss_ckmdSessionObject_GetAttributeSize
    29  *  nss_ckmdSessionObject_GetAttribute
    30  *  nss_ckmdSessionObject_SetAttribute
    31  *  nss_ckmdSessionObject_GetObjectSize
    32  */
    34 struct nssCKMDSessionObjectStr {
    35   CK_ULONG n;
    36   NSSArena *arena;
    37   NSSItem *attributes;
    38   CK_ATTRIBUTE_TYPE_PTR types;
    39   nssCKFWHash *hash;
    40 };
    41 typedef struct nssCKMDSessionObjectStr nssCKMDSessionObject;
    43 #ifdef DEBUG
    44 /*
    45  * But first, the pointer-tracking stuff.
    46  *
    47  * NOTE: the pointer-tracking support in NSS/base currently relies
    48  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
    49  * locking, which is tied into the runtime.  We need a pointer-tracker
    50  * implementation that uses the locks supplied through C_Initialize.
    51  * That support, however, can be filled in later.  So for now, I'll
    52  * just do this routines as no-ops.
    53  */
    55 static CK_RV
    56 nss_ckmdSessionObject_add_pointer
    57 (
    58   const NSSCKMDObject *mdObject
    59 )
    60 {
    61   return CKR_OK;
    62 }
    64 static CK_RV
    65 nss_ckmdSessionObject_remove_pointer
    66 (
    67   const NSSCKMDObject *mdObject
    68 )
    69 {
    70   return CKR_OK;
    71 }
    73 #ifdef NSS_DEBUG
    74 static CK_RV
    75 nss_ckmdSessionObject_verifyPointer
    76 (
    77   const NSSCKMDObject *mdObject
    78 )
    79 {
    80   return CKR_OK;
    81 }
    82 #endif
    84 #endif /* DEBUG */
    86 /*
    87  * We must forward-declare these routines
    88  */
    89 static void
    90 nss_ckmdSessionObject_Finalize
    91 (
    92   NSSCKMDObject *mdObject,
    93   NSSCKFWObject *fwObject,
    94   NSSCKMDSession *mdSession,
    95   NSSCKFWSession *fwSession,
    96   NSSCKMDToken *mdToken,
    97   NSSCKFWToken *fwToken,
    98   NSSCKMDInstance *mdInstance,
    99   NSSCKFWInstance *fwInstance
   100 );
   102 static CK_RV
   103 nss_ckmdSessionObject_Destroy
   104 (
   105   NSSCKMDObject *mdObject,
   106   NSSCKFWObject *fwObject,
   107   NSSCKMDSession *mdSession,
   108   NSSCKFWSession *fwSession,
   109   NSSCKMDToken *mdToken,
   110   NSSCKFWToken *fwToken,
   111   NSSCKMDInstance *mdInstance,
   112   NSSCKFWInstance *fwInstance
   113 );
   115 static CK_BBOOL
   116 nss_ckmdSessionObject_IsTokenObject
   117 (
   118   NSSCKMDObject *mdObject,
   119   NSSCKFWObject *fwObject,
   120   NSSCKMDSession *mdSession,
   121   NSSCKFWSession *fwSession,
   122   NSSCKMDToken *mdToken,
   123   NSSCKFWToken *fwToken,
   124   NSSCKMDInstance *mdInstance,
   125   NSSCKFWInstance *fwInstance
   126 );
   128 static CK_ULONG
   129 nss_ckmdSessionObject_GetAttributeCount
   130 (
   131   NSSCKMDObject *mdObject,
   132   NSSCKFWObject *fwObject,
   133   NSSCKMDSession *mdSession,
   134   NSSCKFWSession *fwSession,
   135   NSSCKMDToken *mdToken,
   136   NSSCKFWToken *fwToken,
   137   NSSCKMDInstance *mdInstance,
   138   NSSCKFWInstance *fwInstance,
   139   CK_RV *pError
   140 );
   142 static CK_RV
   143 nss_ckmdSessionObject_GetAttributeTypes
   144 (
   145   NSSCKMDObject *mdObject,
   146   NSSCKFWObject *fwObject,
   147   NSSCKMDSession *mdSession,
   148   NSSCKFWSession *fwSession,
   149   NSSCKMDToken *mdToken,
   150   NSSCKFWToken *fwToken,
   151   NSSCKMDInstance *mdInstance,
   152   NSSCKFWInstance *fwInstance,
   153   CK_ATTRIBUTE_TYPE_PTR typeArray,
   154   CK_ULONG ulCount
   155 );
   157 static CK_ULONG
   158 nss_ckmdSessionObject_GetAttributeSize
   159 (
   160   NSSCKMDObject *mdObject,
   161   NSSCKFWObject *fwObject,
   162   NSSCKMDSession *mdSession,
   163   NSSCKFWSession *fwSession,
   164   NSSCKMDToken *mdToken,
   165   NSSCKFWToken *fwToken,
   166   NSSCKMDInstance *mdInstance,
   167   NSSCKFWInstance *fwInstance,
   168   CK_ATTRIBUTE_TYPE attribute,
   169   CK_RV *pError
   170 );
   172 static NSSCKFWItem
   173 nss_ckmdSessionObject_GetAttribute
   174 (
   175   NSSCKMDObject *mdObject,
   176   NSSCKFWObject *fwObject,
   177   NSSCKMDSession *mdSession,
   178   NSSCKFWSession *fwSession,
   179   NSSCKMDToken *mdToken,
   180   NSSCKFWToken *fwToken,
   181   NSSCKMDInstance *mdInstance,
   182   NSSCKFWInstance *fwInstance,
   183   CK_ATTRIBUTE_TYPE attribute,
   184   CK_RV *pError
   185 );
   187 static CK_RV
   188 nss_ckmdSessionObject_SetAttribute
   189 (
   190   NSSCKMDObject *mdObject,
   191   NSSCKFWObject *fwObject,
   192   NSSCKMDSession *mdSession,
   193   NSSCKFWSession *fwSession,
   194   NSSCKMDToken *mdToken,
   195   NSSCKFWToken *fwToken,
   196   NSSCKMDInstance *mdInstance,
   197   NSSCKFWInstance *fwInstance,
   198   CK_ATTRIBUTE_TYPE attribute,
   199   NSSItem *value
   200 );
   202 static CK_ULONG
   203 nss_ckmdSessionObject_GetObjectSize
   204 (
   205   NSSCKMDObject *mdObject,
   206   NSSCKFWObject *fwObject,
   207   NSSCKMDSession *mdSession,
   208   NSSCKFWSession *fwSession,
   209   NSSCKMDToken *mdToken,
   210   NSSCKFWToken *fwToken,
   211   NSSCKMDInstance *mdInstance,
   212   NSSCKFWInstance *fwInstance,
   213   CK_RV *pError
   214 );
   216 /*
   217  * nssCKMDSessionObject_Create
   218  *
   219  */
   220 NSS_IMPLEMENT NSSCKMDObject *
   221 nssCKMDSessionObject_Create
   222 (
   223   NSSCKFWToken *fwToken,
   224   NSSArena *arena,
   225   CK_ATTRIBUTE_PTR attributes,
   226   CK_ULONG ulCount,
   227   CK_RV *pError
   228 )
   229 {
   230   NSSCKMDObject *mdObject = (NSSCKMDObject *)NULL;
   231   nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)NULL;
   232   CK_ULONG i;
   233   nssCKFWHash *hash;
   235   *pError = CKR_OK;
   237   mdso = nss_ZNEW(arena, nssCKMDSessionObject);
   238   if (!mdso) {
   239     goto loser;
   240   }
   242   mdso->arena = arena;
   243   mdso->n = ulCount;
   244   mdso->attributes = nss_ZNEWARRAY(arena, NSSItem, ulCount);
   245   if (!mdso->attributes) {
   246     goto loser;
   247   }
   249   mdso->types = nss_ZNEWARRAY(arena, CK_ATTRIBUTE_TYPE, ulCount);
   250   if (!mdso->types) {
   251     goto loser;
   252   }
   253   for( i = 0; i < ulCount; i++ ) {
   254     mdso->types[i] = attributes[i].type;
   255     mdso->attributes[i].size = attributes[i].ulValueLen;
   256     mdso->attributes[i].data = nss_ZAlloc(arena, attributes[i].ulValueLen);
   257     if (!mdso->attributes[i].data) {
   258       goto loser;
   259     }
   260     (void)nsslibc_memcpy(mdso->attributes[i].data, attributes[i].pValue,
   261       attributes[i].ulValueLen);
   262   }
   264   mdObject = nss_ZNEW(arena, NSSCKMDObject);
   265   if (!mdObject) {
   266     goto loser;
   267   }
   269   mdObject->etc = (void *)mdso;
   270   mdObject->Finalize = nss_ckmdSessionObject_Finalize;
   271   mdObject->Destroy = nss_ckmdSessionObject_Destroy;
   272   mdObject->IsTokenObject = nss_ckmdSessionObject_IsTokenObject;
   273   mdObject->GetAttributeCount = nss_ckmdSessionObject_GetAttributeCount;
   274   mdObject->GetAttributeTypes = nss_ckmdSessionObject_GetAttributeTypes;
   275   mdObject->GetAttributeSize = nss_ckmdSessionObject_GetAttributeSize;
   276   mdObject->GetAttribute = nss_ckmdSessionObject_GetAttribute;
   277   mdObject->SetAttribute = nss_ckmdSessionObject_SetAttribute;
   278   mdObject->GetObjectSize = nss_ckmdSessionObject_GetObjectSize;
   280   hash = nssCKFWToken_GetSessionObjectHash(fwToken);
   281   if (!hash) {
   282     *pError = CKR_GENERAL_ERROR;
   283     goto loser;
   284   }
   286   mdso->hash = hash;
   288   *pError = nssCKFWHash_Add(hash, mdObject, mdObject);
   289   if( CKR_OK != *pError ) {
   290     goto loser;
   291   }
   293 #ifdef DEBUG
   294   if(( *pError = nss_ckmdSessionObject_add_pointer(mdObject)) != CKR_OK ) {
   295     goto loser;
   296   }
   297 #endif /* DEBUG */
   299   return mdObject;
   301  loser:
   302   if (mdso) {
   303     if (mdso->attributes) {
   304       for( i = 0; i < ulCount; i++ ) {
   305         nss_ZFreeIf(mdso->attributes[i].data);
   306       }
   307       nss_ZFreeIf(mdso->attributes);
   308     }
   309     nss_ZFreeIf(mdso->types);
   310     nss_ZFreeIf(mdso);
   311   }
   313   nss_ZFreeIf(mdObject);
   314   if (*pError == CKR_OK) {
   315       *pError = CKR_HOST_MEMORY;
   316   }
   317   return (NSSCKMDObject *)NULL;
   318 }
   320 /*
   321  * nss_ckmdSessionObject_Finalize
   322  *
   323  */
   324 static void
   325 nss_ckmdSessionObject_Finalize
   326 (
   327   NSSCKMDObject *mdObject,
   328   NSSCKFWObject *fwObject,
   329   NSSCKMDSession *mdSession,
   330   NSSCKFWSession *fwSession,
   331   NSSCKMDToken *mdToken,
   332   NSSCKFWToken *fwToken,
   333   NSSCKMDInstance *mdInstance,
   334   NSSCKFWInstance *fwInstance
   335 )
   336 {
   337   /* This shouldn't ever be called */
   338   return;
   339 }
   341 /*
   342  * nss_ckmdSessionObject_Destroy
   343  *
   344  */
   346 static CK_RV
   347 nss_ckmdSessionObject_Destroy
   348 (
   349   NSSCKMDObject *mdObject,
   350   NSSCKFWObject *fwObject,
   351   NSSCKMDSession *mdSession,
   352   NSSCKFWSession *fwSession,
   353   NSSCKMDToken *mdToken,
   354   NSSCKFWToken *fwToken,
   355   NSSCKMDInstance *mdInstance,
   356   NSSCKFWInstance *fwInstance
   357 )
   358 {
   359 #ifdef NSSDEBUG
   360   CK_RV error = CKR_OK;
   361 #endif /* NSSDEBUG */
   362   nssCKMDSessionObject *mdso;
   363   CK_ULONG i;
   365 #ifdef NSSDEBUG
   366   error = nss_ckmdSessionObject_verifyPointer(mdObject);
   367   if( CKR_OK != error ) {
   368     return error;
   369   }
   370 #endif /* NSSDEBUG */
   372   mdso = (nssCKMDSessionObject *)mdObject->etc;
   374   nssCKFWHash_Remove(mdso->hash, mdObject);
   376   for( i = 0; i < mdso->n; i++ ) {
   377     nss_ZFreeIf(mdso->attributes[i].data);
   378   }
   379   nss_ZFreeIf(mdso->attributes);
   380   nss_ZFreeIf(mdso->types);
   381   nss_ZFreeIf(mdso);
   382   nss_ZFreeIf(mdObject);
   384 #ifdef DEBUG
   385   (void)nss_ckmdSessionObject_remove_pointer(mdObject);
   386 #endif /* DEBUG */
   388   return CKR_OK;
   389 }
   391 /*
   392  * nss_ckmdSessionObject_IsTokenObject
   393  *
   394  */
   396 static CK_BBOOL
   397 nss_ckmdSessionObject_IsTokenObject
   398 (
   399   NSSCKMDObject *mdObject,
   400   NSSCKFWObject *fwObject,
   401   NSSCKMDSession *mdSession,
   402   NSSCKFWSession *fwSession,
   403   NSSCKMDToken *mdToken,
   404   NSSCKFWToken *fwToken,
   405   NSSCKMDInstance *mdInstance,
   406   NSSCKFWInstance *fwInstance
   407 )
   408 {
   409 #ifdef NSSDEBUG
   410   if( CKR_OK != nss_ckmdSessionObject_verifyPointer(mdObject) ) {
   411     return CK_FALSE;
   412   }
   413 #endif /* NSSDEBUG */
   415   /*
   416    * This implementation is only ever used for session objects.
   417    */
   418   return CK_FALSE;
   419 }
   421 /*
   422  * nss_ckmdSessionObject_GetAttributeCount
   423  *
   424  */
   425 static CK_ULONG
   426 nss_ckmdSessionObject_GetAttributeCount
   427 (
   428   NSSCKMDObject *mdObject,
   429   NSSCKFWObject *fwObject,
   430   NSSCKMDSession *mdSession,
   431   NSSCKFWSession *fwSession,
   432   NSSCKMDToken *mdToken,
   433   NSSCKFWToken *fwToken,
   434   NSSCKMDInstance *mdInstance,
   435   NSSCKFWInstance *fwInstance,
   436   CK_RV *pError
   437 )
   438 {
   439   nssCKMDSessionObject *obj;
   441 #ifdef NSSDEBUG
   442   if (!pError) {
   443     return 0;
   444   }
   446   *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
   447   if( CKR_OK != *pError ) {
   448     return 0;
   449   }
   451   /* We could even check all the other arguments, for sanity. */
   452 #endif /* NSSDEBUG */
   454   obj = (nssCKMDSessionObject *)mdObject->etc;
   456   return obj->n;
   457 }
   459 /*
   460  * nss_ckmdSessionObject_GetAttributeTypes
   461  *
   462  */
   463 static CK_RV
   464 nss_ckmdSessionObject_GetAttributeTypes
   465 (
   466   NSSCKMDObject *mdObject,
   467   NSSCKFWObject *fwObject,
   468   NSSCKMDSession *mdSession,
   469   NSSCKFWSession *fwSession,
   470   NSSCKMDToken *mdToken,
   471   NSSCKFWToken *fwToken,
   472   NSSCKMDInstance *mdInstance,
   473   NSSCKFWInstance *fwInstance,
   474   CK_ATTRIBUTE_TYPE_PTR typeArray,
   475   CK_ULONG ulCount
   476 )
   477 {
   478 #ifdef NSSDEBUG
   479   CK_RV error = CKR_OK;
   480 #endif /* NSSDEBUG */
   481   nssCKMDSessionObject *obj;
   483 #ifdef NSSDEBUG
   484   error = nss_ckmdSessionObject_verifyPointer(mdObject);
   485   if( CKR_OK != error ) {
   486     return error;
   487   }
   489   /* We could even check all the other arguments, for sanity. */
   490 #endif /* NSSDEBUG */
   492   obj = (nssCKMDSessionObject *)mdObject->etc;
   494   if( ulCount < obj->n ) {
   495     return CKR_BUFFER_TOO_SMALL;
   496   }
   498   (void)nsslibc_memcpy(typeArray, obj->types, 
   499     sizeof(CK_ATTRIBUTE_TYPE) * obj->n);
   501   return CKR_OK;
   502 }
   504 /*
   505  * nss_ckmdSessionObject_GetAttributeSize
   506  *
   507  */
   508 static CK_ULONG
   509 nss_ckmdSessionObject_GetAttributeSize
   510 (
   511   NSSCKMDObject *mdObject,
   512   NSSCKFWObject *fwObject,
   513   NSSCKMDSession *mdSession,
   514   NSSCKFWSession *fwSession,
   515   NSSCKMDToken *mdToken,
   516   NSSCKFWToken *fwToken,
   517   NSSCKMDInstance *mdInstance,
   518   NSSCKFWInstance *fwInstance,
   519   CK_ATTRIBUTE_TYPE attribute,
   520   CK_RV *pError
   521 )
   522 {
   523   nssCKMDSessionObject *obj;
   524   CK_ULONG i;
   526 #ifdef NSSDEBUG
   527   if (!pError) {
   528     return 0;
   529   }
   531   *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
   532   if( CKR_OK != *pError ) {
   533     return 0;
   534   }
   536   /* We could even check all the other arguments, for sanity. */
   537 #endif /* NSSDEBUG */
   539   obj = (nssCKMDSessionObject *)mdObject->etc;
   541   for( i = 0; i < obj->n; i++ ) {
   542     if( attribute == obj->types[i] ) {
   543       return (CK_ULONG)(obj->attributes[i].size);
   544     }
   545   }
   547   *pError = CKR_ATTRIBUTE_TYPE_INVALID;
   548   return 0;
   549 }
   551 /*
   552  * nss_ckmdSessionObject_GetAttribute
   553  *
   554  */
   555 static NSSCKFWItem
   556 nss_ckmdSessionObject_GetAttribute
   557 (
   558   NSSCKMDObject *mdObject,
   559   NSSCKFWObject *fwObject,
   560   NSSCKMDSession *mdSession,
   561   NSSCKFWSession *fwSession,
   562   NSSCKMDToken *mdToken,
   563   NSSCKFWToken *fwToken,
   564   NSSCKMDInstance *mdInstance,
   565   NSSCKFWInstance *fwInstance,
   566   CK_ATTRIBUTE_TYPE attribute,
   567   CK_RV *pError
   568 )
   569 {
   570   NSSCKFWItem item;
   571   nssCKMDSessionObject *obj;
   572   CK_ULONG i;
   574   item.needsFreeing = PR_FALSE;
   575   item.item = NULL;
   576 #ifdef NSSDEBUG
   577   if (!pError) {
   578     return item;
   579   }
   581   *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
   582   if( CKR_OK != *pError ) {
   583     return item;
   584   }
   586   /* We could even check all the other arguments, for sanity. */
   587 #endif /* NSSDEBUG */
   589   obj = (nssCKMDSessionObject *)mdObject->etc;
   591   for( i = 0; i < obj->n; i++ ) {
   592     if( attribute == obj->types[i] ) {
   593       item.item = &obj->attributes[i];
   594       return item;
   595     }
   596   }
   598   *pError = CKR_ATTRIBUTE_TYPE_INVALID;
   599   return item;
   600 }
   602 /*
   603  * nss_ckmdSessionObject_SetAttribute
   604  *
   605  */
   607 /*
   608  * Okay, so this implementation sucks.  It doesn't support removing
   609  * an attribute (if value == NULL), and could be more graceful about
   610  * memory.  It should allow "blank" slots in the arrays, with some
   611  * invalid attribute type, and then it could support removal much
   612  * more easily.  Do this later.
   613  */
   614 static CK_RV
   615 nss_ckmdSessionObject_SetAttribute
   616 (
   617   NSSCKMDObject *mdObject,
   618   NSSCKFWObject *fwObject,
   619   NSSCKMDSession *mdSession,
   620   NSSCKFWSession *fwSession,
   621   NSSCKMDToken *mdToken,
   622   NSSCKFWToken *fwToken,
   623   NSSCKMDInstance *mdInstance,
   624   NSSCKFWInstance *fwInstance,
   625   CK_ATTRIBUTE_TYPE attribute,
   626   NSSItem *value
   627 )
   628 {
   629   nssCKMDSessionObject *obj;
   630   CK_ULONG i;
   631   NSSItem n;
   632   NSSItem *ra;
   633   CK_ATTRIBUTE_TYPE_PTR rt;
   634 #ifdef NSSDEBUG
   635   CK_RV error;
   636 #endif /* NSSDEBUG */
   638 #ifdef NSSDEBUG
   639   error = nss_ckmdSessionObject_verifyPointer(mdObject);
   640   if( CKR_OK != error ) {
   641     return 0;
   642   }
   644   /* We could even check all the other arguments, for sanity. */
   645 #endif /* NSSDEBUG */
   647   obj = (nssCKMDSessionObject *)mdObject->etc;
   649   n.size = value->size;
   650   n.data = nss_ZAlloc(obj->arena, n.size);
   651   if (!n.data) {
   652     return CKR_HOST_MEMORY;
   653   }
   654   (void)nsslibc_memcpy(n.data, value->data, n.size);
   656   for( i = 0; i < obj->n; i++ ) {
   657     if( attribute == obj->types[i] ) {
   658       nss_ZFreeIf(obj->attributes[i].data);
   659       obj->attributes[i] = n;
   660       return CKR_OK;
   661     }
   662   }
   664   /*
   665    * It's new.
   666    */
   668   ra = (NSSItem *)nss_ZRealloc(obj->attributes, sizeof(NSSItem) * (obj->n + 1));
   669   if (!ra) {
   670     nss_ZFreeIf(n.data);
   671     return CKR_HOST_MEMORY;
   672   }
   673   obj->attributes = ra;
   675   rt = (CK_ATTRIBUTE_TYPE_PTR)nss_ZRealloc(obj->types, 
   676                                       sizeof(CK_ATTRIBUTE_TYPE) * (obj->n + 1));
   677   if (!rt) {
   678     nss_ZFreeIf(n.data);
   679     return CKR_HOST_MEMORY;
   680   }
   682   obj->types = rt;
   683   obj->attributes[obj->n] = n;
   684   obj->types[obj->n] = attribute;
   685   obj->n++;
   687   return CKR_OK;
   688 }
   690 /*
   691  * nss_ckmdSessionObject_GetObjectSize
   692  *
   693  */
   694 static CK_ULONG
   695 nss_ckmdSessionObject_GetObjectSize
   696 (
   697   NSSCKMDObject *mdObject,
   698   NSSCKFWObject *fwObject,
   699   NSSCKMDSession *mdSession,
   700   NSSCKFWSession *fwSession,
   701   NSSCKMDToken *mdToken,
   702   NSSCKFWToken *fwToken,
   703   NSSCKMDInstance *mdInstance,
   704   NSSCKFWInstance *fwInstance,
   705   CK_RV *pError
   706 )
   707 {
   708   nssCKMDSessionObject *obj;
   709   CK_ULONG i;
   710   CK_ULONG rv = (CK_ULONG)0;
   712 #ifdef NSSDEBUG
   713   if (!pError) {
   714     return 0;
   715   }
   717   *pError = nss_ckmdSessionObject_verifyPointer(mdObject);
   718   if( CKR_OK != *pError ) {
   719     return 0;
   720   }
   722   /* We could even check all the other arguments, for sanity. */
   723 #endif /* NSSDEBUG */
   725   obj = (nssCKMDSessionObject *)mdObject->etc;
   727   for( i = 0; i < obj->n; i++ ) {
   728     rv += obj->attributes[i].size;
   729   }
   731   rv += sizeof(NSSItem) * obj->n;
   732   rv += sizeof(CK_ATTRIBUTE_TYPE) * obj->n;
   733   rv += sizeof(nssCKMDSessionObject);
   735   return rv;
   736 }
   738 /*
   739  * nssCKMDFindSessionObjects
   740  *
   741  *  -- create --
   742  *  nssCKMDFindSessionObjects_Create
   743  *
   744  *  -- EPV calls --
   745  *  nss_ckmdFindSessionObjects_Final
   746  *  nss_ckmdFindSessionObjects_Next
   747  */
   749 struct nodeStr {
   750   struct nodeStr *next;
   751   NSSCKMDObject *mdObject;
   752 };
   754 struct nssCKMDFindSessionObjectsStr {
   755   NSSArena *arena;
   756   CK_RV error;
   757   CK_ATTRIBUTE_PTR pTemplate;
   758   CK_ULONG ulCount;
   759   struct nodeStr *list;
   760   nssCKFWHash *hash;
   762 };
   763 typedef struct nssCKMDFindSessionObjectsStr nssCKMDFindSessionObjects;
   765 #ifdef DEBUG
   766 /*
   767  * But first, the pointer-tracking stuff.
   768  *
   769  * NOTE: the pointer-tracking support in NSS/base currently relies
   770  * upon NSPR's CallOnce support.  That, however, relies upon NSPR's
   771  * locking, which is tied into the runtime.  We need a pointer-tracker
   772  * implementation that uses the locks supplied through C_Initialize.
   773  * That support, however, can be filled in later.  So for now, I'll
   774  * just do this routines as no-ops.
   775  */
   777 static CK_RV
   778 nss_ckmdFindSessionObjects_add_pointer
   779 (
   780   const NSSCKMDFindObjects *mdFindObjects
   781 )
   782 {
   783   return CKR_OK;
   784 }
   786 static CK_RV
   787 nss_ckmdFindSessionObjects_remove_pointer
   788 (
   789   const NSSCKMDFindObjects *mdFindObjects
   790 )
   791 {
   792   return CKR_OK;
   793 }
   795 #ifdef NSS_DEBUG
   796 static CK_RV
   797 nss_ckmdFindSessionObjects_verifyPointer
   798 (
   799   const NSSCKMDFindObjects *mdFindObjects
   800 )
   801 {
   802   return CKR_OK;
   803 }
   804 #endif
   806 #endif /* DEBUG */
   808 /*
   809  * We must forward-declare these routines.
   810  */
   811 static void
   812 nss_ckmdFindSessionObjects_Final
   813 (
   814   NSSCKMDFindObjects *mdFindObjects,
   815   NSSCKFWFindObjects *fwFindObjects,
   816   NSSCKMDSession *mdSession,
   817   NSSCKFWSession *fwSession,
   818   NSSCKMDToken *mdToken,
   819   NSSCKFWToken *fwToken,
   820   NSSCKMDInstance *mdInstance,
   821   NSSCKFWInstance *fwInstance
   822 );
   824 static NSSCKMDObject *
   825 nss_ckmdFindSessionObjects_Next
   826 (
   827   NSSCKMDFindObjects *mdFindObjects,
   828   NSSCKFWFindObjects *fwFindObjects,
   829   NSSCKMDSession *mdSession,
   830   NSSCKFWSession *fwSession,
   831   NSSCKMDToken *mdToken,
   832   NSSCKFWToken *fwToken,
   833   NSSCKMDInstance *mdInstance,
   834   NSSCKFWInstance *fwInstance,
   835   NSSArena *arena,
   836   CK_RV *pError
   837 );
   839 static CK_BBOOL
   840 items_match
   841 (
   842   NSSItem *a,
   843   CK_VOID_PTR pValue,
   844   CK_ULONG ulValueLen
   845 )
   846 {
   847   if( a->size != ulValueLen ) {
   848     return CK_FALSE;
   849   }
   851   if( PR_TRUE == nsslibc_memequal(a->data, pValue, ulValueLen, (PRStatus *)NULL) ) {
   852     return CK_TRUE;
   853   } else {
   854     return CK_FALSE;
   855   }
   856 }
   858 /*
   859  * Our hashtable iterator
   860  */
   861 static void
   862 findfcn
   863 (
   864   const void *key,
   865   void *value,
   866   void *closure
   867 )
   868 {
   869   NSSCKMDObject *mdObject = (NSSCKMDObject *)value;
   870   nssCKMDSessionObject *mdso = (nssCKMDSessionObject *)mdObject->etc;
   871   nssCKMDFindSessionObjects *mdfso = (nssCKMDFindSessionObjects *)closure;
   872   CK_ULONG i, j;
   873   struct nodeStr *node;
   875   if( CKR_OK != mdfso->error ) {
   876     return;
   877   }
   879   for( i = 0; i < mdfso->ulCount; i++ ) {
   880     CK_ATTRIBUTE_PTR p = &mdfso->pTemplate[i];
   882     for( j = 0; j < mdso->n; j++ ) {
   883       if( mdso->types[j] == p->type ) {
   884         if( !items_match(&mdso->attributes[j], p->pValue, p->ulValueLen) ) {
   885           return;
   886         } else {
   887           break;
   888         }
   889       }
   890     }
   892     if( j == mdso->n ) {
   893       /* Attribute not found */
   894       return;
   895     }
   896   }
   898   /* Matches */
   899   node = nss_ZNEW(mdfso->arena, struct nodeStr);
   900   if( (struct nodeStr *)NULL == node ) {
   901     mdfso->error = CKR_HOST_MEMORY;
   902     return;
   903   }
   905   node->mdObject = mdObject;
   906   node->next = mdfso->list;
   907   mdfso->list = node;
   909   return;
   910 }
   912 /*
   913  * nssCKMDFindSessionObjects_Create
   914  *
   915  */
   916 NSS_IMPLEMENT NSSCKMDFindObjects *
   917 nssCKMDFindSessionObjects_Create
   918 (
   919   NSSCKFWToken *fwToken,
   920   CK_ATTRIBUTE_PTR pTemplate,
   921   CK_ULONG ulCount,
   922   CK_RV *pError
   923 )
   924 {
   925   NSSArena *arena;
   926   nssCKMDFindSessionObjects *mdfso;
   927   nssCKFWHash *hash;
   928   NSSCKMDFindObjects *rv;
   930 #ifdef NSSDEBUG
   931   if (!pError) {
   932     return (NSSCKMDFindObjects *)NULL;
   933   }
   935   *pError = nssCKFWToken_verifyPointer(fwToken);
   936   if( CKR_OK != *pError ) {
   937     return (NSSCKMDFindObjects *)NULL;
   938   }
   940   if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
   941     *pError = CKR_ARGUMENTS_BAD;
   942     return (NSSCKMDFindObjects *)NULL;
   943   }
   944 #endif /* NSSDEBUG */
   946   *pError = CKR_OK;
   948   hash = nssCKFWToken_GetSessionObjectHash(fwToken);
   949   if (!hash) {
   950     *pError= CKR_GENERAL_ERROR;
   951     return (NSSCKMDFindObjects *)NULL;
   952   }
   954   arena = NSSArena_Create();
   955   if (!arena) {
   956     *pError = CKR_HOST_MEMORY;
   957     return (NSSCKMDFindObjects *)NULL;
   958   }
   960   mdfso = nss_ZNEW(arena, nssCKMDFindSessionObjects);
   961   if (!mdfso) {
   962     goto loser;
   963   }
   965   rv = nss_ZNEW(arena, NSSCKMDFindObjects);
   966   if(rv == NULL) {
   967     goto loser;
   968   }
   970   mdfso->error = CKR_OK;
   971   mdfso->pTemplate = pTemplate;
   972   mdfso->ulCount = ulCount;
   973   mdfso->hash = hash;
   975   nssCKFWHash_Iterate(hash, findfcn, mdfso);
   977   if( CKR_OK != mdfso->error ) {
   978     goto loser;
   979   }
   981   rv->etc = (void *)mdfso;
   982   rv->Final = nss_ckmdFindSessionObjects_Final;
   983   rv->Next = nss_ckmdFindSessionObjects_Next;
   985 #ifdef DEBUG
   986   if( (*pError = nss_ckmdFindSessionObjects_add_pointer(rv)) != CKR_OK ) {
   987     goto loser;
   988   }
   989 #endif /* DEBUG */    
   990   mdfso->arena = arena;
   992   return rv;
   994 loser:
   995   if (arena) {
   996     NSSArena_Destroy(arena);
   997   }
   998   if (*pError == CKR_OK) {
   999       *pError = CKR_HOST_MEMORY;
  1001   return NULL;
  1004 static void
  1005 nss_ckmdFindSessionObjects_Final
  1007   NSSCKMDFindObjects *mdFindObjects,
  1008   NSSCKFWFindObjects *fwFindObjects,
  1009   NSSCKMDSession *mdSession,
  1010   NSSCKFWSession *fwSession,
  1011   NSSCKMDToken *mdToken,
  1012   NSSCKFWToken *fwToken,
  1013   NSSCKMDInstance *mdInstance,
  1014   NSSCKFWInstance *fwInstance
  1017   nssCKMDFindSessionObjects *mdfso;
  1019 #ifdef NSSDEBUG
  1020   if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
  1021     return;
  1023 #endif /* NSSDEBUG */
  1025   mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
  1026   if (mdfso->arena) NSSArena_Destroy(mdfso->arena);
  1028 #ifdef DEBUG
  1029   (void)nss_ckmdFindSessionObjects_remove_pointer(mdFindObjects);
  1030 #endif /* DEBUG */
  1032   return;
  1035 static NSSCKMDObject *
  1036 nss_ckmdFindSessionObjects_Next
  1038   NSSCKMDFindObjects *mdFindObjects,
  1039   NSSCKFWFindObjects *fwFindObjects,
  1040   NSSCKMDSession *mdSession,
  1041   NSSCKFWSession *fwSession,
  1042   NSSCKMDToken *mdToken,
  1043   NSSCKFWToken *fwToken,
  1044   NSSCKMDInstance *mdInstance,
  1045   NSSCKFWInstance *fwInstance,
  1046   NSSArena *arena,
  1047   CK_RV *pError
  1050   nssCKMDFindSessionObjects *mdfso;
  1051   NSSCKMDObject *rv = (NSSCKMDObject *)NULL;
  1053 #ifdef NSSDEBUG
  1054   if( CKR_OK != nss_ckmdFindSessionObjects_verifyPointer(mdFindObjects) ) {
  1055     return (NSSCKMDObject *)NULL;
  1057 #endif /* NSSDEBUG */
  1059   mdfso = (nssCKMDFindSessionObjects *)mdFindObjects->etc;
  1061   while (!rv) {
  1062     if( (struct nodeStr *)NULL == mdfso->list ) {
  1063       *pError = CKR_OK;
  1064       return (NSSCKMDObject *)NULL;
  1067     if( nssCKFWHash_Exists(mdfso->hash, mdfso->list->mdObject) ) {
  1068       rv = mdfso->list->mdObject;
  1071     mdfso->list = mdfso->list->next;
  1074   return rv;

mercurial