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 case ELFSIGN_RESTRICTED: 702 break; 703 case ELFSIGN_NOTSIGNED: 704 estatus_str = "not a signed provider."; 705 break; 706 case ELFSIGN_FAILED: 707 estatus_str = "signature verification failed."; 708 break; 709 case ELFSIGN_UNAVAILABLE: 710 estatus_str = "kcfd(1m) is not available for " 711 "signature verification. Cannot continue loading " 712 "the cryptographic framework."; 713 break; 714 default: 715 estatus_str = "unexpected failure in ELF " 716 "signature verification."; 717 } 718 if (estatus_str != NULL) { 719 if (estatus != ELFSIGN_UNAVAILABLE) { 720 cryptoerror(LOG_ERR, "libpkcs11: %s %s %s", 721 fullpath, estatus_str, 722 estatus == ELFSIGN_UNKNOWN ? 723 "See cryptoadm (1M). " 724 "Cannot continue parsing " 725 _PATH_PKCS11_CONF : conf_err); 726 } else { 727 cryptoerror(LOG_ERR, "libpkcs11: %s", 728 estatus_str); 729 } 730 731 (void) prov_funcs->C_Finalize(NULL); 732 (void) dlclose(dldesc); 733 estatus_str = NULL; 734 if (estatus == ELFSIGN_UNKNOWN || 735 estatus == ELFSIGN_UNAVAILABLE) { 736 prov_funcs = NULL; 737 dldesc = NULL; 738 rv = CKR_GENERAL_ERROR; 739 goto conferror; 740 } 741 goto contparse; 742 } 743 744 /* Allocate memory for the slot list */ 745 prov_slots = calloc(prov_slot_count, sizeof (CK_SLOT_ID)); 746 747 if (prov_slots == NULL) { 748 cryptoerror(LOG_ERR, 749 "libpkcs11: Could not allocate memory for " 750 "plug-in slots. Cannot continue parsing %s\n", 751 _PATH_PKCS11_CONF); 752 rv = CKR_HOST_MEMORY; 753 goto conferror; 754 } 755 756 /* Get slot list from provider */ 757 prov_rv = prov_funcs->C_GetSlotList(FALSE, 758 prov_slots, &prov_slot_count); 759 760 /* if second call fails, drop this provider */ 761 if (prov_rv != CKR_OK) { 762 cryptoerror(LOG_ERR, 763 "libpkcs11: Second call to C_GetSlotList() for %s " 764 "failed. %s Error: %s.", 765 fullpath, conf_err, pkcs11_strerror(prov_rv)); 766 (void) prov_funcs->C_Finalize(NULL); 767 (void) dlclose(dldesc); 768 goto contparse; 769 } 770 771 /* 772 * Parse the list of disabled or enabled mechanisms, will 773 * apply to each of the provider's slots. 774 */ 775 if (phead->puent->count > 0) { 776 rv = pkcs11_mech_parse(phead->puent->policylist, 777 &prov_pol_mechs, phead->puent->count); 778 779 if (rv == CKR_HOST_MEMORY) { 780 cryptoerror(LOG_ERR, 781 "libpkcs11: Could not parse configuration," 782 "out of memory. Cannot continue parsing " 783 "%s.", _PATH_PKCS11_CONF); 784 goto conferror; 785 } else if (rv == CKR_MECHANISM_INVALID) { 786 /* 787 * Configuration file is corrupted for this 788 * provider. 789 */ 790 cryptoerror(LOG_ERR, 791 "libpkcs11: Policy invalid or corrupted " 792 "for %s. Use cryptoadm(1M) to fix " 793 "this. Skipping this plug-in.", 794 fullpath); 795 (void) prov_funcs->C_Finalize(NULL); 796 (void) dlclose(dldesc); 797 goto contparse; 798 } 799 } 800 801 /* Allocate memory in our slottable for these slots */ 802 rv = pkcs11_slottable_increase(prov_slot_count); 803 804 /* 805 * If any error is returned, it will be memory related, 806 * so we need to abort the attempt at filling the 807 * slottable. 808 */ 809 if (rv != CKR_OK) { 810 cryptoerror(LOG_ERR, 811 "libpkcs11: slottable could not increase. " 812 "Cannot continue parsing %s.", 813 _PATH_PKCS11_CONF); 814 goto conferror; 815 } 816 817 /* Configure information for each new slot */ 818 for (i = 0; i < prov_slot_count; i++) { 819 /* allocate slot in framework */ 820 rv = pkcs11_slot_allocate(&slot_id); 821 if (rv != CKR_OK) { 822 cryptoerror(LOG_ERR, 823 "libpkcs11: Could not allocate " 824 "new slot. Cannot continue parsing %s.", 825 _PATH_PKCS11_CONF); 826 goto conferror; 827 } 828 slot_count++; 829 cur_slot = slottable->st_slots[slot_id]; 830 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 831 cur_slot->sl_id = prov_slots[i]; 832 cur_slot->sl_func_list = prov_funcs; 833 cur_slot->sl_enabledpol = 834 phead->puent->flag_enabledlist; 835 cur_slot->sl_pol_mechs = prov_pol_mechs; 836 cur_slot->sl_pol_count = phead->puent->count; 837 cur_slot->sl_norandom = phead->puent->flag_norandom; 838 cur_slot->sl_dldesc = dldesc; 839 cur_slot->sl_prov_id = prov_count + 1; 840 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 841 } 842 843 /* 844 * Get the pointer to private interface _SUNW_GetThreshold() 845 * in pkcs11_kernel. 846 */ 847 848 if (Tmp_GetThreshold == NULL) { 849 Tmp_GetThreshold = 850 (void(*)())dlsym(dldesc, "_SUNW_GetThreshold"); 851 852 /* Get the threshold values for the supported mechs */ 853 if (Tmp_GetThreshold != NULL) { 854 (void) memset(meta_mechs_threshold, 0, 855 sizeof (meta_mechs_threshold)); 856 Tmp_GetThreshold(meta_mechs_threshold); 857 } 858 } 859 860 /* Set and reset values to process next provider */ 861 prov_count++; 862 contparse: 863 prov_slot_count = 0; 864 Tmp_C_GetFunctionList = NULL; 865 prov_funcs = NULL; 866 dldesc = NULL; 867 if (fullpath != NULL) { 868 free(fullpath); 869 fullpath = NULL; 870 } 871 if (prov_slots != NULL) { 872 free(prov_slots); 873 prov_slots = NULL; 874 } 875 phead = phead->next; 876 } 877 878 if (slot_count == 0) { 879 /* 880 * there's no other slot in the framework, 881 * there is nothing to do 882 */ 883 goto config_complete; 884 } 885 886 /* determine if metaslot should be enabled */ 887 888 /* 889 * Check to see if any environment variable is defined 890 * by the user for configuring metaslot. Users' 891 * setting always take precedence over the system wide 892 * setting. So, we will first check for any user's 893 * defined env variables before looking at the system-wide 894 * configuration. 895 */ 896 get_user_metaslot_config(); 897 898 /* no metaslot entry in /etc/crypto/pkcs11.conf */ 899 if (!metaslot_entry) { 900 /* 901 * If user env variable indicates metaslot should be enabled, 902 * but there's no entry in /etc/crypto/pkcs11.conf for 903 * metaslot at all, will respect the user's defined value 904 */ 905 if ((metaslot_config.enabled_specified) && 906 (metaslot_config.enabled)) { 907 metaslot_enabled = B_TRUE; 908 } 909 } else { 910 if (!metaslot_config.enabled_specified) { 911 /* 912 * take system wide value if 913 * it is not specified by user 914 */ 915 metaslot_enabled 916 = metaslot_entry->flag_metaslot_enabled; 917 } else { 918 metaslot_enabled = metaslot_config.enabled; 919 } 920 } 921 922 /* 923 * 924 * As long as the user or system configuration file does not 925 * disable metaslot, it will be enabled regardless of the 926 * number of slots plugged into the framework. Therefore, 927 * metaslot is enabled even when there's only one slot 928 * plugged into the framework. This is necessary for 929 * presenting a consistent token label view to applications. 930 * 931 * However, for the case where there is only 1 slot plugged into 932 * the framework, we can use "fastpath". 933 * 934 * "fastpath" will pass all of the application's requests 935 * directly to the underlying provider. Only when policy is in 936 * effect will we need to keep slotID around. 937 * 938 * When metaslot is enabled, and fastpath is enabled, 939 * all the metaslot processing will be skipped. 940 * When there is only 1 slot, there's 941 * really not much metaslot can do in terms of combining functionality 942 * of different slots, and object migration. 943 * 944 */ 945 946 /* check to see if fastpath can be used */ 947 if (slottable->st_last == slottable->st_first) { 948 949 cur_slot = slottable->st_slots[slottable->st_first]; 950 951 (void) pthread_mutex_lock(&cur_slot->sl_mutex); 952 953 if ((cur_slot->sl_pol_count == 0) && 954 (!cur_slot->sl_enabledpol) && (!cur_slot->sl_norandom)) { 955 /* No policy is in effect, don't need slotid */ 956 fast_funcs = cur_slot->sl_func_list; 957 purefastpath = B_TRUE; 958 } else { 959 fast_funcs = cur_slot->sl_func_list; 960 fast_slot = slottable->st_first; 961 policyfastpath = B_TRUE; 962 } 963 964 (void) pthread_mutex_unlock(&cur_slot->sl_mutex); 965 } 966 967 if ((purefastpath || policyfastpath) && (!metaslot_enabled)) { 968 goto config_complete; 969 } 970 971 /* 972 * If we get here, there are more than 2 slots in the framework, 973 * we need to set up metaslot if it is enabled 974 */ 975 if (metaslot_enabled) { 976 rv = setup_metaslot(metaslot_entry); 977 if (rv != CKR_OK) { 978 goto conferror; 979 } 980 } 981 982 983 config_complete: 984 985 return (CKR_OK); 986 987 conferror: 988 /* 989 * This cleanup code is only exercised when a major, 990 * unrecoverable error like "out of memory" or 991 * kcfd is not reachable occurs. 992 */ 993 if (prov_funcs != NULL) { 994 (void) prov_funcs->C_Finalize(NULL); 995 } 996 if (dldesc != NULL) { 997 (void) dlclose(dldesc); 998 } 999 if (fullpath != NULL) { 1000 free(fullpath); 1001 fullpath = NULL; 1002 } 1003 if (prov_slots != NULL) { 1004 free(prov_slots); 1005 prov_slots = NULL; 1006 } 1007 1008 return (rv); 1009 } 1010 1011 /* 1012 * pkcs11_mech_parse will take hex mechanism ids, as a list of 1013 * strings, and convert them to CK_MECHANISM_TYPE_PTR. 1014 */ 1015 CK_RV 1016 pkcs11_mech_parse(umechlist_t *str_list, CK_MECHANISM_TYPE_PTR *mech_list, 1017 int mech_count) 1018 { 1019 CK_MECHANISM_TYPE_PTR tmp_list; 1020 umechlist_t *shead = str_list; 1021 1022 tmp_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE)); 1023 1024 if (tmp_list == NULL) { 1025 cryptoerror(LOG_ERR, "libpkcs11: parsing %s, out of memory. " 1026 "Cannot continue.", 1027 _PATH_PKCS11_CONF); 1028 return (CKR_HOST_MEMORY); 1029 } 1030 1031 *mech_list = tmp_list; 1032 1033 /* 1034 * The following will loop mech_count times, as there are 1035 * exactly mech_count items in the str_list. 1036 */ 1037 while (shead != NULL) { 1038 CK_MECHANISM_TYPE cur_mech; 1039 1040 errno = 0; 1041 1042 /* 1043 * "name" is a hexadecimal number, preceded by 0x. 1044 */ 1045 cur_mech = strtoul(shead->name, NULL, 16); 1046 1047 if ((cur_mech == 0) && 1048 ((errno == EINVAL) || (errno == ERANGE))) { 1049 free(mech_list); 1050 return (CKR_MECHANISM_INVALID); 1051 } 1052 *tmp_list = (CK_MECHANISM_TYPE)cur_mech; 1053 tmp_list++; 1054 shead = shead->next; 1055 } 1056 1057 return (CKR_OK); 1058 } 1059 1060 /* 1061 * pkcs11_is_dismech is provided a slotid and a mechanism. 1062 * If mech is not disabled, then return B_FALSE. 1063 */ 1064 boolean_t 1065 pkcs11_is_dismech(CK_SLOT_ID slotid, CK_MECHANISM_TYPE mech) 1066 { 1067 ulong_t i; 1068 boolean_t enabled_pol; 1069 CK_MECHANISM_TYPE_PTR pol_mechs; 1070 ulong_t pol_count; 1071 1072 /* Find the associated slot and get the mech policy info */ 1073 (void) pthread_mutex_lock(&slottable->st_slots[slotid]->sl_mutex); 1074 enabled_pol = slottable->st_slots[slotid]->sl_enabledpol; 1075 pol_mechs = slottable->st_slots[slotid]->sl_pol_mechs; 1076 pol_count = slottable->st_slots[slotid]->sl_pol_count; 1077 (void) pthread_mutex_unlock(&slottable->st_slots[slotid]->sl_mutex); 1078 1079 /* Check for policy */ 1080 if ((!enabled_pol) && (pol_mechs == NULL)) { 1081 /* no policy */ 1082 return (B_FALSE); 1083 } else if (pol_mechs == NULL) { 1084 /* 1085 * We have an empty enabled list, which means no 1086 * mechanisms are exempted from this policy: all 1087 * are disabled. 1088 */ 1089 return (B_TRUE); 1090 } 1091 1092 for (i = 0; i < pol_count; i++) { 1093 /* 1094 * If it matches, return status based on this 1095 * being and enabled or a disabled list of mechs. 1096 */ 1097 if (pol_mechs[i] == mech) { 1098 return (enabled_pol ? B_FALSE : B_TRUE); 1099 } 1100 } 1101 1102 /* mech was not found in list */ 1103 return (enabled_pol ? B_TRUE : B_FALSE); 1104 } 1105