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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #include <dlfcn.h> 29 #include <fcntl.h> 30 #include <link.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <strings.h> 34 #include <errno.h> 35 #include <door.h> 36 #include <pthread.h> 37 #include <sys/mman.h> 38 #include <libscf.h> 39 40 #include <sys/crypto/elfsign.h> 41 #include <cryptoutil.h> 42 43 #include <security/cryptoki.h> 44 #include "pkcs11Global.h" 45 #include "pkcs11Conf.h" 46 #include "pkcs11Slot.h" 47 #include "metaGlobal.h" 48 49 /* 50 * Fastpath is used when there is only one slot available from a single provider 51 * plugged into the framework this is the common case. 52 * These globals are used to track the function pointers and policy when 53 * the fast-path is activated. 54 * This will need to be revisted if per-slot policy is ever 55 * implemented. 56 */ 57 boolean_t purefastpath = B_FALSE; 58 boolean_t policyfastpath = B_FALSE; 59 CK_FUNCTION_LIST_PTR fast_funcs = NULL; 60 CK_SLOT_ID fast_slot = 0; 61 boolean_t metaslot_enabled = B_FALSE; 62 boolean_t metaslot_auto_key_migrate = B_FALSE; 63 metaslot_config_t metaslot_config; 64 void (*Tmp_GetThreshold)(void *) = NULL; 65 cipher_mechs_threshold_t meta_mechs_threshold[MAX_NUM_THRESHOLD]; 66 67 static const char *conf_err = "See cryptoadm(1M). Skipping this plug-in."; 68 69 #define CRYPTOSVC_DEFAULT_INSTANCE_FMRI "svc:/system/cryptosvc:default" 70 #define MAX_CRYPTOSVC_ONLINE_TRIES 5 71 72 /* 73 * Set up metaslot for the framework using either user configuration 74 * or system wide configuration options 75 * 76 * Also sets up the global "slottable" to have the first slot be metaslot. 77 */ 78 static CK_RV 79 setup_metaslot(uentry_t *metaslot_entry) { 80 CK_RV rv; 81 CK_MECHANISM_TYPE_PTR prov_pol_mechs = NULL; 82 pkcs11_slot_t *cur_slot; 83 84 /* process policies for mechanisms */ 85 if ((metaslot_entry) && (metaslot_entry->count > 0)) { 86 rv = pkcs11_mech_parse(metaslot_entry->policylist, 87 &prov_pol_mechs, metaslot_entry->count); 88 89 if (rv == CKR_HOST_MEMORY) { 90 cryptoerror(LOG_ERR, 91 "libpkcs11: Could not parse configuration," 92 "out of memory. Cannot continue parsing " 93 "%s.\n", _PATH_PKCS11_CONF); 94 return (rv); 95 } else if (rv == CKR_MECHANISM_INVALID) { 96 /* 97 * Configuration file is corrupted for metaslot 98 */ 99 cryptoerror(LOG_ERR, 100 "libpkcs11: Policy invalid or corrupted " 101 "for metaslot. Use cryptoadm(1M) to fix " 102 "this. Disabling metaslot functionality.\n"); 103 metaslot_enabled = B_FALSE; 104 return (rv); 105 } 106 } 107 108 /* 109 * Check for metaslot policy. If all mechanisms are 110 * disabled, disable metaslot since there is nothing 111 * interesting for it to do 112 */ 113 if ((metaslot_entry) && (metaslot_entry->flag_enabledlist) && 114 (prov_pol_mechs == NULL)) { 115 metaslot_enabled = B_FALSE; 116 return (rv); 117 } 118 119 /* 120 * save system wide value for metaslot's keystore. 121 * If either slot description or token label is specified by 122 * the user, the system wide value for both is ignored. 123 */ 124 if ((metaslot_entry) && 125 (!metaslot_config.keystore_token_specified) && 126 (!metaslot_config.keystore_slot_specified)) { 127 /* 128 * blank_str is used for comparing with token label, 129 * and slot description, make sure it is better than 130 * the larger of both 131 */ 132 char blank_str[TOKEN_LABEL_SIZE + SLOT_DESCRIPTION_SIZE]; 133 134 bzero(blank_str, sizeof (blank_str)); 135 136 if (memcmp(metaslot_entry->metaslot_ks_token, 137 blank_str, TOKEN_LABEL_SIZE) != 0) { 138 metaslot_config.keystore_token_specified = B_TRUE; 139 (void) strlcpy( 140 (char *)metaslot_config.keystore_token, 141 (const char *)metaslot_entry->metaslot_ks_token, 142 TOKEN_LABEL_SIZE); 143 } 144 145 if (memcmp(metaslot_entry->metaslot_ks_slot, 146 blank_str, SLOT_DESCRIPTION_SIZE) != 0) { 147 metaslot_config.keystore_slot_specified = B_TRUE; 148 (void) strlcpy( 149 (char *)metaslot_config.keystore_slot, 150 (const char *)metaslot_entry->metaslot_ks_slot, 151 SLOT_DESCRIPTION_SIZE); 152 } 153 } 154 155 /* check system-wide value for auto_key_migrate */ 156 if (metaslot_config.auto_key_migrate_specified) { 157 /* take user's specified value */ 158 metaslot_auto_key_migrate = metaslot_config.auto_key_migrate; 159 } else { 160 if (metaslot_entry) { 161 /* use system-wide default */ 162 metaslot_auto_key_migrate = 163 metaslot_entry->flag_metaslot_auto_key_migrate; 164 } else { 165 /* 166 * there's no system wide metaslot entry, 167 * default auto_key_migrate to true 168 */ 169 metaslot_auto_key_migrate = B_TRUE; 170 } 171 } 172 173 174 /* Make first slotID be 0, for metaslot. */ 175 slottable->st_first = 0; 176 177 /* Set up the slottable entry for metaslot */ 178 slottable->st_slots[0] = NULL; 179 cur_slot = calloc(1, sizeof (pkcs11_slot_t)); 180 if (cur_slot == NULL) { 181 rv = CKR_HOST_MEMORY; 182 return (rv); 183 } 184 cur_slot->sl_wfse_state = WFSE_CLEAR; 185 cur_slot->sl_enabledpol = B_FALSE; 186 cur_slot->sl_no_wfse = B_FALSE; 187 (void) pthread_mutex_init(&cur_slot->sl_mutex, NULL); 188 189 /* 190 * The metaslot entry was prealloc'd by 191 * pkcs11_slottable_increase() 192 */ 193 (void) pthread_mutex_lock(&slottable->st_mutex); 194 slottable->st_slots[0] = cur_slot; 195 (void) pthread_mutex_unlock(&slottable->st_mutex); 196 197 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 198 cur_slot->sl_id = METASLOT_SLOTID; 199 cur_slot->sl_func_list = &metaslot_functionList; 200 if (metaslot_entry) { 201 cur_slot->sl_enabledpol = metaslot_entry->flag_enabledlist; 202 cur_slot->sl_pol_count = metaslot_entry->count; 203 } else { 204 /* if no metaslot entry, assume all mechs are enabled */ 205 cur_slot->sl_enabledpol = B_FALSE; 206 cur_slot->sl_pol_count = 0; 207 } 208 cur_slot->sl_pol_mechs = prov_pol_mechs; 209 cur_slot->sl_dldesc = NULL; /* not applicable */ 210 cur_slot->sl_prov_id = 0; 211 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 212 213 /* Call the meta_Initialize() to initialize metaslot */ 214 rv = meta_Initialize(NULL); 215 if (rv != CKR_OK) { 216 cryptoerror(LOG_ERR, 217 "libpkcs11: Can't initialize metaslot (%s)", 218 pkcs11_strerror(rv)); 219 goto cleanup; 220 } 221 222 return (CKR_OK); 223 224 cleanup: 225 metaslot_enabled = B_FALSE; 226 slottable->st_slots[0] = NULL; 227 228 if (cur_slot) { 229 (void) pthread_mutex_destroy(&cur_slot->sl_mutex); 230 free(cur_slot); 231 } 232 return (rv); 233 } 234 235 /* 236 * cryptosvc_is_online() 237 * 238 * Determine if the SMF service instance is in the online state or 239 * not. A number of operations depend on this state. 240 */ 241 static boolean_t 242 cryptosvc_is_online(void) 243 { 244 char *str; 245 boolean_t ret = B_FALSE; 246 247 if ((str = smf_get_state(CRYPTOSVC_DEFAULT_INSTANCE_FMRI)) != NULL) { 248 ret = (strcmp(str, SCF_STATE_STRING_ONLINE) == 0); 249 free(str); 250 } 251 return (ret); 252 } 253 254 /* 255 * cryptosvc_is_down() 256 * 257 * Determine if the SMF service instance is in the disabled state or 258 * maintenance state. A number of operations depend on this state. 259 */ 260 static boolean_t 261 cryptosvc_is_down(void) 262 { 263 char *str; 264 boolean_t ret = B_FALSE; 265 266 if ((str = smf_get_state(CRYPTOSVC_DEFAULT_INSTANCE_FMRI)) != NULL) { 267 ret = ((strcmp(str, SCF_STATE_STRING_DISABLED) == 0) || 268 (strcmp(str, SCF_STATE_STRING_MAINT) == 0)); 269 free(str); 270 } 271 return (ret); 272 } 273 274 275 /* Generic function for all door calls to kcfd. */ 276 ELFsign_status_t 277 kcfd_door_call(char *fullpath, boolean_t fips140, CK_RV *rv) 278 { 279 boolean_t try_door_open_again = B_FALSE; 280 int kcfdfd = -1; 281 door_arg_t darg; 282 kcf_door_arg_t *kda = NULL; 283 kcf_door_arg_t *rkda = NULL; 284 int r; 285 int is_cryptosvc_up_count = 0; 286 int door_errno = 0; 287 ELFsign_status_t estatus = ELFSIGN_UNKNOWN; 288 289 open_door_file: 290 while ((kcfdfd = open(_PATH_KCFD_DOOR, O_RDONLY)) == -1) { 291 /* save errno and test for EINTR or EAGAIN */ 292 door_errno = errno; 293 if (door_errno == EINTR || 294 door_errno == EAGAIN) 295 continue; 296 /* if disabled or maintenance mode - bail */ 297 if (cryptosvc_is_down()) 298 break; 299 /* exceeded our number of tries? */ 300 if (is_cryptosvc_up_count > MAX_CRYPTOSVC_ONLINE_TRIES) 301 break; 302 /* any other state, try again up to 1/2 minute */ 303 (void) sleep(5); 304 is_cryptosvc_up_count++; 305 } 306 if (kcfdfd == -1) { 307 if (!cryptosvc_is_online()) { 308 cryptoerror(LOG_ERR, "libpkcs11: unable to communicate" 309 " with kcfd, door_file %s: %s. %s is not online." 310 " (see svcs -xv for details).", 311 _PATH_KCFD_DOOR, strerror(door_errno), 312 CRYPTOSVC_DEFAULT_INSTANCE_FMRI); 313 } else { 314 cryptoerror(LOG_ERR, "libpkcs11: unable to open" 315 " kcfd door_file %s: %s.", _PATH_KCFD_DOOR, 316 strerror(door_errno)); 317 } 318 *rv = CKR_CRYPTOKI_NOT_INITIALIZED; 319 estatus = ELFSIGN_UNAVAILABLE; 320 goto verifycleanup; 321 } 322 323 /* Mark the door "close on exec" */ 324 (void) fcntl(kcfdfd, F_SETFD, FD_CLOEXEC); 325 326 if ((kda = malloc(sizeof (kcf_door_arg_t))) == NULL) { 327 cryptoerror(LOG_ERR, "libpkcs11: malloc of kda " 328 "failed: %s", strerror(errno)); 329 goto verifycleanup; 330 } 331 332 if (fips140 == B_TRUE) 333 kda->da_version = KCFD_FIPS140_INTCHECK; 334 else { 335 kda->da_version = KCF_KCFD_VERSION1; 336 (void) strlcpy(kda->da_u.filename, fullpath, 337 strlen(fullpath) + 1); 338 } 339 340 kda->da_iskernel = B_FALSE; 341 342 darg.data_ptr = (char *)kda; 343 darg.data_size = sizeof (kcf_door_arg_t); 344 darg.desc_ptr = NULL; 345 darg.desc_num = 0; 346 darg.rbuf = (char *)kda; 347 darg.rsize = sizeof (kcf_door_arg_t); 348 349 while ((r = door_call(kcfdfd, &darg)) != 0) { 350 /* save errno and test for certain errors */ 351 door_errno = errno; 352 if (door_errno == EINTR || door_errno == EAGAIN) 353 continue; 354 /* if disabled or maintenance mode - bail */ 355 if (cryptosvc_is_down()) 356 break; 357 /* exceeded our number of tries? */ 358 if (is_cryptosvc_up_count > MAX_CRYPTOSVC_ONLINE_TRIES) 359 break; 360 /* if stale door_handle, retry the open */ 361 if (door_errno == EBADF) { 362 try_door_open_again = B_TRUE; 363 is_cryptosvc_up_count++; 364 (void) sleep(5); 365 goto verifycleanup; 366 } else 367 break; 368 } 369 370 if (r != 0) { 371 if (!cryptosvc_is_online()) { 372 cryptoerror(LOG_ERR, "%s is not online " 373 " - unable to utilize cryptographic " 374 "services. (see svcs -xv for details).", 375 CRYPTOSVC_DEFAULT_INSTANCE_FMRI); 376 } else { 377 cryptoerror(LOG_ERR, "libpkcs11: door_call " 378 "of door_file %s failed with error %s.", 379 _PATH_KCFD_DOOR, strerror(door_errno)); 380 } 381 *rv = CKR_CRYPTOKI_NOT_INITIALIZED; 382 estatus = ELFSIGN_UNAVAILABLE; 383 goto verifycleanup; 384 } 385 386 /*LINTED*/ 387 rkda = (kcf_door_arg_t *)darg.rbuf; 388 if ((fips140 == B_FALSE && rkda->da_version != KCF_KCFD_VERSION1) || 389 (fips140 == B_TRUE && rkda->da_version != KCFD_FIPS140_INTCHECK)) { 390 cryptoerror(LOG_ERR, 391 "libpkcs11: kcfd and libelfsign versions " 392 "don't match: got %d expected %d", rkda->da_version, 393 (fips140) ? KCFD_FIPS140_INTCHECK : KCF_KCFD_VERSION1); 394 goto verifycleanup; 395 } 396 estatus = rkda->da_u.result.status; 397 verifycleanup: 398 if (kcfdfd != -1) { 399 (void) close(kcfdfd); 400 } 401 if (rkda != NULL && rkda != kda) 402 (void) munmap((char *)rkda, darg.rsize); 403 if (kda != NULL) { 404 bzero(kda, sizeof (kda)); 405 free(kda); 406 kda = NULL; 407 rkda = NULL; /* rkda is an alias of kda */ 408 } 409 if (try_door_open_again) { 410 try_door_open_again = B_FALSE; 411 goto open_door_file; 412 } 413 414 return (estatus); 415 } 416 417 418 /* 419 * For each provider found in pkcs11.conf: expand $ISA if necessary, 420 * verify the module is signed, load the provider, find all of its 421 * slots, and store the function list and disabled policy. 422 * 423 * This function requires that the uentrylist_t and pkcs11_slottable_t 424 * already have memory allocated, and that the uentrylist_t is already 425 * populated with provider and policy information. 426 * 427 * pInitArgs can be set to NULL, but is normally the same value 428 * the framework's C_Initialize() was called with. 429 * 430 * Unless metaslot is explicitly disabled, it is setup when all other 431 * providers are loaded. 432 */ 433 CK_RV 434 pkcs11_slot_mapping(uentrylist_t *pplist, CK_VOID_PTR pInitArgs) 435 { 436 CK_RV rv = CKR_OK; 437 CK_RV prov_rv; /* Provider's return code */ 438 CK_INFO prov_info; 439 CK_RV (*Tmp_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR); 440 CK_FUNCTION_LIST_PTR prov_funcs = NULL; /* Provider's function list */ 441 CK_ULONG prov_slot_count; /* Number of slots */ 442 CK_SLOT_ID slot_id; /* slotID assigned for framework */ 443 CK_SLOT_ID_PTR prov_slots = NULL; /* Provider's slot list */ 444 /* Enabled or Disabled policy */ 445 CK_MECHANISM_TYPE_PTR prov_pol_mechs = NULL; 446 447 void *dldesc = NULL; 448 char *isa, *fullpath = NULL, *dl_error; 449 uentrylist_t *phead; 450 uint_t prov_count = 0; 451 pkcs11_slot_t *cur_slot; 452 CK_ULONG i; 453 size_t len; 454 uentry_t *metaslot_entry = NULL; 455 /* number of slots in the framework, not including metaslot */ 456 uint_t slot_count = 0; 457 458 ELFsign_status_t estatus = ELFSIGN_UNKNOWN; 459 char *estatus_str = NULL; 460 int fips140_mode = CRYPTO_FIPS_MODE_DISABLED; 461 462 /* Check FIPS 140 configuration and execute check if enabled */ 463 (void) get_fips_mode(&fips140_mode); 464 if (fips140_mode) { 465 estatus = kcfd_door_call(NULL, B_TRUE, &rv); 466 if (estatus != ELFSIGN_SUCCESS) { 467 cryptoerror(LOG_ERR, "libpkcs11: failed FIPS 140 " 468 "integrity check."); 469 return (CKR_GENERAL_ERROR); 470 } 471 } 472 473 phead = pplist; 474 475 /* Loop through all of the provider listed in pkcs11.conf */ 476 while (phead != NULL) { 477 if (!strcasecmp(phead->puent->name, "metaslot")) { 478 /* 479 * Skip standard processing for metaslot 480 * entry since it is not an actual library 481 * that can be dlopened. 482 * It will be initialized later. 483 */ 484 if (metaslot_entry != NULL) { 485 cryptoerror(LOG_ERR, 486 "libpkcs11: multiple entries for metaslot " 487 "detected. All but the first entry will " 488 "be ignored"); 489 } else { 490 metaslot_entry = phead->puent; 491 } 492 goto contparse; 493 } 494 495 if (!strcasecmp(phead->puent->name, FIPS_KEYWORD)) { 496 /* 497 * Skip standard processing for fips-140 498 * entry since it is not an actual library 499 * that can be dlopened. 500 */ 501 goto contparse; 502 } 503 504 /* Check for Instruction Set Architecture indicator */ 505 if ((isa = strstr(phead->puent->name, PKCS11_ISA)) != NULL) { 506 /* Substitute the architecture dependent path */ 507 len = strlen(phead->puent->name) - 508 strlen(PKCS11_ISA) + 509 strlen(PKCS11_ISA_DIR) + 1; 510 if ((fullpath = (char *)malloc(len)) == NULL) { 511 cryptoerror(LOG_ERR, 512 "libpksc11: parsing %s, out of memory. " 513 "Cannot continue parsing.", 514 _PATH_PKCS11_CONF); 515 rv = CKR_HOST_MEMORY; 516 goto conferror; 517 } 518 *isa = '\000'; 519 isa += strlen(PKCS11_ISA); 520 (void) snprintf(fullpath, len, "%s%s%s", 521 phead->puent->name, PKCS11_ISA_DIR, isa); 522 } else if ((fullpath = strdup(phead->puent->name)) == 0) { 523 cryptoerror(LOG_ERR, 524 "libpkcs11: parsing %s, out of memory. " 525 "Cannot continue parsing.", 526 _PATH_PKCS11_CONF); 527 rv = CKR_HOST_MEMORY; 528 goto conferror; 529 } 530 531 /* 532 * Open the provider. Use RTLD_NOW to make sure we 533 * will not encounter symbol referencing errors later. 534 * Use RTLD_GROUP to limit the provider to it's own 535 * symbols, which prevents it from mistakenly accessing 536 * the framework's C_* functions. 537 */ 538 dldesc = dlopen(fullpath, RTLD_NOW|RTLD_GROUP); 539 540 /* 541 * If we failed to load it, we will just skip this 542 * provider and move on to the next one. 543 */ 544 if (dldesc == NULL) { 545 dl_error = dlerror(); 546 cryptoerror(LOG_ERR, 547 "libpkcs11: Cannot load PKCS#11 library %s. " 548 "dlerror: %s. %s", 549 fullpath, dl_error != NULL ? dl_error : "Unknown", 550 conf_err); 551 goto contparse; 552 } 553 554 /* Get the pointer to provider's C_GetFunctionList() */ 555 Tmp_C_GetFunctionList = 556 (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList"); 557 558 /* 559 * If we failed to get the pointer to C_GetFunctionList(), 560 * skip this provider and continue to the next one. 561 */ 562 if (Tmp_C_GetFunctionList == NULL) { 563 cryptoerror(LOG_ERR, 564 "libpkcs11: Could not dlsym() C_GetFunctionList() " 565 "for %s. May not be a PKCS#11 library. %s", 566 fullpath, conf_err); 567 (void) dlclose(dldesc); 568 goto contparse; 569 } 570 571 572 /* Get the provider's function list */ 573 prov_rv = Tmp_C_GetFunctionList(&prov_funcs); 574 575 /* 576 * If we failed to get the provider's function list, 577 * skip this provider and continue to the next one. 578 */ 579 if (prov_rv != CKR_OK) { 580 cryptoerror(LOG_ERR, 581 "libpkcs11: Could not get function list for %s. " 582 "%s Error: %s.", 583 fullpath, conf_err, pkcs11_strerror(prov_rv)); 584 (void) dlclose(dldesc); 585 goto contparse; 586 } 587 588 /* Initialize this provider */ 589 prov_rv = prov_funcs->C_Initialize(pInitArgs); 590 591 /* 592 * If we failed to initialize this provider, 593 * skip this provider and continue to the next one. 594 */ 595 if ((prov_rv != CKR_OK) && 596 (prov_rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 597 cryptoerror(LOG_ERR, 598 "libpkcs11: Could not initialize %s. " 599 "%s Error: %s.", 600 fullpath, conf_err, pkcs11_strerror(prov_rv)); 601 (void) dlclose(dldesc); 602 goto contparse; 603 } 604 605 /* 606 * Make sure this provider is implementing the same 607 * major version, and at least the same minor version 608 * that we are. 609 */ 610 prov_rv = prov_funcs->C_GetInfo(&prov_info); 611 612 /* 613 * If we can't verify that we are implementing the 614 * same major version, or if it is definitely not the same 615 * version, we need to skip this provider. 616 */ 617 if ((prov_rv != CKR_OK) || 618 (prov_info.cryptokiVersion.major != 619 CRYPTOKI_VERSION_MAJOR)) { 620 if (prov_rv != CKR_OK) { 621 cryptoerror(LOG_ERR, 622 "libpkcs11: Could not verify version of " 623 "%s. %s Error: %s.", fullpath, 624 conf_err, pkcs11_strerror(prov_rv)); 625 } else { 626 cryptoerror(LOG_ERR, 627 "libpkcs11: Only CRYPTOKI major version " 628 "%d is supported. %s is major " 629 "version %d. %s", 630 CRYPTOKI_VERSION_MAJOR, fullpath, 631 prov_info.cryptokiVersion.major, conf_err); 632 } 633 (void) prov_funcs->C_Finalize(NULL); 634 (void) dlclose(dldesc); 635 goto contparse; 636 } 637 638 /* 639 * Warn the administrator (at debug) that a provider with 640 * a significantly older or newer version of 641 * CRYPTOKI is being used. It should not cause 642 * problems, but logging a warning makes it easier 643 * to debug later. 644 */ 645 if ((prov_info.cryptokiVersion.minor < 646 CRYPTOKI_VERSION_WARN_MINOR) || 647 (prov_info.cryptokiVersion.minor > 648 CRYPTOKI_VERSION_MINOR)) { 649 cryptoerror(LOG_DEBUG, 650 "libpkcs11: %s CRYPTOKI minor version, %d, may " 651 "not be compatible with minor version %d.", 652 fullpath, prov_info.cryptokiVersion.minor, 653 CRYPTOKI_VERSION_MINOR); 654 } 655 656 /* 657 * Find out how many slots this provider has, 658 * call with tokenPresent set to FALSE so all 659 * potential slots are returned. 660 */ 661 prov_rv = prov_funcs->C_GetSlotList(FALSE, 662 NULL, &prov_slot_count); 663 664 /* 665 * If the call failed, or if no slots are returned, 666 * then skip this provider and continue to next one. 667 */ 668 if (prov_rv != CKR_OK) { 669 cryptoerror(LOG_ERR, 670 "libpksc11: Could not get slot list from %s. " 671 "%s Error: %s.", 672 fullpath, conf_err, pkcs11_strerror(prov_rv)); 673 (void) prov_funcs->C_Finalize(NULL); 674 (void) dlclose(dldesc); 675 goto contparse; 676 } 677 678 if (prov_slot_count == 0) { 679 cryptodebug("libpkcs11: No slots presented from %s. " 680 "Skipping this plug-in at this time.\n", 681 fullpath); 682 (void) prov_funcs->C_Finalize(NULL); 683 (void) dlclose(dldesc); 684 goto contparse; 685 } 686 687 /* 688 * Verify that the module is signed correctly. 689 * 690 * NOTE: there is a potential race condition here, 691 * since the module is verified well after we have 692 * opened the provider via dlopen(). This could be 693 * resolved by a variant of dlopen() that would take a 694 * file descriptor as an argument and by changing the 695 * kcfd libelfsign door protocol to use and fd instead 696 * of a path - but that wouldn't work in the kernel case. 697 */ 698 estatus = kcfd_door_call(fullpath, B_FALSE, &rv); 699 700 switch (estatus) { 701 case ELFSIGN_SUCCESS: 702 case ELFSIGN_RESTRICTED: 703 break; 704 case ELFSIGN_NOTSIGNED: 705 estatus_str = strdup("not a signed provider."); 706 break; 707 case ELFSIGN_FAILED: 708 estatus_str = strdup("signature verification failed."); 709 break; 710 case ELFSIGN_UNAVAILABLE: 711 estatus_str = strdup("kcfd(1m) is not available for " 712 "signature verification. Cannot continue loading " 713 "the cryptographic framework."); 714 break; 715 default: 716 estatus_str = strdup("unexpected failure in ELF " 717 "signature verification."); 718 } 719 if (estatus_str != NULL) { 720 cryptoerror(LOG_ERR, "libpkcs11: %s %s %s", 721 fullpath, estatus_str, 722 (estatus == ELFSIGN_UNKNOWN || 723 estatus == ELFSIGN_UNAVAILABLE) ? 724 "See cryptoadm (1M). Cannot continue parsing " 725 _PATH_PKCS11_CONF : conf_err); 726 (void) prov_funcs->C_Finalize(NULL); 727 (void) dlclose(dldesc); 728 free(estatus_str); 729 estatus_str = NULL; 730 if (estatus == ELFSIGN_UNKNOWN || 731 estatus == ELFSIGN_UNAVAILABLE) { 732 prov_funcs = NULL; 733 dldesc = NULL; 734 rv = CKR_GENERAL_ERROR; 735 goto conferror; 736 } 737 goto contparse; 738 } 739 740 /* Allocate memory for the slot list */ 741 prov_slots = calloc(prov_slot_count, sizeof (CK_SLOT_ID)); 742 743 if (prov_slots == NULL) { 744 cryptoerror(LOG_ERR, 745 "libpkcs11: Could not allocate memory for " 746 "plug-in slots. Cannot continue parsing %s\n", 747 _PATH_PKCS11_CONF); 748 rv = CKR_HOST_MEMORY; 749 goto conferror; 750 } 751 752 /* Get slot list from provider */ 753 prov_rv = prov_funcs->C_GetSlotList(FALSE, 754 prov_slots, &prov_slot_count); 755 756 /* if second call fails, drop this provider */ 757 if (prov_rv != CKR_OK) { 758 cryptoerror(LOG_ERR, 759 "libpkcs11: Second call to C_GetSlotList() for %s " 760 "failed. %s Error: %s.", 761 fullpath, conf_err, pkcs11_strerror(prov_rv)); 762 (void) prov_funcs->C_Finalize(NULL); 763 (void) dlclose(dldesc); 764 goto contparse; 765 } 766 767 /* 768 * Parse the list of disabled or enabled mechanisms, will 769 * apply to each of the provider's slots. 770 */ 771 if (phead->puent->count > 0) { 772 rv = pkcs11_mech_parse(phead->puent->policylist, 773 &prov_pol_mechs, phead->puent->count); 774 775 if (rv == CKR_HOST_MEMORY) { 776 cryptoerror(LOG_ERR, 777 "libpkcs11: Could not parse configuration," 778 "out of memory. Cannot continue parsing " 779 "%s.", _PATH_PKCS11_CONF); 780 goto conferror; 781 } else if (rv == CKR_MECHANISM_INVALID) { 782 /* 783 * Configuration file is corrupted for this 784 * provider. 785 */ 786 cryptoerror(LOG_ERR, 787 "libpkcs11: Policy invalid or corrupted " 788 "for %s. Use cryptoadm(1M) to fix " 789 "this. Skipping this plug-in.", 790 fullpath); 791 (void) prov_funcs->C_Finalize(NULL); 792 (void) dlclose(dldesc); 793 goto contparse; 794 } 795 } 796 797 /* Allocate memory in our slottable for these slots */ 798 rv = pkcs11_slottable_increase(prov_slot_count); 799 800 /* 801 * If any error is returned, it will be memory related, 802 * so we need to abort the attempt at filling the 803 * slottable. 804 */ 805 if (rv != CKR_OK) { 806 cryptoerror(LOG_ERR, 807 "libpkcs11: slottable could not increase. " 808 "Cannot continue parsing %s.", 809 _PATH_PKCS11_CONF); 810 goto conferror; 811 } 812 813 /* Configure information for each new slot */ 814 for (i = 0; i < prov_slot_count; i++) { 815 /* allocate slot in framework */ 816 rv = pkcs11_slot_allocate(&slot_id); 817 if (rv != CKR_OK) { 818 cryptoerror(LOG_ERR, 819 "libpkcs11: Could not allocate " 820 "new slot. Cannot continue parsing %s.", 821 _PATH_PKCS11_CONF); 822 goto conferror; 823 } 824 slot_count++; 825 cur_slot = slottable->st_slots[slot_id]; 826 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 827 cur_slot->sl_id = prov_slots[i]; 828 cur_slot->sl_func_list = prov_funcs; 829 cur_slot->sl_enabledpol = 830 phead->puent->flag_enabledlist; 831 cur_slot->sl_pol_mechs = prov_pol_mechs; 832 cur_slot->sl_pol_count = phead->puent->count; 833 cur_slot->sl_norandom = phead->puent->flag_norandom; 834 cur_slot->sl_dldesc = dldesc; 835 cur_slot->sl_prov_id = prov_count + 1; 836 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 837 } 838 839 /* 840 * Get the pointer to private interface _SUNW_GetThreshold() 841 * in pkcs11_kernel. 842 */ 843 844 if (Tmp_GetThreshold == NULL) { 845 Tmp_GetThreshold = 846 (void(*)())dlsym(dldesc, "_SUNW_GetThreshold"); 847 848 /* Get the threshold values for the supported mechs */ 849 if (Tmp_GetThreshold != NULL) { 850 (void) memset(meta_mechs_threshold, 0, 851 sizeof (meta_mechs_threshold)); 852 Tmp_GetThreshold(meta_mechs_threshold); 853 } 854 } 855 856 /* Set and reset values to process next provider */ 857 prov_count++; 858 contparse: 859 prov_slot_count = 0; 860 Tmp_C_GetFunctionList = NULL; 861 prov_funcs = NULL; 862 dldesc = NULL; 863 if (fullpath != NULL) { 864 free(fullpath); 865 fullpath = NULL; 866 } 867 if (prov_slots != NULL) { 868 free(prov_slots); 869 prov_slots = NULL; 870 } 871 phead = phead->next; 872 } 873 874 if (slot_count == 0) { 875 /* 876 * there's no other slot in the framework, 877 * there is nothing to do 878 */ 879 goto config_complete; 880 } 881 882 /* determine if metaslot should be enabled */ 883 884 /* 885 * Check to see if any environment variable is defined 886 * by the user for configuring metaslot. Users' 887 * setting always take precedence over the system wide 888 * setting. So, we will first check for any user's 889 * defined env variables before looking at the system-wide 890 * configuration. 891 */ 892 get_user_metaslot_config(); 893 894 /* no metaslot entry in /etc/crypto/pkcs11.conf */ 895 if (!metaslot_entry) { 896 /* 897 * If user env variable indicates metaslot should be enabled, 898 * but there's no entry in /etc/crypto/pkcs11.conf for 899 * metaslot at all, will respect the user's defined value 900 */ 901 if ((metaslot_config.enabled_specified) && 902 (metaslot_config.enabled)) { 903 metaslot_enabled = B_TRUE; 904 } 905 } else { 906 if (!metaslot_config.enabled_specified) { 907 /* 908 * take system wide value if 909 * it is not specified by user 910 */ 911 metaslot_enabled 912 = metaslot_entry->flag_metaslot_enabled; 913 } else { 914 metaslot_enabled = metaslot_config.enabled; 915 } 916 } 917 918 /* 919 * 920 * As long as the user or system configuration file does not 921 * disable metaslot, it will be enabled regardless of the 922 * number of slots plugged into the framework. Therefore, 923 * metaslot is enabled even when there's only one slot 924 * plugged into the framework. This is necessary for 925 * presenting a consistent token label view to applications. 926 * 927 * However, for the case where there is only 1 slot plugged into 928 * the framework, we can use "fastpath". 929 * 930 * "fastpath" will pass all of the application's requests 931 * directly to the underlying provider. Only when policy is in 932 * effect will we need to keep slotID around. 933 * 934 * When metaslot is enabled, and fastpath is enabled, 935 * all the metaslot processing will be skipped. 936 * When there is only 1 slot, there's 937 * really not much metaslot can do in terms of combining functionality 938 * of different slots, and object migration. 939 * 940 */ 941 942 /* check to see if fastpath can be used */ 943 if (slottable->st_last == slottable->st_first) { 944 945 cur_slot = slottable->st_slots[slottable->st_first]; 946 947 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 948 949 if ((cur_slot->sl_pol_count == 0) && 950 (!cur_slot->sl_enabledpol) && (!cur_slot->sl_norandom)) { 951 /* No policy is in effect, don't need slotid */ 952 fast_funcs = cur_slot->sl_func_list; 953 purefastpath = B_TRUE; 954 } else { 955 fast_funcs = cur_slot->sl_func_list; 956 fast_slot = slottable->st_first; 957 policyfastpath = B_TRUE; 958 } 959 960 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 961 } 962 963 if ((purefastpath || policyfastpath) && (!metaslot_enabled)) { 964 goto config_complete; 965 } 966 967 /* 968 * If we get here, there are more than 2 slots in the framework, 969 * we need to set up metaslot if it is enabled 970 */ 971 if (metaslot_enabled) { 972 rv = setup_metaslot(metaslot_entry); 973 if (rv != CKR_OK) { 974 goto conferror; 975 } 976 } 977 978 979 config_complete: 980 981 return (CKR_OK); 982 983 conferror: 984 /* 985 * This cleanup code is only exercised when a major, 986 * unrecoverable error like "out of memory" occurs. 987 */ 988 if (prov_funcs != NULL) { 989 (void) prov_funcs->C_Finalize(NULL); 990 } 991 if (dldesc != NULL) { 992 (void) dlclose(dldesc); 993 } 994 if (fullpath != NULL) { 995 free(fullpath); 996 fullpath = NULL; 997 } 998 if (prov_slots != NULL) { 999 free(prov_slots); 1000 prov_slots = NULL; 1001 } 1002 1003 return (rv); 1004 } 1005 1006 /* 1007 * pkcs11_mech_parse will take hex mechanism ids, as a list of 1008 * strings, and convert them to CK_MECHANISM_TYPE_PTR. 1009 */ 1010 CK_RV 1011 pkcs11_mech_parse(umechlist_t *str_list, CK_MECHANISM_TYPE_PTR *mech_list, 1012 int mech_count) 1013 { 1014 CK_MECHANISM_TYPE_PTR tmp_list; 1015 umechlist_t *shead = str_list; 1016 1017 tmp_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE)); 1018 1019 if (tmp_list == NULL) { 1020 cryptoerror(LOG_ERR, "libpkcs11: parsing %s, out of memory. " 1021 "Cannot continue.", 1022 _PATH_PKCS11_CONF); 1023 return (CKR_HOST_MEMORY); 1024 } 1025 1026 *mech_list = tmp_list; 1027 1028 /* 1029 * The following will loop mech_count times, as there are 1030 * exactly mech_count items in the str_list. 1031 */ 1032 while (shead != NULL) { 1033 CK_MECHANISM_TYPE cur_mech; 1034 1035 errno = 0; 1036 1037 /* 1038 * "name" is a hexadecimal number, preceded by 0x. 1039 */ 1040 cur_mech = strtoul(shead->name, NULL, 16); 1041 1042 if ((cur_mech == 0) && 1043 ((errno == EINVAL) || (errno == ERANGE))) { 1044 free(mech_list); 1045 return (CKR_MECHANISM_INVALID); 1046 } 1047 *tmp_list = (CK_MECHANISM_TYPE)cur_mech; 1048 tmp_list++; 1049 shead = shead->next; 1050 } 1051 1052 return (CKR_OK); 1053 } 1054 1055 /* 1056 * pkcs11_is_dismech is provided a slotid and a mechanism. 1057 * If mech is not disabled, then return B_FALSE. 1058 */ 1059 boolean_t 1060 pkcs11_is_dismech(CK_SLOT_ID slotid, CK_MECHANISM_TYPE mech) 1061 { 1062 ulong_t i; 1063 boolean_t enabled_pol; 1064 CK_MECHANISM_TYPE_PTR pol_mechs; 1065 ulong_t pol_count; 1066 1067 /* Find the associated slot and get the mech policy info */ 1068 (void) pthread_mutex_lock(&slottable->st_slots[slotid]->sl_mutex); 1069 enabled_pol = slottable->st_slots[slotid]->sl_enabledpol; 1070 pol_mechs = slottable->st_slots[slotid]->sl_pol_mechs; 1071 pol_count = slottable->st_slots[slotid]->sl_pol_count; 1072 (void) pthread_mutex_unlock(&slottable->st_slots[slotid]->sl_mutex); 1073 1074 /* Check for policy */ 1075 if ((!enabled_pol) && (pol_mechs == NULL)) { 1076 /* no policy */ 1077 return (B_FALSE); 1078 } else if (pol_mechs == NULL) { 1079 /* 1080 * We have an empty enabled list, which means no 1081 * mechanisms are exempted from this policy: all 1082 * are disabled. 1083 */ 1084 return (B_TRUE); 1085 } 1086 1087 for (i = 0; i < pol_count; i++) { 1088 /* 1089 * If it matches, return status based on this 1090 * being and enabled or a disabled list of mechs. 1091 */ 1092 if (pol_mechs[i] == mech) { 1093 return (enabled_pol ? B_FALSE : B_TRUE); 1094 } 1095 } 1096 1097 /* mech was not found in list */ 1098 return (enabled_pol ? B_TRUE : B_FALSE); 1099 } 1100