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]
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
26 * Functions used for manipulating the keystore
37 #include <sys/types.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
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)
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)
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;
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",
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
);
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
);
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
);
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
);
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
);
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.
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
) {
248 if (readn_nointr(fd
, (char *)&salt_length
,
249 KS_HASHED_PIN_SALT_LEN_SIZE
) != KS_HASHED_PIN_SALT_LEN_SIZE
) {
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
;
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
268 lock_file(int fd
, boolean_t read_lock
, boolean_t set_lock
)
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 */
279 lock_info
.l_type
= F_RDLCK
;
281 lock_info
.l_type
= F_WRLCK
;
285 while ((r
= fcntl(fd
, F_SETLKW
, &lock_info
)) == -1) {
293 lock_info
.l_type
= F_UNLCK
;
294 while ((r
= fcntl(fd
, F_SETLKW
, &lock_info
)) == -1) {
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
;
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
) {
324 if (errno
== EACCES
) {
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
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) {
344 /* create $HOME/.sunw/pkcs11_softtoken */
345 (void) snprintf(keystore
, sizeof (keystore
),
346 "%s/%s/%s", home
, SUNW_PATH
, KEYSTORE_PATH
);
348 S_IRUSR
|S_IWUSR
|S_IXUSR
) < 0) {
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
);
361 if (errno
== EEXIST
) {
364 /* can't create keystore description file */
365 (void) rmdir(get_keystore_path());
370 if (lock_file(fd
, B_FALSE
, B_TRUE
) != 0) {
371 (void) unlink(ks_desc_file
);
373 (void) rmdir(get_keystore_path());
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
);
383 (void) rmdir(get_keystore_path());
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
);
393 (void) rmdir(get_keystore_path());
394 (void) rmdir(pub_obj_path
);
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
)) {
407 /* write version number, version = 0 since keystore just created */
409 if (writen_nointr(fd
, (void *)&buf
, KS_VER_SIZE
) != KS_VER_SIZE
) {
413 /* write monotonic-counter. Counter for keystore objects start at 1 */
415 if (writen_nointr(fd
, (void *)&buf
, KS_COUNTER_SIZE
)
416 != KS_COUNTER_SIZE
) {
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
) {
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
) {
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) {
439 if ((hashed_pin_salt
== NULL
) || (hashed_pin
== NULL
)) {
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
) {
453 if (writen_nointr(fd
, (void *)hashed_pin_salt
,
454 hashed_pin_salt_len
) != hashed_pin_salt_len
) {
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
) {
465 if (writen_nointr(fd
, (void *)hashed_pin
, hashed_pin_len
)
470 (void) lock_file(fd
, B_FALSE
, B_FALSE
);
473 free(hashed_pin_salt
);
477 (void) lock_file(fd
, B_FALSE
, B_FALSE
);
478 (void) unlink(ks_desc_file
);
480 (void) rmdir(get_keystore_path());
481 (void) rmdir(pub_obj_path
);
482 (void) rmdir(pri_obj_path
);
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.
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) {
507 if (stat(fname
, &fn_stat
) != 0) {
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
)) {
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
)) {
530 if (lock_file(*fd
, read_lock
, B_TRUE
) != 0) {
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 */
543 while (!same_inode
) {
545 * need to unlock file, close, re-open the file,
546 * and re-acquire the lock
550 if (lock_file(*fd
, B_TRUE
, B_FALSE
) != 0) {
557 *fd
= open_nointr(fname
, mode
|O_NONBLOCK
);
562 /* acquire lock again */
563 if (lock_file(*fd
, read_lock
, B_TRUE
) != 0) {
567 if (is_inode_same(*fd
, fname
, &same_inode
) != 0) {
568 (void) lock_file(*fd
, B_TRUE
, B_FALSE
); /* unlock */
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
583 open_and_lock_keystore_desc(mode_t mode
, boolean_t do_create_keystore
,
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
);
594 if ((errno
== ENOENT
) && (do_create_keystore
)) {
595 if (create_keystore() < 0) {
598 fd
= open_nointr(fname
, mode
|O_NONBLOCK
);
608 /* already hold the lock */
612 if (acquire_file_lock(&fd
, fname
, mode
) != 0) {
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
631 lock_desc_file(boolean_t read_lock
, boolean_t set_lock
)
634 char ks_desc_file
[MAXPATHLEN
];
640 * make sure desc_fd is not already used. If used, it means
641 * some other lock is already set on the file
647 (void) get_desc_file_path(ks_desc_file
);
654 if ((desc_fd
= open_and_lock_keystore_desc(oflag
,
655 B_FALSE
, B_FALSE
)) < 0) {
659 /* make sure we have a valid fd */
664 if (lock_file(desc_fd
, read_lock
, B_FALSE
) == 1) {
668 (void) close(desc_fd
);
676 open_and_lock_object_file(ks_obj_handle_t
*ks_handle
, int oflag
,
679 char obj_fname
[MAXPATHLEN
];
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
);
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
);
698 /* already hold the lock */
702 if (acquire_file_lock(&fd
, obj_fname
, oflag
) != 0) {
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
726 create_updated_keystore_version(int fd
, char *tmp_fname
)
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
);
740 * copy everything from keystore version to temp file except
741 * the keystore version. Keystore version is updated
746 if (readn_nointr(fd
, buf
, KS_PKCS11_VER_SIZE
) != KS_PKCS11_VER_SIZE
) {
750 if (writen_nointr(tmp_fd
, buf
, KS_PKCS11_VER_SIZE
) !=
751 KS_PKCS11_VER_SIZE
) {
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
) {
762 version
= SWAP32(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
)
772 /* read rest of information, nothing needs to be updated */
773 nread
= readn_nointr(fd
, buf
, BUFSIZ
);
775 if (writen_nointr(tmp_fd
, buf
, nread
) != nread
) {
778 nread
= readn_nointr(fd
, buf
, BUFSIZ
);
781 (void) close(tmp_fd
);
782 return (0); /* no error */
785 (void) close(tmp_fd
);
786 (void) remove(tmp_fname
);
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
)
798 while ((dp
= readdir(dirp
)) != NULL
) {
800 if (strncmp(dp
->d_name
, OBJ_PREFIX
, OBJ_PREFIX_LEN
) != 0)
803 (void) strcpy((char *)ks_handle
->name
, dp
->d_name
);
804 rv
= soft_keystore_get_single_obj(ks_handle
, &obj
, lock_held
);
809 if (*result_obj_list
== NULL
) {
810 *result_obj_list
= obj
;
812 obj
->next
= *result_obj_list
;
813 *result_obj_list
= obj
;
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.
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
) {
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
854 bzero(*prepared_buf
, MAXPATHLEN
);
855 (void) memcpy(*prepared_buf
, obj_path
, strlen(obj_path
));
856 (void) memcpy(*prepared_buf
+ MAXPATHLEN
, buf
, buf_len
);
861 * retrieves the hashed pin from the keystore
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
) {
896 return (CKR_FUNCTION_FAILED
);
898 (*hashed_pin
)[hashed_pin_size
] = '\0';
904 * FUNCTION: soft_keystore_lock
907 * set_lock: TRUE to set readlock on the keystore object file,
908 * FALSE to remove readlock on keystore object file.
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
931 * set_lock: TRUE to set writelock on the keystore description file
932 * FALSE to remove write lock on keystore description file.
937 * 1: some error occurred
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
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.
961 * If no error, file descriptor of locked file will be returned
962 * -1: some error occurred
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
)
980 if ((fd
= open_and_lock_object_file(ks_handle
, oflag
, B_FALSE
)) < 0) {
988 * FUNCTION: soft_keystore_unlock_object
991 * fd: file descriptor returned from soft_keystore_lock_object
995 * 1: some error occurred while getting the pin
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) {
1014 * FUNCTION: soft_keystore_get_version
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.
1024 * -1: some error occurred while getting the version number
1027 * get the version number of the keystore from keystore
1031 soft_keystore_get_version(uint_t
*version
, boolean_t lock_held
)
1033 int fd
, ret_val
= 0;
1036 if ((fd
= open_and_lock_keystore_desc(O_RDONLY
,
1037 B_FALSE
, lock_held
)) < 0) {
1041 if (lseek(fd
, KS_VER_OFFSET
, SEEK_SET
) != KS_VER_OFFSET
) {
1046 if (readn_nointr(fd
, (char *)&buf
, KS_VER_SIZE
) != KS_VER_SIZE
) {
1050 *version
= SWAP32(buf
);
1055 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
1065 * FUNCTION: soft_keystore_get_object_version
1069 * ks_handle: handle of the key store object to be accessed.
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.
1078 * -1: some error occurred while getting the pin
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;
1090 if ((fd
= open_and_lock_object_file(ks_handle
, O_RDONLY
,
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
) {
1104 *version
= SWAP32(tmp
);
1108 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
1119 * FUNCTION: soft_keystore_getpin
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.
1129 * -1: some error occurred while getting the pin
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;
1147 if ((fd
= open_and_lock_keystore_desc(O_RDONLY
, B_FALSE
,
1152 rv
= get_hashed_pin(fd
, hashed_pin
);
1159 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
1170 * Generate a 16-byte Initialization Vector (IV).
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
1190 read_obj_data(int old_fd
, char **buf
, ssize_t
*bytes_read
)
1193 ssize_t nread
, loop_count
;
1196 *buf
= malloc(BUFSIZ
);
1198 return (CKR_HOST_MEMORY
);
1201 nread
= readn_nointr(old_fd
, *buf
, BUFSIZ
);
1204 return (CKR_FUNCTION_FAILED
);
1207 while (nread
== (loop_count
* BUFSIZ
)) {
1211 /* more than BUFSIZ of data */
1212 buf1
= reallocarray(*buf
, loop_count
, BUFSIZ
);
1215 return (CKR_HOST_MEMORY
);
1218 nread_tmp
= readn_nointr(old_fd
,
1219 *buf
+ ((loop_count
- 1) * BUFSIZ
), BUFSIZ
);
1220 if (nread_tmp
< 0) {
1222 return (CKR_FUNCTION_FAILED
);
1226 *bytes_read
= nread
;
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.
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
];
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
);
1258 if (acquire_file_lock(&old_fd
, orig_obj_name
, O_RDONLY
) != 0) {
1260 (void) close(old_fd
);
1265 new_fd
= open_nointr(new_obj_name
,
1266 O_WRONLY
|O_CREAT
|O_EXCL
|O_NONBLOCK
, S_IRUSR
|S_IWUSR
);
1268 (void) close(old_fd
);
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
);
1280 /* read version, increment, and write to tmp file */
1281 if (readn_nointr(old_fd
, (char *)&version
, OBJ_VER_SIZE
)
1286 version
= SWAP32(version
);
1288 version
= SWAP32(version
);
1290 if (writen_nointr(new_fd
, (char *)&version
, OBJ_VER_SIZE
)
1296 if (readn_nointr(old_fd
, (char *)old_iv
, OBJ_IV_SIZE
) != OBJ_IV_SIZE
) {
1300 /* generate new IV */
1301 if (soft_gen_iv(iv
) != CKR_OK
) {
1305 if (writen_nointr(new_fd
, (char *)iv
, OBJ_IV_SIZE
) != OBJ_IV_SIZE
) {
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
) {
1314 if (read_obj_data(old_fd
, (char **)&buf
, &nread
) != CKR_OK
) {
1318 /* decrypt data using old key */
1320 if (soft_keystore_crypt(enc_key
, old_iv
, B_FALSE
, buf
, nread
,
1321 NULL
, &decrypted_len
) != CKR_OK
) {
1326 decrypted_buf
= malloc(decrypted_len
);
1327 if (decrypted_buf
== NULL
) {
1332 if (soft_keystore_crypt(enc_key
, old_iv
, B_FALSE
, buf
, nread
,
1333 decrypted_buf
, &decrypted_len
) != CKR_OK
) {
1335 free(decrypted_buf
);
1341 /* re-encrypt with new key */
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
);
1349 buf
= malloc(encrypted_len
);
1351 free(decrypted_buf
);
1355 if (soft_keystore_crypt(new_enc_key
, iv
, B_TRUE
, decrypted_buf
,
1356 decrypted_len
, buf
, &encrypted_len
) != CKR_OK
) {
1358 free(decrypted_buf
);
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
) {
1372 /* just for sanity check */
1373 if (hmac_len
!= OBJ_HMAC_SIZE
) {
1378 /* write new hmac */
1379 if (writen_nointr(new_fd
, (char *)hmac
, OBJ_HMAC_SIZE
)
1385 /* write re-encrypted buffer to temp file */
1386 if (writen_nointr(new_fd
, (void *)buf
, encrypted_len
)
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
);
1402 (void) remove(new_obj_name
);
1408 * FUNCTION: soft_keystore_setpin
1411 * newpin: new pin entered by the user.
1412 * lock_held: TRUE if the lock is held by caller.
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
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
];
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
;
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
;
1453 if ((enc_key
== NULL
) ||
1454 (enc_key
->magic_marker
!= SOFTTOKEN_OBJECT_MAGIC
)) {
1455 user_logged_in
= B_FALSE
;
1457 user_logged_in
= B_TRUE
;
1460 if ((fd
= open_and_lock_keystore_desc(O_RDWR
, B_TRUE
,
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) {
1479 /* read and write PKCS version to temp file */
1480 if (readn_nointr(fd
, filebuf
, KS_PKCS11_VER_SIZE
)
1481 != KS_PKCS11_VER_SIZE
) {
1485 if (writen_nointr(tmp_ks_fd
, filebuf
, KS_PKCS11_VER_SIZE
)
1486 != KS_PKCS11_VER_SIZE
) {
1490 /* get version number, and write updated number to temp file */
1491 if (readn_nointr(fd
, &version
, KS_VER_SIZE
) != KS_VER_SIZE
) {
1495 version
= SWAP32(version
);
1497 version
= SWAP32(version
);
1499 if (writen_nointr(tmp_ks_fd
, (void *)&version
, KS_VER_SIZE
)
1505 /* read and write counter, no modification necessary */
1506 if (readn_nointr(fd
, filebuf
, KS_COUNTER_SIZE
) != KS_COUNTER_SIZE
) {
1510 if (writen_nointr(tmp_ks_fd
, filebuf
, KS_COUNTER_SIZE
)
1511 != KS_COUNTER_SIZE
) {
1515 /* read old encryption salt */
1516 crypt_salt
= malloc(KS_KEY_SALT_SIZE
);
1517 if (crypt_salt
== NULL
) {
1520 if (readn_nointr(fd
, (char *)crypt_salt
, KS_KEY_SALT_SIZE
)
1521 != KS_KEY_SALT_SIZE
) {
1525 /* read old hmac salt */
1526 hmac_salt
= malloc(KS_HMAC_SALT_SIZE
);
1527 if (hmac_salt
== NULL
) {
1530 if (readn_nointr(fd
, (char *)hmac_salt
, KS_HMAC_SALT_SIZE
)
1531 != KS_HMAC_SALT_SIZE
) {
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
)
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
);
1553 free(new_crypt_salt
);
1555 if (soft_gen_hmac_key(newpin
, &new_hmac_key
, &new_hmac_salt
)
1557 (void) soft_cleanup_object(new_crypt_key
);
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
);
1565 free(new_hmac_salt
);
1567 if (soft_gen_crypt_key(newpin
, &new_crypt_key
,
1568 (CK_BYTE
**)&crypt_salt
) != CKR_OK
) {
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
);
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
);
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
) {
1592 * read hashed pin salt, and write to updated keystore description
1595 if (readn_nointr(fd
, (char *)&hashed_pin_salt_length
,
1596 KS_HASHED_PIN_SALT_LEN_SIZE
) != KS_HASHED_PIN_SALT_LEN_SIZE
) {
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
) {
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
) {
1612 if ((readn_nointr(fd
, hashed_pin_salt
, hashed_pin_salt_length
)) !=
1613 (ssize_t
)hashed_pin_salt_length
) {
1614 free(hashed_pin_salt
);
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
);
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
);
1633 free(hashed_pin_salt
);
1635 if (new_hashed_pin
== NULL
) {
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
) {
1648 if (writen_nointr(tmp_ks_fd
, (void *)new_hashed_pin
,
1649 new_hashed_pin_len
) != (ssize_t
)new_hashed_pin_len
) {
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.
1670 /* if user did not login, need to set the old pin */
1671 if (!user_logged_in
) {
1672 if (soft_keystore_authpin(oldpin
) != 0) {
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)) {
1686 obj
= malloc(sizeof (priobjs_t
));
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) {
1701 /* insert into list of file to be renamed */
1702 if (pri_objs
== NULL
) {
1706 obj
->next
= pri_objs
;
1711 /* rename all the private objects */
1714 (void) rename(tmp
->tmp_name
, tmp
->orig_name
);
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
);
1735 if (pri_objs
!= NULL
) {
1736 priobjs_t
*p
= pri_objs
;
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
);
1754 if ((ret_val
!= 0) || (!user_logged_in
)) {
1755 (void) soft_cleanup_object(new_crypt_key
);
1756 (void) soft_cleanup_object(new_hmac_key
);
1761 if (lock_file(fd
, B_FALSE
, B_FALSE
) < 0) {
1765 if (crypt_salt
!= NULL
) {
1768 if (hmac_salt
!= NULL
) {
1772 (void) close(tmp_ks_fd
);
1774 (void) remove(tmp_ks_desc_name
);
1780 * FUNCTION: soft_keystore_authpin
1783 * pin: pin specified by the user for logging into
1788 * -1: if there is any error
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
)
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) {
1813 crypt_salt
= malloc(KS_KEY_SALT_SIZE
);
1814 if (crypt_salt
== NULL
) {
1818 if (lseek(fd
, KS_KEY_SALT_OFFSET
, SEEK_SET
) != KS_KEY_SALT_OFFSET
) {
1822 if (readn_nointr(fd
, (char *)crypt_salt
, KS_KEY_SALT_SIZE
)
1823 != KS_KEY_SALT_SIZE
) {
1827 if (soft_gen_crypt_key(pin
, &enc_key
, (CK_BYTE
**)&crypt_salt
)
1832 hmac_salt
= malloc(KS_HMAC_SALT_SIZE
);
1833 if (hmac_salt
== NULL
) {
1837 if (lseek(fd
, KS_HMAC_SALT_OFFSET
, SEEK_SET
) != KS_HMAC_SALT_OFFSET
) {
1841 if (readn_nointr(fd
, (char *)hmac_salt
, KS_HMAC_SALT_SIZE
)
1842 != KS_HMAC_SALT_SIZE
) {
1846 if (soft_gen_hmac_key(pin
, &hmac_key
, (CK_BYTE
**)&hmac_salt
)
1854 /* unlock the file */
1855 (void) lock_file(fd
, B_TRUE
, B_FALSE
);
1857 if (crypt_salt
!= NULL
) {
1860 if (hmac_salt
!= NULL
) {
1867 * FUNCTION: soft_keystore_get_objs
1871 * search_type: Specify type of objects to return.
1872 * lock_held: TRUE if the lock is held by caller.
1877 * NULL: if there are no object in the database.
1879 * Otherwise, linked list of objects as requested
1882 * The linked list returned will need to be freed
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
1894 * The buffers returned for private objects are already
1898 soft_keystore_get_objs(ks_search_type_t search_type
,
1899 ks_obj_t
**result_obj_list
, boolean_t lock_held
)
1902 ks_obj_handle_t ks_handle
;
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
1914 if ((ks_fd
= open_and_lock_keystore_desc(O_RDONLY
, B_FALSE
,
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
,
1933 (void) closedir(dirp
);
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
);
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
);
1959 rv
= get_all_objs_in_dir(dirp
, &ks_handle
, result_obj_list
,
1962 (void) closedir(dirp
);
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
);
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
;
1981 *result_obj_list
= tmp
->next
;
1984 tmp
= *result_obj_list
;
1986 *result_obj_list
= NULL
;
1992 * FUNCTION: soft_keystore_get_single_obj
1995 * ks_handle: handle of the key store object to be accessed
1996 * lock_held: TRUE if the lock is held by caller.
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.
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
2016 * The buffer returned for the requested private object
2017 * is already decrypted.
2020 soft_keystore_get_single_obj(ks_obj_handle_t
*ks_handle
,
2021 ks_obj_t
**return_obj
, boolean_t lock_held
)
2025 uchar_t iv
[OBJ_IV_SIZE
], obj_hmac
[OBJ_HMAC_SIZE
];
2026 uchar_t
*buf
, *decrypted_buf
;
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
,
2040 return (CKR_FUNCTION_FAILED
);
2043 obj
= malloc(sizeof (ks_obj_t
));
2045 return (CKR_HOST_MEMORY
);
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
)
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
) {
2066 /* Then, read the HMAC */
2067 if (readn_nointr(fd
, obj_hmac
, OBJ_HMAC_SIZE
) != OBJ_HMAC_SIZE
) {
2071 /* read the object */
2072 rv
= read_obj_data(fd
, (char **)&buf
, &nread
);
2077 if (ks_handle
->public) {
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
) {
2090 rv
= CKR_FUNCTION_FAILED
;
2094 /* decrypt object */
2095 if (soft_keystore_crypt(enc_key
, iv
, B_FALSE
, buf
, nread
,
2096 NULL
, &out_len
) != CKR_OK
) {
2098 rv
= CKR_FUNCTION_FAILED
;
2102 decrypted_buf
= malloc(sizeof (uchar_t
) * out_len
);
2103 if (decrypted_buf
== NULL
) {
2105 rv
= CKR_HOST_MEMORY
;
2109 if (soft_keystore_crypt(enc_key
, iv
, B_FALSE
, buf
, nread
,
2110 decrypted_buf
, &out_len
) != CKR_OK
) {
2111 free(decrypted_buf
);
2113 rv
= CKR_FUNCTION_FAILED
;
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
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
);
2130 rv
= CKR_HOST_MEMORY
;
2133 (void) memcpy(obj
->buf
, decrypted_buf
+ MAXPATHLEN
, obj
->size
);
2134 free(decrypted_buf
);
2145 /* unlock the file after reading */
2147 (void) lock_file(fd
, B_TRUE
, B_FALSE
);
2157 * FUNCTION: soft_keystore_put_new_obj
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
2170 * 0: object successfully stored in file
2171 * -1: some error occurred, object is not stored in file.
2174 * This API is used to write a newly created token object
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
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
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
];
2206 if (keyhandle
== NULL
) {
2210 /* if it is private object, make sure we have the key */
2212 if ((enc_key
== NULL
) ||
2213 (enc_key
->magic_marker
!= SOFTTOKEN_OBJECT_MAGIC
)) {
2218 /* open keystore, and set write lock */
2219 if ((fd
= open_and_lock_keystore_desc(O_RDWR
, B_FALSE
,
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) {
2238 /* read and write pkcs11 version */
2239 if (readn_nointr(fd
, filebuf
, KS_PKCS11_VER_SIZE
)
2240 != KS_PKCS11_VER_SIZE
) {
2244 if (writen_nointr(tmp_ks_fd
, filebuf
, KS_PKCS11_VER_SIZE
)
2245 != KS_PKCS11_VER_SIZE
) {
2249 /* get version number, and write updated number to temp file */
2250 if (readn_nointr(fd
, &version
, KS_VER_SIZE
) != KS_VER_SIZE
) {
2254 version
= SWAP32(version
);
2256 version
= SWAP32(version
);
2258 if (writen_nointr(tmp_ks_fd
, (void *)&version
,
2259 KS_VER_SIZE
) != KS_VER_SIZE
) {
2263 /* get object count value */
2264 if (readn_nointr(fd
, &counter
, KS_COUNTER_SIZE
) != KS_COUNTER_SIZE
) {
2267 counter
= SWAP32(counter
);
2269 bzero(obj_name
, sizeof (obj_name
));
2271 (void) snprintf(obj_name
, MAXPATHLEN
, "%s/%s%d",
2272 get_pub_obj_path(pub_obj_path
), OBJ_PREFIX
, counter
);
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
);
2282 /* can't create object file */
2286 /* lock object file for writing */
2287 if (lock_file(obj_fd
, B_FALSE
, B_TRUE
) != 0) {
2288 (void) close(obj_fd
);
2292 /* write object meta data */
2293 version
= SWAP32(1);
2294 if (writen_nointr(obj_fd
, (void *)&version
, sizeof (version
))
2295 != sizeof (version
)) {
2300 bzero(iv
, sizeof (iv
));
2302 /* generate an IV */
2303 if (soft_gen_iv(iv
) != CKR_OK
) {
2309 if (writen_nointr(obj_fd
, (void *)iv
, sizeof (iv
)) != sizeof (iv
)) {
2315 bzero(obj_hmac
, sizeof (obj_hmac
));
2316 if (writen_nointr(obj_fd
, (void *)obj_hmac
,
2317 sizeof (obj_hmac
)) != sizeof (obj_hmac
)) {
2321 if (writen_nointr(obj_fd
, (char *)buf
, len
) != len
) {
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) {
2335 if (soft_keystore_crypt(enc_key
, iv
,
2336 B_TRUE
, prepared_buf
, prepared_len
,
2337 NULL
, &out_len
) != CKR_OK
) {
2342 encrypted_buf
= malloc(out_len
* sizeof (char));
2343 if (encrypted_buf
== NULL
) {
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
);
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
);
2365 if (hmac_size
!= OBJ_HMAC_SIZE
) {
2366 free(encrypted_buf
);
2371 if (writen_nointr(obj_fd
, (void *)obj_hmac
,
2372 sizeof (obj_hmac
)) != sizeof (obj_hmac
)) {
2373 free(encrypted_buf
);
2377 /* write encrypted object */
2378 if (writen_nointr(obj_fd
, (void *)encrypted_buf
, out_len
)
2380 free(encrypted_buf
);
2384 free(encrypted_buf
);
2388 (void) close(obj_fd
);
2389 (void) snprintf((char *)keyhandle
->name
, sizeof (keyhandle
->name
),
2391 keyhandle
->public = public;
2394 * store new counter to temp keystore description file.
2397 counter
= SWAP32(counter
);
2398 if (writen_nointr(tmp_ks_fd
, (void *)&counter
,
2399 sizeof (counter
)) != sizeof (counter
)) {
2403 /* read rest of keystore description file and store into temp file */
2404 nread
= readn_nointr(fd
, filebuf
, sizeof (filebuf
));
2406 if (writen_nointr(tmp_ks_fd
, filebuf
, nread
) != nread
) {
2409 nread
= readn_nointr(fd
, filebuf
, sizeof (filebuf
));
2412 (void) close(tmp_ks_fd
);
2413 (void) rename(tmp_ks_desc_name
, ks_desc_file
);
2416 /* release lock on description file */
2417 if (lock_file(fd
, B_FALSE
, B_FALSE
) != 0) {
2427 /* remove object file. No need to remove lock first */
2428 (void) unlink(obj_name
);
2432 (void) close(tmp_ks_fd
);
2433 (void) remove(tmp_ks_desc_name
);
2435 /* release lock on description file */
2436 (void) lock_file(fd
, B_FALSE
, B_FALSE
);
2444 * FUNCTION: soft_keystore_modify_obj
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.
2454 * -1: if any error occurred.
2455 * Otherwise, 0 is returned.
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
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
];
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
)) {
2488 /* open and lock keystore description file */
2489 if ((ks_fd
= open_and_lock_keystore_desc(O_RDWR
, B_FALSE
,
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
);
2505 /* open object file */
2506 if ((fd
= open_and_lock_object_file(ks_handle
, O_RDWR
,
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
);
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
);
2533 /* can't create tmp object file */
2537 /* read version, increment, and write to tmp file */
2538 if (readn_nointr(fd
, (char *)&version
, OBJ_VER_SIZE
) != OBJ_VER_SIZE
) {
2542 version
= SWAP32(version
);
2544 version
= SWAP32(version
);
2546 if (writen_nointr(tmp_fd
, (char *)&version
, OBJ_VER_SIZE
)
2551 /* generate a new IV for the object, old one can be ignored */
2552 if (soft_gen_iv(iv
) != CKR_OK
) {
2556 if (writen_nointr(tmp_fd
, (char *)iv
, OBJ_IV_SIZE
) != OBJ_IV_SIZE
) {
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
)
2569 /* write updated object */
2570 if (writen_nointr(tmp_fd
, (char *)buf
, len
) != len
) {
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) {
2584 /* encrypt the data */
2585 if (soft_keystore_crypt(enc_key
, iv
, B_TRUE
, prepared_buf
,
2586 prepared_len
, NULL
, &out_len
) != CKR_OK
) {
2591 encrypted_buf
= malloc(out_len
* sizeof (char));
2592 if (encrypted_buf
== NULL
) {
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
);
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
);
2614 if (hmac_size
!= OBJ_HMAC_SIZE
) {
2615 free(encrypted_buf
);
2619 if (writen_nointr(tmp_fd
, (char *)obj_hmac
, OBJ_HMAC_SIZE
)
2621 free(encrypted_buf
);
2625 if (writen_nointr(tmp_fd
, (void *)encrypted_buf
, out_len
)
2627 free(encrypted_buf
);
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
);
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
);
2647 /* determine need to unlock file or not */
2649 if (lock_file(fd
, B_FALSE
, B_FALSE
) < 0) {
2651 (void) unlink(tmp_name
);
2656 /* unlock keystore description file */
2657 if (lock_file(ks_fd
, B_FALSE
, B_FALSE
) != 0) {
2658 (void) close(ks_fd
);
2663 (void) close(ks_fd
);
2667 return (0); /* All operations completed successfully */
2670 (void) close(tmp_fd
);
2671 (void) remove(tmp_name
);
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
);
2685 * FUNCTION: soft_keystore_del_obj
2688 * ks_handle: handle of the key store object to be deleted
2689 * lock_held: TRUE if the lock is held by caller.
2692 * -1: if any error occurred.
2693 * 0: object successfully deleted from keystore.
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
];
2707 char pub_obj_path
[MAXPATHLEN
], pri_obj_path
[MAXPATHLEN
],
2708 ks_desc_file
[MAXPATHLEN
];
2712 if ((fd
= open_and_lock_keystore_desc(O_RDWR
, B_FALSE
,
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) {
2723 if (ks_handle
->public) {
2724 (void) snprintf(objname
, MAXPATHLEN
, "%s/%s",
2725 get_pub_obj_path(pub_obj_path
), ks_handle
->name
);
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
,
2740 if (unlink(objname
) != 0) {
2741 (void) lock_file(obj_fd
, B_FALSE
, B_FALSE
);
2742 (void) close(obj_fd
);
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) {
2755 /* unlock keystore description file */
2757 if (lock_file(fd
, B_FALSE
, B_FALSE
) != 0) {
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
,
2787 if (lseek(fd
, KS_HASHED_PIN_SALT_LEN_OFFSET
, SEEK_SET
)
2788 != KS_HASHED_PIN_SALT_LEN_OFFSET
) {
2792 if (readn_nointr(fd
, (char *)&hashed_pin_salt_size
,
2793 KS_HASHED_PIN_SALT_LEN_SIZE
) != KS_HASHED_PIN_SALT_LEN_SIZE
) {
2796 hashed_pin_salt_size
= SWAP64(hashed_pin_salt_size
);
2798 *salt
= malloc(hashed_pin_salt_size
+ 1);
2799 if (*salt
== NULL
) {
2803 if ((readn_nointr(fd
, *salt
, hashed_pin_salt_size
))
2804 != (ssize_t
)hashed_pin_salt_size
) {
2808 (*salt
)[hashed_pin_salt_size
] = '\0';
2813 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
2822 * FUNCTION: soft_keystore_pin_initialized
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
2832 * lock_held: TRUE if the lock is held by caller.
2836 * any other appropriate CKR_value
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.
2849 soft_keystore_pin_initialized(boolean_t
*initialized
, char **hashed_pin
,
2850 boolean_t lock_held
)
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
,
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
;
2866 if (readn_nointr(fd
, (char *)crypt_salt
, KS_KEY_SALT_SIZE
)
2867 != KS_KEY_SALT_SIZE
) {
2868 ret_val
= CKR_FUNCTION_FAILED
;
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
;
2878 *initialized
= B_TRUE
;
2879 ret_val
= get_hashed_pin(fd
, hashed_pin
);
2885 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
2886 ret_val
= CKR_FUNCTION_FAILED
;
2895 * This checks if the keystore file exists
2899 soft_keystore_exists()
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
);
2913 * FUNCTION: soft_keystore_init
2916 * desired_state: The keystore state the caller would like
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.
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
)
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
2958 switch (soft_slot
.keystore_load_status
) {
2959 case KEYSTORE_UNINITIALIZED
:
2960 ret
= soft_keystore_exists();
2962 soft_slot
.keystore_load_status
= KEYSTORE_PRESENT
;
2963 else if (ret
== ENOENT
)
2964 if (create_keystore() == 0)
2965 soft_slot
.keystore_load_status
=
2968 soft_slot
.keystore_load_status
=
2969 KEYSTORE_UNAVAILABLE
;
2970 cryptoerror(LOG_DEBUG
,
2971 "pkcs11_softtoken: "
2972 "Cannot create keystore.");
2976 if (desired_state
<= KEYSTORE_PRESENT
)
2980 case KEYSTORE_PRESENT
:
2981 if (soft_keystore_get_version(&soft_slot
.ks_version
, B_FALSE
)
2983 soft_slot
.keystore_load_status
= KEYSTORE_UNAVAILABLE
;
2984 cryptoerror(LOG_DEBUG
,
2985 "pkcs11_softtoken: Keystore access failed.");
2989 soft_slot
.keystore_load_status
= KEYSTORE_LOAD
;
2990 if (desired_state
<= KEYSTORE_LOAD
)
2995 /* Load all the public token objects from keystore */
2996 if (soft_get_token_objects_from_keystore(PUB_TOKENOBJS
)
2998 (void) soft_destroy_token_session();
2999 soft_slot
.keystore_load_status
= KEYSTORE_UNAVAILABLE
;
3000 cryptoerror(LOG_DEBUG
,
3001 "pkcs11_softtoken: Cannot initialize keystore.");
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
3016 * desired_state: The keystore state the caller would like
3020 * B_TRUE if keystore is ready and at the desired state.
3021 * B_FALSE if keystore had an error and is not available.
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.
3033 soft_keystore_status(int desired_state
)
3036 if (soft_slot
.keystore_load_status
== KEYSTORE_UNAVAILABLE
)
3039 return ((desired_state
<= soft_slot
.keystore_load_status
) ||
3040 (soft_keystore_init(desired_state
) == desired_state
));