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) 2003, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 /* 25 * Copyright 2010 Nexenta Systems, Inc. All rights reserved. 26 */ 27 28 #include <sys/types.h> 29 #include <sys/stat.h> 30 #include <dlfcn.h> 31 #include <fcntl.h> 32 #include <link.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <strings.h> 36 #include <errno.h> 37 #include <pthread.h> 38 #include <sys/mman.h> 39 #include <libscf.h> 40 41 #include <sys/crypto/elfsign.h> 42 #include <cryptoutil.h> 43 44 #include <security/cryptoki.h> 45 #include "pkcs11Global.h" 46 #include "pkcs11Conf.h" 47 #include "pkcs11Slot.h" 48 #include "metaGlobal.h" 49 50 /* 51 * Fastpath is used when there is only one slot available from a single provider 52 * plugged into the framework this is the common case. 53 * These globals are used to track the function pointers and policy when 54 * the fast-path is activated. 55 * This will need to be revisted if per-slot policy is ever 56 * implemented. 57 */ 58 boolean_t purefastpath = B_FALSE; 59 boolean_t policyfastpath = B_FALSE; 60 CK_FUNCTION_LIST_PTR fast_funcs = NULL; 61 CK_SLOT_ID fast_slot = 0; 62 boolean_t metaslot_enabled = B_FALSE; 63 boolean_t metaslot_auto_key_migrate = B_FALSE; 64 metaslot_config_t metaslot_config; 65 void (*Tmp_GetThreshold)(void *) = NULL; 66 cipher_mechs_threshold_t meta_mechs_threshold[MAX_NUM_THRESHOLD]; 67 68 static const char *conf_err = "See cryptoadm(1M). Skipping this plug-in."; 69 70 /* 71 * Set up metaslot for the framework using either user configuration 72 * or system wide configuration options 73 * 74 * Also sets up the global "slottable" to have the first slot be metaslot. 75 */ 76 static CK_RV 77 setup_metaslot(uentry_t *metaslot_entry) { 78 CK_RV rv; 79 CK_MECHANISM_TYPE_PTR prov_pol_mechs = NULL; 80 pkcs11_slot_t *cur_slot; 81 82 /* process policies for mechanisms */ 83 if ((metaslot_entry) && (metaslot_entry->count > 0)) { 84 rv = pkcs11_mech_parse(metaslot_entry->policylist, 85 &prov_pol_mechs, metaslot_entry->count); 86 87 if (rv == CKR_HOST_MEMORY) { 88 cryptoerror(LOG_ERR, 89 "libpkcs11: Could not parse configuration," 90 "out of memory. Cannot continue parsing " 91 "%s.\n", _PATH_PKCS11_CONF); 92 return (rv); 93 } else if (rv == CKR_MECHANISM_INVALID) { 94 /* 95 * Configuration file is corrupted for metaslot 96 */ 97 cryptoerror(LOG_ERR, 98 "libpkcs11: Policy invalid or corrupted " 99 "for metaslot. Use cryptoadm(1M) to fix " 100 "this. Disabling metaslot functionality.\n"); 101 metaslot_enabled = B_FALSE; 102 return (rv); 103 } 104 } 105 106 /* 107 * Check for metaslot policy. If all mechanisms are 108 * disabled, disable metaslot since there is nothing 109 * interesting for it to do 110 */ 111 if ((metaslot_entry) && (metaslot_entry->flag_enabledlist) && 112 (prov_pol_mechs == NULL)) { 113 metaslot_enabled = B_FALSE; 114 return (rv); 115 } 116 117 /* 118 * save system wide value for metaslot's keystore. 119 * If either slot description or token label is specified by 120 * the user, the system wide value for both is ignored. 121 */ 122 if ((metaslot_entry) && 123 (!metaslot_config.keystore_token_specified) && 124 (!metaslot_config.keystore_slot_specified)) { 125 /* 126 * blank_str is used for comparing with token label, 127 * and slot description, make sure it is better than 128 * the larger of both 129 */ 130 char blank_str[TOKEN_LABEL_SIZE + SLOT_DESCRIPTION_SIZE]; 131 132 bzero(blank_str, sizeof (blank_str)); 133 134 if (memcmp(metaslot_entry->metaslot_ks_token, 135 blank_str, TOKEN_LABEL_SIZE) != 0) { 136 metaslot_config.keystore_token_specified = B_TRUE; 137 (void) strlcpy( 138 (char *)metaslot_config.keystore_token, 139 (const char *)metaslot_entry->metaslot_ks_token, 140 TOKEN_LABEL_SIZE); 141 } 142 143 if (memcmp(metaslot_entry->metaslot_ks_slot, 144 blank_str, SLOT_DESCRIPTION_SIZE) != 0) { 145 metaslot_config.keystore_slot_specified = B_TRUE; 146 (void) strlcpy( 147 (char *)metaslot_config.keystore_slot, 148 (const char *)metaslot_entry->metaslot_ks_slot, 149 SLOT_DESCRIPTION_SIZE); 150 } 151 } 152 153 /* check system-wide value for auto_key_migrate */ 154 if (metaslot_config.auto_key_migrate_specified) { 155 /* take user's specified value */ 156 metaslot_auto_key_migrate = metaslot_config.auto_key_migrate; 157 } else { 158 if (metaslot_entry) { 159 /* use system-wide default */ 160 metaslot_auto_key_migrate = 161 metaslot_entry->flag_metaslot_auto_key_migrate; 162 } else { 163 /* 164 * there's no system wide metaslot entry, 165 * default auto_key_migrate to true 166 */ 167 metaslot_auto_key_migrate = B_TRUE; 168 } 169 } 170 171 172 /* Make first slotID be 0, for metaslot. */ 173 slottable->st_first = 0; 174 175 /* Set up the slottable entry for metaslot */ 176 slottable->st_slots[0] = NULL; 177 cur_slot = calloc(1, sizeof (pkcs11_slot_t)); 178 if (cur_slot == NULL) { 179 rv = CKR_HOST_MEMORY; 180 return (rv); 181 } 182 cur_slot->sl_wfse_state = WFSE_CLEAR; 183 cur_slot->sl_enabledpol = B_FALSE; 184 cur_slot->sl_no_wfse = B_FALSE; 185 (void) pthread_mutex_init(&cur_slot->sl_mutex, NULL); 186 187 /* 188 * The metaslot entry was prealloc'd by 189 * pkcs11_slottable_increase() 190 */ 191 (void) pthread_mutex_lock(&slottable->st_mutex); 192 slottable->st_slots[0] = cur_slot; 193 (void) pthread_mutex_unlock(&slottable->st_mutex); 194 195 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 196 cur_slot->sl_id = METASLOT_SLOTID; 197 cur_slot->sl_func_list = &metaslot_functionList; 198 if (metaslot_entry) { 199 cur_slot->sl_enabledpol = metaslot_entry->flag_enabledlist; 200 cur_slot->sl_pol_count = metaslot_entry->count; 201 } else { 202 /* if no metaslot entry, assume all mechs are enabled */ 203 cur_slot->sl_enabledpol = B_FALSE; 204 cur_slot->sl_pol_count = 0; 205 } 206 cur_slot->sl_pol_mechs = prov_pol_mechs; 207 cur_slot->sl_dldesc = NULL; /* not applicable */ 208 cur_slot->sl_prov_id = 0; 209 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 210 211 /* Call the meta_Initialize() to initialize metaslot */ 212 rv = meta_Initialize(NULL); 213 if (rv != CKR_OK) { 214 cryptoerror(LOG_ERR, 215 "libpkcs11: Can't initialize metaslot (%s)", 216 pkcs11_strerror(rv)); 217 goto cleanup; 218 } 219 220 return (CKR_OK); 221 222 cleanup: 223 metaslot_enabled = B_FALSE; 224 slottable->st_slots[0] = NULL; 225 226 if (cur_slot) { 227 (void) pthread_mutex_destroy(&cur_slot->sl_mutex); 228 free(cur_slot); 229 } 230 return (rv); 231 } 232 233 /* 234 * For each provider found in pkcs11.conf: expand $ISA if necessary, 235 * verify the module is signed, load the provider, find all of its 236 * slots, and store the function list and disabled policy. 237 * 238 * This function requires that the uentrylist_t and pkcs11_slottable_t 239 * already have memory allocated, and that the uentrylist_t is already 240 * populated with provider and policy information. 241 * 242 * pInitArgs can be set to NULL, but is normally the same value 243 * the framework's C_Initialize() was called with. 244 * 245 * Unless metaslot is explicitly disabled, it is setup when all other 246 * providers are loaded. 247 */ 248 CK_RV 249 pkcs11_slot_mapping(uentrylist_t *pplist, CK_VOID_PTR pInitArgs) 250 { 251 CK_RV rv = CKR_OK; 252 CK_RV prov_rv; /* Provider's return code */ 253 CK_INFO prov_info; 254 CK_RV (*Tmp_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR); 255 CK_FUNCTION_LIST_PTR prov_funcs = NULL; /* Provider's function list */ 256 CK_ULONG prov_slot_count; /* Number of slots */ 257 CK_SLOT_ID slot_id; /* slotID assigned for framework */ 258 CK_SLOT_ID_PTR prov_slots = NULL; /* Provider's slot list */ 259 /* Enabled or Disabled policy */ 260 CK_MECHANISM_TYPE_PTR prov_pol_mechs = NULL; 261 262 void *dldesc = NULL; 263 char *isa, *fullpath = NULL, *dl_error; 264 uentrylist_t *phead; 265 uint_t prov_count = 0; 266 pkcs11_slot_t *cur_slot; 267 CK_ULONG i; 268 size_t len; 269 uentry_t *metaslot_entry = NULL; 270 /* number of slots in the framework, not including metaslot */ 271 uint_t slot_count = 0; 272 273 phead = pplist; 274 275 /* Loop through all of the provider listed in pkcs11.conf */ 276 while (phead != NULL) { 277 if (!strcasecmp(phead->puent->name, "metaslot")) { 278 /* 279 * Skip standard processing for metaslot 280 * entry since it is not an actual library 281 * that can be dlopened. 282 * It will be initialized later. 283 */ 284 if (metaslot_entry != NULL) { 285 cryptoerror(LOG_ERR, 286 "libpkcs11: multiple entries for metaslot " 287 "detected. All but the first entry will " 288 "be ignored"); 289 } else { 290 metaslot_entry = phead->puent; 291 } 292 goto contparse; 293 } 294 295 if (!strcasecmp(phead->puent->name, FIPS_KEYWORD)) { 296 /* 297 * Skip standard processing for fips-140 298 * entry since it is not an actual library 299 * that can be dlopened. 300 */ 301 goto contparse; 302 } 303 304 /* Check for Instruction Set Architecture indicator */ 305 if ((isa = strstr(phead->puent->name, PKCS11_ISA)) != NULL) { 306 /* Substitute the architecture dependent path */ 307 len = strlen(phead->puent->name) - 308 strlen(PKCS11_ISA) + 309 strlen(PKCS11_ISA_DIR) + 1; 310 if ((fullpath = (char *)malloc(len)) == NULL) { 311 cryptoerror(LOG_ERR, 312 "libpksc11: parsing %s, out of memory. " 313 "Cannot continue parsing.", 314 _PATH_PKCS11_CONF); 315 rv = CKR_HOST_MEMORY; 316 goto conferror; 317 } 318 *isa = '\000'; 319 isa += strlen(PKCS11_ISA); 320 (void) snprintf(fullpath, len, "%s%s%s", 321 phead->puent->name, PKCS11_ISA_DIR, isa); 322 } else if ((fullpath = strdup(phead->puent->name)) == 0) { 323 cryptoerror(LOG_ERR, 324 "libpkcs11: parsing %s, out of memory. " 325 "Cannot continue parsing.", 326 _PATH_PKCS11_CONF); 327 rv = CKR_HOST_MEMORY; 328 goto conferror; 329 } 330 331 /* 332 * Open the provider. We assume all of our plugins have 333 * their symbols properly defined, so the use of RTLD_NOW 334 * to flush out errors immediately is not necessary. 335 * 336 * Note that for proper operation, all plugins must be 337 * built with direct bindings enabled. 338 */ 339 dldesc = dlopen(fullpath, RTLD_LAZY); 340 341 /* 342 * If we failed to load it, we will just skip this 343 * provider and move on to the next one. 344 */ 345 if (dldesc == NULL) { 346 dl_error = dlerror(); 347 cryptoerror(LOG_ERR, 348 "libpkcs11: Cannot load PKCS#11 library %s. " 349 "dlerror: %s. %s", 350 fullpath, dl_error != NULL ? dl_error : "Unknown", 351 conf_err); 352 goto contparse; 353 } 354 355 /* Get the pointer to provider's C_GetFunctionList() */ 356 Tmp_C_GetFunctionList = 357 (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList"); 358 359 /* 360 * If we failed to get the pointer to C_GetFunctionList(), 361 * skip this provider and continue to the next one. 362 */ 363 if (Tmp_C_GetFunctionList == NULL) { 364 cryptoerror(LOG_ERR, 365 "libpkcs11: Could not dlsym() C_GetFunctionList() " 366 "for %s. May not be a PKCS#11 library. %s", 367 fullpath, conf_err); 368 (void) dlclose(dldesc); 369 goto contparse; 370 } 371 372 373 /* Get the provider's function list */ 374 prov_rv = Tmp_C_GetFunctionList(&prov_funcs); 375 376 /* 377 * If we failed to get the provider's function list, 378 * skip this provider and continue to the next one. 379 */ 380 if (prov_rv != CKR_OK) { 381 cryptoerror(LOG_ERR, 382 "libpkcs11: Could not get function list for %s. " 383 "%s Error: %s.", 384 fullpath, conf_err, pkcs11_strerror(prov_rv)); 385 (void) dlclose(dldesc); 386 goto contparse; 387 } 388 389 /* Initialize this provider */ 390 prov_rv = prov_funcs->C_Initialize(pInitArgs); 391 392 /* 393 * If we failed to initialize this provider, 394 * skip this provider and continue to the next one. 395 */ 396 if ((prov_rv != CKR_OK) && 397 (prov_rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 398 cryptoerror(LOG_ERR, 399 "libpkcs11: Could not initialize %s. " 400 "%s Error: %s.", 401 fullpath, conf_err, pkcs11_strerror(prov_rv)); 402 (void) dlclose(dldesc); 403 goto contparse; 404 } 405 406 /* 407 * Make sure this provider is implementing the same 408 * major version, and at least the same minor version 409 * that we are. 410 */ 411 prov_rv = prov_funcs->C_GetInfo(&prov_info); 412 413 /* 414 * If we can't verify that we are implementing the 415 * same major version, or if it is definitely not the same 416 * version, we need to skip this provider. 417 */ 418 if ((prov_rv != CKR_OK) || 419 (prov_info.cryptokiVersion.major != 420 CRYPTOKI_VERSION_MAJOR)) { 421 if (prov_rv != CKR_OK) { 422 cryptoerror(LOG_ERR, 423 "libpkcs11: Could not verify version of " 424 "%s. %s Error: %s.", fullpath, 425 conf_err, pkcs11_strerror(prov_rv)); 426 } else { 427 cryptoerror(LOG_ERR, 428 "libpkcs11: Only CRYPTOKI major version " 429 "%d is supported. %s is major " 430 "version %d. %s", 431 CRYPTOKI_VERSION_MAJOR, fullpath, 432 prov_info.cryptokiVersion.major, conf_err); 433 } 434 (void) prov_funcs->C_Finalize(NULL); 435 (void) dlclose(dldesc); 436 goto contparse; 437 } 438 439 /* 440 * Warn the administrator (at debug) that a provider with 441 * a significantly older or newer version of 442 * CRYPTOKI is being used. It should not cause 443 * problems, but logging a warning makes it easier 444 * to debug later. 445 */ 446 if ((prov_info.cryptokiVersion.minor < 447 CRYPTOKI_VERSION_WARN_MINOR) || 448 (prov_info.cryptokiVersion.minor > 449 CRYPTOKI_VERSION_MINOR)) { 450 cryptoerror(LOG_DEBUG, 451 "libpkcs11: %s CRYPTOKI minor version, %d, may " 452 "not be compatible with minor version %d.", 453 fullpath, prov_info.cryptokiVersion.minor, 454 CRYPTOKI_VERSION_MINOR); 455 } 456 457 /* 458 * Find out how many slots this provider has, 459 * call with tokenPresent set to FALSE so all 460 * potential slots are returned. 461 */ 462 prov_rv = prov_funcs->C_GetSlotList(FALSE, 463 NULL, &prov_slot_count); 464 465 /* 466 * If the call failed, or if no slots are returned, 467 * then skip this provider and continue to next one. 468 */ 469 if (prov_rv != CKR_OK) { 470 cryptoerror(LOG_ERR, 471 "libpksc11: Could not get slot list from %s. " 472 "%s Error: %s.", 473 fullpath, conf_err, pkcs11_strerror(prov_rv)); 474 (void) prov_funcs->C_Finalize(NULL); 475 (void) dlclose(dldesc); 476 goto contparse; 477 } 478 479 if (prov_slot_count == 0) { 480 cryptodebug("libpkcs11: No slots presented from %s. " 481 "Skipping this plug-in at this time.\n", 482 fullpath); 483 (void) prov_funcs->C_Finalize(NULL); 484 (void) dlclose(dldesc); 485 goto contparse; 486 } 487 488 /* Allocate memory for the slot list */ 489 prov_slots = calloc(prov_slot_count, sizeof (CK_SLOT_ID)); 490 491 if (prov_slots == NULL) { 492 cryptoerror(LOG_ERR, 493 "libpkcs11: Could not allocate memory for " 494 "plug-in slots. Cannot continue parsing %s\n", 495 _PATH_PKCS11_CONF); 496 rv = CKR_HOST_MEMORY; 497 goto conferror; 498 } 499 500 /* Get slot list from provider */ 501 prov_rv = prov_funcs->C_GetSlotList(FALSE, 502 prov_slots, &prov_slot_count); 503 504 /* if second call fails, drop this provider */ 505 if (prov_rv != CKR_OK) { 506 cryptoerror(LOG_ERR, 507 "libpkcs11: Second call to C_GetSlotList() for %s " 508 "failed. %s Error: %s.", 509 fullpath, conf_err, pkcs11_strerror(prov_rv)); 510 (void) prov_funcs->C_Finalize(NULL); 511 (void) dlclose(dldesc); 512 goto contparse; 513 } 514 515 /* 516 * Parse the list of disabled or enabled mechanisms, will 517 * apply to each of the provider's slots. 518 */ 519 if (phead->puent->count > 0) { 520 rv = pkcs11_mech_parse(phead->puent->policylist, 521 &prov_pol_mechs, phead->puent->count); 522 523 if (rv == CKR_HOST_MEMORY) { 524 cryptoerror(LOG_ERR, 525 "libpkcs11: Could not parse configuration," 526 "out of memory. Cannot continue parsing " 527 "%s.", _PATH_PKCS11_CONF); 528 goto conferror; 529 } else if (rv == CKR_MECHANISM_INVALID) { 530 /* 531 * Configuration file is corrupted for this 532 * provider. 533 */ 534 cryptoerror(LOG_ERR, 535 "libpkcs11: Policy invalid or corrupted " 536 "for %s. Use cryptoadm(1M) to fix " 537 "this. Skipping this plug-in.", 538 fullpath); 539 (void) prov_funcs->C_Finalize(NULL); 540 (void) dlclose(dldesc); 541 goto contparse; 542 } 543 } 544 545 /* Allocate memory in our slottable for these slots */ 546 rv = pkcs11_slottable_increase(prov_slot_count); 547 548 /* 549 * If any error is returned, it will be memory related, 550 * so we need to abort the attempt at filling the 551 * slottable. 552 */ 553 if (rv != CKR_OK) { 554 cryptoerror(LOG_ERR, 555 "libpkcs11: slottable could not increase. " 556 "Cannot continue parsing %s.", 557 _PATH_PKCS11_CONF); 558 goto conferror; 559 } 560 561 /* Configure information for each new slot */ 562 for (i = 0; i < prov_slot_count; i++) { 563 /* allocate slot in framework */ 564 rv = pkcs11_slot_allocate(&slot_id); 565 if (rv != CKR_OK) { 566 cryptoerror(LOG_ERR, 567 "libpkcs11: Could not allocate " 568 "new slot. Cannot continue parsing %s.", 569 _PATH_PKCS11_CONF); 570 goto conferror; 571 } 572 slot_count++; 573 cur_slot = slottable->st_slots[slot_id]; 574 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 575 cur_slot->sl_id = prov_slots[i]; 576 cur_slot->sl_func_list = prov_funcs; 577 cur_slot->sl_enabledpol = 578 phead->puent->flag_enabledlist; 579 cur_slot->sl_pol_mechs = prov_pol_mechs; 580 cur_slot->sl_pol_count = phead->puent->count; 581 cur_slot->sl_norandom = phead->puent->flag_norandom; 582 cur_slot->sl_dldesc = dldesc; 583 cur_slot->sl_prov_id = prov_count + 1; 584 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 585 } 586 587 /* 588 * Get the pointer to private interface _SUNW_GetThreshold() 589 * in pkcs11_kernel. 590 */ 591 592 if (Tmp_GetThreshold == NULL) { 593 Tmp_GetThreshold = 594 (void(*)())dlsym(dldesc, "_SUNW_GetThreshold"); 595 596 /* Get the threshold values for the supported mechs */ 597 if (Tmp_GetThreshold != NULL) { 598 (void) memset(meta_mechs_threshold, 0, 599 sizeof (meta_mechs_threshold)); 600 Tmp_GetThreshold(meta_mechs_threshold); 601 } 602 } 603 604 /* Set and reset values to process next provider */ 605 prov_count++; 606 contparse: 607 prov_slot_count = 0; 608 Tmp_C_GetFunctionList = NULL; 609 prov_funcs = NULL; 610 dldesc = NULL; 611 if (fullpath != NULL) { 612 free(fullpath); 613 fullpath = NULL; 614 } 615 if (prov_slots != NULL) { 616 free(prov_slots); 617 prov_slots = NULL; 618 } 619 phead = phead->next; 620 } 621 622 if (slot_count == 0) { 623 /* 624 * there's no other slot in the framework, 625 * there is nothing to do 626 */ 627 goto config_complete; 628 } 629 630 /* determine if metaslot should be enabled */ 631 632 /* 633 * Check to see if any environment variable is defined 634 * by the user for configuring metaslot. Users' 635 * setting always take precedence over the system wide 636 * setting. So, we will first check for any user's 637 * defined env variables before looking at the system-wide 638 * configuration. 639 */ 640 get_user_metaslot_config(); 641 642 /* no metaslot entry in /etc/crypto/pkcs11.conf */ 643 if (!metaslot_entry) { 644 /* 645 * If user env variable indicates metaslot should be enabled, 646 * but there's no entry in /etc/crypto/pkcs11.conf for 647 * metaslot at all, will respect the user's defined value 648 */ 649 if ((metaslot_config.enabled_specified) && 650 (metaslot_config.enabled)) { 651 metaslot_enabled = B_TRUE; 652 } 653 } else { 654 if (!metaslot_config.enabled_specified) { 655 /* 656 * take system wide value if 657 * it is not specified by user 658 */ 659 metaslot_enabled 660 = metaslot_entry->flag_metaslot_enabled; 661 } else { 662 metaslot_enabled = metaslot_config.enabled; 663 } 664 } 665 666 /* 667 * 668 * As long as the user or system configuration file does not 669 * disable metaslot, it will be enabled regardless of the 670 * number of slots plugged into the framework. Therefore, 671 * metaslot is enabled even when there's only one slot 672 * plugged into the framework. This is necessary for 673 * presenting a consistent token label view to applications. 674 * 675 * However, for the case where there is only 1 slot plugged into 676 * the framework, we can use "fastpath". 677 * 678 * "fastpath" will pass all of the application's requests 679 * directly to the underlying provider. Only when policy is in 680 * effect will we need to keep slotID around. 681 * 682 * When metaslot is enabled, and fastpath is enabled, 683 * all the metaslot processing will be skipped. 684 * When there is only 1 slot, there's 685 * really not much metaslot can do in terms of combining functionality 686 * of different slots, and object migration. 687 * 688 */ 689 690 /* check to see if fastpath can be used */ 691 if (slottable->st_last == slottable->st_first) { 692 693 cur_slot = slottable->st_slots[slottable->st_first]; 694 695 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 696 697 if ((cur_slot->sl_pol_count == 0) && 698 (!cur_slot->sl_enabledpol) && (!cur_slot->sl_norandom)) { 699 /* No policy is in effect, don't need slotid */ 700 fast_funcs = cur_slot->sl_func_list; 701 purefastpath = B_TRUE; 702 } else { 703 fast_funcs = cur_slot->sl_func_list; 704 fast_slot = slottable->st_first; 705 policyfastpath = B_TRUE; 706 } 707 708 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 709 } 710 711 if ((purefastpath || policyfastpath) && (!metaslot_enabled)) { 712 goto config_complete; 713 } 714 715 /* 716 * If we get here, there are more than 2 slots in the framework, 717 * we need to set up metaslot if it is enabled 718 */ 719 if (metaslot_enabled) { 720 rv = setup_metaslot(metaslot_entry); 721 if (rv != CKR_OK) { 722 goto conferror; 723 } 724 } 725 726 727 config_complete: 728 729 return (CKR_OK); 730 731 conferror: 732 /* 733 * This cleanup code is only exercised when a major, 734 * unrecoverable error like "out of memory". 735 */ 736 if (prov_funcs != NULL) { 737 (void) prov_funcs->C_Finalize(NULL); 738 } 739 if (dldesc != NULL) { 740 (void) dlclose(dldesc); 741 } 742 if (fullpath != NULL) { 743 free(fullpath); 744 fullpath = NULL; 745 } 746 if (prov_slots != NULL) { 747 free(prov_slots); 748 prov_slots = NULL; 749 } 750 751 return (rv); 752 } 753 754 /* 755 * pkcs11_mech_parse will take hex mechanism ids, as a list of 756 * strings, and convert them to CK_MECHANISM_TYPE_PTR. 757 */ 758 CK_RV 759 pkcs11_mech_parse(umechlist_t *str_list, CK_MECHANISM_TYPE_PTR *mech_list, 760 int mech_count) 761 { 762 CK_MECHANISM_TYPE_PTR tmp_list; 763 umechlist_t *shead = str_list; 764 765 tmp_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE)); 766 767 if (tmp_list == NULL) { 768 cryptoerror(LOG_ERR, "libpkcs11: parsing %s, out of memory. " 769 "Cannot continue.", 770 _PATH_PKCS11_CONF); 771 return (CKR_HOST_MEMORY); 772 } 773 774 *mech_list = tmp_list; 775 776 /* 777 * The following will loop mech_count times, as there are 778 * exactly mech_count items in the str_list. 779 */ 780 while (shead != NULL) { 781 CK_MECHANISM_TYPE cur_mech; 782 783 errno = 0; 784 785 /* 786 * "name" is a hexadecimal number, preceded by 0x. 787 */ 788 cur_mech = strtoul(shead->name, NULL, 16); 789 790 if ((cur_mech == 0) && 791 ((errno == EINVAL) || (errno == ERANGE))) { 792 free(mech_list); 793 return (CKR_MECHANISM_INVALID); 794 } 795 *tmp_list = (CK_MECHANISM_TYPE)cur_mech; 796 tmp_list++; 797 shead = shead->next; 798 } 799 800 return (CKR_OK); 801 } 802 803 /* 804 * pkcs11_is_dismech is provided a slotid and a mechanism. 805 * If mech is not disabled, then return B_FALSE. 806 */ 807 boolean_t 808 pkcs11_is_dismech(CK_SLOT_ID slotid, CK_MECHANISM_TYPE mech) 809 { 810 ulong_t i; 811 boolean_t enabled_pol; 812 CK_MECHANISM_TYPE_PTR pol_mechs; 813 ulong_t pol_count; 814 815 /* Find the associated slot and get the mech policy info */ 816 (void) pthread_mutex_lock(&slottable->st_slots[slotid]->sl_mutex); 817 enabled_pol = slottable->st_slots[slotid]->sl_enabledpol; 818 pol_mechs = slottable->st_slots[slotid]->sl_pol_mechs; 819 pol_count = slottable->st_slots[slotid]->sl_pol_count; 820 (void) pthread_mutex_unlock(&slottable->st_slots[slotid]->sl_mutex); 821 822 /* Check for policy */ 823 if ((!enabled_pol) && (pol_mechs == NULL)) { 824 /* no policy */ 825 return (B_FALSE); 826 } else if (pol_mechs == NULL) { 827 /* 828 * We have an empty enabled list, which means no 829 * mechanisms are exempted from this policy: all 830 * are disabled. 831 */ 832 return (B_TRUE); 833 } 834 835 for (i = 0; i < pol_count; i++) { 836 /* 837 * If it matches, return status based on this 838 * being and enabled or a disabled list of mechs. 839 */ 840 if (pol_mechs[i] == mech) { 841 return (enabled_pol ? B_FALSE : B_TRUE); 842 } 843 } 844 845 /* mech was not found in list */ 846 return (enabled_pol ? B_TRUE : B_FALSE); 847 } 848