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
296SESSION *
297session_mgr_find(CK_SESSION_HANDLE handle)
298{
299	DL_NODE  * node   = NULL;
300	SESSION  * result = NULL;
301	CK_RV	rc;
302
303	rc = pthread_mutex_lock(&sess_list_mutex);
304	if (rc != CKR_OK) {
305		return (NULL);
306	}
307	node = sess_list;
308
309	while (node) {
310		SESSION *s = (SESSION *)node->data;
311
312		if (s->handle == handle) {
313			result = s;
314			break;
315		}
316
317		node = node->next;
318	}
319
320	(void) pthread_mutex_unlock(&sess_list_mutex);
321	return (result);
322}
323
324
325/*
326 * session_mgr_new()
327 *
328 * creates a new session structure and adds it to the process's list
329 * of sessions
330 *
331 * Args:  CK_ULONG	flags : session flags		   (INPUT)
332 *	SESSION **	sess : new session pointer		(OUTPUT)
333 *
334 * Returns:  CK_RV
335 */
336CK_RV
337session_mgr_new(CK_ULONG flags, SESSION **sess)
338{
339	SESSION  * new_session  = NULL;
340	SESSION  * s	    = NULL;
341	DL_NODE  * node	 = NULL;
342	CK_BBOOL   user_session = FALSE;
343	CK_BBOOL   so_session   = FALSE;
344	CK_BBOOL   pkcs_locked  = TRUE;
345	CK_BBOOL   sess_locked  = TRUE;
346	CK_RV	rc;
347
348	new_session = (SESSION *)malloc(sizeof (SESSION));
349	if (! new_session) {
350		rc = CKR_HOST_MEMORY;
351		goto done;
352	}
353
354	(void) memset(new_session, 0x0, sizeof (SESSION));
355
356	rc = pthread_mutex_lock(&pkcs_mutex);
357	if (rc != CKR_OK) {
358		return (rc);
359	}
360	pkcs_locked = TRUE;
361
362	do {
363		s = session_mgr_find(next_session_handle);
364		if (s != NULL)
365			next_session_handle++;
366		else
367			new_session->handle = next_session_handle++;
368	} while (s != NULL);
369
370	(void) pthread_mutex_unlock(&pkcs_mutex);
371	pkcs_locked = FALSE;
372
373
374	new_session->session_info.slotID	= 1;
375	new_session->session_info.flags	 = flags;
376	new_session->session_info.ulDeviceError = 0;
377
378	rc = pthread_mutex_lock(&sess_list_mutex);
379	if (rc != CKR_OK) {
380		return (rc);
381	}
382	sess_locked = TRUE;
383
384	node = sess_list;
385	while (node) {
386		SESSION *s = (SESSION *)node->data;
387		if (s->session_info.state == CKS_RW_SO_FUNCTIONS) {
388			so_session = TRUE;
389			break;
390		}
391
392		if ((s->session_info.state == CKS_RO_USER_FUNCTIONS) ||
393		    (s->session_info.state == CKS_RW_USER_FUNCTIONS)) {
394			user_session = TRUE;
395			break;
396		}
397
398		node = node->next;
399	}
400
401	if (global_login_state == CKS_RW_SO_FUNCTIONS) {
402		so_session = TRUE;
403	}
404	if ((global_login_state == CKS_RO_USER_FUNCTIONS) ||
405	    (global_login_state == CKS_RW_USER_FUNCTIONS)) {
406		user_session = TRUE;
407	}
408
409	if (user_session) {
410		if (new_session->session_info.flags & CKF_RW_SESSION)
411			new_session->session_info.state = CKS_RW_USER_FUNCTIONS;
412		else
413			new_session->session_info.state = CKS_RO_USER_FUNCTIONS;
414		} else if (so_session) {
415
416		new_session->session_info.state = CKS_RW_SO_FUNCTIONS;
417	} else {
418		if (new_session->session_info.flags & CKF_RW_SESSION)
419			new_session->session_info.state = CKS_RW_PUBLIC_SESSION;
420		else
421			new_session->session_info.state = CKS_RO_PUBLIC_SESSION;
422	}
423
424	sess_list = dlist_add_as_first(sess_list, new_session);
425	*sess = new_session;
426
427	done:
428	if (pkcs_locked)
429		(void) pthread_mutex_unlock(&pkcs_mutex);
430
431	if (sess_locked)
432		(void) pthread_mutex_unlock(&sess_list_mutex);
433
434	if (rc != CKR_OK && new_session != NULL) {
435		free(new_session);
436	}
437	return (rc);
438}
439
440CK_BBOOL
441session_mgr_so_session_exists(void)
442{
443	DL_NODE *node = NULL;
444	CK_RV    rc;
445
446	rc = pthread_mutex_lock(&sess_list_mutex);
447	if (rc != CKR_OK) {
448		return (rc);
449	}
450	node = sess_list;
451	while (node) {
452		SESSION *s = (SESSION *)node->data;
453		if (s->session_info.state == CKS_RW_SO_FUNCTIONS) {
454			rc = TRUE;
455			goto done;
456		}
457
458		node = node->next;
459	}
460
461	rc = FALSE;
462
463done:
464	(void) pthread_mutex_unlock(&sess_list_mutex);
465	return (rc);
466}
467
468CK_BBOOL
469session_mgr_user_session_exists(void)
470{
471	DL_NODE *node = NULL;
472	CK_RV    rc;
473
474	rc = pthread_mutex_lock(&sess_list_mutex);
475	if (rc != CKR_OK) {
476		return (rc);
477	}
478	node = sess_list;
479	while (node) {
480		SESSION *s = (SESSION *)node->data;
481		if ((s->session_info.state == CKS_RO_USER_FUNCTIONS) ||
482		    (s->session_info.state == CKS_RW_USER_FUNCTIONS)) {
483			rc = TRUE;
484			goto done;
485		}
486
487		node = node->next;
488	}
489
490	rc = FALSE;
491
492done:
493	(void) pthread_mutex_unlock(&sess_list_mutex);
494	return (rc);
495}
496
497CK_BBOOL
498session_mgr_public_session_exists(void)
499{
500	DL_NODE *node = NULL;
501	CK_RV    rc;
502
503	rc = pthread_mutex_lock(&sess_list_mutex);
504	if (rc != CKR_OK) {
505		return (rc);
506	}
507	node = sess_list;
508	while (node) {
509		SESSION *s = (SESSION *)node->data;
510		if ((s->session_info.state == CKS_RO_PUBLIC_SESSION) ||
511		    (s->session_info.state == CKS_RW_PUBLIC_SESSION)) {
512			rc = TRUE;
513			goto done;
514		}
515
516		node = node->next;
517	}
518
519	rc = FALSE;
520
521done:
522	(void) pthread_mutex_unlock(&sess_list_mutex);
523	return (rc);
524}
525
526CK_BBOOL
527session_mgr_readonly_exists(void)
528{
529	DL_NODE *node = NULL;
530	CK_RV    rc;
531
532	rc = pthread_mutex_lock(&sess_list_mutex);
533	if (rc != CKR_OK) {
534		return (rc);
535	}
536	node = sess_list;
537	while (node) {
538		SESSION *s = (SESSION *)node->data;
539		if ((s->session_info.flags & CKF_RW_SESSION) == 0) {
540			rc = TRUE;
541			goto done;
542		}
543
544		node = node->next;
545	}
546
547	rc = FALSE;
548
549done:
550	(void) pthread_mutex_unlock(&sess_list_mutex);
551	return (rc);
552}
553
554CK_RV
555session_mgr_close_session(SESSION *sess)
556{
557	DL_NODE  * node = NULL;
558	CK_RV	rc = CKR_OK;
559
560	if (! sess)
561		return (FALSE);
562	rc = pthread_mutex_lock(&sess_list_mutex);
563	if (rc != CKR_OK) {
564		return (CKR_FUNCTION_FAILED);
565	}
566	node = dlist_find(sess_list, sess);
567	if (! node) {
568		rc = CKR_FUNCTION_FAILED;
569		goto done;
570	}
571
572	(void) object_mgr_purge_session_objects(sess, ALL);
573
574	if (sess->find_list)
575		free(sess->find_list);
576
577	if (sess->encr_ctx.context)
578		free(sess->encr_ctx.context);
579
580	if (sess->encr_ctx.mech.pParameter)
581		free(sess->encr_ctx.mech.pParameter);
582
583	if (sess->decr_ctx.context)
584		free(sess->decr_ctx.context);
585
586	if (sess->decr_ctx.mech.pParameter)
587		free(sess->decr_ctx.mech.pParameter);
588
589	if (sess->digest_ctx.context.ref)
590		free(sess->digest_ctx.context.ref);
591
592	if (sess->digest_ctx.mech.pParameter)
593		free(sess->digest_ctx.mech.pParameter);
594
595	if (sess->sign_ctx.context)
596		free(sess->sign_ctx.context);
597
598	if (sess->sign_ctx.mech.pParameter)
599		free(sess->sign_ctx.mech.pParameter);
600
601	if (sess->verify_ctx.context)
602		free(sess->verify_ctx.context);
603
604	if (sess->verify_ctx.mech.pParameter)
605		free(sess->verify_ctx.mech.pParameter);
606
607	if (sess->hContext)
608		(void) Tspi_Context_Close(sess->hContext);
609
610	free(sess);
611
612	sess_list = dlist_remove_node(sess_list, node);
613
614	if (sess_list == NULL) {
615		TSS_HCONTEXT hContext;
616		if (open_tss_context(&hContext) == 0) {
617			(void) object_mgr_purge_private_token_objects(hContext);
618			(void) Tspi_Context_Close(hContext);
619		}
620
621		global_login_state = 0;
622
623		(void) pthread_mutex_lock(&obj_list_mutex);
624		(void) object_mgr_purge_map((SESSION *)0xFFFF, PRIVATE);
625		(void) pthread_mutex_unlock(&obj_list_mutex);
626	}
627
628	done:
629	(void) pthread_mutex_unlock(&sess_list_mutex);
630	return (rc);
631}
632
633// session_mgr_close_all_sessions()
634//
635// removes all sessions from the specified process
636//
637CK_RV
638session_mgr_close_all_sessions(void)
639{
640	CK_RV   rc = CKR_OK;
641
642	rc = pthread_mutex_lock(&sess_list_mutex);
643	if (rc != CKR_OK) {
644		return (CKR_FUNCTION_FAILED);
645	}
646	while (sess_list) {
647		SESSION *sess = (SESSION *)sess_list->data;
648
649		(void) object_mgr_purge_session_objects(sess, ALL);
650
651		if (sess->find_list)
652			free(sess->find_list);
653
654		if (sess->encr_ctx.context)
655			free(sess->encr_ctx.context);
656
657		if (sess->encr_ctx.mech.pParameter)
658			free(sess->encr_ctx.mech.pParameter);
659
660		if (sess->decr_ctx.context)
661			free(sess->decr_ctx.context);
662
663		if (sess->decr_ctx.mech.pParameter)
664			free(sess->decr_ctx.mech.pParameter);
665
666		if (sess->digest_ctx.context.ref)
667			free(sess->digest_ctx.context.ref);
668
669		if (sess->digest_ctx.mech.pParameter)
670			free(sess->digest_ctx.mech.pParameter);
671
672		if (sess->sign_ctx.context)
673			free(sess->sign_ctx.context);
674
675		if (sess->sign_ctx.mech.pParameter)
676			free(sess->sign_ctx.mech.pParameter);
677
678		if (sess->verify_ctx.context)
679			free(sess->verify_ctx.context);
680
681		if (sess->verify_ctx.mech.pParameter)
682			free(sess->verify_ctx.mech.pParameter);
683
684		if (sess->hContext)
685			(void) Tspi_Context_Close(sess->hContext);
686
687		free(sess);
688
689		sess_list = dlist_remove_node(sess_list, sess_list);
690	}
691
692	(void) pthread_mutex_unlock(&sess_list_mutex);
693	return (CKR_OK);
694}
695
696// session_mgr_login_all()
697//
698// changes the login status of all sessions in the token
699//
700// Arg:  CK_USER_TYPE  user_type : USER or SO
701//
702CK_RV
703session_mgr_login_all(CK_USER_TYPE user_type) {
704	DL_NODE  * node = NULL;
705	CK_RV	rc = CKR_OK;
706
707	rc = pthread_mutex_lock(&sess_list_mutex);
708	if (rc != CKR_OK) {
709		return (CKR_FUNCTION_FAILED);
710	}
711	node = sess_list;
712	while (node) {
713		SESSION *s = (SESSION *)node->data;
714
715		if (s->session_info.flags & CKF_RW_SESSION) {
716			if (user_type == CKU_USER)
717				s->session_info.state = CKS_RW_USER_FUNCTIONS;
718			else
719				s->session_info.state = CKS_RW_SO_FUNCTIONS;
720		} else {
721			if (user_type == CKU_USER)
722				s->session_info.state = CKS_RO_USER_FUNCTIONS;
723		}
724
725		global_login_state = s->session_info.state;
726		node = node->next;
727	}
728
729	(void) pthread_mutex_unlock(&sess_list_mutex);
730	return (CKR_OK);
731}
732
733CK_RV
734session_mgr_logout_all(void) {
735	DL_NODE  * node = NULL;
736	SESSION  * s    = NULL;
737	CK_RV	rc   = CKR_OK;
738
739	rc = pthread_mutex_lock(&sess_list_mutex);
740	if (rc != CKR_OK) {
741		return (CKR_FUNCTION_FAILED);
742	}
743	node = sess_list;
744	while (node) {
745		s = (SESSION *)node->data;
746
747		(void) object_mgr_purge_session_objects(s, PRIVATE);
748
749		if (s->session_info.flags & CKF_RW_SESSION)
750			s->session_info.state = CKS_RW_PUBLIC_SESSION;
751		else
752			s->session_info.state = CKS_RO_PUBLIC_SESSION;
753
754		global_login_state = s->session_info.state; // SAB
755
756		node = node->next;
757	}
758
759	(void) pthread_mutex_unlock(&sess_list_mutex);
760	return (CKR_OK);
761}
762
763CK_RV
764session_mgr_get_op_state(SESSION   *sess,
765	CK_BBOOL   length_only,
766	CK_BYTE   *data,
767	CK_ULONG  *data_len) {
768	OP_STATE_DATA  *op_data = NULL;
769	CK_ULONG	op_data_len = 0;
770	CK_ULONG	offset;
771	void		*dptr = data;
772
773	if (! sess) {
774		return (CKR_FUNCTION_FAILED);
775	}
776
777	if (sess->find_active == TRUE) {
778		return (CKR_STATE_UNSAVEABLE);
779	}
780	if (sess->encr_ctx.active == TRUE) {
781		if (op_data != NULL) {
782			return (CKR_STATE_UNSAVEABLE);
783		}
784		op_data_len = sizeof (OP_STATE_DATA)	+
785		    sizeof (ENCR_DECR_CONTEXT)  +
786		    sess->encr_ctx.context_len +
787		    sess->encr_ctx.mech.ulParameterLen;
788
789		if (length_only == FALSE) {
790			op_data = (OP_STATE_DATA *)dptr;
791
792			op_data->data_len = op_data_len -
793			    sizeof (OP_STATE_DATA);
794			op_data->session_state = sess->session_info.state;
795			op_data->active_operation = STATE_ENCR;
796
797			offset = sizeof (OP_STATE_DATA);
798
799			(void) (void) memcpy((CK_BYTE *)op_data + offset,
800			&sess->encr_ctx,
801			sizeof (ENCR_DECR_CONTEXT));
802
803			offset += sizeof (ENCR_DECR_CONTEXT);
804
805			if (sess->encr_ctx.context_len != 0) {
806				(void) memcpy((CK_BYTE *)op_data + offset,
807				sess->encr_ctx.context,
808				sess->encr_ctx.context_len);
809
810				offset += sess->encr_ctx.context_len;
811			}
812
813			if (sess->encr_ctx.mech.ulParameterLen != 0) {
814				(void) memcpy((CK_BYTE *)op_data + offset,
815				sess->encr_ctx.mech.pParameter,
816				sess->encr_ctx.mech.ulParameterLen);
817			}
818		}
819	}
820
821	if (sess->decr_ctx.active == TRUE) {
822		if (op_data != NULL) {
823			return (CKR_STATE_UNSAVEABLE);
824		}
825		op_data_len = sizeof (OP_STATE_DATA)	+
826		    sizeof (ENCR_DECR_CONTEXT)  +
827		    sess->decr_ctx.context_len +
828		    sess->decr_ctx.mech.ulParameterLen;
829
830		if (length_only == FALSE) {
831			op_data = (OP_STATE_DATA *)dptr;
832
833			op_data->data_len = op_data_len -
834			    sizeof (OP_STATE_DATA);
835			op_data->session_state    = sess->session_info.state;
836			op_data->active_operation = STATE_DECR;
837
838			offset = sizeof (OP_STATE_DATA);
839
840			(void) memcpy((CK_BYTE *)op_data + offset,
841			&sess->decr_ctx,
842			sizeof (ENCR_DECR_CONTEXT));
843
844			offset += sizeof (ENCR_DECR_CONTEXT);
845
846			if (sess->decr_ctx.context_len != 0) {
847				(void) memcpy((CK_BYTE *)op_data + offset,
848				sess->decr_ctx.context,
849				sess->decr_ctx.context_len);
850
851				offset += sess->decr_ctx.context_len;
852			}
853
854			if (sess->decr_ctx.mech.ulParameterLen != 0) {
855				(void) memcpy((CK_BYTE *)op_data + offset,
856				sess->decr_ctx.mech.pParameter,
857				sess->decr_ctx.mech.ulParameterLen);
858			}
859		}
860	}
861
862	if (sess->digest_ctx.active == TRUE) {
863		if (op_data != NULL) {
864			return (CKR_STATE_UNSAVEABLE);
865		}
866		op_data_len = sizeof (OP_STATE_DATA) +
867		    sizeof (DIGEST_CONTEXT) +
868		    sess->digest_ctx.context_len +
869		    sess->digest_ctx.mech.ulParameterLen;
870
871		if (length_only == FALSE) {
872			op_data = (OP_STATE_DATA *)dptr;
873
874			op_data->data_len = op_data_len -
875			    sizeof (OP_STATE_DATA);
876			op_data->session_state    = sess->session_info.state;
877			op_data->active_operation = STATE_DIGEST;
878
879			offset = sizeof (OP_STATE_DATA);
880
881			(void) memcpy((CK_BYTE *)op_data + offset,
882			    &sess->digest_ctx, sizeof (DIGEST_CONTEXT));
883
884			offset += sizeof (DIGEST_CONTEXT);
885
886			if (sess->digest_ctx.context_len != 0) {
887				(void) memcpy((CK_BYTE *)op_data + offset,
888				    sess->digest_ctx.context.ref,
889				    sess->digest_ctx.context_len);
890
891				offset += sess->digest_ctx.context_len;
892			}
893
894			if (sess->digest_ctx.mech.ulParameterLen != 0) {
895				(void) memcpy((CK_BYTE *)op_data + offset,
896				    sess->digest_ctx.mech.pParameter,
897				    sess->digest_ctx.mech.ulParameterLen);
898			}
899		}
900	}
901
902	if (sess->sign_ctx.active == TRUE) {
903		if (op_data != NULL) {
904			return (CKR_STATE_UNSAVEABLE);
905		}
906		op_data_len = sizeof (OP_STATE_DATA) +
907		    sizeof (SIGN_VERIFY_CONTEXT) +
908		    sess->sign_ctx.context_len +
909		    sess->sign_ctx.mech.ulParameterLen;
910
911		if (length_only == FALSE) {
912			op_data = (OP_STATE_DATA *)dptr;
913
914			op_data->data_len = op_data_len -
915			    sizeof (OP_STATE_DATA);
916			op_data->session_state    = sess->session_info.state;
917			op_data->active_operation = STATE_SIGN;
918
919			offset = sizeof (OP_STATE_DATA);
920
921			(void) memcpy((CK_BYTE *)op_data + offset,
922			    &sess->sign_ctx, sizeof (SIGN_VERIFY_CONTEXT));
923
924			offset += sizeof (SIGN_VERIFY_CONTEXT);
925
926			if (sess->sign_ctx.context_len != 0) {
927				(void) memcpy((CK_BYTE *)op_data + offset,
928				    sess->sign_ctx.context,
929				    sess->sign_ctx.context_len);
930
931				offset += sess->sign_ctx.context_len;
932			}
933
934			if (sess->sign_ctx.mech.ulParameterLen != 0) {
935				(void) memcpy((CK_BYTE *)op_data + offset,
936				    sess->sign_ctx.mech.pParameter,
937				    sess->sign_ctx.mech.ulParameterLen);
938			}
939		}
940	}
941
942	if (sess->verify_ctx.active == TRUE) {
943		if (op_data != NULL) {
944			return (CKR_STATE_UNSAVEABLE);
945		}
946		op_data_len = sizeof (OP_STATE_DATA)	+
947		    sizeof (SIGN_VERIFY_CONTEXT)  +
948		    sess->verify_ctx.context_len +
949		    sess->verify_ctx.mech.ulParameterLen;
950
951		if (length_only == FALSE) {
952			op_data = (OP_STATE_DATA *)dptr;
953
954			op_data->data_len = op_data_len -
955			    sizeof (OP_STATE_DATA);
956			op_data->session_state    = sess->session_info.state;
957			op_data->active_operation = STATE_SIGN;
958
959			offset = sizeof (OP_STATE_DATA);
960
961			(void) memcpy((CK_BYTE *)op_data + offset,
962			    &sess->verify_ctx, sizeof (SIGN_VERIFY_CONTEXT));
963
964			offset += sizeof (SIGN_VERIFY_CONTEXT);
965
966			if (sess->verify_ctx.context_len != 0) {
967				(void) memcpy((CK_BYTE *)op_data + offset,
968				    sess->verify_ctx.context,
969				    sess->verify_ctx.context_len);
970
971				offset += sess->verify_ctx.context_len;
972			}
973
974			if (sess->verify_ctx.mech.ulParameterLen != 0) {
975				(void) memcpy((CK_BYTE *)op_data + offset,
976				    sess->verify_ctx.mech.pParameter,
977				    sess->verify_ctx.mech.ulParameterLen);
978			}
979		}
980	}
981
982	*data_len = op_data_len;
983	return (CKR_OK);
984}
985
986CK_RV
987session_mgr_set_op_state(
988	SESSION	*sess,
989	CK_OBJECT_HANDLE encr_key,
990	CK_OBJECT_HANDLE auth_key,
991	CK_BYTE	*data)
992{
993	OP_STATE_DATA  *op_data = NULL;
994	CK_BYTE	*mech_param = NULL;
995	CK_BYTE	*context  = NULL;
996	CK_BYTE	*ptr1	= NULL;
997	CK_BYTE	*ptr2	= NULL;
998	CK_BYTE	*ptr3	= NULL;
999	CK_ULONG len;
1000	void	*dptr = data;
1001
1002	if (! sess || ! data) {
1003		return (CKR_FUNCTION_FAILED);
1004	}
1005	op_data = (OP_STATE_DATA *)dptr;
1006
1007	if (sess->session_info.state != op_data->session_state) {
1008		return (CKR_SAVED_STATE_INVALID);
1009	}
1010	switch (op_data->active_operation) {
1011		case STATE_ENCR:
1012		case STATE_DECR:
1013		{
1014			void *cptr = data + sizeof (OP_STATE_DATA);
1015			ENCR_DECR_CONTEXT *ctx = (ENCR_DECR_CONTEXT *)cptr;
1016
1017			len = sizeof (ENCR_DECR_CONTEXT) +
1018			    ctx->context_len + ctx->mech.ulParameterLen;
1019			if (len != op_data->data_len) {
1020				return (CKR_SAVED_STATE_INVALID);
1021			}
1022			if (auth_key != 0) {
1023				return (CKR_KEY_NOT_NEEDED);
1024			}
1025			if (encr_key == 0) {
1026				return (CKR_KEY_NEEDED);
1027			}
1028			ptr1 = (CK_BYTE *)ctx;
1029			ptr2 = ptr1 + sizeof (ENCR_DECR_CONTEXT);
1030			ptr3 = ptr2 + ctx->context_len;
1031
1032			if (ctx->context_len) {
1033				context = (CK_BYTE *)malloc(ctx->context_len);
1034				if (! context) {
1035					return (CKR_HOST_MEMORY);
1036				}
1037				(void) memcpy(context, ptr2, ctx->context_len);
1038			}
1039
1040			if (ctx->mech.ulParameterLen) {
1041				mech_param = (CK_BYTE *)malloc(
1042				    ctx->mech.ulParameterLen);
1043				if (! mech_param) {
1044					if (context)
1045						free(context);
1046					return (CKR_HOST_MEMORY);
1047				}
1048				(void) memcpy(mech_param, ptr3,
1049				    ctx->mech.ulParameterLen);
1050			}
1051		}
1052		break;
1053
1054		case STATE_SIGN:
1055		case STATE_VERIFY:
1056		{
1057			void *cptr = data + sizeof (OP_STATE_DATA);
1058			SIGN_VERIFY_CONTEXT *ctx = (SIGN_VERIFY_CONTEXT *)cptr;
1059
1060			len = sizeof (SIGN_VERIFY_CONTEXT) +
1061			    ctx->context_len + ctx->mech.ulParameterLen;
1062			if (len != op_data->data_len) {
1063				return (CKR_SAVED_STATE_INVALID);
1064			}
1065			if (auth_key == 0) {
1066				return (CKR_KEY_NEEDED);
1067			}
1068			if (encr_key != 0) {
1069				return (CKR_KEY_NOT_NEEDED);
1070			}
1071			ptr1 = (CK_BYTE *)ctx;
1072			ptr2 = ptr1 + sizeof (SIGN_VERIFY_CONTEXT);
1073			ptr3 = ptr2 + ctx->context_len;
1074
1075			if (ctx->context_len) {
1076				context = (CK_BYTE *)malloc(ctx->context_len);
1077				if (! context) {
1078					return (CKR_HOST_MEMORY);
1079				}
1080				(void) memcpy(context, ptr2, ctx->context_len);
1081			}
1082
1083			if (ctx->mech.ulParameterLen) {
1084				mech_param = (CK_BYTE *)malloc(
1085				    ctx->mech.ulParameterLen);
1086				if (! mech_param) {
1087					if (context)
1088						free(context);
1089					return (CKR_HOST_MEMORY);
1090				}
1091				(void) memcpy(mech_param, ptr3,
1092				    ctx->mech.ulParameterLen);
1093			}
1094		}
1095		break;
1096
1097		case STATE_DIGEST:
1098		{
1099			void *cptr = data + sizeof (OP_STATE_DATA);
1100			DIGEST_CONTEXT *ctx = (DIGEST_CONTEXT *)cptr;
1101
1102			len = sizeof (DIGEST_CONTEXT) +
1103			    ctx->context_len + ctx->mech.ulParameterLen;
1104			if (len != op_data->data_len) {
1105				return (CKR_SAVED_STATE_INVALID);
1106			}
1107			if (auth_key != 0) {
1108				return (CKR_KEY_NOT_NEEDED);
1109			}
1110			if (encr_key != 0) {
1111				return (CKR_KEY_NOT_NEEDED);
1112			}
1113			ptr1 = (CK_BYTE *)ctx;
1114			ptr2 = ptr1 + sizeof (DIGEST_CONTEXT);
1115			ptr3 = ptr2 + ctx->context_len;
1116
1117			if (ctx->context_len) {
1118				context = (CK_BYTE *)malloc(ctx->context_len);
1119				if (! context) {
1120					return (CKR_HOST_MEMORY);
1121				}
1122				(void) memcpy(context, ptr2, ctx->context_len);
1123			}
1124
1125			if (ctx->mech.ulParameterLen) {
1126				mech_param = (CK_BYTE *)malloc(
1127				    ctx->mech.ulParameterLen);
1128				if (! mech_param) {
1129					if (context)
1130						free(context);
1131					return (CKR_HOST_MEMORY);
1132				}
1133				(void) memcpy(mech_param, ptr3,
1134				    ctx->mech.ulParameterLen);
1135			}
1136		}
1137		break;
1138
1139		default:
1140		return (CKR_SAVED_STATE_INVALID);
1141	}
1142
1143
1144	if (sess->encr_ctx.active)
1145		(void) encr_mgr_cleanup(&sess->encr_ctx);
1146
1147	if (sess->decr_ctx.active)
1148		(void) decr_mgr_cleanup(&sess->decr_ctx);
1149
1150	if (sess->digest_ctx.active)
1151		(void) digest_mgr_cleanup(&sess->digest_ctx);
1152
1153	if (sess->sign_ctx.active)
1154		(void) sign_mgr_cleanup(&sess->sign_ctx);
1155
1156	if (sess->verify_ctx.active)
1157		(void) verify_mgr_cleanup(&sess->verify_ctx);
1158
1159	switch (op_data->active_operation) {
1160		case STATE_ENCR:
1161		(void) memcpy(&sess->encr_ctx, ptr1,
1162		    sizeof (ENCR_DECR_CONTEXT));
1163
1164		sess->encr_ctx.key	= encr_key;
1165		sess->encr_ctx.context	= context;
1166		sess->encr_ctx.mech.pParameter = mech_param;
1167		break;
1168
1169		case STATE_DECR:
1170		(void) memcpy(&sess->decr_ctx, ptr1,
1171		    sizeof (ENCR_DECR_CONTEXT));
1172
1173		sess->decr_ctx.key = encr_key;
1174		sess->decr_ctx.context = context;
1175		sess->decr_ctx.mech.pParameter = mech_param;
1176		break;
1177
1178		case STATE_SIGN:
1179		(void) memcpy(&sess->sign_ctx, ptr1,
1180		    sizeof (SIGN_VERIFY_CONTEXT));
1181
1182		sess->sign_ctx.key	= auth_key;
1183		sess->sign_ctx.context  = context;
1184		sess->sign_ctx.mech.pParameter = mech_param;
1185		break;
1186
1187		case STATE_VERIFY:
1188		(void) memcpy(&sess->verify_ctx, ptr1,
1189		    sizeof (SIGN_VERIFY_CONTEXT));
1190
1191		sess->verify_ctx.key = auth_key;
1192		sess->verify_ctx.context = context;
1193		sess->verify_ctx.mech.pParameter = mech_param;
1194		break;
1195
1196		case STATE_DIGEST:
1197		(void) memcpy(&sess->digest_ctx, ptr1,
1198		    sizeof (DIGEST_CONTEXT));
1199
1200		sess->digest_ctx.context.ref = context;
1201		sess->digest_ctx.mech.pParameter = mech_param;
1202		break;
1203	}
1204
1205	return (CKR_OK);
1206}
1207
1208CK_BBOOL
1209pin_expired(CK_SESSION_INFO *si, CK_FLAGS flags)
1210{
1211	// If this is an SO session
1212	if ((flags & CKF_SO_PIN_TO_BE_CHANGED) &&
1213	    (si->state == CKS_RW_SO_FUNCTIONS))
1214		return (TRUE);
1215	return ((flags & CKF_USER_PIN_TO_BE_CHANGED) &&
1216	    ((si->state == CKS_RO_USER_FUNCTIONS) ||
1217	    (si->state == CKS_RW_USER_FUNCTIONS)));
1218}
1219
1220CK_BBOOL
1221pin_locked(CK_SESSION_INFO *si, CK_FLAGS flags) {
1222	// If this is an SO session
1223	if ((flags & CKF_SO_PIN_LOCKED) &&
1224	    (si->state == CKS_RW_SO_FUNCTIONS))
1225		return (TRUE);
1226
1227	return ((flags & CKF_USER_PIN_LOCKED) &&
1228	    ((si->state == CKS_RO_USER_FUNCTIONS) ||
1229	    (si->state == CKS_RW_USER_FUNCTIONS)));
1230}
1231
1232void
1233set_login_flags(CK_USER_TYPE userType, CK_FLAGS *flags) {
1234	if (userType == CKU_USER) {
1235		if (*flags & CKF_USER_PIN_FINAL_TRY) {
1236			*flags |= CKF_USER_PIN_LOCKED;
1237			*flags &= ~(CKF_USER_PIN_FINAL_TRY);
1238		} else if (*flags & CKF_USER_PIN_COUNT_LOW) {
1239			*flags |= CKF_USER_PIN_FINAL_TRY;
1240			*flags &= ~(CKF_USER_PIN_COUNT_LOW);
1241		} else {
1242			*flags |= CKF_USER_PIN_COUNT_LOW;
1243		}
1244	} else {
1245		if (*flags & CKF_SO_PIN_FINAL_TRY) {
1246			*flags |= CKF_SO_PIN_LOCKED;
1247			*flags &= ~(CKF_SO_PIN_FINAL_TRY);
1248		} else if (*flags & CKF_SO_PIN_COUNT_LOW) {
1249			*flags |= CKF_SO_PIN_FINAL_TRY;
1250			*flags &= ~(CKF_SO_PIN_COUNT_LOW);
1251		} else {
1252			*flags |= CKF_SO_PIN_COUNT_LOW;
1253		}
1254	}
1255}
1256