1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate  * Use is subject to license terms.
25*0Sstevel@tonic-gate  */
26*0Sstevel@tonic-gate 
27*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate /*
30*0Sstevel@tonic-gate  * Administration for metaslot
31*0Sstevel@tonic-gate  *
32*0Sstevel@tonic-gate  * All the "list" operations will call functions in libpkcs11.so
33*0Sstevel@tonic-gate  * Normally, it doesn't make sense to call functions in libpkcs11.so directly
34*0Sstevel@tonic-gate  * because libpkcs11.so depends on the configuration file (pkcs11.conf) the
35*0Sstevel@tonic-gate  * cryptoadm command is trying to administer.  However, since metaslot
36*0Sstevel@tonic-gate  * is part of the framework, it is not possible to get information about
37*0Sstevel@tonic-gate  * it without actually calling functions in libpkcs11.so.
38*0Sstevel@tonic-gate  *
39*0Sstevel@tonic-gate  * So, for the listing operation, which won't modify the value of pkcs11.conf
40*0Sstevel@tonic-gate  * it is safe to call libpkcs11.so.
41*0Sstevel@tonic-gate  *
42*0Sstevel@tonic-gate  * For other operations that modifies the pkcs11.conf file, libpkcs11.so
43*0Sstevel@tonic-gate  * will not be called.
44*0Sstevel@tonic-gate  *
45*0Sstevel@tonic-gate  */
46*0Sstevel@tonic-gate 
47*0Sstevel@tonic-gate #include <cryptoutil.h>
48*0Sstevel@tonic-gate #include <stdio.h>
49*0Sstevel@tonic-gate #include <libintl.h>
50*0Sstevel@tonic-gate #include <dlfcn.h>
51*0Sstevel@tonic-gate #include <link.h>
52*0Sstevel@tonic-gate #include <strings.h>
53*0Sstevel@tonic-gate #include <security/cryptoki.h>
54*0Sstevel@tonic-gate #include <cryptoutil.h>
55*0Sstevel@tonic-gate #include "cryptoadm.h"
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate #define	METASLOT_ID	0
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate int
60*0Sstevel@tonic-gate list_metaslot_info(boolean_t show_mechs, boolean_t verbose,
61*0Sstevel@tonic-gate     mechlist_t *mechlist)
62*0Sstevel@tonic-gate {
63*0Sstevel@tonic-gate 	int rc = SUCCESS;
64*0Sstevel@tonic-gate 	CK_RV rv;
65*0Sstevel@tonic-gate 	CK_SLOT_INFO slot_info;
66*0Sstevel@tonic-gate 	CK_TOKEN_INFO token_info;
67*0Sstevel@tonic-gate 	CK_MECHANISM_TYPE_PTR pmech_list = NULL;
68*0Sstevel@tonic-gate 	CK_ULONG mech_count;
69*0Sstevel@tonic-gate 	int i;
70*0Sstevel@tonic-gate 	CK_RV (*Tmp_C_GetFunctionList)(CK_FUNCTION_LIST_PTR_PTR);
71*0Sstevel@tonic-gate 	CK_FUNCTION_LIST_PTR	funcs;
72*0Sstevel@tonic-gate 	void *dldesc = NULL;
73*0Sstevel@tonic-gate 	boolean_t lib_initialized = B_FALSE;
74*0Sstevel@tonic-gate 	uentry_t *puent;
75*0Sstevel@tonic-gate 	char buf[128];
76*0Sstevel@tonic-gate 
77*0Sstevel@tonic-gate 
78*0Sstevel@tonic-gate 	/*
79*0Sstevel@tonic-gate 	 * Display the system-wide metaslot settings as specified
80*0Sstevel@tonic-gate 	 * in pkcs11.conf file.
81*0Sstevel@tonic-gate 	 */
82*0Sstevel@tonic-gate 	if ((puent = getent_uef(METASLOT_KEYWORD)) == NULL) {
83*0Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
84*0Sstevel@tonic-gate 		    gettext("metaslot entry doesn't exist."));
85*0Sstevel@tonic-gate 		return (FAILURE);
86*0Sstevel@tonic-gate 	}
87*0Sstevel@tonic-gate 
88*0Sstevel@tonic-gate 	(void) printf(gettext("System-wide Meta Slot Configuration:\n"));
89*0Sstevel@tonic-gate 	/*
90*0Sstevel@tonic-gate 	 * TRANSLATION_NOTE:
91*0Sstevel@tonic-gate 	 * Strictly for appearance's sake, this line should be as long as
92*0Sstevel@tonic-gate 	 * the length of the translated text above.
93*0Sstevel@tonic-gate 	 */
94*0Sstevel@tonic-gate 	(void) printf(gettext("------------------------------------\n"));
95*0Sstevel@tonic-gate 	(void) printf(gettext("Status: %s\n"), puent->flag_metaslot_enabled ?
96*0Sstevel@tonic-gate 	    gettext("enabled") : gettext("disabled"));
97*0Sstevel@tonic-gate 	(void) printf(gettext("Sensitive Token Object Automatic Migrate: %s\n"),
98*0Sstevel@tonic-gate 	    puent->flag_metaslot_auto_key_migrate ? gettext("enabled") :
99*0Sstevel@tonic-gate 	    gettext("disabled"));
100*0Sstevel@tonic-gate 
101*0Sstevel@tonic-gate 	bzero(buf, sizeof (buf));
102*0Sstevel@tonic-gate 	if (memcmp(puent->metaslot_ks_slot, buf, SLOT_DESCRIPTION_SIZE) != 0) {
103*0Sstevel@tonic-gate 		(void) printf(gettext("Persistent object store slot: %s\n"),
104*0Sstevel@tonic-gate 		    puent->metaslot_ks_slot);
105*0Sstevel@tonic-gate 	}
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate 	if (memcmp(puent->metaslot_ks_token, buf, TOKEN_LABEL_SIZE) != 0) {
108*0Sstevel@tonic-gate 		(void) printf(gettext("Persistent object store token: %s\n"),
109*0Sstevel@tonic-gate 		    puent->metaslot_ks_token);
110*0Sstevel@tonic-gate 	}
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate 	if ((!verbose) && (!show_mechs)) {
113*0Sstevel@tonic-gate 		return (SUCCESS);
114*0Sstevel@tonic-gate 	}
115*0Sstevel@tonic-gate 
116*0Sstevel@tonic-gate 	if (verbose) {
117*0Sstevel@tonic-gate 		(void) printf(gettext("\nDetailed Meta Slot Information:\n"));
118*0Sstevel@tonic-gate 		/*
119*0Sstevel@tonic-gate 		 * TRANSLATION_NOTE:
120*0Sstevel@tonic-gate 		 * Strictly for appearance's sake, this line should be as
121*0Sstevel@tonic-gate 		 * long as the length of the translated text above.
122*0Sstevel@tonic-gate 		 */
123*0Sstevel@tonic-gate 		(void) printf(gettext("-------------------------------\n"));
124*0Sstevel@tonic-gate 	}
125*0Sstevel@tonic-gate 
126*0Sstevel@tonic-gate 	/*
127*0Sstevel@tonic-gate 	 * Need to actually make calls to libpkcs11.so to get
128*0Sstevel@tonic-gate 	 * information about metaslot.
129*0Sstevel@tonic-gate 	 */
130*0Sstevel@tonic-gate 
131*0Sstevel@tonic-gate 	dldesc = dlopen(UEF_FRAME_LIB, RTLD_NOW);
132*0Sstevel@tonic-gate 	if (dldesc == NULL) {
133*0Sstevel@tonic-gate 		char *dl_error;
134*0Sstevel@tonic-gate 		dl_error = dlerror();
135*0Sstevel@tonic-gate 		cryptodebug("Cannot load PKCS#11 framework library. "
136*0Sstevel@tonic-gate 		    "dlerror:%s", dl_error);
137*0Sstevel@tonic-gate 		return (FAILURE);
138*0Sstevel@tonic-gate 	}
139*0Sstevel@tonic-gate 
140*0Sstevel@tonic-gate 	/* Get the pointer to library's C_GetFunctionList() */
141*0Sstevel@tonic-gate 	Tmp_C_GetFunctionList = (CK_RV(*)())dlsym(dldesc, "C_GetFunctionList");
142*0Sstevel@tonic-gate 	if (Tmp_C_GetFunctionList == NULL) {
143*0Sstevel@tonic-gate 		cryptodebug("Cannot get the address of the C_GetFunctionList "
144*0Sstevel@tonic-gate 		    "from framework");
145*0Sstevel@tonic-gate 		rc = FAILURE;
146*0Sstevel@tonic-gate 		goto finish;
147*0Sstevel@tonic-gate 	}
148*0Sstevel@tonic-gate 
149*0Sstevel@tonic-gate 
150*0Sstevel@tonic-gate 	/* Get the provider's function list */
151*0Sstevel@tonic-gate 	rv = Tmp_C_GetFunctionList(&funcs);
152*0Sstevel@tonic-gate 	if (rv != CKR_OK) {
153*0Sstevel@tonic-gate 		cryptodebug("failed to call C_GetFunctionList in "
154*0Sstevel@tonic-gate 		    "framework library");
155*0Sstevel@tonic-gate 		rc = FAILURE;
156*0Sstevel@tonic-gate 		goto finish;
157*0Sstevel@tonic-gate 	}
158*0Sstevel@tonic-gate 
159*0Sstevel@tonic-gate 	/* Initialize this provider */
160*0Sstevel@tonic-gate 	rv = funcs->C_Initialize(NULL_PTR);
161*0Sstevel@tonic-gate 	if (rv != CKR_OK) {
162*0Sstevel@tonic-gate 		cryptodebug("C_Initialize failed with error code 0x%x\n", rv);
163*0Sstevel@tonic-gate 		rc = FAILURE;
164*0Sstevel@tonic-gate 		goto finish;
165*0Sstevel@tonic-gate 	} else {
166*0Sstevel@tonic-gate 		lib_initialized = B_TRUE;
167*0Sstevel@tonic-gate 	}
168*0Sstevel@tonic-gate 
169*0Sstevel@tonic-gate 	/*
170*0Sstevel@tonic-gate 	 * We know for sure that metaslot is slot 0 in the framework,
171*0Sstevel@tonic-gate 	 * so, we will do a C_GetSlotInfo() trying to see if it works.
172*0Sstevel@tonic-gate 	 * If it failes with CKR_SLOT_ID_INVALID, we know that metaslot
173*0Sstevel@tonic-gate 	 * is not really enabled.
174*0Sstevel@tonic-gate 	 */
175*0Sstevel@tonic-gate 	rv = funcs->C_GetSlotInfo(METASLOT_ID, &slot_info);
176*0Sstevel@tonic-gate 	if (rv == CKR_SLOT_ID_INVALID) {
177*0Sstevel@tonic-gate 		(void) printf(gettext("actual status: disabled.\n"));
178*0Sstevel@tonic-gate 		/*
179*0Sstevel@tonic-gate 		 * Even if the -m and -v flag is supplied, there's nothing
180*0Sstevel@tonic-gate 		 * interesting to display about metaslot since it is disabled,
181*0Sstevel@tonic-gate 		 * so, just stop right here.
182*0Sstevel@tonic-gate 		 */
183*0Sstevel@tonic-gate 		goto finish;
184*0Sstevel@tonic-gate 	}
185*0Sstevel@tonic-gate 
186*0Sstevel@tonic-gate 	if (rv != CKR_OK) {
187*0Sstevel@tonic-gate 		cryptodebug("C_GetSlotInfo failed with error "
188*0Sstevel@tonic-gate 		    "code 0x%x\n", rv);
189*0Sstevel@tonic-gate 		rc = FAILURE;
190*0Sstevel@tonic-gate 		goto finish;
191*0Sstevel@tonic-gate 	}
192*0Sstevel@tonic-gate 
193*0Sstevel@tonic-gate 	if (!verbose) {
194*0Sstevel@tonic-gate 		goto display_mechs;
195*0Sstevel@tonic-gate 	}
196*0Sstevel@tonic-gate 
197*0Sstevel@tonic-gate 	(void) printf(gettext("actual status: enabled.\n"));
198*0Sstevel@tonic-gate 
199*0Sstevel@tonic-gate 	(void) printf(gettext("Description: %.64s\n"),
200*0Sstevel@tonic-gate 	    slot_info.slotDescription);
201*0Sstevel@tonic-gate 
202*0Sstevel@tonic-gate 	(void) printf(gettext("Token Present: %s\n"),
203*0Sstevel@tonic-gate 	    (slot_info.flags & CKF_TOKEN_PRESENT ?
204*0Sstevel@tonic-gate 	    gettext("True") : gettext("False")));
205*0Sstevel@tonic-gate 
206*0Sstevel@tonic-gate 	rv = funcs->C_GetTokenInfo(METASLOT_ID, &token_info);
207*0Sstevel@tonic-gate 	if (rv != CKR_OK) {
208*0Sstevel@tonic-gate 		cryptodebug("C_GetTokenInfo failed with error "
209*0Sstevel@tonic-gate 		    "code 0x%x\n", rv);
210*0Sstevel@tonic-gate 		rc = FAILURE;
211*0Sstevel@tonic-gate 		goto finish;
212*0Sstevel@tonic-gate 	}
213*0Sstevel@tonic-gate 
214*0Sstevel@tonic-gate 	(void) printf(gettext("Token Label: %.32s\n"
215*0Sstevel@tonic-gate 	    "Manufacturer ID: %.32s\n"
216*0Sstevel@tonic-gate 	    "Model: %.16s\n"
217*0Sstevel@tonic-gate 	    "Serial Number: %.16s\n"
218*0Sstevel@tonic-gate 	    "Hardware Version: %d.%d\n"
219*0Sstevel@tonic-gate 	    "Firmware Version: %d.%d\n"
220*0Sstevel@tonic-gate 	    "UTC Time: %.16s\n"
221*0Sstevel@tonic-gate 	    "PIN Length: %d-%d\n"),
222*0Sstevel@tonic-gate 	    token_info.label,
223*0Sstevel@tonic-gate 	    token_info.manufacturerID,
224*0Sstevel@tonic-gate 	    token_info.model,
225*0Sstevel@tonic-gate 	    token_info.serialNumber,
226*0Sstevel@tonic-gate 	    token_info.hardwareVersion.major,
227*0Sstevel@tonic-gate 	    token_info.hardwareVersion.minor,
228*0Sstevel@tonic-gate 	    token_info.firmwareVersion.major,
229*0Sstevel@tonic-gate 	    token_info.firmwareVersion.minor,
230*0Sstevel@tonic-gate 	    token_info.utcTime,
231*0Sstevel@tonic-gate 	    token_info.ulMinPinLen,
232*0Sstevel@tonic-gate 	    token_info.ulMaxPinLen);
233*0Sstevel@tonic-gate 
234*0Sstevel@tonic-gate 	display_token_flags(token_info.flags);
235*0Sstevel@tonic-gate 
236*0Sstevel@tonic-gate 	if (!show_mechs) {
237*0Sstevel@tonic-gate 		goto finish;
238*0Sstevel@tonic-gate 	}
239*0Sstevel@tonic-gate 
240*0Sstevel@tonic-gate display_mechs:
241*0Sstevel@tonic-gate 
242*0Sstevel@tonic-gate 	if (mechlist == NULL) {
243*0Sstevel@tonic-gate 		rv = funcs->C_GetMechanismList(METASLOT_ID, NULL_PTR,
244*0Sstevel@tonic-gate 		    &mech_count);
245*0Sstevel@tonic-gate 		if (rv != CKR_OK) {
246*0Sstevel@tonic-gate 			cryptodebug("C_GetMechanismList failed with error "
247*0Sstevel@tonic-gate 			    "code 0x%x\n", rv);
248*0Sstevel@tonic-gate 			rc = FAILURE;
249*0Sstevel@tonic-gate 			goto finish;
250*0Sstevel@tonic-gate 		}
251*0Sstevel@tonic-gate 
252*0Sstevel@tonic-gate 		if (mech_count > 0) {
253*0Sstevel@tonic-gate 			pmech_list = malloc(mech_count *
254*0Sstevel@tonic-gate 			    sizeof (CK_MECHANISM_TYPE));
255*0Sstevel@tonic-gate 			if (pmech_list == NULL) {
256*0Sstevel@tonic-gate 				cryptodebug("out of memory");
257*0Sstevel@tonic-gate 				rc = FAILURE;
258*0Sstevel@tonic-gate 				goto finish;
259*0Sstevel@tonic-gate 			}
260*0Sstevel@tonic-gate 			rv = funcs->C_GetMechanismList(METASLOT_ID, pmech_list,
261*0Sstevel@tonic-gate 			    &mech_count);
262*0Sstevel@tonic-gate 			if (rv != CKR_OK) {
263*0Sstevel@tonic-gate 				cryptodebug("C_GetMechanismList failed with "
264*0Sstevel@tonic-gate 				    "error code 0x%x\n", rv);
265*0Sstevel@tonic-gate 				rc = FAILURE;
266*0Sstevel@tonic-gate 				goto finish;
267*0Sstevel@tonic-gate 			}
268*0Sstevel@tonic-gate 		}
269*0Sstevel@tonic-gate 	} else {
270*0Sstevel@tonic-gate 		rc = convert_mechlist(&pmech_list, &mech_count, mechlist);
271*0Sstevel@tonic-gate 		if (rc != SUCCESS) {
272*0Sstevel@tonic-gate 			goto finish;
273*0Sstevel@tonic-gate 		}
274*0Sstevel@tonic-gate 	}
275*0Sstevel@tonic-gate 
276*0Sstevel@tonic-gate 	(void) printf(gettext("Mechanisms:\n"));
277*0Sstevel@tonic-gate 	if (mech_count == 0) {
278*0Sstevel@tonic-gate 		/* should never be this case */
279*0Sstevel@tonic-gate 		(void) printf(gettext("No mechanisms\n"));
280*0Sstevel@tonic-gate 		goto finish;
281*0Sstevel@tonic-gate 	}
282*0Sstevel@tonic-gate 	if (verbose) {
283*0Sstevel@tonic-gate 		display_verbose_mech_header();
284*0Sstevel@tonic-gate 	}
285*0Sstevel@tonic-gate 
286*0Sstevel@tonic-gate 	for (i = 0; i < mech_count; i++) {
287*0Sstevel@tonic-gate 		(void) printf("%-29s", pkcs11_mech2str(pmech_list[i]));
288*0Sstevel@tonic-gate 		if (verbose) {
289*0Sstevel@tonic-gate 			CK_MECHANISM_INFO mech_info;
290*0Sstevel@tonic-gate 			rv = funcs->C_GetMechanismInfo(METASLOT_ID,
291*0Sstevel@tonic-gate 			    pmech_list[i], &mech_info);
292*0Sstevel@tonic-gate 			if (rv != CKR_OK) {
293*0Sstevel@tonic-gate 				cryptodebug("C_GetMechanismInfo failed with "
294*0Sstevel@tonic-gate 				    "error code 0x%x\n", rv);
295*0Sstevel@tonic-gate 				rc = FAILURE;
296*0Sstevel@tonic-gate 				goto finish;
297*0Sstevel@tonic-gate 			}
298*0Sstevel@tonic-gate 			display_mech_info(&mech_info);
299*0Sstevel@tonic-gate 		}
300*0Sstevel@tonic-gate 		(void) printf("\n");
301*0Sstevel@tonic-gate 	}
302*0Sstevel@tonic-gate 
303*0Sstevel@tonic-gate finish:
304*0Sstevel@tonic-gate 
305*0Sstevel@tonic-gate 	if ((rc == FAILURE) && (show_mechs)) {
306*0Sstevel@tonic-gate 		(void) printf(gettext(
307*0Sstevel@tonic-gate 		    "metaslot: failed to retrieve the mechanism list.\n"));
308*0Sstevel@tonic-gate 	}
309*0Sstevel@tonic-gate 
310*0Sstevel@tonic-gate 	if (lib_initialized) {
311*0Sstevel@tonic-gate 		(void) funcs->C_Finalize(NULL_PTR);
312*0Sstevel@tonic-gate 	}
313*0Sstevel@tonic-gate 
314*0Sstevel@tonic-gate 	if (dldesc != NULL) {
315*0Sstevel@tonic-gate 		(void) dlclose(dldesc);
316*0Sstevel@tonic-gate 	}
317*0Sstevel@tonic-gate 
318*0Sstevel@tonic-gate 	if (pmech_list != NULL) {
319*0Sstevel@tonic-gate 		(void) free(pmech_list);
320*0Sstevel@tonic-gate 	}
321*0Sstevel@tonic-gate 
322*0Sstevel@tonic-gate 	return (rc);
323*0Sstevel@tonic-gate }
324*0Sstevel@tonic-gate 
325*0Sstevel@tonic-gate int
326*0Sstevel@tonic-gate list_metaslot_policy()
327*0Sstevel@tonic-gate {
328*0Sstevel@tonic-gate 
329*0Sstevel@tonic-gate 	uentry_t *puent;
330*0Sstevel@tonic-gate 	int rc;
331*0Sstevel@tonic-gate 
332*0Sstevel@tonic-gate 	if ((puent = getent_uef(METASLOT_KEYWORD)) == NULL) {
333*0Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
334*0Sstevel@tonic-gate 		    gettext("metaslot entry doesn't exist."));
335*0Sstevel@tonic-gate 		return (FAILURE);
336*0Sstevel@tonic-gate 	}
337*0Sstevel@tonic-gate 
338*0Sstevel@tonic-gate 	rc = display_policy(puent);
339*0Sstevel@tonic-gate 	(void) printf("\n");
340*0Sstevel@tonic-gate 	free_uentry(puent);
341*0Sstevel@tonic-gate 	return (rc);
342*0Sstevel@tonic-gate }
343*0Sstevel@tonic-gate 
344*0Sstevel@tonic-gate /*
345*0Sstevel@tonic-gate  * disable metaslot and some of its configuration options
346*0Sstevel@tonic-gate  *
347*0Sstevel@tonic-gate  * If mechlist==NULL, and the other 2 flags are false, just disabled
348*0Sstevel@tonic-gate  * the metaslot feature.
349*0Sstevel@tonic-gate  *
350*0Sstevel@tonic-gate  * mechlist: list of mechanisms to disable
351*0Sstevel@tonic-gate  * allflag: if true, indicates all mechanisms should be disabled.
352*0Sstevel@tonic-gate  * auto_key_migrate_flag: if true, indicates auto key migrate should be disabled
353*0Sstevel@tonic-gate  */
354*0Sstevel@tonic-gate int
355*0Sstevel@tonic-gate disable_metaslot(mechlist_t *mechlist, boolean_t allflag,
356*0Sstevel@tonic-gate     boolean_t auto_key_migrate_flag)
357*0Sstevel@tonic-gate {
358*0Sstevel@tonic-gate 	uentry_t *puent;
359*0Sstevel@tonic-gate 	int rc = SUCCESS;
360*0Sstevel@tonic-gate 
361*0Sstevel@tonic-gate 	if ((puent = getent_uef(METASLOT_KEYWORD)) == NULL) {
362*0Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
363*0Sstevel@tonic-gate 		    gettext("metaslot entry doesn't exist."));
364*0Sstevel@tonic-gate 		return (FAILURE);
365*0Sstevel@tonic-gate 	}
366*0Sstevel@tonic-gate 
367*0Sstevel@tonic-gate 
368*0Sstevel@tonic-gate 	if ((mechlist == NULL) && (!auto_key_migrate_flag) && (!allflag)) {
369*0Sstevel@tonic-gate 		/* disable metaslot */
370*0Sstevel@tonic-gate 		puent->flag_metaslot_enabled = B_FALSE;
371*0Sstevel@tonic-gate 		goto write_to_file;
372*0Sstevel@tonic-gate 	}
373*0Sstevel@tonic-gate 
374*0Sstevel@tonic-gate 	if (auto_key_migrate_flag) {
375*0Sstevel@tonic-gate 		/* need to disable auto_key_migrate */
376*0Sstevel@tonic-gate 		puent->flag_metaslot_auto_key_migrate = B_FALSE;
377*0Sstevel@tonic-gate 	}
378*0Sstevel@tonic-gate 
379*0Sstevel@tonic-gate 	if ((mechlist == NULL) && (!allflag)) {
380*0Sstevel@tonic-gate 		goto write_to_file;
381*0Sstevel@tonic-gate 	}
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate 	/* disable specified mechanisms */
384*0Sstevel@tonic-gate 	if (allflag) {
385*0Sstevel@tonic-gate 		free_umechlist(puent->policylist);
386*0Sstevel@tonic-gate 		puent->policylist = NULL;
387*0Sstevel@tonic-gate 		puent->count = 0;
388*0Sstevel@tonic-gate 		puent->flag_enabledlist = B_TRUE;
389*0Sstevel@tonic-gate 		rc = SUCCESS;
390*0Sstevel@tonic-gate 	} else {
391*0Sstevel@tonic-gate 		if (puent->flag_enabledlist == B_TRUE) {
392*0Sstevel@tonic-gate 			/*
393*0Sstevel@tonic-gate 			 * The current default policy mode
394*0Sstevel@tonic-gate 			 * is "all are disabled, except ...", so if a
395*0Sstevel@tonic-gate 			 * specified mechanism is in the exception list
396*0Sstevel@tonic-gate 			 * (the policylist), delete it from the policylist.
397*0Sstevel@tonic-gate 			 */
398*0Sstevel@tonic-gate 			rc = update_policylist(puent, mechlist, DELETE_MODE);
399*0Sstevel@tonic-gate 		} else {
400*0Sstevel@tonic-gate 			/*
401*0Sstevel@tonic-gate 			 * The current default policy mode of this library
402*0Sstevel@tonic-gate 			 * is "all are enabled", so if a specified mechanism
403*0Sstevel@tonic-gate 			 * is not in the exception list (policylist), add
404*0Sstevel@tonic-gate 			 * it into the policylist.
405*0Sstevel@tonic-gate 			 */
406*0Sstevel@tonic-gate 			rc = update_policylist(puent, mechlist, ADD_MODE);
407*0Sstevel@tonic-gate 		}
408*0Sstevel@tonic-gate 	}
409*0Sstevel@tonic-gate 
410*0Sstevel@tonic-gate 	if (rc != SUCCESS) {
411*0Sstevel@tonic-gate 		goto finish;
412*0Sstevel@tonic-gate 	}
413*0Sstevel@tonic-gate 
414*0Sstevel@tonic-gate 	/* If all mechanisms are disabled, metaslot will be disabled as well */
415*0Sstevel@tonic-gate 	if ((puent->flag_enabledlist) && (puent->count == 0)) {
416*0Sstevel@tonic-gate 		puent->flag_metaslot_enabled = B_FALSE;
417*0Sstevel@tonic-gate 	}
418*0Sstevel@tonic-gate 
419*0Sstevel@tonic-gate write_to_file:
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate 	rc = update_pkcs11conf(puent);
422*0Sstevel@tonic-gate 
423*0Sstevel@tonic-gate finish:
424*0Sstevel@tonic-gate 	free_uentry(puent);
425*0Sstevel@tonic-gate 	return (rc);
426*0Sstevel@tonic-gate }
427*0Sstevel@tonic-gate 
428*0Sstevel@tonic-gate /*
429*0Sstevel@tonic-gate  * enable metaslot and some of its configuration options
430*0Sstevel@tonic-gate  *
431*0Sstevel@tonic-gate  * If mechlist==NULL, and the other flags are false, or not specified,
432*0Sstevel@tonic-gate  * just enable the metaslot feature.
433*0Sstevel@tonic-gate  *
434*0Sstevel@tonic-gate  * token: if specified, indicate label of token to be used as keystore.
435*0Sstevel@tonic-gate  * slot: if specified, indicate slot to be used as keystore.
436*0Sstevel@tonic-gate  * use_default: if true, indicate to use the default keystore.  It should
437*0Sstevel@tonic-gate  * 		not be specified if either token or slot is specified.
438*0Sstevel@tonic-gate  * mechlist: list of mechanisms to enable
439*0Sstevel@tonic-gate  * allflag: if true, indicates all mechanisms should be enabled.
440*0Sstevel@tonic-gate  * auto_key_migrate_flag: if true, indicates auto key migrate should be enabled
441*0Sstevel@tonic-gate  */
442*0Sstevel@tonic-gate int
443*0Sstevel@tonic-gate enable_metaslot(char *token, char *slot, boolean_t use_default,
444*0Sstevel@tonic-gate     mechlist_t *mechlist,  boolean_t allflag, boolean_t auto_key_migrate_flag)
445*0Sstevel@tonic-gate {
446*0Sstevel@tonic-gate 	uentry_t *puent;
447*0Sstevel@tonic-gate 	int rc = SUCCESS;
448*0Sstevel@tonic-gate 
449*0Sstevel@tonic-gate 	if ((puent = getent_uef(METASLOT_KEYWORD)) == NULL) {
450*0Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
451*0Sstevel@tonic-gate 		    gettext("metaslot entry doesn't exist."));
452*0Sstevel@tonic-gate 		return (FAILURE);
453*0Sstevel@tonic-gate 	}
454*0Sstevel@tonic-gate 
455*0Sstevel@tonic-gate 	puent->flag_metaslot_enabled = B_TRUE;
456*0Sstevel@tonic-gate 
457*0Sstevel@tonic-gate 	if (auto_key_migrate_flag) {
458*0Sstevel@tonic-gate 		/* need to enable auto_key_migrate */
459*0Sstevel@tonic-gate 		puent->flag_metaslot_auto_key_migrate = B_TRUE;
460*0Sstevel@tonic-gate 	}
461*0Sstevel@tonic-gate 
462*0Sstevel@tonic-gate 	if (allflag) {
463*0Sstevel@tonic-gate 		/*
464*0Sstevel@tonic-gate 		 * If enabling all, what needs to be done are cleaning up the
465*0Sstevel@tonic-gate 		 * policylist and setting the "flag_enabledlist" flag to
466*0Sstevel@tonic-gate 		 * B_FALSE.
467*0Sstevel@tonic-gate 		 */
468*0Sstevel@tonic-gate 		free_umechlist(puent->policylist);
469*0Sstevel@tonic-gate 		puent->policylist = NULL;
470*0Sstevel@tonic-gate 		puent->count = 0;
471*0Sstevel@tonic-gate 		puent->flag_enabledlist = B_FALSE;
472*0Sstevel@tonic-gate 		rc = SUCCESS;
473*0Sstevel@tonic-gate 	} else {
474*0Sstevel@tonic-gate 		if (mechlist) {
475*0Sstevel@tonic-gate 			if (puent->flag_enabledlist == B_TRUE) {
476*0Sstevel@tonic-gate 				/*
477*0Sstevel@tonic-gate 				 * The current default policy mode of this
478*0Sstevel@tonic-gate 				 * library is "all are disabled, except ...",
479*0Sstevel@tonic-gate 				 * so if a specified mechanism is not in the
480*0Sstevel@tonic-gate 				 * exception list (policylist), add it.
481*0Sstevel@tonic-gate 				 */
482*0Sstevel@tonic-gate 				rc = update_policylist(puent, mechlist,
483*0Sstevel@tonic-gate 				    ADD_MODE);
484*0Sstevel@tonic-gate 			} else {
485*0Sstevel@tonic-gate 				/*
486*0Sstevel@tonic-gate 				 * The current default policy mode of this
487*0Sstevel@tonic-gate 				 * library is "all are enabled, except", so if
488*0Sstevel@tonic-gate 				 * a specified  mechanism is in the exception
489*0Sstevel@tonic-gate 				 * list (policylist), delete it.
490*0Sstevel@tonic-gate 				 */
491*0Sstevel@tonic-gate 				rc = update_policylist(puent, mechlist,
492*0Sstevel@tonic-gate 				    DELETE_MODE);
493*0Sstevel@tonic-gate 			}
494*0Sstevel@tonic-gate 		}
495*0Sstevel@tonic-gate 	}
496*0Sstevel@tonic-gate 
497*0Sstevel@tonic-gate 	if (rc != SUCCESS) {
498*0Sstevel@tonic-gate 		goto finish;
499*0Sstevel@tonic-gate 	}
500*0Sstevel@tonic-gate 
501*0Sstevel@tonic-gate 	if (!use_default && !token && !slot) {
502*0Sstevel@tonic-gate 		/* no need to change metaslot keystore */
503*0Sstevel@tonic-gate 		goto write_to_file;
504*0Sstevel@tonic-gate 	}
505*0Sstevel@tonic-gate 
506*0Sstevel@tonic-gate 	(void) bzero((char *)puent->metaslot_ks_token, TOKEN_LABEL_SIZE);
507*0Sstevel@tonic-gate 	(void) bzero((char *)puent->metaslot_ks_slot, SLOT_DESCRIPTION_SIZE);
508*0Sstevel@tonic-gate 
509*0Sstevel@tonic-gate 	if (use_default) {
510*0Sstevel@tonic-gate 		(void) strlcpy((char *)puent->metaslot_ks_token,
511*0Sstevel@tonic-gate 		    SOFT_TOKEN_LABEL, TOKEN_LABEL_SIZE);
512*0Sstevel@tonic-gate 		(void) strlcpy((char *)puent->metaslot_ks_slot,
513*0Sstevel@tonic-gate 		    SOFT_SLOT_DESCRIPTION, SLOT_DESCRIPTION_SIZE);
514*0Sstevel@tonic-gate 	} else {
515*0Sstevel@tonic-gate 
516*0Sstevel@tonic-gate 		if (token) {
517*0Sstevel@tonic-gate 			(void) strlcpy((char *)puent->metaslot_ks_token, token,
518*0Sstevel@tonic-gate 			    TOKEN_LABEL_SIZE);
519*0Sstevel@tonic-gate 		}
520*0Sstevel@tonic-gate 
521*0Sstevel@tonic-gate 		if (slot) {
522*0Sstevel@tonic-gate 			(void) strlcpy((char *)puent->metaslot_ks_slot, slot,
523*0Sstevel@tonic-gate 			    SLOT_DESCRIPTION_SIZE);
524*0Sstevel@tonic-gate 		}
525*0Sstevel@tonic-gate 	}
526*0Sstevel@tonic-gate 
527*0Sstevel@tonic-gate 
528*0Sstevel@tonic-gate write_to_file:
529*0Sstevel@tonic-gate 
530*0Sstevel@tonic-gate 	rc = update_pkcs11conf(puent);
531*0Sstevel@tonic-gate 
532*0Sstevel@tonic-gate finish:
533*0Sstevel@tonic-gate 	free_uentry(puent);
534*0Sstevel@tonic-gate 	return (rc);
535*0Sstevel@tonic-gate }
536