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
);
474 free(hashed_pin_salt
);
478 (void) lock_file(fd
, B_FALSE
, B_FALSE
);
479 (void) unlink(ks_desc_file
);
481 (void) rmdir(get_keystore_path());
482 (void) rmdir(pub_obj_path
);
483 (void) rmdir(pri_obj_path
);
488 * Determines if the file referenced by "fd" has the same
489 * inode as the file referenced by "fname".
491 * The argument "same" contains the result of determining
492 * if the inode is the same or not
494 * Returns 0 if there's no error.
495 * Returns 1 if there's any error with opening the file.
500 is_inode_same(int fd
, char *fname
, boolean_t
*same
)
502 struct stat fn_stat
, fd_stat
;
504 if (fstat(fd
, &fd_stat
) != 0) {
508 if (stat(fname
, &fn_stat
) != 0) {
512 /* It's the same file if both st_ino and st_dev match */
513 if ((fd_stat
.st_ino
== fn_stat
.st_ino
) &&
514 (fd_stat
.st_dev
== fn_stat
.st_dev
)) {
523 acquire_file_lock(int *fd
, char *fname
, mode_t mode
) {
525 boolean_t read_lock
= B_TRUE
, same_inode
;
527 if ((mode
== O_RDWR
) || (mode
== O_WRONLY
)) {
531 if (lock_file(*fd
, read_lock
, B_TRUE
) != 0) {
536 * make sure another process did not modify the file
537 * while we were trying to get the lock
539 if (is_inode_same(*fd
, fname
, &same_inode
) != 0) {
540 (void) lock_file(*fd
, B_TRUE
, B_FALSE
); /* unlock file */
544 while (!same_inode
) {
546 * need to unlock file, close, re-open the file,
547 * and re-acquire the lock
551 if (lock_file(*fd
, B_TRUE
, B_FALSE
) != 0) {
558 *fd
= open_nointr(fname
, mode
|O_NONBLOCK
);
563 /* acquire lock again */
564 if (lock_file(*fd
, read_lock
, B_TRUE
) != 0) {
568 if (is_inode_same(*fd
, fname
, &same_inode
) != 0) {
569 (void) lock_file(*fd
, B_TRUE
, B_FALSE
); /* unlock */
579 * Open the keystore description file in the specified mode.
580 * If the keystore doesn't exist, the "do_create_keystore"
581 * argument determines if the keystore should be created
584 open_and_lock_keystore_desc(mode_t mode
, boolean_t do_create_keystore
,
589 char *fname
, ks_desc_file
[MAXPATHLEN
];
591 /* open the keystore description file in requested mode */
592 fname
= get_desc_file_path(ks_desc_file
);
593 fd
= open_nointr(fname
, mode
|O_NONBLOCK
);
595 if ((errno
== ENOENT
) && (do_create_keystore
)) {
596 if (create_keystore() < 0) {
599 fd
= open_nointr(fname
, mode
|O_NONBLOCK
);
609 /* already hold the lock */
613 if (acquire_file_lock(&fd
, fname
, mode
) != 0) {
626 * Set or remove read or write lock on keystore description file
628 * read_lock: true for read lock, false for write lock
629 * set_lock: true for set a lock, false to remove a lock
632 lock_desc_file(boolean_t read_lock
, boolean_t set_lock
)
635 char ks_desc_file
[MAXPATHLEN
];
641 * make sure desc_fd is not already used. If used, it means
642 * some other lock is already set on the file
648 (void) get_desc_file_path(ks_desc_file
);
655 if ((desc_fd
= open_and_lock_keystore_desc(oflag
,
656 B_FALSE
, B_FALSE
)) < 0) {
660 /* make sure we have a valid fd */
665 if (lock_file(desc_fd
, read_lock
, B_FALSE
) == 1) {
669 (void) close(desc_fd
);
677 open_and_lock_object_file(ks_obj_handle_t
*ks_handle
, int oflag
,
680 char obj_fname
[MAXPATHLEN
];
683 if (ks_handle
->public) {
684 char pub_obj_path
[MAXPATHLEN
];
685 (void) snprintf(obj_fname
, MAXPATHLEN
, "%s/%s",
686 get_pub_obj_path(pub_obj_path
), ks_handle
->name
);
688 char pri_obj_path
[MAXPATHLEN
];
689 (void) snprintf(obj_fname
, MAXPATHLEN
, "%s/%s",
690 get_pri_obj_path(pri_obj_path
), ks_handle
->name
);
693 fd
= open_nointr(obj_fname
, oflag
|O_NONBLOCK
);
699 /* already hold the lock */
703 if (acquire_file_lock(&fd
, obj_fname
, oflag
) != 0) {
716 * Update file version number in a temporary file that's
717 * a copy of the keystore description file.
718 * The update is NOT made to the original keystore description
719 * file. It makes the update in a tempoary file.
721 * Name of the temporary file is assumed to be provided, but
722 * the file is assumed to not exist.
724 * return 0 if creating temp file is successful, returns -1 otherwise
727 create_updated_keystore_version(int fd
, char *tmp_fname
)
733 /* first, create the tempoary file */
734 tmp_fd
= open_nointr(tmp_fname
,
735 O_WRONLY
|O_CREAT
|O_EXCL
|O_NONBLOCK
, S_IRUSR
|S_IWUSR
);
741 * copy everything from keystore version to temp file except
742 * the keystore version. Keystore version is updated
747 if (readn_nointr(fd
, buf
, KS_PKCS11_VER_SIZE
) != KS_PKCS11_VER_SIZE
) {
751 if (writen_nointr(tmp_fd
, buf
, KS_PKCS11_VER_SIZE
) !=
752 KS_PKCS11_VER_SIZE
) {
756 /* version number, it needs to be updated */
758 /* read the current version number */
759 if (readn_nointr(fd
, &version
, KS_VER_SIZE
) != KS_VER_SIZE
) {
763 version
= SWAP32(version
);
765 version
= SWAP32(version
);
767 /* write the updated value to the tmp file */
768 if (writen_nointr(tmp_fd
, (void *)&version
, KS_VER_SIZE
)
773 /* read rest of information, nothing needs to be updated */
774 nread
= readn_nointr(fd
, buf
, BUFSIZ
);
776 if (writen_nointr(tmp_fd
, buf
, nread
) != nread
) {
779 nread
= readn_nointr(fd
, buf
, BUFSIZ
);
782 (void) close(tmp_fd
);
783 return (0); /* no error */
786 (void) close(tmp_fd
);
787 (void) remove(tmp_fname
);
792 get_all_objs_in_dir(DIR *dirp
, ks_obj_handle_t
*ks_handle
,
793 ks_obj_t
**result_obj_list
, boolean_t lock_held
)
799 while ((dp
= readdir(dirp
)) != NULL
) {
801 if (strncmp(dp
->d_name
, OBJ_PREFIX
, OBJ_PREFIX_LEN
) != 0)
804 (void) strcpy((char *)ks_handle
->name
, dp
->d_name
);
805 rv
= soft_keystore_get_single_obj(ks_handle
, &obj
, lock_held
);
810 if (*result_obj_list
== NULL
) {
811 *result_obj_list
= obj
;
813 obj
->next
= *result_obj_list
;
814 *result_obj_list
= obj
;
822 * This function prepares the obj data for encryption by prepending
823 * the FULL path of the file that will be used for storing
824 * the object. Having full path of the file as part of
825 * of the data for the object will prevent an attacker from
826 * copying a "bad" object into the keystore undetected.
828 * This function will always allocate:
829 * MAXPATHLEN + buf_len
830 * amount of data. If the full path of the filename doesn't occupy
831 * the whole MAXPATHLEN, the rest of the space will just be empty.
832 * It is the caller's responsibility to free the buffer allocated here.
834 * The allocated buffer is returned in the variable "prepared_buf"
835 * if there's no error.
837 * Returns 0 if there's no error, -1 otherwise.
840 prepare_data_for_encrypt(char *obj_path
, unsigned char *buf
, CK_ULONG buf_len
,
841 unsigned char **prepared_buf
, CK_ULONG
*prepared_len
)
843 *prepared_len
= MAXPATHLEN
+ buf_len
;
844 *prepared_buf
= malloc(*prepared_len
);
845 if (*prepared_buf
== NULL
) {
850 * only zero out the space for the path name. I could zero out
851 * the whole buffer, but that will be a waste of processing
852 * cycle since the rest of the buffer will be 100% filled all
855 bzero(*prepared_buf
, MAXPATHLEN
);
856 (void) memcpy(*prepared_buf
, obj_path
, strlen(obj_path
));
857 (void) memcpy(*prepared_buf
+ MAXPATHLEN
, buf
, buf_len
);
862 * retrieves the hashed pin from the keystore
865 get_hashed_pin(int fd
, char **hashed_pin
)
867 uint64_t hashed_pin_size
;
869 if (ks_hashed_pinlen_offset
== -1) {
870 if (calculate_hashed_pin_offset(fd
) != 0) {
871 return (CKR_FUNCTION_FAILED
);
875 /* first, get size of the hashed pin */
876 if (lseek(fd
, ks_hashed_pinlen_offset
, SEEK_SET
)
877 != ks_hashed_pinlen_offset
) {
878 return (CKR_FUNCTION_FAILED
);
881 if (readn_nointr(fd
, (char *)&hashed_pin_size
,
882 KS_HASHED_PINLEN_SIZE
) != KS_HASHED_PINLEN_SIZE
) {
883 return (CKR_FUNCTION_FAILED
);
886 hashed_pin_size
= SWAP64(hashed_pin_size
);
888 *hashed_pin
= malloc(hashed_pin_size
+ 1);
889 if (*hashed_pin
== NULL
) {
890 return (CKR_HOST_MEMORY
);
893 if ((readn_nointr(fd
, *hashed_pin
, hashed_pin_size
))
894 != (ssize_t
)hashed_pin_size
) {
897 return (CKR_FUNCTION_FAILED
);
899 (*hashed_pin
)[hashed_pin_size
] = '\0';
905 * FUNCTION: soft_keystore_lock
908 * set_lock: TRUE to set readlock on the keystore object file,
909 * FALSE to remove readlock on keystore object file.
918 * set or remove readlock on the keystore description file.
921 soft_keystore_readlock(boolean_t set_lock
)
924 return (lock_desc_file(B_TRUE
, set_lock
));
929 * FUNCTION: soft_keystore_writelock
932 * set_lock: TRUE to set writelock on the keystore description file
933 * FALSE to remove write lock on keystore description file.
938 * 1: some error occurred
941 * set/reset writelock on the keystore description file.
944 soft_keystore_writelock(boolean_t set_lock
)
946 return (lock_desc_file(B_FALSE
, set_lock
));
952 * FUNCTION: soft_keystore_lock_object
956 * ks_handle: handle of the keystore object file to be accessed.
957 * read_lock: TRUE to set readlock on the keystore object file,
958 * FALSE to set writelock on keystore object file.
962 * If no error, file descriptor of locked file will be returned
963 * -1: some error occurred
967 * set readlock or writelock on the keystore object file.
970 soft_keystore_lock_object(ks_obj_handle_t
*ks_handle
, boolean_t read_lock
)
981 if ((fd
= open_and_lock_object_file(ks_handle
, oflag
, B_FALSE
)) < 0) {
989 * FUNCTION: soft_keystore_unlock_object
992 * fd: file descriptor returned from soft_keystore_lock_object
996 * 1: some error occurred while getting the pin
999 * set/reset writelock on the keystore object file.
1002 soft_keystore_unlock_object(int fd
)
1004 if (lock_file(fd
, B_TRUE
, B_FALSE
) != 0) {
1015 * FUNCTION: soft_keystore_get_version
1018 * version: pointer to caller allocated memory for storing
1019 * the version of the keystore.
1020 * lock_held: TRUE if the lock is held by caller.
1025 * -1: some error occurred while getting the version number
1028 * get the version number of the keystore from keystore
1032 soft_keystore_get_version(uint_t
*version
, boolean_t lock_held
)
1034 int fd
, ret_val
= 0;
1037 if ((fd
= open_and_lock_keystore_desc(O_RDONLY
,
1038 B_FALSE
, lock_held
)) < 0) {
1042 if (lseek(fd
, KS_VER_OFFSET
, SEEK_SET
) != KS_VER_OFFSET
) {
1047 if (readn_nointr(fd
, (char *)&buf
, KS_VER_SIZE
) != KS_VER_SIZE
) {
1051 *version
= SWAP32(buf
);
1056 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
1066 * FUNCTION: soft_keystore_get_object_version
1070 * ks_handle: handle of the key store object to be accessed.
1072 * pointer to caller allocated memory for storing
1073 * the version of the object.
1074 * lock_held: TRUE if the lock is held by caller.
1079 * -1: some error occurred while getting the pin
1082 * get the version number of the specified token object.
1085 soft_keystore_get_object_version(ks_obj_handle_t
*ks_handle
,
1086 uint_t
*version
, boolean_t lock_held
)
1088 int fd
, ret_val
= 0;
1091 if ((fd
= open_and_lock_object_file(ks_handle
, O_RDONLY
,
1097 * read version. Version is always first item in object file
1098 * so, no need to do lseek
1100 if (readn_nointr(fd
, (char *)&tmp
, OBJ_VER_SIZE
) != OBJ_VER_SIZE
) {
1105 *version
= SWAP32(tmp
);
1109 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
1120 * FUNCTION: soft_keystore_getpin
1123 * hashed_pin: pointer to caller allocated memory
1124 * for storing the pin to be returned.
1125 * lock_held: TRUE if the lock is held by caller.
1130 * -1: some error occurred while getting the pin
1134 * Reads the MD5 hash from the keystore description
1135 * file and return it to the caller in the provided
1136 * buffer. If there is no PIN in the description file
1137 * because the file is just created, this function
1138 * will get a MD5 digest of the string "changeme",
1139 * store it in the file, and also return this
1140 * string to the caller.
1143 soft_keystore_getpin(char **hashed_pin
, boolean_t lock_held
)
1145 int fd
, ret_val
= -1;
1148 if ((fd
= open_and_lock_keystore_desc(O_RDONLY
, B_FALSE
,
1153 rv
= get_hashed_pin(fd
, hashed_pin
);
1160 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
1171 * Generate a 16-byte Initialization Vector (IV).
1174 soft_gen_iv(CK_BYTE
*iv
)
1176 return (pkcs11_get_nzero_urandom(iv
, 16) < 0 ?
1177 CKR_DEVICE_ERROR
: CKR_OK
);
1182 * This function reads all the data until the end of the file, and
1183 * put the data into the "buf" in argument. Memory for buf will
1184 * be allocated in this function. It is the caller's responsibility
1185 * to free it. The number of bytes read will be returned
1186 * in the argument "bytes_read"
1188 * returns CKR_OK if no error. Other CKR error codes if there's an error
1191 read_obj_data(int old_fd
, char **buf
, ssize_t
*bytes_read
)
1194 ssize_t nread
, loop_count
;
1197 *buf
= malloc(BUFSIZ
);
1199 return (CKR_HOST_MEMORY
);
1202 nread
= readn_nointr(old_fd
, *buf
, BUFSIZ
);
1205 return (CKR_FUNCTION_FAILED
);
1208 while (nread
== (loop_count
* BUFSIZ
)) {
1212 /* more than BUFSIZ of data */
1213 buf1
= realloc(*buf
, loop_count
* BUFSIZ
);
1216 return (CKR_HOST_MEMORY
);
1219 nread_tmp
= readn_nointr(old_fd
,
1220 *buf
+ ((loop_count
- 1) * BUFSIZ
), BUFSIZ
);
1221 if (nread_tmp
< 0) {
1223 return (CKR_FUNCTION_FAILED
);
1227 *bytes_read
= nread
;
1232 * Re-encrypt an object using the provided new_enc_key. The new HMAC
1233 * is calculated using the new_hmac_key. The global static variables
1234 * enc_key, and hmac_key will be used for decrypting the original
1235 * object, and verifying its signature.
1237 * The re-encrypted object will be stored in the file named
1238 * in the "new_obj_name" variable. The content of the "original"
1239 * file named in "orig_obj_name" is not disturbed.
1241 * Returns 0 if there's no error, returns -1 otherwise.
1245 reencrypt_obj(soft_object_t
*new_enc_key
, soft_object_t
*new_hmac_key
,
1246 char *orig_obj_name
, char *new_obj_name
) {
1248 int old_fd
, new_fd
, version
, ret_val
= -1;
1249 CK_BYTE iv
[OBJ_IV_SIZE
], old_iv
[OBJ_IV_SIZE
];
1251 CK_ULONG decrypted_len
, encrypted_len
, hmac_len
;
1252 CK_BYTE hmac
[OBJ_HMAC_SIZE
], *decrypted_buf
= NULL
, *buf
= NULL
;
1254 old_fd
= open_nointr(orig_obj_name
, O_RDONLY
|O_NONBLOCK
);
1259 if (acquire_file_lock(&old_fd
, orig_obj_name
, O_RDONLY
) != 0) {
1261 (void) close(old_fd
);
1266 new_fd
= open_nointr(new_obj_name
,
1267 O_WRONLY
|O_CREAT
|O_EXCL
|O_NONBLOCK
, S_IRUSR
|S_IWUSR
);
1269 (void) close(old_fd
);
1273 if (lock_file(new_fd
, B_FALSE
, B_TRUE
) != 0) {
1274 /* unlock old file */
1275 (void) lock_file(old_fd
, B_TRUE
, B_FALSE
);
1276 (void) close(old_fd
);
1277 (void) close(new_fd
);
1281 /* read version, increment, and write to tmp file */
1282 if (readn_nointr(old_fd
, (char *)&version
, OBJ_VER_SIZE
)
1287 version
= SWAP32(version
);
1289 version
= SWAP32(version
);
1291 if (writen_nointr(new_fd
, (char *)&version
, OBJ_VER_SIZE
)
1297 if (readn_nointr(old_fd
, (char *)old_iv
, OBJ_IV_SIZE
) != OBJ_IV_SIZE
) {
1301 /* generate new IV */
1302 if (soft_gen_iv(iv
) != CKR_OK
) {
1306 if (writen_nointr(new_fd
, (char *)iv
, OBJ_IV_SIZE
) != OBJ_IV_SIZE
) {
1310 /* seek to the original encrypted data, and read all of them */
1311 if (lseek(old_fd
, OBJ_DATA_OFFSET
, SEEK_SET
) != OBJ_DATA_OFFSET
) {
1315 if (read_obj_data(old_fd
, (char **)&buf
, &nread
) != CKR_OK
) {
1319 /* decrypt data using old key */
1321 if (soft_keystore_crypt(enc_key
, old_iv
, B_FALSE
, buf
, nread
,
1322 NULL
, &decrypted_len
) != CKR_OK
) {
1327 decrypted_buf
= malloc(decrypted_len
);
1328 if (decrypted_buf
== NULL
) {
1333 if (soft_keystore_crypt(enc_key
, old_iv
, B_FALSE
, buf
, nread
,
1334 decrypted_buf
, &decrypted_len
) != CKR_OK
) {
1336 free(decrypted_buf
);
1342 /* re-encrypt with new key */
1344 if (soft_keystore_crypt(new_enc_key
, iv
, B_TRUE
, decrypted_buf
,
1345 decrypted_len
, NULL
, &encrypted_len
) != CKR_OK
) {
1346 free(decrypted_buf
);
1350 buf
= malloc(encrypted_len
);
1352 free(decrypted_buf
);
1356 if (soft_keystore_crypt(new_enc_key
, iv
, B_TRUE
, decrypted_buf
,
1357 decrypted_len
, buf
, &encrypted_len
) != CKR_OK
) {
1359 free(decrypted_buf
);
1363 free(decrypted_buf
);
1365 /* calculate hmac on re-encrypted data using new hmac key */
1366 hmac_len
= OBJ_HMAC_SIZE
;
1367 if (soft_keystore_hmac(new_hmac_key
, B_TRUE
, buf
,
1368 encrypted_len
, hmac
, &hmac_len
) != CKR_OK
) {
1373 /* just for sanity check */
1374 if (hmac_len
!= OBJ_HMAC_SIZE
) {
1379 /* write new hmac */
1380 if (writen_nointr(new_fd
, (char *)hmac
, OBJ_HMAC_SIZE
)
1386 /* write re-encrypted buffer to temp file */
1387 if (writen_nointr(new_fd
, (void *)buf
, encrypted_len
)
1396 /* unlock the files */
1397 (void) lock_file(old_fd
, B_TRUE
, B_FALSE
);
1398 (void) lock_file(new_fd
, B_FALSE
, B_FALSE
);
1400 (void) close(old_fd
);
1401 (void) close(new_fd
);
1403 (void) remove(new_obj_name
);
1409 * FUNCTION: soft_keystore_setpin
1412 * newpin: new pin entered by the user.
1413 * lock_held: TRUE if the lock is held by caller.
1421 * This function does the following:
1423 * 1) Generates crypted value of newpin and store it
1424 * in keystore description file.
1425 * 2) Dervies the new encryption key from the newpin. This key
1426 * will be used to re-encrypt the private token objects.
1427 * 3) Re-encrypt all of this user's existing private token
1429 * 4) Increments the keystore version number.
1432 soft_keystore_setpin(uchar_t
*oldpin
, uchar_t
*newpin
, boolean_t lock_held
)
1434 int fd
, tmp_ks_fd
, version
, ret_val
= -1;
1435 soft_object_t
*new_crypt_key
= NULL
, *new_hmac_key
= NULL
;
1436 char filebuf
[BUFSIZ
];
1438 struct dirent
*pri_ent
;
1439 char pri_obj_path
[MAXPATHLEN
], ks_desc_file
[MAXPATHLEN
],
1440 tmp_ks_desc_name
[MAXPATHLEN
];
1441 typedef struct priobjs
{
1442 char orig_name
[MAXPATHLEN
];
1443 char tmp_name
[MAXPATHLEN
];
1444 struct priobjs
*next
;
1446 priobjs_t
*pri_objs
= NULL
, *tmp
;
1447 CK_BYTE
*crypt_salt
= NULL
, *hmac_salt
= NULL
;
1448 boolean_t pin_never_set
= B_FALSE
, user_logged_in
;
1449 char *new_hashed_pin
= NULL
;
1450 uint64_t hashed_pin_salt_length
, new_hashed_pin_len
, swaped_val
;
1451 char *hashed_pin_salt
= NULL
;
1454 if ((enc_key
== NULL
) ||
1455 (enc_key
->magic_marker
!= SOFTTOKEN_OBJECT_MAGIC
)) {
1456 user_logged_in
= B_FALSE
;
1458 user_logged_in
= B_TRUE
;
1461 if ((fd
= open_and_lock_keystore_desc(O_RDWR
, B_TRUE
,
1466 (void) get_desc_file_path(ks_desc_file
);
1467 (void) get_tmp_desc_file_path(tmp_ks_desc_name
);
1470 * create a tempoary file for the keystore description
1471 * file for updating version and counter information
1473 tmp_ks_fd
= open_nointr(tmp_ks_desc_name
,
1474 O_RDWR
|O_CREAT
|O_EXCL
|O_NONBLOCK
, S_IRUSR
|S_IWUSR
);
1475 if (tmp_ks_fd
< 0) {
1480 /* read and write PKCS version to temp file */
1481 if (readn_nointr(fd
, filebuf
, KS_PKCS11_VER_SIZE
)
1482 != KS_PKCS11_VER_SIZE
) {
1486 if (writen_nointr(tmp_ks_fd
, filebuf
, KS_PKCS11_VER_SIZE
)
1487 != KS_PKCS11_VER_SIZE
) {
1491 /* get version number, and write updated number to temp file */
1492 if (readn_nointr(fd
, &version
, KS_VER_SIZE
) != KS_VER_SIZE
) {
1496 version
= SWAP32(version
);
1498 version
= SWAP32(version
);
1500 if (writen_nointr(tmp_ks_fd
, (void *)&version
, KS_VER_SIZE
)
1506 /* read and write counter, no modification necessary */
1507 if (readn_nointr(fd
, filebuf
, KS_COUNTER_SIZE
) != KS_COUNTER_SIZE
) {
1511 if (writen_nointr(tmp_ks_fd
, filebuf
, KS_COUNTER_SIZE
)
1512 != KS_COUNTER_SIZE
) {
1516 /* read old encryption salt */
1517 crypt_salt
= malloc(KS_KEY_SALT_SIZE
);
1518 if (crypt_salt
== NULL
) {
1521 if (readn_nointr(fd
, (char *)crypt_salt
, KS_KEY_SALT_SIZE
)
1522 != KS_KEY_SALT_SIZE
) {
1526 /* read old hmac salt */
1527 hmac_salt
= malloc(KS_HMAC_SALT_SIZE
);
1528 if (hmac_salt
== NULL
) {
1531 if (readn_nointr(fd
, (char *)hmac_salt
, KS_HMAC_SALT_SIZE
)
1532 != KS_HMAC_SALT_SIZE
) {
1536 /* just create some empty bytes */
1537 bzero(filebuf
, sizeof (filebuf
));
1539 if (memcmp(crypt_salt
, filebuf
, KS_KEY_SALT_SIZE
) == 0) {
1540 /* PIN as never been set */
1541 CK_BYTE
*new_crypt_salt
= NULL
, *new_hmac_salt
= NULL
;
1543 pin_never_set
= B_TRUE
;
1544 if (soft_gen_crypt_key(newpin
, &new_crypt_key
, &new_crypt_salt
)
1548 if (writen_nointr(tmp_ks_fd
, (void *)new_crypt_salt
,
1549 KS_KEY_SALT_SIZE
) != KS_KEY_SALT_SIZE
) {
1550 free(new_crypt_salt
);
1551 (void) soft_cleanup_object(new_crypt_key
);
1554 free(new_crypt_salt
);
1556 if (soft_gen_hmac_key(newpin
, &new_hmac_key
, &new_hmac_salt
)
1558 (void) soft_cleanup_object(new_crypt_key
);
1561 if (writen_nointr(tmp_ks_fd
, (void *)new_hmac_salt
,
1562 KS_HMAC_SALT_SIZE
) != KS_HMAC_SALT_SIZE
) {
1563 free(new_hmac_salt
);
1566 free(new_hmac_salt
);
1568 if (soft_gen_crypt_key(newpin
, &new_crypt_key
,
1569 (CK_BYTE
**)&crypt_salt
) != CKR_OK
) {
1572 /* no change to the encryption salt */
1573 if (writen_nointr(tmp_ks_fd
, (void *)crypt_salt
,
1574 KS_KEY_SALT_SIZE
) != KS_KEY_SALT_SIZE
) {
1575 (void) soft_cleanup_object(new_crypt_key
);
1579 if (soft_gen_hmac_key(newpin
, &new_hmac_key
,
1580 (CK_BYTE
**)&hmac_salt
) != CKR_OK
) {
1581 (void) soft_cleanup_object(new_crypt_key
);
1585 /* no change to the hmac salt */
1586 if (writen_nointr(tmp_ks_fd
, (void *)hmac_salt
,
1587 KS_HMAC_SALT_SIZE
) != KS_HMAC_SALT_SIZE
) {
1593 * read hashed pin salt, and write to updated keystore description
1596 if (readn_nointr(fd
, (char *)&hashed_pin_salt_length
,
1597 KS_HASHED_PIN_SALT_LEN_SIZE
) != KS_HASHED_PIN_SALT_LEN_SIZE
) {
1601 if (writen_nointr(tmp_ks_fd
, (void *)&hashed_pin_salt_length
,
1602 KS_HASHED_PIN_SALT_LEN_SIZE
) != KS_HASHED_PIN_SALT_LEN_SIZE
) {
1606 hashed_pin_salt_length
= SWAP64(hashed_pin_salt_length
);
1608 hashed_pin_salt
= malloc(hashed_pin_salt_length
+ 1);
1609 if (hashed_pin_salt
== NULL
) {
1613 if ((readn_nointr(fd
, hashed_pin_salt
, hashed_pin_salt_length
)) !=
1614 (ssize_t
)hashed_pin_salt_length
) {
1615 free(hashed_pin_salt
);
1619 if ((writen_nointr(tmp_ks_fd
, hashed_pin_salt
, hashed_pin_salt_length
))
1620 != (ssize_t
)hashed_pin_salt_length
) {
1621 free(hashed_pin_salt
);
1625 hashed_pin_salt
[hashed_pin_salt_length
] = '\0';
1627 /* old hashed pin length and value can be ignored, generate new one */
1628 if (soft_gen_hashed_pin(newpin
, &new_hashed_pin
,
1629 &hashed_pin_salt
) < 0) {
1630 free(hashed_pin_salt
);
1634 free(hashed_pin_salt
);
1636 if (new_hashed_pin
== NULL
) {
1640 new_hashed_pin_len
= strlen(new_hashed_pin
);
1642 /* write new hashed pin length to file */
1643 swaped_val
= SWAP64(new_hashed_pin_len
);
1644 if (writen_nointr(tmp_ks_fd
, (void *)&swaped_val
,
1645 KS_HASHED_PINLEN_SIZE
) != KS_HASHED_PINLEN_SIZE
) {
1649 if (writen_nointr(tmp_ks_fd
, (void *)new_hashed_pin
,
1650 new_hashed_pin_len
) != (ssize_t
)new_hashed_pin_len
) {
1654 if (pin_never_set
) {
1655 /* there was no private object, no need to re-encrypt them */
1656 goto rename_desc_file
;
1659 /* re-encrypt all the private objects */
1660 pri_dirp
= opendir(get_pri_obj_path(pri_obj_path
));
1661 if (pri_dirp
== NULL
) {
1663 * this directory should exist, even if it doesn't contain
1664 * any objects. Don't want to update the pin if the
1665 * keystore is somehow messed up.
1671 /* if user did not login, need to set the old pin */
1672 if (!user_logged_in
) {
1673 if (soft_keystore_authpin(oldpin
) != 0) {
1678 while ((pri_ent
= readdir(pri_dirp
)) != NULL
) {
1680 if ((strcmp(pri_ent
->d_name
, ".") == 0) ||
1681 (strcmp(pri_ent
->d_name
, "..") == 0) ||
1682 (strncmp(pri_ent
->d_name
, TMP_OBJ_PREFIX
,
1683 strlen(TMP_OBJ_PREFIX
)) == 0)) {
1687 obj
= malloc(sizeof (priobjs_t
));
1691 (void) snprintf(obj
->orig_name
, MAXPATHLEN
,
1692 "%s/%s", pri_obj_path
, pri_ent
->d_name
);
1693 (void) snprintf(obj
->tmp_name
, MAXPATHLEN
, "%s/%s%s",
1694 pri_obj_path
, TMP_OBJ_PREFIX
,
1695 (pri_ent
->d_name
) + OBJ_PREFIX_LEN
);
1696 if (reencrypt_obj(new_crypt_key
, new_hmac_key
,
1697 obj
->orig_name
, obj
->tmp_name
) != 0) {
1702 /* insert into list of file to be renamed */
1703 if (pri_objs
== NULL
) {
1707 obj
->next
= pri_objs
;
1712 /* rename all the private objects */
1715 (void) rename(tmp
->tmp_name
, tmp
->orig_name
);
1721 /* destroy the old encryption key, and hmac key */
1722 if ((!pin_never_set
) && (user_logged_in
)) {
1723 (void) soft_cleanup_object(enc_key
);
1724 (void) soft_cleanup_object(hmac_key
);
1727 if (user_logged_in
) {
1728 enc_key
= new_crypt_key
;
1729 hmac_key
= new_hmac_key
;
1731 (void) rename(tmp_ks_desc_name
, ks_desc_file
);
1736 if (pri_objs
!= NULL
) {
1737 priobjs_t
*p
= pri_objs
;
1744 if (!pin_never_set
) {
1745 (void) closedir(pri_dirp
);
1748 if ((!user_logged_in
) && (!pin_never_set
)) {
1749 (void) soft_cleanup_object(enc_key
);
1750 (void) soft_cleanup_object(hmac_key
);
1755 if ((ret_val
!= 0) || (!user_logged_in
)) {
1756 (void) soft_cleanup_object(new_crypt_key
);
1757 (void) soft_cleanup_object(new_hmac_key
);
1762 if (lock_file(fd
, B_FALSE
, B_FALSE
) < 0) {
1766 if (crypt_salt
!= NULL
) {
1769 if (hmac_salt
!= NULL
) {
1773 (void) close(tmp_ks_fd
);
1775 (void) remove(tmp_ks_desc_name
);
1781 * FUNCTION: soft_keystore_authpin
1784 * pin: pin specified by the user for logging into
1789 * -1: if there is any error
1793 * This function takes the pin specified in the argument
1794 * and generates an encryption key based on the pin.
1795 * The generated encryption key will be used for
1796 * all future encryption and decryption for private
1797 * objects. Before this function is called, none
1798 * of the keystore related interfaces is able
1799 * to decrypt/encrypt any private object.
1802 soft_keystore_authpin(uchar_t
*pin
)
1806 CK_BYTE
*crypt_salt
= NULL
, *hmac_salt
;
1808 /* get the salt from the keystore description file */
1809 if ((fd
= open_and_lock_keystore_desc(O_RDONLY
,
1810 B_FALSE
, B_FALSE
)) < 0) {
1814 crypt_salt
= malloc(KS_KEY_SALT_SIZE
);
1815 if (crypt_salt
== NULL
) {
1819 if (lseek(fd
, KS_KEY_SALT_OFFSET
, SEEK_SET
) != KS_KEY_SALT_OFFSET
) {
1823 if (readn_nointr(fd
, (char *)crypt_salt
, KS_KEY_SALT_SIZE
)
1824 != KS_KEY_SALT_SIZE
) {
1828 if (soft_gen_crypt_key(pin
, &enc_key
, (CK_BYTE
**)&crypt_salt
)
1833 hmac_salt
= malloc(KS_HMAC_SALT_SIZE
);
1834 if (hmac_salt
== NULL
) {
1838 if (lseek(fd
, KS_HMAC_SALT_OFFSET
, SEEK_SET
) != KS_HMAC_SALT_OFFSET
) {
1842 if (readn_nointr(fd
, (char *)hmac_salt
, KS_HMAC_SALT_SIZE
)
1843 != KS_HMAC_SALT_SIZE
) {
1847 if (soft_gen_hmac_key(pin
, &hmac_key
, (CK_BYTE
**)&hmac_salt
)
1855 /* unlock the file */
1856 (void) lock_file(fd
, B_TRUE
, B_FALSE
);
1858 if (crypt_salt
!= NULL
) {
1861 if (hmac_salt
!= NULL
) {
1868 * FUNCTION: soft_keystore_get_objs
1872 * search_type: Specify type of objects to return.
1873 * lock_held: TRUE if the lock is held by caller.
1878 * NULL: if there are no object in the database.
1880 * Otherwise, linked list of objects as requested
1883 * The linked list returned will need to be freed
1888 * Returns objects as requested.
1890 * If private objects is requested, and the caller
1891 * has not previously passed in the pin or if the pin
1892 * passed in is wrong, private objects will not
1895 * The buffers returned for private objects are already
1899 soft_keystore_get_objs(ks_search_type_t search_type
,
1900 ks_obj_t
**result_obj_list
, boolean_t lock_held
)
1903 ks_obj_handle_t ks_handle
;
1908 *result_obj_list
= NULL
;
1911 * lock the keystore description file in "read" mode so that
1912 * objects won't get added/deleted/modified while we are
1915 if ((ks_fd
= open_and_lock_keystore_desc(O_RDONLY
, B_FALSE
,
1917 return (CKR_FUNCTION_FAILED
);
1920 if ((search_type
== ALL_TOKENOBJS
) || (search_type
== PUB_TOKENOBJS
)) {
1922 char pub_obj_path
[MAXPATHLEN
];
1924 ks_handle
.public = B_TRUE
;
1926 if ((dirp
= opendir(get_pub_obj_path(pub_obj_path
))) == NULL
) {
1927 (void) lock_file(ks_fd
, B_TRUE
, B_FALSE
);
1928 (void) close(ks_fd
);
1929 return (CKR_FUNCTION_FAILED
);
1931 rv
= get_all_objs_in_dir(dirp
, &ks_handle
, result_obj_list
,
1934 (void) closedir(dirp
);
1938 (void) closedir(dirp
);
1941 if ((search_type
== ALL_TOKENOBJS
) || (search_type
== PRI_TOKENOBJS
)) {
1943 char pri_obj_path
[MAXPATHLEN
];
1945 if ((enc_key
== NULL
) ||
1946 (enc_key
->magic_marker
!= SOFTTOKEN_OBJECT_MAGIC
)) {
1947 /* has not login - no need to go any further */
1948 (void) lock_file(ks_fd
, B_TRUE
, B_FALSE
);
1949 (void) close(ks_fd
);
1953 ks_handle
.public = B_FALSE
;
1955 if ((dirp
= opendir(get_pri_obj_path(pri_obj_path
))) == NULL
) {
1956 (void) lock_file(ks_fd
, B_TRUE
, B_FALSE
);
1957 (void) close(ks_fd
);
1960 rv
= get_all_objs_in_dir(dirp
, &ks_handle
, result_obj_list
,
1963 (void) closedir(dirp
);
1967 (void) closedir(dirp
);
1969 /* close the keystore description file */
1970 (void) lock_file(ks_fd
, B_TRUE
, B_FALSE
);
1971 (void) close(ks_fd
);
1975 /* close the keystore description file */
1976 (void) lock_file(ks_fd
, B_TRUE
, B_FALSE
);
1977 (void) close(ks_fd
);
1979 /* free all the objects found before hitting the error */
1980 tmp
= *result_obj_list
;
1982 *result_obj_list
= tmp
->next
;
1985 tmp
= *result_obj_list
;
1987 *result_obj_list
= NULL
;
1993 * FUNCTION: soft_keystore_get_single_obj
1996 * ks_handle: handle of the key store object to be accessed
1997 * lock_held: TRUE if the lock is held by caller.
2001 * NULL: if handle doesn't match any object
2003 * Otherwise, the object is returned in
2004 * the same structure used in soft_keystore_get_objs().
2005 * The structure need to be freed by the caller.
2009 * Retrieves the object specified by the object
2010 * handle to the caller.
2012 * If a private object is requested, and the caller
2013 * has not previously passed in the pin or if the pin
2014 * passed in is wrong, the requested private object will not
2017 * The buffer returned for the requested private object
2018 * is already decrypted.
2021 soft_keystore_get_single_obj(ks_obj_handle_t
*ks_handle
,
2022 ks_obj_t
**return_obj
, boolean_t lock_held
)
2026 uchar_t iv
[OBJ_IV_SIZE
], obj_hmac
[OBJ_HMAC_SIZE
];
2027 uchar_t
*buf
, *decrypted_buf
;
2030 CK_RV rv
= CKR_FUNCTION_FAILED
;
2032 if (!(ks_handle
->public)) {
2033 if ((enc_key
== NULL
) ||
2034 (enc_key
->magic_marker
!= SOFTTOKEN_OBJECT_MAGIC
)) {
2035 return (CKR_FUNCTION_FAILED
);
2039 if ((fd
= open_and_lock_object_file(ks_handle
, O_RDONLY
,
2041 return (CKR_FUNCTION_FAILED
);
2044 obj
= malloc(sizeof (ks_obj_t
));
2046 return (CKR_HOST_MEMORY
);
2051 (void) strcpy((char *)((obj
->ks_handle
).name
),
2052 (char *)ks_handle
->name
);
2053 (obj
->ks_handle
).public = ks_handle
->public;
2055 /* 1st get the version */
2056 if (readn_nointr(fd
, &(obj
->obj_version
), OBJ_VER_SIZE
)
2060 obj
->obj_version
= SWAP32(obj
->obj_version
);
2062 /* Then, read the IV */
2063 if (readn_nointr(fd
, iv
, OBJ_IV_SIZE
) != OBJ_IV_SIZE
) {
2067 /* Then, read the HMAC */
2068 if (readn_nointr(fd
, obj_hmac
, OBJ_HMAC_SIZE
) != OBJ_HMAC_SIZE
) {
2072 /* read the object */
2073 rv
= read_obj_data(fd
, (char **)&buf
, &nread
);
2078 if (ks_handle
->public) {
2084 CK_ULONG out_len
= 0, hmac_size
;
2086 /* verify HMAC of the object, make sure it matches */
2087 hmac_size
= OBJ_HMAC_SIZE
;
2088 if (soft_keystore_hmac(hmac_key
, B_FALSE
, buf
,
2089 nread
, obj_hmac
, &hmac_size
) != CKR_OK
) {
2091 rv
= CKR_FUNCTION_FAILED
;
2095 /* decrypt object */
2096 if (soft_keystore_crypt(enc_key
, iv
, B_FALSE
, buf
, nread
,
2097 NULL
, &out_len
) != CKR_OK
) {
2099 rv
= CKR_FUNCTION_FAILED
;
2103 decrypted_buf
= malloc(sizeof (uchar_t
) * out_len
);
2104 if (decrypted_buf
== NULL
) {
2106 rv
= CKR_HOST_MEMORY
;
2110 if (soft_keystore_crypt(enc_key
, iv
, B_FALSE
, buf
, nread
,
2111 decrypted_buf
, &out_len
) != CKR_OK
) {
2112 free(decrypted_buf
);
2114 rv
= CKR_FUNCTION_FAILED
;
2118 obj
->size
= out_len
- MAXPATHLEN
;
2121 * decrypted buf here actually contains full path name of
2122 * object plus the actual data. so, need to skip the
2124 * See prepare_data_for_encrypt() function in the file
2125 * to understand how and why the pathname is added.
2127 obj
->buf
= malloc(sizeof (uchar_t
) * (out_len
- MAXPATHLEN
));
2128 if (obj
->buf
== NULL
) {
2129 free(decrypted_buf
);
2131 rv
= CKR_HOST_MEMORY
;
2134 (void) memcpy(obj
->buf
, decrypted_buf
+ MAXPATHLEN
, obj
->size
);
2135 free(decrypted_buf
);
2146 /* unlock the file after reading */
2148 (void) lock_file(fd
, B_TRUE
, B_FALSE
);
2158 * FUNCTION: soft_keystore_put_new_obj
2161 * buf: buffer containing un-encrypted data
2162 * to be stored in keystore.
2163 * len: length of data
2164 * public: TRUE if it is a public object,
2165 * FALSE if it is private obj
2166 * lock_held: TRUE if the lock is held by caller.
2167 * keyhandle: pointer to object handle to
2168 * receive keyhandle for new object
2171 * 0: object successfully stored in file
2172 * -1: some error occurred, object is not stored in file.
2175 * This API is used to write a newly created token object
2178 * This function does the following:
2180 * 1) Creates a token object file based on "public" parameter.
2181 * 2) Generates a new IV and stores it in obj_meta_data_t if it is
2183 * 3) Set object version number to 1.
2184 * 4) If it is a private object, it will be encrypted before
2185 * being written to the newly created keystore token object
2187 * 5) Calculates the obj_chksum in obj_meta_data_t.
2188 * 6) Calculates the pin_chksum in obj_meta_data_t.
2189 * 7) Increments the keystore version number.
2192 soft_keystore_put_new_obj(uchar_t
*buf
, size_t len
, boolean_t
public,
2193 boolean_t lock_held
, ks_obj_handle_t
*keyhandle
)
2196 int fd
, tmp_ks_fd
, obj_fd
;
2197 unsigned int counter
, version
;
2198 uchar_t obj_hmac
[OBJ_HMAC_SIZE
];
2199 CK_BYTE iv
[OBJ_IV_SIZE
];
2200 char obj_name
[MAXPATHLEN
], tmp_ks_desc_name
[MAXPATHLEN
];
2201 char filebuf
[BUFSIZ
];
2202 char pub_obj_path
[MAXPATHLEN
], pri_obj_path
[MAXPATHLEN
],
2203 ks_desc_file
[MAXPATHLEN
];
2207 if (keyhandle
== NULL
) {
2211 /* if it is private object, make sure we have the key */
2213 if ((enc_key
== NULL
) ||
2214 (enc_key
->magic_marker
!= SOFTTOKEN_OBJECT_MAGIC
)) {
2219 /* open keystore, and set write lock */
2220 if ((fd
= open_and_lock_keystore_desc(O_RDWR
, B_FALSE
,
2225 (void) get_desc_file_path(ks_desc_file
);
2226 (void) get_tmp_desc_file_path(tmp_ks_desc_name
);
2229 * create a tempoary file for the keystore description
2230 * file for updating version and counter information
2232 tmp_ks_fd
= open_nointr(tmp_ks_desc_name
,
2233 O_RDWR
|O_CREAT
|O_EXCL
|O_NONBLOCK
, S_IRUSR
|S_IWUSR
);
2234 if (tmp_ks_fd
< 0) {
2239 /* read and write pkcs11 version */
2240 if (readn_nointr(fd
, filebuf
, KS_PKCS11_VER_SIZE
)
2241 != KS_PKCS11_VER_SIZE
) {
2245 if (writen_nointr(tmp_ks_fd
, filebuf
, KS_PKCS11_VER_SIZE
)
2246 != KS_PKCS11_VER_SIZE
) {
2250 /* get version number, and write updated number to temp file */
2251 if (readn_nointr(fd
, &version
, KS_VER_SIZE
) != KS_VER_SIZE
) {
2255 version
= SWAP32(version
);
2257 version
= SWAP32(version
);
2259 if (writen_nointr(tmp_ks_fd
, (void *)&version
,
2260 KS_VER_SIZE
) != KS_VER_SIZE
) {
2264 /* get object count value */
2265 if (readn_nointr(fd
, &counter
, KS_COUNTER_SIZE
) != KS_COUNTER_SIZE
) {
2268 counter
= SWAP32(counter
);
2270 bzero(obj_name
, sizeof (obj_name
));
2272 (void) snprintf(obj_name
, MAXPATHLEN
, "%s/%s%d",
2273 get_pub_obj_path(pub_obj_path
), OBJ_PREFIX
, counter
);
2275 (void) snprintf(obj_name
, MAXPATHLEN
, "%s/%s%d",
2276 get_pri_obj_path(pri_obj_path
), OBJ_PREFIX
, counter
);
2279 /* create object file */
2280 obj_fd
= open_nointr(obj_name
,
2281 O_WRONLY
|O_CREAT
|O_EXCL
|O_NONBLOCK
, S_IRUSR
|S_IWUSR
);
2283 /* can't create object file */
2287 /* lock object file for writing */
2288 if (lock_file(obj_fd
, B_FALSE
, B_TRUE
) != 0) {
2289 (void) close(obj_fd
);
2293 /* write object meta data */
2294 version
= SWAP32(1);
2295 if (writen_nointr(obj_fd
, (void *)&version
, sizeof (version
))
2296 != sizeof (version
)) {
2301 bzero(iv
, sizeof (iv
));
2303 /* generate an IV */
2304 if (soft_gen_iv(iv
) != CKR_OK
) {
2310 if (writen_nointr(obj_fd
, (void *)iv
, sizeof (iv
)) != sizeof (iv
)) {
2316 bzero(obj_hmac
, sizeof (obj_hmac
));
2317 if (writen_nointr(obj_fd
, (void *)obj_hmac
,
2318 sizeof (obj_hmac
)) != sizeof (obj_hmac
)) {
2322 if (writen_nointr(obj_fd
, (char *)buf
, len
) != len
) {
2328 uchar_t
*encrypted_buf
, *prepared_buf
;
2329 CK_ULONG out_len
= 0, prepared_len
;
2331 if (prepare_data_for_encrypt(obj_name
, buf
, len
,
2332 &prepared_buf
, &prepared_len
) != 0) {
2336 if (soft_keystore_crypt(enc_key
, iv
,
2337 B_TRUE
, prepared_buf
, prepared_len
,
2338 NULL
, &out_len
) != CKR_OK
) {
2343 encrypted_buf
= malloc(out_len
* sizeof (char));
2344 if (encrypted_buf
== NULL
) {
2349 if (soft_keystore_crypt(enc_key
, iv
,
2350 B_TRUE
, prepared_buf
, prepared_len
,
2351 encrypted_buf
, &out_len
) != CKR_OK
) {
2352 free(encrypted_buf
);
2358 /* calculate HMAC of encrypted object */
2359 hmac_size
= OBJ_HMAC_SIZE
;
2360 if (soft_keystore_hmac(hmac_key
, B_TRUE
, encrypted_buf
,
2361 out_len
, obj_hmac
, &hmac_size
) != CKR_OK
) {
2362 free(encrypted_buf
);
2366 if (hmac_size
!= OBJ_HMAC_SIZE
) {
2367 free(encrypted_buf
);
2372 if (writen_nointr(obj_fd
, (void *)obj_hmac
,
2373 sizeof (obj_hmac
)) != sizeof (obj_hmac
)) {
2374 free(encrypted_buf
);
2378 /* write encrypted object */
2379 if (writen_nointr(obj_fd
, (void *)encrypted_buf
, out_len
)
2381 free(encrypted_buf
);
2385 free(encrypted_buf
);
2389 (void) close(obj_fd
);
2390 (void) snprintf((char *)keyhandle
->name
, sizeof (keyhandle
->name
),
2392 keyhandle
->public = public;
2395 * store new counter to temp keystore description file.
2398 counter
= SWAP32(counter
);
2399 if (writen_nointr(tmp_ks_fd
, (void *)&counter
,
2400 sizeof (counter
)) != sizeof (counter
)) {
2404 /* read rest of keystore description file and store into temp file */
2405 nread
= readn_nointr(fd
, filebuf
, sizeof (filebuf
));
2407 if (writen_nointr(tmp_ks_fd
, filebuf
, nread
) != nread
) {
2410 nread
= readn_nointr(fd
, filebuf
, sizeof (filebuf
));
2413 (void) close(tmp_ks_fd
);
2414 (void) rename(tmp_ks_desc_name
, ks_desc_file
);
2417 /* release lock on description file */
2418 if (lock_file(fd
, B_FALSE
, B_FALSE
) != 0) {
2428 /* remove object file. No need to remove lock first */
2429 (void) unlink(obj_name
);
2433 (void) close(tmp_ks_fd
);
2434 (void) remove(tmp_ks_desc_name
);
2436 /* release lock on description file */
2437 (void) lock_file(fd
, B_FALSE
, B_FALSE
);
2445 * FUNCTION: soft_keystore_modify_obj
2448 * ks_handle: handle of the key store object to be modified
2449 * buf: buffer containing un-encrypted data
2450 * to be modified in keystore.
2451 * len: length of data
2452 * lock_held: TRUE if the lock is held by caller.
2455 * -1: if any error occurred.
2456 * Otherwise, 0 is returned.
2460 * This API is used to write a modified token object back
2461 * to keystore. This function will do the following:
2463 * 1) If it is a private object, it will be encrypted before
2464 * being written to the corresponding keystore token
2466 * 2) Record incremented object version number.
2467 * 3) Record incremented keystore version number.
2470 soft_keystore_modify_obj(ks_obj_handle_t
*ks_handle
, uchar_t
*buf
,
2471 size_t len
, boolean_t lock_held
)
2473 int fd
, ks_fd
, tmp_fd
, version
;
2474 char orig_name
[MAXPATHLEN
], tmp_name
[MAXPATHLEN
],
2475 tmp_ks_name
[MAXPATHLEN
];
2476 uchar_t iv
[OBJ_IV_SIZE
], obj_hmac
[OBJ_HMAC_SIZE
];
2477 char pub_obj_path
[MAXPATHLEN
], pri_obj_path
[MAXPATHLEN
],
2478 ks_desc_file
[MAXPATHLEN
];
2481 /* if it is private object, make sure we have the key */
2482 if (!(ks_handle
->public)) {
2483 if ((enc_key
== NULL
) ||
2484 (enc_key
->magic_marker
!= SOFTTOKEN_OBJECT_MAGIC
)) {
2489 /* open and lock keystore description file */
2490 if ((ks_fd
= open_and_lock_keystore_desc(O_RDWR
, B_FALSE
,
2495 (void) get_desc_file_path(ks_desc_file
);
2497 /* update the version of for keystore file in tempoary file */
2498 (void) get_tmp_desc_file_path(tmp_ks_name
);
2499 if (create_updated_keystore_version(ks_fd
, tmp_ks_name
) != 0) {
2500 /* unlock keystore description file */
2501 (void) lock_file(ks_fd
, B_FALSE
, B_FALSE
);
2502 (void) close(ks_fd
);
2506 /* open object file */
2507 if ((fd
= open_and_lock_object_file(ks_handle
, O_RDWR
,
2513 * make the change in a temporary file. Create the temp
2514 * file in the same directory as the token object. That
2515 * way, the "rename" later will be an atomic operation
2517 if (ks_handle
->public) {
2518 (void) snprintf(orig_name
, MAXPATHLEN
, "%s/%s",
2519 get_pub_obj_path(pub_obj_path
), ks_handle
->name
);
2520 (void) snprintf(tmp_name
, MAXPATHLEN
, "%s/%s%s",
2521 pub_obj_path
, TMP_OBJ_PREFIX
,
2522 (ks_handle
->name
) + OBJ_PREFIX_LEN
);
2524 (void) snprintf(orig_name
, MAXPATHLEN
, "%s/%s",
2525 get_pri_obj_path(pri_obj_path
), ks_handle
->name
);
2526 (void) snprintf(tmp_name
, MAXPATHLEN
, "%s/%s%s",
2527 pri_obj_path
, TMP_OBJ_PREFIX
,
2528 (ks_handle
->name
) + OBJ_PREFIX_LEN
);
2531 tmp_fd
= open_nointr(tmp_name
,
2532 O_WRONLY
|O_CREAT
|O_EXCL
|O_NONBLOCK
, S_IRUSR
|S_IWUSR
);
2534 /* can't create tmp object file */
2538 /* read version, increment, and write to tmp file */
2539 if (readn_nointr(fd
, (char *)&version
, OBJ_VER_SIZE
) != OBJ_VER_SIZE
) {
2543 version
= SWAP32(version
);
2545 version
= SWAP32(version
);
2547 if (writen_nointr(tmp_fd
, (char *)&version
, OBJ_VER_SIZE
)
2552 /* generate a new IV for the object, old one can be ignored */
2553 if (soft_gen_iv(iv
) != CKR_OK
) {
2557 if (writen_nointr(tmp_fd
, (char *)iv
, OBJ_IV_SIZE
) != OBJ_IV_SIZE
) {
2561 if (ks_handle
->public) {
2563 /* hmac is always NULL for public objects */
2564 bzero(obj_hmac
, sizeof (obj_hmac
));
2565 if (writen_nointr(tmp_fd
, (char *)obj_hmac
, OBJ_HMAC_SIZE
)
2570 /* write updated object */
2571 if (writen_nointr(tmp_fd
, (char *)buf
, len
) != len
) {
2577 uchar_t
*encrypted_buf
, *prepared_buf
;
2578 CK_ULONG out_len
= 0, prepared_len
;
2580 if (prepare_data_for_encrypt(orig_name
, buf
, len
,
2581 &prepared_buf
, &prepared_len
) != 0) {
2585 /* encrypt the data */
2586 if (soft_keystore_crypt(enc_key
, iv
, B_TRUE
, prepared_buf
,
2587 prepared_len
, NULL
, &out_len
) != CKR_OK
) {
2592 encrypted_buf
= malloc(out_len
* sizeof (char));
2593 if (encrypted_buf
== NULL
) {
2598 if (soft_keystore_crypt(enc_key
, iv
, B_TRUE
, prepared_buf
,
2599 prepared_len
, encrypted_buf
, &out_len
) != CKR_OK
) {
2600 free(encrypted_buf
);
2607 /* calculate hmac on encrypted buf */
2608 hmac_size
= OBJ_HMAC_SIZE
;
2609 if (soft_keystore_hmac(hmac_key
, B_TRUE
, encrypted_buf
,
2610 out_len
, obj_hmac
, &hmac_size
) != CKR_OK
) {
2611 free(encrypted_buf
);
2615 if (hmac_size
!= OBJ_HMAC_SIZE
) {
2616 free(encrypted_buf
);
2620 if (writen_nointr(tmp_fd
, (char *)obj_hmac
, OBJ_HMAC_SIZE
)
2622 free(encrypted_buf
);
2626 if (writen_nointr(tmp_fd
, (void *)encrypted_buf
, out_len
)
2628 free(encrypted_buf
);
2631 free(encrypted_buf
);
2633 (void) close(tmp_fd
);
2635 /* rename updated temporary object file */
2636 if (rename(tmp_name
, orig_name
) != 0) {
2637 (void) unlink(tmp_name
);
2641 /* rename updated keystore description file */
2642 if (rename(tmp_ks_name
, ks_desc_file
) != 0) {
2643 (void) unlink(tmp_name
);
2644 (void) unlink(tmp_ks_name
);
2648 /* determine need to unlock file or not */
2650 if (lock_file(fd
, B_FALSE
, B_FALSE
) < 0) {
2652 (void) unlink(tmp_name
);
2657 /* unlock keystore description file */
2658 if (lock_file(ks_fd
, B_FALSE
, B_FALSE
) != 0) {
2659 (void) close(ks_fd
);
2664 (void) close(ks_fd
);
2668 return (0); /* All operations completed successfully */
2671 (void) close(tmp_fd
);
2672 (void) remove(tmp_name
);
2678 /* unlock keystore description file */
2679 (void) lock_file(ks_fd
, B_FALSE
, B_FALSE
);
2680 (void) close(ks_fd
);
2681 (void) remove(tmp_ks_name
);
2686 * FUNCTION: soft_keystore_del_obj
2689 * ks_handle: handle of the key store object to be deleted
2690 * lock_held: TRUE if the lock is held by caller.
2693 * -1: if any error occurred.
2694 * 0: object successfully deleted from keystore.
2697 * This API is used to delete a particular token object from
2698 * the keystore. The corresponding token object file will be
2699 * removed from the file system.
2700 * Any future reference to the deleted file will
2701 * return an CKR_OBJECT_HANDLE_INVALID error.
2704 soft_keystore_del_obj(ks_obj_handle_t
*ks_handle
, boolean_t lock_held
)
2706 char objname
[MAXPATHLEN
], tmp_ks_name
[MAXPATHLEN
];
2708 char pub_obj_path
[MAXPATHLEN
], pri_obj_path
[MAXPATHLEN
],
2709 ks_desc_file
[MAXPATHLEN
];
2713 if ((fd
= open_and_lock_keystore_desc(O_RDWR
, B_FALSE
,
2718 (void) get_desc_file_path(ks_desc_file
);
2719 (void) get_tmp_desc_file_path(tmp_ks_name
);
2720 if (create_updated_keystore_version(fd
, tmp_ks_name
) != 0) {
2724 if (ks_handle
->public) {
2725 (void) snprintf(objname
, MAXPATHLEN
, "%s/%s",
2726 get_pub_obj_path(pub_obj_path
), ks_handle
->name
);
2728 (void) snprintf(objname
, MAXPATHLEN
, "%s/%s",
2729 get_pri_obj_path(pri_obj_path
), ks_handle
->name
);
2733 * make sure no other process is reading/writing the file
2734 * by acquiring the lock on the file
2736 if ((obj_fd
= open_and_lock_object_file(ks_handle
, O_WRONLY
,
2741 if (unlink(objname
) != 0) {
2742 (void) lock_file(obj_fd
, B_FALSE
, B_FALSE
);
2743 (void) close(obj_fd
);
2747 (void) lock_file(obj_fd
, B_FALSE
, B_FALSE
);
2748 (void) close(obj_fd
);
2750 if (rename(tmp_ks_name
, ks_desc_file
) != 0) {
2756 /* unlock keystore description file */
2758 if (lock_file(fd
, B_FALSE
, B_FALSE
) != 0) {
2769 * Get the salt used for generating hashed pin from the
2770 * keystore description file.
2772 * The result will be stored in the provided buffer "salt" passed
2773 * in as an argument.
2775 * Return 0 if no error, return -1 if there's any error.
2778 soft_keystore_get_pin_salt(char **salt
)
2780 int fd
, ret_val
= -1;
2781 uint64_t hashed_pin_salt_size
;
2783 if ((fd
= open_and_lock_keystore_desc(O_RDONLY
, B_FALSE
,
2788 if (lseek(fd
, KS_HASHED_PIN_SALT_LEN_OFFSET
, SEEK_SET
)
2789 != KS_HASHED_PIN_SALT_LEN_OFFSET
) {
2793 if (readn_nointr(fd
, (char *)&hashed_pin_salt_size
,
2794 KS_HASHED_PIN_SALT_LEN_SIZE
) != KS_HASHED_PIN_SALT_LEN_SIZE
) {
2797 hashed_pin_salt_size
= SWAP64(hashed_pin_salt_size
);
2799 *salt
= malloc(hashed_pin_salt_size
+ 1);
2800 if (*salt
== NULL
) {
2804 if ((readn_nointr(fd
, *salt
, hashed_pin_salt_size
))
2805 != (ssize_t
)hashed_pin_salt_size
) {
2809 (*salt
)[hashed_pin_salt_size
] = '\0';
2814 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
2823 * FUNCTION: soft_keystore_pin_initialized
2826 * initialized: This value will be set to true if keystore is
2827 * initialized, and false otherwise.
2828 * hashed_pin: If the keystore is initialized, this will contain
2829 * the hashed pin. It will be NULL if the keystore
2830 * pin is not initialized. Memory allocated
2831 * for the hashed pin needs to be freed by
2833 * lock_held: TRUE if the lock is held by caller.
2837 * any other appropriate CKR_value
2840 * This API is used to determine if the PIN in the keystore
2841 * has been initialized or not.
2842 * It makes the determination using the salt for generating the
2843 * encryption key. The salt is stored in the keystore
2844 * descryption file. The salt should be all zero if
2845 * the keystore pin has not been initialized.
2846 * If the pin has been initialized, it is returned in the
2847 * hashed_pin argument.
2850 soft_keystore_pin_initialized(boolean_t
*initialized
, char **hashed_pin
,
2851 boolean_t lock_held
)
2854 CK_BYTE crypt_salt
[KS_KEY_SALT_SIZE
], tmp_buf
[KS_KEY_SALT_SIZE
];
2855 CK_RV ret_val
= CKR_OK
;
2857 if ((fd
= open_and_lock_keystore_desc(O_RDONLY
, B_FALSE
,
2859 return (CKR_FUNCTION_FAILED
);
2862 if (lseek(fd
, KS_KEY_SALT_OFFSET
, SEEK_SET
) != KS_KEY_SALT_OFFSET
) {
2863 ret_val
= CKR_FUNCTION_FAILED
;
2867 if (readn_nointr(fd
, (char *)crypt_salt
, KS_KEY_SALT_SIZE
)
2868 != KS_KEY_SALT_SIZE
) {
2869 ret_val
= CKR_FUNCTION_FAILED
;
2873 (void) bzero(tmp_buf
, KS_KEY_SALT_SIZE
);
2875 if (memcmp(crypt_salt
, tmp_buf
, KS_KEY_SALT_SIZE
) == 0) {
2876 *initialized
= B_FALSE
;
2879 *initialized
= B_TRUE
;
2880 ret_val
= get_hashed_pin(fd
, hashed_pin
);
2886 if (lock_file(fd
, B_TRUE
, B_FALSE
) < 0) {
2887 ret_val
= CKR_FUNCTION_FAILED
;
2896 * This checks if the keystore file exists
2900 soft_keystore_exists()
2903 struct stat fn_stat
;
2904 char *fname
, ks_desc_file
[MAXPATHLEN
];
2906 fname
= get_desc_file_path(ks_desc_file
);
2907 ret
= stat(fname
, &fn_stat
);
2914 * FUNCTION: soft_keystore_init
2917 * desired_state: The keystore state the caller would like
2921 * Returns the state the function is in. If it succeeded, it
2922 * will be the same as the desired, if not it will be
2923 * KEYSTORE_UNAVAILABLE.
2926 * This function will only load as much keystore data as is
2927 * requested at that time. This is for performace by delaying the
2928 * reading of token objects until they are needed or never at
2929 * all if they are not used.
2931 * Primary use is from C_InitToken().
2932 * It is also called by soft_keystore_status() when the
2933 * "desired_state" is not the the current load state of keystore.
2937 soft_keystore_init(int desired_state
)
2941 (void) pthread_mutex_lock(&soft_slot
.keystore_mutex
);
2944 * If more than one session tries to initialize the keystore, the
2945 * second and other following sessions that were waiting for the lock
2946 * will quickly exit if their requirements are satisfied.
2948 if (desired_state
<= soft_slot
.keystore_load_status
) {
2949 (void) pthread_mutex_unlock(&soft_slot
.keystore_mutex
);
2950 return (soft_slot
.keystore_load_status
);
2954 * With 'keystore_load_status' giving the current state of the
2955 * process, this switch will bring it up to the desired state if
2959 switch (soft_slot
.keystore_load_status
) {
2960 case KEYSTORE_UNINITIALIZED
:
2961 ret
= soft_keystore_exists();
2963 soft_slot
.keystore_load_status
= KEYSTORE_PRESENT
;
2964 else if (ret
== ENOENT
)
2965 if (create_keystore() == 0)
2966 soft_slot
.keystore_load_status
=
2969 soft_slot
.keystore_load_status
=
2970 KEYSTORE_UNAVAILABLE
;
2971 cryptoerror(LOG_DEBUG
,
2972 "pkcs11_softtoken: "
2973 "Cannot create keystore.");
2977 if (desired_state
<= KEYSTORE_PRESENT
)
2981 case KEYSTORE_PRESENT
:
2982 if (soft_keystore_get_version(&soft_slot
.ks_version
, B_FALSE
)
2984 soft_slot
.keystore_load_status
= KEYSTORE_UNAVAILABLE
;
2985 cryptoerror(LOG_DEBUG
,
2986 "pkcs11_softtoken: Keystore access failed.");
2990 soft_slot
.keystore_load_status
= KEYSTORE_LOAD
;
2991 if (desired_state
<= KEYSTORE_LOAD
)
2996 /* Load all the public token objects from keystore */
2997 if (soft_get_token_objects_from_keystore(PUB_TOKENOBJS
)
2999 (void) soft_destroy_token_session();
3000 soft_slot
.keystore_load_status
= KEYSTORE_UNAVAILABLE
;
3001 cryptoerror(LOG_DEBUG
,
3002 "pkcs11_softtoken: Cannot initialize keystore.");
3006 soft_slot
.keystore_load_status
= KEYSTORE_INITIALIZED
;
3009 (void) pthread_mutex_unlock(&soft_slot
.keystore_mutex
);
3010 return (soft_slot
.keystore_load_status
);
3014 * FUNCTION: soft_keystore_status
3017 * desired_state: The keystore state the caller would like
3021 * B_TRUE if keystore is ready and at the desired state.
3022 * B_FALSE if keystore had an error and is not available.
3025 * The calling function wants to make sure the keystore load
3026 * status to in a state it requires. If it is not at that
3027 * state it will call the load function.
3028 * If keystore is at the desired state or has just been
3029 * loaded to that state, it will return TRUE. If there has been
3030 * load failure, it will return FALSE.
3034 soft_keystore_status(int desired_state
)
3037 if (soft_slot
.keystore_load_status
== KEYSTORE_UNAVAILABLE
)
3040 return ((desired_state
<= soft_slot
.keystore_load_status
) ||
3041 (soft_keystore_init(desired_state
) == desired_state
));