xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_tpm/common/obj_mgr.c (revision 33efde4275d24731ef87927237b0ffb0630b6b2d)
1 /*
2  *		Common Public License Version 0.5
3  *
4  *		THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
5  *		THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
6  *		REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
7  *		RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
8  *
9  *		1. DEFINITIONS
10  *
11  *		"Contribution" means:
12  *		      a) in the case of the initial Contributor, the
13  *		      initial code and documentation distributed under
14  *		      this Agreement, and
15  *
16  *		      b) in the case of each subsequent Contributor:
17  *		      i) changes to the Program, and
18  *		      ii) additions to the Program;
19  *
20  *		      where such changes and/or additions to the Program
21  *		      originate from and are distributed by that
22  *		      particular Contributor. A Contribution 'originates'
23  *		      from a Contributor if it was added to the Program
24  *		      by such Contributor itself or anyone acting on such
25  *		      Contributor's behalf. Contributions do not include
26  *		      additions to the Program which: (i) are separate
27  *		      modules of software distributed in conjunction with
28  *		      the Program under their own license agreement, and
29  *		      (ii) are not derivative works of the Program.
30  *
31  *
32  *		"Contributor" means any person or entity that distributes
33  *		the Program.
34  *
35  *		"Licensed Patents " mean patent claims licensable by a
36  *		Contributor which are necessarily infringed by the use or
37  *		sale of its Contribution alone or when combined with the
38  *		Program.
39  *
40  *		"Program" means the Contributions distributed in
41  *		accordance with this Agreement.
42  *
43  *		"Recipient" means anyone who receives the Program under
44  *		this Agreement, including all Contributors.
45  *
46  *		2. GRANT OF RIGHTS
47  *
48  *		      a) Subject to the terms of this Agreement, each
49  *		      Contributor hereby grants Recipient a
50  *		      no - exclusive, worldwide, royalt - free copyright
51  *		      license to reproduce, prepare derivative works of,
52  *		      publicly display, publicly perform, distribute and
53  *		      sublicense the Contribution of such Contributor, if
54  *		      any, and such derivative works, in source code and
55  *		      object code form.
56  *
57  *		      b) Subject to the terms of this Agreement, each
58  *		      Contributor hereby grants Recipient a
59  *		      no - exclusive, worldwide, royalt - free patent
60  *		      license under Licensed Patents to make, use, sell,
61  *		      offer to sell, import and otherwise transfer the
62  *		      Contribution of such Contributor, if any, in source
63  *		      code and object code form. This patent license
64  *		      shall apply to the combination of the Contribution
65  *		      and the Program if, at the time the Contribution is
66  *		      added by the Contributor, such addition of the
67  *		      Contribution causes such combination to be covered
68  *		      by the Licensed Patents. The patent license shall
69  *		      not apply to any other combinations which include
70  *		      the Contribution. No hardware per se is licensed
71  *		      hereunder.
72  *
73  *		      c) Recipient understands that although each
74  *		      Contributor grants the licenses to its
75  *		      Contributions set forth herein, no assurances are
76  *		      provided by any Contributor that the Program does
77  *		      not infringe the patent or other intellectual
78  *		      property rights of any other entity. Each
79  *		      Contributor disclaims any liability to Recipient
80  *		      for claims brought by any other entity based on
81  *		      infringement of intellectual property rights or
82  *		      otherwise. As a condition to exercising the rights
83  *		      and licenses granted hereunder, each Recipient
84  *		      hereby assumes sole responsibility to secure any
85  *		      other intellectual property rights needed, if any.
86  *
87  *		      For example, if a third party patent license is
88  *		      required to allow Recipient to distribute the
89  *		      Program, it is Recipient's responsibility to
90  *		      acquire that license before distributing the
91  *		      Program.
92  *
93  *		      d) Each Contributor represents that to its
94  *		      knowledge it has sufficient copyright rights in its
95  *		      Contribution, if any, to grant the copyright
96  *		      license set forth in this Agreement.
97  *
98  *		3. REQUIREMENTS
99  *
100  *		A Contributor may choose to distribute the Program in
101  *		object code form under its own license agreement, provided
102  *		that:
103  *		      a) it complies with the terms and conditions of
104  *		      this Agreement; and
105  *
106  *		      b) its license agreement:
107  *		      i) effectively disclaims on behalf of all
108  *		      Contributors all warranties and conditions, express
109  *		      and implied, including warranties or conditions of
110  *		      title and no - infringement, and implied warranties
111  *		      or conditions of merchantability and fitness for a
112  *		      particular purpose;
113  *
114  *		      ii) effectively excludes on behalf of all
115  *		      Contributors all liability for damages, including
116  *		      direct, indirect, special, incidental and
117  *		      consequential damages, such as lost profits;
118  *
119  *		      iii) states that any provisions which differ from
120  *		      this Agreement are offered by that Contributor
121  *		      alone and not by any other party; and
122  *
123  *		      iv) states that source code for the Program is
124  *		      available from such Contributor, and informs
125  *		      licensees how to obtain it in a reasonable manner
126  *		      on or through a medium customarily used for
127  *		      software exchange.
128  *
129  *		When the Program is made available in source code form:
130  *		      a) it must be made available under this Agreement;
131  *		      and
132  *		      b) a copy of this Agreement must be included with
133  *		      each copy of the Program.
134  *
135  *		Contributors may not remove or alter any copyright notices
136  *		contained within the Program.
137  *
138  *		Each Contributor must identify itself as the originator of
139  *		its Contribution, if any, in a manner that reasonably
140  *		allows subsequent Recipients to identify the originator of
141  *		the Contribution.
142  *
143  *
144  *		4. COMMERCIAL DISTRIBUTION
145  *
146  *		Commercial distributors of software may accept certain
147  *		responsibilities with respect to end users, business
148  *		partners and the like. While this license is intended to
149  *		facilitate the commercial use of the Program, the
150  *		Contributor who includes the Program in a commercial
151  *		product offering should do so in a manner which does not
152  *		create potential liability for other Contributors.
153  *		Therefore, if a Contributor includes the Program in a
154  *		commercial product offering, such Contributor ("Commercial
155  *		Contributor") hereby agrees to defend and indemnify every
156  *		other Contributor ("Indemnified Contributor") against any
157  *		losses, damages and costs (collectively "Losses") arising
158  *		from claims, lawsuits and other legal actions brought by a
159  *		third party against the Indemnified Contributor to the
160  *		extent caused by the acts or omissions of such Commercial
161  *		Contributor in connection with its distribution of the
162  *		Program in a commercial product offering. The obligations
163  *		in this section do not apply to any claims or Losses
164  *		relating to any actual or alleged intellectual property
165  *		infringement. In order to qualify, an Indemnified
166  *		Contributor must: a) promptly notify the Commercial
167  *		Contributor in writing of such claim, and b) allow the
168  *		Commercial Contributor to control, and cooperate with the
169  *		Commercial Contributor in, the defense and any related
170  *		settlement negotiations. The Indemnified Contributor may
171  *		participate in any such claim at its own expense.
172  *
173  *
174  *		For example, a Contributor might include the Program in a
175  *		commercial product offering, Product X. That Contributor
176  *		is then a Commercial Contributor. If that Commercial
177  *		Contributor then makes performance claims, or offers
178  *		warranties related to Product X, those performance claims
179  *		and warranties are such Commercial Contributor's
180  *		responsibility alone. Under this section, the Commercial
181  *		Contributor would have to defend claims against the other
182  *		Contributors related to those performance claims and
183  *		warranties, and if a court requires any other Contributor
184  *		to pay any damages as a result, the Commercial Contributor
185  *		must pay those damages.
186  *
187  *
188  *		5. NO WARRANTY
189  *
190  *		EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
191  *		PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
192  *		WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
193  *		IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
194  *		CONDITIONS OF TITLE, NO - INFRINGEMENT, MERCHANTABILITY OR
195  *		FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
196  *		responsible for determining the appropriateness of using
197  *		and distributing the Program and assumes all risks
198  *		associated with its exercise of rights under this
199  *		Agreement, including but not limited to the risks and
200  *		costs of program errors, compliance with applicable laws,
201  *		damage to or loss of data, programs or equipment, and
202  *		unavailability or interruption of operations.
203  *
204  *		6. DISCLAIMER OF LIABILITY
205  *		EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
206  *		RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
207  *		FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
208  *		OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
209  *		LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
210  *		LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
211  *		(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
212  *		OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
213  *		OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
214  *		POSSIBILITY OF SUCH DAMAGES.
215  *
216  *		7. GENERAL
217  *
218  *		If any provision of this Agreement is invalid or
219  *		unenforceable under applicable law, it shall not affect
220  *		the validity or enforceability of the remainder of the
221  *		terms of this Agreement, and without further action by the
222  *		parties hereto, such provision shall be reformed to the
223  *		minimum extent necessary to make such provision valid and
224  *		enforceable.
225  *
226  *
227  *		If Recipient institutes patent litigation against a
228  *		Contributor with respect to a patent applicable to
229  *		software (including a cros - claim or counterclaim in a
230  *		lawsuit), then any patent licenses granted by that
231  *		Contributor to such Recipient under this Agreement shall
232  *		terminate as of the date such litigation is filed. In
233  *		addition, If Recipient institutes patent litigation
234  *		against any entity (including a cros - claim or
235  *		counterclaim in a lawsuit) alleging that the Program
236  *		itself (excluding combinations of the Program with other
237  *		software or hardware) infringes such Recipient's
238  *		patent(s), then such Recipient's rights granted under
239  *		Section 2(b) shall terminate as of the date such
240  *		litigation is filed.
241  *
242  *		All Recipient's rights under this Agreement shall
243  *		terminate if it fails to comply with any of the material
244  *		terms or conditions of this Agreement and does not cure
245  *		such failure in a reasonable period of time after becoming
246  *		aware of such noncompliance. If all Recipient's rights
247  *		under this Agreement terminate, Recipient agrees to cease
248  *		use and distribution of the Program as soon as reasonably
249  *		practicable. However, Recipient's obligations under this
250  *		Agreement and any licenses granted by Recipient relating
251  *		to the Program shall continue and survive.
252  *
253  *		Everyone is permitted to copy and distribute copies of
254  *		this Agreement, but in order to avoid inconsistency the
255  *		Agreement is copyrighted and may only be modified in the
256  *		following manner. The Agreement Steward reserves the right
257  *		to publish new versions (including revisions) of this
258  *		Agreement from time to time. No one other than the
259  *		Agreement Steward has the right to modify this Agreement.
260  *
261  *		IBM is the initial Agreement Steward. IBM may assign the
262  *		responsibility to serve as the Agreement Steward to a
263  *		suitable separate entity. Each new version of the
264  *		Agreement will be given a distinguishing version number.
265  *		The Program (including Contributions) may always be
266  *		distributed subject to the version of the Agreement under
267  *		which it was received. In addition, after a new version of
268  *		the Agreement is published, Contributor may elect to
269  *		distribute the Program (including its Contributions) under
270  *		the new version. Except as expressly stated in Sections
271  *		2(a) and 2(b) above, Recipient receives no rights or
272  *		licenses to the intellectual property of any Contributor
273  *		under this Agreement, whether expressly, by implication,
274  *		estoppel or otherwise. All rights in the Program not
275  *		expressly granted under this Agreement are reserved.
276  *
277  *
278  *		This Agreement is governed by the laws of the State of New
279  *		York and the intellectual property laws of the United
280  *		States of America. No party to this Agreement will bring a
281  *		legal action under this Agreement more than one year after
282  *		the cause of action arose. Each party waives its rights to
283  *		a jury trial in any resulting litigation.
284  *
285  *
286  *
287  * (C) COPYRIGHT International Business Machines Corp. 2001, 2002
288  */
289 /*
290  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
291  * Use is subject to license terms.
292  */
293 
294 #include "tpmtok_int.h"
295 
296 pthread_rwlock_t obj_list_rw_mutex = PTHREAD_RWLOCK_INITIALIZER;
297 
298 static CK_RV
299 object_mgr_search_shm_for_obj(TOK_OBJ_ENTRY *,
300 	CK_ULONG, CK_ULONG, OBJECT *, CK_ULONG *);
301 static CK_RV object_mgr_update_from_shm(TSS_HCONTEXT);
302 static CK_RV object_mgr_check_shm(TSS_HCONTEXT, OBJECT *);
303 
304 static CK_RV
check_object_access(SESSION * sess,OBJECT * o)305 check_object_access(SESSION *sess, OBJECT *o)
306 {
307 	CK_BBOOL sess_obj, priv_obj;
308 	CK_RV rc = CKR_OK;
309 
310 	/*
311 	 * check whether session has permissions to create the object, etc
312 	 *
313 	 * Object	  R/O	    R/W    R/O   R/W    R/W
314 	 * Type		  Public   Public  User  User   SO
315 	 * -------------------------------------------------------------
316 	 * Public session  R/W	    R/W	   R/W   R/W    R/W
317 	 * Private session			 R/W    R/W
318 	 * Public token	   R/O	    R/W	   R/O   R/W    R/W
319 	 * Private token			 R/O    R/W
320 	 */
321 	sess_obj = object_is_session_object(o);
322 	priv_obj = object_is_private(o);
323 
324 	if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
325 		if (priv_obj) {
326 			rc = CKR_USER_NOT_LOGGED_IN;
327 			goto done;
328 		}
329 
330 		if (!sess_obj) {
331 			rc = CKR_SESSION_READ_ONLY;
332 			goto done;
333 		}
334 	}
335 
336 	if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
337 		if (! sess_obj) {
338 			rc = CKR_SESSION_READ_ONLY;
339 			goto done;
340 		}
341 	}
342 
343 	if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
344 		if (priv_obj) {
345 			rc = CKR_USER_NOT_LOGGED_IN;
346 			goto done;
347 		}
348 	}
349 
350 	if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
351 		if (priv_obj) {
352 			rc = CKR_USER_NOT_LOGGED_IN;
353 			goto done;
354 		}
355 	}
356 done:
357 	return (rc);
358 }
359 
360 CK_RV
object_mgr_add(SESSION * sess,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE * handle)361 object_mgr_add(SESSION	  * sess,
362 	CK_ATTRIBUTE	* pTemplate,
363 	CK_ULONG	   ulCount,
364 	CK_OBJECT_HANDLE * handle)
365 {
366 	OBJECT    * o = NULL;
367 	CK_BBOOL    priv_obj, sess_obj;
368 	CK_RV	rc;
369 
370 	if (! sess || ! pTemplate || ! handle) {
371 		return (CKR_FUNCTION_FAILED);
372 	}
373 
374 	rc = pthread_mutex_lock(&obj_list_mutex);
375 	if (rc != CKR_OK)
376 		return (CKR_FUNCTION_FAILED);
377 
378 	rc = object_create(pTemplate, ulCount, &o);
379 	if (rc != CKR_OK) {
380 		goto done;
381 	}
382 	rc = check_object_access(sess, o);
383 	if (rc != CKR_OK)
384 		goto done;
385 
386 	/*
387 	 * okay, object is created and the session permissions look okay.
388 	 * add the object to the appropriate list and assign an object handle
389 	 */
390 	sess_obj = object_is_session_object(o);
391 	priv_obj = object_is_private(o);
392 
393 	if (sess_obj) {
394 		o->session = sess;
395 		(void) memset(o->name, 0x00, sizeof (CK_BYTE) * 8);
396 
397 		sess_obj_list = dlist_add_as_first(sess_obj_list, o);
398 	} else {
399 		CK_BYTE current[8];
400 		CK_BYTE next[8];
401 
402 		rc = XProcLock(xproclock);
403 		if (rc != CKR_OK) {
404 			goto done;
405 		} else {
406 
407 			if (priv_obj) {
408 				if (global_shm->num_priv_tok_obj >=
409 				    MAX_TOK_OBJS) {
410 					rc = CKR_HOST_MEMORY;
411 					(void) XProcUnLock(xproclock);
412 					goto done;
413 				}
414 			} else {
415 				if (global_shm->num_publ_tok_obj >=
416 				    MAX_TOK_OBJS) {
417 					rc = CKR_HOST_MEMORY;
418 					(void) XProcUnLock(xproclock);
419 					goto done;
420 				}
421 			}
422 
423 			(void) memcpy(current,
424 			    &nv_token_data->next_token_object_name, 8);
425 
426 			o->session = NULL;
427 			(void) memcpy(&o->name, current, 8);
428 
429 			(void) compute_next_token_obj_name(current, next);
430 
431 			(void) memcpy(&nv_token_data->next_token_object_name,
432 			    next, 8);
433 
434 			rc = save_token_object(sess->hContext, o);
435 			if (rc != CKR_OK) {
436 				(void) XProcUnLock(xproclock);
437 				goto done;
438 			}
439 
440 			(void) object_mgr_add_to_shm(o);
441 			(void) XProcUnLock(xproclock);
442 
443 			(void) save_token_data(nv_token_data);
444 		}
445 
446 		if (priv_obj)
447 			priv_token_obj_list =
448 			    dlist_add_as_last(priv_token_obj_list, o);
449 		else
450 			publ_token_obj_list =
451 			    dlist_add_as_last(publ_token_obj_list, o);
452 	}
453 
454 	rc = object_mgr_add_to_map(sess, o, handle);
455 	if (rc != CKR_OK) {
456 		DL_NODE *node = NULL;
457 
458 		if (sess_obj) {
459 			node = dlist_find(sess_obj_list, o);
460 			if (node)
461 				sess_obj_list =
462 				    dlist_remove_node(sess_obj_list, node);
463 		} else {
464 			(void) delete_token_object(o);
465 
466 			if (priv_obj) {
467 				node = dlist_find(priv_token_obj_list, o);
468 				if (node)
469 					priv_token_obj_list =
470 					    dlist_remove_node(
471 					    priv_token_obj_list, node);
472 			} else {
473 				node = dlist_find(publ_token_obj_list, o);
474 				if (node)
475 					publ_token_obj_list =
476 					    dlist_remove_node(
477 					    publ_token_obj_list, node);
478 			}
479 
480 			rc = XProcLock(xproclock);
481 			if (rc != CKR_OK) {
482 				goto done;
483 			}
484 			(void) object_mgr_del_from_shm(o);
485 
486 			(void) XProcUnLock(xproclock);
487 		}
488 	}
489 
490 done:
491 	(void) pthread_mutex_unlock(&obj_list_mutex);
492 
493 	if ((rc != CKR_OK) && (o != NULL))
494 		(void) object_free(o);
495 
496 	return (rc);
497 }
498 
499 CK_RV
object_mgr_add_to_map(SESSION * sess,OBJECT * obj,CK_OBJECT_HANDLE * handle)500 object_mgr_add_to_map(SESSION	  * sess,
501 	OBJECT	   * obj,
502 	CK_OBJECT_HANDLE * handle) {
503 	OBJECT_MAP  *map_node = NULL;
504 
505 	if (! sess || ! obj || ! handle) {
506 		return (CKR_FUNCTION_FAILED);
507 	}
508 
509 	map_node = (OBJECT_MAP *)malloc(sizeof (OBJECT_MAP));
510 	if (! map_node) {
511 		return (CKR_HOST_MEMORY);
512 	}
513 	map_node->handle   = next_object_handle++;
514 	map_node->session  = sess;
515 	map_node->ptr	= obj;
516 
517 	if (obj->session != NULL)
518 		map_node->is_session_obj = TRUE;
519 	else
520 		map_node->is_session_obj = FALSE;
521 
522 	// add the new map entry to the list
523 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
524 		return (CKR_FUNCTION_FAILED);
525 	}
526 	object_map = dlist_add_as_first(object_map, map_node);
527 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
528 
529 	*handle = map_node->handle;
530 	return (CKR_OK);
531 }
532 
533 // object_mgr_copy()
534 //
535 // algorithm:
536 //    1) find the old object
537 //    2) get the template from the old object
538 //    3) merge in the new object's template
539 //    4) perform class - specific sanity checks
540 //
541 CK_RV
object_mgr_copy(SESSION * sess,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,CK_OBJECT_HANDLE old_handle,CK_OBJECT_HANDLE * new_handle)542 object_mgr_copy(SESSION	  * sess,
543 	CK_ATTRIBUTE	* pTemplate,
544 	CK_ULONG	   ulCount,
545 	CK_OBJECT_HANDLE   old_handle,
546 	CK_OBJECT_HANDLE * new_handle)
547 {
548 	OBJECT	*old_obj = NULL;
549 	OBJECT	*new_obj = NULL;
550 	CK_BBOOL    priv_obj;
551 	CK_BBOOL    sess_obj;
552 	CK_RV	rc;
553 
554 	if (! sess || ! pTemplate || ! new_handle) {
555 		return (CKR_FUNCTION_FAILED);
556 	}
557 
558 	rc = pthread_mutex_lock(&obj_list_mutex);
559 	if (rc != CKR_OK)
560 		return (CKR_FUNCTION_FAILED);
561 
562 	rc = object_mgr_find_in_map1(sess->hContext, old_handle, &old_obj);
563 	if (rc != CKR_OK) {
564 		goto done;
565 	}
566 	rc = object_copy(pTemplate, ulCount, old_obj, &new_obj);
567 	if (rc != CKR_OK) {
568 		goto done;
569 	}
570 
571 	rc = check_object_access(sess, new_obj);
572 	if (rc != CKR_OK)
573 		goto done;
574 
575 	sess_obj = object_is_session_object(new_obj);
576 	priv_obj = object_is_private(new_obj);
577 
578 	if (sess_obj) {
579 		new_obj->session = sess;
580 		(void) memset(&new_obj->name, 0x00, sizeof (CK_BYTE) * 8);
581 
582 		sess_obj_list = dlist_add_as_first(sess_obj_list, new_obj);
583 	} else {
584 		CK_BYTE current[8];
585 		CK_BYTE next[8];
586 
587 		rc = XProcLock(xproclock);
588 		if (rc != CKR_OK) {
589 			goto done;
590 		} else {
591 			if (priv_obj) {
592 				if (global_shm->num_priv_tok_obj >=
593 				    MAX_TOK_OBJS) {
594 					(void) XProcUnLock(xproclock);
595 					rc = CKR_HOST_MEMORY;
596 					goto done;
597 				}
598 			} else {
599 				if (global_shm->num_publ_tok_obj >=
600 				    MAX_TOK_OBJS) {
601 					(void) XProcUnLock(xproclock);
602 					rc = CKR_HOST_MEMORY;
603 					goto done;
604 				}
605 			}
606 			(void) memcpy(current,
607 			    &nv_token_data->next_token_object_name, 8);
608 
609 			new_obj->session = NULL;
610 			(void) memcpy(&new_obj->name, current, 8);
611 
612 			(void) compute_next_token_obj_name(current, next);
613 			(void) memcpy(&nv_token_data->next_token_object_name,
614 			    next, 8);
615 
616 			rc = save_token_object(sess->hContext, new_obj);
617 			if (rc != CKR_OK) {
618 				(void) XProcUnLock(xproclock);
619 				goto done;
620 			}
621 
622 			(void) object_mgr_add_to_shm(new_obj);
623 
624 			(void) XProcUnLock(xproclock);
625 
626 			(void) save_token_data(nv_token_data);
627 		}
628 
629 		if (priv_obj)
630 			priv_token_obj_list = dlist_add_as_last(
631 			    priv_token_obj_list, new_obj);
632 		else
633 			publ_token_obj_list = dlist_add_as_last(
634 			    publ_token_obj_list, new_obj);
635 	}
636 
637 	rc = object_mgr_add_to_map(sess, new_obj, new_handle);
638 	if (rc != CKR_OK) {
639 		DL_NODE *node = NULL;
640 
641 		if (sess_obj) {
642 			node = dlist_find(sess_obj_list, new_obj);
643 			if (node)
644 				sess_obj_list = dlist_remove_node(
645 				    sess_obj_list, node);
646 		} else {
647 			(void) delete_token_object(new_obj);
648 
649 			if (priv_obj) {
650 				node = dlist_find(priv_token_obj_list, new_obj);
651 				if (node)
652 					priv_token_obj_list = dlist_remove_node(
653 					    priv_token_obj_list, node);
654 			} else {
655 				node = dlist_find(publ_token_obj_list, new_obj);
656 				if (node)
657 					publ_token_obj_list = dlist_remove_node(
658 					    publ_token_obj_list, node);
659 			}
660 
661 			rc = XProcLock(xproclock);
662 			if (rc != CKR_OK) {
663 				goto done;
664 			}
665 			(void) object_mgr_del_from_shm(new_obj);
666 
667 			(void) XProcUnLock(xproclock);
668 		}
669 	}
670 
671 done:
672 	(void) pthread_mutex_unlock(&obj_list_mutex);
673 
674 	if ((rc != CKR_OK) && (new_obj != NULL))
675 		(void) object_free(new_obj);
676 
677 	return (rc);
678 }
679 
680 //
681 // determines whether the session is allowed to create an object.  creates
682 // the object but doesn't add the object to any object lists or to the
683 // process' object map.
684 //
685 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)686 object_mgr_create_skel(SESSION	* sess,
687 	CK_ATTRIBUTE  * pTemplate,
688 	CK_ULONG	ulCount,
689 	CK_ULONG	mode,
690 	CK_ULONG	obj_type,
691 	CK_ULONG	sub_class,
692 	OBJECT	** obj)
693 {
694 	OBJECT	*o = NULL;
695 	CK_RV	rc;
696 	CK_BBOOL    priv_obj;
697 	CK_BBOOL    sess_obj;
698 
699 	if (! sess || ! obj) {
700 		return (CKR_FUNCTION_FAILED);
701 	}
702 	if (! pTemplate && (ulCount != 0)) {
703 		return (CKR_FUNCTION_FAILED);
704 	}
705 	rc = object_create_skel(pTemplate, ulCount,
706 	    mode, obj_type, sub_class, &o);
707 	if (rc != CKR_OK) {
708 		return (rc);
709 	}
710 	sess_obj = object_is_session_object(o);
711 	priv_obj = object_is_private(o);
712 
713 	if (sess->session_info.state == CKS_RO_PUBLIC_SESSION) {
714 		if (priv_obj) {
715 			(void) object_free(o);
716 			return (CKR_USER_NOT_LOGGED_IN);
717 		}
718 
719 		if (! sess_obj) {
720 			(void) object_free(o);
721 			return (CKR_SESSION_READ_ONLY);
722 		}
723 	}
724 
725 	if (sess->session_info.state == CKS_RO_USER_FUNCTIONS) {
726 		if (! sess_obj) {
727 			(void) object_free(o);
728 			return (CKR_SESSION_READ_ONLY);
729 		}
730 	}
731 
732 	if (sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
733 		if (priv_obj) {
734 			(void) object_free(o);
735 			return (CKR_USER_NOT_LOGGED_IN);
736 		}
737 	}
738 
739 	if (sess->session_info.state == CKS_RW_SO_FUNCTIONS) {
740 		if (priv_obj) {
741 			(void) object_free(o);
742 			return (CKR_USER_NOT_LOGGED_IN);
743 		}
744 	}
745 
746 	*obj = o;
747 	return (CKR_OK);
748 }
749 
750 CK_RV
object_mgr_create_final(SESSION * sess,OBJECT * obj,CK_OBJECT_HANDLE * handle)751 object_mgr_create_final(SESSION	   * sess,
752 	OBJECT	    * obj,
753 	CK_OBJECT_HANDLE  * handle)
754 {
755 	CK_BBOOL  sess_obj;
756 	CK_BBOOL  priv_obj;
757 	CK_RV	rc;
758 
759 	if (!sess || !obj || !handle)
760 		return (CKR_FUNCTION_FAILED);
761 
762 	rc = pthread_mutex_lock(&obj_list_mutex);
763 	if (rc != CKR_OK)
764 		return (CKR_FUNCTION_FAILED);
765 
766 	sess_obj = object_is_session_object(obj);
767 	priv_obj = object_is_private(obj);
768 
769 	if (sess_obj) {
770 		obj->session = sess;
771 		(void) memset(obj->name, 0x0, sizeof (CK_BYTE) * 8);
772 
773 		sess_obj_list = dlist_add_as_first(sess_obj_list, obj);
774 	} else {
775 		CK_BYTE current[8];
776 		CK_BYTE next[8];
777 
778 		rc = XProcLock(xproclock);
779 		if (rc != CKR_OK) {
780 			goto done;
781 		} else {
782 			if (priv_obj) {
783 				if (global_shm->num_priv_tok_obj >=
784 				    MAX_TOK_OBJS) {
785 					(void) XProcUnLock(xproclock);
786 					rc = CKR_HOST_MEMORY;
787 					goto done;
788 				}
789 			} else {
790 				if (global_shm->num_publ_tok_obj >=
791 				    MAX_TOK_OBJS) {
792 					(void) XProcUnLock(xproclock);
793 					rc = CKR_HOST_MEMORY;
794 					goto done;
795 				}
796 			}
797 			(void) memcpy(current,
798 			    &nv_token_data->next_token_object_name, 8);
799 
800 			obj->session = NULL;
801 			(void) memcpy(&obj->name, current, 8);
802 
803 			(void) compute_next_token_obj_name(current, next);
804 			(void) memcpy(&nv_token_data->next_token_object_name,
805 			    next, 8);
806 
807 			rc = save_token_object(sess->hContext, obj);
808 			if (rc != CKR_OK) {
809 				(void) XProcUnLock(xproclock);
810 				goto done;
811 			}
812 
813 			(void) object_mgr_add_to_shm(obj);
814 
815 			(void) XProcUnLock(xproclock);
816 
817 			(void) save_token_data(nv_token_data);
818 		}
819 
820 		if (priv_obj)
821 			priv_token_obj_list = dlist_add_as_last(
822 			    priv_token_obj_list, obj);
823 		else
824 			publ_token_obj_list = dlist_add_as_last(
825 			    publ_token_obj_list, obj);
826 	}
827 
828 	rc = object_mgr_add_to_map(sess, obj, handle);
829 	if (rc != CKR_OK) {
830 		DL_NODE *node = NULL;
831 
832 		if (sess_obj) {
833 			node = dlist_find(sess_obj_list, obj);
834 			if (node)
835 				sess_obj_list = dlist_remove_node(
836 				    sess_obj_list, node);
837 		} else {
838 			(void) delete_token_object(obj);
839 
840 			if (priv_obj) {
841 				node = dlist_find(priv_token_obj_list, obj);
842 				if (node)
843 					priv_token_obj_list = dlist_remove_node(
844 					    priv_token_obj_list, node);
845 			} else {
846 				node = dlist_find(publ_token_obj_list, obj);
847 				if (node)
848 					publ_token_obj_list = dlist_remove_node(
849 					    publ_token_obj_list, node);
850 			}
851 
852 			rc = XProcLock(xproclock);
853 			if (rc != CKR_OK) {
854 				goto done;
855 			}
856 			(void) object_mgr_del_from_shm(obj);
857 
858 			(void) XProcUnLock(xproclock);
859 		}
860 	}
861 
862 done:
863 	(void) pthread_mutex_unlock(&obj_list_mutex);
864 
865 	return (rc);
866 }
867 
868 CK_RV
object_mgr_destroy_object(SESSION * sess,CK_OBJECT_HANDLE handle)869 object_mgr_destroy_object(SESSION	  * sess,
870 	CK_OBJECT_HANDLE   handle)
871 {
872 	OBJECT    * obj = NULL;
873 	CK_BBOOL    sess_obj;
874 	CK_BBOOL    priv_obj;
875 	CK_RV	rc;
876 
877 	if (! sess)
878 		return (CKR_FUNCTION_FAILED);
879 
880 	rc = pthread_mutex_lock(&obj_list_mutex);
881 	if (rc != CKR_OK)
882 		return (CKR_FUNCTION_FAILED);
883 
884 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
885 	if (rc != CKR_OK) {
886 		goto done;
887 	}
888 
889 	rc = check_object_access(sess, obj);
890 	if (rc != CKR_OK)
891 		goto done;
892 
893 	sess_obj = object_is_session_object(obj);
894 	priv_obj = object_is_private(obj);
895 
896 	if (sess_obj) {
897 		DL_NODE *node;
898 
899 		node = dlist_find(sess_obj_list, obj);
900 		if (node) {
901 			(void) object_mgr_remove_from_map(handle);
902 
903 			(void) object_free(obj);
904 			sess_obj_list = dlist_remove_node(
905 			    sess_obj_list, node);
906 
907 			rc = CKR_OK;
908 			goto done;
909 		}
910 	} else {
911 		DL_NODE *node = NULL;
912 
913 		(void) delete_token_object(obj);
914 
915 		if (priv_obj)
916 			node = dlist_find(priv_token_obj_list, obj);
917 		else
918 			node = dlist_find(publ_token_obj_list, obj);
919 
920 		if (node) {
921 			rc = XProcLock(xproclock);
922 			if (rc != CKR_OK) {
923 				goto done;
924 			}
925 			(void) object_mgr_del_from_shm(obj);
926 
927 			(void) XProcUnLock(xproclock);
928 
929 			(void) object_mgr_remove_from_map(handle);
930 
931 			(void) object_free(obj);
932 
933 			if (priv_obj)
934 				priv_token_obj_list = dlist_remove_node(
935 				    priv_token_obj_list, node);
936 			else
937 				publ_token_obj_list = dlist_remove_node(
938 				    publ_token_obj_list, node);
939 
940 			rc = CKR_OK;
941 			goto done;
942 		}
943 	}
944 
945 	rc = CKR_FUNCTION_FAILED;
946 done:
947 	(void) pthread_mutex_unlock(&obj_list_mutex);
948 
949 	return (rc);
950 }
951 
952 CK_RV
object_mgr_destroy_token_objects(TSS_HCONTEXT hContext)953 object_mgr_destroy_token_objects(TSS_HCONTEXT hContext)
954 {
955 	CK_BBOOL locked2 = FALSE;
956 	CK_RV rc;
957 
958 	rc = pthread_mutex_lock(&obj_list_mutex);
959 	if (rc != CKR_OK)
960 		return (CKR_FUNCTION_FAILED);
961 
962 	while (publ_token_obj_list) {
963 		OBJECT *obj = (OBJECT *)publ_token_obj_list->data;
964 
965 		CK_OBJECT_HANDLE handle;
966 
967 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
968 		if (rc == CKR_OK) {
969 			(void) object_mgr_remove_from_map(handle);
970 		}
971 		(void) delete_token_object(obj);
972 		(void) object_free(obj);
973 
974 		publ_token_obj_list = dlist_remove_node(
975 		    publ_token_obj_list, publ_token_obj_list);
976 	}
977 
978 	while (priv_token_obj_list) {
979 		OBJECT *obj = (OBJECT *)priv_token_obj_list->data;
980 
981 		CK_OBJECT_HANDLE handle;
982 
983 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
984 		if (rc == CKR_OK) {
985 			(void) object_mgr_remove_from_map(handle);
986 		}
987 		(void) delete_token_object(obj);
988 		(void) object_free(obj);
989 
990 		priv_token_obj_list = dlist_remove_node(
991 		    priv_token_obj_list, priv_token_obj_list);
992 	}
993 
994 	// now we want to purge the token object list in shared memory
995 	//
996 	rc = XProcLock(xproclock);
997 	if (rc == CKR_OK) {
998 		locked2 = TRUE;
999 
1000 		global_shm->num_priv_tok_obj = 0;
1001 		global_shm->num_publ_tok_obj = 0;
1002 
1003 		(void) memset(&global_shm->publ_tok_objs, 0x0,
1004 		    MAX_TOK_OBJS * sizeof (TOK_OBJ_ENTRY));
1005 		(void) memset(&global_shm->priv_tok_objs, 0x0,
1006 		    MAX_TOK_OBJS * sizeof (TOK_OBJ_ENTRY));
1007 	}
1008 
1009 	(void) pthread_mutex_unlock(&obj_list_mutex);
1010 
1011 	if (locked2 == TRUE) (void) XProcUnLock(xproclock);
1012 
1013 	return (rc);
1014 }
1015 
1016 //
1017 // Locates the specified object in the map
1018 // without going and checking for cache update
1019 //
1020 CK_RV
object_mgr_find_in_map_nocache(CK_OBJECT_HANDLE handle,OBJECT ** ptr)1021 object_mgr_find_in_map_nocache(CK_OBJECT_HANDLE    handle,
1022 	OBJECT	   ** ptr) {
1023 	DL_NODE   * node = NULL;
1024 	OBJECT    * obj  = NULL;
1025 
1026 	if (! ptr) {
1027 		return (CKR_FUNCTION_FAILED);
1028 	}
1029 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1030 		return (CKR_FUNCTION_FAILED);
1031 	}
1032 	node = object_map;
1033 	while (node) {
1034 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1035 
1036 		if (map->handle == handle) {
1037 			obj = map->ptr;
1038 			break;
1039 		}
1040 
1041 		node = node->next;
1042 	}
1043 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1044 
1045 	if (obj == NULL || node == NULL) {
1046 		return (CKR_OBJECT_HANDLE_INVALID);
1047 	}
1048 
1049 	if (object_is_session_object(obj) == TRUE) {
1050 		 *ptr = obj;
1051 		return (CKR_OK);
1052 	}
1053 
1054 	*ptr = obj;
1055 	return (CKR_OK);
1056 }
1057 
1058 CK_RV
object_mgr_find_in_map1(TSS_HCONTEXT hContext,CK_OBJECT_HANDLE handle,OBJECT ** ptr)1059 object_mgr_find_in_map1(
1060 	TSS_HCONTEXT hContext,
1061 	CK_OBJECT_HANDLE    handle,
1062 	OBJECT	   ** ptr)
1063 {
1064 	DL_NODE   * node = NULL;
1065 	OBJECT    * obj  = NULL;
1066 
1067 	if (! ptr) {
1068 		return (CKR_FUNCTION_FAILED);
1069 	}
1070 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1071 		return (CKR_FUNCTION_FAILED);
1072 	}
1073 	node = object_map;
1074 	while (node) {
1075 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1076 
1077 		if (map->handle == handle) {
1078 			obj = map->ptr;
1079 			break;
1080 		}
1081 
1082 		node = node->next;
1083 	}
1084 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1085 
1086 	if (obj == NULL || node == NULL) {
1087 		return (CKR_OBJECT_HANDLE_INVALID);
1088 	}
1089 
1090 	if (object_is_session_object(obj) == TRUE) {
1091 		*ptr = obj;
1092 		return (CKR_OK);
1093 	}
1094 
1095 	(void) object_mgr_check_shm(hContext, obj);
1096 
1097 	*ptr = obj;
1098 	return (CKR_OK);
1099 }
1100 
1101 CK_RV
object_mgr_find_in_map2(TSS_HCONTEXT hContext,OBJECT * obj,CK_OBJECT_HANDLE * handle)1102 object_mgr_find_in_map2(
1103 	TSS_HCONTEXT hContext,
1104 	OBJECT	   * obj,
1105 	CK_OBJECT_HANDLE * handle)
1106 {
1107 	DL_NODE	   * node = NULL;
1108 	CK_OBJECT_HANDLE    h    = (CK_OBJECT_HANDLE)NULL;
1109 
1110 	if (! obj || ! handle) {
1111 		return (CKR_FUNCTION_FAILED);
1112 	}
1113 	if (pthread_rwlock_rdlock(&obj_list_rw_mutex)) {
1114 		return (CKR_FUNCTION_FAILED);
1115 	}
1116 	node = object_map;
1117 	while (node) {
1118 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1119 
1120 		if (map->ptr == obj) {
1121 			h = map->handle;
1122 			break;
1123 		}
1124 
1125 		node = node->next;
1126 	}
1127 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1128 
1129 	if (node == NULL) {
1130 		return (CKR_OBJECT_HANDLE_INVALID);
1131 	}
1132 
1133 	if (object_is_session_object(obj) == TRUE) {
1134 		*handle = h;
1135 		return (CKR_OK);
1136 	}
1137 
1138 	(void) object_mgr_check_shm(hContext, obj);
1139 
1140 	*handle = h;
1141 	return (CKR_OK);
1142 }
1143 
1144 CK_RV
object_mgr_find_init(SESSION * sess,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)1145 object_mgr_find_init(SESSION	* sess,
1146 	CK_ATTRIBUTE * pTemplate,
1147 	CK_ULONG	ulCount)
1148 {
1149 	if (! sess) {
1150 		return (CKR_FUNCTION_FAILED);
1151 	}
1152 	if (sess->find_active != FALSE) {
1153 		return (CKR_OPERATION_ACTIVE);
1154 	}
1155 	// initialize the found object list.  if it doesn't exist, allocate
1156 	// a list big enough for 10 handles.  we'll reallocate if we need more
1157 	//
1158 	if (sess->find_list != NULL) {
1159 		(void) memset(sess->find_list, 0x0,
1160 		    sess->find_len * sizeof (CK_OBJECT_HANDLE));
1161 	} else {
1162 		sess->find_list = (CK_OBJECT_HANDLE *)malloc(
1163 		    10 * sizeof (CK_OBJECT_HANDLE));
1164 		if (! sess->find_list) {
1165 			return (CKR_HOST_MEMORY);
1166 		} else {
1167 			(void) memset(sess->find_list, 0x0,
1168 			    10 * sizeof (CK_OBJECT_HANDLE));
1169 			sess->find_len = 10;
1170 		}
1171 	}
1172 
1173 	sess->find_count = 0;
1174 	sess->find_idx   = 0;
1175 
1176 	//  --- need to grab the object lock here
1177 	if (pthread_mutex_lock(&obj_list_mutex))
1178 		return (CKR_FUNCTION_FAILED);
1179 
1180 	(void) object_mgr_update_from_shm(sess->hContext);
1181 
1182 	// which objects can be return (ed:
1183 	//
1184 	//   Public Session:   public session objects, public token objects
1185 	//   User Session:	all session objects,    all token objects
1186 	//   SO session:	public session objects, public token objects
1187 	//
1188 	switch (sess->session_info.state) {
1189 		case CKS_RO_PUBLIC_SESSION:
1190 		case CKS_RW_PUBLIC_SESSION:
1191 		case CKS_RW_SO_FUNCTIONS:
1192 		(void) object_mgr_find_build_list(sess, pTemplate,
1193 		    ulCount, publ_token_obj_list, TRUE);
1194 		(void) object_mgr_find_build_list(sess, pTemplate,
1195 		    ulCount, sess_obj_list,	TRUE);
1196 		break;
1197 
1198 		case CKS_RO_USER_FUNCTIONS:
1199 		case CKS_RW_USER_FUNCTIONS:
1200 		(void) object_mgr_find_build_list(sess, pTemplate,
1201 		    ulCount, priv_token_obj_list, FALSE);
1202 		(void) object_mgr_find_build_list(sess, pTemplate,
1203 		    ulCount, publ_token_obj_list, FALSE);
1204 		(void) object_mgr_find_build_list(sess, pTemplate,
1205 		    ulCount, sess_obj_list,  FALSE);
1206 		break;
1207 	}
1208 	(void) pthread_mutex_unlock(&obj_list_mutex);
1209 
1210 	sess->find_active = TRUE;
1211 
1212 	return (CKR_OK);
1213 }
1214 
1215 CK_RV
object_mgr_find_build_list(SESSION * sess,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount,DL_NODE * obj_list,CK_BBOOL public_only)1216 object_mgr_find_build_list(SESSION	* sess,
1217 	CK_ATTRIBUTE * pTemplate,
1218 	CK_ULONG	ulCount,
1219 	DL_NODE	* obj_list,
1220 	CK_BBOOL	public_only)
1221 {
1222 	OBJECT	   * obj  = NULL;
1223 	DL_NODE	  * node = NULL;
1224 	CK_OBJECT_HANDLE   handle;
1225 	CK_BBOOL	   is_priv;
1226 	CK_BBOOL	   match;
1227 	CK_BBOOL	   hw_feature = FALSE;
1228 	CK_BBOOL	   hidden_object = FALSE;
1229 	CK_RV		rc;
1230 	CK_ATTRIBUTE	* attr;
1231 	unsigned int		i;
1232 
1233 	if (! sess) {
1234 		return (CKR_FUNCTION_FAILED);
1235 	}
1236 	if (! obj_list)
1237 		return (CKR_OK);
1238 	// PKCS#11 v2.11 (pg. 79): "When searching using C_FindObjectsInit
1239 	// and C_FindObjects, hardware feature objects are not returned
1240 	// unless the CKA_CLASS attribute in the template has the value
1241 	// CKO_HW_FEATURE." So, we check for CKO_HW_FEATURE and if its set,
1242 	// we'll find these objects below. - KEY
1243 	for (i = 0; i < ulCount; i++) {
1244 		if (pTemplate[i].type == CKA_CLASS) {
1245 			if (*(CK_ULONG *)pTemplate[i].pValue ==
1246 			    CKO_HW_FEATURE) {
1247 				hw_feature = TRUE;
1248 				break;
1249 			}
1250 		}
1251 
1252 		if (pTemplate[i].type == CKA_HIDDEN) {
1253 			if (*(CK_BBOOL *)pTemplate[i].pValue == TRUE) {
1254 				hidden_object = TRUE;
1255 				break;
1256 			}
1257 		}
1258 	}
1259 
1260 	node = obj_list;
1261 	while (node) {
1262 		match   = FALSE;
1263 		obj	= (OBJECT *)node->data;
1264 		is_priv = object_is_private(obj);
1265 
1266 
1267 		if ((is_priv == FALSE) || (public_only == FALSE)) {
1268 			if (pTemplate == NULL || ulCount == 0)
1269 				match = TRUE;
1270 			else
1271 				match = template_compare(pTemplate,
1272 				    ulCount, obj->template);
1273 		}
1274 
1275 		if (match) {
1276 			rc = object_mgr_find_in_map2(sess->hContext, obj,
1277 			    &handle);
1278 			if (rc != CKR_OK) {
1279 				rc = object_mgr_add_to_map(sess, obj, &handle);
1280 				if (rc != CKR_OK) {
1281 					return (CKR_FUNCTION_FAILED);
1282 				}
1283 			}
1284 			if (rc == CKR_OK) {
1285 				if ((hw_feature == FALSE) &&
1286 				    (template_attribute_find(obj->template,
1287 				    CKA_CLASS, &attr) == TRUE)) {
1288 					if (*(CK_OBJECT_CLASS *)attr->pValue ==
1289 					    CKO_HW_FEATURE)
1290 						goto next_loop;
1291 				}
1292 
1293 				if ((hidden_object == FALSE) &&
1294 				    (template_attribute_find(obj->template,
1295 				    CKA_HIDDEN, &attr) == TRUE)) {
1296 					if (*(CK_BBOOL *)attr->pValue == TRUE)
1297 						goto next_loop;
1298 				}
1299 
1300 				sess->find_list[ sess->find_count ] = handle;
1301 				sess->find_count++;
1302 
1303 				if (sess->find_count >= sess->find_len) {
1304 					sess->find_len += 15;
1305 					sess->find_list =
1306 					    (CK_OBJECT_HANDLE *)realloc(
1307 					    sess->find_list, sess->find_len *
1308 					    sizeof (CK_OBJECT_HANDLE));
1309 					if (! sess->find_list) {
1310 						return (CKR_HOST_MEMORY);
1311 					}
1312 				}
1313 			}
1314 		}
1315 		next_loop:
1316 		node = node->next;
1317 	}
1318 
1319 	return (CKR_OK);
1320 }
1321 
1322 CK_RV
object_mgr_find_final(SESSION * sess)1323 object_mgr_find_final(SESSION *sess)
1324 {
1325 	if (! sess) {
1326 		return (CKR_FUNCTION_FAILED);
1327 	}
1328 	if (sess->find_active == FALSE) {
1329 		return (CKR_OPERATION_NOT_INITIALIZED);
1330 	}
1331 	free(sess->find_list);
1332 	sess->find_list   = NULL;
1333 	sess->find_count  = 0;
1334 	sess->find_idx    = 0;
1335 	sess->find_active = FALSE;
1336 
1337 	return (CKR_OK);
1338 }
1339 
1340 CK_RV
object_mgr_get_attribute_values(SESSION * sess,CK_OBJECT_HANDLE handle,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)1341 object_mgr_get_attribute_values(SESSION	   * sess,
1342 	CK_OBJECT_HANDLE    handle,
1343 	CK_ATTRIBUTE	* pTemplate,
1344 	CK_ULONG	    ulCount)
1345 {
1346 	OBJECT   * obj;
1347 	CK_BBOOL   priv_obj;
1348 	CK_RV	rc;
1349 
1350 	if (! pTemplate) {
1351 		return (CKR_FUNCTION_FAILED);
1352 	}
1353 	rc = pthread_mutex_lock(&obj_list_mutex);
1354 	if (rc != CKR_OK)
1355 		return (CKR_FUNCTION_FAILED);
1356 
1357 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
1358 	if (rc != CKR_OK) {
1359 		goto done;
1360 	}
1361 	priv_obj = object_is_private(obj);
1362 
1363 	if (priv_obj == TRUE) {
1364 		if (sess->session_info.state == CKS_RO_PUBLIC_SESSION ||
1365 		    sess->session_info.state == CKS_RW_PUBLIC_SESSION) {
1366 			rc = CKR_USER_NOT_LOGGED_IN;
1367 			goto done;
1368 		}
1369 	}
1370 
1371 	rc = object_get_attribute_values(obj, pTemplate, ulCount);
1372 done:
1373 	(void) pthread_mutex_unlock(&obj_list_mutex);
1374 
1375 	return (rc);
1376 }
1377 
1378 CK_RV
object_mgr_get_object_size(TSS_HCONTEXT hContext,CK_OBJECT_HANDLE handle,CK_ULONG * size)1379 object_mgr_get_object_size(
1380 	TSS_HCONTEXT hContext,
1381 	CK_OBJECT_HANDLE   handle,
1382 	CK_ULONG	 * size)
1383 {
1384 	OBJECT    * obj;
1385 	CK_RV	rc;
1386 
1387 	rc = pthread_mutex_lock(&obj_list_mutex);
1388 	if (rc != CKR_OK)
1389 		return (CKR_FUNCTION_FAILED);
1390 
1391 	rc = object_mgr_find_in_map1(hContext, handle, &obj);
1392 	if (rc != CKR_OK) {
1393 		rc = CKR_OBJECT_HANDLE_INVALID;
1394 		goto done;
1395 	}
1396 
1397 	*size = object_get_size(obj);
1398 
1399 done:
1400 	(void) pthread_mutex_unlock(&obj_list_mutex);
1401 	return (rc);
1402 }
1403 
1404 
1405 // object_mgr_invalidate_handle1()
1406 //
1407 // Returns:  TRUE  if successfully removes the node
1408 //	   FALSE if cannot remove the node (not found, etc)
1409 //
1410 CK_BBOOL
object_mgr_invalidate_handle1(CK_OBJECT_HANDLE handle)1411 object_mgr_invalidate_handle1(CK_OBJECT_HANDLE handle)
1412 {
1413 	DL_NODE *node = NULL;
1414 
1415 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1416 		return (CKR_FUNCTION_FAILED);
1417 	}
1418 	node = object_map;
1419 
1420 	while (node) {
1421 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1422 
1423 		if (map->handle == handle) {
1424 			object_map = dlist_remove_node(object_map, node);
1425 			free(map);
1426 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1427 			return (TRUE);
1428 		}
1429 
1430 		node = node->next;
1431 	}
1432 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1433 	return (FALSE);
1434 }
1435 
1436 // object_mgr_invalidate_handle2()
1437 //
1438 // Returns:  TRUE  if successfully removes the node
1439 //	   FALSE if cannot remove the node (not found, etc)
1440 //
1441 CK_BBOOL
object_mgr_invalidate_handle2(OBJECT * obj)1442 object_mgr_invalidate_handle2(OBJECT *obj)
1443 {
1444 	DL_NODE *node = NULL;
1445 
1446 	if (! obj)
1447 		return (FALSE);
1448 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1449 		return (CKR_FUNCTION_FAILED);
1450 	}
1451 	node = object_map;
1452 
1453 	while (node) {
1454 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1455 		if (map->ptr == obj) {
1456 			object_map = dlist_remove_node(object_map, node);
1457 			free(map);
1458 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1459 			return (TRUE);
1460 		}
1461 		node = node->next;
1462 	}
1463 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1464 
1465 	return (FALSE);
1466 }
1467 
1468 // object_mgr_purge_session_objects()
1469 //
1470 // Args:    SESSION *
1471 //	  SESS_OBJ_TYPE:  can be ALL, PRIVATE or PUBLIC
1472 //
1473 // Remove all session objects owned by the specified session satisfying
1474 // the 'type' requirements
1475 //
1476 CK_BBOOL
object_mgr_purge_session_objects(SESSION * sess,SESS_OBJ_TYPE type)1477 object_mgr_purge_session_objects(SESSION	* sess,
1478 	SESS_OBJ_TYPE   type)
1479 {
1480 	DL_NODE   *node = NULL;
1481 	DL_NODE   *next = NULL;
1482 	OBJECT    *obj = NULL;
1483 	CK_BBOOL   del;
1484 	CK_RV	rc;
1485 
1486 	if (!sess)
1487 		return (FALSE);
1488 
1489 	rc = pthread_mutex_lock(&obj_list_mutex);
1490 	if (rc != CKR_OK)
1491 		return (FALSE);
1492 
1493 	node = sess_obj_list;
1494 
1495 	while (node) {
1496 		obj = (OBJECT *)node->data;
1497 		del = FALSE;
1498 
1499 		if (obj->session == sess) {
1500 			if (type == PRIVATE) {
1501 				if (object_is_private(obj))
1502 					del = TRUE;
1503 			} else if (type == PUBLIC) {
1504 				if (object_is_public(obj))
1505 					del = TRUE;
1506 			} else if (type == ALL)
1507 				del = TRUE;
1508 		}
1509 		if (del == TRUE) {
1510 
1511 			CK_OBJECT_HANDLE handle;
1512 			CK_RV	    rc;
1513 
1514 			rc = object_mgr_find_in_map2(sess->hContext, obj,
1515 			    &handle);
1516 			if (rc == CKR_OK) {
1517 				(void) object_mgr_invalidate_handle1(handle);
1518 				(void) object_free(obj);
1519 			}
1520 
1521 			next = node->next;
1522 			sess_obj_list = dlist_remove_node(sess_obj_list, node);
1523 			node = next;
1524 		}
1525 		else
1526 			node = node->next;
1527 	}
1528 
1529 	(void) pthread_mutex_unlock(&obj_list_mutex);
1530 
1531 	return (TRUE);
1532 }
1533 
1534 //
1535 // This routine cleans up the list of token objects.  in general, we don't
1536 // need to do this but when tracing memory leaks, it's best that we free
1537 // everything that we've allocated.
1538 //
1539 CK_BBOOL
object_mgr_purge_token_objects(TSS_HCONTEXT hContext)1540 object_mgr_purge_token_objects(TSS_HCONTEXT hContext)
1541 {
1542 	DL_NODE   *node = NULL;
1543 	DL_NODE   *next = NULL;
1544 	OBJECT    *obj = NULL;
1545 	CK_RV	rc;
1546 
1547 	rc = pthread_mutex_lock(&obj_list_mutex);
1548 	if (rc != CKR_OK)
1549 		return (FALSE);
1550 
1551 	node = publ_token_obj_list;
1552 	while (publ_token_obj_list) {
1553 		CK_OBJECT_HANDLE handle;
1554 		CK_RV	    rc;
1555 
1556 		obj = (OBJECT *)node->data;
1557 
1558 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1559 		if (rc == CKR_OK) {
1560 			(void) object_mgr_invalidate_handle1(handle);
1561 		}
1562 		(void) object_free(obj);
1563 
1564 		next = node->next;
1565 		publ_token_obj_list = dlist_remove_node(
1566 		    publ_token_obj_list, node);
1567 		node = next;
1568 	}
1569 
1570 	node = priv_token_obj_list;
1571 
1572 	while (priv_token_obj_list) {
1573 		CK_OBJECT_HANDLE handle;
1574 		CK_RV	    rc;
1575 
1576 		obj = (OBJECT *)node->data;
1577 
1578 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1579 		if (rc == CKR_OK)
1580 			(void) object_mgr_invalidate_handle1(handle);
1581 		(void) object_free(obj);
1582 
1583 		next = node->next;
1584 		priv_token_obj_list = dlist_remove_node(
1585 		    priv_token_obj_list, node);
1586 		node = next;
1587 	}
1588 
1589 	(void) pthread_mutex_unlock(&obj_list_mutex);
1590 
1591 	return (TRUE);
1592 }
1593 
1594 CK_BBOOL
object_mgr_purge_private_token_objects(TSS_HCONTEXT hContext)1595 object_mgr_purge_private_token_objects(TSS_HCONTEXT hContext) {
1596 	OBJECT   * obj  = NULL;
1597 	DL_NODE  * node = NULL;
1598 	DL_NODE  * next = NULL;
1599 	CK_RV	rc;
1600 
1601 	rc = pthread_mutex_lock(&obj_list_mutex);
1602 	if (rc != CKR_OK)
1603 		return (FALSE);
1604 
1605 	node = priv_token_obj_list;
1606 	while (priv_token_obj_list) {
1607 		CK_OBJECT_HANDLE handle;
1608 		CK_RV	    rc;
1609 
1610 		obj = (OBJECT *)node->data;
1611 
1612 		rc = object_mgr_find_in_map2(hContext, obj, &handle);
1613 		if (rc == CKR_OK) {
1614 			(void) object_mgr_invalidate_handle1(handle);
1615 		}
1616 
1617 		(void) object_free(obj);
1618 
1619 		next = node->next;
1620 		priv_token_obj_list = dlist_remove_node(
1621 		    priv_token_obj_list, node);
1622 		node = next;
1623 	}
1624 
1625 	(void) pthread_mutex_unlock(&obj_list_mutex);
1626 
1627 	return (TRUE);
1628 }
1629 
1630 CK_RV
object_mgr_remove_from_map(CK_OBJECT_HANDLE handle)1631 object_mgr_remove_from_map(CK_OBJECT_HANDLE  handle)
1632 {
1633 	DL_NODE  *node = NULL;
1634 
1635 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
1636 		return (CKR_FUNCTION_FAILED);
1637 	}
1638 	node = object_map;
1639 	while (node) {
1640 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
1641 		if (map->handle == handle) {
1642 			object_map = dlist_remove_node(object_map, node);
1643 			free(map);
1644 			(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1645 			return (CKR_OK);
1646 		}
1647 		node = node->next;
1648 	}
1649 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
1650 
1651 	return (CKR_FUNCTION_FAILED);
1652 }
1653 
1654 CK_RV
object_mgr_restore_obj(CK_BYTE * data,OBJECT * oldObj)1655 object_mgr_restore_obj(CK_BYTE *data, OBJECT *oldObj)
1656 {
1657 	OBJECT    * obj  = NULL;
1658 	CK_BBOOL    priv;
1659 	CK_RV	rc;
1660 
1661 	if (! data) {
1662 		return (CKR_FUNCTION_FAILED);
1663 	}
1664 	if (oldObj != NULL) {
1665 		obj = oldObj;
1666 		rc = object_restore(data, &obj, TRUE);
1667 	} else {
1668 		rc = object_restore(data, &obj, FALSE);
1669 		if (rc == CKR_OK) {
1670 			priv = object_is_private(obj);
1671 
1672 			if (priv)
1673 				priv_token_obj_list = dlist_add_as_last(
1674 				    priv_token_obj_list, obj);
1675 			else
1676 				publ_token_obj_list = dlist_add_as_last(
1677 				    publ_token_obj_list, obj);
1678 
1679 			(void) XProcLock(xproclock);
1680 
1681 			if (priv) {
1682 				if (global_shm->priv_loaded == FALSE) {
1683 					if (global_shm->num_priv_tok_obj <
1684 					    MAX_TOK_OBJS)
1685 						(void) object_mgr_add_to_shm(
1686 						    obj);
1687 					else
1688 						rc = CKR_HOST_MEMORY;
1689 				}
1690 			} else {
1691 				if (global_shm->publ_loaded == FALSE) {
1692 					if (global_shm->num_publ_tok_obj <
1693 					    MAX_TOK_OBJS)
1694 						(void) object_mgr_add_to_shm(
1695 						    obj);
1696 					else
1697 						rc = CKR_HOST_MEMORY;
1698 				}
1699 			}
1700 
1701 			(void) XProcUnLock(xproclock);
1702 		}
1703 	}
1704 
1705 	// make the callers have to have the mutes
1706 	// to many grab it now.
1707 	return (rc);
1708 }
1709 
1710 CK_RV
object_mgr_set_attribute_values(SESSION * sess,CK_OBJECT_HANDLE handle,CK_ATTRIBUTE * pTemplate,CK_ULONG ulCount)1711 object_mgr_set_attribute_values(SESSION	   * sess,
1712 	CK_OBJECT_HANDLE    handle,
1713 	CK_ATTRIBUTE	* pTemplate,
1714 	CK_ULONG	    ulCount)
1715 {
1716 	OBJECT    * obj;
1717 	CK_BBOOL    sess_obj, priv_obj;
1718 	CK_BBOOL    modifiable;
1719 	CK_RV	rc;
1720 
1721 	if (! pTemplate) {
1722 		return (CKR_FUNCTION_FAILED);
1723 	}
1724 	rc = pthread_mutex_lock(&obj_list_mutex);
1725 	if (rc != CKR_OK)
1726 		return (CKR_FUNCTION_FAILED);
1727 
1728 	rc = object_mgr_find_in_map1(sess->hContext, handle, &obj);
1729 	if (rc != CKR_OK) {
1730 		(void) pthread_mutex_unlock(&obj_list_mutex);
1731 		return (CKR_OBJECT_HANDLE_INVALID);
1732 	}
1733 	(void) pthread_mutex_unlock(&obj_list_mutex);
1734 
1735 	modifiable = object_is_modifiable(obj);
1736 	sess_obj   = object_is_session_object(obj);
1737 	priv_obj   = object_is_private(obj);
1738 
1739 	if (! modifiable) {
1740 		return (CKR_ATTRIBUTE_READ_ONLY);
1741 	}
1742 	rc = check_object_access(sess, obj);
1743 	if (rc != CKR_OK)
1744 		return (rc);
1745 
1746 	rc = object_set_attribute_values(obj, pTemplate, ulCount);
1747 	if (rc != CKR_OK) {
1748 		return (rc);
1749 	}
1750 	if (! sess_obj) {
1751 		TOK_OBJ_ENTRY  *entry = NULL;
1752 		CK_ULONG	index;
1753 
1754 		obj->count_lo++;
1755 		if (obj->count_lo == 0)
1756 			obj->count_hi++;
1757 
1758 		rc = save_token_object(sess->hContext, obj);
1759 		if (rc != CKR_OK)
1760 			return (rc);
1761 
1762 		rc = XProcLock(xproclock);
1763 		if (rc != CKR_OK) {
1764 			return (rc);
1765 		}
1766 		if (priv_obj) {
1767 			rc = object_mgr_search_shm_for_obj(
1768 			    global_shm->priv_tok_objs,
1769 			    0, global_shm->num_priv_tok_obj - 1,
1770 			    obj, &index);
1771 
1772 			if (rc != CKR_OK) {
1773 				(void) XProcUnLock(xproclock);
1774 				return (rc);
1775 			}
1776 
1777 			entry = &global_shm->priv_tok_objs[index];
1778 		} else {
1779 			rc = object_mgr_search_shm_for_obj(
1780 			    global_shm->publ_tok_objs,
1781 			    0, global_shm->num_publ_tok_obj - 1,
1782 			    obj, &index);
1783 			if (rc != CKR_OK) {
1784 				(void) XProcUnLock(xproclock);
1785 				return (rc);
1786 			}
1787 
1788 			entry = &global_shm->publ_tok_objs[index];
1789 		}
1790 
1791 		entry->count_lo = obj->count_lo;
1792 		entry->count_hi = obj->count_hi;
1793 
1794 		(void) XProcUnLock(xproclock);
1795 	}
1796 
1797 	return (rc);
1798 }
1799 
1800 CK_RV
object_mgr_add_to_shm(OBJECT * obj)1801 object_mgr_add_to_shm(OBJECT *obj)
1802 {
1803 	TOK_OBJ_ENTRY  * entry  = NULL;
1804 	CK_BBOOL	 priv;
1805 
1806 	priv = object_is_private(obj);
1807 
1808 	if (priv)
1809 		entry = &global_shm->priv_tok_objs[
1810 		    global_shm->num_priv_tok_obj];
1811 	else
1812 		entry = &global_shm->publ_tok_objs[
1813 		    global_shm->num_publ_tok_obj];
1814 
1815 	entry->deleted  = FALSE;
1816 	entry->count_lo = 0;
1817 	entry->count_hi = 0;
1818 	(void) memcpy(entry->name, obj->name, 8);
1819 
1820 	if (priv) {
1821 		global_shm->num_priv_tok_obj++;
1822 	} else {
1823 		global_shm->num_publ_tok_obj++;
1824 	}
1825 
1826 	return (CKR_OK);
1827 }
1828 
1829 CK_RV
object_mgr_del_from_shm(OBJECT * obj)1830 object_mgr_del_from_shm(OBJECT *obj)
1831 {
1832 	CK_ULONG	  index, count;
1833 	CK_BBOOL	  priv;
1834 	CK_RV		rc;
1835 
1836 	priv = object_is_private(obj);
1837 
1838 	if (priv) {
1839 		rc = object_mgr_search_shm_for_obj(global_shm->priv_tok_objs,
1840 		    0, global_shm->num_priv_tok_obj - 1, obj, &index);
1841 		if (rc != CKR_OK) {
1842 			return (CKR_FUNCTION_FAILED);
1843 		}
1844 
1845 		global_shm->num_priv_tok_obj--;
1846 		if (index > global_shm->num_priv_tok_obj) {
1847 			count = index - global_shm->num_priv_tok_obj;
1848 		} else {
1849 			count = global_shm->num_priv_tok_obj - index;
1850 		}
1851 
1852 		if (count > 0) {
1853 			(void) memcpy((char *)&global_shm->priv_tok_objs[index],
1854 			    (char *)&global_shm->priv_tok_objs[index + 1],
1855 			    sizeof (TOK_OBJ_ENTRY) * count);
1856 
1857 			(void) memset((char *)&global_shm->priv_tok_objs[
1858 			    global_shm->num_priv_tok_obj + 1], 0,
1859 			    sizeof (TOK_OBJ_ENTRY));
1860 		} else {
1861 			(void) memset((char *)&global_shm->priv_tok_objs[
1862 			    global_shm->num_priv_tok_obj], 0,
1863 			    sizeof (TOK_OBJ_ENTRY));
1864 		}
1865 	} else {
1866 		rc = object_mgr_search_shm_for_obj(global_shm->publ_tok_objs,
1867 		    0, global_shm->num_publ_tok_obj - 1, obj, &index);
1868 		if (rc != CKR_OK) {
1869 			return (CKR_FUNCTION_FAILED);
1870 		}
1871 		global_shm->num_publ_tok_obj--;
1872 
1873 		if (index > global_shm->num_publ_tok_obj) {
1874 			count = index - global_shm->num_publ_tok_obj;
1875 		} else {
1876 			count = global_shm->num_publ_tok_obj - index;
1877 		}
1878 
1879 		if (count > 0) {
1880 			(void) memcpy((char *)&global_shm->publ_tok_objs[index],
1881 			    (char *)&global_shm->publ_tok_objs[index + 1],
1882 			    sizeof (TOK_OBJ_ENTRY) * count);
1883 			(void) memset((char *)&global_shm->publ_tok_objs[
1884 			    global_shm->num_publ_tok_obj + 1], 0,
1885 			    sizeof (TOK_OBJ_ENTRY));
1886 		} else {
1887 			(void) memset((char *)&global_shm->publ_tok_objs[
1888 			    global_shm->num_publ_tok_obj], 0,
1889 			    sizeof (TOK_OBJ_ENTRY));
1890 		}
1891 	}
1892 
1893 	return (CKR_OK);
1894 }
1895 
1896 static CK_RV
object_mgr_check_shm(TSS_HCONTEXT hContext,OBJECT * obj)1897 object_mgr_check_shm(TSS_HCONTEXT hContext, OBJECT *obj)
1898 {
1899 	TOK_OBJ_ENTRY   * entry = NULL;
1900 	CK_BBOOL	  priv;
1901 	CK_ULONG	  index;
1902 	CK_RV		rc;
1903 
1904 
1905 	priv = object_is_private(obj);
1906 
1907 	if (priv) {
1908 		rc = object_mgr_search_shm_for_obj(
1909 		    global_shm->priv_tok_objs,
1910 		    0, global_shm->num_priv_tok_obj - 1, obj, &index);
1911 		if (rc != CKR_OK) {
1912 			return (CKR_FUNCTION_FAILED);
1913 		}
1914 		entry = &global_shm->priv_tok_objs[index];
1915 	} else {
1916 		rc = object_mgr_search_shm_for_obj(
1917 		    global_shm->publ_tok_objs,
1918 		    0, global_shm->num_publ_tok_obj - 1, obj, &index);
1919 		if (rc != CKR_OK) {
1920 			return (CKR_FUNCTION_FAILED);
1921 		}
1922 		entry = &global_shm->publ_tok_objs[index];
1923 	}
1924 
1925 	if ((obj->count_hi == entry->count_hi) &&
1926 	    (obj->count_lo == entry->count_lo))
1927 		return (CKR_OK);
1928 	rc = reload_token_object(hContext, obj);
1929 	return (rc);
1930 }
1931 
1932 /*ARGSUSED*/
1933 static CK_RV
object_mgr_search_shm_for_obj(TOK_OBJ_ENTRY * obj_list,CK_ULONG lo,CK_ULONG hi,OBJECT * obj,CK_ULONG * index)1934 object_mgr_search_shm_for_obj(
1935 	TOK_OBJ_ENTRY *obj_list,
1936 	CK_ULONG lo,
1937 	CK_ULONG hi,
1938 	OBJECT *obj,
1939 	CK_ULONG *index)
1940 {
1941 	CK_ULONG idx;
1942 	if (obj->index == 0) {
1943 		for (idx = lo; idx <= hi; idx++) {
1944 			if (memcmp(obj->name, obj_list[idx].name, 8) == 0) {
1945 				*index = idx;
1946 				obj->index = idx;
1947 				return (CKR_OK);
1948 			}
1949 		}
1950 	} else {
1951 		if (memcmp(obj->name, obj_list[obj->index].name, 8) == 0) {
1952 			*index = obj->index;
1953 			return (CKR_OK);
1954 		} else {
1955 			for (idx = lo; idx <= hi; idx++) {
1956 				if (memcmp(obj->name,
1957 				    obj_list[idx].name, 8) == 0) {
1958 					*index = idx;
1959 					obj->index = idx;
1960 					return (CKR_OK);
1961 				}
1962 			}
1963 		}
1964 	}
1965 	return (CKR_FUNCTION_FAILED);
1966 }
1967 
1968 static CK_RV
object_mgr_update_publ_tok_obj_from_shm(TSS_HCONTEXT hContext)1969 object_mgr_update_publ_tok_obj_from_shm(TSS_HCONTEXT hContext)
1970 {
1971 	DL_NODE	   * node = NULL;
1972 	DL_NODE	   * next = NULL;
1973 	TOK_OBJ_ENTRY	* te   = NULL;
1974 	OBJECT	    * obj  = NULL;
1975 	CK_OBJECT_HANDLE    handle;
1976 	CK_ULONG	    index;
1977 	int		 val;
1978 	CK_RV		rc;
1979 
1980 	node  = publ_token_obj_list;
1981 	index = 0;
1982 
1983 	while ((node != NULL) && (index < global_shm->num_publ_tok_obj)) {
1984 		te = &global_shm->publ_tok_objs[index];
1985 		obj = (OBJECT *)node->data;
1986 
1987 		val = memcmp(obj->name, te->name, 8);
1988 
1989 		// 3 cases:
1990 		//    1) object in local list but not in the global list,
1991 		//	need to remove from local list
1992 		//    2) object in both lists, need to compare counters
1993 		//	and update as needed
1994 		//    3) object in global list but not in the local list,
1995 		//	need to add the object here.
1996 		//
1997 		if (val < 0) {
1998 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
1999 			if (rc == CKR_OK) {
2000 				(void) object_mgr_remove_from_map(handle);
2001 			}
2002 			(void) object_free(obj);
2003 
2004 			next = node->next;
2005 			publ_token_obj_list = dlist_remove_node(
2006 			    publ_token_obj_list, node);
2007 
2008 		} else if (val == 0) {
2009 			if ((te->count_hi != obj->count_hi) ||
2010 			    (te->count_lo != obj->count_lo)) {
2011 				(void) reload_token_object(hContext, obj);
2012 				obj->count_hi = te->count_hi;
2013 				obj->count_lo = te->count_lo;
2014 			}
2015 
2016 			next = node->next;
2017 			index++;
2018 		} else {
2019 			DL_NODE  *new_node = NULL;
2020 			OBJECT   *new_obj  = NULL;
2021 
2022 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2023 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2024 
2025 			(void) memcpy(new_obj->name, te->name, 8);
2026 			(void) reload_token_object(hContext, new_obj);
2027 
2028 			new_node = (DL_NODE *)malloc(sizeof (DL_NODE));
2029 			new_node->data = new_obj;
2030 
2031 			new_node->next = node->next;
2032 			node->next	= new_node;
2033 			new_node->prev = node;
2034 
2035 			next = new_node->next;
2036 			index++;
2037 		}
2038 
2039 		node = next;
2040 	}
2041 
2042 	if ((node == NULL) && (index < global_shm->num_publ_tok_obj)) {
2043 		OBJECT   *new_obj  = NULL;
2044 		unsigned int i;
2045 
2046 		for (i = index; i < global_shm->num_publ_tok_obj; i++) {
2047 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2048 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2049 
2050 			te = &global_shm->publ_tok_objs[index];
2051 
2052 			(void) memcpy(new_obj->name, te->name, 8);
2053 			(void) reload_token_object(hContext, new_obj);
2054 
2055 			publ_token_obj_list = dlist_add_as_last(
2056 			    publ_token_obj_list, new_obj);
2057 		}
2058 	} else if ((node != NULL) && (index >= global_shm->num_publ_tok_obj)) {
2059 		while (node) {
2060 			obj = (OBJECT *)node->data;
2061 
2062 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2063 			if (rc == CKR_OK) {
2064 				(void) object_mgr_remove_from_map(handle);
2065 			}
2066 			(void) object_free(obj);
2067 
2068 			next = node->next;
2069 			publ_token_obj_list = dlist_remove_node(
2070 			    publ_token_obj_list, node);
2071 
2072 			node = next;
2073 		}
2074 	}
2075 
2076 	return (CKR_OK);
2077 }
2078 
2079 static CK_RV
object_mgr_update_priv_tok_obj_from_shm(TSS_HCONTEXT hContext)2080 object_mgr_update_priv_tok_obj_from_shm(TSS_HCONTEXT hContext)
2081 {
2082 	DL_NODE	   * node = NULL;
2083 	DL_NODE	   * next = NULL;
2084 	TOK_OBJ_ENTRY	* te   = NULL;
2085 	OBJECT	    * obj  = NULL;
2086 	CK_OBJECT_HANDLE    handle;
2087 	CK_ULONG	    index;
2088 	int		 val;
2089 	CK_RV		rc;
2090 
2091 	node  = priv_token_obj_list;
2092 	index = 0;
2093 
2094 	if (! (global_login_state == CKS_RW_USER_FUNCTIONS ||
2095 	    global_login_state == CKS_RO_USER_FUNCTIONS)) {
2096 		return (CKR_OK);
2097 	}
2098 
2099 	while ((node != NULL) && (index < global_shm->num_priv_tok_obj)) {
2100 		te = &global_shm->priv_tok_objs[index];
2101 		obj = (OBJECT *)node->data;
2102 
2103 		val = memcmp(obj->name, te->name, 8);
2104 
2105 		if (val < 0) {
2106 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2107 			if (rc == CKR_OK) {
2108 				(void) object_mgr_remove_from_map(handle);
2109 			}
2110 			(void) object_free(obj);
2111 
2112 			next = node->next;
2113 			priv_token_obj_list = dlist_remove_node(
2114 			    priv_token_obj_list, node);
2115 
2116 		} else if (val == 0) {
2117 			if ((te->count_hi != obj->count_hi) ||
2118 			    (te->count_lo != obj->count_lo)) {
2119 				(void) reload_token_object(hContext, obj);
2120 				obj->count_hi = te->count_hi;
2121 				obj->count_lo = te->count_lo;
2122 			}
2123 
2124 			next = node->next;
2125 			index++;
2126 		} else {
2127 			DL_NODE  *new_node = NULL;
2128 			OBJECT   *new_obj  = NULL;
2129 
2130 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2131 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2132 
2133 			(void) memcpy(new_obj->name, te->name, 8);
2134 			(void) reload_token_object(hContext, new_obj);
2135 
2136 			new_node = (DL_NODE *)malloc(sizeof (DL_NODE));
2137 			new_node->data = new_obj;
2138 
2139 			new_node->next = node->next;
2140 			node->next	= new_node;
2141 			new_node->prev = node;
2142 
2143 			next = new_node->next;
2144 			index++;
2145 		}
2146 
2147 		node = next;
2148 	}
2149 
2150 	if ((node == NULL) && (index < global_shm->num_priv_tok_obj)) {
2151 		OBJECT   *new_obj  = NULL;
2152 		unsigned int i;
2153 
2154 		for (i = index; i < global_shm->num_priv_tok_obj; i++) {
2155 			new_obj = (OBJECT *)malloc(sizeof (OBJECT));
2156 			(void) memset(new_obj, 0x0, sizeof (OBJECT));
2157 
2158 			te = &global_shm->priv_tok_objs[index];
2159 
2160 			(void) memcpy(new_obj->name, te->name, 8);
2161 			(void) reload_token_object(hContext, new_obj);
2162 
2163 			priv_token_obj_list = dlist_add_as_last(
2164 			    priv_token_obj_list, new_obj);
2165 		}
2166 	} else if ((node != NULL) && (index >= global_shm->num_priv_tok_obj)) {
2167 		while (node) {
2168 			obj = (OBJECT *)node->data;
2169 
2170 			rc = object_mgr_find_in_map2(hContext, obj, &handle);
2171 			if (rc == CKR_OK) {
2172 				(void) object_mgr_remove_from_map(handle);
2173 			}
2174 			(void) object_free(obj);
2175 
2176 			next = node->next;
2177 			priv_token_obj_list = dlist_remove_node(
2178 			    priv_token_obj_list, node);
2179 
2180 			node = next;
2181 		}
2182 	}
2183 
2184 	return (CKR_OK);
2185 }
2186 
2187 static CK_RV
object_mgr_update_from_shm(TSS_HCONTEXT hContext)2188 object_mgr_update_from_shm(TSS_HCONTEXT hContext)
2189 {
2190 	(void) object_mgr_update_publ_tok_obj_from_shm(hContext);
2191 	(void) object_mgr_update_priv_tok_obj_from_shm(hContext);
2192 
2193 	return (CKR_OK);
2194 }
2195 
2196 /*ARGSUSED*/
2197 CK_BBOOL
object_mgr_purge_map(SESSION * sess,SESS_OBJ_TYPE type)2198 object_mgr_purge_map(
2199 	SESSION	*sess,
2200 	SESS_OBJ_TYPE type)
2201 {
2202 	DL_NODE *node = NULL;
2203 	DL_NODE *next = NULL;
2204 
2205 	if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
2206 		return (CKR_FUNCTION_FAILED);
2207 	}
2208 	node = object_map;
2209 	while (node) {
2210 		OBJECT_MAP *map = (OBJECT_MAP *)node->data;
2211 		OBJECT	*obj = (OBJECT *)map->ptr;
2212 		next = node->next;
2213 		if (type == PRIVATE) {
2214 			if (object_is_private(obj)) {
2215 				object_map = dlist_remove_node(
2216 				    object_map, node);
2217 				free(map);
2218 			}
2219 		}
2220 		if (type == PUBLIC) {
2221 			if (object_is_public(obj)) {
2222 				object_map = dlist_remove_node(
2223 				    object_map, node);
2224 				free(map);
2225 			}
2226 		}
2227 		node = next;
2228 	}
2229 	(void) pthread_rwlock_unlock(&obj_list_rw_mutex);
2230 
2231 	return (TRUE);
2232 }
2233