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 /* 1185 * Generate a 16-byte Initialization Vector (IV). 1186 */ 1187 CK_RV 1188 soft_gen_iv(CK_BYTE *iv) 1189 { 1190 return (pkcs11_get_nzero_urandom(iv, 16) < 0 ? 1191 CKR_DEVICE_ERROR : CKR_OK); 1192 } 1193 1194 1195 /* 1196 * This function reads all the data until the end of the file, and 1197 * put the data into the "buf" in argument. Memory for buf will 1198 * be allocated in this function. It is the caller's responsibility 1199 * to free it. The number of bytes read will be returned 1200 * in the argument "bytes_read" 1201 * 1202 * returns CKR_OK if no error. Other CKR error codes if there's an error 1203 */ 1204 static CK_RV 1205 read_obj_data(int old_fd, char **buf, ssize_t *bytes_read) 1206 { 1207 1208 ssize_t nread, loop_count; 1209 char *buf1 = NULL; 1210 1211 *buf = malloc(BUFSIZ); 1212 if (*buf == NULL) { 1213 return (CKR_HOST_MEMORY); 1214 } 1215 1216 nread = readn_nointr(old_fd, *buf, BUFSIZ); 1217 if (nread < 0) { 1218 free(*buf); 1219 return (CKR_FUNCTION_FAILED); 1220 } 1221 loop_count = 1; 1222 while (nread == (loop_count * BUFSIZ)) { 1223 ssize_t nread_tmp; 1224 1225 loop_count++; 1226 /* more than BUFSIZ of data */ 1227 buf1 = realloc(*buf, loop_count * BUFSIZ); 1228 if (buf1 == NULL) { 1229 free(*buf); 1230 return (CKR_HOST_MEMORY); 1231 } 1232 *buf = buf1; 1233 nread_tmp = readn_nointr(old_fd, 1234 *buf + ((loop_count - 1) * BUFSIZ), BUFSIZ); 1235 if (nread_tmp < 0) { 1236 free(*buf); 1237 return (CKR_FUNCTION_FAILED); 1238 } 1239 nread += nread_tmp; 1240 } 1241 *bytes_read = nread; 1242 return (CKR_OK); 1243 } 1244 1245 /* 1246 * Re-encrypt an object using the provided new_enc_key. The new HMAC 1247 * is calculated using the new_hmac_key. The global static variables 1248 * enc_key, and hmac_key will be used for decrypting the original 1249 * object, and verifying its signature. 1250 * 1251 * The re-encrypted object will be stored in the file named 1252 * in the "new_obj_name" variable. The content of the "original" 1253 * file named in "orig_obj_name" is not disturbed. 1254 * 1255 * Returns 0 if there's no error, returns -1 otherwise. 1256 * 1257 */ 1258 static int 1259 reencrypt_obj(soft_object_t *new_enc_key, soft_object_t *new_hmac_key, 1260 char *orig_obj_name, char *new_obj_name) { 1261 1262 int old_fd, new_fd, version, ret_val = -1; 1263 CK_BYTE iv[OBJ_IV_SIZE], old_iv[OBJ_IV_SIZE]; 1264 ssize_t nread; 1265 CK_ULONG decrypted_len, encrypted_len, hmac_len; 1266 CK_BYTE hmac[OBJ_HMAC_SIZE], *decrypted_buf = NULL, *buf = NULL; 1267 1268 old_fd = open_nointr(orig_obj_name, O_RDONLY|O_NONBLOCK); 1269 if (old_fd < 0) { 1270 return (-1); 1271 } 1272 1273 if (acquire_file_lock(&old_fd, orig_obj_name, O_RDONLY) != 0) { 1274 if (old_fd > 0) { 1275 (void) close(old_fd); 1276 } 1277 return (-1); 1278 } 1279 1280 new_fd = open_nointr(new_obj_name, 1281 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 1282 if (new_fd < 0) { 1283 (void) close(old_fd); 1284 return (-1); 1285 } 1286 1287 if (lock_file(new_fd, B_FALSE, B_TRUE) != 0) { 1288 /* unlock old file */ 1289 (void) lock_file(old_fd, B_TRUE, B_FALSE); 1290 (void) close(old_fd); 1291 (void) close(new_fd); 1292 return (-1); 1293 } 1294 1295 /* read version, increment, and write to tmp file */ 1296 if (readn_nointr(old_fd, (char *)&version, OBJ_VER_SIZE) 1297 != OBJ_VER_SIZE) { 1298 goto cleanup; 1299 } 1300 1301 version = SWAP32(version); 1302 version++; 1303 version = SWAP32(version); 1304 1305 if (writen_nointr(new_fd, (char *)&version, OBJ_VER_SIZE) 1306 != OBJ_VER_SIZE) { 1307 goto cleanup; 1308 } 1309 1310 /* read old iv */ 1311 if (readn_nointr(old_fd, (char *)old_iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 1312 goto cleanup; 1313 } 1314 1315 /* generate new IV */ 1316 if (soft_gen_iv(iv) != CKR_OK) { 1317 goto cleanup; 1318 } 1319 1320 if (writen_nointr(new_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 1321 goto cleanup; 1322 } 1323 1324 /* seek to the original encrypted data, and read all of them */ 1325 if (lseek(old_fd, OBJ_DATA_OFFSET, SEEK_SET) != OBJ_DATA_OFFSET) { 1326 goto cleanup; 1327 } 1328 1329 if (read_obj_data(old_fd, (char **)&buf, &nread) != CKR_OK) { 1330 goto cleanup; 1331 } 1332 1333 /* decrypt data using old key */ 1334 decrypted_len = 0; 1335 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread, 1336 NULL, &decrypted_len) != CKR_OK) { 1337 free(buf); 1338 goto cleanup; 1339 } 1340 1341 decrypted_buf = malloc(decrypted_len); 1342 if (decrypted_buf == NULL) { 1343 free(buf); 1344 goto cleanup; 1345 } 1346 1347 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread, 1348 decrypted_buf, &decrypted_len) != CKR_OK) { 1349 free(buf); 1350 free(decrypted_buf); 1351 goto cleanup; 1352 } 1353 1354 free(buf); 1355 1356 /* re-encrypt with new key */ 1357 encrypted_len = 0; 1358 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf, 1359 decrypted_len, NULL, &encrypted_len) != CKR_OK) { 1360 free(decrypted_buf); 1361 goto cleanup; 1362 } 1363 1364 buf = malloc(encrypted_len); 1365 if (buf == NULL) { 1366 free(decrypted_buf); 1367 goto cleanup; 1368 } 1369 1370 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf, 1371 decrypted_len, buf, &encrypted_len) != CKR_OK) { 1372 free(buf); 1373 free(decrypted_buf); 1374 goto cleanup; 1375 } 1376 1377 free(decrypted_buf); 1378 1379 /* calculate hmac on re-encrypted data using new hmac key */ 1380 hmac_len = OBJ_HMAC_SIZE; 1381 if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf, 1382 encrypted_len, hmac, &hmac_len) != CKR_OK) { 1383 free(buf); 1384 goto cleanup; 1385 } 1386 1387 /* just for sanity check */ 1388 if (hmac_len != OBJ_HMAC_SIZE) { 1389 free(buf); 1390 goto cleanup; 1391 } 1392 1393 /* write new hmac */ 1394 if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE) 1395 != OBJ_HMAC_SIZE) { 1396 free(buf); 1397 goto cleanup; 1398 } 1399 1400 /* write re-encrypted buffer to temp file */ 1401 if (writen_nointr(new_fd, (void *)buf, encrypted_len) 1402 != encrypted_len) { 1403 free(buf); 1404 goto cleanup; 1405 } 1406 free(buf); 1407 ret_val = 0; 1408 1409 cleanup: 1410 /* unlock the files */ 1411 (void) lock_file(old_fd, B_TRUE, B_FALSE); 1412 (void) lock_file(new_fd, B_FALSE, B_FALSE); 1413 1414 (void) close(old_fd); 1415 (void) close(new_fd); 1416 if (ret_val != 0) { 1417 (void) remove(new_obj_name); 1418 } 1419 return (ret_val); 1420 } 1421 1422 /* 1423 * FUNCTION: soft_keystore_setpin 1424 * 1425 * ARGUMENTS: 1426 * newpin: new pin entered by the user. 1427 * lock_held: TRUE if the lock is held by caller. 1428 * 1429 * RETURN VALUE: 1430 * 0: no error 1431 * -1: failure 1432 * 1433 * DESCRIPTION: 1434 * 1435 * This function does the following: 1436 * 1437 * 1) Generates crypted value of newpin and store it 1438 * in keystore description file. 1439 * 2) Dervies the new encryption key from the newpin. This key 1440 * will be used to re-encrypt the private token objects. 1441 * 3) Re-encrypt all of this user's existing private token 1442 * objects (if any). 1443 * 4) Increments the keystore version number. 1444 */ 1445 int 1446 soft_keystore_setpin(uchar_t *oldpin, uchar_t *newpin, boolean_t lock_held) 1447 { 1448 int fd, tmp_ks_fd, version, ret_val = -1; 1449 soft_object_t *new_crypt_key = NULL, *new_hmac_key = NULL; 1450 char filebuf[BUFSIZ]; 1451 DIR *pri_dirp; 1452 struct dirent *pri_ent; 1453 char pri_obj_path[MAXPATHLEN], ks_desc_file[MAXPATHLEN], 1454 tmp_ks_desc_name[MAXPATHLEN]; 1455 typedef struct priobjs { 1456 char orig_name[MAXPATHLEN]; 1457 char tmp_name[MAXPATHLEN]; 1458 struct priobjs *next; 1459 } priobjs_t; 1460 priobjs_t *pri_objs = NULL, *tmp; 1461 CK_BYTE *crypt_salt = NULL, *hmac_salt = NULL; 1462 boolean_t pin_never_set = B_FALSE, user_logged_in; 1463 char *new_hashed_pin = NULL; 1464 uint64_t hashed_pin_salt_length, new_hashed_pin_len, swaped_val; 1465 char *hashed_pin_salt = NULL; 1466 priobjs_t *obj; 1467 1468 if ((enc_key == NULL) || 1469 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 1470 user_logged_in = B_FALSE; 1471 } else { 1472 user_logged_in = B_TRUE; 1473 } 1474 1475 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 1476 lock_held)) < 0) { 1477 return (-1); 1478 } 1479 1480 (void) get_desc_file_path(ks_desc_file); 1481 (void) get_tmp_desc_file_path(tmp_ks_desc_name); 1482 1483 /* 1484 * create a tempoary file for the keystore description 1485 * file for updating version and counter information 1486 */ 1487 tmp_ks_fd = open_nointr(tmp_ks_desc_name, 1488 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 1489 if (tmp_ks_fd < 0) { 1490 (void) close(fd); 1491 return (-1); 1492 } 1493 1494 /* read and write PKCS version to temp file */ 1495 if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE) 1496 != KS_PKCS11_VER_SIZE) { 1497 goto cleanup; 1498 } 1499 1500 if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE) 1501 != KS_PKCS11_VER_SIZE) { 1502 goto cleanup; 1503 } 1504 1505 /* get version number, and write updated number to temp file */ 1506 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 1507 goto cleanup; 1508 } 1509 1510 version = SWAP32(version); 1511 version++; 1512 version = SWAP32(version); 1513 1514 if (writen_nointr(tmp_ks_fd, (void *)&version, KS_VER_SIZE) 1515 != KS_VER_SIZE) { 1516 goto cleanup; 1517 } 1518 1519 1520 /* read and write counter, no modification necessary */ 1521 if (readn_nointr(fd, filebuf, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) { 1522 goto cleanup; 1523 } 1524 1525 if (writen_nointr(tmp_ks_fd, filebuf, KS_COUNTER_SIZE) 1526 != KS_COUNTER_SIZE) { 1527 goto cleanup; 1528 } 1529 1530 /* read old encryption salt */ 1531 crypt_salt = malloc(KS_KEY_SALT_SIZE); 1532 if (crypt_salt == NULL) { 1533 goto cleanup; 1534 } 1535 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 1536 != KS_KEY_SALT_SIZE) { 1537 goto cleanup; 1538 } 1539 1540 /* read old hmac salt */ 1541 hmac_salt = malloc(KS_HMAC_SALT_SIZE); 1542 if (hmac_salt == NULL) { 1543 goto cleanup; 1544 } 1545 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE) 1546 != KS_HMAC_SALT_SIZE) { 1547 goto cleanup; 1548 } 1549 1550 /* just create some empty bytes */ 1551 bzero(filebuf, sizeof (filebuf)); 1552 1553 if (memcmp(crypt_salt, filebuf, KS_KEY_SALT_SIZE) == 0) { 1554 /* PIN as never been set */ 1555 CK_BYTE *new_crypt_salt = NULL, *new_hmac_salt = NULL; 1556 1557 pin_never_set = B_TRUE; 1558 if (soft_gen_crypt_key(newpin, &new_crypt_key, &new_crypt_salt) 1559 != CKR_OK) { 1560 goto cleanup; 1561 } 1562 if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt, 1563 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) { 1564 free(new_crypt_salt); 1565 (void) soft_cleanup_object(new_crypt_key); 1566 goto cleanup; 1567 } 1568 free(new_crypt_salt); 1569 1570 if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt) 1571 != CKR_OK) { 1572 (void) soft_cleanup_object(new_crypt_key); 1573 goto cleanup; 1574 } 1575 if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt, 1576 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) { 1577 free(new_hmac_salt); 1578 goto cleanup3; 1579 } 1580 free(new_hmac_salt); 1581 } else { 1582 if (soft_gen_crypt_key(newpin, &new_crypt_key, 1583 (CK_BYTE **)&crypt_salt) != CKR_OK) { 1584 goto cleanup; 1585 } 1586 /* no change to the encryption salt */ 1587 if (writen_nointr(tmp_ks_fd, (void *)crypt_salt, 1588 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) { 1589 (void) soft_cleanup_object(new_crypt_key); 1590 goto cleanup; 1591 } 1592 1593 if (soft_gen_hmac_key(newpin, &new_hmac_key, 1594 (CK_BYTE **)&hmac_salt) != CKR_OK) { 1595 (void) soft_cleanup_object(new_crypt_key); 1596 goto cleanup; 1597 } 1598 1599 /* no change to the hmac salt */ 1600 if (writen_nointr(tmp_ks_fd, (void *)hmac_salt, 1601 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) { 1602 goto cleanup3; 1603 } 1604 } 1605 1606 /* 1607 * read hashed pin salt, and write to updated keystore description 1608 * file unmodified. 1609 */ 1610 if (readn_nointr(fd, (char *)&hashed_pin_salt_length, 1611 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 1612 goto cleanup3; 1613 } 1614 1615 if (writen_nointr(tmp_ks_fd, (void *)&hashed_pin_salt_length, 1616 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 1617 goto cleanup3; 1618 } 1619 1620 hashed_pin_salt_length = SWAP64(hashed_pin_salt_length); 1621 1622 hashed_pin_salt = malloc(hashed_pin_salt_length + 1); 1623 if (hashed_pin_salt == NULL) { 1624 goto cleanup3; 1625 } 1626 1627 if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) != 1628 (ssize_t)hashed_pin_salt_length) { 1629 free(hashed_pin_salt); 1630 goto cleanup3; 1631 } 1632 1633 if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length)) 1634 != (ssize_t)hashed_pin_salt_length) { 1635 free(hashed_pin_salt); 1636 goto cleanup3; 1637 } 1638 1639 hashed_pin_salt[hashed_pin_salt_length] = '\0'; 1640 1641 /* old hashed pin length and value can be ignored, generate new one */ 1642 if (soft_gen_hashed_pin(newpin, &new_hashed_pin, 1643 &hashed_pin_salt) < 0) { 1644 free(hashed_pin_salt); 1645 goto cleanup3; 1646 } 1647 1648 free(hashed_pin_salt); 1649 1650 if (new_hashed_pin == NULL) { 1651 goto cleanup3; 1652 } 1653 1654 new_hashed_pin_len = strlen(new_hashed_pin); 1655 1656 /* write new hashed pin length to file */ 1657 swaped_val = SWAP64(new_hashed_pin_len); 1658 if (writen_nointr(tmp_ks_fd, (void *)&swaped_val, 1659 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) { 1660 goto cleanup3; 1661 } 1662 1663 if (writen_nointr(tmp_ks_fd, (void *)new_hashed_pin, 1664 new_hashed_pin_len) != (ssize_t)new_hashed_pin_len) { 1665 goto cleanup3; 1666 } 1667 1668 if (pin_never_set) { 1669 /* there was no private object, no need to re-encrypt them */ 1670 goto rename_desc_file; 1671 } 1672 1673 /* re-encrypt all the private objects */ 1674 pri_dirp = opendir(get_pri_obj_path(pri_obj_path)); 1675 if (pri_dirp == NULL) { 1676 /* 1677 * this directory should exist, even if it doesn't contain 1678 * any objects. Don't want to update the pin if the 1679 * keystore is somehow messed up. 1680 */ 1681 1682 goto cleanup3; 1683 } 1684 1685 /* if user did not login, need to set the old pin */ 1686 if (!user_logged_in) { 1687 if (soft_keystore_authpin(oldpin) != 0) { 1688 goto cleanup3; 1689 } 1690 } 1691 1692 while ((pri_ent = readdir(pri_dirp)) != NULL) { 1693 1694 if ((strcmp(pri_ent->d_name, ".") == 0) || 1695 (strcmp(pri_ent->d_name, "..") == 0) || 1696 (strncmp(pri_ent->d_name, TMP_OBJ_PREFIX, 1697 strlen(TMP_OBJ_PREFIX)) == 0)) { 1698 continue; 1699 } 1700 1701 obj = malloc(sizeof (priobjs_t)); 1702 if (obj == NULL) { 1703 goto cleanup2; 1704 } 1705 (void) snprintf(obj->orig_name, MAXPATHLEN, 1706 "%s/%s", pri_obj_path, pri_ent->d_name); 1707 (void) snprintf(obj->tmp_name, MAXPATHLEN, "%s/%s%s", 1708 pri_obj_path, TMP_OBJ_PREFIX, 1709 (pri_ent->d_name) + strlen(OBJ_PREFIX)); 1710 if (reencrypt_obj(new_crypt_key, new_hmac_key, 1711 obj->orig_name, obj->tmp_name) != 0) { 1712 free(obj); 1713 goto cleanup2; 1714 } 1715 1716 /* insert into list of file to be renamed */ 1717 if (pri_objs == NULL) { 1718 obj->next = NULL; 1719 pri_objs = obj; 1720 } else { 1721 obj->next = pri_objs; 1722 pri_objs = obj; 1723 } 1724 } 1725 1726 /* rename all the private objects */ 1727 tmp = pri_objs; 1728 while (tmp) { 1729 (void) rename(tmp->tmp_name, tmp->orig_name); 1730 tmp = tmp->next; 1731 } 1732 1733 rename_desc_file: 1734 1735 /* destroy the old encryption key, and hmac key */ 1736 if ((!pin_never_set) && (user_logged_in)) { 1737 (void) soft_cleanup_object(enc_key); 1738 (void) soft_cleanup_object(hmac_key); 1739 } 1740 1741 if (user_logged_in) { 1742 enc_key = new_crypt_key; 1743 hmac_key = new_hmac_key; 1744 } 1745 (void) rename(tmp_ks_desc_name, ks_desc_file); 1746 1747 ret_val = 0; 1748 1749 cleanup2: 1750 if (pri_objs != NULL) { 1751 priobjs_t *p = pri_objs; 1752 while (p) { 1753 tmp = p->next; 1754 free(p); 1755 p = tmp; 1756 } 1757 } 1758 if (!pin_never_set) { 1759 (void) closedir(pri_dirp); 1760 } 1761 1762 if ((!user_logged_in) && (!pin_never_set)) { 1763 (void) soft_cleanup_object(enc_key); 1764 (void) soft_cleanup_object(hmac_key); 1765 enc_key = NULL; 1766 hmac_key = NULL; 1767 } 1768 cleanup3: 1769 if ((ret_val != 0) || (!user_logged_in)) { 1770 (void) soft_cleanup_object(new_crypt_key); 1771 (void) soft_cleanup_object(new_hmac_key); 1772 } 1773 1774 cleanup: 1775 if (!lock_held) { 1776 if (lock_file(fd, B_FALSE, B_FALSE) < 0) { 1777 ret_val = 1; 1778 } 1779 } 1780 if (crypt_salt != NULL) { 1781 free(crypt_salt); 1782 } 1783 if (hmac_salt != NULL) { 1784 free(hmac_salt); 1785 } 1786 (void) close(fd); 1787 (void) close(tmp_ks_fd); 1788 if (ret_val != 0) { 1789 (void) remove(tmp_ks_desc_name); 1790 } 1791 return (ret_val); 1792 } 1793 1794 /* 1795 * FUNCTION: soft_keystore_authpin 1796 * 1797 * ARGUMENTS: 1798 * pin: pin specified by the user for logging into 1799 * the keystore. 1800 * 1801 * RETURN VALUE: 1802 * 0: if no error 1803 * -1: if there is any error 1804 * 1805 * DESCRIPTION: 1806 * 1807 * This function takes the pin specified in the argument 1808 * and generates an encryption key based on the pin. 1809 * The generated encryption key will be used for 1810 * all future encryption and decryption for private 1811 * objects. Before this function is called, none 1812 * of the keystore related interfaces is able 1813 * to decrypt/encrypt any private object. 1814 */ 1815 int 1816 soft_keystore_authpin(uchar_t *pin) 1817 { 1818 int fd; 1819 int ret_val = -1; 1820 CK_BYTE *crypt_salt = NULL, *hmac_salt; 1821 1822 /* get the salt from the keystore description file */ 1823 if ((fd = open_and_lock_keystore_desc(O_RDONLY, 1824 B_FALSE, B_FALSE)) < 0) { 1825 return (-1); 1826 } 1827 1828 crypt_salt = malloc(KS_KEY_SALT_SIZE); 1829 if (crypt_salt == NULL) { 1830 goto cleanup; 1831 } 1832 1833 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) { 1834 goto cleanup; 1835 } 1836 1837 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 1838 != KS_KEY_SALT_SIZE) { 1839 goto cleanup; 1840 } 1841 1842 if (soft_gen_crypt_key(pin, &enc_key, (CK_BYTE **)&crypt_salt) 1843 != CKR_OK) { 1844 goto cleanup; 1845 } 1846 1847 hmac_salt = malloc(KS_HMAC_SALT_SIZE); 1848 if (hmac_salt == NULL) { 1849 goto cleanup; 1850 } 1851 1852 if (lseek(fd, KS_HMAC_SALT_OFFSET, SEEK_SET) != KS_HMAC_SALT_OFFSET) { 1853 goto cleanup; 1854 } 1855 1856 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE) 1857 != KS_HMAC_SALT_SIZE) { 1858 goto cleanup; 1859 } 1860 1861 if (soft_gen_hmac_key(pin, &hmac_key, (CK_BYTE **)&hmac_salt) 1862 != CKR_OK) { 1863 goto cleanup; 1864 } 1865 1866 ret_val = 0; 1867 1868 cleanup: 1869 /* unlock the file */ 1870 (void) lock_file(fd, B_TRUE, B_FALSE); 1871 (void) close(fd); 1872 if (crypt_salt != NULL) { 1873 free(crypt_salt); 1874 } 1875 if (hmac_salt != NULL) { 1876 free(hmac_salt); 1877 } 1878 return (ret_val); 1879 } 1880 1881 /* 1882 * FUNCTION: soft_keystore_get_objs 1883 * 1884 * ARGUMENTS: 1885 * 1886 * search_type: Specify type of objects to return. 1887 * lock_held: TRUE if the lock is held by caller. 1888 * 1889 * 1890 * RETURN VALUE: 1891 * 1892 * NULL: if there are no object in the database. 1893 * 1894 * Otherwise, linked list of objects as requested 1895 * in search type. 1896 * 1897 * The linked list returned will need to be freed 1898 * by the caller. 1899 * 1900 * DESCRIPTION: 1901 * 1902 * Returns objects as requested. 1903 * 1904 * If private objects is requested, and the caller 1905 * has not previously passed in the pin or if the pin 1906 * passed in is wrong, private objects will not 1907 * be returned. 1908 * 1909 * The buffers returned for private objects are already 1910 * decrypted. 1911 */ 1912 CK_RV 1913 soft_keystore_get_objs(ks_search_type_t search_type, 1914 ks_obj_t **result_obj_list, boolean_t lock_held) 1915 { 1916 DIR *dirp; 1917 ks_obj_handle_t ks_handle; 1918 CK_RV rv; 1919 ks_obj_t *tmp; 1920 int ks_fd; 1921 1922 *result_obj_list = NULL; 1923 1924 /* 1925 * lock the keystore description file in "read" mode so that 1926 * objects won't get added/deleted/modified while we are 1927 * doing the search 1928 */ 1929 if ((ks_fd = open_and_lock_keystore_desc(O_RDONLY, B_TRUE, 1930 B_FALSE)) < 0) { 1931 return (CKR_FUNCTION_FAILED); 1932 } 1933 1934 if ((search_type == ALL_TOKENOBJS) || (search_type == PUB_TOKENOBJS)) { 1935 1936 char pub_obj_path[MAXPATHLEN]; 1937 1938 ks_handle.public = B_TRUE; 1939 1940 if ((dirp = opendir(get_pub_obj_path(pub_obj_path))) == NULL) { 1941 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1942 (void) close(ks_fd); 1943 return (CKR_FUNCTION_FAILED); 1944 } 1945 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list, 1946 lock_held); 1947 if (rv != CKR_OK) { 1948 (void) closedir(dirp); 1949 goto cleanup; 1950 } 1951 1952 (void) closedir(dirp); 1953 } 1954 1955 if ((search_type == ALL_TOKENOBJS) || (search_type == PRI_TOKENOBJS)) { 1956 1957 char pri_obj_path[MAXPATHLEN]; 1958 1959 if ((enc_key == NULL) || 1960 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 1961 /* has not login - no need to go any further */ 1962 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1963 (void) close(ks_fd); 1964 return (CKR_OK); 1965 } 1966 1967 ks_handle.public = B_FALSE; 1968 1969 if ((dirp = opendir(get_pri_obj_path(pri_obj_path))) == NULL) { 1970 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1971 (void) close(ks_fd); 1972 return (CKR_OK); 1973 } 1974 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list, 1975 lock_held); 1976 if (rv != CKR_OK) { 1977 (void) closedir(dirp); 1978 goto cleanup; 1979 } 1980 1981 (void) closedir(dirp); 1982 } 1983 /* close the keystore description file */ 1984 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1985 (void) close(ks_fd); 1986 return (CKR_OK); 1987 cleanup: 1988 1989 /* close the keystore description file */ 1990 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1991 (void) close(ks_fd); 1992 1993 /* free all the objects found before hitting the error */ 1994 tmp = *result_obj_list; 1995 while (tmp) { 1996 *result_obj_list = tmp->next; 1997 free(tmp->buf); 1998 free(tmp); 1999 tmp = *result_obj_list; 2000 } 2001 *result_obj_list = NULL; 2002 return (rv); 2003 } 2004 2005 2006 /* 2007 * FUNCTION: soft_keystore_get_single_obj 2008 * 2009 * ARGUMENTS: 2010 * ks_handle: handle of the key store object to be accessed 2011 * lock_held: TRUE if the lock is held by caller. 2012 * 2013 * RETURN VALUE: 2014 * 2015 * NULL: if handle doesn't match any object 2016 * 2017 * Otherwise, the object is returned in 2018 * the same structure used in soft_keystore_get_objs(). 2019 * The structure need to be freed by the caller. 2020 * 2021 * DESCRIPTION: 2022 * 2023 * Retrieves the object specified by the object 2024 * handle to the caller. 2025 * 2026 * If a private object is requested, and the caller 2027 * has not previously passed in the pin or if the pin 2028 * passed in is wrong, the requested private object will not 2029 * be returned. 2030 * 2031 * The buffer returned for the requested private object 2032 * is already decrypted. 2033 */ 2034 CK_RV 2035 soft_keystore_get_single_obj(ks_obj_handle_t *ks_handle, 2036 ks_obj_t **return_obj, boolean_t lock_held) 2037 { 2038 2039 ks_obj_t *obj; 2040 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE]; 2041 uchar_t *buf, *decrypted_buf; 2042 int fd; 2043 ssize_t nread; 2044 CK_RV rv = CKR_FUNCTION_FAILED; 2045 2046 if (!(ks_handle->public)) { 2047 if ((enc_key == NULL) || 2048 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2049 return (CKR_FUNCTION_FAILED); 2050 } 2051 } 2052 2053 if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY, 2054 lock_held)) < 0) { 2055 return (CKR_FUNCTION_FAILED); 2056 } 2057 2058 obj = malloc(sizeof (ks_obj_t)); 2059 if (obj == NULL) { 2060 return (CKR_HOST_MEMORY); 2061 } 2062 2063 obj->next = NULL; 2064 2065 (void) strcpy((char *)((obj->ks_handle).name), 2066 (char *)ks_handle->name); 2067 (obj->ks_handle).public = ks_handle->public; 2068 2069 /* 1st get the version */ 2070 if (readn_nointr(fd, &(obj->obj_version), OBJ_VER_SIZE) 2071 != OBJ_VER_SIZE) { 2072 goto cleanup; 2073 } 2074 obj->obj_version = SWAP32(obj->obj_version); 2075 2076 /* Then, read the IV */ 2077 if (readn_nointr(fd, iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 2078 goto cleanup; 2079 } 2080 2081 /* Then, read the HMAC */ 2082 if (readn_nointr(fd, obj_hmac, OBJ_HMAC_SIZE) != OBJ_HMAC_SIZE) { 2083 goto cleanup; 2084 } 2085 2086 /* read the object */ 2087 rv = read_obj_data(fd, (char **)&buf, &nread); 2088 if (rv != CKR_OK) { 2089 goto cleanup; 2090 } 2091 2092 if (ks_handle->public) { 2093 obj->size = nread; 2094 obj->buf = buf; 2095 *return_obj = obj; 2096 } else { 2097 2098 CK_ULONG out_len = 0, hmac_size; 2099 2100 /* verify HMAC of the object, make sure it matches */ 2101 hmac_size = OBJ_HMAC_SIZE; 2102 if (soft_keystore_hmac(hmac_key, B_FALSE, buf, 2103 nread, obj_hmac, &hmac_size) != CKR_OK) { 2104 free(buf); 2105 rv = CKR_FUNCTION_FAILED; 2106 goto cleanup; 2107 } 2108 2109 /* decrypt object */ 2110 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread, 2111 NULL, &out_len) != CKR_OK) { 2112 free(buf); 2113 rv = CKR_FUNCTION_FAILED; 2114 goto cleanup; 2115 } 2116 2117 decrypted_buf = malloc(sizeof (uchar_t) * out_len); 2118 if (decrypted_buf == NULL) { 2119 free(buf); 2120 rv = CKR_HOST_MEMORY; 2121 goto cleanup; 2122 } 2123 2124 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread, 2125 decrypted_buf, &out_len) != CKR_OK) { 2126 free(decrypted_buf); 2127 free(buf); 2128 rv = CKR_FUNCTION_FAILED; 2129 goto cleanup; 2130 } 2131 2132 obj->size = out_len - MAXPATHLEN; 2133 2134 /* 2135 * decrypted buf here actually contains full path name of 2136 * object plus the actual data. so, need to skip the 2137 * full pathname. 2138 * See prepare_data_for_encrypt() function in the file 2139 * to understand how and why the pathname is added. 2140 */ 2141 obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN)); 2142 if (obj->buf == NULL) { 2143 free(decrypted_buf); 2144 free(buf); 2145 rv = CKR_HOST_MEMORY; 2146 goto cleanup; 2147 } 2148 (void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size); 2149 free(decrypted_buf); 2150 free(buf); 2151 *return_obj = obj; 2152 } 2153 2154 cleanup: 2155 2156 if (rv != CKR_OK) { 2157 free(obj); 2158 } 2159 2160 /* unlock the file after reading */ 2161 if (!lock_held) { 2162 (void) lock_file(fd, B_TRUE, B_FALSE); 2163 } 2164 2165 (void) close(fd); 2166 2167 return (rv); 2168 } 2169 2170 2171 /* 2172 * FUNCTION: soft_keystore_put_new_obj 2173 * 2174 * ARGUMENTS: 2175 * buf: buffer containing un-encrypted data 2176 * to be stored in keystore. 2177 * len: length of data 2178 * public: TRUE if it is a public object, 2179 * FALSE if it is private obj 2180 * lock_held: TRUE if the lock is held by caller. 2181 * keyhandle: pointer to object handle to 2182 * receive keyhandle for new object 2183 * 2184 * RETURN VALUE: 2185 * 0: object successfully stored in file 2186 * -1: some error occurred, object is not stored in file. 2187 * 2188 * DESCRIPTION: 2189 * This API is used to write a newly created token object 2190 * to keystore. 2191 * 2192 * This function does the following: 2193 * 2194 * 1) Creates a token object file based on "public" parameter. 2195 * 2) Generates a new IV and stores it in obj_meta_data_t if it is 2196 * private object. 2197 * 3) Set object version number to 1. 2198 * 4) If it is a private object, it will be encrypted before 2199 * being written to the newly created keystore token object 2200 * file. 2201 * 5) Calculates the obj_chksum in obj_meta_data_t. 2202 * 6) Calculates the pin_chksum in obj_meta_data_t. 2203 * 7) Increments the keystore version number. 2204 */ 2205 int 2206 soft_keystore_put_new_obj(uchar_t *buf, size_t len, boolean_t public, 2207 boolean_t lock_held, ks_obj_handle_t *keyhandle) 2208 { 2209 2210 int fd, tmp_ks_fd, obj_fd; 2211 unsigned int counter, version; 2212 uchar_t obj_hmac[OBJ_HMAC_SIZE]; 2213 CK_BYTE iv[OBJ_IV_SIZE]; 2214 char obj_name[MAXPATHLEN], tmp_ks_desc_name[MAXPATHLEN]; 2215 char filebuf[BUFSIZ]; 2216 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2217 ks_desc_file[MAXPATHLEN]; 2218 CK_ULONG hmac_size; 2219 ssize_t nread; 2220 2221 if (keyhandle == NULL) { 2222 return (-1); 2223 } 2224 2225 /* if it is private object, make sure we have the key */ 2226 if (!public) { 2227 if ((enc_key == NULL) || 2228 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2229 return (-1); 2230 } 2231 } 2232 2233 /* open keystore, and set write lock */ 2234 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_TRUE, 2235 lock_held)) < 0) { 2236 return (-1); 2237 } 2238 2239 (void) get_desc_file_path(ks_desc_file); 2240 (void) get_tmp_desc_file_path(tmp_ks_desc_name); 2241 2242 /* 2243 * create a tempoary file for the keystore description 2244 * file for updating version and counter information 2245 */ 2246 tmp_ks_fd = open_nointr(tmp_ks_desc_name, 2247 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2248 if (tmp_ks_fd < 0) { 2249 (void) close(fd); 2250 return (-1); 2251 } 2252 2253 /* read and write pkcs11 version */ 2254 if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE) 2255 != KS_PKCS11_VER_SIZE) { 2256 goto cleanup; 2257 } 2258 2259 if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE) 2260 != KS_PKCS11_VER_SIZE) { 2261 goto cleanup; 2262 } 2263 2264 /* get version number, and write updated number to temp file */ 2265 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 2266 goto cleanup; 2267 } 2268 2269 version = SWAP32(version); 2270 version++; 2271 version = SWAP32(version); 2272 2273 if (writen_nointr(tmp_ks_fd, (void *)&version, 2274 KS_VER_SIZE) != KS_VER_SIZE) { 2275 goto cleanup; 2276 } 2277 2278 /* get object count value */ 2279 if (readn_nointr(fd, &counter, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) { 2280 goto cleanup; 2281 } 2282 counter = SWAP32(counter); 2283 2284 bzero(obj_name, sizeof (obj_name)); 2285 if (public) { 2286 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d", 2287 get_pub_obj_path(pub_obj_path), OBJ_PREFIX, counter); 2288 } else { 2289 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d", 2290 get_pri_obj_path(pri_obj_path), OBJ_PREFIX, counter); 2291 } 2292 2293 /* create object file */ 2294 obj_fd = open_nointr(obj_name, 2295 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2296 if (obj_fd < 0) { 2297 /* can't create object file */ 2298 goto cleanup; 2299 } 2300 2301 /* lock object file for writing */ 2302 if (lock_file(obj_fd, B_FALSE, B_TRUE) != 0) { 2303 (void) close(obj_fd); 2304 goto cleanup2; 2305 } 2306 2307 /* write object meta data */ 2308 version = SWAP32(1); 2309 if (writen_nointr(obj_fd, (void *)&version, sizeof (version)) 2310 != sizeof (version)) { 2311 goto cleanup2; 2312 } 2313 2314 if (public) { 2315 bzero(iv, sizeof (iv)); 2316 } else { 2317 /* generate an IV */ 2318 if (soft_gen_iv(iv) != CKR_OK) { 2319 goto cleanup2; 2320 } 2321 2322 } 2323 2324 if (writen_nointr(obj_fd, (void *)iv, sizeof (iv)) != sizeof (iv)) { 2325 goto cleanup2; 2326 } 2327 2328 if (public) { 2329 2330 bzero(obj_hmac, sizeof (obj_hmac)); 2331 if (writen_nointr(obj_fd, (void *)obj_hmac, 2332 sizeof (obj_hmac)) != sizeof (obj_hmac)) { 2333 goto cleanup2; 2334 } 2335 2336 if (writen_nointr(obj_fd, (char *)buf, len) != len) { 2337 goto cleanup2; 2338 } 2339 2340 } else { 2341 2342 uchar_t *encrypted_buf, *prepared_buf; 2343 CK_ULONG out_len = 0, prepared_len; 2344 2345 if (prepare_data_for_encrypt(obj_name, buf, len, 2346 &prepared_buf, &prepared_len) != 0) { 2347 goto cleanup2; 2348 } 2349 2350 if (soft_keystore_crypt(enc_key, iv, 2351 B_TRUE, prepared_buf, prepared_len, 2352 NULL, &out_len) != CKR_OK) { 2353 free(prepared_buf); 2354 goto cleanup2; 2355 } 2356 2357 encrypted_buf = malloc(out_len * sizeof (char)); 2358 if (encrypted_buf == NULL) { 2359 free(prepared_buf); 2360 goto cleanup2; 2361 } 2362 2363 if (soft_keystore_crypt(enc_key, iv, 2364 B_TRUE, prepared_buf, prepared_len, 2365 encrypted_buf, &out_len) != CKR_OK) { 2366 free(encrypted_buf); 2367 free(prepared_buf); 2368 goto cleanup2; 2369 } 2370 free(prepared_buf); 2371 2372 /* calculate HMAC of encrypted object */ 2373 hmac_size = OBJ_HMAC_SIZE; 2374 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf, 2375 out_len, obj_hmac, &hmac_size) != CKR_OK) { 2376 free(encrypted_buf); 2377 goto cleanup2; 2378 } 2379 2380 if (hmac_size != OBJ_HMAC_SIZE) { 2381 free(encrypted_buf); 2382 goto cleanup2; 2383 } 2384 2385 /* write hmac */ 2386 if (writen_nointr(obj_fd, (void *)obj_hmac, 2387 sizeof (obj_hmac)) != sizeof (obj_hmac)) { 2388 free(encrypted_buf); 2389 goto cleanup2; 2390 } 2391 2392 /* write encrypted object */ 2393 if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len) 2394 != out_len) { 2395 free(encrypted_buf); 2396 goto cleanup2; 2397 } 2398 2399 free(encrypted_buf); 2400 } 2401 2402 2403 (void) close(obj_fd); 2404 (void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name), 2405 "obj%d", counter); 2406 keyhandle->public = public; 2407 2408 /* 2409 * store new counter to temp keystore description file. 2410 */ 2411 counter++; 2412 counter = SWAP32(counter); 2413 if (writen_nointr(tmp_ks_fd, (void *)&counter, 2414 sizeof (counter)) != sizeof (counter)) { 2415 goto cleanup2; 2416 } 2417 2418 /* read rest of keystore description file and store into temp file */ 2419 nread = readn_nointr(fd, filebuf, sizeof (filebuf)); 2420 while (nread > 0) { 2421 if (writen_nointr(tmp_ks_fd, filebuf, nread) != nread) { 2422 goto cleanup2; 2423 } 2424 nread = readn_nointr(fd, filebuf, sizeof (filebuf)); 2425 } 2426 2427 (void) close(tmp_ks_fd); 2428 (void) rename(tmp_ks_desc_name, ks_desc_file); 2429 2430 if (!lock_held) { 2431 /* release lock on description file */ 2432 if (lock_file(fd, B_FALSE, B_FALSE) != 0) { 2433 (void) close(fd); 2434 return (-1); 2435 } 2436 } 2437 (void) close(fd); 2438 return (0); 2439 2440 cleanup2: 2441 2442 /* remove object file. No need to remove lock first */ 2443 (void) unlink(obj_name); 2444 2445 cleanup: 2446 2447 (void) close(tmp_ks_fd); 2448 (void) remove(tmp_ks_desc_name); 2449 if (!lock_held) { 2450 /* release lock on description file */ 2451 (void) lock_file(fd, B_FALSE, B_FALSE); 2452 } 2453 2454 (void) close(fd); 2455 return (-1); 2456 } 2457 2458 /* 2459 * FUNCTION: soft_keystore_modify_obj 2460 * 2461 * ARGUMENTS: 2462 * ks_handle: handle of the key store object to be modified 2463 * buf: buffer containing un-encrypted data 2464 * to be modified in keystore. 2465 * len: length of data 2466 * lock_held: TRUE if the lock is held by caller. 2467 * 2468 * RETURN VALUE: 2469 * -1: if any error occurred. 2470 * Otherwise, 0 is returned. 2471 * 2472 * DESCRIPTION: 2473 * 2474 * This API is used to write a modified token object back 2475 * to keystore. This function will do the following: 2476 * 2477 * 1) If it is a private object, it will be encrypted before 2478 * being written to the corresponding keystore token 2479 * object file. 2480 * 2) Record incremented object version number. 2481 * 3) Record incremented keystore version number. 2482 */ 2483 int 2484 soft_keystore_modify_obj(ks_obj_handle_t *ks_handle, uchar_t *buf, 2485 size_t len, boolean_t lock_held) 2486 { 2487 int fd, ks_fd, tmp_fd, version; 2488 char orig_name[MAXPATHLEN], tmp_name[MAXPATHLEN], 2489 tmp_ks_name[MAXPATHLEN]; 2490 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE]; 2491 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2492 ks_desc_file[MAXPATHLEN]; 2493 CK_ULONG hmac_size; 2494 2495 /* if it is private object, make sure we have the key */ 2496 if (!(ks_handle->public)) { 2497 if ((enc_key == NULL) || 2498 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2499 return (-1); 2500 } 2501 } 2502 2503 /* open and lock keystore description file */ 2504 if ((ks_fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2505 B_FALSE)) < 0) { 2506 return (-1); 2507 } 2508 2509 (void) get_desc_file_path(ks_desc_file); 2510 2511 /* update the version of for keystore file in tempoary file */ 2512 (void) get_tmp_desc_file_path(tmp_ks_name); 2513 if (create_updated_keystore_version(ks_fd, tmp_ks_name) != 0) { 2514 /* unlock keystore description file */ 2515 (void) lock_file(ks_fd, B_FALSE, B_FALSE); 2516 (void) close(ks_fd); 2517 return (-1); 2518 } 2519 2520 /* open object file */ 2521 if ((fd = open_and_lock_object_file(ks_handle, O_RDWR, 2522 lock_held)) < 0) { 2523 goto cleanup; 2524 } 2525 2526 /* 2527 * make the change in a temporary file. Create the temp 2528 * file in the same directory as the token object. That 2529 * way, the "rename" later will be an atomic operation 2530 */ 2531 if (ks_handle->public) { 2532 (void) snprintf(orig_name, MAXPATHLEN, "%s/%s", 2533 get_pub_obj_path(pub_obj_path), ks_handle->name); 2534 (void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s", 2535 pub_obj_path, TMP_OBJ_PREFIX, 2536 (ks_handle->name) + strlen(OBJ_PREFIX)); 2537 } else { 2538 (void) snprintf(orig_name, MAXPATHLEN, "%s/%s", 2539 get_pri_obj_path(pri_obj_path), ks_handle->name); 2540 (void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s", 2541 pri_obj_path, TMP_OBJ_PREFIX, 2542 (ks_handle->name) + strlen(OBJ_PREFIX)); 2543 } 2544 2545 tmp_fd = open_nointr(tmp_name, 2546 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2547 if (tmp_fd < 0) { 2548 /* can't create tmp object file */ 2549 goto cleanup1; 2550 } 2551 2552 /* read version, increment, and write to tmp file */ 2553 if (readn_nointr(fd, (char *)&version, OBJ_VER_SIZE) != OBJ_VER_SIZE) { 2554 goto cleanup2; 2555 } 2556 2557 version = SWAP32(version); 2558 version++; 2559 version = SWAP32(version); 2560 2561 if (writen_nointr(tmp_fd, (char *)&version, OBJ_VER_SIZE) 2562 != OBJ_VER_SIZE) { 2563 goto cleanup2; 2564 } 2565 2566 /* generate a new IV for the object, old one can be ignored */ 2567 if (soft_gen_iv(iv) != CKR_OK) { 2568 goto cleanup2; 2569 } 2570 2571 if (writen_nointr(tmp_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 2572 goto cleanup2; 2573 } 2574 2575 if (ks_handle->public) { 2576 2577 /* hmac is always NULL for public objects */ 2578 bzero(obj_hmac, sizeof (obj_hmac)); 2579 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE) 2580 != OBJ_HMAC_SIZE) { 2581 goto cleanup2; 2582 } 2583 2584 /* write updated object */ 2585 if (writen_nointr(tmp_fd, (char *)buf, len) != len) { 2586 goto cleanup2; 2587 } 2588 2589 } else { 2590 2591 uchar_t *encrypted_buf, *prepared_buf; 2592 CK_ULONG out_len = 0, prepared_len; 2593 2594 if (prepare_data_for_encrypt(orig_name, buf, len, 2595 &prepared_buf, &prepared_len) != 0) { 2596 goto cleanup2; 2597 } 2598 2599 /* encrypt the data */ 2600 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf, 2601 prepared_len, NULL, &out_len) != CKR_OK) { 2602 free(prepared_buf); 2603 goto cleanup2; 2604 } 2605 2606 encrypted_buf = malloc(out_len * sizeof (char)); 2607 if (encrypted_buf == NULL) { 2608 free(prepared_buf); 2609 goto cleanup2; 2610 } 2611 2612 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf, 2613 prepared_len, encrypted_buf, &out_len) != CKR_OK) { 2614 free(encrypted_buf); 2615 free(prepared_buf); 2616 goto cleanup2; 2617 } 2618 2619 free(prepared_buf); 2620 2621 /* calculate hmac on encrypted buf */ 2622 hmac_size = OBJ_HMAC_SIZE; 2623 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf, 2624 out_len, obj_hmac, &hmac_size) != CKR_OK) { 2625 free(encrypted_buf); 2626 goto cleanup2; 2627 } 2628 2629 if (hmac_size != OBJ_HMAC_SIZE) { 2630 free(encrypted_buf); 2631 goto cleanup2; 2632 } 2633 2634 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE) 2635 != OBJ_HMAC_SIZE) { 2636 free(encrypted_buf); 2637 goto cleanup2; 2638 } 2639 2640 if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len) 2641 != out_len) { 2642 free(encrypted_buf); 2643 goto cleanup2; 2644 } 2645 free(encrypted_buf); 2646 } 2647 (void) close(tmp_fd); 2648 2649 /* rename updated temporary object file */ 2650 if (rename(tmp_name, orig_name) != 0) { 2651 (void) unlink(tmp_name); 2652 return (-1); 2653 } 2654 2655 /* rename updated keystore description file */ 2656 if (rename(tmp_ks_name, ks_desc_file) != 0) { 2657 (void) unlink(tmp_name); 2658 (void) unlink(tmp_ks_name); 2659 return (-1); 2660 } 2661 2662 /* determine need to unlock file or not */ 2663 if (!lock_held) { 2664 if (lock_file(fd, B_FALSE, B_FALSE) < 0) { 2665 (void) close(fd); 2666 (void) unlink(tmp_name); 2667 return (-1); 2668 } 2669 } 2670 2671 /* unlock keystore description file */ 2672 if (lock_file(ks_fd, B_FALSE, B_FALSE) != 0) { 2673 (void) close(ks_fd); 2674 (void) close(fd); 2675 return (-1); 2676 } 2677 2678 (void) close(ks_fd); 2679 2680 (void) close(fd); 2681 2682 return (0); /* All operations completed successfully */ 2683 2684 cleanup2: 2685 (void) close(tmp_fd); 2686 (void) remove(tmp_name); 2687 2688 cleanup1: 2689 (void) close(fd); 2690 2691 cleanup: 2692 /* unlock keystore description file */ 2693 (void) lock_file(ks_fd, B_FALSE, B_FALSE); 2694 (void) close(ks_fd); 2695 (void) remove(tmp_ks_name); 2696 return (-1); 2697 } 2698 2699 /* 2700 * FUNCTION: soft_keystore_del_obj 2701 * 2702 * ARGUMENTS: 2703 * ks_handle: handle of the key store object to be deleted 2704 * lock_held: TRUE if the lock is held by caller. 2705 * 2706 * RETURN VALUE: 2707 * -1: if any error occurred. 2708 * 0: object successfully deleted from keystore. 2709 * 2710 * DESCRIPTION: 2711 * This API is used to delete a particular token object from 2712 * the keystore. The corresponding token object file will be 2713 * removed from the file system. 2714 * Any future reference to the deleted file will 2715 * return an CKR_OBJECT_HANDLE_INVALID error. 2716 */ 2717 int 2718 soft_keystore_del_obj(ks_obj_handle_t *ks_handle, boolean_t lock_held) 2719 { 2720 char objname[MAXPATHLEN], tmp_ks_name[MAXPATHLEN]; 2721 int fd; 2722 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2723 ks_desc_file[MAXPATHLEN]; 2724 int ret_val = -1; 2725 int obj_fd; 2726 2727 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2728 lock_held)) < 0) { 2729 return (-1); 2730 } 2731 2732 (void) get_desc_file_path(ks_desc_file); 2733 (void) get_tmp_desc_file_path(tmp_ks_name); 2734 if (create_updated_keystore_version(fd, tmp_ks_name) != 0) { 2735 goto cleanup; 2736 } 2737 2738 if (ks_handle->public) { 2739 (void) snprintf(objname, MAXPATHLEN, "%s/%s", 2740 get_pub_obj_path(pub_obj_path), ks_handle->name); 2741 } else { 2742 (void) snprintf(objname, MAXPATHLEN, "%s/%s", 2743 get_pri_obj_path(pri_obj_path), ks_handle->name); 2744 } 2745 2746 /* 2747 * make sure no other process is reading/writing the file 2748 * by acquiring the lock on the file 2749 */ 2750 if ((obj_fd = open_and_lock_object_file(ks_handle, O_WRONLY, 2751 B_FALSE)) < 0) { 2752 return (-1); 2753 } 2754 2755 if (unlink(objname) != 0) { 2756 (void) lock_file(obj_fd, B_FALSE, B_FALSE); 2757 (void) close(obj_fd); 2758 goto cleanup; 2759 } 2760 2761 (void) lock_file(obj_fd, B_FALSE, B_FALSE); 2762 (void) close(obj_fd); 2763 2764 if (rename(tmp_ks_name, ks_desc_file) != 0) { 2765 goto cleanup; 2766 } 2767 ret_val = 0; 2768 2769 cleanup: 2770 /* unlock keystore description file */ 2771 if (!lock_held) { 2772 if (lock_file(fd, B_FALSE, B_FALSE) != 0) { 2773 (void) close(fd); 2774 return (-1); 2775 } 2776 } 2777 2778 (void) close(fd); 2779 return (ret_val); 2780 } 2781 2782 /* 2783 * Get the salt used for generating hashed pin from the 2784 * keystore description file. 2785 * 2786 * The result will be stored in the provided buffer "salt" passed 2787 * in as an argument. 2788 * 2789 * Return 0 if no error, return -1 if there's any error. 2790 */ 2791 int 2792 soft_keystore_get_pin_salt(char **salt) 2793 { 2794 int fd, ret_val = -1; 2795 uint64_t hashed_pin_salt_size; 2796 2797 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_TRUE, 2798 B_FALSE)) < 0) { 2799 return (-1); 2800 } 2801 2802 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET) 2803 != KS_HASHED_PIN_SALT_LEN_OFFSET) { 2804 goto cleanup; 2805 } 2806 2807 if (readn_nointr(fd, (char *)&hashed_pin_salt_size, 2808 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 2809 goto cleanup; 2810 } 2811 hashed_pin_salt_size = SWAP64(hashed_pin_salt_size); 2812 2813 *salt = malloc(hashed_pin_salt_size + 1); 2814 if (*salt == NULL) { 2815 goto cleanup; 2816 } 2817 2818 if ((readn_nointr(fd, *salt, hashed_pin_salt_size)) 2819 != (ssize_t)hashed_pin_salt_size) { 2820 free(*salt); 2821 goto cleanup; 2822 } 2823 (*salt)[hashed_pin_salt_size] = '\0'; 2824 2825 ret_val = 0; 2826 2827 cleanup: 2828 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 2829 ret_val = -1; 2830 } 2831 2832 (void) close(fd); 2833 return (ret_val); 2834 } 2835 2836 /* 2837 * FUNCTION: soft_keystore_pin_initialized 2838 * 2839 * ARGUMENTS: 2840 * initialized: This value will be set to true if keystore is 2841 * initialized, and false otherwise. 2842 * hashed_pin: If the keystore is initialized, this will contain 2843 * the hashed pin. It will be NULL if the keystore 2844 * pin is not initialized. Memory allocated 2845 * for the hashed pin needs to be freed by 2846 * the caller. 2847 * lock_held: TRUE if the lock is held by caller. 2848 * 2849 * RETURN VALUE: 2850 * CKR_OK: No error 2851 * any other appropriate CKR_value 2852 * 2853 * DESCRIPTION: 2854 * This API is used to determine if the PIN in the keystore 2855 * has been initialized or not. 2856 * It makes the determination using the salt for generating the 2857 * encryption key. The salt is stored in the keystore 2858 * descryption file. The salt should be all zero if 2859 * the keystore pin has not been initialized. 2860 * If the pin has been initialized, it is returned in the 2861 * hashed_pin argument. 2862 */ 2863 CK_RV 2864 soft_keystore_pin_initialized(boolean_t *initialized, char **hashed_pin, 2865 boolean_t lock_held) 2866 { 2867 int fd; 2868 CK_BYTE crypt_salt[KS_KEY_SALT_SIZE], tmp_buf[KS_KEY_SALT_SIZE]; 2869 CK_RV ret_val = CKR_OK; 2870 2871 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_TRUE, 2872 lock_held)) < 0) { 2873 return (CKR_FUNCTION_FAILED); 2874 } 2875 2876 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) { 2877 ret_val = CKR_FUNCTION_FAILED; 2878 goto cleanup; 2879 } 2880 2881 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 2882 != KS_KEY_SALT_SIZE) { 2883 ret_val = CKR_FUNCTION_FAILED; 2884 goto cleanup; 2885 } 2886 2887 (void) bzero(tmp_buf, KS_KEY_SALT_SIZE); 2888 2889 if (memcmp(crypt_salt, tmp_buf, KS_KEY_SALT_SIZE) == 0) { 2890 *initialized = B_FALSE; 2891 hashed_pin = NULL; 2892 } else { 2893 *initialized = B_TRUE; 2894 ret_val = get_hashed_pin(fd, hashed_pin); 2895 } 2896 2897 cleanup: 2898 2899 if (!lock_held) { 2900 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 2901 ret_val = CKR_FUNCTION_FAILED; 2902 } 2903 } 2904 2905 (void) close(fd); 2906 return (ret_val); 2907 } 2908 2909 /* 2910 * This checks if the keystore file exists 2911 */ 2912 2913 static int 2914 soft_keystore_exists() 2915 { 2916 int ret; 2917 struct stat fn_stat; 2918 char *fname, ks_desc_file[MAXPATHLEN]; 2919 2920 fname = get_desc_file_path(ks_desc_file); 2921 ret = stat(fname, &fn_stat); 2922 if (ret == 0) 2923 return (0); 2924 return (errno); 2925 } 2926 2927 /* 2928 * FUNCTION: soft_keystore_init 2929 * 2930 * ARGUMENTS: 2931 * desired_state: The keystore state the caller would like 2932 * it to be. 2933 * 2934 * RETURN VALUE: 2935 * Returns the state the function is in. If it succeeded, it 2936 * will be the same as the desired, if not it will be 2937 * KEYSTORE_UNAVAILABLE. 2938 * 2939 * DESCRIPTION: 2940 * This function will only load as much keystore data as is 2941 * requested at that time. This is for performace by delaying the 2942 * reading of token objects until they are needed or never at 2943 * all if they are not used. 2944 * 2945 * It is only called by soft_keystore_status() when the 2946 * "desired_state" is not the the current load state of keystore. 2947 * 2948 */ 2949 int 2950 soft_keystore_init(int desired_state) 2951 { 2952 int ret; 2953 2954 (void) pthread_mutex_lock(&soft_slot.keystore_mutex); 2955 2956 /* 2957 * If more than one session tries to initialize the keystore, the 2958 * second and other following sessions that were waiting for the lock 2959 * will quickly exit if their requirements are satisfied. 2960 */ 2961 if (desired_state <= soft_slot.keystore_load_status) { 2962 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex); 2963 return (soft_slot.keystore_load_status); 2964 } 2965 2966 /* 2967 * With 'keystore_load_status' giving the current state of the 2968 * process, this switch will bring it up to the desired state if 2969 * possible. 2970 */ 2971 2972 switch (soft_slot.keystore_load_status) { 2973 case KEYSTORE_UNINITIALIZED: 2974 ret = soft_keystore_exists(); 2975 if (ret == 0) 2976 soft_slot.keystore_load_status = KEYSTORE_PRESENT; 2977 else if (ret == ENOENT) 2978 if (create_keystore() == 0) 2979 soft_slot.keystore_load_status = 2980 KEYSTORE_PRESENT; 2981 else { 2982 soft_slot.keystore_load_status = 2983 KEYSTORE_UNAVAILABLE; 2984 cryptoerror(LOG_DEBUG, 2985 "pkcs11_softtoken: " 2986 "Cannot create keystore."); 2987 break; 2988 } 2989 2990 if (desired_state <= KEYSTORE_PRESENT) 2991 break; 2992 2993 /* FALLTHRU */ 2994 case KEYSTORE_PRESENT: 2995 if (soft_keystore_get_version(&soft_slot.ks_version, B_FALSE) 2996 != 0) { 2997 soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE; 2998 cryptoerror(LOG_DEBUG, 2999 "pkcs11_softtoken: Keystore access failed."); 3000 break; 3001 } 3002 3003 soft_slot.keystore_load_status = KEYSTORE_VERSION_OK; 3004 if (desired_state <= KEYSTORE_VERSION_OK) 3005 break; 3006 3007 /* FALLTHRU */ 3008 case KEYSTORE_VERSION_OK: 3009 /* Load all the public token objects from keystore */ 3010 if (soft_get_token_objects_from_keystore(PUB_TOKENOBJS) 3011 != CKR_OK) { 3012 (void) soft_destroy_token_session(); 3013 soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE; 3014 cryptoerror(LOG_DEBUG, 3015 "pkcs11_softtoken: Cannot initialize keystore."); 3016 break; 3017 } 3018 3019 soft_slot.keystore_load_status = KEYSTORE_INITIALIZED; 3020 }; 3021 3022 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex); 3023 return (soft_slot.keystore_load_status); 3024 } 3025 3026 /* 3027 * FUNCTION: soft_keystore_status 3028 * 3029 * ARGUMENTS: 3030 * desired_state: The keystore state the caller would like 3031 * it to be. 3032 * 3033 * RETURN VALUE: 3034 * B_TRUE if keystore is ready and at the desired state. 3035 * B_FALSE if keystore had an error and is not available. 3036 * 3037 * DESCRIPTION: 3038 * The calling function wants to make sure the keystore load 3039 * status to in a state it requires. If it is not at that 3040 * state it will call the load function. 3041 * If keystore is at the desired state or has just been 3042 * loaded to that state, it will return TRUE. If there has been 3043 * load failure, it will return FALSE. 3044 * 3045 */ 3046 boolean_t 3047 soft_keystore_status(int desired_state) 3048 { 3049 3050 if (soft_slot.keystore_load_status == KEYSTORE_UNAVAILABLE) 3051 return (B_FALSE); 3052 3053 return ((desired_state <= soft_slot.keystore_load_status) || 3054 (soft_keystore_init(desired_state) == desired_state)); 3055 } 3056