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