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