xref: /illumos-gate/usr/src/lib/pkcs11/pkcs11_softtoken/common/softKeystoreUtil.c (revision 33efde4275d24731ef87927237b0ffb0630b6b2d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23  * Copyright 2018, Joyent, Inc.
24  */
25 
26 /*
27  * Functions used for manipulating the keystore
28  */
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <errno.h>
33 #include <sys/stat.h>
34 #include <fcntl.h>
35 #include <time.h>
36 #include <unistd.h>
37 #include <pwd.h>
38 #include <sys/types.h>
39 #include <dirent.h>
40 #include <limits.h>
41 #include <libgen.h>
42 #include <strings.h>
43 #include <security/cryptoki.h>
44 #include <cryptoutil.h>
45 #include "softGlobal.h"
46 #include "softObject.h"
47 #include "softSession.h"
48 #include "softKeystore.h"
49 #include "softKeystoreUtil.h"
50 
51 #define	MAXPATHLEN	1024
52 #define	SUNW_PATH	".sunw"		/* top level Sun directory */
53 #define	KEYSTORE_PATH	"pkcs11_softtoken"	/* keystore directory */
54 #define	PUB_OBJ_DIR	"public"	/* directory for public objects */
55 #define	PRI_OBJ_DIR	"private"	/* directory for private objects */
56 #define	DS_FILE		"objstore_info"	/* keystore description file */
57 #define	TMP_DS_FILE	"t_info"	/* temp name for keystore desc. file */
58 #define	OBJ_PREFIX	"obj"	/* prefix of the keystore object file names */
59 #define	OBJ_PREFIX_LEN	sizeof (OBJ_PREFIX) - 1	/* length of prefix */
60 #define	TMP_OBJ_PREFIX	"t_o"	/* prefix of the temp object file names */
61 
62 /*
63  * KEYSTORE DESCRIPTION FILE:
64  *
65  * The following describes the content of the keystore description file
66  *
67  * The order AND data type of the fields are very important.
68  * All the code in this file assume that they are in the order specified
69  * below.  If either order of the fields or their data type changed,
70  * you must make sure the ALL the pre-define values are still valid
71  *
72  * 1) PKCS#11 release number.  It's 2.20 in this release (uchar_t[32])
73  * 2) keystore version number: used for synchronizing when different
74  *    processes access the keystore at the same time.  It is incremented
75  *    when there is a change to the keystore. (uint_32)
76  * 3) monotonic-counter: last counter value for name of token object file.
77  *    used for assigning unique name to each token (uint_32)
78  * 4) salt used for generating encryption key (uint_16)
79  * 5) salt used for generating key used for doing HMAC (uint_16)
80  * 6) Length of salt used for generating hashed pin (length of salt
81  *    is variable)
82  * 7) Salt used for generating hashed pin.
83  * 8) Hashed pin len (length of hashed pin could be variable, the offset of
84  *    where this value lives in the file is calculated at run time)
85  * 9) Hashed pin
86  *
87  */
88 
89 /* Keystore description file pre-defined values */
90 #define	KS_PKCS11_VER		"2.20"
91 #define	KS_PKCS11_OFFSET	0
92 #define	KS_PKCS11_VER_SIZE	32
93 
94 #define	KS_VER_OFFSET		(KS_PKCS11_OFFSET + KS_PKCS11_VER_SIZE)
95 #define	KS_VER_SIZE	4	/* size in bytes of keystore version value */
96 
97 #define	KS_COUNTER_OFFSET	(KS_VER_OFFSET + KS_VER_SIZE)
98 #define	KS_COUNTER_SIZE	4	/* size in bytes of the monotonic counter */
99 
100 #define	KS_KEY_SALT_OFFSET	(KS_COUNTER_OFFSET + KS_COUNTER_SIZE)
101 #define	KS_KEY_SALT_SIZE	PBKD2_SALT_SIZE
102 
103 #define	KS_HMAC_SALT_OFFSET	(KS_KEY_SALT_OFFSET + KS_KEY_SALT_SIZE)
104 #define	KS_HMAC_SALT_SIZE	PBKD2_SALT_SIZE
105 
106 /* Salt for hashed pin */
107 #define	KS_HASHED_PIN_SALT_LEN_OFFSET (KS_HMAC_SALT_OFFSET + KS_HMAC_SALT_SIZE)
108 #define	KS_HASHED_PIN_SALT_LEN_SIZE 8 /* stores length of hashed pin salt */
109 
110 #define	KS_HASHED_PIN_SALT_OFFSET \
111 		(KS_HASHED_PIN_SALT_LEN_OFFSET + KS_HASHED_PIN_SALT_LEN_SIZE)
112 
113 /*
114  * hashed pin
115  *
116  * hashed_pin length offset will be calculated at run time since
117  * there's the hashed pin salt size is variable.
118  *
119  * The offset will be calculated at run time by calling the
120  * function calculate_hashed_pin_offset()
121  */
122 static off_t	ks_hashed_pinlen_offset = -1;
123 #define	KS_HASHED_PINLEN_SIZE	8
124 
125 /* End of Keystore description file pre-defined values */
126 
127 /*
128  * Metadata for each object
129  *
130  * The order AND data type of all the fields is very important.
131  * All the code in this file assume that they are in the order specified
132  * below.  If either order of the fields or their data type is changed,
133  * you must make sure the following pre-define value is still valid
134  * Each object will have the meta data at the beginning of the object file.
135  *
136  * 1) object_version: used by softtoken to see if the object
137  *    has been modified since it last reads it. (uint_32)
138  * 2) iv: initialization vector for encrypted data in the object.  This
139  *    value will be 0 for public objects.  (uchar_t[16])
140  * 3) obj_hmac: keyed hash as verifier to detect private object
141  *    being tampered this value will be 0 for public objects (uchar_t[16])
142  */
143 
144 /* Object metadata pre-defined values */
145 #define	OBJ_VER_OFFSET	0
146 #define	OBJ_VER_SIZE	4	/* size of object version in bytes */
147 #define	OBJ_IV_OFFSET	(OBJ_VER_OFFSET + OBJ_VER_SIZE)
148 #define	OBJ_IV_SIZE	16
149 #define	OBJ_HMAC_OFFSET	(OBJ_IV_OFFSET + OBJ_IV_SIZE)
150 #define	OBJ_HMAC_SIZE	16	/* MD5 HMAC keyed hash */
151 #define	OBJ_DATA_OFFSET	(OBJ_HMAC_OFFSET + OBJ_HMAC_SIZE)
152 /* End of object metadata pre-defined values */
153 
154 #define	ALTERNATE_KEYSTORE_PATH	"SOFTTOKEN_DIR"
155 
156 static soft_object_t	*enc_key = NULL;
157 static soft_object_t	*hmac_key = NULL;
158 static char		keystore_path[MAXPATHLEN];
159 static boolean_t	keystore_path_initialized = B_FALSE;
160 static int		desc_fd = 0;
161 
162 static char *
get_keystore_path()163 get_keystore_path()
164 {
165 	char *home = getenv("HOME");
166 	char *alt = getenv(ALTERNATE_KEYSTORE_PATH);
167 
168 	if (keystore_path_initialized) {
169 		return (keystore_path);
170 	}
171 
172 	bzero(keystore_path, sizeof (keystore_path));
173 	/*
174 	 * If it isn't set or is set to the empty string use the
175 	 * default location.  We need to check for the empty string
176 	 * because some users "unset" environment variables by giving
177 	 * them no value, this isn't the same thing as removing it
178 	 * from the environment.
179 	 *
180 	 * We don't want that to attempt to open /.sunw/pkcs11_sofftoken
181 	 */
182 	if ((alt != NULL) && (strcmp(alt, "") != 0)) {
183 		(void) snprintf(keystore_path, MAXPATHLEN, "%s/%s",
184 		    alt, KEYSTORE_PATH);
185 		keystore_path_initialized = B_TRUE;
186 	} else if ((home != NULL) && (strcmp(home, "") != 0)) {
187 		/* alternate path not specified, try user's home dir */
188 		(void) snprintf(keystore_path, MAXPATHLEN, "%s/%s/%s",
189 		    home, SUNW_PATH, KEYSTORE_PATH);
190 		keystore_path_initialized = B_TRUE;
191 	}
192 	return (keystore_path);
193 }
194 
195 static char *
get_pub_obj_path(char * name)196 get_pub_obj_path(char *name)
197 {
198 	bzero(name, sizeof (name));
199 	(void) snprintf(name, MAXPATHLEN, "%s/%s",
200 	    get_keystore_path(), PUB_OBJ_DIR);
201 	return (name);
202 }
203 
204 static char *
get_pri_obj_path(char * name)205 get_pri_obj_path(char *name)
206 {
207 	bzero(name, sizeof (name));
208 	(void) snprintf(name, MAXPATHLEN, "%s/%s",
209 	    get_keystore_path(), PRI_OBJ_DIR);
210 	return (name);
211 }
212 
213 static char *
get_desc_file_path(char * name)214 get_desc_file_path(char *name)
215 {
216 	bzero(name, sizeof (name));
217 	(void) snprintf(name, MAXPATHLEN, "%s/%s",
218 	    get_keystore_path(), DS_FILE);
219 	return (name);
220 }
221 
222 static char *
get_tmp_desc_file_path(char * name)223 get_tmp_desc_file_path(char *name)
224 {
225 	bzero(name, sizeof (name));
226 	(void) snprintf(name, MAXPATHLEN, "%s/%s",
227 	    get_keystore_path(), TMP_DS_FILE);
228 	return (name);
229 }
230 
231 /*
232  * Calculates the offset for hashed_pin length and hashed pin
233  *
234  * Returns 0 if successful, -1 if there's any error.
235  *
236  * If successful, global variables "ks_hashed_pinlen_offset" will be set.
237  *
238  */
239 static int
calculate_hashed_pin_offset(int fd)240 calculate_hashed_pin_offset(int fd)
241 {
242 	uint64_t salt_length;
243 
244 	if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET)
245 	    != KS_HASHED_PIN_SALT_LEN_OFFSET) {
246 		return (-1);
247 	}
248 
249 	if (readn_nointr(fd, (char *)&salt_length,
250 	    KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
251 		return (-1);
252 	}
253 	salt_length = SWAP64(salt_length);
254 
255 	ks_hashed_pinlen_offset = KS_HASHED_PIN_SALT_LEN_OFFSET
256 	    + KS_HASHED_PIN_SALT_LEN_SIZE + salt_length;
257 
258 	return (0);
259 
260 }
261 
262 /*
263  * acquire or release read/write lock on a specific file
264  *
265  * read_lock: true for read lock; false for write lock
266  * set_lock:  true to set a lock; false to release a lock
267  */
268 static int
lock_file(int fd,boolean_t read_lock,boolean_t set_lock)269 lock_file(int fd, boolean_t read_lock, boolean_t set_lock)
270 {
271 
272 	flock_t lock_info;
273 	int r;
274 
275 	lock_info.l_whence = SEEK_SET;
276 	lock_info.l_start = 0;
277 	lock_info.l_len = 0; /* l_len == 0 means until end of  file */
278 
279 	if (read_lock) {
280 		lock_info.l_type = F_RDLCK;
281 	} else {
282 		lock_info.l_type = F_WRLCK;
283 	}
284 
285 	if (set_lock) {
286 		while ((r = fcntl(fd, F_SETLKW, &lock_info)) == -1) {
287 			if (errno != EINTR)
288 				break;
289 		}
290 		if (r == -1) {
291 			return (-1);
292 		}
293 	} else {
294 		lock_info.l_type = F_UNLCK;
295 		while ((r = fcntl(fd, F_SETLKW, &lock_info)) == -1) {
296 			if (errno != EINTR)
297 				break;
298 		}
299 		if (r == -1) {
300 			return (-1);
301 		}
302 	}
303 
304 	return (0);
305 }
306 
307 int
create_keystore()308 create_keystore()
309 {
310 	int fd, buf;
311 	uint64_t hashed_pin_len, hashed_pin_salt_len, ulong_buf;
312 	uchar_t ver_buf[KS_PKCS11_VER_SIZE];
313 	char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN],
314 	    ks_desc_file[MAXPATHLEN];
315 	CK_BYTE salt[KS_KEY_SALT_SIZE];
316 	char *hashed_pin = NULL, *hashed_pin_salt = NULL;
317 	char *alt;
318 
319 	/* keystore doesn't exist, create keystore directory */
320 	if (mkdir(get_keystore_path(), S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
321 		if (errno == EEXIST) {
322 			return (0);
323 		}
324 
325 		if (errno == EACCES) {
326 			return (-1);
327 		}
328 
329 		/* can't create keystore directory */
330 		if (errno == ENOENT) { /* part of the path doesn't exist */
331 			char keystore[MAXPATHLEN];
332 			/*
333 			 * try to create $HOME/.sunw/pkcs11_softtoken if it
334 			 * doesn't exist.  If it is a alternate path provided
335 			 * by the user, it should have existed.  Will not
336 			 * create for them.
337 			 */
338 			alt = getenv(ALTERNATE_KEYSTORE_PATH);
339 			if ((alt == NULL) || (strcmp(alt, "") == 0)) {
340 				char *home = getenv("HOME");
341 
342 				if (home == NULL || strcmp(home, "") == 0) {
343 					return (-1);
344 				}
345 				/* create $HOME/.sunw/pkcs11_softtoken */
346 				(void) snprintf(keystore, sizeof (keystore),
347 				    "%s/%s/%s", home, SUNW_PATH, KEYSTORE_PATH);
348 				if (mkdirp(keystore,
349 				    S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
350 					return (-1);
351 				}
352 			} else {
353 				return (-1);
354 			}
355 		}
356 	}
357 
358 	/* create keystore description file */
359 	fd = open_nointr(get_desc_file_path(ks_desc_file),
360 	    O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
361 	if (fd < 0) {
362 		if (errno == EEXIST) {
363 			return (0);
364 		} else {
365 			/* can't create keystore description file */
366 			(void) rmdir(get_keystore_path());
367 			return (-1);
368 		}
369 	}
370 
371 	if (lock_file(fd, B_FALSE, B_TRUE) != 0) {
372 		(void) unlink(ks_desc_file);
373 		(void) close(fd);
374 		(void) rmdir(get_keystore_path());
375 		return (-1);
376 	}
377 
378 	if (mkdir(get_pub_obj_path(pub_obj_path),
379 	    S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
380 		/* can't create directory for public objects */
381 		(void) lock_file(fd, B_FALSE, B_FALSE);
382 		(void) unlink(ks_desc_file);
383 		(void) close(fd);
384 		(void) rmdir(get_keystore_path());
385 		return (-1);
386 	}
387 
388 	if (mkdir(get_pri_obj_path(pri_obj_path),
389 	    S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
390 		/* can't create directory for private objects */
391 		(void) lock_file(fd, B_FALSE, B_FALSE);
392 		(void) unlink(ks_desc_file);
393 		(void) close(fd);
394 		(void) rmdir(get_keystore_path());
395 		(void) rmdir(pub_obj_path);
396 		return (-1);
397 	}
398 
399 
400 	/* write file format release number */
401 	bzero(ver_buf, sizeof (ver_buf));
402 	(void) strcpy((char *)ver_buf, KS_PKCS11_VER);
403 	if ((writen_nointr(fd, (char *)ver_buf, sizeof (ver_buf)))
404 	    != sizeof (ver_buf)) {
405 		goto cleanup;
406 	}
407 
408 	/* write version number, version = 0 since keystore just created */
409 	buf = SWAP32(0);
410 	if (writen_nointr(fd, (void *)&buf, KS_VER_SIZE) != KS_VER_SIZE) {
411 		goto cleanup;
412 	}
413 
414 	/* write monotonic-counter.  Counter for keystore objects start at 1 */
415 	buf = SWAP32(1);
416 	if (writen_nointr(fd, (void *)&buf, KS_COUNTER_SIZE)
417 	    != KS_COUNTER_SIZE) {
418 		goto cleanup;
419 	}
420 
421 	/* initial encryption key salt should be all NULL */
422 	bzero(salt, sizeof (salt));
423 	if (writen_nointr(fd, (void *)salt, KS_KEY_SALT_SIZE)
424 	    != KS_KEY_SALT_SIZE) {
425 		goto cleanup;
426 	}
427 
428 	/* initial HMAC key salt should also be all NULL */
429 	if (writen_nointr(fd, (void *)salt, KS_HMAC_SALT_SIZE)
430 	    != KS_HMAC_SALT_SIZE) {
431 		goto cleanup;
432 	}
433 
434 	/* generate the hashed pin salt, and MD5 hashed pin of default pin */
435 	if (soft_gen_hashed_pin((CK_CHAR_PTR)SOFT_DEFAULT_PIN, &hashed_pin,
436 	    &hashed_pin_salt) < 0) {
437 		goto cleanup;
438 	}
439 
440 	if ((hashed_pin_salt == NULL) || (hashed_pin == NULL)) {
441 		goto cleanup;
442 	}
443 
444 	hashed_pin_salt_len = (uint64_t)strlen(hashed_pin_salt);
445 	hashed_pin_len = (uint64_t)strlen(hashed_pin);
446 
447 	/* write hashed pin salt length */
448 	ulong_buf = SWAP64(hashed_pin_salt_len);
449 	if (writen_nointr(fd, (void *)&ulong_buf, KS_HASHED_PIN_SALT_LEN_SIZE)
450 	    != KS_HASHED_PIN_SALT_LEN_SIZE) {
451 		goto cleanup;
452 	}
453 
454 	if (writen_nointr(fd, (void *)hashed_pin_salt,
455 	    hashed_pin_salt_len) != hashed_pin_salt_len) {
456 		goto cleanup;
457 	}
458 
459 	/* write MD5 hashed pin of the default pin */
460 	ulong_buf = SWAP64(hashed_pin_len);
461 	if (writen_nointr(fd, (void *)&ulong_buf, KS_HASHED_PINLEN_SIZE)
462 	    != KS_HASHED_PINLEN_SIZE) {
463 		goto cleanup;
464 	}
465 
466 	if (writen_nointr(fd, (void *)hashed_pin, hashed_pin_len)
467 	    != hashed_pin_len) {
468 		goto cleanup;
469 	}
470 
471 	(void) lock_file(fd, B_FALSE, B_FALSE);
472 
473 	(void) close(fd);
474 	freezero(hashed_pin_salt, hashed_pin_salt_len);
475 	return (0);
476 
477 cleanup:
478 	(void) lock_file(fd, B_FALSE, B_FALSE);
479 	(void) unlink(ks_desc_file);
480 	(void) close(fd);
481 	(void) rmdir(get_keystore_path());
482 	(void) rmdir(pub_obj_path);
483 	(void) rmdir(pri_obj_path);
484 	return (-1);
485 }
486 
487 /*
488  * Determines if the file referenced by "fd" has the same
489  * inode as the file referenced by "fname".
490  *
491  * The argument "same" contains the result of determining
492  * if the inode is the same or not
493  *
494  * Returns 0 if there's no error.
495  * Returns 1 if there's any error with opening the file.
496  *
497  *
498  */
499 static int
is_inode_same(int fd,char * fname,boolean_t * same)500 is_inode_same(int fd, char *fname, boolean_t *same)
501 {
502 	struct stat fn_stat, fd_stat;
503 
504 	if (fstat(fd, &fd_stat) != 0) {
505 		return (-1);
506 	}
507 
508 	if (stat(fname, &fn_stat) != 0) {
509 		return (-1);
510 	}
511 
512 	/* It's the same file if both st_ino and st_dev match */
513 	if ((fd_stat.st_ino == fn_stat.st_ino) &&
514 	    (fd_stat.st_dev == fn_stat.st_dev)) {
515 		*same = B_TRUE;
516 	} else {
517 		*same = B_FALSE;
518 	}
519 	return (0);
520 }
521 
522 static int
acquire_file_lock(int * fd,char * fname,mode_t mode)523 acquire_file_lock(int *fd, char *fname, mode_t mode)
524 {
525 	boolean_t read_lock = B_TRUE, same_inode;
526 
527 	if ((mode == O_RDWR) || (mode == O_WRONLY)) {
528 		read_lock = B_FALSE;
529 	}
530 
531 	if (lock_file(*fd, read_lock, B_TRUE) != 0) {
532 		return (-1);
533 	}
534 
535 	/*
536 	 * make sure another process did not modify the file
537 	 * while we were trying to get the lock
538 	 */
539 	if (is_inode_same(*fd, fname, &same_inode) != 0) {
540 		(void) lock_file(*fd, B_TRUE, B_FALSE); /* unlock file */
541 		return (-1);
542 	}
543 
544 	while (!same_inode) {
545 		/*
546 		 * need to unlock file, close, re-open the file,
547 		 * and re-acquire the lock
548 		 */
549 
550 		/* unlock file */
551 		if (lock_file(*fd, B_TRUE, B_FALSE) != 0) {
552 			return (-1);
553 		}
554 
555 		(void) close(*fd);
556 
557 		/* re-open */
558 		*fd = open_nointr(fname, mode|O_NONBLOCK);
559 		if (*fd < 0) {
560 			return (-1);
561 		}
562 
563 		/* acquire lock again */
564 		if (lock_file(*fd, read_lock, B_TRUE) != 0) {
565 			return (-1);
566 		}
567 
568 		if (is_inode_same(*fd, fname, &same_inode) != 0) {
569 			(void) lock_file(*fd, B_TRUE, B_FALSE); /* unlock */
570 			return (-1);
571 		}
572 
573 	}
574 
575 	return (0);
576 }
577 
578 /*
579  * Open the keystore description file in the specified mode.
580  * If the keystore doesn't exist, the "do_create_keystore"
581  * argument determines if the keystore should be created
582  */
583 static int
open_and_lock_keystore_desc(mode_t mode,boolean_t do_create_keystore,boolean_t lock_held)584 open_and_lock_keystore_desc(mode_t mode, boolean_t do_create_keystore,
585     boolean_t lock_held)
586 {
587 
588 	int fd;
589 	char *fname, ks_desc_file[MAXPATHLEN];
590 
591 	/* open the keystore description file in requested mode */
592 	fname = get_desc_file_path(ks_desc_file);
593 	fd = open_nointr(fname, mode|O_NONBLOCK);
594 	if (fd < 0) {
595 		if ((errno == ENOENT) && (do_create_keystore)) {
596 			if (create_keystore() < 0) {
597 				goto done;
598 			}
599 			fd = open_nointr(fname, mode|O_NONBLOCK);
600 			if (fd < 0) {
601 				goto done;
602 			}
603 		} else {
604 			goto done;
605 		}
606 	}
607 
608 	if (lock_held) {
609 		/* already hold the lock */
610 		return (fd);
611 	}
612 
613 	if (acquire_file_lock(&fd, fname, mode) != 0) {
614 		if (fd > 0) {
615 			(void) close(fd);
616 		}
617 		return (-1);
618 	}
619 
620 done:
621 	return (fd);
622 }
623 
624 
625 /*
626  * Set or remove read or write lock on keystore description file
627  *
628  * read_lock: true for read lock, false for write lock
629  * set_lock: true for set a lock, false to remove a lock
630  */
631 static int
lock_desc_file(boolean_t read_lock,boolean_t set_lock)632 lock_desc_file(boolean_t read_lock, boolean_t set_lock)
633 {
634 
635 	char ks_desc_file[MAXPATHLEN];
636 
637 	if (set_lock) {
638 		int oflag;
639 
640 		/*
641 		 * make sure desc_fd is not already used.  If used, it means
642 		 * some other lock is already set on the file
643 		 */
644 		if (desc_fd > 0) {
645 			return (-1);
646 		}
647 
648 		(void) get_desc_file_path(ks_desc_file);
649 
650 		if (read_lock) {
651 			oflag = O_RDONLY;
652 		} else {
653 			oflag = O_WRONLY;
654 		}
655 		if ((desc_fd = open_and_lock_keystore_desc(oflag,
656 		    B_FALSE, B_FALSE)) < 0) {
657 			return (-1);
658 		}
659 	} else {
660 		/* make sure we have a valid fd */
661 		if (desc_fd <= 0) {
662 			return (-1);
663 		}
664 
665 		if (lock_file(desc_fd, read_lock, B_FALSE) == 1) {
666 			return (-1);
667 		}
668 
669 		(void) close(desc_fd);
670 		desc_fd = 0;
671 
672 	}
673 	return (0);
674 }
675 
676 static int
open_and_lock_object_file(ks_obj_handle_t * ks_handle,int oflag,boolean_t lock_held)677 open_and_lock_object_file(ks_obj_handle_t *ks_handle, int oflag,
678     boolean_t lock_held)
679 {
680 	char obj_fname[MAXPATHLEN];
681 	int fd;
682 
683 	if (ks_handle->public) {
684 		char pub_obj_path[MAXPATHLEN];
685 		(void) snprintf(obj_fname, MAXPATHLEN, "%s/%s",
686 		    get_pub_obj_path(pub_obj_path), ks_handle->name);
687 	} else {
688 		char pri_obj_path[MAXPATHLEN];
689 		(void) snprintf(obj_fname, MAXPATHLEN, "%s/%s",
690 		    get_pri_obj_path(pri_obj_path), ks_handle->name);
691 	}
692 
693 	fd = open_nointr(obj_fname, oflag|O_NONBLOCK);
694 	if (fd < 0) {
695 		return (-1);
696 	}
697 
698 	if (lock_held) {
699 		/* already hold the lock */
700 		return (fd);
701 	}
702 
703 	if (acquire_file_lock(&fd, obj_fname, oflag) != 0) {
704 		if (fd > 0) {
705 			(void) close(fd);
706 		}
707 		return (-1);
708 	}
709 
710 
711 	return (fd);
712 }
713 
714 
715 /*
716  * Update file version number in a temporary file that's
717  * a copy of the keystore description file.
718  * The update is NOT made to the original keystore description
719  * file.  It makes the update in a tempoary file.
720  *
721  * Name of the temporary file is assumed to be provided, but
722  * the file is assumed to not exist.
723  *
724  * return 0 if creating temp file is successful, returns -1 otherwise
725  */
726 static int
create_updated_keystore_version(int fd,char * tmp_fname)727 create_updated_keystore_version(int fd, char *tmp_fname)
728 {
729 	int version, tmp_fd;
730 	char buf[BUFSIZ];
731 	size_t nread;
732 
733 	/* first, create the tempoary file */
734 	tmp_fd = open_nointr(tmp_fname,
735 	    O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
736 	if (tmp_fd < 0) {
737 		return (-1);
738 	}
739 
740 	/*
741 	 * copy everything from keystore version to temp file except
742 	 * the keystore version.  Keystore version is updated
743 	 *
744 	 */
745 
746 	/* pkcs11 version */
747 	if (readn_nointr(fd, buf, KS_PKCS11_VER_SIZE) != KS_PKCS11_VER_SIZE) {
748 		goto cleanup;
749 	}
750 
751 	if (writen_nointr(tmp_fd, buf, KS_PKCS11_VER_SIZE) !=
752 	    KS_PKCS11_VER_SIZE) {
753 		goto cleanup;
754 	}
755 
756 	/* version number, it needs to be updated */
757 
758 	/* read the current version number */
759 	if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) {
760 		goto cleanup;
761 	}
762 
763 	version = SWAP32(version);
764 	version++;
765 	version = SWAP32(version);
766 
767 	/* write the updated value to the tmp file */
768 	if (writen_nointr(tmp_fd, (void *)&version, KS_VER_SIZE)
769 	    != KS_VER_SIZE) {
770 		goto cleanup;
771 	}
772 
773 	/* read rest of information, nothing needs to be updated */
774 	nread = readn_nointr(fd, buf, BUFSIZ);
775 	while (nread > 0) {
776 		if (writen_nointr(tmp_fd, buf, nread) != nread) {
777 			goto cleanup;
778 		}
779 		nread = readn_nointr(fd, buf, BUFSIZ);
780 	}
781 
782 	(void) close(tmp_fd);
783 	return (0);	/* no error */
784 
785 cleanup:
786 	(void) close(tmp_fd);
787 	(void) remove(tmp_fname);
788 	return (-1);
789 }
790 
791 static CK_RV
get_all_objs_in_dir(DIR * dirp,ks_obj_handle_t * ks_handle,ks_obj_t ** result_obj_list,boolean_t lock_held)792 get_all_objs_in_dir(DIR *dirp, ks_obj_handle_t *ks_handle,
793     ks_obj_t **result_obj_list, boolean_t lock_held)
794 {
795 	struct dirent *dp;
796 	ks_obj_t *obj;
797 	CK_RV rv;
798 
799 	while ((dp = readdir(dirp)) != NULL) {
800 
801 		if (strncmp(dp->d_name, OBJ_PREFIX, OBJ_PREFIX_LEN) != 0)
802 			continue;
803 
804 		(void) strcpy((char *)ks_handle->name, dp->d_name);
805 		rv = soft_keystore_get_single_obj(ks_handle, &obj, lock_held);
806 		if (rv != CKR_OK) {
807 			return (rv);
808 		}
809 		if (obj != NULL) {
810 			if (*result_obj_list == NULL) {
811 				*result_obj_list = obj;
812 			} else {
813 				obj->next = *result_obj_list;
814 				*result_obj_list = obj;
815 			}
816 		}
817 	}
818 	return (CKR_OK);
819 }
820 
821 /*
822  * This function prepares the obj data for encryption by prepending
823  * the FULL path of the file that will be used for storing
824  * the object.  Having full path of the file as part of
825  * of the data for the object will prevent an attacker from
826  * copying a "bad" object into the keystore undetected.
827  *
828  * This function will always allocate:
829  *	MAXPATHLEN + buf_len
830  * amount of data.  If the full path of the filename doesn't occupy
831  * the whole MAXPATHLEN, the rest of the space will just be empty.
832  * It is the caller's responsibility to free the buffer allocated here.
833  *
834  * The allocated buffer is returned in the variable "prepared_buf"
835  * if there's no error.
836  *
837  * Returns 0 if there's no error, -1 otherwise.
838  */
839 static int
prepare_data_for_encrypt(char * obj_path,unsigned char * buf,CK_ULONG buf_len,unsigned char ** prepared_buf,CK_ULONG * prepared_len)840 prepare_data_for_encrypt(char *obj_path, unsigned char *buf, CK_ULONG buf_len,
841     unsigned char **prepared_buf, CK_ULONG *prepared_len)
842 {
843 	*prepared_len = MAXPATHLEN + buf_len;
844 	*prepared_buf = malloc(*prepared_len);
845 	if (*prepared_buf == NULL) {
846 		return (-1);
847 	}
848 
849 	/*
850 	 * only zero out the space for the path name.  I could zero out
851 	 * the whole buffer, but that will be a waste of processing
852 	 * cycle since the rest of the buffer will be 100% filled all
853 	 * the time
854 	 */
855 	bzero(*prepared_buf, MAXPATHLEN);
856 	(void) memcpy(*prepared_buf, obj_path, strlen(obj_path));
857 	(void) memcpy(*prepared_buf + MAXPATHLEN, buf, buf_len);
858 	return (0);
859 }
860 
861 /*
862  * retrieves the hashed pin from the keystore
863  */
864 static CK_RV
get_hashed_pin(int fd,char ** hashed_pin)865 get_hashed_pin(int fd, char **hashed_pin)
866 {
867 	uint64_t hashed_pin_size;
868 
869 	if (ks_hashed_pinlen_offset == -1) {
870 		if (calculate_hashed_pin_offset(fd) != 0) {
871 			return (CKR_FUNCTION_FAILED);
872 		}
873 	}
874 
875 	/* first, get size of the hashed pin */
876 	if (lseek(fd, ks_hashed_pinlen_offset, SEEK_SET)
877 	    != ks_hashed_pinlen_offset) {
878 		return (CKR_FUNCTION_FAILED);
879 	}
880 
881 	if (readn_nointr(fd, (char *)&hashed_pin_size,
882 	    KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) {
883 		return (CKR_FUNCTION_FAILED);
884 	}
885 
886 	hashed_pin_size = SWAP64(hashed_pin_size);
887 
888 	*hashed_pin = malloc(hashed_pin_size + 1);
889 	if (*hashed_pin == NULL) {
890 		return (CKR_HOST_MEMORY);
891 	}
892 
893 	if ((readn_nointr(fd, *hashed_pin, hashed_pin_size))
894 	    != (ssize_t)hashed_pin_size) {
895 		freezero(*hashed_pin, hashed_pin_size + 1);
896 		*hashed_pin = NULL;
897 		return (CKR_FUNCTION_FAILED);
898 	}
899 	(*hashed_pin)[hashed_pin_size] = '\0';
900 	return (CKR_OK);
901 }
902 
903 
904 /*
905  *	FUNCTION: soft_keystore_lock
906  *
907  *	ARGUMENTS:
908  *		set_lock: TRUE to set readlock on the keystore object file,
909  *		          FALSE to remove readlock on keystore object file.
910  *
911  *	RETURN VALUE:
912  *
913  *		0: success
914  *		-1: failure
915  *
916  *	DESCRIPTION:
917  *
918  *		set or remove readlock on the keystore description file.
919  */
920 int
soft_keystore_readlock(boolean_t set_lock)921 soft_keystore_readlock(boolean_t set_lock)
922 {
923 
924 	return (lock_desc_file(B_TRUE, set_lock));
925 }
926 
927 
928 /*
929  *	FUNCTION: soft_keystore_writelock
930  *
931  *	ARGUMENTS:
932  *		set_lock: TRUE to set writelock on the keystore description file
933  *			FALSE to remove write lock on keystore description file.
934  *
935  *	RETURN VALUE:
936  *
937  *		0: no error
938  *		1: some error occurred
939  *
940  *	DESCRIPTION:
941  *		set/reset writelock on the keystore description file.
942  */
943 int
soft_keystore_writelock(boolean_t set_lock)944 soft_keystore_writelock(boolean_t set_lock)
945 {
946 	return (lock_desc_file(B_FALSE, set_lock));
947 
948 }
949 
950 /*
951  *
952  *	FUNCTION: soft_keystore_lock_object
953  *
954  *	ARGUMENTS:
955  *
956  *		ks_handle: handle of the keystore object file to be accessed.
957  *		read_lock: TRUE to set readlock on the keystore object file,
958  *			  FALSE to set writelock on keystore object file.
959  *
960  *	RETURN VALUE:
961  *
962  *		If no error, file descriptor of locked file will be returned
963  *		-1: some error occurred
964  *
965  *	DESCRIPTION:
966  *
967  *		set readlock or writelock on the keystore object file.
968  */
969 int
soft_keystore_lock_object(ks_obj_handle_t * ks_handle,boolean_t read_lock)970 soft_keystore_lock_object(ks_obj_handle_t *ks_handle, boolean_t read_lock)
971 {
972 	int fd;
973 	int oflag;
974 
975 	if (read_lock) {
976 		oflag = O_RDONLY;
977 	} else {
978 		oflag = O_WRONLY;
979 	}
980 
981 	if ((fd = open_and_lock_object_file(ks_handle, oflag, B_FALSE)) < 0) {
982 		return (-1);
983 	}
984 
985 	return (fd);
986 }
987 
988 /*
989  *	FUNCTION: soft_keystore_unlock_object
990  *
991  *	ARGUMENTS:
992  *		fd: file descriptor returned from soft_keystore_lock_object
993  *
994  *	RETURN VALUE:
995  *		0: no error
996  *		1: some error occurred while getting the pin
997  *
998  *	DESCRIPTION:
999  *		set/reset writelock on the keystore object file.
1000  */
1001 int
soft_keystore_unlock_object(int fd)1002 soft_keystore_unlock_object(int fd)
1003 {
1004 	if (lock_file(fd, B_TRUE, B_FALSE) != 0) {
1005 		return (1);
1006 	}
1007 
1008 	(void) close(fd);
1009 	return (0);
1010 }
1011 
1012 
1013 
1014 /*
1015  *	FUNCTION: soft_keystore_get_version
1016  *
1017  *	ARGUMENTS:
1018  *		version: pointer to caller allocated memory for storing
1019  *			 the version of the keystore.
1020  *		lock_held: TRUE if the lock is held by caller.
1021  *
1022  *	RETURN VALUE:
1023  *
1024  *		0: no error
1025  *		-1: some error occurred while getting the version number
1026  *
1027  *	DESCRIPTION:
1028  *		get the version number of the keystore from keystore
1029  *		description file.
1030  */
1031 int
soft_keystore_get_version(uint_t * version,boolean_t lock_held)1032 soft_keystore_get_version(uint_t *version, boolean_t lock_held)
1033 {
1034 	int fd, ret_val = 0;
1035 	uint_t buf;
1036 
1037 	if ((fd = open_and_lock_keystore_desc(O_RDONLY,
1038 	    B_FALSE, lock_held)) < 0) {
1039 		return (-1);
1040 	}
1041 
1042 	if (lseek(fd, KS_VER_OFFSET, SEEK_SET) != KS_VER_OFFSET) {
1043 		ret_val = -1;
1044 		goto cleanup;
1045 	}
1046 
1047 	if (readn_nointr(fd, (char *)&buf, KS_VER_SIZE) != KS_VER_SIZE) {
1048 		ret_val = -1;
1049 		goto cleanup;
1050 	}
1051 	*version = SWAP32(buf);
1052 
1053 cleanup:
1054 
1055 	if (!lock_held) {
1056 		if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
1057 			ret_val = -1;
1058 		}
1059 	}
1060 
1061 	(void) close(fd);
1062 	return (ret_val);
1063 }
1064 
1065 /*
1066  *	FUNCTION: soft_keystore_get_object_version
1067  *
1068  *	ARGUMENTS:
1069  *
1070  *		ks_handle: handle of the key store object to be accessed.
1071  *		version:
1072  *			pointer to caller allocated memory for storing
1073  *			the version of the object.
1074  *		lock_held: TRUE if the lock is held by caller.
1075  *
1076  *	RETURN VALUE:
1077  *
1078  *		0: no error
1079  *		-1: some error occurred while getting the pin
1080  *
1081  *	DESCRIPTION:
1082  *		get the version number of the specified token object.
1083  */
1084 int
soft_keystore_get_object_version(ks_obj_handle_t * ks_handle,uint_t * version,boolean_t lock_held)1085 soft_keystore_get_object_version(ks_obj_handle_t *ks_handle,
1086     uint_t *version, boolean_t lock_held)
1087 {
1088 	int fd, ret_val = 0;
1089 	uint_t tmp;
1090 
1091 	if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY,
1092 	    lock_held)) < 0) {
1093 		return (-1);
1094 	}
1095 
1096 	/*
1097 	 * read version.  Version is always first item in object file
1098 	 * so, no need to do lseek
1099 	 */
1100 	if (readn_nointr(fd, (char *)&tmp, OBJ_VER_SIZE) != OBJ_VER_SIZE) {
1101 		ret_val = -1;
1102 		goto cleanup;
1103 	}
1104 
1105 	*version = SWAP32(tmp);
1106 
1107 cleanup:
1108 	if (!lock_held) {
1109 		if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
1110 			ret_val = -1;
1111 		}
1112 	}
1113 
1114 
1115 	(void) close(fd);
1116 	return (ret_val);
1117 }
1118 
1119 /*
1120  *		FUNCTION: soft_keystore_getpin
1121  *
1122  *		ARGUMENTS:
1123  *			hashed_pin: pointer to caller allocated memory
1124  *				for storing the pin to be returned.
1125  *			lock_held: TRUE if the lock is held by caller.
1126  *
1127  *		RETURN VALUE:
1128  *
1129  *			0: no error
1130  *			-1: some error occurred while getting the pin
1131  *
1132  *		DESCRIPTION:
1133  *
1134  *			Reads the MD5 hash from the keystore description
1135  *			file and return it to the caller in the provided
1136  *			buffer. If there is no PIN in the description file
1137  *			because the file is just created, this function
1138  *			will get a MD5 digest of the string "changeme",
1139  *			store it in the file, and also return this
1140  *			string to the caller.
1141  */
1142 int
soft_keystore_getpin(char ** hashed_pin,boolean_t lock_held)1143 soft_keystore_getpin(char **hashed_pin, boolean_t lock_held)
1144 {
1145 	int fd, ret_val = -1;
1146 	CK_RV rv;
1147 
1148 	if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE,
1149 	    lock_held)) < 0) {
1150 		return (-1);
1151 	}
1152 
1153 	rv = get_hashed_pin(fd, hashed_pin);
1154 	if (rv == CKR_OK) {
1155 		ret_val = 0;
1156 	}
1157 
1158 	if (!lock_held) {
1159 		if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
1160 			ret_val = -1;
1161 		}
1162 	}
1163 
1164 	(void) close(fd);
1165 	return (ret_val);
1166 }
1167 
1168 
1169 /*
1170  * Generate a 16-byte Initialization Vector (IV).
1171  */
1172 CK_RV
soft_gen_iv(CK_BYTE * iv)1173 soft_gen_iv(CK_BYTE *iv)
1174 {
1175 	return (pkcs11_get_nzero_urandom(iv, 16) < 0 ?
1176 	    CKR_DEVICE_ERROR : CKR_OK);
1177 }
1178 
1179 
1180 /*
1181  * This function reads all the data until the end of the file, and
1182  * put the data into the "buf" in argument.  Memory for buf will
1183  * be allocated in this function.  It is the caller's responsibility
1184  * to free it.  The number of bytes read will be returned
1185  * in the argument "bytes_read"
1186  *
1187  * returns CKR_OK if no error.  Other CKR error codes if there's an error
1188  */
1189 static CK_RV
read_obj_data(int old_fd,char ** buf,ssize_t * bytes_read)1190 read_obj_data(int old_fd, char **buf, ssize_t *bytes_read)
1191 {
1192 
1193 	ssize_t nread, loop_count;
1194 	char *buf1 = NULL;
1195 
1196 	*buf = malloc(BUFSIZ);
1197 	if (*buf == NULL) {
1198 		return (CKR_HOST_MEMORY);
1199 	}
1200 
1201 	nread = readn_nointr(old_fd, *buf, BUFSIZ);
1202 	if (nread < 0) {
1203 		free(*buf);
1204 		return (CKR_FUNCTION_FAILED);
1205 	}
1206 	loop_count = 1;
1207 	while (nread == (loop_count * BUFSIZ)) {
1208 		ssize_t nread_tmp;
1209 
1210 		loop_count++;
1211 		/* more than BUFSIZ of data */
1212 		buf1 = realloc(*buf, loop_count * BUFSIZ);
1213 		if (buf1 == NULL) {
1214 			free(*buf);
1215 			return (CKR_HOST_MEMORY);
1216 		}
1217 		*buf = buf1;
1218 		nread_tmp = readn_nointr(old_fd,
1219 		    *buf + ((loop_count - 1) * BUFSIZ), BUFSIZ);
1220 		if (nread_tmp < 0) {
1221 			free(*buf);
1222 			return (CKR_FUNCTION_FAILED);
1223 		}
1224 		nread += nread_tmp;
1225 	}
1226 	*bytes_read = nread;
1227 	return (CKR_OK);
1228 }
1229 
1230 /*
1231  * Re-encrypt an object using the provided new_enc_key.  The new HMAC
1232  * is calculated using the new_hmac_key.  The global static variables
1233  * enc_key, and hmac_key will be used for decrypting the original
1234  * object, and verifying its signature.
1235  *
1236  * The re-encrypted object will be stored in the file named
1237  * in the "new_obj_name" variable.  The content of the "original"
1238  * file named in "orig_obj_name" is not disturbed.
1239  *
1240  * Returns 0 if there's no error, returns -1 otherwise.
1241  *
1242  */
1243 static int
reencrypt_obj(soft_object_t * new_enc_key,soft_object_t * new_hmac_key,char * orig_obj_name,char * new_obj_name)1244 reencrypt_obj(soft_object_t *new_enc_key, soft_object_t *new_hmac_key,
1245     char *orig_obj_name, char *new_obj_name)
1246 {
1247 	int old_fd, new_fd, version, ret_val = -1;
1248 	CK_BYTE iv[OBJ_IV_SIZE], old_iv[OBJ_IV_SIZE];
1249 	ssize_t nread;
1250 	CK_ULONG decrypted_len, encrypted_len, hmac_len;
1251 	CK_BYTE hmac[OBJ_HMAC_SIZE], *decrypted_buf = NULL, *buf = NULL;
1252 
1253 	old_fd = open_nointr(orig_obj_name, O_RDONLY|O_NONBLOCK);
1254 	if (old_fd < 0) {
1255 		return (-1);
1256 	}
1257 
1258 	if (acquire_file_lock(&old_fd, orig_obj_name, O_RDONLY) != 0) {
1259 		if (old_fd > 0) {
1260 			(void) close(old_fd);
1261 		}
1262 		return (-1);
1263 	}
1264 
1265 	new_fd = open_nointr(new_obj_name,
1266 	    O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
1267 	if (new_fd < 0) {
1268 		(void) close(old_fd);
1269 		return (-1);
1270 	}
1271 
1272 	if (lock_file(new_fd, B_FALSE, B_TRUE) != 0) {
1273 		/* unlock old file */
1274 		(void) lock_file(old_fd, B_TRUE, B_FALSE);
1275 		(void) close(old_fd);
1276 		(void) close(new_fd);
1277 		return (-1);
1278 	}
1279 
1280 	/* read version, increment, and write to tmp file */
1281 	if (readn_nointr(old_fd, (char *)&version, OBJ_VER_SIZE)
1282 	    != OBJ_VER_SIZE) {
1283 		goto cleanup;
1284 	}
1285 
1286 	version = SWAP32(version);
1287 	version++;
1288 	version = SWAP32(version);
1289 
1290 	if (writen_nointr(new_fd, (char *)&version, OBJ_VER_SIZE)
1291 	    != OBJ_VER_SIZE) {
1292 		goto cleanup;
1293 	}
1294 
1295 	/* read old iv */
1296 	if (readn_nointr(old_fd, (char *)old_iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
1297 		goto cleanup;
1298 	}
1299 
1300 	/* generate new IV */
1301 	if (soft_gen_iv(iv) != CKR_OK) {
1302 		goto cleanup;
1303 	}
1304 
1305 	if (writen_nointr(new_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
1306 		goto cleanup;
1307 	}
1308 
1309 	/* seek to the original encrypted data, and read all of them */
1310 	if (lseek(old_fd, OBJ_DATA_OFFSET, SEEK_SET) != OBJ_DATA_OFFSET) {
1311 		goto cleanup;
1312 	}
1313 
1314 	if (read_obj_data(old_fd, (char **)&buf, &nread) != CKR_OK) {
1315 		goto cleanup;
1316 	}
1317 
1318 	/* decrypt data using old key */
1319 	decrypted_len = 0;
1320 	if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
1321 	    NULL, &decrypted_len) != CKR_OK) {
1322 		freezero(buf, nread);
1323 		goto cleanup;
1324 	}
1325 
1326 	decrypted_buf = malloc(decrypted_len);
1327 	if (decrypted_buf == NULL) {
1328 		freezero(buf, nread);
1329 		goto cleanup;
1330 	}
1331 
1332 	if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
1333 	    decrypted_buf, &decrypted_len) != CKR_OK) {
1334 		freezero(buf, nread);
1335 		freezero(decrypted_buf, decrypted_len);
1336 	}
1337 
1338 	freezero(buf, nread);
1339 
1340 	/* re-encrypt with new key */
1341 	encrypted_len = 0;
1342 	if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
1343 	    decrypted_len, NULL, &encrypted_len) != CKR_OK) {
1344 		freezero(decrypted_buf, decrypted_len);
1345 		goto cleanup;
1346 	}
1347 
1348 	buf = malloc(encrypted_len);
1349 	if (buf == NULL) {
1350 		freezero(decrypted_buf, decrypted_len);
1351 		goto cleanup;
1352 	}
1353 
1354 	if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
1355 	    decrypted_len, buf, &encrypted_len) != CKR_OK) {
1356 		freezero(buf, encrypted_len);
1357 		freezero(buf, decrypted_len);
1358 		goto cleanup;
1359 	}
1360 
1361 	freezero(decrypted_buf, decrypted_len);
1362 
1363 	/* calculate hmac on re-encrypted data using new hmac key */
1364 	hmac_len = OBJ_HMAC_SIZE;
1365 	if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf,
1366 	    encrypted_len, hmac, &hmac_len) != CKR_OK) {
1367 		freezero(buf, encrypted_len);
1368 		goto cleanup;
1369 	}
1370 
1371 	/* just for sanity check */
1372 	if (hmac_len != OBJ_HMAC_SIZE) {
1373 		freezero(buf, encrypted_len);
1374 		goto cleanup;
1375 	}
1376 
1377 	/* write new hmac */
1378 	if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE)
1379 	    != OBJ_HMAC_SIZE) {
1380 		freezero(buf, encrypted_len);
1381 		goto cleanup;
1382 	}
1383 
1384 	/* write re-encrypted buffer to temp file */
1385 	if (writen_nointr(new_fd, (void *)buf, encrypted_len)
1386 	    != encrypted_len) {
1387 		freezero(buf, encrypted_len);
1388 		goto cleanup;
1389 	}
1390 	freezero(buf, encrypted_len);
1391 	ret_val = 0;
1392 
1393 cleanup:
1394 	/* unlock the files */
1395 	(void) lock_file(old_fd, B_TRUE, B_FALSE);
1396 	(void) lock_file(new_fd, B_FALSE, B_FALSE);
1397 
1398 	(void) close(old_fd);
1399 	(void) close(new_fd);
1400 	if (ret_val != 0) {
1401 		(void) remove(new_obj_name);
1402 	}
1403 	return (ret_val);
1404 }
1405 
1406 /*
1407  *	FUNCTION: soft_keystore_setpin
1408  *
1409  *	ARGUMENTS:
1410  *		newpin: new pin entered by the user.
1411  *		lock_held: TRUE if the lock is held by caller.
1412  *
1413  *	RETURN VALUE:
1414  *		0: no error
1415  *		-1: failure
1416  *
1417  *	DESCRIPTION:
1418  *
1419  *		This function does the following:
1420  *
1421  *		1) Generates crypted value of newpin and store it
1422  *		   in keystore description file.
1423  *		2) Dervies the new encryption key from the newpin.  This key
1424  *		   will be used to re-encrypt the private token objects.
1425  *		3) Re-encrypt all of this user's existing private token
1426  *		   objects (if any).
1427  *		4) Increments the keystore version number.
1428  */
1429 int
soft_keystore_setpin(uchar_t * oldpin,uchar_t * newpin,boolean_t lock_held)1430 soft_keystore_setpin(uchar_t *oldpin, uchar_t *newpin, boolean_t lock_held)
1431 {
1432 	int fd, tmp_ks_fd, version, ret_val = -1;
1433 	soft_object_t *new_crypt_key = NULL, *new_hmac_key = NULL;
1434 	char filebuf[BUFSIZ];
1435 	DIR	*pri_dirp;
1436 	struct dirent *pri_ent;
1437 	char pri_obj_path[MAXPATHLEN], ks_desc_file[MAXPATHLEN],
1438 	    tmp_ks_desc_name[MAXPATHLEN];
1439 	typedef struct priobjs {
1440 		char orig_name[MAXPATHLEN];
1441 		char tmp_name[MAXPATHLEN];
1442 		struct priobjs *next;
1443 	} priobjs_t;
1444 	priobjs_t *pri_objs = NULL, *tmp;
1445 	CK_BYTE *crypt_salt = NULL, *hmac_salt = NULL;
1446 	boolean_t pin_never_set = B_FALSE, user_logged_in;
1447 	char *new_hashed_pin = NULL;
1448 	uint64_t hashed_pin_salt_length, new_hashed_pin_len, swaped_val;
1449 	char *hashed_pin_salt = NULL;
1450 	priobjs_t *obj;
1451 
1452 	if ((enc_key == NULL) ||
1453 	    (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
1454 		user_logged_in = B_FALSE;
1455 	} else {
1456 		user_logged_in = B_TRUE;
1457 	}
1458 
1459 	if ((fd = open_and_lock_keystore_desc(O_RDWR, B_TRUE,
1460 	    lock_held)) < 0) {
1461 		return (-1);
1462 	}
1463 
1464 	(void) get_desc_file_path(ks_desc_file);
1465 	(void) get_tmp_desc_file_path(tmp_ks_desc_name);
1466 
1467 	/*
1468 	 * create a tempoary file for the keystore description
1469 	 * file for updating version and counter information
1470 	 */
1471 	tmp_ks_fd = open_nointr(tmp_ks_desc_name,
1472 	    O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
1473 	if (tmp_ks_fd < 0) {
1474 		(void) close(fd);
1475 		return (-1);
1476 	}
1477 
1478 	/* read and write PKCS version to temp file */
1479 	if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE)
1480 	    != KS_PKCS11_VER_SIZE) {
1481 		goto cleanup;
1482 	}
1483 
1484 	if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE)
1485 	    != KS_PKCS11_VER_SIZE) {
1486 		goto cleanup;
1487 	}
1488 
1489 	/* get version number, and write updated number to temp file */
1490 	if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) {
1491 		goto cleanup;
1492 	}
1493 
1494 	version = SWAP32(version);
1495 	version++;
1496 	version = SWAP32(version);
1497 
1498 	if (writen_nointr(tmp_ks_fd, (void *)&version, KS_VER_SIZE)
1499 	    != KS_VER_SIZE) {
1500 		goto cleanup;
1501 	}
1502 
1503 
1504 	/* read and write counter, no modification necessary */
1505 	if (readn_nointr(fd, filebuf, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) {
1506 		goto cleanup;
1507 	}
1508 
1509 	if (writen_nointr(tmp_ks_fd, filebuf, KS_COUNTER_SIZE)
1510 	    != KS_COUNTER_SIZE) {
1511 		goto cleanup;
1512 	}
1513 
1514 	/* read old encryption salt */
1515 	crypt_salt = malloc(KS_KEY_SALT_SIZE);
1516 	if (crypt_salt == NULL) {
1517 		goto cleanup;
1518 	}
1519 	if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE)
1520 	    != KS_KEY_SALT_SIZE) {
1521 		goto cleanup;
1522 	}
1523 
1524 	/* read old hmac salt */
1525 	hmac_salt = malloc(KS_HMAC_SALT_SIZE);
1526 	if (hmac_salt == NULL) {
1527 		goto cleanup;
1528 	}
1529 	if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE)
1530 	    != KS_HMAC_SALT_SIZE) {
1531 		goto cleanup;
1532 	}
1533 
1534 	/* just create some empty bytes */
1535 	bzero(filebuf, sizeof (filebuf));
1536 
1537 	if (memcmp(crypt_salt, filebuf, KS_KEY_SALT_SIZE) == 0) {
1538 		/* PIN as never been set */
1539 		CK_BYTE *new_crypt_salt = NULL, *new_hmac_salt = NULL;
1540 
1541 		pin_never_set = B_TRUE;
1542 		if (soft_gen_crypt_key(newpin, &new_crypt_key, &new_crypt_salt)
1543 		    != CKR_OK) {
1544 			goto cleanup;
1545 		}
1546 		if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt,
1547 		    KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
1548 			freezero(new_crypt_salt,
1549 			    KS_KEY_SALT_SIZE);
1550 			(void) soft_cleanup_object(new_crypt_key);
1551 			goto cleanup;
1552 		}
1553 		freezero(new_crypt_salt, KS_KEY_SALT_SIZE);
1554 
1555 		if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt)
1556 		    != CKR_OK) {
1557 			(void) soft_cleanup_object(new_crypt_key);
1558 			goto cleanup;
1559 		}
1560 		if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt,
1561 		    KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) {
1562 			freezero(new_hmac_salt,
1563 			    KS_HMAC_SALT_SIZE);
1564 			goto cleanup3;
1565 		}
1566 		freezero(new_hmac_salt, KS_HMAC_SALT_SIZE);
1567 	} else {
1568 		if (soft_gen_crypt_key(newpin, &new_crypt_key,
1569 		    (CK_BYTE **)&crypt_salt) != CKR_OK) {
1570 			goto cleanup;
1571 		}
1572 		/* no change to the encryption salt */
1573 		if (writen_nointr(tmp_ks_fd, (void *)crypt_salt,
1574 		    KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
1575 			(void) soft_cleanup_object(new_crypt_key);
1576 			goto cleanup;
1577 		}
1578 
1579 		if (soft_gen_hmac_key(newpin, &new_hmac_key,
1580 		    (CK_BYTE **)&hmac_salt) != CKR_OK) {
1581 			(void) soft_cleanup_object(new_crypt_key);
1582 			goto cleanup;
1583 		}
1584 
1585 		/* no change to the hmac salt */
1586 		if (writen_nointr(tmp_ks_fd, (void *)hmac_salt,
1587 		    KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) {
1588 			goto cleanup3;
1589 		}
1590 	}
1591 
1592 	/*
1593 	 * read hashed pin salt, and write to updated keystore description
1594 	 * file unmodified.
1595 	 */
1596 	if (readn_nointr(fd, (char *)&hashed_pin_salt_length,
1597 	    KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
1598 		goto cleanup3;
1599 	}
1600 
1601 	if (writen_nointr(tmp_ks_fd, (void *)&hashed_pin_salt_length,
1602 	    KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
1603 		goto cleanup3;
1604 	}
1605 
1606 	hashed_pin_salt_length = SWAP64(hashed_pin_salt_length);
1607 
1608 	hashed_pin_salt = malloc(hashed_pin_salt_length + 1);
1609 	if (hashed_pin_salt == NULL) {
1610 		goto cleanup3;
1611 	}
1612 
1613 	if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) !=
1614 	    (ssize_t)hashed_pin_salt_length) {
1615 		freezero(hashed_pin_salt,
1616 		    hashed_pin_salt_length + 1);
1617 		goto cleanup3;
1618 	}
1619 
1620 	if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length))
1621 	    != (ssize_t)hashed_pin_salt_length) {
1622 		freezero(hashed_pin_salt,
1623 		    hashed_pin_salt_length + 1);
1624 		goto cleanup3;
1625 	}
1626 
1627 	hashed_pin_salt[hashed_pin_salt_length] = '\0';
1628 
1629 	/* old hashed pin length and value can be ignored, generate new one */
1630 	if (soft_gen_hashed_pin(newpin, &new_hashed_pin,
1631 	    &hashed_pin_salt) < 0) {
1632 		freezero(hashed_pin_salt,
1633 		    hashed_pin_salt_length + 1);
1634 		goto cleanup3;
1635 	}
1636 
1637 	freezero(hashed_pin_salt, hashed_pin_salt_length + 1);
1638 
1639 	if (new_hashed_pin == NULL) {
1640 		goto cleanup3;
1641 	}
1642 
1643 	new_hashed_pin_len = strlen(new_hashed_pin);
1644 
1645 	/* write new hashed pin length to file */
1646 	swaped_val = SWAP64(new_hashed_pin_len);
1647 	if (writen_nointr(tmp_ks_fd, (void *)&swaped_val,
1648 	    KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) {
1649 		goto cleanup3;
1650 	}
1651 
1652 	if (writen_nointr(tmp_ks_fd, (void *)new_hashed_pin,
1653 	    new_hashed_pin_len) != (ssize_t)new_hashed_pin_len) {
1654 		goto cleanup3;
1655 	}
1656 
1657 	if (pin_never_set) {
1658 		/* there was no private object, no need to re-encrypt them */
1659 		goto rename_desc_file;
1660 	}
1661 
1662 	/* re-encrypt all the private objects */
1663 	pri_dirp = opendir(get_pri_obj_path(pri_obj_path));
1664 	if (pri_dirp == NULL) {
1665 		/*
1666 		 * this directory should exist, even if it doesn't contain
1667 		 * any objects.  Don't want to update the pin if the
1668 		 * keystore is somehow messed up.
1669 		 */
1670 
1671 		goto cleanup3;
1672 	}
1673 
1674 	/* if user did not login, need to set the old pin */
1675 	if (!user_logged_in) {
1676 		if (soft_keystore_authpin(oldpin) != 0) {
1677 			goto cleanup3;
1678 		}
1679 	}
1680 
1681 	while ((pri_ent = readdir(pri_dirp)) != NULL) {
1682 
1683 		if ((strcmp(pri_ent->d_name, ".") == 0) ||
1684 		    (strcmp(pri_ent->d_name, "..") == 0) ||
1685 		    (strncmp(pri_ent->d_name, TMP_OBJ_PREFIX,
1686 		    strlen(TMP_OBJ_PREFIX)) == 0)) {
1687 			continue;
1688 		}
1689 
1690 		obj = malloc(sizeof (priobjs_t));
1691 		if (obj == NULL) {
1692 			goto cleanup2;
1693 		}
1694 		(void) snprintf(obj->orig_name, MAXPATHLEN,
1695 		    "%s/%s", pri_obj_path, pri_ent->d_name);
1696 		(void) snprintf(obj->tmp_name, MAXPATHLEN, "%s/%s%s",
1697 		    pri_obj_path, TMP_OBJ_PREFIX,
1698 		    (pri_ent->d_name) + OBJ_PREFIX_LEN);
1699 		if (reencrypt_obj(new_crypt_key, new_hmac_key,
1700 		    obj->orig_name, obj->tmp_name) != 0) {
1701 			free(obj);
1702 			goto cleanup2;
1703 		}
1704 
1705 		/* insert into list of file to be renamed */
1706 		if (pri_objs == NULL) {
1707 			obj->next = NULL;
1708 			pri_objs = obj;
1709 		} else {
1710 			obj->next = pri_objs;
1711 			pri_objs = obj;
1712 		}
1713 	}
1714 
1715 	/* rename all the private objects */
1716 	tmp = pri_objs;
1717 	while (tmp) {
1718 		(void) rename(tmp->tmp_name, tmp->orig_name);
1719 		tmp = tmp->next;
1720 	}
1721 
1722 rename_desc_file:
1723 
1724 	/* destroy the old encryption key, and hmac key */
1725 	if ((!pin_never_set) && (user_logged_in)) {
1726 		(void) soft_cleanup_object(enc_key);
1727 		(void) soft_cleanup_object(hmac_key);
1728 	}
1729 
1730 	if (user_logged_in) {
1731 		enc_key = new_crypt_key;
1732 		hmac_key = new_hmac_key;
1733 	}
1734 	(void) rename(tmp_ks_desc_name, ks_desc_file);
1735 
1736 	ret_val = 0;
1737 
1738 cleanup2:
1739 	if (pri_objs != NULL) {
1740 		priobjs_t *p = pri_objs;
1741 		while (p) {
1742 			tmp = p->next;
1743 			free(p);
1744 			p = tmp;
1745 		}
1746 	}
1747 	if (!pin_never_set) {
1748 		(void) closedir(pri_dirp);
1749 	}
1750 
1751 	if ((!user_logged_in) && (!pin_never_set)) {
1752 		(void) soft_cleanup_object(enc_key);
1753 		(void) soft_cleanup_object(hmac_key);
1754 		enc_key = NULL;
1755 		hmac_key = NULL;
1756 	}
1757 cleanup3:
1758 	if ((ret_val != 0) || (!user_logged_in)) {
1759 		(void) soft_cleanup_object(new_crypt_key);
1760 		(void) soft_cleanup_object(new_hmac_key);
1761 	}
1762 
1763 cleanup:
1764 	if (!lock_held) {
1765 		if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
1766 			ret_val = 1;
1767 		}
1768 	}
1769 	freezero(crypt_salt, KS_KEY_SALT_SIZE);
1770 	freezero(hmac_salt, KS_HMAC_SALT_SIZE);
1771 	(void) close(fd);
1772 	(void) close(tmp_ks_fd);
1773 	if (ret_val != 0) {
1774 		(void) remove(tmp_ks_desc_name);
1775 	}
1776 	return (ret_val);
1777 }
1778 
1779 /*
1780  *	FUNCTION: soft_keystore_authpin
1781  *
1782  *	ARGUMENTS:
1783  *		pin: pin specified by the user for logging into
1784  *		     the keystore.
1785  *
1786  *	RETURN VALUE:
1787  *		0: if no error
1788  *		-1: if there is any error
1789  *
1790  *	DESCRIPTION:
1791  *
1792  *		This function takes the pin specified in the argument
1793  *		and generates an encryption key based on the pin.
1794  *		The generated encryption key will be used for
1795  *		all future encryption and decryption for private
1796  *		objects.  Before this function is called, none
1797  *		of the keystore related interfaces is able
1798  *		to decrypt/encrypt any private object.
1799  */
1800 int
soft_keystore_authpin(uchar_t * pin)1801 soft_keystore_authpin(uchar_t  *pin)
1802 {
1803 	int fd;
1804 	int ret_val = -1;
1805 	CK_BYTE *crypt_salt = NULL, *hmac_salt;
1806 
1807 	/* get the salt from the keystore description file */
1808 	if ((fd = open_and_lock_keystore_desc(O_RDONLY,
1809 	    B_FALSE, B_FALSE)) < 0) {
1810 		return (-1);
1811 	}
1812 
1813 	crypt_salt = malloc(KS_KEY_SALT_SIZE);
1814 	if (crypt_salt == NULL) {
1815 		goto cleanup;
1816 	}
1817 
1818 	if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) {
1819 		goto cleanup;
1820 	}
1821 
1822 	if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE)
1823 	    != KS_KEY_SALT_SIZE) {
1824 		goto cleanup;
1825 	}
1826 
1827 	if (soft_gen_crypt_key(pin, &enc_key, (CK_BYTE **)&crypt_salt)
1828 	    != CKR_OK) {
1829 		goto cleanup;
1830 	}
1831 
1832 	hmac_salt = malloc(KS_HMAC_SALT_SIZE);
1833 	if (hmac_salt == NULL) {
1834 		goto cleanup;
1835 	}
1836 
1837 	if (lseek(fd, KS_HMAC_SALT_OFFSET, SEEK_SET) != KS_HMAC_SALT_OFFSET) {
1838 		goto cleanup;
1839 	}
1840 
1841 	if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE)
1842 	    != KS_HMAC_SALT_SIZE) {
1843 		goto cleanup;
1844 	}
1845 
1846 	if (soft_gen_hmac_key(pin, &hmac_key, (CK_BYTE **)&hmac_salt)
1847 	    != CKR_OK) {
1848 		goto cleanup;
1849 	}
1850 
1851 	ret_val = 0;
1852 
1853 cleanup:
1854 	/* unlock the file */
1855 	(void) lock_file(fd, B_TRUE, B_FALSE);
1856 	(void) close(fd);
1857 	freezero(crypt_salt, KS_KEY_SALT_SIZE);
1858 	freezero(hmac_salt, KS_HMAC_SALT_SIZE);
1859 	return (ret_val);
1860 }
1861 
1862 /*
1863  *	FUNCTION: soft_keystore_get_objs
1864  *
1865  *	ARGUMENTS:
1866  *
1867  *		search_type: Specify type of objects to return.
1868  *		lock_held: TRUE if the lock is held by caller.
1869  *
1870  *
1871  *	RETURN VALUE:
1872  *
1873  *		NULL: if there are no object in the database.
1874  *
1875  *		Otherwise, linked list of objects as requested
1876  *		in search type.
1877  *
1878  *		The linked list returned will need to be freed
1879  *		by the caller.
1880  *
1881  *	DESCRIPTION:
1882  *
1883  *		Returns objects as requested.
1884  *
1885  *		If private objects is requested, and the caller
1886  *		has not previously passed in the pin or if the pin
1887  *		passed in is wrong, private objects will not
1888  *		be returned.
1889  *
1890  *		The buffers returned for private objects are already
1891  *		decrypted.
1892  */
1893 CK_RV
soft_keystore_get_objs(ks_search_type_t search_type,ks_obj_t ** result_obj_list,boolean_t lock_held)1894 soft_keystore_get_objs(ks_search_type_t search_type,
1895     ks_obj_t **result_obj_list, boolean_t lock_held)
1896 {
1897 	DIR *dirp;
1898 	ks_obj_handle_t ks_handle;
1899 	CK_RV rv;
1900 	ks_obj_t *tmp;
1901 	int ks_fd;
1902 
1903 	*result_obj_list = NULL;
1904 
1905 	/*
1906 	 * lock the keystore description file in "read" mode so that
1907 	 * objects won't get added/deleted/modified while we are
1908 	 * doing the search
1909 	 */
1910 	if ((ks_fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE,
1911 	    B_FALSE)) < 0) {
1912 		return (CKR_FUNCTION_FAILED);
1913 	}
1914 
1915 	if ((search_type == ALL_TOKENOBJS) || (search_type == PUB_TOKENOBJS)) {
1916 
1917 		char pub_obj_path[MAXPATHLEN];
1918 
1919 		ks_handle.public = B_TRUE;
1920 
1921 		if ((dirp = opendir(get_pub_obj_path(pub_obj_path))) == NULL) {
1922 			(void) lock_file(ks_fd, B_TRUE, B_FALSE);
1923 			(void) close(ks_fd);
1924 			return (CKR_FUNCTION_FAILED);
1925 		}
1926 		rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list,
1927 		    lock_held);
1928 		if (rv != CKR_OK) {
1929 			(void) closedir(dirp);
1930 			goto cleanup;
1931 		}
1932 
1933 		(void) closedir(dirp);
1934 	}
1935 
1936 	if ((search_type == ALL_TOKENOBJS) || (search_type == PRI_TOKENOBJS)) {
1937 
1938 		char pri_obj_path[MAXPATHLEN];
1939 
1940 		if ((enc_key == NULL) ||
1941 		    (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
1942 			/* has not login - no need to go any further */
1943 			(void) lock_file(ks_fd, B_TRUE, B_FALSE);
1944 			(void) close(ks_fd);
1945 			return (CKR_OK);
1946 		}
1947 
1948 		ks_handle.public = B_FALSE;
1949 
1950 		if ((dirp = opendir(get_pri_obj_path(pri_obj_path))) == NULL) {
1951 			(void) lock_file(ks_fd, B_TRUE, B_FALSE);
1952 			(void) close(ks_fd);
1953 			return (CKR_OK);
1954 		}
1955 		rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list,
1956 		    lock_held);
1957 		if (rv != CKR_OK) {
1958 			(void) closedir(dirp);
1959 			goto cleanup;
1960 		}
1961 
1962 		(void) closedir(dirp);
1963 	}
1964 	/* close the keystore description file */
1965 	(void) lock_file(ks_fd, B_TRUE, B_FALSE);
1966 	(void) close(ks_fd);
1967 	return (CKR_OK);
1968 cleanup:
1969 
1970 	/* close the keystore description file */
1971 	(void) lock_file(ks_fd, B_TRUE, B_FALSE);
1972 	(void) close(ks_fd);
1973 
1974 	/* free all the objects found before hitting the error */
1975 	tmp = *result_obj_list;
1976 	while (tmp) {
1977 		*result_obj_list = tmp->next;
1978 		freezero(tmp->buf, tmp->size);
1979 		free(tmp);
1980 		tmp = *result_obj_list;
1981 	}
1982 	*result_obj_list = NULL;
1983 	return (rv);
1984 }
1985 
1986 
1987 /*
1988  *	FUNCTION: soft_keystore_get_single_obj
1989  *
1990  *	ARGUMENTS:
1991  *		ks_handle: handle of the key store object to be accessed
1992  *		lock_held: TRUE if the lock is held by caller.
1993  *
1994  *	RETURN VALUE:
1995  *
1996  *		NULL: if handle doesn't match any object
1997  *
1998  *		Otherwise, the object is returned in
1999  *		the same structure used in soft_keystore_get_objs().
2000  *		The structure need to be freed by the caller.
2001  *
2002  *	DESCRIPTION:
2003  *
2004  *		Retrieves the object specified by the object
2005  *		handle to the caller.
2006  *
2007  *		If a private object is requested, and the caller
2008  *		has not previously passed in the pin or if the pin
2009  *		passed in is wrong, the requested private object will not
2010  *		be returned.
2011  *
2012  *		The buffer returned for the requested private object
2013  *		is already decrypted.
2014  */
2015 CK_RV
soft_keystore_get_single_obj(ks_obj_handle_t * ks_handle,ks_obj_t ** return_obj,boolean_t lock_held)2016 soft_keystore_get_single_obj(ks_obj_handle_t *ks_handle,
2017     ks_obj_t **return_obj, boolean_t lock_held)
2018 {
2019 
2020 	ks_obj_t *obj;
2021 	uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE];
2022 	uchar_t *buf, *decrypted_buf;
2023 	int fd;
2024 	ssize_t nread;
2025 	CK_RV rv = CKR_FUNCTION_FAILED;
2026 
2027 	if (!(ks_handle->public)) {
2028 		if ((enc_key == NULL) ||
2029 		    (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
2030 			return (CKR_FUNCTION_FAILED);
2031 		}
2032 	}
2033 
2034 	if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY,
2035 	    lock_held)) < 0) {
2036 		return (CKR_FUNCTION_FAILED);
2037 	}
2038 
2039 	obj = malloc(sizeof (ks_obj_t));
2040 	if (obj == NULL) {
2041 		return (CKR_HOST_MEMORY);
2042 	}
2043 
2044 	obj->next = NULL;
2045 
2046 	(void) strcpy((char *)((obj->ks_handle).name),
2047 	    (char *)ks_handle->name);
2048 	(obj->ks_handle).public = ks_handle->public;
2049 
2050 	/* 1st get the version */
2051 	if (readn_nointr(fd, &(obj->obj_version), OBJ_VER_SIZE)
2052 	    != OBJ_VER_SIZE) {
2053 		goto cleanup;
2054 	}
2055 	obj->obj_version = SWAP32(obj->obj_version);
2056 
2057 	/* Then, read the IV */
2058 	if (readn_nointr(fd, iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
2059 		goto cleanup;
2060 	}
2061 
2062 	/* Then, read the HMAC */
2063 	if (readn_nointr(fd, obj_hmac, OBJ_HMAC_SIZE) != OBJ_HMAC_SIZE) {
2064 		goto cleanup;
2065 	}
2066 
2067 	/* read the object */
2068 	rv = read_obj_data(fd, (char **)&buf, &nread);
2069 	if (rv != CKR_OK) {
2070 		goto cleanup;
2071 	}
2072 
2073 	if (ks_handle->public) {
2074 		obj->size = nread;
2075 		obj->buf = buf;
2076 		*return_obj = obj;
2077 	} else {
2078 
2079 		CK_ULONG out_len = 0, hmac_size;
2080 
2081 		/* verify HMAC of the object, make sure it matches */
2082 		hmac_size = OBJ_HMAC_SIZE;
2083 		if (soft_keystore_hmac(hmac_key, B_FALSE, buf,
2084 		    nread, obj_hmac, &hmac_size) != CKR_OK) {
2085 			freezero(buf, nread);
2086 			rv = CKR_FUNCTION_FAILED;
2087 			goto cleanup;
2088 		}
2089 
2090 		/* decrypt object */
2091 		if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
2092 		    NULL, &out_len) != CKR_OK) {
2093 			freezero(buf, nread);
2094 			rv = CKR_FUNCTION_FAILED;
2095 			goto cleanup;
2096 		}
2097 
2098 		decrypted_buf = malloc(sizeof (uchar_t) * out_len);
2099 		if (decrypted_buf == NULL) {
2100 			freezero(buf, nread);
2101 			rv = CKR_HOST_MEMORY;
2102 			goto cleanup;
2103 		}
2104 
2105 		if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
2106 		    decrypted_buf, &out_len) != CKR_OK) {
2107 			freezero(buf, nread);
2108 			freezero(decrypted_buf, out_len);
2109 			rv = CKR_FUNCTION_FAILED;
2110 			goto cleanup;
2111 		}
2112 
2113 		obj->size = out_len - MAXPATHLEN;
2114 
2115 		/*
2116 		 * decrypted buf here actually contains full path name of
2117 		 * object plus the actual data.  so, need to skip the
2118 		 * full pathname.
2119 		 * See prepare_data_for_encrypt() function in the file
2120 		 * to understand how and why the pathname is added.
2121 		 */
2122 		obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN));
2123 		if (obj->buf == NULL) {
2124 			freezero(buf, nread);
2125 			freezero(decrypted_buf, out_len);
2126 			rv = CKR_HOST_MEMORY;
2127 			goto cleanup;
2128 		}
2129 		(void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size);
2130 		freezero(buf, nread);
2131 		freezero(decrypted_buf, out_len);
2132 		*return_obj = obj;
2133 	}
2134 
2135 cleanup:
2136 
2137 	if (rv != CKR_OK) {
2138 		free(obj);
2139 	}
2140 
2141 	/* unlock the file after reading */
2142 	if (!lock_held) {
2143 		(void) lock_file(fd, B_TRUE, B_FALSE);
2144 	}
2145 
2146 	(void) close(fd);
2147 
2148 	return (rv);
2149 }
2150 
2151 
2152 /*
2153  *	FUNCTION: soft_keystore_put_new_obj
2154  *
2155  *	ARGUMENTS:
2156  *		buf: buffer containing un-encrypted data
2157  *		     to be stored in keystore.
2158  *		len: length of data
2159  *		public:  TRUE if it is a public object,
2160  *			 FALSE if it is private obj
2161  *		lock_held: TRUE if the lock is held by caller.
2162  *		keyhandle: pointer to object handle to
2163  *			   receive keyhandle for new object
2164  *
2165  *	RETURN VALUE:
2166  *		0: object successfully stored in file
2167  *		-1: some error occurred, object is not stored in file.
2168  *
2169  *	DESCRIPTION:
2170  *		This API is used to write a newly created token object
2171  *		to keystore.
2172  *
2173  *		This function does the following:
2174  *
2175  *		1) Creates a token object file based on "public" parameter.
2176  *		2) Generates a new IV and stores it in obj_meta_data_t if it is
2177  *		   private object.
2178  *		3) Set object version number to 1.
2179  *		4) If it is a private object, it will be encrypted before
2180  *		   being written to the newly created keystore token object
2181  *		   file.
2182  *		5) Calculates the obj_chksum in obj_meta_data_t.
2183  *		6) Calculates the pin_chksum in obj_meta_data_t.
2184  *		7) Increments the keystore version number.
2185  */
2186 int
soft_keystore_put_new_obj(uchar_t * buf,size_t len,boolean_t public,boolean_t lock_held,ks_obj_handle_t * keyhandle)2187 soft_keystore_put_new_obj(uchar_t *buf, size_t len, boolean_t public,
2188     boolean_t lock_held, ks_obj_handle_t *keyhandle)
2189 {
2190 
2191 	int fd, tmp_ks_fd, obj_fd;
2192 	unsigned int counter, version;
2193 	uchar_t obj_hmac[OBJ_HMAC_SIZE];
2194 	CK_BYTE iv[OBJ_IV_SIZE];
2195 	char obj_name[MAXPATHLEN], tmp_ks_desc_name[MAXPATHLEN];
2196 	char filebuf[BUFSIZ];
2197 	char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN],
2198 	    ks_desc_file[MAXPATHLEN];
2199 	CK_ULONG hmac_size;
2200 	ssize_t nread;
2201 
2202 	if (keyhandle == NULL) {
2203 		return (-1);
2204 	}
2205 
2206 	/* if it is private object, make sure we have the key */
2207 	if (!public) {
2208 		if ((enc_key == NULL) ||
2209 		    (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
2210 			return (-1);
2211 		}
2212 	}
2213 
2214 	/* open keystore, and set write lock */
2215 	if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE,
2216 	    lock_held)) < 0) {
2217 		return (-1);
2218 	}
2219 
2220 	(void) get_desc_file_path(ks_desc_file);
2221 	(void) get_tmp_desc_file_path(tmp_ks_desc_name);
2222 
2223 	/*
2224 	 * create a tempoary file for the keystore description
2225 	 * file for updating version and counter information
2226 	 */
2227 	tmp_ks_fd = open_nointr(tmp_ks_desc_name,
2228 	    O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
2229 	if (tmp_ks_fd < 0) {
2230 		(void) close(fd);
2231 		return (-1);
2232 	}
2233 
2234 	/* read and write pkcs11 version */
2235 	if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE)
2236 	    != KS_PKCS11_VER_SIZE) {
2237 		goto cleanup;
2238 	}
2239 
2240 	if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE)
2241 	    != KS_PKCS11_VER_SIZE) {
2242 		goto cleanup;
2243 	}
2244 
2245 	/* get version number, and write updated number to temp file */
2246 	if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) {
2247 		goto cleanup;
2248 	}
2249 
2250 	version = SWAP32(version);
2251 	version++;
2252 	version = SWAP32(version);
2253 
2254 	if (writen_nointr(tmp_ks_fd, (void *)&version,
2255 	    KS_VER_SIZE) != KS_VER_SIZE) {
2256 		goto cleanup;
2257 	}
2258 
2259 	/* get object count value */
2260 	if (readn_nointr(fd, &counter, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) {
2261 		goto cleanup;
2262 	}
2263 	counter = SWAP32(counter);
2264 
2265 	bzero(obj_name, sizeof (obj_name));
2266 	if (public) {
2267 		(void) snprintf(obj_name, MAXPATHLEN,  "%s/%s%d",
2268 		    get_pub_obj_path(pub_obj_path), OBJ_PREFIX, counter);
2269 	} else {
2270 		(void) snprintf(obj_name, MAXPATHLEN,  "%s/%s%d",
2271 		    get_pri_obj_path(pri_obj_path), OBJ_PREFIX, counter);
2272 	}
2273 
2274 	/* create object file */
2275 	obj_fd = open_nointr(obj_name,
2276 	    O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
2277 	if (obj_fd < 0) {
2278 		/* can't create object file */
2279 		goto cleanup;
2280 	}
2281 
2282 	/* lock object file for writing */
2283 	if (lock_file(obj_fd, B_FALSE, B_TRUE) != 0) {
2284 		(void) close(obj_fd);
2285 		goto cleanup2;
2286 	}
2287 
2288 	/* write object meta data */
2289 	version = SWAP32(1);
2290 	if (writen_nointr(obj_fd, (void *)&version, sizeof (version))
2291 	    != sizeof (version)) {
2292 		goto cleanup2;
2293 	}
2294 
2295 	if (public) {
2296 		bzero(iv, sizeof (iv));
2297 	} else {
2298 		/* generate an IV */
2299 		if (soft_gen_iv(iv) != CKR_OK) {
2300 			goto cleanup2;
2301 		}
2302 
2303 	}
2304 
2305 	if (writen_nointr(obj_fd, (void *)iv, sizeof (iv)) != sizeof (iv)) {
2306 		goto cleanup2;
2307 	}
2308 
2309 	if (public) {
2310 
2311 		bzero(obj_hmac, sizeof (obj_hmac));
2312 		if (writen_nointr(obj_fd, (void *)obj_hmac,
2313 		    sizeof (obj_hmac)) != sizeof (obj_hmac)) {
2314 			goto cleanup2;
2315 		}
2316 
2317 		if (writen_nointr(obj_fd, (char *)buf, len) != len) {
2318 			goto cleanup2;
2319 		}
2320 
2321 	} else {
2322 
2323 		uchar_t *encrypted_buf, *prepared_buf;
2324 		CK_ULONG out_len = 0, prepared_len;
2325 
2326 		if (prepare_data_for_encrypt(obj_name, buf, len,
2327 		    &prepared_buf, &prepared_len) != 0) {
2328 			goto cleanup2;
2329 		}
2330 
2331 		if (soft_keystore_crypt(enc_key, iv,
2332 		    B_TRUE, prepared_buf, prepared_len,
2333 		    NULL, &out_len) != CKR_OK) {
2334 			freezero(prepared_buf, prepared_len);
2335 			goto cleanup2;
2336 		}
2337 
2338 		encrypted_buf = malloc(out_len * sizeof (char));
2339 		if (encrypted_buf == NULL) {
2340 			freezero(prepared_buf, prepared_len);
2341 			goto cleanup2;
2342 		}
2343 
2344 		if (soft_keystore_crypt(enc_key, iv,
2345 		    B_TRUE, prepared_buf, prepared_len,
2346 		    encrypted_buf, &out_len) != CKR_OK) {
2347 			freezero(encrypted_buf, out_len);
2348 			freezero(prepared_buf, prepared_len);
2349 			goto cleanup2;
2350 		}
2351 		freezero(prepared_buf, prepared_len);
2352 
2353 		/* calculate HMAC of encrypted object */
2354 		hmac_size = OBJ_HMAC_SIZE;
2355 		if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
2356 		    out_len, obj_hmac, &hmac_size) != CKR_OK) {
2357 			freezero(encrypted_buf, out_len);
2358 			goto cleanup2;
2359 		}
2360 
2361 		if (hmac_size != OBJ_HMAC_SIZE) {
2362 			freezero(encrypted_buf, out_len);
2363 			goto cleanup2;
2364 		}
2365 
2366 		/* write hmac */
2367 		if (writen_nointr(obj_fd, (void *)obj_hmac,
2368 		    sizeof (obj_hmac)) != sizeof (obj_hmac)) {
2369 			freezero(encrypted_buf, out_len);
2370 			goto cleanup2;
2371 		}
2372 
2373 		/* write encrypted object */
2374 		if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len)
2375 		    != out_len) {
2376 			freezero(encrypted_buf, out_len);
2377 			goto cleanup2;
2378 		}
2379 
2380 		freezero(encrypted_buf, out_len);
2381 	}
2382 
2383 
2384 	(void) close(obj_fd);
2385 	(void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name),
2386 	    "obj%d", counter);
2387 	keyhandle->public = public;
2388 
2389 	/*
2390 	 * store new counter to temp keystore description file.
2391 	 */
2392 	counter++;
2393 	counter = SWAP32(counter);
2394 	if (writen_nointr(tmp_ks_fd, (void *)&counter,
2395 	    sizeof (counter)) != sizeof (counter)) {
2396 		goto cleanup2;
2397 	}
2398 
2399 	/* read rest of keystore description file and store into temp file */
2400 	nread = readn_nointr(fd, filebuf, sizeof (filebuf));
2401 	while (nread > 0) {
2402 		if (writen_nointr(tmp_ks_fd, filebuf, nread) != nread) {
2403 			goto cleanup2;
2404 		}
2405 		nread = readn_nointr(fd, filebuf, sizeof (filebuf));
2406 	}
2407 
2408 	(void) close(tmp_ks_fd);
2409 	(void) rename(tmp_ks_desc_name, ks_desc_file);
2410 
2411 	if (!lock_held) {
2412 		/* release lock on description file */
2413 		if (lock_file(fd, B_FALSE, B_FALSE) != 0) {
2414 			(void) close(fd);
2415 			return (-1);
2416 		}
2417 	}
2418 	(void) close(fd);
2419 	explicit_bzero(obj_hmac, sizeof (obj_hmac));
2420 	explicit_bzero(iv, sizeof (iv));
2421 	return (0);
2422 
2423 cleanup2:
2424 
2425 	/* remove object file.  No need to remove lock first */
2426 	(void) unlink(obj_name);
2427 
2428 cleanup:
2429 
2430 	(void) close(tmp_ks_fd);
2431 	(void) remove(tmp_ks_desc_name);
2432 	if (!lock_held) {
2433 		/* release lock on description file */
2434 		(void) lock_file(fd, B_FALSE, B_FALSE);
2435 	}
2436 
2437 	(void) close(fd);
2438 	explicit_bzero(obj_hmac, sizeof (obj_hmac));
2439 	explicit_bzero(iv, sizeof (iv));
2440 	return (-1);
2441 }
2442 
2443 /*
2444  *	FUNCTION: soft_keystore_modify_obj
2445  *
2446  *	ARGUMENTS:
2447  *		ks_handle: handle of the key store object to be modified
2448  *		buf: buffer containing un-encrypted data
2449  *		     to be modified in keystore.
2450  *		len: length of data
2451  *		lock_held: TRUE if the lock is held by caller.
2452  *
2453  *	RETURN VALUE:
2454  *		-1: if any error occurred.
2455  *		Otherwise, 0 is returned.
2456  *
2457  *	DESCRIPTION:
2458  *
2459  *		This API is used to write a modified token object back
2460  *		to keystore.   This function will do the following:
2461  *
2462  *		1) If it is a private object, it will be encrypted before
2463  *		   being written to the corresponding keystore token
2464  *		   object file.
2465  *		2) Record incremented object version number.
2466  *		3) Record incremented keystore version number.
2467  */
2468 int
soft_keystore_modify_obj(ks_obj_handle_t * ks_handle,uchar_t * buf,size_t len,boolean_t lock_held)2469 soft_keystore_modify_obj(ks_obj_handle_t *ks_handle, uchar_t *buf,
2470     size_t len, boolean_t lock_held)
2471 {
2472 	int fd, ks_fd, tmp_fd, version;
2473 	char orig_name[MAXPATHLEN], tmp_name[MAXPATHLEN],
2474 	    tmp_ks_name[MAXPATHLEN];
2475 	uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE];
2476 	char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN],
2477 	    ks_desc_file[MAXPATHLEN];
2478 	CK_ULONG hmac_size;
2479 
2480 	/* if it is private object, make sure we have the key */
2481 	if (!(ks_handle->public)) {
2482 		if ((enc_key == NULL) ||
2483 		    (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
2484 			return (-1);
2485 		}
2486 	}
2487 
2488 	/* open and lock keystore description file */
2489 	if ((ks_fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE,
2490 	    B_FALSE)) < 0) {
2491 		return (-1);
2492 	}
2493 
2494 	(void) get_desc_file_path(ks_desc_file);
2495 
2496 	/* update the version of for keystore file in tempoary file */
2497 	(void) get_tmp_desc_file_path(tmp_ks_name);
2498 	if (create_updated_keystore_version(ks_fd, tmp_ks_name) != 0) {
2499 		/* unlock keystore description file */
2500 		(void) lock_file(ks_fd, B_FALSE, B_FALSE);
2501 		(void) close(ks_fd);
2502 		return (-1);
2503 	}
2504 
2505 	/* open object file */
2506 	if ((fd = open_and_lock_object_file(ks_handle, O_RDWR,
2507 	    lock_held)) < 0) {
2508 		goto cleanup;
2509 	}
2510 
2511 	/*
2512 	 * make the change in a temporary file.  Create the temp
2513 	 * file in the same directory as the token object.  That
2514 	 * way, the "rename" later will be an atomic operation
2515 	 */
2516 	if (ks_handle->public) {
2517 		(void) snprintf(orig_name, MAXPATHLEN, "%s/%s",
2518 		    get_pub_obj_path(pub_obj_path), ks_handle->name);
2519 		(void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s",
2520 		    pub_obj_path, TMP_OBJ_PREFIX,
2521 		    (ks_handle->name) + OBJ_PREFIX_LEN);
2522 	} else {
2523 		(void) snprintf(orig_name, MAXPATHLEN, "%s/%s",
2524 		    get_pri_obj_path(pri_obj_path), ks_handle->name);
2525 		(void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s",
2526 		    pri_obj_path, TMP_OBJ_PREFIX,
2527 		    (ks_handle->name) + OBJ_PREFIX_LEN);
2528 	}
2529 
2530 	tmp_fd = open_nointr(tmp_name,
2531 	    O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
2532 	if (tmp_fd < 0) {
2533 		/* can't create tmp object file */
2534 		goto cleanup1;
2535 	}
2536 
2537 	/* read version, increment, and write to tmp file */
2538 	if (readn_nointr(fd, (char *)&version, OBJ_VER_SIZE) != OBJ_VER_SIZE) {
2539 		goto cleanup2;
2540 	}
2541 
2542 	version = SWAP32(version);
2543 	version++;
2544 	version = SWAP32(version);
2545 
2546 	if (writen_nointr(tmp_fd, (char *)&version, OBJ_VER_SIZE)
2547 	    != OBJ_VER_SIZE) {
2548 		goto cleanup2;
2549 	}
2550 
2551 	/* generate a new IV for the object, old one can be ignored */
2552 	if (soft_gen_iv(iv) != CKR_OK) {
2553 		goto cleanup2;
2554 	}
2555 
2556 	if (writen_nointr(tmp_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
2557 		goto cleanup2;
2558 	}
2559 
2560 	if (ks_handle->public) {
2561 
2562 		/* hmac is always NULL for public objects */
2563 		bzero(obj_hmac, sizeof (obj_hmac));
2564 		if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE)
2565 		    != OBJ_HMAC_SIZE) {
2566 			goto cleanup2;
2567 		}
2568 
2569 		/* write updated object */
2570 		if (writen_nointr(tmp_fd, (char *)buf, len) != len) {
2571 			goto cleanup2;
2572 		}
2573 
2574 	} else {
2575 
2576 		uchar_t *encrypted_buf, *prepared_buf;
2577 		CK_ULONG out_len = 0, prepared_len;
2578 
2579 		if (prepare_data_for_encrypt(orig_name, buf, len,
2580 		    &prepared_buf, &prepared_len) != 0) {
2581 			goto cleanup2;
2582 		}
2583 
2584 		/* encrypt the data */
2585 		if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
2586 		    prepared_len, NULL, &out_len) != CKR_OK) {
2587 			free(prepared_buf);
2588 			goto cleanup2;
2589 		}
2590 
2591 		encrypted_buf = malloc(out_len * sizeof (char));
2592 		if (encrypted_buf == NULL) {
2593 			freezero(prepared_buf, prepared_len);
2594 			goto cleanup2;
2595 		}
2596 
2597 		if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
2598 		    prepared_len, encrypted_buf, &out_len) != CKR_OK) {
2599 			freezero(prepared_buf, prepared_len);
2600 			freezero(encrypted_buf, out_len);
2601 			goto cleanup2;
2602 		}
2603 
2604 		freezero(prepared_buf, prepared_len);
2605 
2606 		/* calculate hmac on encrypted buf */
2607 		hmac_size = OBJ_HMAC_SIZE;
2608 		if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
2609 		    out_len, obj_hmac, &hmac_size) != CKR_OK) {
2610 			freezero(encrypted_buf, out_len);
2611 			goto cleanup2;
2612 		}
2613 
2614 		if (hmac_size != OBJ_HMAC_SIZE) {
2615 			freezero(encrypted_buf, out_len);
2616 			goto cleanup2;
2617 		}
2618 
2619 		if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE)
2620 		    != OBJ_HMAC_SIZE) {
2621 			freezero(encrypted_buf, out_len);
2622 			goto cleanup2;
2623 		}
2624 
2625 		if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len)
2626 		    != out_len) {
2627 			freezero(encrypted_buf, out_len);
2628 			goto cleanup2;
2629 		}
2630 		freezero(encrypted_buf, out_len);
2631 	}
2632 	(void) close(tmp_fd);
2633 
2634 	/* rename updated temporary object file */
2635 	if (rename(tmp_name, orig_name) != 0) {
2636 		(void) unlink(tmp_name);
2637 		return (-1);
2638 	}
2639 
2640 	/* rename updated keystore description file */
2641 	if (rename(tmp_ks_name, ks_desc_file) != 0) {
2642 		(void) unlink(tmp_name);
2643 		(void) unlink(tmp_ks_name);
2644 		return (-1);
2645 	}
2646 
2647 	/* determine need to unlock file or not */
2648 	if (!lock_held) {
2649 		if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
2650 			(void) close(fd);
2651 			(void) unlink(tmp_name);
2652 			return (-1);
2653 		}
2654 	}
2655 
2656 	/* unlock keystore description file */
2657 	if (lock_file(ks_fd, B_FALSE, B_FALSE) != 0) {
2658 		(void) close(ks_fd);
2659 		(void) close(fd);
2660 		return (-1);
2661 	}
2662 
2663 	(void) close(ks_fd);
2664 
2665 	(void) close(fd);
2666 
2667 	explicit_bzero(iv, sizeof (iv));
2668 	explicit_bzero(obj_hmac, sizeof (obj_hmac));
2669 	return (0); /* All operations completed successfully */
2670 
2671 cleanup2:
2672 	(void) close(tmp_fd);
2673 	(void) remove(tmp_name);
2674 
2675 cleanup1:
2676 	(void) close(fd);
2677 
2678 cleanup:
2679 	/* unlock keystore description file */
2680 	(void) lock_file(ks_fd, B_FALSE, B_FALSE);
2681 	(void) close(ks_fd);
2682 	(void) remove(tmp_ks_name);
2683 	explicit_bzero(iv, sizeof (iv));
2684 	explicit_bzero(obj_hmac, sizeof (obj_hmac));
2685 	return (-1);
2686 }
2687 
2688 /*
2689  *	FUNCTION: soft_keystore_del_obj
2690  *
2691  *	ARGUMENTS:
2692  *		ks_handle: handle of the key store object to be deleted
2693  *		lock_held: TRUE if the lock is held by caller.
2694  *
2695  *	RETURN VALUE:
2696  *		-1: if any error occurred.
2697  *		0: object successfully deleted from keystore.
2698  *
2699  *	DESCRIPTION:
2700  *		This API is used to delete a particular token object from
2701  *		the keystore.  The corresponding token object file will be
2702  *		removed from the file system.
2703  *		Any future reference to the deleted file will
2704  *		return an CKR_OBJECT_HANDLE_INVALID error.
2705  */
2706 int
soft_keystore_del_obj(ks_obj_handle_t * ks_handle,boolean_t lock_held)2707 soft_keystore_del_obj(ks_obj_handle_t *ks_handle, boolean_t lock_held)
2708 {
2709 	char objname[MAXPATHLEN], tmp_ks_name[MAXPATHLEN];
2710 	int fd;
2711 	char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN],
2712 	    ks_desc_file[MAXPATHLEN];
2713 	int ret_val = -1;
2714 	int obj_fd;
2715 
2716 	if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE,
2717 	    lock_held)) < 0) {
2718 		return (-1);
2719 	}
2720 
2721 	(void) get_desc_file_path(ks_desc_file);
2722 	(void) get_tmp_desc_file_path(tmp_ks_name);
2723 	if (create_updated_keystore_version(fd, tmp_ks_name) != 0) {
2724 		goto cleanup;
2725 	}
2726 
2727 	if (ks_handle->public) {
2728 		(void) snprintf(objname, MAXPATHLEN, "%s/%s",
2729 		    get_pub_obj_path(pub_obj_path), ks_handle->name);
2730 	} else {
2731 		(void) snprintf(objname, MAXPATHLEN, "%s/%s",
2732 		    get_pri_obj_path(pri_obj_path), ks_handle->name);
2733 	}
2734 
2735 	/*
2736 	 * make sure no other process is reading/writing the file
2737 	 * by acquiring the lock on the file
2738 	 */
2739 	if ((obj_fd = open_and_lock_object_file(ks_handle, O_WRONLY,
2740 	    B_FALSE)) < 0) {
2741 		return (-1);
2742 	}
2743 
2744 	if (unlink(objname) != 0) {
2745 		(void) lock_file(obj_fd, B_FALSE, B_FALSE);
2746 		(void) close(obj_fd);
2747 		goto cleanup;
2748 	}
2749 
2750 	(void) lock_file(obj_fd, B_FALSE, B_FALSE);
2751 	(void) close(obj_fd);
2752 
2753 	if (rename(tmp_ks_name, ks_desc_file) != 0) {
2754 		goto cleanup;
2755 	}
2756 	ret_val = 0;
2757 
2758 cleanup:
2759 	/* unlock keystore description file */
2760 	if (!lock_held) {
2761 		if (lock_file(fd, B_FALSE, B_FALSE) != 0) {
2762 			(void) close(fd);
2763 			return (-1);
2764 		}
2765 	}
2766 
2767 	(void) close(fd);
2768 	return (ret_val);
2769 }
2770 
2771 /*
2772  * Get the salt used for generating hashed pin from the
2773  * keystore description file.
2774  *
2775  * The result will be stored in the provided buffer "salt" passed
2776  * in as an argument.
2777  *
2778  * Return 0 if no error, return -1 if there's any error.
2779  */
2780 int
soft_keystore_get_pin_salt(char ** salt)2781 soft_keystore_get_pin_salt(char **salt)
2782 {
2783 	int fd, ret_val = -1;
2784 	uint64_t hashed_pin_salt_size;
2785 
2786 	if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE,
2787 	    B_FALSE)) < 0) {
2788 		return (-1);
2789 	}
2790 
2791 	if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET)
2792 	    != KS_HASHED_PIN_SALT_LEN_OFFSET) {
2793 		goto cleanup;
2794 	}
2795 
2796 	if (readn_nointr(fd, (char *)&hashed_pin_salt_size,
2797 	    KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
2798 		goto cleanup;
2799 	}
2800 	hashed_pin_salt_size = SWAP64(hashed_pin_salt_size);
2801 
2802 	*salt = malloc(hashed_pin_salt_size + 1);
2803 	if (*salt == NULL) {
2804 		goto cleanup;
2805 	}
2806 
2807 	if ((readn_nointr(fd, *salt, hashed_pin_salt_size))
2808 	    != (ssize_t)hashed_pin_salt_size) {
2809 		freezero(*salt, hashed_pin_salt_size + 1);
2810 		goto cleanup;
2811 	}
2812 	(*salt)[hashed_pin_salt_size] = '\0';
2813 
2814 	ret_val = 0;
2815 
2816 cleanup:
2817 	if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
2818 		ret_val = -1;
2819 	}
2820 
2821 	(void) close(fd);
2822 	return (ret_val);
2823 }
2824 
2825 /*
2826  *	FUNCTION: soft_keystore_pin_initialized
2827  *
2828  *	ARGUMENTS:
2829  *		initialized: This value will be set to true if keystore is
2830  *			     initialized, and false otherwise.
2831  *		hashed_pin: If the keystore is initialized, this will contain
2832  *			    the hashed pin.  It will be NULL if the keystore
2833  *			    pin is not initialized.  Memory allocated
2834  *			    for the hashed pin needs to be freed by
2835  *			    the caller.
2836  *		lock_held: TRUE if the lock is held by caller.
2837  *
2838  *	RETURN VALUE:
2839  *		CKR_OK: No error
2840  *		any other appropriate CKR_value
2841  *
2842  *	DESCRIPTION:
2843  *		This API is used to determine if the PIN in the keystore
2844  *		has been initialized or not.
2845  *		It makes the determination using the salt for generating the
2846  *		encryption key.  The salt is stored in the keystore
2847  *		descryption file.  The salt should be all zero if
2848  *		the keystore pin has not been initialized.
2849  *		If the pin has been initialized, it is returned in the
2850  *		hashed_pin argument.
2851  */
2852 CK_RV
soft_keystore_pin_initialized(boolean_t * initialized,char ** hashed_pin,boolean_t lock_held)2853 soft_keystore_pin_initialized(boolean_t *initialized, char **hashed_pin,
2854     boolean_t lock_held)
2855 {
2856 	int fd;
2857 	CK_BYTE crypt_salt[KS_KEY_SALT_SIZE], tmp_buf[KS_KEY_SALT_SIZE];
2858 	CK_RV ret_val = CKR_OK;
2859 
2860 	if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE,
2861 	    lock_held)) < 0) {
2862 		return (CKR_FUNCTION_FAILED);
2863 	}
2864 
2865 	if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) {
2866 		ret_val = CKR_FUNCTION_FAILED;
2867 		goto cleanup;
2868 	}
2869 
2870 	if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE)
2871 	    != KS_KEY_SALT_SIZE) {
2872 		ret_val = CKR_FUNCTION_FAILED;
2873 		goto cleanup;
2874 	}
2875 
2876 	(void) bzero(tmp_buf, KS_KEY_SALT_SIZE);
2877 
2878 	if (memcmp(crypt_salt, tmp_buf, KS_KEY_SALT_SIZE) == 0) {
2879 		*initialized = B_FALSE;
2880 		hashed_pin = NULL;
2881 	} else {
2882 		*initialized = B_TRUE;
2883 		ret_val = get_hashed_pin(fd, hashed_pin);
2884 	}
2885 
2886 cleanup:
2887 
2888 	if (!lock_held) {
2889 		if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
2890 			ret_val = CKR_FUNCTION_FAILED;
2891 		}
2892 	}
2893 
2894 	(void) close(fd);
2895 	return (ret_val);
2896 }
2897 
2898 /*
2899  * This checks if the keystore file exists
2900  */
2901 
2902 static int
soft_keystore_exists()2903 soft_keystore_exists()
2904 {
2905 	int ret;
2906 	struct stat fn_stat;
2907 	char *fname, ks_desc_file[MAXPATHLEN];
2908 
2909 	fname = get_desc_file_path(ks_desc_file);
2910 	ret = stat(fname, &fn_stat);
2911 	if (ret == 0)
2912 		return (0);
2913 	return (errno);
2914 }
2915 
2916 /*
2917  *	FUNCTION: soft_keystore_init
2918  *
2919  *	ARGUMENTS:
2920  *		desired_state:  The keystore state the caller would like
2921  *				it to be.
2922  *
2923  *	RETURN VALUE:
2924  *		Returns the state the function is in.  If it succeeded, it
2925  *		will be the same as the desired, if not it will be
2926  *		KEYSTORE_UNAVAILABLE.
2927  *
2928  *	DESCRIPTION:
2929  *		This function will only load as much keystore data as is
2930  *		requested at that time. This is for performace by delaying the
2931  *		reading of token objects until they are needed or never at
2932  *		all if they are not used.
2933  *
2934  *		Primary use is from C_InitToken().
2935  *		It is also called by soft_keystore_status() when the
2936  *		"desired_state" is not the the current load state of keystore.
2937  *
2938  */
2939 int
soft_keystore_init(int desired_state)2940 soft_keystore_init(int desired_state)
2941 {
2942 	int ret;
2943 
2944 	(void) pthread_mutex_lock(&soft_slot.keystore_mutex);
2945 
2946 	/*
2947 	 * If more than one session tries to initialize the keystore, the
2948 	 * second and other following sessions that were waiting for the lock
2949 	 * will quickly exit if their requirements are satisfied.
2950 	 */
2951 	if (desired_state <= soft_slot.keystore_load_status) {
2952 		(void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
2953 		return (soft_slot.keystore_load_status);
2954 	}
2955 
2956 	/*
2957 	 * With 'keystore_load_status' giving the current state of the
2958 	 * process, this switch will bring it up to the desired state if
2959 	 * possible.
2960 	 */
2961 
2962 	switch (soft_slot.keystore_load_status) {
2963 	case KEYSTORE_UNINITIALIZED:
2964 		ret = soft_keystore_exists();
2965 		if (ret == 0)
2966 			soft_slot.keystore_load_status = KEYSTORE_PRESENT;
2967 		else if (ret == ENOENT)
2968 			if (create_keystore() == 0)
2969 				soft_slot.keystore_load_status =
2970 				    KEYSTORE_PRESENT;
2971 			else {
2972 				soft_slot.keystore_load_status =
2973 				    KEYSTORE_UNAVAILABLE;
2974 				cryptoerror(LOG_DEBUG,
2975 				    "pkcs11_softtoken: "
2976 				    "Cannot create keystore.");
2977 				break;
2978 			}
2979 
2980 		if (desired_state <= KEYSTORE_PRESENT)
2981 			break;
2982 
2983 	/* FALLTHRU */
2984 	case KEYSTORE_PRESENT:
2985 		if (soft_keystore_get_version(&soft_slot.ks_version, B_FALSE)
2986 		    != 0) {
2987 			soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE;
2988 			cryptoerror(LOG_DEBUG,
2989 			    "pkcs11_softtoken: Keystore access failed.");
2990 			break;
2991 		}
2992 
2993 		soft_slot.keystore_load_status = KEYSTORE_LOAD;
2994 		if (desired_state <= KEYSTORE_LOAD)
2995 			break;
2996 
2997 	/* FALLTHRU */
2998 	case KEYSTORE_LOAD:
2999 		/* Load all the public token objects from keystore */
3000 		if (soft_get_token_objects_from_keystore(PUB_TOKENOBJS)
3001 		    != CKR_OK) {
3002 			(void) soft_destroy_token_session();
3003 			soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE;
3004 			cryptoerror(LOG_DEBUG,
3005 			    "pkcs11_softtoken: Cannot initialize keystore.");
3006 			break;
3007 		}
3008 
3009 		soft_slot.keystore_load_status = KEYSTORE_INITIALIZED;
3010 	};
3011 
3012 	(void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
3013 	return (soft_slot.keystore_load_status);
3014 }
3015 
3016 /*
3017  *	FUNCTION: soft_keystore_status
3018  *
3019  *	ARGUMENTS:
3020  *		desired_state:  The keystore state the caller would like
3021  *				it to be.
3022  *
3023  *	RETURN VALUE:
3024  *		B_TRUE if keystore is ready and at the desired state.
3025  *		B_FALSE if keystore had an error and is not available.
3026  *
3027  *	DESCRIPTION:
3028  *		The calling function wants to make sure the keystore load
3029  *		status to in a state it requires.  If it is not at that
3030  *		state it will call the load function.
3031  *		If keystore is at the desired state or has just been
3032  *		loaded to that state, it will return TRUE.  If there has been
3033  *		load failure, it will return FALSE.
3034  *
3035  */
3036 boolean_t
soft_keystore_status(int desired_state)3037 soft_keystore_status(int desired_state)
3038 {
3039 
3040 	if (soft_slot.keystore_load_status == KEYSTORE_UNAVAILABLE)
3041 		return (B_FALSE);
3042 
3043 	return ((desired_state <= soft_slot.keystore_load_status) ||
3044 	    (soft_keystore_init(desired_state) == desired_state));
3045 }
3046