dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / pkcs11_softtoken / common / softKeystoreUtil.c
blob996524b8f4fc0b1cd7fe037adb17b80c473ec9ee
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
26 * Functions used for manipulating the keystore
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <errno.h>
32 #include <sys/stat.h>
33 #include <fcntl.h>
34 #include <time.h>
35 #include <unistd.h>
36 #include <pwd.h>
37 #include <sys/types.h>
38 #include <dirent.h>
39 #include <limits.h>
40 #include <libgen.h>
41 #include <strings.h>
42 #include <security/cryptoki.h>
43 #include <cryptoutil.h>
44 #include "softGlobal.h"
45 #include "softObject.h"
46 #include "softSession.h"
47 #include "softKeystore.h"
48 #include "softKeystoreUtil.h"
50 #define MAXPATHLEN 1024
51 #define SUNW_PATH ".sunw" /* top level Sun directory */
52 #define KEYSTORE_PATH "pkcs11_softtoken" /* keystore directory */
53 #define PUB_OBJ_DIR "public" /* directory for public objects */
54 #define PRI_OBJ_DIR "private" /* directory for private objects */
55 #define DS_FILE "objstore_info" /* keystore description file */
56 #define TMP_DS_FILE "t_info" /* temp name for keystore desc. file */
57 #define OBJ_PREFIX "obj" /* prefix of the keystore object file names */
58 #define OBJ_PREFIX_LEN sizeof (OBJ_PREFIX) - 1 /* length of prefix */
59 #define TMP_OBJ_PREFIX "t_o" /* prefix of the temp object file names */
62 * KEYSTORE DESCRIPTION FILE:
64 * The following describes the content of the keystore description file
66 * The order AND data type of the fields are very important.
67 * All the code in this file assume that they are in the order specified
68 * below. If either order of the fields or their data type changed,
69 * you must make sure the ALL the pre-define values are still valid
71 * 1) PKCS#11 release number. It's 2.20 in this release (uchar_t[32])
72 * 2) keystore version number: used for synchronizing when different
73 * processes access the keystore at the same time. It is incremented
74 * when there is a change to the keystore. (uint_32)
75 * 3) monotonic-counter: last counter value for name of token object file.
76 * used for assigning unique name to each token (uint_32)
77 * 4) salt used for generating encryption key (uint_16)
78 * 5) salt used for generating key used for doing HMAC (uint_16)
79 * 6) Length of salt used for generating hashed pin (length of salt
80 * is variable)
81 * 7) Salt used for generating hashed pin.
82 * 8) Hashed pin len (length of hashed pin could be variable, the offset of
83 * where this value lives in the file is calculated at run time)
84 * 9) Hashed pin
88 /* Keystore description file pre-defined values */
89 #define KS_PKCS11_VER "2.20"
90 #define KS_PKCS11_OFFSET 0
91 #define KS_PKCS11_VER_SIZE 32
93 #define KS_VER_OFFSET (KS_PKCS11_OFFSET + KS_PKCS11_VER_SIZE)
94 #define KS_VER_SIZE 4 /* size in bytes of keystore version value */
96 #define KS_COUNTER_OFFSET (KS_VER_OFFSET + KS_VER_SIZE)
97 #define KS_COUNTER_SIZE 4 /* size in bytes of the monotonic counter */
99 #define KS_KEY_SALT_OFFSET (KS_COUNTER_OFFSET + KS_COUNTER_SIZE)
100 #define KS_KEY_SALT_SIZE PBKD2_SALT_SIZE
102 #define KS_HMAC_SALT_OFFSET (KS_KEY_SALT_OFFSET + KS_KEY_SALT_SIZE)
103 #define KS_HMAC_SALT_SIZE PBKD2_SALT_SIZE
105 /* Salt for hashed pin */
106 #define KS_HASHED_PIN_SALT_LEN_OFFSET (KS_HMAC_SALT_OFFSET + KS_HMAC_SALT_SIZE)
107 #define KS_HASHED_PIN_SALT_LEN_SIZE 8 /* stores length of hashed pin salt */
109 #define KS_HASHED_PIN_SALT_OFFSET \
110 (KS_HASHED_PIN_SALT_LEN_OFFSET + KS_HASHED_PIN_SALT_LEN_SIZE)
113 * hashed pin
115 * hashed_pin length offset will be calculated at run time since
116 * there's the hashed pin salt size is variable.
118 * The offset will be calculated at run time by calling the
119 * function calculate_hashed_pin_offset()
121 static off_t ks_hashed_pinlen_offset = -1;
122 #define KS_HASHED_PINLEN_SIZE 8
124 /* End of Keystore description file pre-defined values */
127 * Metadata for each object
129 * The order AND data type of all the fields is very important.
130 * All the code in this file assume that they are in the order specified
131 * below. If either order of the fields or their data type is changed,
132 * you must make sure the following pre-define value is still valid
133 * Each object will have the meta data at the beginning of the object file.
135 * 1) object_version: used by softtoken to see if the object
136 * has been modified since it last reads it. (uint_32)
137 * 2) iv: initialization vector for encrypted data in the object. This
138 * value will be 0 for public objects. (uchar_t[16])
139 * 3) obj_hmac: keyed hash as verifier to detect private object
140 * being tampered this value will be 0 for public objects (uchar_t[16])
143 /* Object metadata pre-defined values */
144 #define OBJ_VER_OFFSET 0
145 #define OBJ_VER_SIZE 4 /* size of object version in bytes */
146 #define OBJ_IV_OFFSET (OBJ_VER_OFFSET + OBJ_VER_SIZE)
147 #define OBJ_IV_SIZE 16
148 #define OBJ_HMAC_OFFSET (OBJ_IV_OFFSET + OBJ_IV_SIZE)
149 #define OBJ_HMAC_SIZE 16 /* MD5 HMAC keyed hash */
150 #define OBJ_DATA_OFFSET (OBJ_HMAC_OFFSET + OBJ_HMAC_SIZE)
151 /* End of object metadata pre-defined values */
153 #define ALTERNATE_KEYSTORE_PATH "SOFTTOKEN_DIR"
155 static soft_object_t *enc_key = NULL;
156 static soft_object_t *hmac_key = NULL;
157 static char keystore_path[MAXPATHLEN];
158 static boolean_t keystore_path_initialized = B_FALSE;
159 static int desc_fd = 0;
161 static char *
162 get_keystore_path()
164 char *home = getenv("HOME");
165 char *alt = getenv(ALTERNATE_KEYSTORE_PATH);
167 if (keystore_path_initialized) {
168 return (keystore_path);
171 bzero(keystore_path, sizeof (keystore_path));
173 * If it isn't set or is set to the empty string use the
174 * default location. We need to check for the empty string
175 * because some users "unset" environment variables by giving
176 * them no value, this isn't the same thing as removing it
177 * from the environment.
179 * We don't want that to attempt to open /.sunw/pkcs11_sofftoken
181 if ((alt != NULL) && (strcmp(alt, "") != 0)) {
182 (void) snprintf(keystore_path, MAXPATHLEN, "%s/%s",
183 alt, KEYSTORE_PATH);
184 keystore_path_initialized = B_TRUE;
185 } else if ((home != NULL) && (strcmp(home, "") != 0)) {
186 /* alternate path not specified, try user's home dir */
187 (void) snprintf(keystore_path, MAXPATHLEN, "%s/%s/%s",
188 home, SUNW_PATH, KEYSTORE_PATH);
189 keystore_path_initialized = B_TRUE;
191 return (keystore_path);
194 static char *
195 get_pub_obj_path(char *name)
197 bzero(name, sizeof (name));
198 (void) snprintf(name, MAXPATHLEN, "%s/%s",
199 get_keystore_path(), PUB_OBJ_DIR);
200 return (name);
203 static char *
204 get_pri_obj_path(char *name)
206 bzero(name, sizeof (name));
207 (void) snprintf(name, MAXPATHLEN, "%s/%s",
208 get_keystore_path(), PRI_OBJ_DIR);
209 return (name);
212 static char *
213 get_desc_file_path(char *name)
215 bzero(name, sizeof (name));
216 (void) snprintf(name, MAXPATHLEN, "%s/%s",
217 get_keystore_path(), DS_FILE);
218 return (name);
221 static char *
222 get_tmp_desc_file_path(char *name)
224 bzero(name, sizeof (name));
225 (void) snprintf(name, MAXPATHLEN, "%s/%s",
226 get_keystore_path(), TMP_DS_FILE);
227 return (name);
231 * Calculates the offset for hashed_pin length and hashed pin
233 * Returns 0 if successful, -1 if there's any error.
235 * If successful, global variables "ks_hashed_pinlen_offset" will be set.
238 static int
239 calculate_hashed_pin_offset(int fd)
241 uint64_t salt_length;
243 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET)
244 != KS_HASHED_PIN_SALT_LEN_OFFSET) {
245 return (-1);
248 if (readn_nointr(fd, (char *)&salt_length,
249 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
250 return (-1);
252 salt_length = SWAP64(salt_length);
254 ks_hashed_pinlen_offset = KS_HASHED_PIN_SALT_LEN_OFFSET
255 + KS_HASHED_PIN_SALT_LEN_SIZE + salt_length;
257 return (0);
262 * acquire or release read/write lock on a specific file
264 * read_lock: true for read lock; false for write lock
265 * set_lock: true to set a lock; false to release a lock
267 static int
268 lock_file(int fd, boolean_t read_lock, boolean_t set_lock)
271 flock_t lock_info;
272 int r;
274 lock_info.l_whence = SEEK_SET;
275 lock_info.l_start = 0;
276 lock_info.l_len = 0; /* l_len == 0 means until end of file */
278 if (read_lock) {
279 lock_info.l_type = F_RDLCK;
280 } else {
281 lock_info.l_type = F_WRLCK;
284 if (set_lock) {
285 while ((r = fcntl(fd, F_SETLKW, &lock_info)) == -1) {
286 if (errno != EINTR)
287 break;
289 if (r == -1) {
290 return (-1);
292 } else {
293 lock_info.l_type = F_UNLCK;
294 while ((r = fcntl(fd, F_SETLKW, &lock_info)) == -1) {
295 if (errno != EINTR)
296 break;
298 if (r == -1) {
299 return (-1);
303 return (0);
307 create_keystore()
309 int fd, buf;
310 uint64_t hashed_pin_len, hashed_pin_salt_len, ulong_buf;
311 uchar_t ver_buf[KS_PKCS11_VER_SIZE];
312 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN],
313 ks_desc_file[MAXPATHLEN];
314 CK_BYTE salt[KS_KEY_SALT_SIZE];
315 char *hashed_pin = NULL, *hashed_pin_salt = NULL;
316 char *alt;
318 /* keystore doesn't exist, create keystore directory */
319 if (mkdir(get_keystore_path(), S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
320 if (errno == EEXIST) {
321 return (0);
324 if (errno == EACCES) {
325 return (-1);
328 /* can't create keystore directory */
329 if (errno == ENOENT) { /* part of the path doesn't exist */
330 char keystore[MAXPATHLEN];
332 * try to create $HOME/.sunw/pkcs11_softtoken if it
333 * doesn't exist. If it is a alternate path provided
334 * by the user, it should have existed. Will not
335 * create for them.
337 alt = getenv(ALTERNATE_KEYSTORE_PATH);
338 if ((alt == NULL) || (strcmp(alt, "") == 0)) {
339 char *home = getenv("HOME");
341 if (home == NULL || strcmp(home, "") == 0) {
342 return (-1);
344 /* create $HOME/.sunw/pkcs11_softtoken */
345 (void) snprintf(keystore, sizeof (keystore),
346 "%s/%s/%s", home, SUNW_PATH, KEYSTORE_PATH);
347 if (mkdirp(keystore,
348 S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
349 return (-1);
351 } else {
352 return (-1);
357 /* create keystore description file */
358 fd = open_nointr(get_desc_file_path(ks_desc_file),
359 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
360 if (fd < 0) {
361 if (errno == EEXIST) {
362 return (0);
363 } else {
364 /* can't create keystore description file */
365 (void) rmdir(get_keystore_path());
366 return (-1);
370 if (lock_file(fd, B_FALSE, B_TRUE) != 0) {
371 (void) unlink(ks_desc_file);
372 (void) close(fd);
373 (void) rmdir(get_keystore_path());
374 return (-1);
377 if (mkdir(get_pub_obj_path(pub_obj_path),
378 S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
379 /* can't create directory for public objects */
380 (void) lock_file(fd, B_FALSE, B_FALSE);
381 (void) unlink(ks_desc_file);
382 (void) close(fd);
383 (void) rmdir(get_keystore_path());
384 return (-1);
387 if (mkdir(get_pri_obj_path(pri_obj_path),
388 S_IRUSR|S_IWUSR|S_IXUSR) < 0) {
389 /* can't create directory for private objects */
390 (void) lock_file(fd, B_FALSE, B_FALSE);
391 (void) unlink(ks_desc_file);
392 (void) close(fd);
393 (void) rmdir(get_keystore_path());
394 (void) rmdir(pub_obj_path);
395 return (-1);
399 /* write file format release number */
400 bzero(ver_buf, sizeof (ver_buf));
401 (void) strcpy((char *)ver_buf, KS_PKCS11_VER);
402 if ((writen_nointr(fd, (char *)ver_buf, sizeof (ver_buf)))
403 != sizeof (ver_buf)) {
404 goto cleanup;
407 /* write version number, version = 0 since keystore just created */
408 buf = SWAP32(0);
409 if (writen_nointr(fd, (void *)&buf, KS_VER_SIZE) != KS_VER_SIZE) {
410 goto cleanup;
413 /* write monotonic-counter. Counter for keystore objects start at 1 */
414 buf = SWAP32(1);
415 if (writen_nointr(fd, (void *)&buf, KS_COUNTER_SIZE)
416 != KS_COUNTER_SIZE) {
417 goto cleanup;
420 /* initial encryption key salt should be all NULL */
421 bzero(salt, sizeof (salt));
422 if (writen_nointr(fd, (void *)salt, KS_KEY_SALT_SIZE)
423 != KS_KEY_SALT_SIZE) {
424 goto cleanup;
427 /* initial HMAC key salt should also be all NULL */
428 if (writen_nointr(fd, (void *)salt, KS_HMAC_SALT_SIZE)
429 != KS_HMAC_SALT_SIZE) {
430 goto cleanup;
433 /* generate the hashed pin salt, and MD5 hashed pin of default pin */
434 if (soft_gen_hashed_pin((CK_CHAR_PTR)SOFT_DEFAULT_PIN, &hashed_pin,
435 &hashed_pin_salt) < 0) {
436 goto cleanup;
439 if ((hashed_pin_salt == NULL) || (hashed_pin == NULL)) {
440 goto cleanup;
443 hashed_pin_salt_len = (uint64_t)strlen(hashed_pin_salt);
444 hashed_pin_len = (uint64_t)strlen(hashed_pin);
446 /* write hashed pin salt length */
447 ulong_buf = SWAP64(hashed_pin_salt_len);
448 if (writen_nointr(fd, (void *)&ulong_buf, KS_HASHED_PIN_SALT_LEN_SIZE)
449 != KS_HASHED_PIN_SALT_LEN_SIZE) {
450 goto cleanup;
453 if (writen_nointr(fd, (void *)hashed_pin_salt,
454 hashed_pin_salt_len) != hashed_pin_salt_len) {
455 goto cleanup;
458 /* write MD5 hashed pin of the default pin */
459 ulong_buf = SWAP64(hashed_pin_len);
460 if (writen_nointr(fd, (void *)&ulong_buf, KS_HASHED_PINLEN_SIZE)
461 != KS_HASHED_PINLEN_SIZE) {
462 goto cleanup;
465 if (writen_nointr(fd, (void *)hashed_pin, hashed_pin_len)
466 != hashed_pin_len) {
467 goto cleanup;
470 (void) lock_file(fd, B_FALSE, B_FALSE);
472 (void) close(fd);
473 free(hashed_pin_salt);
474 return (0);
476 cleanup:
477 (void) lock_file(fd, B_FALSE, B_FALSE);
478 (void) unlink(ks_desc_file);
479 (void) close(fd);
480 (void) rmdir(get_keystore_path());
481 (void) rmdir(pub_obj_path);
482 (void) rmdir(pri_obj_path);
483 return (-1);
487 * Determines if the file referenced by "fd" has the same
488 * inode as the file referenced by "fname".
490 * The argument "same" contains the result of determining
491 * if the inode is the same or not
493 * Returns 0 if there's no error.
494 * Returns 1 if there's any error with opening the file.
498 static int
499 is_inode_same(int fd, char *fname, boolean_t *same)
501 struct stat fn_stat, fd_stat;
503 if (fstat(fd, &fd_stat) != 0) {
504 return (-1);
507 if (stat(fname, &fn_stat) != 0) {
508 return (-1);
511 /* It's the same file if both st_ino and st_dev match */
512 if ((fd_stat.st_ino == fn_stat.st_ino) &&
513 (fd_stat.st_dev == fn_stat.st_dev)) {
514 *same = B_TRUE;
515 } else {
516 *same = B_FALSE;
518 return (0);
521 static int
522 acquire_file_lock(int *fd, char *fname, mode_t mode) {
524 boolean_t read_lock = B_TRUE, same_inode;
526 if ((mode == O_RDWR) || (mode == O_WRONLY)) {
527 read_lock = B_FALSE;
530 if (lock_file(*fd, read_lock, B_TRUE) != 0) {
531 return (-1);
535 * make sure another process did not modify the file
536 * while we were trying to get the lock
538 if (is_inode_same(*fd, fname, &same_inode) != 0) {
539 (void) lock_file(*fd, B_TRUE, B_FALSE); /* unlock file */
540 return (-1);
543 while (!same_inode) {
545 * need to unlock file, close, re-open the file,
546 * and re-acquire the lock
549 /* unlock file */
550 if (lock_file(*fd, B_TRUE, B_FALSE) != 0) {
551 return (-1);
554 (void) close(*fd);
556 /* re-open */
557 *fd = open_nointr(fname, mode|O_NONBLOCK);
558 if (*fd < 0) {
559 return (-1);
562 /* acquire lock again */
563 if (lock_file(*fd, read_lock, B_TRUE) != 0) {
564 return (-1);
567 if (is_inode_same(*fd, fname, &same_inode) != 0) {
568 (void) lock_file(*fd, B_TRUE, B_FALSE); /* unlock */
569 return (-1);
574 return (0);
578 * Open the keystore description file in the specified mode.
579 * If the keystore doesn't exist, the "do_create_keystore"
580 * argument determines if the keystore should be created
582 static int
583 open_and_lock_keystore_desc(mode_t mode, boolean_t do_create_keystore,
584 boolean_t lock_held)
587 int fd;
588 char *fname, ks_desc_file[MAXPATHLEN];
590 /* open the keystore description file in requested mode */
591 fname = get_desc_file_path(ks_desc_file);
592 fd = open_nointr(fname, mode|O_NONBLOCK);
593 if (fd < 0) {
594 if ((errno == ENOENT) && (do_create_keystore)) {
595 if (create_keystore() < 0) {
596 goto done;
598 fd = open_nointr(fname, mode|O_NONBLOCK);
599 if (fd < 0) {
600 goto done;
602 } else {
603 goto done;
607 if (lock_held) {
608 /* already hold the lock */
609 return (fd);
612 if (acquire_file_lock(&fd, fname, mode) != 0) {
613 if (fd > 0) {
614 (void) close(fd);
616 return (-1);
619 done:
620 return (fd);
625 * Set or remove read or write lock on keystore description file
627 * read_lock: true for read lock, false for write lock
628 * set_lock: true for set a lock, false to remove a lock
630 static int
631 lock_desc_file(boolean_t read_lock, boolean_t set_lock)
634 char ks_desc_file[MAXPATHLEN];
636 if (set_lock) {
637 int oflag;
640 * make sure desc_fd is not already used. If used, it means
641 * some other lock is already set on the file
643 if (desc_fd > 0) {
644 return (-1);
647 (void) get_desc_file_path(ks_desc_file);
649 if (read_lock) {
650 oflag = O_RDONLY;
651 } else {
652 oflag = O_WRONLY;
654 if ((desc_fd = open_and_lock_keystore_desc(oflag,
655 B_FALSE, B_FALSE)) < 0) {
656 return (-1);
658 } else {
659 /* make sure we have a valid fd */
660 if (desc_fd <= 0) {
661 return (-1);
664 if (lock_file(desc_fd, read_lock, B_FALSE) == 1) {
665 return (-1);
668 (void) close(desc_fd);
669 desc_fd = 0;
672 return (0);
675 static int
676 open_and_lock_object_file(ks_obj_handle_t *ks_handle, int oflag,
677 boolean_t lock_held)
679 char obj_fname[MAXPATHLEN];
680 int fd;
682 if (ks_handle->public) {
683 char pub_obj_path[MAXPATHLEN];
684 (void) snprintf(obj_fname, MAXPATHLEN, "%s/%s",
685 get_pub_obj_path(pub_obj_path), ks_handle->name);
686 } else {
687 char pri_obj_path[MAXPATHLEN];
688 (void) snprintf(obj_fname, MAXPATHLEN, "%s/%s",
689 get_pri_obj_path(pri_obj_path), ks_handle->name);
692 fd = open_nointr(obj_fname, oflag|O_NONBLOCK);
693 if (fd < 0) {
694 return (-1);
697 if (lock_held) {
698 /* already hold the lock */
699 return (fd);
702 if (acquire_file_lock(&fd, obj_fname, oflag) != 0) {
703 if (fd > 0) {
704 (void) close(fd);
706 return (-1);
710 return (fd);
715 * Update file version number in a temporary file that's
716 * a copy of the keystore description file.
717 * The update is NOT made to the original keystore description
718 * file. It makes the update in a tempoary file.
720 * Name of the temporary file is assumed to be provided, but
721 * the file is assumed to not exist.
723 * return 0 if creating temp file is successful, returns -1 otherwise
725 static int
726 create_updated_keystore_version(int fd, char *tmp_fname)
728 int version, tmp_fd;
729 char buf[BUFSIZ];
730 size_t nread;
732 /* first, create the tempoary file */
733 tmp_fd = open_nointr(tmp_fname,
734 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
735 if (tmp_fd < 0) {
736 return (-1);
740 * copy everything from keystore version to temp file except
741 * the keystore version. Keystore version is updated
745 /* pkcs11 version */
746 if (readn_nointr(fd, buf, KS_PKCS11_VER_SIZE) != KS_PKCS11_VER_SIZE) {
747 goto cleanup;
750 if (writen_nointr(tmp_fd, buf, KS_PKCS11_VER_SIZE) !=
751 KS_PKCS11_VER_SIZE) {
752 goto cleanup;
755 /* version number, it needs to be updated */
757 /* read the current version number */
758 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) {
759 goto cleanup;
762 version = SWAP32(version);
763 version++;
764 version = SWAP32(version);
766 /* write the updated value to the tmp file */
767 if (writen_nointr(tmp_fd, (void *)&version, KS_VER_SIZE)
768 != KS_VER_SIZE) {
769 goto cleanup;
772 /* read rest of information, nothing needs to be updated */
773 nread = readn_nointr(fd, buf, BUFSIZ);
774 while (nread > 0) {
775 if (writen_nointr(tmp_fd, buf, nread) != nread) {
776 goto cleanup;
778 nread = readn_nointr(fd, buf, BUFSIZ);
781 (void) close(tmp_fd);
782 return (0); /* no error */
784 cleanup:
785 (void) close(tmp_fd);
786 (void) remove(tmp_fname);
787 return (-1);
790 static CK_RV
791 get_all_objs_in_dir(DIR *dirp, ks_obj_handle_t *ks_handle,
792 ks_obj_t **result_obj_list, boolean_t lock_held)
794 struct dirent *dp;
795 ks_obj_t *obj;
796 CK_RV rv;
798 while ((dp = readdir(dirp)) != NULL) {
800 if (strncmp(dp->d_name, OBJ_PREFIX, OBJ_PREFIX_LEN) != 0)
801 continue;
803 (void) strcpy((char *)ks_handle->name, dp->d_name);
804 rv = soft_keystore_get_single_obj(ks_handle, &obj, lock_held);
805 if (rv != CKR_OK) {
806 return (rv);
808 if (obj != NULL) {
809 if (*result_obj_list == NULL) {
810 *result_obj_list = obj;
811 } else {
812 obj->next = *result_obj_list;
813 *result_obj_list = obj;
817 return (CKR_OK);
821 * This function prepares the obj data for encryption by prepending
822 * the FULL path of the file that will be used for storing
823 * the object. Having full path of the file as part of
824 * of the data for the object will prevent an attacker from
825 * copying a "bad" object into the keystore undetected.
827 * This function will always allocate:
828 * MAXPATHLEN + buf_len
829 * amount of data. If the full path of the filename doesn't occupy
830 * the whole MAXPATHLEN, the rest of the space will just be empty.
831 * It is the caller's responsibility to free the buffer allocated here.
833 * The allocated buffer is returned in the variable "prepared_buf"
834 * if there's no error.
836 * Returns 0 if there's no error, -1 otherwise.
838 static int
839 prepare_data_for_encrypt(char *obj_path, unsigned char *buf, CK_ULONG buf_len,
840 unsigned char **prepared_buf, CK_ULONG *prepared_len)
842 *prepared_len = MAXPATHLEN + buf_len;
843 *prepared_buf = malloc(*prepared_len);
844 if (*prepared_buf == NULL) {
845 return (-1);
849 * only zero out the space for the path name. I could zero out
850 * the whole buffer, but that will be a waste of processing
851 * cycle since the rest of the buffer will be 100% filled all
852 * the time
854 bzero(*prepared_buf, MAXPATHLEN);
855 (void) memcpy(*prepared_buf, obj_path, strlen(obj_path));
856 (void) memcpy(*prepared_buf + MAXPATHLEN, buf, buf_len);
857 return (0);
861 * retrieves the hashed pin from the keystore
863 static CK_RV
864 get_hashed_pin(int fd, char **hashed_pin)
866 uint64_t hashed_pin_size;
868 if (ks_hashed_pinlen_offset == -1) {
869 if (calculate_hashed_pin_offset(fd) != 0) {
870 return (CKR_FUNCTION_FAILED);
874 /* first, get size of the hashed pin */
875 if (lseek(fd, ks_hashed_pinlen_offset, SEEK_SET)
876 != ks_hashed_pinlen_offset) {
877 return (CKR_FUNCTION_FAILED);
880 if (readn_nointr(fd, (char *)&hashed_pin_size,
881 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) {
882 return (CKR_FUNCTION_FAILED);
885 hashed_pin_size = SWAP64(hashed_pin_size);
887 *hashed_pin = malloc(hashed_pin_size + 1);
888 if (*hashed_pin == NULL) {
889 return (CKR_HOST_MEMORY);
892 if ((readn_nointr(fd, *hashed_pin, hashed_pin_size))
893 != (ssize_t)hashed_pin_size) {
894 free(*hashed_pin);
895 *hashed_pin = NULL;
896 return (CKR_FUNCTION_FAILED);
898 (*hashed_pin)[hashed_pin_size] = '\0';
899 return (CKR_OK);
904 * FUNCTION: soft_keystore_lock
906 * ARGUMENTS:
907 * set_lock: TRUE to set readlock on the keystore object file,
908 * FALSE to remove readlock on keystore object file.
910 * RETURN VALUE:
912 * 0: success
913 * -1: failure
915 * DESCRIPTION:
917 * set or remove readlock on the keystore description file.
920 soft_keystore_readlock(boolean_t set_lock)
923 return (lock_desc_file(B_TRUE, set_lock));
928 * FUNCTION: soft_keystore_writelock
930 * ARGUMENTS:
931 * set_lock: TRUE to set writelock on the keystore description file
932 * FALSE to remove write lock on keystore description file.
934 * RETURN VALUE:
936 * 0: no error
937 * 1: some error occurred
939 * DESCRIPTION:
940 * set/reset writelock on the keystore description file.
943 soft_keystore_writelock(boolean_t set_lock)
945 return (lock_desc_file(B_FALSE, set_lock));
951 * FUNCTION: soft_keystore_lock_object
953 * ARGUMENTS:
955 * ks_handle: handle of the keystore object file to be accessed.
956 * read_lock: TRUE to set readlock on the keystore object file,
957 * FALSE to set writelock on keystore object file.
959 * RETURN VALUE:
961 * If no error, file descriptor of locked file will be returned
962 * -1: some error occurred
964 * DESCRIPTION:
966 * set readlock or writelock on the keystore object file.
969 soft_keystore_lock_object(ks_obj_handle_t *ks_handle, boolean_t read_lock)
971 int fd;
972 int oflag;
974 if (read_lock) {
975 oflag = O_RDONLY;
976 } else {
977 oflag = O_WRONLY;
980 if ((fd = open_and_lock_object_file(ks_handle, oflag, B_FALSE)) < 0) {
981 return (-1);
984 return (fd);
988 * FUNCTION: soft_keystore_unlock_object
990 * ARGUMENTS:
991 * fd: file descriptor returned from soft_keystore_lock_object
993 * RETURN VALUE:
994 * 0: no error
995 * 1: some error occurred while getting the pin
997 * DESCRIPTION:
998 * set/reset writelock on the keystore object file.
1001 soft_keystore_unlock_object(int fd)
1003 if (lock_file(fd, B_TRUE, B_FALSE) != 0) {
1004 return (1);
1007 (void) close(fd);
1008 return (0);
1014 * FUNCTION: soft_keystore_get_version
1016 * ARGUMENTS:
1017 * version: pointer to caller allocated memory for storing
1018 * the version of the keystore.
1019 * lock_held: TRUE if the lock is held by caller.
1021 * RETURN VALUE:
1023 * 0: no error
1024 * -1: some error occurred while getting the version number
1026 * DESCRIPTION:
1027 * get the version number of the keystore from keystore
1028 * description file.
1031 soft_keystore_get_version(uint_t *version, boolean_t lock_held)
1033 int fd, ret_val = 0;
1034 uint_t buf;
1036 if ((fd = open_and_lock_keystore_desc(O_RDONLY,
1037 B_FALSE, lock_held)) < 0) {
1038 return (-1);
1041 if (lseek(fd, KS_VER_OFFSET, SEEK_SET) != KS_VER_OFFSET) {
1042 ret_val = -1;
1043 goto cleanup;
1046 if (readn_nointr(fd, (char *)&buf, KS_VER_SIZE) != KS_VER_SIZE) {
1047 ret_val = -1;
1048 goto cleanup;
1050 *version = SWAP32(buf);
1052 cleanup:
1054 if (!lock_held) {
1055 if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
1056 ret_val = -1;
1060 (void) close(fd);
1061 return (ret_val);
1065 * FUNCTION: soft_keystore_get_object_version
1067 * ARGUMENTS:
1069 * ks_handle: handle of the key store object to be accessed.
1070 * version:
1071 * pointer to caller allocated memory for storing
1072 * the version of the object.
1073 * lock_held: TRUE if the lock is held by caller.
1075 * RETURN VALUE:
1077 * 0: no error
1078 * -1: some error occurred while getting the pin
1080 * DESCRIPTION:
1081 * get the version number of the specified token object.
1084 soft_keystore_get_object_version(ks_obj_handle_t *ks_handle,
1085 uint_t *version, boolean_t lock_held)
1087 int fd, ret_val = 0;
1088 uint_t tmp;
1090 if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY,
1091 lock_held)) < 0) {
1092 return (-1);
1096 * read version. Version is always first item in object file
1097 * so, no need to do lseek
1099 if (readn_nointr(fd, (char *)&tmp, OBJ_VER_SIZE) != OBJ_VER_SIZE) {
1100 ret_val = -1;
1101 goto cleanup;
1104 *version = SWAP32(tmp);
1106 cleanup:
1107 if (!lock_held) {
1108 if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
1109 ret_val = -1;
1114 (void) close(fd);
1115 return (ret_val);
1119 * FUNCTION: soft_keystore_getpin
1121 * ARGUMENTS:
1122 * hashed_pin: pointer to caller allocated memory
1123 * for storing the pin to be returned.
1124 * lock_held: TRUE if the lock is held by caller.
1126 * RETURN VALUE:
1128 * 0: no error
1129 * -1: some error occurred while getting the pin
1131 * DESCRIPTION:
1133 * Reads the MD5 hash from the keystore description
1134 * file and return it to the caller in the provided
1135 * buffer. If there is no PIN in the description file
1136 * because the file is just created, this function
1137 * will get a MD5 digest of the string "changeme",
1138 * store it in the file, and also return this
1139 * string to the caller.
1142 soft_keystore_getpin(char **hashed_pin, boolean_t lock_held)
1144 int fd, ret_val = -1;
1145 CK_RV rv;
1147 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE,
1148 lock_held)) < 0) {
1149 return (-1);
1152 rv = get_hashed_pin(fd, hashed_pin);
1153 if (rv == CKR_OK) {
1154 ret_val = 0;
1157 cleanup:
1158 if (!lock_held) {
1159 if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
1160 ret_val = -1;
1164 (void) close(fd);
1165 return (ret_val);
1170 * Generate a 16-byte Initialization Vector (IV).
1172 CK_RV
1173 soft_gen_iv(CK_BYTE *iv)
1175 return (pkcs11_get_nzero_urandom(iv, 16) < 0 ?
1176 CKR_DEVICE_ERROR : CKR_OK);
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"
1187 * returns CKR_OK if no error. Other CKR error codes if there's an error
1189 static CK_RV
1190 read_obj_data(int old_fd, char **buf, ssize_t *bytes_read)
1193 ssize_t nread, loop_count;
1194 char *buf1 = NULL;
1196 *buf = malloc(BUFSIZ);
1197 if (*buf == NULL) {
1198 return (CKR_HOST_MEMORY);
1201 nread = readn_nointr(old_fd, *buf, BUFSIZ);
1202 if (nread < 0) {
1203 free(*buf);
1204 return (CKR_FUNCTION_FAILED);
1206 loop_count = 1;
1207 while (nread == (loop_count * BUFSIZ)) {
1208 ssize_t nread_tmp;
1210 loop_count++;
1211 /* more than BUFSIZ of data */
1212 buf1 = reallocarray(*buf, loop_count, BUFSIZ);
1213 if (buf1 == NULL) {
1214 free(*buf);
1215 return (CKR_HOST_MEMORY);
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);
1224 nread += nread_tmp;
1226 *bytes_read = nread;
1227 return (CKR_OK);
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.
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.
1240 * Returns 0 if there's no error, returns -1 otherwise.
1243 static int
1244 reencrypt_obj(soft_object_t *new_enc_key, soft_object_t *new_hmac_key,
1245 char *orig_obj_name, char *new_obj_name) {
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;
1253 old_fd = open_nointr(orig_obj_name, O_RDONLY|O_NONBLOCK);
1254 if (old_fd < 0) {
1255 return (-1);
1258 if (acquire_file_lock(&old_fd, orig_obj_name, O_RDONLY) != 0) {
1259 if (old_fd > 0) {
1260 (void) close(old_fd);
1262 return (-1);
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);
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);
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;
1286 version = SWAP32(version);
1287 version++;
1288 version = SWAP32(version);
1290 if (writen_nointr(new_fd, (char *)&version, OBJ_VER_SIZE)
1291 != OBJ_VER_SIZE) {
1292 goto cleanup;
1295 /* read old iv */
1296 if (readn_nointr(old_fd, (char *)old_iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
1297 goto cleanup;
1300 /* generate new IV */
1301 if (soft_gen_iv(iv) != CKR_OK) {
1302 goto cleanup;
1305 if (writen_nointr(new_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
1306 goto cleanup;
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;
1314 if (read_obj_data(old_fd, (char **)&buf, &nread) != CKR_OK) {
1315 goto cleanup;
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 free(buf);
1323 goto cleanup;
1326 decrypted_buf = malloc(decrypted_len);
1327 if (decrypted_buf == NULL) {
1328 free(buf);
1329 goto cleanup;
1332 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread,
1333 decrypted_buf, &decrypted_len) != CKR_OK) {
1334 free(buf);
1335 free(decrypted_buf);
1336 goto cleanup;
1339 free(buf);
1341 /* re-encrypt with new key */
1342 encrypted_len = 0;
1343 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
1344 decrypted_len, NULL, &encrypted_len) != CKR_OK) {
1345 free(decrypted_buf);
1346 goto cleanup;
1349 buf = malloc(encrypted_len);
1350 if (buf == NULL) {
1351 free(decrypted_buf);
1352 goto cleanup;
1355 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf,
1356 decrypted_len, buf, &encrypted_len) != CKR_OK) {
1357 free(buf);
1358 free(decrypted_buf);
1359 goto cleanup;
1362 free(decrypted_buf);
1364 /* calculate hmac on re-encrypted data using new hmac key */
1365 hmac_len = OBJ_HMAC_SIZE;
1366 if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf,
1367 encrypted_len, hmac, &hmac_len) != CKR_OK) {
1368 free(buf);
1369 goto cleanup;
1372 /* just for sanity check */
1373 if (hmac_len != OBJ_HMAC_SIZE) {
1374 free(buf);
1375 goto cleanup;
1378 /* write new hmac */
1379 if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE)
1380 != OBJ_HMAC_SIZE) {
1381 free(buf);
1382 goto cleanup;
1385 /* write re-encrypted buffer to temp file */
1386 if (writen_nointr(new_fd, (void *)buf, encrypted_len)
1387 != encrypted_len) {
1388 free(buf);
1389 goto cleanup;
1391 free(buf);
1392 ret_val = 0;
1394 cleanup:
1395 /* unlock the files */
1396 (void) lock_file(old_fd, B_TRUE, B_FALSE);
1397 (void) lock_file(new_fd, B_FALSE, B_FALSE);
1399 (void) close(old_fd);
1400 (void) close(new_fd);
1401 if (ret_val != 0) {
1402 (void) remove(new_obj_name);
1404 return (ret_val);
1408 * FUNCTION: soft_keystore_setpin
1410 * ARGUMENTS:
1411 * newpin: new pin entered by the user.
1412 * lock_held: TRUE if the lock is held by caller.
1414 * RETURN VALUE:
1415 * 0: no error
1416 * -1: failure
1418 * DESCRIPTION:
1420 * This function does the following:
1422 * 1) Generates crypted value of newpin and store it
1423 * in keystore description file.
1424 * 2) Dervies the new encryption key from the newpin. This key
1425 * will be used to re-encrypt the private token objects.
1426 * 3) Re-encrypt all of this user's existing private token
1427 * objects (if any).
1428 * 4) Increments the keystore version number.
1431 soft_keystore_setpin(uchar_t *oldpin, uchar_t *newpin, boolean_t lock_held)
1433 int fd, tmp_ks_fd, version, ret_val = -1;
1434 soft_object_t *new_crypt_key = NULL, *new_hmac_key = NULL;
1435 char filebuf[BUFSIZ];
1436 DIR *pri_dirp;
1437 struct dirent *pri_ent;
1438 char pri_obj_path[MAXPATHLEN], ks_desc_file[MAXPATHLEN],
1439 tmp_ks_desc_name[MAXPATHLEN];
1440 typedef struct priobjs {
1441 char orig_name[MAXPATHLEN];
1442 char tmp_name[MAXPATHLEN];
1443 struct priobjs *next;
1444 } priobjs_t;
1445 priobjs_t *pri_objs = NULL, *tmp;
1446 CK_BYTE *crypt_salt = NULL, *hmac_salt = NULL;
1447 boolean_t pin_never_set = B_FALSE, user_logged_in;
1448 char *new_hashed_pin = NULL;
1449 uint64_t hashed_pin_salt_length, new_hashed_pin_len, swaped_val;
1450 char *hashed_pin_salt = NULL;
1451 priobjs_t *obj;
1453 if ((enc_key == NULL) ||
1454 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
1455 user_logged_in = B_FALSE;
1456 } else {
1457 user_logged_in = B_TRUE;
1460 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_TRUE,
1461 lock_held)) < 0) {
1462 return (-1);
1465 (void) get_desc_file_path(ks_desc_file);
1466 (void) get_tmp_desc_file_path(tmp_ks_desc_name);
1469 * create a tempoary file for the keystore description
1470 * file for updating version and counter information
1472 tmp_ks_fd = open_nointr(tmp_ks_desc_name,
1473 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
1474 if (tmp_ks_fd < 0) {
1475 (void) close(fd);
1476 return (-1);
1479 /* read and write PKCS version to temp file */
1480 if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE)
1481 != KS_PKCS11_VER_SIZE) {
1482 goto cleanup;
1485 if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE)
1486 != KS_PKCS11_VER_SIZE) {
1487 goto cleanup;
1490 /* get version number, and write updated number to temp file */
1491 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) {
1492 goto cleanup;
1495 version = SWAP32(version);
1496 version++;
1497 version = SWAP32(version);
1499 if (writen_nointr(tmp_ks_fd, (void *)&version, KS_VER_SIZE)
1500 != KS_VER_SIZE) {
1501 goto cleanup;
1505 /* read and write counter, no modification necessary */
1506 if (readn_nointr(fd, filebuf, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) {
1507 goto cleanup;
1510 if (writen_nointr(tmp_ks_fd, filebuf, KS_COUNTER_SIZE)
1511 != KS_COUNTER_SIZE) {
1512 goto cleanup;
1515 /* read old encryption salt */
1516 crypt_salt = malloc(KS_KEY_SALT_SIZE);
1517 if (crypt_salt == NULL) {
1518 goto cleanup;
1520 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE)
1521 != KS_KEY_SALT_SIZE) {
1522 goto cleanup;
1525 /* read old hmac salt */
1526 hmac_salt = malloc(KS_HMAC_SALT_SIZE);
1527 if (hmac_salt == NULL) {
1528 goto cleanup;
1530 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE)
1531 != KS_HMAC_SALT_SIZE) {
1532 goto cleanup;
1535 /* just create some empty bytes */
1536 bzero(filebuf, sizeof (filebuf));
1538 if (memcmp(crypt_salt, filebuf, KS_KEY_SALT_SIZE) == 0) {
1539 /* PIN as never been set */
1540 CK_BYTE *new_crypt_salt = NULL, *new_hmac_salt = NULL;
1542 pin_never_set = B_TRUE;
1543 if (soft_gen_crypt_key(newpin, &new_crypt_key, &new_crypt_salt)
1544 != CKR_OK) {
1545 goto cleanup;
1547 if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt,
1548 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
1549 free(new_crypt_salt);
1550 (void) soft_cleanup_object(new_crypt_key);
1551 goto cleanup;
1553 free(new_crypt_salt);
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;
1560 if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt,
1561 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) {
1562 free(new_hmac_salt);
1563 goto cleanup3;
1565 free(new_hmac_salt);
1566 } else {
1567 if (soft_gen_crypt_key(newpin, &new_crypt_key,
1568 (CK_BYTE **)&crypt_salt) != CKR_OK) {
1569 goto cleanup;
1571 /* no change to the encryption salt */
1572 if (writen_nointr(tmp_ks_fd, (void *)crypt_salt,
1573 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) {
1574 (void) soft_cleanup_object(new_crypt_key);
1575 goto cleanup;
1578 if (soft_gen_hmac_key(newpin, &new_hmac_key,
1579 (CK_BYTE **)&hmac_salt) != CKR_OK) {
1580 (void) soft_cleanup_object(new_crypt_key);
1581 goto cleanup;
1584 /* no change to the hmac salt */
1585 if (writen_nointr(tmp_ks_fd, (void *)hmac_salt,
1586 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) {
1587 goto cleanup3;
1592 * read hashed pin salt, and write to updated keystore description
1593 * file unmodified.
1595 if (readn_nointr(fd, (char *)&hashed_pin_salt_length,
1596 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
1597 goto cleanup3;
1600 if (writen_nointr(tmp_ks_fd, (void *)&hashed_pin_salt_length,
1601 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
1602 goto cleanup3;
1605 hashed_pin_salt_length = SWAP64(hashed_pin_salt_length);
1607 hashed_pin_salt = malloc(hashed_pin_salt_length + 1);
1608 if (hashed_pin_salt == NULL) {
1609 goto cleanup3;
1612 if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) !=
1613 (ssize_t)hashed_pin_salt_length) {
1614 free(hashed_pin_salt);
1615 goto cleanup3;
1618 if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length))
1619 != (ssize_t)hashed_pin_salt_length) {
1620 free(hashed_pin_salt);
1621 goto cleanup3;
1624 hashed_pin_salt[hashed_pin_salt_length] = '\0';
1626 /* old hashed pin length and value can be ignored, generate new one */
1627 if (soft_gen_hashed_pin(newpin, &new_hashed_pin,
1628 &hashed_pin_salt) < 0) {
1629 free(hashed_pin_salt);
1630 goto cleanup3;
1633 free(hashed_pin_salt);
1635 if (new_hashed_pin == NULL) {
1636 goto cleanup3;
1639 new_hashed_pin_len = strlen(new_hashed_pin);
1641 /* write new hashed pin length to file */
1642 swaped_val = SWAP64(new_hashed_pin_len);
1643 if (writen_nointr(tmp_ks_fd, (void *)&swaped_val,
1644 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) {
1645 goto cleanup3;
1648 if (writen_nointr(tmp_ks_fd, (void *)new_hashed_pin,
1649 new_hashed_pin_len) != (ssize_t)new_hashed_pin_len) {
1650 goto cleanup3;
1653 if (pin_never_set) {
1654 /* there was no private object, no need to re-encrypt them */
1655 goto rename_desc_file;
1658 /* re-encrypt all the private objects */
1659 pri_dirp = opendir(get_pri_obj_path(pri_obj_path));
1660 if (pri_dirp == NULL) {
1662 * this directory should exist, even if it doesn't contain
1663 * any objects. Don't want to update the pin if the
1664 * keystore is somehow messed up.
1667 goto cleanup3;
1670 /* if user did not login, need to set the old pin */
1671 if (!user_logged_in) {
1672 if (soft_keystore_authpin(oldpin) != 0) {
1673 goto cleanup3;
1677 while ((pri_ent = readdir(pri_dirp)) != NULL) {
1679 if ((strcmp(pri_ent->d_name, ".") == 0) ||
1680 (strcmp(pri_ent->d_name, "..") == 0) ||
1681 (strncmp(pri_ent->d_name, TMP_OBJ_PREFIX,
1682 strlen(TMP_OBJ_PREFIX)) == 0)) {
1683 continue;
1686 obj = malloc(sizeof (priobjs_t));
1687 if (obj == NULL) {
1688 goto cleanup2;
1690 (void) snprintf(obj->orig_name, MAXPATHLEN,
1691 "%s/%s", pri_obj_path, pri_ent->d_name);
1692 (void) snprintf(obj->tmp_name, MAXPATHLEN, "%s/%s%s",
1693 pri_obj_path, TMP_OBJ_PREFIX,
1694 (pri_ent->d_name) + OBJ_PREFIX_LEN);
1695 if (reencrypt_obj(new_crypt_key, new_hmac_key,
1696 obj->orig_name, obj->tmp_name) != 0) {
1697 free(obj);
1698 goto cleanup2;
1701 /* insert into list of file to be renamed */
1702 if (pri_objs == NULL) {
1703 obj->next = NULL;
1704 pri_objs = obj;
1705 } else {
1706 obj->next = pri_objs;
1707 pri_objs = obj;
1711 /* rename all the private objects */
1712 tmp = pri_objs;
1713 while (tmp) {
1714 (void) rename(tmp->tmp_name, tmp->orig_name);
1715 tmp = tmp->next;
1718 rename_desc_file:
1720 /* destroy the old encryption key, and hmac key */
1721 if ((!pin_never_set) && (user_logged_in)) {
1722 (void) soft_cleanup_object(enc_key);
1723 (void) soft_cleanup_object(hmac_key);
1726 if (user_logged_in) {
1727 enc_key = new_crypt_key;
1728 hmac_key = new_hmac_key;
1730 (void) rename(tmp_ks_desc_name, ks_desc_file);
1732 ret_val = 0;
1734 cleanup2:
1735 if (pri_objs != NULL) {
1736 priobjs_t *p = pri_objs;
1737 while (p) {
1738 tmp = p->next;
1739 free(p);
1740 p = tmp;
1743 if (!pin_never_set) {
1744 (void) closedir(pri_dirp);
1747 if ((!user_logged_in) && (!pin_never_set)) {
1748 (void) soft_cleanup_object(enc_key);
1749 (void) soft_cleanup_object(hmac_key);
1750 enc_key = NULL;
1751 hmac_key = NULL;
1753 cleanup3:
1754 if ((ret_val != 0) || (!user_logged_in)) {
1755 (void) soft_cleanup_object(new_crypt_key);
1756 (void) soft_cleanup_object(new_hmac_key);
1759 cleanup:
1760 if (!lock_held) {
1761 if (lock_file(fd, B_FALSE, B_FALSE) < 0) {
1762 ret_val = 1;
1765 if (crypt_salt != NULL) {
1766 free(crypt_salt);
1768 if (hmac_salt != NULL) {
1769 free(hmac_salt);
1771 (void) close(fd);
1772 (void) close(tmp_ks_fd);
1773 if (ret_val != 0) {
1774 (void) remove(tmp_ks_desc_name);
1776 return (ret_val);
1780 * FUNCTION: soft_keystore_authpin
1782 * ARGUMENTS:
1783 * pin: pin specified by the user for logging into
1784 * the keystore.
1786 * RETURN VALUE:
1787 * 0: if no error
1788 * -1: if there is any error
1790 * DESCRIPTION:
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.
1801 soft_keystore_authpin(uchar_t *pin)
1803 int fd;
1804 int ret_val = -1;
1805 CK_BYTE *crypt_salt = NULL, *hmac_salt;
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);
1813 crypt_salt = malloc(KS_KEY_SALT_SIZE);
1814 if (crypt_salt == NULL) {
1815 goto cleanup;
1818 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) {
1819 goto cleanup;
1822 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE)
1823 != KS_KEY_SALT_SIZE) {
1824 goto cleanup;
1827 if (soft_gen_crypt_key(pin, &enc_key, (CK_BYTE **)&crypt_salt)
1828 != CKR_OK) {
1829 goto cleanup;
1832 hmac_salt = malloc(KS_HMAC_SALT_SIZE);
1833 if (hmac_salt == NULL) {
1834 goto cleanup;
1837 if (lseek(fd, KS_HMAC_SALT_OFFSET, SEEK_SET) != KS_HMAC_SALT_OFFSET) {
1838 goto cleanup;
1841 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE)
1842 != KS_HMAC_SALT_SIZE) {
1843 goto cleanup;
1846 if (soft_gen_hmac_key(pin, &hmac_key, (CK_BYTE **)&hmac_salt)
1847 != CKR_OK) {
1848 goto cleanup;
1851 ret_val = 0;
1853 cleanup:
1854 /* unlock the file */
1855 (void) lock_file(fd, B_TRUE, B_FALSE);
1856 (void) close(fd);
1857 if (crypt_salt != NULL) {
1858 free(crypt_salt);
1860 if (hmac_salt != NULL) {
1861 free(hmac_salt);
1863 return (ret_val);
1867 * FUNCTION: soft_keystore_get_objs
1869 * ARGUMENTS:
1871 * search_type: Specify type of objects to return.
1872 * lock_held: TRUE if the lock is held by caller.
1875 * RETURN VALUE:
1877 * NULL: if there are no object in the database.
1879 * Otherwise, linked list of objects as requested
1880 * in search type.
1882 * The linked list returned will need to be freed
1883 * by the caller.
1885 * DESCRIPTION:
1887 * Returns objects as requested.
1889 * If private objects is requested, and the caller
1890 * has not previously passed in the pin or if the pin
1891 * passed in is wrong, private objects will not
1892 * be returned.
1894 * The buffers returned for private objects are already
1895 * decrypted.
1897 CK_RV
1898 soft_keystore_get_objs(ks_search_type_t search_type,
1899 ks_obj_t **result_obj_list, boolean_t lock_held)
1901 DIR *dirp;
1902 ks_obj_handle_t ks_handle;
1903 CK_RV rv;
1904 ks_obj_t *tmp;
1905 int ks_fd;
1907 *result_obj_list = NULL;
1910 * lock the keystore description file in "read" mode so that
1911 * objects won't get added/deleted/modified while we are
1912 * doing the search
1914 if ((ks_fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE,
1915 B_FALSE)) < 0) {
1916 return (CKR_FUNCTION_FAILED);
1919 if ((search_type == ALL_TOKENOBJS) || (search_type == PUB_TOKENOBJS)) {
1921 char pub_obj_path[MAXPATHLEN];
1923 ks_handle.public = B_TRUE;
1925 if ((dirp = opendir(get_pub_obj_path(pub_obj_path))) == NULL) {
1926 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1927 (void) close(ks_fd);
1928 return (CKR_FUNCTION_FAILED);
1930 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list,
1931 lock_held);
1932 if (rv != CKR_OK) {
1933 (void) closedir(dirp);
1934 goto cleanup;
1937 (void) closedir(dirp);
1940 if ((search_type == ALL_TOKENOBJS) || (search_type == PRI_TOKENOBJS)) {
1942 char pri_obj_path[MAXPATHLEN];
1944 if ((enc_key == NULL) ||
1945 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
1946 /* has not login - no need to go any further */
1947 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1948 (void) close(ks_fd);
1949 return (CKR_OK);
1952 ks_handle.public = B_FALSE;
1954 if ((dirp = opendir(get_pri_obj_path(pri_obj_path))) == NULL) {
1955 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1956 (void) close(ks_fd);
1957 return (CKR_OK);
1959 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list,
1960 lock_held);
1961 if (rv != CKR_OK) {
1962 (void) closedir(dirp);
1963 goto cleanup;
1966 (void) closedir(dirp);
1968 /* close the keystore description file */
1969 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1970 (void) close(ks_fd);
1971 return (CKR_OK);
1972 cleanup:
1974 /* close the keystore description file */
1975 (void) lock_file(ks_fd, B_TRUE, B_FALSE);
1976 (void) close(ks_fd);
1978 /* free all the objects found before hitting the error */
1979 tmp = *result_obj_list;
1980 while (tmp) {
1981 *result_obj_list = tmp->next;
1982 free(tmp->buf);
1983 free(tmp);
1984 tmp = *result_obj_list;
1986 *result_obj_list = NULL;
1987 return (rv);
1992 * FUNCTION: soft_keystore_get_single_obj
1994 * ARGUMENTS:
1995 * ks_handle: handle of the key store object to be accessed
1996 * lock_held: TRUE if the lock is held by caller.
1998 * RETURN VALUE:
2000 * NULL: if handle doesn't match any object
2002 * Otherwise, the object is returned in
2003 * the same structure used in soft_keystore_get_objs().
2004 * The structure need to be freed by the caller.
2006 * DESCRIPTION:
2008 * Retrieves the object specified by the object
2009 * handle to the caller.
2011 * If a private object is requested, and the caller
2012 * has not previously passed in the pin or if the pin
2013 * passed in is wrong, the requested private object will not
2014 * be returned.
2016 * The buffer returned for the requested private object
2017 * is already decrypted.
2019 CK_RV
2020 soft_keystore_get_single_obj(ks_obj_handle_t *ks_handle,
2021 ks_obj_t **return_obj, boolean_t lock_held)
2024 ks_obj_t *obj;
2025 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE];
2026 uchar_t *buf, *decrypted_buf;
2027 int fd;
2028 ssize_t nread;
2029 CK_RV rv = CKR_FUNCTION_FAILED;
2031 if (!(ks_handle->public)) {
2032 if ((enc_key == NULL) ||
2033 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
2034 return (CKR_FUNCTION_FAILED);
2038 if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY,
2039 lock_held)) < 0) {
2040 return (CKR_FUNCTION_FAILED);
2043 obj = malloc(sizeof (ks_obj_t));
2044 if (obj == NULL) {
2045 return (CKR_HOST_MEMORY);
2048 obj->next = NULL;
2050 (void) strcpy((char *)((obj->ks_handle).name),
2051 (char *)ks_handle->name);
2052 (obj->ks_handle).public = ks_handle->public;
2054 /* 1st get the version */
2055 if (readn_nointr(fd, &(obj->obj_version), OBJ_VER_SIZE)
2056 != OBJ_VER_SIZE) {
2057 goto cleanup;
2059 obj->obj_version = SWAP32(obj->obj_version);
2061 /* Then, read the IV */
2062 if (readn_nointr(fd, iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
2063 goto cleanup;
2066 /* Then, read the HMAC */
2067 if (readn_nointr(fd, obj_hmac, OBJ_HMAC_SIZE) != OBJ_HMAC_SIZE) {
2068 goto cleanup;
2071 /* read the object */
2072 rv = read_obj_data(fd, (char **)&buf, &nread);
2073 if (rv != CKR_OK) {
2074 goto cleanup;
2077 if (ks_handle->public) {
2078 obj->size = nread;
2079 obj->buf = buf;
2080 *return_obj = obj;
2081 } else {
2083 CK_ULONG out_len = 0, hmac_size;
2085 /* verify HMAC of the object, make sure it matches */
2086 hmac_size = OBJ_HMAC_SIZE;
2087 if (soft_keystore_hmac(hmac_key, B_FALSE, buf,
2088 nread, obj_hmac, &hmac_size) != CKR_OK) {
2089 free(buf);
2090 rv = CKR_FUNCTION_FAILED;
2091 goto cleanup;
2094 /* decrypt object */
2095 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
2096 NULL, &out_len) != CKR_OK) {
2097 free(buf);
2098 rv = CKR_FUNCTION_FAILED;
2099 goto cleanup;
2102 decrypted_buf = malloc(sizeof (uchar_t) * out_len);
2103 if (decrypted_buf == NULL) {
2104 free(buf);
2105 rv = CKR_HOST_MEMORY;
2106 goto cleanup;
2109 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread,
2110 decrypted_buf, &out_len) != CKR_OK) {
2111 free(decrypted_buf);
2112 free(buf);
2113 rv = CKR_FUNCTION_FAILED;
2114 goto cleanup;
2117 obj->size = out_len - MAXPATHLEN;
2120 * decrypted buf here actually contains full path name of
2121 * object plus the actual data. so, need to skip the
2122 * full pathname.
2123 * See prepare_data_for_encrypt() function in the file
2124 * to understand how and why the pathname is added.
2126 obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN));
2127 if (obj->buf == NULL) {
2128 free(decrypted_buf);
2129 free(buf);
2130 rv = CKR_HOST_MEMORY;
2131 goto cleanup;
2133 (void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size);
2134 free(decrypted_buf);
2135 free(buf);
2136 *return_obj = obj;
2139 cleanup:
2141 if (rv != CKR_OK) {
2142 free(obj);
2145 /* unlock the file after reading */
2146 if (!lock_held) {
2147 (void) lock_file(fd, B_TRUE, B_FALSE);
2150 (void) close(fd);
2152 return (rv);
2157 * FUNCTION: soft_keystore_put_new_obj
2159 * ARGUMENTS:
2160 * buf: buffer containing un-encrypted data
2161 * to be stored in keystore.
2162 * len: length of data
2163 * public: TRUE if it is a public object,
2164 * FALSE if it is private obj
2165 * lock_held: TRUE if the lock is held by caller.
2166 * keyhandle: pointer to object handle to
2167 * receive keyhandle for new object
2169 * RETURN VALUE:
2170 * 0: object successfully stored in file
2171 * -1: some error occurred, object is not stored in file.
2173 * DESCRIPTION:
2174 * This API is used to write a newly created token object
2175 * to keystore.
2177 * This function does the following:
2179 * 1) Creates a token object file based on "public" parameter.
2180 * 2) Generates a new IV and stores it in obj_meta_data_t if it is
2181 * private object.
2182 * 3) Set object version number to 1.
2183 * 4) If it is a private object, it will be encrypted before
2184 * being written to the newly created keystore token object
2185 * file.
2186 * 5) Calculates the obj_chksum in obj_meta_data_t.
2187 * 6) Calculates the pin_chksum in obj_meta_data_t.
2188 * 7) Increments the keystore version number.
2191 soft_keystore_put_new_obj(uchar_t *buf, size_t len, boolean_t public,
2192 boolean_t lock_held, ks_obj_handle_t *keyhandle)
2195 int fd, tmp_ks_fd, obj_fd;
2196 unsigned int counter, version;
2197 uchar_t obj_hmac[OBJ_HMAC_SIZE];
2198 CK_BYTE iv[OBJ_IV_SIZE];
2199 char obj_name[MAXPATHLEN], tmp_ks_desc_name[MAXPATHLEN];
2200 char filebuf[BUFSIZ];
2201 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN],
2202 ks_desc_file[MAXPATHLEN];
2203 CK_ULONG hmac_size;
2204 ssize_t nread;
2206 if (keyhandle == NULL) {
2207 return (-1);
2210 /* if it is private object, make sure we have the key */
2211 if (!public) {
2212 if ((enc_key == NULL) ||
2213 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) {
2214 return (-1);
2218 /* open keystore, and set write lock */
2219 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE,
2220 lock_held)) < 0) {
2221 return (-1);
2224 (void) get_desc_file_path(ks_desc_file);
2225 (void) get_tmp_desc_file_path(tmp_ks_desc_name);
2228 * create a tempoary file for the keystore description
2229 * file for updating version and counter information
2231 tmp_ks_fd = open_nointr(tmp_ks_desc_name,
2232 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
2233 if (tmp_ks_fd < 0) {
2234 (void) close(fd);
2235 return (-1);
2238 /* read and write pkcs11 version */
2239 if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE)
2240 != KS_PKCS11_VER_SIZE) {
2241 goto cleanup;
2244 if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE)
2245 != KS_PKCS11_VER_SIZE) {
2246 goto cleanup;
2249 /* get version number, and write updated number to temp file */
2250 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) {
2251 goto cleanup;
2254 version = SWAP32(version);
2255 version++;
2256 version = SWAP32(version);
2258 if (writen_nointr(tmp_ks_fd, (void *)&version,
2259 KS_VER_SIZE) != KS_VER_SIZE) {
2260 goto cleanup;
2263 /* get object count value */
2264 if (readn_nointr(fd, &counter, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) {
2265 goto cleanup;
2267 counter = SWAP32(counter);
2269 bzero(obj_name, sizeof (obj_name));
2270 if (public) {
2271 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d",
2272 get_pub_obj_path(pub_obj_path), OBJ_PREFIX, counter);
2273 } else {
2274 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d",
2275 get_pri_obj_path(pri_obj_path), OBJ_PREFIX, counter);
2278 /* create object file */
2279 obj_fd = open_nointr(obj_name,
2280 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR);
2281 if (obj_fd < 0) {
2282 /* can't create object file */
2283 goto cleanup;
2286 /* lock object file for writing */
2287 if (lock_file(obj_fd, B_FALSE, B_TRUE) != 0) {
2288 (void) close(obj_fd);
2289 goto cleanup2;
2292 /* write object meta data */
2293 version = SWAP32(1);
2294 if (writen_nointr(obj_fd, (void *)&version, sizeof (version))
2295 != sizeof (version)) {
2296 goto cleanup2;
2299 if (public) {
2300 bzero(iv, sizeof (iv));
2301 } else {
2302 /* generate an IV */
2303 if (soft_gen_iv(iv) != CKR_OK) {
2304 goto cleanup2;
2309 if (writen_nointr(obj_fd, (void *)iv, sizeof (iv)) != sizeof (iv)) {
2310 goto cleanup2;
2313 if (public) {
2315 bzero(obj_hmac, sizeof (obj_hmac));
2316 if (writen_nointr(obj_fd, (void *)obj_hmac,
2317 sizeof (obj_hmac)) != sizeof (obj_hmac)) {
2318 goto cleanup2;
2321 if (writen_nointr(obj_fd, (char *)buf, len) != len) {
2322 goto cleanup2;
2325 } else {
2327 uchar_t *encrypted_buf, *prepared_buf;
2328 CK_ULONG out_len = 0, prepared_len;
2330 if (prepare_data_for_encrypt(obj_name, buf, len,
2331 &prepared_buf, &prepared_len) != 0) {
2332 goto cleanup2;
2335 if (soft_keystore_crypt(enc_key, iv,
2336 B_TRUE, prepared_buf, prepared_len,
2337 NULL, &out_len) != CKR_OK) {
2338 free(prepared_buf);
2339 goto cleanup2;
2342 encrypted_buf = malloc(out_len * sizeof (char));
2343 if (encrypted_buf == NULL) {
2344 free(prepared_buf);
2345 goto cleanup2;
2348 if (soft_keystore_crypt(enc_key, iv,
2349 B_TRUE, prepared_buf, prepared_len,
2350 encrypted_buf, &out_len) != CKR_OK) {
2351 free(encrypted_buf);
2352 free(prepared_buf);
2353 goto cleanup2;
2355 free(prepared_buf);
2357 /* calculate HMAC of encrypted object */
2358 hmac_size = OBJ_HMAC_SIZE;
2359 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf,
2360 out_len, obj_hmac, &hmac_size) != CKR_OK) {
2361 free(encrypted_buf);
2362 goto cleanup2;
2365 if (hmac_size != OBJ_HMAC_SIZE) {
2366 free(encrypted_buf);
2367 goto cleanup2;
2370 /* write hmac */
2371 if (writen_nointr(obj_fd, (void *)obj_hmac,
2372 sizeof (obj_hmac)) != sizeof (obj_hmac)) {
2373 free(encrypted_buf);
2374 goto cleanup2;
2377 /* write encrypted object */
2378 if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len)
2379 != out_len) {
2380 free(encrypted_buf);
2381 goto cleanup2;
2384 free(encrypted_buf);
2388 (void) close(obj_fd);
2389 (void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name),
2390 "obj%d", counter);
2391 keyhandle->public = public;
2394 * store new counter to temp keystore description file.
2396 counter++;
2397 counter = SWAP32(counter);
2398 if (writen_nointr(tmp_ks_fd, (void *)&counter,
2399 sizeof (counter)) != sizeof (counter)) {
2400 goto cleanup2;
2403 /* read rest of keystore description file and store into temp file */
2404 nread = readn_nointr(fd, filebuf, sizeof (filebuf));
2405 while (nread > 0) {
2406 if (writen_nointr(tmp_ks_fd, filebuf, nread) != nread) {
2407 goto cleanup2;
2409 nread = readn_nointr(fd, filebuf, sizeof (filebuf));
2412 (void) close(tmp_ks_fd);
2413 (void) rename(tmp_ks_desc_name, ks_desc_file);
2415 if (!lock_held) {
2416 /* release lock on description file */
2417 if (lock_file(fd, B_FALSE, B_FALSE) != 0) {
2418 (void) close(fd);
2419 return (-1);
2422 (void) close(fd);
2423 return (0);
2425 cleanup2:
2427 /* remove object file. No need to remove lock first */
2428 (void) unlink(obj_name);
2430 cleanup:
2432 (void) close(tmp_ks_fd);
2433 (void) remove(tmp_ks_desc_name);
2434 if (!lock_held) {
2435 /* release lock on description file */
2436 (void) lock_file(fd, B_FALSE, B_FALSE);
2439 (void) close(fd);
2440 return (-1);
2444 * FUNCTION: soft_keystore_modify_obj
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.
2453 * RETURN VALUE:
2454 * -1: if any error occurred.
2455 * Otherwise, 0 is returned.
2457 * DESCRIPTION:
2459 * This API is used to write a modified token object back
2460 * to keystore. This function will do the following:
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.
2469 soft_keystore_modify_obj(ks_obj_handle_t *ks_handle, uchar_t *buf,
2470 size_t len, boolean_t lock_held)
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;
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);
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);
2494 (void) get_desc_file_path(ks_desc_file);
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);
2505 /* open object file */
2506 if ((fd = open_and_lock_object_file(ks_handle, O_RDWR,
2507 lock_held)) < 0) {
2508 goto cleanup;
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
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);
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;
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;
2542 version = SWAP32(version);
2543 version++;
2544 version = SWAP32(version);
2546 if (writen_nointr(tmp_fd, (char *)&version, OBJ_VER_SIZE)
2547 != OBJ_VER_SIZE) {
2548 goto cleanup2;
2551 /* generate a new IV for the object, old one can be ignored */
2552 if (soft_gen_iv(iv) != CKR_OK) {
2553 goto cleanup2;
2556 if (writen_nointr(tmp_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) {
2557 goto cleanup2;
2560 if (ks_handle->public) {
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;
2569 /* write updated object */
2570 if (writen_nointr(tmp_fd, (char *)buf, len) != len) {
2571 goto cleanup2;
2574 } else {
2576 uchar_t *encrypted_buf, *prepared_buf;
2577 CK_ULONG out_len = 0, prepared_len;
2579 if (prepare_data_for_encrypt(orig_name, buf, len,
2580 &prepared_buf, &prepared_len) != 0) {
2581 goto cleanup2;
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;
2591 encrypted_buf = malloc(out_len * sizeof (char));
2592 if (encrypted_buf == NULL) {
2593 free(prepared_buf);
2594 goto cleanup2;
2597 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf,
2598 prepared_len, encrypted_buf, &out_len) != CKR_OK) {
2599 free(encrypted_buf);
2600 free(prepared_buf);
2601 goto cleanup2;
2604 free(prepared_buf);
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 free(encrypted_buf);
2611 goto cleanup2;
2614 if (hmac_size != OBJ_HMAC_SIZE) {
2615 free(encrypted_buf);
2616 goto cleanup2;
2619 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE)
2620 != OBJ_HMAC_SIZE) {
2621 free(encrypted_buf);
2622 goto cleanup2;
2625 if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len)
2626 != out_len) {
2627 free(encrypted_buf);
2628 goto cleanup2;
2630 free(encrypted_buf);
2632 (void) close(tmp_fd);
2634 /* rename updated temporary object file */
2635 if (rename(tmp_name, orig_name) != 0) {
2636 (void) unlink(tmp_name);
2637 return (-1);
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);
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);
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);
2663 (void) close(ks_fd);
2665 (void) close(fd);
2667 return (0); /* All operations completed successfully */
2669 cleanup2:
2670 (void) close(tmp_fd);
2671 (void) remove(tmp_name);
2673 cleanup1:
2674 (void) close(fd);
2676 cleanup:
2677 /* unlock keystore description file */
2678 (void) lock_file(ks_fd, B_FALSE, B_FALSE);
2679 (void) close(ks_fd);
2680 (void) remove(tmp_ks_name);
2681 return (-1);
2685 * FUNCTION: soft_keystore_del_obj
2687 * ARGUMENTS:
2688 * ks_handle: handle of the key store object to be deleted
2689 * lock_held: TRUE if the lock is held by caller.
2691 * RETURN VALUE:
2692 * -1: if any error occurred.
2693 * 0: object successfully deleted from keystore.
2695 * DESCRIPTION:
2696 * This API is used to delete a particular token object from
2697 * the keystore. The corresponding token object file will be
2698 * removed from the file system.
2699 * Any future reference to the deleted file will
2700 * return an CKR_OBJECT_HANDLE_INVALID error.
2703 soft_keystore_del_obj(ks_obj_handle_t *ks_handle, boolean_t lock_held)
2705 char objname[MAXPATHLEN], tmp_ks_name[MAXPATHLEN];
2706 int fd;
2707 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN],
2708 ks_desc_file[MAXPATHLEN];
2709 int ret_val = -1;
2710 int obj_fd;
2712 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE,
2713 lock_held)) < 0) {
2714 return (-1);
2717 (void) get_desc_file_path(ks_desc_file);
2718 (void) get_tmp_desc_file_path(tmp_ks_name);
2719 if (create_updated_keystore_version(fd, tmp_ks_name) != 0) {
2720 goto cleanup;
2723 if (ks_handle->public) {
2724 (void) snprintf(objname, MAXPATHLEN, "%s/%s",
2725 get_pub_obj_path(pub_obj_path), ks_handle->name);
2726 } else {
2727 (void) snprintf(objname, MAXPATHLEN, "%s/%s",
2728 get_pri_obj_path(pri_obj_path), ks_handle->name);
2732 * make sure no other process is reading/writing the file
2733 * by acquiring the lock on the file
2735 if ((obj_fd = open_and_lock_object_file(ks_handle, O_WRONLY,
2736 B_FALSE)) < 0) {
2737 return (-1);
2740 if (unlink(objname) != 0) {
2741 (void) lock_file(obj_fd, B_FALSE, B_FALSE);
2742 (void) close(obj_fd);
2743 goto cleanup;
2746 (void) lock_file(obj_fd, B_FALSE, B_FALSE);
2747 (void) close(obj_fd);
2749 if (rename(tmp_ks_name, ks_desc_file) != 0) {
2750 goto cleanup;
2752 ret_val = 0;
2754 cleanup:
2755 /* unlock keystore description file */
2756 if (!lock_held) {
2757 if (lock_file(fd, B_FALSE, B_FALSE) != 0) {
2758 (void) close(fd);
2759 return (-1);
2763 (void) close(fd);
2764 return (ret_val);
2768 * Get the salt used for generating hashed pin from the
2769 * keystore description file.
2771 * The result will be stored in the provided buffer "salt" passed
2772 * in as an argument.
2774 * Return 0 if no error, return -1 if there's any error.
2777 soft_keystore_get_pin_salt(char **salt)
2779 int fd, ret_val = -1;
2780 uint64_t hashed_pin_salt_size;
2782 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE,
2783 B_FALSE)) < 0) {
2784 return (-1);
2787 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET)
2788 != KS_HASHED_PIN_SALT_LEN_OFFSET) {
2789 goto cleanup;
2792 if (readn_nointr(fd, (char *)&hashed_pin_salt_size,
2793 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) {
2794 goto cleanup;
2796 hashed_pin_salt_size = SWAP64(hashed_pin_salt_size);
2798 *salt = malloc(hashed_pin_salt_size + 1);
2799 if (*salt == NULL) {
2800 goto cleanup;
2803 if ((readn_nointr(fd, *salt, hashed_pin_salt_size))
2804 != (ssize_t)hashed_pin_salt_size) {
2805 free(*salt);
2806 goto cleanup;
2808 (*salt)[hashed_pin_salt_size] = '\0';
2810 ret_val = 0;
2812 cleanup:
2813 if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
2814 ret_val = -1;
2817 (void) close(fd);
2818 return (ret_val);
2822 * FUNCTION: soft_keystore_pin_initialized
2824 * ARGUMENTS:
2825 * initialized: This value will be set to true if keystore is
2826 * initialized, and false otherwise.
2827 * hashed_pin: If the keystore is initialized, this will contain
2828 * the hashed pin. It will be NULL if the keystore
2829 * pin is not initialized. Memory allocated
2830 * for the hashed pin needs to be freed by
2831 * the caller.
2832 * lock_held: TRUE if the lock is held by caller.
2834 * RETURN VALUE:
2835 * CKR_OK: No error
2836 * any other appropriate CKR_value
2838 * DESCRIPTION:
2839 * This API is used to determine if the PIN in the keystore
2840 * has been initialized or not.
2841 * It makes the determination using the salt for generating the
2842 * encryption key. The salt is stored in the keystore
2843 * descryption file. The salt should be all zero if
2844 * the keystore pin has not been initialized.
2845 * If the pin has been initialized, it is returned in the
2846 * hashed_pin argument.
2848 CK_RV
2849 soft_keystore_pin_initialized(boolean_t *initialized, char **hashed_pin,
2850 boolean_t lock_held)
2852 int fd;
2853 CK_BYTE crypt_salt[KS_KEY_SALT_SIZE], tmp_buf[KS_KEY_SALT_SIZE];
2854 CK_RV ret_val = CKR_OK;
2856 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE,
2857 lock_held)) < 0) {
2858 return (CKR_FUNCTION_FAILED);
2861 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) {
2862 ret_val = CKR_FUNCTION_FAILED;
2863 goto cleanup;
2866 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE)
2867 != KS_KEY_SALT_SIZE) {
2868 ret_val = CKR_FUNCTION_FAILED;
2869 goto cleanup;
2872 (void) bzero(tmp_buf, KS_KEY_SALT_SIZE);
2874 if (memcmp(crypt_salt, tmp_buf, KS_KEY_SALT_SIZE) == 0) {
2875 *initialized = B_FALSE;
2876 hashed_pin = NULL;
2877 } else {
2878 *initialized = B_TRUE;
2879 ret_val = get_hashed_pin(fd, hashed_pin);
2882 cleanup:
2884 if (!lock_held) {
2885 if (lock_file(fd, B_TRUE, B_FALSE) < 0) {
2886 ret_val = CKR_FUNCTION_FAILED;
2890 (void) close(fd);
2891 return (ret_val);
2895 * This checks if the keystore file exists
2898 static int
2899 soft_keystore_exists()
2901 int ret;
2902 struct stat fn_stat;
2903 char *fname, ks_desc_file[MAXPATHLEN];
2905 fname = get_desc_file_path(ks_desc_file);
2906 ret = stat(fname, &fn_stat);
2907 if (ret == 0)
2908 return (0);
2909 return (errno);
2913 * FUNCTION: soft_keystore_init
2915 * ARGUMENTS:
2916 * desired_state: The keystore state the caller would like
2917 * it to be.
2919 * RETURN VALUE:
2920 * Returns the state the function is in. If it succeeded, it
2921 * will be the same as the desired, if not it will be
2922 * KEYSTORE_UNAVAILABLE.
2924 * DESCRIPTION:
2925 * This function will only load as much keystore data as is
2926 * requested at that time. This is for performace by delaying the
2927 * reading of token objects until they are needed or never at
2928 * all if they are not used.
2930 * Primary use is from C_InitToken().
2931 * It is also called by soft_keystore_status() when the
2932 * "desired_state" is not the the current load state of keystore.
2936 soft_keystore_init(int desired_state)
2938 int ret;
2940 (void) pthread_mutex_lock(&soft_slot.keystore_mutex);
2943 * If more than one session tries to initialize the keystore, the
2944 * second and other following sessions that were waiting for the lock
2945 * will quickly exit if their requirements are satisfied.
2947 if (desired_state <= soft_slot.keystore_load_status) {
2948 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
2949 return (soft_slot.keystore_load_status);
2953 * With 'keystore_load_status' giving the current state of the
2954 * process, this switch will bring it up to the desired state if
2955 * possible.
2958 switch (soft_slot.keystore_load_status) {
2959 case KEYSTORE_UNINITIALIZED:
2960 ret = soft_keystore_exists();
2961 if (ret == 0)
2962 soft_slot.keystore_load_status = KEYSTORE_PRESENT;
2963 else if (ret == ENOENT)
2964 if (create_keystore() == 0)
2965 soft_slot.keystore_load_status =
2966 KEYSTORE_PRESENT;
2967 else {
2968 soft_slot.keystore_load_status =
2969 KEYSTORE_UNAVAILABLE;
2970 cryptoerror(LOG_DEBUG,
2971 "pkcs11_softtoken: "
2972 "Cannot create keystore.");
2973 break;
2976 if (desired_state <= KEYSTORE_PRESENT)
2977 break;
2979 /* FALLTHRU */
2980 case KEYSTORE_PRESENT:
2981 if (soft_keystore_get_version(&soft_slot.ks_version, B_FALSE)
2982 != 0) {
2983 soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE;
2984 cryptoerror(LOG_DEBUG,
2985 "pkcs11_softtoken: Keystore access failed.");
2986 break;
2989 soft_slot.keystore_load_status = KEYSTORE_LOAD;
2990 if (desired_state <= KEYSTORE_LOAD)
2991 break;
2993 /* FALLTHRU */
2994 case KEYSTORE_LOAD:
2995 /* Load all the public token objects from keystore */
2996 if (soft_get_token_objects_from_keystore(PUB_TOKENOBJS)
2997 != CKR_OK) {
2998 (void) soft_destroy_token_session();
2999 soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE;
3000 cryptoerror(LOG_DEBUG,
3001 "pkcs11_softtoken: Cannot initialize keystore.");
3002 break;
3005 soft_slot.keystore_load_status = KEYSTORE_INITIALIZED;
3008 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
3009 return (soft_slot.keystore_load_status);
3013 * FUNCTION: soft_keystore_status
3015 * ARGUMENTS:
3016 * desired_state: The keystore state the caller would like
3017 * it to be.
3019 * RETURN VALUE:
3020 * B_TRUE if keystore is ready and at the desired state.
3021 * B_FALSE if keystore had an error and is not available.
3023 * DESCRIPTION:
3024 * The calling function wants to make sure the keystore load
3025 * status to in a state it requires. If it is not at that
3026 * state it will call the load function.
3027 * If keystore is at the desired state or has just been
3028 * loaded to that state, it will return TRUE. If there has been
3029 * load failure, it will return FALSE.
3032 boolean_t
3033 soft_keystore_status(int desired_state)
3036 if (soft_slot.keystore_load_status == KEYSTORE_UNAVAILABLE)
3037 return (B_FALSE);
3039 return ((desired_state <= soft_slot.keystore_load_status) ||
3040 (soft_keystore_init(desired_state) == desired_state));