xref: /titanic_50/usr/src/cmd/cmd-crypto/cryptoadm/adm_uef.c (revision 6ea3c0609e50782557505b88bb391b786bca32c9)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
599ebb4caSwyllys  * Common Development and Distribution License (the "License").
699ebb4caSwyllys  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
2212240b1dSDarren J Moffat  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
24*6ea3c060SGarrett D'Amore /*
25*6ea3c060SGarrett D'Amore  * Copyright 2010 Nexenta Systems, Inc.  All rights resrved.
26*6ea3c060SGarrett D'Amore  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <cryptoutil.h>
297c478bd9Sstevel@tonic-gate #include <fcntl.h>
307c478bd9Sstevel@tonic-gate #include <libintl.h>
317c478bd9Sstevel@tonic-gate #include <stdio.h>
327c478bd9Sstevel@tonic-gate #include <stdlib.h>
337c478bd9Sstevel@tonic-gate #include <strings.h>
347c478bd9Sstevel@tonic-gate #include <unistd.h>
357c478bd9Sstevel@tonic-gate #include <errno.h>
367c478bd9Sstevel@tonic-gate #include <dlfcn.h>
377c478bd9Sstevel@tonic-gate #include <link.h>
387c478bd9Sstevel@tonic-gate #include <sys/types.h>
397c478bd9Sstevel@tonic-gate #include <sys/stat.h>
407c478bd9Sstevel@tonic-gate #include <security/cryptoki.h>
417c478bd9Sstevel@tonic-gate #include "cryptoadm.h"
427c478bd9Sstevel@tonic-gate 
437c478bd9Sstevel@tonic-gate #define	HDR1 "                                     P\n"
447c478bd9Sstevel@tonic-gate #define	HDR2 "                         S     V  K  a     U  D\n"
457c478bd9Sstevel@tonic-gate #define	HDR3 "                         i     e  e  i     n  e\n"
467c478bd9Sstevel@tonic-gate #define	HDR4 "                      S  g  V  r  y  r  W  w  r\n"
477c478bd9Sstevel@tonic-gate #define	HDR5 "             E  D  D  i  n  e  i  G  G  r  r  i\n"
487c478bd9Sstevel@tonic-gate #define	HDR6 "          H  n  e  i  g  +  r  +  e  e  a  a  v  E\n"
497c478bd9Sstevel@tonic-gate #define	HDR7 "min  max  W  c  c  g  n  R  i  R  n  n  p  p  e  C\n"
507c478bd9Sstevel@tonic-gate 
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate static int err; /* To store errno which may be overwritten by gettext() */
537c478bd9Sstevel@tonic-gate static boolean_t is_in_policylist(midstr_t, umechlist_t *);
547c478bd9Sstevel@tonic-gate static char *uent2str(uentry_t *);
557c478bd9Sstevel@tonic-gate static boolean_t check_random(CK_SLOT_ID, CK_FUNCTION_LIST_PTR);
567c478bd9Sstevel@tonic-gate 
display_slot_flags(CK_FLAGS flags)577c478bd9Sstevel@tonic-gate static void display_slot_flags(CK_FLAGS flags)
587c478bd9Sstevel@tonic-gate {
597c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Slot Flags: "));
607c478bd9Sstevel@tonic-gate 	if (flags & CKF_TOKEN_PRESENT)
617c478bd9Sstevel@tonic-gate 		(void) printf("CKF_TOKEN_PRESENT ");
627c478bd9Sstevel@tonic-gate 	if (flags & CKF_REMOVABLE_DEVICE)
637c478bd9Sstevel@tonic-gate 		(void) printf("CKF_REMOVABLE_DEVICE ");
647c478bd9Sstevel@tonic-gate 	if (flags & CKF_HW_SLOT)
657c478bd9Sstevel@tonic-gate 		(void) printf("CKF_HW_SLOT ");
667c478bd9Sstevel@tonic-gate 	(void) printf("\n");
677c478bd9Sstevel@tonic-gate }
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate void
display_token_flags(CK_FLAGS flags)707c478bd9Sstevel@tonic-gate display_token_flags(CK_FLAGS flags)
717c478bd9Sstevel@tonic-gate {
727c478bd9Sstevel@tonic-gate 	(void) printf(gettext("Flags: "));
737c478bd9Sstevel@tonic-gate 	if (flags & CKF_RNG)
747c478bd9Sstevel@tonic-gate 		(void) printf("CKF_RNG ");
757c478bd9Sstevel@tonic-gate 	if (flags & CKF_WRITE_PROTECTED)
767c478bd9Sstevel@tonic-gate 		(void) printf("CKF_WRITE_PROTECTED ");
777c478bd9Sstevel@tonic-gate 	if (flags & CKF_LOGIN_REQUIRED)
787c478bd9Sstevel@tonic-gate 		(void) printf("CKF_LOGIN_REQUIRED ");
797c478bd9Sstevel@tonic-gate 	if (flags & CKF_USER_PIN_INITIALIZED)
807c478bd9Sstevel@tonic-gate 		(void) printf("CKF_USER_PIN_INITIALIZED ");
817c478bd9Sstevel@tonic-gate 	if (flags & CKF_RESTORE_KEY_NOT_NEEDED)
827c478bd9Sstevel@tonic-gate 		(void) printf("CKF_RESTORE_KEY_NOT_NEEDED ");
837c478bd9Sstevel@tonic-gate 	if (flags & CKF_CLOCK_ON_TOKEN)
847c478bd9Sstevel@tonic-gate 		(void) printf("CKF_CLOCK_ON_TOKEN ");
857c478bd9Sstevel@tonic-gate 	if (flags & CKF_PROTECTED_AUTHENTICATION_PATH)
867c478bd9Sstevel@tonic-gate 		(void) printf("CKF_PROTECTED_AUTHENTICATION_PATH ");
877c478bd9Sstevel@tonic-gate 	if (flags & CKF_DUAL_CRYPTO_OPERATIONS)
887c478bd9Sstevel@tonic-gate 		(void) printf("CKF_DUAL_CRYPTO_OPERATIONS ");
897c478bd9Sstevel@tonic-gate 	if (flags & CKF_TOKEN_INITIALIZED)
907c478bd9Sstevel@tonic-gate 		(void) printf("CKF_TOKEN_INITIALIZED ");
917c478bd9Sstevel@tonic-gate 	if (flags & CKF_SECONDARY_AUTHENTICATION)
927c478bd9Sstevel@tonic-gate 		(void) printf("CKF_SECONDARY_AUTHENTICATION ");
937c478bd9Sstevel@tonic-gate 	if (flags & CKF_USER_PIN_COUNT_LOW)
947c478bd9Sstevel@tonic-gate 		(void) printf("CKF_USER_PIN_COUNT_LOW ");
957c478bd9Sstevel@tonic-gate 	if (flags & CKF_USER_PIN_FINAL_TRY)
967c478bd9Sstevel@tonic-gate 		(void) printf("CKF_USER_PIN_FINAL_TRY ");
977c478bd9Sstevel@tonic-gate 	if (flags & CKF_USER_PIN_LOCKED)
987c478bd9Sstevel@tonic-gate 		(void) printf("CKF_USER_PIN_LOCKED ");
997c478bd9Sstevel@tonic-gate 	if (flags & CKF_USER_PIN_TO_BE_CHANGED)
1007c478bd9Sstevel@tonic-gate 		(void) printf("CKF_USER_PIN_TO_BE_CHANGED ");
1017c478bd9Sstevel@tonic-gate 	if (flags & CKF_SO_PIN_COUNT_LOW)
1027c478bd9Sstevel@tonic-gate 		(void) printf("CKF_SO_PIN_COUNT_LOW ");
1037c478bd9Sstevel@tonic-gate 	if (flags & CKF_SO_PIN_FINAL_TRY)
1047c478bd9Sstevel@tonic-gate 		(void) printf("CKF_SO_PIN_FINAL_TRY ");
1057c478bd9Sstevel@tonic-gate 	if (flags & CKF_SO_PIN_LOCKED)
1067c478bd9Sstevel@tonic-gate 		(void) printf("CKF_SO_PIN_LOCKED ");
1077c478bd9Sstevel@tonic-gate 	if (flags & CKF_SO_PIN_TO_BE_CHANGED)
1087c478bd9Sstevel@tonic-gate 		(void) printf("CKF_SO_PIN_TO_BE_CHANGED ");
1097c478bd9Sstevel@tonic-gate 	if (flags & CKF_SO_PIN_TO_BE_CHANGED)
1107c478bd9Sstevel@tonic-gate 		(void) printf("CKF_SO_PIN_TO_BE_CHANGED ");
1117c478bd9Sstevel@tonic-gate 	(void) printf("\n");
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate 
1147c478bd9Sstevel@tonic-gate void
display_mech_info(CK_MECHANISM_INFO * mechInfo)1157c478bd9Sstevel@tonic-gate display_mech_info(CK_MECHANISM_INFO *mechInfo)
1167c478bd9Sstevel@tonic-gate {
1177c478bd9Sstevel@tonic-gate 	CK_FLAGS ec_flags = CKF_EC_F_P | CKF_EC_F_2M | CKF_EC_ECPARAMETERS |
1187c478bd9Sstevel@tonic-gate 	    CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS | CKF_EC_COMPRESS;
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	(void) printf("%-4ld %-4ld ", mechInfo->ulMinKeySize,
1217c478bd9Sstevel@tonic-gate 	    mechInfo->ulMaxKeySize);
1227c478bd9Sstevel@tonic-gate 	(void) printf("%s  %s  %s  %s  %s  %s  %s  %s  %s  %s  %s  %s  "
1237c478bd9Sstevel@tonic-gate 	    "%s  %s",
1247c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_HW) ? "X" : ".",
1257c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_ENCRYPT) ? "X" : ".",
1267c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_DECRYPT) ? "X" : ".",
1277c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_DIGEST) ? "X" : ".",
1287c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_SIGN) ? "X" : ".",
1297c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_SIGN_RECOVER) ? "X" : ".",
1307c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_VERIFY) ? "X" : ".",
1317c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_VERIFY_RECOVER) ? "X" : ".",
1327c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_GENERATE) ? "X" : ".",
1337c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_GENERATE_KEY_PAIR) ? "X" : ".",
1347c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_WRAP) ? "X" : ".",
1357c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_UNWRAP) ? "X" : ".",
1367c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & CKF_DERIVE) ? "X" : ".",
1377c478bd9Sstevel@tonic-gate 	    (mechInfo->flags & ec_flags) ? "X" : ".");
1387c478bd9Sstevel@tonic-gate }
1397c478bd9Sstevel@tonic-gate 
1407c478bd9Sstevel@tonic-gate /*
1417c478bd9Sstevel@tonic-gate  * Converts the provided list of mechanism names in their string format to
1422321aa36Sda73024  * their corresponding PKCS#11 mechanism IDs.
1437c478bd9Sstevel@tonic-gate  *
1447c478bd9Sstevel@tonic-gate  * The list of mechanism names to be converted is provided in the
1457c478bd9Sstevel@tonic-gate  * "mlist" argument.  The list of converted mechanism IDs is returned
1467c478bd9Sstevel@tonic-gate  * in the "pmech_list" argument.
1477c478bd9Sstevel@tonic-gate  *
1487c478bd9Sstevel@tonic-gate  * This function is called by list_metaslot_info() and
1497c478bd9Sstevel@tonic-gate  * list_mechlist_for_lib() functions.
1507c478bd9Sstevel@tonic-gate  */
1517c478bd9Sstevel@tonic-gate int
convert_mechlist(CK_MECHANISM_TYPE ** pmech_list,CK_ULONG * mech_count,mechlist_t * mlist)1527c478bd9Sstevel@tonic-gate convert_mechlist(CK_MECHANISM_TYPE **pmech_list, CK_ULONG *mech_count,
1537c478bd9Sstevel@tonic-gate     mechlist_t *mlist)
1547c478bd9Sstevel@tonic-gate {
1557c478bd9Sstevel@tonic-gate 	int i, n = 0;
1567c478bd9Sstevel@tonic-gate 	mechlist_t *p = mlist;
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 	while (p != NULL) {
1597c478bd9Sstevel@tonic-gate 		p = p->next;
1607c478bd9Sstevel@tonic-gate 		n++;
1617c478bd9Sstevel@tonic-gate 	}
1627c478bd9Sstevel@tonic-gate 
1637c478bd9Sstevel@tonic-gate 	*pmech_list = malloc(n * sizeof (CK_MECHANISM_TYPE));
1647c478bd9Sstevel@tonic-gate 	if (pmech_list == NULL) {
1657c478bd9Sstevel@tonic-gate 		cryptodebug("out of memory");
1667c478bd9Sstevel@tonic-gate 		return (FAILURE);
1677c478bd9Sstevel@tonic-gate 	}
1687c478bd9Sstevel@tonic-gate 	p = mlist;
1697c478bd9Sstevel@tonic-gate 	for (i = 0; i < n; i++) {
1707c478bd9Sstevel@tonic-gate 		if (pkcs11_str2mech(p->name, &(*pmech_list[i])) != CKR_OK) {
1717c478bd9Sstevel@tonic-gate 			free(*pmech_list);
1727c478bd9Sstevel@tonic-gate 			return (FAILURE);
1737c478bd9Sstevel@tonic-gate 		}
1747c478bd9Sstevel@tonic-gate 		p = p->next;
1757c478bd9Sstevel@tonic-gate 	}
1767c478bd9Sstevel@tonic-gate 	*mech_count = n;
1777c478bd9Sstevel@tonic-gate 	return (SUCCESS);
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /*
1817c478bd9Sstevel@tonic-gate  * Display the mechanism list for a user-level library
1827c478bd9Sstevel@tonic-gate  */
1837c478bd9Sstevel@tonic-gate int
list_mechlist_for_lib(char * libname,mechlist_t * mlist,flag_val_t * rng_flag,boolean_t no_warn,boolean_t verbose,boolean_t show_mechs)1847c478bd9Sstevel@tonic-gate list_mechlist_for_lib(char *libname, mechlist_t *mlist,
1857c478bd9Sstevel@tonic-gate 		flag_val_t *rng_flag, boolean_t no_warn,
1867c478bd9Sstevel@tonic-gate 		boolean_t verbose, boolean_t show_mechs)
1877c478bd9Sstevel@tonic-gate {
1887c478bd9Sstevel@tonic-gate 	CK_RV	rv = CKR_OK;
1897c478bd9Sstevel@tonic-gate 	CK_RV	(*Tmp_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR);
1907c478bd9Sstevel@tonic-gate 	CK_FUNCTION_LIST_PTR	prov_funcs; /* Provider's function list */
1917c478bd9Sstevel@tonic-gate 	CK_SLOT_ID_PTR		prov_slots = NULL; /* Provider's slot list */
19212240b1dSDarren J Moffat 	CK_MECHANISM_TYPE_PTR	pmech_list = NULL; /* mech list for a slot */
1937c478bd9Sstevel@tonic-gate 	CK_SLOT_INFO	slotinfo;
1947c478bd9Sstevel@tonic-gate 	CK_ULONG	slot_count;
1957c478bd9Sstevel@tonic-gate 	CK_ULONG	mech_count;
1967c478bd9Sstevel@tonic-gate 	uentry_t	*puent = NULL;
1977c478bd9Sstevel@tonic-gate 	boolean_t	lib_initialized = B_FALSE;
1987c478bd9Sstevel@tonic-gate 	void		*dldesc = NULL;
1997c478bd9Sstevel@tonic-gate 	char		*dl_error;
2002321aa36Sda73024 	const char 	*mech_name;
2017c478bd9Sstevel@tonic-gate 	char		*isa;
2027c478bd9Sstevel@tonic-gate 	char		libpath[MAXPATHLEN];
2037c478bd9Sstevel@tonic-gate 	char		buf[MAXPATHLEN];
2047c478bd9Sstevel@tonic-gate 	int		i, j;
2057c478bd9Sstevel@tonic-gate 	int		rc = SUCCESS;
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	if (libname == NULL) {
2087c478bd9Sstevel@tonic-gate 		/* should not happen */
2097c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
2107c478bd9Sstevel@tonic-gate 		cryptodebug("list_mechlist_for_lib() - libname is NULL.");
2117c478bd9Sstevel@tonic-gate 		return (FAILURE);
2127c478bd9Sstevel@tonic-gate 	}
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 	/* Check if the library is in the pkcs11.conf file */
2157c478bd9Sstevel@tonic-gate 	if ((puent = getent_uef(libname)) == NULL) {
2167c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
2177c478bd9Sstevel@tonic-gate 		    gettext("%s does not exist."), libname);
2187c478bd9Sstevel@tonic-gate 		return (FAILURE);
2197c478bd9Sstevel@tonic-gate 	}
2207c478bd9Sstevel@tonic-gate 	free_uentry(puent);
2217c478bd9Sstevel@tonic-gate 
2227c478bd9Sstevel@tonic-gate 	/* Remove $ISA from the library name */
2237c478bd9Sstevel@tonic-gate 	if (strlcpy(buf, libname, sizeof (buf)) >= sizeof (buf)) {
2247c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s: the provider name is too long."),
2257c478bd9Sstevel@tonic-gate 		    libname);
2267c478bd9Sstevel@tonic-gate 		return (FAILURE);
2277c478bd9Sstevel@tonic-gate 	}
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 	if ((isa = strstr(buf, PKCS11_ISA)) != NULL) {
2307c478bd9Sstevel@tonic-gate 		*isa = '\000';
2317c478bd9Sstevel@tonic-gate 		isa += strlen(PKCS11_ISA);
2327c478bd9Sstevel@tonic-gate 		(void) snprintf(libpath, MAXPATHLEN, "%s%s%s", buf, "/", isa);
2337c478bd9Sstevel@tonic-gate 	} else {
2347c478bd9Sstevel@tonic-gate 		(void) strlcpy(libpath, libname, sizeof (libpath));
2357c478bd9Sstevel@tonic-gate 	}
2367c478bd9Sstevel@tonic-gate 
237699ea13aSValerie Bubb Fenwick 	/*
238699ea13aSValerie Bubb Fenwick 	 * Open the provider. Use RTLD_NOW here, as a way to
239699ea13aSValerie Bubb Fenwick 	 * catch any providers with incomplete symbols that
240699ea13aSValerie Bubb Fenwick 	 * might otherwise cause problems during libpkcs11's
241699ea13aSValerie Bubb Fenwick 	 * execution.
242699ea13aSValerie Bubb Fenwick 	 */
2437c478bd9Sstevel@tonic-gate 	dldesc = dlopen(libpath, RTLD_NOW);
2447c478bd9Sstevel@tonic-gate 	if (dldesc == NULL) {
2457c478bd9Sstevel@tonic-gate 		dl_error = dlerror();
2467c478bd9Sstevel@tonic-gate 		cryptodebug("Cannot load PKCS#11 library %s.  dlerror: %s",
2477c478bd9Sstevel@tonic-gate 		    libname, dl_error != NULL ? dl_error : "Unknown");
2487c478bd9Sstevel@tonic-gate 		rc = FAILURE;
2497c478bd9Sstevel@tonic-gate 		goto clean_exit;
2507c478bd9Sstevel@tonic-gate 	}
2517c478bd9Sstevel@tonic-gate 
2527c478bd9Sstevel@tonic-gate 	/* Get the pointer to provider's C_GetFunctionList() */
2537c478bd9Sstevel@tonic-gate 	Tmp_C_GetFunctionList = (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList");
2547c478bd9Sstevel@tonic-gate 	if (Tmp_C_GetFunctionList == NULL) {
2557c478bd9Sstevel@tonic-gate 		cryptodebug("Cannot get the address of the C_GetFunctionList "
2567c478bd9Sstevel@tonic-gate 		    "from %s", libname);
2577c478bd9Sstevel@tonic-gate 		rc = FAILURE;
2587c478bd9Sstevel@tonic-gate 		goto clean_exit;
2597c478bd9Sstevel@tonic-gate 	}
2607c478bd9Sstevel@tonic-gate 
2617c478bd9Sstevel@tonic-gate 	/* Get the provider's function list */
2627c478bd9Sstevel@tonic-gate 	rv = Tmp_C_GetFunctionList(&prov_funcs);
2637c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
2647c478bd9Sstevel@tonic-gate 		cryptodebug("failed to call C_GetFunctionList from %s",
2657c478bd9Sstevel@tonic-gate 		    libname);
2667c478bd9Sstevel@tonic-gate 		rc = FAILURE;
2677c478bd9Sstevel@tonic-gate 		goto clean_exit;
2687c478bd9Sstevel@tonic-gate 	}
2697c478bd9Sstevel@tonic-gate 
2707c478bd9Sstevel@tonic-gate 	/* Initialize this provider */
2717c478bd9Sstevel@tonic-gate 	rv = prov_funcs->C_Initialize(NULL_PTR);
2727c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
2737c478bd9Sstevel@tonic-gate 		cryptodebug("failed to call C_Initialize from %s, "
2747c478bd9Sstevel@tonic-gate 		    "return code = %d", libname, rv);
2757c478bd9Sstevel@tonic-gate 		rc = FAILURE;
2767c478bd9Sstevel@tonic-gate 		goto clean_exit;
2777c478bd9Sstevel@tonic-gate 	} else {
2787c478bd9Sstevel@tonic-gate 		lib_initialized = B_TRUE;
2797c478bd9Sstevel@tonic-gate 	}
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 	/*
2827c478bd9Sstevel@tonic-gate 	 * Find out how many slots this provider has, call with tokenPresent
2837c478bd9Sstevel@tonic-gate 	 * set to FALSE so all potential slots are returned.
2847c478bd9Sstevel@tonic-gate 	 */
2857c478bd9Sstevel@tonic-gate 	rv = prov_funcs->C_GetSlotList(FALSE, NULL_PTR, &slot_count);
2867c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
2877c478bd9Sstevel@tonic-gate 		cryptodebug("failed to get the slotlist from %s.", libname);
2887c478bd9Sstevel@tonic-gate 		rc = FAILURE;
2897c478bd9Sstevel@tonic-gate 		goto clean_exit;
2907c478bd9Sstevel@tonic-gate 	} else if (slot_count == 0) {
2917c478bd9Sstevel@tonic-gate 		if (!no_warn)
2927c478bd9Sstevel@tonic-gate 			(void) printf(gettext("%s: no slots presented.\n"),
2937c478bd9Sstevel@tonic-gate 			    libname);
2947c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
2957c478bd9Sstevel@tonic-gate 		goto clean_exit;
2967c478bd9Sstevel@tonic-gate 	}
2977c478bd9Sstevel@tonic-gate 
2987c478bd9Sstevel@tonic-gate 	/* Allocate memory for the slot list */
2997c478bd9Sstevel@tonic-gate 	prov_slots = malloc(slot_count * sizeof (CK_SLOT_ID));
3007c478bd9Sstevel@tonic-gate 	if (prov_slots == NULL) {
3017c478bd9Sstevel@tonic-gate 		cryptodebug("out of memory.");
3027c478bd9Sstevel@tonic-gate 		rc = FAILURE;
3037c478bd9Sstevel@tonic-gate 		goto clean_exit;
3047c478bd9Sstevel@tonic-gate 	}
3057c478bd9Sstevel@tonic-gate 
3067c478bd9Sstevel@tonic-gate 	/* Get the slot list from provider */
3077c478bd9Sstevel@tonic-gate 	rv = prov_funcs->C_GetSlotList(FALSE, prov_slots, &slot_count);
3087c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK) {
3097c478bd9Sstevel@tonic-gate 		cryptodebug("failed to call C_GetSlotList() from %s.",
3107c478bd9Sstevel@tonic-gate 		    libname);
3117c478bd9Sstevel@tonic-gate 		rc = FAILURE;
3127c478bd9Sstevel@tonic-gate 		goto clean_exit;
3137c478bd9Sstevel@tonic-gate 	}
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 	if (verbose) {
3167c478bd9Sstevel@tonic-gate 		(void) printf(gettext("Number of slots: %d\n"), slot_count);
3177c478bd9Sstevel@tonic-gate 	}
3187c478bd9Sstevel@tonic-gate 
3197c478bd9Sstevel@tonic-gate 	/* Get the mechanism list for each slot */
3207c478bd9Sstevel@tonic-gate 	for (i = 0; i < slot_count; i++) {
3217c478bd9Sstevel@tonic-gate 		if (verbose)
3227c478bd9Sstevel@tonic-gate 			/*
3230a85b835SDaniel Anderson 			 * TRANSLATION_NOTE
3247c478bd9Sstevel@tonic-gate 			 * In some languages, the # symbol should be
3257c478bd9Sstevel@tonic-gate 			 * converted to "no", an "n" followed by a
3267c478bd9Sstevel@tonic-gate 			 * superscript "o"..
3277c478bd9Sstevel@tonic-gate 			 */
3287c478bd9Sstevel@tonic-gate 			(void) printf(gettext("\nSlot #%d\n"), i+1);
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate 		if ((rng_flag != NULL) && (*rng_flag == NO_RNG)) {
3317c478bd9Sstevel@tonic-gate 			if (check_random(prov_slots[i], prov_funcs)) {
3327c478bd9Sstevel@tonic-gate 				*rng_flag = HAS_RNG;
3337c478bd9Sstevel@tonic-gate 				rc = SUCCESS;
3347c478bd9Sstevel@tonic-gate 				goto clean_exit;
3357c478bd9Sstevel@tonic-gate 			} else
3367c478bd9Sstevel@tonic-gate 				continue;
3377c478bd9Sstevel@tonic-gate 		}
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate 		rv = prov_funcs->C_GetSlotInfo(prov_slots[i], &slotinfo);
3407c478bd9Sstevel@tonic-gate 		if (rv != CKR_OK) {
3417c478bd9Sstevel@tonic-gate 			cryptodebug("failed to get slotinfo from %s", libname);
3427c478bd9Sstevel@tonic-gate 			rc = FAILURE;
3437c478bd9Sstevel@tonic-gate 			break;
3447c478bd9Sstevel@tonic-gate 		}
3457c478bd9Sstevel@tonic-gate 		if (verbose) {
3467c478bd9Sstevel@tonic-gate 			CK_TOKEN_INFO tokeninfo;
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Description: %.64s\n"
3497c478bd9Sstevel@tonic-gate 			    "Manufacturer: %.32s\n"
3507c478bd9Sstevel@tonic-gate 			    "PKCS#11 Version: %d.%d\n"),
3517c478bd9Sstevel@tonic-gate 			    slotinfo.slotDescription,
3527c478bd9Sstevel@tonic-gate 			    slotinfo.manufacturerID,
3537c478bd9Sstevel@tonic-gate 			    prov_funcs->version.major,
3547c478bd9Sstevel@tonic-gate 			    prov_funcs->version.minor);
3557c478bd9Sstevel@tonic-gate 
3567c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Hardware Version: %d.%d\n"
3577c478bd9Sstevel@tonic-gate 			    "Firmware Version: %d.%d\n"),
3587c478bd9Sstevel@tonic-gate 			    slotinfo.hardwareVersion.major,
3597c478bd9Sstevel@tonic-gate 			    slotinfo.hardwareVersion.minor,
3607c478bd9Sstevel@tonic-gate 			    slotinfo.firmwareVersion.major,
3617c478bd9Sstevel@tonic-gate 			    slotinfo.firmwareVersion.minor);
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Token Present: %s\n"),
3647c478bd9Sstevel@tonic-gate 			    (slotinfo.flags & CKF_TOKEN_PRESENT ?
3657c478bd9Sstevel@tonic-gate 			    gettext("True") : gettext("False")));
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 			display_slot_flags(slotinfo.flags);
3687c478bd9Sstevel@tonic-gate 
3697c478bd9Sstevel@tonic-gate 			rv = prov_funcs->C_GetTokenInfo(prov_slots[i],
3707c478bd9Sstevel@tonic-gate 			    &tokeninfo);
3717c478bd9Sstevel@tonic-gate 			if (rv != CKR_OK) {
3727c478bd9Sstevel@tonic-gate 				cryptodebug("Failed to get "
3737c478bd9Sstevel@tonic-gate 				    "token info from %s", libname);
3747c478bd9Sstevel@tonic-gate 				rc = FAILURE;
3757c478bd9Sstevel@tonic-gate 				break;
3767c478bd9Sstevel@tonic-gate 			}
3777c478bd9Sstevel@tonic-gate 
3787c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Token Label: %.32s\n"
3797c478bd9Sstevel@tonic-gate 			    "Manufacturer ID: %.32s\n"
3807c478bd9Sstevel@tonic-gate 			    "Model: %.16s\n"
3817c478bd9Sstevel@tonic-gate 			    "Serial Number: %.16s\n"
3827c478bd9Sstevel@tonic-gate 			    "Hardware Version: %d.%d\n"
3837c478bd9Sstevel@tonic-gate 			    "Firmware Version: %d.%d\n"
3847c478bd9Sstevel@tonic-gate 			    "UTC Time: %.16s\n"
3857f3340f0SDarren Moffat 			    "PIN Min Length: %d\n"
3867f3340f0SDarren Moffat 			    "PIN Max Length: %d\n"),
3877c478bd9Sstevel@tonic-gate 			    tokeninfo.label,
3887c478bd9Sstevel@tonic-gate 			    tokeninfo.manufacturerID,
3897c478bd9Sstevel@tonic-gate 			    tokeninfo.model,
3907c478bd9Sstevel@tonic-gate 			    tokeninfo.serialNumber,
3917c478bd9Sstevel@tonic-gate 			    tokeninfo.hardwareVersion.major,
3927c478bd9Sstevel@tonic-gate 			    tokeninfo.hardwareVersion.minor,
3937c478bd9Sstevel@tonic-gate 			    tokeninfo.firmwareVersion.major,
3947c478bd9Sstevel@tonic-gate 			    tokeninfo.firmwareVersion.minor,
3957c478bd9Sstevel@tonic-gate 			    tokeninfo.utcTime,
3967c478bd9Sstevel@tonic-gate 			    tokeninfo.ulMinPinLen,
3977c478bd9Sstevel@tonic-gate 			    tokeninfo.ulMaxPinLen);
3987c478bd9Sstevel@tonic-gate 
3997c478bd9Sstevel@tonic-gate 			display_token_flags(tokeninfo.flags);
4007c478bd9Sstevel@tonic-gate 		}
4017c478bd9Sstevel@tonic-gate 
4027c478bd9Sstevel@tonic-gate 		if (mlist == NULL) {
4037c478bd9Sstevel@tonic-gate 			rv = prov_funcs->C_GetMechanismList(prov_slots[i],
4047c478bd9Sstevel@tonic-gate 			    NULL_PTR, &mech_count);
4057c478bd9Sstevel@tonic-gate 			if (rv != CKR_OK) {
4067c478bd9Sstevel@tonic-gate 				cryptodebug(
4077c478bd9Sstevel@tonic-gate 				    "failed to call C_GetMechanismList() "
4087c478bd9Sstevel@tonic-gate 				    "from %s.", libname);
4097c478bd9Sstevel@tonic-gate 				rc = FAILURE;
4107c478bd9Sstevel@tonic-gate 				break;
4117c478bd9Sstevel@tonic-gate 			}
4127c478bd9Sstevel@tonic-gate 
4137c478bd9Sstevel@tonic-gate 			if (mech_count == 0) {
4147c478bd9Sstevel@tonic-gate 				/* no mechanisms in this slot */
4157c478bd9Sstevel@tonic-gate 				continue;
4167c478bd9Sstevel@tonic-gate 			}
4177c478bd9Sstevel@tonic-gate 
4187c478bd9Sstevel@tonic-gate 			pmech_list = malloc(mech_count *
4197c478bd9Sstevel@tonic-gate 			    sizeof (CK_MECHANISM_TYPE));
4207c478bd9Sstevel@tonic-gate 			if (pmech_list == NULL) {
4217c478bd9Sstevel@tonic-gate 				cryptodebug("out of memory");
4227c478bd9Sstevel@tonic-gate 				rc = FAILURE;
4237c478bd9Sstevel@tonic-gate 				break;
4247c478bd9Sstevel@tonic-gate 			}
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate 			/* Get the actual mechanism list */
4277c478bd9Sstevel@tonic-gate 			rv = prov_funcs->C_GetMechanismList(prov_slots[i],
4287c478bd9Sstevel@tonic-gate 			    pmech_list, &mech_count);
4297c478bd9Sstevel@tonic-gate 			if (rv != CKR_OK) {
4307c478bd9Sstevel@tonic-gate 				cryptodebug(
4317c478bd9Sstevel@tonic-gate 				    "failed to call C_GetMechanismList() "
4327c478bd9Sstevel@tonic-gate 				    "from %s.", libname);
43312240b1dSDarren J Moffat 				free(pmech_list);
4347c478bd9Sstevel@tonic-gate 				rc = FAILURE;
4357c478bd9Sstevel@tonic-gate 				break;
4367c478bd9Sstevel@tonic-gate 			}
4377c478bd9Sstevel@tonic-gate 		} else  {
4387c478bd9Sstevel@tonic-gate 			/* use the mechanism list passed in */
4397c478bd9Sstevel@tonic-gate 			rc = convert_mechlist(&pmech_list, &mech_count, mlist);
4407c478bd9Sstevel@tonic-gate 			if (rc != SUCCESS) {
4417c478bd9Sstevel@tonic-gate 				goto clean_exit;
4427c478bd9Sstevel@tonic-gate 			}
4437c478bd9Sstevel@tonic-gate 		}
4447c478bd9Sstevel@tonic-gate 		if (show_mechs)
4457c478bd9Sstevel@tonic-gate 			(void) printf(gettext("Mechanisms:\n"));
4467c478bd9Sstevel@tonic-gate 
4477c478bd9Sstevel@tonic-gate 		if (verbose && show_mechs) {
4487c478bd9Sstevel@tonic-gate 			display_verbose_mech_header();
4497c478bd9Sstevel@tonic-gate 		}
4507c478bd9Sstevel@tonic-gate 		/*
4517c478bd9Sstevel@tonic-gate 		 * Merge the current mechanism list into the returning
4527c478bd9Sstevel@tonic-gate 		 * mechanism list.
4537c478bd9Sstevel@tonic-gate 		 */
4547c478bd9Sstevel@tonic-gate 		for (j = 0; show_mechs && j < mech_count; j++) {
4552321aa36Sda73024 			CK_MECHANISM_TYPE	mech = pmech_list[j];
45612240b1dSDarren J Moffat 			CK_MECHANISM_INFO mech_info;
4572321aa36Sda73024 
45812240b1dSDarren J Moffat 			rv = prov_funcs->C_GetMechanismInfo(
45912240b1dSDarren J Moffat 			    prov_slots[i], mech, &mech_info);
46012240b1dSDarren J Moffat 			if (rv != CKR_OK) {
46112240b1dSDarren J Moffat 				cryptodebug(
46212240b1dSDarren J Moffat 				    "failed to call "
46312240b1dSDarren J Moffat 				    "C_GetMechanismInfo() from %s.",
46412240b1dSDarren J Moffat 				    libname);
46512240b1dSDarren J Moffat 				free(pmech_list);
46612240b1dSDarren J Moffat 				pmech_list = NULL;
46712240b1dSDarren J Moffat 				rc = FAILURE;
46812240b1dSDarren J Moffat 				break;
46912240b1dSDarren J Moffat 			}
47076d1b5a9Sda73024 			if (mech >= CKM_VENDOR_DEFINED) {
4712321aa36Sda73024 				(void) printf("%#lx", mech);
4722321aa36Sda73024 			} else {
4732321aa36Sda73024 				mech_name = pkcs11_mech2str(mech);
4747c478bd9Sstevel@tonic-gate 				(void) printf("%-29s", mech_name);
4752321aa36Sda73024 			}
4762321aa36Sda73024 
4777c478bd9Sstevel@tonic-gate 			if (verbose) {
4787c478bd9Sstevel@tonic-gate 				display_mech_info(&mech_info);
4797c478bd9Sstevel@tonic-gate 			}
4807c478bd9Sstevel@tonic-gate 			(void) printf("\n");
4817c478bd9Sstevel@tonic-gate 		}
48212240b1dSDarren J Moffat 		if (pmech_list)
48312240b1dSDarren J Moffat 			free(pmech_list);
4847c478bd9Sstevel@tonic-gate 		if (rc == FAILURE) {
4857c478bd9Sstevel@tonic-gate 			break;
4867c478bd9Sstevel@tonic-gate 		}
4877c478bd9Sstevel@tonic-gate 	}
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate 	if (rng_flag != NULL || rc == FAILURE) {
4907c478bd9Sstevel@tonic-gate 		goto clean_exit;
4917c478bd9Sstevel@tonic-gate 	}
4927c478bd9Sstevel@tonic-gate 
4937c478bd9Sstevel@tonic-gate clean_exit:
4947c478bd9Sstevel@tonic-gate 
4957c478bd9Sstevel@tonic-gate 	if (rc == FAILURE) {
4967c478bd9Sstevel@tonic-gate 		(void) printf(gettext(
4977c478bd9Sstevel@tonic-gate 		    "%s: failed to retrieve the mechanism list.\n"), libname);
4987c478bd9Sstevel@tonic-gate 	}
4997c478bd9Sstevel@tonic-gate 
5007c478bd9Sstevel@tonic-gate 	if (lib_initialized) {
5017c478bd9Sstevel@tonic-gate 		(void) prov_funcs->C_Finalize(NULL_PTR);
5027c478bd9Sstevel@tonic-gate 	}
5037c478bd9Sstevel@tonic-gate 
5047c478bd9Sstevel@tonic-gate 	if (dldesc != NULL) {
5057c478bd9Sstevel@tonic-gate 		(void) dlclose(dldesc);
5067c478bd9Sstevel@tonic-gate 	}
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate 	if (prov_slots != NULL) {
50912240b1dSDarren J Moffat 		free(prov_slots);
5107c478bd9Sstevel@tonic-gate 	}
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate 	return (rc);
5137c478bd9Sstevel@tonic-gate }
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate /*
5177c478bd9Sstevel@tonic-gate  * Display the mechanism policy for a user-level library
5187c478bd9Sstevel@tonic-gate  */
5197c478bd9Sstevel@tonic-gate int
list_policy_for_lib(char * libname)5207c478bd9Sstevel@tonic-gate list_policy_for_lib(char *libname)
5217c478bd9Sstevel@tonic-gate {
5227c478bd9Sstevel@tonic-gate 	uentry_t *puent = NULL;
5237c478bd9Sstevel@tonic-gate 	int rc;
5247c478bd9Sstevel@tonic-gate 
5257c478bd9Sstevel@tonic-gate 	if (libname == NULL) {
5267c478bd9Sstevel@tonic-gate 		/* should not happen */
5277c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
5287c478bd9Sstevel@tonic-gate 		cryptodebug("list_policy_for_lib() - libname is NULL.");
5297c478bd9Sstevel@tonic-gate 		return (FAILURE);
5307c478bd9Sstevel@tonic-gate 	}
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate 	/* Get the library entry from the pkcs11.conf file */
5337c478bd9Sstevel@tonic-gate 	if ((puent = getent_uef(libname)) == NULL) {
5347c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
5357c478bd9Sstevel@tonic-gate 		    gettext("%s does not exist."), libname);
5367c478bd9Sstevel@tonic-gate 		return (FAILURE);
5377c478bd9Sstevel@tonic-gate 	}
5387c478bd9Sstevel@tonic-gate 
5397c478bd9Sstevel@tonic-gate 	/* Print the policy for this library */
5407c478bd9Sstevel@tonic-gate 	rc = print_uef_policy(puent);
5417c478bd9Sstevel@tonic-gate 	free_uentry(puent);
5427c478bd9Sstevel@tonic-gate 
5437c478bd9Sstevel@tonic-gate 	return (rc);
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate /*
5487c478bd9Sstevel@tonic-gate  * Disable mechanisms for a user-level library
5497c478bd9Sstevel@tonic-gate  */
5507c478bd9Sstevel@tonic-gate int
disable_uef_lib(char * libname,boolean_t rndflag,boolean_t allflag,mechlist_t * marglist)5517c478bd9Sstevel@tonic-gate disable_uef_lib(char *libname, boolean_t rndflag, boolean_t allflag,
5527c478bd9Sstevel@tonic-gate     mechlist_t *marglist)
5537c478bd9Sstevel@tonic-gate {
5547c478bd9Sstevel@tonic-gate 	uentry_t	*puent;
5557c478bd9Sstevel@tonic-gate 	int	rc;
5567c478bd9Sstevel@tonic-gate 
5577c478bd9Sstevel@tonic-gate 	if (libname == NULL) {
5587c478bd9Sstevel@tonic-gate 		/* should not happen */
5597c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
5607c478bd9Sstevel@tonic-gate 		cryptodebug("disable_uef_lib() - libname is NULL.");
5617c478bd9Sstevel@tonic-gate 		return (FAILURE);
5627c478bd9Sstevel@tonic-gate 	}
5637c478bd9Sstevel@tonic-gate 
5647c478bd9Sstevel@tonic-gate 	/* Get the provider entry from the pkcs11.conf file */
5657c478bd9Sstevel@tonic-gate 	if ((puent = getent_uef(libname)) == NULL) {
5667c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
5677c478bd9Sstevel@tonic-gate 		    gettext("%s does not exist."), libname);
5687c478bd9Sstevel@tonic-gate 		return (FAILURE);
5697c478bd9Sstevel@tonic-gate 	}
5707c478bd9Sstevel@tonic-gate 
5717c478bd9Sstevel@tonic-gate 	/*
5727c478bd9Sstevel@tonic-gate 	 * Update the mechanism policy of this library entry, based on
5737c478bd9Sstevel@tonic-gate 	 * the current policy mode of the library and the mechanisms specified
5747c478bd9Sstevel@tonic-gate 	 * in CLI.
5757c478bd9Sstevel@tonic-gate 	 */
5767c478bd9Sstevel@tonic-gate 	if (allflag) {
5777c478bd9Sstevel@tonic-gate 		/*
5787c478bd9Sstevel@tonic-gate 		 * If disabling all, just need to clean up the policylist and
5797c478bd9Sstevel@tonic-gate 		 * set the flag_enabledlist flag to be B_TRUE.
5807c478bd9Sstevel@tonic-gate 		 */
5817c478bd9Sstevel@tonic-gate 		free_umechlist(puent->policylist);
5827c478bd9Sstevel@tonic-gate 		puent->policylist = NULL;
5837c478bd9Sstevel@tonic-gate 		puent->count = 0;
5847c478bd9Sstevel@tonic-gate 		puent->flag_enabledlist = B_TRUE;
5857c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
5867c478bd9Sstevel@tonic-gate 	} else if (marglist != NULL) {
5877c478bd9Sstevel@tonic-gate 		if (puent->flag_enabledlist == B_TRUE) {
5887c478bd9Sstevel@tonic-gate 			/*
5897c478bd9Sstevel@tonic-gate 			 * The current default policy mode of this library
5907c478bd9Sstevel@tonic-gate 			 * is "all are disabled, except ...", so if a
5917c478bd9Sstevel@tonic-gate 			 * specified mechanism is in the exception list
5927c478bd9Sstevel@tonic-gate 			 * (the policylist), delete it from the policylist.
5937c478bd9Sstevel@tonic-gate 			 */
5947c478bd9Sstevel@tonic-gate 			rc = update_policylist(puent, marglist, DELETE_MODE);
5957c478bd9Sstevel@tonic-gate 		} else {
5967c478bd9Sstevel@tonic-gate 			/*
5977c478bd9Sstevel@tonic-gate 			 * The current default policy mode of this library
5987c478bd9Sstevel@tonic-gate 			 * is "all are enabled", so if a specified mechanism
5997c478bd9Sstevel@tonic-gate 			 * is not in the exception list (policylist), add
6007c478bd9Sstevel@tonic-gate 			 * it into the policylist.
6017c478bd9Sstevel@tonic-gate 			 */
6027c478bd9Sstevel@tonic-gate 			rc = update_policylist(puent, marglist, ADD_MODE);
6037c478bd9Sstevel@tonic-gate 		}
6047c478bd9Sstevel@tonic-gate 	} else if (!rndflag) {
6057c478bd9Sstevel@tonic-gate 		/* should not happen */
6067c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
6077c478bd9Sstevel@tonic-gate 		cryptodebug("disable_uef_lib() - wrong arguments.");
6087c478bd9Sstevel@tonic-gate 		return (FAILURE);
6097c478bd9Sstevel@tonic-gate 	}
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 	if (rndflag)
6127c478bd9Sstevel@tonic-gate 		puent->flag_norandom = B_TRUE;
6137c478bd9Sstevel@tonic-gate 
6147c478bd9Sstevel@tonic-gate 	if (rc == FAILURE) {
6157c478bd9Sstevel@tonic-gate 		free_uentry(puent);
6167c478bd9Sstevel@tonic-gate 		return (FAILURE);
6177c478bd9Sstevel@tonic-gate 	}
6187c478bd9Sstevel@tonic-gate 
6197c478bd9Sstevel@tonic-gate 	/* Update the pkcs11.conf file with the updated entry */
6207c478bd9Sstevel@tonic-gate 	rc = update_pkcs11conf(puent);
6217c478bd9Sstevel@tonic-gate 	free_uentry(puent);
6227c478bd9Sstevel@tonic-gate 	return (rc);
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate /*
6277c478bd9Sstevel@tonic-gate  * Enable disabled mechanisms for a user-level library.
6287c478bd9Sstevel@tonic-gate  */
6297c478bd9Sstevel@tonic-gate int
enable_uef_lib(char * libname,boolean_t rndflag,boolean_t allflag,mechlist_t * marglist)6307c478bd9Sstevel@tonic-gate enable_uef_lib(char *libname, boolean_t rndflag, boolean_t allflag,
6317c478bd9Sstevel@tonic-gate     mechlist_t *marglist)
6327c478bd9Sstevel@tonic-gate {
6337c478bd9Sstevel@tonic-gate 	uentry_t	*puent;
6347c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 	if (libname == NULL) {
6377c478bd9Sstevel@tonic-gate 		/* should not happen */
6387c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
6397c478bd9Sstevel@tonic-gate 		cryptodebug("enable_uef_lib() - libname is NULL.");
6407c478bd9Sstevel@tonic-gate 		return (FAILURE);
6417c478bd9Sstevel@tonic-gate 	}
6427c478bd9Sstevel@tonic-gate 
6437c478bd9Sstevel@tonic-gate 	/* Get the provider entry from the pkcs11.conf file */
6447c478bd9Sstevel@tonic-gate 	if ((puent = getent_uef(libname)) == NULL) {
6457c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
6467c478bd9Sstevel@tonic-gate 		    gettext("%s does not exist."), libname);
6477c478bd9Sstevel@tonic-gate 		return (FAILURE);
6487c478bd9Sstevel@tonic-gate 	}
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate 	/*
6517c478bd9Sstevel@tonic-gate 	 * Update the mechanism policy of this library entry, based on
6527c478bd9Sstevel@tonic-gate 	 * the current policy mode of the library and the mechanisms
6537c478bd9Sstevel@tonic-gate 	 * specified in CLI.
6547c478bd9Sstevel@tonic-gate 	 */
6557c478bd9Sstevel@tonic-gate 	if (allflag) {
6567c478bd9Sstevel@tonic-gate 		/*
6577c478bd9Sstevel@tonic-gate 		 * If enabling all, what needs to be done are cleaning up the
6587c478bd9Sstevel@tonic-gate 		 * policylist and setting the "flag_enabledlist" flag to
6597c478bd9Sstevel@tonic-gate 		 * B_FALSE.
6607c478bd9Sstevel@tonic-gate 		 */
6617c478bd9Sstevel@tonic-gate 		free_umechlist(puent->policylist);
6627c478bd9Sstevel@tonic-gate 		puent->policylist = NULL;
6637c478bd9Sstevel@tonic-gate 		puent->count = 0;
6647c478bd9Sstevel@tonic-gate 		puent->flag_enabledlist = B_FALSE;
6657c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
6667c478bd9Sstevel@tonic-gate 	} else if (marglist != NULL) {
6677c478bd9Sstevel@tonic-gate 		if (puent->flag_enabledlist == B_TRUE) {
6687c478bd9Sstevel@tonic-gate 			/*
6697c478bd9Sstevel@tonic-gate 			 * The current default policy mode of this library
6707c478bd9Sstevel@tonic-gate 			 * is "all are disabled, except ...", so if a
6717c478bd9Sstevel@tonic-gate 			 * specified mechanism is not in the exception list
6727c478bd9Sstevel@tonic-gate 			 * (policylist), add it.
6737c478bd9Sstevel@tonic-gate 			 */
6747c478bd9Sstevel@tonic-gate 			rc = update_policylist(puent, marglist, ADD_MODE);
6757c478bd9Sstevel@tonic-gate 		} else {
6767c478bd9Sstevel@tonic-gate 			/*
6777c478bd9Sstevel@tonic-gate 			 * The current default policy mode of this library
6787c478bd9Sstevel@tonic-gate 			 * is "all are enabled, except", so if a specified
6797c478bd9Sstevel@tonic-gate 			 * mechanism is in the exception list (policylist),
6807c478bd9Sstevel@tonic-gate 			 * delete it.
6817c478bd9Sstevel@tonic-gate 			 */
6827c478bd9Sstevel@tonic-gate 			rc = update_policylist(puent, marglist, DELETE_MODE);
6837c478bd9Sstevel@tonic-gate 		}
6847c478bd9Sstevel@tonic-gate 	} else if (!rndflag) {
6857c478bd9Sstevel@tonic-gate 		/* should not come here */
6867c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
6877c478bd9Sstevel@tonic-gate 		cryptodebug("enable_uef_lib() - wrong arguments.");
6887c478bd9Sstevel@tonic-gate 		return (FAILURE);
6897c478bd9Sstevel@tonic-gate 	}
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 	if (rndflag)
6927c478bd9Sstevel@tonic-gate 		puent->flag_norandom = B_FALSE;
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate 	if (rc == FAILURE) {
6957c478bd9Sstevel@tonic-gate 		free_uentry(puent);
6967c478bd9Sstevel@tonic-gate 		return (FAILURE);
6977c478bd9Sstevel@tonic-gate 	}
6987c478bd9Sstevel@tonic-gate 
6997c478bd9Sstevel@tonic-gate 	/* Update the pkcs11.conf file with the updated entry */
7007c478bd9Sstevel@tonic-gate 	rc = update_pkcs11conf(puent);
7017c478bd9Sstevel@tonic-gate 	free_uentry(puent);
7027c478bd9Sstevel@tonic-gate 	return (rc);
7037c478bd9Sstevel@tonic-gate }
7047c478bd9Sstevel@tonic-gate 
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate /*
7077c478bd9Sstevel@tonic-gate  * Install a user-level library.
7087c478bd9Sstevel@tonic-gate  */
7097c478bd9Sstevel@tonic-gate int
install_uef_lib(char * libname)7107c478bd9Sstevel@tonic-gate install_uef_lib(char *libname)
7117c478bd9Sstevel@tonic-gate {
7127c478bd9Sstevel@tonic-gate 	uentry_t	*puent;
7137c478bd9Sstevel@tonic-gate 	struct stat 	statbuf;
7147c478bd9Sstevel@tonic-gate 	char	libpath[MAXPATHLEN];
7157c478bd9Sstevel@tonic-gate 	char	libbuf[MAXPATHLEN];
7167c478bd9Sstevel@tonic-gate 	char	*isa;
7177c478bd9Sstevel@tonic-gate 
7187c478bd9Sstevel@tonic-gate 	if (libname == NULL) {
7197c478bd9Sstevel@tonic-gate 		/* should not happen */
7207c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
7217c478bd9Sstevel@tonic-gate 		cryptodebug("install_uef_lib() - libname is NULL.");
7227c478bd9Sstevel@tonic-gate 		return (FAILURE);
7237c478bd9Sstevel@tonic-gate 	}
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate 	/* Check if the provider already exists in the framework */
7267c478bd9Sstevel@tonic-gate 	if ((puent = getent_uef(libname)) != NULL) {
7277c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("%s exists already."),
7287c478bd9Sstevel@tonic-gate 		    libname);
7297c478bd9Sstevel@tonic-gate 		free_uentry(puent);
7307c478bd9Sstevel@tonic-gate 		return (FAILURE);
7317c478bd9Sstevel@tonic-gate 	}
7327c478bd9Sstevel@tonic-gate 
7337c478bd9Sstevel@tonic-gate 	/*
7347c478bd9Sstevel@tonic-gate 	 * Check if the library exists in the system. if $ISA is in the
7357c478bd9Sstevel@tonic-gate 	 * path, only check the 32bit version.
7367c478bd9Sstevel@tonic-gate 	 */
7377c478bd9Sstevel@tonic-gate 	if (strlcpy(libbuf, libname, MAXPATHLEN) >= MAXPATHLEN) {
7387c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
7397c478bd9Sstevel@tonic-gate 		    gettext("the provider name is too long - %s"), libname);
7407c478bd9Sstevel@tonic-gate 		return (FAILURE);
7417c478bd9Sstevel@tonic-gate 	}
7427c478bd9Sstevel@tonic-gate 
7437c478bd9Sstevel@tonic-gate 	if ((isa = strstr(libbuf, PKCS11_ISA)) != NULL) {
7447c478bd9Sstevel@tonic-gate 		*isa = '\000';
7457c478bd9Sstevel@tonic-gate 		isa += strlen(PKCS11_ISA);
7467c478bd9Sstevel@tonic-gate 		(void) snprintf(libpath, sizeof (libpath), "%s%s%s", libbuf,
7477c478bd9Sstevel@tonic-gate 		    "/", isa);
7487c478bd9Sstevel@tonic-gate 	} else {
7497c478bd9Sstevel@tonic-gate 		(void) strlcpy(libpath, libname, sizeof (libpath));
7507c478bd9Sstevel@tonic-gate 	}
7517c478bd9Sstevel@tonic-gate 
7527c478bd9Sstevel@tonic-gate 	/* Check if it is same as the framework library */
7537c478bd9Sstevel@tonic-gate 	if (strcmp(libpath, UEF_FRAME_LIB) == 0) {
7547c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
7557c478bd9Sstevel@tonic-gate 		    "The framework library %s can not be installed."),
7567c478bd9Sstevel@tonic-gate 		    libname);
7577c478bd9Sstevel@tonic-gate 		return (FAILURE);
7587c478bd9Sstevel@tonic-gate 	}
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 	if (stat(libpath, &statbuf) != 0) {
7617c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("%s not found"), libname);
7627c478bd9Sstevel@tonic-gate 		return (FAILURE);
7637c478bd9Sstevel@tonic-gate 	}
7647c478bd9Sstevel@tonic-gate 
7657c478bd9Sstevel@tonic-gate 	/* Need to add "\n" to libname for adding into the config file */
7667c478bd9Sstevel@tonic-gate 	if (strlcat(libname, "\n", MAXPATHLEN) >= MAXPATHLEN) {
7677c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
7687c478bd9Sstevel@tonic-gate 		    "can not install %s; the name is too long."), libname);
7697c478bd9Sstevel@tonic-gate 		return (FAILURE);
7707c478bd9Sstevel@tonic-gate 	}
7717c478bd9Sstevel@tonic-gate 
772b5a2d845SHai-May Chao 	return (update_conf(_PATH_PKCS11_CONF, libname));
7737c478bd9Sstevel@tonic-gate 
7747c478bd9Sstevel@tonic-gate }
7757c478bd9Sstevel@tonic-gate 
7767c478bd9Sstevel@tonic-gate 
7777c478bd9Sstevel@tonic-gate /*
7787c478bd9Sstevel@tonic-gate  * Uninstall a user-level library.
7797c478bd9Sstevel@tonic-gate  */
7807c478bd9Sstevel@tonic-gate int
uninstall_uef_lib(char * libname)7817c478bd9Sstevel@tonic-gate uninstall_uef_lib(char *libname)
7827c478bd9Sstevel@tonic-gate {
7837c478bd9Sstevel@tonic-gate 	uentry_t	*puent;
7847c478bd9Sstevel@tonic-gate 	FILE	*pfile;
7857c478bd9Sstevel@tonic-gate 	FILE	*pfile_tmp;
7867c478bd9Sstevel@tonic-gate 	char 	buffer[BUFSIZ];
7877c478bd9Sstevel@tonic-gate 	char 	buffer2[BUFSIZ];
7887c478bd9Sstevel@tonic-gate 	char	tmpfile_name[MAXPATHLEN];
7897c478bd9Sstevel@tonic-gate 	char 	*name;
7907c478bd9Sstevel@tonic-gate 	boolean_t	found;
7917c478bd9Sstevel@tonic-gate 	boolean_t	in_package;
7927c478bd9Sstevel@tonic-gate 	int	len;
7937c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate 	if (libname == NULL) {
7967c478bd9Sstevel@tonic-gate 		/* should not happen */
7977c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
7987c478bd9Sstevel@tonic-gate 		cryptodebug("uninstall_uef_lib() - libname is NULL.");
7997c478bd9Sstevel@tonic-gate 		return (FAILURE);
8007c478bd9Sstevel@tonic-gate 	}
8017c478bd9Sstevel@tonic-gate 
8027c478bd9Sstevel@tonic-gate 	/* Check if the provider exists */
8037c478bd9Sstevel@tonic-gate 	if ((puent = getent_uef(libname)) == NULL) {
8047c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
8057c478bd9Sstevel@tonic-gate 		    gettext("%s does not exist."), libname);
8067c478bd9Sstevel@tonic-gate 		return (FAILURE);
8077c478bd9Sstevel@tonic-gate 	}
8087c478bd9Sstevel@tonic-gate 	free_uentry(puent);
8097c478bd9Sstevel@tonic-gate 
8107c478bd9Sstevel@tonic-gate 	/*  Open the pkcs11.conf file and lock it */
8117c478bd9Sstevel@tonic-gate 	if ((pfile = fopen(_PATH_PKCS11_CONF, "r+")) == NULL) {
8127c478bd9Sstevel@tonic-gate 		err = errno;
8137c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
8147c478bd9Sstevel@tonic-gate 		    gettext("failed to update the configuration - %s"),
8157c478bd9Sstevel@tonic-gate 		    strerror(err));
8167c478bd9Sstevel@tonic-gate 		cryptodebug("failed to open %s for write.", _PATH_PKCS11_CONF);
8177c478bd9Sstevel@tonic-gate 		return (FAILURE);
8187c478bd9Sstevel@tonic-gate 	}
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 	if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
8217c478bd9Sstevel@tonic-gate 		err = errno;
8227c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
8237c478bd9Sstevel@tonic-gate 		    gettext("failed to lock the configuration - %s"),
8247c478bd9Sstevel@tonic-gate 		    strerror(err));
8257c478bd9Sstevel@tonic-gate 		(void) fclose(pfile);
8267c478bd9Sstevel@tonic-gate 		return (FAILURE);
8277c478bd9Sstevel@tonic-gate 	}
8287c478bd9Sstevel@tonic-gate 
8297c478bd9Sstevel@tonic-gate 	/*
8307c478bd9Sstevel@tonic-gate 	 * Create a temporary file in the /etc/crypto directory to save
8317c478bd9Sstevel@tonic-gate 	 * the new configuration file first.
8327c478bd9Sstevel@tonic-gate 	 */
8337c478bd9Sstevel@tonic-gate 	(void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name));
8347c478bd9Sstevel@tonic-gate 	if (mkstemp(tmpfile_name) == -1) {
8357c478bd9Sstevel@tonic-gate 		err = errno;
8367c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
8377c478bd9Sstevel@tonic-gate 		    gettext("failed to create a temporary file - %s"),
8387c478bd9Sstevel@tonic-gate 		    strerror(err));
8397c478bd9Sstevel@tonic-gate 		(void) fclose(pfile);
8407c478bd9Sstevel@tonic-gate 		return (FAILURE);
8417c478bd9Sstevel@tonic-gate 	}
8427c478bd9Sstevel@tonic-gate 
8437c478bd9Sstevel@tonic-gate 	if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
8447c478bd9Sstevel@tonic-gate 		err = errno;
8457c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"),
8467c478bd9Sstevel@tonic-gate 		    tmpfile_name, strerror(err));
8477c478bd9Sstevel@tonic-gate 		if (unlink(tmpfile_name) != 0) {
8487c478bd9Sstevel@tonic-gate 			err = errno;
8497c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext(
8507c478bd9Sstevel@tonic-gate 			    "(Warning) failed to remove %s: %s"),
8517c478bd9Sstevel@tonic-gate 			    tmpfile_name, strerror(err));
8527c478bd9Sstevel@tonic-gate 		}
8537c478bd9Sstevel@tonic-gate 		(void) fclose(pfile);
8547c478bd9Sstevel@tonic-gate 		return (FAILURE);
8557c478bd9Sstevel@tonic-gate 	}
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 	/*
8597c478bd9Sstevel@tonic-gate 	 * Loop thru the config file.  If the library to be uninstalled
8607c478bd9Sstevel@tonic-gate 	 * is in a package, just comment it off.
8617c478bd9Sstevel@tonic-gate 	 */
8627c478bd9Sstevel@tonic-gate 	in_package = B_FALSE;
8637c478bd9Sstevel@tonic-gate 	while (fgets(buffer, BUFSIZ, pfile) != NULL) {
8647c478bd9Sstevel@tonic-gate 		found = B_FALSE;
8657c478bd9Sstevel@tonic-gate 		if (!(buffer[0] == ' ' || buffer[0] == '\n' ||
8667c478bd9Sstevel@tonic-gate 		    buffer[0] == '\t')) {
8677c478bd9Sstevel@tonic-gate 			if (strstr(buffer, " Start ") != NULL) {
8687c478bd9Sstevel@tonic-gate 				in_package = B_TRUE;
8697c478bd9Sstevel@tonic-gate 			} else if (strstr(buffer, " End ") != NULL) {
8707c478bd9Sstevel@tonic-gate 				in_package = B_FALSE;
8717c478bd9Sstevel@tonic-gate 			} else if (buffer[0] != '#') {
8727c478bd9Sstevel@tonic-gate 				(void) strlcpy(buffer2, buffer, BUFSIZ);
8737c478bd9Sstevel@tonic-gate 
8747c478bd9Sstevel@tonic-gate 				/* get rid of trailing '\n' */
8757c478bd9Sstevel@tonic-gate 				len = strlen(buffer2);
8767c478bd9Sstevel@tonic-gate 				if (buffer2[len-1] == '\n') {
8777c478bd9Sstevel@tonic-gate 					len--;
8787c478bd9Sstevel@tonic-gate 				}
8797c478bd9Sstevel@tonic-gate 				buffer2[len] = '\0';
8807c478bd9Sstevel@tonic-gate 
8817c478bd9Sstevel@tonic-gate 				if ((name = strtok(buffer2, SEP_COLON))
8827c478bd9Sstevel@tonic-gate 				    == NULL) {
8837c478bd9Sstevel@tonic-gate 					rc = FAILURE;
8847c478bd9Sstevel@tonic-gate 					break;
8857c478bd9Sstevel@tonic-gate 				} else if (strcmp(libname, name) == 0) {
8867c478bd9Sstevel@tonic-gate 					found = B_TRUE;
8877c478bd9Sstevel@tonic-gate 				}
8887c478bd9Sstevel@tonic-gate 			}
8897c478bd9Sstevel@tonic-gate 		}
8907c478bd9Sstevel@tonic-gate 
8917c478bd9Sstevel@tonic-gate 		if (found) {
8927c478bd9Sstevel@tonic-gate 			if (in_package) {
8937c478bd9Sstevel@tonic-gate 				(void) snprintf(buffer2, sizeof (buffer2),
8947c478bd9Sstevel@tonic-gate 				    "%s%s%s", "#", libname, "\n");
8957c478bd9Sstevel@tonic-gate 				if (fputs(buffer2, pfile_tmp) == EOF) {
8967c478bd9Sstevel@tonic-gate 					rc = FAILURE;
8977c478bd9Sstevel@tonic-gate 				}
8987c478bd9Sstevel@tonic-gate 			}
8997c478bd9Sstevel@tonic-gate 		} else {
9007c478bd9Sstevel@tonic-gate 			if (fputs(buffer, pfile_tmp) == EOF) {
9017c478bd9Sstevel@tonic-gate 				rc = FAILURE;
9027c478bd9Sstevel@tonic-gate 			}
9037c478bd9Sstevel@tonic-gate 		}
9047c478bd9Sstevel@tonic-gate 
9057c478bd9Sstevel@tonic-gate 		if (rc == FAILURE) {
9067c478bd9Sstevel@tonic-gate 			break;
9077c478bd9Sstevel@tonic-gate 		}
9087c478bd9Sstevel@tonic-gate 	}
9097c478bd9Sstevel@tonic-gate 
9107c478bd9Sstevel@tonic-gate 	if (rc == FAILURE) {
9117c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("write error."));
9127c478bd9Sstevel@tonic-gate 		(void) fclose(pfile);
9137c478bd9Sstevel@tonic-gate 		(void) fclose(pfile_tmp);
9147c478bd9Sstevel@tonic-gate 		if (unlink(tmpfile_name) != 0) {
9157c478bd9Sstevel@tonic-gate 			err = errno;
9167c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext(
9177c478bd9Sstevel@tonic-gate 			    "(Warning) failed to remove %s: %s"),
9187c478bd9Sstevel@tonic-gate 			    tmpfile_name, strerror(err));
9197c478bd9Sstevel@tonic-gate 		}
9207c478bd9Sstevel@tonic-gate 		return (FAILURE);
9217c478bd9Sstevel@tonic-gate 	}
9227c478bd9Sstevel@tonic-gate 
9237c478bd9Sstevel@tonic-gate 	(void) fclose(pfile);
9247c478bd9Sstevel@tonic-gate 	if (fclose(pfile_tmp) != 0) {
9257c478bd9Sstevel@tonic-gate 		err = errno;
9267c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
9277c478bd9Sstevel@tonic-gate 		    gettext("failed to close a temporary file - %s"),
9287c478bd9Sstevel@tonic-gate 		    strerror(err));
9297c478bd9Sstevel@tonic-gate 		return (FAILURE);
9307c478bd9Sstevel@tonic-gate 	}
9317c478bd9Sstevel@tonic-gate 
9327c478bd9Sstevel@tonic-gate 	/* Now update the real config file */
9337c478bd9Sstevel@tonic-gate 	if (rename(tmpfile_name, _PATH_PKCS11_CONF) == -1) {
9347c478bd9Sstevel@tonic-gate 		err = errno;
9357c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
9367c478bd9Sstevel@tonic-gate 		    gettext("failed to update the configuration - %s"),
9377c478bd9Sstevel@tonic-gate 		    strerror(err));
9387c478bd9Sstevel@tonic-gate 		cryptodebug("failed to rename %s to %s: %s", tmpfile,
9397c478bd9Sstevel@tonic-gate 		    _PATH_PKCS11_CONF, strerror(err));
9407c478bd9Sstevel@tonic-gate 		rc = FAILURE;
9417c478bd9Sstevel@tonic-gate 	} else if (chmod(_PATH_PKCS11_CONF,
9427c478bd9Sstevel@tonic-gate 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
9437c478bd9Sstevel@tonic-gate 		err = errno;
9447c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
9457c478bd9Sstevel@tonic-gate 		    gettext("failed to update the configuration - %s"),
9467c478bd9Sstevel@tonic-gate 		    strerror(err));
9477c478bd9Sstevel@tonic-gate 		cryptodebug("failed to chmod to %s: %s", _PATH_PKCS11_CONF,
9487c478bd9Sstevel@tonic-gate 		    strerror(err));
9497c478bd9Sstevel@tonic-gate 		rc = FAILURE;
9507c478bd9Sstevel@tonic-gate 	} else {
9517c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
9527c478bd9Sstevel@tonic-gate 	}
9537c478bd9Sstevel@tonic-gate 
9547c478bd9Sstevel@tonic-gate 	if ((rc == FAILURE) && (unlink(tmpfile_name) != 0)) {
9557c478bd9Sstevel@tonic-gate 		err = errno;
9567c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
9577c478bd9Sstevel@tonic-gate 		    "(Warning) failed to remove %s: %s"),
9587c478bd9Sstevel@tonic-gate 		    tmpfile_name, strerror(err));
9597c478bd9Sstevel@tonic-gate 	}
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 	return (rc);
9627c478bd9Sstevel@tonic-gate }
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate 
9657c478bd9Sstevel@tonic-gate int
display_policy(uentry_t * puent)9667c478bd9Sstevel@tonic-gate display_policy(uentry_t *puent)
9677c478bd9Sstevel@tonic-gate {
9687c478bd9Sstevel@tonic-gate 	CK_MECHANISM_TYPE	mech_id;
9692321aa36Sda73024 	const char		*mech_name;
9707c478bd9Sstevel@tonic-gate 	umechlist_t		*ptr;
9717c478bd9Sstevel@tonic-gate 
9727c478bd9Sstevel@tonic-gate 	if (puent == NULL) {
9737c478bd9Sstevel@tonic-gate 		return (SUCCESS);
9747c478bd9Sstevel@tonic-gate 	}
9757c478bd9Sstevel@tonic-gate 
9767c478bd9Sstevel@tonic-gate 	if (puent->flag_enabledlist == B_FALSE) {
9777c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s: all mechanisms are enabled"),
9787c478bd9Sstevel@tonic-gate 		    puent->name);
9797c478bd9Sstevel@tonic-gate 		ptr = puent->policylist;
9807c478bd9Sstevel@tonic-gate 		if (ptr == NULL) {
9817c478bd9Sstevel@tonic-gate 			(void) printf(".");
9827c478bd9Sstevel@tonic-gate 		} else {
9837c478bd9Sstevel@tonic-gate 			(void) printf(gettext(", except "));
9847c478bd9Sstevel@tonic-gate 			while (ptr != NULL) {
9857c478bd9Sstevel@tonic-gate 				mech_id = strtoul(ptr->name, NULL, 0);
9867c478bd9Sstevel@tonic-gate 				if (mech_id & CKO_VENDOR_DEFINED) {
9877c478bd9Sstevel@tonic-gate 					/* vendor defined mechanism */
9887c478bd9Sstevel@tonic-gate 					(void) printf("%s", ptr->name);
9897c478bd9Sstevel@tonic-gate 				} else {
99076d1b5a9Sda73024 					if (mech_id >= CKM_VENDOR_DEFINED) {
9912321aa36Sda73024 						(void) printf("%#lx", mech_id);
9922321aa36Sda73024 					} else {
9932321aa36Sda73024 						mech_name = pkcs11_mech2str(
9942321aa36Sda73024 						    mech_id);
9957c478bd9Sstevel@tonic-gate 						if (mech_name == NULL) {
9967c478bd9Sstevel@tonic-gate 							return (FAILURE);
9977c478bd9Sstevel@tonic-gate 						}
9987c478bd9Sstevel@tonic-gate 						(void) printf("%s", mech_name);
9992321aa36Sda73024 					}
10007c478bd9Sstevel@tonic-gate 				}
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate 				ptr = ptr->next;
10037c478bd9Sstevel@tonic-gate 				if (ptr == NULL) {
10047c478bd9Sstevel@tonic-gate 					(void) printf(".");
10057c478bd9Sstevel@tonic-gate 				} else {
10067c478bd9Sstevel@tonic-gate 					(void) printf(",");
10077c478bd9Sstevel@tonic-gate 				}
10087c478bd9Sstevel@tonic-gate 			}
10097c478bd9Sstevel@tonic-gate 		}
10107c478bd9Sstevel@tonic-gate 	} else { /* puent->flag_enabledlist == B_TRUE */
10117c478bd9Sstevel@tonic-gate 		(void) printf(gettext("%s: all mechanisms are disabled"),
10127c478bd9Sstevel@tonic-gate 		    puent->name);
10137c478bd9Sstevel@tonic-gate 		ptr = puent->policylist;
10147c478bd9Sstevel@tonic-gate 		if (ptr == NULL) {
10157c478bd9Sstevel@tonic-gate 			(void) printf(".");
10167c478bd9Sstevel@tonic-gate 		} else {
10177c478bd9Sstevel@tonic-gate 			(void) printf(gettext(", except "));
10187c478bd9Sstevel@tonic-gate 			while (ptr != NULL) {
10197c478bd9Sstevel@tonic-gate 				mech_id = strtoul(ptr->name, NULL, 0);
10207c478bd9Sstevel@tonic-gate 				if (mech_id & CKO_VENDOR_DEFINED) {
10217c478bd9Sstevel@tonic-gate 					/* vendor defined mechanism */
10227c478bd9Sstevel@tonic-gate 					(void) printf("%s", ptr->name);
10237c478bd9Sstevel@tonic-gate 				} else {
10247c478bd9Sstevel@tonic-gate 					mech_name = pkcs11_mech2str(mech_id);
10257c478bd9Sstevel@tonic-gate 					if (mech_name == NULL) {
10267c478bd9Sstevel@tonic-gate 						return (FAILURE);
10277c478bd9Sstevel@tonic-gate 					}
10287c478bd9Sstevel@tonic-gate 					(void) printf("%s", mech_name);
10297c478bd9Sstevel@tonic-gate 				}
10307c478bd9Sstevel@tonic-gate 				ptr = ptr->next;
10317c478bd9Sstevel@tonic-gate 				if (ptr == NULL) {
10327c478bd9Sstevel@tonic-gate 					(void) printf(".");
10337c478bd9Sstevel@tonic-gate 				} else {
10347c478bd9Sstevel@tonic-gate 					(void) printf(",");
10357c478bd9Sstevel@tonic-gate 				}
10367c478bd9Sstevel@tonic-gate 			}
10377c478bd9Sstevel@tonic-gate 		}
10387c478bd9Sstevel@tonic-gate 	}
10397c478bd9Sstevel@tonic-gate 	return (SUCCESS);
10407c478bd9Sstevel@tonic-gate }
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate 
10437c478bd9Sstevel@tonic-gate 
10447c478bd9Sstevel@tonic-gate /*
10457c478bd9Sstevel@tonic-gate  * Print out the mechanism policy for a user-level provider pointed by puent.
10467c478bd9Sstevel@tonic-gate  */
10477c478bd9Sstevel@tonic-gate int
print_uef_policy(uentry_t * puent)10487c478bd9Sstevel@tonic-gate print_uef_policy(uentry_t *puent)
10497c478bd9Sstevel@tonic-gate {
10507c478bd9Sstevel@tonic-gate 	flag_val_t rng_flag;
10517c478bd9Sstevel@tonic-gate 
10527c478bd9Sstevel@tonic-gate 	if (puent == NULL) {
10537c478bd9Sstevel@tonic-gate 		return (FAILURE);
10547c478bd9Sstevel@tonic-gate 	}
10557c478bd9Sstevel@tonic-gate 
10567c478bd9Sstevel@tonic-gate 	rng_flag = NO_RNG;
10577c478bd9Sstevel@tonic-gate 	if (list_mechlist_for_lib(puent->name, NULL, &rng_flag, B_TRUE,
10587c478bd9Sstevel@tonic-gate 	    B_FALSE, B_FALSE) != SUCCESS) {
10597c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
10607c478bd9Sstevel@tonic-gate 		    gettext("%s internal error."), puent->name);
10617c478bd9Sstevel@tonic-gate 		return (FAILURE);
10627c478bd9Sstevel@tonic-gate 	}
10637c478bd9Sstevel@tonic-gate 
10647c478bd9Sstevel@tonic-gate 	if (display_policy(puent) != SUCCESS) {
10657c478bd9Sstevel@tonic-gate 		goto failed_exit;
10667c478bd9Sstevel@tonic-gate 	}
10677c478bd9Sstevel@tonic-gate 
10687c478bd9Sstevel@tonic-gate 
10697c478bd9Sstevel@tonic-gate 	if (puent->flag_norandom == B_TRUE)
10707c478bd9Sstevel@tonic-gate 		/*
10710a85b835SDaniel Anderson 		 * TRANSLATION_NOTE
10727c478bd9Sstevel@tonic-gate 		 * "random" is a keyword and not to be translated.
10737c478bd9Sstevel@tonic-gate 		 */
10747c478bd9Sstevel@tonic-gate 		(void) printf(gettext(" %s is disabled."), "random");
10757c478bd9Sstevel@tonic-gate 	else {
10767c478bd9Sstevel@tonic-gate 		if (rng_flag == HAS_RNG)
10777c478bd9Sstevel@tonic-gate 			/*
10780a85b835SDaniel Anderson 			 * TRANSLATION_NOTE
10797c478bd9Sstevel@tonic-gate 			 * "random" is a keyword and not to be translated.
10807c478bd9Sstevel@tonic-gate 			 */
10817c478bd9Sstevel@tonic-gate 			(void) printf(gettext(" %s is enabled."), "random");
10827c478bd9Sstevel@tonic-gate 	}
10837c478bd9Sstevel@tonic-gate 	(void) printf("\n");
10847c478bd9Sstevel@tonic-gate 
10857c478bd9Sstevel@tonic-gate 	return (SUCCESS);
10867c478bd9Sstevel@tonic-gate 
10877c478bd9Sstevel@tonic-gate failed_exit:
10887c478bd9Sstevel@tonic-gate 
10897c478bd9Sstevel@tonic-gate 	(void) printf(gettext("\nout of memory.\n"));
10907c478bd9Sstevel@tonic-gate 	return (FAILURE);
10917c478bd9Sstevel@tonic-gate }
10927c478bd9Sstevel@tonic-gate 
10937c478bd9Sstevel@tonic-gate 
10947c478bd9Sstevel@tonic-gate /*
10957c478bd9Sstevel@tonic-gate  * Check if the mechanism is in the mechanism list.
10967c478bd9Sstevel@tonic-gate  */
10977c478bd9Sstevel@tonic-gate static boolean_t
is_in_policylist(midstr_t mechname,umechlist_t * plist)10987c478bd9Sstevel@tonic-gate is_in_policylist(midstr_t mechname, umechlist_t *plist)
10997c478bd9Sstevel@tonic-gate {
11007c478bd9Sstevel@tonic-gate 	boolean_t found = B_FALSE;
11017c478bd9Sstevel@tonic-gate 
11027c478bd9Sstevel@tonic-gate 	if (mechname == NULL) {
11037c478bd9Sstevel@tonic-gate 		return (B_FALSE);
11047c478bd9Sstevel@tonic-gate 	}
11057c478bd9Sstevel@tonic-gate 
11067c478bd9Sstevel@tonic-gate 	while (plist != NULL) {
11077c478bd9Sstevel@tonic-gate 		if (strcmp(plist->name, mechname) == 0) {
11087c478bd9Sstevel@tonic-gate 			found = B_TRUE;
11097c478bd9Sstevel@tonic-gate 			break;
11107c478bd9Sstevel@tonic-gate 		}
11117c478bd9Sstevel@tonic-gate 		plist = plist->next;
11127c478bd9Sstevel@tonic-gate 	}
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate 	return (found);
11157c478bd9Sstevel@tonic-gate }
11167c478bd9Sstevel@tonic-gate 
11177c478bd9Sstevel@tonic-gate 
11187c478bd9Sstevel@tonic-gate /*
11197c478bd9Sstevel@tonic-gate  * Update the pkcs11.conf file with the updated entry.
11207c478bd9Sstevel@tonic-gate  */
11217c478bd9Sstevel@tonic-gate int
update_pkcs11conf(uentry_t * puent)11227c478bd9Sstevel@tonic-gate update_pkcs11conf(uentry_t *puent)
11237c478bd9Sstevel@tonic-gate {
11247c478bd9Sstevel@tonic-gate 	FILE	*pfile;
11257c478bd9Sstevel@tonic-gate 	FILE	*pfile_tmp;
11267c478bd9Sstevel@tonic-gate 	char buffer[BUFSIZ];
11277c478bd9Sstevel@tonic-gate 	char buffer2[BUFSIZ];
11287c478bd9Sstevel@tonic-gate 	char tmpfile_name[MAXPATHLEN];
11297c478bd9Sstevel@tonic-gate 	char *name;
11307c478bd9Sstevel@tonic-gate 	char *str;
11317c478bd9Sstevel@tonic-gate 	int len;
11327c478bd9Sstevel@tonic-gate 	int rc = SUCCESS;
11337c478bd9Sstevel@tonic-gate 	boolean_t found;
11347c478bd9Sstevel@tonic-gate 
11357c478bd9Sstevel@tonic-gate 	if (puent == NULL) {
11367c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
11377c478bd9Sstevel@tonic-gate 		return (FAILURE);
11387c478bd9Sstevel@tonic-gate 	}
11397c478bd9Sstevel@tonic-gate 
11407c478bd9Sstevel@tonic-gate 	/* Open the pkcs11.conf file */
11417c478bd9Sstevel@tonic-gate 	if ((pfile = fopen(_PATH_PKCS11_CONF, "r+")) == NULL) {
11427c478bd9Sstevel@tonic-gate 		err = errno;
11437c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
11447c478bd9Sstevel@tonic-gate 		    gettext("failed to update the configuration - %s"),
11457c478bd9Sstevel@tonic-gate 		    strerror(err));
11467c478bd9Sstevel@tonic-gate 		cryptodebug("failed to open %s for write.", _PATH_PKCS11_CONF);
11477c478bd9Sstevel@tonic-gate 		return (FAILURE);
11487c478bd9Sstevel@tonic-gate 	}
11497c478bd9Sstevel@tonic-gate 
11507c478bd9Sstevel@tonic-gate 	/* Lock the pkcs11.conf file */
11517c478bd9Sstevel@tonic-gate 	if (lockf(fileno(pfile), F_TLOCK, 0) == -1) {
11527c478bd9Sstevel@tonic-gate 		err = errno;
11537c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
11547c478bd9Sstevel@tonic-gate 		    gettext("failed to update the configuration - %s"),
11557c478bd9Sstevel@tonic-gate 		    strerror(err));
11567c478bd9Sstevel@tonic-gate 		(void) fclose(pfile);
11577c478bd9Sstevel@tonic-gate 		return (FAILURE);
11587c478bd9Sstevel@tonic-gate 	}
11597c478bd9Sstevel@tonic-gate 
11607c478bd9Sstevel@tonic-gate 	/*
11617c478bd9Sstevel@tonic-gate 	 * Create a temporary file in the /etc/crypto directory to save
11627c478bd9Sstevel@tonic-gate 	 * updated configuration file first.
11637c478bd9Sstevel@tonic-gate 	 */
11647c478bd9Sstevel@tonic-gate 	(void) strlcpy(tmpfile_name, TMPFILE_TEMPLATE, sizeof (tmpfile_name));
11657c478bd9Sstevel@tonic-gate 	if (mkstemp(tmpfile_name) == -1) {
11667c478bd9Sstevel@tonic-gate 		err = errno;
11677c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
11687c478bd9Sstevel@tonic-gate 		    gettext("failed to create a temporary file - %s"),
11697c478bd9Sstevel@tonic-gate 		    strerror(err));
11707c478bd9Sstevel@tonic-gate 		(void) fclose(pfile);
11717c478bd9Sstevel@tonic-gate 		return (FAILURE);
11727c478bd9Sstevel@tonic-gate 	}
11737c478bd9Sstevel@tonic-gate 
11747c478bd9Sstevel@tonic-gate 	if ((pfile_tmp = fopen(tmpfile_name, "w")) == NULL) {
11757c478bd9Sstevel@tonic-gate 		err = errno;
11767c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("failed to open %s - %s"),
11777c478bd9Sstevel@tonic-gate 		    tmpfile_name, strerror(err));
11787c478bd9Sstevel@tonic-gate 		if (unlink(tmpfile_name) != 0) {
11797c478bd9Sstevel@tonic-gate 			err = errno;
11807c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext(
11817c478bd9Sstevel@tonic-gate 			    "(Warning) failed to remove %s: %s"),
11827c478bd9Sstevel@tonic-gate 			    tmpfile_name, strerror(err));
11837c478bd9Sstevel@tonic-gate 		}
11847c478bd9Sstevel@tonic-gate 		(void) fclose(pfile);
11857c478bd9Sstevel@tonic-gate 		return (FAILURE);
11867c478bd9Sstevel@tonic-gate 	}
11877c478bd9Sstevel@tonic-gate 
11887c478bd9Sstevel@tonic-gate 
11897c478bd9Sstevel@tonic-gate 	/*
11907c478bd9Sstevel@tonic-gate 	 * Loop thru entire pkcs11.conf file, update the entry to be
11917c478bd9Sstevel@tonic-gate 	 * updated and save the updated file to the temporary file first.
11927c478bd9Sstevel@tonic-gate 	 */
11937c478bd9Sstevel@tonic-gate 	while (fgets(buffer, BUFSIZ, pfile) != NULL) {
11947c478bd9Sstevel@tonic-gate 		found = B_FALSE;
11957c478bd9Sstevel@tonic-gate 		if (!(buffer[0] == '#' || buffer[0] == ' ' ||
11967c478bd9Sstevel@tonic-gate 		    buffer[0] == '\n'|| buffer[0] == '\t')) {
11977c478bd9Sstevel@tonic-gate 			/*
11987c478bd9Sstevel@tonic-gate 			 * Get the provider name from this line and check if
11997c478bd9Sstevel@tonic-gate 			 * this is the entry to be updated. Note: can not use
12007c478bd9Sstevel@tonic-gate 			 * "buffer" directly because strtok will change its
12017c478bd9Sstevel@tonic-gate 			 * value.
12027c478bd9Sstevel@tonic-gate 			 */
12037c478bd9Sstevel@tonic-gate 			(void) strlcpy(buffer2, buffer, BUFSIZ);
12047c478bd9Sstevel@tonic-gate 
12057c478bd9Sstevel@tonic-gate 			/* get rid of trailing '\n' */
12067c478bd9Sstevel@tonic-gate 			len = strlen(buffer2);
12077c478bd9Sstevel@tonic-gate 			if (buffer2[len-1] == '\n') {
12087c478bd9Sstevel@tonic-gate 				len--;
12097c478bd9Sstevel@tonic-gate 			}
12107c478bd9Sstevel@tonic-gate 			buffer2[len] = '\0';
12117c478bd9Sstevel@tonic-gate 
12127c478bd9Sstevel@tonic-gate 			if ((name = strtok(buffer2, SEP_COLON)) == NULL) {
12137c478bd9Sstevel@tonic-gate 				rc = FAILURE;
12147c478bd9Sstevel@tonic-gate 				break;
12157c478bd9Sstevel@tonic-gate 			} else if (strcmp(puent->name, name) == 0) {
12167c478bd9Sstevel@tonic-gate 				found = B_TRUE;
12177c478bd9Sstevel@tonic-gate 			}
12187c478bd9Sstevel@tonic-gate 		}
12197c478bd9Sstevel@tonic-gate 
12207c478bd9Sstevel@tonic-gate 		if (found) {
12217c478bd9Sstevel@tonic-gate 			/*
12227c478bd9Sstevel@tonic-gate 			 * This is the entry to be modified, get the updated
12237c478bd9Sstevel@tonic-gate 			 * string.
12247c478bd9Sstevel@tonic-gate 			 */
12257c478bd9Sstevel@tonic-gate 			if ((str = uent2str(puent)) == NULL) {
12267c478bd9Sstevel@tonic-gate 				rc = FAILURE;
12277c478bd9Sstevel@tonic-gate 				break;
12287c478bd9Sstevel@tonic-gate 			} else {
12297c478bd9Sstevel@tonic-gate 				(void) strlcpy(buffer, str, BUFSIZ);
12307c478bd9Sstevel@tonic-gate 				free(str);
12317c478bd9Sstevel@tonic-gate 			}
12327c478bd9Sstevel@tonic-gate 		}
12337c478bd9Sstevel@tonic-gate 
12347c478bd9Sstevel@tonic-gate 		if (fputs(buffer, pfile_tmp) == EOF) {
12357c478bd9Sstevel@tonic-gate 			err = errno;
12367c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext(
12377c478bd9Sstevel@tonic-gate 			    "failed to write to a temp file: %s."),
12387c478bd9Sstevel@tonic-gate 			    strerror(err));
12397c478bd9Sstevel@tonic-gate 			rc = FAILURE;
12407c478bd9Sstevel@tonic-gate 			break;
12417c478bd9Sstevel@tonic-gate 		}
12427c478bd9Sstevel@tonic-gate 	}
12437c478bd9Sstevel@tonic-gate 
12447c478bd9Sstevel@tonic-gate 	if (rc == FAILURE) {
12457c478bd9Sstevel@tonic-gate 		(void) fclose(pfile);
12467c478bd9Sstevel@tonic-gate 		(void) fclose(pfile_tmp);
12477c478bd9Sstevel@tonic-gate 		if (unlink(tmpfile_name) != 0) {
12487c478bd9Sstevel@tonic-gate 			err = errno;
12497c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext(
12507c478bd9Sstevel@tonic-gate 			    "(Warning) failed to remove %s: %s"),
12517c478bd9Sstevel@tonic-gate 			    tmpfile_name, strerror(err));
12527c478bd9Sstevel@tonic-gate 		}
12537c478bd9Sstevel@tonic-gate 		return (FAILURE);
12547c478bd9Sstevel@tonic-gate 	}
12557c478bd9Sstevel@tonic-gate 
12567c478bd9Sstevel@tonic-gate 	(void) fclose(pfile);
12577c478bd9Sstevel@tonic-gate 	if (fclose(pfile_tmp) != 0) {
12587c478bd9Sstevel@tonic-gate 		err = errno;
12597c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
12607c478bd9Sstevel@tonic-gate 		    gettext("failed to close %s: %s"), tmpfile_name,
12617c478bd9Sstevel@tonic-gate 		    strerror(err));
12627c478bd9Sstevel@tonic-gate 		return (FAILURE);
12637c478bd9Sstevel@tonic-gate 	}
12647c478bd9Sstevel@tonic-gate 
12657c478bd9Sstevel@tonic-gate 	/* Copy the temporary file to the pkcs11.conf file */
12667c478bd9Sstevel@tonic-gate 	if (rename(tmpfile_name, _PATH_PKCS11_CONF) == -1) {
12677c478bd9Sstevel@tonic-gate 		err = errno;
12687c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
12697c478bd9Sstevel@tonic-gate 		    gettext("failed to update the configuration - %s"),
12707c478bd9Sstevel@tonic-gate 		    strerror(err));
12717c478bd9Sstevel@tonic-gate 		cryptodebug("failed to rename %s to %s: %s", tmpfile_name,
12727c478bd9Sstevel@tonic-gate 		    _PATH_PKCS11_CONF, strerror(err));
12737c478bd9Sstevel@tonic-gate 		rc = FAILURE;
12747c478bd9Sstevel@tonic-gate 	} else if (chmod(_PATH_PKCS11_CONF,
12757c478bd9Sstevel@tonic-gate 	    S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1) {
12767c478bd9Sstevel@tonic-gate 		err = errno;
12777c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
12787c478bd9Sstevel@tonic-gate 		    gettext("failed to update the configuration - %s"),
12797c478bd9Sstevel@tonic-gate 		    strerror(err));
12807c478bd9Sstevel@tonic-gate 		cryptodebug("failed to chmod to %s: %s", _PATH_PKCS11_CONF,
12817c478bd9Sstevel@tonic-gate 		    strerror(err));
12827c478bd9Sstevel@tonic-gate 		rc = FAILURE;
12837c478bd9Sstevel@tonic-gate 	} else {
12847c478bd9Sstevel@tonic-gate 		rc = SUCCESS;
12857c478bd9Sstevel@tonic-gate 	}
12867c478bd9Sstevel@tonic-gate 
12877c478bd9Sstevel@tonic-gate 	if ((rc == FAILURE) && (unlink(tmpfile_name) != 0)) {
12887c478bd9Sstevel@tonic-gate 		err = errno;
12897c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext(
12907c478bd9Sstevel@tonic-gate 		    "(Warning) failed to remove %s: %s"),
12917c478bd9Sstevel@tonic-gate 		    tmpfile_name, strerror(err));
12927c478bd9Sstevel@tonic-gate 	}
12937c478bd9Sstevel@tonic-gate 
12947c478bd9Sstevel@tonic-gate 	return (rc);
12957c478bd9Sstevel@tonic-gate }
12967c478bd9Sstevel@tonic-gate 
12977c478bd9Sstevel@tonic-gate 
12987c478bd9Sstevel@tonic-gate /*
12997c478bd9Sstevel@tonic-gate  * Convert an uentry to a character string
13007c478bd9Sstevel@tonic-gate  */
13017c478bd9Sstevel@tonic-gate static char *
uent2str(uentry_t * puent)13027c478bd9Sstevel@tonic-gate uent2str(uentry_t *puent)
13037c478bd9Sstevel@tonic-gate {
13047c478bd9Sstevel@tonic-gate 	umechlist_t	*phead;
13057c478bd9Sstevel@tonic-gate 	boolean_t tok1_present = B_FALSE;
13067c478bd9Sstevel@tonic-gate 	char *buf;
13077c478bd9Sstevel@tonic-gate 	char blank_buf[128];
13087c478bd9Sstevel@tonic-gate 
13097c478bd9Sstevel@tonic-gate 	if (puent == NULL) {
13107c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
13117c478bd9Sstevel@tonic-gate 		return (NULL);
13127c478bd9Sstevel@tonic-gate 	}
13137c478bd9Sstevel@tonic-gate 
13147c478bd9Sstevel@tonic-gate 	buf = malloc(BUFSIZ);
13157c478bd9Sstevel@tonic-gate 	if (buf == NULL) {
13167c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("out of memory."));
13177c478bd9Sstevel@tonic-gate 		return (NULL);
13187c478bd9Sstevel@tonic-gate 	}
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate 	/* convert the library name */
13217c478bd9Sstevel@tonic-gate 	if (strlcpy(buf, puent->name, BUFSIZ) >= BUFSIZ) {
13227c478bd9Sstevel@tonic-gate 		free(buf);
13237c478bd9Sstevel@tonic-gate 		return (NULL);
13247c478bd9Sstevel@tonic-gate 	}
13257c478bd9Sstevel@tonic-gate 
13267c478bd9Sstevel@tonic-gate 
13277c478bd9Sstevel@tonic-gate 	/* convert the enabledlist or the disabledlist */
13287c478bd9Sstevel@tonic-gate 	if (puent->flag_enabledlist == B_TRUE) {
13297c478bd9Sstevel@tonic-gate 		if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) {
13307c478bd9Sstevel@tonic-gate 			free(buf);
13317c478bd9Sstevel@tonic-gate 			return (NULL);
13327c478bd9Sstevel@tonic-gate 		}
13337c478bd9Sstevel@tonic-gate 
13347c478bd9Sstevel@tonic-gate 		if (strlcat(buf, EF_ENABLED, BUFSIZ) >= BUFSIZ) {
13357c478bd9Sstevel@tonic-gate 			free(buf);
13367c478bd9Sstevel@tonic-gate 			return (NULL);
13377c478bd9Sstevel@tonic-gate 		}
13387c478bd9Sstevel@tonic-gate 
13397c478bd9Sstevel@tonic-gate 		phead = puent->policylist;
13407c478bd9Sstevel@tonic-gate 		while (phead != NULL) {
13417c478bd9Sstevel@tonic-gate 			if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) {
13427c478bd9Sstevel@tonic-gate 				free(buf);
13437c478bd9Sstevel@tonic-gate 				return (NULL);
13447c478bd9Sstevel@tonic-gate 			}
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate 			phead = phead->next;
13477c478bd9Sstevel@tonic-gate 			if (phead != NULL) {
13487c478bd9Sstevel@tonic-gate 				if (strlcat(buf, SEP_COMMA, BUFSIZ)
13497c478bd9Sstevel@tonic-gate 				    >= BUFSIZ) {
13507c478bd9Sstevel@tonic-gate 					free(buf);
13517c478bd9Sstevel@tonic-gate 					return (NULL);
13527c478bd9Sstevel@tonic-gate 				}
13537c478bd9Sstevel@tonic-gate 			}
13547c478bd9Sstevel@tonic-gate 		}
13557c478bd9Sstevel@tonic-gate 		tok1_present = B_TRUE;
13567c478bd9Sstevel@tonic-gate 	} else if (puent->policylist != NULL) {
13577c478bd9Sstevel@tonic-gate 		if (strlcat(buf, SEP_COLON, BUFSIZ) >= BUFSIZ) {
13587c478bd9Sstevel@tonic-gate 			free(buf);
13597c478bd9Sstevel@tonic-gate 			return (NULL);
13607c478bd9Sstevel@tonic-gate 		}
13617c478bd9Sstevel@tonic-gate 
13627c478bd9Sstevel@tonic-gate 		if (strlcat(buf, EF_DISABLED, BUFSIZ) >= BUFSIZ) {
13637c478bd9Sstevel@tonic-gate 			free(buf);
13647c478bd9Sstevel@tonic-gate 			return (NULL);
13657c478bd9Sstevel@tonic-gate 		}
13667c478bd9Sstevel@tonic-gate 		phead = puent->policylist;
13677c478bd9Sstevel@tonic-gate 		while (phead != NULL) {
13687c478bd9Sstevel@tonic-gate 			if (strlcat(buf, phead->name, BUFSIZ) >= BUFSIZ) {
13697c478bd9Sstevel@tonic-gate 				free(buf);
13707c478bd9Sstevel@tonic-gate 				return (NULL);
13717c478bd9Sstevel@tonic-gate 			}
13727c478bd9Sstevel@tonic-gate 
13737c478bd9Sstevel@tonic-gate 			phead = phead->next;
13747c478bd9Sstevel@tonic-gate 			if (phead != NULL) {
13757c478bd9Sstevel@tonic-gate 				if (strlcat(buf, SEP_COMMA, BUFSIZ)
13767c478bd9Sstevel@tonic-gate 				    >= BUFSIZ) {
13777c478bd9Sstevel@tonic-gate 					free(buf);
13787c478bd9Sstevel@tonic-gate 					return (NULL);
13797c478bd9Sstevel@tonic-gate 				}
13807c478bd9Sstevel@tonic-gate 			}
13817c478bd9Sstevel@tonic-gate 		}
13827c478bd9Sstevel@tonic-gate 		tok1_present = B_TRUE;
13837c478bd9Sstevel@tonic-gate 	}
13847c478bd9Sstevel@tonic-gate 
13857c478bd9Sstevel@tonic-gate 	if (puent->flag_norandom == B_TRUE) {
13867c478bd9Sstevel@tonic-gate 		if (strlcat(buf, (tok1_present ? SEP_SEMICOLON : SEP_COLON),
13877c478bd9Sstevel@tonic-gate 		    BUFSIZ) >= BUFSIZ) {
13887c478bd9Sstevel@tonic-gate 			free(buf);
13897c478bd9Sstevel@tonic-gate 			return (NULL);
13907c478bd9Sstevel@tonic-gate 		}
13917c478bd9Sstevel@tonic-gate 
13927c478bd9Sstevel@tonic-gate 		if (strlcat(buf, EF_NORANDOM, BUFSIZ) >= BUFSIZ) {
13937c478bd9Sstevel@tonic-gate 			free(buf);
13947c478bd9Sstevel@tonic-gate 			return (NULL);
13957c478bd9Sstevel@tonic-gate 		}
13967c478bd9Sstevel@tonic-gate 	}
13977c478bd9Sstevel@tonic-gate 
13987c478bd9Sstevel@tonic-gate 	if (strcmp(puent->name, METASLOT_KEYWORD) == 0) {
13997c478bd9Sstevel@tonic-gate 
14007c478bd9Sstevel@tonic-gate 		/* write the metaslot_status= value */
14017c478bd9Sstevel@tonic-gate 		if (strlcat(buf, (tok1_present ? SEP_SEMICOLON : SEP_COLON),
14027c478bd9Sstevel@tonic-gate 		    BUFSIZ) >= BUFSIZ) {
14037c478bd9Sstevel@tonic-gate 			free(buf);
14047c478bd9Sstevel@tonic-gate 			return (NULL);
14057c478bd9Sstevel@tonic-gate 		}
14067c478bd9Sstevel@tonic-gate 
14077c478bd9Sstevel@tonic-gate 		if (strlcat(buf, METASLOT_STATUS, BUFSIZ) >= BUFSIZ) {
14087c478bd9Sstevel@tonic-gate 			free(buf);
14097c478bd9Sstevel@tonic-gate 			return (NULL);
14107c478bd9Sstevel@tonic-gate 		}
14117c478bd9Sstevel@tonic-gate 
14127c478bd9Sstevel@tonic-gate 		if (puent->flag_metaslot_enabled) {
1413b5a2d845SHai-May Chao 			if (strlcat(buf, ENABLED_KEYWORD, BUFSIZ) >= BUFSIZ) {
14147c478bd9Sstevel@tonic-gate 				free(buf);
14157c478bd9Sstevel@tonic-gate 				return (NULL);
14167c478bd9Sstevel@tonic-gate 			}
14177c478bd9Sstevel@tonic-gate 		} else {
1418b5a2d845SHai-May Chao 			if (strlcat(buf, DISABLED_KEYWORD, BUFSIZ)
14197c478bd9Sstevel@tonic-gate 			    >= BUFSIZ) {
14207c478bd9Sstevel@tonic-gate 				free(buf);
14217c478bd9Sstevel@tonic-gate 				return (NULL);
14227c478bd9Sstevel@tonic-gate 			}
14237c478bd9Sstevel@tonic-gate 		}
14247c478bd9Sstevel@tonic-gate 
14257c478bd9Sstevel@tonic-gate 		if (!tok1_present) {
14267c478bd9Sstevel@tonic-gate 			tok1_present = B_TRUE;
14277c478bd9Sstevel@tonic-gate 		}
14287c478bd9Sstevel@tonic-gate 
14297c478bd9Sstevel@tonic-gate 		if (strlcat(buf, SEP_SEMICOLON, BUFSIZ) >= BUFSIZ) {
14307c478bd9Sstevel@tonic-gate 			free(buf);
14317c478bd9Sstevel@tonic-gate 			return (NULL);
14327c478bd9Sstevel@tonic-gate 		}
14337c478bd9Sstevel@tonic-gate 
14347c478bd9Sstevel@tonic-gate 		if (strlcat(buf, METASLOT_AUTO_KEY_MIGRATE, BUFSIZ) >= BUFSIZ) {
14357c478bd9Sstevel@tonic-gate 			free(buf);
14367c478bd9Sstevel@tonic-gate 			return (NULL);
14377c478bd9Sstevel@tonic-gate 		}
14387c478bd9Sstevel@tonic-gate 
14397c478bd9Sstevel@tonic-gate 		if (puent->flag_metaslot_auto_key_migrate) {
1440b5a2d845SHai-May Chao 			if (strlcat(buf, ENABLED_KEYWORD, BUFSIZ) >= BUFSIZ) {
14417c478bd9Sstevel@tonic-gate 				free(buf);
14427c478bd9Sstevel@tonic-gate 				return (NULL);
14437c478bd9Sstevel@tonic-gate 			}
14447c478bd9Sstevel@tonic-gate 		} else {
1445b5a2d845SHai-May Chao 			if (strlcat(buf, DISABLED_KEYWORD, BUFSIZ) >= BUFSIZ) {
14467c478bd9Sstevel@tonic-gate 				free(buf);
14477c478bd9Sstevel@tonic-gate 				return (NULL);
14487c478bd9Sstevel@tonic-gate 			}
14497c478bd9Sstevel@tonic-gate 		}
14507c478bd9Sstevel@tonic-gate 
14517c478bd9Sstevel@tonic-gate 		bzero(blank_buf, sizeof (blank_buf));
14527c478bd9Sstevel@tonic-gate 
14537c478bd9Sstevel@tonic-gate 		/* write metaslot_token= if specified */
14547c478bd9Sstevel@tonic-gate 		if (memcmp(puent->metaslot_ks_token, blank_buf,
14557c478bd9Sstevel@tonic-gate 		    TOKEN_LABEL_SIZE) != 0) {
14567c478bd9Sstevel@tonic-gate 			/* write the metaslot_status= value */
14577c478bd9Sstevel@tonic-gate 			if (strlcat(buf, (tok1_present ?
14587c478bd9Sstevel@tonic-gate 			    SEP_SEMICOLON : SEP_COLON), BUFSIZ) >= BUFSIZ) {
14597c478bd9Sstevel@tonic-gate 				free(buf);
14607c478bd9Sstevel@tonic-gate 				return (NULL);
14617c478bd9Sstevel@tonic-gate 			}
14627c478bd9Sstevel@tonic-gate 
14637c478bd9Sstevel@tonic-gate 			if (strlcat(buf, METASLOT_TOKEN, BUFSIZ) >= BUFSIZ) {
14647c478bd9Sstevel@tonic-gate 				free(buf);
14657c478bd9Sstevel@tonic-gate 				return (NULL);
14667c478bd9Sstevel@tonic-gate 			}
14677c478bd9Sstevel@tonic-gate 
14687c478bd9Sstevel@tonic-gate 			if (strlcat(buf,
14697c478bd9Sstevel@tonic-gate 			    (const char *)puent->metaslot_ks_token, BUFSIZ)
14707c478bd9Sstevel@tonic-gate 			    >= BUFSIZ) {
14717c478bd9Sstevel@tonic-gate 				free(buf);
14727c478bd9Sstevel@tonic-gate 				return (NULL);
14737c478bd9Sstevel@tonic-gate 			}
14747c478bd9Sstevel@tonic-gate 		}
14757c478bd9Sstevel@tonic-gate 
14767c478bd9Sstevel@tonic-gate 		/* write metaslot_slot= if specified */
14777c478bd9Sstevel@tonic-gate 		if (memcmp(puent->metaslot_ks_slot, blank_buf,
14787c478bd9Sstevel@tonic-gate 		    SLOT_DESCRIPTION_SIZE) != 0) {
14797c478bd9Sstevel@tonic-gate 			/* write the metaslot_status= value */
14807c478bd9Sstevel@tonic-gate 			if (strlcat(buf, (tok1_present ?
14817c478bd9Sstevel@tonic-gate 			    SEP_SEMICOLON : SEP_COLON), BUFSIZ) >= BUFSIZ) {
14827c478bd9Sstevel@tonic-gate 				free(buf);
14837c478bd9Sstevel@tonic-gate 				return (NULL);
14847c478bd9Sstevel@tonic-gate 			}
14857c478bd9Sstevel@tonic-gate 
14867c478bd9Sstevel@tonic-gate 			if (strlcat(buf, METASLOT_SLOT, BUFSIZ) >= BUFSIZ) {
14877c478bd9Sstevel@tonic-gate 				free(buf);
14887c478bd9Sstevel@tonic-gate 				return (NULL);
14897c478bd9Sstevel@tonic-gate 			}
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate 			if (strlcat(buf,
14927c478bd9Sstevel@tonic-gate 			    (const char *)puent->metaslot_ks_slot, BUFSIZ)
14937c478bd9Sstevel@tonic-gate 			    >= BUFSIZ) {
14947c478bd9Sstevel@tonic-gate 				free(buf);
14957c478bd9Sstevel@tonic-gate 				return (NULL);
14967c478bd9Sstevel@tonic-gate 			}
14977c478bd9Sstevel@tonic-gate 		}
14987c478bd9Sstevel@tonic-gate 	}
14997c478bd9Sstevel@tonic-gate 
15007c478bd9Sstevel@tonic-gate 	if (strlcat(buf, "\n", BUFSIZ) >= BUFSIZ) {
15017c478bd9Sstevel@tonic-gate 		free(buf);
15027c478bd9Sstevel@tonic-gate 		return (NULL);
15037c478bd9Sstevel@tonic-gate 	}
15047c478bd9Sstevel@tonic-gate 
15057c478bd9Sstevel@tonic-gate 	return (buf);
15067c478bd9Sstevel@tonic-gate }
15077c478bd9Sstevel@tonic-gate 
15087c478bd9Sstevel@tonic-gate 
15097c478bd9Sstevel@tonic-gate /*
15107c478bd9Sstevel@tonic-gate  * This function updates the default policy mode and the policy exception list
15117c478bd9Sstevel@tonic-gate  * for a user-level provider based on the mechanism specified in the disable
15127c478bd9Sstevel@tonic-gate  * or enable subcommand and the update mode.   This function is called by the
15137c478bd9Sstevel@tonic-gate  * enable_uef_lib() or disable_uef_lib().
15147c478bd9Sstevel@tonic-gate  */
15157c478bd9Sstevel@tonic-gate int
update_policylist(uentry_t * puent,mechlist_t * marglist,int update_mode)15167c478bd9Sstevel@tonic-gate update_policylist(uentry_t *puent, mechlist_t *marglist, int update_mode)
15177c478bd9Sstevel@tonic-gate {
15187c478bd9Sstevel@tonic-gate 	CK_MECHANISM_TYPE mech_type;
15197c478bd9Sstevel@tonic-gate 	midstr_t	midname;
15207c478bd9Sstevel@tonic-gate 	umechlist_t	*phead;
15217c478bd9Sstevel@tonic-gate 	umechlist_t	*pcur;
15227c478bd9Sstevel@tonic-gate 	umechlist_t	*pumech;
15237c478bd9Sstevel@tonic-gate 	boolean_t	found;
15247c478bd9Sstevel@tonic-gate 	int	rc = SUCCESS;
15257c478bd9Sstevel@tonic-gate 
15267c478bd9Sstevel@tonic-gate 	if ((puent == NULL) || (marglist == NULL)) {
15277c478bd9Sstevel@tonic-gate 		/* should not happen */
15287c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
15297c478bd9Sstevel@tonic-gate 		cryptodebug("update_policylist()- puent or marglist is NULL.");
15307c478bd9Sstevel@tonic-gate 		return (FAILURE);
15317c478bd9Sstevel@tonic-gate 	}
15327c478bd9Sstevel@tonic-gate 
15337c478bd9Sstevel@tonic-gate 	if ((update_mode != ADD_MODE) && (update_mode != DELETE_MODE)) {
15347c478bd9Sstevel@tonic-gate 		/* should not happen */
15357c478bd9Sstevel@tonic-gate 		cryptoerror(LOG_STDERR, gettext("internal error."));
15367c478bd9Sstevel@tonic-gate 		cryptodebug("update_policylist() - update_mode is incorrect.");
15377c478bd9Sstevel@tonic-gate 		return (FAILURE);
15387c478bd9Sstevel@tonic-gate 	}
15397c478bd9Sstevel@tonic-gate 
15407c478bd9Sstevel@tonic-gate 	/*
15417c478bd9Sstevel@tonic-gate 	 * For each mechanism operand, get its mechanism type first.
15427c478bd9Sstevel@tonic-gate 	 * If fails to get the mechanism type, the mechanism operand must be
15437c478bd9Sstevel@tonic-gate 	 * invalid, gives an warning and ignore it. Otherwise,
15447c478bd9Sstevel@tonic-gate 	 * - convert the mechanism type to the internal representation (hex)
15457c478bd9Sstevel@tonic-gate 	 *   in the pkcs11.conf file
15467c478bd9Sstevel@tonic-gate 	 * - If update_mode == DELETE_MODE,
15477c478bd9Sstevel@tonic-gate 	 *	If the mechanism is in the policy list, delete it.
15487c478bd9Sstevel@tonic-gate 	 *	If the mechanism is not in the policy list, do nothing.
15497c478bd9Sstevel@tonic-gate 	 * - If update_mode == ADD_MODE,
15507c478bd9Sstevel@tonic-gate 	 *	If the mechanism is not in the policy list, add it.
15517c478bd9Sstevel@tonic-gate 	 *	If the mechanism is in the policy list already, do nothing.
15527c478bd9Sstevel@tonic-gate 	 */
15537c478bd9Sstevel@tonic-gate 	while (marglist) {
15547c478bd9Sstevel@tonic-gate 		if (pkcs11_str2mech(marglist->name, &mech_type) != CKR_OK) {
15557c478bd9Sstevel@tonic-gate 			/*
15567c478bd9Sstevel@tonic-gate 			 * This mechanism is not a valid PKCS11 mechanism,
15577c478bd9Sstevel@tonic-gate 			 * give warning and ignore it.
15587c478bd9Sstevel@tonic-gate 			 */
15597c478bd9Sstevel@tonic-gate 			cryptoerror(LOG_STDERR, gettext(
15607c478bd9Sstevel@tonic-gate 			    "(Warning) %s is not a valid PKCS#11 mechanism."),
15617c478bd9Sstevel@tonic-gate 			    marglist->name);
15627c478bd9Sstevel@tonic-gate 			rc = FAILURE;
15637c478bd9Sstevel@tonic-gate 		} else {
15647c478bd9Sstevel@tonic-gate 			(void) snprintf(midname, sizeof (midname), "%#010x",
15657c478bd9Sstevel@tonic-gate 			    (int)mech_type);
15667c478bd9Sstevel@tonic-gate 			if (update_mode == DELETE_MODE) {
15677c478bd9Sstevel@tonic-gate 				found = B_FALSE;
15687c478bd9Sstevel@tonic-gate 				phead = pcur = puent->policylist;
15697c478bd9Sstevel@tonic-gate 				while (!found && pcur) {
15707c478bd9Sstevel@tonic-gate 					if (strcmp(pcur->name, midname) == 0) {
15717c478bd9Sstevel@tonic-gate 						found = B_TRUE;
15727c478bd9Sstevel@tonic-gate 					} else {
15737c478bd9Sstevel@tonic-gate 						phead = pcur;
15747c478bd9Sstevel@tonic-gate 						pcur = pcur->next;
15757c478bd9Sstevel@tonic-gate 					}
15767c478bd9Sstevel@tonic-gate 				}
15777c478bd9Sstevel@tonic-gate 
15787c478bd9Sstevel@tonic-gate 				if (found) {
15797c478bd9Sstevel@tonic-gate 					if (phead == pcur) {
15807c478bd9Sstevel@tonic-gate 						puent->policylist =
15817c478bd9Sstevel@tonic-gate 						    puent->policylist->next;
15827c478bd9Sstevel@tonic-gate 						free(pcur);
15837c478bd9Sstevel@tonic-gate 					} else {
15847c478bd9Sstevel@tonic-gate 						phead->next = pcur->next;
15857c478bd9Sstevel@tonic-gate 						free(pcur);
15867c478bd9Sstevel@tonic-gate 					}
15877c478bd9Sstevel@tonic-gate 					puent->count--;
15887c478bd9Sstevel@tonic-gate 					if (puent->count == 0) {
15897c478bd9Sstevel@tonic-gate 						puent->policylist = NULL;
15907c478bd9Sstevel@tonic-gate 					}
15917c478bd9Sstevel@tonic-gate 				}
15927c478bd9Sstevel@tonic-gate 			} else if (update_mode == ADD_MODE) {
15937c478bd9Sstevel@tonic-gate 				if (!is_in_policylist(midname,
15947c478bd9Sstevel@tonic-gate 				    puent->policylist)) {
15957c478bd9Sstevel@tonic-gate 					pumech = create_umech(midname);
15967c478bd9Sstevel@tonic-gate 					if (pumech == NULL) {
15977c478bd9Sstevel@tonic-gate 						rc = FAILURE;
15987c478bd9Sstevel@tonic-gate 						break;
15997c478bd9Sstevel@tonic-gate 					}
16007c478bd9Sstevel@tonic-gate 					phead = puent->policylist;
16017c478bd9Sstevel@tonic-gate 					puent->policylist = pumech;
16027c478bd9Sstevel@tonic-gate 					pumech->next = phead;
16037c478bd9Sstevel@tonic-gate 					puent->count++;
16047c478bd9Sstevel@tonic-gate 				}
16057c478bd9Sstevel@tonic-gate 			}
16067c478bd9Sstevel@tonic-gate 		}
16077c478bd9Sstevel@tonic-gate 		marglist = marglist->next;
16087c478bd9Sstevel@tonic-gate 	}
16097c478bd9Sstevel@tonic-gate 
16107c478bd9Sstevel@tonic-gate 	return (rc);
16117c478bd9Sstevel@tonic-gate }
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate /*
16147c478bd9Sstevel@tonic-gate  * Open a session to the given slot and check if we can do
16157c478bd9Sstevel@tonic-gate  * random numbers by asking for one byte.
16167c478bd9Sstevel@tonic-gate  */
16177c478bd9Sstevel@tonic-gate static boolean_t
check_random(CK_SLOT_ID slot_id,CK_FUNCTION_LIST_PTR prov_funcs)16187c478bd9Sstevel@tonic-gate check_random(CK_SLOT_ID slot_id, CK_FUNCTION_LIST_PTR prov_funcs)
16197c478bd9Sstevel@tonic-gate {
16207c478bd9Sstevel@tonic-gate 	CK_RV rv;
16217c478bd9Sstevel@tonic-gate 	CK_SESSION_HANDLE hSession;
16227c478bd9Sstevel@tonic-gate 	CK_BYTE test_byte;
16237c478bd9Sstevel@tonic-gate 	CK_BYTE_PTR test_byte_ptr = &test_byte;
16247c478bd9Sstevel@tonic-gate 
16257c478bd9Sstevel@tonic-gate 	rv = prov_funcs->C_OpenSession(slot_id, CKF_SERIAL_SESSION,
16267c478bd9Sstevel@tonic-gate 	    NULL_PTR, NULL, &hSession);
16277c478bd9Sstevel@tonic-gate 	if (rv != CKR_OK)
16287c478bd9Sstevel@tonic-gate 		return (B_FALSE);
16297c478bd9Sstevel@tonic-gate 
16307c478bd9Sstevel@tonic-gate 	/* We care only about the return value */
16317c478bd9Sstevel@tonic-gate 	rv = prov_funcs->C_GenerateRandom(hSession, test_byte_ptr,
16327c478bd9Sstevel@tonic-gate 	    sizeof (test_byte));
16337c478bd9Sstevel@tonic-gate 	(void) prov_funcs->C_CloseSession(hSession);
16347c478bd9Sstevel@tonic-gate 
16357c478bd9Sstevel@tonic-gate 	/*
16367c478bd9Sstevel@tonic-gate 	 * These checks are purely to determine whether the slot can do
16377c478bd9Sstevel@tonic-gate 	 * random numbers. So, we don't check whether the routine
16387c478bd9Sstevel@tonic-gate 	 * succeeds. The reason we check for CKR_RANDOM_NO_RNG also is that
16397c478bd9Sstevel@tonic-gate 	 * this error effectively means CKR_FUNCTION_NOT_SUPPORTED.
16407c478bd9Sstevel@tonic-gate 	 */
16417c478bd9Sstevel@tonic-gate 	if (rv != CKR_FUNCTION_NOT_SUPPORTED && rv != CKR_RANDOM_NO_RNG)
16427c478bd9Sstevel@tonic-gate 		return (B_TRUE);
16437c478bd9Sstevel@tonic-gate 	else
16447c478bd9Sstevel@tonic-gate 		return (B_FALSE);
16457c478bd9Sstevel@tonic-gate }
16467c478bd9Sstevel@tonic-gate 
16477c478bd9Sstevel@tonic-gate void
display_verbose_mech_header()16487c478bd9Sstevel@tonic-gate display_verbose_mech_header()
16497c478bd9Sstevel@tonic-gate {
16507c478bd9Sstevel@tonic-gate 	(void) printf("%28s %s", " ", HDR1);
16517c478bd9Sstevel@tonic-gate 	(void) printf("%28s %s", " ", HDR2);
16527c478bd9Sstevel@tonic-gate 	(void) printf("%28s %s", " ", HDR3);
16537c478bd9Sstevel@tonic-gate 	(void) printf("%28s %s", " ", HDR4);
16547c478bd9Sstevel@tonic-gate 	(void) printf("%28s %s", " ", HDR5);
16557c478bd9Sstevel@tonic-gate 	(void) printf("%28s %s", " ", HDR6);
16567c478bd9Sstevel@tonic-gate 	(void) printf("%-28.28s %s", gettext("mechanism name"), HDR7);
16577c478bd9Sstevel@tonic-gate 	/*
16580a85b835SDaniel Anderson 	 * TRANSLATION_NOTE
16597c478bd9Sstevel@tonic-gate 	 * Strictly for appearance's sake, the first header line should be
16607c478bd9Sstevel@tonic-gate 	 * as long as the length of the translated text above.  The format
16617c478bd9Sstevel@tonic-gate 	 * lengths should all match too.
16627c478bd9Sstevel@tonic-gate 	 */
16637c478bd9Sstevel@tonic-gate 	(void) printf("%28s ---- ---- "
16647c478bd9Sstevel@tonic-gate 	    "-  -  -  -  -  -  -  -  -  -  -  -  -  -\n",
16657c478bd9Sstevel@tonic-gate 	    gettext("----------------------------"));
16667c478bd9Sstevel@tonic-gate }
1667