2788 lines
84 KiB
Diff
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
|