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