list.c revision 3089:8ddeb2ace8aa
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 2006 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
44static void
45pk_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
50	for (i = 0; i < num_certs; i++) {
51		subject = NULL;
52		issuer = NULL;
53		serial = NULL;
54		id = NULL;
55		altname = NULL;
56
57		(void) fprintf(stdout,
58			gettext("%d. (X.509 certificate)\n"), i + 1);
59		if (certs[i].kmf_private.label != NULL)
60			(void) fprintf(stdout, gettext("\t%s: %s\n"),
61				(certs[i].kmf_private.keystore_type ==
62				KMF_KEYSTORE_OPENSSL ?  "Filename" : "Label"),
63				certs[i].kmf_private.label);
64		if (KMF_GetCertIDString(&certs[i].certificate,
65				&id) == KMF_OK)
66			(void) fprintf(stdout, gettext("\tID: %s\n"), id);
67		if (KMF_GetCertSubjectNameString(kmfhandle,
68			&certs[i].certificate, &subject) == KMF_OK)
69			(void) fprintf(stdout, gettext("\tSubject: %s\n"),
70				subject);
71		if (KMF_GetCertIssuerNameString(kmfhandle,
72			&certs[i].certificate, &issuer) == KMF_OK)
73			(void) fprintf(stdout, gettext("\tIssuer: %s\n"),
74				issuer);
75		if (KMF_GetCertSerialNumberString(kmfhandle,
76			&certs[i].certificate, &serial) == KMF_OK)
77			(void) fprintf(stdout, gettext("\tSerial: %s\n"),
78				serial);
79
80		if (KMF_GetCertExtensionString(kmfhandle,
81			&certs[i].certificate, KMF_X509_EXT_SUBJ_ALTNAME,
82			&altname) == KMF_OK)  {
83			(void) fprintf(stdout, gettext("\t%s\n"),
84				altname);
85		}
86
87		KMF_FreeString(subject);
88		KMF_FreeString(issuer);
89		KMF_FreeString(serial);
90		KMF_FreeString(id);
91		KMF_FreeString(altname);
92		(void) fprintf(stdout, "\n");
93	}
94}
95
96static char *
97describeKey(KMF_KEY_HANDLE *key)
98{
99	if (key->keyclass == KMF_ASYM_PUB) {
100		if (key->keyalg == KMF_RSA)
101			return (gettext("RSA public key"));
102		if (key->keyalg == KMF_DSA)
103			return (gettext("DSA public key"));
104	}
105	if (key->keyclass == KMF_ASYM_PRI) {
106		if (key->keyalg == KMF_RSA)
107			return ("RSA private key");
108		if (key->keyalg == KMF_DSA)
109			return ("DSA private key");
110	}
111	if (key->keyclass == KMF_SYMMETRIC) {
112		switch (key->keyalg) {
113			case KMF_AES:
114				return (gettext("AES"));
115				break;
116			case KMF_RC4:
117				return (gettext("ARCFOUR"));
118				break;
119			case KMF_DES:
120				return (gettext("DES"));
121				break;
122			case KMF_DES3:
123				return (gettext("Triple-DES"));
124				break;
125			default:
126				return (gettext("symmetric"));
127				break;
128		}
129	}
130
131	return (gettext("unrecognized key object"));
132
133}
134
135static char *
136keybitstr(KMF_KEY_HANDLE *key)
137{
138	KMF_RAW_SYM_KEY *rkey;
139	char keystr[256];
140	char *p;
141
142	if (key == NULL || (key->keyclass != KMF_SYMMETRIC))
143		return ("");
144
145	rkey = (KMF_RAW_SYM_KEY *)key->keyp;
146	(void) memset(keystr, 0, sizeof (keystr));
147	if (rkey != NULL) {
148		(void) snprintf(keystr, sizeof (keystr),
149			" (%d bits)", rkey->keydata.len * 8);
150		p = keystr;
151	} else {
152		return ("");
153	}
154
155	return (p);
156}
157
158static void
159pk_show_keys(void *handle, KMF_KEY_HANDLE *keys, int numkeys)
160{
161	int i;
162
163	for (i = 0; i < numkeys; i++) {
164		(void) fprintf(stdout, gettext("Key #%d - %s:  %s%s"),
165			i+1, describeKey(&keys[i]),
166			keys[i].keylabel ? keys[i].keylabel :
167			gettext("No label"),
168			(keys[i].keyclass == KMF_SYMMETRIC ?
169			keybitstr(&keys[i]) : ""));
170
171		if (keys[i].keyclass == KMF_SYMMETRIC) {
172			KMF_RETURN rv;
173			KMF_RAW_SYM_KEY rkey;
174			rv = KMF_GetSymKeyValue(handle, &keys[i],
175				&rkey);
176			if (rv == KMF_OK) {
177				(void) fprintf(stdout, "\t %d bits",
178					rkey.keydata.len * 8);
179				KMF_FreeRawSymKey(&rkey);
180			}
181		}
182		(void) fprintf(stdout, "\n");
183	}
184}
185
186/*
187 * Generic routine used by all "list cert" operations to find
188 * all matching certificates.
189 */
190static KMF_RETURN
191pk_find_certs(KMF_HANDLE_T kmfhandle, KMF_FINDCERT_PARAMS *params)
192{
193	KMF_RETURN rv = KMF_OK;
194	KMF_X509_DER_CERT *certlist = NULL;
195	uint32_t numcerts = 0;
196
197	numcerts = 0;
198	rv = KMF_FindCert(kmfhandle, params, NULL, &numcerts);
199	if (rv == KMF_OK && numcerts > 0) {
200		(void) printf(gettext("Found %d certificates.\n"),
201			numcerts);
202		certlist = (KMF_X509_DER_CERT *)malloc(numcerts *
203				sizeof (KMF_X509_DER_CERT));
204		if (certlist == NULL)
205			return (KMF_ERR_MEMORY);
206		(void) memset(certlist, 0, numcerts *
207			sizeof (KMF_X509_DER_CERT));
208
209		rv = KMF_FindCert(kmfhandle, params, certlist, &numcerts);
210		if (rv == KMF_OK) {
211			int i;
212			(void) pk_show_certs(kmfhandle, certlist,
213				numcerts);
214			for (i = 0; i < numcerts; i++)
215				KMF_FreeKMFCert(kmfhandle, &certlist[i]);
216		}
217		free(certlist);
218	}
219	if (rv == KMF_ERR_CERT_NOT_FOUND &&
220		params->kstype != KMF_KEYSTORE_OPENSSL)
221		rv = KMF_OK;
222
223	return (rv);
224}
225
226static KMF_RETURN
227pk_list_keys(void *handle, KMF_FINDKEY_PARAMS *parms)
228{
229	KMF_RETURN rv;
230	KMF_KEY_HANDLE *keys;
231	uint32_t numkeys = 0;
232
233	numkeys = 0;
234	rv = KMF_FindKey(handle, parms, NULL, &numkeys);
235	if (rv == KMF_OK && numkeys > 0) {
236		int i;
237		(void) printf(gettext("Found %d keys.\n"), numkeys);
238		keys = (KMF_KEY_HANDLE *)malloc(numkeys *
239				sizeof (KMF_KEY_HANDLE));
240		if (keys == NULL)
241			return (KMF_ERR_MEMORY);
242		(void) memset(keys, 0, numkeys *
243			sizeof (KMF_KEY_HANDLE));
244
245		rv = KMF_FindKey(handle, parms, keys, &numkeys);
246		if (rv == KMF_OK)
247			pk_show_keys(handle, keys, numkeys);
248		for (i = 0; i < numkeys; i++)
249			KMF_FreeKMFKey(handle, &keys[i]);
250		free(keys);
251	}
252	if (rv == KMF_ERR_KEY_NOT_FOUND &&
253		parms->kstype != KMF_KEYSTORE_OPENSSL)
254		rv = KMF_OK;
255	return (rv);
256}
257
258static KMF_RETURN
259list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass,
260	char *objlabel, KMF_BIGINT *serial, char *issuer, char *subject,
261	char *dir, char *filename, KMF_CREDENTIAL *tokencred,
262	KMF_CERT_VALIDITY find_criteria_flag)
263{
264	KMF_RETURN rv;
265	KMF_LISTCRL_PARAMS lcrlargs;
266
267	/*
268	 * Symmetric keys and RSA/DSA private keys are always
269	 * created with the "CKA_PRIVATE" field == TRUE, so
270	 * make sure we search for them with it also set.
271	 */
272	if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ))
273		oclass |= PK_PRIVATE_OBJ;
274
275	rv = select_token(kmfhandle, token,
276		!(oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)));
277
278	if (rv != KMF_OK) {
279		return (rv);
280	}
281
282	if (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ)) {
283		KMF_FINDKEY_PARAMS parms;
284
285		(void) memset(&parms, 0, sizeof (parms));
286		parms.kstype = KMF_KEYSTORE_PK11TOKEN;
287
288		if (oclass & PK_PRIKEY_OBJ) {
289			parms.keyclass = KMF_ASYM_PRI;
290			parms.findLabel = objlabel;
291			parms.cred = *tokencred;
292			parms.pkcs11parms.private =
293				((oclass & PK_PRIVATE_OBJ) > 0);
294
295			/* list asymmetric private keys */
296			rv = pk_list_keys(kmfhandle, &parms);
297		}
298
299		if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
300			parms.keyclass = KMF_SYMMETRIC;
301			parms.findLabel = objlabel;
302			parms.cred = *tokencred;
303			parms.format = KMF_FORMAT_RAWKEY;
304			parms.pkcs11parms.private =
305				((oclass & PK_PRIVATE_OBJ) > 0);
306
307			/* list symmetric keys */
308			rv = pk_list_keys(kmfhandle, &parms);
309		}
310
311		if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
312			parms.keyclass = KMF_ASYM_PUB;
313			parms.findLabel = objlabel;
314			parms.pkcs11parms.private =
315				((oclass & PK_PRIVATE_OBJ) > 0);
316
317			/* list asymmetric public keys (if any) */
318			rv = pk_list_keys(kmfhandle, &parms);
319		}
320
321		if (rv != KMF_OK)
322			return (rv);
323	}
324
325	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
326		KMF_FINDCERT_PARAMS parms;
327
328		(void) memset(&parms, 0, sizeof (parms));
329		parms.kstype = KMF_KEYSTORE_PK11TOKEN;
330		parms.certLabel = objlabel;
331		parms.issuer = issuer;
332		parms.subject = subject;
333		parms.serial = serial;
334		parms.pkcs11parms.private = FALSE;
335		parms.find_cert_validity = find_criteria_flag;
336
337		rv = pk_find_certs(kmfhandle, &parms);
338		if (rv != KMF_OK)
339			return (rv);
340	}
341
342	if (oclass & PK_CRL_OBJ) {
343		char *crldata;
344
345		(void) memset(&lcrlargs, 0, sizeof (lcrlargs));
346		lcrlargs.kstype = KMF_KEYSTORE_OPENSSL;
347		lcrlargs.sslparms.dirpath = dir;
348		lcrlargs.sslparms.crlfile = filename;
349
350		rv = KMF_ListCRL(kmfhandle, &lcrlargs, &crldata);
351		if (rv == KMF_OK) {
352			(void) printf("%s\n", crldata);
353			free(crldata);
354		}
355	}
356
357	return (rv);
358}
359
360static int
361list_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
362	char *dir, char *filename, KMF_BIGINT *serial,
363	char *issuer, char *subject,
364	KMF_CERT_VALIDITY find_criteria_flag)
365{
366	int rv;
367	KMF_FINDCERT_PARAMS fcargs;
368	KMF_FINDKEY_PARAMS fkargs;
369	KMF_LISTCRL_PARAMS lcrlargs;
370
371	if (oclass & PK_KEY_OBJ) {
372		(void) memset(&fkargs, 0, sizeof (fkargs));
373		fkargs.kstype = KMF_KEYSTORE_OPENSSL;
374		fkargs.sslparms.dirpath = dir;
375		fkargs.sslparms.keyfile = filename;
376		if (oclass & PK_PRIKEY_OBJ) {
377			fkargs.keyclass = KMF_ASYM_PRI;
378
379			rv = pk_list_keys(kmfhandle, &fkargs);
380		}
381		if (rv == KMF_ERR_KEY_NOT_FOUND)
382			rv = KMF_OK;
383
384		if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
385			fkargs.keyclass = KMF_SYMMETRIC;
386			fkargs.format = KMF_FORMAT_RAWKEY;
387
388			rv = pk_list_keys(kmfhandle, &fkargs);
389		}
390		if (rv == KMF_ERR_KEY_NOT_FOUND)
391			rv = KMF_OK;
392		if (rv != KMF_OK)
393			return (rv);
394	}
395
396	if (oclass & PK_CERT_OBJ) {
397		(void) memset(&fcargs, 0, sizeof (fcargs));
398		fcargs.kstype = KMF_KEYSTORE_OPENSSL;
399		fcargs.certLabel = NULL;
400		fcargs.issuer = issuer;
401		fcargs.subject = subject;
402		fcargs.serial = serial;
403		fcargs.sslparms.dirpath = dir;
404		fcargs.sslparms.certfile = filename;
405		fcargs.find_cert_validity = find_criteria_flag;
406
407		rv = pk_find_certs(kmfhandle, &fcargs);
408		if (rv != KMF_OK)
409			return (rv);
410	}
411
412	if (oclass & PK_CRL_OBJ) {
413		char *crldata;
414
415		(void) memset(&lcrlargs, 0, sizeof (lcrlargs));
416		lcrlargs.kstype = KMF_KEYSTORE_OPENSSL;
417		lcrlargs.sslparms.dirpath = dir;
418		lcrlargs.sslparms.crlfile = filename;
419
420		rv = KMF_ListCRL(kmfhandle, &lcrlargs, &crldata);
421		if (rv == KMF_OK) {
422			(void) printf("%s\n", crldata);
423			free(crldata);
424		}
425	}
426
427	return (rv);
428}
429
430static int
431list_nss_objects(KMF_HANDLE_T kmfhandle,
432	int oclass, char *token_spec, char *dir, char *prefix,
433	char *nickname, KMF_BIGINT *serial, char *issuer, char *subject,
434	KMF_CREDENTIAL *tokencred,
435	KMF_CERT_VALIDITY find_criteria_flag)
436{
437	KMF_RETURN rv = KMF_OK;
438	KMF_FINDKEY_PARAMS fkargs;
439
440	rv = configure_nss(kmfhandle, dir, prefix);
441	if (rv != KMF_OK)
442		return (rv);
443
444	if (oclass & PK_KEY_OBJ) {
445		(void) memset(&fkargs, 0, sizeof (fkargs));
446		fkargs.kstype = KMF_KEYSTORE_NSS;
447		fkargs.findLabel = nickname;
448		fkargs.cred = *tokencred;
449		fkargs.nssparms.slotlabel = token_spec;
450	}
451
452	if (oclass & PK_PRIKEY_OBJ) {
453		fkargs.keyclass = KMF_ASYM_PRI;
454		rv = pk_list_keys(kmfhandle, &fkargs);
455	}
456	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
457		fkargs.keyclass = KMF_SYMMETRIC;
458		fkargs.format = KMF_FORMAT_RAWKEY;
459		rv = pk_list_keys(kmfhandle, &fkargs);
460	}
461	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
462		fkargs.keyclass = KMF_ASYM_PUB;
463		rv = pk_list_keys(kmfhandle, &fkargs);
464	}
465
466	/* If searching for public objects or certificates, find certs now */
467	if (rv == KMF_OK && (oclass & PK_CERT_OBJ)) {
468		KMF_FINDCERT_PARAMS fcargs;
469
470		(void) memset(&fcargs, 0, sizeof (fcargs));
471		fcargs.kstype = KMF_KEYSTORE_NSS;
472		fcargs.certLabel = nickname;
473		fcargs.issuer = issuer;
474		fcargs.subject = subject;
475		fcargs.serial = serial;
476		fcargs.nssparms.slotlabel = token_spec;
477		fcargs.find_cert_validity = find_criteria_flag;
478
479		rv = pk_find_certs(kmfhandle, &fcargs);
480	}
481
482	if (rv == KMF_OK && (oclass & PK_CRL_OBJ)) {
483		int numcrls;
484		KMF_FINDCRL_PARAMS fcrlargs;
485
486		(void) memset(&fcrlargs, 0, sizeof (fcrlargs));
487		fcrlargs.kstype = KMF_KEYSTORE_NSS;
488		fcrlargs.nssparms.slotlabel = token_spec;
489
490		rv = KMF_FindCRL(kmfhandle, &fcrlargs, NULL, &numcrls);
491		if (rv == KMF_OK) {
492			char **p;
493			if (numcrls == 0) {
494				(void) printf(gettext("No CRLs found in "
495					"NSS keystore.\n"));
496
497				return (KMF_OK);
498			}
499			p = malloc(numcrls * sizeof (char *));
500			if (p == NULL) {
501				return (KMF_ERR_MEMORY);
502			}
503			(void) memset(p, 0, numcrls * sizeof (char *));
504			rv = KMF_FindCRL(kmfhandle, &fcrlargs,
505				p, &numcrls);
506			if (rv == KMF_OK) {
507				int i;
508				for (i = 0; i < numcrls; i++) {
509					(void) printf("%d. Name = %s\n",
510						i + 1, p[i]);
511					free(p[i]);
512				}
513			}
514			free(p);
515		}
516	}
517	return (rv);
518}
519
520/*
521 * List token object.
522 */
523int
524pk_list(int argc, char *argv[])
525{
526	int			opt;
527	extern int		optind_av;
528	extern char		*optarg_av;
529	char			*token_spec = NULL;
530	char			*subject = NULL;
531	char			*issuer = NULL;
532	char			*dir = NULL;
533	char			*prefix = NULL;
534	char			*filename = NULL;
535	char			*serstr = NULL;
536	KMF_BIGINT		serial = { NULL, 0 };
537
538	char			*list_label = NULL;
539	int			oclass = 0;
540	KMF_KEYSTORE_TYPE	kstype = 0;
541	KMF_RETURN		rv = KMF_OK;
542	KMF_HANDLE_T		kmfhandle = NULL;
543	char			*find_criteria = NULL;
544	KMF_CERT_VALIDITY	find_criteria_flag = KMF_ALL_CERTS;
545	KMF_CREDENTIAL		tokencred = {NULL, 0};
546
547	/* Parse command line options.  Do NOT i18n/l10n. */
548	while ((opt = getopt_av(argc, argv,
549		"k:(keystore)t:(objtype)T:(token)d:(dir)"
550		"p:(prefix)n:(nickname)S:(serial)s:(subject)"
551		"c:(criteria)"
552		"i:(issuer)l:(label)f:(infile)")) != EOF) {
553		if (EMPTYSTRING(optarg_av))
554			return (PK_ERR_USAGE);
555		switch (opt) {
556			case 'k':
557				if (kstype != 0)
558					return (PK_ERR_USAGE);
559				kstype = KS2Int(optarg_av);
560				if (kstype == 0)
561					return (PK_ERR_USAGE);
562				break;
563			case 't':
564				if (oclass != 0)
565					return (PK_ERR_USAGE);
566				oclass = OT2Int(optarg_av);
567				if (oclass == -1)
568					return (PK_ERR_USAGE);
569				break;
570			case 's':
571				if (subject)
572					return (PK_ERR_USAGE);
573				subject = optarg_av;
574				break;
575			case 'i':
576				if (issuer)
577					return (PK_ERR_USAGE);
578				issuer = optarg_av;
579				break;
580			case 'd':
581				if (dir)
582					return (PK_ERR_USAGE);
583				dir = optarg_av;
584				break;
585			case 'p':
586				if (prefix)
587					return (PK_ERR_USAGE);
588				prefix = optarg_av;
589				break;
590			case 'S':
591				serstr = optarg_av;
592				break;
593			case 'f':
594				if (filename)
595					return (PK_ERR_USAGE);
596				filename = optarg_av;
597				break;
598			case 'T':	/* token specifier */
599				if (token_spec)
600					return (PK_ERR_USAGE);
601				token_spec = optarg_av;
602				break;
603			case 'n':
604			case 'l':	/* object with specific label */
605				if (list_label)
606					return (PK_ERR_USAGE);
607				list_label = optarg_av;
608				break;
609			case 'c':
610				find_criteria = optarg_av;
611				if (!strcasecmp(find_criteria, "valid"))
612					find_criteria_flag =
613					    KMF_NONEXPIRED_CERTS;
614				else if (!strcasecmp(find_criteria, "expired"))
615					find_criteria_flag = KMF_EXPIRED_CERTS;
616				else if (!strcasecmp(find_criteria, "both"))
617					find_criteria_flag = KMF_ALL_CERTS;
618				else
619					return (PK_ERR_USAGE);
620				break;
621			default:
622				return (PK_ERR_USAGE);
623		}
624	}
625	/* No additional args allowed. */
626	argc -= optind_av;
627	argv += optind_av;
628	if (argc)
629		return (PK_ERR_USAGE);
630
631	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
632		/* Error message ? */
633		return (rv);
634	}
635
636	/* Assume keystore = PKCS#11 if not specified. */
637	if (kstype == 0)
638		kstype = KMF_KEYSTORE_PK11TOKEN;
639
640	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
641	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
642		kstype != KMF_KEYSTORE_PK11TOKEN) {
643
644		(void) fprintf(stderr, gettext("The objtype parameter "
645			"is only relevant if keystore=pkcs11\n"));
646		return (PK_ERR_USAGE);
647	}
648
649	/* If no object class specified, list certificate objects. */
650	if (oclass == 0)
651		oclass = PK_CERT_OBJ;
652
653	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) {
654		token_spec = PK_DEFAULT_PK11TOKEN;
655	} else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) {
656		token_spec = DEFAULT_NSS_TOKEN;
657	}
658
659	if (serstr != NULL) {
660		uchar_t *bytes = NULL;
661		size_t bytelen;
662
663		rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen);
664		if (rv != KMF_OK || bytes == NULL) {
665			(void) fprintf(stderr, gettext("serial number "
666				"must be specified as a hex number "
667				"(ex: 0x0102030405ffeeddee)\n"));
668			return (PK_ERR_USAGE);
669		}
670		serial.val = bytes;
671		serial.len = bytelen;
672	}
673
674	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
675		kstype == KMF_KEYSTORE_NSS) &&
676		(oclass & (PK_PRIKEY_OBJ | PK_PRIVATE_OBJ))) {
677
678		(void) get_token_password(kstype, token_spec,
679			&tokencred);
680	}
681	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
682		rv = list_pk11_objects(kmfhandle, token_spec,
683			oclass, list_label, &serial,
684			issuer, subject, dir, filename,
685			&tokencred, find_criteria_flag);
686
687	} else if (kstype == KMF_KEYSTORE_NSS) {
688		if (dir == NULL)
689			dir = PK_DEFAULT_DIRECTORY;
690		rv = list_nss_objects(kmfhandle,
691			oclass, token_spec, dir, prefix,
692			list_label, &serial, issuer, subject,
693			&tokencred, find_criteria_flag);
694
695	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
696
697		rv = list_file_objects(kmfhandle,
698			oclass, dir, filename,
699			&serial, issuer, subject, find_criteria_flag);
700	}
701
702	if (rv != KMF_OK) {
703		display_error(kmfhandle, rv,
704			gettext("Error listing objects"));
705	}
706
707	if (serial.val != NULL)
708		free(serial.val);
709
710	if (tokencred.cred != NULL)
711		free(tokencred.cred);
712
713	(void) KMF_Finalize(kmfhandle);
714	return (rv);
715}
716