xref: /illumos-gate/usr/src/lib/pkcs11/libpkcs11/common/pkcs11Conf.c (revision 581cede61ac9c14d8d4ea452562a567189eead78)
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  * For each provider found in pkcs11.conf: expand $ISA if necessary,
276  * verify the module is signed, load the provider, find all of its
277  * slots, and store the function list and disabled policy.
278  *
279  * This function requires that the uentrylist_t and pkcs11_slottable_t
280  * already have memory allocated, and that the uentrylist_t is already
281  * populated with provider and policy information.
282  *
283  * pInitArgs can be set to NULL, but is normally the same value
284  * the framework's C_Initialize() was called with.
285  *
286  * Unless metaslot is explicitly disabled, it is setup when all other
287  * providers are loaded.
288  */
289 CK_RV
290 pkcs11_slot_mapping(uentrylist_t *pplist, CK_VOID_PTR pInitArgs)
291 {
292 	CK_RV rv = CKR_OK;
293 	CK_RV prov_rv;			/* Provider's return code */
294 	CK_INFO prov_info;
295 	CK_RV (*Tmp_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR);
296 	CK_FUNCTION_LIST_PTR prov_funcs = NULL; /* Provider's function list */
297 	CK_ULONG prov_slot_count; 		/* Number of slots */
298 	CK_SLOT_ID slot_id; 		/* slotID assigned for framework */
299 	CK_SLOT_ID_PTR prov_slots = NULL; 	/* Provider's slot list */
300 					/* Enabled or Disabled policy */
301 	CK_MECHANISM_TYPE_PTR prov_pol_mechs = NULL;
302 
303 	void *dldesc = NULL;
304 	char *isa, *fullpath = NULL, *dl_error;
305 	uentrylist_t *phead;
306 	uint_t prov_count = 0;
307 	pkcs11_slot_t *cur_slot;
308 	CK_ULONG i;
309 	size_t len;
310 	uentry_t *metaslot_entry = NULL;
311 	/* number of slots in the framework, not including metaslot */
312 	uint_t slot_count = 0;
313 
314 	ELFsign_status_t estatus = ELFSIGN_UNKNOWN;
315 	char *estatus_str = NULL;
316 	int kcfdfd = -1;
317 	door_arg_t	darg;
318 	kcf_door_arg_t *kda = NULL;
319 	kcf_door_arg_t *rkda = NULL;
320 	int r;
321 	int		is_cryptosvc_up_count = 0;
322 	int		door_errno = 0;
323 	boolean_t	try_door_open_again = B_FALSE;
324 
325 	phead = pplist;
326 
327 	/* Loop through all of the provider listed in pkcs11.conf */
328 	while (phead != NULL) {
329 		if (!strcasecmp(phead->puent->name, "metaslot")) {
330 			/*
331 			 * Skip standard processing for metaslot
332 			 * entry since it is not an actual library
333 			 * that can be dlopened.
334 			 * It will be initialized later.
335 			 */
336 			if (metaslot_entry != NULL) {
337 				cryptoerror(LOG_ERR,
338 				    "libpkcs11: multiple entries for metaslot "
339 				    "detected.  All but the first entry will "
340 				    "be ignored");
341 			} else {
342 				metaslot_entry = phead->puent;
343 			}
344 			goto contparse;
345 		}
346 
347 		/* Check for Instruction Set Architecture indicator */
348 		if ((isa = strstr(phead->puent->name, PKCS11_ISA)) != NULL) {
349 			/* Substitute the architecture dependent path */
350 			len = strlen(phead->puent->name) -
351 			    strlen(PKCS11_ISA) +
352 			    strlen(PKCS11_ISA_DIR) + 1;
353 			if ((fullpath = (char *)malloc(len)) == NULL) {
354 				cryptoerror(LOG_ERR,
355 				    "libpksc11: parsing %s, out of memory. "
356 				    "Cannot continue parsing.",
357 				    _PATH_PKCS11_CONF);
358 				rv = CKR_HOST_MEMORY;
359 				goto conferror;
360 			}
361 			*isa = '\000';
362 			isa += strlen(PKCS11_ISA);
363 			(void) snprintf(fullpath, len, "%s%s%s",
364 			    phead->puent->name, PKCS11_ISA_DIR, isa);
365 		} else if ((fullpath = strdup(phead->puent->name)) == 0) {
366 			cryptoerror(LOG_ERR,
367 			    "libpkcs11: parsing %s, out of memory. "
368 			    "Cannot continue parsing.",
369 			    _PATH_PKCS11_CONF);
370 			rv = CKR_HOST_MEMORY;
371 			goto conferror;
372 		}
373 
374 		/*
375 		 * Open the provider. Use RTLD_NOW to make sure we
376 		 * will not encounter symbol referencing errors later.
377 		 * Use RTLD_GROUP to limit the provider to it's own
378 		 * symbols, which prevents it from mistakenly accessing
379 		 * the framework's C_* functions.
380 		 */
381 		dldesc = dlopen(fullpath, RTLD_NOW|RTLD_GROUP);
382 
383 		/*
384 		 * If we failed to load it, we will just skip this
385 		 * provider and move on to the next one.
386 		 */
387 		if (dldesc == NULL) {
388 			dl_error = dlerror();
389 			cryptoerror(LOG_ERR,
390 			    "libpkcs11: Cannot load PKCS#11 library %s.  "
391 			    "dlerror: %s. %s",
392 			    fullpath, dl_error != NULL ? dl_error : "Unknown",
393 			    conf_err);
394 			goto contparse;
395 		}
396 
397 		/* Get the pointer to provider's C_GetFunctionList() */
398 		Tmp_C_GetFunctionList =
399 		    (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList");
400 
401 		/*
402 		 * If we failed to get the pointer to C_GetFunctionList(),
403 		 * skip this provider and continue to the next one.
404 		 */
405 		if (Tmp_C_GetFunctionList == NULL) {
406 			cryptoerror(LOG_ERR,
407 			    "libpkcs11: Could not dlsym() C_GetFunctionList() "
408 			    "for %s. May not be a PKCS#11 library. %s",
409 			    fullpath, conf_err);
410 			(void) dlclose(dldesc);
411 			goto contparse;
412 		}
413 
414 
415 		/* Get the provider's function list */
416 		prov_rv = Tmp_C_GetFunctionList(&prov_funcs);
417 
418 		/*
419 		 * If we failed to get the provider's function list,
420 		 * skip this provider and continue to the next one.
421 		 */
422 		if (prov_rv != CKR_OK) {
423 			cryptoerror(LOG_ERR,
424 			    "libpkcs11: Could not get function list for %s. "
425 			    "%s Error: %s.",
426 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
427 			(void) dlclose(dldesc);
428 			goto contparse;
429 		}
430 
431 		/* Initialize this provider */
432 		prov_rv = prov_funcs->C_Initialize(pInitArgs);
433 
434 		/*
435 		 * If we failed to initialize this provider,
436 		 * skip this provider and continue to the next one.
437 		 */
438 		if ((prov_rv != CKR_OK) &&
439 		    (prov_rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
440 			cryptoerror(LOG_ERR,
441 			    "libpkcs11: Could not initialize %s. "
442 			    "%s Error: %s.",
443 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
444 			(void) dlclose(dldesc);
445 			goto contparse;
446 		}
447 
448 		/*
449 		 * Make sure this provider is implementing the same
450 		 * major version, and at least the same minor version
451 		 * that we are.
452 		 */
453 		prov_rv = prov_funcs->C_GetInfo(&prov_info);
454 
455 		/*
456 		 * If we can't verify that we are implementing the
457 		 * same major version, or if it is definitely not the same
458 		 * version, we need to skip this provider.
459 		 */
460 		if ((prov_rv != CKR_OK) ||
461 		    (prov_info.cryptokiVersion.major !=
462 		    CRYPTOKI_VERSION_MAJOR))  {
463 			if (prov_rv != CKR_OK) {
464 				cryptoerror(LOG_ERR,
465 				    "libpkcs11: Could not verify version of "
466 				    "%s. %s Error: %s.", fullpath,
467 				    conf_err, pkcs11_strerror(prov_rv));
468 			} else {
469 				cryptoerror(LOG_ERR,
470 				    "libpkcs11: Only CRYPTOKI major version "
471 				    "%d is supported.  %s is major "
472 				    "version %d. %s",
473 				    CRYPTOKI_VERSION_MAJOR, fullpath,
474 				    prov_info.cryptokiVersion.major, conf_err);
475 			}
476 			(void) prov_funcs->C_Finalize(NULL);
477 			(void) dlclose(dldesc);
478 			goto contparse;
479 		}
480 
481 		/*
482 		 * Warn the administrator (at debug) that a provider with
483 		 * a significantly older or newer version of
484 		 * CRYPTOKI is being used.  It should not cause
485 		 * problems, but logging a warning makes it easier
486 		 * to debug later.
487 		 */
488 		if ((prov_info.cryptokiVersion.minor <
489 		    CRYPTOKI_VERSION_WARN_MINOR) ||
490 		    (prov_info.cryptokiVersion.minor >
491 		    CRYPTOKI_VERSION_MINOR)) {
492 			cryptoerror(LOG_DEBUG,
493 			    "libpkcs11: %s CRYPTOKI minor version, %d, may "
494 			    "not be compatible with minor version %d.",
495 			    fullpath, prov_info.cryptokiVersion.minor,
496 			    CRYPTOKI_VERSION_MINOR);
497 		}
498 
499 		/*
500 		 * Find out how many slots this provider has,
501 		 * call with tokenPresent set to FALSE so all
502 		 * potential slots are returned.
503 		 */
504 		prov_rv = prov_funcs->C_GetSlotList(FALSE,
505 		    NULL, &prov_slot_count);
506 
507 		/*
508 		 * If the call failed, or if no slots are returned,
509 		 * then skip this provider and continue to next one.
510 		 */
511 		if (prov_rv != CKR_OK) {
512 			cryptoerror(LOG_ERR,
513 			    "libpksc11: Could not get slot list from %s. "
514 			    "%s Error: %s.",
515 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
516 			(void) prov_funcs->C_Finalize(NULL);
517 			(void) dlclose(dldesc);
518 			goto contparse;
519 		}
520 
521 		if (prov_slot_count == 0) {
522 			cryptodebug("libpkcs11: No slots presented from %s. "
523 			    "Skipping this plug-in at this time.\n",
524 			    fullpath);
525 			(void) prov_funcs->C_Finalize(NULL);
526 			(void) dlclose(dldesc);
527 			goto contparse;
528 		}
529 
530 		/*
531 		 * Verify that the module is signed correctly.
532 		 *
533 		 * NOTE: there is a potential race condition here,
534 		 * since the module is verified well after we have
535 		 * opened the provider via dlopen().  This could be
536 		 * resolved by a variant of dlopen() that would take a
537 		 * file descriptor as an argument and by changing the
538 		 * kcfd libelfsign door protocol to use and fd instead
539 		 * of a path - but that wouldn't work in the kernel case.
540 		 */
541 open_door_file:
542 		while ((kcfdfd = open(_PATH_KCFD_DOOR, O_RDONLY)) == -1) {
543 			/* save errno and test for EINTR or EAGAIN */
544 			door_errno = errno;
545 			if (door_errno == EINTR ||
546 			    door_errno == EAGAIN)
547 				continue;
548 			/* if disabled or maintenance mode - bail */
549 			if (cryptosvc_is_down())
550 				break;
551 			/* exceeded our number of tries? */
552 			if (is_cryptosvc_up_count > MAX_CRYPTOSVC_ONLINE_TRIES)
553 				break;
554 			/* any other state, try again up to 1/2 minute */
555 			(void) sleep(5);
556 			is_cryptosvc_up_count++;
557 		}
558 		if (kcfdfd == -1) {
559 			if (!cryptosvc_is_online()) {
560 				cryptoerror(LOG_ERR, "libpkcs11: unable to open"
561 				    " kcfd door_file %s: %s.  %s is not online."
562 				    " (see svcs -xv for details).",
563 				    _PATH_KCFD_DOOR, strerror(door_errno),
564 				    CRYPTOSVC_DEFAULT_INSTANCE_FMRI);
565 			} else {
566 				cryptoerror(LOG_ERR, "libpkcs11: unable to open"
567 				    " kcfd door_file %s: %s.", _PATH_KCFD_DOOR,
568 				    strerror(door_errno));
569 			}
570 			rv = CKR_CRYPTOKI_NOT_INITIALIZED;
571 			estatus = ELFSIGN_UNKNOWN;
572 			goto verifycleanup;
573 		}
574 
575 		/* Mark the door "close on exec" */
576 		(void) fcntl(kcfdfd, F_SETFD, FD_CLOEXEC);
577 
578 		if ((kda = malloc(sizeof (kcf_door_arg_t))) == NULL) {
579 			cryptoerror(LOG_ERR, "libpkcs11: malloc of kda "
580 			    "failed: %s", strerror(errno));
581 			goto verifycleanup;
582 		}
583 		kda->da_version = KCF_KCFD_VERSION1;
584 		kda->da_iskernel = B_FALSE;
585 		(void) strlcpy(kda->da_u.filename, fullpath,
586 		    strlen(fullpath) + 1);
587 
588 		darg.data_ptr = (char *)kda;
589 		darg.data_size = sizeof (kcf_door_arg_t);
590 		darg.desc_ptr = NULL;
591 		darg.desc_num = 0;
592 		darg.rbuf = (char *)kda;
593 		darg.rsize = sizeof (kcf_door_arg_t);
594 
595 		while ((r = door_call(kcfdfd, &darg)) != 0) {
596 			/* save errno and test for certain errors */
597 			door_errno = errno;
598 			if (door_errno == EINTR || door_errno == EAGAIN)
599 				continue;
600 			/* if disabled or maintenance mode - bail */
601 			if (cryptosvc_is_down())
602 				break;
603 			/* exceeded our number of tries? */
604 			if (is_cryptosvc_up_count > MAX_CRYPTOSVC_ONLINE_TRIES)
605 				break;
606 			/* if stale door_handle, retry the open */
607 			if (door_errno == EBADF) {
608 				try_door_open_again = B_TRUE;
609 				is_cryptosvc_up_count++;
610 				(void) sleep(5);
611 				goto verifycleanup;
612 			} else
613 				break;
614 		}
615 
616 		if (r != 0) {
617 			if (!cryptosvc_is_online()) {
618 				cryptoerror(LOG_ERR, "%s is not online "
619 				    " - unable to utilize cryptographic "
620 				    "services.  (see svcs -xv for details).",
621 				    CRYPTOSVC_DEFAULT_INSTANCE_FMRI);
622 			} else {
623 				cryptoerror(LOG_ERR, "libpkcs11: door_call "
624 				    "of door_file %s failed with error %s.",
625 				    _PATH_KCFD_DOOR, strerror(door_errno));
626 			}
627 			rv = CKR_CRYPTOKI_NOT_INITIALIZED;
628 			estatus = ELFSIGN_UNKNOWN;
629 			goto verifycleanup;
630 		}
631 
632 		/*LINTED*/
633 		rkda = (kcf_door_arg_t *)darg.rbuf;
634 		if (rkda->da_version != KCF_KCFD_VERSION1) {
635 			cryptoerror(LOG_ERR,
636 			    "libpkcs11: kcfd and libelfsign versions "
637 			    "don't match: got %d expected %d",
638 			    rkda->da_version, KCF_KCFD_VERSION1);
639 			goto verifycleanup;
640 		}
641 		estatus = rkda->da_u.result.status;
642 verifycleanup:
643 		if (kcfdfd != -1) {
644 			(void) close(kcfdfd);
645 		}
646 		if (rkda != NULL && rkda != kda)
647 			(void) munmap((char *)rkda, darg.rsize);
648 		if (kda != NULL) {
649 			bzero(kda, sizeof (kda));
650 			free(kda);
651 			kda = NULL;
652 			rkda = NULL;	/* rkda is an alias of kda */
653 		}
654 		if (try_door_open_again) {
655 			try_door_open_again = B_FALSE;
656 			goto open_door_file;
657 		}
658 
659 		switch (estatus) {
660 		case ELFSIGN_UNKNOWN:
661 		case ELFSIGN_SUCCESS:
662 		case ELFSIGN_RESTRICTED:
663 			break;
664 		case ELFSIGN_NOTSIGNED:
665 			estatus_str = strdup("not a signed provider.");
666 			break;
667 		case ELFSIGN_FAILED:
668 			estatus_str = strdup("signature verification failed.");
669 			break;
670 		default:
671 			estatus_str = strdup("unexpected failure in ELF "
672 			    "signature verification. "
673 			    "System may have been tampered with.");
674 		}
675 		if (estatus_str != NULL) {
676 			cryptoerror(LOG_ERR, "libpkcs11: %s %s %s",
677 			    fullpath, estatus_str ? estatus_str : "",
678 			    estatus == ELFSIGN_UNKNOWN ?
679 			    "Cannot continue parsing " _PATH_PKCS11_CONF:
680 			    conf_err);
681 			(void) prov_funcs->C_Finalize(NULL);
682 			(void) dlclose(dldesc);
683 			free(estatus_str);
684 			estatus_str = NULL;
685 			if (estatus == ELFSIGN_UNKNOWN) {
686 				prov_funcs = NULL;
687 				dldesc = NULL;
688 				rv = CKR_GENERAL_ERROR;
689 				goto conferror;
690 			}
691 			goto contparse;
692 		}
693 
694 		/* Allocate memory for the slot list */
695 		prov_slots = calloc(prov_slot_count, sizeof (CK_SLOT_ID));
696 
697 		if (prov_slots == NULL) {
698 			cryptoerror(LOG_ERR,
699 			    "libpkcs11: Could not allocate memory for "
700 			    "plug-in slots. Cannot continue parsing %s\n",
701 			    _PATH_PKCS11_CONF);
702 			rv = CKR_HOST_MEMORY;
703 			goto conferror;
704 		}
705 
706 		/* Get slot list from provider */
707 		prov_rv = prov_funcs->C_GetSlotList(FALSE,
708 		    prov_slots, &prov_slot_count);
709 
710 		/* if second call fails, drop this provider */
711 		if (prov_rv != CKR_OK) {
712 			cryptoerror(LOG_ERR,
713 			    "libpkcs11: Second call to C_GetSlotList() for %s "
714 			    "failed. %s Error: %s.",
715 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
716 			(void) prov_funcs->C_Finalize(NULL);
717 			(void) dlclose(dldesc);
718 			goto contparse;
719 		}
720 
721 		/*
722 		 * Parse the list of disabled or enabled mechanisms, will
723 		 * apply to each of the provider's slots.
724 		 */
725 		if (phead->puent->count > 0) {
726 			rv = pkcs11_mech_parse(phead->puent->policylist,
727 			    &prov_pol_mechs, phead->puent->count);
728 
729 			if (rv == CKR_HOST_MEMORY) {
730 				cryptoerror(LOG_ERR,
731 				    "libpkcs11: Could not parse configuration,"
732 				    "out of memory. Cannot continue parsing "
733 				    "%s.", _PATH_PKCS11_CONF);
734 				goto conferror;
735 			} else if (rv == CKR_MECHANISM_INVALID) {
736 				/*
737 				 * Configuration file is corrupted for this
738 				 * provider.
739 				 */
740 				cryptoerror(LOG_ERR,
741 				    "libpkcs11: Policy invalid or corrupted "
742 				    "for %s. Use cryptoadm(1M) to fix "
743 				    "this. Skipping this plug-in.",
744 				    fullpath);
745 				(void) prov_funcs->C_Finalize(NULL);
746 				(void) dlclose(dldesc);
747 				goto contparse;
748 			}
749 		}
750 
751 		/* Allocate memory in our slottable for these slots */
752 		rv = pkcs11_slottable_increase(prov_slot_count);
753 
754 		/*
755 		 * If any error is returned, it will be memory related,
756 		 * so we need to abort the attempt at filling the
757 		 * slottable.
758 		 */
759 		if (rv != CKR_OK) {
760 			cryptoerror(LOG_ERR,
761 			    "libpkcs11: slottable could not increase. "
762 			    "Cannot continue parsing %s.",
763 			    _PATH_PKCS11_CONF);
764 			goto conferror;
765 		}
766 
767 		/* Configure information for each new slot */
768 		for (i = 0; i < prov_slot_count; i++) {
769 			/* allocate slot in framework */
770 			rv = pkcs11_slot_allocate(&slot_id);
771 			if (rv != CKR_OK) {
772 				cryptoerror(LOG_ERR,
773 				    "libpkcs11: Could not allocate "
774 				    "new slot.  Cannot continue parsing %s.",
775 				    _PATH_PKCS11_CONF);
776 				goto conferror;
777 			}
778 			slot_count++;
779 			cur_slot = slottable->st_slots[slot_id];
780 			(void) pthread_mutex_lock(&cur_slot->sl_mutex);
781 			cur_slot->sl_id = prov_slots[i];
782 			cur_slot->sl_func_list = prov_funcs;
783 			cur_slot->sl_enabledpol =
784 			    phead->puent->flag_enabledlist;
785 			cur_slot->sl_pol_mechs = prov_pol_mechs;
786 			cur_slot->sl_pol_count = phead->puent->count;
787 			cur_slot->sl_norandom = phead->puent->flag_norandom;
788 			cur_slot->sl_dldesc = dldesc;
789 			cur_slot->sl_prov_id = prov_count + 1;
790 			(void) pthread_mutex_unlock(&cur_slot->sl_mutex);
791 		}
792 
793 		/*
794 		 * Get the pointer to private interface _SUNW_GetThreshold()
795 		 * in pkcs11_kernel.
796 		 */
797 
798 		if (Tmp_GetThreshold == NULL) {
799 			Tmp_GetThreshold =
800 			    (void(*)())dlsym(dldesc, "_SUNW_GetThreshold");
801 
802 			/* Get the threshold values for the supported mechs */
803 			if (Tmp_GetThreshold != NULL) {
804 				(void) memset(meta_mechs_threshold, 0,
805 				    sizeof (meta_mechs_threshold));
806 				Tmp_GetThreshold(meta_mechs_threshold);
807 			}
808 		}
809 
810 		/* Set and reset values to process next provider */
811 		prov_count++;
812 contparse:
813 		prov_slot_count = 0;
814 		Tmp_C_GetFunctionList = NULL;
815 		prov_funcs = NULL;
816 		dldesc = NULL;
817 		if (fullpath != NULL) {
818 			free(fullpath);
819 			fullpath = NULL;
820 		}
821 		if (prov_slots != NULL) {
822 			free(prov_slots);
823 			prov_slots = NULL;
824 		}
825 		phead = phead->next;
826 	}
827 
828 	if (slot_count == 0) {
829 		/*
830 		 * there's no other slot in the framework,
831 		 * there is nothing to do
832 		 */
833 		goto config_complete;
834 	}
835 
836 	/* determine if metaslot should be enabled */
837 
838 	/*
839 	 * Check to see if any environment variable is defined
840 	 * by the user for configuring metaslot.  Users'
841 	 * setting always take precedence over the system wide
842 	 * setting.  So, we will first check for any user's
843 	 * defined env variables before looking at the system-wide
844 	 * configuration.
845 	 */
846 	get_user_metaslot_config();
847 
848 	/* no metaslot entry in /etc/crypto/pkcs11.conf */
849 	if (!metaslot_entry) {
850 		/*
851 		 * If user env variable indicates metaslot should be enabled,
852 		 * but there's no entry in /etc/crypto/pkcs11.conf for
853 		 * metaslot at all, will respect the user's defined value
854 		 */
855 		if ((metaslot_config.enabled_specified) &&
856 		    (metaslot_config.enabled)) {
857 			metaslot_enabled = B_TRUE;
858 		}
859 	} else {
860 		if (!metaslot_config.enabled_specified) {
861 			/*
862 			 * take system wide value if
863 			 * it is not specified by user
864 			 */
865 			metaslot_enabled
866 			    = metaslot_entry->flag_metaslot_enabled;
867 		} else {
868 			metaslot_enabled = metaslot_config.enabled;
869 		}
870 	}
871 
872 	/*
873 	 *
874 	 * As long as the user or system configuration file does not
875 	 * disable metaslot, it will be enabled regardless of the
876 	 * number of slots plugged into the framework.  Therefore,
877 	 * metaslot is enabled even when there's only one slot
878 	 * plugged into the framework.  This is necessary for
879 	 * presenting a consistent token label view to applications.
880 	 *
881 	 * However, for the case where there is only 1 slot plugged into
882 	 * the framework, we can use "fastpath".
883 	 *
884 	 * "fastpath" will pass all of the application's requests
885 	 * directly to the underlying provider.  Only when policy is in
886 	 * effect will we need to keep slotID around.
887 	 *
888 	 * When metaslot is enabled, and fastpath is enabled,
889 	 * all the metaslot processing will be skipped.
890 	 * When there is only 1 slot, there's
891 	 * really not much metaslot can do in terms of combining functionality
892 	 * of different slots, and object migration.
893 	 *
894 	 */
895 
896 	/* check to see if fastpath can be used */
897 	if (slottable->st_last == slottable->st_first) {
898 
899 		cur_slot = slottable->st_slots[slottable->st_first];
900 
901 		(void) pthread_mutex_lock(&cur_slot->sl_mutex);
902 
903 		if ((cur_slot->sl_pol_count == 0) &&
904 		    (!cur_slot->sl_enabledpol) && (!cur_slot->sl_norandom)) {
905 			/* No policy is in effect, don't need slotid */
906 			fast_funcs = cur_slot->sl_func_list;
907 			purefastpath = B_TRUE;
908 		} else {
909 			fast_funcs = cur_slot->sl_func_list;
910 			fast_slot = slottable->st_first;
911 			policyfastpath = B_TRUE;
912 		}
913 
914 		(void) pthread_mutex_unlock(&cur_slot->sl_mutex);
915 	}
916 
917 	if ((purefastpath || policyfastpath) && (!metaslot_enabled)) {
918 		goto config_complete;
919 	}
920 
921 	/*
922 	 * If we get here, there are more than 2 slots in the framework,
923 	 * we need to set up metaslot if it is enabled
924 	 */
925 	if (metaslot_enabled) {
926 		rv = setup_metaslot(metaslot_entry);
927 		if (rv != CKR_OK) {
928 			goto conferror;
929 		}
930 	}
931 
932 
933 config_complete:
934 
935 	return (CKR_OK);
936 
937 conferror:
938 	/*
939 	 * This cleanup code is only exercised when a major,
940 	 * unrecoverable error like "out of memory" occurs.
941 	 */
942 	if (prov_funcs != NULL) {
943 		(void) prov_funcs->C_Finalize(NULL);
944 	}
945 	if (dldesc != NULL) {
946 		(void) dlclose(dldesc);
947 	}
948 	if (fullpath != NULL) {
949 		free(fullpath);
950 		fullpath = NULL;
951 	}
952 	if (prov_slots != NULL) {
953 		free(prov_slots);
954 		prov_slots = NULL;
955 	}
956 
957 	return (rv);
958 }
959 
960 /*
961  * pkcs11_mech_parse will take hex mechanism ids, as a list of
962  * strings, and convert them to CK_MECHANISM_TYPE_PTR.
963  */
964 CK_RV
965 pkcs11_mech_parse(umechlist_t *str_list, CK_MECHANISM_TYPE_PTR *mech_list,
966     int mech_count)
967 {
968 	CK_MECHANISM_TYPE_PTR tmp_list;
969 	umechlist_t *shead = str_list;
970 
971 	tmp_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE));
972 
973 	if (tmp_list == NULL) {
974 		cryptoerror(LOG_ERR, "libpkcs11: parsing %s, out of memory. "
975 		    "Cannot continue.",
976 		    _PATH_PKCS11_CONF);
977 		return (CKR_HOST_MEMORY);
978 	}
979 
980 	*mech_list = tmp_list;
981 
982 	/*
983 	 * The following will loop mech_count times, as there are
984 	 * exactly mech_count items in the str_list.
985 	 */
986 	while (shead != NULL) {
987 		CK_MECHANISM_TYPE cur_mech;
988 
989 		errno = 0;
990 
991 		/*
992 		 * "name" is a hexadecimal number, preceded by 0x.
993 		 */
994 		cur_mech = strtoul(shead->name, NULL, 16);
995 
996 		if ((cur_mech == 0) &&
997 		    ((errno == EINVAL) || (errno == ERANGE))) {
998 			free(mech_list);
999 			return (CKR_MECHANISM_INVALID);
1000 		}
1001 		*tmp_list = (CK_MECHANISM_TYPE)cur_mech;
1002 		tmp_list++;
1003 		shead = shead->next;
1004 	}
1005 
1006 	return (CKR_OK);
1007 }
1008 
1009 /*
1010  * pkcs11_is_dismech is provided a slotid and a mechanism.
1011  * If mech is not disabled, then return B_FALSE.
1012  */
1013 boolean_t
1014 pkcs11_is_dismech(CK_SLOT_ID slotid, CK_MECHANISM_TYPE mech)
1015 {
1016 	ulong_t i;
1017 	boolean_t enabled_pol;
1018 	CK_MECHANISM_TYPE_PTR pol_mechs;
1019 	ulong_t pol_count;
1020 
1021 	/* Find the associated slot and get the mech policy info */
1022 	(void) pthread_mutex_lock(&slottable->st_slots[slotid]->sl_mutex);
1023 	enabled_pol = slottable->st_slots[slotid]->sl_enabledpol;
1024 	pol_mechs = slottable->st_slots[slotid]->sl_pol_mechs;
1025 	pol_count = slottable->st_slots[slotid]->sl_pol_count;
1026 	(void) pthread_mutex_unlock(&slottable->st_slots[slotid]->sl_mutex);
1027 
1028 	/* Check for policy */
1029 	if ((!enabled_pol) && (pol_mechs == NULL)) {
1030 		/* no policy */
1031 		return (B_FALSE);
1032 	} else if (pol_mechs == NULL) {
1033 		/*
1034 		 * We have an empty enabled list, which means no
1035 		 * mechanisms are exempted from this policy: all
1036 		 * are disabled.
1037 		 */
1038 		return (B_TRUE);
1039 	}
1040 
1041 	for (i = 0; i < pol_count; i++) {
1042 		/*
1043 		 * If it matches, return status based on this
1044 		 * being and enabled or a disabled list of mechs.
1045 		 */
1046 		if (pol_mechs[i] == mech) {
1047 			return (enabled_pol ? B_FALSE : B_TRUE);
1048 		}
1049 	}
1050 
1051 	/* mech was not found in list */
1052 	return (enabled_pol ? B_TRUE : B_FALSE);
1053 }
1054