xref: /illumos-gate/usr/src/cmd/cmd-crypto/pktool/list.c (revision cb6207858a9fcc2feaee22e626912fba281ac969)
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 2007 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 
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 
96 static char *
97 describeKey(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 
135 static char *
136 keybitstr(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 
158 static void
159 pk_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  */
190 static KMF_RETURN
191 pk_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 
226 static KMF_RETURN
227 pk_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 
258 static KMF_RETURN
259 list_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 			parms.pkcs11parms.token = 1;
295 
296 			/* list asymmetric private keys */
297 			rv = pk_list_keys(kmfhandle, &parms);
298 		}
299 
300 		if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
301 			parms.keyclass = KMF_SYMMETRIC;
302 			parms.findLabel = objlabel;
303 			parms.cred = *tokencred;
304 			parms.format = KMF_FORMAT_RAWKEY;
305 			parms.pkcs11parms.private =
306 				((oclass & PK_PRIVATE_OBJ) > 0);
307 			parms.pkcs11parms.token = 1;
308 
309 			/* list symmetric keys */
310 			rv = pk_list_keys(kmfhandle, &parms);
311 		}
312 
313 		if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
314 			parms.keyclass = KMF_ASYM_PUB;
315 			parms.findLabel = objlabel;
316 			parms.pkcs11parms.private =
317 				((oclass & PK_PRIVATE_OBJ) > 0);
318 			parms.pkcs11parms.token = 1;
319 
320 			/* list asymmetric public keys (if any) */
321 			rv = pk_list_keys(kmfhandle, &parms);
322 		}
323 
324 		if (rv != KMF_OK)
325 			return (rv);
326 	}
327 
328 	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
329 		KMF_FINDCERT_PARAMS parms;
330 
331 		(void) memset(&parms, 0, sizeof (parms));
332 		parms.kstype = KMF_KEYSTORE_PK11TOKEN;
333 		parms.certLabel = objlabel;
334 		parms.issuer = issuer;
335 		parms.subject = subject;
336 		parms.serial = serial;
337 		parms.pkcs11parms.private = FALSE;
338 		parms.find_cert_validity = find_criteria_flag;
339 
340 		rv = pk_find_certs(kmfhandle, &parms);
341 		if (rv != KMF_OK)
342 			return (rv);
343 	}
344 
345 	if (oclass & PK_CRL_OBJ) {
346 		char *crldata;
347 
348 		(void) memset(&lcrlargs, 0, sizeof (lcrlargs));
349 		lcrlargs.kstype = KMF_KEYSTORE_OPENSSL;
350 		lcrlargs.sslparms.dirpath = dir;
351 		lcrlargs.sslparms.crlfile = filename;
352 
353 		rv = KMF_ListCRL(kmfhandle, &lcrlargs, &crldata);
354 		if (rv == KMF_OK) {
355 			(void) printf("%s\n", crldata);
356 			free(crldata);
357 		}
358 	}
359 
360 	return (rv);
361 }
362 
363 static int
364 list_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
365 	char *dir, char *filename, KMF_BIGINT *serial,
366 	char *issuer, char *subject,
367 	KMF_CERT_VALIDITY find_criteria_flag)
368 {
369 	int rv;
370 	KMF_FINDCERT_PARAMS fcargs;
371 	KMF_FINDKEY_PARAMS fkargs;
372 	KMF_LISTCRL_PARAMS lcrlargs;
373 
374 	if (oclass & PK_KEY_OBJ) {
375 		(void) memset(&fkargs, 0, sizeof (fkargs));
376 		fkargs.kstype = KMF_KEYSTORE_OPENSSL;
377 		fkargs.sslparms.dirpath = dir;
378 		fkargs.sslparms.keyfile = filename;
379 		if (oclass & PK_PRIKEY_OBJ) {
380 			fkargs.keyclass = KMF_ASYM_PRI;
381 
382 			rv = pk_list_keys(kmfhandle, &fkargs);
383 		}
384 		if (rv == KMF_ERR_KEY_NOT_FOUND)
385 			rv = KMF_OK;
386 
387 		if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
388 			fkargs.keyclass = KMF_SYMMETRIC;
389 			fkargs.format = KMF_FORMAT_RAWKEY;
390 
391 			rv = pk_list_keys(kmfhandle, &fkargs);
392 		}
393 		if (rv == KMF_ERR_KEY_NOT_FOUND)
394 			rv = KMF_OK;
395 		if (rv != KMF_OK)
396 			return (rv);
397 	}
398 
399 	if (oclass & PK_CERT_OBJ) {
400 		(void) memset(&fcargs, 0, sizeof (fcargs));
401 		fcargs.kstype = KMF_KEYSTORE_OPENSSL;
402 		fcargs.certLabel = NULL;
403 		fcargs.issuer = issuer;
404 		fcargs.subject = subject;
405 		fcargs.serial = serial;
406 		fcargs.sslparms.dirpath = dir;
407 		fcargs.sslparms.certfile = filename;
408 		fcargs.find_cert_validity = find_criteria_flag;
409 
410 		rv = pk_find_certs(kmfhandle, &fcargs);
411 		if (rv != KMF_OK)
412 			return (rv);
413 	}
414 
415 	if (oclass & PK_CRL_OBJ) {
416 		char *crldata;
417 
418 		(void) memset(&lcrlargs, 0, sizeof (lcrlargs));
419 		lcrlargs.kstype = KMF_KEYSTORE_OPENSSL;
420 		lcrlargs.sslparms.dirpath = dir;
421 		lcrlargs.sslparms.crlfile = filename;
422 
423 		rv = KMF_ListCRL(kmfhandle, &lcrlargs, &crldata);
424 		if (rv == KMF_OK) {
425 			(void) printf("%s\n", crldata);
426 			free(crldata);
427 		}
428 	}
429 
430 	return (rv);
431 }
432 
433 static int
434 list_nss_objects(KMF_HANDLE_T kmfhandle,
435 	int oclass, char *token_spec, char *dir, char *prefix,
436 	char *nickname, KMF_BIGINT *serial, char *issuer, char *subject,
437 	KMF_CREDENTIAL *tokencred,
438 	KMF_CERT_VALIDITY find_criteria_flag)
439 {
440 	KMF_RETURN rv = KMF_OK;
441 	KMF_FINDKEY_PARAMS fkargs;
442 
443 	rv = configure_nss(kmfhandle, dir, prefix);
444 	if (rv != KMF_OK)
445 		return (rv);
446 
447 	if (oclass & PK_KEY_OBJ) {
448 		(void) memset(&fkargs, 0, sizeof (fkargs));
449 		fkargs.kstype = KMF_KEYSTORE_NSS;
450 		fkargs.findLabel = nickname;
451 		fkargs.cred = *tokencred;
452 		fkargs.nssparms.slotlabel = token_spec;
453 	}
454 
455 	if (oclass & PK_PRIKEY_OBJ) {
456 		fkargs.keyclass = KMF_ASYM_PRI;
457 		rv = pk_list_keys(kmfhandle, &fkargs);
458 	}
459 	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
460 		fkargs.keyclass = KMF_SYMMETRIC;
461 		fkargs.format = KMF_FORMAT_RAWKEY;
462 		rv = pk_list_keys(kmfhandle, &fkargs);
463 	}
464 	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
465 		fkargs.keyclass = KMF_ASYM_PUB;
466 		rv = pk_list_keys(kmfhandle, &fkargs);
467 	}
468 
469 	/* If searching for public objects or certificates, find certs now */
470 	if (rv == KMF_OK && (oclass & PK_CERT_OBJ)) {
471 		KMF_FINDCERT_PARAMS fcargs;
472 
473 		(void) memset(&fcargs, 0, sizeof (fcargs));
474 		fcargs.kstype = KMF_KEYSTORE_NSS;
475 		fcargs.certLabel = nickname;
476 		fcargs.issuer = issuer;
477 		fcargs.subject = subject;
478 		fcargs.serial = serial;
479 		fcargs.nssparms.slotlabel = token_spec;
480 		fcargs.find_cert_validity = find_criteria_flag;
481 
482 		rv = pk_find_certs(kmfhandle, &fcargs);
483 	}
484 
485 	if (rv == KMF_OK && (oclass & PK_CRL_OBJ)) {
486 		int numcrls;
487 		KMF_FINDCRL_PARAMS fcrlargs;
488 
489 		(void) memset(&fcrlargs, 0, sizeof (fcrlargs));
490 		fcrlargs.kstype = KMF_KEYSTORE_NSS;
491 		fcrlargs.nssparms.slotlabel = token_spec;
492 
493 		rv = KMF_FindCRL(kmfhandle, &fcrlargs, NULL, &numcrls);
494 		if (rv == KMF_OK) {
495 			char **p;
496 			if (numcrls == 0) {
497 				(void) printf(gettext("No CRLs found in "
498 					"NSS keystore.\n"));
499 
500 				return (KMF_OK);
501 			}
502 			p = malloc(numcrls * sizeof (char *));
503 			if (p == NULL) {
504 				return (KMF_ERR_MEMORY);
505 			}
506 			(void) memset(p, 0, numcrls * sizeof (char *));
507 			rv = KMF_FindCRL(kmfhandle, &fcrlargs,
508 				p, &numcrls);
509 			if (rv == KMF_OK) {
510 				int i;
511 				for (i = 0; i < numcrls; i++) {
512 					(void) printf("%d. Name = %s\n",
513 						i + 1, p[i]);
514 					free(p[i]);
515 				}
516 			}
517 			free(p);
518 		}
519 	}
520 	return (rv);
521 }
522 
523 /*
524  * List token object.
525  */
526 int
527 pk_list(int argc, char *argv[])
528 {
529 	int			opt;
530 	extern int		optind_av;
531 	extern char		*optarg_av;
532 	char			*token_spec = NULL;
533 	char			*subject = NULL;
534 	char			*issuer = NULL;
535 	char			*dir = NULL;
536 	char			*prefix = NULL;
537 	char			*filename = NULL;
538 	char			*serstr = NULL;
539 	KMF_BIGINT		serial = { NULL, 0 };
540 
541 	char			*list_label = NULL;
542 	int			oclass = 0;
543 	KMF_KEYSTORE_TYPE	kstype = 0;
544 	KMF_RETURN		rv = KMF_OK;
545 	KMF_HANDLE_T		kmfhandle = NULL;
546 	char			*find_criteria = NULL;
547 	KMF_CERT_VALIDITY	find_criteria_flag = KMF_ALL_CERTS;
548 	KMF_CREDENTIAL		tokencred = {NULL, 0};
549 
550 	/* Parse command line options.  Do NOT i18n/l10n. */
551 	while ((opt = getopt_av(argc, argv,
552 		"k:(keystore)t:(objtype)T:(token)d:(dir)"
553 		"p:(prefix)n:(nickname)S:(serial)s:(subject)"
554 		"c:(criteria)"
555 		"i:(issuer)l:(label)f:(infile)")) != EOF) {
556 		if (EMPTYSTRING(optarg_av))
557 			return (PK_ERR_USAGE);
558 		switch (opt) {
559 			case 'k':
560 				if (kstype != 0)
561 					return (PK_ERR_USAGE);
562 				kstype = KS2Int(optarg_av);
563 				if (kstype == 0)
564 					return (PK_ERR_USAGE);
565 				break;
566 			case 't':
567 				if (oclass != 0)
568 					return (PK_ERR_USAGE);
569 				oclass = OT2Int(optarg_av);
570 				if (oclass == -1)
571 					return (PK_ERR_USAGE);
572 				break;
573 			case 's':
574 				if (subject)
575 					return (PK_ERR_USAGE);
576 				subject = optarg_av;
577 				break;
578 			case 'i':
579 				if (issuer)
580 					return (PK_ERR_USAGE);
581 				issuer = optarg_av;
582 				break;
583 			case 'd':
584 				if (dir)
585 					return (PK_ERR_USAGE);
586 				dir = optarg_av;
587 				break;
588 			case 'p':
589 				if (prefix)
590 					return (PK_ERR_USAGE);
591 				prefix = optarg_av;
592 				break;
593 			case 'S':
594 				serstr = optarg_av;
595 				break;
596 			case 'f':
597 				if (filename)
598 					return (PK_ERR_USAGE);
599 				filename = optarg_av;
600 				break;
601 			case 'T':	/* token specifier */
602 				if (token_spec)
603 					return (PK_ERR_USAGE);
604 				token_spec = optarg_av;
605 				break;
606 			case 'n':
607 			case 'l':	/* object with specific label */
608 				if (list_label)
609 					return (PK_ERR_USAGE);
610 				list_label = optarg_av;
611 				break;
612 			case 'c':
613 				find_criteria = optarg_av;
614 				if (!strcasecmp(find_criteria, "valid"))
615 					find_criteria_flag =
616 					    KMF_NONEXPIRED_CERTS;
617 				else if (!strcasecmp(find_criteria, "expired"))
618 					find_criteria_flag = KMF_EXPIRED_CERTS;
619 				else if (!strcasecmp(find_criteria, "both"))
620 					find_criteria_flag = KMF_ALL_CERTS;
621 				else
622 					return (PK_ERR_USAGE);
623 				break;
624 			default:
625 				return (PK_ERR_USAGE);
626 		}
627 	}
628 	/* No additional args allowed. */
629 	argc -= optind_av;
630 	argv += optind_av;
631 	if (argc)
632 		return (PK_ERR_USAGE);
633 
634 	if ((rv = KMF_Initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
635 		/* Error message ? */
636 		return (rv);
637 	}
638 
639 	/* Assume keystore = PKCS#11 if not specified. */
640 	if (kstype == 0)
641 		kstype = KMF_KEYSTORE_PK11TOKEN;
642 
643 	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
644 	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
645 		kstype != KMF_KEYSTORE_PK11TOKEN) {
646 
647 		(void) fprintf(stderr, gettext("The objtype parameter "
648 			"is only relevant if keystore=pkcs11\n"));
649 		return (PK_ERR_USAGE);
650 	}
651 
652 	/* If no object class specified, list certificate objects. */
653 	if (oclass == 0)
654 		oclass = PK_CERT_OBJ;
655 
656 	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) {
657 		token_spec = PK_DEFAULT_PK11TOKEN;
658 	} else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) {
659 		token_spec = DEFAULT_NSS_TOKEN;
660 	}
661 
662 	if (serstr != NULL) {
663 		uchar_t *bytes = NULL;
664 		size_t bytelen;
665 
666 		rv = KMF_HexString2Bytes((uchar_t *)serstr, &bytes, &bytelen);
667 		if (rv != KMF_OK || bytes == NULL) {
668 			(void) fprintf(stderr, gettext("serial number "
669 				"must be specified as a hex number "
670 				"(ex: 0x0102030405ffeeddee)\n"));
671 			return (PK_ERR_USAGE);
672 		}
673 		serial.val = bytes;
674 		serial.len = bytelen;
675 	}
676 
677 	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
678 		kstype == KMF_KEYSTORE_NSS) &&
679 		(oclass & (PK_PRIKEY_OBJ | PK_PRIVATE_OBJ))) {
680 
681 		(void) get_token_password(kstype, token_spec,
682 			&tokencred);
683 	}
684 	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
685 		rv = list_pk11_objects(kmfhandle, token_spec,
686 			oclass, list_label, &serial,
687 			issuer, subject, dir, filename,
688 			&tokencred, find_criteria_flag);
689 
690 	} else if (kstype == KMF_KEYSTORE_NSS) {
691 		if (dir == NULL)
692 			dir = PK_DEFAULT_DIRECTORY;
693 		rv = list_nss_objects(kmfhandle,
694 			oclass, token_spec, dir, prefix,
695 			list_label, &serial, issuer, subject,
696 			&tokencred, find_criteria_flag);
697 
698 	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
699 
700 		rv = list_file_objects(kmfhandle,
701 			oclass, dir, filename,
702 			&serial, issuer, subject, find_criteria_flag);
703 	}
704 
705 	if (rv != KMF_OK) {
706 		display_error(kmfhandle, rv,
707 			gettext("Error listing objects"));
708 	}
709 
710 	if (serial.val != NULL)
711 		free(serial.val);
712 
713 	if (tokencred.cred != NULL)
714 		free(tokencred.cred);
715 
716 	(void) KMF_Finalize(kmfhandle);
717 	return (rv);
718 }
719