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