opencryptoki/opencryptoki-3.0-bz1033284....

2788 lines
84 KiB
Diff

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