1 /*	$NetBSD: pkcs11-destroy.c,v 1.7 2014/12/10 04:37:52 christos Exp $	*/
2 
3 /*
4  * Copyright (C) 2009  Internet Systems Consortium, Inc. ("ISC")
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC AND NETWORK ASSOCIATES DISCLAIMS
11  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12  * WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE
13  * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
16  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 /*
20  * Portions copyright (c) 2008 Nominet UK.  All rights reserved.
21  *
22  * Redistribution and use in source and binary forms, with or without
23  * modification, are permitted provided that the following conditions
24  * are met:
25  * 1. Redistributions of source code must retain the above copyright
26  *    notice, this list of conditions and the following disclaimer.
27  * 2. Redistributions in binary form must reproduce the above copyright
28  *    notice, this list of conditions and the following disclaimer in the
29  *    documentation and/or other materials provided with the distribution.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  */
42 
43 /* Id: pkcs11-destroy.c,v 1.8 2010/01/13 21:19:52 fdupont Exp  */
44 
45 /*
46  * pkcs11-destroy [-m module] [-s $slot] [-i $id | -l $label]
47  *                 [-p $pin] [ -w $wait ]
48  */
49 
50 /*! \file */
51 
52 #include <config.h>
53 
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <fcntl.h>
57 #include <errno.h>
58 #include <string.h>
59 #include <sys/types.h>
60 
61 #include <isc/commandline.h>
62 #include <isc/result.h>
63 #include <isc/types.h>
64 
65 #include <pk11/pk11.h>
66 #include <pk11/result.h>
67 
68 #ifdef WIN32
69 #define sleep(x)	Sleep(x)
70 #endif
71 
72 #if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun)))
73 #define getpassphrase(x)	getpass(x)
74 #endif
75 
76 int
77 main(int argc, char *argv[]) {
78 	isc_result_t result;
79 	CK_RV rv;
80 	CK_SLOT_ID slot = 0;
81 	CK_SESSION_HANDLE hSession;
82 	CK_BYTE attr_id[2];
83 	CK_OBJECT_HANDLE akey[50];
84 	pk11_context_t pctx;
85 	char *lib_name = NULL;
86 	char *label = NULL;
87 	char *pin = NULL;
88 	int error = 0;
89 	unsigned int id = 0, i = 0, wait = 5;
90 	int c, errflg = 0;
91 	CK_ULONG ulObjectCount;
92 	CK_ATTRIBUTE search_template[] = {
93 		{CKA_ID, &attr_id, sizeof(attr_id)}
94 	};
95 	unsigned int j, len;
96 
97 	while ((c = isc_commandline_parse(argc, argv, ":m:s:i:l:p:w:")) != -1) {
98 		switch (c) {
99 		case 'm':
100 			lib_name = isc_commandline_argument;
101 			break;
102 		case 's':
103 			slot = atoi(isc_commandline_argument);
104 			break;
105 		case 'i':
106 			id = atoi(isc_commandline_argument);
107 			id &= 0xffff;
108 			break;
109 		case 'l':
110 			label = isc_commandline_argument;
111 			break;
112 		case 'p':
113 			pin = isc_commandline_argument;
114 			break;
115 		case 'w':
116 			wait = atoi(isc_commandline_argument);
117 			break;
118 		case ':':
119 			fprintf(stderr,
120 				"Option -%c requires an operand\n",
121 				isc_commandline_option);
122 			errflg++;
123 			break;
124 		case '?':
125 		default:
126 			fprintf(stderr, "Unrecognised option: -%c\n",
127 				isc_commandline_option);
128 			errflg++;
129 		}
130 	}
131 
132 	if (errflg || (id && (label != NULL))) {
133 		fprintf(stderr, "Usage:\n");
134 		fprintf(stderr, "\tpkcs11-destroy [-m module] [-s slot] "
135 				"[-i id | -l label] [-p pin] [-w waittime]\n");
136 		exit(1);
137 	}
138 
139 	if (id) {
140 		attr_id[0] = (id >> 8) & 0xff;
141 		attr_id[1] = id & 0xff;
142 	} else if (label) {
143 		search_template[0].type = CKA_LABEL;
144 		search_template[0].pValue = label;
145 		search_template[0].ulValueLen = strlen(label);
146 	}
147 
148 	pk11_result_register();
149 
150 	/* Initialize the CRYPTOKI library */
151 	if (lib_name != NULL)
152 		pk11_set_lib_name(lib_name);
153 
154 	if (pin == NULL)
155 		pin = getpassphrase("Enter Pin: ");
156 
157 	result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_TRUE,
158 				  ISC_TRUE, (const char *) pin, slot);
159 	if (result == PK11_R_NORANDOMSERVICE ||
160 	    result == PK11_R_NODIGESTSERVICE ||
161 	    result == PK11_R_NOAESSERVICE) {
162 		fprintf(stderr, "Warning: %s\n", isc_result_totext(result));
163 		fprintf(stderr, "This HSM will not work with BIND 9 "
164 				"using native PKCS#11.\n");
165 	} else if (result != ISC_R_SUCCESS) {
166 		fprintf(stderr, "Unrecoverable error initializing "
167 				"PKCS#11: %s\n", isc_result_totext(result));
168 		exit(1);
169 	}
170 
171 	memset(pin, 0, strlen(pin));
172 
173 	hSession = pctx.session;
174 
175 	rv = pkcs_C_FindObjectsInit(hSession, search_template,
176 				    ((id != 0) || (label != NULL)) ? 1 : 0);
177 
178 	if (rv != CKR_OK) {
179 		fprintf(stderr, "C_FindObjectsInit: Error = 0x%.8lX\n", rv);
180 		error = 1;
181 		goto exit_session;
182 	}
183 
184 	rv = pkcs_C_FindObjects(hSession, akey, 50, &ulObjectCount);
185 	if (rv != CKR_OK) {
186 		fprintf(stderr, "C_FindObjects: Error = 0x%.8lX\n", rv);
187 		error = 1;
188 		goto exit_search;
189 	}
190 
191 	if (ulObjectCount == 0) {
192 		printf("No matching key objects found.\n");
193 		goto exit_search;
194 	} else
195 		printf("Key object%s found:\n", ulObjectCount > 1 ? "s" : "");
196 
197 	for (i = 0; i < ulObjectCount; i++) {
198 		CK_OBJECT_CLASS oclass = 0;
199 		CK_BYTE labelbuf[64 + 1];
200 		CK_BYTE idbuf[64];
201 		CK_ATTRIBUTE attr_template[] = {
202 			{CKA_CLASS, &oclass, sizeof(oclass)},
203 			{CKA_LABEL, labelbuf, sizeof(labelbuf) - 1},
204 			{CKA_ID, idbuf, sizeof(idbuf)}
205 		};
206 
207 		memset(labelbuf, 0, sizeof(labelbuf));
208 		memset(idbuf, 0, sizeof(idbuf));
209 
210 		rv = pkcs_C_GetAttributeValue(hSession, akey[i],
211 					      attr_template, 3);
212 		if (rv != CKR_OK) {
213 			fprintf(stderr,
214 				"C_GetAttributeValue[%u]: rv = 0x%.8lX\n",
215 				i, rv);
216 			error = 1;
217 			goto exit_search;
218 		}
219 		len = attr_template[2].ulValueLen;
220 		printf("  object[%u]: class %lu, label '%s', id[%lu] ",
221 		       i, oclass, labelbuf, attr_template[2].ulValueLen);
222 		if (len > 4)
223 			len = 4;
224 		if (len > 0)
225 			printf("0x");
226 		for (j = 0; j < len; j++)
227 			printf("%02x", idbuf[j]);
228 		if (attr_template[2].ulValueLen > len)
229 			printf("...\n");
230 		else
231 			printf("\n");
232 	}
233 
234 	if (wait != 0) {
235 		printf("WARNING: This action is irreversible! "
236 		       "Destroying key objects in %d seconds\n  ", wait);
237 		for (i = 0; i < wait; i++) {
238 			printf(".");
239 			fflush(stdout);
240 			sleep(1);
241 		}
242 		printf("\n");
243 	}
244 
245 	for (i = 0; i < ulObjectCount; i++) {
246 		rv = pkcs_C_DestroyObject(hSession, akey[i]);
247 		if (rv != CKR_OK) {
248 			fprintf(stderr,
249 				"C_DestroyObject[%u] failed: rv = 0x%.8lX\n",
250 				i, rv);
251 			error = 1;
252 		}
253 	}
254 
255 	if (error == 0)
256 		printf("Destruction complete.\n");
257 
258  exit_search:
259 	rv = pkcs_C_FindObjectsFinal(hSession);
260 	if (rv != CKR_OK) {
261 		fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8lX\n", rv);
262 		error = 1;
263 	}
264 
265  exit_session:
266 	pk11_return_session(&pctx);
267 	(void) pk11_finalize();
268 
269 	exit(error);
270 }
271