list.c revision 5051:cbbb7c8b40a9
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
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	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
121static char *
122describeKey(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
161static void
162pk_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 */
208static KMF_RETURN
209pk_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
258static KMF_RETURN
259pk_list_keys(void *handle, KMF_ATTRIBUTE *attrlist, int numattr)
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 keys.\n"), numkeys);
279		keys = (KMF_KEY_HANDLE *)malloc(numkeys *
280		    sizeof (KMF_KEY_HANDLE));
281		if (keys == NULL)
282			return (KMF_ERR_MEMORY);
283		(void) memset(keys, 0, numkeys *
284		    sizeof (KMF_KEY_HANDLE));
285
286		kmf_set_attr_at_index(attrlist, numattr,
287		    KMF_KEY_HANDLE_ATTR,
288		    keys, sizeof (KMF_KEY_HANDLE));
289		numattr++;
290
291		rv = kmf_find_key(handle, numattr, attrlist);
292		if (rv == KMF_OK)
293			pk_show_keys(handle, keys, numkeys);
294		for (i = 0; i < numkeys; i++)
295			kmf_free_kmf_key(handle, &keys[i]);
296		free(keys);
297	}
298	if (rv == KMF_ERR_KEY_NOT_FOUND &&
299	    kstype != KMF_KEYSTORE_OPENSSL)
300		rv = KMF_OK;
301	return (rv);
302}
303
304static KMF_RETURN
305list_pk11_objects(KMF_HANDLE_T kmfhandle, char *token, int oclass,
306	char *objlabel, KMF_BIGINT *serial, char *issuer, char *subject,
307	char *dir, char *filename, KMF_CREDENTIAL *tokencred,
308	KMF_CERT_VALIDITY find_criteria_flag)
309{
310	KMF_RETURN rv;
311	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_PK11TOKEN;
312	int numattr = 0;
313	KMF_ATTRIBUTE attrlist[16];
314	boolean_t token_bool = B_TRUE;
315	boolean_t private = B_FALSE;
316	KMF_KEY_CLASS keyclass;
317	KMF_ENCODE_FORMAT format;
318
319	/*
320	 * Symmetric keys and RSA/DSA private keys are always
321	 * created with the "CKA_PRIVATE" field == TRUE, so
322	 * make sure we search for them with it also set.
323	 */
324	if (oclass & (PK_SYMKEY_OBJ | PK_PRIKEY_OBJ))
325		oclass |= PK_PRIVATE_OBJ;
326
327	rv = select_token(kmfhandle, token,
328	    !(oclass & (PK_PRIVATE_OBJ | PK_PRIKEY_OBJ)));
329
330	if (rv != KMF_OK) {
331		return (rv);
332	}
333
334	if (oclass & (PK_KEY_OBJ | PK_PRIVATE_OBJ)) {
335		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
336		    &kstype, sizeof (kstype));
337		numattr++;
338
339		if (objlabel != NULL) {
340			kmf_set_attr_at_index(attrlist, numattr,
341			    KMF_KEYLABEL_ATTR, objlabel,
342			    strlen(objlabel));
343			numattr++;
344		}
345
346		private = ((oclass & PK_PRIVATE_OBJ) > 0);
347
348		kmf_set_attr_at_index(attrlist, numattr,
349		    KMF_PRIVATE_BOOL_ATTR, &private,
350		    sizeof (private));
351		numattr++;
352
353		kmf_set_attr_at_index(attrlist, numattr,
354		    KMF_TOKEN_BOOL_ATTR, &token_bool,
355		    sizeof (token_bool));
356		numattr++;
357
358		if (oclass & PK_PRIKEY_OBJ) {
359			int num = numattr;
360
361			keyclass = KMF_ASYM_PRI;
362			kmf_set_attr_at_index(attrlist, num,
363			    KMF_KEYCLASS_ATTR, &keyclass,
364			    sizeof (keyclass));
365			num++;
366
367			if (tokencred != NULL &&
368			    tokencred->credlen > 0) {
369				kmf_set_attr_at_index(attrlist, num,
370				    KMF_CREDENTIAL_ATTR, tokencred,
371				    sizeof (KMF_CREDENTIAL));
372				num++;
373			}
374
375			/* list asymmetric private keys */
376			rv = pk_list_keys(kmfhandle, attrlist, num);
377		}
378
379		if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
380			int num = numattr;
381
382			keyclass = KMF_SYMMETRIC;
383			kmf_set_attr_at_index(attrlist, num,
384			    KMF_KEYCLASS_ATTR, &keyclass,
385			    sizeof (keyclass));
386			num++;
387
388			if (tokencred != NULL &&
389			    tokencred->credlen > 0) {
390				kmf_set_attr_at_index(attrlist, num,
391				    KMF_CREDENTIAL_ATTR, tokencred,
392				    sizeof (KMF_CREDENTIAL));
393				num++;
394			}
395
396			format = KMF_FORMAT_RAWKEY;
397			kmf_set_attr_at_index(attrlist, num,
398			    KMF_ENCODE_FORMAT_ATTR, &format,
399			    sizeof (format));
400			num++;
401
402			/* list symmetric keys */
403			rv = pk_list_keys(kmfhandle, attrlist, num);
404		}
405
406		if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
407			int num = numattr;
408
409			keyclass = KMF_ASYM_PUB;
410			kmf_set_attr_at_index(attrlist, num,
411			    KMF_KEYCLASS_ATTR, &keyclass,
412			    sizeof (keyclass));
413			num++;
414
415			/* list asymmetric public keys (if any) */
416			rv = pk_list_keys(kmfhandle, attrlist, num);
417		}
418
419		if (rv != KMF_OK)
420			return (rv);
421	}
422
423	numattr = 0;
424	if (oclass & (PK_CERT_OBJ | PK_PUBLIC_OBJ)) {
425		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
426		    &kstype, sizeof (kstype));
427		numattr++;
428
429		if (objlabel != NULL) {
430			kmf_set_attr_at_index(attrlist, numattr,
431			    KMF_CERT_LABEL_ATTR, objlabel,
432			    strlen(objlabel));
433			numattr++;
434		}
435
436		if (issuer != NULL) {
437			kmf_set_attr_at_index(attrlist, numattr,
438			    KMF_ISSUER_NAME_ATTR, issuer,
439			    strlen(issuer));
440			numattr++;
441		}
442
443		if (subject != NULL) {
444			kmf_set_attr_at_index(attrlist, numattr,
445			    KMF_SUBJECT_NAME_ATTR, subject,
446			    strlen(subject));
447			numattr++;
448		}
449
450		if (serial != NULL) {
451			kmf_set_attr_at_index(attrlist, numattr,
452			    KMF_BIGINT_ATTR, serial,
453			    sizeof (KMF_BIGINT));
454			numattr++;
455		}
456
457		kmf_set_attr_at_index(attrlist, numattr,
458		    KMF_PRIVATE_BOOL_ATTR, &private,
459		    sizeof (private));
460		numattr++;
461
462		kmf_set_attr_at_index(attrlist, numattr,
463		    KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
464		    sizeof (KMF_CERT_VALIDITY));
465		numattr++;
466
467		rv = pk_find_certs(kmfhandle, attrlist, numattr);
468		if (rv != KMF_OK)
469			return (rv);
470	}
471
472	numattr = 0;
473	kstype = KMF_KEYSTORE_OPENSSL; /* CRL is file-based */
474	if (oclass & PK_CRL_OBJ) {
475		char *crldata = NULL;
476
477		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
478		    &kstype, sizeof (kstype));
479		numattr++;
480
481		if (dir != NULL) {
482			kmf_set_attr_at_index(attrlist, numattr,
483			    KMF_DIRPATH_ATTR, dir, strlen(dir));
484			numattr++;
485		}
486		if (filename != NULL) {
487			kmf_set_attr_at_index(attrlist, numattr,
488			    KMF_CRL_FILENAME_ATTR,
489			    filename, strlen(filename));
490			numattr++;
491		}
492		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_DATA_ATTR,
493		    &crldata, sizeof (char *));
494		numattr++;
495
496		rv = kmf_list_crl(kmfhandle, numattr, attrlist);
497		if (rv == KMF_OK && crldata != NULL) {
498			(void) printf("%s\n", crldata);
499			free(crldata);
500		}
501	}
502
503	return (rv);
504}
505
506static int
507list_file_objects(KMF_HANDLE_T kmfhandle, int oclass,
508	char *dir, char *filename, KMF_BIGINT *serial,
509	char *issuer, char *subject,
510	KMF_CERT_VALIDITY find_criteria_flag)
511{
512	int rv;
513	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_OPENSSL;
514	int numattr = 0;
515	KMF_ATTRIBUTE attrlist[16];
516	KMF_KEY_CLASS keyclass;
517	KMF_ENCODE_FORMAT format;
518	char *defaultdir = ".";
519
520	if (oclass & PK_KEY_OBJ) {
521		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
522		    &kstype, sizeof (kstype));
523		numattr++;
524
525		if (dir == NULL && filename == NULL)
526			dir = defaultdir;
527
528		if (dir != NULL) {
529			kmf_set_attr_at_index(attrlist, numattr,
530			    KMF_DIRPATH_ATTR, dir,
531			    strlen(dir));
532			numattr++;
533		}
534
535		if (filename != NULL) {
536			kmf_set_attr_at_index(attrlist, numattr,
537			    KMF_KEY_FILENAME_ATTR, filename,
538			    strlen(filename));
539			numattr++;
540		}
541
542		if (oclass & PK_PRIKEY_OBJ) {
543			int num = numattr;
544
545			keyclass = KMF_ASYM_PRI;
546			kmf_set_attr_at_index(attrlist, num,
547			    KMF_KEYCLASS_ATTR, &keyclass,
548			    sizeof (keyclass));
549			num++;
550
551			/* list asymmetric private keys */
552			rv = pk_list_keys(kmfhandle, attrlist, num);
553		}
554		if (rv == KMF_ERR_KEY_NOT_FOUND)
555			rv = KMF_OK;
556
557		if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
558			int num = numattr;
559
560			keyclass = KMF_SYMMETRIC;
561			kmf_set_attr_at_index(attrlist, num,
562			    KMF_KEYCLASS_ATTR, &keyclass,
563			    sizeof (keyclass));
564			num++;
565
566			format = KMF_FORMAT_RAWKEY;
567			kmf_set_attr_at_index(attrlist, num,
568			    KMF_ENCODE_FORMAT_ATTR, &format,
569			    sizeof (format));
570			num++;
571
572			/* list symmetric keys */
573			rv = pk_list_keys(kmfhandle, attrlist, num);
574		}
575		if (rv == KMF_ERR_KEY_NOT_FOUND)
576			rv = KMF_OK;
577		if (rv != KMF_OK)
578			return (rv);
579	}
580
581	numattr = 0;
582	if (oclass & PK_CERT_OBJ) {
583		kmf_set_attr_at_index(attrlist, numattr,
584		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
585		    sizeof (kstype));
586		numattr++;
587
588		if (issuer != NULL) {
589			kmf_set_attr_at_index(attrlist, numattr,
590			    KMF_ISSUER_NAME_ATTR, issuer,
591			    strlen(issuer));
592			numattr++;
593		}
594
595		if (subject != NULL) {
596			kmf_set_attr_at_index(attrlist, numattr,
597			    KMF_SUBJECT_NAME_ATTR, subject,
598			    strlen(subject));
599			numattr++;
600		}
601
602		if (serial != NULL) {
603			kmf_set_attr_at_index(attrlist, numattr,
604			    KMF_BIGINT_ATTR, serial,
605			    sizeof (KMF_BIGINT));
606			numattr++;
607		}
608
609		if (filename != NULL) {
610			kmf_set_attr_at_index(attrlist, numattr,
611			    KMF_CERT_FILENAME_ATTR, filename,
612			    strlen(filename));
613			numattr++;
614		}
615
616		if (dir != NULL) {
617			kmf_set_attr_at_index(attrlist, numattr,
618			    KMF_DIRPATH_ATTR, dir,
619			    strlen(dir));
620			numattr++;
621		}
622
623		kmf_set_attr_at_index(attrlist, numattr,
624		    KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
625		    sizeof (KMF_CERT_VALIDITY));
626		numattr++;
627
628		rv = pk_find_certs(kmfhandle, attrlist, numattr);
629		if (rv != KMF_OK)
630			return (rv);
631	}
632
633	numattr = 0;
634	if (oclass & PK_CRL_OBJ) {
635		char *crldata = NULL;
636
637		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
638		    &kstype, sizeof (kstype));
639		numattr++;
640
641		if (dir != NULL) {
642			kmf_set_attr_at_index(attrlist, numattr,
643			    KMF_DIRPATH_ATTR, dir, strlen(dir));
644			numattr++;
645		}
646		if (filename != NULL) {
647			kmf_set_attr_at_index(attrlist, numattr,
648			    KMF_CRL_FILENAME_ATTR,
649			    filename, strlen(filename));
650			numattr++;
651		}
652		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_DATA_ATTR,
653		    &crldata, sizeof (char *));
654		numattr++;
655
656		rv = kmf_list_crl(kmfhandle, numattr, attrlist);
657		if (rv == KMF_OK && crldata != NULL) {
658			(void) printf("%s\n", crldata);
659			free(crldata);
660		}
661	}
662
663	return (rv);
664}
665
666static int
667list_nss_objects(KMF_HANDLE_T kmfhandle,
668	int oclass, char *token_spec, char *dir, char *prefix,
669	char *nickname, KMF_BIGINT *serial, char *issuer, char *subject,
670	KMF_CREDENTIAL *tokencred,
671	KMF_CERT_VALIDITY find_criteria_flag)
672{
673	KMF_RETURN rv = KMF_OK;
674	KMF_KEYSTORE_TYPE kstype = KMF_KEYSTORE_NSS;
675	int numattr = 0;
676	KMF_ATTRIBUTE attrlist[16];
677	KMF_KEY_CLASS keyclass;
678	KMF_ENCODE_FORMAT format;
679
680	rv = configure_nss(kmfhandle, dir, prefix);
681	if (rv != KMF_OK)
682		return (rv);
683
684	kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
685	    &kstype, sizeof (kstype));
686	numattr++;
687
688	if (oclass & PK_KEY_OBJ) {
689		if (tokencred != NULL && tokencred->credlen > 0) {
690			kmf_set_attr_at_index(attrlist, numattr,
691			    KMF_CREDENTIAL_ATTR, tokencred,
692			    sizeof (KMF_CREDENTIAL));
693			numattr++;
694		}
695
696		if (token_spec && strlen(token_spec)) {
697			kmf_set_attr_at_index(attrlist, numattr,
698			    KMF_TOKEN_LABEL_ATTR, token_spec,
699			    strlen(token_spec));
700			numattr++;
701		}
702
703		if (nickname != NULL) {
704			kmf_set_attr_at_index(attrlist, numattr,
705			    KMF_KEYLABEL_ATTR, nickname,
706			    strlen(nickname));
707			numattr++;
708		}
709	}
710
711	if (oclass & PK_PRIKEY_OBJ) {
712		int num = numattr;
713
714		keyclass = KMF_ASYM_PRI;
715		kmf_set_attr_at_index(attrlist, num,
716		    KMF_KEYCLASS_ATTR, &keyclass,
717		    sizeof (keyclass));
718		num++;
719
720		/* list asymmetric private keys */
721		rv = pk_list_keys(kmfhandle, attrlist, num);
722	}
723
724	if (rv == KMF_OK && (oclass & PK_SYMKEY_OBJ)) {
725		int num = numattr;
726
727		keyclass = KMF_SYMMETRIC;
728		kmf_set_attr_at_index(attrlist, num,
729		    KMF_KEYCLASS_ATTR, &keyclass,
730		    sizeof (keyclass));
731		num++;
732
733		format = KMF_FORMAT_RAWKEY;
734		kmf_set_attr_at_index(attrlist, num,
735		    KMF_ENCODE_FORMAT_ATTR, &format,
736		    sizeof (format));
737		num++;
738
739		/* list symmetric keys */
740		rv = pk_list_keys(kmfhandle, attrlist, num);
741	}
742
743	if (rv == KMF_OK && (oclass & PK_PUBKEY_OBJ)) {
744		int num = numattr;
745
746		keyclass = KMF_ASYM_PUB;
747		kmf_set_attr_at_index(attrlist, num,
748		    KMF_KEYCLASS_ATTR, &keyclass,
749		    sizeof (keyclass));
750		num++;
751
752		/* list asymmetric public keys */
753		rv = pk_list_keys(kmfhandle, attrlist, num);
754	}
755
756	/* If searching for public objects or certificates, find certs now */
757	numattr = 0;
758	if (rv == KMF_OK && (oclass & PK_CERT_OBJ)) {
759		kmf_set_attr_at_index(attrlist, numattr,
760		    KMF_KEYSTORE_TYPE_ATTR, &kstype,
761		    sizeof (kstype));
762		numattr++;
763
764		if (nickname != NULL) {
765			kmf_set_attr_at_index(attrlist, numattr,
766			    KMF_CERT_LABEL_ATTR, nickname,
767			    strlen(nickname));
768			numattr++;
769		}
770
771		if (issuer != NULL) {
772			kmf_set_attr_at_index(attrlist, numattr,
773			    KMF_ISSUER_NAME_ATTR, issuer,
774			    strlen(issuer));
775			numattr++;
776		}
777
778		if (subject != NULL) {
779			kmf_set_attr_at_index(attrlist, numattr,
780			    KMF_SUBJECT_NAME_ATTR, subject,
781			    strlen(subject));
782			numattr++;
783		}
784
785		if (serial != NULL) {
786			kmf_set_attr_at_index(attrlist, numattr,
787			    KMF_BIGINT_ATTR, serial,
788			    sizeof (KMF_BIGINT));
789			numattr++;
790		}
791
792		if (token_spec != NULL) {
793			kmf_set_attr_at_index(attrlist, numattr,
794			    KMF_TOKEN_LABEL_ATTR, token_spec,
795			    strlen(token_spec));
796			numattr++;
797		}
798
799		kmf_set_attr_at_index(attrlist, numattr,
800		    KMF_CERT_VALIDITY_ATTR, &find_criteria_flag,
801		    sizeof (KMF_CERT_VALIDITY));
802		numattr++;
803
804		rv = pk_find_certs(kmfhandle, attrlist, numattr);
805	}
806
807	numattr = 0;
808	if (rv == KMF_OK && (oclass & PK_CRL_OBJ)) {
809		int numcrls;
810
811		kmf_set_attr_at_index(attrlist, numattr, KMF_KEYSTORE_TYPE_ATTR,
812		    &kstype, sizeof (kstype));
813		numattr++;
814
815		if (token_spec != NULL) {
816			kmf_set_attr_at_index(attrlist, numattr,
817			    KMF_TOKEN_LABEL_ATTR,
818			    token_spec, strlen(token_spec));
819			numattr++;
820		}
821		kmf_set_attr_at_index(attrlist, numattr, KMF_CRL_COUNT_ATTR,
822		    &numcrls, sizeof (int));
823		numattr++;
824
825		rv = kmf_find_crl(kmfhandle, numattr, attrlist);
826		if (rv == KMF_OK) {
827			char **p;
828			if (numcrls == 0) {
829				(void) printf(gettext("No CRLs found in "
830				    "NSS keystore.\n"));
831
832				return (KMF_OK);
833			}
834			p = malloc(numcrls * sizeof (char *));
835			if (p == NULL) {
836				return (KMF_ERR_MEMORY);
837			}
838			(void) memset(p, 0, numcrls * sizeof (char *));
839
840			kmf_set_attr_at_index(attrlist, numattr,
841			    KMF_CRL_NAMELIST_ATTR, p, sizeof (char *));
842			numattr++;
843			rv = kmf_find_crl(kmfhandle, numattr, attrlist);
844			if (rv == KMF_OK) {
845				int i;
846				for (i = 0; i < numcrls; i++) {
847					(void) printf("%d. Name = %s\n",
848					    i + 1, p[i]);
849					free(p[i]);
850				}
851			}
852			free(p);
853		}
854	}
855	return (rv);
856}
857
858/*
859 * List token object.
860 */
861int
862pk_list(int argc, char *argv[])
863{
864	int			opt;
865	extern int		optind_av;
866	extern char		*optarg_av;
867	char			*token_spec = NULL;
868	char			*subject = NULL;
869	char			*issuer = NULL;
870	char			*dir = NULL;
871	char			*prefix = NULL;
872	char			*filename = NULL;
873	char			*serstr = NULL;
874	KMF_BIGINT		serial = { NULL, 0 };
875
876	char			*list_label = NULL;
877	int			oclass = 0;
878	KMF_KEYSTORE_TYPE	kstype = 0;
879	KMF_RETURN		rv = KMF_OK;
880	KMF_HANDLE_T		kmfhandle = NULL;
881	char			*find_criteria = NULL;
882	KMF_CERT_VALIDITY	find_criteria_flag = KMF_ALL_CERTS;
883	KMF_CREDENTIAL		tokencred = {NULL, 0};
884
885	/* Parse command line options.  Do NOT i18n/l10n. */
886	while ((opt = getopt_av(argc, argv,
887	    "k:(keystore)t:(objtype)T:(token)d:(dir)"
888	    "p:(prefix)n:(nickname)S:(serial)s:(subject)"
889	    "c:(criteria)"
890	    "i:(issuer)l:(label)f:(infile)")) != EOF) {
891		if (EMPTYSTRING(optarg_av))
892			return (PK_ERR_USAGE);
893		switch (opt) {
894			case 'k':
895				if (kstype != 0)
896					return (PK_ERR_USAGE);
897				kstype = KS2Int(optarg_av);
898				if (kstype == 0)
899					return (PK_ERR_USAGE);
900				break;
901			case 't':
902				if (oclass != 0)
903					return (PK_ERR_USAGE);
904				oclass = OT2Int(optarg_av);
905				if (oclass == -1)
906					return (PK_ERR_USAGE);
907				break;
908			case 's':
909				if (subject)
910					return (PK_ERR_USAGE);
911				subject = optarg_av;
912				break;
913			case 'i':
914				if (issuer)
915					return (PK_ERR_USAGE);
916				issuer = optarg_av;
917				break;
918			case 'd':
919				if (dir)
920					return (PK_ERR_USAGE);
921				dir = optarg_av;
922				break;
923			case 'p':
924				if (prefix)
925					return (PK_ERR_USAGE);
926				prefix = optarg_av;
927				break;
928			case 'S':
929				serstr = optarg_av;
930				break;
931			case 'f':
932				if (filename)
933					return (PK_ERR_USAGE);
934				filename = optarg_av;
935				break;
936			case 'T':	/* token specifier */
937				if (token_spec)
938					return (PK_ERR_USAGE);
939				token_spec = optarg_av;
940				break;
941			case 'n':
942			case 'l':	/* object with specific label */
943				if (list_label)
944					return (PK_ERR_USAGE);
945				list_label = optarg_av;
946				break;
947			case 'c':
948				find_criteria = optarg_av;
949				if (!strcasecmp(find_criteria, "valid"))
950					find_criteria_flag =
951					    KMF_NONEXPIRED_CERTS;
952				else if (!strcasecmp(find_criteria, "expired"))
953					find_criteria_flag = KMF_EXPIRED_CERTS;
954				else if (!strcasecmp(find_criteria, "both"))
955					find_criteria_flag = KMF_ALL_CERTS;
956				else
957					return (PK_ERR_USAGE);
958				break;
959			default:
960				return (PK_ERR_USAGE);
961		}
962	}
963	/* No additional args allowed. */
964	argc -= optind_av;
965	argv += optind_av;
966	if (argc)
967		return (PK_ERR_USAGE);
968
969	if ((rv = kmf_initialize(&kmfhandle, NULL, NULL)) != KMF_OK) {
970		/* Error message ? */
971		return (rv);
972	}
973
974	/* Assume keystore = PKCS#11 if not specified. */
975	if (kstype == 0)
976		kstype = KMF_KEYSTORE_PK11TOKEN;
977
978	/* if PUBLIC or PRIVATE obj was given, the old syntax was used. */
979	if ((oclass & (PK_PUBLIC_OBJ | PK_PRIVATE_OBJ)) &&
980	    kstype != KMF_KEYSTORE_PK11TOKEN) {
981
982		(void) fprintf(stderr, gettext("The objtype parameter "
983		    "is only relevant if keystore=pkcs11\n"));
984		return (PK_ERR_USAGE);
985	}
986
987	/* If no object class specified, list certificate objects. */
988	if (oclass == 0)
989		oclass = PK_CERT_OBJ;
990
991	if (kstype == KMF_KEYSTORE_PK11TOKEN && EMPTYSTRING(token_spec)) {
992		token_spec = PK_DEFAULT_PK11TOKEN;
993	} else if (kstype == KMF_KEYSTORE_NSS && EMPTYSTRING(token_spec)) {
994		token_spec = DEFAULT_NSS_TOKEN;
995	}
996
997	if (serstr != NULL) {
998		uchar_t *bytes = NULL;
999		size_t bytelen;
1000
1001		rv = kmf_hexstr_to_bytes((uchar_t *)serstr, &bytes, &bytelen);
1002		if (rv != KMF_OK || bytes == NULL) {
1003			(void) fprintf(stderr, gettext("serial number "
1004			    "must be specified as a hex number "
1005			    "(ex: 0x0102030405ffeeddee)\n"));
1006			return (PK_ERR_USAGE);
1007		}
1008		serial.val = bytes;
1009		serial.len = bytelen;
1010	}
1011
1012	if ((kstype == KMF_KEYSTORE_PK11TOKEN ||
1013	    kstype == KMF_KEYSTORE_NSS) &&
1014	    (oclass & (PK_PRIKEY_OBJ | PK_PRIVATE_OBJ))) {
1015
1016		(void) get_token_password(kstype, token_spec,
1017		    &tokencred);
1018	}
1019	if (kstype == KMF_KEYSTORE_PK11TOKEN) {
1020		rv = list_pk11_objects(kmfhandle, token_spec,
1021		    oclass, list_label, &serial,
1022		    issuer, subject, dir, filename,
1023		    &tokencred, find_criteria_flag);
1024
1025	} else if (kstype == KMF_KEYSTORE_NSS) {
1026		if (dir == NULL)
1027			dir = PK_DEFAULT_DIRECTORY;
1028		rv = list_nss_objects(kmfhandle,
1029		    oclass, token_spec, dir, prefix,
1030		    list_label, &serial, issuer, subject,
1031		    &tokencred, find_criteria_flag);
1032
1033	} else if (kstype == KMF_KEYSTORE_OPENSSL) {
1034
1035		rv = list_file_objects(kmfhandle,
1036		    oclass, dir, filename,
1037		    &serial, issuer, subject, find_criteria_flag);
1038	}
1039
1040	if (rv != KMF_OK) {
1041		display_error(kmfhandle, rv,
1042		    gettext("Error listing objects"));
1043	}
1044
1045	if (serial.val != NULL)
1046		free(serial.val);
1047
1048	if (tokencred.cred != NULL)
1049		free(tokencred.cred);
1050
1051	(void) kmf_finalize(kmfhandle);
1052	return (rv);
1053}
1054