dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / pkcs11 / libpkcs11 / common / pkcs11Conf.c
blobdd66f6b808d6fc526d3a7f612247260ad2f570f5
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright 2010 Nexenta Systems, Inc. All rights reserved.
28 #include <sys/types.h>
29 #include <sys/stat.h>
30 #include <dlfcn.h>
31 #include <fcntl.h>
32 #include <link.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <strings.h>
36 #include <errno.h>
37 #include <pthread.h>
38 #include <sys/mman.h>
40 #include <sys/crypto/elfsign.h>
41 #include <cryptoutil.h>
43 #include <security/cryptoki.h>
44 #include "pkcs11Global.h"
45 #include "pkcs11Conf.h"
46 #include "pkcs11Slot.h"
47 #include "metaGlobal.h"
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.
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];
67 static const char *conf_err = "See cryptoadm(1M). Skipping this plug-in.";
70 * Set up metaslot for the framework using either user configuration
71 * or system wide configuration options
73 * Also sets up the global "slottable" to have the first slot be metaslot.
75 static CK_RV
76 setup_metaslot(uentry_t *metaslot_entry) {
77 CK_RV rv;
78 CK_MECHANISM_TYPE_PTR prov_pol_mechs = NULL;
79 pkcs11_slot_t *cur_slot;
81 /* process policies for mechanisms */
82 if ((metaslot_entry) && (metaslot_entry->count > 0)) {
83 rv = pkcs11_mech_parse(metaslot_entry->policylist,
84 &prov_pol_mechs, metaslot_entry->count);
86 if (rv == CKR_HOST_MEMORY) {
87 cryptoerror(LOG_ERR,
88 "libpkcs11: Could not parse configuration,"
89 "out of memory. Cannot continue parsing "
90 "%s.\n", _PATH_PKCS11_CONF);
91 return (rv);
92 } else if (rv == CKR_MECHANISM_INVALID) {
94 * Configuration file is corrupted for metaslot
96 cryptoerror(LOG_ERR,
97 "libpkcs11: Policy invalid or corrupted "
98 "for metaslot. Use cryptoadm(1M) to fix "
99 "this. Disabling metaslot functionality.\n");
100 metaslot_enabled = B_FALSE;
101 return (rv);
106 * Check for metaslot policy. If all mechanisms are
107 * disabled, disable metaslot since there is nothing
108 * interesting for it to do
110 if ((metaslot_entry) && (metaslot_entry->flag_enabledlist) &&
111 (prov_pol_mechs == NULL)) {
112 metaslot_enabled = B_FALSE;
113 return (rv);
117 * save system wide value for metaslot's keystore.
118 * If either slot description or token label is specified by
119 * the user, the system wide value for both is ignored.
121 if ((metaslot_entry) &&
122 (!metaslot_config.keystore_token_specified) &&
123 (!metaslot_config.keystore_slot_specified)) {
125 * blank_str is used for comparing with token label,
126 * and slot description, make sure it is better than
127 * the larger of both
129 char blank_str[TOKEN_LABEL_SIZE + SLOT_DESCRIPTION_SIZE];
131 bzero(blank_str, sizeof (blank_str));
133 if (memcmp(metaslot_entry->metaslot_ks_token,
134 blank_str, TOKEN_LABEL_SIZE) != 0) {
135 metaslot_config.keystore_token_specified = B_TRUE;
136 (void) strlcpy(
137 (char *)metaslot_config.keystore_token,
138 (const char *)metaslot_entry->metaslot_ks_token,
139 TOKEN_LABEL_SIZE);
142 if (memcmp(metaslot_entry->metaslot_ks_slot,
143 blank_str, SLOT_DESCRIPTION_SIZE) != 0) {
144 metaslot_config.keystore_slot_specified = B_TRUE;
145 (void) strlcpy(
146 (char *)metaslot_config.keystore_slot,
147 (const char *)metaslot_entry->metaslot_ks_slot,
148 SLOT_DESCRIPTION_SIZE);
152 /* check system-wide value for auto_key_migrate */
153 if (metaslot_config.auto_key_migrate_specified) {
154 /* take user's specified value */
155 metaslot_auto_key_migrate = metaslot_config.auto_key_migrate;
156 } else {
157 if (metaslot_entry) {
158 /* use system-wide default */
159 metaslot_auto_key_migrate =
160 metaslot_entry->flag_metaslot_auto_key_migrate;
161 } else {
163 * there's no system wide metaslot entry,
164 * default auto_key_migrate to true
166 metaslot_auto_key_migrate = B_TRUE;
171 /* Make first slotID be 0, for metaslot. */
172 slottable->st_first = 0;
174 /* Set up the slottable entry for metaslot */
175 slottable->st_slots[0] = NULL;
176 cur_slot = calloc(1, sizeof (pkcs11_slot_t));
177 if (cur_slot == NULL) {
178 rv = CKR_HOST_MEMORY;
179 return (rv);
181 cur_slot->sl_wfse_state = WFSE_CLEAR;
182 cur_slot->sl_enabledpol = B_FALSE;
183 cur_slot->sl_no_wfse = B_FALSE;
184 (void) pthread_mutex_init(&cur_slot->sl_mutex, NULL);
187 * The metaslot entry was prealloc'd by
188 * pkcs11_slottable_increase()
190 (void) pthread_mutex_lock(&slottable->st_mutex);
191 slottable->st_slots[0] = cur_slot;
192 (void) pthread_mutex_unlock(&slottable->st_mutex);
194 (void) pthread_mutex_lock(&cur_slot->sl_mutex);
195 cur_slot->sl_id = METASLOT_SLOTID;
196 cur_slot->sl_func_list = &metaslot_functionList;
197 if (metaslot_entry) {
198 cur_slot->sl_enabledpol = metaslot_entry->flag_enabledlist;
199 cur_slot->sl_pol_count = metaslot_entry->count;
200 } else {
201 /* if no metaslot entry, assume all mechs are enabled */
202 cur_slot->sl_enabledpol = B_FALSE;
203 cur_slot->sl_pol_count = 0;
205 cur_slot->sl_pol_mechs = prov_pol_mechs;
206 cur_slot->sl_dldesc = NULL; /* not applicable */
207 cur_slot->sl_prov_id = 0;
208 (void) pthread_mutex_unlock(&cur_slot->sl_mutex);
210 /* Call the meta_Initialize() to initialize metaslot */
211 rv = meta_Initialize(NULL);
212 if (rv != CKR_OK) {
213 cryptoerror(LOG_ERR,
214 "libpkcs11: Can't initialize metaslot (%s)",
215 pkcs11_strerror(rv));
216 goto cleanup;
219 return (CKR_OK);
221 cleanup:
222 metaslot_enabled = B_FALSE;
223 slottable->st_slots[0] = NULL;
225 if (cur_slot) {
226 (void) pthread_mutex_destroy(&cur_slot->sl_mutex);
227 free(cur_slot);
229 return (rv);
233 * For each provider found in pkcs11.conf: expand $ISA if necessary,
234 * verify the module is signed, load the provider, find all of its
235 * slots, and store the function list and disabled policy.
237 * This function requires that the uentrylist_t and pkcs11_slottable_t
238 * already have memory allocated, and that the uentrylist_t is already
239 * populated with provider and policy information.
241 * pInitArgs can be set to NULL, but is normally the same value
242 * the framework's C_Initialize() was called with.
244 * Unless metaslot is explicitly disabled, it is setup when all other
245 * providers are loaded.
247 CK_RV
248 pkcs11_slot_mapping(uentrylist_t *pplist, CK_VOID_PTR pInitArgs)
250 CK_RV rv = CKR_OK;
251 CK_RV prov_rv; /* Provider's return code */
252 CK_INFO prov_info;
253 CK_RV (*Tmp_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR);
254 CK_FUNCTION_LIST_PTR prov_funcs = NULL; /* Provider's function list */
255 CK_ULONG prov_slot_count; /* Number of slots */
256 CK_SLOT_ID slot_id; /* slotID assigned for framework */
257 CK_SLOT_ID_PTR prov_slots = NULL; /* Provider's slot list */
258 /* Enabled or Disabled policy */
259 CK_MECHANISM_TYPE_PTR prov_pol_mechs = NULL;
261 void *dldesc = NULL;
262 char *isa, *fullpath = NULL, *dl_error;
263 uentrylist_t *phead;
264 uint_t prov_count = 0;
265 pkcs11_slot_t *cur_slot;
266 CK_ULONG i;
267 size_t len;
268 uentry_t *metaslot_entry = NULL;
269 /* number of slots in the framework, not including metaslot */
270 uint_t slot_count = 0;
272 phead = pplist;
274 /* Loop through all of the provider listed in pkcs11.conf */
275 while (phead != NULL) {
276 if (!strcasecmp(phead->puent->name, "metaslot")) {
278 * Skip standard processing for metaslot
279 * entry since it is not an actual library
280 * that can be dlopened.
281 * It will be initialized later.
283 if (metaslot_entry != NULL) {
284 cryptoerror(LOG_ERR,
285 "libpkcs11: multiple entries for metaslot "
286 "detected. All but the first entry will "
287 "be ignored");
288 } else {
289 metaslot_entry = phead->puent;
291 goto contparse;
294 if (!strcasecmp(phead->puent->name, FIPS_KEYWORD)) {
296 * Skip standard processing for fips-140
297 * entry since it is not an actual library
298 * that can be dlopened.
300 goto contparse;
303 /* Check for Instruction Set Architecture indicator */
304 if ((isa = strstr(phead->puent->name, PKCS11_ISA)) != NULL) {
305 /* Substitute the architecture dependent path */
306 len = strlen(phead->puent->name) -
307 strlen(PKCS11_ISA) +
308 strlen(PKCS11_ISA_DIR) + 1;
309 if ((fullpath = (char *)malloc(len)) == NULL) {
310 cryptoerror(LOG_ERR,
311 "libpksc11: parsing %s, out of memory. "
312 "Cannot continue parsing.",
313 _PATH_PKCS11_CONF);
314 rv = CKR_HOST_MEMORY;
315 goto conferror;
317 *isa = '\000';
318 isa += strlen(PKCS11_ISA);
319 (void) snprintf(fullpath, len, "%s%s%s",
320 phead->puent->name, PKCS11_ISA_DIR, isa);
321 } else if ((fullpath = strdup(phead->puent->name)) == 0) {
322 cryptoerror(LOG_ERR,
323 "libpkcs11: parsing %s, out of memory. "
324 "Cannot continue parsing.",
325 _PATH_PKCS11_CONF);
326 rv = CKR_HOST_MEMORY;
327 goto conferror;
331 * Open the provider. We assume all of our plugins have
332 * their symbols properly defined, so the use of RTLD_NOW
333 * to flush out errors immediately is not necessary.
335 * Note that for proper operation, all plugins must be
336 * built with direct bindings enabled.
338 dldesc = dlopen(fullpath, RTLD_LAZY);
341 * If we failed to load it, we will just skip this
342 * provider and move on to the next one.
344 if (dldesc == NULL) {
345 dl_error = dlerror();
346 cryptoerror(LOG_ERR,
347 "libpkcs11: Cannot load PKCS#11 library %s. "
348 "dlerror: %s. %s",
349 fullpath, dl_error != NULL ? dl_error : "Unknown",
350 conf_err);
351 goto contparse;
354 /* Get the pointer to provider's C_GetFunctionList() */
355 Tmp_C_GetFunctionList =
356 (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList");
359 * If we failed to get the pointer to C_GetFunctionList(),
360 * skip this provider and continue to the next one.
362 if (Tmp_C_GetFunctionList == NULL) {
363 cryptoerror(LOG_ERR,
364 "libpkcs11: Could not dlsym() C_GetFunctionList() "
365 "for %s. May not be a PKCS#11 library. %s",
366 fullpath, conf_err);
367 (void) dlclose(dldesc);
368 goto contparse;
372 /* Get the provider's function list */
373 prov_rv = Tmp_C_GetFunctionList(&prov_funcs);
376 * If we failed to get the provider's function list,
377 * skip this provider and continue to the next one.
379 if (prov_rv != CKR_OK) {
380 cryptoerror(LOG_ERR,
381 "libpkcs11: Could not get function list for %s. "
382 "%s Error: %s.",
383 fullpath, conf_err, pkcs11_strerror(prov_rv));
384 (void) dlclose(dldesc);
385 goto contparse;
388 /* Initialize this provider */
389 prov_rv = prov_funcs->C_Initialize(pInitArgs);
392 * If we failed to initialize this provider,
393 * skip this provider and continue to the next one.
395 if ((prov_rv != CKR_OK) &&
396 (prov_rv != CKR_CRYPTOKI_ALREADY_INITIALIZED)) {
397 cryptoerror(LOG_ERR,
398 "libpkcs11: Could not initialize %s. "
399 "%s Error: %s.",
400 fullpath, conf_err, pkcs11_strerror(prov_rv));
401 (void) dlclose(dldesc);
402 goto contparse;
406 * Make sure this provider is implementing the same
407 * major version, and at least the same minor version
408 * that we are.
410 prov_rv = prov_funcs->C_GetInfo(&prov_info);
413 * If we can't verify that we are implementing the
414 * same major version, or if it is definitely not the same
415 * version, we need to skip this provider.
417 if ((prov_rv != CKR_OK) ||
418 (prov_info.cryptokiVersion.major !=
419 CRYPTOKI_VERSION_MAJOR)) {
420 if (prov_rv != CKR_OK) {
421 cryptoerror(LOG_ERR,
422 "libpkcs11: Could not verify version of "
423 "%s. %s Error: %s.", fullpath,
424 conf_err, pkcs11_strerror(prov_rv));
425 } else {
426 cryptoerror(LOG_ERR,
427 "libpkcs11: Only CRYPTOKI major version "
428 "%d is supported. %s is major "
429 "version %d. %s",
430 CRYPTOKI_VERSION_MAJOR, fullpath,
431 prov_info.cryptokiVersion.major, conf_err);
433 (void) prov_funcs->C_Finalize(NULL);
434 (void) dlclose(dldesc);
435 goto contparse;
439 * Warn the administrator (at debug) that a provider with
440 * a significantly older or newer version of
441 * CRYPTOKI is being used. It should not cause
442 * problems, but logging a warning makes it easier
443 * to debug later.
445 if ((prov_info.cryptokiVersion.minor <
446 CRYPTOKI_VERSION_WARN_MINOR) ||
447 (prov_info.cryptokiVersion.minor >
448 CRYPTOKI_VERSION_MINOR)) {
449 cryptoerror(LOG_DEBUG,
450 "libpkcs11: %s CRYPTOKI minor version, %d, may "
451 "not be compatible with minor version %d.",
452 fullpath, prov_info.cryptokiVersion.minor,
453 CRYPTOKI_VERSION_MINOR);
457 * Find out how many slots this provider has,
458 * call with tokenPresent set to FALSE so all
459 * potential slots are returned.
461 prov_rv = prov_funcs->C_GetSlotList(FALSE,
462 NULL, &prov_slot_count);
465 * If the call failed, or if no slots are returned,
466 * then skip this provider and continue to next one.
468 if (prov_rv != CKR_OK) {
469 cryptoerror(LOG_ERR,
470 "libpksc11: Could not get slot list from %s. "
471 "%s Error: %s.",
472 fullpath, conf_err, pkcs11_strerror(prov_rv));
473 (void) prov_funcs->C_Finalize(NULL);
474 (void) dlclose(dldesc);
475 goto contparse;
478 if (prov_slot_count == 0) {
479 cryptodebug("libpkcs11: No slots presented from %s. "
480 "Skipping this plug-in at this time.\n",
481 fullpath);
482 (void) prov_funcs->C_Finalize(NULL);
483 (void) dlclose(dldesc);
484 goto contparse;
487 /* Allocate memory for the slot list */
488 prov_slots = calloc(prov_slot_count, sizeof (CK_SLOT_ID));
490 if (prov_slots == NULL) {
491 cryptoerror(LOG_ERR,
492 "libpkcs11: Could not allocate memory for "
493 "plug-in slots. Cannot continue parsing %s\n",
494 _PATH_PKCS11_CONF);
495 rv = CKR_HOST_MEMORY;
496 goto conferror;
499 /* Get slot list from provider */
500 prov_rv = prov_funcs->C_GetSlotList(FALSE,
501 prov_slots, &prov_slot_count);
503 /* if second call fails, drop this provider */
504 if (prov_rv != CKR_OK) {
505 cryptoerror(LOG_ERR,
506 "libpkcs11: Second call to C_GetSlotList() for %s "
507 "failed. %s Error: %s.",
508 fullpath, conf_err, pkcs11_strerror(prov_rv));
509 (void) prov_funcs->C_Finalize(NULL);
510 (void) dlclose(dldesc);
511 goto contparse;
515 * Parse the list of disabled or enabled mechanisms, will
516 * apply to each of the provider's slots.
518 if (phead->puent->count > 0) {
519 rv = pkcs11_mech_parse(phead->puent->policylist,
520 &prov_pol_mechs, phead->puent->count);
522 if (rv == CKR_HOST_MEMORY) {
523 cryptoerror(LOG_ERR,
524 "libpkcs11: Could not parse configuration,"
525 "out of memory. Cannot continue parsing "
526 "%s.", _PATH_PKCS11_CONF);
527 goto conferror;
528 } else if (rv == CKR_MECHANISM_INVALID) {
530 * Configuration file is corrupted for this
531 * provider.
533 cryptoerror(LOG_ERR,
534 "libpkcs11: Policy invalid or corrupted "
535 "for %s. Use cryptoadm(1M) to fix "
536 "this. Skipping this plug-in.",
537 fullpath);
538 (void) prov_funcs->C_Finalize(NULL);
539 (void) dlclose(dldesc);
540 goto contparse;
544 /* Allocate memory in our slottable for these slots */
545 rv = pkcs11_slottable_increase(prov_slot_count);
548 * If any error is returned, it will be memory related,
549 * so we need to abort the attempt at filling the
550 * slottable.
552 if (rv != CKR_OK) {
553 cryptoerror(LOG_ERR,
554 "libpkcs11: slottable could not increase. "
555 "Cannot continue parsing %s.",
556 _PATH_PKCS11_CONF);
557 goto conferror;
560 /* Configure information for each new slot */
561 for (i = 0; i < prov_slot_count; i++) {
562 /* allocate slot in framework */
563 rv = pkcs11_slot_allocate(&slot_id);
564 if (rv != CKR_OK) {
565 cryptoerror(LOG_ERR,
566 "libpkcs11: Could not allocate "
567 "new slot. Cannot continue parsing %s.",
568 _PATH_PKCS11_CONF);
569 goto conferror;
571 slot_count++;
572 cur_slot = slottable->st_slots[slot_id];
573 (void) pthread_mutex_lock(&cur_slot->sl_mutex);
574 cur_slot->sl_id = prov_slots[i];
575 cur_slot->sl_func_list = prov_funcs;
576 cur_slot->sl_enabledpol =
577 phead->puent->flag_enabledlist;
578 cur_slot->sl_pol_mechs = prov_pol_mechs;
579 cur_slot->sl_pol_count = phead->puent->count;
580 cur_slot->sl_norandom = phead->puent->flag_norandom;
581 cur_slot->sl_dldesc = dldesc;
582 cur_slot->sl_prov_id = prov_count + 1;
583 (void) pthread_mutex_unlock(&cur_slot->sl_mutex);
587 * Get the pointer to private interface _SUNW_GetThreshold()
588 * in pkcs11_kernel.
591 if (Tmp_GetThreshold == NULL) {
592 Tmp_GetThreshold =
593 (void(*)())dlsym(dldesc, "_SUNW_GetThreshold");
595 /* Get the threshold values for the supported mechs */
596 if (Tmp_GetThreshold != NULL) {
597 (void) memset(meta_mechs_threshold, 0,
598 sizeof (meta_mechs_threshold));
599 Tmp_GetThreshold(meta_mechs_threshold);
603 /* Set and reset values to process next provider */
604 prov_count++;
605 contparse:
606 prov_slot_count = 0;
607 Tmp_C_GetFunctionList = NULL;
608 prov_funcs = NULL;
609 dldesc = NULL;
610 if (fullpath != NULL) {
611 free(fullpath);
612 fullpath = NULL;
614 if (prov_slots != NULL) {
615 free(prov_slots);
616 prov_slots = NULL;
618 phead = phead->next;
621 if (slot_count == 0) {
623 * there's no other slot in the framework,
624 * there is nothing to do
626 goto config_complete;
629 /* determine if metaslot should be enabled */
632 * Check to see if any environment variable is defined
633 * by the user for configuring metaslot. Users'
634 * setting always take precedence over the system wide
635 * setting. So, we will first check for any user's
636 * defined env variables before looking at the system-wide
637 * configuration.
639 get_user_metaslot_config();
641 /* no metaslot entry in /etc/crypto/pkcs11.conf */
642 if (!metaslot_entry) {
644 * If user env variable indicates metaslot should be enabled,
645 * but there's no entry in /etc/crypto/pkcs11.conf for
646 * metaslot at all, will respect the user's defined value
648 if ((metaslot_config.enabled_specified) &&
649 (metaslot_config.enabled)) {
650 metaslot_enabled = B_TRUE;
652 } else {
653 if (!metaslot_config.enabled_specified) {
655 * take system wide value if
656 * it is not specified by user
658 metaslot_enabled
659 = metaslot_entry->flag_metaslot_enabled;
660 } else {
661 metaslot_enabled = metaslot_config.enabled;
667 * As long as the user or system configuration file does not
668 * disable metaslot, it will be enabled regardless of the
669 * number of slots plugged into the framework. Therefore,
670 * metaslot is enabled even when there's only one slot
671 * plugged into the framework. This is necessary for
672 * presenting a consistent token label view to applications.
674 * However, for the case where there is only 1 slot plugged into
675 * the framework, we can use "fastpath".
677 * "fastpath" will pass all of the application's requests
678 * directly to the underlying provider. Only when policy is in
679 * effect will we need to keep slotID around.
681 * When metaslot is enabled, and fastpath is enabled,
682 * all the metaslot processing will be skipped.
683 * When there is only 1 slot, there's
684 * really not much metaslot can do in terms of combining functionality
685 * of different slots, and object migration.
689 /* check to see if fastpath can be used */
690 if (slottable->st_last == slottable->st_first) {
692 cur_slot = slottable->st_slots[slottable->st_first];
694 (void) pthread_mutex_lock(&cur_slot->sl_mutex);
696 if ((cur_slot->sl_pol_count == 0) &&
697 (!cur_slot->sl_enabledpol) && (!cur_slot->sl_norandom)) {
698 /* No policy is in effect, don't need slotid */
699 fast_funcs = cur_slot->sl_func_list;
700 purefastpath = B_TRUE;
701 } else {
702 fast_funcs = cur_slot->sl_func_list;
703 fast_slot = slottable->st_first;
704 policyfastpath = B_TRUE;
707 (void) pthread_mutex_unlock(&cur_slot->sl_mutex);
710 if ((purefastpath || policyfastpath) && (!metaslot_enabled)) {
711 goto config_complete;
715 * If we get here, there are more than 2 slots in the framework,
716 * we need to set up metaslot if it is enabled
718 if (metaslot_enabled) {
719 rv = setup_metaslot(metaslot_entry);
720 if (rv != CKR_OK) {
721 goto conferror;
726 config_complete:
728 return (CKR_OK);
730 conferror:
732 * This cleanup code is only exercised when a major,
733 * unrecoverable error like "out of memory".
735 if (prov_funcs != NULL) {
736 (void) prov_funcs->C_Finalize(NULL);
738 if (dldesc != NULL) {
739 (void) dlclose(dldesc);
741 if (fullpath != NULL) {
742 free(fullpath);
743 fullpath = NULL;
745 if (prov_slots != NULL) {
746 free(prov_slots);
747 prov_slots = NULL;
750 return (rv);
754 * pkcs11_mech_parse will take hex mechanism ids, as a list of
755 * strings, and convert them to CK_MECHANISM_TYPE_PTR.
757 CK_RV
758 pkcs11_mech_parse(umechlist_t *str_list, CK_MECHANISM_TYPE_PTR *mech_list,
759 int mech_count)
761 CK_MECHANISM_TYPE_PTR tmp_list;
762 umechlist_t *shead = str_list;
764 tmp_list = malloc(mech_count * sizeof (CK_MECHANISM_TYPE));
766 if (tmp_list == NULL) {
767 cryptoerror(LOG_ERR, "libpkcs11: parsing %s, out of memory. "
768 "Cannot continue.",
769 _PATH_PKCS11_CONF);
770 return (CKR_HOST_MEMORY);
773 *mech_list = tmp_list;
776 * The following will loop mech_count times, as there are
777 * exactly mech_count items in the str_list.
779 while (shead != NULL) {
780 CK_MECHANISM_TYPE cur_mech;
782 errno = 0;
785 * "name" is a hexadecimal number, preceded by 0x.
787 cur_mech = strtoul(shead->name, NULL, 16);
789 if ((cur_mech == 0) &&
790 ((errno == EINVAL) || (errno == ERANGE))) {
791 free(mech_list);
792 return (CKR_MECHANISM_INVALID);
794 *tmp_list = (CK_MECHANISM_TYPE)cur_mech;
795 tmp_list++;
796 shead = shead->next;
799 return (CKR_OK);
803 * pkcs11_is_dismech is provided a slotid and a mechanism.
804 * If mech is not disabled, then return B_FALSE.
806 boolean_t
807 pkcs11_is_dismech(CK_SLOT_ID slotid, CK_MECHANISM_TYPE mech)
809 ulong_t i;
810 boolean_t enabled_pol;
811 CK_MECHANISM_TYPE_PTR pol_mechs;
812 ulong_t pol_count;
814 /* Find the associated slot and get the mech policy info */
815 (void) pthread_mutex_lock(&slottable->st_slots[slotid]->sl_mutex);
816 enabled_pol = slottable->st_slots[slotid]->sl_enabledpol;
817 pol_mechs = slottable->st_slots[slotid]->sl_pol_mechs;
818 pol_count = slottable->st_slots[slotid]->sl_pol_count;
819 (void) pthread_mutex_unlock(&slottable->st_slots[slotid]->sl_mutex);
821 /* Check for policy */
822 if ((!enabled_pol) && (pol_mechs == NULL)) {
823 /* no policy */
824 return (B_FALSE);
825 } else if (pol_mechs == NULL) {
827 * We have an empty enabled list, which means no
828 * mechanisms are exempted from this policy: all
829 * are disabled.
831 return (B_TRUE);
834 for (i = 0; i < pol_count; i++) {
836 * If it matches, return status based on this
837 * being and enabled or a disabled list of mechs.
839 if (pol_mechs[i] == mech) {
840 return (enabled_pol ? B_FALSE : B_TRUE);
844 /* mech was not found in list */
845 return (enabled_pol ? B_TRUE : B_FALSE);