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 2007 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 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 ELFsign_status_t estatus = ELFSIGN_UNKNOWN; 274 char *estatus_str = NULL; 275 int kcfdfd = -1; 276 door_arg_t darg; 277 kcf_door_arg_t *kda = NULL; 278 kcf_door_arg_t *rkda = NULL; 279 int r; 280 281 phead = pplist; 282 283 /* Loop through all of the provider listed in pkcs11.conf */ 284 while (phead != NULL) { 285 if (!strcasecmp(phead->puent->name, "metaslot")) { 286 /* 287 * Skip standard processing for metaslot 288 * entry since it is not an actual library 289 * that can be dlopened. 290 * It will be initialized later. 291 */ 292 if (metaslot_entry != NULL) { 293 cryptoerror(LOG_ERR, 294 "libpkcs11: multiple entries for metaslot " 295 "detected. All but the first entry will " 296 "be ignored"); 297 } else { 298 metaslot_entry = phead->puent; 299 } 300 goto contparse; 301 } 302 303 /* Check for Instruction Set Architecture indicator */ 304 if ((isa = strstr(phead->puent->name, PKCS11_ISA)) != NULL) { 305 /* Substitute the architecture dependent path */ 306 len = strlen(phead->puent->name) - 307 strlen(PKCS11_ISA) + 308 strlen(PKCS11_ISA_DIR) + 1; 309 if ((fullpath = (char *)malloc(len)) == NULL) { 310 cryptoerror(LOG_ERR, 311 "libpksc11: parsing %s, out of memory. " 312 "Cannot continue parsing.", 313 _PATH_PKCS11_CONF); 314 rv = CKR_HOST_MEMORY; 315 goto conferror; 316 } 317 *isa = '\000'; 318 isa += strlen(PKCS11_ISA); 319 (void) snprintf(fullpath, len, "%s%s%s", 320 phead->puent->name, PKCS11_ISA_DIR, isa); 321 } else if ((fullpath = strdup(phead->puent->name)) == 0) { 322 cryptoerror(LOG_ERR, 323 "libpkcs11: parsing %s, out of memory. " 324 "Cannot continue parsing.", 325 _PATH_PKCS11_CONF); 326 rv = CKR_HOST_MEMORY; 327 goto conferror; 328 } 329 330 /* 331 * Open the provider. Use RTLD_NOW to make sure we 332 * will not encounter symbol referencing errors later. 333 * Use RTLD_GROUP to limit the provider to it's own 334 * symbols, which prevents it from mistakenly accessing 335 * the framework's C_* functions. 336 */ 337 dldesc = dlopen(fullpath, RTLD_NOW|RTLD_GROUP); 338 339 /* 340 * If we failed to load it, we will just skip this 341 * provider and move on to the next one. 342 */ 343 if (dldesc == NULL) { 344 dl_error = dlerror(); 345 cryptoerror(LOG_ERR, 346 "libpkcs11: Cannot load PKCS#11 library %s. " 347 "dlerror: %s. %s", 348 fullpath, dl_error != NULL ? dl_error : "Unknown", 349 conf_err); 350 goto contparse; 351 } 352 353 /* Get the pointer to provider's C_GetFunctionList() */ 354 Tmp_C_GetFunctionList = 355 (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList"); 356 357 /* 358 * If we failed to get the pointer to C_GetFunctionList(), 359 * skip this provider and continue to the next one. 360 */ 361 if (Tmp_C_GetFunctionList == NULL) { 362 cryptoerror(LOG_ERR, 363 "libpkcs11: Could not dlsym() C_GetFunctionList() " 364 "for %s. May not be a PKCS#11 library. %s", 365 fullpath, conf_err); 366 (void) dlclose(dldesc); 367 goto contparse; 368 } 369 370 371 /* Get the provider's function list */ 372 prov_rv = Tmp_C_GetFunctionList(&prov_funcs); 373 374 /* 375 * If we failed to get the provider's function list, 376 * skip this provider and continue to the next one. 377 */ 378 if (prov_rv != CKR_OK) { 379 cryptoerror(LOG_ERR, 380 "libpkcs11: Could not get function list for %s. " 381 "%s Error: %s.", 382 fullpath, conf_err, pkcs11_strerror(prov_rv)); 383 (void) dlclose(dldesc); 384 goto contparse; 385 } 386 387 /* Initialize this provider */ 388 prov_rv = prov_funcs->C_Initialize(pInitArgs); 389 390 /* 391 * If we failed to initialize this provider, 392 * skip this provider and continue to the next one. 393 */ 394 if ((prov_rv != CKR_OK) && 395 (prov_rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) { 396 cryptoerror(LOG_ERR, 397 "libpkcs11: Could not initialize %s. " 398 "%s Error: %s.", 399 fullpath, conf_err, pkcs11_strerror(prov_rv)); 400 (void) dlclose(dldesc); 401 goto contparse; 402 } 403 404 /* 405 * Make sure this provider is implementing the same 406 * major version, and at least the same minor version 407 * that we are. 408 */ 409 prov_rv = prov_funcs->C_GetInfo(&prov_info); 410 411 /* 412 * If we can't verify that we are implementing the 413 * same major version, or if it is definitely not the same 414 * version, we need to skip this provider. 415 */ 416 if ((prov_rv != CKR_OK) || 417 (prov_info.cryptokiVersion.major != 418 CRYPTOKI_VERSION_MAJOR)) { 419 if (prov_rv != CKR_OK) { 420 cryptoerror(LOG_ERR, 421 "libpkcs11: Could not verify version of " 422 "%s. %s Error: %s.", fullpath, 423 conf_err, pkcs11_strerror(prov_rv)); 424 } else { 425 cryptoerror(LOG_ERR, 426 "libpkcs11: Only CRYPTOKI major version " 427 "%d is supported. %s is major " 428 "version %d. %s", 429 CRYPTOKI_VERSION_MAJOR, fullpath, 430 prov_info.cryptokiVersion.major, conf_err); 431 } 432 (void) prov_funcs->C_Finalize(NULL); 433 (void) dlclose(dldesc); 434 goto contparse; 435 } 436 437 /* 438 * Warn the administrator (at debug) that a provider with 439 * a significantly older or newer version of 440 * CRYPTOKI is being used. It should not cause 441 * problems, but logging a warning makes it easier 442 * to debug later. 443 */ 444 if ((prov_info.cryptokiVersion.minor < 445 CRYPTOKI_VERSION_WARN_MINOR) || 446 (prov_info.cryptokiVersion.minor > 447 CRYPTOKI_VERSION_MINOR)) { 448 cryptoerror(LOG_DEBUG, 449 "libpkcs11: %s CRYPTOKI minor version, %d, may " 450 "not be compatible with minor version %d.", 451 fullpath, prov_info.cryptokiVersion.minor, 452 CRYPTOKI_VERSION_MINOR); 453 } 454 455 /* 456 * Find out how many slots this provider has, 457 * call with tokenPresent set to FALSE so all 458 * potential slots are returned. 459 */ 460 prov_rv = prov_funcs->C_GetSlotList(FALSE, 461 NULL, &prov_slot_count); 462 463 /* 464 * If the call failed, or if no slots are returned, 465 * then skip this provider and continue to next one. 466 */ 467 if (prov_rv != CKR_OK) { 468 cryptoerror(LOG_ERR, 469 "libpksc11: Could not get slot list from %s. " 470 "%s Error: %s.", 471 fullpath, conf_err, pkcs11_strerror(prov_rv)); 472 (void) prov_funcs->C_Finalize(NULL); 473 (void) dlclose(dldesc); 474 goto contparse; 475 } 476 477 if (prov_slot_count == 0) { 478 cryptodebug("libpkcs11: No slots presented from %s. " 479 "Skipping this plug-in at this time.\n", 480 fullpath); 481 (void) prov_funcs->C_Finalize(NULL); 482 (void) dlclose(dldesc); 483 goto contparse; 484 } 485 486 /* 487 * Verify that the module is signed correctly. 488 * 489 * NOTE: there is a potential race condition here, 490 * since the module is verified well after we have 491 * opened the provider via dlopen(). This could be 492 * resolved by a variant of dlopen() that would take a 493 * file descriptor as an argument and by changing the 494 * kcfd libelfsign door protocol to use and fd instead 495 * of a path - but that wouldn't work in the kernel case. 496 */ 497 while ((kcfdfd = open(_PATH_KCFD_DOOR, O_RDONLY)) == -1) { 498 if (!(errno == EINTR || errno == EAGAIN)) 499 break; 500 } 501 if (kcfdfd == -1) { 502 cryptoerror(LOG_ERR, "libpkcs11: open %s: %s", 503 _PATH_KCFD_DOOR, strerror(errno)); 504 goto verifycleanup; 505 } 506 507 /* Mark the door "close on exec" */ 508 (void) fcntl(kcfdfd, F_SETFD, FD_CLOEXEC); 509 510 if ((kda = malloc(sizeof (kcf_door_arg_t))) == NULL) { 511 cryptoerror(LOG_ERR, "libpkcs11: malloc of kda " 512 "failed: %s", strerror(errno)); 513 goto verifycleanup; 514 } 515 kda->da_version = KCF_KCFD_VERSION1; 516 kda->da_iskernel = B_FALSE; 517 (void) strlcpy(kda->da_u.filename, fullpath, 518 strlen(fullpath) + 1); 519 520 darg.data_ptr = (char *)kda; 521 darg.data_size = sizeof (kcf_door_arg_t); 522 darg.desc_ptr = NULL; 523 darg.desc_num = 0; 524 darg.rbuf = (char *)kda; 525 darg.rsize = sizeof (kcf_door_arg_t); 526 527 while ((r = door_call(kcfdfd, &darg)) != 0) { 528 if (!(errno == EINTR || errno == EAGAIN)) 529 break; 530 } 531 532 if (r != 0) { 533 cryptoerror(LOG_ERR, 534 "libpkcs11: Unable to contact kcfd: %s", 535 strerror(errno)); 536 goto verifycleanup; 537 } 538 539 /*LINTED*/ 540 rkda = (kcf_door_arg_t *)darg.rbuf; 541 if (rkda->da_version != KCF_KCFD_VERSION1) { 542 cryptoerror(LOG_ERR, 543 "libpkcs11: kcfd and libelfsign versions " 544 "don't match: got %d expected %d", 545 rkda->da_version, KCF_KCFD_VERSION1); 546 goto verifycleanup; 547 } 548 estatus = rkda->da_u.result.status; 549 verifycleanup: 550 if (kcfdfd != -1) { 551 (void) close(kcfdfd); 552 } 553 if (rkda != NULL && rkda != kda) 554 (void) munmap((char *)rkda, darg.rsize); 555 if (kda != NULL) { 556 bzero(kda, sizeof (kda)); 557 free(kda); 558 kda = NULL; 559 rkda = NULL; /* rkda is an alias of kda */ 560 } 561 562 switch (estatus) { 563 case ELFSIGN_SUCCESS: 564 case ELFSIGN_RESTRICTED: 565 break; 566 case ELFSIGN_NOTSIGNED: 567 estatus_str = strdup("not a signed provider."); 568 break; 569 case ELFSIGN_FAILED: 570 estatus_str = strdup("signature verification failed."); 571 break; 572 default: 573 estatus_str = strdup("unexpected failure in ELF " 574 "signature verification. " 575 "System may have been tampered with."); 576 } 577 if (estatus_str != NULL) { 578 cryptoerror(LOG_ERR, "libpkcs11: %s %s %s", 579 fullpath, estatus_str ? estatus_str : "", 580 estatus == ELFSIGN_UNKNOWN ? 581 "Cannot continue parsing " _PATH_PKCS11_CONF: 582 conf_err); 583 (void) prov_funcs->C_Finalize(NULL); 584 (void) dlclose(dldesc); 585 free(estatus_str); 586 estatus_str = NULL; 587 if (estatus == ELFSIGN_UNKNOWN) { 588 prov_funcs = NULL; 589 dldesc = NULL; 590 rv = CKR_GENERAL_ERROR; 591 goto conferror; 592 } 593 goto contparse; 594 } 595 596 /* Allocate memory for the slot list */ 597 prov_slots = calloc(prov_slot_count, sizeof (CK_SLOT_ID)); 598 599 if (prov_slots == NULL) { 600 cryptoerror(LOG_ERR, 601 "libpkcs11: Could not allocate memory for " 602 "plug-in slots. Cannot continue parsing %s\n", 603 _PATH_PKCS11_CONF); 604 rv = CKR_HOST_MEMORY; 605 goto conferror; 606 } 607 608 /* Get slot list from provider */ 609 prov_rv = prov_funcs->C_GetSlotList(FALSE, 610 prov_slots, &prov_slot_count); 611 612 /* if second call fails, drop this provider */ 613 if (prov_rv != CKR_OK) { 614 cryptoerror(LOG_ERR, 615 "libpkcs11: Second call to C_GetSlotList() for %s " 616 "failed. %s Error: %s.", 617 fullpath, conf_err, pkcs11_strerror(prov_rv)); 618 (void) prov_funcs->C_Finalize(NULL); 619 (void) dlclose(dldesc); 620 goto contparse; 621 } 622 623 /* 624 * Parse the list of disabled or enabled mechanisms, will 625 * apply to each of the provider's slots. 626 */ 627 if (phead->puent->count > 0) { 628 rv = pkcs11_mech_parse(phead->puent->policylist, 629 &prov_pol_mechs, phead->puent->count); 630 631 if (rv == CKR_HOST_MEMORY) { 632 cryptoerror(LOG_ERR, 633 "libpkcs11: Could not parse configuration," 634 "out of memory. Cannot continue parsing " 635 "%s.", _PATH_PKCS11_CONF); 636 goto conferror; 637 } else if (rv == CKR_MECHANISM_INVALID) { 638 /* 639 * Configuration file is corrupted for this 640 * provider. 641 */ 642 cryptoerror(LOG_ERR, 643 "libpkcs11: Policy invalid or corrupted " 644 "for %s. Use cryptoadm(1M) to fix " 645 "this. Skipping this plug-in.", 646 fullpath); 647 (void) prov_funcs->C_Finalize(NULL); 648 (void) dlclose(dldesc); 649 goto contparse; 650 } 651 } 652 653 /* Allocate memory in our slottable for these slots */ 654 rv = pkcs11_slottable_increase(prov_slot_count); 655 656 /* 657 * If any error is returned, it will be memory related, 658 * so we need to abort the attempt at filling the 659 * slottable. 660 */ 661 if (rv != CKR_OK) { 662 cryptoerror(LOG_ERR, 663 "libpkcs11: slottable could not increase. " 664 "Cannot continue parsing %s.", 665 _PATH_PKCS11_CONF); 666 goto conferror; 667 } 668 669 /* Configure information for each new slot */ 670 for (i = 0; i < prov_slot_count; i++) { 671 /* allocate slot in framework */ 672 rv = pkcs11_slot_allocate(&slot_id); 673 if (rv != CKR_OK) { 674 cryptoerror(LOG_ERR, 675 "libpkcs11: Could not allocate " 676 "new slot. Cannot continue parsing %s.", 677 _PATH_PKCS11_CONF); 678 goto conferror; 679 } 680 slot_count++; 681 cur_slot = slottable->st_slots[slot_id]; 682 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 683 cur_slot->sl_id = prov_slots[i]; 684 cur_slot->sl_func_list = prov_funcs; 685 cur_slot->sl_enabledpol = 686 phead->puent->flag_enabledlist; 687 cur_slot->sl_pol_mechs = prov_pol_mechs; 688 cur_slot->sl_pol_count = phead->puent->count; 689 cur_slot->sl_norandom = phead->puent->flag_norandom; 690 cur_slot->sl_dldesc = dldesc; 691 cur_slot->sl_prov_id = prov_count + 1; 692 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 693 } 694 695 /* 696 * Get the pointer to private interface _SUNW_GetThreshold() 697 * in pkcs11_kernel. 698 */ 699 700 if (Tmp_GetThreshold == NULL) { 701 Tmp_GetThreshold = 702 (void(*)())dlsym(dldesc, "_SUNW_GetThreshold"); 703 704 /* Get the threshold values for the supported mechs */ 705 if (Tmp_GetThreshold != NULL) { 706 (void) memset(meta_mechs_threshold, 0, 707 sizeof (meta_mechs_threshold)); 708 Tmp_GetThreshold(meta_mechs_threshold); 709 } 710 } 711 712 /* Set and reset values to process next provider */ 713 prov_count++; 714 contparse: 715 prov_slot_count = 0; 716 Tmp_C_GetFunctionList = NULL; 717 prov_funcs = NULL; 718 dldesc = NULL; 719 if (fullpath != NULL) { 720 free(fullpath); 721 fullpath = NULL; 722 } 723 if (prov_slots != NULL) { 724 free(prov_slots); 725 prov_slots = NULL; 726 } 727 phead = phead->next; 728 } 729 730 if (slot_count == 0) { 731 /* 732 * there's no other slot in the framework, 733 * there is nothing to do 734 */ 735 goto config_complete; 736 } 737 738 /* determine if metaslot should be enabled */ 739 740 /* 741 * Check to see if any environment variable is defined 742 * by the user for configuring metaslot. Users' 743 * setting always take precedence over the system wide 744 * setting. So, we will first check for any user's 745 * defined env variables before looking at the system-wide 746 * configuration. 747 */ 748 get_user_metaslot_config(); 749 750 /* no metaslot entry in /etc/crypto/pkcs11.conf */ 751 if (!metaslot_entry) { 752 /* 753 * If user env variable indicates metaslot should be enabled, 754 * but there's no entry in /etc/crypto/pkcs11.conf for 755 * metaslot at all, will respect the user's defined value 756 */ 757 if ((metaslot_config.enabled_specified) && 758 (metaslot_config.enabled)) { 759 metaslot_enabled = B_TRUE; 760 } 761 } else { 762 if (!metaslot_config.enabled_specified) { 763 /* 764 * take system wide value if 765 * it is not specified by user 766 */ 767 metaslot_enabled 768 = metaslot_entry->flag_metaslot_enabled; 769 } else { 770 metaslot_enabled = metaslot_config.enabled; 771 } 772 } 773 774 /* 775 * 776 * As long as the user or system configuration file does not 777 * disable metaslot, it will be enabled regardless of the 778 * number of slots plugged into the framework. Therefore, 779 * metaslot is enabled even when there's only one slot 780 * plugged into the framework. This is necessary for 781 * presenting a consistent token label view to applications. 782 * 783 * However, for the case where there is only 1 slot plugged into 784 * the framework, we can use "fastpath". 785 * 786 * "fastpath" will pass all of the application's requests 787 * directly to the underlying provider. Only when policy is in 788 * effect will we need to keep slotID around. 789 * 790 * When metaslot is enabled, and fastpath is enabled, 791 * all the metaslot processing will be skipped. 792 * When there is only 1 slot, there's 793 * really not much metaslot can do in terms of combining functionality 794 * of different slots, and object migration. 795 * 796 */ 797 798 /* check to see if fastpath can be used */ 799 if (slottable->st_last == slottable->st_first) { 800 801 cur_slot = slottable->st_slots[slottable->st_first]; 802 803 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 804 805 if ((cur_slot->sl_pol_count == 0) && 806 (!cur_slot->sl_enabledpol) && (!cur_slot->sl_norandom)) { 807 /* No policy is in effect, don't need slotid */ 808 fast_funcs = cur_slot->sl_func_list; 809 purefastpath = B_TRUE; 810 } else { 811 fast_funcs = cur_slot->sl_func_list; 812 fast_slot = slottable->st_first; 813 policyfastpath = B_TRUE; 814 } 815 816 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 817 } 818 819 if ((purefastpath || policyfastpath) && (!metaslot_enabled)) { 820 goto config_complete; 821 } 822 823 /* 824 * If we get here, there are more than 2 slots in the framework, 825 * we need to set up metaslot if it is enabled 826 */ 827 if (metaslot_enabled) { 828 rv = setup_metaslot(metaslot_entry); 829 if (rv != CKR_OK) { 830 goto conferror; 831 } 832 } 833 834 835 config_complete: 836 837 return (CKR_OK); 838 839 conferror: 840 /* 841 * This cleanup code is only exercised when a major, 842 * unrecoverable error like "out of memory" occurs. 843 */ 844 if (prov_funcs != NULL) { 845 (void) prov_funcs->C_Finalize(NULL); 846 } 847 if (dldesc != NULL) { 848 (void) dlclose(dldesc); 849 } 850 if (fullpath != NULL) { 851 free(fullpath); 852 fullpath = NULL; 853 } 854 if (prov_slots != NULL) { 855 free(prov_slots); 856 prov_slots = NULL; 857 } 858 859 return (rv); 860 } 861 862 /* 863 * pkcs11_mech_parse will take hex mechanism ids, as a list of 864 * strings, and convert them to CK_MECHANISM_TYPE_PTR. 865 */ 866 CK_RV 867 pkcs11_mech_parse(umechlist_t *str_list, CK_MECHANISM_TYPE_PTR *mech_list, 868 int mech_count) 869 { 870 CK_MECHANISM_TYPE_PTR tmp_list; 871 umechlist_t *shead = str_list; 872 873 tmp_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE)); 874 875 if (tmp_list == NULL) { 876 cryptoerror(LOG_ERR, "libpkcs11: parsing %s, out of memory. " 877 "Cannot continue.", 878 _PATH_PKCS11_CONF); 879 return (CKR_HOST_MEMORY); 880 } 881 882 *mech_list = tmp_list; 883 884 /* 885 * The following will loop mech_count times, as there are 886 * exactly mech_count items in the str_list. 887 */ 888 while (shead != NULL) { 889 CK_MECHANISM_TYPE cur_mech; 890 891 errno = 0; 892 893 /* 894 * "name" is a hexadecimal number, preceded by 0x. 895 */ 896 cur_mech = strtoul(shead->name, NULL, 16); 897 898 if ((cur_mech == 0) && 899 ((errno == EINVAL) || (errno == ERANGE))) { 900 free(mech_list); 901 return (CKR_MECHANISM_INVALID); 902 } 903 *tmp_list = (CK_MECHANISM_TYPE)cur_mech; 904 tmp_list++; 905 shead = shead->next; 906 } 907 908 return (CKR_OK); 909 } 910 911 /* 912 * pkcs11_is_dismech is provided a slotid and a mechanism. 913 * If mech is not disabled, then return B_FALSE. 914 */ 915 boolean_t 916 pkcs11_is_dismech(CK_SLOT_ID slotid, CK_MECHANISM_TYPE mech) 917 { 918 ulong_t i; 919 boolean_t enabled_pol; 920 CK_MECHANISM_TYPE_PTR pol_mechs; 921 ulong_t pol_count; 922 923 /* Find the associated slot and get the mech policy info */ 924 (void) pthread_mutex_lock(&slottable->st_slots[slotid]->sl_mutex); 925 enabled_pol = slottable->st_slots[slotid]->sl_enabledpol; 926 pol_mechs = slottable->st_slots[slotid]->sl_pol_mechs; 927 pol_count = slottable->st_slots[slotid]->sl_pol_count; 928 (void) pthread_mutex_unlock(&slottable->st_slots[slotid]->sl_mutex); 929 930 /* Check for policy */ 931 if ((!enabled_pol) && (pol_mechs == NULL)) { 932 /* no policy */ 933 return (B_FALSE); 934 } else if (pol_mechs == NULL) { 935 /* 936 * We have an empty enabled list, which means no 937 * mechanisms are exempted from this policy: all 938 * are disabled. 939 */ 940 return (B_TRUE); 941 } 942 943 for (i = 0; i < pol_count; i++) { 944 /* 945 * If it matches, return status based on this 946 * being and enabled or a disabled list of mechs. 947 */ 948 if (pol_mechs[i] == mech) { 949 return (enabled_pol ? B_FALSE : B_TRUE); 950 } 951 } 952 953 /* mech was not found in list */ 954 return (enabled_pol ? B_TRUE : B_FALSE); 955 } 956