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