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