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