117Sdinak /* 217Sdinak * CDDL HEADER START 317Sdinak * 417Sdinak * The contents of this file are subject to the terms of the 517Sdinak * Common Development and Distribution License, Version 1.0 only 617Sdinak * (the "License"). You may not use this file except in compliance 717Sdinak * with the License. 817Sdinak * 917Sdinak * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 1017Sdinak * or http://www.opensolaris.org/os/licensing. 1117Sdinak * See the License for the specific language governing permissions 1217Sdinak * and limitations under the License. 1317Sdinak * 1417Sdinak * When distributing Covered Code, include this CDDL HEADER in each 1517Sdinak * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 1617Sdinak * If applicable, add the following below this CDDL HEADER, with the 1717Sdinak * fields enclosed by brackets "[]" replaced with your own identifying 1817Sdinak * information: Portions Copyright [yyyy] [name of copyright owner] 1917Sdinak * 2017Sdinak * CDDL HEADER END 2117Sdinak */ 2217Sdinak /* 2317Sdinak * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 2417Sdinak * Use is subject to license terms. 2517Sdinak */ 2617Sdinak 2717Sdinak #pragma ident "%Z%%M% %I% %E% SMI" 2817Sdinak 2917Sdinak /* 3017Sdinak * This file implements the token object list operation for this tool. 3117Sdinak * It loads the PKCS#11 modules, finds the object to list, lists it, 3217Sdinak * and cleans up. User must be logged into the token to list private 3317Sdinak * objects. 3417Sdinak */ 3517Sdinak 3617Sdinak #include <stdio.h> 3717Sdinak #include <errno.h> 3817Sdinak #include <string.h> 3917Sdinak #include <cryptoutil.h> 4017Sdinak #include <security/cryptoki.h> 4117Sdinak #include "common.h" 4217Sdinak #include "derparse.h" 4317Sdinak 4417Sdinak /* 4517Sdinak * Get key size based on the key type. 4617Sdinak */ 4717Sdinak static CK_ULONG 4817Sdinak get_key_size(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, CK_KEY_TYPE key_type) 4917Sdinak { 5017Sdinak CK_RV rv = CKR_OK; 5117Sdinak CK_ULONG key_size; 5217Sdinak CK_ATTRIBUTE modulus_sz = 5317Sdinak { CKA_MODULUS, NULL, 0 }; /* RSA */ 5417Sdinak CK_ATTRIBUTE prime_sz = 5517Sdinak { CKA_PRIME, NULL, 0 }; /* DSA, DH X9.42 */ 5617Sdinak CK_ATTRIBUTE value_sz = 5717Sdinak { CKA_VALUE, NULL_PTR, 0 }; /* DH, DES/DES3, AES, GENERIC */ 5817Sdinak 5917Sdinak cryptodebug("inside get_key_size"); 6017Sdinak 6117Sdinak switch (key_type) { 6217Sdinak case CKK_RSA: 6317Sdinak if ((rv = C_GetAttributeValue(sess, obj, &modulus_sz, 1)) != 6417Sdinak CKR_OK) { 6517Sdinak cryptoerror(LOG_STDERR, gettext( 6617Sdinak "Unable to get modulus attribute size (%s)."), 6717Sdinak pkcs11_strerror(rv)); 6817Sdinak } else 6917Sdinak /* Convert key size to bits. */ 7017Sdinak key_size = modulus_sz.ulValueLen * 8; 7117Sdinak break; 7217Sdinak case CKK_DH: 7317Sdinak if ((rv = C_GetAttributeValue(sess, obj, &value_sz, 1)) != 7417Sdinak CKR_OK) { 7517Sdinak cryptoerror(LOG_STDERR, gettext( 7617Sdinak "Unable to get value attribute size (%s)."), 7717Sdinak pkcs11_strerror(rv)); 7817Sdinak } else 7917Sdinak /* Convert key size to bits. */ 8017Sdinak key_size = value_sz.ulValueLen * 8; 8117Sdinak break; 8217Sdinak case CKK_X9_42_DH: 8317Sdinak case CKK_DSA: 8417Sdinak if ((rv = C_GetAttributeValue(sess, obj, &prime_sz, 1)) != 8517Sdinak CKR_OK) { 8617Sdinak cryptoerror(LOG_STDERR, gettext( 8717Sdinak "Unable to get prime attribute size (%s)."), 8817Sdinak pkcs11_strerror(rv)); 8917Sdinak } else 9017Sdinak /* Convert key size to bits. */ 9117Sdinak key_size = prime_sz.ulValueLen * 8; 9217Sdinak break; 9317Sdinak case CKK_DES: 9417Sdinak case CKK_DES3: 9517Sdinak if ((rv = C_GetAttributeValue(sess, obj, &value_sz, 1)) != 9617Sdinak CKR_OK) { 9717Sdinak cryptoerror(LOG_STDERR, gettext( 9817Sdinak "Unable to get value attribute size (%s)."), 9917Sdinak pkcs11_strerror(rv)); 10017Sdinak } else 10117Sdinak /* Convert key size to bits -- omitting parity bit. */ 10217Sdinak key_size = value_sz.ulValueLen * 7; 10317Sdinak break; 10417Sdinak case CKK_AES: 10517Sdinak case CKK_GENERIC_SECRET: 10617Sdinak if ((rv = C_GetAttributeValue(sess, obj, &value_sz, 1)) != 10717Sdinak CKR_OK) { 10817Sdinak cryptoerror(LOG_STDERR, gettext( 10917Sdinak "Unable to get value attribute size (%s)."), 11017Sdinak pkcs11_strerror(rv)); 11117Sdinak } else 11217Sdinak /* Convert key size to bits. */ 11317Sdinak key_size = value_sz.ulValueLen * 8; 11417Sdinak break; 11517Sdinak default: 11617Sdinak cryptoerror(LOG_STDERR, gettext( 11717Sdinak "Unknown object key type (0x%02x)."), key_type); 11817Sdinak break; 11917Sdinak } 12017Sdinak 12117Sdinak return (key_size); 12217Sdinak } 12317Sdinak 12417Sdinak /* 12517Sdinak * Display private key. 12617Sdinak */ 12717Sdinak static CK_RV 12817Sdinak display_prikey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int counter) 12917Sdinak { 13017Sdinak CK_RV rv = CKR_OK; 13117Sdinak static CK_BBOOL private; 13217Sdinak static CK_BBOOL modifiable; 13317Sdinak static CK_KEY_TYPE key_type; 13417Sdinak CK_ULONG key_size; 13517Sdinak CK_BYTE *label = NULL; 13617Sdinak CK_ULONG label_len = 0; 13717Sdinak CK_BYTE *id = NULL; 13817Sdinak CK_ULONG id_len = 0; 13917Sdinak CK_BYTE *subject = NULL; 14017Sdinak CK_ULONG subject_len = 0; 14117Sdinak CK_DATE *start_date = NULL; 14217Sdinak CK_ULONG start_date_len = 0; 14317Sdinak CK_DATE *end_date = NULL; 14417Sdinak CK_ULONG end_date_len = 0; 14517Sdinak CK_ATTRIBUTE attrs[18] = { 14617Sdinak /* 0 to 2 */ 14717Sdinak { CKA_PRIVATE, &private, sizeof (private) }, 14817Sdinak { CKA_MODIFIABLE, &modifiable, sizeof (modifiable) }, 14917Sdinak { CKA_KEY_TYPE, &key_type, sizeof (key_type) }, 15017Sdinak /* 3 to 12 */ 15117Sdinak { CKA_DERIVE, NULL, 0 }, 15217Sdinak { CKA_LOCAL, NULL, 0 }, 15317Sdinak { CKA_DECRYPT, NULL, 0 }, 15417Sdinak { CKA_SIGN, NULL, 0 }, 15517Sdinak { CKA_SIGN_RECOVER, NULL, 0 }, 15617Sdinak { CKA_UNWRAP, NULL, 0 }, 15717Sdinak { CKA_SENSITIVE, NULL, 0 }, 15817Sdinak { CKA_ALWAYS_SENSITIVE, NULL, 0 }, 15917Sdinak { CKA_EXTRACTABLE, NULL, 0 }, 16017Sdinak { CKA_NEVER_EXTRACTABLE, NULL, 0 }, 16117Sdinak /* 13 to 17 */ 16217Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 16317Sdinak { CKA_ID, NULL, 0 }, /* optional */ 16417Sdinak { CKA_SUBJECT, NULL, 0 }, /* optional */ 16517Sdinak { CKA_START_DATE, NULL, 0 }, /* optional */ 16617Sdinak { CKA_END_DATE, NULL, 0 } /* optional */ 16717Sdinak /* not displaying CKA_KEY_GEN_MECHANISM */ 16817Sdinak }; 16917Sdinak CK_ULONG n_attrs = sizeof (attrs) / sizeof (CK_ATTRIBUTE); 17017Sdinak int i; 17117Sdinak char *hex_id = NULL; 17217Sdinak int hex_id_len = 0; 17317Sdinak char *hex_subject = NULL; 17417Sdinak int hex_subject_len = 0; 17517Sdinak 17617Sdinak cryptodebug("inside display_prikey"); 17717Sdinak 17817Sdinak /* Get the sizes of the attributes we need. */ 17917Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 18017Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 18117Sdinak cryptoerror(LOG_STDERR, gettext( 18217Sdinak "Unable to get private key attribute sizes (%s)."), 18317Sdinak pkcs11_strerror(rv)); 18417Sdinak return (rv); 18517Sdinak } 18617Sdinak 18717Sdinak /* Allocate memory for each variable-length attribute. */ 18817Sdinak for (i = 3; i < n_attrs; i++) { 18917Sdinak if (attrs[i].ulValueLen == (CK_ULONG)-1 || 19017Sdinak attrs[i].ulValueLen == 0) { 19117Sdinak cryptodebug("display_prikey: *** should not happen"); 19217Sdinak attrs[i].ulValueLen = 0; 19317Sdinak continue; 19417Sdinak } 19517Sdinak if ((attrs[i].pValue = malloc(attrs[i].ulValueLen)) == NULL) { 19617Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 19717Sdinak rv = CKR_HOST_MEMORY; 19817Sdinak goto free_display_prikey; 19917Sdinak } 20017Sdinak } 20117Sdinak 20217Sdinak /* Now really get the attributes. */ 20317Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 20417Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 20517Sdinak cryptoerror(LOG_STDERR, gettext( 20617Sdinak "Unable to get private key attributes (%s)."), 20717Sdinak pkcs11_strerror(rv)); 20817Sdinak goto free_display_prikey; 20917Sdinak } 21017Sdinak 21117Sdinak /* Fill in all the optional temp variables. */ 21217Sdinak i = 13; 21317Sdinak copy_attr_to_string(&(attrs[i++]), &label, &label_len); 21417Sdinak copy_attr_to_string(&(attrs[i++]), &id, &id_len); 21517Sdinak copy_attr_to_string(&(attrs[i++]), &subject, &subject_len); 21617Sdinak copy_attr_to_date(&(attrs[i++]), &start_date, &start_date_len); 21717Sdinak copy_attr_to_date(&(attrs[i++]), &end_date, &end_date_len); 21817Sdinak 21917Sdinak /* Get the key size for the object. */ 22017Sdinak key_size = get_key_size(sess, obj, key_type); 22117Sdinak 22217Sdinak /* Display the object ... */ 22317Sdinak /* ... the label and what it is (and key size in bits) ... */ 22417Sdinak (void) fprintf(stdout, gettext("%d. \"%.*s\" (%d-bit %s %s)\n"), 22517Sdinak counter, label_len, label_len > 0 ? (char *)label : 22617Sdinak gettext("<no label>"), key_size, keytype_str(key_type), 22717Sdinak class_str(CKO_PRIVATE_KEY)); 22817Sdinak 22917Sdinak /* ... the id ... */ 23017Sdinak if (id_len == (CK_ULONG)-1 || id_len == 0) 23117Sdinak (void) fprintf(stdout, gettext("\tId: --\n")); 23217Sdinak else { 23317Sdinak hex_id_len = 3 * id_len + 1; 23417Sdinak if ((hex_id = malloc(hex_id_len)) == NULL) { 23517Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 23617Sdinak rv = CKR_HOST_MEMORY; 23717Sdinak goto free_display_prikey; 23817Sdinak } 23917Sdinak octetify(id, id_len, hex_id, hex_id_len, B_FALSE, B_FALSE, 60, 24017Sdinak "\n\t\t", ""); 24117Sdinak (void) fprintf(stdout, gettext("\tId: %s\n"), hex_id); 24217Sdinak free(hex_id); 24317Sdinak } 24417Sdinak 24517Sdinak /* ... the subject name ... */ 24617Sdinak if (subject_len == (CK_ULONG)-1 || subject_len == 0) 24717Sdinak (void) fprintf(stdout, gettext("\tSubject: --\n")); 24817Sdinak else { 24917Sdinak hex_subject_len = 2 * subject_len + 1; /* best guesstimate */ 25017Sdinak if ((hex_subject = malloc(hex_subject_len)) == NULL) { 25117Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 25217Sdinak rv = CKR_HOST_MEMORY; 25317Sdinak goto free_display_prikey; 25417Sdinak } 25517Sdinak rdnseq_to_str(subject, subject_len, hex_subject, 25617Sdinak hex_subject_len); 25717Sdinak (void) fprintf(stdout, gettext("\tSubject: %.*s\n"), 25817Sdinak hex_subject_len, hex_subject); 25917Sdinak free(hex_subject); 26017Sdinak } 26117Sdinak 26217Sdinak /* ... the start date ... */ 26317Sdinak if (start_date_len == (CK_ULONG)-1 || start_date_len == 0) 26417Sdinak (void) fprintf(stdout, gettext("\tStart Date: --\n")); 26517Sdinak else 26617Sdinak (void) fprintf(stdout, gettext( 26717Sdinak "\tStart Date: %02.2s/%02.2s/%04.4s\n"), 26817Sdinak start_date->month, start_date->day, start_date->year); 26917Sdinak 27017Sdinak /* ... the end date ... */ 27117Sdinak if (end_date_len == (CK_ULONG)-1 || end_date_len == 0) 27217Sdinak (void) fprintf(stdout, gettext("\tEnd Date: --\n")); 27317Sdinak else 27417Sdinak (void) fprintf(stdout, gettext( 27517Sdinak "\tEnd Date: %02.2s/%02.2s/%04.4s\n"), 27617Sdinak end_date->month, end_date->day, end_date->year); 27717Sdinak 27817Sdinak /* ... and its capabilities */ 27917Sdinak (void) fprintf(stdout, "\t(%s, %s", 28017Sdinak private != pk_false ? gettext("private") : gettext("public"), 28117Sdinak modifiable == B_TRUE ? gettext("modifiable") : 28217Sdinak gettext("not modifiable")); 28317Sdinak for (i = 3; i <= 12; i++) { 28417Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 28517Sdinak attrs[i].ulValueLen != 0 && 28617Sdinak *((CK_BBOOL *)(attrs[i].pValue)) == B_TRUE) 28717Sdinak (void) fprintf(stdout, ", %s", attr_str(attrs[i].type)); 28817Sdinak } 28917Sdinak (void) fprintf(stdout, ")\n"); 29017Sdinak 29117Sdinak free_display_prikey: 29217Sdinak for (i = 3; i < n_attrs; i++) 29317Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 29417Sdinak attrs[i].ulValueLen != 0) 29517Sdinak free(attrs[i].pValue); 29617Sdinak return (rv); 29717Sdinak } 29817Sdinak 29917Sdinak /* 30017Sdinak * Display public key. 30117Sdinak */ 30217Sdinak static CK_RV 30317Sdinak display_pubkey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int counter) 30417Sdinak { 30517Sdinak CK_RV rv = CKR_OK; 30617Sdinak static CK_BBOOL private; 30717Sdinak static CK_BBOOL modifiable; 30817Sdinak static CK_BBOOL trusted; 30917Sdinak static CK_KEY_TYPE key_type; 31017Sdinak CK_ULONG key_size; 31117Sdinak CK_BYTE *label = NULL; 31217Sdinak CK_ULONG label_len = 0; 31317Sdinak CK_BYTE *id = NULL; 31417Sdinak CK_ULONG id_len = 0; 31517Sdinak CK_BYTE *subject = NULL; 31617Sdinak CK_ULONG subject_len = 0; 31717Sdinak CK_DATE *start_date = NULL; 31817Sdinak CK_ULONG start_date_len = 0; 31917Sdinak CK_DATE *end_date = NULL; 32017Sdinak CK_ULONG end_date_len = 0; 32117Sdinak CK_ATTRIBUTE attrs[15] = { 32217Sdinak /* 0 to 3 */ 32317Sdinak { CKA_PRIVATE, &private, sizeof (private) }, 32417Sdinak { CKA_MODIFIABLE, &modifiable, sizeof (modifiable) }, 32517Sdinak { CKA_TRUSTED, &trusted, sizeof (trusted) }, 32617Sdinak { CKA_KEY_TYPE, &key_type, sizeof (key_type) }, 32717Sdinak /* 4 to 9 */ 32817Sdinak { CKA_DERIVE, NULL, 0 }, 32917Sdinak { CKA_LOCAL, NULL, 0 }, 33017Sdinak { CKA_ENCRYPT, NULL, 0 }, 33117Sdinak { CKA_VERIFY, NULL, 0 }, 33217Sdinak { CKA_VERIFY_RECOVER, NULL, 0 }, 33317Sdinak { CKA_WRAP, NULL, 0 }, 33417Sdinak /* 10 to 14 */ 33517Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 33617Sdinak { CKA_ID, NULL, 0 }, /* optional */ 33717Sdinak { CKA_SUBJECT, NULL, 0 }, /* optional */ 33817Sdinak { CKA_START_DATE, NULL, 0 }, /* optional */ 33917Sdinak { CKA_END_DATE, NULL, 0 } /* optional */ 34017Sdinak /* not displaying CKA_KEY_GEN_MECHANISM */ 34117Sdinak }; 34217Sdinak CK_ULONG n_attrs = sizeof (attrs) / sizeof (CK_ATTRIBUTE); 34317Sdinak int i; 34417Sdinak char *hex_id = NULL; 34517Sdinak int hex_id_len = 0; 34617Sdinak char *hex_subject = NULL; 34717Sdinak int hex_subject_len = 0; 34817Sdinak 34917Sdinak cryptodebug("inside display_pubkey"); 35017Sdinak 35117Sdinak /* Get the sizes of the attributes we need. */ 35217Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 35317Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 35417Sdinak cryptoerror(LOG_STDERR, gettext( 35517Sdinak "Unable to get public key attribute sizes (%s)."), 35617Sdinak pkcs11_strerror(rv)); 35717Sdinak return (rv); 35817Sdinak } 35917Sdinak 36017Sdinak /* Allocate memory for each variable-length attribute. */ 36117Sdinak for (i = 4; i < n_attrs; i++) { 36217Sdinak if (attrs[i].ulValueLen == (CK_ULONG)-1 || 36317Sdinak attrs[i].ulValueLen == 0) { 36417Sdinak cryptodebug("display_pubkey: *** should not happen"); 36517Sdinak attrs[i].ulValueLen = 0; 36617Sdinak continue; 36717Sdinak } 36817Sdinak if ((attrs[i].pValue = malloc(attrs[i].ulValueLen)) == NULL) { 36917Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 37017Sdinak rv = CKR_HOST_MEMORY; 37117Sdinak goto free_display_pubkey; 37217Sdinak } 37317Sdinak } 37417Sdinak 37517Sdinak /* Now really get the attributes. */ 37617Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 37717Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 37817Sdinak cryptoerror(LOG_STDERR, gettext( 37917Sdinak "Unable to get public key attributes (%s)."), 38017Sdinak pkcs11_strerror(rv)); 38117Sdinak goto free_display_pubkey; 38217Sdinak } 38317Sdinak 38417Sdinak /* Fill in all the optional temp variables. */ 38517Sdinak i = 10; 38617Sdinak copy_attr_to_string(&(attrs[i++]), &label, &label_len); 38717Sdinak copy_attr_to_string(&(attrs[i++]), &id, &id_len); 38817Sdinak copy_attr_to_string(&(attrs[i++]), &subject, &subject_len); 38917Sdinak copy_attr_to_date(&(attrs[i++]), &start_date, &start_date_len); 39017Sdinak copy_attr_to_date(&(attrs[i++]), &end_date, &end_date_len); 39117Sdinak 39217Sdinak /* Get the key size for the object. */ 39317Sdinak key_size = get_key_size(sess, obj, key_type); 39417Sdinak 39517Sdinak /* Display the object ... */ 39617Sdinak /* ... the label and what it is (and key size in bits) ... */ 39717Sdinak (void) fprintf(stdout, gettext("%d. \"%.*s\" (%d-bit %s %s)\n"), 39817Sdinak counter, label_len, label_len > 0 ? (char *)label : 39917Sdinak gettext("<no label>"), key_size, keytype_str(key_type), 40017Sdinak class_str(CKO_PUBLIC_KEY)); 40117Sdinak 40217Sdinak /* ... the id ... */ 40317Sdinak if (id_len == (CK_ULONG)-1 || id_len == 0) 40417Sdinak (void) fprintf(stdout, gettext("\tId: --\n")); 40517Sdinak else { 40617Sdinak hex_id_len = 3 * id_len + 1; 40717Sdinak if ((hex_id = malloc(hex_id_len)) == NULL) { 40817Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 40917Sdinak rv = CKR_HOST_MEMORY; 41017Sdinak goto free_display_pubkey; 41117Sdinak } 41217Sdinak octetify(id, id_len, hex_id, hex_id_len, B_FALSE, B_FALSE, 60, 41317Sdinak "\n\t\t", ""); 41417Sdinak (void) fprintf(stdout, gettext("\tId: %s\n"), hex_id); 41517Sdinak free(hex_id); 41617Sdinak } 41717Sdinak 41817Sdinak /* ... the subject name ... */ 41917Sdinak if (subject_len == (CK_ULONG)-1 || subject_len == 0) 42017Sdinak (void) fprintf(stdout, gettext("\tSubject: --\n")); 42117Sdinak else { 42217Sdinak hex_subject_len = 2 * subject_len + 1; /* best guesstimate */ 42317Sdinak if ((hex_subject = malloc(hex_subject_len)) == NULL) { 42417Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 42517Sdinak rv = CKR_HOST_MEMORY; 42617Sdinak goto free_display_pubkey; 42717Sdinak } 42817Sdinak rdnseq_to_str(subject, subject_len, hex_subject, 42917Sdinak hex_subject_len); 43017Sdinak (void) fprintf(stdout, gettext("\tSubject: %.*s\n"), 43117Sdinak hex_subject_len, hex_subject); 43217Sdinak free(hex_subject); 43317Sdinak } 43417Sdinak 43517Sdinak /* ... the start date ... */ 43617Sdinak if (start_date_len == (CK_ULONG)-1 || start_date_len == 0) 43717Sdinak (void) fprintf(stdout, gettext("\tStart Date: --\n")); 43817Sdinak else 43917Sdinak (void) fprintf(stdout, gettext( 44017Sdinak "\tStart Date: %02.2s/%02.2s/%04.4s\n"), 44117Sdinak start_date->month, start_date->day, start_date->year); 44217Sdinak 44317Sdinak /* ... the end date ... */ 44417Sdinak if (end_date_len == (CK_ULONG)-1 || end_date_len == 0) 44517Sdinak (void) fprintf(stdout, gettext("\tEnd Date: --\n")); 44617Sdinak else 44717Sdinak (void) fprintf(stdout, gettext( 44817Sdinak "\tEnd Date: %02.2s/%02.2s/%04.4s\n"), 44917Sdinak end_date->month, end_date->day, end_date->year); 45017Sdinak 45117Sdinak /* ... and its capabilities */ 45217Sdinak (void) fprintf(stdout, "\t(%s, %s, %s", 45317Sdinak private == B_TRUE ? gettext("private") : gettext("public"), 45417Sdinak modifiable == B_TRUE ? gettext("modifiable") : 45517Sdinak gettext("not modifiable"), 45617Sdinak trusted == B_TRUE ? gettext("trusted") : gettext("untrusted")); 45717Sdinak for (i = 4; i <= 9; i++) { 45817Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 45917Sdinak attrs[i].ulValueLen != 0 && 46017Sdinak *((CK_BBOOL *)(attrs[i].pValue)) == B_TRUE) 46117Sdinak (void) fprintf(stdout, ", %s", attr_str(attrs[i].type)); 46217Sdinak } 46317Sdinak (void) fprintf(stdout, ")\n"); 46417Sdinak 46517Sdinak free_display_pubkey: 46617Sdinak for (i = 4; i < n_attrs; i++) 46717Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 46817Sdinak attrs[i].ulValueLen != 0) 46917Sdinak free(attrs[i].pValue); 47017Sdinak return (rv); 47117Sdinak } 47217Sdinak 47317Sdinak /* 47417Sdinak * Display secret key. 47517Sdinak */ 47617Sdinak static CK_RV 47717Sdinak display_seckey(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int counter) 47817Sdinak { 47917Sdinak CK_RV rv = CKR_OK; 48017Sdinak static CK_BBOOL private; 48117Sdinak static CK_BBOOL modifiable; 48217Sdinak static CK_KEY_TYPE key_type; 48317Sdinak static CK_ULONG key_size; 48417Sdinak CK_BYTE *label = NULL; 48517Sdinak CK_ULONG label_len = 0; 48617Sdinak CK_BYTE *id = NULL; 48717Sdinak CK_ULONG id_len = 0; 48817Sdinak CK_DATE *start_date = NULL; 48917Sdinak CK_ULONG start_date_len = 0; 49017Sdinak CK_DATE *end_date = NULL; 49117Sdinak CK_ULONG end_date_len = 0; 49217Sdinak CK_ATTRIBUTE attrs[19] = { 49317Sdinak /* 0 to 2 */ 49417Sdinak { CKA_PRIVATE, &private, sizeof (private) }, 49517Sdinak { CKA_MODIFIABLE, &modifiable, sizeof (modifiable) }, 49617Sdinak { CKA_KEY_TYPE, &key_type, sizeof (key_type) }, 49717Sdinak /* 3 to 14 */ 49817Sdinak { CKA_DERIVE, NULL, 0 }, 49917Sdinak { CKA_LOCAL, NULL, 0 }, 50017Sdinak { CKA_ENCRYPT, NULL, 0 }, 50117Sdinak { CKA_DECRYPT, NULL, 0 }, 50217Sdinak { CKA_SIGN, NULL, 0 }, 50317Sdinak { CKA_VERIFY, NULL, 0 }, 50417Sdinak { CKA_WRAP, NULL, 0 }, 50517Sdinak { CKA_UNWRAP, NULL, 0 }, 50617Sdinak { CKA_SENSITIVE, NULL, 0 }, 50717Sdinak { CKA_ALWAYS_SENSITIVE, NULL, 0 }, 50817Sdinak { CKA_EXTRACTABLE, NULL, 0 }, 50917Sdinak { CKA_NEVER_EXTRACTABLE, 0 }, 51017Sdinak /* 15 to 18 */ 51117Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 51217Sdinak { CKA_ID, NULL, 0 }, /* optional */ 51317Sdinak { CKA_START_DATE, NULL, 0 }, /* optional */ 51417Sdinak { CKA_END_DATE, NULL, 0 } /* optional */ 51517Sdinak /* not displaying CKA_KEY_GEN_MECHANISM */ 51617Sdinak }; 51717Sdinak CK_ULONG n_attrs = sizeof (attrs) / sizeof (CK_ATTRIBUTE); 51817Sdinak int i; 51917Sdinak char *hex_id = NULL; 52017Sdinak int hex_id_len = 0; 52117Sdinak 52217Sdinak cryptodebug("inside display_seckey"); 52317Sdinak 52417Sdinak /* Get the sizes of the attributes we need. */ 52517Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 52617Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 52717Sdinak cryptoerror(LOG_STDERR, gettext( 52817Sdinak "Unable to get secret key attribute sizes (%s)."), 52917Sdinak pkcs11_strerror(rv)); 53017Sdinak return (rv); 53117Sdinak } 53217Sdinak 53317Sdinak /* Allocate memory for each variable-length attribute. */ 53417Sdinak for (i = 3; i < n_attrs; i++) { 53517Sdinak if (attrs[i].ulValueLen == (CK_ULONG)-1 || 53617Sdinak attrs[i].ulValueLen == 0) { 53717Sdinak cryptodebug("display_seckey: *** should not happen"); 53817Sdinak attrs[i].ulValueLen = 0; 53917Sdinak continue; 54017Sdinak } 54117Sdinak if ((attrs[i].pValue = malloc(attrs[i].ulValueLen)) == NULL) { 54217Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 54317Sdinak rv = CKR_HOST_MEMORY; 54417Sdinak goto free_display_seckey; 54517Sdinak } 54617Sdinak } 54717Sdinak 54817Sdinak /* Now really get the attributes. */ 54917Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 55017Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 55117Sdinak cryptoerror(LOG_STDERR, gettext( 55217Sdinak "Unable to get secret key attributes (%s)."), 55317Sdinak pkcs11_strerror(rv)); 55417Sdinak goto free_display_seckey; 55517Sdinak } 55617Sdinak 55717Sdinak /* Fill in all the optional temp variables. */ 55817Sdinak i = 15; 55917Sdinak copy_attr_to_string(&(attrs[i++]), &label, &label_len); 56017Sdinak copy_attr_to_string(&(attrs[i++]), &id, &id_len); 56117Sdinak copy_attr_to_date(&(attrs[i++]), &start_date, &start_date_len); 56217Sdinak copy_attr_to_date(&(attrs[i++]), &end_date, &end_date_len); 56317Sdinak 56417Sdinak /* Get the key size for the object. */ 56517Sdinak key_size = get_key_size(sess, obj, key_type); 56617Sdinak 56717Sdinak /* Display the object ... */ 56817Sdinak /* ... the label and what it is (and key size in bytes) ... */ 56917Sdinak (void) fprintf(stdout, gettext("%d. \"%.*s\" (%d-bit %s %s)\n"), 57017Sdinak counter, label_len, label_len > 0 ? (char *)label : 57117Sdinak gettext("<no label>"), key_size, keytype_str(key_type), 57217Sdinak class_str(CKO_SECRET_KEY)); 57317Sdinak 57417Sdinak /* ... the id ... */ 57517Sdinak if (id_len == (CK_ULONG)-1 || id_len == 0) 57617Sdinak (void) fprintf(stdout, gettext("\tId: --\n")); 57717Sdinak else { 57817Sdinak hex_id_len = 3 * id_len + 1; 57917Sdinak if ((hex_id = malloc(hex_id_len)) == NULL) { 58017Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 58117Sdinak rv = CKR_HOST_MEMORY; 58217Sdinak goto free_display_seckey; 58317Sdinak } 58417Sdinak octetify(id, id_len, hex_id, hex_id_len, B_FALSE, B_FALSE, 60, 58517Sdinak "\n\t\t", ""); 58617Sdinak (void) fprintf(stdout, gettext("\tId: %s\n"), hex_id); 58717Sdinak free(hex_id); 58817Sdinak } 58917Sdinak 59017Sdinak /* ... the start date ... */ 59117Sdinak if (start_date_len == (CK_ULONG)-1 || start_date_len == 0) 59217Sdinak (void) fprintf(stdout, gettext("\tStart Date: --\n")); 59317Sdinak else 59417Sdinak (void) fprintf(stdout, gettext( 59517Sdinak "\tStart Date: %02.2s/%02.2s/%04.4s\n"), 59617Sdinak start_date->month, start_date->day, start_date->year); 59717Sdinak 59817Sdinak /* ... the end date ... */ 59917Sdinak if (end_date_len == (CK_ULONG)-1 || end_date_len == 0) 60017Sdinak (void) fprintf(stdout, gettext("\tEnd Date: --\n")); 60117Sdinak else 60217Sdinak (void) fprintf(stdout, gettext( 60317Sdinak "\tEnd Date: %02.2s/%02.2s/%04.4s\n"), 60417Sdinak end_date->month, end_date->day, end_date->year); 60517Sdinak 60617Sdinak /* ... and its capabilities */ 60717Sdinak (void) fprintf(stdout, "\t(%s, %s", 60817Sdinak private == B_TRUE ? gettext("private") : gettext("public"), 60917Sdinak modifiable == B_TRUE ? gettext("modifiable") : 61017Sdinak gettext("not modifiable")); 61117Sdinak for (i = 3; i <= 14; i++) { 61217Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 61317Sdinak attrs[i].ulValueLen != 0 && 61417Sdinak *((CK_BBOOL *)(attrs[i].pValue)) == B_TRUE) 61517Sdinak (void) fprintf(stdout, ", %s", attr_str(attrs[i].type)); 61617Sdinak } 61717Sdinak (void) fprintf(stdout, ")\n"); 61817Sdinak 61917Sdinak free_display_seckey: 62017Sdinak for (i = 3; i < n_attrs; i++) 62117Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 62217Sdinak attrs[i].ulValueLen != 0) 62317Sdinak free(attrs[i].pValue); 62417Sdinak return (rv); 62517Sdinak } 62617Sdinak 62717Sdinak /* 62817Sdinak * Display certificate. 62917Sdinak */ 63017Sdinak static CK_RV 63117Sdinak display_cert(CK_SESSION_HANDLE sess, CK_OBJECT_HANDLE obj, int counter) 63217Sdinak { 63317Sdinak CK_RV rv = CKR_OK; 63417Sdinak static CK_BBOOL private; 63517Sdinak static CK_BBOOL modifiable; 63617Sdinak static CK_BBOOL trusted; 63717Sdinak CK_BYTE *subject = NULL; 63817Sdinak CK_ULONG subject_len = 0; 63917Sdinak CK_BYTE *value = NULL; 64017Sdinak CK_ULONG value_len = 0; 64117Sdinak CK_BYTE *label = NULL; 64217Sdinak CK_ULONG label_len = 0; 64317Sdinak CK_BYTE *id = NULL; 64417Sdinak CK_ULONG id_len = 0; 64517Sdinak CK_BYTE *issuer = NULL; 64617Sdinak CK_ULONG issuer_len = 0; 64717Sdinak CK_BYTE *serial = NULL; 64817Sdinak CK_ULONG serial_len = 0; 64917Sdinak CK_ATTRIBUTE attrs[9] = { 65017Sdinak { CKA_PRIVATE, &private, sizeof (private) }, 65117Sdinak { CKA_MODIFIABLE, &modifiable, sizeof (modifiable) }, 65217Sdinak { CKA_TRUSTED, &trusted, sizeof (trusted) }, 65317Sdinak { CKA_SUBJECT, NULL, 0 }, /* required */ 65417Sdinak { CKA_VALUE, NULL, 0 }, /* required */ 65517Sdinak { CKA_LABEL, NULL, 0 }, /* optional */ 65617Sdinak { CKA_ID, NULL, 0 }, /* optional */ 65717Sdinak { CKA_ISSUER, NULL, 0 }, /* optional */ 65817Sdinak { CKA_SERIAL_NUMBER, NULL, 0 } /* optional */ 65917Sdinak }; 66017Sdinak CK_ULONG n_attrs = sizeof (attrs) / sizeof (CK_ATTRIBUTE); 66117Sdinak int i; 66217Sdinak char *hex_id = NULL; 66317Sdinak int hex_id_len = 0; 66417Sdinak char *hex_subject = NULL; 66517Sdinak int hex_subject_len = 0; 66617Sdinak char *hex_issuer = NULL; 66717Sdinak int hex_issuer_len = 0; 66817Sdinak char *hex_serial = NULL; 66917Sdinak int hex_serial_len = NULL; 67017Sdinak uint32_t serial_value = 0; 67117Sdinak char *hex_value = NULL; 67217Sdinak int hex_value_len = 0; 67317Sdinak 67417Sdinak cryptodebug("inside display_cert"); 67517Sdinak 67617Sdinak /* Get the sizes of the attributes we need. */ 67717Sdinak cryptodebug("calling C_GetAttributeValue for size info"); 67817Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 67917Sdinak cryptoerror(LOG_STDERR, gettext( 68017Sdinak "Unable to get certificate attribute sizes (%s)."), 68117Sdinak pkcs11_strerror(rv)); 68217Sdinak return (rv); 68317Sdinak } 68417Sdinak 68517Sdinak /* Allocate memory for each variable-length attribute. */ 68617Sdinak for (i = 3; i < n_attrs; i++) { 68717Sdinak if (attrs[i].ulValueLen == (CK_ULONG)-1 || 68817Sdinak attrs[i].ulValueLen == 0) { 68917Sdinak cryptodebug("display_cert: *** should not happen"); 69017Sdinak attrs[i].ulValueLen = 0; 69117Sdinak continue; 69217Sdinak } 69317Sdinak if ((attrs[i].pValue = malloc(attrs[i].ulValueLen)) == NULL) { 69417Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 69517Sdinak rv = CKR_HOST_MEMORY; 69617Sdinak goto free_display_cert; 69717Sdinak } 69817Sdinak } 69917Sdinak 70017Sdinak /* Now really get the attributes. */ 70117Sdinak cryptodebug("calling C_GetAttributeValue for attribute info"); 70217Sdinak if ((rv = C_GetAttributeValue(sess, obj, attrs, n_attrs)) != CKR_OK) { 70317Sdinak cryptoerror(LOG_STDERR, gettext( 70417Sdinak "Unable to get certificate attributes (%s)."), 70517Sdinak pkcs11_strerror(rv)); 70617Sdinak goto free_display_cert; 70717Sdinak } 70817Sdinak 70917Sdinak /* 71017Sdinak * Fill in all the temp variables. Subject and value are required. 71117Sdinak * The rest are optional. 71217Sdinak */ 71317Sdinak i = 3; 71417Sdinak copy_attr_to_string(&(attrs[i++]), &subject, &subject_len); 71517Sdinak copy_attr_to_string(&(attrs[i++]), &value, &value_len); 71617Sdinak copy_attr_to_string(&(attrs[i++]), &label, &label_len); 71717Sdinak copy_attr_to_string(&(attrs[i++]), &id, &id_len); 71817Sdinak copy_attr_to_string(&(attrs[i++]), &issuer, &issuer_len); 71917Sdinak copy_attr_to_string(&(attrs[i++]), &serial, &serial_len); 72017Sdinak 72117Sdinak /* Display the object ... */ 72217Sdinak /* ... the label and what it is ... */ 72317Sdinak (void) fprintf(stdout, gettext("%d. \"%.*s\" (%s %s)\n"), 72417Sdinak counter, label_len, label_len > 0 ? (char *)label : 72517Sdinak gettext("<no label>"), "X.509", class_str(CKO_CERTIFICATE)); 72617Sdinak 72717Sdinak /* ... its capabilities ... */ 72817Sdinak (void) fprintf(stdout, gettext("\t(%s, %s, %s)\n"), 72917Sdinak private == B_TRUE ? gettext("private") : gettext("public"), 73017Sdinak modifiable == B_TRUE ? gettext("modifiable") : 73117Sdinak gettext("not modifiable"), 73217Sdinak trusted == B_TRUE ? gettext("trusted") : gettext("untrusted")); 73317Sdinak 73417Sdinak /* ... the id ... */ 73517Sdinak if (id_len == (CK_ULONG)-1 || id_len == 0) 73617Sdinak (void) fprintf(stdout, gettext("\tId: --\n")); 73717Sdinak else { 73817Sdinak hex_id_len = 3 * id_len + 1; 73917Sdinak if ((hex_id = malloc(hex_id_len)) == NULL) { 74017Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 74117Sdinak rv = CKR_HOST_MEMORY; 74217Sdinak goto free_display_cert; 74317Sdinak } 74417Sdinak octetify(id, id_len, hex_id, hex_id_len, B_FALSE, B_FALSE, 60, 74517Sdinak "\n\t\t", ""); 74617Sdinak (void) fprintf(stdout, gettext("\tId: %s\n"), hex_id); 74717Sdinak free(hex_id); 74817Sdinak } 74917Sdinak 75017Sdinak /* ... the subject name ... */ 75117Sdinak if (subject_len == (CK_ULONG)-1 || subject_len == 0) 75217Sdinak (void) fprintf(stdout, gettext("\tSubject: --\n")); 75317Sdinak else { 75417Sdinak hex_subject_len = 2 * subject_len + 1; /* best guesstimate */ 75517Sdinak if ((hex_subject = malloc(hex_subject_len)) == NULL) { 75617Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 75717Sdinak rv = CKR_HOST_MEMORY; 75817Sdinak goto free_display_cert; 75917Sdinak } 76017Sdinak rdnseq_to_str(subject, subject_len, hex_subject, 76117Sdinak hex_subject_len); 76217Sdinak (void) fprintf(stdout, gettext("\tSubject: %.*s\n"), 76317Sdinak hex_subject_len, hex_subject); 76417Sdinak free(hex_subject); 76517Sdinak } 76617Sdinak 76717Sdinak /* ... the issuer name ... */ 76817Sdinak if (issuer_len == (CK_ULONG)-1 || issuer_len == 0) 76917Sdinak (void) fprintf(stdout, gettext("\tIssuer: --\n")); 77017Sdinak else { 77117Sdinak hex_issuer_len = 2 * issuer_len + 1; /* best guesstimate */ 77217Sdinak if ((hex_issuer = malloc(hex_issuer_len)) == NULL) { 77317Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 77417Sdinak rv = CKR_HOST_MEMORY; 77517Sdinak goto free_display_cert; 77617Sdinak } 77717Sdinak rdnseq_to_str(issuer, issuer_len, hex_issuer, hex_issuer_len); 77817Sdinak (void) fprintf(stdout, gettext("\tIssuer: %.*s\n"), 77917Sdinak hex_issuer_len, hex_issuer); 78017Sdinak free(hex_issuer); 78117Sdinak } 78217Sdinak 78317Sdinak /* ... the serial number ... */ 78417Sdinak if (serial_len == (CK_ULONG)-1 || serial_len == 0) 78517Sdinak (void) fprintf(stdout, gettext("\tSerial: --\n")); 78617Sdinak else { 78717Sdinak hex_serial_len = 3 * serial_len + 1; 78817Sdinak if ((hex_serial = malloc(hex_serial_len)) == NULL) { 78917Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 79017Sdinak rv = CKR_HOST_MEMORY; 79117Sdinak goto free_display_cert; 79217Sdinak } 79317Sdinak octetify(serial, serial_len, hex_serial, hex_serial_len, 79417Sdinak B_FALSE, B_FALSE, 60, "\n\t\t", ""); 79517Sdinak if (serial_len > 4) 79617Sdinak (void) fprintf(stdout, gettext("\tSerial: %s\n"), 79717Sdinak hex_serial); 79817Sdinak else { 79917Sdinak for (i = 0; i < serial_len; i++) { 80017Sdinak serial_value <<= 8; 80117Sdinak serial_value |= (serial[i] & 0xff); 80217Sdinak } 80317Sdinak (void) fprintf(stdout, gettext("\tSerial: %s (%d)\n"), 80417Sdinak hex_serial, serial_value); 80517Sdinak } 80617Sdinak free(hex_serial); 80717Sdinak } 80817Sdinak 80917Sdinak /* ... and the value */ 81017Sdinak if (value_len == (CK_ULONG)-1 || value_len == 0) 81117Sdinak (void) fprintf(stdout, gettext("\tValue: --\n")); 81217Sdinak else { 81317Sdinak hex_value_len = 3 * value_len + 1; 81417Sdinak if ((hex_value = malloc(hex_value_len)) == NULL) { 81517Sdinak cryptoerror(LOG_STDERR, "%s.", strerror(errno)); 81617Sdinak rv = CKR_HOST_MEMORY; 81717Sdinak goto free_display_cert; 81817Sdinak } 81917Sdinak octetify(value, value_len, hex_value, hex_value_len, 82017Sdinak B_FALSE, B_FALSE, 60, "\n\t\t", ""); 82117Sdinak (void) fprintf(stdout, gettext("\tValue: %s\n"), hex_value); 82217Sdinak free(hex_value); 82317Sdinak } 82417Sdinak 82517Sdinak free_display_cert: 82617Sdinak for (i = 3; i < n_attrs; i++) 82717Sdinak if (attrs[i].ulValueLen != (CK_ULONG)-1 && 82817Sdinak attrs[i].ulValueLen != 0) 82917Sdinak free(attrs[i].pValue); 83017Sdinak return (rv); 83117Sdinak } 83217Sdinak 83317Sdinak /* 83417Sdinak * List token object. 83517Sdinak */ 83617Sdinak int 83717Sdinak pk_list(int argc, char *argv[]) 83817Sdinak { 83917Sdinak int opt; 840*864Sdinak extern int optind_av; 841*864Sdinak extern char *optarg_av; 842*864Sdinak char *token_spec = NULL; 84317Sdinak char *token_name = NULL; 84417Sdinak char *manuf_id = NULL; 84517Sdinak char *serial_no = NULL; 846*864Sdinak char *type_spec = NULL; 84717Sdinak char full_name[FULL_NAME_LEN]; 84817Sdinak boolean_t public_objs = B_FALSE; 84917Sdinak boolean_t private_objs = B_FALSE; 85017Sdinak CK_BYTE *list_label = NULL; 85117Sdinak int obj_type = 0x00; 85217Sdinak CK_SLOT_ID slot_id; 85317Sdinak CK_FLAGS pin_state; 85417Sdinak CK_UTF8CHAR_PTR pin = NULL; 85517Sdinak CK_ULONG pinlen = 0; 85617Sdinak CK_SESSION_HANDLE sess; 85717Sdinak CK_OBJECT_HANDLE *objs; 85817Sdinak CK_ULONG num_objs; 85917Sdinak CK_RV rv = CKR_OK; 86017Sdinak int i; 86117Sdinak static CK_OBJECT_CLASS objclass; 86217Sdinak CK_ATTRIBUTE class_attr = 86317Sdinak { CKA_CLASS, &objclass, sizeof (objclass) }; 86417Sdinak 86517Sdinak cryptodebug("inside pk_list"); 86617Sdinak 86717Sdinak /* Parse command line options. Do NOT i18n/l10n. */ 868*864Sdinak while ((opt = getopt_av(argc, argv, 869*864Sdinak "T:(token)y:(objtype)l:(label)")) != EOF) { 87017Sdinak switch (opt) { 871*864Sdinak case 'T': /* token specifier */ 872*864Sdinak if (token_spec) 873*864Sdinak return (PK_ERR_USAGE); 874*864Sdinak token_spec = optarg_av; 87517Sdinak break; 876*864Sdinak case 'y': /* object type: public, private, both */ 877*864Sdinak if (type_spec) 878*864Sdinak return (PK_ERR_USAGE); 879*864Sdinak type_spec = optarg_av; 88017Sdinak break; 88117Sdinak case 'l': /* object with specific label */ 88217Sdinak if (list_label) 88317Sdinak return (PK_ERR_USAGE); 884*864Sdinak list_label = (CK_BYTE *)optarg_av; 88517Sdinak break; 88617Sdinak default: 88717Sdinak return (PK_ERR_USAGE); 88817Sdinak break; 88917Sdinak } 89017Sdinak } 89117Sdinak 892*864Sdinak /* If no token is specified, default is to use softtoken. */ 893*864Sdinak if (token_spec == NULL) { 894*864Sdinak token_name = SOFT_TOKEN_LABEL; 895*864Sdinak manuf_id = SOFT_MANUFACTURER_ID; 896*864Sdinak serial_no = SOFT_TOKEN_SERIAL; 897*864Sdinak } else { 898*864Sdinak /* 899*864Sdinak * Parse token specifier into token_name, manuf_id, serial_no. 900*864Sdinak * Token_name is required; manuf_id and serial_no are optional. 901*864Sdinak */ 902*864Sdinak if (parse_token_spec(token_spec, &token_name, &manuf_id, 903*864Sdinak &serial_no) < 0) 904*864Sdinak return (PK_ERR_USAGE); 90517Sdinak } 90617Sdinak 907*864Sdinak /* If no object type specified, default is public objects. */ 908*864Sdinak if (!type_spec) { 909*864Sdinak public_objs = B_TRUE; 910*864Sdinak } else { 911*864Sdinak /* 912*864Sdinak * Otherwise, the object type must be "public", "private", 913*864Sdinak * or "both". 914*864Sdinak */ 915*864Sdinak if (strcmp(type_spec, "private") == 0) { 916*864Sdinak private_objs = B_TRUE; 917*864Sdinak } else if (strcmp(type_spec, "public") == 0) { 918*864Sdinak public_objs = B_TRUE; 919*864Sdinak } else if (strcmp(type_spec, "both") == 0) { 920*864Sdinak private_objs = B_TRUE; 921*864Sdinak public_objs = B_TRUE; 922*864Sdinak } else 923*864Sdinak return (PK_ERR_USAGE); 924*864Sdinak } 925*864Sdinak 926*864Sdinak if (private_objs) 927*864Sdinak obj_type |= PK_PRIVATE_OBJ; 928*864Sdinak if (public_objs) 929*864Sdinak obj_type |= PK_PUBLIC_OBJ; 930*864Sdinak 93117Sdinak /* No additional args allowed. */ 932*864Sdinak argc -= optind_av; 933*864Sdinak argv += optind_av; 93417Sdinak if (argc) 93517Sdinak return (PK_ERR_USAGE); 93617Sdinak /* Done parsing command line options. */ 93717Sdinak 93817Sdinak full_token_name(token_name, manuf_id, serial_no, full_name); 93917Sdinak 94017Sdinak /* Find the slot with token. */ 94117Sdinak if ((rv = find_token_slot(token_name, manuf_id, serial_no, &slot_id, 94217Sdinak &pin_state)) != CKR_OK) { 94317Sdinak cryptoerror(LOG_STDERR, gettext( 94417Sdinak "Unable to find token %s (%s)."), full_name, 94517Sdinak pkcs11_strerror(rv)); 94617Sdinak return (PK_ERR_PK11); 94717Sdinak } 94817Sdinak 94917Sdinak /* If private objects are to be listed, user must be logged in. */ 95017Sdinak if (private_objs) { 95117Sdinak /* Get the user's PIN. */ 95217Sdinak if ((rv = get_pin(gettext("Enter token passphrase:"), NULL, 95317Sdinak &pin, &pinlen)) != CKR_OK) { 95417Sdinak cryptoerror(LOG_STDERR, 95517Sdinak gettext("Unable to get token passphrase (%s)."), 95617Sdinak pkcs11_strerror(rv)); 95717Sdinak quick_finish(NULL); 95817Sdinak return (PK_ERR_PK11); 95917Sdinak } 96017Sdinak 96117Sdinak /* Logging in user R/O into the token is sufficient. */ 96217Sdinak cryptodebug("logging in with readonly session"); 96317Sdinak if ((rv = quick_start(slot_id, 0, pin, pinlen, &sess)) != 96417Sdinak CKR_OK) { 96517Sdinak cryptoerror(LOG_STDERR, 96617Sdinak gettext("Unable to log into token (%s)."), 96717Sdinak pkcs11_strerror(rv)); 96817Sdinak quick_finish(sess); 96917Sdinak return (PK_ERR_PK11); 97017Sdinak } 97117Sdinak /* Otherwise, just create a session. */ 97217Sdinak } else { 97317Sdinak cryptodebug("opening a readonly session"); 97417Sdinak if ((rv = open_sess(slot_id, 0, &sess)) != CKR_OK) { 97517Sdinak cryptoerror(LOG_STDERR, 97617Sdinak gettext("Unable to open token session (%s)."), 97717Sdinak pkcs11_strerror(rv)); 97817Sdinak quick_finish(sess); 97917Sdinak return (PK_ERR_PK11); 98017Sdinak } 98117Sdinak } 98217Sdinak 98317Sdinak /* Find the object(s) with the given label and/or type. */ 98417Sdinak if ((rv = find_objs(sess, obj_type, list_label, &objs, &num_objs)) != 98517Sdinak CKR_OK) { 98617Sdinak cryptoerror(LOG_STDERR, gettext( 98717Sdinak "Unable to find token objects (%s)."), pkcs11_strerror(rv)); 98817Sdinak quick_finish(sess); 98917Sdinak return (PK_ERR_PK11); 99017Sdinak } 99117Sdinak 99217Sdinak if (num_objs == 0) { 99317Sdinak cryptoerror(LOG_STDERR, gettext("No objects found.")); 99417Sdinak quick_finish(sess); 99517Sdinak return (0); 99617Sdinak } 99717Sdinak 99817Sdinak /* List the objects found. */ 99917Sdinak for (i = 0; i < num_objs; i++) { 100017Sdinak /* Get object class first, then decide what is next. */ 100117Sdinak cryptodebug("calling C_GetAttributeValue for object class"); 100217Sdinak if ((rv = C_GetAttributeValue(sess, objs[i], &class_attr, 1)) 100317Sdinak != CKR_OK) { 100417Sdinak cryptoerror(LOG_STDERR, gettext( 100517Sdinak "Unable to get object #%d class attribute (%s)."), 100617Sdinak i+1, pkcs11_strerror(rv)); 100717Sdinak continue; 100817Sdinak } 100917Sdinak 101017Sdinak /* Display based on the type of object. */ 101117Sdinak switch (objclass) { 101217Sdinak case CKO_CERTIFICATE: 101317Sdinak if ((rv = display_cert(sess, objs[i], i+1)) != CKR_OK) 101417Sdinak cryptoerror(LOG_STDERR, 101517Sdinak gettext("Unable to display certificate.")); 101617Sdinak break; 101717Sdinak case CKO_PUBLIC_KEY: 101817Sdinak if ((rv = display_pubkey(sess, objs[i], i+1)) != CKR_OK) 101917Sdinak cryptoerror(LOG_STDERR, 102017Sdinak gettext("Unable to display public key.")); 102117Sdinak break; 102217Sdinak case CKO_PRIVATE_KEY: 102317Sdinak if ((rv = display_prikey(sess, objs[i], i+1)) != CKR_OK) 102417Sdinak cryptoerror(LOG_STDERR, 102517Sdinak gettext("Unable to display private key.")); 102617Sdinak break; 102717Sdinak case CKO_SECRET_KEY: 102817Sdinak if ((rv = display_seckey(sess, objs[i], i+1)) != CKR_OK) 102917Sdinak cryptoerror(LOG_STDERR, 103017Sdinak gettext("Unable to display secret key.")); 103117Sdinak break; 103217Sdinak case CKO_DATA: 103317Sdinak cryptoerror(LOG_STDERR, 103417Sdinak gettext("Data object display not implemented.")); 103517Sdinak break; 103617Sdinak default: 103717Sdinak cryptoerror(LOG_STDERR, gettext( 103817Sdinak "Unknown token object class (0x%02x)."), objclass); 103917Sdinak break; 104017Sdinak } 104117Sdinak } 104217Sdinak 104317Sdinak /* Clean up. */ 104417Sdinak quick_finish(sess); 104517Sdinak return (0); 104617Sdinak } 1047