1*17Sdinak /* 2*17Sdinak * CDDL HEADER START 3*17Sdinak * 4*17Sdinak * The contents of this file are subject to the terms of the 5*17Sdinak * Common Development and Distribution License, Version 1.0 only 6*17Sdinak * (the "License"). You may not use this file except in compliance 7*17Sdinak * with the License. 8*17Sdinak * 9*17Sdinak * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*17Sdinak * or http://www.opensolaris.org/os/licensing. 11*17Sdinak * See the License for the specific language governing permissions 12*17Sdinak * and limitations under the License. 13*17Sdinak * 14*17Sdinak * When distributing Covered Code, include this CDDL HEADER in each 15*17Sdinak * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*17Sdinak * If applicable, add the following below this CDDL HEADER, with the 17*17Sdinak * fields enclosed by brackets "[]" replaced with your own identifying 18*17Sdinak * information: Portions Copyright [yyyy] [name of copyright owner] 19*17Sdinak * 20*17Sdinak * CDDL HEADER END 21*17Sdinak */ 22*17Sdinak /* 23*17Sdinak * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*17Sdinak * Use is subject to license terms. 25*17Sdinak */ 26*17Sdinak 27*17Sdinak #pragma ident "%Z%%M% %I% %E% SMI" 28*17Sdinak 29*17Sdinak /* 30*17Sdinak * This file implements the token object list operation for this tool. 31*17Sdinak * It loads the PKCS#11 modules, finds the object to list, lists it, 32*17Sdinak * and cleans up. User must be logged into the token to list private 33*17Sdinak * objects. 34*17Sdinak */ 35*17Sdinak 36*17Sdinak #include <stdio.h> 37*17Sdinak #include <errno.h> 38*17Sdinak #include <string.h> 39*17Sdinak #include <cryptoutil.h> 40*17Sdinak #include <security/cryptoki.h> 41*17Sdinak #include "common.h" 42*17Sdinak #include "derparse.h" 43*17Sdinak 44*17Sdinak /* 45*17Sdinak * Get key size based on the key type. 46*17Sdinak */ 47*17Sdinak static CK_ULONG 48*17Sdinak get_key_size(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, CK_KEY_TYPE key_type) 49*17Sdinak { 50*17Sdinak CK_RV rv = CKR_OK; 51*17Sdinak CK_ULONG key_size; 52*17Sdinak CK_ATTRIBUTE modulus_sz = 53*17Sdinak { CKA_MODULUS, NULL, 0 }; /* RSA */ 54*17Sdinak CK_ATTRIBUTE prime_sz = 55*17Sdinak { CKA_PRIME, NULL, 0 }; /* DSA, DH X9.42 */ 56*17Sdinak CK_ATTRIBUTE value_sz = 57*17Sdinak { CKA_VALUE, NULL_PTR, 0 }; /* DH, DES/DES3, AES, GENERIC */ 58*17Sdinak 59*17Sdinak cryptodebug("inside get_key_size"); 60*17Sdinak 61*17Sdinak switch (key_type) { 62*17Sdinak case CKK_RSA: 63*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, &modulus_sz, 1)) != 64*17Sdinak CKR_OK) { 65*17Sdinak cryptoerror(LOG_STDERR, gettext( 66*17Sdinak "Unable to get modulus attribute size (%s)."), 67*17Sdinak pkcs11_strerror(rv)); 68*17Sdinak } else 69*17Sdinak /* Convert key size to bits. */ 70*17Sdinak key_size = modulus_sz.ulValueLen * 8; 71*17Sdinak break; 72*17Sdinak case CKK_DH: 73*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, &value_sz, 1)) != 74*17Sdinak CKR_OK) { 75*17Sdinak cryptoerror(LOG_STDERR, gettext( 76*17Sdinak "Unable to get value attribute size (%s)."), 77*17Sdinak pkcs11_strerror(rv)); 78*17Sdinak } else 79*17Sdinak /* Convert key size to bits. */ 80*17Sdinak key_size = value_sz.ulValueLen * 8; 81*17Sdinak break; 82*17Sdinak case CKK_X9_42_DH: 83*17Sdinak case CKK_DSA: 84*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, &prime_sz, 1)) != 85*17Sdinak CKR_OK) { 86*17Sdinak cryptoerror(LOG_STDERR, gettext( 87*17Sdinak "Unable to get prime attribute size (%s)."), 88*17Sdinak pkcs11_strerror(rv)); 89*17Sdinak } else 90*17Sdinak /* Convert key size to bits. */ 91*17Sdinak key_size = prime_sz.ulValueLen * 8; 92*17Sdinak break; 93*17Sdinak case CKK_DES: 94*17Sdinak case CKK_DES3: 95*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, &value_sz, 1)) != 96*17Sdinak CKR_OK) { 97*17Sdinak cryptoerror(LOG_STDERR, gettext( 98*17Sdinak "Unable to get value attribute size (%s)."), 99*17Sdinak pkcs11_strerror(rv)); 100*17Sdinak } else 101*17Sdinak /* Convert key size to bits -- omitting parity bit. */ 102*17Sdinak key_size = value_sz.ulValueLen * 7; 103*17Sdinak break; 104*17Sdinak case CKK_AES: 105*17Sdinak case CKK_GENERIC_SECRET: 106*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, &value_sz, 1)) != 107*17Sdinak CKR_OK) { 108*17Sdinak cryptoerror(LOG_STDERR, gettext( 109*17Sdinak "Unable to get value attribute size (%s)."), 110*17Sdinak pkcs11_strerror(rv)); 111*17Sdinak } else 112*17Sdinak /* Convert key size to bits. */ 113*17Sdinak key_size = value_sz.ulValueLen * 8; 114*17Sdinak break; 115*17Sdinak default: 116*17Sdinak cryptoerror(LOG_STDERR, gettext( 117*17Sdinak "Unknown object key type (0x%02x)."), key_type); 118*17Sdinak break; 119*17Sdinak } 120*17Sdinak 121*17Sdinak return (key_size); 122*17Sdinak } 123*17Sdinak 124*17Sdinak /* 125*17Sdinak * Display private key. 126*17Sdinak */ 127*17Sdinak static CK_RV 128*17Sdinak display_prikey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int counter) 129*17Sdinak { 130*17Sdinak CK_RV rv = CKR_OK; 131*17Sdinak static CK_BBOOL private; 132*17Sdinak static CK_BBOOL modifiable; 133*17Sdinak static CK_KEY_TYPE key_type; 134*17Sdinak CK_ULONG key_size; 135*17Sdinak CK_BYTE *label = NULL; 136*17Sdinak CK_ULONG label_len = 0; 137*17Sdinak CK_BYTE *id = NULL; 138*17Sdinak CK_ULONG id_len = 0; 139*17Sdinak CK_BYTE *subject = NULL; 140*17Sdinak CK_ULONG subject_len = 0; 141*17Sdinak CK_DATE *start_date = NULL; 142*17Sdinak CK_ULONG start_date_len = 0; 143*17Sdinak CK_DATE *end_date = NULL; 144*17Sdinak CK_ULONG end_date_len = 0; 145*17Sdinak CK_ATTRIBUTE attrs[18] = { 146*17Sdinak /* 0 to 2 */ 147*17Sdinak { CKA_PRIVATE, &private, sizeof (private) }, 148*17Sdinak { CKA_MODIFIABLE, &modifiable, sizeof (modifiable) }, 149*17Sdinak { CKA_KEY_TYPE, &key_type, sizeof (key_type) }, 150*17Sdinak /* 3 to 12 */ 151*17Sdinak { CKA_DERIVE, NULL, 0 }, 152*17Sdinak { CKA_LOCAL, NULL, 0 }, 153*17Sdinak { CKA_DECRYPT, NULL, 0 }, 154*17Sdinak { CKA_SIGN, NULL, 0 }, 155*17Sdinak { CKA_SIGN_RECOVER, NULL, 0 }, 156*17Sdinak { CKA_UNWRAP, NULL, 0 }, 157*17Sdinak { CKA_SENSITIVE, NULL, 0 }, 158*17Sdinak { CKA_ALWAYS_SENSITIVE, NULL, 0 }, 159*17Sdinak { CKA_EXTRACTABLE, NULL, 0 }, 160*17Sdinak { CKA_NEVER_EXTRACTABLE, NULL, 0 }, 161*17Sdinak /* 13 to 17 */ 162*17Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 163*17Sdinak { CKA_ID, NULL, 0 }, /* optional */ 164*17Sdinak { CKA_SUBJECT, NULL, 0 }, /* optional */ 165*17Sdinak { CKA_START_DATE, NULL, 0 }, /* optional */ 166*17Sdinak { CKA_END_DATE, NULL, 0 } /* optional */ 167*17Sdinak /* not displaying CKA_KEY_GEN_MECHANISM */ 168*17Sdinak }; 169*17Sdinak CK_ULONG n_attrs = sizeof (attrs) / sizeof (CK_ATTRIBUTE); 170*17Sdinak int i; 171*17Sdinak char *hex_id = NULL; 172*17Sdinak int hex_id_len = 0; 173*17Sdinak char *hex_subject = NULL; 174*17Sdinak int hex_subject_len = 0; 175*17Sdinak 176*17Sdinak cryptodebug("inside display_prikey"); 177*17Sdinak 178*17Sdinak /* Get the sizes of the attributes we need. */ 179*17Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 180*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 181*17Sdinak cryptoerror(LOG_STDERR, gettext( 182*17Sdinak "Unable to get private key attribute sizes (%s)."), 183*17Sdinak pkcs11_strerror(rv)); 184*17Sdinak return (rv); 185*17Sdinak } 186*17Sdinak 187*17Sdinak /* Allocate memory for each variable-length attribute. */ 188*17Sdinak for (i = 3; i < n_attrs; i++) { 189*17Sdinak if (attrs[i].ulValueLen == (CK_ULONG)-1 || 190*17Sdinak attrs[i].ulValueLen == 0) { 191*17Sdinak cryptodebug("display_prikey: *** should not happen"); 192*17Sdinak attrs[i].ulValueLen = 0; 193*17Sdinak continue; 194*17Sdinak } 195*17Sdinak if ((attrs[i].pValue = malloc(attrs[i].ulValueLen)) == NULL) { 196*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 197*17Sdinak rv = CKR_HOST_MEMORY; 198*17Sdinak goto free_display_prikey; 199*17Sdinak } 200*17Sdinak } 201*17Sdinak 202*17Sdinak /* Now really get the attributes. */ 203*17Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 204*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 205*17Sdinak cryptoerror(LOG_STDERR, gettext( 206*17Sdinak "Unable to get private key attributes (%s)."), 207*17Sdinak pkcs11_strerror(rv)); 208*17Sdinak goto free_display_prikey; 209*17Sdinak } 210*17Sdinak 211*17Sdinak /* Fill in all the optional temp variables. */ 212*17Sdinak i = 13; 213*17Sdinak copy_attr_to_string(&(attrs[i++]), &label, &label_len); 214*17Sdinak copy_attr_to_string(&(attrs[i++]), &id, &id_len); 215*17Sdinak copy_attr_to_string(&(attrs[i++]), &subject, &subject_len); 216*17Sdinak copy_attr_to_date(&(attrs[i++]), &start_date, &start_date_len); 217*17Sdinak copy_attr_to_date(&(attrs[i++]), &end_date, &end_date_len); 218*17Sdinak 219*17Sdinak /* Get the key size for the object. */ 220*17Sdinak key_size = get_key_size(sess, obj, key_type); 221*17Sdinak 222*17Sdinak /* Display the object ... */ 223*17Sdinak /* ... the label and what it is (and key size in bits) ... */ 224*17Sdinak (void) fprintf(stdout, gettext("%d. \"%.*s\" (%d-bit %s %s)\n"), 225*17Sdinak counter, label_len, label_len > 0 ? (char *)label : 226*17Sdinak gettext("<no label>"), key_size, keytype_str(key_type), 227*17Sdinak class_str(CKO_PRIVATE_KEY)); 228*17Sdinak 229*17Sdinak /* ... the id ... */ 230*17Sdinak if (id_len == (CK_ULONG)-1 || id_len == 0) 231*17Sdinak (void) fprintf(stdout, gettext("\tId: --\n")); 232*17Sdinak else { 233*17Sdinak hex_id_len = 3 * id_len + 1; 234*17Sdinak if ((hex_id = malloc(hex_id_len)) == NULL) { 235*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 236*17Sdinak rv = CKR_HOST_MEMORY; 237*17Sdinak goto free_display_prikey; 238*17Sdinak } 239*17Sdinak octetify(id, id_len, hex_id, hex_id_len, B_FALSE, B_FALSE, 60, 240*17Sdinak "\n\t\t", ""); 241*17Sdinak (void) fprintf(stdout, gettext("\tId: %s\n"), hex_id); 242*17Sdinak free(hex_id); 243*17Sdinak } 244*17Sdinak 245*17Sdinak /* ... the subject name ... */ 246*17Sdinak if (subject_len == (CK_ULONG)-1 || subject_len == 0) 247*17Sdinak (void) fprintf(stdout, gettext("\tSubject: --\n")); 248*17Sdinak else { 249*17Sdinak hex_subject_len = 2 * subject_len + 1; /* best guesstimate */ 250*17Sdinak if ((hex_subject = malloc(hex_subject_len)) == NULL) { 251*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 252*17Sdinak rv = CKR_HOST_MEMORY; 253*17Sdinak goto free_display_prikey; 254*17Sdinak } 255*17Sdinak rdnseq_to_str(subject, subject_len, hex_subject, 256*17Sdinak hex_subject_len); 257*17Sdinak (void) fprintf(stdout, gettext("\tSubject: %.*s\n"), 258*17Sdinak hex_subject_len, hex_subject); 259*17Sdinak free(hex_subject); 260*17Sdinak } 261*17Sdinak 262*17Sdinak /* ... the start date ... */ 263*17Sdinak if (start_date_len == (CK_ULONG)-1 || start_date_len == 0) 264*17Sdinak (void) fprintf(stdout, gettext("\tStart Date: --\n")); 265*17Sdinak else 266*17Sdinak (void) fprintf(stdout, gettext( 267*17Sdinak "\tStart Date: %02.2s/%02.2s/%04.4s\n"), 268*17Sdinak start_date->month, start_date->day, start_date->year); 269*17Sdinak 270*17Sdinak /* ... the end date ... */ 271*17Sdinak if (end_date_len == (CK_ULONG)-1 || end_date_len == 0) 272*17Sdinak (void) fprintf(stdout, gettext("\tEnd Date: --\n")); 273*17Sdinak else 274*17Sdinak (void) fprintf(stdout, gettext( 275*17Sdinak "\tEnd Date: %02.2s/%02.2s/%04.4s\n"), 276*17Sdinak end_date->month, end_date->day, end_date->year); 277*17Sdinak 278*17Sdinak /* ... and its capabilities */ 279*17Sdinak (void) fprintf(stdout, "\t(%s, %s", 280*17Sdinak private != pk_false ? gettext("private") : gettext("public"), 281*17Sdinak modifiable == B_TRUE ? gettext("modifiable") : 282*17Sdinak gettext("not modifiable")); 283*17Sdinak for (i = 3; i <= 12; i++) { 284*17Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 285*17Sdinak attrs[i].ulValueLen != 0 && 286*17Sdinak *((CK_BBOOL *)(attrs[i].pValue)) == B_TRUE) 287*17Sdinak (void) fprintf(stdout, ", %s", attr_str(attrs[i].type)); 288*17Sdinak } 289*17Sdinak (void) fprintf(stdout, ")\n"); 290*17Sdinak 291*17Sdinak free_display_prikey: 292*17Sdinak for (i = 3; i < n_attrs; i++) 293*17Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 294*17Sdinak attrs[i].ulValueLen != 0) 295*17Sdinak free(attrs[i].pValue); 296*17Sdinak return (rv); 297*17Sdinak } 298*17Sdinak 299*17Sdinak /* 300*17Sdinak * Display public key. 301*17Sdinak */ 302*17Sdinak static CK_RV 303*17Sdinak display_pubkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int counter) 304*17Sdinak { 305*17Sdinak CK_RV rv = CKR_OK; 306*17Sdinak static CK_BBOOL private; 307*17Sdinak static CK_BBOOL modifiable; 308*17Sdinak static CK_BBOOL trusted; 309*17Sdinak static CK_KEY_TYPE key_type; 310*17Sdinak CK_ULONG key_size; 311*17Sdinak CK_BYTE *label = NULL; 312*17Sdinak CK_ULONG label_len = 0; 313*17Sdinak CK_BYTE *id = NULL; 314*17Sdinak CK_ULONG id_len = 0; 315*17Sdinak CK_BYTE *subject = NULL; 316*17Sdinak CK_ULONG subject_len = 0; 317*17Sdinak CK_DATE *start_date = NULL; 318*17Sdinak CK_ULONG start_date_len = 0; 319*17Sdinak CK_DATE *end_date = NULL; 320*17Sdinak CK_ULONG end_date_len = 0; 321*17Sdinak CK_ATTRIBUTE attrs[15] = { 322*17Sdinak /* 0 to 3 */ 323*17Sdinak { CKA_PRIVATE, &private, sizeof (private) }, 324*17Sdinak { CKA_MODIFIABLE, &modifiable, sizeof (modifiable) }, 325*17Sdinak { CKA_TRUSTED, &trusted, sizeof (trusted) }, 326*17Sdinak { CKA_KEY_TYPE, &key_type, sizeof (key_type) }, 327*17Sdinak /* 4 to 9 */ 328*17Sdinak { CKA_DERIVE, NULL, 0 }, 329*17Sdinak { CKA_LOCAL, NULL, 0 }, 330*17Sdinak { CKA_ENCRYPT, NULL, 0 }, 331*17Sdinak { CKA_VERIFY, NULL, 0 }, 332*17Sdinak { CKA_VERIFY_RECOVER, NULL, 0 }, 333*17Sdinak { CKA_WRAP, NULL, 0 }, 334*17Sdinak /* 10 to 14 */ 335*17Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 336*17Sdinak { CKA_ID, NULL, 0 }, /* optional */ 337*17Sdinak { CKA_SUBJECT, NULL, 0 }, /* optional */ 338*17Sdinak { CKA_START_DATE, NULL, 0 }, /* optional */ 339*17Sdinak { CKA_END_DATE, NULL, 0 } /* optional */ 340*17Sdinak /* not displaying CKA_KEY_GEN_MECHANISM */ 341*17Sdinak }; 342*17Sdinak CK_ULONG n_attrs = sizeof (attrs) / sizeof (CK_ATTRIBUTE); 343*17Sdinak int i; 344*17Sdinak char *hex_id = NULL; 345*17Sdinak int hex_id_len = 0; 346*17Sdinak char *hex_subject = NULL; 347*17Sdinak int hex_subject_len = 0; 348*17Sdinak 349*17Sdinak cryptodebug("inside display_pubkey"); 350*17Sdinak 351*17Sdinak /* Get the sizes of the attributes we need. */ 352*17Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 353*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 354*17Sdinak cryptoerror(LOG_STDERR, gettext( 355*17Sdinak "Unable to get public key attribute sizes (%s)."), 356*17Sdinak pkcs11_strerror(rv)); 357*17Sdinak return (rv); 358*17Sdinak } 359*17Sdinak 360*17Sdinak /* Allocate memory for each variable-length attribute. */ 361*17Sdinak for (i = 4; i < n_attrs; i++) { 362*17Sdinak if (attrs[i].ulValueLen == (CK_ULONG)-1 || 363*17Sdinak attrs[i].ulValueLen == 0) { 364*17Sdinak cryptodebug("display_pubkey: *** should not happen"); 365*17Sdinak attrs[i].ulValueLen = 0; 366*17Sdinak continue; 367*17Sdinak } 368*17Sdinak if ((attrs[i].pValue = malloc(attrs[i].ulValueLen)) == NULL) { 369*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 370*17Sdinak rv = CKR_HOST_MEMORY; 371*17Sdinak goto free_display_pubkey; 372*17Sdinak } 373*17Sdinak } 374*17Sdinak 375*17Sdinak /* Now really get the attributes. */ 376*17Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 377*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 378*17Sdinak cryptoerror(LOG_STDERR, gettext( 379*17Sdinak "Unable to get public key attributes (%s)."), 380*17Sdinak pkcs11_strerror(rv)); 381*17Sdinak goto free_display_pubkey; 382*17Sdinak } 383*17Sdinak 384*17Sdinak /* Fill in all the optional temp variables. */ 385*17Sdinak i = 10; 386*17Sdinak copy_attr_to_string(&(attrs[i++]), &label, &label_len); 387*17Sdinak copy_attr_to_string(&(attrs[i++]), &id, &id_len); 388*17Sdinak copy_attr_to_string(&(attrs[i++]), &subject, &subject_len); 389*17Sdinak copy_attr_to_date(&(attrs[i++]), &start_date, &start_date_len); 390*17Sdinak copy_attr_to_date(&(attrs[i++]), &end_date, &end_date_len); 391*17Sdinak 392*17Sdinak /* Get the key size for the object. */ 393*17Sdinak key_size = get_key_size(sess, obj, key_type); 394*17Sdinak 395*17Sdinak /* Display the object ... */ 396*17Sdinak /* ... the label and what it is (and key size in bits) ... */ 397*17Sdinak (void) fprintf(stdout, gettext("%d. \"%.*s\" (%d-bit %s %s)\n"), 398*17Sdinak counter, label_len, label_len > 0 ? (char *)label : 399*17Sdinak gettext("<no label>"), key_size, keytype_str(key_type), 400*17Sdinak class_str(CKO_PUBLIC_KEY)); 401*17Sdinak 402*17Sdinak /* ... the id ... */ 403*17Sdinak if (id_len == (CK_ULONG)-1 || id_len == 0) 404*17Sdinak (void) fprintf(stdout, gettext("\tId: --\n")); 405*17Sdinak else { 406*17Sdinak hex_id_len = 3 * id_len + 1; 407*17Sdinak if ((hex_id = malloc(hex_id_len)) == NULL) { 408*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 409*17Sdinak rv = CKR_HOST_MEMORY; 410*17Sdinak goto free_display_pubkey; 411*17Sdinak } 412*17Sdinak octetify(id, id_len, hex_id, hex_id_len, B_FALSE, B_FALSE, 60, 413*17Sdinak "\n\t\t", ""); 414*17Sdinak (void) fprintf(stdout, gettext("\tId: %s\n"), hex_id); 415*17Sdinak free(hex_id); 416*17Sdinak } 417*17Sdinak 418*17Sdinak /* ... the subject name ... */ 419*17Sdinak if (subject_len == (CK_ULONG)-1 || subject_len == 0) 420*17Sdinak (void) fprintf(stdout, gettext("\tSubject: --\n")); 421*17Sdinak else { 422*17Sdinak hex_subject_len = 2 * subject_len + 1; /* best guesstimate */ 423*17Sdinak if ((hex_subject = malloc(hex_subject_len)) == NULL) { 424*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 425*17Sdinak rv = CKR_HOST_MEMORY; 426*17Sdinak goto free_display_pubkey; 427*17Sdinak } 428*17Sdinak rdnseq_to_str(subject, subject_len, hex_subject, 429*17Sdinak hex_subject_len); 430*17Sdinak (void) fprintf(stdout, gettext("\tSubject: %.*s\n"), 431*17Sdinak hex_subject_len, hex_subject); 432*17Sdinak free(hex_subject); 433*17Sdinak } 434*17Sdinak 435*17Sdinak /* ... the start date ... */ 436*17Sdinak if (start_date_len == (CK_ULONG)-1 || start_date_len == 0) 437*17Sdinak (void) fprintf(stdout, gettext("\tStart Date: --\n")); 438*17Sdinak else 439*17Sdinak (void) fprintf(stdout, gettext( 440*17Sdinak "\tStart Date: %02.2s/%02.2s/%04.4s\n"), 441*17Sdinak start_date->month, start_date->day, start_date->year); 442*17Sdinak 443*17Sdinak /* ... the end date ... */ 444*17Sdinak if (end_date_len == (CK_ULONG)-1 || end_date_len == 0) 445*17Sdinak (void) fprintf(stdout, gettext("\tEnd Date: --\n")); 446*17Sdinak else 447*17Sdinak (void) fprintf(stdout, gettext( 448*17Sdinak "\tEnd Date: %02.2s/%02.2s/%04.4s\n"), 449*17Sdinak end_date->month, end_date->day, end_date->year); 450*17Sdinak 451*17Sdinak /* ... and its capabilities */ 452*17Sdinak (void) fprintf(stdout, "\t(%s, %s, %s", 453*17Sdinak private == B_TRUE ? gettext("private") : gettext("public"), 454*17Sdinak modifiable == B_TRUE ? gettext("modifiable") : 455*17Sdinak gettext("not modifiable"), 456*17Sdinak trusted == B_TRUE ? gettext("trusted") : gettext("untrusted")); 457*17Sdinak for (i = 4; i <= 9; i++) { 458*17Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 459*17Sdinak attrs[i].ulValueLen != 0 && 460*17Sdinak *((CK_BBOOL *)(attrs[i].pValue)) == B_TRUE) 461*17Sdinak (void) fprintf(stdout, ", %s", attr_str(attrs[i].type)); 462*17Sdinak } 463*17Sdinak (void) fprintf(stdout, ")\n"); 464*17Sdinak 465*17Sdinak free_display_pubkey: 466*17Sdinak for (i = 4; i < n_attrs; i++) 467*17Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 468*17Sdinak attrs[i].ulValueLen != 0) 469*17Sdinak free(attrs[i].pValue); 470*17Sdinak return (rv); 471*17Sdinak } 472*17Sdinak 473*17Sdinak /* 474*17Sdinak * Display secret key. 475*17Sdinak */ 476*17Sdinak static CK_RV 477*17Sdinak display_seckey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int counter) 478*17Sdinak { 479*17Sdinak CK_RV rv = CKR_OK; 480*17Sdinak static CK_BBOOL private; 481*17Sdinak static CK_BBOOL modifiable; 482*17Sdinak static CK_KEY_TYPE key_type; 483*17Sdinak static CK_ULONG key_size; 484*17Sdinak CK_BYTE *label = NULL; 485*17Sdinak CK_ULONG label_len = 0; 486*17Sdinak CK_BYTE *id = NULL; 487*17Sdinak CK_ULONG id_len = 0; 488*17Sdinak CK_DATE *start_date = NULL; 489*17Sdinak CK_ULONG start_date_len = 0; 490*17Sdinak CK_DATE *end_date = NULL; 491*17Sdinak CK_ULONG end_date_len = 0; 492*17Sdinak CK_ATTRIBUTE attrs[19] = { 493*17Sdinak /* 0 to 2 */ 494*17Sdinak { CKA_PRIVATE, &private, sizeof (private) }, 495*17Sdinak { CKA_MODIFIABLE, &modifiable, sizeof (modifiable) }, 496*17Sdinak { CKA_KEY_TYPE, &key_type, sizeof (key_type) }, 497*17Sdinak /* 3 to 14 */ 498*17Sdinak { CKA_DERIVE, NULL, 0 }, 499*17Sdinak { CKA_LOCAL, NULL, 0 }, 500*17Sdinak { CKA_ENCRYPT, NULL, 0 }, 501*17Sdinak { CKA_DECRYPT, NULL, 0 }, 502*17Sdinak { CKA_SIGN, NULL, 0 }, 503*17Sdinak { CKA_VERIFY, NULL, 0 }, 504*17Sdinak { CKA_WRAP, NULL, 0 }, 505*17Sdinak { CKA_UNWRAP, NULL, 0 }, 506*17Sdinak { CKA_SENSITIVE, NULL, 0 }, 507*17Sdinak { CKA_ALWAYS_SENSITIVE, NULL, 0 }, 508*17Sdinak { CKA_EXTRACTABLE, NULL, 0 }, 509*17Sdinak { CKA_NEVER_EXTRACTABLE, 0 }, 510*17Sdinak /* 15 to 18 */ 511*17Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 512*17Sdinak { CKA_ID, NULL, 0 }, /* optional */ 513*17Sdinak { CKA_START_DATE, NULL, 0 }, /* optional */ 514*17Sdinak { CKA_END_DATE, NULL, 0 } /* optional */ 515*17Sdinak /* not displaying CKA_KEY_GEN_MECHANISM */ 516*17Sdinak }; 517*17Sdinak CK_ULONG n_attrs = sizeof (attrs) / sizeof (CK_ATTRIBUTE); 518*17Sdinak int i; 519*17Sdinak char *hex_id = NULL; 520*17Sdinak int hex_id_len = 0; 521*17Sdinak 522*17Sdinak cryptodebug("inside display_seckey"); 523*17Sdinak 524*17Sdinak /* Get the sizes of the attributes we need. */ 525*17Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 526*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 527*17Sdinak cryptoerror(LOG_STDERR, gettext( 528*17Sdinak "Unable to get secret key attribute sizes (%s)."), 529*17Sdinak pkcs11_strerror(rv)); 530*17Sdinak return (rv); 531*17Sdinak } 532*17Sdinak 533*17Sdinak /* Allocate memory for each variable-length attribute. */ 534*17Sdinak for (i = 3; i < n_attrs; i++) { 535*17Sdinak if (attrs[i].ulValueLen == (CK_ULONG)-1 || 536*17Sdinak attrs[i].ulValueLen == 0) { 537*17Sdinak cryptodebug("display_seckey: *** should not happen"); 538*17Sdinak attrs[i].ulValueLen = 0; 539*17Sdinak continue; 540*17Sdinak } 541*17Sdinak if ((attrs[i].pValue = malloc(attrs[i].ulValueLen)) == NULL) { 542*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 543*17Sdinak rv = CKR_HOST_MEMORY; 544*17Sdinak goto free_display_seckey; 545*17Sdinak } 546*17Sdinak } 547*17Sdinak 548*17Sdinak /* Now really get the attributes. */ 549*17Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 550*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 551*17Sdinak cryptoerror(LOG_STDERR, gettext( 552*17Sdinak "Unable to get secret key attributes (%s)."), 553*17Sdinak pkcs11_strerror(rv)); 554*17Sdinak goto free_display_seckey; 555*17Sdinak } 556*17Sdinak 557*17Sdinak /* Fill in all the optional temp variables. */ 558*17Sdinak i = 15; 559*17Sdinak copy_attr_to_string(&(attrs[i++]), &label, &label_len); 560*17Sdinak copy_attr_to_string(&(attrs[i++]), &id, &id_len); 561*17Sdinak copy_attr_to_date(&(attrs[i++]), &start_date, &start_date_len); 562*17Sdinak copy_attr_to_date(&(attrs[i++]), &end_date, &end_date_len); 563*17Sdinak 564*17Sdinak /* Get the key size for the object. */ 565*17Sdinak key_size = get_key_size(sess, obj, key_type); 566*17Sdinak 567*17Sdinak /* Display the object ... */ 568*17Sdinak /* ... the label and what it is (and key size in bytes) ... */ 569*17Sdinak (void) fprintf(stdout, gettext("%d. \"%.*s\" (%d-bit %s %s)\n"), 570*17Sdinak counter, label_len, label_len > 0 ? (char *)label : 571*17Sdinak gettext("<no label>"), key_size, keytype_str(key_type), 572*17Sdinak class_str(CKO_SECRET_KEY)); 573*17Sdinak 574*17Sdinak /* ... the id ... */ 575*17Sdinak if (id_len == (CK_ULONG)-1 || id_len == 0) 576*17Sdinak (void) fprintf(stdout, gettext("\tId: --\n")); 577*17Sdinak else { 578*17Sdinak hex_id_len = 3 * id_len + 1; 579*17Sdinak if ((hex_id = malloc(hex_id_len)) == NULL) { 580*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 581*17Sdinak rv = CKR_HOST_MEMORY; 582*17Sdinak goto free_display_seckey; 583*17Sdinak } 584*17Sdinak octetify(id, id_len, hex_id, hex_id_len, B_FALSE, B_FALSE, 60, 585*17Sdinak "\n\t\t", ""); 586*17Sdinak (void) fprintf(stdout, gettext("\tId: %s\n"), hex_id); 587*17Sdinak free(hex_id); 588*17Sdinak } 589*17Sdinak 590*17Sdinak /* ... the start date ... */ 591*17Sdinak if (start_date_len == (CK_ULONG)-1 || start_date_len == 0) 592*17Sdinak (void) fprintf(stdout, gettext("\tStart Date: --\n")); 593*17Sdinak else 594*17Sdinak (void) fprintf(stdout, gettext( 595*17Sdinak "\tStart Date: %02.2s/%02.2s/%04.4s\n"), 596*17Sdinak start_date->month, start_date->day, start_date->year); 597*17Sdinak 598*17Sdinak /* ... the end date ... */ 599*17Sdinak if (end_date_len == (CK_ULONG)-1 || end_date_len == 0) 600*17Sdinak (void) fprintf(stdout, gettext("\tEnd Date: --\n")); 601*17Sdinak else 602*17Sdinak (void) fprintf(stdout, gettext( 603*17Sdinak "\tEnd Date: %02.2s/%02.2s/%04.4s\n"), 604*17Sdinak end_date->month, end_date->day, end_date->year); 605*17Sdinak 606*17Sdinak /* ... and its capabilities */ 607*17Sdinak (void) fprintf(stdout, "\t(%s, %s", 608*17Sdinak private == B_TRUE ? gettext("private") : gettext("public"), 609*17Sdinak modifiable == B_TRUE ? gettext("modifiable") : 610*17Sdinak gettext("not modifiable")); 611*17Sdinak for (i = 3; i <= 14; i++) { 612*17Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 613*17Sdinak attrs[i].ulValueLen != 0 && 614*17Sdinak *((CK_BBOOL *)(attrs[i].pValue)) == B_TRUE) 615*17Sdinak (void) fprintf(stdout, ", %s", attr_str(attrs[i].type)); 616*17Sdinak } 617*17Sdinak (void) fprintf(stdout, ")\n"); 618*17Sdinak 619*17Sdinak free_display_seckey: 620*17Sdinak for (i = 3; i < n_attrs; i++) 621*17Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 622*17Sdinak attrs[i].ulValueLen != 0) 623*17Sdinak free(attrs[i].pValue); 624*17Sdinak return (rv); 625*17Sdinak } 626*17Sdinak 627*17Sdinak /* 628*17Sdinak * Display certificate. 629*17Sdinak */ 630*17Sdinak static CK_RV 631*17Sdinak display_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int counter) 632*17Sdinak { 633*17Sdinak CK_RV rv = CKR_OK; 634*17Sdinak static CK_BBOOL private; 635*17Sdinak static CK_BBOOL modifiable; 636*17Sdinak static CK_BBOOL trusted; 637*17Sdinak CK_BYTE *subject = NULL; 638*17Sdinak CK_ULONG subject_len = 0; 639*17Sdinak CK_BYTE *value = NULL; 640*17Sdinak CK_ULONG value_len = 0; 641*17Sdinak CK_BYTE *label = NULL; 642*17Sdinak CK_ULONG label_len = 0; 643*17Sdinak CK_BYTE *id = NULL; 644*17Sdinak CK_ULONG id_len = 0; 645*17Sdinak CK_BYTE *issuer = NULL; 646*17Sdinak CK_ULONG issuer_len = 0; 647*17Sdinak CK_BYTE *serial = NULL; 648*17Sdinak CK_ULONG serial_len = 0; 649*17Sdinak CK_ATTRIBUTE attrs[9] = { 650*17Sdinak { CKA_PRIVATE, &private, sizeof (private) }, 651*17Sdinak { CKA_MODIFIABLE, &modifiable, sizeof (modifiable) }, 652*17Sdinak { CKA_TRUSTED, &trusted, sizeof (trusted) }, 653*17Sdinak { CKA_SUBJECT, NULL, 0 }, /* required */ 654*17Sdinak { CKA_VALUE, NULL, 0 }, /* required */ 655*17Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 656*17Sdinak { CKA_ID, NULL, 0 }, /* optional */ 657*17Sdinak { CKA_ISSUER, NULL, 0 }, /* optional */ 658*17Sdinak { CKA_SERIAL_NUMBER, NULL, 0 } /* optional */ 659*17Sdinak }; 660*17Sdinak CK_ULONG n_attrs = sizeof (attrs) / sizeof (CK_ATTRIBUTE); 661*17Sdinak int i; 662*17Sdinak char *hex_id = NULL; 663*17Sdinak int hex_id_len = 0; 664*17Sdinak char *hex_subject = NULL; 665*17Sdinak int hex_subject_len = 0; 666*17Sdinak char *hex_issuer = NULL; 667*17Sdinak int hex_issuer_len = 0; 668*17Sdinak char *hex_serial = NULL; 669*17Sdinak int hex_serial_len = NULL; 670*17Sdinak uint32_t serial_value = 0; 671*17Sdinak char *hex_value = NULL; 672*17Sdinak int hex_value_len = 0; 673*17Sdinak 674*17Sdinak cryptodebug("inside display_cert"); 675*17Sdinak 676*17Sdinak /* Get the sizes of the attributes we need. */ 677*17Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 678*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 679*17Sdinak cryptoerror(LOG_STDERR, gettext( 680*17Sdinak "Unable to get certificate attribute sizes (%s)."), 681*17Sdinak pkcs11_strerror(rv)); 682*17Sdinak return (rv); 683*17Sdinak } 684*17Sdinak 685*17Sdinak /* Allocate memory for each variable-length attribute. */ 686*17Sdinak for (i = 3; i < n_attrs; i++) { 687*17Sdinak if (attrs[i].ulValueLen == (CK_ULONG)-1 || 688*17Sdinak attrs[i].ulValueLen == 0) { 689*17Sdinak cryptodebug("display_cert: *** should not happen"); 690*17Sdinak attrs[i].ulValueLen = 0; 691*17Sdinak continue; 692*17Sdinak } 693*17Sdinak if ((attrs[i].pValue = malloc(attrs[i].ulValueLen)) == NULL) { 694*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 695*17Sdinak rv = CKR_HOST_MEMORY; 696*17Sdinak goto free_display_cert; 697*17Sdinak } 698*17Sdinak } 699*17Sdinak 700*17Sdinak /* Now really get the attributes. */ 701*17Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 702*17Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 703*17Sdinak cryptoerror(LOG_STDERR, gettext( 704*17Sdinak "Unable to get certificate attributes (%s)."), 705*17Sdinak pkcs11_strerror(rv)); 706*17Sdinak goto free_display_cert; 707*17Sdinak } 708*17Sdinak 709*17Sdinak /* 710*17Sdinak * Fill in all the temp variables. Subject and value are required. 711*17Sdinak * The rest are optional. 712*17Sdinak */ 713*17Sdinak i = 3; 714*17Sdinak copy_attr_to_string(&(attrs[i++]), &subject, &subject_len); 715*17Sdinak copy_attr_to_string(&(attrs[i++]), &value, &value_len); 716*17Sdinak copy_attr_to_string(&(attrs[i++]), &label, &label_len); 717*17Sdinak copy_attr_to_string(&(attrs[i++]), &id, &id_len); 718*17Sdinak copy_attr_to_string(&(attrs[i++]), &issuer, &issuer_len); 719*17Sdinak copy_attr_to_string(&(attrs[i++]), &serial, &serial_len); 720*17Sdinak 721*17Sdinak /* Display the object ... */ 722*17Sdinak /* ... the label and what it is ... */ 723*17Sdinak (void) fprintf(stdout, gettext("%d. \"%.*s\" (%s %s)\n"), 724*17Sdinak counter, label_len, label_len > 0 ? (char *)label : 725*17Sdinak gettext("<no label>"), "X.509", class_str(CKO_CERTIFICATE)); 726*17Sdinak 727*17Sdinak /* ... its capabilities ... */ 728*17Sdinak (void) fprintf(stdout, gettext("\t(%s, %s, %s)\n"), 729*17Sdinak private == B_TRUE ? gettext("private") : gettext("public"), 730*17Sdinak modifiable == B_TRUE ? gettext("modifiable") : 731*17Sdinak gettext("not modifiable"), 732*17Sdinak trusted == B_TRUE ? gettext("trusted") : gettext("untrusted")); 733*17Sdinak 734*17Sdinak /* ... the id ... */ 735*17Sdinak if (id_len == (CK_ULONG)-1 || id_len == 0) 736*17Sdinak (void) fprintf(stdout, gettext("\tId: --\n")); 737*17Sdinak else { 738*17Sdinak hex_id_len = 3 * id_len + 1; 739*17Sdinak if ((hex_id = malloc(hex_id_len)) == NULL) { 740*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 741*17Sdinak rv = CKR_HOST_MEMORY; 742*17Sdinak goto free_display_cert; 743*17Sdinak } 744*17Sdinak octetify(id, id_len, hex_id, hex_id_len, B_FALSE, B_FALSE, 60, 745*17Sdinak "\n\t\t", ""); 746*17Sdinak (void) fprintf(stdout, gettext("\tId: %s\n"), hex_id); 747*17Sdinak free(hex_id); 748*17Sdinak } 749*17Sdinak 750*17Sdinak /* ... the subject name ... */ 751*17Sdinak if (subject_len == (CK_ULONG)-1 || subject_len == 0) 752*17Sdinak (void) fprintf(stdout, gettext("\tSubject: --\n")); 753*17Sdinak else { 754*17Sdinak hex_subject_len = 2 * subject_len + 1; /* best guesstimate */ 755*17Sdinak if ((hex_subject = malloc(hex_subject_len)) == NULL) { 756*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 757*17Sdinak rv = CKR_HOST_MEMORY; 758*17Sdinak goto free_display_cert; 759*17Sdinak } 760*17Sdinak rdnseq_to_str(subject, subject_len, hex_subject, 761*17Sdinak hex_subject_len); 762*17Sdinak (void) fprintf(stdout, gettext("\tSubject: %.*s\n"), 763*17Sdinak hex_subject_len, hex_subject); 764*17Sdinak free(hex_subject); 765*17Sdinak } 766*17Sdinak 767*17Sdinak /* ... the issuer name ... */ 768*17Sdinak if (issuer_len == (CK_ULONG)-1 || issuer_len == 0) 769*17Sdinak (void) fprintf(stdout, gettext("\tIssuer: --\n")); 770*17Sdinak else { 771*17Sdinak hex_issuer_len = 2 * issuer_len + 1; /* best guesstimate */ 772*17Sdinak if ((hex_issuer = malloc(hex_issuer_len)) == NULL) { 773*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 774*17Sdinak rv = CKR_HOST_MEMORY; 775*17Sdinak goto free_display_cert; 776*17Sdinak } 777*17Sdinak rdnseq_to_str(issuer, issuer_len, hex_issuer, hex_issuer_len); 778*17Sdinak (void) fprintf(stdout, gettext("\tIssuer: %.*s\n"), 779*17Sdinak hex_issuer_len, hex_issuer); 780*17Sdinak free(hex_issuer); 781*17Sdinak } 782*17Sdinak 783*17Sdinak /* ... the serial number ... */ 784*17Sdinak if (serial_len == (CK_ULONG)-1 || serial_len == 0) 785*17Sdinak (void) fprintf(stdout, gettext("\tSerial: --\n")); 786*17Sdinak else { 787*17Sdinak hex_serial_len = 3 * serial_len + 1; 788*17Sdinak if ((hex_serial = malloc(hex_serial_len)) == NULL) { 789*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 790*17Sdinak rv = CKR_HOST_MEMORY; 791*17Sdinak goto free_display_cert; 792*17Sdinak } 793*17Sdinak octetify(serial, serial_len, hex_serial, hex_serial_len, 794*17Sdinak B_FALSE, B_FALSE, 60, "\n\t\t", ""); 795*17Sdinak if (serial_len > 4) 796*17Sdinak (void) fprintf(stdout, gettext("\tSerial: %s\n"), 797*17Sdinak hex_serial); 798*17Sdinak else { 799*17Sdinak for (i = 0; i < serial_len; i++) { 800*17Sdinak serial_value <<= 8; 801*17Sdinak serial_value |= (serial[i] & 0xff); 802*17Sdinak } 803*17Sdinak (void) fprintf(stdout, gettext("\tSerial: %s (%d)\n"), 804*17Sdinak hex_serial, serial_value); 805*17Sdinak } 806*17Sdinak free(hex_serial); 807*17Sdinak } 808*17Sdinak 809*17Sdinak /* ... and the value */ 810*17Sdinak if (value_len == (CK_ULONG)-1 || value_len == 0) 811*17Sdinak (void) fprintf(stdout, gettext("\tValue: --\n")); 812*17Sdinak else { 813*17Sdinak hex_value_len = 3 * value_len + 1; 814*17Sdinak if ((hex_value = malloc(hex_value_len)) == NULL) { 815*17Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 816*17Sdinak rv = CKR_HOST_MEMORY; 817*17Sdinak goto free_display_cert; 818*17Sdinak } 819*17Sdinak octetify(value, value_len, hex_value, hex_value_len, 820*17Sdinak B_FALSE, B_FALSE, 60, "\n\t\t", ""); 821*17Sdinak (void) fprintf(stdout, gettext("\tValue: %s\n"), hex_value); 822*17Sdinak free(hex_value); 823*17Sdinak } 824*17Sdinak 825*17Sdinak free_display_cert: 826*17Sdinak for (i = 3; i < n_attrs; i++) 827*17Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 828*17Sdinak attrs[i].ulValueLen != 0) 829*17Sdinak free(attrs[i].pValue); 830*17Sdinak return (rv); 831*17Sdinak } 832*17Sdinak 833*17Sdinak /* 834*17Sdinak * List token object. 835*17Sdinak */ 836*17Sdinak int 837*17Sdinak pk_list(int argc, char *argv[]) 838*17Sdinak { 839*17Sdinak int opt; 840*17Sdinak extern int optind; 841*17Sdinak extern char *optarg; 842*17Sdinak char *token_name = NULL; 843*17Sdinak char *manuf_id = NULL; 844*17Sdinak char *serial_no = NULL; 845*17Sdinak char full_name[FULL_NAME_LEN]; 846*17Sdinak boolean_t public_objs = B_FALSE; 847*17Sdinak boolean_t private_objs = B_FALSE; 848*17Sdinak CK_BYTE *list_label = NULL; 849*17Sdinak int obj_type = 0x00; 850*17Sdinak CK_SLOT_ID slot_id; 851*17Sdinak CK_FLAGS pin_state; 852*17Sdinak CK_UTF8CHAR_PTR pin = NULL; 853*17Sdinak CK_ULONG pinlen = 0; 854*17Sdinak CK_SESSION_HANDLE sess; 855*17Sdinak CK_OBJECT_HANDLE *objs; 856*17Sdinak CK_ULONG num_objs; 857*17Sdinak CK_RV rv = CKR_OK; 858*17Sdinak int i; 859*17Sdinak static CK_OBJECT_CLASS objclass; 860*17Sdinak CK_ATTRIBUTE class_attr = 861*17Sdinak { CKA_CLASS, &objclass, sizeof (objclass) }; 862*17Sdinak 863*17Sdinak cryptodebug("inside pk_list"); 864*17Sdinak 865*17Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 866*17Sdinak while ((opt = getopt(argc, argv, "p(private)P(public)l:(label)")) != 867*17Sdinak EOF) { 868*17Sdinak switch (opt) { 869*17Sdinak case 'p': /* private objects */ 870*17Sdinak private_objs = B_TRUE; 871*17Sdinak obj_type |= PK_PRIVATE_OBJ; 872*17Sdinak break; 873*17Sdinak case 'P': /* public objects */ 874*17Sdinak public_objs = B_TRUE; 875*17Sdinak obj_type |= PK_PUBLIC_OBJ; 876*17Sdinak break; 877*17Sdinak case 'l': /* object with specific label */ 878*17Sdinak if (list_label) 879*17Sdinak return (PK_ERR_USAGE); 880*17Sdinak list_label = (CK_BYTE *)optarg; 881*17Sdinak break; 882*17Sdinak default: 883*17Sdinak return (PK_ERR_USAGE); 884*17Sdinak break; 885*17Sdinak } 886*17Sdinak } 887*17Sdinak 888*17Sdinak /* If nothing specified, default is public objects. */ 889*17Sdinak if (!public_objs && !private_objs) { 890*17Sdinak public_objs = B_TRUE; 891*17Sdinak obj_type |= PK_PUBLIC_OBJ; 892*17Sdinak } 893*17Sdinak 894*17Sdinak /* No additional args allowed. */ 895*17Sdinak argc -= optind; 896*17Sdinak argv += optind; 897*17Sdinak if (argc) 898*17Sdinak return (PK_ERR_USAGE); 899*17Sdinak /* Done parsing command line options. */ 900*17Sdinak 901*17Sdinak /* List operation only supported on softtoken. */ 902*17Sdinak if (token_name == NULL) 903*17Sdinak token_name = SOFT_TOKEN_LABEL; 904*17Sdinak if (manuf_id == NULL) 905*17Sdinak manuf_id = SOFT_MANUFACTURER_ID; 906*17Sdinak if (serial_no == NULL) 907*17Sdinak serial_no = SOFT_TOKEN_SERIAL; 908*17Sdinak full_token_name(token_name, manuf_id, serial_no, full_name); 909*17Sdinak 910*17Sdinak /* Find the slot with token. */ 911*17Sdinak if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, 912*17Sdinak &pin_state)) != CKR_OK) { 913*17Sdinak cryptoerror(LOG_STDERR, gettext( 914*17Sdinak "Unable to find token %s (%s)."), full_name, 915*17Sdinak pkcs11_strerror(rv)); 916*17Sdinak return (PK_ERR_PK11); 917*17Sdinak } 918*17Sdinak 919*17Sdinak /* If private objects are to be listed, user must be logged in. */ 920*17Sdinak if (private_objs) { 921*17Sdinak /* Get the user's PIN. */ 922*17Sdinak if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, 923*17Sdinak &pin, &pinlen)) != CKR_OK) { 924*17Sdinak cryptoerror(LOG_STDERR, 925*17Sdinak gettext("Unable to get token passphrase (%s)."), 926*17Sdinak pkcs11_strerror(rv)); 927*17Sdinak quick_finish(NULL); 928*17Sdinak return (PK_ERR_PK11); 929*17Sdinak } 930*17Sdinak 931*17Sdinak /* Logging in user R/O into the token is sufficient. */ 932*17Sdinak cryptodebug("logging in with readonly session"); 933*17Sdinak if ((rv = quick_start(slot_id, 0, pin, pinlen, &sess)) != 934*17Sdinak CKR_OK) { 935*17Sdinak cryptoerror(LOG_STDERR, 936*17Sdinak gettext("Unable to log into token (%s)."), 937*17Sdinak pkcs11_strerror(rv)); 938*17Sdinak quick_finish(sess); 939*17Sdinak return (PK_ERR_PK11); 940*17Sdinak } 941*17Sdinak /* Otherwise, just create a session. */ 942*17Sdinak } else { 943*17Sdinak cryptodebug("opening a readonly session"); 944*17Sdinak if ((rv = open_sess(slot_id, 0, &sess)) != CKR_OK) { 945*17Sdinak cryptoerror(LOG_STDERR, 946*17Sdinak gettext("Unable to open token session (%s)."), 947*17Sdinak pkcs11_strerror(rv)); 948*17Sdinak quick_finish(sess); 949*17Sdinak return (PK_ERR_PK11); 950*17Sdinak } 951*17Sdinak } 952*17Sdinak 953*17Sdinak /* Find the object(s) with the given label and/or type. */ 954*17Sdinak if ((rv = find_objs(sess, obj_type, list_label, &objs, &num_objs)) != 955*17Sdinak CKR_OK) { 956*17Sdinak cryptoerror(LOG_STDERR, gettext( 957*17Sdinak "Unable to find token objects (%s)."), pkcs11_strerror(rv)); 958*17Sdinak quick_finish(sess); 959*17Sdinak return (PK_ERR_PK11); 960*17Sdinak } 961*17Sdinak 962*17Sdinak if (num_objs == 0) { 963*17Sdinak cryptoerror(LOG_STDERR, gettext("No objects found.")); 964*17Sdinak quick_finish(sess); 965*17Sdinak return (0); 966*17Sdinak } 967*17Sdinak 968*17Sdinak /* List the objects found. */ 969*17Sdinak for (i = 0; i < num_objs; i++) { 970*17Sdinak /* Get object class first, then decide what is next. */ 971*17Sdinak cryptodebug("calling C_GetAttributeValue for object class"); 972*17Sdinak if ((rv = C_GetAttributeValue(sess, objs[i], &class_attr, 1)) 973*17Sdinak != CKR_OK) { 974*17Sdinak cryptoerror(LOG_STDERR, gettext( 975*17Sdinak "Unable to get object #%d class attribute (%s)."), 976*17Sdinak i+1, pkcs11_strerror(rv)); 977*17Sdinak continue; 978*17Sdinak } 979*17Sdinak 980*17Sdinak /* Display based on the type of object. */ 981*17Sdinak switch (objclass) { 982*17Sdinak case CKO_CERTIFICATE: 983*17Sdinak if ((rv = display_cert(sess, objs[i], i+1)) != CKR_OK) 984*17Sdinak cryptoerror(LOG_STDERR, 985*17Sdinak gettext("Unable to display certificate.")); 986*17Sdinak break; 987*17Sdinak case CKO_PUBLIC_KEY: 988*17Sdinak if ((rv = display_pubkey(sess, objs[i], i+1)) != CKR_OK) 989*17Sdinak cryptoerror(LOG_STDERR, 990*17Sdinak gettext("Unable to display public key.")); 991*17Sdinak break; 992*17Sdinak case CKO_PRIVATE_KEY: 993*17Sdinak if ((rv = display_prikey(sess, objs[i], i+1)) != CKR_OK) 994*17Sdinak cryptoerror(LOG_STDERR, 995*17Sdinak gettext("Unable to display private key.")); 996*17Sdinak break; 997*17Sdinak case CKO_SECRET_KEY: 998*17Sdinak if ((rv = display_seckey(sess, objs[i], i+1)) != CKR_OK) 999*17Sdinak cryptoerror(LOG_STDERR, 1000*17Sdinak gettext("Unable to display secret key.")); 1001*17Sdinak break; 1002*17Sdinak case CKO_DATA: 1003*17Sdinak cryptoerror(LOG_STDERR, 1004*17Sdinak gettext("Data object display not implemented.")); 1005*17Sdinak break; 1006*17Sdinak default: 1007*17Sdinak cryptoerror(LOG_STDERR, gettext( 1008*17Sdinak "Unknown token object class (0x%02x)."), objclass); 1009*17Sdinak break; 1010*17Sdinak } 1011*17Sdinak } 1012*17Sdinak 1013*17Sdinak /* Clean up. */ 1014*17Sdinak quick_finish(sess); 1015*17Sdinak return (0); 1016*17Sdinak } 1017