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 * Copyright 2018, Joyent, Inc. 24 */ 25 26 /* 27 * Functions used for manipulating the keystore 28 */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <errno.h> 33 #include <sys/stat.h> 34 #include <fcntl.h> 35 #include <time.h> 36 #include <unistd.h> 37 #include <pwd.h> 38 #include <sys/types.h> 39 #include <dirent.h> 40 #include <limits.h> 41 #include <libgen.h> 42 #include <strings.h> 43 #include <security/cryptoki.h> 44 #include <cryptoutil.h> 45 #include "softGlobal.h" 46 #include "softObject.h" 47 #include "softSession.h" 48 #include "softKeystore.h" 49 #include "softKeystoreUtil.h" 50 51 #define MAXPATHLEN 1024 52 #define SUNW_PATH ".sunw" /* top level Sun directory */ 53 #define KEYSTORE_PATH "pkcs11_softtoken" /* keystore directory */ 54 #define PUB_OBJ_DIR "public" /* directory for public objects */ 55 #define PRI_OBJ_DIR "private" /* directory for private objects */ 56 #define DS_FILE "objstore_info" /* keystore description file */ 57 #define TMP_DS_FILE "t_info" /* temp name for keystore desc. file */ 58 #define OBJ_PREFIX "obj" /* prefix of the keystore object file names */ 59 #define OBJ_PREFIX_LEN sizeof (OBJ_PREFIX) - 1 /* length of prefix */ 60 #define TMP_OBJ_PREFIX "t_o" /* prefix of the temp object file names */ 61 62 /* 63 * KEYSTORE DESCRIPTION FILE: 64 * 65 * The following describes the content of the keystore description file 66 * 67 * The order AND data type of the fields are very important. 68 * All the code in this file assume that they are in the order specified 69 * below. If either order of the fields or their data type changed, 70 * you must make sure the ALL the pre-define values are still valid 71 * 72 * 1) PKCS#11 release number. It's 2.20 in this release (uchar_t[32]) 73 * 2) keystore version number: used for synchronizing when different 74 * processes access the keystore at the same time. It is incremented 75 * when there is a change to the keystore. (uint_32) 76 * 3) monotonic-counter: last counter value for name of token object file. 77 * used for assigning unique name to each token (uint_32) 78 * 4) salt used for generating encryption key (uint_16) 79 * 5) salt used for generating key used for doing HMAC (uint_16) 80 * 6) Length of salt used for generating hashed pin (length of salt 81 * is variable) 82 * 7) Salt used for generating hashed pin. 83 * 8) Hashed pin len (length of hashed pin could be variable, the offset of 84 * where this value lives in the file is calculated at run time) 85 * 9) Hashed pin 86 * 87 */ 88 89 /* Keystore description file pre-defined values */ 90 #define KS_PKCS11_VER "2.20" 91 #define KS_PKCS11_OFFSET 0 92 #define KS_PKCS11_VER_SIZE 32 93 94 #define KS_VER_OFFSET (KS_PKCS11_OFFSET + KS_PKCS11_VER_SIZE) 95 #define KS_VER_SIZE 4 /* size in bytes of keystore version value */ 96 97 #define KS_COUNTER_OFFSET (KS_VER_OFFSET + KS_VER_SIZE) 98 #define KS_COUNTER_SIZE 4 /* size in bytes of the monotonic counter */ 99 100 #define KS_KEY_SALT_OFFSET (KS_COUNTER_OFFSET + KS_COUNTER_SIZE) 101 #define KS_KEY_SALT_SIZE PBKD2_SALT_SIZE 102 103 #define KS_HMAC_SALT_OFFSET (KS_KEY_SALT_OFFSET + KS_KEY_SALT_SIZE) 104 #define KS_HMAC_SALT_SIZE PBKD2_SALT_SIZE 105 106 /* Salt for hashed pin */ 107 #define KS_HASHED_PIN_SALT_LEN_OFFSET (KS_HMAC_SALT_OFFSET + KS_HMAC_SALT_SIZE) 108 #define KS_HASHED_PIN_SALT_LEN_SIZE 8 /* stores length of hashed pin salt */ 109 110 #define KS_HASHED_PIN_SALT_OFFSET \ 111 (KS_HASHED_PIN_SALT_LEN_OFFSET + KS_HASHED_PIN_SALT_LEN_SIZE) 112 113 /* 114 * hashed pin 115 * 116 * hashed_pin length offset will be calculated at run time since 117 * there's the hashed pin salt size is variable. 118 * 119 * The offset will be calculated at run time by calling the 120 * function calculate_hashed_pin_offset() 121 */ 122 static off_t ks_hashed_pinlen_offset = -1; 123 #define KS_HASHED_PINLEN_SIZE 8 124 125 /* End of Keystore description file pre-defined values */ 126 127 /* 128 * Metadata for each object 129 * 130 * The order AND data type of all the fields is very important. 131 * All the code in this file assume that they are in the order specified 132 * below. If either order of the fields or their data type is changed, 133 * you must make sure the following pre-define value is still valid 134 * Each object will have the meta data at the beginning of the object file. 135 * 136 * 1) object_version: used by softtoken to see if the object 137 * has been modified since it last reads it. (uint_32) 138 * 2) iv: initialization vector for encrypted data in the object. This 139 * value will be 0 for public objects. (uchar_t[16]) 140 * 3) obj_hmac: keyed hash as verifier to detect private object 141 * being tampered this value will be 0 for public objects (uchar_t[16]) 142 */ 143 144 /* Object metadata pre-defined values */ 145 #define OBJ_VER_OFFSET 0 146 #define OBJ_VER_SIZE 4 /* size of object version in bytes */ 147 #define OBJ_IV_OFFSET (OBJ_VER_OFFSET + OBJ_VER_SIZE) 148 #define OBJ_IV_SIZE 16 149 #define OBJ_HMAC_OFFSET (OBJ_IV_OFFSET + OBJ_IV_SIZE) 150 #define OBJ_HMAC_SIZE 16 /* MD5 HMAC keyed hash */ 151 #define OBJ_DATA_OFFSET (OBJ_HMAC_OFFSET + OBJ_HMAC_SIZE) 152 /* End of object metadata pre-defined values */ 153 154 #define ALTERNATE_KEYSTORE_PATH "SOFTTOKEN_DIR" 155 156 static soft_object_t *enc_key = NULL; 157 static soft_object_t *hmac_key = NULL; 158 static char keystore_path[MAXPATHLEN]; 159 static boolean_t keystore_path_initialized = B_FALSE; 160 static int desc_fd = 0; 161 162 static char * 163 get_keystore_path() 164 { 165 char *home = getenv("HOME"); 166 char *alt = getenv(ALTERNATE_KEYSTORE_PATH); 167 168 if (keystore_path_initialized) { 169 return (keystore_path); 170 } 171 172 bzero(keystore_path, sizeof (keystore_path)); 173 /* 174 * If it isn't set or is set to the empty string use the 175 * default location. We need to check for the empty string 176 * because some users "unset" environment variables by giving 177 * them no value, this isn't the same thing as removing it 178 * from the environment. 179 * 180 * We don't want that to attempt to open /.sunw/pkcs11_sofftoken 181 */ 182 if ((alt != NULL) && (strcmp(alt, "") != 0)) { 183 (void) snprintf(keystore_path, MAXPATHLEN, "%s/%s", 184 alt, KEYSTORE_PATH); 185 keystore_path_initialized = B_TRUE; 186 } else if ((home != NULL) && (strcmp(home, "") != 0)) { 187 /* alternate path not specified, try user's home dir */ 188 (void) snprintf(keystore_path, MAXPATHLEN, "%s/%s/%s", 189 home, SUNW_PATH, KEYSTORE_PATH); 190 keystore_path_initialized = B_TRUE; 191 } 192 return (keystore_path); 193 } 194 195 static char * 196 get_pub_obj_path(char *name) 197 { 198 bzero(name, sizeof (name)); 199 (void) snprintf(name, MAXPATHLEN, "%s/%s", 200 get_keystore_path(), PUB_OBJ_DIR); 201 return (name); 202 } 203 204 static char * 205 get_pri_obj_path(char *name) 206 { 207 bzero(name, sizeof (name)); 208 (void) snprintf(name, MAXPATHLEN, "%s/%s", 209 get_keystore_path(), PRI_OBJ_DIR); 210 return (name); 211 } 212 213 static char * 214 get_desc_file_path(char *name) 215 { 216 bzero(name, sizeof (name)); 217 (void) snprintf(name, MAXPATHLEN, "%s/%s", 218 get_keystore_path(), DS_FILE); 219 return (name); 220 } 221 222 static char * 223 get_tmp_desc_file_path(char *name) 224 { 225 bzero(name, sizeof (name)); 226 (void) snprintf(name, MAXPATHLEN, "%s/%s", 227 get_keystore_path(), TMP_DS_FILE); 228 return (name); 229 } 230 231 /* 232 * Calculates the offset for hashed_pin length and hashed pin 233 * 234 * Returns 0 if successful, -1 if there's any error. 235 * 236 * If successful, global variables "ks_hashed_pinlen_offset" will be set. 237 * 238 */ 239 static int 240 calculate_hashed_pin_offset(int fd) 241 { 242 uint64_t salt_length; 243 244 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET) 245 != KS_HASHED_PIN_SALT_LEN_OFFSET) { 246 return (-1); 247 } 248 249 if (readn_nointr(fd, (char *)&salt_length, 250 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 251 return (-1); 252 } 253 salt_length = SWAP64(salt_length); 254 255 ks_hashed_pinlen_offset = KS_HASHED_PIN_SALT_LEN_OFFSET 256 + KS_HASHED_PIN_SALT_LEN_SIZE + salt_length; 257 258 return (0); 259 260 } 261 262 /* 263 * acquire or release read/write lock on a specific file 264 * 265 * read_lock: true for read lock; false for write lock 266 * set_lock: true to set a lock; false to release a lock 267 */ 268 static int 269 lock_file(int fd, boolean_t read_lock, boolean_t set_lock) 270 { 271 272 flock_t lock_info; 273 int r; 274 275 lock_info.l_whence = SEEK_SET; 276 lock_info.l_start = 0; 277 lock_info.l_len = 0; /* l_len == 0 means until end of file */ 278 279 if (read_lock) { 280 lock_info.l_type = F_RDLCK; 281 } else { 282 lock_info.l_type = F_WRLCK; 283 } 284 285 if (set_lock) { 286 while ((r = fcntl(fd, F_SETLKW, &lock_info)) == -1) { 287 if (errno != EINTR) 288 break; 289 } 290 if (r == -1) { 291 return (-1); 292 } 293 } else { 294 lock_info.l_type = F_UNLCK; 295 while ((r = fcntl(fd, F_SETLKW, &lock_info)) == -1) { 296 if (errno != EINTR) 297 break; 298 } 299 if (r == -1) { 300 return (-1); 301 } 302 } 303 304 return (0); 305 } 306 307 int 308 create_keystore() 309 { 310 int fd, buf; 311 uint64_t hashed_pin_len, hashed_pin_salt_len, ulong_buf; 312 uchar_t ver_buf[KS_PKCS11_VER_SIZE]; 313 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 314 ks_desc_file[MAXPATHLEN]; 315 CK_BYTE salt[KS_KEY_SALT_SIZE]; 316 char *hashed_pin = NULL, *hashed_pin_salt = NULL; 317 char *alt; 318 319 /* keystore doesn't exist, create keystore directory */ 320 if (mkdir(get_keystore_path(), S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 321 if (errno == EEXIST) { 322 return (0); 323 } 324 325 if (errno == EACCES) { 326 return (-1); 327 } 328 329 /* can't create keystore directory */ 330 if (errno == ENOENT) { /* part of the path doesn't exist */ 331 char keystore[MAXPATHLEN]; 332 /* 333 * try to create $HOME/.sunw/pkcs11_softtoken if it 334 * doesn't exist. If it is a alternate path provided 335 * by the user, it should have existed. Will not 336 * create for them. 337 */ 338 alt = getenv(ALTERNATE_KEYSTORE_PATH); 339 if ((alt == NULL) || (strcmp(alt, "") == 0)) { 340 char *home = getenv("HOME"); 341 342 if (home == NULL || strcmp(home, "") == 0) { 343 return (-1); 344 } 345 /* create $HOME/.sunw/pkcs11_softtoken */ 346 (void) snprintf(keystore, sizeof (keystore), 347 "%s/%s/%s", home, SUNW_PATH, KEYSTORE_PATH); 348 if (mkdirp(keystore, 349 S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 350 return (-1); 351 } 352 } else { 353 return (-1); 354 } 355 } 356 } 357 358 /* create keystore description file */ 359 fd = open_nointr(get_desc_file_path(ks_desc_file), 360 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 361 if (fd < 0) { 362 if (errno == EEXIST) { 363 return (0); 364 } else { 365 /* can't create keystore description file */ 366 (void) rmdir(get_keystore_path()); 367 return (-1); 368 } 369 } 370 371 if (lock_file(fd, B_FALSE, B_TRUE) != 0) { 372 (void) unlink(ks_desc_file); 373 (void) close(fd); 374 (void) rmdir(get_keystore_path()); 375 return (-1); 376 } 377 378 if (mkdir(get_pub_obj_path(pub_obj_path), 379 S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 380 /* can't create directory for public objects */ 381 (void) lock_file(fd, B_FALSE, B_FALSE); 382 (void) unlink(ks_desc_file); 383 (void) close(fd); 384 (void) rmdir(get_keystore_path()); 385 return (-1); 386 } 387 388 if (mkdir(get_pri_obj_path(pri_obj_path), 389 S_IRUSR|S_IWUSR|S_IXUSR) < 0) { 390 /* can't create directory for private objects */ 391 (void) lock_file(fd, B_FALSE, B_FALSE); 392 (void) unlink(ks_desc_file); 393 (void) close(fd); 394 (void) rmdir(get_keystore_path()); 395 (void) rmdir(pub_obj_path); 396 return (-1); 397 } 398 399 400 /* write file format release number */ 401 bzero(ver_buf, sizeof (ver_buf)); 402 (void) strcpy((char *)ver_buf, KS_PKCS11_VER); 403 if ((writen_nointr(fd, (char *)ver_buf, sizeof (ver_buf))) 404 != sizeof (ver_buf)) { 405 goto cleanup; 406 } 407 408 /* write version number, version = 0 since keystore just created */ 409 buf = SWAP32(0); 410 if (writen_nointr(fd, (void *)&buf, KS_VER_SIZE) != KS_VER_SIZE) { 411 goto cleanup; 412 } 413 414 /* write monotonic-counter. Counter for keystore objects start at 1 */ 415 buf = SWAP32(1); 416 if (writen_nointr(fd, (void *)&buf, KS_COUNTER_SIZE) 417 != KS_COUNTER_SIZE) { 418 goto cleanup; 419 } 420 421 /* initial encryption key salt should be all NULL */ 422 bzero(salt, sizeof (salt)); 423 if (writen_nointr(fd, (void *)salt, KS_KEY_SALT_SIZE) 424 != KS_KEY_SALT_SIZE) { 425 goto cleanup; 426 } 427 428 /* initial HMAC key salt should also be all NULL */ 429 if (writen_nointr(fd, (void *)salt, KS_HMAC_SALT_SIZE) 430 != KS_HMAC_SALT_SIZE) { 431 goto cleanup; 432 } 433 434 /* generate the hashed pin salt, and MD5 hashed pin of default pin */ 435 if (soft_gen_hashed_pin((CK_CHAR_PTR)SOFT_DEFAULT_PIN, &hashed_pin, 436 &hashed_pin_salt) < 0) { 437 goto cleanup; 438 } 439 440 if ((hashed_pin_salt == NULL) || (hashed_pin == NULL)) { 441 goto cleanup; 442 } 443 444 hashed_pin_salt_len = (uint64_t)strlen(hashed_pin_salt); 445 hashed_pin_len = (uint64_t)strlen(hashed_pin); 446 447 /* write hashed pin salt length */ 448 ulong_buf = SWAP64(hashed_pin_salt_len); 449 if (writen_nointr(fd, (void *)&ulong_buf, KS_HASHED_PIN_SALT_LEN_SIZE) 450 != KS_HASHED_PIN_SALT_LEN_SIZE) { 451 goto cleanup; 452 } 453 454 if (writen_nointr(fd, (void *)hashed_pin_salt, 455 hashed_pin_salt_len) != hashed_pin_salt_len) { 456 goto cleanup; 457 } 458 459 /* write MD5 hashed pin of the default pin */ 460 ulong_buf = SWAP64(hashed_pin_len); 461 if (writen_nointr(fd, (void *)&ulong_buf, KS_HASHED_PINLEN_SIZE) 462 != KS_HASHED_PINLEN_SIZE) { 463 goto cleanup; 464 } 465 466 if (writen_nointr(fd, (void *)hashed_pin, hashed_pin_len) 467 != hashed_pin_len) { 468 goto cleanup; 469 } 470 471 (void) lock_file(fd, B_FALSE, B_FALSE); 472 473 (void) close(fd); 474 freezero(hashed_pin_salt, hashed_pin_salt_len); 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 freezero(*hashed_pin, hashed_pin_size + 1); 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 if (!lock_held) { 1159 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 1160 ret_val = -1; 1161 } 1162 } 1163 1164 (void) close(fd); 1165 return (ret_val); 1166 } 1167 1168 1169 /* 1170 * Generate a 16-byte Initialization Vector (IV). 1171 */ 1172 CK_RV 1173 soft_gen_iv(CK_BYTE *iv) 1174 { 1175 return (pkcs11_get_nzero_urandom(iv, 16) < 0 ? 1176 CKR_DEVICE_ERROR : CKR_OK); 1177 } 1178 1179 1180 /* 1181 * This function reads all the data until the end of the file, and 1182 * put the data into the "buf" in argument. Memory for buf will 1183 * be allocated in this function. It is the caller's responsibility 1184 * to free it. The number of bytes read will be returned 1185 * in the argument "bytes_read" 1186 * 1187 * returns CKR_OK if no error. Other CKR error codes if there's an error 1188 */ 1189 static CK_RV 1190 read_obj_data(int old_fd, char **buf, ssize_t *bytes_read) 1191 { 1192 1193 ssize_t nread, loop_count; 1194 char *buf1 = NULL; 1195 1196 *buf = malloc(BUFSIZ); 1197 if (*buf == NULL) { 1198 return (CKR_HOST_MEMORY); 1199 } 1200 1201 nread = readn_nointr(old_fd, *buf, BUFSIZ); 1202 if (nread < 0) { 1203 free(*buf); 1204 return (CKR_FUNCTION_FAILED); 1205 } 1206 loop_count = 1; 1207 while (nread == (loop_count * BUFSIZ)) { 1208 ssize_t nread_tmp; 1209 1210 loop_count++; 1211 /* more than BUFSIZ of data */ 1212 buf1 = realloc(*buf, loop_count * BUFSIZ); 1213 if (buf1 == NULL) { 1214 free(*buf); 1215 return (CKR_HOST_MEMORY); 1216 } 1217 *buf = buf1; 1218 nread_tmp = readn_nointr(old_fd, 1219 *buf + ((loop_count - 1) * BUFSIZ), BUFSIZ); 1220 if (nread_tmp < 0) { 1221 free(*buf); 1222 return (CKR_FUNCTION_FAILED); 1223 } 1224 nread += nread_tmp; 1225 } 1226 *bytes_read = nread; 1227 return (CKR_OK); 1228 } 1229 1230 /* 1231 * Re-encrypt an object using the provided new_enc_key. The new HMAC 1232 * is calculated using the new_hmac_key. The global static variables 1233 * enc_key, and hmac_key will be used for decrypting the original 1234 * object, and verifying its signature. 1235 * 1236 * The re-encrypted object will be stored in the file named 1237 * in the "new_obj_name" variable. The content of the "original" 1238 * file named in "orig_obj_name" is not disturbed. 1239 * 1240 * Returns 0 if there's no error, returns -1 otherwise. 1241 * 1242 */ 1243 static int 1244 reencrypt_obj(soft_object_t *new_enc_key, soft_object_t *new_hmac_key, 1245 char *orig_obj_name, char *new_obj_name) 1246 { 1247 int old_fd, new_fd, version, ret_val = -1; 1248 CK_BYTE iv[OBJ_IV_SIZE], old_iv[OBJ_IV_SIZE]; 1249 ssize_t nread; 1250 CK_ULONG decrypted_len, encrypted_len, hmac_len; 1251 CK_BYTE hmac[OBJ_HMAC_SIZE], *decrypted_buf = NULL, *buf = NULL; 1252 1253 old_fd = open_nointr(orig_obj_name, O_RDONLY|O_NONBLOCK); 1254 if (old_fd < 0) { 1255 return (-1); 1256 } 1257 1258 if (acquire_file_lock(&old_fd, orig_obj_name, O_RDONLY) != 0) { 1259 if (old_fd > 0) { 1260 (void) close(old_fd); 1261 } 1262 return (-1); 1263 } 1264 1265 new_fd = open_nointr(new_obj_name, 1266 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 1267 if (new_fd < 0) { 1268 (void) close(old_fd); 1269 return (-1); 1270 } 1271 1272 if (lock_file(new_fd, B_FALSE, B_TRUE) != 0) { 1273 /* unlock old file */ 1274 (void) lock_file(old_fd, B_TRUE, B_FALSE); 1275 (void) close(old_fd); 1276 (void) close(new_fd); 1277 return (-1); 1278 } 1279 1280 /* read version, increment, and write to tmp file */ 1281 if (readn_nointr(old_fd, (char *)&version, OBJ_VER_SIZE) 1282 != OBJ_VER_SIZE) { 1283 goto cleanup; 1284 } 1285 1286 version = SWAP32(version); 1287 version++; 1288 version = SWAP32(version); 1289 1290 if (writen_nointr(new_fd, (char *)&version, OBJ_VER_SIZE) 1291 != OBJ_VER_SIZE) { 1292 goto cleanup; 1293 } 1294 1295 /* read old iv */ 1296 if (readn_nointr(old_fd, (char *)old_iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 1297 goto cleanup; 1298 } 1299 1300 /* generate new IV */ 1301 if (soft_gen_iv(iv) != CKR_OK) { 1302 goto cleanup; 1303 } 1304 1305 if (writen_nointr(new_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 1306 goto cleanup; 1307 } 1308 1309 /* seek to the original encrypted data, and read all of them */ 1310 if (lseek(old_fd, OBJ_DATA_OFFSET, SEEK_SET) != OBJ_DATA_OFFSET) { 1311 goto cleanup; 1312 } 1313 1314 if (read_obj_data(old_fd, (char **)&buf, &nread) != CKR_OK) { 1315 goto cleanup; 1316 } 1317 1318 /* decrypt data using old key */ 1319 decrypted_len = 0; 1320 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread, 1321 NULL, &decrypted_len) != CKR_OK) { 1322 freezero(buf, nread); 1323 goto cleanup; 1324 } 1325 1326 decrypted_buf = malloc(decrypted_len); 1327 if (decrypted_buf == NULL) { 1328 freezero(buf, nread); 1329 goto cleanup; 1330 } 1331 1332 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread, 1333 decrypted_buf, &decrypted_len) != CKR_OK) { 1334 freezero(buf, nread); 1335 freezero(decrypted_buf, decrypted_len); 1336 } 1337 1338 freezero(buf, nread); 1339 1340 /* re-encrypt with new key */ 1341 encrypted_len = 0; 1342 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf, 1343 decrypted_len, NULL, &encrypted_len) != CKR_OK) { 1344 freezero(decrypted_buf, decrypted_len); 1345 goto cleanup; 1346 } 1347 1348 buf = malloc(encrypted_len); 1349 if (buf == NULL) { 1350 freezero(decrypted_buf, decrypted_len); 1351 goto cleanup; 1352 } 1353 1354 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf, 1355 decrypted_len, buf, &encrypted_len) != CKR_OK) { 1356 freezero(buf, encrypted_len); 1357 freezero(buf, decrypted_len); 1358 goto cleanup; 1359 } 1360 1361 freezero(decrypted_buf, decrypted_len); 1362 1363 /* calculate hmac on re-encrypted data using new hmac key */ 1364 hmac_len = OBJ_HMAC_SIZE; 1365 if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf, 1366 encrypted_len, hmac, &hmac_len) != CKR_OK) { 1367 freezero(buf, encrypted_len); 1368 goto cleanup; 1369 } 1370 1371 /* just for sanity check */ 1372 if (hmac_len != OBJ_HMAC_SIZE) { 1373 freezero(buf, encrypted_len); 1374 goto cleanup; 1375 } 1376 1377 /* write new hmac */ 1378 if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE) 1379 != OBJ_HMAC_SIZE) { 1380 freezero(buf, encrypted_len); 1381 goto cleanup; 1382 } 1383 1384 /* write re-encrypted buffer to temp file */ 1385 if (writen_nointr(new_fd, (void *)buf, encrypted_len) 1386 != encrypted_len) { 1387 freezero(buf, encrypted_len); 1388 goto cleanup; 1389 } 1390 freezero(buf, encrypted_len); 1391 ret_val = 0; 1392 1393 cleanup: 1394 /* unlock the files */ 1395 (void) lock_file(old_fd, B_TRUE, B_FALSE); 1396 (void) lock_file(new_fd, B_FALSE, B_FALSE); 1397 1398 (void) close(old_fd); 1399 (void) close(new_fd); 1400 if (ret_val != 0) { 1401 (void) remove(new_obj_name); 1402 } 1403 return (ret_val); 1404 } 1405 1406 /* 1407 * FUNCTION: soft_keystore_setpin 1408 * 1409 * ARGUMENTS: 1410 * newpin: new pin entered by the user. 1411 * lock_held: TRUE if the lock is held by caller. 1412 * 1413 * RETURN VALUE: 1414 * 0: no error 1415 * -1: failure 1416 * 1417 * DESCRIPTION: 1418 * 1419 * This function does the following: 1420 * 1421 * 1) Generates crypted value of newpin and store it 1422 * in keystore description file. 1423 * 2) Dervies the new encryption key from the newpin. This key 1424 * will be used to re-encrypt the private token objects. 1425 * 3) Re-encrypt all of this user's existing private token 1426 * objects (if any). 1427 * 4) Increments the keystore version number. 1428 */ 1429 int 1430 soft_keystore_setpin(uchar_t *oldpin, uchar_t *newpin, boolean_t lock_held) 1431 { 1432 int fd, tmp_ks_fd, version, ret_val = -1; 1433 soft_object_t *new_crypt_key = NULL, *new_hmac_key = NULL; 1434 char filebuf[BUFSIZ]; 1435 DIR *pri_dirp; 1436 struct dirent *pri_ent; 1437 char pri_obj_path[MAXPATHLEN], ks_desc_file[MAXPATHLEN], 1438 tmp_ks_desc_name[MAXPATHLEN]; 1439 typedef struct priobjs { 1440 char orig_name[MAXPATHLEN]; 1441 char tmp_name[MAXPATHLEN]; 1442 struct priobjs *next; 1443 } priobjs_t; 1444 priobjs_t *pri_objs = NULL, *tmp; 1445 CK_BYTE *crypt_salt = NULL, *hmac_salt = NULL; 1446 boolean_t pin_never_set = B_FALSE, user_logged_in; 1447 char *new_hashed_pin = NULL; 1448 uint64_t hashed_pin_salt_length, new_hashed_pin_len, swaped_val; 1449 char *hashed_pin_salt = NULL; 1450 priobjs_t *obj; 1451 1452 if ((enc_key == NULL) || 1453 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 1454 user_logged_in = B_FALSE; 1455 } else { 1456 user_logged_in = B_TRUE; 1457 } 1458 1459 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_TRUE, 1460 lock_held)) < 0) { 1461 return (-1); 1462 } 1463 1464 (void) get_desc_file_path(ks_desc_file); 1465 (void) get_tmp_desc_file_path(tmp_ks_desc_name); 1466 1467 /* 1468 * create a tempoary file for the keystore description 1469 * file for updating version and counter information 1470 */ 1471 tmp_ks_fd = open_nointr(tmp_ks_desc_name, 1472 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 1473 if (tmp_ks_fd < 0) { 1474 (void) close(fd); 1475 return (-1); 1476 } 1477 1478 /* read and write PKCS version to temp file */ 1479 if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE) 1480 != KS_PKCS11_VER_SIZE) { 1481 goto cleanup; 1482 } 1483 1484 if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE) 1485 != KS_PKCS11_VER_SIZE) { 1486 goto cleanup; 1487 } 1488 1489 /* get version number, and write updated number to temp file */ 1490 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 1491 goto cleanup; 1492 } 1493 1494 version = SWAP32(version); 1495 version++; 1496 version = SWAP32(version); 1497 1498 if (writen_nointr(tmp_ks_fd, (void *)&version, KS_VER_SIZE) 1499 != KS_VER_SIZE) { 1500 goto cleanup; 1501 } 1502 1503 1504 /* read and write counter, no modification necessary */ 1505 if (readn_nointr(fd, filebuf, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) { 1506 goto cleanup; 1507 } 1508 1509 if (writen_nointr(tmp_ks_fd, filebuf, KS_COUNTER_SIZE) 1510 != KS_COUNTER_SIZE) { 1511 goto cleanup; 1512 } 1513 1514 /* read old encryption salt */ 1515 crypt_salt = malloc(KS_KEY_SALT_SIZE); 1516 if (crypt_salt == NULL) { 1517 goto cleanup; 1518 } 1519 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 1520 != KS_KEY_SALT_SIZE) { 1521 goto cleanup; 1522 } 1523 1524 /* read old hmac salt */ 1525 hmac_salt = malloc(KS_HMAC_SALT_SIZE); 1526 if (hmac_salt == NULL) { 1527 goto cleanup; 1528 } 1529 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE) 1530 != KS_HMAC_SALT_SIZE) { 1531 goto cleanup; 1532 } 1533 1534 /* just create some empty bytes */ 1535 bzero(filebuf, sizeof (filebuf)); 1536 1537 if (memcmp(crypt_salt, filebuf, KS_KEY_SALT_SIZE) == 0) { 1538 /* PIN as never been set */ 1539 CK_BYTE *new_crypt_salt = NULL, *new_hmac_salt = NULL; 1540 1541 pin_never_set = B_TRUE; 1542 if (soft_gen_crypt_key(newpin, &new_crypt_key, &new_crypt_salt) 1543 != CKR_OK) { 1544 goto cleanup; 1545 } 1546 if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt, 1547 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) { 1548 freezero(new_crypt_salt, 1549 KS_KEY_SALT_SIZE); 1550 (void) soft_cleanup_object(new_crypt_key); 1551 goto cleanup; 1552 } 1553 freezero(new_crypt_salt, KS_KEY_SALT_SIZE); 1554 1555 if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt) 1556 != CKR_OK) { 1557 (void) soft_cleanup_object(new_crypt_key); 1558 goto cleanup; 1559 } 1560 if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt, 1561 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) { 1562 freezero(new_hmac_salt, 1563 KS_HMAC_SALT_SIZE); 1564 goto cleanup3; 1565 } 1566 freezero(new_hmac_salt, KS_HMAC_SALT_SIZE); 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 freezero(hashed_pin_salt, 1616 hashed_pin_salt_length + 1); 1617 goto cleanup3; 1618 } 1619 1620 if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length)) 1621 != (ssize_t)hashed_pin_salt_length) { 1622 freezero(hashed_pin_salt, 1623 hashed_pin_salt_length + 1); 1624 goto cleanup3; 1625 } 1626 1627 hashed_pin_salt[hashed_pin_salt_length] = '\0'; 1628 1629 /* old hashed pin length and value can be ignored, generate new one */ 1630 if (soft_gen_hashed_pin(newpin, &new_hashed_pin, 1631 &hashed_pin_salt) < 0) { 1632 freezero(hashed_pin_salt, 1633 hashed_pin_salt_length + 1); 1634 goto cleanup3; 1635 } 1636 1637 freezero(hashed_pin_salt, hashed_pin_salt_length + 1); 1638 1639 if (new_hashed_pin == NULL) { 1640 goto cleanup3; 1641 } 1642 1643 new_hashed_pin_len = strlen(new_hashed_pin); 1644 1645 /* write new hashed pin length to file */ 1646 swaped_val = SWAP64(new_hashed_pin_len); 1647 if (writen_nointr(tmp_ks_fd, (void *)&swaped_val, 1648 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) { 1649 goto cleanup3; 1650 } 1651 1652 if (writen_nointr(tmp_ks_fd, (void *)new_hashed_pin, 1653 new_hashed_pin_len) != (ssize_t)new_hashed_pin_len) { 1654 goto cleanup3; 1655 } 1656 1657 if (pin_never_set) { 1658 /* there was no private object, no need to re-encrypt them */ 1659 goto rename_desc_file; 1660 } 1661 1662 /* re-encrypt all the private objects */ 1663 pri_dirp = opendir(get_pri_obj_path(pri_obj_path)); 1664 if (pri_dirp == NULL) { 1665 /* 1666 * this directory should exist, even if it doesn't contain 1667 * any objects. Don't want to update the pin if the 1668 * keystore is somehow messed up. 1669 */ 1670 1671 goto cleanup3; 1672 } 1673 1674 /* if user did not login, need to set the old pin */ 1675 if (!user_logged_in) { 1676 if (soft_keystore_authpin(oldpin) != 0) { 1677 goto cleanup3; 1678 } 1679 } 1680 1681 while ((pri_ent = readdir(pri_dirp)) != NULL) { 1682 1683 if ((strcmp(pri_ent->d_name, ".") == 0) || 1684 (strcmp(pri_ent->d_name, "..") == 0) || 1685 (strncmp(pri_ent->d_name, TMP_OBJ_PREFIX, 1686 strlen(TMP_OBJ_PREFIX)) == 0)) { 1687 continue; 1688 } 1689 1690 obj = malloc(sizeof (priobjs_t)); 1691 if (obj == NULL) { 1692 goto cleanup2; 1693 } 1694 (void) snprintf(obj->orig_name, MAXPATHLEN, 1695 "%s/%s", pri_obj_path, pri_ent->d_name); 1696 (void) snprintf(obj->tmp_name, MAXPATHLEN, "%s/%s%s", 1697 pri_obj_path, TMP_OBJ_PREFIX, 1698 (pri_ent->d_name) + OBJ_PREFIX_LEN); 1699 if (reencrypt_obj(new_crypt_key, new_hmac_key, 1700 obj->orig_name, obj->tmp_name) != 0) { 1701 free(obj); 1702 goto cleanup2; 1703 } 1704 1705 /* insert into list of file to be renamed */ 1706 if (pri_objs == NULL) { 1707 obj->next = NULL; 1708 pri_objs = obj; 1709 } else { 1710 obj->next = pri_objs; 1711 pri_objs = obj; 1712 } 1713 } 1714 1715 /* rename all the private objects */ 1716 tmp = pri_objs; 1717 while (tmp) { 1718 (void) rename(tmp->tmp_name, tmp->orig_name); 1719 tmp = tmp->next; 1720 } 1721 1722 rename_desc_file: 1723 1724 /* destroy the old encryption key, and hmac key */ 1725 if ((!pin_never_set) && (user_logged_in)) { 1726 (void) soft_cleanup_object(enc_key); 1727 (void) soft_cleanup_object(hmac_key); 1728 } 1729 1730 if (user_logged_in) { 1731 enc_key = new_crypt_key; 1732 hmac_key = new_hmac_key; 1733 } 1734 (void) rename(tmp_ks_desc_name, ks_desc_file); 1735 1736 ret_val = 0; 1737 1738 cleanup2: 1739 if (pri_objs != NULL) { 1740 priobjs_t *p = pri_objs; 1741 while (p) { 1742 tmp = p->next; 1743 free(p); 1744 p = tmp; 1745 } 1746 } 1747 if (!pin_never_set) { 1748 (void) closedir(pri_dirp); 1749 } 1750 1751 if ((!user_logged_in) && (!pin_never_set)) { 1752 (void) soft_cleanup_object(enc_key); 1753 (void) soft_cleanup_object(hmac_key); 1754 enc_key = NULL; 1755 hmac_key = NULL; 1756 } 1757 cleanup3: 1758 if ((ret_val != 0) || (!user_logged_in)) { 1759 (void) soft_cleanup_object(new_crypt_key); 1760 (void) soft_cleanup_object(new_hmac_key); 1761 } 1762 1763 cleanup: 1764 if (!lock_held) { 1765 if (lock_file(fd, B_FALSE, B_FALSE) < 0) { 1766 ret_val = 1; 1767 } 1768 } 1769 freezero(crypt_salt, KS_KEY_SALT_SIZE); 1770 freezero(hmac_salt, KS_HMAC_SALT_SIZE); 1771 (void) close(fd); 1772 (void) close(tmp_ks_fd); 1773 if (ret_val != 0) { 1774 (void) remove(tmp_ks_desc_name); 1775 } 1776 return (ret_val); 1777 } 1778 1779 /* 1780 * FUNCTION: soft_keystore_authpin 1781 * 1782 * ARGUMENTS: 1783 * pin: pin specified by the user for logging into 1784 * the keystore. 1785 * 1786 * RETURN VALUE: 1787 * 0: if no error 1788 * -1: if there is any error 1789 * 1790 * DESCRIPTION: 1791 * 1792 * This function takes the pin specified in the argument 1793 * and generates an encryption key based on the pin. 1794 * The generated encryption key will be used for 1795 * all future encryption and decryption for private 1796 * objects. Before this function is called, none 1797 * of the keystore related interfaces is able 1798 * to decrypt/encrypt any private object. 1799 */ 1800 int 1801 soft_keystore_authpin(uchar_t *pin) 1802 { 1803 int fd; 1804 int ret_val = -1; 1805 CK_BYTE *crypt_salt = NULL, *hmac_salt; 1806 1807 /* get the salt from the keystore description file */ 1808 if ((fd = open_and_lock_keystore_desc(O_RDONLY, 1809 B_FALSE, B_FALSE)) < 0) { 1810 return (-1); 1811 } 1812 1813 crypt_salt = malloc(KS_KEY_SALT_SIZE); 1814 if (crypt_salt == NULL) { 1815 goto cleanup; 1816 } 1817 1818 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) { 1819 goto cleanup; 1820 } 1821 1822 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 1823 != KS_KEY_SALT_SIZE) { 1824 goto cleanup; 1825 } 1826 1827 if (soft_gen_crypt_key(pin, &enc_key, (CK_BYTE **)&crypt_salt) 1828 != CKR_OK) { 1829 goto cleanup; 1830 } 1831 1832 hmac_salt = malloc(KS_HMAC_SALT_SIZE); 1833 if (hmac_salt == NULL) { 1834 goto cleanup; 1835 } 1836 1837 if (lseek(fd, KS_HMAC_SALT_OFFSET, SEEK_SET) != KS_HMAC_SALT_OFFSET) { 1838 goto cleanup; 1839 } 1840 1841 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE) 1842 != KS_HMAC_SALT_SIZE) { 1843 goto cleanup; 1844 } 1845 1846 if (soft_gen_hmac_key(pin, &hmac_key, (CK_BYTE **)&hmac_salt) 1847 != CKR_OK) { 1848 goto cleanup; 1849 } 1850 1851 ret_val = 0; 1852 1853 cleanup: 1854 /* unlock the file */ 1855 (void) lock_file(fd, B_TRUE, B_FALSE); 1856 (void) close(fd); 1857 freezero(crypt_salt, KS_KEY_SALT_SIZE); 1858 freezero(hmac_salt, KS_HMAC_SALT_SIZE); 1859 return (ret_val); 1860 } 1861 1862 /* 1863 * FUNCTION: soft_keystore_get_objs 1864 * 1865 * ARGUMENTS: 1866 * 1867 * search_type: Specify type of objects to return. 1868 * lock_held: TRUE if the lock is held by caller. 1869 * 1870 * 1871 * RETURN VALUE: 1872 * 1873 * NULL: if there are no object in the database. 1874 * 1875 * Otherwise, linked list of objects as requested 1876 * in search type. 1877 * 1878 * The linked list returned will need to be freed 1879 * by the caller. 1880 * 1881 * DESCRIPTION: 1882 * 1883 * Returns objects as requested. 1884 * 1885 * If private objects is requested, and the caller 1886 * has not previously passed in the pin or if the pin 1887 * passed in is wrong, private objects will not 1888 * be returned. 1889 * 1890 * The buffers returned for private objects are already 1891 * decrypted. 1892 */ 1893 CK_RV 1894 soft_keystore_get_objs(ks_search_type_t search_type, 1895 ks_obj_t **result_obj_list, boolean_t lock_held) 1896 { 1897 DIR *dirp; 1898 ks_obj_handle_t ks_handle; 1899 CK_RV rv; 1900 ks_obj_t *tmp; 1901 int ks_fd; 1902 1903 *result_obj_list = NULL; 1904 1905 /* 1906 * lock the keystore description file in "read" mode so that 1907 * objects won't get added/deleted/modified while we are 1908 * doing the search 1909 */ 1910 if ((ks_fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE, 1911 B_FALSE)) < 0) { 1912 return (CKR_FUNCTION_FAILED); 1913 } 1914 1915 if ((search_type == ALL_TOKENOBJS) || (search_type == PUB_TOKENOBJS)) { 1916 1917 char pub_obj_path[MAXPATHLEN]; 1918 1919 ks_handle.public = B_TRUE; 1920 1921 if ((dirp = opendir(get_pub_obj_path(pub_obj_path))) == NULL) { 1922 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1923 (void) close(ks_fd); 1924 return (CKR_FUNCTION_FAILED); 1925 } 1926 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list, 1927 lock_held); 1928 if (rv != CKR_OK) { 1929 (void) closedir(dirp); 1930 goto cleanup; 1931 } 1932 1933 (void) closedir(dirp); 1934 } 1935 1936 if ((search_type == ALL_TOKENOBJS) || (search_type == PRI_TOKENOBJS)) { 1937 1938 char pri_obj_path[MAXPATHLEN]; 1939 1940 if ((enc_key == NULL) || 1941 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 1942 /* has not login - no need to go any further */ 1943 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1944 (void) close(ks_fd); 1945 return (CKR_OK); 1946 } 1947 1948 ks_handle.public = B_FALSE; 1949 1950 if ((dirp = opendir(get_pri_obj_path(pri_obj_path))) == NULL) { 1951 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1952 (void) close(ks_fd); 1953 return (CKR_OK); 1954 } 1955 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list, 1956 lock_held); 1957 if (rv != CKR_OK) { 1958 (void) closedir(dirp); 1959 goto cleanup; 1960 } 1961 1962 (void) closedir(dirp); 1963 } 1964 /* close the keystore description file */ 1965 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1966 (void) close(ks_fd); 1967 return (CKR_OK); 1968 cleanup: 1969 1970 /* close the keystore description file */ 1971 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1972 (void) close(ks_fd); 1973 1974 /* free all the objects found before hitting the error */ 1975 tmp = *result_obj_list; 1976 while (tmp) { 1977 *result_obj_list = tmp->next; 1978 freezero(tmp->buf, tmp->size); 1979 free(tmp); 1980 tmp = *result_obj_list; 1981 } 1982 *result_obj_list = NULL; 1983 return (rv); 1984 } 1985 1986 1987 /* 1988 * FUNCTION: soft_keystore_get_single_obj 1989 * 1990 * ARGUMENTS: 1991 * ks_handle: handle of the key store object to be accessed 1992 * lock_held: TRUE if the lock is held by caller. 1993 * 1994 * RETURN VALUE: 1995 * 1996 * NULL: if handle doesn't match any object 1997 * 1998 * Otherwise, the object is returned in 1999 * the same structure used in soft_keystore_get_objs(). 2000 * The structure need to be freed by the caller. 2001 * 2002 * DESCRIPTION: 2003 * 2004 * Retrieves the object specified by the object 2005 * handle to the caller. 2006 * 2007 * If a private object is requested, and the caller 2008 * has not previously passed in the pin or if the pin 2009 * passed in is wrong, the requested private object will not 2010 * be returned. 2011 * 2012 * The buffer returned for the requested private object 2013 * is already decrypted. 2014 */ 2015 CK_RV 2016 soft_keystore_get_single_obj(ks_obj_handle_t *ks_handle, 2017 ks_obj_t **return_obj, boolean_t lock_held) 2018 { 2019 2020 ks_obj_t *obj; 2021 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE]; 2022 uchar_t *buf, *decrypted_buf; 2023 int fd; 2024 ssize_t nread; 2025 CK_RV rv = CKR_FUNCTION_FAILED; 2026 2027 if (!(ks_handle->public)) { 2028 if ((enc_key == NULL) || 2029 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2030 return (CKR_FUNCTION_FAILED); 2031 } 2032 } 2033 2034 if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY, 2035 lock_held)) < 0) { 2036 return (CKR_FUNCTION_FAILED); 2037 } 2038 2039 obj = malloc(sizeof (ks_obj_t)); 2040 if (obj == NULL) { 2041 return (CKR_HOST_MEMORY); 2042 } 2043 2044 obj->next = NULL; 2045 2046 (void) strcpy((char *)((obj->ks_handle).name), 2047 (char *)ks_handle->name); 2048 (obj->ks_handle).public = ks_handle->public; 2049 2050 /* 1st get the version */ 2051 if (readn_nointr(fd, &(obj->obj_version), OBJ_VER_SIZE) 2052 != OBJ_VER_SIZE) { 2053 goto cleanup; 2054 } 2055 obj->obj_version = SWAP32(obj->obj_version); 2056 2057 /* Then, read the IV */ 2058 if (readn_nointr(fd, iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 2059 goto cleanup; 2060 } 2061 2062 /* Then, read the HMAC */ 2063 if (readn_nointr(fd, obj_hmac, OBJ_HMAC_SIZE) != OBJ_HMAC_SIZE) { 2064 goto cleanup; 2065 } 2066 2067 /* read the object */ 2068 rv = read_obj_data(fd, (char **)&buf, &nread); 2069 if (rv != CKR_OK) { 2070 goto cleanup; 2071 } 2072 2073 if (ks_handle->public) { 2074 obj->size = nread; 2075 obj->buf = buf; 2076 *return_obj = obj; 2077 } else { 2078 2079 CK_ULONG out_len = 0, hmac_size; 2080 2081 /* verify HMAC of the object, make sure it matches */ 2082 hmac_size = OBJ_HMAC_SIZE; 2083 if (soft_keystore_hmac(hmac_key, B_FALSE, buf, 2084 nread, obj_hmac, &hmac_size) != CKR_OK) { 2085 freezero(buf, nread); 2086 rv = CKR_FUNCTION_FAILED; 2087 goto cleanup; 2088 } 2089 2090 /* decrypt object */ 2091 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread, 2092 NULL, &out_len) != CKR_OK) { 2093 freezero(buf, nread); 2094 rv = CKR_FUNCTION_FAILED; 2095 goto cleanup; 2096 } 2097 2098 decrypted_buf = malloc(sizeof (uchar_t) * out_len); 2099 if (decrypted_buf == NULL) { 2100 freezero(buf, nread); 2101 rv = CKR_HOST_MEMORY; 2102 goto cleanup; 2103 } 2104 2105 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread, 2106 decrypted_buf, &out_len) != CKR_OK) { 2107 freezero(buf, nread); 2108 freezero(decrypted_buf, out_len); 2109 rv = CKR_FUNCTION_FAILED; 2110 goto cleanup; 2111 } 2112 2113 obj->size = out_len - MAXPATHLEN; 2114 2115 /* 2116 * decrypted buf here actually contains full path name of 2117 * object plus the actual data. so, need to skip the 2118 * full pathname. 2119 * See prepare_data_for_encrypt() function in the file 2120 * to understand how and why the pathname is added. 2121 */ 2122 obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN)); 2123 if (obj->buf == NULL) { 2124 freezero(buf, nread); 2125 freezero(decrypted_buf, out_len); 2126 rv = CKR_HOST_MEMORY; 2127 goto cleanup; 2128 } 2129 (void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size); 2130 freezero(buf, nread); 2131 freezero(decrypted_buf, out_len); 2132 *return_obj = obj; 2133 } 2134 2135 cleanup: 2136 2137 if (rv != CKR_OK) { 2138 free(obj); 2139 } 2140 2141 /* unlock the file after reading */ 2142 if (!lock_held) { 2143 (void) lock_file(fd, B_TRUE, B_FALSE); 2144 } 2145 2146 (void) close(fd); 2147 2148 return (rv); 2149 } 2150 2151 2152 /* 2153 * FUNCTION: soft_keystore_put_new_obj 2154 * 2155 * ARGUMENTS: 2156 * buf: buffer containing un-encrypted data 2157 * to be stored in keystore. 2158 * len: length of data 2159 * public: TRUE if it is a public object, 2160 * FALSE if it is private obj 2161 * lock_held: TRUE if the lock is held by caller. 2162 * keyhandle: pointer to object handle to 2163 * receive keyhandle for new object 2164 * 2165 * RETURN VALUE: 2166 * 0: object successfully stored in file 2167 * -1: some error occurred, object is not stored in file. 2168 * 2169 * DESCRIPTION: 2170 * This API is used to write a newly created token object 2171 * to keystore. 2172 * 2173 * This function does the following: 2174 * 2175 * 1) Creates a token object file based on "public" parameter. 2176 * 2) Generates a new IV and stores it in obj_meta_data_t if it is 2177 * private object. 2178 * 3) Set object version number to 1. 2179 * 4) If it is a private object, it will be encrypted before 2180 * being written to the newly created keystore token object 2181 * file. 2182 * 5) Calculates the obj_chksum in obj_meta_data_t. 2183 * 6) Calculates the pin_chksum in obj_meta_data_t. 2184 * 7) Increments the keystore version number. 2185 */ 2186 int 2187 soft_keystore_put_new_obj(uchar_t *buf, size_t len, boolean_t public, 2188 boolean_t lock_held, ks_obj_handle_t *keyhandle) 2189 { 2190 2191 int fd, tmp_ks_fd, obj_fd; 2192 unsigned int counter, version; 2193 uchar_t obj_hmac[OBJ_HMAC_SIZE]; 2194 CK_BYTE iv[OBJ_IV_SIZE]; 2195 char obj_name[MAXPATHLEN], tmp_ks_desc_name[MAXPATHLEN]; 2196 char filebuf[BUFSIZ]; 2197 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2198 ks_desc_file[MAXPATHLEN]; 2199 CK_ULONG hmac_size; 2200 ssize_t nread; 2201 2202 if (keyhandle == NULL) { 2203 return (-1); 2204 } 2205 2206 /* if it is private object, make sure we have the key */ 2207 if (!public) { 2208 if ((enc_key == NULL) || 2209 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2210 return (-1); 2211 } 2212 } 2213 2214 /* open keystore, and set write lock */ 2215 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2216 lock_held)) < 0) { 2217 return (-1); 2218 } 2219 2220 (void) get_desc_file_path(ks_desc_file); 2221 (void) get_tmp_desc_file_path(tmp_ks_desc_name); 2222 2223 /* 2224 * create a tempoary file for the keystore description 2225 * file for updating version and counter information 2226 */ 2227 tmp_ks_fd = open_nointr(tmp_ks_desc_name, 2228 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2229 if (tmp_ks_fd < 0) { 2230 (void) close(fd); 2231 return (-1); 2232 } 2233 2234 /* read and write pkcs11 version */ 2235 if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE) 2236 != KS_PKCS11_VER_SIZE) { 2237 goto cleanup; 2238 } 2239 2240 if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE) 2241 != KS_PKCS11_VER_SIZE) { 2242 goto cleanup; 2243 } 2244 2245 /* get version number, and write updated number to temp file */ 2246 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 2247 goto cleanup; 2248 } 2249 2250 version = SWAP32(version); 2251 version++; 2252 version = SWAP32(version); 2253 2254 if (writen_nointr(tmp_ks_fd, (void *)&version, 2255 KS_VER_SIZE) != KS_VER_SIZE) { 2256 goto cleanup; 2257 } 2258 2259 /* get object count value */ 2260 if (readn_nointr(fd, &counter, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) { 2261 goto cleanup; 2262 } 2263 counter = SWAP32(counter); 2264 2265 bzero(obj_name, sizeof (obj_name)); 2266 if (public) { 2267 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d", 2268 get_pub_obj_path(pub_obj_path), OBJ_PREFIX, counter); 2269 } else { 2270 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d", 2271 get_pri_obj_path(pri_obj_path), OBJ_PREFIX, counter); 2272 } 2273 2274 /* create object file */ 2275 obj_fd = open_nointr(obj_name, 2276 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2277 if (obj_fd < 0) { 2278 /* can't create object file */ 2279 goto cleanup; 2280 } 2281 2282 /* lock object file for writing */ 2283 if (lock_file(obj_fd, B_FALSE, B_TRUE) != 0) { 2284 (void) close(obj_fd); 2285 goto cleanup2; 2286 } 2287 2288 /* write object meta data */ 2289 version = SWAP32(1); 2290 if (writen_nointr(obj_fd, (void *)&version, sizeof (version)) 2291 != sizeof (version)) { 2292 goto cleanup2; 2293 } 2294 2295 if (public) { 2296 bzero(iv, sizeof (iv)); 2297 } else { 2298 /* generate an IV */ 2299 if (soft_gen_iv(iv) != CKR_OK) { 2300 goto cleanup2; 2301 } 2302 2303 } 2304 2305 if (writen_nointr(obj_fd, (void *)iv, sizeof (iv)) != sizeof (iv)) { 2306 goto cleanup2; 2307 } 2308 2309 if (public) { 2310 2311 bzero(obj_hmac, sizeof (obj_hmac)); 2312 if (writen_nointr(obj_fd, (void *)obj_hmac, 2313 sizeof (obj_hmac)) != sizeof (obj_hmac)) { 2314 goto cleanup2; 2315 } 2316 2317 if (writen_nointr(obj_fd, (char *)buf, len) != len) { 2318 goto cleanup2; 2319 } 2320 2321 } else { 2322 2323 uchar_t *encrypted_buf, *prepared_buf; 2324 CK_ULONG out_len = 0, prepared_len; 2325 2326 if (prepare_data_for_encrypt(obj_name, buf, len, 2327 &prepared_buf, &prepared_len) != 0) { 2328 goto cleanup2; 2329 } 2330 2331 if (soft_keystore_crypt(enc_key, iv, 2332 B_TRUE, prepared_buf, prepared_len, 2333 NULL, &out_len) != CKR_OK) { 2334 freezero(prepared_buf, prepared_len); 2335 goto cleanup2; 2336 } 2337 2338 encrypted_buf = malloc(out_len * sizeof (char)); 2339 if (encrypted_buf == NULL) { 2340 freezero(prepared_buf, prepared_len); 2341 goto cleanup2; 2342 } 2343 2344 if (soft_keystore_crypt(enc_key, iv, 2345 B_TRUE, prepared_buf, prepared_len, 2346 encrypted_buf, &out_len) != CKR_OK) { 2347 freezero(encrypted_buf, out_len); 2348 freezero(prepared_buf, prepared_len); 2349 goto cleanup2; 2350 } 2351 freezero(prepared_buf, prepared_len); 2352 2353 /* calculate HMAC of encrypted object */ 2354 hmac_size = OBJ_HMAC_SIZE; 2355 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf, 2356 out_len, obj_hmac, &hmac_size) != CKR_OK) { 2357 freezero(encrypted_buf, out_len); 2358 goto cleanup2; 2359 } 2360 2361 if (hmac_size != OBJ_HMAC_SIZE) { 2362 freezero(encrypted_buf, out_len); 2363 goto cleanup2; 2364 } 2365 2366 /* write hmac */ 2367 if (writen_nointr(obj_fd, (void *)obj_hmac, 2368 sizeof (obj_hmac)) != sizeof (obj_hmac)) { 2369 freezero(encrypted_buf, out_len); 2370 goto cleanup2; 2371 } 2372 2373 /* write encrypted object */ 2374 if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len) 2375 != out_len) { 2376 freezero(encrypted_buf, out_len); 2377 goto cleanup2; 2378 } 2379 2380 freezero(encrypted_buf, out_len); 2381 } 2382 2383 2384 (void) close(obj_fd); 2385 (void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name), 2386 "obj%d", counter); 2387 keyhandle->public = public; 2388 2389 /* 2390 * store new counter to temp keystore description file. 2391 */ 2392 counter++; 2393 counter = SWAP32(counter); 2394 if (writen_nointr(tmp_ks_fd, (void *)&counter, 2395 sizeof (counter)) != sizeof (counter)) { 2396 goto cleanup2; 2397 } 2398 2399 /* read rest of keystore description file and store into temp file */ 2400 nread = readn_nointr(fd, filebuf, sizeof (filebuf)); 2401 while (nread > 0) { 2402 if (writen_nointr(tmp_ks_fd, filebuf, nread) != nread) { 2403 goto cleanup2; 2404 } 2405 nread = readn_nointr(fd, filebuf, sizeof (filebuf)); 2406 } 2407 2408 (void) close(tmp_ks_fd); 2409 (void) rename(tmp_ks_desc_name, ks_desc_file); 2410 2411 if (!lock_held) { 2412 /* release lock on description file */ 2413 if (lock_file(fd, B_FALSE, B_FALSE) != 0) { 2414 (void) close(fd); 2415 return (-1); 2416 } 2417 } 2418 (void) close(fd); 2419 explicit_bzero(obj_hmac, sizeof (obj_hmac)); 2420 explicit_bzero(iv, sizeof (iv)); 2421 return (0); 2422 2423 cleanup2: 2424 2425 /* remove object file. No need to remove lock first */ 2426 (void) unlink(obj_name); 2427 2428 cleanup: 2429 2430 (void) close(tmp_ks_fd); 2431 (void) remove(tmp_ks_desc_name); 2432 if (!lock_held) { 2433 /* release lock on description file */ 2434 (void) lock_file(fd, B_FALSE, B_FALSE); 2435 } 2436 2437 (void) close(fd); 2438 explicit_bzero(obj_hmac, sizeof (obj_hmac)); 2439 explicit_bzero(iv, sizeof (iv)); 2440 return (-1); 2441 } 2442 2443 /* 2444 * FUNCTION: soft_keystore_modify_obj 2445 * 2446 * ARGUMENTS: 2447 * ks_handle: handle of the key store object to be modified 2448 * buf: buffer containing un-encrypted data 2449 * to be modified in keystore. 2450 * len: length of data 2451 * lock_held: TRUE if the lock is held by caller. 2452 * 2453 * RETURN VALUE: 2454 * -1: if any error occurred. 2455 * Otherwise, 0 is returned. 2456 * 2457 * DESCRIPTION: 2458 * 2459 * This API is used to write a modified token object back 2460 * to keystore. This function will do the following: 2461 * 2462 * 1) If it is a private object, it will be encrypted before 2463 * being written to the corresponding keystore token 2464 * object file. 2465 * 2) Record incremented object version number. 2466 * 3) Record incremented keystore version number. 2467 */ 2468 int 2469 soft_keystore_modify_obj(ks_obj_handle_t *ks_handle, uchar_t *buf, 2470 size_t len, boolean_t lock_held) 2471 { 2472 int fd, ks_fd, tmp_fd, version; 2473 char orig_name[MAXPATHLEN], tmp_name[MAXPATHLEN], 2474 tmp_ks_name[MAXPATHLEN]; 2475 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE]; 2476 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2477 ks_desc_file[MAXPATHLEN]; 2478 CK_ULONG hmac_size; 2479 2480 /* if it is private object, make sure we have the key */ 2481 if (!(ks_handle->public)) { 2482 if ((enc_key == NULL) || 2483 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2484 return (-1); 2485 } 2486 } 2487 2488 /* open and lock keystore description file */ 2489 if ((ks_fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2490 B_FALSE)) < 0) { 2491 return (-1); 2492 } 2493 2494 (void) get_desc_file_path(ks_desc_file); 2495 2496 /* update the version of for keystore file in tempoary file */ 2497 (void) get_tmp_desc_file_path(tmp_ks_name); 2498 if (create_updated_keystore_version(ks_fd, tmp_ks_name) != 0) { 2499 /* unlock keystore description file */ 2500 (void) lock_file(ks_fd, B_FALSE, B_FALSE); 2501 (void) close(ks_fd); 2502 return (-1); 2503 } 2504 2505 /* open object file */ 2506 if ((fd = open_and_lock_object_file(ks_handle, O_RDWR, 2507 lock_held)) < 0) { 2508 goto cleanup; 2509 } 2510 2511 /* 2512 * make the change in a temporary file. Create the temp 2513 * file in the same directory as the token object. That 2514 * way, the "rename" later will be an atomic operation 2515 */ 2516 if (ks_handle->public) { 2517 (void) snprintf(orig_name, MAXPATHLEN, "%s/%s", 2518 get_pub_obj_path(pub_obj_path), ks_handle->name); 2519 (void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s", 2520 pub_obj_path, TMP_OBJ_PREFIX, 2521 (ks_handle->name) + OBJ_PREFIX_LEN); 2522 } else { 2523 (void) snprintf(orig_name, MAXPATHLEN, "%s/%s", 2524 get_pri_obj_path(pri_obj_path), ks_handle->name); 2525 (void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s", 2526 pri_obj_path, TMP_OBJ_PREFIX, 2527 (ks_handle->name) + OBJ_PREFIX_LEN); 2528 } 2529 2530 tmp_fd = open_nointr(tmp_name, 2531 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2532 if (tmp_fd < 0) { 2533 /* can't create tmp object file */ 2534 goto cleanup1; 2535 } 2536 2537 /* read version, increment, and write to tmp file */ 2538 if (readn_nointr(fd, (char *)&version, OBJ_VER_SIZE) != OBJ_VER_SIZE) { 2539 goto cleanup2; 2540 } 2541 2542 version = SWAP32(version); 2543 version++; 2544 version = SWAP32(version); 2545 2546 if (writen_nointr(tmp_fd, (char *)&version, OBJ_VER_SIZE) 2547 != OBJ_VER_SIZE) { 2548 goto cleanup2; 2549 } 2550 2551 /* generate a new IV for the object, old one can be ignored */ 2552 if (soft_gen_iv(iv) != CKR_OK) { 2553 goto cleanup2; 2554 } 2555 2556 if (writen_nointr(tmp_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 2557 goto cleanup2; 2558 } 2559 2560 if (ks_handle->public) { 2561 2562 /* hmac is always NULL for public objects */ 2563 bzero(obj_hmac, sizeof (obj_hmac)); 2564 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE) 2565 != OBJ_HMAC_SIZE) { 2566 goto cleanup2; 2567 } 2568 2569 /* write updated object */ 2570 if (writen_nointr(tmp_fd, (char *)buf, len) != len) { 2571 goto cleanup2; 2572 } 2573 2574 } else { 2575 2576 uchar_t *encrypted_buf, *prepared_buf; 2577 CK_ULONG out_len = 0, prepared_len; 2578 2579 if (prepare_data_for_encrypt(orig_name, buf, len, 2580 &prepared_buf, &prepared_len) != 0) { 2581 goto cleanup2; 2582 } 2583 2584 /* encrypt the data */ 2585 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf, 2586 prepared_len, NULL, &out_len) != CKR_OK) { 2587 free(prepared_buf); 2588 goto cleanup2; 2589 } 2590 2591 encrypted_buf = malloc(out_len * sizeof (char)); 2592 if (encrypted_buf == NULL) { 2593 freezero(prepared_buf, prepared_len); 2594 goto cleanup2; 2595 } 2596 2597 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf, 2598 prepared_len, encrypted_buf, &out_len) != CKR_OK) { 2599 freezero(prepared_buf, prepared_len); 2600 freezero(encrypted_buf, out_len); 2601 goto cleanup2; 2602 } 2603 2604 freezero(prepared_buf, prepared_len); 2605 2606 /* calculate hmac on encrypted buf */ 2607 hmac_size = OBJ_HMAC_SIZE; 2608 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf, 2609 out_len, obj_hmac, &hmac_size) != CKR_OK) { 2610 freezero(encrypted_buf, out_len); 2611 goto cleanup2; 2612 } 2613 2614 if (hmac_size != OBJ_HMAC_SIZE) { 2615 freezero(encrypted_buf, out_len); 2616 goto cleanup2; 2617 } 2618 2619 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE) 2620 != OBJ_HMAC_SIZE) { 2621 freezero(encrypted_buf, out_len); 2622 goto cleanup2; 2623 } 2624 2625 if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len) 2626 != out_len) { 2627 freezero(encrypted_buf, out_len); 2628 goto cleanup2; 2629 } 2630 freezero(encrypted_buf, out_len); 2631 } 2632 (void) close(tmp_fd); 2633 2634 /* rename updated temporary object file */ 2635 if (rename(tmp_name, orig_name) != 0) { 2636 (void) unlink(tmp_name); 2637 return (-1); 2638 } 2639 2640 /* rename updated keystore description file */ 2641 if (rename(tmp_ks_name, ks_desc_file) != 0) { 2642 (void) unlink(tmp_name); 2643 (void) unlink(tmp_ks_name); 2644 return (-1); 2645 } 2646 2647 /* determine need to unlock file or not */ 2648 if (!lock_held) { 2649 if (lock_file(fd, B_FALSE, B_FALSE) < 0) { 2650 (void) close(fd); 2651 (void) unlink(tmp_name); 2652 return (-1); 2653 } 2654 } 2655 2656 /* unlock keystore description file */ 2657 if (lock_file(ks_fd, B_FALSE, B_FALSE) != 0) { 2658 (void) close(ks_fd); 2659 (void) close(fd); 2660 return (-1); 2661 } 2662 2663 (void) close(ks_fd); 2664 2665 (void) close(fd); 2666 2667 explicit_bzero(iv, sizeof (iv)); 2668 explicit_bzero(obj_hmac, sizeof (obj_hmac)); 2669 return (0); /* All operations completed successfully */ 2670 2671 cleanup2: 2672 (void) close(tmp_fd); 2673 (void) remove(tmp_name); 2674 2675 cleanup1: 2676 (void) close(fd); 2677 2678 cleanup: 2679 /* unlock keystore description file */ 2680 (void) lock_file(ks_fd, B_FALSE, B_FALSE); 2681 (void) close(ks_fd); 2682 (void) remove(tmp_ks_name); 2683 explicit_bzero(iv, sizeof (iv)); 2684 explicit_bzero(obj_hmac, sizeof (obj_hmac)); 2685 return (-1); 2686 } 2687 2688 /* 2689 * FUNCTION: soft_keystore_del_obj 2690 * 2691 * ARGUMENTS: 2692 * ks_handle: handle of the key store object to be deleted 2693 * lock_held: TRUE if the lock is held by caller. 2694 * 2695 * RETURN VALUE: 2696 * -1: if any error occurred. 2697 * 0: object successfully deleted from keystore. 2698 * 2699 * DESCRIPTION: 2700 * This API is used to delete a particular token object from 2701 * the keystore. The corresponding token object file will be 2702 * removed from the file system. 2703 * Any future reference to the deleted file will 2704 * return an CKR_OBJECT_HANDLE_INVALID error. 2705 */ 2706 int 2707 soft_keystore_del_obj(ks_obj_handle_t *ks_handle, boolean_t lock_held) 2708 { 2709 char objname[MAXPATHLEN], tmp_ks_name[MAXPATHLEN]; 2710 int fd; 2711 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2712 ks_desc_file[MAXPATHLEN]; 2713 int ret_val = -1; 2714 int obj_fd; 2715 2716 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2717 lock_held)) < 0) { 2718 return (-1); 2719 } 2720 2721 (void) get_desc_file_path(ks_desc_file); 2722 (void) get_tmp_desc_file_path(tmp_ks_name); 2723 if (create_updated_keystore_version(fd, tmp_ks_name) != 0) { 2724 goto cleanup; 2725 } 2726 2727 if (ks_handle->public) { 2728 (void) snprintf(objname, MAXPATHLEN, "%s/%s", 2729 get_pub_obj_path(pub_obj_path), ks_handle->name); 2730 } else { 2731 (void) snprintf(objname, MAXPATHLEN, "%s/%s", 2732 get_pri_obj_path(pri_obj_path), ks_handle->name); 2733 } 2734 2735 /* 2736 * make sure no other process is reading/writing the file 2737 * by acquiring the lock on the file 2738 */ 2739 if ((obj_fd = open_and_lock_object_file(ks_handle, O_WRONLY, 2740 B_FALSE)) < 0) { 2741 return (-1); 2742 } 2743 2744 if (unlink(objname) != 0) { 2745 (void) lock_file(obj_fd, B_FALSE, B_FALSE); 2746 (void) close(obj_fd); 2747 goto cleanup; 2748 } 2749 2750 (void) lock_file(obj_fd, B_FALSE, B_FALSE); 2751 (void) close(obj_fd); 2752 2753 if (rename(tmp_ks_name, ks_desc_file) != 0) { 2754 goto cleanup; 2755 } 2756 ret_val = 0; 2757 2758 cleanup: 2759 /* unlock keystore description file */ 2760 if (!lock_held) { 2761 if (lock_file(fd, B_FALSE, B_FALSE) != 0) { 2762 (void) close(fd); 2763 return (-1); 2764 } 2765 } 2766 2767 (void) close(fd); 2768 return (ret_val); 2769 } 2770 2771 /* 2772 * Get the salt used for generating hashed pin from the 2773 * keystore description file. 2774 * 2775 * The result will be stored in the provided buffer "salt" passed 2776 * in as an argument. 2777 * 2778 * Return 0 if no error, return -1 if there's any error. 2779 */ 2780 int 2781 soft_keystore_get_pin_salt(char **salt) 2782 { 2783 int fd, ret_val = -1; 2784 uint64_t hashed_pin_salt_size; 2785 2786 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE, 2787 B_FALSE)) < 0) { 2788 return (-1); 2789 } 2790 2791 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET) 2792 != KS_HASHED_PIN_SALT_LEN_OFFSET) { 2793 goto cleanup; 2794 } 2795 2796 if (readn_nointr(fd, (char *)&hashed_pin_salt_size, 2797 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 2798 goto cleanup; 2799 } 2800 hashed_pin_salt_size = SWAP64(hashed_pin_salt_size); 2801 2802 *salt = malloc(hashed_pin_salt_size + 1); 2803 if (*salt == NULL) { 2804 goto cleanup; 2805 } 2806 2807 if ((readn_nointr(fd, *salt, hashed_pin_salt_size)) 2808 != (ssize_t)hashed_pin_salt_size) { 2809 freezero(*salt, hashed_pin_salt_size + 1); 2810 goto cleanup; 2811 } 2812 (*salt)[hashed_pin_salt_size] = '\0'; 2813 2814 ret_val = 0; 2815 2816 cleanup: 2817 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 2818 ret_val = -1; 2819 } 2820 2821 (void) close(fd); 2822 return (ret_val); 2823 } 2824 2825 /* 2826 * FUNCTION: soft_keystore_pin_initialized 2827 * 2828 * ARGUMENTS: 2829 * initialized: This value will be set to true if keystore is 2830 * initialized, and false otherwise. 2831 * hashed_pin: If the keystore is initialized, this will contain 2832 * the hashed pin. It will be NULL if the keystore 2833 * pin is not initialized. Memory allocated 2834 * for the hashed pin needs to be freed by 2835 * the caller. 2836 * lock_held: TRUE if the lock is held by caller. 2837 * 2838 * RETURN VALUE: 2839 * CKR_OK: No error 2840 * any other appropriate CKR_value 2841 * 2842 * DESCRIPTION: 2843 * This API is used to determine if the PIN in the keystore 2844 * has been initialized or not. 2845 * It makes the determination using the salt for generating the 2846 * encryption key. The salt is stored in the keystore 2847 * descryption file. The salt should be all zero if 2848 * the keystore pin has not been initialized. 2849 * If the pin has been initialized, it is returned in the 2850 * hashed_pin argument. 2851 */ 2852 CK_RV 2853 soft_keystore_pin_initialized(boolean_t *initialized, char **hashed_pin, 2854 boolean_t lock_held) 2855 { 2856 int fd; 2857 CK_BYTE crypt_salt[KS_KEY_SALT_SIZE], tmp_buf[KS_KEY_SALT_SIZE]; 2858 CK_RV ret_val = CKR_OK; 2859 2860 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE, 2861 lock_held)) < 0) { 2862 return (CKR_FUNCTION_FAILED); 2863 } 2864 2865 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) { 2866 ret_val = CKR_FUNCTION_FAILED; 2867 goto cleanup; 2868 } 2869 2870 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 2871 != KS_KEY_SALT_SIZE) { 2872 ret_val = CKR_FUNCTION_FAILED; 2873 goto cleanup; 2874 } 2875 2876 (void) bzero(tmp_buf, KS_KEY_SALT_SIZE); 2877 2878 if (memcmp(crypt_salt, tmp_buf, KS_KEY_SALT_SIZE) == 0) { 2879 *initialized = B_FALSE; 2880 hashed_pin = NULL; 2881 } else { 2882 *initialized = B_TRUE; 2883 ret_val = get_hashed_pin(fd, hashed_pin); 2884 } 2885 2886 cleanup: 2887 2888 if (!lock_held) { 2889 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 2890 ret_val = CKR_FUNCTION_FAILED; 2891 } 2892 } 2893 2894 (void) close(fd); 2895 return (ret_val); 2896 } 2897 2898 /* 2899 * This checks if the keystore file exists 2900 */ 2901 2902 static int 2903 soft_keystore_exists() 2904 { 2905 int ret; 2906 struct stat fn_stat; 2907 char *fname, ks_desc_file[MAXPATHLEN]; 2908 2909 fname = get_desc_file_path(ks_desc_file); 2910 ret = stat(fname, &fn_stat); 2911 if (ret == 0) 2912 return (0); 2913 return (errno); 2914 } 2915 2916 /* 2917 * FUNCTION: soft_keystore_init 2918 * 2919 * ARGUMENTS: 2920 * desired_state: The keystore state the caller would like 2921 * it to be. 2922 * 2923 * RETURN VALUE: 2924 * Returns the state the function is in. If it succeeded, it 2925 * will be the same as the desired, if not it will be 2926 * KEYSTORE_UNAVAILABLE. 2927 * 2928 * DESCRIPTION: 2929 * This function will only load as much keystore data as is 2930 * requested at that time. This is for performace by delaying the 2931 * reading of token objects until they are needed or never at 2932 * all if they are not used. 2933 * 2934 * Primary use is from C_InitToken(). 2935 * It is also called by soft_keystore_status() when the 2936 * "desired_state" is not the the current load state of keystore. 2937 * 2938 */ 2939 int 2940 soft_keystore_init(int desired_state) 2941 { 2942 int ret; 2943 2944 (void) pthread_mutex_lock(&soft_slot.keystore_mutex); 2945 2946 /* 2947 * If more than one session tries to initialize the keystore, the 2948 * second and other following sessions that were waiting for the lock 2949 * will quickly exit if their requirements are satisfied. 2950 */ 2951 if (desired_state <= soft_slot.keystore_load_status) { 2952 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex); 2953 return (soft_slot.keystore_load_status); 2954 } 2955 2956 /* 2957 * With 'keystore_load_status' giving the current state of the 2958 * process, this switch will bring it up to the desired state if 2959 * possible. 2960 */ 2961 2962 switch (soft_slot.keystore_load_status) { 2963 case KEYSTORE_UNINITIALIZED: 2964 ret = soft_keystore_exists(); 2965 if (ret == 0) 2966 soft_slot.keystore_load_status = KEYSTORE_PRESENT; 2967 else if (ret == ENOENT) 2968 if (create_keystore() == 0) 2969 soft_slot.keystore_load_status = 2970 KEYSTORE_PRESENT; 2971 else { 2972 soft_slot.keystore_load_status = 2973 KEYSTORE_UNAVAILABLE; 2974 cryptoerror(LOG_DEBUG, 2975 "pkcs11_softtoken: " 2976 "Cannot create keystore."); 2977 break; 2978 } 2979 2980 if (desired_state <= KEYSTORE_PRESENT) 2981 break; 2982 2983 /* FALLTHRU */ 2984 case KEYSTORE_PRESENT: 2985 if (soft_keystore_get_version(&soft_slot.ks_version, B_FALSE) 2986 != 0) { 2987 soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE; 2988 cryptoerror(LOG_DEBUG, 2989 "pkcs11_softtoken: Keystore access failed."); 2990 break; 2991 } 2992 2993 soft_slot.keystore_load_status = KEYSTORE_LOAD; 2994 if (desired_state <= KEYSTORE_LOAD) 2995 break; 2996 2997 /* FALLTHRU */ 2998 case KEYSTORE_LOAD: 2999 /* Load all the public token objects from keystore */ 3000 if (soft_get_token_objects_from_keystore(PUB_TOKENOBJS) 3001 != CKR_OK) { 3002 (void) soft_destroy_token_session(); 3003 soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE; 3004 cryptoerror(LOG_DEBUG, 3005 "pkcs11_softtoken: Cannot initialize keystore."); 3006 break; 3007 } 3008 3009 soft_slot.keystore_load_status = KEYSTORE_INITIALIZED; 3010 }; 3011 3012 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex); 3013 return (soft_slot.keystore_load_status); 3014 } 3015 3016 /* 3017 * FUNCTION: soft_keystore_status 3018 * 3019 * ARGUMENTS: 3020 * desired_state: The keystore state the caller would like 3021 * it to be. 3022 * 3023 * RETURN VALUE: 3024 * B_TRUE if keystore is ready and at the desired state. 3025 * B_FALSE if keystore had an error and is not available. 3026 * 3027 * DESCRIPTION: 3028 * The calling function wants to make sure the keystore load 3029 * status to in a state it requires. If it is not at that 3030 * state it will call the load function. 3031 * If keystore is at the desired state or has just been 3032 * loaded to that state, it will return TRUE. If there has been 3033 * load failure, it will return FALSE. 3034 * 3035 */ 3036 boolean_t 3037 soft_keystore_status(int desired_state) 3038 { 3039 3040 if (soft_slot.keystore_load_status == KEYSTORE_UNAVAILABLE) 3041 return (B_FALSE); 3042 3043 return ((desired_state <= soft_slot.keystore_load_status) || 3044 (soft_keystore_init(desired_state) == desired_state)); 3045 } 3046