From b32e24b27935ac3e49ee1974af22491b5ec8f978 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 05 2015 13:21:26 +0000 Subject: import opencryptoki-3.2-4.1.el7 --- diff --git a/.gitignore b/.gitignore index bd062f5..f618106 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/opencryptoki-v3.0.tar.gz +SOURCES/opencryptoki-v3.2.tgz diff --git a/.opencryptoki.metadata b/.opencryptoki.metadata index 131c70d..3af4ed2 100644 --- a/.opencryptoki.metadata +++ b/.opencryptoki.metadata @@ -1 +1 @@ -6244e8c3960384ec022c9a6652296388079f31b3 SOURCES/opencryptoki-v3.0.tar.gz +876f34f5fc2dc6d1bd66b70710683854a2e0b265 SOURCES/opencryptoki-v3.2.tgz diff --git a/SOURCES/opencryptoki-2.4-group.patch b/SOURCES/opencryptoki-2.4-group.patch deleted file mode 100644 index abaa592..0000000 --- a/SOURCES/opencryptoki-2.4-group.patch +++ /dev/null @@ -1,47 +0,0 @@ -diff -urp opencryptoki-2.4.orig/usr/lib/pkcs11/api/shrd_mem.c opencryptoki-2.4/usr/lib/pkcs11/api/shrd_mem.c ---- opencryptoki-2.4.orig/usr/lib/pkcs11/api/shrd_mem.c.in 2011-08-15 08:17:14.000000000 -0400 -+++ opencryptoki-2.4/usr/lib/pkcs11/api/shrd_mem.c.in 2011-08-15 10:22:49.000000000 -0400 -@@ -351,43 +351,6 @@ attach_shared_memory() { - return NULL; - } - -- -- // SAB check for the group id here and membership here as well -- grp = getgrnam("pkcs11"); -- if ( grp ) { -- int i=0; -- char member=0; -- -- pw = getpwuid(getuid()); -- -- epw = getpwuid(geteuid()); -- -- while( grp->gr_mem[i] ) { -- if (pw) { -- if ( strncmp(pw->pw_name, grp->gr_mem[i],strlen(pw->pw_name)) == 0 ){ -- member = 1; -- break; -- } -- } -- if (epw) { -- if ( strncmp(epw->pw_name, grp->gr_mem[i],strlen(epw->pw_name)) == 0 ){ -- member = 1; -- break; -- } -- } -- i++; -- } -- if ( ! member ) { -- return NULL; // SAB don't bother even attaching... -- } -- -- -- } else { -- return NULL; -- } -- -- -- - Anchor->shm_tok = ftok(TOK_PATH,'b'); - - // Get the shared memory id. diff --git a/SOURCES/opencryptoki-3.0-bz1033284.patch b/SOURCES/opencryptoki-3.0-bz1033284.patch deleted file mode 100644 index 0d133db..0000000 --- a/SOURCES/opencryptoki-3.0-bz1033284.patch +++ /dev/null @@ -1,2787 +0,0 @@ -commit 84db3078dea9ffffbaeb76ad52e72dbdc8f6c8f1 -Author: Joy Latten -Date: Wed Oct 2 16:34:40 2013 -0500 - - CCA token was not importing rsa keypair correctly in v3. - - Signed-off-by: Joy Latten - -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 --#include --#include --#include // for memcmp() et al --#include -- --#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 -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 - -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 -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 - -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 -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 - -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 diff --git a/SOURCES/opencryptoki-3.0-bz1054661.patch b/SOURCES/opencryptoki-3.0-bz1054661.patch deleted file mode 100644 index 99e12b5..0000000 --- a/SOURCES/opencryptoki-3.0-bz1054661.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 95064291fe13d4ed98e195946d931fe779f8a48f Mon Sep 17 00:00:00 2001 -From: Joy Latten -Date: Fri, 17 Jan 2014 10:33:19 -0600 -Subject: [PATCH] Problem: A regular user in pkcs11 group cannot issue pkcsconf - -t. When shm_open() creates shared memory object, it honors umask of the - caller. This patch ensures the shared memory has expected permissions when it - is created. -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Joy Latten -Signed-off-by: Dan Horák ---- - usr/lib/pkcs11/common/shared_memory.c | 27 ++++++++++++++++++++++----- - 1 file changed, 22 insertions(+), 5 deletions(-) - -diff --git a/usr/lib/pkcs11/common/shared_memory.c b/usr/lib/pkcs11/common/shared_memory.c -index a8710c5..bf0411d 100644 ---- a/usr/lib/pkcs11/common/shared_memory.c -+++ b/usr/lib/pkcs11/common/shared_memory.c -@@ -161,12 +161,29 @@ sm_open(const char *sm_name, int mode, void **p_addr, size_t len, int force) - goto done; - } - -- fd = shm_open(name, O_RDWR | O_CREAT, mode); -+ /* try and open first... */ -+ fd = shm_open(name, O_RDWR, mode); - if (fd < 0) { -- rc = -errno; -- SYS_ERROR(errno, "Failed to open shared memory \"%s\".\n", -- name); -- goto done; -+ /* maybe it needs to be created ... */ -+ fd = shm_open(name, O_RDWR | O_CREAT, mode); -+ if (fd < 0) { -+ rc = -errno; -+ SYS_ERROR(errno, -+ "Failed to open shared memory \"%s\".\n", -+ name); -+ goto done; -+ } else { -+ /* umask may have altered permissions if we created -+ * the shared memory in above call, so set proper -+ * permissions just in case. -+ */ -+ if (fchmod(fd, mode) == -1) { -+ rc = -errno; -+ SYS_ERROR(errno, "fchmod(%s): %s\n", -+ name, strerror(errno)); -+ goto done; -+ } -+ } - } - - /* --- -1.8.1.4 - diff --git a/SOURCES/opencryptoki-3.0-conditional-manpages.patch b/SOURCES/opencryptoki-3.0-conditional-manpages.patch deleted file mode 100644 index a62f414..0000000 --- a/SOURCES/opencryptoki-3.0-conditional-manpages.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/man/man1/Makefile.am b/man/man1/Makefile.am -index 41a1259..824439e 100644 ---- a/man/man1/Makefile.am -+++ b/man/man1/Makefile.am -@@ -1,3 +1,8 @@ --man1_MANS=pkcsconf.1 pkcsicsf.1 pkcscca.1 -+man1_MANS=pkcsconf.1 pkcsicsf.1 -+ -+if ENABLE_CCATOK -+man1_MANS += pkcscca.1 -+endif -+ - EXTRA_DIST = $(man1_MANS) - CLEANFILES = $(man1_MANS) diff --git a/SOURCES/opencryptoki-3.0-format.patch b/SOURCES/opencryptoki-3.0-format.patch deleted file mode 100644 index d2114cf..0000000 --- a/SOURCES/opencryptoki-3.0-format.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 02d46e95acfca2ac3ca85a3f1c3d271a04e29206 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Dan=20Hor=C3=A1k?= -Date: Tue, 3 Dec 2013 14:44:36 +0100 -Subject: [PATCH] fix build with -Werror=format-security -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - - -Signed-off-by: Dan Horák ---- - usr/sbin/pkcsslotd/log.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/usr/sbin/pkcsslotd/log.c b/usr/sbin/pkcsslotd/log.c -index 949d95d..a2292ac 100755 ---- a/usr/sbin/pkcsslotd/log.c -+++ b/usr/sbin/pkcsslotd/log.c -@@ -823,7 +823,7 @@ BOOL PKCS_Log ( pLogHandle phLog, char *Format, va_list ap ) { - - /* Always log to syslog, if we're using it */ - if ( pInfo->UseSyslog ) { -- syslog(pInfo->LogLevel, Buffer); -+ syslog(pInfo->LogLevel, "%s", Buffer); - } - - return TRUE; --- -1.8.1.4 - diff --git a/SOURCES/opencryptoki-3.0-opencryptoki-man.patch b/SOURCES/opencryptoki-3.0-opencryptoki-man.patch deleted file mode 100644 index 8f84da4..0000000 --- a/SOURCES/opencryptoki-3.0-opencryptoki-man.patch +++ /dev/null @@ -1,37 +0,0 @@ -commit b50eb39e3cf8ccfdb735fbddfcdae10bdb70e1c4 -Author: Joy Latten -Date: Wed Sep 4 16:12:38 2013 -0500 - - Update the opencryptoki(7) man page and remove reference to - pkcs11_startup and pk_config_data. - - Signed-off-by: Joy Latten - -diff --git a/man/man7/opencryptoki.7.in b/man/man7/opencryptoki.7.in -index 5030bd2..bf5a65e 100644 ---- a/man/man7/opencryptoki.7.in -+++ b/man/man7/opencryptoki.7.in -@@ -9,11 +9,9 @@ tokens, which may be implemented via software or hardware. The PKCS#11 - specification has been released by RSA Labs. More information on PKCS#11 - can be found on the RSA labs website: http://www.rsa.com/rsalabs. - --To use openCryptoki, first run \fIpkcs11_startup\fP to initialize the --contents of the pk_config_data file. Then run the \fIpkcsslotd\fP daemon. At --this point, openCryptoki is ready to start receiving PKCS#11 requests --from user applications. If openCryptoki is included by your distro, its --likely that pkcs11_startup is run automatically by an init script. -+To use openCryptoki, run the \fIpkcsslotd\fP daemon. The daemon will -+read the \fIopencryptoki.conf\fP file to collect information about the -+tokens and their slots. - - Use the \fIpkcsconf\fP utility to further configure openCryptoki once the - daemon is running. -@@ -33,7 +31,5 @@ privileges of other openCryptoki users. - .TP - \fBpkcsconf\fP(1), - .TP --\fBpk_config_data\fP(5), --.TP --\fBpkcs11_startup\fP(1). -+\fBopencryptoki.conf\fP(5). - .PD diff --git a/SOURCES/opencryptoki-3.0-pkcscca-tool.patch b/SOURCES/opencryptoki-3.0-pkcscca-tool.patch deleted file mode 100644 index b65a7f8..0000000 --- a/SOURCES/opencryptoki-3.0-pkcscca-tool.patch +++ /dev/null @@ -1,1039 +0,0 @@ -diff --git a/.gitignore b/.gitignore -index 2f0768d..4e11a3c 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -18,6 +18,7 @@ libtool - ltmain.sh - man/man1/pkcsconf.1 - man/man1/pkcsicsf.1 -+man/man1/pkcscca.1 - man/man5/opencryptoki.conf.5 - man/man7/opencryptoki.7 - man/man8/pkcsslotd.8 -diff --git a/configure.in b/configure.in -index 8a47472..083c597 100644 ---- a/configure.in -+++ b/configure.in -@@ -739,6 +739,7 @@ AC_CONFIG_FILES([Makefile usr/Makefile \ - usr/sbin/pkcsslotd/Makefile \ - usr/sbin/pkcsconf/Makefile \ - usr/sbin/pkcsicsf/Makefile \ -+ usr/sbin/pkcscca/Makefile \ - usr/sbin/pkcscca_migrate/Makefile \ - usr/lib/pkcs11/methods/Makefile \ - usr/lib/pkcs11/leeds_stdll/Makefile \ -@@ -761,6 +762,7 @@ AC_CONFIG_FILES([Makefile usr/Makefile \ - man/man1/Makefile \ - man/man1/pkcsconf.1 \ - man/man1/pkcsicsf.1 \ -+ man/man1/pkcscca.1 \ - man/man5/Makefile \ - man/man5/opencryptoki.conf.5 \ - man/man7/Makefile \ -diff --git a/doc/README.cca_stdll b/doc/README.cca_stdll -index f535dfa..a0d13f1 100644 ---- a/doc/README.cca_stdll -+++ b/doc/README.cca_stdll -@@ -1,24 +1,173 @@ -+CCA TOKEN - --README for the CCA secure-key token -+OverView -+-------- -+The CCA token is a secure key token. -+A Secure key - key value does not exist in the clear outside of the HSM -+(secure, tamper-resistent boundary of the card). It is a clear key wrapped -+with the appropriate MasterKey that has been installed into the secure hardware. -+A clear key is generated in the hardware, wrapped with the appropriate -+master key that has been installed into the hardware. The wrapped key is then -+passed back to the invoker. Upon an encryption and/or decryption request, -+the wrapped key and the data to be encrypted are passed into the hardware. -+The wrapped key is verified, and the clear key is used to encrypt and/or -+decrypt the data. All this is done in the CCA hardware. - --Kent Yoder -+Within opencryptoki, this wrapped key value is stored in the CKA_IBM_OPAQUE -+attribute rather than the CKA_VALUE attribute. - -- The key used to encrypt private objects on disk is a secure key. -+Pre-requisites: -+The CCA token requires cca library, libcsulcca.so, which is part of the -+csulcca rpm. -+It also requires proper configuration and installation of the MK keys into -+the hardware which is outside the scope of this document. - -- The key used to encrypt that secure key is based on the hash of the --USER and SO pins. Therefore it is a clear key and software is used to --do the encryption/decryption of the secure key. -+Configuration -+------------- - --MK_USER: The secure key used for internal on-disk encryption, encrypted -+To use the CCA token a slot entry must be defined in the -+opencryptoki.conf configuration file that sets the stdll attribute to -+libcsulcca.so. -+ -+The CCA token also requires that the appropriate master keys have -+been installed into the hardware. The corresponding driver must also be -+loaded, i.e. modprobe z90crypt. -+ -+CCA Token Objects -+------------------------- -+ -+Opencryptoki stores token objects on disk. Public token objects are not -+encrypted. Private token objects are encrypted. -+Versions of opencryptoki prior to version 3, used a CCA generated secure key -+(des3 key) and the crypto adapter to encrypt the private token object's data. -+In version 3, a clear key (des3 key) and software crypto (openssl) are used -+to encrypt this data. -+ -+Migration Information -+--------------------- -+ -+Migrating version 2 private token objects to version 3 is ONLY required if -+the system will run opencryptoki version 3 and will use private token -+objects saved or preserved from version 2. -+Note, public token objects do not need to be migrated. -+If there are no private token objects from version 2, then the version 3 -+does not require any migrating. -+ -+In version 2 private token objects are encrypted and decrypted with a secure -+key in the crypto adapter. In version 3, this encryption and decryption is -+done with a clear key using software crypto. Therefore, opencryptoki -+version 3, will not succesfully decrypt a version 2 private token object. -+ -+Version 2 private token objects must be "migrated" to version 3 so that -+opencryptoki version 3 can access these objects. This migration will -+decrypt the objects using the CCA call, CSNBDEC and the current -+opencryptoki key stored in MK_USER. The objects will then be re-encrypted -+using software crypto. The key bits that are stored in MK_USER will then be -+used as a clear key. -+ -+Once the migration has completed, these private token objects should then be -+accessable to version 3. -+ -+Migration Steps -+--------------- -+ -+1. Either update or install version 3. -+a. Update to opencryptoki version 3. In most linux distributions, an update -+from version 2 to version 3 will preserve the contents of the CCA data-store. -+ -+b. Install opencryptoki version 3. In most distributions, an install will -+remove the contents of the CCA data-store. You will essentially be starting -+from the beginning and have to initialize the CCA token. -+ -+In this scenario, if a prior version of opencryptoki had been running on the -+system, and you wanted to preserve your token objects, you will have saved -+or backed them up somewhere. -+ -+2. Backup the CCA data-store before migrating. It is always a good idea to -+back up the data in case the migration is unsuccessful or data is corrupted. -+The data-store is the directory in which the CCA token information is stored -+on disk. In most distributions it can be found in /var/lib/opencryptoki/ccatok. -+Within this directory there is, -+ -+MK_USER: The des3 key used for internal on-disk encryption, encrypted - under the USER's PIN by software routines - --MK_SO: The secure key used for internal on-disk encryption, encrypted -+MK_SO: The des3 key used for internal on-disk encryption, encrypted - under the SO's PIN by software routines - --So, MK_USER and MK_SO contain the same key, encrypted under different PINs -+NKTOK.DAT: Token information. -+ -+TOK_OBJ: The directory in which token objects are stored. -+ -+TOK_OBJ/OBJ.IDX: A list of current token objects. -+ -+**NOTE: MK_USER and MK_SO contain the same key, encrypted under -+different PINs -+ -+3. Ensure no opencryptoki processes are running. Stop the pkcsslotd daemon -+if it is running. -+ -+4. Run the pkcscca tool to perform the migration. -+For example, -+ pkcscca -m v2objectsv3 -v -+ -+Note that the "-v" option will allow you to see which objects did and did not -+get migrated. Specify the "-d" flag if you wish to migrate CCA token objects -+stored in a data-store different from the default, /var/lib/opencryptoki/ccatok. -+ -+5. (Optional) Removing shared memory may be required to pick up -+the newly migrated objects. -+ -+CCA token's shared memory segment tracks its token objects. -+Token objects stored on disk are only loaded into shared memory -+when the shared memory is created. The shared memory is usually -+created after a reboot, an install, or an update of the opencryptoki package. -+ -+If another opencryptoki process accessed the CCA token after install -+or update, then opencryptoki will have loaded all the token objects into -+shared memory, except for the private token objects requiring migration, -+since they will have failed decryption. Subsequent calls to the -+opencryptoki api will not find these objects since they have not -+been loaded into shared memory. Opencryptoki won't read the -+objects from disk and load into shared memory again until the next time -+shared memory is created. -+ -+So, in this case, shared memory must be removed and created again so -+that opencryptoki can successfuly load all the token objects including the -+newly migrated private token objects into CCA token's shared memory segment. -+ -+Remove shared memory if, -+ - after updating or installing, any opencryptoki processes or tools tried -+ to access the CCA token before migrating CCA token's private token -+ objects. For example, the pkcsconf command was run. -+ -+ The pre-migrated objects will have failed decryption and not -+ been loaded into shared memory. A reboot or removing shared memory -+ will cause the token to create shared memory again and load the newly -+ migrated private token objects into it. -+ -+CCA's shared memory can be removed two ways. -+ 1. a reboot -+ -+ 2. remove the shared memory file, -+ i.e. "rm /dev/shm/var.lib.opencryptoki.ccatok" -+ -+ Notes: (1). Ensure that no opencryptoki processes are running -+ before removing the shared memory. Otherwise, you risk corrupting -+ any running opencryptoki processes. -+ (2). If you have installed opencryptoki manually (not via a distro -+ rpm) the CCA token shared memory segment may be named -+ usr.local.var.lib.opencryptoki.ccatok. -+ -+The next opencryptoki process to run will cause opencryptoki to create -+a shared memory segment for the token and load the newly migrated objects -+as well as any other token objects for the token. - --PKCS#11 Notes: -+6. After a successful migration, the CCA private token objects should be -+encrypted and ready to be accessed by opencryptoki version 3. - --DES/3DES PKCS#11 key objects have the CCA key identifier stored in the CKA_VALUE --attribute. Usually the CKA_VALUE attribute would hold a plaintext key, however --in this case, the id used to reference the secure key is stored here. -+TroubleShooting: -+1. If version 3 cannot find the newly migrated CCA private token objects, -+reboot or remove the shared memory file. This will cause token to create -+shared memory again and load the newly migrated private token objects -+into shared memory. -diff --git a/man/man1/Makefile.am b/man/man1/Makefile.am -index a5f3c17..41a1259 100644 ---- a/man/man1/Makefile.am -+++ b/man/man1/Makefile.am -@@ -1,3 +1,3 @@ --man1_MANS=pkcsconf.1 pkcsicsf.1 -+man1_MANS=pkcsconf.1 pkcsicsf.1 pkcscca.1 - EXTRA_DIST = $(man1_MANS) - CLEANFILES = $(man1_MANS) -diff --git a/man/man1/pkcscca.1.in b/man/man1/pkcscca.1.in -new file mode 100644 -index 0000000..c6e49d6 ---- /dev/null -+++ b/man/man1/pkcscca.1.in -@@ -0,0 +1,45 @@ -+.TH PKCSCCA 1 "September 2014" "@PACKAGE_VERSION@" "openCryptoki" -+.SH NAME -+pkcscca \- configuration utility for the CCA token -+ -+.SH SYNOPSIS -+\fBpkcscca\fP -+[\fB-h\fP] -+[\fB-m v2objectsv3\fP] -+[\fIOPTIONS\fP] -+ -+.SH DESCRIPTION -+The \fBpkcscca\fP utility assists in administering the CCA token. Currently it -+migrates opencryptoki version 2 private token objects to the encryption -+method used in opencryptoki version 3. -+ -+In verion 2 of opencryptoki, CCA private token objects were encrypted in CCA -+hardware. In version 3 these objects are encrypted in software. The -+\fBv2objectsv3\fP migration option migrates these version 2 objects by -+decrypting them in CCA hardware using a secure key and then re-encrypting -+them in software using a software key. Afterwards, v2 objects can be accessed -+in version 3. -+ -+.SH "FLAGS" -+.IP "\fB-h\fP" 10 -+show usage information -+.IP "\fB-m\fP" 10 -+perform a migration. \fBv2objectsv3\fP is currently the only type of migration -+supported and must be specified along with this flag. -+ -+.SH "MIGRATION OPTIONS" -+.IP "\fB-d|--datastore\fP \fIdirectory\fp" 10 -+the directory where the CCA token information is kept. This directory will be -+used to locate the private token objects to be migrated. i.e. /var/lib/opencryptoki/ccatok -+.IP "\fB-v|--verbose\fP" 10 -+provide detailed output during migration -+ -+.SH "FILES" -+.IP "/var/lib/opencryptoki/ccatok/TOK_OBJ/OBJ.IDX" -+contains current list of public and private token objects for the CCA token. -+ -+.SH SEE ALSO -+.PD 0 -+.TP -+\fBREADME.cca_stdll\fP (in system's doc directory) -+.PD -diff --git a/usr/sbin/Makefile.am b/usr/sbin/Makefile.am -index 1e61ece..3757735 100644 ---- a/usr/sbin/Makefile.am -+++ b/usr/sbin/Makefile.am -@@ -7,4 +7,8 @@ if ENABLE_ICSFTOK - PKCSICSF_DIR = pkcsicsf - endif - --SUBDIRS = pkcsslotd pkcsconf $(PKCSICSF_DIR) $(PKCSCCA_MIGRATE_DIR) -+if ENABLE_CCATOK -+PKCSCCA_DIR = pkcscca -+endif -+ -+SUBDIRS = pkcsslotd pkcsconf $(PKCSICSF_DIR) $(PKCSCCA_MIGRATE_DIR) $(PKCSCCA_DIR) -diff --git a/usr/sbin/pkcscca/Makefile.am b/usr/sbin/pkcscca/Makefile.am -new file mode 100644 -index 0000000..4d5f6c7 ---- /dev/null -+++ b/usr/sbin/pkcscca/Makefile.am -@@ -0,0 +1,14 @@ -+sbin_PROGRAMS=pkcscca -+ -+pkcscca_CFLAGS = -DSTDLL_NAME=\"pkcscca\" -+pkcscca_LDFLAGS = -lcrypto -ldl -+ -+# Not all versions of automake observe sbinname_CFLAGS -+AM_CFLAGS = -DSTDLL_NAME=\"pkcscca\" -+ -+pkcscca_SOURCES = ../../lib/pkcs11/common/p11util.c \ -+ ../../lib/pkcs11/common/sw_crypt.c \ -+ ../../lib/pkcs11/common/log.c \ -+ pkcscca.c -+ -+INCLUDES = -I. -I../../include/pkcs11 -I../../lib/pkcs11/common -diff --git a/usr/sbin/pkcscca/pkcscca.c b/usr/sbin/pkcscca/pkcscca.c -new file mode 100644 -index 0000000..a1e3bae ---- /dev/null -+++ b/usr/sbin/pkcscca/pkcscca.c -@@ -0,0 +1,661 @@ -+/* -+ * Licensed materials - Property of IBM -+ * -+ * pkcscca - A tool for PKCS#11 CCA token. -+ * Currently, only migrates CCA private token objects from CCA cipher -+ * to using a software cipher. -+ * -+ * -+ * Copyright (C) International Business Machines Corp. 2014 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "sw_crypt.h" -+#include "pkcscca.h" -+ -+void (*CSNBDEC)(); -+int v_flag = 0; -+ -+int compute_hash(int hash_type, int buf_size, char *buf, char *digest) -+{ -+ EVP_MD_CTX md_ctx; -+ unsigned int result_size; -+ int rc; -+ -+ switch (hash_type) { -+ case HASH_SHA1: -+ rc = EVP_DigestInit(&md_ctx, EVP_sha1()); -+ break; -+ case HASH_MD5: -+ rc = EVP_DigestInit(&md_ctx, EVP_md5()); -+ break; -+ default: -+ return -1; -+ break; -+ } -+ -+ if (rc != 1) { -+ fprintf(stderr, "EVP_DigestInit() failed: rc = %d\n", rc); -+ return -1; -+ } -+ -+ rc = EVP_DigestUpdate(&md_ctx, buf, buf_size); -+ if (rc != 1) { -+ fprintf(stderr, "EVP_DigestUpdate() failed: rc = %d\n", rc); -+ return -1; -+ } -+ -+ result_size = EVP_MD_CTX_size(&md_ctx); -+ rc = EVP_DigestFinal(&md_ctx, (unsigned char *)digest, &result_size); -+ if (rc != 1) { -+ fprintf(stderr, "EVP_DigestFinal() failed: rc = %d\n", rc); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+int cca_decrypt(unsigned char *in_data, unsigned long in_data_len, -+ unsigned char *out_data, unsigned long *out_data_len, -+ unsigned char *init_v, unsigned char *key_value) -+{ -+ long return_code, reason_code, rule_array_count, length; -+ unsigned char chaining_vector[18]; -+ unsigned char rule_array[256]; -+ -+ length = in_data_len; -+ rule_array_count = 1; -+ memcpy(rule_array, "CBC ", 8); -+ -+ CSNBDEC(&return_code, &reason_code, NULL, NULL, key_value, -+ &length, in_data, init_v, &rule_array_count, -+ rule_array, chaining_vector, out_data); -+ -+ if (return_code != 0) { -+ fprintf(stderr, "CSNBDEC (DES3 DECRYPT) failed: return_code=%ld reason_code=%ld\n", return_code, reason_code); -+ return -1; -+ } -+ *out_data_len = length; -+ return 0; -+} -+ -+int reencrypt_private_token_object(unsigned char *data, unsigned long len, -+ unsigned char *new_cipher, -+ unsigned long *new_cipher_len, -+ unsigned char *masterkey) -+{ -+ unsigned char *clear = NULL; -+ unsigned char des3_key[64]; -+ unsigned char sw_des3_key[3 * DES_KEY_SIZE]; -+ unsigned long clear_len; -+ CK_RV rc; -+ int ret; -+ -+ /* cca wants 8 extra bytes for padding purposes */ -+ clear_len = len + 8; -+ clear = (unsigned char *) malloc(clear_len); -+ if (!clear) { -+ fprintf(stderr, "malloc() failed: %s.\n", strerror(errno)); -+ ret =-1; -+ goto done; -+ } -+ -+ /* decrypt using cca des3 */ -+ memcpy(des3_key, masterkey, MASTER_KEY_SIZE); -+ ret = cca_decrypt(data, len, clear, &clear_len, "10293847", des3_key); -+ if (ret) -+ goto done; -+ -+ /* now encrypt using software des3 */ -+ memcpy(sw_des3_key, masterkey, 3 * DES_KEY_SIZE); -+ rc = sw_des3_cbc_encrypt(clear, clear_len, new_cipher, new_cipher_len, -+ "10293847", sw_des3_key); -+ if (rc != CKR_OK) -+ ret = -1; -+done: -+ if (clear) -+ free(clear); -+ -+ return ret; -+} -+ -+int load_private_token_objects(unsigned char *data_store, -+ unsigned char *masterkey) -+{ -+ FILE *fp1 = NULL, *fp2 = NULL; -+ unsigned char *buf = NULL; -+ unsigned char tmp[PATH_MAX], fname[PATH_MAX], iname[PATH_MAX]; -+ CK_BBOOL priv; -+ unsigned int size; -+ int rc, scount= 0, fcount = 0; -+ size_t read_size; -+ unsigned char *new_cipher; -+ unsigned long new_cipher_len; -+ -+ snprintf(iname, sizeof(iname), "%s/TOK_OBJ/OBJ.IDX", data_store); -+ -+ fp1 = fopen((char *)iname, "r"); -+ if (!fp1) -+ return -1; // no token objects -+ -+ while (!feof(fp1)) { -+ (void)fgets((char *)tmp, 50, fp1); -+ if (!feof(fp1)) { -+ tmp[strlen((char *)tmp) - 1] = 0; -+ -+ snprintf((char *)fname, sizeof(fname), "%s/TOK_OBJ/", -+ data_store); -+ strcat((char *)fname, (char *)tmp); -+ -+ fp2 = fopen((char *)fname, "r"); -+ if (!fp2) -+ continue; -+ -+ fread(&size, sizeof(unsigned int), 1, fp2); -+ fread(&priv, sizeof(CK_BBOOL), 1, fp2); -+ if (priv == FALSE) { -+ fclose(fp2); -+ continue; -+ } -+ -+ size = size - sizeof(unsigned int) - sizeof(CK_BBOOL); -+ buf = (unsigned char *) malloc(size); -+ if (!buf) { -+ fprintf(stderr, "Cannot malloc for object %s " -+ "(ignoring it).\n", tmp); -+ goto cleanup; -+ } -+ -+ read_size = fread((char *)buf, 1, size, fp2); -+ if (read_size != size) { -+ fprintf(stderr, "Cannot read object %s " -+ "(ignoring it).\n", tmp); -+ goto cleanup; -+ } -+ -+ new_cipher_len = size; -+ new_cipher = malloc(new_cipher_len); -+ if (!new_cipher) { -+ fprintf(stderr, "Cannot malloc space for new " -+ "cipher (ignoring object %s).\n", tmp); -+ goto cleanup; -+ } -+ -+ /* After reading the private token object, -+ * decrypt it using CCA des3 and then re-encrypt it -+ * using software des3. -+ */ -+ memset(new_cipher, 0, new_cipher_len); -+ rc = reencrypt_private_token_object(buf, size, -+ new_cipher, &new_cipher_len, -+ masterkey); -+ if (rc) -+ goto cleanup; -+ -+ fclose(fp2); -+ -+ /* now save the newly re-encrypted object back to -+ * disk in its original file. -+ */ -+ fp2 = fopen((char *)fname, "w"); -+ size = sizeof(unsigned int) + sizeof(CK_BBOOL) -+ + new_cipher_len; -+ (void)fwrite(&size, sizeof(unsigned int), 1, fp2); -+ (void)fwrite(&priv, sizeof(CK_BBOOL), 1, fp2); -+ (void)fwrite(new_cipher, new_cipher_len, 1, fp2); -+ rc = 0; -+ -+cleanup: -+ if (fp2) -+ fclose(fp2); -+ if (buf) -+ free(buf); -+ if (new_cipher) -+ free(new_cipher); -+ -+ if (rc) { -+ if (v_flag) -+ printf("Failed to process %s\n", fname); -+ fcount++; -+ } else { -+ if (v_flag) -+ printf("Processed %s.\n", fname); -+ scount++; -+ } -+ } -+ } -+ fclose(fp1); -+ printf("Successfully migrated %d object(s).\n", scount); -+ -+ if (v_flag && fcount) -+ printf("Failed to migrate %d object(s).\n", fcount); -+ -+ return 0; -+} -+ -+int load_masterkey(char *mkfile, char *pin, char *masterkey) -+{ -+ unsigned char des3_key[3 * DES_KEY_SIZE]; -+ unsigned char hash_sha[SHA1_HASH_SIZE]; -+ unsigned char pin_md5_hash[MD5_HASH_SIZE]; -+ unsigned char *cipher = NULL; -+ unsigned char *clear = NULL; -+ unsigned long cipher_len, clear_len; -+ int ret; -+ CK_RV rc; -+ FILE *fp = NULL; -+ -+ clear_len = cipher_len = MASTER_KEY_SIZE + SHA1_HASH_SIZE + (DES_BLOCK_SIZE - 1) & ~(DES_BLOCK_SIZE - 1); -+ -+ fp = fopen((char *)mkfile, "r"); -+ if (!fp) { -+ fprintf(stderr, "Could not open %s: %s\n", mkfile, -+ strerror(errno)); -+ return -1; -+ } -+ -+ cipher = malloc(cipher_len); -+ clear = malloc(clear_len); -+ if (cipher == NULL || clear == NULL) { -+ ret = -1; -+ goto done; -+ } -+ -+ ret = fread(cipher, cipher_len, 1, fp); -+ if (ret != 1) { -+ fprintf(stderr, "Could not read %s: %s\n", mkfile, -+ strerror(errno)); -+ ret = -1; -+ goto done; -+ } -+ -+ /* decrypt the masterkey */ -+ -+ ret = compute_md5(pin, strlen(pin), pin_md5_hash); -+ if (ret) { -+ fprintf(stderr, "Error calculating MD5 of PIN!\n"); -+ goto done; -+ } -+ -+ memcpy(des3_key, pin_md5_hash, MD5_HASH_SIZE); -+ memcpy(des3_key + MD5_HASH_SIZE, pin_md5_hash, DES_KEY_SIZE); -+ -+ rc = sw_des3_cbc_decrypt(cipher, cipher_len, clear, &clear_len, -+ (unsigned char *)"12345678", des3_key); -+ if (rc != CKR_OK) { -+ fprintf(stderr, "Error decrypting master key file after read"); -+ ret = -1; -+ goto done; -+ } -+ -+ /* -+ * technically should strip PKCS padding here but since I already know -+ * what the length should be, I don't bother. -+ * -+ * compare the hashes to verify integrity -+ */ -+ -+ ret = compute_sha1(clear, MASTER_KEY_SIZE, hash_sha); -+ if (ret) { -+ fprintf(stderr, "Failed to compute sha for masterkey.\n"); -+ goto done; -+ } -+ -+ if (memcmp(hash_sha, clear + MASTER_KEY_SIZE, SHA1_HASH_SIZE) != 0) { -+ fprintf(stderr, "%s appears to have been tampered!\n", mkfile); -+ fprintf(stderr, "Cannot migrate.\n"); -+ ret = -1; -+ goto done; -+ } -+ -+ memcpy(masterkey, clear, MASTER_KEY_SIZE); -+ ret = 0; -+ -+done: -+ if (fp) -+ fclose(fp); -+ if (clear) -+ free(clear); -+ if (cipher) -+ free(cipher); -+ -+ return ret; -+} -+ -+int get_pin(char **pin, size_t *pinlen) -+{ -+ struct termios old, new; -+ int nread; -+ char *buff = NULL; -+ size_t buflen; -+ int rc = 0; -+ -+ /* turn echoing off */ -+ if (tcgetattr(fileno(stdin), &old) != 0) -+ return -1; -+ -+ new = old; -+ new.c_lflag &= ~ECHO; -+ if (tcsetattr (fileno(stdin), TCSAFLUSH, &new) != 0) -+ return -1; -+ -+ /* read the pin -+ * Note: getline will allocate memory for buff. free it when done. -+ */ -+ nread = getline(&buff, &buflen, stdin); -+ if (nread == -1) { -+ rc = -1; -+ goto done; -+ } -+ -+ /* Restore terminal */ -+ (void) tcsetattr(fileno(stdin), TCSAFLUSH, &old); -+ -+ /* start a newline */ -+ printf("\n"); -+ fflush(stdout); -+ -+ /* Allocate PIN. -+ * Note: nread includes carriage return. -+ * Replace with terminating NULL. -+ */ -+ *pin = (unsigned char *)malloc(nread); -+ if (*pin == NULL) { -+ rc = -ENOMEM; -+ goto done; -+ } -+ -+ /* strip the carriage return since not part of pin. */ -+ buff[nread - 1] = '\0'; -+ memcpy(*pin, buff, nread); -+ /* don't include the terminating null in the pinlen */ -+ *pinlen = nread - 1; -+ -+done: -+ if (buff) -+ free(buff); -+ -+ return rc; -+} -+ -+int verify_pins(char *data_store, char *sopin, unsigned long sopinlen, -+ char *userpin, unsigned long userpinlen) -+{ -+ TOKEN_DATA td; -+ unsigned char fname[PATH_MAX]; -+ unsigned char pin_sha[SHA1_HASH_SIZE]; -+ FILE *fp = NULL; -+ int ret; -+ -+ /* read the NVTOK.DAT */ -+ snprintf(fname, PATH_MAX, "%s/NVTOK.DAT", data_store); -+ fp = fopen((char *)fname, "r"); -+ if (!fp) { -+ fprintf(stderr, "Could not open %s: %s\n", fname, -+ strerror(errno)); -+ return -1; -+ } -+ -+ ret = fread(&td, sizeof(TOKEN_DATA), 1, fp); -+ if (ret != 1) { -+ fprintf(stderr, "Could not read %s: %s\n", fname, -+ strerror(errno)); -+ ret = -1; -+ goto done; -+ } -+ -+ /* Now compute the SHAs for the SO and USER pins entered. -+ * Compare with the SHAs for SO and USER PINs saved in -+ * NVTOK.DAT to verify. -+ */ -+ -+ if (sopin != NULL) { -+ ret = compute_sha1(sopin, sopinlen, pin_sha); -+ if (ret) { -+ fprintf(stderr, "Failed to compute sha for SO.\n"); -+ goto done; -+ } -+ -+ if (memcmp(td.so_pin_sha, pin_sha, SHA1_HASH_SIZE) != 0) { -+ fprintf(stderr, "SO PIN is incorrect.\n"); -+ ret = -1; -+ goto done; -+ } -+ } -+ -+ if (userpin != NULL) { -+ ret = compute_sha1(userpin, userpinlen, pin_sha); -+ if (ret) { -+ fprintf(stderr, "Failed to compute sha for USER.\n"); -+ goto done; -+ } -+ -+ if (memcmp(td.user_pin_sha, pin_sha, SHA1_HASH_SIZE) != 0) { -+ fprintf(stderr, "USER PIN is incorrect.\n"); -+ ret = -1; -+ goto done; -+ } -+ } -+ ret = 0; -+ -+done: -+ /* clear out the hash */ -+ memset(pin_sha, 0, SHA1_HASH_SIZE); -+ if (fp) -+ fclose(fp); -+ -+ return ret; -+} -+ -+void usage(char *progname) -+{ -+ printf("usage:\t%s -h | -m v2objectsv3 [OPTIONS] \n", progname); -+ printf(" -h\t\t\t\tshow this help\n"); -+ printf(" -m=migration_type\t\tCurrently the only type of CCA "); -+ printf("migration\n\t\t\t\tsupported is v2objectsv3. v2objectsv3 "); -+ printf("migrates\n\t\t\t\tCCA private token objects from CCA "); -+ printf("encryption\n\t\t\t\t(used in v2)to software encryption "); -+ printf("(used in v3). \n\n"); -+ printf("Migrate options (with -m v2objectsv3):\n"); -+ printf(" -d, --datastore=DIRECTORY\tCCA token datastore location\n"); -+ printf(" -v, --verbose\t\t\tprovide more detailed output\n"); -+ -+ return; -+} -+ -+int main(int argc, char **argv) -+{ -+ int ret, opt; -+ unsigned int m_flag = 0; -+ char *sopin = NULL, *userpin = NULL; -+ size_t sopinlen, userpinlen; -+ unsigned char masterkey[MASTER_KEY_SIZE]; -+ unsigned char *data_store = NULL; -+ unsigned char *m_type = NULL; -+ int data_store_len; -+ char fname[PATH_MAX]; -+ struct stat statbuf; -+ void *lib_csulcca; -+ -+ struct option long_opts[] = { -+ { "datastore", required_argument, NULL, 'd' }, -+ { "verbose", no_argument, NULL, 'v'}, -+ { 0, 0, 0, 0 } -+ }; -+ -+ int long_index; -+ while ((opt = getopt_long(argc, argv, "d:m:hv", long_opts, NULL)) != -1) { -+ switch (opt) { -+ case 'd': -+ data_store = strdup(optarg); -+ break; -+ -+ case 'h': -+ usage(argv[0]); -+ return 0; -+ -+ case 'm': -+ m_type = strdup(optarg); -+ break; -+ -+ case 'v': -+ v_flag++; -+ break; -+ -+ default: -+ usage(argv[0]); -+ return -1; -+ } -+ } -+ -+ if (m_type) { -+ if (memcmp(m_type, "v2objectsv3", strlen("v2objectsv3"))) { -+ fprintf(stderr, "unknown migration type\n"); -+ usage(argv[0]); -+ return -1; -+ } -+ } -+ -+ /* use default data_store if one is not given */ -+ if (data_store == NULL) { -+ data_store_len = strlen(TOK_DATASTORE); -+ data_store = malloc(data_store_len + 1); -+ if (data_store == NULL) { -+ fprintf(stderr, "malloc failed: %s\n",strerror(errno)); -+ return -1; -+ } -+ memset(data_store, 0, data_store_len + 1); -+ memcpy(data_store, TOK_DATASTORE, data_store_len); -+ } -+ -+ /* Verify that the data store is valid by looking for -+ * MK_SO, MK_USER, and TOK_OBJ/OBJ.IDX. -+ */ -+ -+ memset(fname, 0, PATH_MAX); -+ snprintf(fname, PATH_MAX, "%s/MK_SO", data_store); -+ if (stat(fname, &statbuf) != 0) { -+ fprintf(stderr, "Cannot find %s.\n", fname); -+ ret = -1; -+ goto done; -+ } -+ -+ memset(fname, 0, PATH_MAX); -+ snprintf(fname, PATH_MAX, "%s/MK_USER", data_store); -+ if (stat(fname, &statbuf) != 0) { -+ fprintf(stderr, "Cannot find %s.\n", fname); -+ ret = -1; -+ goto done; -+ } -+ -+ memset(fname, 0, PATH_MAX); -+ snprintf(fname, PATH_MAX, "%s/TOK_OBJ/OBJ.IDX", data_store); -+ if (stat(fname, &statbuf) != 0) { -+ fprintf(stderr, "Cannot find %s.\n", fname); -+ ret = -1; -+ goto done; -+ } -+ -+ /* If the OBJ.IDX is empty, then no objects to migrate. */ -+ if (statbuf.st_size == 0) { -+ printf("OBJ.IDX file is empty. Thus no objects to migrate.\n"); -+ goto done; -+ } -+ -+ if (v_flag) -+ printf("%s has an MK_SO, MK_USER and TOK/OBJ.IDX\n", -+ data_store); -+ -+ /* get the SO pin to authorize migration */ -+ printf("Enter the SO PIN: "); -+ fflush(stdout); -+ ret = get_pin(&sopin, &sopinlen); -+ if (ret != 0) { -+ fprintf(stderr, "Could not get SO PIN.\n"); -+ goto done; -+ } -+ -+ /* get the USER pin to authorize migration */ -+ printf("Enter the USER PIN: "); -+ fflush(stdout); -+ ret = get_pin(&userpin, &userpinlen); -+ -+ if (ret != 0) { -+ fprintf(stderr, "Could not get USER PIN.\n"); -+ goto done; -+ } -+ -+ /* Verify the SO and USER PINs entered. */ -+ ret = verify_pins(data_store, sopin, sopinlen, userpin, userpinlen); -+ if (ret) -+ goto done; -+ -+ lib_csulcca = dlopen(CCA_LIBRARY, (RTLD_GLOBAL | RTLD_NOW)); -+ if (lib_csulcca == NULL) { -+ fprintf(stderr, "dlopen(%s) failed: %s\n", CCA_LIBRARY, -+ strerror(errno)); -+ return -1; -+ } -+ -+ CSNBDEC = dlsym(lib_csulcca, "CSNBDEC"); -+ -+ /* Get the masterkey from MK_SO. -+ * This also helps verify that correct SO pin was entered. -+ */ -+ memset(masterkey, 0, MASTER_KEY_SIZE); -+ memset(fname, 0, PATH_MAX); -+ snprintf(fname, PATH_MAX, "%s/MK_SO", data_store); -+ ret = load_masterkey(fname, sopin, masterkey); -+ if (ret) { -+ fprintf(stderr, "Could not load masterkey from MK_SO.\n"); -+ goto done; -+ } -+ -+ if (v_flag) -+ printf("Successfully verified SO Pin.\n"); -+ -+ /* Get the masterkey from MK_USER. -+ * This also helps verift that correct USER pin was entered. -+ */ -+ memset(masterkey, 0, MASTER_KEY_SIZE); -+ memset(fname, 0, PATH_MAX); -+ snprintf(fname, PATH_MAX, "%s/MK_USER", data_store); -+ ret = load_masterkey(fname, userpin, masterkey); -+ if (ret) { -+ fprintf(stderr, "Could not load masterkey from MK_USER.\n"); -+ goto done; -+ } -+ -+ if (v_flag) -+ printf("Successfully verified USER Pin.\n"); -+ -+ /* Load all the private token objects and re-encrypt them -+ * using software des3, instead of CSNBENC. -+ */ -+ (void)load_private_token_objects(data_store, masterkey); -+ -+done: -+ -+ if (sopin) -+ free(sopin); -+ if (userpin) -+ free(userpin); -+ if (data_store) -+ free(data_store); -+ -+ return ret; -+} -diff --git a/usr/sbin/pkcscca/pkcscca.h b/usr/sbin/pkcscca/pkcscca.h -new file mode 100644 -index 0000000..4b23c7a ---- /dev/null -+++ b/usr/sbin/pkcscca/pkcscca.h -@@ -0,0 +1,49 @@ -+/* -+ * Licensed materials - Property of IBM -+ * -+ * pkcscca - A tool for PKCS#11 CCA token. -+ * Currently, only migrates CCA private token objects from using a -+ * CCA cipher to using a software cipher. -+ * -+ * Copyright (C) International Business Machines Corp. 2014 -+ * -+ */ -+ -+ -+#ifndef __PKCSCCA_H_ -+#define __PKCSCCA_H_ -+ -+#define CCA_LIBRARY "libcsulcca.so" -+#define TOK_DATASTORE "/var/lib/opencryptoki/ccatok" -+#define MASTER_KEY_SIZE 64 -+#define SHA1_HASH_SIZE 20 -+#define MD5_HASH_SIZE 16 -+#define DES_BLOCK_SIZE 8 -+#define DES_KEY_SIZE 8 -+#define compute_sha1(a,b,c) compute_hash(HASH_SHA1,b,a,c) -+#define compute_md5(a,b,c) compute_hash(HASH_MD5,b,a,c) -+#define HASH_SHA1 1 -+#define HASH_MD5 2 -+ -+/* from host_defs.h */ -+#include "pkcs32.h" -+typedef struct _TWEAK_VEC -+{ -+ int allow_weak_des ; -+ int check_des_parity ; -+ int allow_key_mods ; -+ int netscape_mods ; -+} TWEAK_VEC; -+ -+typedef struct _TOKEN_DATA -+{ -+ CK_TOKEN_INFO_32 token_info; -+ -+ CK_BYTE user_pin_sha[3 * DES_BLOCK_SIZE]; -+ CK_BYTE so_pin_sha[3 * DES_BLOCK_SIZE]; -+ CK_BYTE next_token_object_name[8]; -+ TWEAK_VEC tweak_vector; -+} TOKEN_DATA; -+ -+ -+#endif diff --git a/SOURCES/opencryptoki-3.0-pkcsconf-man.patch b/SOURCES/opencryptoki-3.0-pkcsconf-man.patch deleted file mode 100644 index cf547ab..0000000 --- a/SOURCES/opencryptoki-3.0-pkcsconf-man.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 48e9a2fdcae6d373f56aefcb85507758803be7df Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Dan=20Hor=C3=A1k?= -Date: Mon, 22 Jul 2013 18:49:43 +0200 -Subject: [PATCH] update options in the pkcsconf man page to match the pkcsconf - binary - ---- - man/man1/pkcsconf.1.in | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/man/man1/pkcsconf.1.in b/man/man1/pkcsconf.1.in -index 1b95651..76293ae 100644 ---- a/man/man1/pkcsconf.1.in -+++ b/man/man1/pkcsconf.1.in -@@ -4,7 +4,7 @@ pkcsconf \- configuration utility for the pkcsslotd daemon - - .SH SYNOPSIS - \fBpkcsconf\fP --[\fB-itsmMIupPh\fP] -+[\fB-itsmlIupPh\fP] - [\fB-c\fP \fIslotnumber\fP \fB-U\fP \fIuserPIN\fP - \fB-S\fP \fISOPin\fP \fB-n\fP \fInewpin\fP] - -@@ -21,6 +21,8 @@ display token info - display slot info - .IP "\fB-m\fP" 10 - display mechanism list -+.IP "\fB-l\fP" 10 -+display slot description - .IP "\fB-I\fP" 10 - initialize token - .IP "\fB-u\fP" 10 --- -1.8.1.4 - diff --git a/SOURCES/opencryptoki-3.0-unit.patch b/SOURCES/opencryptoki-3.0-unit.patch deleted file mode 100644 index 95eb8d4..0000000 --- a/SOURCES/opencryptoki-3.0-unit.patch +++ /dev/null @@ -1,24 +0,0 @@ -From a8870725de46b8c5716e1539a0d01256b319940b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Dan=20Hor=C3=A1k?= -Date: Fri, 23 Aug 2013 16:57:52 +0200 -Subject: [PATCH] update unit file for 3.0 - ---- - misc/pkcsslotd.service.in | 1 - - 1 file changed, 1 deletion(-) - -diff --git a/misc/pkcsslotd.service.in b/misc/pkcsslotd.service.in -index bfd9934..461be60 100644 ---- a/misc/pkcsslotd.service.in -+++ b/misc/pkcsslotd.service.in -@@ -5,7 +5,6 @@ After=syslog.target - [Service] - Type=forking - PIDFile=/var/run/pkcsslotd.pid --ExecStartPre=@sbindir@/pkcs11_startup - ExecStart=@sbindir@/pkcsslotd - - [Install] --- -1.8.1.4 - diff --git a/SOURCES/opencryptoki-3.2-Correctly-declare-OAEP-parameter-in-RSA-Wrap-tests-t.patch b/SOURCES/opencryptoki-3.2-Correctly-declare-OAEP-parameter-in-RSA-Wrap-tests-t.patch new file mode 100644 index 0000000..251d46d --- /dev/null +++ b/SOURCES/opencryptoki-3.2-Correctly-declare-OAEP-parameter-in-RSA-Wrap-tests-t.patch @@ -0,0 +1,35 @@ +From 1e86226c8a6c2f0f6fe262e5e4b9c5f01f5ce272 Mon Sep 17 00:00:00 2001 +From: Joy Latten +Date: Wed, 29 Oct 2014 15:23:12 -0500 +Subject: [PATCH 2/2] Correctly declare OAEP parameter in RSA Wrap tests to + prevent a possible scope issue. + +Signed-off-by: Joy Latten +--- + testcases/crypto/rsa_func.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/testcases/crypto/rsa_func.c b/testcases/crypto/rsa_func.c +index 36fe75b..89eb7d4 100644 +--- a/testcases/crypto/rsa_func.c ++++ b/testcases/crypto/rsa_func.c +@@ -725,6 +725,7 @@ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + CK_BYTE re_cipher[32]; + CK_ULONG cipher_len = 32; + CK_ULONG re_cipher_len = 32; ++ CK_RSA_PKCS_OAEP_PARAMS oaep_params; + + char *s; + +@@ -802,8 +803,6 @@ CK_RV do_WrapUnwrapRSA(struct GENERATED_TEST_SUITE_INFO *tsuite) + // get wrapping mechanism + wrap_mech = tsuite->mech; + if (wrap_mech.mechanism == CKM_RSA_PKCS_OAEP) { +- CK_RSA_PKCS_OAEP_PARAMS oaep_params; +- + oaep_params = tsuite->tv[i].oaep_params; + wrap_mech.pParameter = &oaep_params; + wrap_mech.ulParameterLen = sizeof(CK_RSA_PKCS_OAEP_PARAMS); +-- +2.1.0 + diff --git a/SOURCES/opencryptoki-3.2-conditional-manpages.patch b/SOURCES/opencryptoki-3.2-conditional-manpages.patch new file mode 100644 index 0000000..0e15fdc --- /dev/null +++ b/SOURCES/opencryptoki-3.2-conditional-manpages.patch @@ -0,0 +1,18 @@ +diff --git a/man/man1/Makefile.am b/man/man1/Makefile.am +index f2274d7..d98ae8c 100644 +--- a/man/man1/Makefile.am ++++ b/man/man1/Makefile.am +@@ -1,3 +1,12 @@ +-man1_MANS=pkcsconf.1 pkcsicsf.1 pkcsep11_migrate.1 pkcscca.1 ++man1_MANS=pkcsconf.1 pkcsicsf.1 ++ ++if ENABLE_PKCSEP11_MIGRATE ++man1_MANS += pkcsep11_migrate.1 ++endif ++ ++if ENABLE_CCATOK ++man1_MANS += pkcscca.1 ++endif ++ + EXTRA_DIST = $(man1_MANS) + CLEANFILES = $(man1_MANS) diff --git a/SOURCES/opencryptoki-3.2-fix-root-checks.patch b/SOURCES/opencryptoki-3.2-fix-root-checks.patch new file mode 100644 index 0000000..b12297a --- /dev/null +++ b/SOURCES/opencryptoki-3.2-fix-root-checks.patch @@ -0,0 +1,108 @@ +diff --git a/usr/lib/pkcs11/api/shrd_mem.c.in b/usr/lib/pkcs11/api/shrd_mem.c.in +index 42022c7..9e70a26 100644 +--- a/usr/lib/pkcs11/api/shrd_mem.c.in ++++ b/usr/lib/pkcs11/api/shrd_mem.c.in +@@ -340,6 +340,7 @@ attach_shared_memory() { + struct stat statbuf; + struct group *grp; + struct passwd *pw, *epw; ++ uid_t uid, euid; + + #if !(MMAP) + // Really should fstat the tok_path, since it will be the actual +@@ -351,42 +352,36 @@ attach_shared_memory() { + return NULL; + } + +- +- // SAB check for the group id here and membership here as well +- grp = getgrnam("pkcs11"); +- if ( grp ) { +- int i=0; +- char member=0; +- +- pw = getpwuid(getuid()); +- +- epw = getpwuid(geteuid()); +- +- while( grp->gr_mem[i] ) { +- if (pw) { +- if ( strncmp(pw->pw_name, grp->gr_mem[i],strlen(pw->pw_name)) == 0 ){ +- member = 1; +- break; +- } +- } +- if (epw) { +- if ( strncmp(epw->pw_name, grp->gr_mem[i],strlen(epw->pw_name)) == 0 ){ +- member = 1; +- break; +- } +- } +- i++; +- } +- if ( ! member ) { +- return NULL; // SAB don't bother even attaching... +- } +- +- +- } else { +- return NULL; ++ uid = getuid(); ++ euid = geteuid(); ++ // only check group membership if not root user ++ if (uid != 0 && euid != 0) { ++ int i, member=0; ++ grp = getgrnam("pkcs11"); ++ if (!grp) { ++ // group pkcs11 not known to the system ++ return NULL; ++ } ++ pw = getpwuid(uid); ++ epw = getpwuid(euid); ++ for (i=0; grp->gr_mem[i]; i++) { ++ if (pw) { ++ if (!strncmp(pw->pw_name, grp->gr_mem[i],strlen(pw->pw_name))) { ++ member = 1; ++ break; ++ } ++ } ++ if (epw) { ++ if (!strncmp(epw->pw_name, grp->gr_mem[i],strlen(epw->pw_name))) { ++ member = 1; ++ break; ++ } ++ } ++ } ++ if (!member) { ++ return NULL; ++ } + } +- +- + + Anchor->shm_tok = ftok(TOK_PATH,'b'); + +diff --git a/usr/lib/pkcs11/common/new_host.c b/usr/lib/pkcs11/common/new_host.c +index b6275ab..6c49a07 100755 +--- a/usr/lib/pkcs11/common/new_host.c ++++ b/usr/lib/pkcs11/common/new_host.c +@@ -521,7 +521,7 @@ check_user_and_group() + euid = geteuid(); + + /* Root or effective Root is ok */ +- if (uid != 0 && euid != 0) ++ if (uid == 0 || euid == 0) + return CKR_OK; + + /* +@@ -541,8 +541,8 @@ check_user_and_group() + pw = getpwuid(uid); + epw = getpwuid(euid); + for (i = 0; grp->gr_mem[i]; i++) { +- if ((pw && strcmp(pw->pw_name, grp->gr_mem[i]) == 0) || +- (epw && strcmp(epw->pw_name, grp->gr_mem[i]) == 0)) ++ if ((pw && (strncmp(pw->pw_name, grp->gr_mem[i], strlen(pw->pw_name)) == 0)) || ++ (epw && (strncmp(epw->pw_name, grp->gr_mem[i], strlen(epw->pw_name)) == 0))) + return CKR_OK; + } + diff --git a/SOURCES/opencryptoki-3.2-pkcsep11_migrate-Fixed-parameter-handling-for-pkcsep.patch b/SOURCES/opencryptoki-3.2-pkcsep11_migrate-Fixed-parameter-handling-for-pkcsep.patch new file mode 100644 index 0000000..289f1f2 --- /dev/null +++ b/SOURCES/opencryptoki-3.2-pkcsep11_migrate-Fixed-parameter-handling-for-pkcsep.patch @@ -0,0 +1,172 @@ +From f28dc082ad7a7a431d1b66a0de87b5e484fe08b9 Mon Sep 17 00:00:00 2001 +From: Ingo Tuchscherer +Date: Tue, 21 Oct 2014 10:00:52 -0500 +Subject: [PATCH 1/2] pkcsep11_migrate: Fixed parameter handling for + pkcsep11_migrate tool - Hexadecimal values allowed for input + parameters - Non digit input parameters will be rejected + - Extended Error messages with ock error strings - + improved man-page + +Signed-off-by: Ingo Tuchscherer +--- + man/man1/pkcsep11_migrate.1.in | 8 +++++-- + usr/sbin/pkcsep11_migrate/Makefile.am | 4 ++-- + usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c | 36 +++++++++++++++++++--------- + 3 files changed, 33 insertions(+), 15 deletions(-) + +diff --git a/man/man1/pkcsep11_migrate.1.in b/man/man1/pkcsep11_migrate.1.in +index 0dffb1b..d1b21b0 100644 +--- a/man/man1/pkcsep11_migrate.1.in ++++ b/man/man1/pkcsep11_migrate.1.in +@@ -25,8 +25,8 @@ Trusted Key Entry console (TKE) before using this utility. + .br + 3. Before using this tool make a back-up of the token objects in ep11tok/TOK_OBJ/. + .br +-4. After successfully appling the utility and before (re)starting programs +-using the EP11 token the new master key must be activated using the TKE. ++4. After successfully execution of the migrate utility and before (re)starting ++ programs using the EP11 token the new master key must be activated using the TKE. + + .SH "COMMAND SUMMARY" + .IP "\fB-slot\fP \fIslot-number\fP" 10 +@@ -35,8 +35,12 @@ specifies the token slot of the EP11 token + specifies an EP11 adapter ID. + (Refer to lszcrypt to get a list of installed crypto adapters. + The adapter ID will be the number xx in 'card\fBxx\fP' from the output.) ++This value can be provided either in hexadecimal (e.g. 0x0A) or decimal (10) ++notation. + .IP "\fB-domain\fP \fIdomain-ID\fP" 10 + specifies the usage domain for the EP11 adapter. (see /sys/bus/ap/ap_domain.) ++This value can be provided either in hexadecimal (e.g. 0x0B) or decimal (11) ++notation. + .IP "\fB-h\fP" 10 + show usage information + +diff --git a/usr/sbin/pkcsep11_migrate/Makefile.am b/usr/sbin/pkcsep11_migrate/Makefile.am +index 49deb74..b43756c 100644 +--- a/usr/sbin/pkcsep11_migrate/Makefile.am ++++ b/usr/sbin/pkcsep11_migrate/Makefile.am +@@ -1,9 +1,9 @@ + sbin_PROGRAMS=pkcsep11_migrate + +-pkcsep11_migrate_SOURCES = pkcsep11_migrate.c ++pkcsep11_migrate_SOURCES = ../../lib/pkcs11/common/p11util.c pkcsep11_migrate.c + pkcsep11_migrate_CFLAGS = -I ../../include/pkcs11/ -I../../lib/pkcs11/ep11_stdll/ -DLINUX -DPROGRAM_NAME=\"$(@)\" + pkcsep11_migrate_LDFLAGS = -lc -ldl -lpthread +-INCLUDES = -I. ++INCLUDES = -I. -I../../lib/pkcs11/common + + # Not all versions of automake observe sbinname_CFLAGS + # AM_CFLAGS = -DLINUX -DPROGRAM_NAME=\"$(@)\" +diff --git a/usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c b/usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c +index aa1c3f1..4325b9d 100644 +--- a/usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c ++++ b/usr/sbin/pkcsep11_migrate/pkcsep11_migrate.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + + #define EP11SHAREDLIB "libep11.so" + #define PKCS11_MAX_PIN_LEN 128 +@@ -180,16 +181,16 @@ check_card_status() + + if (rc != CKR_OK) + { +- fprintf(stderr,"m_get_ep11_info rc %lx, valid apapter/domain %lx/%lx?.\n", ++ fprintf(stderr,"m_get_ep11_info rc 0x%lx, valid apapter/domain 0x%02lx/%ld?.\n", + rc,adapter,domain); + return -1; + } + + if (CK_IBM_DOM_COMMITTED_NWK & dinf.flags) { +- fprintf(stderr,"Card ID %ld, domain ID %ld has committed pending(next) WK\n", ++ fprintf(stderr,"Card ID 0x%02lx, domain ID %ld has committed pending(next) WK\n", + adapter, domain); + } else { +- fprintf(stderr,"Card ID %ld, domain ID %ld has no committed pending WK\n", ++ fprintf(stderr,"Card ID 0x%02lx, domain ID %ld has no committed pending WK\n", + adapter, domain); + return -1; + } +@@ -277,15 +278,27 @@ do_ParseArgs(int argc, char **argv) + return 0; + } + else if (strcmp (argv[i], "-slot") == 0) { +- SLOT_ID = atoi (argv[i+1]); ++ if (!isdigit(*argv[i+1])) { ++ printf("Slot parameter is not numeric!\n"); ++ return -1; ++ } ++ SLOT_ID = (int)strtol(argv[i+1], NULL, 0); + i++; + } + else if (strcmp (argv[i], "-adapter") == 0) { +- adapter = atoi (argv[i+1]); ++ if (!isdigit(*argv[i+1])) { ++ printf("Adapter parameter is not numeric!\n"); ++ return -1; ++ } ++ adapter = (int)strtol(argv[i+1], NULL, 0); + i++; + } + else if (strcmp (argv[i], "-domain") == 0) { +- domain = atoi (argv[i+1]); ++ if (!isdigit(*argv[i+1])) { ++ printf("Domain parameter is not numeric!\n"); ++ return -1; ++ } ++ domain = (int)strtol(argv[i+1], NULL, 0); + i++; + } + else { +@@ -374,7 +387,7 @@ int main (int argc, char **argv){ + rc = funcs->C_OpenSession(SLOT_ID, flags, + NULL, NULL, &session ); + if (rc != CKR_OK) { +- fprintf(stderr,"C_OpenSession() rc = %x\n",rc); ++ fprintf(stderr,"C_OpenSession() rc = 0x%02x [%s]\n",rc, p11_get_ckr(rc)); + session = CK_INVALID_HANDLE; + return rc; + } +@@ -384,7 +397,7 @@ int main (int argc, char **argv){ + fprintf(stderr,"get_user_pin() failed\n"); + rc = funcs->C_CloseAllSessions(SLOT_ID); + if (rc != CKR_OK) +- fprintf(stderr,"C_CloseAllSessions() rc = %x\n",rc); ++ fprintf(stderr,"C_CloseAllSessions() rc = 0x%02x [%s]\n",rc, p11_get_ckr(rc)); + return rc; + } + +@@ -392,7 +405,7 @@ int main (int argc, char **argv){ + rc = funcs->C_Login(session, CKU_USER, + user_pin, user_pin_len); + if (rc != CKR_OK) { +- fprintf(stderr,"C_Login() rc = %x\n",rc); ++ fprintf(stderr,"C_Login() rc = 0x%02x [%s]\n",rc, p11_get_ckr(rc)); + return rc; + } + +@@ -410,7 +423,7 @@ int main (int argc, char **argv){ + + if (rc != CKR_OK) + { +- fprintf(stderr,"C_FindObjects() rc = %x\n",rc); ++ fprintf(stderr,"C_FindObjects() rc = 0x%02x [%s]\n",rc, p11_get_ckr(rc)); + return rc; + } + +@@ -443,7 +456,8 @@ int main (int argc, char **argv){ + + if (rc != CKR_OK) + { +- fprintf(stderr,"second C_GetAttributeValue failed %x\n",rc); ++ fprintf(stderr,"second C_GetAttributeValue failed rc = 0x%02x [%s]\n", ++ rc, p11_get_ckr(rc)); + return rc; + } + else +-- +2.1.0 + diff --git a/SPECS/opencryptoki.spec b/SPECS/opencryptoki.spec index ca0d4e3..6ac7729 100644 --- a/SPECS/opencryptoki.spec +++ b/SPECS/opencryptoki.spec @@ -2,36 +2,21 @@ Name: opencryptoki Summary: Implementation of the PKCS#11 (Cryptoki) specification v2.11 -Version: 3.0 -Release: 11%{?dist}.1 +Version: 3.2 +Release: 4.1%{?dist} License: CPL Group: System Environment/Base URL: http://sourceforge.net/projects/opencryptoki -Source0: http://downloads.sourceforge.net/%{name}/%{name}-v%{version}.tar.gz +Source0: http://downloads.sourceforge.net/%{name}/%{name}-v%{version}.tgz Source1: %{name}-tmpfiles.conf # https://bugzilla.redhat.com/show_bug.cgi?id=732756 -Patch0: %{name}-2.4-group.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=948460 -# http://sourceforge.net/mailarchive/message.php?msg_id=31202168 -Patch1: %{name}-3.0-pkcsconf-man.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=995002 -# http://sourceforge.net/mailarchive/message.php?msg_id=31321105 -Patch2: %{name}-3.0-unit.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1001729 -# http://sourceforge.net/p/opencryptoki/opencryptoki/ci/b50eb39e3cf8ccfdb735fbddfcdae10bdb70e1c4/ -Patch3: %{name}-3.0-opencryptoki-man.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1033284 -# post-3.0 upstream fixes -Patch4: %{name}-3.0-bz1033284.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1037228 -Patch5: %{name}-3.0-format.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1054661 -Patch6: %{name}-3.0-bz1054661.patch -# https://bugzilla.redhat.com/show_bug.cgi?id=1165621 -Patch7: %{name}-3.0-pkcscca-tool.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1122505#c8 +Patch0: %{name}-3.2-fix-root-checks.patch # do not install pkcsep11_migrate.1 and pkcscca.1 when it's not enabled -Patch8: %{name}-3.0-conditional-manpages.patch - +Patch1: %{name}-3.2-conditional-manpages.patch +Patch2: %{name}-3.2-pkcsep11_migrate-Fixed-parameter-handling-for-pkcsep.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1088512#c18 +Patch3: %{name}-3.2-Correctly-declare-OAEP-parameter-in-RSA-Wrap-tests-t.patch Requires(pre): shadow-utils coreutils sed BuildRequires: openssl-devel BuildRequires: trousers-devel @@ -40,7 +25,7 @@ BuildRequires: autoconf automake libtool BuildRequires: bison flex BuildRequires: systemd %ifarch s390 s390x -BuildRequires: libica-devel >= 2.0 +BuildRequires: libica-devel >= 2.3 %endif Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} Requires: %{name}-libs%{?_isa} = %{version}-%{release} @@ -62,7 +47,7 @@ This package contains the Slot Daemon (pkcsslotd) and general utilities. %package libs Group: System Environment/Libraries Summary: The run-time libraries for opencryptoki package -Requires: %{name}%{?_isa} = %{version}-%{release} +Requires(pre): shadow-utils %description libs Opencryptoki implements the PKCS#11 specification v2.11 for a set of @@ -172,20 +157,33 @@ This package brings the necessary libraries and files to support CCA devices in the opencryptoki stack. CCA is an interface to IBM cryptographic hardware such as IBM 4764 or 4765 that uses the "co-processor" or "secure-key" path. + +%package ep11tok +Group: System Environment/Libraries +Summary: CCA cryptographic devices (secure-key) support for opencryptoki +Requires(pre): %{name}-libs%{?_isa} = %{version}-%{release} +Requires: %{name}-libs%{?_isa} = %{version}-%{release} +Provides: %{name}(token) + +%description ep11tok +Opencryptoki implements the PKCS#11 specification v2.11 for a set of +cryptographic hardware, such as IBM 4764 and 4765 crypto cards, and the +Trusted Platform Module (TPM) chip. Opencryptoki also brings a software +token implementation that can be used without any cryptographic +hardware. +This package brings the necessary libraries and files to support EP11 +tokens in the opencryptoki stack. The EP11 token is a token that uses +the IBM Crypto Express adapters (starting with Crypto Express 4S adapters) +configured with Enterprise PKCS#11 (EP11) firmware. %endif %prep %setup -q -n %{name} -%patch0 -p1 -b .group -%patch1 -p1 -b .pkcsconf-man -%patch2 -p1 -b .unit -%patch3 -p1 -b .opencryptoki-man -%patch4 -p1 -b .bz1033284 -%patch5 -p1 -b .format -%patch6 -p1 -b .bz1054661 -%patch7 -p1 -b .pkcscca-tool -%patch8 -p1 -b .man +%patch0 -p1 -b .fix-root +%patch1 -p1 -b .man +%patch2 -p1 -b .pkcsep11_migrate +%patch3 -p1 -b .OAEP-in-test # Upstream tarball has unnecessary executable perms set on the sources find . -name '*.[ch]' -print0 | xargs -0 chmod -x @@ -193,7 +191,7 @@ find . -name '*.[ch]' -print0 | xargs -0 chmod -x # append token specific subdirs to tmpfiles.d config token_subdirs="icsf swtok tpm" %ifarch s390 s390x -token_subdirs="$token_subdirs lite ccatok" +token_subdirs="$token_subdirs lite ccatok ep11tok" %endif cp -p %{SOURCE1} %{name}-tmpfiles.conf @@ -208,9 +206,9 @@ done %configure --with-systemd=%{_unitdir} \ %ifarch s390 s390x - --enable-icatok --enable-ccatok + --enable-icatok --enable-ccatok --enable-ep11tok --enable-pkcsep11_migrate %else - --disable-icatok --disable-ccatok --disable-pkcscca_migrate + --disable-icatok --disable-ccatok --disable-ep11tok --disable-pkcsep11_migrate --disable-pkcscca_migrate %endif make %{?_smp_mflags} CHGRP=/bin/true @@ -235,6 +233,7 @@ install -m 0644 %{name}-tmpfiles.conf $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d/% %ifarch s390 s390x %post icatok -p /sbin/ldconfig %post ccatok -p /sbin/ldconfig +%post ep11tok -p /sbin/ldconfig %endif %postun libs -p /sbin/ldconfig @@ -244,6 +243,7 @@ install -m 0644 %{name}-tmpfiles.conf $RPM_BUILD_ROOT%{_prefix}/lib/tmpfiles.d/% %ifarch s390 s390x %postun icatok -p /sbin/ldconfig %postun ccatok -p /sbin/ldconfig +%postun ep11tok -p /sbin/ldconfig %endif %pre libs @@ -285,7 +285,6 @@ exit 0 %{_sysconfdir}/ld.so.conf.d/* # Unversioned .so symlinks usually belong to -devel packages, but opencryptoki # needs them in the main package, because: -# pkcs11_startup looks for opencryptoki/stdll/*.so, and # documentation suggests that programs should dlopen "PKCS11_API.so". %dir %{_libdir}/opencryptoki %{_libdir}/opencryptoki/libopencryptoki.* @@ -335,14 +334,34 @@ exit 0 %{_libdir}/opencryptoki/stdll/PKCS11_CCA.so %dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/ccatok/ %dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/ccatok/TOK_OBJ/ + +%files ep11tok +%doc doc/README.ep11_stdll +%config(noreplace) %{_sysconfdir}/%{name}/ep11tok.conf +%{_sbindir}/pkcsep11_migrate +%{_mandir}/man1/pkcsep11_migrate.1.* +%{_libdir}/opencryptoki/stdll/libpkcs11_ep11.* +%{_libdir}/opencryptoki/stdll/PKCS11_EP11.so +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/ep11tok/ +%dir %attr(770,root,pkcs11) %{_sharedstatedir}/%{name}/ep11tok/TOK_OBJ/ %endif %changelog -* Mon Dec 01 2014 Petr Lautrbach 3.0-11.1 -- Add a pkcscca tool to help migrate cca private token objects - from v2 (encrypted with cca hardware) to v3 (encrypted in software) - (#1165621) +* Wed Dec 03 2014 Petr Lautrbach 3.2-4.1 +- don't check if root is in pkcs11 group + +* Mon Nov 10 2014 Petr Lautrbach 3.2-3 +- Correctly declare OAEP parameter in RSA Wrap tests to prevent a possible + scope issue (#1088512) +- several fixes for pkcsep11_migrate + +* Mon Oct 20 2014 Petr Lautrbach 3.2-2 +- opencryptoki-libs needs shadow-utils to be installed (#1154647) + +* Wed Sep 10 2014 Petr Lautrbach 3.2-1 +- new upstream release 3.2 (#1088512) +- add new sub-package opencryptoki-ep11tok on s390x * Thu Feb 06 2014 Petr Lautrbach 3.0-11 - create the right lock directory for cca tokens (#1054442)