147e946e7SWyllys Ingersoll /*
247e946e7SWyllys Ingersoll  *		Common Public License Version 0.5
347e946e7SWyllys Ingersoll  *
447e946e7SWyllys Ingersoll  *		THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF
547e946e7SWyllys Ingersoll  *		THIS COMMON PUBLIC LICENSE ("AGREEMENT"). ANY USE,
647e946e7SWyllys Ingersoll  *		REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES
747e946e7SWyllys Ingersoll  *		RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
847e946e7SWyllys Ingersoll  *
947e946e7SWyllys Ingersoll  *		1. DEFINITIONS
1047e946e7SWyllys Ingersoll  *
1147e946e7SWyllys Ingersoll  *		"Contribution" means:
1247e946e7SWyllys Ingersoll  *		      a) in the case of the initial Contributor, the
1347e946e7SWyllys Ingersoll  *		      initial code and documentation distributed under
1447e946e7SWyllys Ingersoll  *		      this Agreement, and
1547e946e7SWyllys Ingersoll  *
1647e946e7SWyllys Ingersoll  *		      b) in the case of each subsequent Contributor:
1747e946e7SWyllys Ingersoll  *		      i) changes to the Program, and
1847e946e7SWyllys Ingersoll  *		      ii) additions to the Program;
1947e946e7SWyllys Ingersoll  *
2047e946e7SWyllys Ingersoll  *		      where such changes and/or additions to the Program
2147e946e7SWyllys Ingersoll  *		      originate from and are distributed by that
2247e946e7SWyllys Ingersoll  *		      particular Contributor. A Contribution 'originates'
2347e946e7SWyllys Ingersoll  *		      from a Contributor if it was added to the Program
2447e946e7SWyllys Ingersoll  *		      by such Contributor itself or anyone acting on such
2547e946e7SWyllys Ingersoll  *		      Contributor's behalf. Contributions do not include
2647e946e7SWyllys Ingersoll  *		      additions to the Program which: (i) are separate
2747e946e7SWyllys Ingersoll  *		      modules of software distributed in conjunction with
2847e946e7SWyllys Ingersoll  *		      the Program under their own license agreement, and
2947e946e7SWyllys Ingersoll  *		      (ii) are not derivative works of the Program.
3047e946e7SWyllys Ingersoll  *
3147e946e7SWyllys Ingersoll  *
3247e946e7SWyllys Ingersoll  *		"Contributor" means any person or entity that distributes
3347e946e7SWyllys Ingersoll  *		the Program.
3447e946e7SWyllys Ingersoll  *
3547e946e7SWyllys Ingersoll  *		"Licensed Patents " mean patent claims licensable by a
3647e946e7SWyllys Ingersoll  *		Contributor which are necessarily infringed by the use or
3747e946e7SWyllys Ingersoll  *		sale of its Contribution alone or when combined with the
3847e946e7SWyllys Ingersoll  *		Program.
3947e946e7SWyllys Ingersoll  *
4047e946e7SWyllys Ingersoll  *		"Program" means the Contributions distributed in
4147e946e7SWyllys Ingersoll  *		accordance with this Agreement.
4247e946e7SWyllys Ingersoll  *
4347e946e7SWyllys Ingersoll  *		"Recipient" means anyone who receives the Program under
4447e946e7SWyllys Ingersoll  *		this Agreement, including all Contributors.
4547e946e7SWyllys Ingersoll  *
4647e946e7SWyllys Ingersoll  *		2. GRANT OF RIGHTS
4747e946e7SWyllys Ingersoll  *
4847e946e7SWyllys Ingersoll  *		      a) Subject to the terms of this Agreement, each
4947e946e7SWyllys Ingersoll  *		      Contributor hereby grants Recipient a
5047e946e7SWyllys Ingersoll  *		      non-exclusive, worldwide, royalty-free copyright
5147e946e7SWyllys Ingersoll  *		      license to reproduce, prepare derivative works of,
5247e946e7SWyllys Ingersoll  *		      publicly display, publicly perform, distribute and
5347e946e7SWyllys Ingersoll  *		      sublicense the Contribution of such Contributor, if
5447e946e7SWyllys Ingersoll  *		      any, and such derivative works, in source code and
5547e946e7SWyllys Ingersoll  *		      object code form.
5647e946e7SWyllys Ingersoll  *
5747e946e7SWyllys Ingersoll  *		      b) Subject to the terms of this Agreement, each
5847e946e7SWyllys Ingersoll  *		      Contributor hereby grants Recipient a
5947e946e7SWyllys Ingersoll  *		      non-exclusive, worldwide, royalty-free patent
6047e946e7SWyllys Ingersoll  *		      license under Licensed Patents to make, use, sell,
6147e946e7SWyllys Ingersoll  *		      offer to sell, import and otherwise transfer the
6247e946e7SWyllys Ingersoll  *		      Contribution of such Contributor, if any, in source
6347e946e7SWyllys Ingersoll  *		      code and object code form. This patent license
6447e946e7SWyllys Ingersoll  *		      shall apply to the combination of the Contribution
6547e946e7SWyllys Ingersoll  *		      and the Program if, at the time the Contribution is
6647e946e7SWyllys Ingersoll  *		      added by the Contributor, such addition of the
6747e946e7SWyllys Ingersoll  *		      Contribution causes such combination to be covered
6847e946e7SWyllys Ingersoll  *		      by the Licensed Patents. The patent license shall
6947e946e7SWyllys Ingersoll  *		      not apply to any other combinations which include
7047e946e7SWyllys Ingersoll  *		      the Contribution. No hardware per se is licensed
7147e946e7SWyllys Ingersoll  *		      hereunder.
7247e946e7SWyllys Ingersoll  *
7347e946e7SWyllys Ingersoll  *		      c) Recipient understands that although each
7447e946e7SWyllys Ingersoll  *		      Contributor grants the licenses to its
7547e946e7SWyllys Ingersoll  *		      Contributions set forth herein, no assurances are
7647e946e7SWyllys Ingersoll  *		      provided by any Contributor that the Program does
7747e946e7SWyllys Ingersoll  *		      not infringe the patent or other intellectual
7847e946e7SWyllys Ingersoll  *		      property rights of any other entity. Each
7947e946e7SWyllys Ingersoll  *		      Contributor disclaims any liability to Recipient
8047e946e7SWyllys Ingersoll  *		      for claims brought by any other entity based on
8147e946e7SWyllys Ingersoll  *		      infringement of intellectual property rights or
8247e946e7SWyllys Ingersoll  *		      otherwise. As a condition to exercising the rights
8347e946e7SWyllys Ingersoll  *		      and licenses granted hereunder, each Recipient
8447e946e7SWyllys Ingersoll  *		      hereby assumes sole responsibility to secure any
8547e946e7SWyllys Ingersoll  *		      other intellectual property rights needed, if any.
8647e946e7SWyllys Ingersoll  *
8747e946e7SWyllys Ingersoll  *		      For example, if a third party patent license is
8847e946e7SWyllys Ingersoll  *		      required to allow Recipient to distribute the
8947e946e7SWyllys Ingersoll  *		      Program, it is Recipient's responsibility to
9047e946e7SWyllys Ingersoll  *		      acquire that license before distributing the
9147e946e7SWyllys Ingersoll  *		      Program.
9247e946e7SWyllys Ingersoll  *
9347e946e7SWyllys Ingersoll  *		      d) Each Contributor represents that to its
9447e946e7SWyllys Ingersoll  *		      knowledge it has sufficient copyright rights in its
9547e946e7SWyllys Ingersoll  *		      Contribution, if any, to grant the copyright
9647e946e7SWyllys Ingersoll  *		      license set forth in this Agreement.
9747e946e7SWyllys Ingersoll  *
9847e946e7SWyllys Ingersoll  *		3. REQUIREMENTS
9947e946e7SWyllys Ingersoll  *
10047e946e7SWyllys Ingersoll  *		A Contributor may choose to distribute the Program in
10147e946e7SWyllys Ingersoll  *		object code form under its own license agreement, provided
10247e946e7SWyllys Ingersoll  *		that:
10347e946e7SWyllys Ingersoll  *		      a) it complies with the terms and conditions of
10447e946e7SWyllys Ingersoll  *		      this Agreement; and
10547e946e7SWyllys Ingersoll  *
10647e946e7SWyllys Ingersoll  *		      b) its license agreement:
10747e946e7SWyllys Ingersoll  *		      i) effectively disclaims on behalf of all
10847e946e7SWyllys Ingersoll  *		      Contributors all warranties and conditions, express
10947e946e7SWyllys Ingersoll  *		      and implied, including warranties or conditions of
11047e946e7SWyllys Ingersoll  *		      title and non-infringement, and implied warranties
11147e946e7SWyllys Ingersoll  *		      or conditions of merchantability and fitness for a
11247e946e7SWyllys Ingersoll  *		      particular purpose;
11347e946e7SWyllys Ingersoll  *
11447e946e7SWyllys Ingersoll  *		      ii) effectively excludes on behalf of all
11547e946e7SWyllys Ingersoll  *		      Contributors all liability for damages, including
11647e946e7SWyllys Ingersoll  *		      direct, indirect, special, incidental and
11747e946e7SWyllys Ingersoll  *		      consequential damages, such as lost profits;
11847e946e7SWyllys Ingersoll  *
11947e946e7SWyllys Ingersoll  *		      iii) states that any provisions which differ from
12047e946e7SWyllys Ingersoll  *		      this Agreement are offered by that Contributor
12147e946e7SWyllys Ingersoll  *		      alone and not by any other party; and
12247e946e7SWyllys Ingersoll  *
12347e946e7SWyllys Ingersoll  *		      iv) states that source code for the Program is
12447e946e7SWyllys Ingersoll  *		      available from such Contributor, and informs
12547e946e7SWyllys Ingersoll  *		      licensees how to obtain it in a reasonable manner
12647e946e7SWyllys Ingersoll  *		      on or through a medium customarily used for
12747e946e7SWyllys Ingersoll  *		      software exchange.
12847e946e7SWyllys Ingersoll  *
12947e946e7SWyllys Ingersoll  *		When the Program is made available in source code form:
13047e946e7SWyllys Ingersoll  *		      a) it must be made available under this Agreement;
13147e946e7SWyllys Ingersoll  *		      and
13247e946e7SWyllys Ingersoll  *		      b) a copy of this Agreement must be included with
13347e946e7SWyllys Ingersoll  *		      each copy of the Program.
13447e946e7SWyllys Ingersoll  *
13547e946e7SWyllys Ingersoll  *		Contributors may not remove or alter any copyright notices
13647e946e7SWyllys Ingersoll  *		contained within the Program.
13747e946e7SWyllys Ingersoll  *
13847e946e7SWyllys Ingersoll  *		Each Contributor must identify itself as the originator of
13947e946e7SWyllys Ingersoll  *		its Contribution, if any, in a manner that reasonably
14047e946e7SWyllys Ingersoll  *		allows subsequent Recipients to identify the originator of
14147e946e7SWyllys Ingersoll  *		the Contribution.
14247e946e7SWyllys Ingersoll  *
14347e946e7SWyllys Ingersoll  *
14447e946e7SWyllys Ingersoll  *		4. COMMERCIAL DISTRIBUTION
14547e946e7SWyllys Ingersoll  *
14647e946e7SWyllys Ingersoll  *		Commercial distributors of software may accept certain
14747e946e7SWyllys Ingersoll  *		responsibilities with respect to end users, business
14847e946e7SWyllys Ingersoll  *		partners and the like. While this license is intended to
14947e946e7SWyllys Ingersoll  *		facilitate the commercial use of the Program, the
15047e946e7SWyllys Ingersoll  *		Contributor who includes the Program in a commercial
15147e946e7SWyllys Ingersoll  *		product offering should do so in a manner which does not
15247e946e7SWyllys Ingersoll  *		create potential liability for other Contributors.
15347e946e7SWyllys Ingersoll  *		Therefore, if a Contributor includes the Program in a
15447e946e7SWyllys Ingersoll  *		commercial product offering, such Contributor ("Commercial
15547e946e7SWyllys Ingersoll  *		Contributor") hereby agrees to defend and indemnify every
15647e946e7SWyllys Ingersoll  *		other Contributor ("Indemnified Contributor") against any
15747e946e7SWyllys Ingersoll  *		losses, damages and costs (collectively "Losses") arising
15847e946e7SWyllys Ingersoll  *		from claims, lawsuits and other legal actions brought by a
15947e946e7SWyllys Ingersoll  *		third party against the Indemnified Contributor to the
16047e946e7SWyllys Ingersoll  *		extent caused by the acts or omissions of such Commercial
16147e946e7SWyllys Ingersoll  *		Contributor in connection with its distribution of the
16247e946e7SWyllys Ingersoll  *		Program in a commercial product offering. The obligations
16347e946e7SWyllys Ingersoll  *		in this section do not apply to any claims or Losses
16447e946e7SWyllys Ingersoll  *		relating to any actual or alleged intellectual property
16547e946e7SWyllys Ingersoll  *		infringement. In order to qualify, an Indemnified
16647e946e7SWyllys Ingersoll  *		Contributor must: a) promptly notify the Commercial
16747e946e7SWyllys Ingersoll  *		Contributor in writing of such claim, and b) allow the
16847e946e7SWyllys Ingersoll  *		Commercial Contributor to control, and cooperate with the
16947e946e7SWyllys Ingersoll  *		Commercial Contributor in, the defense and any related
17047e946e7SWyllys Ingersoll  *		settlement negotiations. The Indemnified Contributor may
17147e946e7SWyllys Ingersoll  *		participate in any such claim at its own expense.
17247e946e7SWyllys Ingersoll  *
17347e946e7SWyllys Ingersoll  *
17447e946e7SWyllys Ingersoll  *		For example, a Contributor might include the Program in a
17547e946e7SWyllys Ingersoll  *		commercial product offering, Product X. That Contributor
17647e946e7SWyllys Ingersoll  *		is then a Commercial Contributor. If that Commercial
17747e946e7SWyllys Ingersoll  *		Contributor then makes performance claims, or offers
17847e946e7SWyllys Ingersoll  *		warranties related to Product X, those performance claims
17947e946e7SWyllys Ingersoll  *		and warranties are such Commercial Contributor's
18047e946e7SWyllys Ingersoll  *		responsibility alone. Under this section, the Commercial
18147e946e7SWyllys Ingersoll  *		Contributor would have to defend claims against the other
18247e946e7SWyllys Ingersoll  *		Contributors related to those performance claims and
18347e946e7SWyllys Ingersoll  *		warranties, and if a court requires any other Contributor
18447e946e7SWyllys Ingersoll  *		to pay any damages as a result, the Commercial Contributor
18547e946e7SWyllys Ingersoll  *		must pay those damages.
18647e946e7SWyllys Ingersoll  *
18747e946e7SWyllys Ingersoll  *
18847e946e7SWyllys Ingersoll  *		5. NO WARRANTY
18947e946e7SWyllys Ingersoll  *
19047e946e7SWyllys Ingersoll  *		EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE
19147e946e7SWyllys Ingersoll  *		PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
19247e946e7SWyllys Ingersoll  *		WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
19347e946e7SWyllys Ingersoll  *		IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR
19447e946e7SWyllys Ingersoll  *		CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
19547e946e7SWyllys Ingersoll  *		FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely
19647e946e7SWyllys Ingersoll  *		responsible for determining the appropriateness of using
19747e946e7SWyllys Ingersoll  *		and distributing the Program and assumes all risks
19847e946e7SWyllys Ingersoll  *		associated with its exercise of rights under this
19947e946e7SWyllys Ingersoll  *		Agreement, including but not limited to the risks and
20047e946e7SWyllys Ingersoll  *		costs of program errors, compliance with applicable laws,
20147e946e7SWyllys Ingersoll  *		damage to or loss of data, programs or equipment, and
20247e946e7SWyllys Ingersoll  *		unavailability or interruption of operations.
20347e946e7SWyllys Ingersoll  *
20447e946e7SWyllys Ingersoll  *		6. DISCLAIMER OF LIABILITY
20547e946e7SWyllys Ingersoll  *		EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER
20647e946e7SWyllys Ingersoll  *		RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY
20747e946e7SWyllys Ingersoll  *		FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
20847e946e7SWyllys Ingersoll  *		OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
20947e946e7SWyllys Ingersoll  *		LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF
21047e946e7SWyllys Ingersoll  *		LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21147e946e7SWyllys Ingersoll  *		(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
21247e946e7SWyllys Ingersoll  *		OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE
21347e946e7SWyllys Ingersoll  *		OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE
21447e946e7SWyllys Ingersoll  *		POSSIBILITY OF SUCH DAMAGES.
21547e946e7SWyllys Ingersoll  *
21647e946e7SWyllys Ingersoll  *		7. GENERAL
21747e946e7SWyllys Ingersoll  *
21847e946e7SWyllys Ingersoll  *		If any provision of this Agreement is invalid or
21947e946e7SWyllys Ingersoll  *		unenforceable under applicable law, it shall not affect
22047e946e7SWyllys Ingersoll  *		the validity or enforceability of the remainder of the
22147e946e7SWyllys Ingersoll  *		terms of this Agreement, and without further action by the
22247e946e7SWyllys Ingersoll  *		parties hereto, such provision shall be reformed to the
22347e946e7SWyllys Ingersoll  *		minimum extent necessary to make such provision valid and
22447e946e7SWyllys Ingersoll  *		enforceable.
22547e946e7SWyllys Ingersoll  *
22647e946e7SWyllys Ingersoll  *
22747e946e7SWyllys Ingersoll  *		If Recipient institutes patent litigation against a
22847e946e7SWyllys Ingersoll  *		Contributor with respect to a patent applicable to
22947e946e7SWyllys Ingersoll  *		software (including a cross-claim or counterclaim in a
23047e946e7SWyllys Ingersoll  *		lawsuit), then any patent licenses granted by that
23147e946e7SWyllys Ingersoll  *		Contributor to such Recipient under this Agreement shall
23247e946e7SWyllys Ingersoll  *		terminate as of the date such litigation is filed. In
23347e946e7SWyllys Ingersoll  *		addition, If Recipient institutes patent litigation
23447e946e7SWyllys Ingersoll  *		against any entity (including a cross-claim or
23547e946e7SWyllys Ingersoll  *		counterclaim in a lawsuit) alleging that the Program
23647e946e7SWyllys Ingersoll  *		itself (excluding combinations of the Program with other
23747e946e7SWyllys Ingersoll  *		software or hardware) infringes such Recipient's
23847e946e7SWyllys Ingersoll  *		patent(s), then such Recipient's rights granted under
23947e946e7SWyllys Ingersoll  *		Section 2(b) shall terminate as of the date such
24047e946e7SWyllys Ingersoll  *		litigation is filed.
24147e946e7SWyllys Ingersoll  *
24247e946e7SWyllys Ingersoll  *		All Recipient's rights under this Agreement shall
24347e946e7SWyllys Ingersoll  *		terminate if it fails to comply with any of the material
24447e946e7SWyllys Ingersoll  *		terms or conditions of this Agreement and does not cure
24547e946e7SWyllys Ingersoll  *		such failure in a reasonable period of time after becoming
24647e946e7SWyllys Ingersoll  *		aware of such noncompliance. If all Recipient's rights
24747e946e7SWyllys Ingersoll  *		under this Agreement terminate, Recipient agrees to cease
24847e946e7SWyllys Ingersoll  *		use and distribution of the Program as soon as reasonably
24947e946e7SWyllys Ingersoll  *		practicable. However, Recipient's obligations under this
25047e946e7SWyllys Ingersoll  *		Agreement and any licenses granted by Recipient relating
25147e946e7SWyllys Ingersoll  *		to the Program shall continue and survive.
25247e946e7SWyllys Ingersoll  *
25347e946e7SWyllys Ingersoll  *		Everyone is permitted to copy and distribute copies of
25447e946e7SWyllys Ingersoll  *		this Agreement, but in order to avoid inconsistency the
25547e946e7SWyllys Ingersoll  *		Agreement is copyrighted and may only be modified in the
25647e946e7SWyllys Ingersoll  *		following manner. The Agreement Steward reserves the right
25747e946e7SWyllys Ingersoll  *		to publish new versions (including revisions) of this
25847e946e7SWyllys Ingersoll  *		Agreement from time to time. No one other than the
25947e946e7SWyllys Ingersoll  *		Agreement Steward has the right to modify this Agreement.
26047e946e7SWyllys Ingersoll  *
26147e946e7SWyllys Ingersoll  *		IBM is the initial Agreement Steward. IBM may assign the
26247e946e7SWyllys Ingersoll  *		responsibility to serve as the Agreement Steward to a
26347e946e7SWyllys Ingersoll  *		suitable separate entity. Each new version of the
26447e946e7SWyllys Ingersoll  *		Agreement will be given a distinguishing version number.
26547e946e7SWyllys Ingersoll  *		The Program (including Contributions) may always be
26647e946e7SWyllys Ingersoll  *		distributed subject to the version of the Agreement under
26747e946e7SWyllys Ingersoll  *		which it was received. In addition, after a new version of
26847e946e7SWyllys Ingersoll  *		the Agreement is published, Contributor may elect to
26947e946e7SWyllys Ingersoll  *		distribute the Program (including its Contributions) under
27047e946e7SWyllys Ingersoll  *		the new version. Except as expressly stated in Sections
27147e946e7SWyllys Ingersoll  *		2(a) and 2(b) above, Recipient receives no rights or
27247e946e7SWyllys Ingersoll  *		licenses to the intellectual property of any Contributor
27347e946e7SWyllys Ingersoll  *		under this Agreement, whether expressly, by implication,
27447e946e7SWyllys Ingersoll  *		estoppel or otherwise. All rights in the Program not
27547e946e7SWyllys Ingersoll  *		expressly granted under this Agreement are reserved.
27647e946e7SWyllys Ingersoll  *
27747e946e7SWyllys Ingersoll  *
27847e946e7SWyllys Ingersoll  *		This Agreement is governed by the laws of the State of New
27947e946e7SWyllys Ingersoll  *		York and the intellectual property laws of the United
28047e946e7SWyllys Ingersoll  *		States of America. No party to this Agreement will bring a
28147e946e7SWyllys Ingersoll  *		legal action under this Agreement more than one year after
28247e946e7SWyllys Ingersoll  *		the cause of action arose. Each party waives its rights to
28347e946e7SWyllys Ingersoll  *		a jury trial in any resulting litigation.
28447e946e7SWyllys Ingersoll  *
28547e946e7SWyllys Ingersoll  *
28647e946e7SWyllys Ingersoll  *
28747e946e7SWyllys Ingersoll  * (C) COPYRIGHT International Business Machines Corp. 2001,2002
28847e946e7SWyllys Ingersoll  */
28947e946e7SWyllys Ingersoll /*
29047e946e7SWyllys Ingersoll  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
29147e946e7SWyllys Ingersoll  * Use is subject to license terms.
29247e946e7SWyllys Ingersoll  */
29347e946e7SWyllys Ingersoll 
29447e946e7SWyllys Ingersoll #include "tpmtok_int.h"
29547e946e7SWyllys Ingersoll #include <pwd.h>
29647e946e7SWyllys Ingersoll #include <grp.h>
29747e946e7SWyllys Ingersoll #include <fcntl.h>
29847e946e7SWyllys Ingersoll 
29947e946e7SWyllys Ingersoll #define	ALTERNATE_KEYSTORE_PATH "PKCS11_TPM_DIR"
30047e946e7SWyllys Ingersoll #define	PWD_BUFFER_SIZE	1024
30147e946e7SWyllys Ingersoll 
30247e946e7SWyllys Ingersoll static char keystore_path[MAXPATHLEN];
30347e946e7SWyllys Ingersoll static boolean_t keystore_path_initialized = 0;
30447e946e7SWyllys Ingersoll 
305*b8ccc413SToomas Soome extern TSS_HKEY hPrivateLeafKey;
30647e946e7SWyllys Ingersoll static CK_RV
30747e946e7SWyllys Ingersoll restore_private_token_object(TSS_HCONTEXT, CK_BYTE  *, CK_ULONG, OBJECT *);
30847e946e7SWyllys Ingersoll 
30947e946e7SWyllys Ingersoll static struct flock fl = {
31047e946e7SWyllys Ingersoll 	0,
31147e946e7SWyllys Ingersoll 	0,
31247e946e7SWyllys Ingersoll 	0,
31347e946e7SWyllys Ingersoll 	0,
31447e946e7SWyllys Ingersoll 	0,
31547e946e7SWyllys Ingersoll 	0,
31647e946e7SWyllys Ingersoll 	{0, 0, 0, 0}
31747e946e7SWyllys Ingersoll };
31847e946e7SWyllys Ingersoll 
31947e946e7SWyllys Ingersoll static int
lockfile(int fd,int op)32047e946e7SWyllys Ingersoll lockfile(int fd, int op)
32147e946e7SWyllys Ingersoll {
32247e946e7SWyllys Ingersoll 	fl.l_type = op;
32347e946e7SWyllys Ingersoll 	return (fcntl(fd, F_SETLKW, &fl));
32447e946e7SWyllys Ingersoll }
32547e946e7SWyllys Ingersoll 
32647e946e7SWyllys Ingersoll static char *
get_user_default_path(char * home_path)32747e946e7SWyllys Ingersoll get_user_default_path(char *home_path)
32847e946e7SWyllys Ingersoll {
32947e946e7SWyllys Ingersoll 	struct passwd pwd, *user_info;
33047e946e7SWyllys Ingersoll 	char pwdbuf[PWD_BUFFER_SIZE];
33147e946e7SWyllys Ingersoll 
33247e946e7SWyllys Ingersoll 	if (getpwuid_r(getuid(), &pwd, pwdbuf, PWD_BUFFER_SIZE,
33347e946e7SWyllys Ingersoll 	    &user_info) != 0)
33447e946e7SWyllys Ingersoll 		return (NULL);
33547e946e7SWyllys Ingersoll 
33647e946e7SWyllys Ingersoll 	(void) snprintf(home_path, MAXPATHLEN, "/var/tpm/pkcs11/%s",
33747e946e7SWyllys Ingersoll 	    user_info ? user_info->pw_name : "");
33847e946e7SWyllys Ingersoll 
33947e946e7SWyllys Ingersoll 	return (home_path);
34047e946e7SWyllys Ingersoll }
34147e946e7SWyllys Ingersoll 
34247e946e7SWyllys Ingersoll char *
get_tpm_keystore_path()34347e946e7SWyllys Ingersoll get_tpm_keystore_path()
34447e946e7SWyllys Ingersoll {
34547e946e7SWyllys Ingersoll 	char *env_val;
34647e946e7SWyllys Ingersoll 	char home_path[MAXPATHLEN];
34747e946e7SWyllys Ingersoll 
34847e946e7SWyllys Ingersoll 	if (!keystore_path_initialized) {
34947e946e7SWyllys Ingersoll 		env_val = getenv(ALTERNATE_KEYSTORE_PATH);
35047e946e7SWyllys Ingersoll 		bzero(keystore_path, sizeof (keystore_path));
35147e946e7SWyllys Ingersoll 		/*
35247e946e7SWyllys Ingersoll 		 * If it isn't set or is set to the empty string use the
35347e946e7SWyllys Ingersoll 		 * default location.  We need to check for the empty string
35447e946e7SWyllys Ingersoll 		 * because some users "unset" environment variables by giving
35547e946e7SWyllys Ingersoll 		 * them no value, this isn't the same thing as removing it
35647e946e7SWyllys Ingersoll 		 * from the environment.
35747e946e7SWyllys Ingersoll 		 *
35847e946e7SWyllys Ingersoll 		 * We don't want that to attempt to open the token area.
35947e946e7SWyllys Ingersoll 		 */
36047e946e7SWyllys Ingersoll 		if ((env_val == NULL) || (strcmp(env_val, "") == 0)) {
36147e946e7SWyllys Ingersoll 			/* alternate path not specified, use default dir */
36247e946e7SWyllys Ingersoll 			char *p = get_user_default_path(home_path);
36347e946e7SWyllys Ingersoll 			if (p == NULL)
36447e946e7SWyllys Ingersoll 				return (NULL);
36547e946e7SWyllys Ingersoll 			(void) snprintf(keystore_path, MAXPATHLEN, "%s", p);
36647e946e7SWyllys Ingersoll 		} else {
36747e946e7SWyllys Ingersoll 			(void) snprintf(keystore_path, MAXPATHLEN, "%s",
36847e946e7SWyllys Ingersoll 			    env_val);
36947e946e7SWyllys Ingersoll 		}
37047e946e7SWyllys Ingersoll 		keystore_path_initialized = 1;
37147e946e7SWyllys Ingersoll 	}
37247e946e7SWyllys Ingersoll 	return (keystore_path);
37347e946e7SWyllys Ingersoll }
37447e946e7SWyllys Ingersoll 
37547e946e7SWyllys Ingersoll static CK_RV
create_keystore_dir()37647e946e7SWyllys Ingersoll create_keystore_dir()
37747e946e7SWyllys Ingersoll {
37847e946e7SWyllys Ingersoll 	char *ksdir = get_tpm_keystore_path();
37947e946e7SWyllys Ingersoll 	char objdir[MAXPATHLEN];
38047e946e7SWyllys Ingersoll 	CK_RV rv = 0;
38147e946e7SWyllys Ingersoll 
38247e946e7SWyllys Ingersoll 	if (ksdir == NULL)
38347e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
38447e946e7SWyllys Ingersoll 
38547e946e7SWyllys Ingersoll 	if (mkdir(ksdir, S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
38647e946e7SWyllys Ingersoll 		if (errno == EEXIST) {
38747e946e7SWyllys Ingersoll 			rv = 0;
38847e946e7SWyllys Ingersoll 		} else {
38947e946e7SWyllys Ingersoll 			return (CKR_FUNCTION_FAILED);
39047e946e7SWyllys Ingersoll 		}
39147e946e7SWyllys Ingersoll 	}
39247e946e7SWyllys Ingersoll 	if (rv == 0) {
39347e946e7SWyllys Ingersoll 		(void) snprintf(objdir, sizeof (objdir),
39447e946e7SWyllys Ingersoll 		    "%s/%s", ksdir, TOKEN_OBJ_DIR);
39547e946e7SWyllys Ingersoll 
39647e946e7SWyllys Ingersoll 		if (mkdir(objdir, S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
39747e946e7SWyllys Ingersoll 			if (errno == EEXIST) {
39847e946e7SWyllys Ingersoll 				rv = 0;
39947e946e7SWyllys Ingersoll 			} else {
40047e946e7SWyllys Ingersoll 				return (CKR_FUNCTION_FAILED);
40147e946e7SWyllys Ingersoll 			}
40247e946e7SWyllys Ingersoll 		}
40347e946e7SWyllys Ingersoll 	}
40447e946e7SWyllys Ingersoll 	return (CKR_OK);
40547e946e7SWyllys Ingersoll }
40647e946e7SWyllys Ingersoll 
40747e946e7SWyllys Ingersoll static void
set_perm(int file)40847e946e7SWyllys Ingersoll set_perm(int file)
40947e946e7SWyllys Ingersoll {
41047e946e7SWyllys Ingersoll 	/*
41147e946e7SWyllys Ingersoll 	 * In the TPM token, with per user data stores, we don't share the token
41247e946e7SWyllys Ingersoll 	 * object amongst a group. In fact, we want to restrict access to
41347e946e7SWyllys Ingersoll 	 * a single user.
41447e946e7SWyllys Ingersoll 	 */
41547e946e7SWyllys Ingersoll 	(void) fchmod(file, S_IRUSR|S_IWUSR);
41647e946e7SWyllys Ingersoll }
41747e946e7SWyllys Ingersoll 
418ab8176c2SWyllys Ingersoll #define	READ_TOKEN_INFO_STR(fp, rec, reclen) rc = fread(rec, reclen, 1, fp); \
419ab8176c2SWyllys Ingersoll 	if (rc != 1) { rc = CKR_FUNCTION_FAILED; goto out_unlock; }
420ab8176c2SWyllys Ingersoll 
421ab8176c2SWyllys Ingersoll #define	READ_TOKEN_INFO_UINT32(fp, rec) rc = fread(&fieldval, \
422ab8176c2SWyllys Ingersoll 	sizeof (UINT32), 1, fp); \
423ab8176c2SWyllys Ingersoll 	if (rc != 1) { rc = CKR_FUNCTION_FAILED; goto out_unlock; } \
424ab8176c2SWyllys Ingersoll 	rec = (CK_ULONG)fieldval;
425ab8176c2SWyllys Ingersoll 
42647e946e7SWyllys Ingersoll CK_RV
load_token_data(TSS_HCONTEXT hContext,TOKEN_DATA * td)42747e946e7SWyllys Ingersoll load_token_data(TSS_HCONTEXT hContext, TOKEN_DATA *td)
42847e946e7SWyllys Ingersoll {
42947e946e7SWyllys Ingersoll 	FILE	*fp;
43047e946e7SWyllys Ingersoll 	CK_BYTE	fname[MAXPATHLEN];
43147e946e7SWyllys Ingersoll 	CK_RV	rc;
432ab8176c2SWyllys Ingersoll 	UINT32	fieldval;
43347e946e7SWyllys Ingersoll 	char *p = get_tpm_keystore_path();
43447e946e7SWyllys Ingersoll 
43547e946e7SWyllys Ingersoll 	if (p == NULL)
43647e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
43747e946e7SWyllys Ingersoll 
43847e946e7SWyllys Ingersoll 	(void) snprintf((char *)fname, sizeof (fname),
43947e946e7SWyllys Ingersoll 	    "%s/%s", p, TOKEN_DATA_FILE);
44047e946e7SWyllys Ingersoll 
44147e946e7SWyllys Ingersoll 	rc = XProcLock(xproclock);
44247e946e7SWyllys Ingersoll 	if (rc != CKR_OK)
44347e946e7SWyllys Ingersoll 		return (rc);
44447e946e7SWyllys Ingersoll 
44547e946e7SWyllys Ingersoll 	fp = fopen((char *)fname, "r");
44647e946e7SWyllys Ingersoll 	if (!fp) {
44747e946e7SWyllys Ingersoll 		/* Better error checking added */
44847e946e7SWyllys Ingersoll 		if (errno == ENOENT) {
44947e946e7SWyllys Ingersoll 			(void) XProcUnLock(xproclock);
45047e946e7SWyllys Ingersoll 			rc = create_keystore_dir();
45147e946e7SWyllys Ingersoll 			if (rc != 0)
45247e946e7SWyllys Ingersoll 				goto out_nolock;
45347e946e7SWyllys Ingersoll 
45447e946e7SWyllys Ingersoll 			rc = init_token_data(hContext, td);
45547e946e7SWyllys Ingersoll 			if (rc != CKR_OK) {
45647e946e7SWyllys Ingersoll 				goto out_nolock;
45747e946e7SWyllys Ingersoll 			}
45847e946e7SWyllys Ingersoll 
45947e946e7SWyllys Ingersoll 			rc = XProcLock(xproclock);
46047e946e7SWyllys Ingersoll 			if (rc != CKR_OK) {
46147e946e7SWyllys Ingersoll 				goto out_nolock;
46247e946e7SWyllys Ingersoll 			}
46347e946e7SWyllys Ingersoll 
46447e946e7SWyllys Ingersoll 			fp = fopen((char *)fname, "r");
46547e946e7SWyllys Ingersoll 			if (!fp) {
46647e946e7SWyllys Ingersoll 				LogError("failed opening %s for read: %s",
46747e946e7SWyllys Ingersoll 				    fname, (char *)strerror(errno));
46847e946e7SWyllys Ingersoll 				rc = CKR_FUNCTION_FAILED;
46947e946e7SWyllys Ingersoll 				goto out_unlock;
47047e946e7SWyllys Ingersoll 			}
47147e946e7SWyllys Ingersoll 		} else {
47247e946e7SWyllys Ingersoll 			/* Could not open file for some unknown reason */
47347e946e7SWyllys Ingersoll 			rc = CKR_FUNCTION_FAILED;
47447e946e7SWyllys Ingersoll 			goto out_unlock;
47547e946e7SWyllys Ingersoll 		}
47647e946e7SWyllys Ingersoll 	}
47747e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp), F_RDLCK)) {
47847e946e7SWyllys Ingersoll 		(void) fclose(fp);
47947e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
48047e946e7SWyllys Ingersoll 		goto out_unlock;
48147e946e7SWyllys Ingersoll 	}
48247e946e7SWyllys Ingersoll 	set_perm(fileno(fp));
48347e946e7SWyllys Ingersoll 
484ab8176c2SWyllys Ingersoll 	/* Read fields individually because of 64-bit size diffs */
485ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, td->token_info.label,
486ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.label));
487ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, td->token_info.manufacturerID,
488ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.manufacturerID));
489ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, td->token_info.model,
490ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.model));
491ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, td->token_info.serialNumber,
492ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.serialNumber));
493ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.flags);
494ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulMaxSessionCount);
495ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulSessionCount);
496ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulRwSessionCount);
497ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulMaxPinLen);
498ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulMinPinLen);
499ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulTotalPublicMemory);
500ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulFreePublicMemory);
501ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulTotalPrivateMemory);
502ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_UINT32(fp, td->token_info.ulFreePrivateMemory);
503ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, &td->token_info.hardwareVersion,
504ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.hardwareVersion));
505ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, &td->token_info.firmwareVersion,
506ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.firmwareVersion));
507ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, td->token_info.utcTime,
508ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.utcTime));
509ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, td->user_pin_sha,
510ab8176c2SWyllys Ingersoll 	    sizeof (td->user_pin_sha));
511ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, td->so_pin_sha,
512ab8176c2SWyllys Ingersoll 	    sizeof (td->so_pin_sha));
513ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, td->next_token_object_name,
514ab8176c2SWyllys Ingersoll 	    sizeof (td->next_token_object_name));
515ab8176c2SWyllys Ingersoll 	READ_TOKEN_INFO_STR(fp, &td->tweak_vector,
516ab8176c2SWyllys Ingersoll 	    sizeof (td->tweak_vector));
51747e946e7SWyllys Ingersoll 
51847e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp), F_UNLCK);
51947e946e7SWyllys Ingersoll 	(void) fclose(fp);
52047e946e7SWyllys Ingersoll 
52147e946e7SWyllys Ingersoll 	if (rc == 0)
52247e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
52347e946e7SWyllys Ingersoll 	else
52447e946e7SWyllys Ingersoll 		rc = CKR_OK;
52547e946e7SWyllys Ingersoll 
52647e946e7SWyllys Ingersoll out_unlock:
52747e946e7SWyllys Ingersoll 	(void) XProcUnLock(xproclock);
52847e946e7SWyllys Ingersoll 
52947e946e7SWyllys Ingersoll out_nolock:
53047e946e7SWyllys Ingersoll 	return (rc);
53147e946e7SWyllys Ingersoll }
53247e946e7SWyllys Ingersoll 
533ab8176c2SWyllys Ingersoll 
534ab8176c2SWyllys Ingersoll #define	WRITE_TOKEN_INFO_STR(fp, rec, reclen) rc = fwrite(rec, reclen, 1, fp); \
535ab8176c2SWyllys Ingersoll 	if (rc != 1) { rc = CKR_FUNCTION_FAILED; goto done; }
536ab8176c2SWyllys Ingersoll 
537ab8176c2SWyllys Ingersoll #define	WRITE_TOKEN_INFO_UINT32(fp, rec) fieldval = (UINT32)rec; \
538ab8176c2SWyllys Ingersoll 	rc = fwrite(&fieldval, sizeof (UINT32), 1, fp); \
539ab8176c2SWyllys Ingersoll 	if (rc != 1) { rc = CKR_FUNCTION_FAILED; goto done; }
540ab8176c2SWyllys Ingersoll 
54147e946e7SWyllys Ingersoll CK_RV
save_token_data(TOKEN_DATA * td)54247e946e7SWyllys Ingersoll save_token_data(TOKEN_DATA *td)
54347e946e7SWyllys Ingersoll {
54447e946e7SWyllys Ingersoll 	FILE	*fp;
54547e946e7SWyllys Ingersoll 	CK_RV	rc;
54647e946e7SWyllys Ingersoll 	CK_BYTE	fname[MAXPATHLEN];
54747e946e7SWyllys Ingersoll 	char *p = get_tpm_keystore_path();
548ab8176c2SWyllys Ingersoll 	UINT32 fieldval;
54947e946e7SWyllys Ingersoll 
55047e946e7SWyllys Ingersoll 	if (p == NULL)
55147e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
55247e946e7SWyllys Ingersoll 
55347e946e7SWyllys Ingersoll 	(void) snprintf((char *)fname, sizeof (fname),
55447e946e7SWyllys Ingersoll 	    "%s/%s", p, TOKEN_DATA_FILE);
55547e946e7SWyllys Ingersoll 
55647e946e7SWyllys Ingersoll 	rc = XProcLock(xproclock);
55747e946e7SWyllys Ingersoll 	if (rc != CKR_OK)
55847e946e7SWyllys Ingersoll 		goto out_nolock;
55947e946e7SWyllys Ingersoll 
56047e946e7SWyllys Ingersoll 	fp = fopen((char *)fname, "w");
56147e946e7SWyllys Ingersoll 
56247e946e7SWyllys Ingersoll 	if (!fp) {
56347e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
56447e946e7SWyllys Ingersoll 		goto done;
56547e946e7SWyllys Ingersoll 	}
56647e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp), F_WRLCK)) {
56747e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
56847e946e7SWyllys Ingersoll 		(void) fclose(fp);
56947e946e7SWyllys Ingersoll 		goto done;
57047e946e7SWyllys Ingersoll 	}
57147e946e7SWyllys Ingersoll 	set_perm(fileno(fp));
57247e946e7SWyllys Ingersoll 
573ab8176c2SWyllys Ingersoll 	/* Write token fields individually to maintain sizes on 64 and 32 bit */
574ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, td->token_info.label,
575ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.label));
576ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, td->token_info.manufacturerID,
577ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.manufacturerID));
578ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, td->token_info.model,
579ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.model));
580ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, td->token_info.serialNumber,
581ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.serialNumber));
582ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.flags);
583ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulMaxSessionCount);
584ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulSessionCount);
585ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulRwSessionCount);
586ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulMaxPinLen);
587ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulMinPinLen);
588ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulTotalPublicMemory);
589ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulFreePublicMemory);
590ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulTotalPrivateMemory);
591ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_UINT32(fp, td->token_info.ulFreePrivateMemory);
592ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, &td->token_info.hardwareVersion,
593ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.hardwareVersion));
594ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, &td->token_info.firmwareVersion,
595ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.firmwareVersion));
596ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, td->token_info.utcTime,
597ab8176c2SWyllys Ingersoll 	    sizeof (td->token_info.utcTime));
598ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, td->user_pin_sha,
599ab8176c2SWyllys Ingersoll 	    sizeof (td->user_pin_sha));
600ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, td->so_pin_sha,
601ab8176c2SWyllys Ingersoll 	    sizeof (td->so_pin_sha));
602ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, td->next_token_object_name,
603ab8176c2SWyllys Ingersoll 	    sizeof (td->next_token_object_name));
604ab8176c2SWyllys Ingersoll 	WRITE_TOKEN_INFO_STR(fp, &td->tweak_vector,
605ab8176c2SWyllys Ingersoll 	    sizeof (td->tweak_vector));
606ab8176c2SWyllys Ingersoll 
60747e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp), F_UNLCK);
60847e946e7SWyllys Ingersoll 	(void) fclose(fp);
60947e946e7SWyllys Ingersoll 
61047e946e7SWyllys Ingersoll 	rc = CKR_OK;
61147e946e7SWyllys Ingersoll done:
61247e946e7SWyllys Ingersoll 	(void) XProcUnLock(xproclock);
61347e946e7SWyllys Ingersoll 
61447e946e7SWyllys Ingersoll out_nolock:
61547e946e7SWyllys Ingersoll 	return (rc);
61647e946e7SWyllys Ingersoll }
61747e946e7SWyllys Ingersoll 
61847e946e7SWyllys Ingersoll CK_RV
save_token_object(TSS_HCONTEXT hContext,OBJECT * obj)61947e946e7SWyllys Ingersoll save_token_object(TSS_HCONTEXT hContext, OBJECT *obj)
62047e946e7SWyllys Ingersoll {
62147e946e7SWyllys Ingersoll 	FILE	*fp = NULL;
62247e946e7SWyllys Ingersoll 	CK_BYTE	line[100];
62347e946e7SWyllys Ingersoll 	CK_RV	rc;
62447e946e7SWyllys Ingersoll 	CK_BYTE	fname[MAXPATHLEN];
62547e946e7SWyllys Ingersoll 	char *p = get_tpm_keystore_path();
62647e946e7SWyllys Ingersoll 
62747e946e7SWyllys Ingersoll 	if (p == NULL)
62847e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
62947e946e7SWyllys Ingersoll 
63047e946e7SWyllys Ingersoll 	if (object_is_private(obj) == TRUE)
63147e946e7SWyllys Ingersoll 		rc = save_private_token_object(hContext, obj);
63247e946e7SWyllys Ingersoll 	else
63347e946e7SWyllys Ingersoll 		rc = save_public_token_object(obj);
63447e946e7SWyllys Ingersoll 
63547e946e7SWyllys Ingersoll 	if (rc != CKR_OK)
63647e946e7SWyllys Ingersoll 		return (rc);
63747e946e7SWyllys Ingersoll 
63847e946e7SWyllys Ingersoll 	(void) snprintf((char *)fname, sizeof (fname),
63947e946e7SWyllys Ingersoll 	    "%s/%s/%s", p, TOKEN_OBJ_DIR, TOKEN_OBJ_INDEX_FILE);
64047e946e7SWyllys Ingersoll 
64147e946e7SWyllys Ingersoll 	fp = fopen((char *)fname, "r");
64247e946e7SWyllys Ingersoll 	if (fp) {
64347e946e7SWyllys Ingersoll 		if (lockfile(fileno(fp), F_RDLCK)) {
64447e946e7SWyllys Ingersoll 			(void) fclose(fp);
64547e946e7SWyllys Ingersoll 			return (CKR_FUNCTION_FAILED);
64647e946e7SWyllys Ingersoll 		}
64747e946e7SWyllys Ingersoll 		set_perm(fileno(fp));
64847e946e7SWyllys Ingersoll 		while (!feof(fp)) {
64947e946e7SWyllys Ingersoll 			(void) fgets((char *)line, 50, fp);
65047e946e7SWyllys Ingersoll 			if (!feof(fp)) {
65147e946e7SWyllys Ingersoll 				line[strlen((char *)line) - 1] = 0;
65247e946e7SWyllys Ingersoll 				if (strcmp((char *)line,
65347e946e7SWyllys Ingersoll 				    (char *)(obj->name)) == 0) {
65447e946e7SWyllys Ingersoll 					(void) lockfile(fileno(fp), F_UNLCK);
65547e946e7SWyllys Ingersoll 					(void) fclose(fp);
65647e946e7SWyllys Ingersoll 					return (CKR_OK);
65747e946e7SWyllys Ingersoll 				}
65847e946e7SWyllys Ingersoll 			}
65947e946e7SWyllys Ingersoll 		}
66047e946e7SWyllys Ingersoll 		(void) lockfile(fileno(fp), F_UNLCK);
66147e946e7SWyllys Ingersoll 		(void) fclose(fp);
66247e946e7SWyllys Ingersoll 	}
66347e946e7SWyllys Ingersoll 
66447e946e7SWyllys Ingersoll 	fp = fopen((char *)fname, "a");
66547e946e7SWyllys Ingersoll 	if (!fp)
66647e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
66747e946e7SWyllys Ingersoll 
66847e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp), F_WRLCK)) {
66947e946e7SWyllys Ingersoll 		(void) fclose(fp);
67047e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
67147e946e7SWyllys Ingersoll 	}
67247e946e7SWyllys Ingersoll 	set_perm(fileno(fp));
67347e946e7SWyllys Ingersoll 
67447e946e7SWyllys Ingersoll 	(void) fprintf(fp, "%s\n", obj->name);
67547e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp), F_UNLCK);
67647e946e7SWyllys Ingersoll 	(void) fclose(fp);
67747e946e7SWyllys Ingersoll 
67847e946e7SWyllys Ingersoll 	return (CKR_OK);
67947e946e7SWyllys Ingersoll }
68047e946e7SWyllys Ingersoll 
68147e946e7SWyllys Ingersoll CK_RV
save_public_token_object(OBJECT * obj)68247e946e7SWyllys Ingersoll save_public_token_object(OBJECT *obj)
68347e946e7SWyllys Ingersoll {
68447e946e7SWyllys Ingersoll 	FILE	*fp = NULL;
68547e946e7SWyllys Ingersoll 	CK_BYTE	*cleartxt = NULL;
68647e946e7SWyllys Ingersoll 	CK_BYTE	fname[MAXPATHLEN];
68733c15889SWyllys Ingersoll 	UINT32	cleartxt_len;
68847e946e7SWyllys Ingersoll 	CK_BBOOL	flag = FALSE;
68947e946e7SWyllys Ingersoll 	CK_RV	rc;
690ab8176c2SWyllys Ingersoll 	UINT32	total_len;
69133c15889SWyllys Ingersoll 
69247e946e7SWyllys Ingersoll 	char *p = get_tpm_keystore_path();
69347e946e7SWyllys Ingersoll 
69447e946e7SWyllys Ingersoll 	if (p == NULL)
69547e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
69647e946e7SWyllys Ingersoll 
69747e946e7SWyllys Ingersoll 	(void) snprintf((char *)fname, sizeof (fname),
69847e946e7SWyllys Ingersoll 	    "%s/%s/%s", p, TOKEN_OBJ_DIR, obj->name);
69947e946e7SWyllys Ingersoll 
70047e946e7SWyllys Ingersoll 	rc = object_flatten(obj, &cleartxt, &cleartxt_len);
70147e946e7SWyllys Ingersoll 	if (rc != CKR_OK)
70247e946e7SWyllys Ingersoll 		goto error;
70347e946e7SWyllys Ingersoll 
70447e946e7SWyllys Ingersoll 	fp = fopen((char *)fname, "w");
70547e946e7SWyllys Ingersoll 	if (!fp) {
70647e946e7SWyllys Ingersoll 		LogError("Error opening %s - %s", fname,
70747e946e7SWyllys Ingersoll 		    (char *)strerror(errno));
70847e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
70947e946e7SWyllys Ingersoll 		goto error;
71047e946e7SWyllys Ingersoll 	}
71147e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp), F_WRLCK)) {
71247e946e7SWyllys Ingersoll 		(void) fclose(fp);
71347e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
71447e946e7SWyllys Ingersoll 	}
71547e946e7SWyllys Ingersoll 
71647e946e7SWyllys Ingersoll 	set_perm(fileno(fp));
71747e946e7SWyllys Ingersoll 
71833c15889SWyllys Ingersoll 	total_len = cleartxt_len + sizeof (UINT32) + sizeof (CK_BBOOL);
71947e946e7SWyllys Ingersoll 
72033c15889SWyllys Ingersoll 	(void) fwrite(&total_len, sizeof (total_len), 1, fp);
72133c15889SWyllys Ingersoll 	(void) fwrite(&flag, sizeof (flag), 1, fp);
72247e946e7SWyllys Ingersoll 	(void) fwrite(cleartxt, cleartxt_len, 1, fp);
72347e946e7SWyllys Ingersoll 
72447e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp), F_UNLCK);
72547e946e7SWyllys Ingersoll 	(void) fclose(fp);
72647e946e7SWyllys Ingersoll 	free(cleartxt);
72747e946e7SWyllys Ingersoll 
72847e946e7SWyllys Ingersoll 	return (CKR_OK);
72947e946e7SWyllys Ingersoll 
73047e946e7SWyllys Ingersoll error:
73147e946e7SWyllys Ingersoll 	if (fp)
73247e946e7SWyllys Ingersoll 		(void) fclose(fp);
73347e946e7SWyllys Ingersoll 	if (cleartxt)
73447e946e7SWyllys Ingersoll 		free(cleartxt);
73547e946e7SWyllys Ingersoll 	return (rc);
73647e946e7SWyllys Ingersoll }
73747e946e7SWyllys Ingersoll 
73847e946e7SWyllys Ingersoll CK_RV
save_private_token_object(TSS_HCONTEXT hContext,OBJECT * obj)73947e946e7SWyllys Ingersoll save_private_token_object(TSS_HCONTEXT hContext, OBJECT *obj)
74047e946e7SWyllys Ingersoll {
74147e946e7SWyllys Ingersoll 	FILE *fp = NULL;
74247e946e7SWyllys Ingersoll 	CK_BYTE	*obj_data  = NULL;
74347e946e7SWyllys Ingersoll 	CK_BYTE	*cleartxt  = NULL;
74447e946e7SWyllys Ingersoll 	CK_BYTE	*ciphertxt = NULL;
74547e946e7SWyllys Ingersoll 	CK_BYTE	*ptr = NULL;
74647e946e7SWyllys Ingersoll 	CK_BYTE	fname[100];
74747e946e7SWyllys Ingersoll 	CK_BYTE	hash_sha[SHA1_DIGEST_LENGTH];
74847e946e7SWyllys Ingersoll 	CK_BBOOL	flag;
74947e946e7SWyllys Ingersoll 	CK_RV	rc;
75033c15889SWyllys Ingersoll 	CK_ULONG ciphertxt_len;
75133c15889SWyllys Ingersoll 	UINT32 cleartxt_len;
75233c15889SWyllys Ingersoll 	UINT32 padded_len;
753ab8176c2SWyllys Ingersoll 	UINT32	obj_data_len_32;
754ab8176c2SWyllys Ingersoll 	UINT32	total_len;
755ab8176c2SWyllys Ingersoll 	UINT32	chunksize, blocks;
756*b8ccc413SToomas Soome 	char	*p = get_tpm_keystore_path();
75747e946e7SWyllys Ingersoll 
75847e946e7SWyllys Ingersoll 	if (p == NULL)
75947e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
76047e946e7SWyllys Ingersoll 
76133c15889SWyllys Ingersoll 	rc = object_flatten(obj, &obj_data, &obj_data_len_32);
76247e946e7SWyllys Ingersoll 	if (rc != CKR_OK) {
76347e946e7SWyllys Ingersoll 		goto error;
76447e946e7SWyllys Ingersoll 	}
76547e946e7SWyllys Ingersoll 	/*
76647e946e7SWyllys Ingersoll 	 * format for the object file:
76747e946e7SWyllys Ingersoll 	 *    private flag
76847e946e7SWyllys Ingersoll 	 *	---- begin encrypted part	<--+
76933c15889SWyllys Ingersoll 	 *	length of object data (4 bytes)	|
77047e946e7SWyllys Ingersoll 	 *	object data			+---- sensitive part
77147e946e7SWyllys Ingersoll 	 *	SHA of (object data)		|
77247e946e7SWyllys Ingersoll 	 *	---- end encrypted part		<--+
77347e946e7SWyllys Ingersoll 	 */
77433c15889SWyllys Ingersoll 	if ((rc = compute_sha(obj_data, obj_data_len_32, hash_sha)) != CKR_OK)
77547e946e7SWyllys Ingersoll 		goto error;
77647e946e7SWyllys Ingersoll 
77747e946e7SWyllys Ingersoll 	/*
77847e946e7SWyllys Ingersoll 	 * RSA OAEP crypto uses chunks smaller than the max to make room
77947e946e7SWyllys Ingersoll 	 * for the hashes.
78047e946e7SWyllys Ingersoll 	 * chunksize = RSA_Modulus_Size - (2 * SHA1_DIGEST_SIZE + 2) - (4 - 1)
78147e946e7SWyllys Ingersoll 	 * == 209
78247e946e7SWyllys Ingersoll 	 */
78347e946e7SWyllys Ingersoll 	chunksize = RSA_BLOCK_SIZE - (2 * SHA1_DIGEST_LENGTH + 2) - 5;
78447e946e7SWyllys Ingersoll 
78533c15889SWyllys Ingersoll 	cleartxt_len = sizeof (UINT32) + obj_data_len_32 + SHA1_DIGEST_LENGTH;
78647e946e7SWyllys Ingersoll 
78747e946e7SWyllys Ingersoll 	blocks = cleartxt_len / chunksize + ((cleartxt_len % chunksize) > 0);
78847e946e7SWyllys Ingersoll 	padded_len   = RSA_BLOCK_SIZE * blocks;
78947e946e7SWyllys Ingersoll 
79047e946e7SWyllys Ingersoll 	cleartxt  = (CK_BYTE *)malloc(padded_len);
79147e946e7SWyllys Ingersoll 	ciphertxt = (CK_BYTE *)malloc(padded_len);
79247e946e7SWyllys Ingersoll 	if (!cleartxt || !ciphertxt) {
79347e946e7SWyllys Ingersoll 		rc = CKR_HOST_MEMORY;
79447e946e7SWyllys Ingersoll 		goto error;
79547e946e7SWyllys Ingersoll 	}
79647e946e7SWyllys Ingersoll 
79747e946e7SWyllys Ingersoll 	ciphertxt_len = padded_len;
79847e946e7SWyllys Ingersoll 
79947e946e7SWyllys Ingersoll 	ptr = cleartxt;
80033c15889SWyllys Ingersoll 	(void) memcpy(ptr, &obj_data_len_32, sizeof (UINT32));
80133c15889SWyllys Ingersoll 	ptr += sizeof (UINT32);
80247e946e7SWyllys Ingersoll 	(void) memcpy(ptr,  obj_data, obj_data_len_32);
80347e946e7SWyllys Ingersoll 	ptr += obj_data_len_32;
80447e946e7SWyllys Ingersoll 	(void) memcpy(ptr, hash_sha, SHA1_DIGEST_LENGTH);
80547e946e7SWyllys Ingersoll 
80647e946e7SWyllys Ingersoll 	(void) add_pkcs_padding(cleartxt + cleartxt_len, RSA_BLOCK_SIZE,
80747e946e7SWyllys Ingersoll 	    cleartxt_len, padded_len);
80847e946e7SWyllys Ingersoll 
80947e946e7SWyllys Ingersoll 	/* the encrypt function will compute the padded length */
81047e946e7SWyllys Ingersoll 	rc = tpm_encrypt_data(hContext, hPrivateLeafKey, cleartxt, cleartxt_len,
81147e946e7SWyllys Ingersoll 	    ciphertxt, &ciphertxt_len);
81247e946e7SWyllys Ingersoll 
81347e946e7SWyllys Ingersoll 	if (rc != CKR_OK) {
81447e946e7SWyllys Ingersoll 		goto error;
81547e946e7SWyllys Ingersoll 	}
81647e946e7SWyllys Ingersoll 
81747e946e7SWyllys Ingersoll 	(void) snprintf((char *)fname, sizeof (fname),
81847e946e7SWyllys Ingersoll 	    "%s/%s/%s", p, TOKEN_OBJ_DIR, obj->name);
81947e946e7SWyllys Ingersoll 
82047e946e7SWyllys Ingersoll 	fp = fopen((char *)fname, "w");
82147e946e7SWyllys Ingersoll 	if (!fp) {
82247e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
82347e946e7SWyllys Ingersoll 		goto error;
82447e946e7SWyllys Ingersoll 	}
82547e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp), F_WRLCK)) {
82647e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
82747e946e7SWyllys Ingersoll 		goto error;
82847e946e7SWyllys Ingersoll 	}
82947e946e7SWyllys Ingersoll 
83047e946e7SWyllys Ingersoll 	set_perm(fileno(fp));
83147e946e7SWyllys Ingersoll 
83233c15889SWyllys Ingersoll 	total_len = sizeof (UINT32) + sizeof (CK_BBOOL) + (UINT32)ciphertxt_len;
83347e946e7SWyllys Ingersoll 
83447e946e7SWyllys Ingersoll 	flag = TRUE;
83547e946e7SWyllys Ingersoll 
836ab8176c2SWyllys Ingersoll 	(void) fwrite(&total_len, sizeof (UINT32), 1, fp);
83747e946e7SWyllys Ingersoll 	(void) fwrite(&flag, sizeof (CK_BBOOL), 1, fp);
83847e946e7SWyllys Ingersoll 	(void) fwrite(ciphertxt, ciphertxt_len,    1, fp);
83947e946e7SWyllys Ingersoll 
84047e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp), F_UNLCK);
84147e946e7SWyllys Ingersoll 	(void) fclose(fp);
84247e946e7SWyllys Ingersoll 
84347e946e7SWyllys Ingersoll 	free(obj_data);
84447e946e7SWyllys Ingersoll 	free(cleartxt);
84547e946e7SWyllys Ingersoll 	free(ciphertxt);
84647e946e7SWyllys Ingersoll 	return (CKR_OK);
84747e946e7SWyllys Ingersoll 
84847e946e7SWyllys Ingersoll error:
84947e946e7SWyllys Ingersoll 	if (fp)
85047e946e7SWyllys Ingersoll 		(void) fclose(fp);
85147e946e7SWyllys Ingersoll 	if (obj_data)
85247e946e7SWyllys Ingersoll 		free(obj_data);
85347e946e7SWyllys Ingersoll 	if (cleartxt)
85447e946e7SWyllys Ingersoll 		free(cleartxt);
85547e946e7SWyllys Ingersoll 	if (ciphertxt)
85647e946e7SWyllys Ingersoll 		free(ciphertxt);
85747e946e7SWyllys Ingersoll 
85847e946e7SWyllys Ingersoll 	return (rc);
85947e946e7SWyllys Ingersoll }
86047e946e7SWyllys Ingersoll 
86147e946e7SWyllys Ingersoll CK_RV
load_public_token_objects(void)86247e946e7SWyllys Ingersoll load_public_token_objects(void)
86347e946e7SWyllys Ingersoll {
86447e946e7SWyllys Ingersoll 	FILE	*fp1 = NULL, *fp2 = NULL;
86547e946e7SWyllys Ingersoll 	CK_BYTE *buf = NULL;
86647e946e7SWyllys Ingersoll 	CK_BYTE tmp[MAXPATHLEN], fname[MAXPATHLEN], iname[MAXPATHLEN];
86747e946e7SWyllys Ingersoll 	CK_BBOOL priv;
868ab8176c2SWyllys Ingersoll 	UINT32 size;
86947e946e7SWyllys Ingersoll 	char *ksdir = get_tpm_keystore_path();
87047e946e7SWyllys Ingersoll 
87147e946e7SWyllys Ingersoll 	if (ksdir == NULL)
87247e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
87347e946e7SWyllys Ingersoll 
87447e946e7SWyllys Ingersoll 	(void) snprintf((char *)iname, sizeof (iname),
87547e946e7SWyllys Ingersoll 	    "%s/%s/%s", ksdir,
87647e946e7SWyllys Ingersoll 	    TOKEN_OBJ_DIR, TOKEN_OBJ_INDEX_FILE);
87747e946e7SWyllys Ingersoll 
87847e946e7SWyllys Ingersoll 	fp1 = fopen((char *)iname, "r");
87947e946e7SWyllys Ingersoll 	if (!fp1)
88047e946e7SWyllys Ingersoll 		return (CKR_OK);  // no token objects
88147e946e7SWyllys Ingersoll 
88247e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp1), F_RDLCK)) {
88347e946e7SWyllys Ingersoll 		(void) fclose(fp1);
88447e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
88547e946e7SWyllys Ingersoll 	}
88647e946e7SWyllys Ingersoll 
88747e946e7SWyllys Ingersoll 	while (!feof(fp1)) {
88847e946e7SWyllys Ingersoll 		(void) fgets((char *)tmp, 50, fp1);
88947e946e7SWyllys Ingersoll 		if (feof(fp1))
89047e946e7SWyllys Ingersoll 			break;
89147e946e7SWyllys Ingersoll 
89247e946e7SWyllys Ingersoll 		tmp[strlen((char *)tmp) - 1] = 0;
89347e946e7SWyllys Ingersoll 
89447e946e7SWyllys Ingersoll 		(void) snprintf((char *)fname, sizeof (fname),
89547e946e7SWyllys Ingersoll 		    "%s/%s/", ksdir, TOKEN_OBJ_DIR);
89647e946e7SWyllys Ingersoll 
89747e946e7SWyllys Ingersoll 		(void) strncat((char *)fname, (const char *)tmp,
89847e946e7SWyllys Ingersoll 		    (size_t)sizeof (fname));
89947e946e7SWyllys Ingersoll 
90047e946e7SWyllys Ingersoll 		fp2 = fopen((char *)fname, "r");
90147e946e7SWyllys Ingersoll 		if (!fp2)
90247e946e7SWyllys Ingersoll 			continue;
90347e946e7SWyllys Ingersoll 
904ab8176c2SWyllys Ingersoll 		(void) fread(&size, sizeof (UINT32), 1, fp2);
90547e946e7SWyllys Ingersoll 		(void) fread(&priv, sizeof (CK_BBOOL), 1, fp2);
90647e946e7SWyllys Ingersoll 		if (priv == TRUE) {
90747e946e7SWyllys Ingersoll 			(void) fclose(fp2);
90847e946e7SWyllys Ingersoll 			continue;
90947e946e7SWyllys Ingersoll 		}
91047e946e7SWyllys Ingersoll 
911ab8176c2SWyllys Ingersoll 		size = size - sizeof (UINT32) - sizeof (CK_BBOOL);
91247e946e7SWyllys Ingersoll 		buf = (CK_BYTE *)malloc(size);
91347e946e7SWyllys Ingersoll 		if (!buf) {
91447e946e7SWyllys Ingersoll 			(void) lockfile(fileno(fp1), F_UNLCK);
91547e946e7SWyllys Ingersoll 			(void) fclose(fp1);
91647e946e7SWyllys Ingersoll 			(void) fclose(fp2);
91747e946e7SWyllys Ingersoll 			return (CKR_HOST_MEMORY);
91847e946e7SWyllys Ingersoll 		}
91947e946e7SWyllys Ingersoll 
92047e946e7SWyllys Ingersoll 		(void) fread(buf, size, 1, fp2);
92147e946e7SWyllys Ingersoll 
92247e946e7SWyllys Ingersoll 		if (pthread_mutex_lock(&obj_list_mutex)) {
92347e946e7SWyllys Ingersoll 			(void) lockfile(fileno(fp1), F_UNLCK);
92447e946e7SWyllys Ingersoll 			(void) fclose(fp1);
92547e946e7SWyllys Ingersoll 			(void) fclose(fp2);
92647e946e7SWyllys Ingersoll 			free(buf);
92747e946e7SWyllys Ingersoll 			return (CKR_FUNCTION_FAILED);
92847e946e7SWyllys Ingersoll 		}
92947e946e7SWyllys Ingersoll 
93047e946e7SWyllys Ingersoll 		(void) object_mgr_restore_obj(buf, NULL);
93147e946e7SWyllys Ingersoll 
93247e946e7SWyllys Ingersoll 		(void) pthread_mutex_unlock(&obj_list_mutex);
93347e946e7SWyllys Ingersoll 		free(buf);
93447e946e7SWyllys Ingersoll 		(void) fclose(fp2);
93547e946e7SWyllys Ingersoll 	}
93647e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp1), F_UNLCK);
93747e946e7SWyllys Ingersoll 	(void) fclose(fp1);
93847e946e7SWyllys Ingersoll 
93947e946e7SWyllys Ingersoll 	return (CKR_OK);
94047e946e7SWyllys Ingersoll }
94147e946e7SWyllys Ingersoll 
94247e946e7SWyllys Ingersoll CK_RV
load_private_token_objects(TSS_HCONTEXT hContext)94347e946e7SWyllys Ingersoll load_private_token_objects(TSS_HCONTEXT hContext)
94447e946e7SWyllys Ingersoll {
94547e946e7SWyllys Ingersoll 	FILE *fp1 = NULL, *fp2 = NULL;
94647e946e7SWyllys Ingersoll 	CK_BYTE *buf = NULL;
94747e946e7SWyllys Ingersoll 	CK_BYTE tmp[MAXPATHLEN], fname[MAXPATHLEN], iname[MAXPATHLEN];
94847e946e7SWyllys Ingersoll 	CK_BBOOL priv;
949ab8176c2SWyllys Ingersoll 	UINT32 size;
95047e946e7SWyllys Ingersoll 	CK_RV rc;
95147e946e7SWyllys Ingersoll 	char *ksdir = get_tpm_keystore_path();
95247e946e7SWyllys Ingersoll 
95347e946e7SWyllys Ingersoll 	if (ksdir == NULL)
95447e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
95547e946e7SWyllys Ingersoll 
95647e946e7SWyllys Ingersoll 	(void) snprintf((char *)iname, sizeof (iname),
95747e946e7SWyllys Ingersoll 	    "%s/%s/%s", ksdir, TOKEN_OBJ_DIR, TOKEN_OBJ_INDEX_FILE);
95847e946e7SWyllys Ingersoll 
95947e946e7SWyllys Ingersoll 	fp1 = fopen((char *)iname, "r");
96047e946e7SWyllys Ingersoll 	if (!fp1)
96147e946e7SWyllys Ingersoll 		return (CKR_OK);
96247e946e7SWyllys Ingersoll 
96347e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp1), F_RDLCK)) {
96447e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
96547e946e7SWyllys Ingersoll 		goto error;
96647e946e7SWyllys Ingersoll 	}
96747e946e7SWyllys Ingersoll 
96847e946e7SWyllys Ingersoll 	while (!feof(fp1)) {
96947e946e7SWyllys Ingersoll 		(void) fgets((char *)tmp, sizeof (tmp), fp1);
97047e946e7SWyllys Ingersoll 		if (feof(fp1))
97147e946e7SWyllys Ingersoll 			break;
97247e946e7SWyllys Ingersoll 
97347e946e7SWyllys Ingersoll 		tmp[strlen((char *)tmp) - 1] = 0;
97447e946e7SWyllys Ingersoll 
97547e946e7SWyllys Ingersoll 		(void) snprintf((char *)fname, sizeof (fname),
97647e946e7SWyllys Ingersoll 		    "%s/%s/%s", ksdir, TOKEN_OBJ_DIR, tmp);
97747e946e7SWyllys Ingersoll 
97847e946e7SWyllys Ingersoll 		fp2 = fopen((char *)fname, "r");
97947e946e7SWyllys Ingersoll 		if (!fp2)
98047e946e7SWyllys Ingersoll 			continue;
98147e946e7SWyllys Ingersoll 
982ab8176c2SWyllys Ingersoll 		(void) fread(&size, sizeof (UINT32), 1, fp2);
98347e946e7SWyllys Ingersoll 		(void) fread(&priv, sizeof (CK_BBOOL), 1, fp2);
98447e946e7SWyllys Ingersoll 		if (priv == FALSE) {
98547e946e7SWyllys Ingersoll 			(void) fclose(fp2);
98647e946e7SWyllys Ingersoll 			continue;
98747e946e7SWyllys Ingersoll 		}
98847e946e7SWyllys Ingersoll 
989ab8176c2SWyllys Ingersoll 		size = size - sizeof (UINT32) - sizeof (CK_BBOOL);
99047e946e7SWyllys Ingersoll 		buf = (CK_BYTE *)malloc(size);
99147e946e7SWyllys Ingersoll 		if (!buf) {
99247e946e7SWyllys Ingersoll 			rc = CKR_HOST_MEMORY;
99347e946e7SWyllys Ingersoll 			goto error;
99447e946e7SWyllys Ingersoll 		}
99547e946e7SWyllys Ingersoll 
99647e946e7SWyllys Ingersoll 		rc = fread((char *)buf, size, 1, fp2);
99747e946e7SWyllys Ingersoll 		if (rc != 1) {
99847e946e7SWyllys Ingersoll 			rc = CKR_FUNCTION_FAILED;
99947e946e7SWyllys Ingersoll 			goto error;
100047e946e7SWyllys Ingersoll 		}
100147e946e7SWyllys Ingersoll 
100247e946e7SWyllys Ingersoll 		if (pthread_mutex_lock(&obj_list_mutex)) {
100347e946e7SWyllys Ingersoll 			rc = CKR_FUNCTION_FAILED;
100447e946e7SWyllys Ingersoll 			goto error;
100547e946e7SWyllys Ingersoll 		}
100647e946e7SWyllys Ingersoll 		rc = restore_private_token_object(hContext, buf, size, NULL);
100747e946e7SWyllys Ingersoll 		(void) pthread_mutex_unlock(&obj_list_mutex);
100847e946e7SWyllys Ingersoll 		if (rc != CKR_OK)
100947e946e7SWyllys Ingersoll 			goto error;
101047e946e7SWyllys Ingersoll 
101147e946e7SWyllys Ingersoll 		free(buf);
101247e946e7SWyllys Ingersoll 		(void) fclose(fp2);
101347e946e7SWyllys Ingersoll 	}
101447e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp1), F_UNLCK);
101547e946e7SWyllys Ingersoll 	(void) fclose(fp1);
101647e946e7SWyllys Ingersoll 
101747e946e7SWyllys Ingersoll 	return (CKR_OK);
101847e946e7SWyllys Ingersoll 
101947e946e7SWyllys Ingersoll error:
102047e946e7SWyllys Ingersoll 	if (buf)
102147e946e7SWyllys Ingersoll 		free(buf);
102247e946e7SWyllys Ingersoll 	if (fp1) {
102347e946e7SWyllys Ingersoll 		(void) lockfile(fileno(fp1), F_UNLCK);
102447e946e7SWyllys Ingersoll 		(void) fclose(fp1);
102547e946e7SWyllys Ingersoll 	}
102647e946e7SWyllys Ingersoll 	if (fp2)
102747e946e7SWyllys Ingersoll 		(void) fclose(fp2);
102847e946e7SWyllys Ingersoll 	return (rc);
102947e946e7SWyllys Ingersoll }
103047e946e7SWyllys Ingersoll 
103147e946e7SWyllys Ingersoll static CK_RV
restore_private_token_object(TSS_HCONTEXT hContext,CK_BYTE * data,CK_ULONG len,OBJECT * pObj)103247e946e7SWyllys Ingersoll restore_private_token_object(
103347e946e7SWyllys Ingersoll 	TSS_HCONTEXT hContext,
103447e946e7SWyllys Ingersoll 	CK_BYTE  *data,
103547e946e7SWyllys Ingersoll 	CK_ULONG len,
103647e946e7SWyllys Ingersoll 	OBJECT   *pObj)
103747e946e7SWyllys Ingersoll {
103847e946e7SWyllys Ingersoll 	CK_BYTE * cleartxt  = NULL;
103947e946e7SWyllys Ingersoll 	CK_BYTE * obj_data  = NULL;
104047e946e7SWyllys Ingersoll 	CK_BYTE *ptr = NULL;
104147e946e7SWyllys Ingersoll 	CK_BYTE hash_sha[SHA1_DIGEST_LENGTH];
104233c15889SWyllys Ingersoll 	UINT32 cleartxt_len;
104333c15889SWyllys Ingersoll 	UINT32 obj_data_len;
104447e946e7SWyllys Ingersoll 	CK_RV rc;
104547e946e7SWyllys Ingersoll 
104647e946e7SWyllys Ingersoll 	/*
104747e946e7SWyllys Ingersoll 	 * format for the object data:
104847e946e7SWyllys Ingersoll 	 *    (private flag has already been read at this point)
104947e946e7SWyllys Ingersoll 	 *    ---- begin encrypted part
105033c15889SWyllys Ingersoll 	 *	length of object data (4 bytes)
105147e946e7SWyllys Ingersoll 	 *	object data
105247e946e7SWyllys Ingersoll 	 *	SHA of object data
105347e946e7SWyllys Ingersoll 	 *    ---- end encrypted part
105447e946e7SWyllys Ingersoll 	 */
105547e946e7SWyllys Ingersoll 
105647e946e7SWyllys Ingersoll 	cleartxt_len = len;
105747e946e7SWyllys Ingersoll 
105847e946e7SWyllys Ingersoll 	cleartxt = (CK_BYTE *)malloc(len);
105947e946e7SWyllys Ingersoll 	if (!cleartxt) {
106047e946e7SWyllys Ingersoll 		rc = CKR_HOST_MEMORY;
106147e946e7SWyllys Ingersoll 		goto done;
106247e946e7SWyllys Ingersoll 	}
106347e946e7SWyllys Ingersoll 
106447e946e7SWyllys Ingersoll 	rc = tpm_decrypt_data(hContext, hPrivateLeafKey, data, len,
106547e946e7SWyllys Ingersoll 	    cleartxt, &len);
106647e946e7SWyllys Ingersoll 
106747e946e7SWyllys Ingersoll 	if (rc != CKR_OK) {
106847e946e7SWyllys Ingersoll 		goto done;
106947e946e7SWyllys Ingersoll 	}
107047e946e7SWyllys Ingersoll 
107147e946e7SWyllys Ingersoll 	(void) strip_pkcs_padding(cleartxt, len, &cleartxt_len);
107247e946e7SWyllys Ingersoll 
107347e946e7SWyllys Ingersoll 	if (cleartxt_len > len) {
107447e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
107547e946e7SWyllys Ingersoll 		goto done;
107647e946e7SWyllys Ingersoll 	}
107747e946e7SWyllys Ingersoll 
107847e946e7SWyllys Ingersoll 	ptr = cleartxt;
107947e946e7SWyllys Ingersoll 
108033c15889SWyllys Ingersoll 	bcopy(ptr, &obj_data_len, sizeof (UINT32));
108133c15889SWyllys Ingersoll 	ptr += sizeof (UINT32);
108247e946e7SWyllys Ingersoll 	obj_data = ptr;
108347e946e7SWyllys Ingersoll 
108447e946e7SWyllys Ingersoll 	if ((rc = compute_sha(ptr, obj_data_len, hash_sha)) != CKR_OK)
108547e946e7SWyllys Ingersoll 		goto done;
108647e946e7SWyllys Ingersoll 	ptr += obj_data_len;
108747e946e7SWyllys Ingersoll 
108833c15889SWyllys Ingersoll 	if (memcmp((const void *)ptr, (const void *)hash_sha,
108933c15889SWyllys Ingersoll 	    (size_t)SHA1_DIGEST_LENGTH) != 0) {
109047e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
109147e946e7SWyllys Ingersoll 		goto done;
109247e946e7SWyllys Ingersoll 	}
109347e946e7SWyllys Ingersoll 
109447e946e7SWyllys Ingersoll 	(void) object_mgr_restore_obj(obj_data, pObj);
109547e946e7SWyllys Ingersoll 	rc = CKR_OK;
109647e946e7SWyllys Ingersoll done:
109747e946e7SWyllys Ingersoll 	if (cleartxt)
109847e946e7SWyllys Ingersoll 		free(cleartxt);
109947e946e7SWyllys Ingersoll 
110047e946e7SWyllys Ingersoll 	return (rc);
110147e946e7SWyllys Ingersoll }
110247e946e7SWyllys Ingersoll 
110347e946e7SWyllys Ingersoll CK_RV
reload_token_object(TSS_HCONTEXT hContext,OBJECT * obj)110447e946e7SWyllys Ingersoll reload_token_object(TSS_HCONTEXT hContext, OBJECT *obj)
110547e946e7SWyllys Ingersoll {
110647e946e7SWyllys Ingersoll 	FILE *fp = NULL;
110747e946e7SWyllys Ingersoll 	CK_BYTE *buf = NULL;
110847e946e7SWyllys Ingersoll 	CK_BYTE fname[MAXPATHLEN];
110947e946e7SWyllys Ingersoll 	CK_BBOOL priv;
1110ab8176c2SWyllys Ingersoll 	UINT32 size;
111147e946e7SWyllys Ingersoll 	CK_RV rc;
111247e946e7SWyllys Ingersoll 	char *p = get_tpm_keystore_path();
111347e946e7SWyllys Ingersoll 
111447e946e7SWyllys Ingersoll 	if (p == NULL)
111547e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
111647e946e7SWyllys Ingersoll 
111747e946e7SWyllys Ingersoll 	(void) memset((char *)fname, 0x0, sizeof (fname));
111847e946e7SWyllys Ingersoll 
111947e946e7SWyllys Ingersoll 	(void) snprintf((char *)fname, sizeof (fname),
112047e946e7SWyllys Ingersoll 	    "%s/%s/", p, TOKEN_OBJ_DIR);
112147e946e7SWyllys Ingersoll 
112247e946e7SWyllys Ingersoll 	(void) strncat((char *)fname, (char *)obj->name, sizeof (fname));
112347e946e7SWyllys Ingersoll 
112447e946e7SWyllys Ingersoll 	fp = fopen((char *)fname, "r");
112547e946e7SWyllys Ingersoll 	if (!fp) {
112647e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
112747e946e7SWyllys Ingersoll 		goto done;
112847e946e7SWyllys Ingersoll 	}
112947e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp), F_RDLCK)) {
113047e946e7SWyllys Ingersoll 		rc = CKR_FUNCTION_FAILED;
113147e946e7SWyllys Ingersoll 		goto done;
113247e946e7SWyllys Ingersoll 	}
113347e946e7SWyllys Ingersoll 
113447e946e7SWyllys Ingersoll 	set_perm(fileno(fp));
113547e946e7SWyllys Ingersoll 
1136ab8176c2SWyllys Ingersoll 	(void) fread(&size, sizeof (UINT32), 1, fp);
113747e946e7SWyllys Ingersoll 	(void) fread(&priv, sizeof (CK_BBOOL), 1, fp);
113847e946e7SWyllys Ingersoll 
1139ab8176c2SWyllys Ingersoll 	size = size - sizeof (UINT32) - sizeof (CK_BBOOL);
114047e946e7SWyllys Ingersoll 
114147e946e7SWyllys Ingersoll 	buf = (CK_BYTE *)malloc(size);
114247e946e7SWyllys Ingersoll 	if (!buf) {
114347e946e7SWyllys Ingersoll 		rc = CKR_HOST_MEMORY;
114447e946e7SWyllys Ingersoll 		goto done;
114547e946e7SWyllys Ingersoll 	}
114647e946e7SWyllys Ingersoll 
114747e946e7SWyllys Ingersoll 	(void) fread(buf, size, 1, fp);
114847e946e7SWyllys Ingersoll 
114947e946e7SWyllys Ingersoll 	if (priv) {
1150ab8176c2SWyllys Ingersoll 		rc = restore_private_token_object(hContext, buf, size, obj);
115147e946e7SWyllys Ingersoll 	} else {
115247e946e7SWyllys Ingersoll 		rc = object_mgr_restore_obj(buf, obj);
115347e946e7SWyllys Ingersoll 	}
115447e946e7SWyllys Ingersoll 
115547e946e7SWyllys Ingersoll done:
115647e946e7SWyllys Ingersoll 	if (fp) {
115747e946e7SWyllys Ingersoll 		(void) lockfile(fileno(fp), F_UNLCK);
115847e946e7SWyllys Ingersoll 		(void) fclose(fp);
115947e946e7SWyllys Ingersoll 	}
116047e946e7SWyllys Ingersoll 	if (buf)
116147e946e7SWyllys Ingersoll 		free(buf);
116247e946e7SWyllys Ingersoll 	return (rc);
116347e946e7SWyllys Ingersoll }
116447e946e7SWyllys Ingersoll 
116547e946e7SWyllys Ingersoll static int
islink(char * fname)116647e946e7SWyllys Ingersoll islink(char *fname)
116747e946e7SWyllys Ingersoll {
116847e946e7SWyllys Ingersoll 	struct stat st;
116947e946e7SWyllys Ingersoll 
117047e946e7SWyllys Ingersoll 	if (stat((const char *)fname, &st))
117147e946e7SWyllys Ingersoll 		return (-1);
117247e946e7SWyllys Ingersoll 	else if (S_ISLNK(st.st_mode))
117347e946e7SWyllys Ingersoll 		return (1);
117447e946e7SWyllys Ingersoll 	return (0);
117547e946e7SWyllys Ingersoll }
117647e946e7SWyllys Ingersoll 
117747e946e7SWyllys Ingersoll CK_RV
delete_token_object(OBJECT * obj)117847e946e7SWyllys Ingersoll delete_token_object(OBJECT *obj)
117947e946e7SWyllys Ingersoll {
118047e946e7SWyllys Ingersoll 	FILE *fp1, *fp2;
118147e946e7SWyllys Ingersoll 	CK_BYTE line[100];
118247e946e7SWyllys Ingersoll 	char objidx[MAXPATHLEN], idxtmp[MAXPATHLEN], fname[MAXPATHLEN];
118347e946e7SWyllys Ingersoll 	char *ksdir = get_tpm_keystore_path();
118447e946e7SWyllys Ingersoll 
118547e946e7SWyllys Ingersoll 	if (ksdir == NULL)
118647e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
118747e946e7SWyllys Ingersoll 
118847e946e7SWyllys Ingersoll 	(void) snprintf(objidx, sizeof (objidx),
118947e946e7SWyllys Ingersoll 	    "%s/%s/%s", ksdir, TOKEN_OBJ_DIR, TOKEN_OBJ_INDEX_FILE);
119047e946e7SWyllys Ingersoll 
119147e946e7SWyllys Ingersoll 	(void) snprintf(idxtmp, sizeof (idxtmp),
119247e946e7SWyllys Ingersoll 	    "%s/IDX.TMP", ksdir, TOKEN_OBJ_DIR);
119347e946e7SWyllys Ingersoll 
119447e946e7SWyllys Ingersoll 	/*
119547e946e7SWyllys Ingersoll 	 * If either file is a link, fail.
119647e946e7SWyllys Ingersoll 	 */
119747e946e7SWyllys Ingersoll 	if (islink(objidx) != 0)
119847e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
119947e946e7SWyllys Ingersoll 
120086959661SWyllys Ingersoll 	/*
120186959661SWyllys Ingersoll 	 * idxtmp is a temporary file (and should not exist yet), only fail
120286959661SWyllys Ingersoll 	 * if it is already an existing link.
120386959661SWyllys Ingersoll 	 */
120486959661SWyllys Ingersoll 	if (islink(idxtmp) == 1)
120547e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
120647e946e7SWyllys Ingersoll 
120747e946e7SWyllys Ingersoll 	fp1 = fopen(objidx, "r");
120847e946e7SWyllys Ingersoll 	fp2 = fopen(idxtmp, "w");
120947e946e7SWyllys Ingersoll 	if (!fp1 || !fp2) {
121047e946e7SWyllys Ingersoll 		if (fp1)
121147e946e7SWyllys Ingersoll 			(void) fclose(fp1);
121247e946e7SWyllys Ingersoll 		if (fp2)
121347e946e7SWyllys Ingersoll 			(void) fclose(fp2);
121447e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
121547e946e7SWyllys Ingersoll 	}
121647e946e7SWyllys Ingersoll 
121747e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp1), F_RDLCK)) {
121847e946e7SWyllys Ingersoll 		(void) fclose(fp1);
121947e946e7SWyllys Ingersoll 		(void) fclose(fp2);
122047e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
122147e946e7SWyllys Ingersoll 	}
122247e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp2), F_WRLCK)) {
122347e946e7SWyllys Ingersoll 		(void) lockfile(fileno(fp1), F_UNLCK);
122447e946e7SWyllys Ingersoll 		(void) fclose(fp1);
122547e946e7SWyllys Ingersoll 		(void) fclose(fp2);
122647e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
122747e946e7SWyllys Ingersoll 	}
122847e946e7SWyllys Ingersoll 	set_perm(fileno(fp2));
122947e946e7SWyllys Ingersoll 
123047e946e7SWyllys Ingersoll 	while (!feof(fp1)) {
123147e946e7SWyllys Ingersoll 		(void) fgets((char *)line, 50, fp1);
123247e946e7SWyllys Ingersoll 		if (!feof(fp1)) {
123347e946e7SWyllys Ingersoll 			line[ strlen((char *)line)-1 ] = 0;
123447e946e7SWyllys Ingersoll 			if (strcmp((char *)line, (char *)obj->name))
123547e946e7SWyllys Ingersoll 				(void) fprintf(fp2, "%s\n", line);
123647e946e7SWyllys Ingersoll 		}
123747e946e7SWyllys Ingersoll 	}
123847e946e7SWyllys Ingersoll 
123947e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp1), F_UNLCK);
124047e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp2), F_UNLCK);
124147e946e7SWyllys Ingersoll 	(void) fclose(fp1);
124247e946e7SWyllys Ingersoll 	(void) fclose(fp2);
124347e946e7SWyllys Ingersoll 
124447e946e7SWyllys Ingersoll 	fp2 = fopen(objidx, "w");
124547e946e7SWyllys Ingersoll 	fp1 = fopen(idxtmp, "r");
124647e946e7SWyllys Ingersoll 	if (!fp1 || !fp2) {
124747e946e7SWyllys Ingersoll 		if (fp1)
124847e946e7SWyllys Ingersoll 			(void) fclose(fp1);
124947e946e7SWyllys Ingersoll 		if (fp2)
125047e946e7SWyllys Ingersoll 			(void) fclose(fp2);
125147e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
125247e946e7SWyllys Ingersoll 	}
125347e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp1), F_RDLCK)) {
125447e946e7SWyllys Ingersoll 		(void) fclose(fp1);
125547e946e7SWyllys Ingersoll 		(void) fclose(fp2);
125647e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
125747e946e7SWyllys Ingersoll 	}
125847e946e7SWyllys Ingersoll 	if (lockfile(fileno(fp2), F_WRLCK)) {
125947e946e7SWyllys Ingersoll 		(void) lockfile(fileno(fp1), F_UNLCK);
126047e946e7SWyllys Ingersoll 		(void) fclose(fp1);
126147e946e7SWyllys Ingersoll 		(void) fclose(fp2);
126247e946e7SWyllys Ingersoll 		return (CKR_FUNCTION_FAILED);
126347e946e7SWyllys Ingersoll 	}
126447e946e7SWyllys Ingersoll 
126547e946e7SWyllys Ingersoll 	set_perm(fileno(fp2));
126647e946e7SWyllys Ingersoll 
126747e946e7SWyllys Ingersoll 	while (!feof(fp1)) {
126847e946e7SWyllys Ingersoll 		(void) fgets((char *)line, 50, fp1);
126947e946e7SWyllys Ingersoll 		if (!feof(fp1))
127047e946e7SWyllys Ingersoll 			(void) fprintf(fp2, "%s", (char *)line);
127147e946e7SWyllys Ingersoll 	}
127247e946e7SWyllys Ingersoll 
127347e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp1), F_UNLCK);
127447e946e7SWyllys Ingersoll 	(void) lockfile(fileno(fp2), F_UNLCK);
127547e946e7SWyllys Ingersoll 	(void) fclose(fp1);
127647e946e7SWyllys Ingersoll 	(void) fclose(fp2);
127747e946e7SWyllys Ingersoll 
127847e946e7SWyllys Ingersoll 	(void) snprintf(fname, sizeof (fname),
127947e946e7SWyllys Ingersoll 	    "%s/%s/%s", ksdir, TOKEN_OBJ_DIR, (char *)obj->name);
128047e946e7SWyllys Ingersoll 
128147e946e7SWyllys Ingersoll 	(void) unlink(fname);
128247e946e7SWyllys Ingersoll 	return (CKR_OK);
128347e946e7SWyllys Ingersoll }
1284