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