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