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 		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_UNKNOWN:
702 		case ELFSIGN_SUCCESS:
703 		case ELFSIGN_RESTRICTED:
704 			break;
705 		case ELFSIGN_NOTSIGNED:
706 			estatus_str = strdup("not a signed provider.");
707 			break;
708 		case ELFSIGN_FAILED:
709 			estatus_str = strdup("signature verification failed.");
710 			break;
711 		default:
712 			estatus_str = strdup("unexpected failure in ELF "
713 			    "signature verification. "
714 			    "System may have been tampered with.");
715 		}
716 		if (estatus_str != NULL) {
717 			cryptoerror(LOG_ERR, "libpkcs11: %s %s %s",
718 			    fullpath, estatus_str ? estatus_str : "",
719 			    estatus == ELFSIGN_UNKNOWN ?
720 			    "Cannot continue parsing " _PATH_PKCS11_CONF:
721 			    conf_err);
722 			(void) prov_funcs->C_Finalize(NULL);
723 			(void) dlclose(dldesc);
724 			free(estatus_str);
725 			estatus_str = NULL;
726 			if (estatus == ELFSIGN_UNKNOWN) {
727 				prov_funcs = NULL;
728 				dldesc = NULL;
729 				rv = CKR_GENERAL_ERROR;
730 				goto conferror;
731 			}
732 			goto contparse;
733 		}
734 
735 		/* Allocate memory for the slot list */
736 		prov_slots = calloc(prov_slot_count, sizeof (CK_SLOT_ID));
737 
738 		if (prov_slots == NULL) {
739 			cryptoerror(LOG_ERR,
740 			    "libpkcs11: Could not allocate memory for "
741 			    "plug-in slots. Cannot continue parsing %s\n",
742 			    _PATH_PKCS11_CONF);
743 			rv = CKR_HOST_MEMORY;
744 			goto conferror;
745 		}
746 
747 		/* Get slot list from provider */
748 		prov_rv = prov_funcs->C_GetSlotList(FALSE,
749 		    prov_slots, &prov_slot_count);
750 
751 		/* if second call fails, drop this provider */
752 		if (prov_rv != CKR_OK) {
753 			cryptoerror(LOG_ERR,
754 			    "libpkcs11: Second call to C_GetSlotList() for %s "
755 			    "failed. %s Error: %s.",
756 			    fullpath, conf_err, pkcs11_strerror(prov_rv));
757 			(void) prov_funcs->C_Finalize(NULL);
758 			(void) dlclose(dldesc);
759 			goto contparse;
760 		}
761 
762 		/*
763 		 * Parse the list of disabled or enabled mechanisms, will
764 		 * apply to each of the provider's slots.
765 		 */
766 		if (phead->puent->count > 0) {
767 			rv = pkcs11_mech_parse(phead->puent->policylist,
768 			    &prov_pol_mechs, phead->puent->count);
769 
770 			if (rv == CKR_HOST_MEMORY) {
771 				cryptoerror(LOG_ERR,
772 				    "libpkcs11: Could not parse configuration,"
773 				    "out of memory. Cannot continue parsing "
774 				    "%s.", _PATH_PKCS11_CONF);
775 				goto conferror;
776 			} else if (rv == CKR_MECHANISM_INVALID) {
777 				/*
778 				 * Configuration file is corrupted for this
779 				 * provider.
780 				 */
781 				cryptoerror(LOG_ERR,
782 				    "libpkcs11: Policy invalid or corrupted "
783 				    "for %s. Use cryptoadm(1M) to fix "
784 				    "this. Skipping this plug-in.",
785 				    fullpath);
786 				(void) prov_funcs->C_Finalize(NULL);
787 				(void) dlclose(dldesc);
788 				goto contparse;
789 			}
790 		}
791 
792 		/* Allocate memory in our slottable for these slots */
793 		rv = pkcs11_slottable_increase(prov_slot_count);
794 
795 		/*
796 		 * If any error is returned, it will be memory related,
797 		 * so we need to abort the attempt at filling the
798 		 * slottable.
799 		 */
800 		if (rv != CKR_OK) {
801 			cryptoerror(LOG_ERR,
802 			    "libpkcs11: slottable could not increase. "
803 			    "Cannot continue parsing %s.",
804 			    _PATH_PKCS11_CONF);
805 			goto conferror;
806 		}
807 
808 		/* Configure information for each new slot */
809 		for (i = 0; i < prov_slot_count; i++) {
810 			/* allocate slot in framework */
811 			rv = pkcs11_slot_allocate(&slot_id);
812 			if (rv != CKR_OK) {
813 				cryptoerror(LOG_ERR,
814 				    "libpkcs11: Could not allocate "
815 				    "new slot.  Cannot continue parsing %s.",
816 				    _PATH_PKCS11_CONF);
817 				goto conferror;
818 			}
819 			slot_count++;
820 			cur_slot = slottable->st_slots[slot_id];
821 			(void) pthread_mutex_lock(&cur_slot->sl_mutex);
822 			cur_slot->sl_id = prov_slots[i];
823 			cur_slot->sl_func_list = prov_funcs;
824 			cur_slot->sl_enabledpol =
825 			    phead->puent->flag_enabledlist;
826 			cur_slot->sl_pol_mechs = prov_pol_mechs;
827 			cur_slot->sl_pol_count = phead->puent->count;
828 			cur_slot->sl_norandom = phead->puent->flag_norandom;
829 			cur_slot->sl_dldesc = dldesc;
830 			cur_slot->sl_prov_id = prov_count + 1;
831 			(void) pthread_mutex_unlock(&cur_slot->sl_mutex);
832 		}
833 
834 		/*
835 		 * Get the pointer to private interface _SUNW_GetThreshold()
836 		 * in pkcs11_kernel.
837 		 */
838 
839 		if (Tmp_GetThreshold == NULL) {
840 			Tmp_GetThreshold =
841 			    (void(*)())dlsym(dldesc, "_SUNW_GetThreshold");
842 
843 			/* Get the threshold values for the supported mechs */
844 			if (Tmp_GetThreshold != NULL) {
845 				(void) memset(meta_mechs_threshold, 0,
846 				    sizeof (meta_mechs_threshold));
847 				Tmp_GetThreshold(meta_mechs_threshold);
848 			}
849 		}
850 
851 		/* Set and reset values to process next provider */
852 		prov_count++;
853 contparse:
854 		prov_slot_count = 0;
855 		Tmp_C_GetFunctionList = NULL;
856 		prov_funcs = NULL;
857 		dldesc = NULL;
858 		if (fullpath != NULL) {
859 			free(fullpath);
860 			fullpath = NULL;
861 		}
862 		if (prov_slots != NULL) {
863 			free(prov_slots);
864 			prov_slots = NULL;
865 		}
866 		phead = phead->next;
867 	}
868 
869 	if (slot_count == 0) {
870 		/*
871 		 * there's no other slot in the framework,
872 		 * there is nothing to do
873 		 */
874 		goto config_complete;
875 	}
876 
877 	/* determine if metaslot should be enabled */
878 
879 	/*
880 	 * Check to see if any environment variable is defined
881 	 * by the user for configuring metaslot.  Users'
882 	 * setting always take precedence over the system wide
883 	 * setting.  So, we will first check for any user's
884 	 * defined env variables before looking at the system-wide
885 	 * configuration.
886 	 */
887 	get_user_metaslot_config();
888 
889 	/* no metaslot entry in /etc/crypto/pkcs11.conf */
890 	if (!metaslot_entry) {
891 		/*
892 		 * If user env variable indicates metaslot should be enabled,
893 		 * but there's no entry in /etc/crypto/pkcs11.conf for
894 		 * metaslot at all, will respect the user's defined value
895 		 */
896 		if ((metaslot_config.enabled_specified) &&
897 		    (metaslot_config.enabled)) {
898 			metaslot_enabled = B_TRUE;
899 		}
900 	} else {
901 		if (!metaslot_config.enabled_specified) {
902 			/*
903 			 * take system wide value if
904 			 * it is not specified by user
905 			 */
906 			metaslot_enabled
907 			    = metaslot_entry->flag_metaslot_enabled;
908 		} else {
909 			metaslot_enabled = metaslot_config.enabled;
910 		}
911 	}
912 
913 	/*
914 	 *
915 	 * As long as the user or system configuration file does not
916 	 * disable metaslot, it will be enabled regardless of the
917 	 * number of slots plugged into the framework.  Therefore,
918 	 * metaslot is enabled even when there's only one slot
919 	 * plugged into the framework.  This is necessary for
920 	 * presenting a consistent token label view to applications.
921 	 *
922 	 * However, for the case where there is only 1 slot plugged into
923 	 * the framework, we can use "fastpath".
924 	 *
925 	 * "fastpath" will pass all of the application's requests
926 	 * directly to the underlying provider.  Only when policy is in
927 	 * effect will we need to keep slotID around.
928 	 *
929 	 * When metaslot is enabled, and fastpath is enabled,
930 	 * all the metaslot processing will be skipped.
931 	 * When there is only 1 slot, there's
932 	 * really not much metaslot can do in terms of combining functionality
933 	 * of different slots, and object migration.
934 	 *
935 	 */
936 
937 	/* check to see if fastpath can be used */
938 	if (slottable->st_last == slottable->st_first) {
939 
940 		cur_slot = slottable->st_slots[slottable->st_first];
941 
942 		(void) pthread_mutex_lock(&cur_slot->sl_mutex);
943 
944 		if ((cur_slot->sl_pol_count == 0) &&
945 		    (!cur_slot->sl_enabledpol) && (!cur_slot->sl_norandom)) {
946 			/* No policy is in effect, don't need slotid */
947 			fast_funcs = cur_slot->sl_func_list;
948 			purefastpath = B_TRUE;
949 		} else {
950 			fast_funcs = cur_slot->sl_func_list;
951 			fast_slot = slottable->st_first;
952 			policyfastpath = B_TRUE;
953 		}
954 
955 		(void) pthread_mutex_unlock(&cur_slot->sl_mutex);
956 	}
957 
958 	if ((purefastpath || policyfastpath) && (!metaslot_enabled)) {
959 		goto config_complete;
960 	}
961 
962 	/*
963 	 * If we get here, there are more than 2 slots in the framework,
964 	 * we need to set up metaslot if it is enabled
965 	 */
966 	if (metaslot_enabled) {
967 		rv = setup_metaslot(metaslot_entry);
968 		if (rv != CKR_OK) {
969 			goto conferror;
970 		}
971 	}
972 
973 
974 config_complete:
975 
976 	return (CKR_OK);
977 
978 conferror:
979 	/*
980 	 * This cleanup code is only exercised when a major,
981 	 * unrecoverable error like "out of memory" occurs.
982 	 */
983 	if (prov_funcs != NULL) {
984 		(void) prov_funcs->C_Finalize(NULL);
985 	}
986 	if (dldesc != NULL) {
987 		(void) dlclose(dldesc);
988 	}
989 	if (fullpath != NULL) {
990 		free(fullpath);
991 		fullpath = NULL;
992 	}
993 	if (prov_slots != NULL) {
994 		free(prov_slots);
995 		prov_slots = NULL;
996 	}
997 
998 	return (rv);
999 }
1000 
1001 /*
1002  * pkcs11_mech_parse will take hex mechanism ids, as a list of
1003  * strings, and convert them to CK_MECHANISM_TYPE_PTR.
1004  */
1005 CK_RV
1006 pkcs11_mech_parse(umechlist_t *str_list, CK_MECHANISM_TYPE_PTR *mech_list,
1007     int mech_count)
1008 {
1009 	CK_MECHANISM_TYPE_PTR tmp_list;
1010 	umechlist_t *shead = str_list;
1011 
1012 	tmp_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE));
1013 
1014 	if (tmp_list == NULL) {
1015 		cryptoerror(LOG_ERR, "libpkcs11: parsing %s, out of memory. "
1016 		    "Cannot continue.",
1017 		    _PATH_PKCS11_CONF);
1018 		return (CKR_HOST_MEMORY);
1019 	}
1020 
1021 	*mech_list = tmp_list;
1022 
1023 	/*
1024 	 * The following will loop mech_count times, as there are
1025 	 * exactly mech_count items in the str_list.
1026 	 */
1027 	while (shead != NULL) {
1028 		CK_MECHANISM_TYPE cur_mech;
1029 
1030 		errno = 0;
1031 
1032 		/*
1033 		 * "name" is a hexadecimal number, preceded by 0x.
1034 		 */
1035 		cur_mech = strtoul(shead->name, NULL, 16);
1036 
1037 		if ((cur_mech == 0) &&
1038 		    ((errno == EINVAL) || (errno == ERANGE))) {
1039 			free(mech_list);
1040 			return (CKR_MECHANISM_INVALID);
1041 		}
1042 		*tmp_list = (CK_MECHANISM_TYPE)cur_mech;
1043 		tmp_list++;
1044 		shead = shead->next;
1045 	}
1046 
1047 	return (CKR_OK);
1048 }
1049 
1050 /*
1051  * pkcs11_is_dismech is provided a slotid and a mechanism.
1052  * If mech is not disabled, then return B_FALSE.
1053  */
1054 boolean_t
1055 pkcs11_is_dismech(CK_SLOT_ID slotid, CK_MECHANISM_TYPE mech)
1056 {
1057 	ulong_t i;
1058 	boolean_t enabled_pol;
1059 	CK_MECHANISM_TYPE_PTR pol_mechs;
1060 	ulong_t pol_count;
1061 
1062 	/* Find the associated slot and get the mech policy info */
1063 	(void) pthread_mutex_lock(&slottable->st_slots[slotid]->sl_mutex);
1064 	enabled_pol = slottable->st_slots[slotid]->sl_enabledpol;
1065 	pol_mechs = slottable->st_slots[slotid]->sl_pol_mechs;
1066 	pol_count = slottable->st_slots[slotid]->sl_pol_count;
1067 	(void) pthread_mutex_unlock(&slottable->st_slots[slotid]->sl_mutex);
1068 
1069 	/* Check for policy */
1070 	if ((!enabled_pol) && (pol_mechs == NULL)) {
1071 		/* no policy */
1072 		return (B_FALSE);
1073 	} else if (pol_mechs == NULL) {
1074 		/*
1075 		 * We have an empty enabled list, which means no
1076 		 * mechanisms are exempted from this policy: all
1077 		 * are disabled.
1078 		 */
1079 		return (B_TRUE);
1080 	}
1081 
1082 	for (i = 0; i < pol_count; i++) {
1083 		/*
1084 		 * If it matches, return status based on this
1085 		 * being and enabled or a disabled list of mechs.
1086 		 */
1087 		if (pol_mechs[i] == mech) {
1088 			return (enabled_pol ? B_FALSE : B_TRUE);
1089 		}
1090 	}
1091 
1092 	/* mech was not found in list */
1093 	return (enabled_pol ? B_TRUE : B_FALSE);
1094 }
1095