xref: /titanic_50/usr/src/lib/pkcs11/libpkcs11/common/pkcs11Conf.c (revision 41d4fbbe41ff68b2451773fa974828dcb122c1e3)
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 		/* Check for Instruction Set Architecture indicator */
496 		if ((isa = strstr(phead->puent->name, PKCS11_ISA)) != NULL) {
497 			/* Substitute the architecture dependent path */
498 			len = strlen(phead->puent->name) -
499 			    strlen(PKCS11_ISA) +
500 			    strlen(PKCS11_ISA_DIR) + 1;
501 			if ((fullpath = (char *)malloc(len)) == NULL) {
502 				cryptoerror(LOG_ERR,
503 				    "libpksc11: parsing %s, out of memory. "
504 				    "Cannot continue parsing.",
505 				    _PATH_PKCS11_CONF);
506 				rv = CKR_HOST_MEMORY;
507 				goto conferror;
508 			}
509 			*isa = '\000';
510 			isa += strlen(PKCS11_ISA);
511 			(void) snprintf(fullpath, len, "%s%s%s",
512 			    phead->puent->name, PKCS11_ISA_DIR, isa);
513 		} else if ((fullpath = strdup(phead->puent->name)) == 0) {
514 			cryptoerror(LOG_ERR,
515 			    "libpkcs11: parsing %s, out of memory. "
516 			    "Cannot continue parsing.",
517 			    _PATH_PKCS11_CONF);
518 			rv = CKR_HOST_MEMORY;
519 			goto conferror;
520 		}
521 
522 		/*
523 		 * Open the provider. Use RTLD_NOW to make sure we
524 		 * will not encounter symbol referencing errors later.
525 		 * Use RTLD_GROUP to limit the provider to it's own
526 		 * symbols, which prevents it from mistakenly accessing
527 		 * the framework's C_* functions.
528 		 */
529 		dldesc = dlopen(fullpath, RTLD_NOW|RTLD_GROUP);
530 
531 		/*
532 		 * If we failed to load it, we will just skip this
533 		 * provider and move on to the next one.
534 		 */
535 		if (dldesc == NULL) {
536 			dl_error = dlerror();
537 			cryptoerror(LOG_ERR,
538 			    "libpkcs11: Cannot load PKCS#11 library %s.  "
539 			    "dlerror: %s. %s",
540 			    fullpath, dl_error != NULL ? dl_error : "Unknown",
541 			    conf_err);
542 			goto contparse;
543 		}
544 
545 		/* Get the pointer to provider's C_GetFunctionList() */
546 		Tmp_C_GetFunctionList =
547 		    (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList");
548 
549 		/*
550 		 * If we failed to get the pointer to C_GetFunctionList(),
551 		 * skip this provider and continue to the next one.
552 		 */
553 		if (Tmp_C_GetFunctionList == NULL) {
554 			cryptoerror(LOG_ERR,
555 			    "libpkcs11: Could not dlsym() C_GetFunctionList() "
556 			    "for %s. May not be a PKCS#11 library. %s",
557 			    fullpath, conf_err);
558 			(void) dlclose(dldesc);
559 			goto contparse;
560 		}
561 
562 
563 		/* Get the provider's function list */
564 		prov_rv = Tmp_C_GetFunctionList(&prov_funcs);
565 
566 		/*
567 		 * If we failed to get the provider's function list,
568 		 * skip this provider and continue to the next one.
569 		 */
570 		if (prov_rv != CKR_OK) {
571 			cryptoerror(LOG_ERR,
572 			    "libpkcs11: Could not get function list for %s. "
573 			    "%s Error: %s.",
574 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
575 			(void) dlclose(dldesc);
576 			goto contparse;
577 		}
578 
579 		/* Initialize this provider */
580 		prov_rv = prov_funcs->C_Initialize(pInitArgs);
581 
582 		/*
583 		 * If we failed to initialize this provider,
584 		 * skip this provider and continue to the next one.
585 		 */
586 		if ((prov_rv != CKR_OK) &&
587 		    (prov_rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
588 			cryptoerror(LOG_ERR,
589 			    "libpkcs11: Could not initialize %s. "
590 			    "%s Error: %s.",
591 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
592 			(void) dlclose(dldesc);
593 			goto contparse;
594 		}
595 
596 		/*
597 		 * Make sure this provider is implementing the same
598 		 * major version, and at least the same minor version
599 		 * that we are.
600 		 */
601 		prov_rv = prov_funcs->C_GetInfo(&prov_info);
602 
603 		/*
604 		 * If we can't verify that we are implementing the
605 		 * same major version, or if it is definitely not the same
606 		 * version, we need to skip this provider.
607 		 */
608 		if ((prov_rv != CKR_OK) ||
609 		    (prov_info.cryptokiVersion.major !=
610 		    CRYPTOKI_VERSION_MAJOR))  {
611 			if (prov_rv != CKR_OK) {
612 				cryptoerror(LOG_ERR,
613 				    "libpkcs11: Could not verify version of "
614 				    "%s. %s Error: %s.", fullpath,
615 				    conf_err, pkcs11_strerror(prov_rv));
616 			} else {
617 				cryptoerror(LOG_ERR,
618 				    "libpkcs11: Only CRYPTOKI major version "
619 				    "%d is supported.  %s is major "
620 				    "version %d. %s",
621 				    CRYPTOKI_VERSION_MAJOR, fullpath,
622 				    prov_info.cryptokiVersion.major, conf_err);
623 			}
624 			(void) prov_funcs->C_Finalize(NULL);
625 			(void) dlclose(dldesc);
626 			goto contparse;
627 		}
628 
629 		/*
630 		 * Warn the administrator (at debug) that a provider with
631 		 * a significantly older or newer version of
632 		 * CRYPTOKI is being used.  It should not cause
633 		 * problems, but logging a warning makes it easier
634 		 * to debug later.
635 		 */
636 		if ((prov_info.cryptokiVersion.minor <
637 		    CRYPTOKI_VERSION_WARN_MINOR) ||
638 		    (prov_info.cryptokiVersion.minor >
639 		    CRYPTOKI_VERSION_MINOR)) {
640 			cryptoerror(LOG_DEBUG,
641 			    "libpkcs11: %s CRYPTOKI minor version, %d, may "
642 			    "not be compatible with minor version %d.",
643 			    fullpath, prov_info.cryptokiVersion.minor,
644 			    CRYPTOKI_VERSION_MINOR);
645 		}
646 
647 		/*
648 		 * Find out how many slots this provider has,
649 		 * call with tokenPresent set to FALSE so all
650 		 * potential slots are returned.
651 		 */
652 		prov_rv = prov_funcs->C_GetSlotList(FALSE,
653 		    NULL, &prov_slot_count);
654 
655 		/*
656 		 * If the call failed, or if no slots are returned,
657 		 * then skip this provider and continue to next one.
658 		 */
659 		if (prov_rv != CKR_OK) {
660 			cryptoerror(LOG_ERR,
661 			    "libpksc11: Could not get slot list from %s. "
662 			    "%s Error: %s.",
663 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
664 			(void) prov_funcs->C_Finalize(NULL);
665 			(void) dlclose(dldesc);
666 			goto contparse;
667 		}
668 
669 		if (prov_slot_count == 0) {
670 			cryptodebug("libpkcs11: No slots presented from %s. "
671 			    "Skipping this plug-in at this time.\n",
672 			    fullpath);
673 			(void) prov_funcs->C_Finalize(NULL);
674 			(void) dlclose(dldesc);
675 			goto contparse;
676 		}
677 
678 		/*
679 		 * Verify that the module is signed correctly.
680 		 *
681 		 * NOTE: there is a potential race condition here,
682 		 * since the module is verified well after we have
683 		 * opened the provider via dlopen().  This could be
684 		 * resolved by a variant of dlopen() that would take a
685 		 * file descriptor as an argument and by changing the
686 		 * kcfd libelfsign door protocol to use and fd instead
687 		 * of a path - but that wouldn't work in the kernel case.
688 		 */
689 		estatus = kcfd_door_call(fullpath, B_FALSE, &rv);
690 
691 		switch (estatus) {
692 		case ELFSIGN_UNKNOWN:
693 		case ELFSIGN_SUCCESS:
694 		case ELFSIGN_RESTRICTED:
695 			break;
696 		case ELFSIGN_NOTSIGNED:
697 			estatus_str = strdup("not a signed provider.");
698 			break;
699 		case ELFSIGN_FAILED:
700 			estatus_str = strdup("signature verification failed.");
701 			break;
702 		default:
703 			estatus_str = strdup("unexpected failure in ELF "
704 			    "signature verification. "
705 			    "System may have been tampered with.");
706 		}
707 		if (estatus_str != NULL) {
708 			cryptoerror(LOG_ERR, "libpkcs11: %s %s %s",
709 			    fullpath, estatus_str ? estatus_str : "",
710 			    estatus == ELFSIGN_UNKNOWN ?
711 			    "Cannot continue parsing " _PATH_PKCS11_CONF:
712 			    conf_err);
713 			(void) prov_funcs->C_Finalize(NULL);
714 			(void) dlclose(dldesc);
715 			free(estatus_str);
716 			estatus_str = NULL;
717 			if (estatus == ELFSIGN_UNKNOWN) {
718 				prov_funcs = NULL;
719 				dldesc = NULL;
720 				rv = CKR_GENERAL_ERROR;
721 				goto conferror;
722 			}
723 			goto contparse;
724 		}
725 
726 		/* Allocate memory for the slot list */
727 		prov_slots = calloc(prov_slot_count, sizeof (CK_SLOT_ID));
728 
729 		if (prov_slots == NULL) {
730 			cryptoerror(LOG_ERR,
731 			    "libpkcs11: Could not allocate memory for "
732 			    "plug-in slots. Cannot continue parsing %s\n",
733 			    _PATH_PKCS11_CONF);
734 			rv = CKR_HOST_MEMORY;
735 			goto conferror;
736 		}
737 
738 		/* Get slot list from provider */
739 		prov_rv = prov_funcs->C_GetSlotList(FALSE,
740 		    prov_slots, &prov_slot_count);
741 
742 		/* if second call fails, drop this provider */
743 		if (prov_rv != CKR_OK) {
744 			cryptoerror(LOG_ERR,
745 			    "libpkcs11: Second call to C_GetSlotList() for %s "
746 			    "failed. %s Error: %s.",
747 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
748 			(void) prov_funcs->C_Finalize(NULL);
749 			(void) dlclose(dldesc);
750 			goto contparse;
751 		}
752 
753 		/*
754 		 * Parse the list of disabled or enabled mechanisms, will
755 		 * apply to each of the provider's slots.
756 		 */
757 		if (phead->puent->count > 0) {
758 			rv = pkcs11_mech_parse(phead->puent->policylist,
759 			    &prov_pol_mechs, phead->puent->count);
760 
761 			if (rv == CKR_HOST_MEMORY) {
762 				cryptoerror(LOG_ERR,
763 				    "libpkcs11: Could not parse configuration,"
764 				    "out of memory. Cannot continue parsing "
765 				    "%s.", _PATH_PKCS11_CONF);
766 				goto conferror;
767 			} else if (rv == CKR_MECHANISM_INVALID) {
768 				/*
769 				 * Configuration file is corrupted for this
770 				 * provider.
771 				 */
772 				cryptoerror(LOG_ERR,
773 				    "libpkcs11: Policy invalid or corrupted "
774 				    "for %s. Use cryptoadm(1M) to fix "
775 				    "this. Skipping this plug-in.",
776 				    fullpath);
777 				(void) prov_funcs->C_Finalize(NULL);
778 				(void) dlclose(dldesc);
779 				goto contparse;
780 			}
781 		}
782 
783 		/* Allocate memory in our slottable for these slots */
784 		rv = pkcs11_slottable_increase(prov_slot_count);
785 
786 		/*
787 		 * If any error is returned, it will be memory related,
788 		 * so we need to abort the attempt at filling the
789 		 * slottable.
790 		 */
791 		if (rv != CKR_OK) {
792 			cryptoerror(LOG_ERR,
793 			    "libpkcs11: slottable could not increase. "
794 			    "Cannot continue parsing %s.",
795 			    _PATH_PKCS11_CONF);
796 			goto conferror;
797 		}
798 
799 		/* Configure information for each new slot */
800 		for (i = 0; i < prov_slot_count; i++) {
801 			/* allocate slot in framework */
802 			rv = pkcs11_slot_allocate(&slot_id);
803 			if (rv != CKR_OK) {
804 				cryptoerror(LOG_ERR,
805 				    "libpkcs11: Could not allocate "
806 				    "new slot.  Cannot continue parsing %s.",
807 				    _PATH_PKCS11_CONF);
808 				goto conferror;
809 			}
810 			slot_count++;
811 			cur_slot = slottable->st_slots[slot_id];
812 			(void) pthread_mutex_lock(&cur_slot->sl_mutex);
813 			cur_slot->sl_id = prov_slots[i];
814 			cur_slot->sl_func_list = prov_funcs;
815 			cur_slot->sl_enabledpol =
816 			    phead->puent->flag_enabledlist;
817 			cur_slot->sl_pol_mechs = prov_pol_mechs;
818 			cur_slot->sl_pol_count = phead->puent->count;
819 			cur_slot->sl_norandom = phead->puent->flag_norandom;
820 			cur_slot->sl_dldesc = dldesc;
821 			cur_slot->sl_prov_id = prov_count + 1;
822 			(void) pthread_mutex_unlock(&cur_slot->sl_mutex);
823 		}
824 
825 		/*
826 		 * Get the pointer to private interface _SUNW_GetThreshold()
827 		 * in pkcs11_kernel.
828 		 */
829 
830 		if (Tmp_GetThreshold == NULL) {
831 			Tmp_GetThreshold =
832 			    (void(*)())dlsym(dldesc, "_SUNW_GetThreshold");
833 
834 			/* Get the threshold values for the supported mechs */
835 			if (Tmp_GetThreshold != NULL) {
836 				(void) memset(meta_mechs_threshold, 0,
837 				    sizeof (meta_mechs_threshold));
838 				Tmp_GetThreshold(meta_mechs_threshold);
839 			}
840 		}
841 
842 		/* Set and reset values to process next provider */
843 		prov_count++;
844 contparse:
845 		prov_slot_count = 0;
846 		Tmp_C_GetFunctionList = NULL;
847 		prov_funcs = NULL;
848 		dldesc = NULL;
849 		if (fullpath != NULL) {
850 			free(fullpath);
851 			fullpath = NULL;
852 		}
853 		if (prov_slots != NULL) {
854 			free(prov_slots);
855 			prov_slots = NULL;
856 		}
857 		phead = phead->next;
858 	}
859 
860 	if (slot_count == 0) {
861 		/*
862 		 * there's no other slot in the framework,
863 		 * there is nothing to do
864 		 */
865 		goto config_complete;
866 	}
867 
868 	/* determine if metaslot should be enabled */
869 
870 	/*
871 	 * Check to see if any environment variable is defined
872 	 * by the user for configuring metaslot.  Users'
873 	 * setting always take precedence over the system wide
874 	 * setting.  So, we will first check for any user's
875 	 * defined env variables before looking at the system-wide
876 	 * configuration.
877 	 */
878 	get_user_metaslot_config();
879 
880 	/* no metaslot entry in /etc/crypto/pkcs11.conf */
881 	if (!metaslot_entry) {
882 		/*
883 		 * If user env variable indicates metaslot should be enabled,
884 		 * but there's no entry in /etc/crypto/pkcs11.conf for
885 		 * metaslot at all, will respect the user's defined value
886 		 */
887 		if ((metaslot_config.enabled_specified) &&
888 		    (metaslot_config.enabled)) {
889 			metaslot_enabled = B_TRUE;
890 		}
891 	} else {
892 		if (!metaslot_config.enabled_specified) {
893 			/*
894 			 * take system wide value if
895 			 * it is not specified by user
896 			 */
897 			metaslot_enabled
898 			    = metaslot_entry->flag_metaslot_enabled;
899 		} else {
900 			metaslot_enabled = metaslot_config.enabled;
901 		}
902 	}
903 
904 	/*
905 	 *
906 	 * As long as the user or system configuration file does not
907 	 * disable metaslot, it will be enabled regardless of the
908 	 * number of slots plugged into the framework.  Therefore,
909 	 * metaslot is enabled even when there's only one slot
910 	 * plugged into the framework.  This is necessary for
911 	 * presenting a consistent token label view to applications.
912 	 *
913 	 * However, for the case where there is only 1 slot plugged into
914 	 * the framework, we can use "fastpath".
915 	 *
916 	 * "fastpath" will pass all of the application's requests
917 	 * directly to the underlying provider.  Only when policy is in
918 	 * effect will we need to keep slotID around.
919 	 *
920 	 * When metaslot is enabled, and fastpath is enabled,
921 	 * all the metaslot processing will be skipped.
922 	 * When there is only 1 slot, there's
923 	 * really not much metaslot can do in terms of combining functionality
924 	 * of different slots, and object migration.
925 	 *
926 	 */
927 
928 	/* check to see if fastpath can be used */
929 	if (slottable->st_last == slottable->st_first) {
930 
931 		cur_slot = slottable->st_slots[slottable->st_first];
932 
933 		(void) pthread_mutex_lock(&cur_slot->sl_mutex);
934 
935 		if ((cur_slot->sl_pol_count == 0) &&
936 		    (!cur_slot->sl_enabledpol) && (!cur_slot->sl_norandom)) {
937 			/* No policy is in effect, don't need slotid */
938 			fast_funcs = cur_slot->sl_func_list;
939 			purefastpath = B_TRUE;
940 		} else {
941 			fast_funcs = cur_slot->sl_func_list;
942 			fast_slot = slottable->st_first;
943 			policyfastpath = B_TRUE;
944 		}
945 
946 		(void) pthread_mutex_unlock(&cur_slot->sl_mutex);
947 	}
948 
949 	if ((purefastpath || policyfastpath) && (!metaslot_enabled)) {
950 		goto config_complete;
951 	}
952 
953 	/*
954 	 * If we get here, there are more than 2 slots in the framework,
955 	 * we need to set up metaslot if it is enabled
956 	 */
957 	if (metaslot_enabled) {
958 		rv = setup_metaslot(metaslot_entry);
959 		if (rv != CKR_OK) {
960 			goto conferror;
961 		}
962 	}
963 
964 
965 config_complete:
966 
967 	return (CKR_OK);
968 
969 conferror:
970 	/*
971 	 * This cleanup code is only exercised when a major,
972 	 * unrecoverable error like "out of memory" occurs.
973 	 */
974 	if (prov_funcs != NULL) {
975 		(void) prov_funcs->C_Finalize(NULL);
976 	}
977 	if (dldesc != NULL) {
978 		(void) dlclose(dldesc);
979 	}
980 	if (fullpath != NULL) {
981 		free(fullpath);
982 		fullpath = NULL;
983 	}
984 	if (prov_slots != NULL) {
985 		free(prov_slots);
986 		prov_slots = NULL;
987 	}
988 
989 	return (rv);
990 }
991 
992 /*
993  * pkcs11_mech_parse will take hex mechanism ids, as a list of
994  * strings, and convert them to CK_MECHANISM_TYPE_PTR.
995  */
996 CK_RV
997 pkcs11_mech_parse(umechlist_t *str_list, CK_MECHANISM_TYPE_PTR *mech_list,
998     int mech_count)
999 {
1000 	CK_MECHANISM_TYPE_PTR tmp_list;
1001 	umechlist_t *shead = str_list;
1002 
1003 	tmp_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE));
1004 
1005 	if (tmp_list == NULL) {
1006 		cryptoerror(LOG_ERR, "libpkcs11: parsing %s, out of memory. "
1007 		    "Cannot continue.",
1008 		    _PATH_PKCS11_CONF);
1009 		return (CKR_HOST_MEMORY);
1010 	}
1011 
1012 	*mech_list = tmp_list;
1013 
1014 	/*
1015 	 * The following will loop mech_count times, as there are
1016 	 * exactly mech_count items in the str_list.
1017 	 */
1018 	while (shead != NULL) {
1019 		CK_MECHANISM_TYPE cur_mech;
1020 
1021 		errno = 0;
1022 
1023 		/*
1024 		 * "name" is a hexadecimal number, preceded by 0x.
1025 		 */
1026 		cur_mech = strtoul(shead->name, NULL, 16);
1027 
1028 		if ((cur_mech == 0) &&
1029 		    ((errno == EINVAL) || (errno == ERANGE))) {
1030 			free(mech_list);
1031 			return (CKR_MECHANISM_INVALID);
1032 		}
1033 		*tmp_list = (CK_MECHANISM_TYPE)cur_mech;
1034 		tmp_list++;
1035 		shead = shead->next;
1036 	}
1037 
1038 	return (CKR_OK);
1039 }
1040 
1041 /*
1042  * pkcs11_is_dismech is provided a slotid and a mechanism.
1043  * If mech is not disabled, then return B_FALSE.
1044  */
1045 boolean_t
1046 pkcs11_is_dismech(CK_SLOT_ID slotid, CK_MECHANISM_TYPE mech)
1047 {
1048 	ulong_t i;
1049 	boolean_t enabled_pol;
1050 	CK_MECHANISM_TYPE_PTR pol_mechs;
1051 	ulong_t pol_count;
1052 
1053 	/* Find the associated slot and get the mech policy info */
1054 	(void) pthread_mutex_lock(&slottable->st_slots[slotid]->sl_mutex);
1055 	enabled_pol = slottable->st_slots[slotid]->sl_enabledpol;
1056 	pol_mechs = slottable->st_slots[slotid]->sl_pol_mechs;
1057 	pol_count = slottable->st_slots[slotid]->sl_pol_count;
1058 	(void) pthread_mutex_unlock(&slottable->st_slots[slotid]->sl_mutex);
1059 
1060 	/* Check for policy */
1061 	if ((!enabled_pol) && (pol_mechs == NULL)) {
1062 		/* no policy */
1063 		return (B_FALSE);
1064 	} else if (pol_mechs == NULL) {
1065 		/*
1066 		 * We have an empty enabled list, which means no
1067 		 * mechanisms are exempted from this policy: all
1068 		 * are disabled.
1069 		 */
1070 		return (B_TRUE);
1071 	}
1072 
1073 	for (i = 0; i < pol_count; i++) {
1074 		/*
1075 		 * If it matches, return status based on this
1076 		 * being and enabled or a disabled list of mechs.
1077 		 */
1078 		if (pol_mechs[i] == mech) {
1079 			return (enabled_pol ? B_FALSE : B_TRUE);
1080 		}
1081 	}
1082 
1083 	/* mech was not found in list */
1084 	return (enabled_pol ? B_TRUE : B_FALSE);
1085 }
1086