xref: /titanic_44/usr/src/cmd/cmd-crypto/pktool/delete.c (revision 7711facfe58561dd91d6ece0f5f41150c3956c83)
1*7711facfSdinak /*
2*7711facfSdinak  * CDDL HEADER START
3*7711facfSdinak  *
4*7711facfSdinak  * The contents of this file are subject to the terms of the
5*7711facfSdinak  * Common Development and Distribution License, Version 1.0 only
6*7711facfSdinak  * (the "License").  You may not use this file except in compliance
7*7711facfSdinak  * with the License.
8*7711facfSdinak  *
9*7711facfSdinak  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7711facfSdinak  * or http://www.opensolaris.org/os/licensing.
11*7711facfSdinak  * See the License for the specific language governing permissions
12*7711facfSdinak  * and limitations under the License.
13*7711facfSdinak  *
14*7711facfSdinak  * When distributing Covered Code, include this CDDL HEADER in each
15*7711facfSdinak  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7711facfSdinak  * If applicable, add the following below this CDDL HEADER, with the
17*7711facfSdinak  * fields enclosed by brackets "[]" replaced with your own identifying
18*7711facfSdinak  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7711facfSdinak  *
20*7711facfSdinak  * CDDL HEADER END
21*7711facfSdinak  */
22*7711facfSdinak /*
23*7711facfSdinak  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*7711facfSdinak  * Use is subject to license terms.
25*7711facfSdinak  */
26*7711facfSdinak 
27*7711facfSdinak #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*7711facfSdinak 
29*7711facfSdinak /*
30*7711facfSdinak  * This file implements the token object delete operation for this tool.
31*7711facfSdinak  * It loads the PKCS#11 modules, finds the object to delete, deletes it,
32*7711facfSdinak  * and cleans up.  User must be R/W logged into the token.
33*7711facfSdinak  */
34*7711facfSdinak 
35*7711facfSdinak #include <stdio.h>
36*7711facfSdinak #include <string.h>
37*7711facfSdinak #include <cryptoutil.h>
38*7711facfSdinak #include <security/cryptoki.h>
39*7711facfSdinak #include "common.h"
40*7711facfSdinak 
41*7711facfSdinak /*
42*7711facfSdinak  * Delete token objects.
43*7711facfSdinak  */
44*7711facfSdinak int
45*7711facfSdinak pk_delete(int argc, char *argv[])
46*7711facfSdinak {
47*7711facfSdinak 	int		opt;
48*7711facfSdinak 	extern int	optind;
49*7711facfSdinak 	extern char	*optarg;
50*7711facfSdinak 	char		*token_name = NULL;
51*7711facfSdinak 	char		*manuf_id = NULL;
52*7711facfSdinak 	char		*serial_no = NULL;
53*7711facfSdinak 	char		full_name[FULL_NAME_LEN];
54*7711facfSdinak 	boolean_t	public_objs = B_FALSE;
55*7711facfSdinak 	boolean_t	private_objs = B_FALSE;
56*7711facfSdinak 	CK_BYTE		*object_label = NULL;
57*7711facfSdinak 	int		obj_type = 0x00;
58*7711facfSdinak 	CK_SLOT_ID	slot_id;
59*7711facfSdinak 	CK_FLAGS	pin_state;
60*7711facfSdinak 	CK_UTF8CHAR_PTR	pin = NULL;
61*7711facfSdinak 	CK_ULONG	pinlen = 0;
62*7711facfSdinak 	CK_SESSION_HANDLE	sess;
63*7711facfSdinak 	CK_OBJECT_HANDLE	*objs;
64*7711facfSdinak 	CK_ULONG	num_objs;
65*7711facfSdinak 	CK_ATTRIBUTE	label = { CKA_LABEL, NULL, 0 };
66*7711facfSdinak 	CK_RV		rv = CKR_OK;
67*7711facfSdinak 	int		i;
68*7711facfSdinak 
69*7711facfSdinak 	cryptodebug("inside pk_delete");
70*7711facfSdinak 
71*7711facfSdinak 	/* Parse command line options.  Do NOT i18n/l10n. */
72*7711facfSdinak 	while ((opt = getopt(argc, argv, "p(private)P(public)l:(label)")) !=
73*7711facfSdinak 	    EOF) {
74*7711facfSdinak 		switch (opt) {
75*7711facfSdinak 		case 'p':	/* private objects */
76*7711facfSdinak 			private_objs = B_TRUE;
77*7711facfSdinak 			obj_type |= PK_PRIVATE_OBJ;
78*7711facfSdinak 			break;
79*7711facfSdinak 		case 'P':	/* public objects */
80*7711facfSdinak 			public_objs = B_TRUE;
81*7711facfSdinak 			obj_type |= PK_PUBLIC_OBJ;
82*7711facfSdinak 			break;
83*7711facfSdinak 		case 'l':	/* objects with specific label */
84*7711facfSdinak 			if (object_label)
85*7711facfSdinak 				return (PK_ERR_USAGE);
86*7711facfSdinak 			object_label = (CK_BYTE *)optarg;
87*7711facfSdinak 			break;
88*7711facfSdinak 		default:
89*7711facfSdinak 			return (PK_ERR_USAGE);
90*7711facfSdinak 			break;
91*7711facfSdinak 		}
92*7711facfSdinak 	}
93*7711facfSdinak 
94*7711facfSdinak 	/* At least one of public, private, or object label is required. */
95*7711facfSdinak 	if (!private_objs && !public_objs && object_label == NULL)
96*7711facfSdinak 		return (PK_ERR_USAGE);
97*7711facfSdinak 
98*7711facfSdinak 	/*
99*7711facfSdinak 	 * If object label is given but neither public/private is specified,
100*7711facfSdinak 	 * delete all objects with that label.
101*7711facfSdinak 	 */
102*7711facfSdinak 	if (!private_objs && !public_objs && object_label != NULL)
103*7711facfSdinak 		obj_type = PK_ALL_OBJ;
104*7711facfSdinak 
105*7711facfSdinak 	/* No additional args allowed. */
106*7711facfSdinak 	argc -= optind;
107*7711facfSdinak 	argv += optind;
108*7711facfSdinak 	if (argc)
109*7711facfSdinak 		return (PK_ERR_USAGE);
110*7711facfSdinak 	/* Done parsing command line options. */
111*7711facfSdinak 
112*7711facfSdinak 	/* Delete operation only supported on softtoken. */
113*7711facfSdinak 	if (token_name == NULL)
114*7711facfSdinak 		token_name = SOFT_TOKEN_LABEL;
115*7711facfSdinak 	if (manuf_id == NULL)
116*7711facfSdinak 		manuf_id = SOFT_MANUFACTURER_ID;
117*7711facfSdinak 	if (serial_no == NULL)
118*7711facfSdinak 		serial_no = SOFT_TOKEN_SERIAL;
119*7711facfSdinak 	full_token_name(token_name, manuf_id, serial_no, full_name);
120*7711facfSdinak 
121*7711facfSdinak 	/* Find the slot with token. */
122*7711facfSdinak 	if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id,
123*7711facfSdinak 	    &pin_state)) != CKR_OK) {
124*7711facfSdinak 		cryptoerror(LOG_STDERR, gettext(
125*7711facfSdinak 		    "Unable to find token %s (%s)."), full_name,
126*7711facfSdinak 		    pkcs11_strerror(rv));
127*7711facfSdinak 		return (PK_ERR_PK11);
128*7711facfSdinak 	}
129*7711facfSdinak 
130*7711facfSdinak 	/* Always get the user's PIN for delete operations. */
131*7711facfSdinak 	if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, &pin,
132*7711facfSdinak 	    &pinlen)) != CKR_OK) {
133*7711facfSdinak 		cryptoerror(LOG_STDERR, gettext(
134*7711facfSdinak 		    "Unable to get token passphrase (%s)."),
135*7711facfSdinak 		    pkcs11_strerror(rv));
136*7711facfSdinak 		quick_finish(NULL);
137*7711facfSdinak 		return (PK_ERR_PK11);
138*7711facfSdinak 	}
139*7711facfSdinak 
140*7711facfSdinak 	/* Log the user R/W into the token. */
141*7711facfSdinak 	if ((rv = quick_start(slot_id, CKF_RW_SESSION, pin, pinlen, &sess)) !=
142*7711facfSdinak 	    CKR_OK) {
143*7711facfSdinak 		cryptoerror(LOG_STDERR, gettext(
144*7711facfSdinak 		    "Unable to log into token (%s)."), pkcs11_strerror(rv));
145*7711facfSdinak 		quick_finish(sess);
146*7711facfSdinak 		return (PK_ERR_PK11);
147*7711facfSdinak 	}
148*7711facfSdinak 
149*7711facfSdinak 	/* Find the object(s) with the given label and/or type. */
150*7711facfSdinak 	if ((rv = find_objs(sess, obj_type, object_label, &objs, &num_objs)) !=
151*7711facfSdinak 	    CKR_OK) {
152*7711facfSdinak 		cryptoerror(LOG_STDERR, gettext(
153*7711facfSdinak 		    "Unable to find token objects (%s)."), pkcs11_strerror(rv));
154*7711facfSdinak 		quick_finish(sess);
155*7711facfSdinak 		return (PK_ERR_PK11);
156*7711facfSdinak 	}
157*7711facfSdinak 
158*7711facfSdinak 	if (num_objs == 0) {
159*7711facfSdinak 		(void) fprintf(stdout, gettext("No matching objects found.\n"));
160*7711facfSdinak 		quick_finish(sess);
161*7711facfSdinak 		return (0);
162*7711facfSdinak 	}
163*7711facfSdinak 
164*7711facfSdinak 	if (num_objs != 1) {
165*7711facfSdinak 		(void) fprintf(stdout, gettext(
166*7711facfSdinak 		    "Warning: %d matching objects found, deleting all.\n"),
167*7711facfSdinak 		    num_objs);
168*7711facfSdinak 		if (yesno(gettext("Continue with delete? "),
169*7711facfSdinak 		    gettext("Respond with yes or no.\n"), B_FALSE) == B_FALSE) {
170*7711facfSdinak 			quick_finish(sess);
171*7711facfSdinak 			return (0);
172*7711facfSdinak 		}
173*7711facfSdinak 	}
174*7711facfSdinak 
175*7711facfSdinak 	/* Destroy the objects if found. */
176*7711facfSdinak 	for (i = 0; i < num_objs; i++) {
177*7711facfSdinak 		/*
178*7711facfSdinak 		 * To give nice feedback to the user, get the object's
179*7711facfSdinak 		 * label before deleting it.
180*7711facfSdinak 		 */
181*7711facfSdinak 		cryptodebug("calling C_GetAttributeValue for label");
182*7711facfSdinak 		label.pValue = NULL;
183*7711facfSdinak 		label.ulValueLen = 0;
184*7711facfSdinak 		if (C_GetAttributeValue(sess, objs[i], &label, 1) == CKR_OK) {
185*7711facfSdinak 			if (label.ulValueLen != (CK_ULONG)-1 &&
186*7711facfSdinak 			    label.ulValueLen != 0 &&
187*7711facfSdinak 			    (label.pValue = malloc(label.ulValueLen)) != NULL) {
188*7711facfSdinak 				if (C_GetAttributeValue(sess, objs[i], &label,
189*7711facfSdinak 				    1) != CKR_OK) {
190*7711facfSdinak 					free(label.pValue);
191*7711facfSdinak 					label.pValue = NULL;
192*7711facfSdinak 					label.ulValueLen = 0;
193*7711facfSdinak 				}
194*7711facfSdinak 			} else {
195*7711facfSdinak 				label.ulValueLen = 0;
196*7711facfSdinak 			}
197*7711facfSdinak 		}
198*7711facfSdinak 
199*7711facfSdinak 		cryptodebug("calling C_DestroyObject");
200*7711facfSdinak 		if ((rv = C_DestroyObject(sess, objs[i])) != CKR_OK) {
201*7711facfSdinak 			if (label.pValue != NULL)
202*7711facfSdinak 				cryptoerror(LOG_STDERR, gettext(
203*7711facfSdinak 				    "Unable to delete object #%d \"%.*s\" "
204*7711facfSdinak 				    "(%s)."), i+1, label.ulValueLen,
205*7711facfSdinak 				    label.pValue, pkcs11_strerror(rv));
206*7711facfSdinak 			else
207*7711facfSdinak 				cryptoerror(LOG_STDERR, gettext(
208*7711facfSdinak 				    "Unable to delete object #%d (%s)."),
209*7711facfSdinak 				    i+1, pkcs11_strerror(rv));
210*7711facfSdinak 		} else {
211*7711facfSdinak 			if (label.pValue != NULL)
212*7711facfSdinak 				(void) fprintf(stdout, gettext("Object #%d "
213*7711facfSdinak 				    "\"%.*s\" successfully deleted.\n"),
214*7711facfSdinak 				    i+1, label.ulValueLen, label.pValue);
215*7711facfSdinak 			else
216*7711facfSdinak 				(void) fprintf(stdout, gettext(
217*7711facfSdinak 				    "Object #%d successfully deleted.\n"), i+1);
218*7711facfSdinak 		}
219*7711facfSdinak 
220*7711facfSdinak 		if (label.pValue != NULL)
221*7711facfSdinak 			free(label.pValue);
222*7711facfSdinak 	}
223*7711facfSdinak 
224*7711facfSdinak 	/* Clean up. */
225*7711facfSdinak 	quick_finish(sess);
226*7711facfSdinak 	return (0);
227*7711facfSdinak }
228