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