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