list.c revision 49e212991a3065f7e499a4b29ae8d8eaf33f3135
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This file implements the token object list operation for this tool.
* It loads the PKCS#11 modules, finds the object to list, lists it,
* and cleans up. User must be logged into the token to list private
* objects.
*/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <cryptoutil.h>
#include <security/cryptoki.h>
#include "common.h"
#include "derparse.h"
/*
* Get key size based on the key type.
*/
static CK_ULONG
{
cryptodebug("inside get_key_size");
switch (key_type) {
case CKK_RSA:
CKR_OK) {
"Unable to get modulus attribute size (%s)."),
} else
/* Convert key size to bits. */
break;
case CKK_DH:
CKR_OK) {
"Unable to get value attribute size (%s)."),
} else
/* Convert key size to bits. */
break;
case CKK_X9_42_DH:
case CKK_DSA:
CKR_OK) {
"Unable to get prime attribute size (%s)."),
} else
/* Convert key size to bits. */
break;
case CKK_DES:
case CKK_DES3:
CKR_OK) {
"Unable to get value attribute size (%s)."),
} else
/* Convert key size to bits -- omitting parity bit. */
break;
case CKK_AES:
case CKK_GENERIC_SECRET:
CKR_OK) {
"Unable to get value attribute size (%s)."),
} else
/* Convert key size to bits. */
break;
default:
"Unknown object key type (0x%02x)."), key_type);
break;
}
return (key_size);
}
/*
* Display private key.
*/
static CK_RV
{
static CK_BBOOL modifiable;
static CK_KEY_TYPE key_type;
CK_ULONG subject_len = 0;
CK_ULONG start_date_len = 0;
CK_ULONG end_date_len = 0;
/* 0 to 2 */
/* 3 to 12 */
{ CKA_DERIVE, NULL, 0 },
{ CKA_DECRYPT, NULL, 0 },
{ CKA_SIGN_RECOVER, NULL, 0 },
{ CKA_UNWRAP, NULL, 0 },
{ CKA_SENSITIVE, NULL, 0 },
{ CKA_ALWAYS_SENSITIVE, NULL, 0 },
{ CKA_EXTRACTABLE, NULL, 0 },
{ CKA_NEVER_EXTRACTABLE, NULL, 0 },
/* 13 to 17 */
/* not displaying CKA_KEY_GEN_MECHANISM */
};
int i;
int hex_id_len = 0;
char *hex_subject = NULL;
int hex_subject_len = 0;
cryptodebug("inside display_prikey");
/* Get the sizes of the attributes we need. */
cryptodebug("calling C_GetAttributeValue for size info");
"Unable to get private key attribute sizes (%s)."),
return (rv);
}
/* Allocate memory for each variable-length attribute. */
for (i = 3; i < n_attrs; i++) {
attrs[i].ulValueLen == 0) {
cryptodebug("display_prikey: *** should not happen");
attrs[i].ulValueLen = 0;
continue;
}
goto free_display_prikey;
}
}
/* Now really get the attributes. */
cryptodebug("calling C_GetAttributeValue for attribute info");
"Unable to get private key attributes (%s)."),
goto free_display_prikey;
}
/* Fill in all the optional temp variables. */
i = 13;
/* Get the key size for the object. */
/* Display the object ... */
/* ... the label and what it is (and key size in bits) ... */
/* ... the id ... */
else {
goto free_display_prikey;
}
"\n\t\t", "");
}
/* ... the subject name ... */
else {
goto free_display_prikey;
}
}
/* ... the start date ... */
else
"\tStart Date: %02.2s/%02.2s/%04.4s\n"),
/* ... the end date ... */
else
"\tEnd Date: %02.2s/%02.2s/%04.4s\n"),
/* ... and its capabilities */
gettext("not modifiable"));
for (i = 3; i <= 12; i++) {
attrs[i].ulValueLen != 0 &&
}
for (i = 3; i < n_attrs; i++)
attrs[i].ulValueLen != 0)
return (rv);
}
/*
* Display public key.
*/
static CK_RV
{
static CK_BBOOL modifiable;
static CK_KEY_TYPE key_type;
CK_ULONG subject_len = 0;
CK_ULONG start_date_len = 0;
CK_ULONG end_date_len = 0;
/* 0 to 3 */
/* 4 to 9 */
{ CKA_DERIVE, NULL, 0 },
{ CKA_ENCRYPT, NULL, 0 },
{ CKA_VERIFY, NULL, 0 },
{ CKA_VERIFY_RECOVER, NULL, 0 },
/* 10 to 14 */
/* not displaying CKA_KEY_GEN_MECHANISM */
};
int i;
int hex_id_len = 0;
char *hex_subject = NULL;
int hex_subject_len = 0;
cryptodebug("inside display_pubkey");
/* Get the sizes of the attributes we need. */
cryptodebug("calling C_GetAttributeValue for size info");
"Unable to get public key attribute sizes (%s)."),
return (rv);
}
/* Allocate memory for each variable-length attribute. */
for (i = 4; i < n_attrs; i++) {
attrs[i].ulValueLen == 0) {
cryptodebug("display_pubkey: *** should not happen");
attrs[i].ulValueLen = 0;
continue;
}
goto free_display_pubkey;
}
}
/* Now really get the attributes. */
cryptodebug("calling C_GetAttributeValue for attribute info");
"Unable to get public key attributes (%s)."),
goto free_display_pubkey;
}
/* Fill in all the optional temp variables. */
i = 10;
/* Get the key size for the object. */
/* Display the object ... */
/* ... the label and what it is (and key size in bits) ... */
/* ... the id ... */
else {
goto free_display_pubkey;
}
"\n\t\t", "");
}
/* ... the subject name ... */
else {
goto free_display_pubkey;
}
}
/* ... the start date ... */
else
"\tStart Date: %02.2s/%02.2s/%04.4s\n"),
/* ... the end date ... */
else
"\tEnd Date: %02.2s/%02.2s/%04.4s\n"),
/* ... and its capabilities */
gettext("not modifiable"),
for (i = 4; i <= 9; i++) {
attrs[i].ulValueLen != 0 &&
}
for (i = 4; i < n_attrs; i++)
attrs[i].ulValueLen != 0)
return (rv);
}
/*
* Display secret key.
*/
static CK_RV
{
static CK_BBOOL modifiable;
static CK_KEY_TYPE key_type;
CK_ULONG start_date_len = 0;
CK_ULONG end_date_len = 0;
/* 0 to 2 */
/* 3 to 14 */
{ CKA_DERIVE, NULL, 0 },
{ CKA_ENCRYPT, NULL, 0 },
{ CKA_DECRYPT, NULL, 0 },
{ CKA_VERIFY, NULL, 0 },
{ CKA_UNWRAP, NULL, 0 },
{ CKA_SENSITIVE, NULL, 0 },
{ CKA_ALWAYS_SENSITIVE, NULL, 0 },
{ CKA_EXTRACTABLE, NULL, 0 },
{ CKA_NEVER_EXTRACTABLE, 0 },
/* 15 to 18 */
/* not displaying CKA_KEY_GEN_MECHANISM */
};
int i;
int hex_id_len = 0;
cryptodebug("inside display_seckey");
/* Get the sizes of the attributes we need. */
cryptodebug("calling C_GetAttributeValue for size info");
"Unable to get secret key attribute sizes (%s)."),
return (rv);
}
/* Allocate memory for each variable-length attribute. */
for (i = 3; i < n_attrs; i++) {
attrs[i].ulValueLen == 0) {
cryptodebug("display_seckey: *** should not happen");
attrs[i].ulValueLen = 0;
continue;
}
goto free_display_seckey;
}
}
/* Now really get the attributes. */
cryptodebug("calling C_GetAttributeValue for attribute info");
"Unable to get secret key attributes (%s)."),
goto free_display_seckey;
}
/* Fill in all the optional temp variables. */
i = 15;
/* Get the key size for the object. */
/* Display the object ... */
/* ... the label and what it is (and key size in bytes) ... */
/* ... the id ... */
else {
goto free_display_seckey;
}
"\n\t\t", "");
}
/* ... the start date ... */
else
"\tStart Date: %02.2s/%02.2s/%04.4s\n"),
/* ... the end date ... */
else
"\tEnd Date: %02.2s/%02.2s/%04.4s\n"),
/* ... and its capabilities */
gettext("not modifiable"));
for (i = 3; i <= 14; i++) {
attrs[i].ulValueLen != 0 &&
}
for (i = 3; i < n_attrs; i++)
attrs[i].ulValueLen != 0)
return (rv);
}
/*
* Display certificate.
*/
static CK_RV
{
static CK_BBOOL modifiable;
CK_ULONG subject_len = 0;
CK_ULONG issuer_len = 0;
CK_ULONG serial_len = 0;
};
int i;
int hex_id_len = 0;
char *hex_subject = NULL;
int hex_subject_len = 0;
char *hex_issuer = NULL;
int hex_issuer_len = 0;
char *hex_serial = NULL;
int hex_serial_len = NULL;
uint32_t serial_value = 0;
int hex_value_len = 0;
cryptodebug("inside display_cert");
/* Get the sizes of the attributes we need. */
cryptodebug("calling C_GetAttributeValue for size info");
"Unable to get certificate attribute sizes (%s)."),
return (rv);
}
/* Allocate memory for each variable-length attribute. */
for (i = 3; i < n_attrs; i++) {
attrs[i].ulValueLen == 0) {
cryptodebug("display_cert: *** should not happen");
attrs[i].ulValueLen = 0;
continue;
}
goto free_display_cert;
}
}
/* Now really get the attributes. */
cryptodebug("calling C_GetAttributeValue for attribute info");
"Unable to get certificate attributes (%s)."),
goto free_display_cert;
}
/*
* Fill in all the temp variables. Subject and value are required.
* The rest are optional.
*/
i = 3;
/* Display the object ... */
/* ... the label and what it is ... */
/* ... its capabilities ... */
gettext("not modifiable"),
/* ... the id ... */
else {
goto free_display_cert;
}
"\n\t\t", "");
}
/* ... the subject name ... */
else {
goto free_display_cert;
}
}
/* ... the issuer name ... */
else {
goto free_display_cert;
}
}
/* ... the serial number ... */
else {
goto free_display_cert;
}
if (serial_len > 4)
else {
for (i = 0; i < serial_len; i++) {
serial_value <<= 8;
}
}
}
/* ... and the value */
else {
goto free_display_cert;
}
}
for (i = 3; i < n_attrs; i++)
attrs[i].ulValueLen != 0)
return (rv);
}
/*
* List token object.
*/
int
{
int opt;
extern int optind_av;
extern char *optarg_av;
char *token_spec = NULL;
char *token_name = NULL;
char full_name[FULL_NAME_LEN];
int obj_type = 0x00;
int i;
static CK_OBJECT_CLASS objclass;
cryptodebug("inside pk_list");
"T:(token)y:(objtype)l:(label)")) != EOF) {
switch (opt) {
case 'T': /* token specifier */
if (token_spec)
return (PK_ERR_USAGE);
break;
case 'y': /* object type: public, private, both */
if (type_spec)
return (PK_ERR_USAGE);
break;
case 'l': /* object with specific label */
if (list_label)
return (PK_ERR_USAGE);
break;
default:
return (PK_ERR_USAGE);
break;
}
}
/* If no token is specified, default is to use softtoken. */
if (token_spec == NULL) {
} else {
/*
* Parse token specifier into token_name, manuf_id, serial_no.
* Token_name is required; manuf_id and serial_no are optional.
*/
&serial_no) < 0)
return (PK_ERR_USAGE);
}
/* If no object type specified, default is public objects. */
if (!type_spec) {
} else {
/*
* Otherwise, the object type must be "public", "private",
* or "both".
*/
} else
return (PK_ERR_USAGE);
}
if (private_objs)
if (public_objs)
/* No additional args allowed. */
if (argc)
return (PK_ERR_USAGE);
/* Done parsing command line options. */
/* Find the slot with token. */
"Unable to find token %s (%s)."), full_name,
return (PK_ERR_PK11);
}
/* If private objects are to be listed, user must be logged in. */
if (private_objs) {
/* Get the user's PIN. */
gettext("Unable to get token passphrase (%s)."),
return (PK_ERR_PK11);
}
/* Logging in user R/O into the token is sufficient. */
cryptodebug("logging in with readonly session");
CKR_OK) {
gettext("Unable to log into token (%s)."),
return (PK_ERR_PK11);
}
/* Otherwise, just create a session. */
} else {
cryptodebug("opening a readonly session");
gettext("Unable to open token session (%s)."),
return (PK_ERR_PK11);
}
}
CKR_OK) {
return (PK_ERR_PK11);
}
if (num_objs == 0) {
return (0);
}
/* List the objects found. */
for (i = 0; i < num_objs; i++) {
/* Get object class first, then decide what is next. */
cryptodebug("calling C_GetAttributeValue for object class");
!= CKR_OK) {
"Unable to get object #%d class attribute (%s)."),
continue;
}
/* Display based on the type of object. */
switch (objclass) {
case CKO_CERTIFICATE:
gettext("Unable to display certificate."));
break;
case CKO_PUBLIC_KEY:
gettext("Unable to display public key."));
break;
case CKO_PRIVATE_KEY:
gettext("Unable to display private key."));
break;
case CKO_SECRET_KEY:
gettext("Unable to display secret key."));
break;
case CKO_DATA:
gettext("Data object display not implemented."));
break;
default:
"Unknown token object class (0x%02x)."), objclass);
break;
}
}
/* Clean up. */
return (0);
}