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