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