Blame SOURCES/opencryptoki-3.0-bz1033284.patch

50440f
commit 84db3078dea9ffffbaeb76ad52e72dbdc8f6c8f1
50440f
Author: Joy Latten <jmlatten@linux.vnet.ibm.com>
50440f
Date:   Wed Oct 2 16:34:40 2013 -0500
50440f
50440f
    CCA token was not importing rsa keypair correctly in v3.
50440f
    
50440f
    Signed-off-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
50440f
50440f
diff --git a/usr/lib/pkcs11/cca_stdll/obj_mgr.c b/usr/lib/pkcs11/cca_stdll/obj_mgr.c
50440f
deleted file mode 100644
50440f
index 4c819e9..0000000
50440f
--- a/usr/lib/pkcs11/cca_stdll/obj_mgr.c
50440f
+++ /dev/null
50440f
@@ -1,2479 +0,0 @@
50440f
-/*
50440f
-             Common Public License Version 0.5
50440f
-
50440f
-             THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
50440f
-             THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
50440f
-             REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
50440f
-             RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
50440f
-
50440f
-             1. DEFINITIONS
50440f
-
50440f
-             "Contribution" means:
50440f
-                   a) in the case of the initial Contributor, the
50440f
-                   initial code and documentation distributed under
50440f
-                   this Agreement, and
50440f
-
50440f
-                   b) in the case of each subsequent Contributor:
50440f
-                   i) changes to the Program, and
50440f
-                   ii) additions to the Program;
50440f
-
50440f
-                   where such changes and/or additions to the Program
50440f
-                   originate from and are distributed by that
50440f
-                   particular Contributor. A Contribution 'originates'
50440f
-                   from a Contributor if it was added to the Program
50440f
-                   by such Contributor itself or anyone acting on such
50440f
-                   Contributor's behalf. Contributions do not include
50440f
-                   additions to the Program which: (i) are separate
50440f
-                   modules of software distributed in conjunction with
50440f
-                   the Program under their own license agreement, and
50440f
-                   (ii) are not derivative works of the Program.
50440f
-
50440f
-
50440f
-             "Contributor" means any person or entity that distributes
50440f
-             the Program.
50440f
-
50440f
-             "Licensed Patents " mean patent claims licensable by a
50440f
-             Contributor which are necessarily infringed by the use or
50440f
-             sale of its Contribution alone or when combined with the
50440f
-             Program.
50440f
-
50440f
-             "Program" means the Contributions distributed in
50440f
-             accordance with this Agreement.
50440f
-
50440f
-             "Recipient" means anyone who receives the Program under
50440f
-             this Agreement, including all Contributors.
50440f
-
50440f
-             2. GRANT OF RIGHTS
50440f
-
50440f
-                   a) Subject to the terms of this Agreement, each
50440f
-                   Contributor hereby grants Recipient a
50440f
-                   non-exclusive, worldwide, royalty-free copyright
50440f
-                   license to reproduce, prepare derivative works of,
50440f
-                   publicly display, publicly perform, distribute and
50440f
-                   sublicense the Contribution of such Contributor, if
50440f
-                   any, and such derivative works, in source code and
50440f
-                   object code form.
50440f
-
50440f
-                   b) Subject to the terms of this Agreement, each
50440f
-                   Contributor hereby grants Recipient a
50440f
-                   non-exclusive, worldwide, royalty-free patent
50440f
-                   license under Licensed Patents to make, use, sell,
50440f
-                   offer to sell, import and otherwise transfer the
50440f
-                   Contribution of such Contributor, if any, in source
50440f
-                   code and object code form. This patent license
50440f
-                   shall apply to the combination of the Contribution
50440f
-                   and the Program if, at the time the Contribution is
50440f
-                   added by the Contributor, such addition of the
50440f
-                   Contribution causes such combination to be covered
50440f
-                   by the Licensed Patents. The patent license shall
50440f
-                   not apply to any other combinations which include
50440f
-                   the Contribution. No hardware per se is licensed
50440f
-                   hereunder.
50440f
-
50440f
-                   c) Recipient understands that although each
50440f
-                   Contributor grants the licenses to its
50440f
-                   Contributions set forth herein, no assurances are
50440f
-                   provided by any Contributor that the Program does
50440f
-                   not infringe the patent or other intellectual
50440f
-                   property rights of any other entity. Each
50440f
-                   Contributor disclaims any liability to Recipient
50440f
-                   for claims brought by any other entity based on
50440f
-                   infringement of intellectual property rights or
50440f
-                   otherwise. As a condition to exercising the rights
50440f
-                   and licenses granted hereunder, each Recipient
50440f
-                   hereby assumes sole responsibility to secure any
50440f
-                   other intellectual property rights needed, if any.
50440f
-
50440f
-                   For example, if a third party patent license is
50440f
-                   required to allow Recipient to distribute the
50440f
-                   Program, it is Recipient's responsibility to
50440f
-                   acquire that license before distributing the
50440f
-                   Program.
50440f
-
50440f
-                   d) Each Contributor represents that to its
50440f
-                   knowledge it has sufficient copyright rights in its
50440f
-                   Contribution, if any, to grant the copyright
50440f
-                   license set forth in this Agreement.
50440f
-
50440f
-             3. REQUIREMENTS
50440f
-
50440f
-             A Contributor may choose to distribute the Program in
50440f
-             object code form under its own license agreement, provided
50440f
-             that:
50440f
-                   a) it complies with the terms and conditions of
50440f
-                   this Agreement; and
50440f
-
50440f
-                   b) its license agreement:
50440f
-                   i) effectively disclaims on behalf of all
50440f
-                   Contributors all warranties and conditions, express
50440f
-                   and implied, including warranties or conditions of
50440f
-                   title and non-infringement, and implied warranties
50440f
-                   or conditions of merchantability and fitness for a
50440f
-                   particular purpose;
50440f
-
50440f
-                   ii) effectively excludes on behalf of all
50440f
-                   Contributors all liability for damages, including
50440f
-                   direct, indirect, special, incidental and
50440f
-                   consequential damages, such as lost profits;
50440f
-
50440f
-                   iii) states that any provisions which differ from
50440f
-                   this Agreement are offered by that Contributor
50440f
-                   alone and not by any other party; and
50440f
-
50440f
-                   iv) states that source code for the Program is
50440f
-                   available from such Contributor, and informs
50440f
-                   licensees how to obtain it in a reasonable manner
50440f
-                   on or through a medium customarily used for
50440f
-                   software exchange.
50440f
-
50440f
-             When the Program is made available in source code form:
50440f
-                   a) it must be made available under this Agreement;
50440f
-                   and
50440f
-                   b) a copy of this Agreement must be included with
50440f
-                   each copy of the Program.
50440f
-
50440f
-             Contributors may not remove or alter any copyright notices
50440f
-             contained within the Program.
50440f
-
50440f
-             Each Contributor must identify itself as the originator of
50440f
-             its Contribution, if any, in a manner that reasonably
50440f
-             allows subsequent Recipients to identify the originator of
50440f
-             the Contribution.
50440f
-
50440f
-
50440f
-             4. COMMERCIAL DISTRIBUTION
50440f
-
50440f
-             Commercial distributors of software may accept certain
50440f
-             responsibilities with respect to end users, business
50440f
-             partners and the like. While this license is intended to
50440f
-             facilitate the commercial use of the Program, the
50440f
-             Contributor who includes the Program in a commercial
50440f
-             product offering should do so in a manner which does not
50440f
-             create potential liability for other Contributors.
50440f
-             Therefore, if a Contributor includes the Program in a
50440f
-             commercial product offering, such Contributor ("Commercial
50440f
-             Contributor") hereby agrees to defend and indemnify every
50440f
-             other Contributor ("Indemnified Contributor") against any
50440f
-             losses, damages and costs (collectively "Losses") arising
50440f
-             from claims, lawsuits and other legal actions brought by a
50440f
-             third party against the Indemnified Contributor to the
50440f
-             extent caused by the acts or omissions of such Commercial
50440f
-             Contributor in connection with its distribution of the
50440f
-             Program in a commercial product offering. The obligations
50440f
-             in this section do not apply to any claims or Losses
50440f
-             relating to any actual or alleged intellectual property
50440f
-             infringement. In order to qualify, an Indemnified
50440f
-             Contributor must: a) promptly notify the Commercial
50440f
-             Contributor in writing of such claim, and b) allow the
50440f
-             Commercial Contributor to control, and cooperate with the
50440f
-             Commercial Contributor in, the defense and any related
50440f
-             settlement negotiations. The Indemnified Contributor may
50440f
-             participate in any such claim at its own expense.
50440f
-
50440f
-
50440f
-             For example, a Contributor might include the Program in a
50440f
-             commercial product offering, Product X. That Contributor
50440f
-             is then a Commercial Contributor. If that Commercial
50440f
-             Contributor then makes performance claims, or offers
50440f
-             warranties related to Product X, those performance claims
50440f
-             and warranties are such Commercial Contributor's
50440f
-             responsibility alone. Under this section, the Commercial
50440f
-             Contributor would have to defend claims against the other
50440f
-             Contributors related to those performance claims and
50440f
-             warranties, and if a court requires any other Contributor
50440f
-             to pay any damages as a result, the Commercial Contributor
50440f
-             must pay those damages.
50440f
-
50440f
-
50440f
-             5. NO WARRANTY
50440f
-
50440f
-             EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
50440f
-             PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
50440f
-             WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
50440f
-             IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
50440f
-             CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
50440f
-             FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
50440f
-             responsible for determining the appropriateness of using
50440f
-             and distributing the Program and assumes all risks
50440f
-             associated with its exercise of rights under this
50440f
-             Agreement, including but not limited to the risks and
50440f
-             costs of program errors, compliance with applicable laws,
50440f
-             damage to or loss of data, programs or equipment, and
50440f
-             unavailability or interruption of operations.
50440f
-
50440f
-             6. DISCLAIMER OF LIABILITY
50440f
-             EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
50440f
-             RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
50440f
-             FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
50440f
-             OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
50440f
-             LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
50440f
-             LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
50440f
-             (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50440f
-             OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
50440f
-             OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
50440f
-             POSSIBILITY OF SUCH DAMAGES.
50440f
-
50440f
-             7. GENERAL
50440f
-
50440f
-             If any provision of this Agreement is invalid or
50440f
-             unenforceable under applicable law, it shall not affect
50440f
-             the validity or enforceability of the remainder of the
50440f
-             terms of this Agreement, and without further action by the
50440f
-             parties hereto, such provision shall be reformed to the
50440f
-             minimum extent necessary to make such provision valid and
50440f
-             enforceable.
50440f
-
50440f
-
50440f
-             If Recipient institutes patent litigation against a
50440f
-             Contributor with respect to a patent applicable to
50440f
-             software (including a cross-claim or counterclaim in a
50440f
-             lawsuit), then any patent licenses granted by that
50440f
-             Contributor to such Recipient under this Agreement shall
50440f
-             terminate as of the date such litigation is filed. In
50440f
-             addition, If Recipient institutes patent litigation
50440f
-             against any entity (including a cross-claim or
50440f
-             counterclaim in a lawsuit) alleging that the Program
50440f
-             itself (excluding combinations of the Program with other
50440f
-             software or hardware) infringes such Recipient's
50440f
-             patent(s), then such Recipient's rights granted under
50440f
-             Section 2(b) shall terminate as of the date such
50440f
-             litigation is filed.
50440f
-
50440f
-             All Recipient's rights under this Agreement shall
50440f
-             terminate if it fails to comply with any of the material
50440f
-             terms or conditions of this Agreement and does not cure
50440f
-             such failure in a reasonable period of time after becoming
50440f
-             aware of such noncompliance. If all Recipient's rights
50440f
-             under this Agreement terminate, Recipient agrees to cease
50440f
-             use and distribution of the Program as soon as reasonably
50440f
-             practicable. However, Recipient's obligations under this
50440f
-             Agreement and any licenses granted by Recipient relating
50440f
-             to the Program shall continue and survive.
50440f
-
50440f
-             Everyone is permitted to copy and distribute copies of
50440f
-             this Agreement, but in order to avoid inconsistency the
50440f
-             Agreement is copyrighted and may only be modified in the
50440f
-             following manner. The Agreement Steward reserves the right
50440f
-             to publish new versions (including revisions) of this
50440f
-             Agreement from time to time. No one other than the
50440f
-             Agreement Steward has the right to modify this Agreement.
50440f
-
50440f
-             IBM is the initial Agreement Steward. IBM may assign the
50440f
-             responsibility to serve as the Agreement Steward to a
50440f
-             suitable separate entity. Each new version of the
50440f
-             Agreement will be given a distinguishing version number.
50440f
-             The Program (including Contributions) may always be
50440f
-             distributed subject to the version of the Agreement under
50440f
-             which it was received. In addition, after a new version of
50440f
-             the Agreement is published, Contributor may elect to
50440f
-             distribute the Program (including its Contributions) under
50440f
-             the new version. Except as expressly stated in Sections
50440f
-             2(a) and 2(b) above, Recipient receives no rights or
50440f
-             licenses to the intellectual property of any Contributor
50440f
-             under this Agreement, whether expressly, by implication,
50440f
-             estoppel or otherwise. All rights in the Program not
50440f
-             expressly granted under this Agreement are reserved.
50440f
-
50440f
-
50440f
-             This Agreement is governed by the laws of the State of New
50440f
-             York and the intellectual property laws of the United
50440f
-             States of America. No party to this Agreement will bring a
50440f
-             legal action under this Agreement more than one year after
50440f
-             the cause of action arose. Each party waives its rights to
50440f
-             a jury trial in any resulting litigation.
50440f
-
50440f
-
50440f
-
50440f
-*/
50440f
-
50440f
-/* (C) COPYRIGHT International Business Machines Corp. 2001,2002          */
50440f
-
50440f
-
50440f
-// File:  obj_mgr.c
50440f
-//
50440f
-// Object manager related functions
50440f
-//
50440f
-
50440f
-#include <pthread.h>
50440f
-#include <stdlib.h>
50440f
-#include <stdio.h>
50440f
-#include <string.h>  // for memcmp() et al
50440f
-#include <strings.h>
50440f
-
50440f
-#include "pkcs11types.h"
50440f
-#include "defs.h"
50440f
-#include "cca_stdll.h"
50440f
-#include "host_defs.h"
50440f
-#include "h_extern.h"
50440f
-#include "tok_spec_struct.h"
50440f
-
50440f
-#include "../api/apiproto.h"
50440f
-
50440f
-pthread_rwlock_t obj_list_rw_mutex = PTHREAD_RWLOCK_INITIALIZER;
50440f
-
50440f
-CK_RV
50440f
-object_mgr_add( SESSION          * sess,
50440f
-                CK_ATTRIBUTE     * pTemplate,
50440f
-                CK_ULONG           ulCount,
50440f
-                CK_OBJECT_HANDLE * handle )
50440f
-{
50440f
-   OBJECT    * o = NULL;
50440f
-   CK_BBOOL    priv_obj, sess_obj;
50440f
-   CK_BBOOL    locked = FALSE;
50440f
-   CK_RV       rc;
50440f
-   unsigned long obj_handle;
50440f
-
50440f
-   if (!sess || !pTemplate || !handle){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return rc;
50440f
-   }
50440f
-   locked = TRUE;
50440f
-
50440f
-   rc = object_create( pTemplate, ulCount, &o );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_OBJ_CREATE);
50440f
-      goto done;
50440f
-   }
50440f
-
50440f
-   if (token_specific.t_object_add != NULL) {
50440f
-      rc = token_specific.t_object_add(o);
50440f
-      if (rc != CKR_OK) {
50440f
-	 OCK_LOG_ERR(ERR_OBJ_CREATE);
50440f
-	 goto done;
50440f
-       }
50440f
-   }
50440f
-
50440f
-   // check whether session has permissions to create the object, etc
50440f
-   //
50440f
-   // Object                  R/O      R/W      R/O     R/W    R/W
50440f
-   // Type                   Public   Public    User    User   SO
50440f
-   // -------------------------------------------------------------
50440f
-   // Public session          R/W      R/W      R/W     R/W    R/W
50440f
-   // Private session                           R/W     R/W
50440f
-   // Public token            R/O      R/W      R/O     R/W    R/W
50440f
-   // Private token                             R/O     R/W
50440f
-   //
50440f
-   sess_obj = object_is_session_object( o );
50440f
-   priv_obj = object_is_private( o );
50440f
-
50440f
-   if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
50440f
-      if (priv_obj) {
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         rc = CKR_USER_NOT_LOGGED_IN;
50440f
-         goto done;
50440f
-      }
50440f
-
50440f
-      if (!sess_obj) {
50440f
-         OCK_LOG_ERR(ERR_SESSION_READ_ONLY);
50440f
-         rc = CKR_SESSION_READ_ONLY;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
50440f
-      if (!sess_obj) {
50440f
-         OCK_LOG_ERR(ERR_SESSION_READ_ONLY);
50440f
-         rc = CKR_SESSION_READ_ONLY;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
50440f
-      if (priv_obj) {
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         rc = CKR_USER_NOT_LOGGED_IN;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
50440f
-      if (priv_obj) {
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         rc = CKR_USER_NOT_LOGGED_IN;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   // okay, object is created and the session permissions look okay.
50440f
-   // add the object to the appropriate list and assign an object handle
50440f
-   //
50440f
-
50440f
-   if (sess_obj) {
50440f
-      o->session = sess;
50440f
-      memset( o->name, 0x00, sizeof(CK_BYTE) * 8 );
50440f
-
50440f
-      if ((obj_handle = bt_node_add(&sess_obj_btree, o)) == 0) {
50440f
-	 OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-	 rc = CKR_HOST_MEMORY;
50440f
-	 goto done;
50440f
-      }
50440f
-   }
50440f
-   else {
50440f
-      CK_BYTE current[8];
50440f
-      CK_BYTE next[8];
50440f
-
50440f
-      // we'll be modifying nv_token_data so we should protect this part with
50440f
-      // the 'pkcs_mutex'
50440f
-      //
50440f
-      rc = XProcLock();
50440f
-      if (rc != CKR_OK){
50440f
-         OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-         goto done;
50440f
-      }
50440f
-      else {
50440f
-
50440f
-         // Determine if we have already reached our Max Token Objects
50440f
-         //
50440f
-         if (priv_obj) {
50440f
-            if (global_shm->num_priv_tok_obj >= MAX_TOK_OBJS) {
50440f
-               rc = CKR_HOST_MEMORY;
50440f
-               OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-               XProcUnLock();
50440f
-               goto done;
50440f
-            }
50440f
-         }
50440f
-         else {
50440f
-            if (global_shm->num_publ_tok_obj >= MAX_TOK_OBJS) {
50440f
-               rc = CKR_HOST_MEMORY;
50440f
-               OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-               XProcUnLock();
50440f
-               goto done;
50440f
-            }
50440f
-         }
50440f
-
50440f
-         memcpy( current, &nv_token_data->next_token_object_name, 8 );
50440f
-
50440f
-         o->session = NULL;
50440f
-         memcpy( &o->name, current, 8 );
50440f
-
50440f
-         rc = compute_next_token_obj_name( current, next );
50440f
-         if (rc != CKR_OK) {
50440f
-                 // TODO: handle error, check if rc is a valid per spec
50440f
-                XProcUnLock();
50440f
-                 goto done;
50440f
-         }
50440f
-         memcpy( &nv_token_data->next_token_object_name, next, 8 );
50440f
-
50440f
-         rc = save_token_object( o );
50440f
-         if (rc != CKR_OK) {
50440f
-                 // TODO: handle error, check if rc is a valid per spec
50440f
-                XProcUnLock();
50440f
-                goto done;
50440f
-         }
50440f
-
50440f
-         // add the object identifier to the shared memory segment
50440f
-         //
50440f
-         object_mgr_add_to_shm( o );
50440f
-
50440f
-         XProcUnLock();
50440f
-
50440f
-         // save_token_data has to lock the mutex itself because it's used elsewhere
50440f
-         //
50440f
-         rc = save_token_data();
50440f
-         if (rc != CKR_OK) {
50440f
-                 // TODO: handle error, check if rc is a valid per spec
50440f
-                XProcUnLock();
50440f
-                goto done;
50440f
-         }
50440f
-
50440f
-      }
50440f
-
50440f
-      // now, store the object in the appropriate btree
50440f
-      //
50440f
-      if (priv_obj)
50440f
-         obj_handle = bt_node_add(&priv_token_obj_btree, o);
50440f
-      else
50440f
-         obj_handle = bt_node_add(&publ_token_obj_btree, o);
50440f
-
50440f
-      if (!obj_handle) {
50440f
-	 OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-	 rc = CKR_HOST_MEMORY;
50440f
-	 goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   rc = object_mgr_add_to_map( sess, o, obj_handle, handle );
50440f
-   if (rc != CKR_OK) {
50440f
-      // we need to remove the object from whatever btree we just added it to
50440f
-      if (sess_obj) {
50440f
-	 // put the binary tree node which holds o on the free list, but pass NULL here, so that
50440f
-	 // o (the binary tree node's value pointer) isn't touched. It is free'd below
50440f
-	 bt_node_free(&sess_obj_btree, obj_handle, NULL);
50440f
-      }
50440f
-      else {
50440f
-         // we'll want to delete the token object file too!
50440f
-         //
50440f
-         delete_token_object( o );
50440f
-
50440f
-         if (priv_obj) {
50440f
-	    // put the binary tree node which holds o on the free list, but pass NULL here, so that
50440f
-	    // o (the binary tree node's value pointer) isn't touched. It is free'd below
50440f
-	    bt_node_free(&priv_token_obj_btree, obj_handle, NULL);
50440f
-         }
50440f
-         else {
50440f
-	    // put the binary tree node which holds o on the free list, but pass NULL here, so that
50440f
-	    // o (the binary tree node's value pointer) isn't touched. It is free'd below
50440f
-	    bt_node_free(&publ_token_obj_btree, obj_handle, NULL);
50440f
-         }
50440f
-
50440f
-         rc = XProcLock();
50440f
-         if (rc != CKR_OK){
50440f
-            OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-            goto done;
50440f
-         }
50440f
-         object_mgr_del_from_shm( o );
50440f
-
50440f
-         XProcUnLock();
50440f
-      }
50440f
-   }
50440f
-
50440f
-
50440f
-done:
50440f
-   if (locked)
50440f
-      MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   if ((rc != CKR_OK) && (o != NULL))
50440f
-      object_free( o );
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-
50440f
-// object_mgr_add_to_map()
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_add_to_map( SESSION          * sess,
50440f
-                       OBJECT           * obj,
50440f
-		       unsigned long      obj_handle,
50440f
-                       CK_OBJECT_HANDLE * map_handle )
50440f
-{
50440f
-   OBJECT_MAP  *map_node = NULL;
50440f
-
50440f
-   if (!sess || !obj || !map_handle){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   //
50440f
-   // this guy doesn't lock a mutex because it's calling routines should have
50440f
-   // already locked it
50440f
-   //
50440f
-
50440f
-   map_node = (OBJECT_MAP *)malloc(sizeof(OBJECT_MAP));
50440f
-   if (!map_node){
50440f
-      OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-      return CKR_HOST_MEMORY;
50440f
-   }
50440f
-   map_node->session  = sess;
50440f
-
50440f
-   if (obj->session != NULL)
50440f
-      map_node->is_session_obj = TRUE;
50440f
-   else
50440f
-      map_node->is_session_obj = FALSE;
50440f
-
50440f
-   map_node->is_private = object_is_private( obj );
50440f
-
50440f
-   // add the new map entry to the list
50440f
-   if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
50440f
-      free(map_node);
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-
50440f
-   // map_node->obj_handle will store the index of the btree node in one of these lists:
50440f
-   // publ_token_obj_btree - for public token object
50440f
-   // priv_token_obj_btree - for private token objects
50440f
-   // sess_obj_btree - for session objects
50440f
-   //
50440f
-   // *map_handle, the application's CK_OBJECT_HANDLE, will then be the index of the btree node
50440f
-   // in the object_map_btree
50440f
-   //
50440f
-   map_node->obj_handle = obj_handle;
50440f
-   *map_handle = bt_node_add(&object_map_btree, map_node);
50440f
-
50440f
-   pthread_rwlock_unlock(&obj_list_rw_mutex);
50440f
-
50440f
-   if (*map_handle == 0) {
50440f
-      free(map_node);
50440f
-      OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-      return CKR_HOST_MEMORY;
50440f
-   }
50440f
-   obj->map_handle = *map_handle;
50440f
-
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-
50440f
-// object_mgr_copy()
50440f
-//
50440f
-// algorithm:
50440f
-//    1) find the old object
50440f
-//    2) get the template from the old object
50440f
-//    3) merge in the new object's template
50440f
-//    4) perform class-specific sanity checks
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_copy( SESSION          * sess,
50440f
-                 CK_ATTRIBUTE     * pTemplate,
50440f
-                 CK_ULONG           ulCount,
50440f
-                 CK_OBJECT_HANDLE   old_handle,
50440f
-                 CK_OBJECT_HANDLE * new_handle )
50440f
-{
50440f
-   OBJECT     *old_obj = NULL;
50440f
-   OBJECT     *new_obj = NULL;
50440f
-   CK_BBOOL    priv_obj;
50440f
-   CK_BBOOL    sess_obj;
50440f
-   CK_BBOOL    locked = FALSE;
50440f
-   CK_RV       rc;
50440f
-   unsigned long obj_handle;
50440f
-
50440f
-   if (!sess || !pTemplate || !new_handle){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return rc;
50440f
-   }
50440f
-   locked = TRUE;
50440f
-
50440f
-   rc = object_mgr_find_in_map1( old_handle, &old_obj );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_OBJMGR_FIND_MAP);
50440f
-      goto done;
50440f
-   }
50440f
-   rc = object_copy( pTemplate, ulCount, old_obj, &new_obj );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_OBJ_COPY);
50440f
-      goto done;
50440f
-   }
50440f
-
50440f
-   // check whether session has permissions to create the object, etc
50440f
-   //
50440f
-   // Object                  R/O      R/W      R/O     R/W    R/W
50440f
-   // Type                   Public   Public    User    User   SO
50440f
-   // -------------------------------------------------------------
50440f
-   // Public session          R/W      R/W      R/W     R/W    R/W
50440f
-   // Private session                           R/W     R/W
50440f
-   // Public token            R/O      R/W      R/O     R/W    R/W
50440f
-   // Private token                             R/O     R/W
50440f
-   //
50440f
-   sess_obj = object_is_session_object( new_obj );
50440f
-   priv_obj = object_is_private( new_obj );
50440f
-
50440f
-   if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
50440f
-      if (priv_obj) {
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         rc = CKR_USER_NOT_LOGGED_IN;
50440f
-         goto done;
50440f
-      }
50440f
-
50440f
-      if (!sess_obj) {
50440f
-         OCK_LOG_ERR(ERR_SESSION_READ_ONLY);
50440f
-         rc = CKR_SESSION_READ_ONLY;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
50440f
-      if (!sess_obj) {
50440f
-         OCK_LOG_ERR(ERR_SESSION_READ_ONLY);
50440f
-         rc = CKR_SESSION_READ_ONLY;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
50440f
-      if (priv_obj) {
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         rc = CKR_USER_NOT_LOGGED_IN;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
50440f
-      if (priv_obj) {
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         rc = CKR_USER_NOT_LOGGED_IN;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   // okay, object is created and the session permissions look okay.
50440f
-   // add the object to the appropriate list and assign an object handle
50440f
-   //
50440f
-
50440f
-   if (sess_obj) {
50440f
-      new_obj->session = sess;
50440f
-      memset( &new_obj->name, 0x00, sizeof(CK_BYTE) * 8 );
50440f
-
50440f
-      if ((obj_handle = bt_node_add(&sess_obj_btree, new_obj)) == 0) {
50440f
-	 OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-	 rc = CKR_HOST_MEMORY;
50440f
-	 goto done;
50440f
-      }
50440f
-   }
50440f
-   else {
50440f
-      CK_BYTE current[8];
50440f
-      CK_BYTE next[8];
50440f
-
50440f
-      // we'll be modifying nv_token_data so we should protect this part
50440f
-      // with 'pkcs_mutex'
50440f
-      //
50440f
-      rc = XProcLock();
50440f
-      if (rc != CKR_OK){
50440f
-         OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-         goto done;
50440f
-      }
50440f
-      else {
50440f
-
50440f
-         // Determine if we have already reached our Max Token Objects
50440f
-         //
50440f
-         if (priv_obj) {
50440f
-            if (global_shm->num_priv_tok_obj >= MAX_TOK_OBJS) {
50440f
-               XProcUnLock();
50440f
-               OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-               rc = CKR_HOST_MEMORY;
50440f
-               goto done;
50440f
-            }
50440f
-         }
50440f
-         else {
50440f
-            if (global_shm->num_publ_tok_obj >= MAX_TOK_OBJS) {
50440f
-               XProcUnLock();
50440f
-               OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-               rc = CKR_HOST_MEMORY;
50440f
-               goto done;
50440f
-            }
50440f
-         }
50440f
-         memcpy( current, &nv_token_data->next_token_object_name, 8 );
50440f
-
50440f
-         new_obj->session = NULL;
50440f
-         memcpy( &new_obj->name, current, 8 );
50440f
-
50440f
-         compute_next_token_obj_name( current, next );
50440f
-         memcpy( &nv_token_data->next_token_object_name, next, 8 );
50440f
-
50440f
-         save_token_object( new_obj );
50440f
-
50440f
-         // add the object identifier to the shared memory segment
50440f
-         //
50440f
-         object_mgr_add_to_shm( new_obj );
50440f
-
50440f
-         XProcUnLock();
50440f
-
50440f
-         save_token_data();
50440f
-      }
50440f
-
50440f
-      // now, store the object in the token object btree
50440f
-      //
50440f
-      if (priv_obj)
50440f
-         obj_handle = bt_node_add(&priv_token_obj_btree, new_obj);
50440f
-      else
50440f
-         obj_handle = bt_node_add(&publ_token_obj_btree, new_obj);
50440f
-
50440f
-      if (!obj_handle) {
50440f
-	 OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-	 rc = CKR_HOST_MEMORY;
50440f
-	 goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   rc = object_mgr_add_to_map( sess, new_obj, obj_handle, new_handle );
50440f
-   if (rc != CKR_OK) {
50440f
-      OCK_LOG_ERR(ERR_OBJMGR_MAP_ADD);
50440f
-
50440f
-      // this is messy but we need to remove the object from whatever
50440f
-      // list we just added it to
50440f
-      //
50440f
-      if (sess_obj) {
50440f
-	 // put the binary tree node which holds new_obj on the free list, but pass NULL here, so
50440f
-	 // that new_obj (the binary tree node's value pointer) isn't touched. It is free'd below
50440f
-	 bt_node_free(&sess_obj_btree, obj_handle, NULL);
50440f
-      }
50440f
-      else {
50440f
-         // FIXME - need to destroy the token object file too
50440f
-         //
50440f
-         delete_token_object( new_obj );
50440f
-
50440f
-         if (priv_obj) {
50440f
-	    // put the binary tree node which holds new_obj on the free list, but pass NULL here,
50440f
-	    // so that new_obj (the binary tree node's value pointer) isn't touched. It is free'd
50440f
-	    // below
50440f
-	    bt_node_free(&priv_token_obj_btree, obj_handle, NULL);
50440f
-         }
50440f
-         else {
50440f
-	    // put the binary tree node which holds new_obj on the free list, but pass NULL here,
50440f
-	    // so that new_obj (the binary tree node's value pointer) isn't touched. It is free'd
50440f
-	    // below
50440f
-	    bt_node_free(&publ_token_obj_btree, obj_handle, NULL);
50440f
-         }
50440f
-
50440f
-         rc = XProcLock();
50440f
-         if (rc != CKR_OK){
50440f
-            OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-            goto done;
50440f
-         }
50440f
-         object_mgr_del_from_shm( new_obj );
50440f
-
50440f
-         XProcUnLock();
50440f
-      }
50440f
-   }
50440f
-
50440f
-done:
50440f
-   if (locked)
50440f
-      MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   if ((rc != CKR_OK) && (new_obj != NULL))
50440f
-      object_free( new_obj );
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-
50440f
-// determines whether the session is allowed to create an object.  creates
50440f
-// the object but doesn't add the object to any object lists or to the
50440f
-// process' object map.
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_create_skel( SESSION       * sess,
50440f
-                        CK_ATTRIBUTE  * pTemplate,
50440f
-                        CK_ULONG        ulCount,
50440f
-                        CK_ULONG        mode,
50440f
-                        CK_ULONG        obj_type,
50440f
-                        CK_ULONG        sub_class,
50440f
-                        OBJECT       ** obj )
50440f
-{
50440f
-   OBJECT     *o = NULL;
50440f
-   CK_RV       rc;
50440f
-   CK_BBOOL    priv_obj;
50440f
-   CK_BBOOL    sess_obj;
50440f
-
50440f
-   if (!sess || !obj){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   if (!pTemplate && (ulCount != 0)){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   //
50440f
-   // we don't need to lock mutex for this routine
50440f
-   //
50440f
-
50440f
-   rc = object_create_skel( pTemplate, ulCount,
50440f
-                            mode,
50440f
-                            obj_type, sub_class,
50440f
-                            &o );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_OBJMGR_CREATE_SKEL);
50440f
-      return rc;
50440f
-   }
50440f
-   sess_obj = object_is_session_object( o );
50440f
-   priv_obj = object_is_private( o );
50440f
-
50440f
-   if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
50440f
-      if (priv_obj) {
50440f
-         object_free( o );
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         return CKR_USER_NOT_LOGGED_IN;
50440f
-      }
50440f
-
50440f
-      if (!sess_obj) {
50440f
-         object_free( o );
50440f
-         OCK_LOG_ERR(ERR_SESSION_READ_ONLY);
50440f
-         return CKR_SESSION_READ_ONLY;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
50440f
-      if (!sess_obj) {
50440f
-         object_free( o );
50440f
-         OCK_LOG_ERR(ERR_SESSION_READ_ONLY);
50440f
-         return CKR_SESSION_READ_ONLY;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
50440f
-      if (priv_obj) {
50440f
-         object_free( o );
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         return CKR_USER_NOT_LOGGED_IN;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
50440f
-      if (priv_obj) {
50440f
-         object_free( o );
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         return CKR_USER_NOT_LOGGED_IN;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   *obj = o;
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-
50440f
-CK_RV
50440f
-object_mgr_create_final( SESSION           * sess,
50440f
-                         OBJECT            * obj,
50440f
-                         CK_OBJECT_HANDLE  * handle )
50440f
-{
50440f
-   CK_BBOOL  sess_obj;
50440f
-   CK_BBOOL  priv_obj;
50440f
-   CK_BBOOL  locked = FALSE;
50440f
-   CK_RV     rc;
50440f
-   unsigned long obj_handle;
50440f
-
50440f
-   if (!sess || !obj || !handle){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return rc;
50440f
-   }
50440f
-   locked = TRUE;
50440f
-
50440f
-   sess_obj = object_is_session_object( obj );
50440f
-   priv_obj = object_is_private( obj );
50440f
-
50440f
-   if (sess_obj) {
50440f
-      obj->session = sess;
50440f
-      memset( obj->name, 0x0, sizeof(CK_BYTE) * 8 );
50440f
-
50440f
-      if ((obj_handle = bt_node_add(&sess_obj_btree, obj)) == 0) {
50440f
-	 OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-	 rc = CKR_HOST_MEMORY;
50440f
-	 goto done;
50440f
-      }
50440f
-   }
50440f
-   else {
50440f
-      CK_BYTE current[8];
50440f
-      CK_BYTE next[8];
50440f
-
50440f
-      // we'll be modifying nv_token_data so we should protect this part
50440f
-      // with 'pkcs_mutex'
50440f
-      //
50440f
-      rc = XProcLock();
50440f
-      if (rc != CKR_OK){
50440f
-         OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-         goto done;
50440f
-      }
50440f
-      else {
50440f
-
50440f
-         // Determine if we have already reached our Max Token Objects
50440f
-         //
50440f
-         if (priv_obj) {
50440f
-            if (global_shm->num_priv_tok_obj >= MAX_TOK_OBJS) {
50440f
-               XProcUnLock();
50440f
-               OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-               rc = CKR_HOST_MEMORY;
50440f
-               goto done;
50440f
-            }
50440f
-         }
50440f
-         else {
50440f
-            if (global_shm->num_publ_tok_obj >= MAX_TOK_OBJS) {
50440f
-               XProcUnLock();
50440f
-               OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-               rc = CKR_HOST_MEMORY;
50440f
-               goto done;
50440f
-            }
50440f
-         }
50440f
-         memcpy( current, &nv_token_data->next_token_object_name, 8 );
50440f
-
50440f
-         obj->session = NULL;
50440f
-         memcpy( &obj->name, current, 8 );
50440f
-
50440f
-         compute_next_token_obj_name( current, next );
50440f
-         memcpy( &nv_token_data->next_token_object_name, next, 8 );
50440f
-
50440f
-         save_token_object( obj );
50440f
-
50440f
-         // add the object identifier to the shared memory segment
50440f
-         //
50440f
-         object_mgr_add_to_shm( obj );
50440f
-
50440f
-         XProcUnLock();
50440f
-
50440f
-         save_token_data();
50440f
-      }
50440f
-
50440f
-      // now, store the object in the token object btree
50440f
-      //
50440f
-      if (priv_obj)
50440f
-         obj_handle = bt_node_add(&priv_token_obj_btree, obj);
50440f
-      else
50440f
-         obj_handle = bt_node_add(&publ_token_obj_btree, obj);
50440f
-
50440f
-      if (!obj_handle) {
50440f
-	 OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-	 rc = CKR_HOST_MEMORY;
50440f
-	 goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   rc = object_mgr_add_to_map( sess, obj, obj_handle, handle );
50440f
-   if (rc != CKR_OK) {
50440f
-      OCK_LOG_ERR(ERR_OBJMGR_MAP_ADD);
50440f
-      // this is messy but we need to remove the object from whatever
50440f
-      // list we just added it to
50440f
-      //
50440f
-      if (sess_obj) {
50440f
-	 // put the binary tree node which holds obj on the free list, but pass NULL here, so
50440f
-	 // that obj (the binary tree node's value pointer) isn't touched. It is free'd below
50440f
-	 bt_node_free(&sess_obj_btree, obj_handle, NULL);
50440f
-      }
50440f
-      else {
50440f
-         // FIXME - need to destroy the token object file too
50440f
-         //
50440f
-         delete_token_object( obj );
50440f
-
50440f
-         if (priv_obj) {
50440f
-	    // put the binary tree node which holds obj on the free list, but pass NULL here,
50440f
-	    // so that obj (the binary tree node's value pointer) isn't touched. It is free'd
50440f
-	    // below
50440f
-	    bt_node_free(&priv_token_obj_btree, obj_handle, NULL);
50440f
-         }
50440f
-         else {
50440f
-	    // put the binary tree node which holds obj on the free list, but pass NULL here,
50440f
-	    // so that obj (the binary tree node's value pointer) isn't touched. It is free'd
50440f
-	    // below
50440f
-	    bt_node_free(&publ_token_obj_btree, obj_handle, NULL);
50440f
-         }
50440f
-
50440f
-         rc = XProcLock();
50440f
-         if (rc != CKR_OK){
50440f
-            OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-            goto done;
50440f
-         }
50440f
-         object_mgr_del_from_shm( obj );
50440f
-
50440f
-         XProcUnLock();
50440f
-      }
50440f
-   }
50440f
-
50440f
-done:
50440f
-   if (locked)
50440f
-      MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-/* destroy_object_cb
50440f
- *
50440f
- * Callback used to delete an object from the object map btree and whichever other btree its
50440f
- * in (based on its type)
50440f
- */
50440f
-void
50440f
-destroy_object_cb(void *node)
50440f
-{
50440f
-	OBJECT_MAP *map = (OBJECT_MAP *)node;
50440f
-	OBJECT *o;
50440f
-
50440f
-	if (map->is_session_obj)
50440f
-		bt_node_free(&sess_obj_btree, map->obj_handle, object_free);
50440f
-	else {
50440f
-		if (map->is_private)
50440f
-			o = bt_get_node_value(&priv_token_obj_btree, map->obj_handle);
50440f
-		else
50440f
-			o = bt_get_node_value(&publ_token_obj_btree, map->obj_handle);
50440f
-
50440f
-		if (!o)
50440f
-			return;
50440f
-
50440f
-		delete_token_object(o);
50440f
-
50440f
-		/* Use the same calling convention as the old code, if XProcLock fails, don't
50440f
-		 * delete from shm and don't free the object in its other btree */
50440f
-		if (XProcLock()) {
50440f
-			OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-			goto done;
50440f
-		}
50440f
-		DUMP_SHM("before");
50440f
-		object_mgr_del_from_shm(o);
50440f
-		DUMP_SHM("after");
50440f
-
50440f
-		XProcUnLock();
50440f
-
50440f
-		if (map->is_private)
50440f
-			bt_node_free(&priv_token_obj_btree, map->obj_handle, object_free);
50440f
-		else
50440f
-			bt_node_free(&publ_token_obj_btree, map->obj_handle, object_free);
50440f
-	}
50440f
-done:
50440f
-	free(map);
50440f
-}
50440f
-
50440f
-// XXX Why does this function take @sess as an argument?
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_destroy_object( SESSION          * sess,
50440f
-                           CK_OBJECT_HANDLE   handle )
50440f
-{
50440f
-   CK_BBOOL    locked = FALSE;
50440f
-   CK_RV       rc;
50440f
-
50440f
-
50440f
-   if (!sess){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      goto done;
50440f
-   }
50440f
-   locked = TRUE;
50440f
-   if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
50440f
-	   OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-	   rc = CKR_FUNCTION_FAILED;
50440f
-	   goto done; // FIXME: Proper error messages
50440f
-   }
50440f
-
50440f
-   if (!bt_node_free(&object_map_btree, handle, destroy_object_cb)) {
50440f
-      OCK_LOG_ERR(ERR_OBJECT_HANDLE_INVALID);
50440f
-      rc = CKR_OBJECT_HANDLE_INVALID;
50440f
-   }
50440f
-
50440f
-   pthread_rwlock_unlock(&obj_list_rw_mutex);
50440f
-done:
50440f
-   if (locked)
50440f
-      MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-/* delete_token_obj_cb
50440f
- *
50440f
- * Callback to delete an object if its a token object
50440f
- */
50440f
-void
50440f
-delete_token_obj_cb(void *node, unsigned long map_handle, void *p3)
50440f
-{
50440f
-	OBJECT_MAP *map = (OBJECT_MAP *)node;
50440f
-	OBJECT *o;
50440f
-
50440f
-	if (!(map->is_session_obj)) {
50440f
-		if (map->is_private)
50440f
-			o = bt_get_node_value(&priv_token_obj_btree, map->obj_handle);
50440f
-		else
50440f
-			o = bt_get_node_value(&publ_token_obj_btree, map->obj_handle);
50440f
-
50440f
-		if (!o)
50440f
-			goto done;
50440f
-
50440f
-		delete_token_object(o);
50440f
-
50440f
-		/* Use the same calling convention as the old code, if
50440f
-		 * XProcLock fails, don't delete from shm and don't free
50440f
-		 * the object in its other btree
50440f
-		 */
50440f
-		if (XProcLock()) {
50440f
-			OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-			goto done;
50440f
-		}
50440f
-
50440f
-		object_mgr_del_from_shm(o);
50440f
-
50440f
-		XProcUnLock();
50440f
-
50440f
-		if (map->is_private)
50440f
-			bt_node_free(&priv_token_obj_btree, map->obj_handle, object_free);
50440f
-		else
50440f
-			bt_node_free(&publ_token_obj_btree, map->obj_handle, object_free);
50440f
-	}
50440f
-done:
50440f
-	/* delete @node from this btree */
50440f
-	bt_node_free(&object_map_btree, map_handle, free);
50440f
-}
50440f
-
50440f
-// this routine will destroy all token objects in the system
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_destroy_token_objects( void )
50440f
-{
50440f
-   CK_BBOOL locked1 = FALSE, locked2 = FALSE;
50440f
-   CK_RV rc;
50440f
-
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      goto done;
50440f
-   }
50440f
-   else
50440f
-      locked1 = TRUE;
50440f
-   bt_for_each_node(&object_map_btree, delete_token_obj_cb, NULL);
50440f
-
50440f
-   // now we want to purge the token object list in shared memory
50440f
-   //
50440f
-   rc = XProcLock();
50440f
-   if (rc == CKR_OK) {
50440f
-      locked2 = TRUE;
50440f
-
50440f
-      global_shm->num_priv_tok_obj = 0;
50440f
-      global_shm->num_publ_tok_obj = 0;
50440f
-
50440f
-      memset( &global_shm->publ_tok_objs, 0x0, MAX_TOK_OBJS * sizeof(TOK_OBJ_ENTRY) );
50440f
-      memset( &global_shm->priv_tok_objs, 0x0, MAX_TOK_OBJS * sizeof(TOK_OBJ_ENTRY) );
50440f
-   }
50440f
-   else
50440f
-      OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-done:
50440f
-   if (locked1 == TRUE) MY_UnlockMutex( &obj_list_mutex );
50440f
-/*   if (locked2 == TRUE) XProcUnLock(); */
50440f
-   if (locked2 == TRUE) {
50440f
-	XProcUnLock();
50440f
-   }
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-
50440f
-// object_mgr_find_in_map_nocache()
50440f
-//
50440f
-// Locates the specified object in the map
50440f
-// without going and checking for cache update
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_find_in_map_nocache( CK_OBJECT_HANDLE    handle,
50440f
-                         OBJECT           ** ptr )
50440f
-{
50440f
-   DL_NODE    * node = NULL;
50440f
-   OBJECT_MAP * map  = NULL;
50440f
-   OBJECT     * obj  = NULL;
50440f
-   CK_RV      rc = CKR_OK;
50440f
-
50440f
-
50440f
-   if (!ptr){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-
50440f
-   if (!handle) {
50440f
-      OCK_LOG_ERR(ERR_OBJECT_HANDLE_INVALID);
50440f
-      return CKR_OBJECT_HANDLE_INVALID;
50440f
-   }
50440f
-
50440f
-   //
50440f
-   // no mutex here.  the calling function should have locked the mutex
50440f
-   //
50440f
-
50440f
-   if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
50440f
-     OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-     return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-
50440f
-   map = bt_get_node_value(&object_map_btree, handle);
50440f
-   if (!map) {
50440f
-      OCK_LOG_ERR(ERR_OBJECT_HANDLE_INVALID);
50440f
-      rc = CKR_OBJECT_HANDLE_INVALID;
50440f
-      goto done;
50440f
-   }
50440f
-
50440f
-   if (map->is_session_obj)
50440f
-      obj = bt_get_node_value(&sess_obj_btree, map->obj_handle);
50440f
-   else if (map->is_private)
50440f
-      obj = bt_get_node_value(&priv_token_obj_btree, map->obj_handle);
50440f
-   else
50440f
-      obj = bt_get_node_value(&publ_token_obj_btree, map->obj_handle);
50440f
-
50440f
-   if (!obj) {
50440f
-      OCK_LOG_ERR(ERR_OBJECT_HANDLE_INVALID);
50440f
-      rc = CKR_OBJECT_HANDLE_INVALID;
50440f
-      goto done;
50440f
-   }
50440f
-
50440f
-   *ptr = obj;
50440f
-done:
50440f
-   pthread_rwlock_unlock(&obj_list_rw_mutex);
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-// object_mgr_find_in_map1()
50440f
-//
50440f
-// Locates the specified object in the map
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_find_in_map1( CK_OBJECT_HANDLE    handle,
50440f
-                         OBJECT           ** ptr )
50440f
-{
50440f
-   OBJECT_MAP * map  = NULL;
50440f
-   OBJECT     * obj  = NULL;
50440f
-   CK_RV      rc = CKR_OK;
50440f
-
50440f
-
50440f
-   if (!ptr){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
50440f
-     OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-     return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-
50440f
-   map = bt_get_node_value(&object_map_btree, handle);
50440f
-   if (!map) {
50440f
-      OCK_LOG_ERR(ERR_OBJECT_HANDLE_INVALID);
50440f
-      rc = CKR_OBJECT_HANDLE_INVALID;
50440f
-      goto done;
50440f
-   }
50440f
-
50440f
-   if (map->is_session_obj)
50440f
-      obj = bt_get_node_value(&sess_obj_btree, map->obj_handle);
50440f
-   else if (map->is_private)
50440f
-      obj = bt_get_node_value(&priv_token_obj_btree, map->obj_handle);
50440f
-   else
50440f
-      obj = bt_get_node_value(&publ_token_obj_btree, map->obj_handle);
50440f
-
50440f
-   if (!obj) {
50440f
-      OCK_LOG_ERR(ERR_OBJECT_HANDLE_INVALID);
50440f
-      rc = CKR_OBJECT_HANDLE_INVALID;
50440f
-      goto done;
50440f
-   }
50440f
-
50440f
-// SAB XXX Fix me.. need to make it more efficient than just looking for the object to be changed
50440f
-// set a global flag that contains the ref count to all objects.. if the shm ref count changes, then we update the object
50440f
-// if not
50440f
-
50440f
-   XProcLock();
50440f
-   object_mgr_check_shm( obj );
50440f
-   XProcUnLock();
50440f
-
50440f
-   *ptr = obj;
50440f
-done:
50440f
-   pthread_rwlock_unlock(&obj_list_rw_mutex);
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-void
50440f
-find_obj_cb(void *node, unsigned long map_handle, void *p3)
50440f
-{
50440f
-	OBJECT_MAP *map = (OBJECT_MAP *)node;
50440f
-	OBJECT     *obj;
50440f
-	struct find_args *fa = (struct find_args *)p3;
50440f
-
50440f
-	if (fa->done)
50440f
-		return;
50440f
-
50440f
-	if (map->is_session_obj)
50440f
-		obj = bt_get_node_value(&sess_obj_btree, map->obj_handle);
50440f
-	else if (map->is_private)
50440f
-		obj = bt_get_node_value(&priv_token_obj_btree, map->obj_handle);
50440f
-	else
50440f
-		obj = bt_get_node_value(&publ_token_obj_btree, map->obj_handle);
50440f
-
50440f
-	if (!obj)
50440f
-		return;
50440f
-
50440f
-	/* if this object is the one we're looking for (matches p3->obj), return
50440f
-	 * its map_handle in p3->map_handle */
50440f
-	if (obj == fa->obj) {
50440f
-		fa->map_handle = map_handle;
50440f
-		fa->done = TRUE;
50440f
-	}
50440f
-}
50440f
-
50440f
-// object_mgr_find_in_map2()
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_find_in_map2( OBJECT           * obj,
50440f
-                         CK_OBJECT_HANDLE * handle )
50440f
-{
50440f
-   struct find_args fa;
50440f
-
50440f
-   if (!obj || !handle){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   //
50440f
-   // no mutex here.  the calling function should have locked the mutex
50440f
-   //
50440f
-
50440f
-   if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
50440f
-     OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-     return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-
50440f
-   fa.done = FALSE;
50440f
-   fa.obj = obj;
50440f
-   fa.map_handle = 0;
50440f
-
50440f
-   // pass the fa structure with the values to operate on in the find_obj_cb function
50440f
-   bt_for_each_node(&object_map_btree, find_obj_cb, &fa);
50440f
-
50440f
-   pthread_rwlock_unlock(&obj_list_rw_mutex);
50440f
-
50440f
-   if (fa.done == FALSE || fa.map_handle == 0) {
50440f
-      return CKR_OBJECT_HANDLE_INVALID;
50440f
-   }
50440f
-
50440f
-   *handle = fa.map_handle;
50440f
-
50440f
-   XProcLock();
50440f
-   object_mgr_check_shm( obj );
50440f
-   XProcUnLock();
50440f
-
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-void
50440f
-find_build_list_cb(void *node, unsigned long obj_handle, void *p3)
50440f
-{
50440f
-   OBJECT *obj = (OBJECT *)node;
50440f
-   struct find_build_list_args *fa = (struct find_build_list_args *)p3;
50440f
-   CK_OBJECT_HANDLE map_handle;
50440f
-   CK_ATTRIBUTE *attr;
50440f
-   CK_BBOOL match = FALSE;
50440f
-   CK_RV rc;
50440f
-
50440f
-   if ((object_is_private(obj) == FALSE) || (fa->public_only == FALSE)) {
50440f
-      // if the user doesn't specify any template attributes then we return
50440f
-      // all objects
50440f
-      //
50440f
-      if (fa->pTemplate == NULL || fa->ulCount == 0)
50440f
-         match = TRUE;
50440f
-      else
50440f
-         match = template_compare( fa->pTemplate, fa->ulCount, obj->template );
50440f
-   }
50440f
-
50440f
-   // if we have a match, find the object in the map (add it if necessary)
50440f
-   // then add the object to the list of found objects //
50440f
-   if (match) {
50440f
-      rc = object_mgr_find_in_map2( obj, &map_handle );
50440f
-      if (rc != CKR_OK) {
50440f
-         //OCK_LOG_ERR(ERR_OBJMGR_FIND_MAP);
50440f
-         rc = object_mgr_add_to_map( fa->sess, obj, obj_handle, &map_handle );
50440f
-         if (rc != CKR_OK){
50440f
-            OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-            return;
50440f
-         }
50440f
-      }
50440f
-
50440f
-      // If hw_feature is false here, we need to filter out all objects
50440f
-      // that have the CKO_HW_FEATURE attribute set. - KEY
50440f
-      if ((fa->hw_feature == FALSE) &&
50440f
-	  (template_attribute_find(obj->template, CKA_CLASS, &attr) == TRUE)) {
50440f
-	 //axelrh: prevent segfault if pValue set to NULL (bad parse)
50440f
-	 if (attr->pValue == NULL) {
50440f
-	    OCK_LOG_ERR(ERR_GENERAL_ERROR);
50440f
-	    return;
50440f
-	 }
50440f
-	 if (*(CK_OBJECT_CLASS *)attr->pValue == CKO_HW_FEATURE)
50440f
-	    return;
50440f
-      }
50440f
-
50440f
-      /* Don't find objects that have been created with the CKA_HIDDEN
50440f
-       * attribute set */
50440f
-      if ((fa->hidden_object == FALSE) &&
50440f
-	  (template_attribute_find(obj->template, CKA_HIDDEN, &attr) == TRUE)) {
50440f
-	 if (*(CK_BBOOL *)attr->pValue == TRUE)
50440f
-	    return;
50440f
-      }
50440f
-
50440f
-      fa->sess->find_list[ fa->sess->find_count ] = map_handle;
50440f
-      fa->sess->find_count++;
50440f
-
50440f
-      if (fa->sess->find_count >= fa->sess->find_len) {
50440f
-	 fa->sess->find_len += 15;
50440f
-	 fa->sess->find_list =
50440f
-		 (CK_OBJECT_HANDLE *)realloc(fa->sess->find_list,
50440f
-					     fa->sess->find_len * sizeof(CK_OBJECT_HANDLE));
50440f
-	 if (!fa->sess->find_list) {
50440f
-	    OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-	    return;
50440f
-	 }
50440f
-      }
50440f
-   }
50440f
-}
50440f
-
50440f
-CK_RV
50440f
-object_mgr_find_init( SESSION      * sess,
50440f
-                      CK_ATTRIBUTE * pTemplate,
50440f
-                      CK_ULONG       ulCount )
50440f
-{
50440f
-   struct find_build_list_args fa;
50440f
-   CK_ULONG i;
50440f
-   // it is possible the pTemplate == NULL
50440f
-   //
50440f
-
50440f
-   if (!sess){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   if (sess->find_active != FALSE){
50440f
-      return CKR_OPERATION_ACTIVE;
50440f
-      OCK_LOG_ERR(ERR_OPERATION_ACTIVE);
50440f
-   }
50440f
-   // initialize the found object list.  if it doesn't exist, allocate
50440f
-   // a list big enough for 10 handles.  we'll reallocate if we need more
50440f
-   //
50440f
-   if (sess->find_list != NULL) {
50440f
-      memset( sess->find_list, 0x0, sess->find_len * sizeof(CK_OBJECT_HANDLE) );
50440f
-   }
50440f
-   else {
50440f
-      sess->find_list = (CK_OBJECT_HANDLE *)malloc(10 * sizeof(CK_OBJECT_HANDLE));
50440f
-      if (!sess->find_list){
50440f
-         OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-         return CKR_HOST_MEMORY;
50440f
-      }
50440f
-      else {
50440f
-         memset( sess->find_list, 0x0, 10 * sizeof(CK_OBJECT_HANDLE) );
50440f
-         sess->find_len = 10;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   sess->find_count = 0;
50440f
-   sess->find_idx   = 0;
50440f
-
50440f
-//  --- need to grab the object lock here
50440f
-   MY_LockMutex(&obj_list_mutex);
50440f
-   XProcLock();
50440f
-   object_mgr_update_from_shm();
50440f
-   XProcUnLock();
50440f
-
50440f
-   fa.hw_feature = FALSE;
50440f
-   fa.hidden_object = FALSE;
50440f
-   fa.sess = sess;
50440f
-   fa.pTemplate = pTemplate;
50440f
-   fa.ulCount = ulCount;
50440f
-
50440f
-   // which objects can be returned:
50440f
-   //
50440f
-   //   Public Session:   public session objects, public token objects
50440f
-   //   User Session:     all session objects,    all token objects
50440f
-   //   SO session:       public session objects, public token objects
50440f
-   //
50440f
-   // PKCS#11 v2.11 (pg. 79): "When searching using C_FindObjectsInit
50440f
-   // and C_FindObjects, hardware feature objects are not returned
50440f
-   // unless the CKA_CLASS attribute in the template has the value
50440f
-   // CKO_HW_FEATURE." So, we check for CKO_HW_FEATURE and if its set,
50440f
-   // we'll find these objects below. - KEY
50440f
-   for (i = 0; i < ulCount; i++) {
50440f
-      if (pTemplate[i].type == CKA_CLASS) {
50440f
-	 if (*(CK_ULONG *)pTemplate[i].pValue == CKO_HW_FEATURE) {
50440f
-	    fa.hw_feature = TRUE;
50440f
-	    break;
50440f
-	 }
50440f
-      }
50440f
-
50440f
-      /* only find CKA_HIDDEN objects if its specified in the template. */
50440f
-      if (pTemplate[i].type == CKA_HIDDEN) {
50440f
-	 if (*(CK_BBOOL *)pTemplate[i].pValue == TRUE) {
50440f
-	    fa.hidden_object = TRUE;
50440f
-	    break;
50440f
-	 }
50440f
-      }
50440f
-   }
50440f
-
50440f
-   switch (sess->session_info.state) {
50440f
-      case CKS_RO_PUBLIC_SESSION:
50440f
-      case CKS_RW_PUBLIC_SESSION:
50440f
-      case CKS_RW_SO_FUNCTIONS:
50440f
-	 fa.public_only = TRUE;
50440f
-
50440f
-	 bt_for_each_node(&publ_token_obj_btree, find_build_list_cb, &fa);
50440f
-	 bt_for_each_node(&sess_obj_btree, find_build_list_cb, &fa);
50440f
-         break;
50440f
-
50440f
-      case CKS_RO_USER_FUNCTIONS:
50440f
-      case CKS_RW_USER_FUNCTIONS:
50440f
-	 fa.public_only = FALSE;
50440f
-
50440f
-	 bt_for_each_node(&priv_token_obj_btree, find_build_list_cb, &fa);
50440f
-	 bt_for_each_node(&publ_token_obj_btree, find_build_list_cb, &fa);
50440f
-	 bt_for_each_node(&sess_obj_btree, find_build_list_cb, &fa);
50440f
-         break;
50440f
-   }
50440f
-
50440f
-   MY_UnlockMutex(&obj_list_mutex);
50440f
-
50440f
-   sess->find_active = TRUE;
50440f
-
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_find_final( SESSION *sess )
50440f
-{
50440f
-   if (!sess){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   if (sess->find_active == FALSE){
50440f
-      OCK_LOG_ERR(ERR_OPERATION_NOT_INITIALIZED);
50440f
-      return CKR_OPERATION_NOT_INITIALIZED;
50440f
-   }
50440f
-   free( sess->find_list );
50440f
-   sess->find_list   = NULL;
50440f
-   sess->find_count  = 0;
50440f
-   sess->find_idx    = 0;
50440f
-   sess->find_active = FALSE;
50440f
-
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_get_attribute_values( SESSION           * sess,
50440f
-                                 CK_OBJECT_HANDLE    handle,
50440f
-                                 CK_ATTRIBUTE      * pTemplate,
50440f
-                                 CK_ULONG            ulCount )
50440f
-{
50440f
-   OBJECT   * obj;
50440f
-   CK_BBOOL   priv_obj;
50440f
-   CK_BBOOL   locked = FALSE;
50440f
-   CK_RV      rc;
50440f
-
50440f
-   if (!pTemplate){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return rc;
50440f
-   }
50440f
-   locked = TRUE;
50440f
-
50440f
-   rc = object_mgr_find_in_map1( handle, &obj );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_OBJMGR_FIND_MAP);
50440f
-      goto done;
50440f
-   }
50440f
-   priv_obj = object_is_private( obj );
50440f
-
50440f
-   if (priv_obj == TRUE) {
50440f
-      if (sess->session_info.state == CKS_RO_PUBLIC_SESSION ||
50440f
-          sess->session_info.state == CKS_RW_PUBLIC_SESSION)
50440f
-      {
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         rc = CKR_USER_NOT_LOGGED_IN;
50440f
-         goto done;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   rc = object_get_attribute_values( obj, pTemplate, ulCount );
50440f
-   if (rc != CKR_OK)
50440f
-         OCK_LOG_ERR(ERR_OBJ_GETATTR_VALUES);
50440f
-done:
50440f
-   if (locked)
50440f
-      MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_get_object_size( CK_OBJECT_HANDLE   handle,
50440f
-                            CK_ULONG         * size )
50440f
-{
50440f
-   OBJECT    * obj;
50440f
-   CK_RV       rc;
50440f
-
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return rc;
50440f
-   }
50440f
-   rc = object_mgr_find_in_map1( handle, &obj );
50440f
-   if (rc != CKR_OK) {
50440f
-      OCK_LOG_ERR(ERR_OBJECT_HANDLE_INVALID);
50440f
-      rc = CKR_OBJECT_HANDLE_INVALID;
50440f
-      goto done;
50440f
-   }
50440f
-
50440f
-   *size = object_get_size( obj );
50440f
-
50440f
-done:
50440f
-   MY_UnlockMutex( &obj_list_mutex );
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-void
50440f
-purge_session_obj_cb(void *node, unsigned long obj_handle, void *p3)
50440f
-{
50440f
-   OBJECT *obj = (OBJECT *)node;
50440f
-   struct purge_args *pa = (struct purge_args *)p3;
50440f
-   CK_BBOOL del = FALSE;
50440f
-
50440f
-   if (obj->session == pa->sess) {
50440f
-      if (pa->type == PRIVATE) {
50440f
-         if (object_is_private(obj))
50440f
-            del = TRUE;
50440f
-      }
50440f
-      else if (pa->type == PUBLIC) {
50440f
-         if (object_is_public(obj))
50440f
-            del = TRUE;
50440f
-      }
50440f
-      else if (pa->type == ALL) {
50440f
-         del = TRUE;
50440f
-      }
50440f
-
50440f
-      if (del == TRUE) {
50440f
-         if (obj->map_handle)
50440f
-	    bt_node_free(&object_map_btree, obj->map_handle, free);
50440f
-
50440f
-	 bt_node_free(&sess_obj_btree, obj_handle, object_free);
50440f
-      }
50440f
-   }
50440f
-}
50440f
-
50440f
-// object_mgr_purge_session_objects()
50440f
-//
50440f
-// Args:    SESSION *
50440f
-//          SESS_OBJ_TYPE:  can be ALL, PRIVATE or PUBLIC
50440f
-//
50440f
-// Remove all session objects owned by the specified session satisfying
50440f
-// the 'type' requirements
50440f
-//
50440f
-CK_BBOOL
50440f
-object_mgr_purge_session_objects( SESSION       * sess,
50440f
-                                  SESS_OBJ_TYPE   type )
50440f
-{
50440f
-   struct purge_args pa = { sess, type };
50440f
-   CK_RV      rc;
50440f
-
50440f
-   if (!sess)
50440f
-      return FALSE;
50440f
-
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return FALSE;
50440f
-   }
50440f
-
50440f
-   bt_for_each_node(&sess_obj_btree, purge_session_obj_cb, &pa);
50440f
-
50440f
-   MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   return TRUE;
50440f
-}
50440f
-
50440f
-/* purge_token_obj_cb
50440f
- *
50440f
- * @p3 is the btree we're purging from
50440f
- */
50440f
-void
50440f
-purge_token_obj_cb(void *node, unsigned long obj_handle, void *p3)
50440f
-{
50440f
-   OBJECT *obj = (OBJECT *)node;
50440f
-   struct btree *t = (struct btree *)p3;
50440f
-
50440f
-   if (obj->map_handle)
50440f
-      bt_node_free(&object_map_btree, obj->map_handle, free);
50440f
-
50440f
-   bt_node_free(t, obj_handle, object_free);
50440f
-}
50440f
-
50440f
-// this routine cleans up the list of token objects.  in general, we don't
50440f
-// need to do this but when tracing memory leaks, it's best that we free everything
50440f
-// that we've allocated
50440f
-//
50440f
-CK_BBOOL
50440f
-object_mgr_purge_token_objects( )
50440f
-{
50440f
-   CK_RV      rc;
50440f
-
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return FALSE;
50440f
-   }
50440f
-
50440f
-   bt_for_each_node(&priv_token_obj_btree, purge_token_obj_cb, &priv_token_obj_btree);
50440f
-   bt_for_each_node(&publ_token_obj_btree, purge_token_obj_cb, &publ_token_obj_btree);
50440f
-
50440f
-   MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   return TRUE;
50440f
-}
50440f
-
50440f
-
50440f
-CK_BBOOL
50440f
-object_mgr_purge_private_token_objects( void )
50440f
-{
50440f
-   CK_RV      rc;
50440f
-
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return FALSE;
50440f
-   }
50440f
-
50440f
-   bt_for_each_node(&priv_token_obj_btree, purge_token_obj_cb, &priv_token_obj_btree);
50440f
-
50440f
-   MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   return TRUE;
50440f
-}
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_restore_obj( CK_BYTE *data, OBJECT *oldObj )
50440f
-{
50440f
-    return object_mgr_restore_obj_withSize(data, oldObj, -1);
50440f
-}
50440f
-
50440f
-//
50440f
-//Modified verrsion of object_mgr_restore_obj to bounds check
50440f
-//If data_size==-1, won't check bounds
50440f
-CK_RV
50440f
-object_mgr_restore_obj_withSize( CK_BYTE *data, OBJECT *oldObj, int data_size )
50440f
-{
50440f
-   OBJECT    * obj  = NULL;
50440f
-   CK_BBOOL    priv;
50440f
-   CK_RV       rc;
50440f
-
50440f
-   if (!data){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   // The calling stack MUST have the mutex
50440f
-   // to many grab it now.
50440f
-
50440f
-   if (oldObj != NULL) {
50440f
-      obj = oldObj;
50440f
-      rc = object_restore_withSize( data, &obj, TRUE, data_size );
50440f
-   }
50440f
-   else {
50440f
-      rc = object_restore_withSize( data, &obj, FALSE, data_size );
50440f
-      if (rc == CKR_OK) {
50440f
-         priv = object_is_private( obj );
50440f
-
50440f
-	 if (priv) {
50440f
-	    if (!bt_node_add(&priv_token_obj_btree, obj)) {
50440f
-               OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-               return CKR_HOST_MEMORY;
50440f
-	    }
50440f
-	 } else {
50440f
-	    if (!bt_node_add(&publ_token_obj_btree, obj)) {
50440f
-               OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-               return CKR_HOST_MEMORY;
50440f
-	    }
50440f
-	 }
50440f
-
50440f
-         XProcLock();
50440f
-
50440f
-         if (priv) {
50440f
-            if (global_shm->priv_loaded == FALSE){
50440f
-               if (global_shm->num_priv_tok_obj < MAX_TOK_OBJS)
50440f
-                  object_mgr_add_to_shm( obj );
50440f
-               else{
50440f
-                  OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-                  rc = CKR_HOST_MEMORY;
50440f
-               }
50440f
-            }
50440f
-         } else {
50440f
-            if (global_shm->publ_loaded == FALSE){
50440f
-               if (global_shm->num_publ_tok_obj < MAX_TOK_OBJS)
50440f
-                  object_mgr_add_to_shm( obj );
50440f
-               else{
50440f
-                  OCK_LOG_ERR(ERR_HOST_MEMORY);
50440f
-                  rc = CKR_HOST_MEMORY;
50440f
-               }
50440f
-            }
50440f
-         }
50440f
-
50440f
-         XProcUnLock();
50440f
-      } else {
50440f
-         OCK_LOG_ERR(ERR_OBJ_RESTORE_DATA);
50440f
-      }
50440f
-   }
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_set_attribute_values( SESSION           * sess,
50440f
-                                 CK_OBJECT_HANDLE    handle,
50440f
-                                 CK_ATTRIBUTE      * pTemplate,
50440f
-                                 CK_ULONG            ulCount )
50440f
-{
50440f
-   OBJECT    * obj;
50440f
-   CK_BBOOL    sess_obj, priv_obj;
50440f
-   CK_BBOOL    modifiable;
50440f
-   CK_RV       rc;
50440f
-
50440f
-
50440f
-   if (!pTemplate){
50440f
-      OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-      return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-   rc = MY_LockMutex( &obj_list_mutex );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_MUTEX_LOCK);
50440f
-      return rc;
50440f
-   }
50440f
-
50440f
-   rc = object_mgr_find_in_map1( handle, &obj );
50440f
-
50440f
-   MY_UnlockMutex( &obj_list_mutex );
50440f
-
50440f
-   if (rc != CKR_OK) {
50440f
-      OCK_LOG_ERR(ERR_OBJMGR_FIND_MAP);
50440f
-      return CKR_OBJECT_HANDLE_INVALID;
50440f
-   }
50440f
-
50440f
-   // determine whether the session is allowed to modify the object
50440f
-   //
50440f
-   modifiable = object_is_modifiable( obj );
50440f
-   sess_obj   = object_is_session_object( obj );
50440f
-   priv_obj   = object_is_private( obj );
50440f
-
50440f
-   // if object is not modifiable, it doesn't matter what kind of session
50440f
-   // is issuing the request...
50440f
-   //
50440f
-   if (!modifiable){
50440f
-      OCK_LOG_ERR(ERR_ATTRIBUTE_READ_ONLY);
50440f
-      return CKR_ATTRIBUTE_READ_ONLY;
50440f
-   }
50440f
-   if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
50440f
-      if (priv_obj){
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         return CKR_USER_NOT_LOGGED_IN;
50440f
-      }
50440f
-      if (!sess_obj){
50440f
-         OCK_LOG_ERR(ERR_SESSION_READ_ONLY);
50440f
-         return CKR_SESSION_READ_ONLY;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
50440f
-      if (!sess_obj){
50440f
-         OCK_LOG_ERR(ERR_SESSION_READ_ONLY);
50440f
-         return CKR_SESSION_READ_ONLY;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
50440f
-      if (priv_obj){
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         return CKR_USER_NOT_LOGGED_IN;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
50440f
-      if (priv_obj){
50440f
-         OCK_LOG_ERR(ERR_USER_NOT_LOGGED_IN);
50440f
-         return CKR_USER_NOT_LOGGED_IN;
50440f
-      }
50440f
-   }
50440f
-
50440f
-
50440f
-   rc = object_set_attribute_values( obj, pTemplate, ulCount );
50440f
-   if (rc != CKR_OK){
50440f
-      OCK_LOG_ERR(ERR_OBJ_SETATTR_VALUES);
50440f
-      return rc;
50440f
-   }
50440f
-   // okay.  the object has been updated.  if it's a session object,
50440f
-   // we're finished.  if it's a token object, we need to update
50440f
-   // non-volatile storage.
50440f
-   //
50440f
-   if (!sess_obj) {
50440f
-      TOK_OBJ_ENTRY  *entry = NULL;
50440f
-      CK_ULONG        index;
50440f
-
50440f
-      // I still think there's a race condition here if two processes are
50440f
-      // updating the same token object at the same time.  I don't know how
50440f
-      // to solve this short of assigning each token object it's own mutex...
50440f
-      //
50440f
-      obj->count_lo++;
50440f
-      if (obj->count_lo == 0)
50440f
-         obj->count_hi++;
50440f
-
50440f
-      save_token_object( obj );
50440f
-
50440f
-      rc = XProcLock();
50440f
-      if (rc != CKR_OK){
50440f
-         OCK_LOG_ERR(ERR_PROCESS_LOCK);
50440f
-         return rc;
50440f
-      }
50440f
-      if (priv_obj) {
50440f
-         rc = object_mgr_search_shm_for_obj( global_shm->priv_tok_objs,
50440f
-                                             0, global_shm->num_priv_tok_obj-1,
50440f
-                                             obj, &index );
50440f
-
50440f
-         if (rc != CKR_OK) {
50440f
-            OCK_LOG_ERR(ERR_OBJMGR_SEARCH);
50440f
-            XProcUnLock();
50440f
-            return rc;
50440f
-         }
50440f
-
50440f
-         entry = &global_shm->priv_tok_objs[index];
50440f
-      }
50440f
-      else {
50440f
-         rc = object_mgr_search_shm_for_obj( global_shm->publ_tok_objs,
50440f
-                                             0, global_shm->num_publ_tok_obj-1,
50440f
-                                             obj, &index );
50440f
-         if (rc != CKR_OK) {
50440f
-            OCK_LOG_ERR(ERR_OBJMGR_SEARCH);
50440f
-            XProcUnLock();
50440f
-            return rc;
50440f
-         }
50440f
-
50440f
-         entry = &global_shm->publ_tok_objs[index];
50440f
-      }
50440f
-
50440f
-      entry->count_lo = obj->count_lo;
50440f
-      entry->count_hi = obj->count_hi;
50440f
-
50440f
-      XProcUnLock();
50440f
-   }
50440f
-
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-
50440f
-//
50440f
-//
50440f
-void
50440f
-object_mgr_add_to_shm( OBJECT *obj )
50440f
-{
50440f
-   // TODO: Can't this function fail?
50440f
-   TOK_OBJ_ENTRY  * entry  = NULL;
50440f
-   CK_BBOOL         priv;
50440f
-
50440f
-   // the calling routine is responsible for locking the global_shm mutex
50440f
-   //
50440f
-
50440f
-   priv = object_is_private( obj );
50440f
-
50440f
-   if (priv)
50440f
-      entry = &global_shm->priv_tok_objs[global_shm->num_priv_tok_obj];
50440f
-   else
50440f
-      entry = &global_shm->publ_tok_objs[global_shm->num_publ_tok_obj];
50440f
-
50440f
-   entry->deleted  = FALSE;
50440f
-   entry->count_lo = 0;
50440f
-   entry->count_hi = 0;
50440f
-   memcpy( entry->name, obj->name, 8 );
50440f
-
50440f
-   if (priv) {
50440f
-      global_shm->num_priv_tok_obj++;
50440f
-      object_mgr_sort_priv_shm();
50440f
-   }
50440f
-   else {
50440f
-      global_shm->num_publ_tok_obj++;
50440f
-      object_mgr_sort_publ_shm();
50440f
-   }
50440f
-
50440f
-   return;
50440f
-}
50440f
-
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_del_from_shm( OBJECT *obj )
50440f
-{
50440f
-   CK_ULONG          index, count;
50440f
-   CK_BBOOL          priv;
50440f
-   CK_RV             rc;
50440f
-
50440f
-
50440f
-   // the calling routine is responsible for locking the global_shm mutex
50440f
-   //
50440f
-
50440f
-   priv = object_is_private( obj );
50440f
-
50440f
-   if (priv) {
50440f
-      rc = object_mgr_search_shm_for_obj( global_shm->priv_tok_objs,
50440f
-                                          0, global_shm->num_priv_tok_obj-1,
50440f
-                                          obj, &index );
50440f
-      if (rc != CKR_OK){
50440f
-         OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-         return CKR_FUNCTION_FAILED;
50440f
-      }
50440f
-      // Since the number of objects starts at 1 and index starts at zero, we
50440f
-      // decrement before we get count.  This eliminates the need to perform
50440f
-      // this operation later as well as decrementing the number of objects.
50440f
-      // (i.e. If we have 10 objects, num will be 10 but the last index is 9.
50440f
-      // If we want to delete the last object we need to subtract 9 from 9 not
50440f
-      // 10 from 9.)
50440f
-      //
50440f
-      global_shm->num_priv_tok_obj--;
50440f
-	if (index > global_shm->num_priv_tok_obj) {
50440f
-	      count = index - global_shm->num_priv_tok_obj;
50440f
-	} else {
50440f
-	      count = global_shm->num_priv_tok_obj - index;
50440f
-	}
50440f
-
50440f
-      if (count > 0) {  // If we are not deleting the last element in the list
50440f
-         // Move up count number of elements effectively deleting the index
50440f
-	 // NB: memmove is required since the copied regions may overlap
50440f
-         memmove((char *)&global_shm->priv_tok_objs[index],
50440f
-                (char *)&global_shm->priv_tok_objs[index+1],
50440f
-                sizeof(TOK_OBJ_ENTRY) * count );
50440f
-         // We need to zero out the last entry... Since the memcopy
50440f
-         // does not zero it out...
50440f
-         memset((char *)&global_shm->priv_tok_objs[global_shm->num_priv_tok_obj+1], 0,
50440f
-                sizeof(TOK_OBJ_ENTRY));
50440f
-      }
50440f
-      else { // We are deleting the last element which is in num_priv_tok_obj
50440f
-         memset((char *)&global_shm->priv_tok_objs[global_shm->num_priv_tok_obj], 0,
50440f
-                sizeof(TOK_OBJ_ENTRY));
50440f
-      }
50440f
-   }
50440f
-   else {
50440f
-      rc = object_mgr_search_shm_for_obj( global_shm->publ_tok_objs,
50440f
-                                          0, global_shm->num_publ_tok_obj-1,
50440f
-                                          obj, &index );
50440f
-      if (rc != CKR_OK){
50440f
-         OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-         return CKR_FUNCTION_FAILED;
50440f
-      }
50440f
-      global_shm->num_publ_tok_obj--;
50440f
-
50440f
-
50440f
-	if (index > global_shm->num_publ_tok_obj) {
50440f
-	      count = index - global_shm->num_publ_tok_obj;
50440f
-	} else {
50440f
-	      count = global_shm->num_publ_tok_obj - index;
50440f
-	}
50440f
-
50440f
-      if (count > 0) {
50440f
-	 // NB: memmove is required since the copied regions may overlap
50440f
-         memmove((char *)&global_shm->publ_tok_objs[index],
50440f
-                (char *)&global_shm->publ_tok_objs[index+1],
50440f
-                sizeof(TOK_OBJ_ENTRY) * count);
50440f
-         // We need to zero out the last entry... Since the memcopy
50440f
-         // does not zero it out...
50440f
-         memset((char *)&global_shm->publ_tok_objs[global_shm->num_publ_tok_obj+1], 0,
50440f
-                sizeof(TOK_OBJ_ENTRY));
50440f
-      }
50440f
-      else {
50440f
-         memset((char *)&global_shm->publ_tok_objs[global_shm->num_publ_tok_obj], 0,
50440f
-                sizeof(TOK_OBJ_ENTRY));
50440f
-      }
50440f
-   }
50440f
-
50440f
-   //
50440f
-   // object list is still sorted...so no need to re-sort
50440f
-   //
50440f
-
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_check_shm( OBJECT *obj )
50440f
-{
50440f
-   TOK_OBJ_ENTRY   * entry = NULL;
50440f
-   CK_BBOOL          priv;
50440f
-   CK_ULONG          index;
50440f
-   CK_RV             rc;
50440f
-
50440f
-
50440f
-   // the calling routine is responsible for locking the global_shm mutex
50440f
-   //
50440f
-
50440f
-   priv = object_is_private( obj );
50440f
-
50440f
-   if (priv) {
50440f
-      rc = object_mgr_search_shm_for_obj( global_shm->priv_tok_objs,
50440f
-                                          0, global_shm->num_priv_tok_obj-1,
50440f
-                                          obj, &index );
50440f
-      if (rc != CKR_OK){
50440f
-         OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-         return CKR_FUNCTION_FAILED;
50440f
-      }
50440f
-      entry = &global_shm->priv_tok_objs[index];
50440f
-   }
50440f
-   else {
50440f
-      rc = object_mgr_search_shm_for_obj( global_shm->publ_tok_objs,
50440f
-                                          0, global_shm->num_publ_tok_obj-1,
50440f
-                                          obj, &index );
50440f
-      if (rc != CKR_OK){
50440f
-         OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-         return CKR_FUNCTION_FAILED;
50440f
-      }
50440f
-      entry = &global_shm->publ_tok_objs[index];
50440f
-   }
50440f
-
50440f
-   if ((obj->count_hi == entry->count_hi) && (obj->count_lo == entry->count_lo))
50440f
-      return CKR_OK;
50440f
-
50440f
-   rc = reload_token_object( obj );
50440f
-   return rc;
50440f
-}
50440f
-
50440f
-
50440f
-// I'd use the standard bsearch() routine but I want an index, not a pointer.
50440f
-// Converting the pointer to an index might cause problems when switching
50440f
-// to a 64-bit environment...
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_search_shm_for_obj( TOK_OBJ_ENTRY  * obj_list,
50440f
-                               CK_ULONG         lo,
50440f
-                               CK_ULONG         hi,
50440f
-                               OBJECT         * obj,
50440f
-                               CK_ULONG       * index )
50440f
-{
50440f
-// SAB  XXX reduce the search time since this is what seems to be burning cycles
50440f
-   CK_ULONG idx;
50440f
-   if ( obj->index == 0 ) {
50440f
-	   for (idx=0;idx<=hi;idx++){
50440f
-	      if (memcmp(obj->name, obj_list[idx].name,8) == 0) {
50440f
-		 *index = idx;
50440f
-		 obj->index = idx;
50440f
-		 return CKR_OK ;
50440f
-	      }
50440f
-	   }
50440f
-   } else {
50440f
-	// SAB better double check
50440f
-	if ( memcmp(obj->name, obj_list[obj->index].name,8) == 0 ){
50440f
-		 *index = obj->index;
50440f
-		 return CKR_OK ;
50440f
-	} else { // something is hosed.. go back to the brute force method
50440f
-	   for (idx=0;idx<=hi;idx++){
50440f
-	      if (memcmp(obj->name, obj_list[idx].name,8) == 0) {
50440f
-		 *index = idx;
50440f
-		 obj->index = idx;
50440f
-		 return CKR_OK ;
50440f
-	      }
50440f
-	   }
50440f
-        }
50440f
-   }
50440f
-   OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-   return CKR_FUNCTION_FAILED;
50440f
-}
50440f
-
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_sort_priv_shm( void )
50440f
-{
50440f
-   // for now, we assume the list is sorted by design.  this is not unreasonable
50440f
-   // since new object handles are assigned in increasing order.  problems
50440f
-   // will arise after 36^8 token objects have been created...
50440f
-   //
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-
50440f
-//
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_sort_publ_shm( void )
50440f
-{
50440f
-   // for now, we assume the list is sorted by design.  this is not unreasonable
50440f
-   // since new object handles are assigned in increasing order.  problems
50440f
-   // will arise after 36^8 token objects have been created...
50440f
-   //
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-
50440f
-// this routine scans the local token object lists and updates any objects that
50440f
-// have changed.  it also adds any new token objects that have been added by
50440f
-// other processes and deletes any objects that have been deleted by other
50440f
-// processes
50440f
-//
50440f
-CK_RV
50440f
-object_mgr_update_from_shm( void )
50440f
-{
50440f
-   object_mgr_update_publ_tok_obj_from_shm();
50440f
-   object_mgr_update_priv_tok_obj_from_shm();
50440f
-
50440f
-   return CKR_OK;
50440f
-}
50440f
-
50440f
-void
50440f
-delete_objs_from_btree_cb(void *node, unsigned long obj_handle, void *p3)
50440f
-{
50440f
-   struct update_tok_obj_args * ua = (struct update_tok_obj_args *)p3;
50440f
-   TOK_OBJ_ENTRY              * shm_te = NULL;
50440f
-   OBJECT                     * obj = (OBJECT *)node;
50440f
-   CK_ULONG                     index;
50440f
-
50440f
-   /* for each TOK_OBJ_ENTRY in the SHM list */
50440f
-   for (index = 0; index < *(ua->num_entries); index++) {
50440f
-      shm_te = &(ua->entries[index]);
50440f
-
50440f
-      /* found it, return */
50440f
-      if (!memcmp(obj->name, shm_te->name, 8)) {
50440f
-	 return;
50440f
-      }
50440f
-   }
50440f
-
50440f
-   /* didn't find it in SHM, delete it from its btree */
50440f
-   bt_node_free(ua->t, obj_handle, object_free);
50440f
-}
50440f
-
50440f
-void
50440f
-find_by_name_cb(void *node, unsigned long obj_handle, void *p3)
50440f
-{
50440f
-	OBJECT *obj                  = (OBJECT *)node;
50440f
-	struct find_by_name_args *fa = (struct find_by_name_args *)p3;
50440f
-
50440f
-	if (fa->done)
50440f
-		return;
50440f
-
50440f
-	if (!memcmp(obj->name, fa->name, 8)) {
50440f
-		fa->done = TRUE;
50440f
-	}
50440f
-}
50440f
-
50440f
-CK_RV
50440f
-object_mgr_update_publ_tok_obj_from_shm()
50440f
-{
50440f
-	struct update_tok_obj_args   ua;
50440f
-	struct find_by_name_args     fa;
50440f
-	TOK_OBJ_ENTRY              * shm_te = NULL;
50440f
-	CK_ULONG                     index;
50440f
-	OBJECT                     * new_obj;
50440f
-
50440f
-	ua.entries = global_shm->publ_tok_objs;
50440f
-	ua.num_entries = &(global_shm->num_publ_tok_obj);
50440f
-	ua.t = &publ_token_obj_btree;
50440f
-
50440f
-	/* delete any objects not in SHM from the btree */
50440f
-	bt_for_each_node(&publ_token_obj_btree, delete_objs_from_btree_cb, &ua);
50440f
-
50440f
-	/* for each item in SHM, add it to the btree if its not there */
50440f
-	for (index = 0; index < global_shm->num_publ_tok_obj; index++) {
50440f
-		shm_te = &global_shm->publ_tok_objs[index];
50440f
-
50440f
-		fa.done = FALSE;
50440f
-		fa.name = shm_te->name;
50440f
-
50440f
-		/* find an object from SHM in the btree */
50440f
-		bt_for_each_node(&publ_token_obj_btree, find_by_name_cb, &fa);
50440f
-
50440f
-		/* we didn't find it in the btree, so add it */
50440f
-		if (fa.done == FALSE) {
50440f
-			new_obj = (OBJECT *)malloc(sizeof(OBJECT));
50440f
-			memset( new_obj, 0x0, sizeof(OBJECT) );
50440f
-
50440f
-			memcpy( new_obj->name, shm_te->name, 8 );
50440f
-			reload_token_object( new_obj );
50440f
-			bt_node_add(&publ_token_obj_btree, new_obj);
50440f
-		}
50440f
-	}
50440f
-
50440f
-	return CKR_OK;
50440f
-}
50440f
-
50440f
-CK_RV
50440f
-object_mgr_update_priv_tok_obj_from_shm()
50440f
-{
50440f
-	struct update_tok_obj_args   ua;
50440f
-	struct find_by_name_args     fa;
50440f
-	TOK_OBJ_ENTRY              * shm_te = NULL;
50440f
-	CK_ULONG                     index;
50440f
-	OBJECT                     * new_obj;
50440f
-
50440f
-	// SAB XXX don't bother doing this call if we are not in the correct
50440f
-	// login state
50440f
-	if ( !(global_login_state == CKS_RW_USER_FUNCTIONS ||
50440f
-	       global_login_state == CKS_RO_USER_FUNCTIONS) ) {
50440f
-		return CKR_OK;
50440f
-	}
50440f
-
50440f
-	ua.entries = global_shm->priv_tok_objs;
50440f
-	ua.num_entries = &(global_shm->num_priv_tok_obj);
50440f
-	ua.t = &priv_token_obj_btree;
50440f
-
50440f
-	/* delete any objects not in SHM from the btree */
50440f
-	bt_for_each_node(&priv_token_obj_btree, delete_objs_from_btree_cb, &ua);
50440f
-
50440f
-	/* for each item in SHM, add it to the btree if its not there */
50440f
-	for (index = 0; index < global_shm->num_priv_tok_obj; index++) {
50440f
-		shm_te = &global_shm->priv_tok_objs[index];
50440f
-
50440f
-		fa.done = FALSE;
50440f
-		fa.name = shm_te->name;
50440f
-
50440f
-		/* find an object from SHM in the btree */
50440f
-		bt_for_each_node(&priv_token_obj_btree, find_by_name_cb, &fa);
50440f
-
50440f
-		/* we didn't find it in the btree, so add it */
50440f
-		if (fa.done == FALSE) {
50440f
-			new_obj = (OBJECT *)malloc(sizeof(OBJECT));
50440f
-			memset( new_obj, 0x0, sizeof(OBJECT) );
50440f
-
50440f
-			memcpy( new_obj->name, shm_te->name, 8 );
50440f
-			reload_token_object( new_obj );
50440f
-			bt_node_add(&priv_token_obj_btree, new_obj);
50440f
-		}
50440f
-	}
50440f
-
50440f
-	return CKR_OK;
50440f
-}
50440f
-
50440f
-// SAB FIXME FIXME
50440f
-
50440f
-void
50440f
-purge_map_by_type_cb(void *node, unsigned long map_handle, void *p3)
50440f
-{
50440f
-   OBJECT_MAP    *map  = (OBJECT_MAP *)node;
50440f
-   SESS_OBJ_TYPE  type = *(SESS_OBJ_TYPE *)p3;
50440f
-
50440f
-   if (type == PRIVATE) {
50440f
-      if (map->is_private) {
50440f
-	 bt_node_free(&object_map_btree, map_handle, free);
50440f
-      }
50440f
-   } else if (type == PUBLIC) {
50440f
-      if (!map->is_private) {
50440f
-	 bt_node_free(&object_map_btree, map_handle, free);
50440f
-      }
50440f
-   }
50440f
-}
50440f
-
50440f
-CK_BBOOL
50440f
-object_mgr_purge_map(
50440f
-                      SESSION       * sess,
50440f
-                      SESS_OBJ_TYPE   type )
50440f
-{
50440f
-   if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
50440f
-     OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
-     return CKR_FUNCTION_FAILED;
50440f
-   }
50440f
-
50440f
-   bt_for_each_node(&object_map_btree, purge_map_by_type_cb, &type);
50440f
-
50440f
-   pthread_rwlock_unlock(&obj_list_rw_mutex);
50440f
-
50440f
-   return TRUE;
50440f
-}
50440f
-
50440f
-#ifdef DEBUG
50440f
-void
50440f
-dump_shm(const char *s)
50440f
-{
50440f
-	CK_ULONG i;
50440f
-	OCK_LOG_DEBUG("%s: dump_shm priv:", s);
50440f
-
50440f
-	for (i = 0; i < global_shm->num_priv_tok_obj; i++) {
50440f
-		OCK_LOG_DEBUG("[%lu]: %.8s", i, global_shm->priv_tok_objs[i].name);
50440f
-	}
50440f
-	OCK_LOG_DEBUG("%s: dump_shm publ:", s);
50440f
-	for (i = 0; i < global_shm->num_publ_tok_obj; i++) {
50440f
-		OCK_LOG_DEBUG("[%lu]: %.8s", i, global_shm->publ_tok_objs[i].name);
50440f
-	}
50440f
-}
50440f
-#endif
50440f
diff --git a/usr/lib/pkcs11/common/obj_mgr.c b/usr/lib/pkcs11/common/obj_mgr.c
50440f
index 98c3d42..92c11c2 100755
50440f
--- a/usr/lib/pkcs11/common/obj_mgr.c
50440f
+++ b/usr/lib/pkcs11/common/obj_mgr.c
50440f
@@ -339,6 +339,15 @@ object_mgr_add( SESSION          * sess,
50440f
       OCK_LOG_ERR(ERR_OBJ_CREATE); 
50440f
       goto done;
50440f
    }
50440f
+
50440f
+   if (token_specific.t_object_add != NULL) {
50440f
+      rc = token_specific.t_object_add(o);
50440f
+      if (rc != CKR_OK) {
50440f
+	 OCK_LOG_ERR(ERR_OBJ_CREATE);
50440f
+	 goto done;
50440f
+      }
50440f
+   }
50440f
+
50440f
    // check whether session has permissions to create the object, etc
50440f
    //
50440f
    // Object                  R/O      R/W      R/O     R/W    R/W
50440f
commit ce8de9df2c93ad93f07b002fed6c0f59ce79bcda
50440f
Author: Joy Latten <jmlatten@linux.vnet.ibm.com>
50440f
Date:   Wed Nov 13 15:23:52 2013 -0600
50440f
50440f
    Objects were not being encrypted and saved to disk for secure key token.
50440f
    Needed to call encrypt_data_with_clear_key() and let it determine if
50440f
    clear key or secure key and do appropriate actions.
50440f
    
50440f
    Signed-off-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
50440f
50440f
diff --git a/usr/lib/pkcs11/common/loadsave.c b/usr/lib/pkcs11/common/loadsave.c
50440f
index b564de0..d0d0673 100755
50440f
--- a/usr/lib/pkcs11/common/loadsave.c
50440f
+++ b/usr/lib/pkcs11/common/loadsave.c
50440f
@@ -965,7 +965,7 @@ CK_RV save_private_token_object(OBJECT * obj)
50440f
 	add_pkcs_padding(clear + clear_len, block_size, clear_len,
50440f
 			 padded_len);
50440f
 
50440f
-	rc = encrypt_data(key, key_len,
50440f
+	rc = encrypt_data_with_clear_key(key, key_len,
50440f
 			  token_specific.data_store.obj_initial_vector,
50440f
 			  clear, padded_len, cipher, &cipher_len);
50440f
 	if (rc != CKR_OK) {
50440f
@@ -1227,7 +1227,7 @@ CK_RV restore_private_token_object(CK_BYTE * data, CK_ULONG len, OBJECT * pObj)
50440f
 	}
50440f
 	memcpy(key, master_key, key_len);
50440f
 
50440f
-	rc = decrypt_data(key, key_len,
50440f
+	rc = decrypt_data_with_clear_key(key, key_len,
50440f
 			  token_specific.data_store.obj_initial_vector,
50440f
 			  data, len, clear, &clear_len);
50440f
 	if (rc != CKR_OK) {
50440f
commit f4df4a49d478f9846199250a4e7cda6135ff234f
50440f
Author: Joy Latten <jmlatten@linux.vnet.ibm.com>
50440f
Date:   Wed Nov 13 15:59:59 2013 -0600
50440f
50440f
    CCA token was putting incorrect OID info into CKA_ECDSA_PARAMS.
50440f
    This attribute must be passed in by user when generating EC keypair
50440f
    and should not be over-written.
50440f
    Since CKA_EC_POINT is for public key, does not require being in private key.
50440f
    Created a routine to get signature length when length only.
50440f
    
50440f
    Signed-off-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
50440f
50440f
diff --git a/usr/lib/pkcs11/cca_stdll/cca_specific.c b/usr/lib/pkcs11/cca_stdll/cca_specific.c
50440f
index be4073b..f4bb76c 100644
50440f
--- a/usr/lib/pkcs11/cca_stdll/cca_specific.c
50440f
+++ b/usr/lib/pkcs11/cca_stdll/cca_specific.c
50440f
@@ -1340,6 +1340,7 @@ token_create_ec_keypair(TEMPLATE *publ_tmpl,
50440f
 	CK_BYTE q[CCATOK_EC_MAX_Q_LEN];
50440f
 	CK_BBOOL found = FALSE;
50440f
 	CK_RV rv;
50440f
+	CK_ATTRIBUTE *attr = NULL;
50440f
 
50440f
 	/*
50440f
 	 * The token includes the header section first,
50440f
@@ -1347,8 +1348,14 @@ token_create_ec_keypair(TEMPLATE *publ_tmpl,
50440f
 	 * and the public key section last.
50440f
 	 */
50440f
 
50440f
+	/* The pkcs#11v2.20:
50440f
+	 * CKA_ECDSA_PARAMS must be in public key's template when
50440f
+	 * generating key pair and added to private key template.
50440f
+	 * CKA_EC_POINT added to public key when key is generated.
50440f
+	 */
50440f
+
50440f
 	/*
50440f
-	 * Get Q data for public and private key.
50440f
+	 * Get Q data for public key.
50440f
 	 */
50440f
 	pubkey_offset = cca_ec_publkey_offset(tok);
50440f
 
50440f
@@ -1370,41 +1377,14 @@ token_create_ec_keypair(TEMPLATE *publ_tmpl,
50440f
 		return rv;
50440f
 	}
50440f
 
50440f
-	if ((rv = build_update_attribute(priv_tmpl, CKA_EC_POINT, q, q_len)))
50440f
-	{
50440f
-		DBG("Build and update attribute for q failed rv=0x%lx\n", rv);
50440f
-		return rv;
50440f
-	}
50440f
-
50440f
-	/*
50440f
-	 * Get ECDSA PAMRAMS for both keys.
50440f
-	 */
50440f
-	p_len_offset = pubkey_offset + CCA_PUBL_P_LEN_OFFSET;
50440f
-	p_len = *(uint16_t *)&tok[p_len_offset];
50440f
-	p_len = ntohs(p_len);
50440f
-
50440f
-	for (i = 0; i < NUMEC; i++) {
50440f
-		if (p_len == der_ec_supported[i].len_bits) {
50440f
-			found = TRUE;
50440f
-			break;
50440f
-		}
50440f
-	}
50440f
-
50440f
-	if(found == FALSE) {
50440f
-		DBG("The p len %lx is not valid.\n", p_len);
50440f
-		return CKR_FUNCTION_FAILED;
50440f
-	}
50440f
-
50440f
-	if ((rv = build_update_attribute(publ_tmpl, CKA_ECDSA_PARAMS,
50440f
-					der_ec_supported[i].data,
50440f
-					der_ec_supported[i].data_size))) {
50440f
-		DBG("Build and update attribute for der data failed rv=0x%lx\n", rv);
50440f
-		return rv;
50440f
+	/* Add ec params to private key */
50440f
+	if (!template_attribute_find(publ_tmpl, CKA_ECDSA_PARAMS, &attr)) {
50440f
+		OCK_LOG_ERR(ERR_TEMPLATE_INCOMPLETE);
50440f
+		return CKR_TEMPLATE_INCOMPLETE;
50440f
 	}
50440f
 
50440f
 	if ((rv = build_update_attribute(priv_tmpl, CKA_ECDSA_PARAMS,
50440f
-					der_ec_supported[i].data,
50440f
-					der_ec_supported[i].data_size))) {
50440f
+					attr->pValue, attr->ulValueLen))) {
50440f
 		DBG("Build and update attribute for der data failed rv=0x%lx\n", rv);
50440f
 		return rv;
50440f
 	}
50440f
@@ -2180,3 +2160,40 @@ token_specific_object_add(OBJECT *object)
50440f
 
50440f
 	return CKR_OK;
50440f
 }
50440f
+
50440f
+CK_RV
50440f
+get_ecsiglen(OBJECT *key_obj, CK_ULONG *size)
50440f
+{
50440f
+        CK_BBOOL flag;
50440f
+        CK_ATTRIBUTE *attr = NULL;
50440f
+        int i;
50440f
+
50440f
+        flag = template_attribute_find( key_obj->template,
50440f
+                        CKA_ECDSA_PARAMS, &attr );
50440f
+        if (flag == FALSE) {
50440f
+                OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
+                return CKR_FUNCTION_FAILED;
50440f
+        }
50440f
+
50440f
+        /* loop thru supported curves to find the size.
50440f
+         * both pkcs#11v2.20 and CCA expect the signature length to be
50440f
+         * twice the length of p.
50440f
+         * (See EC Signatures in pkcs#11v2.20 and docs for CSNDDSG.)
50440f
+         */
50440f
+        for (i = 0; i < NUMEC; i++) {
50440f
+                if ((memcmp(attr->pValue, der_ec_supported[i].data,
50440f
+                                attr->ulValueLen) == 0)) {
50440f
+			*size = der_ec_supported[i].len_bits;
50440f
+			/* round up if necessary */
50440f
+			if ((*size % 8) == 0)
50440f
+				*size = (*size / 8) * 2;
50440f
+			else
50440f
+				*size = ((*size / 8) + 1) * 2;
50440f
+			OCK_LOG_DEBUG("getlen, curve = %d, size = %d\n", der_ec_supported[i].len_bits, *size);
50440f
+                        return CKR_OK;
50440f
+                }
50440f
+        }
50440f
+
50440f
+        OCK_LOG_ERR(ERR_MECHANISM_PARAM_INVALID);
50440f
+        return CKR_MECHANISM_PARAM_INVALID;
50440f
+}
50440f
diff --git a/usr/lib/pkcs11/common/mech_ec.c b/usr/lib/pkcs11/common/mech_ec.c
50440f
index cf1c140..aab11b8 100644
50440f
--- a/usr/lib/pkcs11/common/mech_ec.c
50440f
+++ b/usr/lib/pkcs11/common/mech_ec.c
50440f
@@ -75,8 +75,7 @@ ec_sign( SESSION			*sess,
50440f
                CK_ULONG			*out_data_len )
50440f
 {
50440f
 	OBJECT          *key_obj   = NULL;
50440f
-	CK_ATTRIBUTE    *attr      = NULL;
50440f
-	CK_ULONG         public_key_len;
50440f
+	CK_ULONG         plen;
50440f
 	CK_BBOOL         flag;
50440f
 	CK_RV            rc;
50440f
 
50440f
@@ -91,23 +90,21 @@ ec_sign( SESSION			*sess,
50440f
 		return rc;
50440f
 	}
50440f
 
50440f
-	flag = template_attribute_find( key_obj->template,
50440f
-			CKA_EC_POINT, &attr );
50440f
-	if (flag == FALSE)
50440f
-		return CKR_FUNCTION_FAILED;
50440f
-	else
50440f
-		public_key_len = attr->ulValueLen;
50440f
+	rc = get_ecsiglen(key_obj, &plen);
50440f
+	if (rc != CKR_OK) {
50440f
+		OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
+		return rc;
50440f
+	}
50440f
 
50440f
 	if (length_only == TRUE) {
50440f
-		*out_data_len = public_key_len;
50440f
+		*out_data_len = plen;
50440f
 		return CKR_OK;
50440f
 	}
50440f
 
50440f
-	if (*out_data_len < public_key_len) {
50440f
+	if (*out_data_len < plen) {
50440f
 		OCK_LOG_ERR(ERR_BUFFER_TOO_SMALL);
50440f
 		return CKR_BUFFER_TOO_SMALL;
50440f
 	}
50440f
-	*out_data_len = public_key_len;
50440f
 
50440f
 	rc = ckm_ec_sign( in_data, in_data_len, out_data,
50440f
 			out_data_len, key_obj );
50440f
@@ -160,8 +157,7 @@ ec_verify(SESSION		*sess,
50440f
 	CK_ULONG		sig_len )
50440f
 {
50440f
 	OBJECT          *key_obj  = NULL;
50440f
-	CK_ATTRIBUTE    *attr     = NULL;
50440f
-	CK_ULONG         public_key_len;
50440f
+	CK_ULONG         plen;
50440f
 	CK_BBOOL         flag;
50440f
 	CK_RV            rc;
50440f
 
50440f
@@ -171,16 +167,16 @@ ec_verify(SESSION		*sess,
50440f
 		OCK_LOG_ERR(ERR_OBJMGR_FIND_MAP);
50440f
 		return rc;
50440f
 	}
50440f
-	flag = template_attribute_find( key_obj->template,
50440f
-			CKA_EC_POINT, &attr );
50440f
-	if (flag == FALSE)
50440f
-		return CKR_FUNCTION_FAILED;
50440f
-	else
50440f
-		public_key_len = attr->ulValueLen;
50440f
+
50440f
+	rc = get_ecsiglen(key_obj, &plen);
50440f
+	if (rc != CKR_OK) {
50440f
+		OCK_LOG_ERR(ERR_FUNCTION_FAILED);
50440f
+		return rc;
50440f
+	}
50440f
 
50440f
 	// check input data length restrictions
50440f
 	//
50440f
-	if (sig_len > public_key_len){
50440f
+	if (sig_len > plen){
50440f
 		OCK_LOG_ERR(ERR_SIGNATURE_LEN_RANGE);
50440f
 		return CKR_SIGNATURE_LEN_RANGE;
50440f
 	}
50440f
commit b3c5e1635e1dd25d73f57b206c390719dac4b5f8
50440f
Author: Joy Latten <jmlatten@linux.vnet.ibm.com>
50440f
Date:   Wed Oct 2 17:15:34 2013 -0500
50440f
50440f
    The sha256 in CCA (CSNBOWH) can take input larger than 32MB.
50440f
    
50440f
    Signed-off-by: Joy Latten <jmlatten@linux.vnet.ibm.com>
50440f
50440f
diff --git a/usr/lib/pkcs11/cca_stdll/cca_specific.c b/usr/lib/pkcs11/cca_stdll/cca_specific.c
50440f
index bfee04e..be4073b 100644
50440f
--- a/usr/lib/pkcs11/cca_stdll/cca_specific.c
50440f
+++ b/usr/lib/pkcs11/cca_stdll/cca_specific.c
50440f
@@ -1675,9 +1675,7 @@ token_specific_sha2_update(DIGEST_CONTEXT *c, CK_BYTE *in_data, CK_ULONG in_data
50440f
 
50440f
 	DBG("update %lu", in_data_len);
50440f
 
50440f
-	if (in_data_len > CCA_MAX_SHA256_DATA_LEN)
50440f
-		return CKR_DATA_LEN_RANGE;
50440f
-	else if (!in_data)
50440f
+	if (!in_data)
50440f
 		goto done;
50440f
 
50440f
 	cca_ctx = (struct cca_sha256_ctx *)c->context;
50440f
diff --git a/usr/lib/pkcs11/cca_stdll/defs.h b/usr/lib/pkcs11/cca_stdll/defs.h
50440f
index 927cf8e..19e14dd 100755
50440f
--- a/usr/lib/pkcs11/cca_stdll/defs.h
50440f
+++ b/usr/lib/pkcs11/cca_stdll/defs.h
50440f
@@ -18,7 +18,6 @@
50440f
 #define MAX_PIN_LEN 128
50440f
 #define MIN_PIN_LEN   4
50440f
 
50440f
-#define CCA_MAX_SHA256_DATA_LEN  (32 * 1024 * 1024 - 64) /* 32MB - 64 */
50440f
 #define CCA_CHAIN_VECTOR_LEN     128
50440f
 #define CCA_MAX_TAIL_LEN          64
50440f
 #define CCA_HASH_PART_FIRST        0