object.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:22k
源码类别:

CA认证

开发平台:

WINDOWS

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