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