Home | History | Annotate | Download | only in pktool
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License (the "License").
      6  * You may not use this file except in compliance with the License.
      7  *
      8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9  * or http://www.opensolaris.org/os/licensing.
     10  * See the License for the specific language governing permissions
     11  * and limitations under the License.
     12  *
     13  * When distributing Covered Code, include this CDDL HEADER in each
     14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15  * If applicable, add the following below this CDDL HEADER, with the
     16  * fields enclosed by brackets "[]" replaced with your own identifying
     17  * information: Portions Copyright [yyyy] [name of copyright owner]
     18  *
     19  * CDDL HEADER END
     20  */
     21 /*
     22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     27 
     28 /*
     29  * This file implements the token object list operation for this tool.
     30  * It loads the PKCS#11 modules, finds the object to list, lists it,
     31  * and cleans up.  User must be logged into the token to list private
     32  * objects.
     33  */
     34 
     35 #include <stdio.h>
     36 #include <errno.h>
     37 #include <string.h>
     38 #include <cryptoutil.h>
     39 #include <security/cryptoki.h>
     40 #include "common.h"
     41 
     42 #include <kmfapi.h>
     43 
     44 static void
     45 pk_show_certs(KMF_HANDLE_T kmfhandle, KMF_X509_DER_CERT *certs, int num_certs)
     46 {
     47 	int i;
     48 	char *subject, *issuer, *serial, *id, *altname;
     49 	char *start, *end, *keyusage, *extkeyusage;
     50 
     51 	for (i = 0; i < num_certs; i++) {
     52 		subject = NULL;
     53 		issuer = NULL;
     54 		serial = NULL;
     55 		id = NULL;
     56 		altname = NULL;
     57 		start = end = NULL;
     58 		keyusage = extkeyusage = NULL;
     59 
     60 		(void) fprintf(stdout,
     61 		    gettext("%d. (X.509 certificate)\n"), i + 1);
     62 		if (certs[i].kmf_private.label != NULL)
     63 			(void) fprintf(stdout, gettext("\t%s: %s\n"),
     64 			    (certs[i].kmf_private.keystore_type ==
     65 			    KMF_KEYSTORE_OPENSSL ?  "Filename" : "Label"),
     66 			    certs[i].kmf_private.label);
     67 		if (kmf_get_cert_id_str(&certs[i].certificate,
     68 		    &id) == KMF_OK)
     69 			(void) fprintf(stdout, gettext("\tID: %s\n"), id);
     70 		if (kmf_get_cert_subject_str(kmfhandle,
     71 		    &certs[i].certificate, &subject) == KMF_OK)
     72 			(void) fprintf(stdout, gettext("\tSubject: %s\n"),
     73 			    subject);
     74 		if (kmf_get_cert_issuer_str(kmfhandle,
     75 		    &certs[i].certificate, &issuer) == KMF_OK)
     76 			(void) fprintf(stdout, gettext("\tIssuer: %s\n"),
     77 			    issuer);
     78 		if (kmf_get_cert_start_date_str(kmfhandle,
     79 		    &certs[i].certificate, &start) == KMF_OK)
     80 			(void) fprintf(stdout, gettext("\tNot Before: %s\n"),
     81 			    start);
     82 		if (kmf_get_cert_end_date_str(kmfhandle,
     83 		    &certs[i].certificate, &end) == KMF_OK)
     84 			(void) fprintf(stdout, gettext("\tNot After: %s\n"),
     85 			    end);
     86 		if (kmf_get_cert_serial_str(kmfhandle,
     87 		    &certs[i].certificate, &serial) == KMF_OK)
     88 			(void) fprintf(stdout, gettext("\tSerial: %s\n"),
     89 			    serial);
     90 		if (kmf_get_cert_extn_str(kmfhandle,
     91 		    &certs[i].certificate, KMF_X509_EXT_SUBJ_ALTNAME,
     92 		    &altname) == KMF_OK)  {
     93 			(void) fprintf(stdout, gettext("\t%s\n"),
     94 			    altname);
     95 		}
     96 		if (kmf_get_cert_extn_str(kmfhandle,
     97 		    &certs[i].certificate, KMF_X509_EXT_KEY_USAGE,
     98 		    &keyusage) == KMF_OK)  {
     99 			(void) fprintf(stdout, gettext("\t%s\n"),
    100 			    keyusage);
    101 		}
    102 		if (kmf_get_cert_extn_str(kmfhandle,
    103 		    &certs[i].certificate, KMF_X509_EXT_EXT_KEY_USAGE,
    104 		    &extkeyusage) == KMF_OK)  {
    105 			(void) fprintf(stdout, gettext("\t%s\n"),
    106 			    extkeyusage);
    107 		}
    108 		kmf_free_str(subject);
    109 		kmf_free_str(issuer);
    110 		kmf_free_str(serial);
    111 		kmf_free_str(id);
    112 		kmf_free_str(altname);
    113 		kmf_free_str(keyusage);
    114 		kmf_free_str(extkeyusage);
    115 		kmf_free_str(start);
    116 		kmf_free_str(end);
    117 		(void) fprintf(stdout, "\n");
    118 	}
    119 }
    120 
    121 static char *
    122 describeKey(KMF_KEY_HANDLE *key)
    123 {
    124 	if (key->keyclass == KMF_ASYM_PUB) {
    125 		if (key->keyalg == KMF_RSA)
    126 			return (gettext("RSA public key"));
    127 		if (key->keyalg == KMF_DSA)
    128 			return (gettext("DSA public key"));
    129 	}
    130 	if (key->keyclass == KMF_ASYM_PRI) {
    131 		if (key->keyalg == KMF_RSA)
    132 			return ("RSA private key");
    133 		if (key->keyalg == KMF_DSA)
    134 			return ("DSA private key");
    135 	}
    136 	if (key->keyclass == KMF_SYMMETRIC) {
    137 		switch (key->keyalg) {
    138 			case KMF_AES:
    139 				return (gettext("AES"));
    140 				break;
    141 			case KMF_RC4:
    142 				return (gettext("ARCFOUR"));
    143 				break;
    144 			case KMF_DES:
    145 				return (gettext("DES"));
    146 				break;
    147 			case KMF_DES3:
    148 				return (gettext("Triple-DES"));
    149 				break;
    150 			default:
    151 				return (gettext("symmetric"));
    152 				break;
    153 		}
    154 	}
    155 
    156 	return (gettext("unrecognized key object"));
    157 
    158 }
    159 
    160 
    161 static void
    162 pk_show_keys(void *handle, KMF_KEY_HANDLE *keys, int numkeys)
    163 {
    164 	int i;
    165 
    166 	for (i = 0; i < numkeys; i++) {
    167 		(void) fprintf(stdout, gettext("Key #%d - %s:  %s"),
    168 		    i+1, describeKey(&keys[i]),
    169 		    keys[i].keylabel ? keys[i].keylabel :
    170 		    gettext("No label"));
    171 
    172 		if (keys[i].keyclass == KMF_SYMMETRIC) {
    173 			KMF_RETURN rv;
    174 			KMF_RAW_SYM_KEY rkey;
    175 
    176 			(void) memset(&rkey, 0, sizeof (rkey));
    177 			rv = kmf_get_sym_key_value(handle, &keys[i],
    178 			    &rkey);
    179 			if (rv == KMF_OK) {
    180 				(void) fprintf(stdout, " (%d bits)",
    181 				    rkey.keydata.len * 8);
    182 				kmf_free_bigint(&rkey.keydata);
    183 			} else if (keys[i].kstype == KMF_KEYSTORE_PK11TOKEN) {
    184 				if (rv == KMF_ERR_SENSITIVE_KEY) {
    185 					(void) fprintf(stdout, " (sensitive)");
    186 				} else if (rv == KMF_ERR_UNEXTRACTABLE_KEY) {
    187 					(void) fprintf(stdout,
    188 					    " (non-extractable)");
    189 				} else {
    190 					char *err = NULL;
    191 					if (kmf_get_kmf_error_str(rv, &err) ==
    192 					    KMF_OK)
    193 						(void) fprintf(stdout,
    194 						    " (error: %s)", err);
    195 					if (err != NULL)
    196 						free(err);
    197 				}
    198 			}
    199 		}
    200 		(void) fprintf(stdout, "\n");
    201 	}
    202 }
    203 
    204 /*
    205  * Generic routine used by all "list cert" operations to find
    206  * all matching certificates.
    207  */
    208 static KMF_RETURN
    209 pk_find_certs(KMF_HANDLE_T kmfhandle, KMF_ATTRIBUTE *attrlist, int numattr)
    210 {
    211 	KMF_RETURN rv = KMF_OK;
    212 	KMF_X509_DER_CERT *certlist = NULL;
    213 	uint32_t numcerts = 0;
    214 	KMF_KEYSTORE_TYPE kstype;
    215 
    216 	rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
    217 	    &kstype, NULL);
    218 	if (rv != KMF_OK)
    219 		return (rv);
    220 
    221 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
    222 	    &numcerts, sizeof (uint32_t));
    223 	numattr++;
    224 
    225 	rv = kmf_find_cert(kmfhandle, numattr, attrlist);
    226 	if (rv == KMF_OK && numcerts > 0) {
    227 		(void) printf(gettext("Found %d certificates.\n"),
    228 		    numcerts);
    229 		certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
    230 		    sizeof (KMF_X509_DER_CERT));
    231 		if (certlist == NULL)
    232 			return (KMF_ERR_MEMORY);
    233 		(void) memset(certlist, 0, numcerts *
    234 		    sizeof (KMF_X509_DER_CERT));
    235 
    236 		kmf_set_attr_at_index(attrlist, numattr,
    237 		    KMF_X509_DER_CERT_ATTR, certlist,
    238 		    sizeof (KMF_X509_DER_CERT));
    239 		numattr++;
    240 
    241 		rv = kmf_find_cert(kmfhandle, numattr, attrlist);
    242 		if (rv == KMF_OK) {
    243 			int i;
    244 			(void) pk_show_certs(kmfhandle, certlist,
    245 			    numcerts);
    246 			for (i = 0; i < numcerts; i++)
    247 				kmf_free_kmf_cert(kmfhandle, &certlist[i]);
    248 		}
    249 		free(certlist);
    250 	}
    251 	if (rv == KMF_ERR_CERT_NOT_FOUND &&
    252 	    kstype != KMF_KEYSTORE_OPENSSL)
    253 		rv = KMF_OK;
    254 
    255 	return (rv);
    256 }
    257 
    258 static KMF_RETURN
    259 pk_list_keys(void *handle, KMF_ATTRIBUTE *attrlist, int numattr, char *label)
    260 {
    261 	KMF_RETURN rv;
    262 	KMF_KEY_HANDLE *keys;
    263 	uint32_t numkeys = 0;
    264 	KMF_KEYSTORE_TYPE kstype;
    265 
    266 	rv = kmf_get_attr(KMF_KEYSTORE_TYPE_ATTR, attrlist, numattr,
    267 	    &kstype, NULL);
    268 	if (rv != KMF_OK)
    269 		return (rv);
    270 
    271 	kmf_set_attr_at_index(attrlist, numattr, KMF_COUNT_ATTR,
    272 	    &numkeys, sizeof (uint32_t));
    273 	numattr++;
    274 
    275 	rv = kmf_find_key(handle, numattr, attrlist);
    276 	if (rv == KMF_OK && numkeys > 0) {
    277 		int i;
    278 		(void) printf(gettext("Found %d %s keys.\n"),
    279 		    numkeys, label);
    280 		keys = (KMF_KEY_HANDLE *)malloc(numkeys *
    281 		    sizeof (KMF_KEY_HANDLE));
    282 		if (keys == NULL)
    283 			return (KMF_ERR_MEMORY);
    284 		(void) memset(keys, 0, numkeys *
    285 		    sizeof (KMF_KEY_HANDLE));
    286 
    287 		kmf_set_attr_at_index(attrlist, numattr,
    288 		    KMF_KEY_HANDLE_ATTR,
    289 		    keys, sizeof (KMF_KEY_HANDLE));
    290 		numattr++;
    291 
    292 		rv = kmf_find_key(handle, numattr, attrlist);
    293 		if (rv == KMF_OK)
    294 			pk_show_keys(handle, keys, numkeys);
    295 		for (i = 0; i < numkeys; i++)
    296 			kmf_free_kmf_key(handle, &keys[i]);
    297 		free(keys);
    298 	}
    299 	if (rv == KMF_ERR_KEY_NOT_FOUND &&
    300 	    kstype != KMF_KEYSTORE_OPENSSL)
    301 		rv = KMF_OK;
    302 	return (rv);
    303 }
    304 
    305 static KMF_RETURN
    306 list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass,
    307 	char *objlabel, KMF_BIGINT *serial, char *issuer, char *subject,
    308 	char *dir, char *filename, KMF_CREDENTIAL *tokencred,
    309 	KMF_CERT_VALIDITY find_criteria_flag)
    310 {
    311 	KMF_RETURN rv;
    312 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
    313 	int numattr = 0;
    314 	KMF_ATTRIBUTE attrlist[18];
    315 	boolean_t token_bool = B_TRUE;
    316 	boolean_t private = B_FALSE;
    317 	KMF_KEY_CLASS keyclass;
    318 	KMF_ENCODE_FORMAT format;
    319 	int auth = 0;
    320 	KMF_CREDENTIAL cred = {NULL, 0};
    321 
    322 	/*
    323 	 * Symmetric keys and RSA/DSA private keys are always
    324 	 * created with the "CKA_PRIVATE" field == TRUE, so
    325 	 * make sure we search for them with it also set.
    326 	 */
    327 	if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ))
    328 		oclass |= PK_PRIVATE_OBJ;
    329 
    330 	rv = select_token(kmfhandle, token,
    331 	    !(oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)));
    332 
    333 	if (rv != KMF_OK) {
    334 		return (rv);
    335 	}
    336 
    337 	rv = token_auth_needed(kmfhandle, token, &auth);
    338 	if (rv != KMF_OK)
    339 		return (rv);
    340 
    341 	if (tokencred != NULL)
    342 		cred = *tokencred;
    343 
    344 	if (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ)) {
    345 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    346 		    &kstype, sizeof (kstype));
    347 		numattr++;
    348 
    349 		if (objlabel != NULL) {
    350 			kmf_set_attr_at_index(attrlist, numattr,
    351 			    KMF_KEYLABEL_ATTR, objlabel,
    352 			    strlen(objlabel));
    353 			numattr++;
    354 		}
    355 
    356 		private = ((oclass & PK_PRIVATE_OBJ) > 0);
    357 
    358 		kmf_set_attr_at_index(attrlist, numattr,
    359 		    KMF_PRIVATE_BOOL_ATTR, &private,
    360 		    sizeof (private));
    361 		numattr++;
    362 
    363 		kmf_set_attr_at_index(attrlist, numattr,
    364 		    KMF_TOKEN_BOOL_ATTR, &token_bool,
    365 		    sizeof (token_bool));
    366 		numattr++;
    367 
    368 		if (oclass & PK_PRIKEY_OBJ) {
    369 			int num = numattr;
    370 
    371 			keyclass = KMF_ASYM_PRI;
    372 			kmf_set_attr_at_index(attrlist, num,
    373 			    KMF_KEYCLASS_ATTR, &keyclass,
    374 			    sizeof (keyclass));
    375 			num++;
    376 
    377 			if (tokencred != NULL &&
    378 			    tokencred->credlen > 0) {
    379 				kmf_set_attr_at_index(attrlist, num,
    380 				    KMF_CREDENTIAL_ATTR, tokencred,
    381 				    sizeof (KMF_CREDENTIAL));
    382 				num++;
    383 			}
    384 
    385 			/* list asymmetric private keys */
    386 			rv = pk_list_keys(kmfhandle, attrlist, num,
    387 			    "asymmetric private");
    388 		}
    389 
    390 		if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
    391 			int num = numattr;
    392 
    393 			keyclass = KMF_SYMMETRIC;
    394 			kmf_set_attr_at_index(attrlist, num,
    395 			    KMF_KEYCLASS_ATTR, &keyclass,
    396 			    sizeof (keyclass));
    397 			num++;
    398 
    399 			if (tokencred != NULL &&
    400 			    tokencred->credlen > 0) {
    401 				kmf_set_attr_at_index(attrlist, num,
    402 				    KMF_CREDENTIAL_ATTR, tokencred,
    403 				    sizeof (KMF_CREDENTIAL));
    404 				num++;
    405 			}
    406 
    407 			format = KMF_FORMAT_RAWKEY;
    408 			kmf_set_attr_at_index(attrlist, num,
    409 			    KMF_ENCODE_FORMAT_ATTR, &format,
    410 			    sizeof (format));
    411 			num++;
    412 
    413 			/* list symmetric keys */
    414 			rv = pk_list_keys(kmfhandle, attrlist, num,
    415 			    "symmetric");
    416 		}
    417 
    418 		if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
    419 			int num = numattr;
    420 
    421 			if (auth > 0 && (tokencred == NULL ||
    422 			    tokencred->cred == NULL) &&
    423 			    (cred.cred == NULL)) {
    424 				(void) get_token_password(kstype, token, &cred);
    425 				kmf_set_attr_at_index(attrlist, numattr,
    426 				    KMF_CREDENTIAL_ATTR,
    427 				    &cred, sizeof (KMF_CREDENTIAL));
    428 				numattr++;
    429 			}
    430 
    431 			private = B_FALSE;
    432 			keyclass = KMF_ASYM_PUB;
    433 			kmf_set_attr_at_index(attrlist, num,
    434 			    KMF_KEYCLASS_ATTR, &keyclass,
    435 			    sizeof (keyclass));
    436 			num++;
    437 
    438 			/* list asymmetric public keys (if any) */
    439 			rv = pk_list_keys(kmfhandle, attrlist, num,
    440 			    "asymmetric public");
    441 		}
    442 
    443 		if (rv != KMF_OK)
    444 			return (rv);
    445 	}
    446 
    447 	numattr = 0;
    448 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
    449 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    450 		    &kstype, sizeof (kstype));
    451 
    452 		numattr++;
    453 		if (auth > 0 && (cred.cred == NULL)) {
    454 			(void) get_token_password(kstype, token, &cred);
    455 		}
    456 
    457 		if (cred.cred != NULL) {
    458 			kmf_set_attr_at_index(attrlist, numattr,
    459 			    KMF_CREDENTIAL_ATTR,
    460 			    &cred, sizeof (KMF_CREDENTIAL));
    461 			numattr++;
    462 		}
    463 
    464 		if (objlabel != NULL) {
    465 			kmf_set_attr_at_index(attrlist, numattr,
    466 			    KMF_CERT_LABEL_ATTR, objlabel,
    467 			    strlen(objlabel));
    468 			numattr++;
    469 		}
    470 
    471 		if (issuer != NULL) {
    472 			kmf_set_attr_at_index(attrlist, numattr,
    473 			    KMF_ISSUER_NAME_ATTR, issuer,
    474 			    strlen(issuer));
    475 			numattr++;
    476 		}
    477 
    478 		if (subject != NULL) {
    479 			kmf_set_attr_at_index(attrlist, numattr,
    480 			    KMF_SUBJECT_NAME_ATTR, subject,
    481 			    strlen(subject));
    482 			numattr++;
    483 		}
    484 
    485 		if (serial != NULL && serial->val != NULL) {
    486 			kmf_set_attr_at_index(attrlist, numattr,
    487 			    KMF_BIGINT_ATTR, serial,
    488 			    sizeof (KMF_BIGINT));
    489 			numattr++;
    490 		}
    491 
    492 		kmf_set_attr_at_index(attrlist, numattr,
    493 		    KMF_PRIVATE_BOOL_ATTR, &private,
    494 		    sizeof (private));
    495 		numattr++;
    496 
    497 		kmf_set_attr_at_index(attrlist, numattr,
    498 		    KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
    499 		    sizeof (KMF_CERT_VALIDITY));
    500 		numattr++;
    501 
    502 		rv = pk_find_certs(kmfhandle, attrlist, numattr);
    503 		if (rv != KMF_OK)
    504 			return (rv);
    505 	}
    506 
    507 	numattr = 0;
    508 	kstype = KMF_KEYSTORE_OPENSSL; /* CRL is file-based */
    509 	if (oclass & PK_CRL_OBJ) {
    510 		char *crldata = NULL;
    511 
    512 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    513 		    &kstype, sizeof (kstype));
    514 		numattr++;
    515 
    516 		if (dir != NULL) {
    517 			kmf_set_attr_at_index(attrlist, numattr,
    518 			    KMF_DIRPATH_ATTR, dir, strlen(dir));
    519 			numattr++;
    520 		}
    521 		if (filename != NULL) {
    522 			kmf_set_attr_at_index(attrlist, numattr,
    523 			    KMF_CRL_FILENAME_ATTR,
    524 			    filename, strlen(filename));
    525 			numattr++;
    526 		}
    527 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_DATA_ATTR,
    528 		    &crldata, sizeof (char *));
    529 		numattr++;
    530 
    531 		rv = kmf_list_crl(kmfhandle, numattr, attrlist);
    532 		if (rv == KMF_OK && crldata != NULL) {
    533 			(void) printf("%s\n", crldata);
    534 			free(crldata);
    535 		}
    536 	}
    537 
    538 	return (rv);
    539 }
    540 
    541 static int
    542 list_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
    543 	char *dir, char *filename, KMF_BIGINT *serial,
    544 	char *issuer, char *subject,
    545 	KMF_CERT_VALIDITY find_criteria_flag)
    546 {
    547 	KMF_RETURN rv = KMF_OK;
    548 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
    549 	int numattr = 0;
    550 	KMF_ATTRIBUTE attrlist[16];
    551 	KMF_KEY_CLASS keyclass;
    552 	KMF_ENCODE_FORMAT format;
    553 	char *defaultdir = ".";
    554 
    555 	if (oclass & PK_KEY_OBJ) {
    556 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    557 		    &kstype, sizeof (kstype));
    558 		numattr++;
    559 
    560 		if (dir == NULL && filename == NULL)
    561 			dir = defaultdir;
    562 
    563 		if (dir != NULL) {
    564 			kmf_set_attr_at_index(attrlist, numattr,
    565 			    KMF_DIRPATH_ATTR, dir,
    566 			    strlen(dir));
    567 			numattr++;
    568 		}
    569 
    570 		if (filename != NULL) {
    571 			kmf_set_attr_at_index(attrlist, numattr,
    572 			    KMF_KEY_FILENAME_ATTR, filename,
    573 			    strlen(filename));
    574 			numattr++;
    575 		}
    576 
    577 		if (oclass & PK_PRIKEY_OBJ) {
    578 			int num = numattr;
    579 
    580 			keyclass = KMF_ASYM_PRI;
    581 			kmf_set_attr_at_index(attrlist, num,
    582 			    KMF_KEYCLASS_ATTR, &keyclass,
    583 			    sizeof (keyclass));
    584 			num++;
    585 
    586 			/* list asymmetric private keys */
    587 			rv = pk_list_keys(kmfhandle, attrlist, num,
    588 			    "asymmetric private");
    589 		}
    590 		if (rv == KMF_ERR_KEY_NOT_FOUND)
    591 			rv = KMF_OK;
    592 
    593 		if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
    594 			int num = numattr;
    595 
    596 			keyclass = KMF_SYMMETRIC;
    597 			kmf_set_attr_at_index(attrlist, num,
    598 			    KMF_KEYCLASS_ATTR, &keyclass,
    599 			    sizeof (keyclass));
    600 			num++;
    601 
    602 			format = KMF_FORMAT_RAWKEY;
    603 			kmf_set_attr_at_index(attrlist, num,
    604 			    KMF_ENCODE_FORMAT_ATTR, &format,
    605 			    sizeof (format));
    606 			num++;
    607 
    608 			/* list symmetric keys */
    609 			rv = pk_list_keys(kmfhandle, attrlist, num,
    610 			    "symmetric");
    611 		}
    612 		if (rv == KMF_ERR_KEY_NOT_FOUND)
    613 			rv = KMF_OK;
    614 		if (rv != KMF_OK)
    615 			return (rv);
    616 	}
    617 
    618 	numattr = 0;
    619 	if (oclass & PK_CERT_OBJ) {
    620 		kmf_set_attr_at_index(attrlist, numattr,
    621 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
    622 		    sizeof (kstype));
    623 		numattr++;
    624 
    625 		if (issuer != NULL) {
    626 			kmf_set_attr_at_index(attrlist, numattr,
    627 			    KMF_ISSUER_NAME_ATTR, issuer,
    628 			    strlen(issuer));
    629 			numattr++;
    630 		}
    631 
    632 		if (subject != NULL) {
    633 			kmf_set_attr_at_index(attrlist, numattr,
    634 			    KMF_SUBJECT_NAME_ATTR, subject,
    635 			    strlen(subject));
    636 			numattr++;
    637 		}
    638 
    639 		if (serial != NULL && serial->val != NULL) {
    640 			kmf_set_attr_at_index(attrlist, numattr,
    641 			    KMF_BIGINT_ATTR, serial,
    642 			    sizeof (KMF_BIGINT));
    643 			numattr++;
    644 		}
    645 
    646 		if (filename != NULL) {
    647 			kmf_set_attr_at_index(attrlist, numattr,
    648 			    KMF_CERT_FILENAME_ATTR, filename,
    649 			    strlen(filename));
    650 			numattr++;
    651 		}
    652 
    653 		if (dir != NULL) {
    654 			kmf_set_attr_at_index(attrlist, numattr,
    655 			    KMF_DIRPATH_ATTR, dir,
    656 			    strlen(dir));
    657 			numattr++;
    658 		}
    659 
    660 		kmf_set_attr_at_index(attrlist, numattr,
    661 		    KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
    662 		    sizeof (KMF_CERT_VALIDITY));
    663 		numattr++;
    664 
    665 		rv = pk_find_certs(kmfhandle, attrlist, numattr);
    666 		if (rv != KMF_OK)
    667 			return (rv);
    668 	}
    669 
    670 	numattr = 0;
    671 	if (oclass & PK_CRL_OBJ) {
    672 		char *crldata = NULL;
    673 
    674 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    675 		    &kstype, sizeof (kstype));
    676 		numattr++;
    677 
    678 		if (dir != NULL) {
    679 			kmf_set_attr_at_index(attrlist, numattr,
    680 			    KMF_DIRPATH_ATTR, dir, strlen(dir));
    681 			numattr++;
    682 		}
    683 		if (filename != NULL) {
    684 			kmf_set_attr_at_index(attrlist, numattr,
    685 			    KMF_CRL_FILENAME_ATTR,
    686 			    filename, strlen(filename));
    687 			numattr++;
    688 		}
    689 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_DATA_ATTR,
    690 		    &crldata, sizeof (char *));
    691 		numattr++;
    692 
    693 		rv = kmf_list_crl(kmfhandle, numattr, attrlist);
    694 		if (rv == KMF_OK && crldata != NULL) {
    695 			(void) printf("%s\n", crldata);
    696 			free(crldata);
    697 		}
    698 	}
    699 
    700 	return (rv);
    701 }
    702 
    703 static int
    704 list_nss_objects(KMF_HANDLE_T kmfhandle,
    705 	int oclass, char *token_spec, char *dir, char *prefix,
    706 	char *nickname, KMF_BIGINT *serial, char *issuer, char *subject,
    707 	KMF_CREDENTIAL *tokencred,
    708 	KMF_CERT_VALIDITY find_criteria_flag)
    709 {
    710 	KMF_RETURN rv = KMF_OK;
    711 	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
    712 	int numattr = 0;
    713 	KMF_ATTRIBUTE attrlist[16];
    714 	KMF_KEY_CLASS keyclass;
    715 	KMF_ENCODE_FORMAT format;
    716 
    717 	rv = configure_nss(kmfhandle, dir, prefix);
    718 	if (rv != KMF_OK)
    719 		return (rv);
    720 
    721 	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    722 	    &kstype, sizeof (kstype));
    723 	numattr++;
    724 
    725 	if (oclass & PK_KEY_OBJ) {
    726 		if (tokencred != NULL && tokencred->credlen > 0) {
    727 			kmf_set_attr_at_index(attrlist, numattr,
    728 			    KMF_CREDENTIAL_ATTR, tokencred,
    729 			    sizeof (KMF_CREDENTIAL));
    730 			numattr++;
    731 		}
    732 
    733 		if (token_spec && strlen(token_spec)) {
    734 			kmf_set_attr_at_index(attrlist, numattr,
    735 			    KMF_TOKEN_LABEL_ATTR, token_spec,
    736 			    strlen(token_spec));
    737 			numattr++;
    738 		}
    739 
    740 		if (nickname != NULL) {
    741 			kmf_set_attr_at_index(attrlist, numattr,
    742 			    KMF_KEYLABEL_ATTR, nickname,
    743 			    strlen(nickname));
    744 			numattr++;
    745 		}
    746 	}
    747 
    748 	if (oclass & PK_PRIKEY_OBJ) {
    749 		int num = numattr;
    750 
    751 		keyclass = KMF_ASYM_PRI;
    752 		kmf_set_attr_at_index(attrlist, num,
    753 		    KMF_KEYCLASS_ATTR, &keyclass,
    754 		    sizeof (keyclass));
    755 		num++;
    756 
    757 		/* list asymmetric private keys */
    758 		rv = pk_list_keys(kmfhandle, attrlist, num,
    759 		    "asymmetric private");
    760 	}
    761 
    762 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
    763 		int num = numattr;
    764 
    765 		keyclass = KMF_SYMMETRIC;
    766 		kmf_set_attr_at_index(attrlist, num,
    767 		    KMF_KEYCLASS_ATTR, &keyclass,
    768 		    sizeof (keyclass));
    769 		num++;
    770 
    771 		format = KMF_FORMAT_RAWKEY;
    772 		kmf_set_attr_at_index(attrlist, num,
    773 		    KMF_ENCODE_FORMAT_ATTR, &format,
    774 		    sizeof (format));
    775 		num++;
    776 
    777 		/* list symmetric keys */
    778 		rv = pk_list_keys(kmfhandle, attrlist, num, "symmetric");
    779 	}
    780 
    781 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
    782 		int num = numattr;
    783 
    784 		keyclass = KMF_ASYM_PUB;
    785 		kmf_set_attr_at_index(attrlist, num,
    786 		    KMF_KEYCLASS_ATTR, &keyclass,
    787 		    sizeof (keyclass));
    788 		num++;
    789 
    790 		/* list asymmetric public keys */
    791 		rv = pk_list_keys(kmfhandle, attrlist, num,
    792 		    "asymmetric public");
    793 	}
    794 
    795 	/* If searching for public objects or certificates, find certs now */
    796 	numattr = 0;
    797 	if (rv == KMF_OK && (oclass & PK_CERT_OBJ)) {
    798 		kmf_set_attr_at_index(attrlist, numattr,
    799 		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
    800 		    sizeof (kstype));
    801 		numattr++;
    802 
    803 		if (nickname != NULL) {
    804 			kmf_set_attr_at_index(attrlist, numattr,
    805 			    KMF_CERT_LABEL_ATTR, nickname,
    806 			    strlen(nickname));
    807 			numattr++;
    808 		}
    809 
    810 		if (issuer != NULL) {
    811 			kmf_set_attr_at_index(attrlist, numattr,
    812 			    KMF_ISSUER_NAME_ATTR, issuer,
    813 			    strlen(issuer));
    814 			numattr++;
    815 		}
    816 
    817 		if (subject != NULL) {
    818 			kmf_set_attr_at_index(attrlist, numattr,
    819 			    KMF_SUBJECT_NAME_ATTR, subject,
    820 			    strlen(subject));
    821 			numattr++;
    822 		}
    823 
    824 		if (serial != NULL) {
    825 			kmf_set_attr_at_index(attrlist, numattr,
    826 			    KMF_BIGINT_ATTR, serial,
    827 			    sizeof (KMF_BIGINT));
    828 			numattr++;
    829 		}
    830 
    831 		if (token_spec != NULL) {
    832 			kmf_set_attr_at_index(attrlist, numattr,
    833 			    KMF_TOKEN_LABEL_ATTR, token_spec,
    834 			    strlen(token_spec));
    835 			numattr++;
    836 		}
    837 
    838 		kmf_set_attr_at_index(attrlist, numattr,
    839 		    KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
    840 		    sizeof (KMF_CERT_VALIDITY));
    841 		numattr++;
    842 
    843 		rv = pk_find_certs(kmfhandle, attrlist, numattr);
    844 	}
    845 
    846 	numattr = 0;
    847 	if (rv == KMF_OK && (oclass & PK_CRL_OBJ)) {
    848 		int numcrls;
    849 
    850 		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
    851 		    &kstype, sizeof (kstype));
    852 		numattr++;
    853 
    854 		if (token_spec != NULL) {
    855 			kmf_set_attr_at_index(attrlist, numattr,
    856 			    KMF_TOKEN_LABEL_ATTR,
    857 			    token_spec, strlen(token_spec));
    858 			numattr++;
    859 		}
    860 		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_COUNT_ATTR,
    861 		    &numcrls, sizeof (int));
    862 		numattr++;
    863 
    864 		rv = kmf_find_crl(kmfhandle, numattr, attrlist);
    865 		if (rv == KMF_OK) {
    866 			char **p;
    867 			if (numcrls == 0) {
    868 				(void) printf(gettext("No CRLs found in "
    869 				    "NSS keystore.\n"));
    870 
    871 				return (KMF_OK);
    872 			}
    873 			p = malloc(numcrls * sizeof (char *));
    874 			if (p == NULL) {
    875 				return (KMF_ERR_MEMORY);
    876 			}
    877 			(void) memset(p, 0, numcrls * sizeof (char *));
    878 
    879 			kmf_set_attr_at_index(attrlist, numattr,
    880 			    KMF_CRL_NAMELIST_ATTR, p, sizeof (char *));
    881 			numattr++;
    882 			rv = kmf_find_crl(kmfhandle, numattr, attrlist);
    883 			if (rv == KMF_OK) {
    884 				int i;
    885 				for (i = 0; i < numcrls; i++) {
    886 					(void) printf("%d. Name = %s\n",
    887 					    i + 1, p[i]);
    888 					free(p[i]);
    889 				}
    890 			}
    891 			free(p);
    892 		}
    893 	}
    894 	return (rv);
    895 }
    896 
    897 /*
    898  * List token object.
    899  */
    900 int
    901 pk_list(int argc, char *argv[])
    902 {
    903 	int			opt;
    904 	extern int		optind_av;
    905 	extern char		*optarg_av;
    906 	char			*token_spec = NULL;
    907 	char			*subject = NULL;
    908 	char			*issuer = NULL;
    909 	char			*dir = NULL;
    910 	char			*prefix = NULL;
    911 	char			*filename = NULL;
    912 	char			*serstr = NULL;
    913 	KMF_BIGINT		serial = { NULL, 0 };
    914 
    915 	char			*list_label = NULL;
    916 	int			oclass = 0;
    917 	KMF_KEYSTORE_TYPE	kstype = 0;
    918 	KMF_RETURN		rv = KMF_OK;
    919 	KMF_HANDLE_T		kmfhandle = NULL;
    920 	char			*find_criteria = NULL;
    921 	KMF_CERT_VALIDITY	find_criteria_flag = KMF_ALL_CERTS;
    922 	KMF_CREDENTIAL		tokencred = {NULL, 0};
    923 
    924 	/* Parse command line options.  Do NOT i18n/l10n. */
    925 	while ((opt = getopt_av(argc, argv,
    926 	    "k:(keystore)t:(objtype)T:(token)d:(dir)"
    927 	    "p:(prefix)n:(nickname)S:(serial)s:(subject)"
    928 	    "c:(criteria)"
    929 	    "i:(issuer)l:(label)f:(infile)")) != EOF) {
    930 		if (EMPTYSTRING(optarg_av))
    931 			return (PK_ERR_USAGE);
    932 		switch (opt) {
    933 			case 'k':
    934 				if (kstype != 0)
    935 					return (PK_ERR_USAGE);
    936 				kstype = KS2Int(optarg_av);
    937 				if (kstype == 0)
    938 					return (PK_ERR_USAGE);
    939 				break;
    940 			case 't':
    941 				if (oclass != 0)
    942 					return (PK_ERR_USAGE);
    943 				oclass = OT2Int(optarg_av);
    944 				if (oclass == -1)
    945 					return (PK_ERR_USAGE);
    946 				break;
    947 			case 's':
    948 				if (subject)
    949 					return (PK_ERR_USAGE);
    950 				subject = optarg_av;
    951 				break;
    952 			case 'i':
    953 				if (issuer)
    954 					return (PK_ERR_USAGE);
    955 				issuer = optarg_av;
    956 				break;
    957 			case 'd':
    958 				if (dir)
    959 					return (PK_ERR_USAGE);
    960 				dir = optarg_av;
    961 				break;
    962 			case 'p':
    963 				if (prefix)
    964 					return (PK_ERR_USAGE);
    965 				prefix = optarg_av;
    966 				break;
    967 			case 'S':
    968 				serstr = optarg_av;
    969 				break;
    970 			case 'f':
    971 				if (filename)
    972 					return (PK_ERR_USAGE);
    973 				filename = optarg_av;
    974 				break;
    975 			case 'T':	/* token specifier */
    976 				if (token_spec)
    977 					return (PK_ERR_USAGE);
    978 				token_spec = optarg_av;
    979 				break;
    980 			case 'n':
    981 			case 'l':	/* object with specific label */
    982 				if (list_label)
    983 					return (PK_ERR_USAGE);
    984 				list_label = optarg_av;
    985 				break;
    986 			case 'c':
    987 				find_criteria = optarg_av;
    988 				if (!strcasecmp(find_criteria, "valid"))
    989 					find_criteria_flag =
    990 					    KMF_NONEXPIRED_CERTS;
    991 				else if (!strcasecmp(find_criteria, "expired"))
    992 					find_criteria_flag = KMF_EXPIRED_CERTS;
    993 				else if (!strcasecmp(find_criteria, "both"))
    994 					find_criteria_flag = KMF_ALL_CERTS;
    995 				else
    996 					return (PK_ERR_USAGE);
    997 				break;
    998 			default:
    999 				return (PK_ERR_USAGE);
   1000 		}
   1001 	}
   1002 	/* No additional args allowed. */
   1003 	argc -= optind_av;
   1004 	argv += optind_av;
   1005 	if (argc)
   1006 		return (PK_ERR_USAGE);
   1007 
   1008 	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
   1009 		/* Error message ? */
   1010 		return (rv);
   1011 	}
   1012 
   1013 	/* Assume keystore = PKCS#11 if not specified. */
   1014 	if (kstype == 0)
   1015 		kstype = KMF_KEYSTORE_PK11TOKEN;
   1016 
   1017 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
   1018 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
   1019 	    kstype != KMF_KEYSTORE_PK11TOKEN) {
   1020 
   1021 		(void) fprintf(stderr, gettext("The objtype parameter "
   1022 		    "is only relevant if keystore=pkcs11\n"));
   1023 		return (PK_ERR_USAGE);
   1024 	}
   1025 
   1026 
   1027 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) {
   1028 		token_spec = PK_DEFAULT_PK11TOKEN;
   1029 	} else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) {
   1030 		token_spec = DEFAULT_NSS_TOKEN;
   1031 	}
   1032 
   1033 	if (serstr != NULL) {
   1034 		uchar_t *bytes = NULL;
   1035 		size_t bytelen;
   1036 
   1037 		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
   1038 		if (rv != KMF_OK || bytes == NULL) {
   1039 			(void) fprintf(stderr, gettext("serial number "
   1040 			    "must be specified as a hex number "
   1041 			    "(ex: 0x0102030405ffeeddee)\n"));
   1042 			return (PK_ERR_USAGE);
   1043 		}
   1044 		serial.val = bytes;
   1045 		serial.len = bytelen;
   1046 		/* if objtype was not given, it must be for certs */
   1047 		if (oclass == 0)
   1048 			oclass = PK_CERT_OBJ;
   1049 	}
   1050 	if (oclass == 0 && (issuer != NULL || subject != NULL))
   1051 		oclass = PK_CERT_OBJ;
   1052 
   1053 	/* If no object class specified, list public objects. */
   1054 	if (oclass == 0)
   1055 		oclass = PK_CERT_OBJ | PK_PUBKEY_OBJ;
   1056 
   1057 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
   1058 	    kstype == KMF_KEYSTORE_NSS) &&
   1059 	    (oclass & (PK_PRIKEY_OBJ | PK_PRIVATE_OBJ))) {
   1060 
   1061 		(void) get_token_password(kstype, token_spec,
   1062 		    &tokencred);
   1063 	}
   1064 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
   1065 		rv = list_pk11_objects(kmfhandle, token_spec,
   1066 		    oclass, list_label, &serial,
   1067 		    issuer, subject, dir, filename,
   1068 		    &tokencred, find_criteria_flag);
   1069 
   1070 	} else if (kstype == KMF_KEYSTORE_NSS) {
   1071 		if (dir == NULL)
   1072 			dir = PK_DEFAULT_DIRECTORY;
   1073 		rv = list_nss_objects(kmfhandle,
   1074 		    oclass, token_spec, dir, prefix,
   1075 		    list_label, &serial, issuer, subject,
   1076 		    &tokencred, find_criteria_flag);
   1077 
   1078 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
   1079 
   1080 		rv = list_file_objects(kmfhandle,
   1081 		    oclass, dir, filename,
   1082 		    &serial, issuer, subject, find_criteria_flag);
   1083 	}
   1084 
   1085 	if (rv != KMF_OK) {
   1086 		display_error(kmfhandle, rv,
   1087 		    gettext("Error listing objects"));
   1088 	}
   1089 
   1090 	if (serial.val != NULL)
   1091 		free(serial.val);
   1092 
   1093 	if (tokencred.cred != NULL)
   1094 		free(tokencred.cred);
   1095 
   1096 	(void) kmf_finalize(kmfhandle);
   1097 	return (rv);
   1098 }
   1099