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 cleanup: 1159 if (!lock_held) { 1160 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 1161 ret_val = -1; 1162 } 1163 } 1164 1165 (void) close(fd); 1166 return (ret_val); 1167 } 1168 1169 1170 /* 1171 * Generate a 16-byte Initialization Vector (IV). 1172 */ 1173 CK_RV 1174 soft_gen_iv(CK_BYTE *iv) 1175 { 1176 return (pkcs11_get_nzero_urandom(iv, 16) < 0 ? 1177 CKR_DEVICE_ERROR : CKR_OK); 1178 } 1179 1180 1181 /* 1182 * This function reads all the data until the end of the file, and 1183 * put the data into the "buf" in argument. Memory for buf will 1184 * be allocated in this function. It is the caller's responsibility 1185 * to free it. The number of bytes read will be returned 1186 * in the argument "bytes_read" 1187 * 1188 * returns CKR_OK if no error. Other CKR error codes if there's an error 1189 */ 1190 static CK_RV 1191 read_obj_data(int old_fd, char **buf, ssize_t *bytes_read) 1192 { 1193 1194 ssize_t nread, loop_count; 1195 char *buf1 = NULL; 1196 1197 *buf = malloc(BUFSIZ); 1198 if (*buf == NULL) { 1199 return (CKR_HOST_MEMORY); 1200 } 1201 1202 nread = readn_nointr(old_fd, *buf, BUFSIZ); 1203 if (nread < 0) { 1204 free(*buf); 1205 return (CKR_FUNCTION_FAILED); 1206 } 1207 loop_count = 1; 1208 while (nread == (loop_count * BUFSIZ)) { 1209 ssize_t nread_tmp; 1210 1211 loop_count++; 1212 /* more than BUFSIZ of data */ 1213 buf1 = realloc(*buf, loop_count * BUFSIZ); 1214 if (buf1 == NULL) { 1215 free(*buf); 1216 return (CKR_HOST_MEMORY); 1217 } 1218 *buf = buf1; 1219 nread_tmp = readn_nointr(old_fd, 1220 *buf + ((loop_count - 1) * BUFSIZ), BUFSIZ); 1221 if (nread_tmp < 0) { 1222 free(*buf); 1223 return (CKR_FUNCTION_FAILED); 1224 } 1225 nread += nread_tmp; 1226 } 1227 *bytes_read = nread; 1228 return (CKR_OK); 1229 } 1230 1231 /* 1232 * Re-encrypt an object using the provided new_enc_key. The new HMAC 1233 * is calculated using the new_hmac_key. The global static variables 1234 * enc_key, and hmac_key will be used for decrypting the original 1235 * object, and verifying its signature. 1236 * 1237 * The re-encrypted object will be stored in the file named 1238 * in the "new_obj_name" variable. The content of the "original" 1239 * file named in "orig_obj_name" is not disturbed. 1240 * 1241 * Returns 0 if there's no error, returns -1 otherwise. 1242 * 1243 */ 1244 static int 1245 reencrypt_obj(soft_object_t *new_enc_key, soft_object_t *new_hmac_key, 1246 char *orig_obj_name, char *new_obj_name) 1247 { 1248 int old_fd, new_fd, version, ret_val = -1; 1249 CK_BYTE iv[OBJ_IV_SIZE], old_iv[OBJ_IV_SIZE]; 1250 ssize_t nread; 1251 CK_ULONG decrypted_len, encrypted_len, hmac_len; 1252 CK_BYTE hmac[OBJ_HMAC_SIZE], *decrypted_buf = NULL, *buf = NULL; 1253 1254 old_fd = open_nointr(orig_obj_name, O_RDONLY|O_NONBLOCK); 1255 if (old_fd < 0) { 1256 return (-1); 1257 } 1258 1259 if (acquire_file_lock(&old_fd, orig_obj_name, O_RDONLY) != 0) { 1260 if (old_fd > 0) { 1261 (void) close(old_fd); 1262 } 1263 return (-1); 1264 } 1265 1266 new_fd = open_nointr(new_obj_name, 1267 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 1268 if (new_fd < 0) { 1269 (void) close(old_fd); 1270 return (-1); 1271 } 1272 1273 if (lock_file(new_fd, B_FALSE, B_TRUE) != 0) { 1274 /* unlock old file */ 1275 (void) lock_file(old_fd, B_TRUE, B_FALSE); 1276 (void) close(old_fd); 1277 (void) close(new_fd); 1278 return (-1); 1279 } 1280 1281 /* read version, increment, and write to tmp file */ 1282 if (readn_nointr(old_fd, (char *)&version, OBJ_VER_SIZE) 1283 != OBJ_VER_SIZE) { 1284 goto cleanup; 1285 } 1286 1287 version = SWAP32(version); 1288 version++; 1289 version = SWAP32(version); 1290 1291 if (writen_nointr(new_fd, (char *)&version, OBJ_VER_SIZE) 1292 != OBJ_VER_SIZE) { 1293 goto cleanup; 1294 } 1295 1296 /* read old iv */ 1297 if (readn_nointr(old_fd, (char *)old_iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 1298 goto cleanup; 1299 } 1300 1301 /* generate new IV */ 1302 if (soft_gen_iv(iv) != CKR_OK) { 1303 goto cleanup; 1304 } 1305 1306 if (writen_nointr(new_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 1307 goto cleanup; 1308 } 1309 1310 /* seek to the original encrypted data, and read all of them */ 1311 if (lseek(old_fd, OBJ_DATA_OFFSET, SEEK_SET) != OBJ_DATA_OFFSET) { 1312 goto cleanup; 1313 } 1314 1315 if (read_obj_data(old_fd, (char **)&buf, &nread) != CKR_OK) { 1316 goto cleanup; 1317 } 1318 1319 /* decrypt data using old key */ 1320 decrypted_len = 0; 1321 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread, 1322 NULL, &decrypted_len) != CKR_OK) { 1323 freezero(buf, nread); 1324 goto cleanup; 1325 } 1326 1327 decrypted_buf = malloc(decrypted_len); 1328 if (decrypted_buf == NULL) { 1329 freezero(buf, nread); 1330 goto cleanup; 1331 } 1332 1333 if (soft_keystore_crypt(enc_key, old_iv, B_FALSE, buf, nread, 1334 decrypted_buf, &decrypted_len) != CKR_OK) { 1335 freezero(buf, nread); 1336 freezero(decrypted_buf, decrypted_len); 1337 } 1338 1339 freezero(buf, nread); 1340 1341 /* re-encrypt with new key */ 1342 encrypted_len = 0; 1343 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf, 1344 decrypted_len, NULL, &encrypted_len) != CKR_OK) { 1345 freezero(decrypted_buf, decrypted_len); 1346 goto cleanup; 1347 } 1348 1349 buf = malloc(encrypted_len); 1350 if (buf == NULL) { 1351 freezero(decrypted_buf, decrypted_len); 1352 goto cleanup; 1353 } 1354 1355 if (soft_keystore_crypt(new_enc_key, iv, B_TRUE, decrypted_buf, 1356 decrypted_len, buf, &encrypted_len) != CKR_OK) { 1357 freezero(buf, encrypted_len); 1358 freezero(buf, decrypted_len); 1359 goto cleanup; 1360 } 1361 1362 freezero(decrypted_buf, decrypted_len); 1363 1364 /* calculate hmac on re-encrypted data using new hmac key */ 1365 hmac_len = OBJ_HMAC_SIZE; 1366 if (soft_keystore_hmac(new_hmac_key, B_TRUE, buf, 1367 encrypted_len, hmac, &hmac_len) != CKR_OK) { 1368 freezero(buf, encrypted_len); 1369 goto cleanup; 1370 } 1371 1372 /* just for sanity check */ 1373 if (hmac_len != OBJ_HMAC_SIZE) { 1374 freezero(buf, encrypted_len); 1375 goto cleanup; 1376 } 1377 1378 /* write new hmac */ 1379 if (writen_nointr(new_fd, (char *)hmac, OBJ_HMAC_SIZE) 1380 != OBJ_HMAC_SIZE) { 1381 freezero(buf, encrypted_len); 1382 goto cleanup; 1383 } 1384 1385 /* write re-encrypted buffer to temp file */ 1386 if (writen_nointr(new_fd, (void *)buf, encrypted_len) 1387 != encrypted_len) { 1388 freezero(buf, encrypted_len); 1389 goto cleanup; 1390 } 1391 freezero(buf, encrypted_len); 1392 ret_val = 0; 1393 1394 cleanup: 1395 /* unlock the files */ 1396 (void) lock_file(old_fd, B_TRUE, B_FALSE); 1397 (void) lock_file(new_fd, B_FALSE, B_FALSE); 1398 1399 (void) close(old_fd); 1400 (void) close(new_fd); 1401 if (ret_val != 0) { 1402 (void) remove(new_obj_name); 1403 } 1404 return (ret_val); 1405 } 1406 1407 /* 1408 * FUNCTION: soft_keystore_setpin 1409 * 1410 * ARGUMENTS: 1411 * newpin: new pin entered by the user. 1412 * lock_held: TRUE if the lock is held by caller. 1413 * 1414 * RETURN VALUE: 1415 * 0: no error 1416 * -1: failure 1417 * 1418 * DESCRIPTION: 1419 * 1420 * This function does the following: 1421 * 1422 * 1) Generates crypted value of newpin and store it 1423 * in keystore description file. 1424 * 2) Dervies the new encryption key from the newpin. This key 1425 * will be used to re-encrypt the private token objects. 1426 * 3) Re-encrypt all of this user's existing private token 1427 * objects (if any). 1428 * 4) Increments the keystore version number. 1429 */ 1430 int 1431 soft_keystore_setpin(uchar_t *oldpin, uchar_t *newpin, boolean_t lock_held) 1432 { 1433 int fd, tmp_ks_fd, version, ret_val = -1; 1434 soft_object_t *new_crypt_key = NULL, *new_hmac_key = NULL; 1435 char filebuf[BUFSIZ]; 1436 DIR *pri_dirp; 1437 struct dirent *pri_ent; 1438 char pri_obj_path[MAXPATHLEN], ks_desc_file[MAXPATHLEN], 1439 tmp_ks_desc_name[MAXPATHLEN]; 1440 typedef struct priobjs { 1441 char orig_name[MAXPATHLEN]; 1442 char tmp_name[MAXPATHLEN]; 1443 struct priobjs *next; 1444 } priobjs_t; 1445 priobjs_t *pri_objs = NULL, *tmp; 1446 CK_BYTE *crypt_salt = NULL, *hmac_salt = NULL; 1447 boolean_t pin_never_set = B_FALSE, user_logged_in; 1448 char *new_hashed_pin = NULL; 1449 uint64_t hashed_pin_salt_length, new_hashed_pin_len, swaped_val; 1450 char *hashed_pin_salt = NULL; 1451 priobjs_t *obj; 1452 1453 if ((enc_key == NULL) || 1454 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 1455 user_logged_in = B_FALSE; 1456 } else { 1457 user_logged_in = B_TRUE; 1458 } 1459 1460 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_TRUE, 1461 lock_held)) < 0) { 1462 return (-1); 1463 } 1464 1465 (void) get_desc_file_path(ks_desc_file); 1466 (void) get_tmp_desc_file_path(tmp_ks_desc_name); 1467 1468 /* 1469 * create a tempoary file for the keystore description 1470 * file for updating version and counter information 1471 */ 1472 tmp_ks_fd = open_nointr(tmp_ks_desc_name, 1473 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 1474 if (tmp_ks_fd < 0) { 1475 (void) close(fd); 1476 return (-1); 1477 } 1478 1479 /* read and write PKCS version to temp file */ 1480 if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE) 1481 != KS_PKCS11_VER_SIZE) { 1482 goto cleanup; 1483 } 1484 1485 if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE) 1486 != KS_PKCS11_VER_SIZE) { 1487 goto cleanup; 1488 } 1489 1490 /* get version number, and write updated number to temp file */ 1491 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 1492 goto cleanup; 1493 } 1494 1495 version = SWAP32(version); 1496 version++; 1497 version = SWAP32(version); 1498 1499 if (writen_nointr(tmp_ks_fd, (void *)&version, KS_VER_SIZE) 1500 != KS_VER_SIZE) { 1501 goto cleanup; 1502 } 1503 1504 1505 /* read and write counter, no modification necessary */ 1506 if (readn_nointr(fd, filebuf, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) { 1507 goto cleanup; 1508 } 1509 1510 if (writen_nointr(tmp_ks_fd, filebuf, KS_COUNTER_SIZE) 1511 != KS_COUNTER_SIZE) { 1512 goto cleanup; 1513 } 1514 1515 /* read old encryption salt */ 1516 crypt_salt = malloc(KS_KEY_SALT_SIZE); 1517 if (crypt_salt == NULL) { 1518 goto cleanup; 1519 } 1520 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 1521 != KS_KEY_SALT_SIZE) { 1522 goto cleanup; 1523 } 1524 1525 /* read old hmac salt */ 1526 hmac_salt = malloc(KS_HMAC_SALT_SIZE); 1527 if (hmac_salt == NULL) { 1528 goto cleanup; 1529 } 1530 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE) 1531 != KS_HMAC_SALT_SIZE) { 1532 goto cleanup; 1533 } 1534 1535 /* just create some empty bytes */ 1536 bzero(filebuf, sizeof (filebuf)); 1537 1538 if (memcmp(crypt_salt, filebuf, KS_KEY_SALT_SIZE) == 0) { 1539 /* PIN as never been set */ 1540 CK_BYTE *new_crypt_salt = NULL, *new_hmac_salt = NULL; 1541 1542 pin_never_set = B_TRUE; 1543 if (soft_gen_crypt_key(newpin, &new_crypt_key, &new_crypt_salt) 1544 != CKR_OK) { 1545 goto cleanup; 1546 } 1547 if (writen_nointr(tmp_ks_fd, (void *)new_crypt_salt, 1548 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) { 1549 freezero(new_crypt_salt, 1550 KS_KEY_SALT_SIZE); 1551 (void) soft_cleanup_object(new_crypt_key); 1552 goto cleanup; 1553 } 1554 freezero(new_crypt_salt, KS_KEY_SALT_SIZE); 1555 1556 if (soft_gen_hmac_key(newpin, &new_hmac_key, &new_hmac_salt) 1557 != CKR_OK) { 1558 (void) soft_cleanup_object(new_crypt_key); 1559 goto cleanup; 1560 } 1561 if (writen_nointr(tmp_ks_fd, (void *)new_hmac_salt, 1562 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) { 1563 freezero(new_hmac_salt, 1564 KS_HMAC_SALT_SIZE); 1565 goto cleanup3; 1566 } 1567 freezero(new_hmac_salt, KS_HMAC_SALT_SIZE); 1568 } else { 1569 if (soft_gen_crypt_key(newpin, &new_crypt_key, 1570 (CK_BYTE **)&crypt_salt) != CKR_OK) { 1571 goto cleanup; 1572 } 1573 /* no change to the encryption salt */ 1574 if (writen_nointr(tmp_ks_fd, (void *)crypt_salt, 1575 KS_KEY_SALT_SIZE) != KS_KEY_SALT_SIZE) { 1576 (void) soft_cleanup_object(new_crypt_key); 1577 goto cleanup; 1578 } 1579 1580 if (soft_gen_hmac_key(newpin, &new_hmac_key, 1581 (CK_BYTE **)&hmac_salt) != CKR_OK) { 1582 (void) soft_cleanup_object(new_crypt_key); 1583 goto cleanup; 1584 } 1585 1586 /* no change to the hmac salt */ 1587 if (writen_nointr(tmp_ks_fd, (void *)hmac_salt, 1588 KS_HMAC_SALT_SIZE) != KS_HMAC_SALT_SIZE) { 1589 goto cleanup3; 1590 } 1591 } 1592 1593 /* 1594 * read hashed pin salt, and write to updated keystore description 1595 * file unmodified. 1596 */ 1597 if (readn_nointr(fd, (char *)&hashed_pin_salt_length, 1598 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 1599 goto cleanup3; 1600 } 1601 1602 if (writen_nointr(tmp_ks_fd, (void *)&hashed_pin_salt_length, 1603 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 1604 goto cleanup3; 1605 } 1606 1607 hashed_pin_salt_length = SWAP64(hashed_pin_salt_length); 1608 1609 hashed_pin_salt = malloc(hashed_pin_salt_length + 1); 1610 if (hashed_pin_salt == NULL) { 1611 goto cleanup3; 1612 } 1613 1614 if ((readn_nointr(fd, hashed_pin_salt, hashed_pin_salt_length)) != 1615 (ssize_t)hashed_pin_salt_length) { 1616 freezero(hashed_pin_salt, 1617 hashed_pin_salt_length + 1); 1618 goto cleanup3; 1619 } 1620 1621 if ((writen_nointr(tmp_ks_fd, hashed_pin_salt, hashed_pin_salt_length)) 1622 != (ssize_t)hashed_pin_salt_length) { 1623 freezero(hashed_pin_salt, 1624 hashed_pin_salt_length + 1); 1625 goto cleanup3; 1626 } 1627 1628 hashed_pin_salt[hashed_pin_salt_length] = '\0'; 1629 1630 /* old hashed pin length and value can be ignored, generate new one */ 1631 if (soft_gen_hashed_pin(newpin, &new_hashed_pin, 1632 &hashed_pin_salt) < 0) { 1633 freezero(hashed_pin_salt, 1634 hashed_pin_salt_length + 1); 1635 goto cleanup3; 1636 } 1637 1638 freezero(hashed_pin_salt, hashed_pin_salt_length + 1); 1639 1640 if (new_hashed_pin == NULL) { 1641 goto cleanup3; 1642 } 1643 1644 new_hashed_pin_len = strlen(new_hashed_pin); 1645 1646 /* write new hashed pin length to file */ 1647 swaped_val = SWAP64(new_hashed_pin_len); 1648 if (writen_nointr(tmp_ks_fd, (void *)&swaped_val, 1649 KS_HASHED_PINLEN_SIZE) != KS_HASHED_PINLEN_SIZE) { 1650 goto cleanup3; 1651 } 1652 1653 if (writen_nointr(tmp_ks_fd, (void *)new_hashed_pin, 1654 new_hashed_pin_len) != (ssize_t)new_hashed_pin_len) { 1655 goto cleanup3; 1656 } 1657 1658 if (pin_never_set) { 1659 /* there was no private object, no need to re-encrypt them */ 1660 goto rename_desc_file; 1661 } 1662 1663 /* re-encrypt all the private objects */ 1664 pri_dirp = opendir(get_pri_obj_path(pri_obj_path)); 1665 if (pri_dirp == NULL) { 1666 /* 1667 * this directory should exist, even if it doesn't contain 1668 * any objects. Don't want to update the pin if the 1669 * keystore is somehow messed up. 1670 */ 1671 1672 goto cleanup3; 1673 } 1674 1675 /* if user did not login, need to set the old pin */ 1676 if (!user_logged_in) { 1677 if (soft_keystore_authpin(oldpin) != 0) { 1678 goto cleanup3; 1679 } 1680 } 1681 1682 while ((pri_ent = readdir(pri_dirp)) != NULL) { 1683 1684 if ((strcmp(pri_ent->d_name, ".") == 0) || 1685 (strcmp(pri_ent->d_name, "..") == 0) || 1686 (strncmp(pri_ent->d_name, TMP_OBJ_PREFIX, 1687 strlen(TMP_OBJ_PREFIX)) == 0)) { 1688 continue; 1689 } 1690 1691 obj = malloc(sizeof (priobjs_t)); 1692 if (obj == NULL) { 1693 goto cleanup2; 1694 } 1695 (void) snprintf(obj->orig_name, MAXPATHLEN, 1696 "%s/%s", pri_obj_path, pri_ent->d_name); 1697 (void) snprintf(obj->tmp_name, MAXPATHLEN, "%s/%s%s", 1698 pri_obj_path, TMP_OBJ_PREFIX, 1699 (pri_ent->d_name) + OBJ_PREFIX_LEN); 1700 if (reencrypt_obj(new_crypt_key, new_hmac_key, 1701 obj->orig_name, obj->tmp_name) != 0) { 1702 free(obj); 1703 goto cleanup2; 1704 } 1705 1706 /* insert into list of file to be renamed */ 1707 if (pri_objs == NULL) { 1708 obj->next = NULL; 1709 pri_objs = obj; 1710 } else { 1711 obj->next = pri_objs; 1712 pri_objs = obj; 1713 } 1714 } 1715 1716 /* rename all the private objects */ 1717 tmp = pri_objs; 1718 while (tmp) { 1719 (void) rename(tmp->tmp_name, tmp->orig_name); 1720 tmp = tmp->next; 1721 } 1722 1723 rename_desc_file: 1724 1725 /* destroy the old encryption key, and hmac key */ 1726 if ((!pin_never_set) && (user_logged_in)) { 1727 (void) soft_cleanup_object(enc_key); 1728 (void) soft_cleanup_object(hmac_key); 1729 } 1730 1731 if (user_logged_in) { 1732 enc_key = new_crypt_key; 1733 hmac_key = new_hmac_key; 1734 } 1735 (void) rename(tmp_ks_desc_name, ks_desc_file); 1736 1737 ret_val = 0; 1738 1739 cleanup2: 1740 if (pri_objs != NULL) { 1741 priobjs_t *p = pri_objs; 1742 while (p) { 1743 tmp = p->next; 1744 free(p); 1745 p = tmp; 1746 } 1747 } 1748 if (!pin_never_set) { 1749 (void) closedir(pri_dirp); 1750 } 1751 1752 if ((!user_logged_in) && (!pin_never_set)) { 1753 (void) soft_cleanup_object(enc_key); 1754 (void) soft_cleanup_object(hmac_key); 1755 enc_key = NULL; 1756 hmac_key = NULL; 1757 } 1758 cleanup3: 1759 if ((ret_val != 0) || (!user_logged_in)) { 1760 (void) soft_cleanup_object(new_crypt_key); 1761 (void) soft_cleanup_object(new_hmac_key); 1762 } 1763 1764 cleanup: 1765 if (!lock_held) { 1766 if (lock_file(fd, B_FALSE, B_FALSE) < 0) { 1767 ret_val = 1; 1768 } 1769 } 1770 freezero(crypt_salt, KS_KEY_SALT_SIZE); 1771 freezero(hmac_salt, KS_HMAC_SALT_SIZE); 1772 (void) close(fd); 1773 (void) close(tmp_ks_fd); 1774 if (ret_val != 0) { 1775 (void) remove(tmp_ks_desc_name); 1776 } 1777 return (ret_val); 1778 } 1779 1780 /* 1781 * FUNCTION: soft_keystore_authpin 1782 * 1783 * ARGUMENTS: 1784 * pin: pin specified by the user for logging into 1785 * the keystore. 1786 * 1787 * RETURN VALUE: 1788 * 0: if no error 1789 * -1: if there is any error 1790 * 1791 * DESCRIPTION: 1792 * 1793 * This function takes the pin specified in the argument 1794 * and generates an encryption key based on the pin. 1795 * The generated encryption key will be used for 1796 * all future encryption and decryption for private 1797 * objects. Before this function is called, none 1798 * of the keystore related interfaces is able 1799 * to decrypt/encrypt any private object. 1800 */ 1801 int 1802 soft_keystore_authpin(uchar_t *pin) 1803 { 1804 int fd; 1805 int ret_val = -1; 1806 CK_BYTE *crypt_salt = NULL, *hmac_salt; 1807 1808 /* get the salt from the keystore description file */ 1809 if ((fd = open_and_lock_keystore_desc(O_RDONLY, 1810 B_FALSE, B_FALSE)) < 0) { 1811 return (-1); 1812 } 1813 1814 crypt_salt = malloc(KS_KEY_SALT_SIZE); 1815 if (crypt_salt == NULL) { 1816 goto cleanup; 1817 } 1818 1819 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) { 1820 goto cleanup; 1821 } 1822 1823 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 1824 != KS_KEY_SALT_SIZE) { 1825 goto cleanup; 1826 } 1827 1828 if (soft_gen_crypt_key(pin, &enc_key, (CK_BYTE **)&crypt_salt) 1829 != CKR_OK) { 1830 goto cleanup; 1831 } 1832 1833 hmac_salt = malloc(KS_HMAC_SALT_SIZE); 1834 if (hmac_salt == NULL) { 1835 goto cleanup; 1836 } 1837 1838 if (lseek(fd, KS_HMAC_SALT_OFFSET, SEEK_SET) != KS_HMAC_SALT_OFFSET) { 1839 goto cleanup; 1840 } 1841 1842 if (readn_nointr(fd, (char *)hmac_salt, KS_HMAC_SALT_SIZE) 1843 != KS_HMAC_SALT_SIZE) { 1844 goto cleanup; 1845 } 1846 1847 if (soft_gen_hmac_key(pin, &hmac_key, (CK_BYTE **)&hmac_salt) 1848 != CKR_OK) { 1849 goto cleanup; 1850 } 1851 1852 ret_val = 0; 1853 1854 cleanup: 1855 /* unlock the file */ 1856 (void) lock_file(fd, B_TRUE, B_FALSE); 1857 (void) close(fd); 1858 freezero(crypt_salt, KS_KEY_SALT_SIZE); 1859 freezero(hmac_salt, KS_HMAC_SALT_SIZE); 1860 return (ret_val); 1861 } 1862 1863 /* 1864 * FUNCTION: soft_keystore_get_objs 1865 * 1866 * ARGUMENTS: 1867 * 1868 * search_type: Specify type of objects to return. 1869 * lock_held: TRUE if the lock is held by caller. 1870 * 1871 * 1872 * RETURN VALUE: 1873 * 1874 * NULL: if there are no object in the database. 1875 * 1876 * Otherwise, linked list of objects as requested 1877 * in search type. 1878 * 1879 * The linked list returned will need to be freed 1880 * by the caller. 1881 * 1882 * DESCRIPTION: 1883 * 1884 * Returns objects as requested. 1885 * 1886 * If private objects is requested, and the caller 1887 * has not previously passed in the pin or if the pin 1888 * passed in is wrong, private objects will not 1889 * be returned. 1890 * 1891 * The buffers returned for private objects are already 1892 * decrypted. 1893 */ 1894 CK_RV 1895 soft_keystore_get_objs(ks_search_type_t search_type, 1896 ks_obj_t **result_obj_list, boolean_t lock_held) 1897 { 1898 DIR *dirp; 1899 ks_obj_handle_t ks_handle; 1900 CK_RV rv; 1901 ks_obj_t *tmp; 1902 int ks_fd; 1903 1904 *result_obj_list = NULL; 1905 1906 /* 1907 * lock the keystore description file in "read" mode so that 1908 * objects won't get added/deleted/modified while we are 1909 * doing the search 1910 */ 1911 if ((ks_fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE, 1912 B_FALSE)) < 0) { 1913 return (CKR_FUNCTION_FAILED); 1914 } 1915 1916 if ((search_type == ALL_TOKENOBJS) || (search_type == PUB_TOKENOBJS)) { 1917 1918 char pub_obj_path[MAXPATHLEN]; 1919 1920 ks_handle.public = B_TRUE; 1921 1922 if ((dirp = opendir(get_pub_obj_path(pub_obj_path))) == NULL) { 1923 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1924 (void) close(ks_fd); 1925 return (CKR_FUNCTION_FAILED); 1926 } 1927 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list, 1928 lock_held); 1929 if (rv != CKR_OK) { 1930 (void) closedir(dirp); 1931 goto cleanup; 1932 } 1933 1934 (void) closedir(dirp); 1935 } 1936 1937 if ((search_type == ALL_TOKENOBJS) || (search_type == PRI_TOKENOBJS)) { 1938 1939 char pri_obj_path[MAXPATHLEN]; 1940 1941 if ((enc_key == NULL) || 1942 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 1943 /* has not login - no need to go any further */ 1944 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1945 (void) close(ks_fd); 1946 return (CKR_OK); 1947 } 1948 1949 ks_handle.public = B_FALSE; 1950 1951 if ((dirp = opendir(get_pri_obj_path(pri_obj_path))) == NULL) { 1952 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1953 (void) close(ks_fd); 1954 return (CKR_OK); 1955 } 1956 rv = get_all_objs_in_dir(dirp, &ks_handle, result_obj_list, 1957 lock_held); 1958 if (rv != CKR_OK) { 1959 (void) closedir(dirp); 1960 goto cleanup; 1961 } 1962 1963 (void) closedir(dirp); 1964 } 1965 /* close the keystore description file */ 1966 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1967 (void) close(ks_fd); 1968 return (CKR_OK); 1969 cleanup: 1970 1971 /* close the keystore description file */ 1972 (void) lock_file(ks_fd, B_TRUE, B_FALSE); 1973 (void) close(ks_fd); 1974 1975 /* free all the objects found before hitting the error */ 1976 tmp = *result_obj_list; 1977 while (tmp) { 1978 *result_obj_list = tmp->next; 1979 freezero(tmp->buf, tmp->size); 1980 free(tmp); 1981 tmp = *result_obj_list; 1982 } 1983 *result_obj_list = NULL; 1984 return (rv); 1985 } 1986 1987 1988 /* 1989 * FUNCTION: soft_keystore_get_single_obj 1990 * 1991 * ARGUMENTS: 1992 * ks_handle: handle of the key store object to be accessed 1993 * lock_held: TRUE if the lock is held by caller. 1994 * 1995 * RETURN VALUE: 1996 * 1997 * NULL: if handle doesn't match any object 1998 * 1999 * Otherwise, the object is returned in 2000 * the same structure used in soft_keystore_get_objs(). 2001 * The structure need to be freed by the caller. 2002 * 2003 * DESCRIPTION: 2004 * 2005 * Retrieves the object specified by the object 2006 * handle to the caller. 2007 * 2008 * If a private object is requested, and the caller 2009 * has not previously passed in the pin or if the pin 2010 * passed in is wrong, the requested private object will not 2011 * be returned. 2012 * 2013 * The buffer returned for the requested private object 2014 * is already decrypted. 2015 */ 2016 CK_RV 2017 soft_keystore_get_single_obj(ks_obj_handle_t *ks_handle, 2018 ks_obj_t **return_obj, boolean_t lock_held) 2019 { 2020 2021 ks_obj_t *obj; 2022 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE]; 2023 uchar_t *buf, *decrypted_buf; 2024 int fd; 2025 ssize_t nread; 2026 CK_RV rv = CKR_FUNCTION_FAILED; 2027 2028 if (!(ks_handle->public)) { 2029 if ((enc_key == NULL) || 2030 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2031 return (CKR_FUNCTION_FAILED); 2032 } 2033 } 2034 2035 if ((fd = open_and_lock_object_file(ks_handle, O_RDONLY, 2036 lock_held)) < 0) { 2037 return (CKR_FUNCTION_FAILED); 2038 } 2039 2040 obj = malloc(sizeof (ks_obj_t)); 2041 if (obj == NULL) { 2042 return (CKR_HOST_MEMORY); 2043 } 2044 2045 obj->next = NULL; 2046 2047 (void) strcpy((char *)((obj->ks_handle).name), 2048 (char *)ks_handle->name); 2049 (obj->ks_handle).public = ks_handle->public; 2050 2051 /* 1st get the version */ 2052 if (readn_nointr(fd, &(obj->obj_version), OBJ_VER_SIZE) 2053 != OBJ_VER_SIZE) { 2054 goto cleanup; 2055 } 2056 obj->obj_version = SWAP32(obj->obj_version); 2057 2058 /* Then, read the IV */ 2059 if (readn_nointr(fd, iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 2060 goto cleanup; 2061 } 2062 2063 /* Then, read the HMAC */ 2064 if (readn_nointr(fd, obj_hmac, OBJ_HMAC_SIZE) != OBJ_HMAC_SIZE) { 2065 goto cleanup; 2066 } 2067 2068 /* read the object */ 2069 rv = read_obj_data(fd, (char **)&buf, &nread); 2070 if (rv != CKR_OK) { 2071 goto cleanup; 2072 } 2073 2074 if (ks_handle->public) { 2075 obj->size = nread; 2076 obj->buf = buf; 2077 *return_obj = obj; 2078 } else { 2079 2080 CK_ULONG out_len = 0, hmac_size; 2081 2082 /* verify HMAC of the object, make sure it matches */ 2083 hmac_size = OBJ_HMAC_SIZE; 2084 if (soft_keystore_hmac(hmac_key, B_FALSE, buf, 2085 nread, obj_hmac, &hmac_size) != CKR_OK) { 2086 freezero(buf, nread); 2087 rv = CKR_FUNCTION_FAILED; 2088 goto cleanup; 2089 } 2090 2091 /* decrypt object */ 2092 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread, 2093 NULL, &out_len) != CKR_OK) { 2094 freezero(buf, nread); 2095 rv = CKR_FUNCTION_FAILED; 2096 goto cleanup; 2097 } 2098 2099 decrypted_buf = malloc(sizeof (uchar_t) * out_len); 2100 if (decrypted_buf == NULL) { 2101 freezero(buf, nread); 2102 rv = CKR_HOST_MEMORY; 2103 goto cleanup; 2104 } 2105 2106 if (soft_keystore_crypt(enc_key, iv, B_FALSE, buf, nread, 2107 decrypted_buf, &out_len) != CKR_OK) { 2108 freezero(buf, nread); 2109 freezero(decrypted_buf, out_len); 2110 rv = CKR_FUNCTION_FAILED; 2111 goto cleanup; 2112 } 2113 2114 obj->size = out_len - MAXPATHLEN; 2115 2116 /* 2117 * decrypted buf here actually contains full path name of 2118 * object plus the actual data. so, need to skip the 2119 * full pathname. 2120 * See prepare_data_for_encrypt() function in the file 2121 * to understand how and why the pathname is added. 2122 */ 2123 obj->buf = malloc(sizeof (uchar_t) * (out_len - MAXPATHLEN)); 2124 if (obj->buf == NULL) { 2125 freezero(buf, nread); 2126 freezero(decrypted_buf, out_len); 2127 rv = CKR_HOST_MEMORY; 2128 goto cleanup; 2129 } 2130 (void) memcpy(obj->buf, decrypted_buf + MAXPATHLEN, obj->size); 2131 freezero(buf, nread); 2132 freezero(decrypted_buf, out_len); 2133 *return_obj = obj; 2134 } 2135 2136 cleanup: 2137 2138 if (rv != CKR_OK) { 2139 free(obj); 2140 } 2141 2142 /* unlock the file after reading */ 2143 if (!lock_held) { 2144 (void) lock_file(fd, B_TRUE, B_FALSE); 2145 } 2146 2147 (void) close(fd); 2148 2149 return (rv); 2150 } 2151 2152 2153 /* 2154 * FUNCTION: soft_keystore_put_new_obj 2155 * 2156 * ARGUMENTS: 2157 * buf: buffer containing un-encrypted data 2158 * to be stored in keystore. 2159 * len: length of data 2160 * public: TRUE if it is a public object, 2161 * FALSE if it is private obj 2162 * lock_held: TRUE if the lock is held by caller. 2163 * keyhandle: pointer to object handle to 2164 * receive keyhandle for new object 2165 * 2166 * RETURN VALUE: 2167 * 0: object successfully stored in file 2168 * -1: some error occurred, object is not stored in file. 2169 * 2170 * DESCRIPTION: 2171 * This API is used to write a newly created token object 2172 * to keystore. 2173 * 2174 * This function does the following: 2175 * 2176 * 1) Creates a token object file based on "public" parameter. 2177 * 2) Generates a new IV and stores it in obj_meta_data_t if it is 2178 * private object. 2179 * 3) Set object version number to 1. 2180 * 4) If it is a private object, it will be encrypted before 2181 * being written to the newly created keystore token object 2182 * file. 2183 * 5) Calculates the obj_chksum in obj_meta_data_t. 2184 * 6) Calculates the pin_chksum in obj_meta_data_t. 2185 * 7) Increments the keystore version number. 2186 */ 2187 int 2188 soft_keystore_put_new_obj(uchar_t *buf, size_t len, boolean_t public, 2189 boolean_t lock_held, ks_obj_handle_t *keyhandle) 2190 { 2191 2192 int fd, tmp_ks_fd, obj_fd; 2193 unsigned int counter, version; 2194 uchar_t obj_hmac[OBJ_HMAC_SIZE]; 2195 CK_BYTE iv[OBJ_IV_SIZE]; 2196 char obj_name[MAXPATHLEN], tmp_ks_desc_name[MAXPATHLEN]; 2197 char filebuf[BUFSIZ]; 2198 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2199 ks_desc_file[MAXPATHLEN]; 2200 CK_ULONG hmac_size; 2201 ssize_t nread; 2202 2203 if (keyhandle == NULL) { 2204 return (-1); 2205 } 2206 2207 /* if it is private object, make sure we have the key */ 2208 if (!public) { 2209 if ((enc_key == NULL) || 2210 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2211 return (-1); 2212 } 2213 } 2214 2215 /* open keystore, and set write lock */ 2216 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2217 lock_held)) < 0) { 2218 return (-1); 2219 } 2220 2221 (void) get_desc_file_path(ks_desc_file); 2222 (void) get_tmp_desc_file_path(tmp_ks_desc_name); 2223 2224 /* 2225 * create a tempoary file for the keystore description 2226 * file for updating version and counter information 2227 */ 2228 tmp_ks_fd = open_nointr(tmp_ks_desc_name, 2229 O_RDWR|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2230 if (tmp_ks_fd < 0) { 2231 (void) close(fd); 2232 return (-1); 2233 } 2234 2235 /* read and write pkcs11 version */ 2236 if (readn_nointr(fd, filebuf, KS_PKCS11_VER_SIZE) 2237 != KS_PKCS11_VER_SIZE) { 2238 goto cleanup; 2239 } 2240 2241 if (writen_nointr(tmp_ks_fd, filebuf, KS_PKCS11_VER_SIZE) 2242 != KS_PKCS11_VER_SIZE) { 2243 goto cleanup; 2244 } 2245 2246 /* get version number, and write updated number to temp file */ 2247 if (readn_nointr(fd, &version, KS_VER_SIZE) != KS_VER_SIZE) { 2248 goto cleanup; 2249 } 2250 2251 version = SWAP32(version); 2252 version++; 2253 version = SWAP32(version); 2254 2255 if (writen_nointr(tmp_ks_fd, (void *)&version, 2256 KS_VER_SIZE) != KS_VER_SIZE) { 2257 goto cleanup; 2258 } 2259 2260 /* get object count value */ 2261 if (readn_nointr(fd, &counter, KS_COUNTER_SIZE) != KS_COUNTER_SIZE) { 2262 goto cleanup; 2263 } 2264 counter = SWAP32(counter); 2265 2266 bzero(obj_name, sizeof (obj_name)); 2267 if (public) { 2268 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d", 2269 get_pub_obj_path(pub_obj_path), OBJ_PREFIX, counter); 2270 } else { 2271 (void) snprintf(obj_name, MAXPATHLEN, "%s/%s%d", 2272 get_pri_obj_path(pri_obj_path), OBJ_PREFIX, counter); 2273 } 2274 2275 /* create object file */ 2276 obj_fd = open_nointr(obj_name, 2277 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2278 if (obj_fd < 0) { 2279 /* can't create object file */ 2280 goto cleanup; 2281 } 2282 2283 /* lock object file for writing */ 2284 if (lock_file(obj_fd, B_FALSE, B_TRUE) != 0) { 2285 (void) close(obj_fd); 2286 goto cleanup2; 2287 } 2288 2289 /* write object meta data */ 2290 version = SWAP32(1); 2291 if (writen_nointr(obj_fd, (void *)&version, sizeof (version)) 2292 != sizeof (version)) { 2293 goto cleanup2; 2294 } 2295 2296 if (public) { 2297 bzero(iv, sizeof (iv)); 2298 } else { 2299 /* generate an IV */ 2300 if (soft_gen_iv(iv) != CKR_OK) { 2301 goto cleanup2; 2302 } 2303 2304 } 2305 2306 if (writen_nointr(obj_fd, (void *)iv, sizeof (iv)) != sizeof (iv)) { 2307 goto cleanup2; 2308 } 2309 2310 if (public) { 2311 2312 bzero(obj_hmac, sizeof (obj_hmac)); 2313 if (writen_nointr(obj_fd, (void *)obj_hmac, 2314 sizeof (obj_hmac)) != sizeof (obj_hmac)) { 2315 goto cleanup2; 2316 } 2317 2318 if (writen_nointr(obj_fd, (char *)buf, len) != len) { 2319 goto cleanup2; 2320 } 2321 2322 } else { 2323 2324 uchar_t *encrypted_buf, *prepared_buf; 2325 CK_ULONG out_len = 0, prepared_len; 2326 2327 if (prepare_data_for_encrypt(obj_name, buf, len, 2328 &prepared_buf, &prepared_len) != 0) { 2329 goto cleanup2; 2330 } 2331 2332 if (soft_keystore_crypt(enc_key, iv, 2333 B_TRUE, prepared_buf, prepared_len, 2334 NULL, &out_len) != CKR_OK) { 2335 freezero(prepared_buf, prepared_len); 2336 goto cleanup2; 2337 } 2338 2339 encrypted_buf = malloc(out_len * sizeof (char)); 2340 if (encrypted_buf == NULL) { 2341 freezero(prepared_buf, prepared_len); 2342 goto cleanup2; 2343 } 2344 2345 if (soft_keystore_crypt(enc_key, iv, 2346 B_TRUE, prepared_buf, prepared_len, 2347 encrypted_buf, &out_len) != CKR_OK) { 2348 freezero(encrypted_buf, out_len); 2349 freezero(prepared_buf, prepared_len); 2350 goto cleanup2; 2351 } 2352 freezero(prepared_buf, prepared_len); 2353 2354 /* calculate HMAC of encrypted object */ 2355 hmac_size = OBJ_HMAC_SIZE; 2356 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf, 2357 out_len, obj_hmac, &hmac_size) != CKR_OK) { 2358 freezero(encrypted_buf, out_len); 2359 goto cleanup2; 2360 } 2361 2362 if (hmac_size != OBJ_HMAC_SIZE) { 2363 freezero(encrypted_buf, out_len); 2364 goto cleanup2; 2365 } 2366 2367 /* write hmac */ 2368 if (writen_nointr(obj_fd, (void *)obj_hmac, 2369 sizeof (obj_hmac)) != sizeof (obj_hmac)) { 2370 freezero(encrypted_buf, out_len); 2371 goto cleanup2; 2372 } 2373 2374 /* write encrypted object */ 2375 if (writen_nointr(obj_fd, (void *)encrypted_buf, out_len) 2376 != out_len) { 2377 freezero(encrypted_buf, out_len); 2378 goto cleanup2; 2379 } 2380 2381 freezero(encrypted_buf, out_len); 2382 } 2383 2384 2385 (void) close(obj_fd); 2386 (void) snprintf((char *)keyhandle->name, sizeof (keyhandle->name), 2387 "obj%d", counter); 2388 keyhandle->public = public; 2389 2390 /* 2391 * store new counter to temp keystore description file. 2392 */ 2393 counter++; 2394 counter = SWAP32(counter); 2395 if (writen_nointr(tmp_ks_fd, (void *)&counter, 2396 sizeof (counter)) != sizeof (counter)) { 2397 goto cleanup2; 2398 } 2399 2400 /* read rest of keystore description file and store into temp file */ 2401 nread = readn_nointr(fd, filebuf, sizeof (filebuf)); 2402 while (nread > 0) { 2403 if (writen_nointr(tmp_ks_fd, filebuf, nread) != nread) { 2404 goto cleanup2; 2405 } 2406 nread = readn_nointr(fd, filebuf, sizeof (filebuf)); 2407 } 2408 2409 (void) close(tmp_ks_fd); 2410 (void) rename(tmp_ks_desc_name, ks_desc_file); 2411 2412 if (!lock_held) { 2413 /* release lock on description file */ 2414 if (lock_file(fd, B_FALSE, B_FALSE) != 0) { 2415 (void) close(fd); 2416 return (-1); 2417 } 2418 } 2419 (void) close(fd); 2420 explicit_bzero(obj_hmac, sizeof (obj_hmac)); 2421 explicit_bzero(iv, sizeof (iv)); 2422 return (0); 2423 2424 cleanup2: 2425 2426 /* remove object file. No need to remove lock first */ 2427 (void) unlink(obj_name); 2428 2429 cleanup: 2430 2431 (void) close(tmp_ks_fd); 2432 (void) remove(tmp_ks_desc_name); 2433 if (!lock_held) { 2434 /* release lock on description file */ 2435 (void) lock_file(fd, B_FALSE, B_FALSE); 2436 } 2437 2438 (void) close(fd); 2439 explicit_bzero(obj_hmac, sizeof (obj_hmac)); 2440 explicit_bzero(iv, sizeof (iv)); 2441 return (-1); 2442 } 2443 2444 /* 2445 * FUNCTION: soft_keystore_modify_obj 2446 * 2447 * ARGUMENTS: 2448 * ks_handle: handle of the key store object to be modified 2449 * buf: buffer containing un-encrypted data 2450 * to be modified in keystore. 2451 * len: length of data 2452 * lock_held: TRUE if the lock is held by caller. 2453 * 2454 * RETURN VALUE: 2455 * -1: if any error occurred. 2456 * Otherwise, 0 is returned. 2457 * 2458 * DESCRIPTION: 2459 * 2460 * This API is used to write a modified token object back 2461 * to keystore. This function will do the following: 2462 * 2463 * 1) If it is a private object, it will be encrypted before 2464 * being written to the corresponding keystore token 2465 * object file. 2466 * 2) Record incremented object version number. 2467 * 3) Record incremented keystore version number. 2468 */ 2469 int 2470 soft_keystore_modify_obj(ks_obj_handle_t *ks_handle, uchar_t *buf, 2471 size_t len, boolean_t lock_held) 2472 { 2473 int fd, ks_fd, tmp_fd, version; 2474 char orig_name[MAXPATHLEN], tmp_name[MAXPATHLEN], 2475 tmp_ks_name[MAXPATHLEN]; 2476 uchar_t iv[OBJ_IV_SIZE], obj_hmac[OBJ_HMAC_SIZE]; 2477 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2478 ks_desc_file[MAXPATHLEN]; 2479 CK_ULONG hmac_size; 2480 2481 /* if it is private object, make sure we have the key */ 2482 if (!(ks_handle->public)) { 2483 if ((enc_key == NULL) || 2484 (enc_key->magic_marker != SOFTTOKEN_OBJECT_MAGIC)) { 2485 return (-1); 2486 } 2487 } 2488 2489 /* open and lock keystore description file */ 2490 if ((ks_fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2491 B_FALSE)) < 0) { 2492 return (-1); 2493 } 2494 2495 (void) get_desc_file_path(ks_desc_file); 2496 2497 /* update the version of for keystore file in tempoary file */ 2498 (void) get_tmp_desc_file_path(tmp_ks_name); 2499 if (create_updated_keystore_version(ks_fd, tmp_ks_name) != 0) { 2500 /* unlock keystore description file */ 2501 (void) lock_file(ks_fd, B_FALSE, B_FALSE); 2502 (void) close(ks_fd); 2503 return (-1); 2504 } 2505 2506 /* open object file */ 2507 if ((fd = open_and_lock_object_file(ks_handle, O_RDWR, 2508 lock_held)) < 0) { 2509 goto cleanup; 2510 } 2511 2512 /* 2513 * make the change in a temporary file. Create the temp 2514 * file in the same directory as the token object. That 2515 * way, the "rename" later will be an atomic operation 2516 */ 2517 if (ks_handle->public) { 2518 (void) snprintf(orig_name, MAXPATHLEN, "%s/%s", 2519 get_pub_obj_path(pub_obj_path), ks_handle->name); 2520 (void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s", 2521 pub_obj_path, TMP_OBJ_PREFIX, 2522 (ks_handle->name) + OBJ_PREFIX_LEN); 2523 } else { 2524 (void) snprintf(orig_name, MAXPATHLEN, "%s/%s", 2525 get_pri_obj_path(pri_obj_path), ks_handle->name); 2526 (void) snprintf(tmp_name, MAXPATHLEN, "%s/%s%s", 2527 pri_obj_path, TMP_OBJ_PREFIX, 2528 (ks_handle->name) + OBJ_PREFIX_LEN); 2529 } 2530 2531 tmp_fd = open_nointr(tmp_name, 2532 O_WRONLY|O_CREAT|O_EXCL|O_NONBLOCK, S_IRUSR|S_IWUSR); 2533 if (tmp_fd < 0) { 2534 /* can't create tmp object file */ 2535 goto cleanup1; 2536 } 2537 2538 /* read version, increment, and write to tmp file */ 2539 if (readn_nointr(fd, (char *)&version, OBJ_VER_SIZE) != OBJ_VER_SIZE) { 2540 goto cleanup2; 2541 } 2542 2543 version = SWAP32(version); 2544 version++; 2545 version = SWAP32(version); 2546 2547 if (writen_nointr(tmp_fd, (char *)&version, OBJ_VER_SIZE) 2548 != OBJ_VER_SIZE) { 2549 goto cleanup2; 2550 } 2551 2552 /* generate a new IV for the object, old one can be ignored */ 2553 if (soft_gen_iv(iv) != CKR_OK) { 2554 goto cleanup2; 2555 } 2556 2557 if (writen_nointr(tmp_fd, (char *)iv, OBJ_IV_SIZE) != OBJ_IV_SIZE) { 2558 goto cleanup2; 2559 } 2560 2561 if (ks_handle->public) { 2562 2563 /* hmac is always NULL for public objects */ 2564 bzero(obj_hmac, sizeof (obj_hmac)); 2565 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE) 2566 != OBJ_HMAC_SIZE) { 2567 goto cleanup2; 2568 } 2569 2570 /* write updated object */ 2571 if (writen_nointr(tmp_fd, (char *)buf, len) != len) { 2572 goto cleanup2; 2573 } 2574 2575 } else { 2576 2577 uchar_t *encrypted_buf, *prepared_buf; 2578 CK_ULONG out_len = 0, prepared_len; 2579 2580 if (prepare_data_for_encrypt(orig_name, buf, len, 2581 &prepared_buf, &prepared_len) != 0) { 2582 goto cleanup2; 2583 } 2584 2585 /* encrypt the data */ 2586 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf, 2587 prepared_len, NULL, &out_len) != CKR_OK) { 2588 free(prepared_buf); 2589 goto cleanup2; 2590 } 2591 2592 encrypted_buf = malloc(out_len * sizeof (char)); 2593 if (encrypted_buf == NULL) { 2594 freezero(prepared_buf, prepared_len); 2595 goto cleanup2; 2596 } 2597 2598 if (soft_keystore_crypt(enc_key, iv, B_TRUE, prepared_buf, 2599 prepared_len, encrypted_buf, &out_len) != CKR_OK) { 2600 freezero(prepared_buf, prepared_len); 2601 freezero(encrypted_buf, out_len); 2602 goto cleanup2; 2603 } 2604 2605 freezero(prepared_buf, prepared_len); 2606 2607 /* calculate hmac on encrypted buf */ 2608 hmac_size = OBJ_HMAC_SIZE; 2609 if (soft_keystore_hmac(hmac_key, B_TRUE, encrypted_buf, 2610 out_len, obj_hmac, &hmac_size) != CKR_OK) { 2611 freezero(encrypted_buf, out_len); 2612 goto cleanup2; 2613 } 2614 2615 if (hmac_size != OBJ_HMAC_SIZE) { 2616 freezero(encrypted_buf, out_len); 2617 goto cleanup2; 2618 } 2619 2620 if (writen_nointr(tmp_fd, (char *)obj_hmac, OBJ_HMAC_SIZE) 2621 != OBJ_HMAC_SIZE) { 2622 freezero(encrypted_buf, out_len); 2623 goto cleanup2; 2624 } 2625 2626 if (writen_nointr(tmp_fd, (void *)encrypted_buf, out_len) 2627 != out_len) { 2628 freezero(encrypted_buf, out_len); 2629 goto cleanup2; 2630 } 2631 freezero(encrypted_buf, out_len); 2632 } 2633 (void) close(tmp_fd); 2634 2635 /* rename updated temporary object file */ 2636 if (rename(tmp_name, orig_name) != 0) { 2637 (void) unlink(tmp_name); 2638 return (-1); 2639 } 2640 2641 /* rename updated keystore description file */ 2642 if (rename(tmp_ks_name, ks_desc_file) != 0) { 2643 (void) unlink(tmp_name); 2644 (void) unlink(tmp_ks_name); 2645 return (-1); 2646 } 2647 2648 /* determine need to unlock file or not */ 2649 if (!lock_held) { 2650 if (lock_file(fd, B_FALSE, B_FALSE) < 0) { 2651 (void) close(fd); 2652 (void) unlink(tmp_name); 2653 return (-1); 2654 } 2655 } 2656 2657 /* unlock keystore description file */ 2658 if (lock_file(ks_fd, B_FALSE, B_FALSE) != 0) { 2659 (void) close(ks_fd); 2660 (void) close(fd); 2661 return (-1); 2662 } 2663 2664 (void) close(ks_fd); 2665 2666 (void) close(fd); 2667 2668 explicit_bzero(iv, sizeof (iv)); 2669 explicit_bzero(obj_hmac, sizeof (obj_hmac)); 2670 return (0); /* All operations completed successfully */ 2671 2672 cleanup2: 2673 (void) close(tmp_fd); 2674 (void) remove(tmp_name); 2675 2676 cleanup1: 2677 (void) close(fd); 2678 2679 cleanup: 2680 /* unlock keystore description file */ 2681 (void) lock_file(ks_fd, B_FALSE, B_FALSE); 2682 (void) close(ks_fd); 2683 (void) remove(tmp_ks_name); 2684 explicit_bzero(iv, sizeof (iv)); 2685 explicit_bzero(obj_hmac, sizeof (obj_hmac)); 2686 return (-1); 2687 } 2688 2689 /* 2690 * FUNCTION: soft_keystore_del_obj 2691 * 2692 * ARGUMENTS: 2693 * ks_handle: handle of the key store object to be deleted 2694 * lock_held: TRUE if the lock is held by caller. 2695 * 2696 * RETURN VALUE: 2697 * -1: if any error occurred. 2698 * 0: object successfully deleted from keystore. 2699 * 2700 * DESCRIPTION: 2701 * This API is used to delete a particular token object from 2702 * the keystore. The corresponding token object file will be 2703 * removed from the file system. 2704 * Any future reference to the deleted file will 2705 * return an CKR_OBJECT_HANDLE_INVALID error. 2706 */ 2707 int 2708 soft_keystore_del_obj(ks_obj_handle_t *ks_handle, boolean_t lock_held) 2709 { 2710 char objname[MAXPATHLEN], tmp_ks_name[MAXPATHLEN]; 2711 int fd; 2712 char pub_obj_path[MAXPATHLEN], pri_obj_path[MAXPATHLEN], 2713 ks_desc_file[MAXPATHLEN]; 2714 int ret_val = -1; 2715 int obj_fd; 2716 2717 if ((fd = open_and_lock_keystore_desc(O_RDWR, B_FALSE, 2718 lock_held)) < 0) { 2719 return (-1); 2720 } 2721 2722 (void) get_desc_file_path(ks_desc_file); 2723 (void) get_tmp_desc_file_path(tmp_ks_name); 2724 if (create_updated_keystore_version(fd, tmp_ks_name) != 0) { 2725 goto cleanup; 2726 } 2727 2728 if (ks_handle->public) { 2729 (void) snprintf(objname, MAXPATHLEN, "%s/%s", 2730 get_pub_obj_path(pub_obj_path), ks_handle->name); 2731 } else { 2732 (void) snprintf(objname, MAXPATHLEN, "%s/%s", 2733 get_pri_obj_path(pri_obj_path), ks_handle->name); 2734 } 2735 2736 /* 2737 * make sure no other process is reading/writing the file 2738 * by acquiring the lock on the file 2739 */ 2740 if ((obj_fd = open_and_lock_object_file(ks_handle, O_WRONLY, 2741 B_FALSE)) < 0) { 2742 return (-1); 2743 } 2744 2745 if (unlink(objname) != 0) { 2746 (void) lock_file(obj_fd, B_FALSE, B_FALSE); 2747 (void) close(obj_fd); 2748 goto cleanup; 2749 } 2750 2751 (void) lock_file(obj_fd, B_FALSE, B_FALSE); 2752 (void) close(obj_fd); 2753 2754 if (rename(tmp_ks_name, ks_desc_file) != 0) { 2755 goto cleanup; 2756 } 2757 ret_val = 0; 2758 2759 cleanup: 2760 /* unlock keystore description file */ 2761 if (!lock_held) { 2762 if (lock_file(fd, B_FALSE, B_FALSE) != 0) { 2763 (void) close(fd); 2764 return (-1); 2765 } 2766 } 2767 2768 (void) close(fd); 2769 return (ret_val); 2770 } 2771 2772 /* 2773 * Get the salt used for generating hashed pin from the 2774 * keystore description file. 2775 * 2776 * The result will be stored in the provided buffer "salt" passed 2777 * in as an argument. 2778 * 2779 * Return 0 if no error, return -1 if there's any error. 2780 */ 2781 int 2782 soft_keystore_get_pin_salt(char **salt) 2783 { 2784 int fd, ret_val = -1; 2785 uint64_t hashed_pin_salt_size; 2786 2787 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE, 2788 B_FALSE)) < 0) { 2789 return (-1); 2790 } 2791 2792 if (lseek(fd, KS_HASHED_PIN_SALT_LEN_OFFSET, SEEK_SET) 2793 != KS_HASHED_PIN_SALT_LEN_OFFSET) { 2794 goto cleanup; 2795 } 2796 2797 if (readn_nointr(fd, (char *)&hashed_pin_salt_size, 2798 KS_HASHED_PIN_SALT_LEN_SIZE) != KS_HASHED_PIN_SALT_LEN_SIZE) { 2799 goto cleanup; 2800 } 2801 hashed_pin_salt_size = SWAP64(hashed_pin_salt_size); 2802 2803 *salt = malloc(hashed_pin_salt_size + 1); 2804 if (*salt == NULL) { 2805 goto cleanup; 2806 } 2807 2808 if ((readn_nointr(fd, *salt, hashed_pin_salt_size)) 2809 != (ssize_t)hashed_pin_salt_size) { 2810 freezero(*salt, hashed_pin_salt_size + 1); 2811 goto cleanup; 2812 } 2813 (*salt)[hashed_pin_salt_size] = '\0'; 2814 2815 ret_val = 0; 2816 2817 cleanup: 2818 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 2819 ret_val = -1; 2820 } 2821 2822 (void) close(fd); 2823 return (ret_val); 2824 } 2825 2826 /* 2827 * FUNCTION: soft_keystore_pin_initialized 2828 * 2829 * ARGUMENTS: 2830 * initialized: This value will be set to true if keystore is 2831 * initialized, and false otherwise. 2832 * hashed_pin: If the keystore is initialized, this will contain 2833 * the hashed pin. It will be NULL if the keystore 2834 * pin is not initialized. Memory allocated 2835 * for the hashed pin needs to be freed by 2836 * the caller. 2837 * lock_held: TRUE if the lock is held by caller. 2838 * 2839 * RETURN VALUE: 2840 * CKR_OK: No error 2841 * any other appropriate CKR_value 2842 * 2843 * DESCRIPTION: 2844 * This API is used to determine if the PIN in the keystore 2845 * has been initialized or not. 2846 * It makes the determination using the salt for generating the 2847 * encryption key. The salt is stored in the keystore 2848 * descryption file. The salt should be all zero if 2849 * the keystore pin has not been initialized. 2850 * If the pin has been initialized, it is returned in the 2851 * hashed_pin argument. 2852 */ 2853 CK_RV 2854 soft_keystore_pin_initialized(boolean_t *initialized, char **hashed_pin, 2855 boolean_t lock_held) 2856 { 2857 int fd; 2858 CK_BYTE crypt_salt[KS_KEY_SALT_SIZE], tmp_buf[KS_KEY_SALT_SIZE]; 2859 CK_RV ret_val = CKR_OK; 2860 2861 if ((fd = open_and_lock_keystore_desc(O_RDONLY, B_FALSE, 2862 lock_held)) < 0) { 2863 return (CKR_FUNCTION_FAILED); 2864 } 2865 2866 if (lseek(fd, KS_KEY_SALT_OFFSET, SEEK_SET) != KS_KEY_SALT_OFFSET) { 2867 ret_val = CKR_FUNCTION_FAILED; 2868 goto cleanup; 2869 } 2870 2871 if (readn_nointr(fd, (char *)crypt_salt, KS_KEY_SALT_SIZE) 2872 != KS_KEY_SALT_SIZE) { 2873 ret_val = CKR_FUNCTION_FAILED; 2874 goto cleanup; 2875 } 2876 2877 (void) bzero(tmp_buf, KS_KEY_SALT_SIZE); 2878 2879 if (memcmp(crypt_salt, tmp_buf, KS_KEY_SALT_SIZE) == 0) { 2880 *initialized = B_FALSE; 2881 hashed_pin = NULL; 2882 } else { 2883 *initialized = B_TRUE; 2884 ret_val = get_hashed_pin(fd, hashed_pin); 2885 } 2886 2887 cleanup: 2888 2889 if (!lock_held) { 2890 if (lock_file(fd, B_TRUE, B_FALSE) < 0) { 2891 ret_val = CKR_FUNCTION_FAILED; 2892 } 2893 } 2894 2895 (void) close(fd); 2896 return (ret_val); 2897 } 2898 2899 /* 2900 * This checks if the keystore file exists 2901 */ 2902 2903 static int 2904 soft_keystore_exists() 2905 { 2906 int ret; 2907 struct stat fn_stat; 2908 char *fname, ks_desc_file[MAXPATHLEN]; 2909 2910 fname = get_desc_file_path(ks_desc_file); 2911 ret = stat(fname, &fn_stat); 2912 if (ret == 0) 2913 return (0); 2914 return (errno); 2915 } 2916 2917 /* 2918 * FUNCTION: soft_keystore_init 2919 * 2920 * ARGUMENTS: 2921 * desired_state: The keystore state the caller would like 2922 * it to be. 2923 * 2924 * RETURN VALUE: 2925 * Returns the state the function is in. If it succeeded, it 2926 * will be the same as the desired, if not it will be 2927 * KEYSTORE_UNAVAILABLE. 2928 * 2929 * DESCRIPTION: 2930 * This function will only load as much keystore data as is 2931 * requested at that time. This is for performace by delaying the 2932 * reading of token objects until they are needed or never at 2933 * all if they are not used. 2934 * 2935 * Primary use is from C_InitToken(). 2936 * It is also called by soft_keystore_status() when the 2937 * "desired_state" is not the the current load state of keystore. 2938 * 2939 */ 2940 int 2941 soft_keystore_init(int desired_state) 2942 { 2943 int ret; 2944 2945 (void) pthread_mutex_lock(&soft_slot.keystore_mutex); 2946 2947 /* 2948 * If more than one session tries to initialize the keystore, the 2949 * second and other following sessions that were waiting for the lock 2950 * will quickly exit if their requirements are satisfied. 2951 */ 2952 if (desired_state <= soft_slot.keystore_load_status) { 2953 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex); 2954 return (soft_slot.keystore_load_status); 2955 } 2956 2957 /* 2958 * With 'keystore_load_status' giving the current state of the 2959 * process, this switch will bring it up to the desired state if 2960 * possible. 2961 */ 2962 2963 switch (soft_slot.keystore_load_status) { 2964 case KEYSTORE_UNINITIALIZED: 2965 ret = soft_keystore_exists(); 2966 if (ret == 0) 2967 soft_slot.keystore_load_status = KEYSTORE_PRESENT; 2968 else if (ret == ENOENT) 2969 if (create_keystore() == 0) 2970 soft_slot.keystore_load_status = 2971 KEYSTORE_PRESENT; 2972 else { 2973 soft_slot.keystore_load_status = 2974 KEYSTORE_UNAVAILABLE; 2975 cryptoerror(LOG_DEBUG, 2976 "pkcs11_softtoken: " 2977 "Cannot create keystore."); 2978 break; 2979 } 2980 2981 if (desired_state <= KEYSTORE_PRESENT) 2982 break; 2983 2984 /* FALLTHRU */ 2985 case KEYSTORE_PRESENT: 2986 if (soft_keystore_get_version(&soft_slot.ks_version, B_FALSE) 2987 != 0) { 2988 soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE; 2989 cryptoerror(LOG_DEBUG, 2990 "pkcs11_softtoken: Keystore access failed."); 2991 break; 2992 } 2993 2994 soft_slot.keystore_load_status = KEYSTORE_LOAD; 2995 if (desired_state <= KEYSTORE_LOAD) 2996 break; 2997 2998 /* FALLTHRU */ 2999 case KEYSTORE_LOAD: 3000 /* Load all the public token objects from keystore */ 3001 if (soft_get_token_objects_from_keystore(PUB_TOKENOBJS) 3002 != CKR_OK) { 3003 (void) soft_destroy_token_session(); 3004 soft_slot.keystore_load_status = KEYSTORE_UNAVAILABLE; 3005 cryptoerror(LOG_DEBUG, 3006 "pkcs11_softtoken: Cannot initialize keystore."); 3007 break; 3008 } 3009 3010 soft_slot.keystore_load_status = KEYSTORE_INITIALIZED; 3011 }; 3012 3013 (void) pthread_mutex_unlock(&soft_slot.keystore_mutex); 3014 return (soft_slot.keystore_load_status); 3015 } 3016 3017 /* 3018 * FUNCTION: soft_keystore_status 3019 * 3020 * ARGUMENTS: 3021 * desired_state: The keystore state the caller would like 3022 * it to be. 3023 * 3024 * RETURN VALUE: 3025 * B_TRUE if keystore is ready and at the desired state. 3026 * B_FALSE if keystore had an error and is not available. 3027 * 3028 * DESCRIPTION: 3029 * The calling function wants to make sure the keystore load 3030 * status to in a state it requires. If it is not at that 3031 * state it will call the load function. 3032 * If keystore is at the desired state or has just been 3033 * loaded to that state, it will return TRUE. If there has been 3034 * load failure, it will return FALSE. 3035 * 3036 */ 3037 boolean_t 3038 soft_keystore_status(int desired_state) 3039 { 3040 3041 if (soft_slot.keystore_load_status == KEYSTORE_UNAVAILABLE) 3042 return (B_FALSE); 3043 3044 return ((desired_state <= soft_slot.keystore_load_status) || 3045 (soft_keystore_init(desired_state) == desired_state)); 3046 } 3047