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