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