1 /* $NetBSD: pkcs11-list.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-list.c,v 1.7 2009/10/26 23:36:53 each Exp */ 44 45 /* pkcs11-list [-P] [-m module] [-s slot] [-i $id | -l $label] [-p $pin] */ 46 47 /*! \file */ 48 49 #include <config.h> 50 51 #include <stdio.h> 52 #include <stdlib.h> 53 #include <fcntl.h> 54 #include <errno.h> 55 #include <string.h> 56 #include <sys/types.h> 57 58 #include <isc/commandline.h> 59 #include <isc/result.h> 60 #include <isc/types.h> 61 62 #include <pk11/pk11.h> 63 #include <pk11/result.h> 64 65 #if !(defined(HAVE_GETPASSPHRASE) || (defined (__SVR4) && defined (__sun))) 66 #define getpassphrase(x) getpass(x) 67 #endif 68 69 int 70 main(int argc, char *argv[]) { 71 isc_result_t result; 72 CK_RV rv; 73 CK_SLOT_ID slot = 0; 74 CK_SESSION_HANDLE hSession; 75 CK_BYTE attr_id[2]; 76 CK_OBJECT_HANDLE akey[50]; 77 pk11_context_t pctx; 78 char *lib_name = NULL; 79 char *label = NULL; 80 char *pin = NULL; 81 isc_boolean_t error = ISC_FALSE, logon = ISC_TRUE, all = ISC_FALSE; 82 unsigned int i = 0, id = 0; 83 int c, errflg = 0; 84 CK_ULONG ulObjectCount; 85 CK_ATTRIBUTE search_template[] = { 86 {CKA_ID, &attr_id, sizeof(attr_id)} 87 }; 88 89 while ((c = isc_commandline_parse(argc, argv, ":m:s:i:l:p:P")) != -1) { 90 switch (c) { 91 case 'P': 92 logon = ISC_FALSE; 93 break; 94 case 'm': 95 lib_name = isc_commandline_argument; 96 break; 97 case 's': 98 slot = atoi(isc_commandline_argument); 99 break; 100 case 'i': 101 id = atoi(isc_commandline_argument); 102 id &= 0xffff; 103 break; 104 case 'l': 105 label = isc_commandline_argument; 106 break; 107 case 'p': 108 pin = isc_commandline_argument; 109 break; 110 case ':': 111 fprintf(stderr, "Option -%c requires an operand\n", 112 isc_commandline_option); 113 errflg++; 114 break; 115 case '?': 116 default: 117 fprintf(stderr, "Unrecognised option: -%c\n", 118 isc_commandline_option); 119 errflg++; 120 } 121 } 122 123 if (errflg) { 124 fprintf(stderr, "Usage:\n"); 125 fprintf(stderr, "\tpkcs11-list [-P] [-m module] [-s slot] " 126 "[-i id | -l label] [-p pin]\n"); 127 exit(1); 128 } 129 130 if (!id && (label == NULL)) 131 all = ISC_TRUE; 132 133 if (slot) 134 printf("slot %lu\n", slot); 135 136 if (id) { 137 printf("id %i\n", id); 138 attr_id[0] = (id >> 8) & 0xff; 139 attr_id[1] = id & 0xff; 140 } else if (label != NULL) { 141 printf("label %s\n", label); 142 search_template[0].type = CKA_LABEL; 143 search_template[0].pValue = label; 144 search_template[0].ulValueLen = strlen(label); 145 } 146 147 pk11_result_register(); 148 149 /* Initialize the CRYPTOKI library */ 150 if (lib_name != NULL) 151 pk11_set_lib_name(lib_name); 152 153 if (logon && pin == NULL) 154 pin = getpassphrase("Enter Pin: "); 155 156 result = pk11_get_session(&pctx, OP_ANY, ISC_FALSE, ISC_FALSE, 157 logon, pin, slot); 158 if (result == PK11_R_NORANDOMSERVICE || 159 result == PK11_R_NODIGESTSERVICE || 160 result == PK11_R_NOAESSERVICE) { 161 fprintf(stderr, "Warning: %s\n", isc_result_totext(result)); 162 fprintf(stderr, "This HSM will not work with BIND 9 " 163 "using native PKCS#11.\n"); 164 } else if (result != ISC_R_SUCCESS) { 165 fprintf(stderr, "Unrecoverable error initializing " 166 "PKCS#11: %s\n", isc_result_totext(result)); 167 fprintf(stderr, "Unrecoverable error initializing " 168 "PKCS#11: %s\n", isc_result_totext(result)); 169 exit(1); 170 } 171 172 if (pin != NULL) 173 memset(pin, 0, strlen(pin)); 174 175 hSession = pctx.session; 176 177 rv = pkcs_C_FindObjectsInit(hSession, search_template, all ? 0 : 1); 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 ulObjectCount = 1; 185 while (ulObjectCount) { 186 rv = pkcs_C_FindObjects(hSession, akey, 50, &ulObjectCount); 187 if (rv != CKR_OK) { 188 fprintf(stderr, 189 "C_FindObjects: Error = 0x%.8lX\n", 190 rv); 191 error = 1; 192 goto exit_search; 193 } 194 for (i = 0; i < ulObjectCount; i++) { 195 unsigned int j, len; 196 197 CK_OBJECT_CLASS oclass = 0; 198 CK_BYTE labelbuf[64 + 1]; 199 CK_BYTE idbuf[64]; 200 CK_ATTRIBUTE template[] = { 201 {CKA_CLASS, &oclass, sizeof(oclass)}, 202 {CKA_LABEL, labelbuf, sizeof(labelbuf) - 1}, 203 {CKA_ID, idbuf, sizeof(idbuf)} 204 }; 205 206 memset(labelbuf, 0, sizeof(labelbuf)); 207 memset(idbuf, 0, sizeof(idbuf)); 208 209 rv = pkcs_C_GetAttributeValue(hSession, akey[i], 210 template, 3); 211 if (rv != CKR_OK) { 212 fprintf(stderr, 213 "C_GetAttributeValue[%u]: " 214 "rv = 0x%.8lX\n", 215 i, rv); 216 if (rv == CKR_BUFFER_TOO_SMALL) 217 fprintf(stderr, 218 "%u too small: %lu %lu %lu\n", 219 i, 220 template[0].ulValueLen, 221 template[1].ulValueLen, 222 template[2].ulValueLen); 223 error = 1; 224 continue; 225 } 226 227 len = template[2].ulValueLen; 228 printf("object[%u]: handle %lu class %lu " 229 "label[%lu] '%s' id[%lu] ", 230 i, akey[i], oclass, 231 template[1].ulValueLen, 232 labelbuf, 233 template[2].ulValueLen); 234 if (len == 2) { 235 id = (idbuf[0] << 8) & 0xff00; 236 id |= idbuf[1] & 0xff; 237 printf("%u\n", id); 238 } else { 239 if (len > 8) 240 len = 8; 241 if (len > 0) 242 printf("0x"); 243 for (j = 0; j < len; j++) 244 printf("%02x", idbuf[j]); 245 if (template[2].ulValueLen > len) 246 printf("...\n"); 247 else 248 printf("\n"); 249 } 250 } 251 } 252 253 exit_search: 254 rv = pkcs_C_FindObjectsFinal(hSession); 255 if (rv != CKR_OK) { 256 fprintf(stderr, "C_FindObjectsFinal: Error = 0x%.8lX\n", rv); 257 error = 1; 258 } 259 260 exit_session: 261 pk11_return_session(&pctx); 262 (void) pk11_finalize(); 263 264 exit(error); 265 } 266