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