xref: /onnv-gate/usr/src/cmd/cmd-crypto/pktool/pktool.c (revision 10241:356a64b58ebc)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
53089Swyllys  * Common Development and Distribution License (the "License").
63089Swyllys  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
229126SWyllys.Ingersoll@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*
270Sstevel@tonic-gate  * This file comprises the main driver for this tool.
2817Sdinak  * Upon parsing the command verbs from user input, it
2917Sdinak  * branches to the appropriate modules to perform the
3017Sdinak  * requested task.
310Sstevel@tonic-gate  */
320Sstevel@tonic-gate 
330Sstevel@tonic-gate #include <stdio.h>
340Sstevel@tonic-gate #include <string.h>
350Sstevel@tonic-gate #include <ctype.h>
360Sstevel@tonic-gate #include <malloc.h>
376051Swyllys #include <libintl.h>
380Sstevel@tonic-gate #include <libgen.h>
390Sstevel@tonic-gate #include <errno.h>
400Sstevel@tonic-gate #include <cryptoutil.h>
410Sstevel@tonic-gate #include <security/cryptoki.h>
420Sstevel@tonic-gate #include "common.h"
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate  * The verbcmd construct allows genericizing information about a verb so
460Sstevel@tonic-gate  * that it is easier to manipulate.  Makes parsing code easier to read,
470Sstevel@tonic-gate  * fix, and extend with new verbs.
480Sstevel@tonic-gate  */
490Sstevel@tonic-gate typedef struct verbcmd_s {
500Sstevel@tonic-gate 	char	*verb;
510Sstevel@tonic-gate 	int	(*action)(int, char *[]);
5217Sdinak 	int	mode;
533501Swyllys 	char	*summary;
5417Sdinak 	char	*synopsis;
550Sstevel@tonic-gate } verbcmd;
560Sstevel@tonic-gate 
570Sstevel@tonic-gate /* External declarations for supported verb actions. */
580Sstevel@tonic-gate extern int	pk_setpin(int argc, char *argv[]);
5917Sdinak extern int	pk_list(int argc, char *argv[]);
6017Sdinak extern int	pk_delete(int argc, char *argv[]);
6117Sdinak extern int	pk_import(int argc, char *argv[]);
6217Sdinak extern int	pk_export(int argc, char *argv[]);
6317Sdinak extern int	pk_tokens(int argc, char *argv[]);
643089Swyllys extern int	pk_gencert(int argc, char *argv[]);
653089Swyllys extern int	pk_gencsr(int argc, char *argv[]);
663089Swyllys extern int	pk_download(int argc, char *argv[]);
673089Swyllys extern int	pk_genkey(int argc, char *argv[]);
686051Swyllys extern int	pk_signcsr(int argc, char *argv[]);
699126SWyllys.Ingersoll@Sun.COM extern int	pk_inittoken(int argc, char *argv[]);
7017Sdinak 
7117Sdinak /* Forward declarations for "built-in" verb actions. */
7217Sdinak static int	pk_help(int argc, char *argv[]);
730Sstevel@tonic-gate 
746051Swyllys #define	TOKEN_IDX 0
756354Swyllys #define	TOKEN_VERB "tokens"
766051Swyllys #define	TOKEN_SUMM gettext("lists all visible PKCS#11 tokens")
776354Swyllys #define	TOKEN_SYN  "tokens"
786051Swyllys 
796051Swyllys #define	SETPIN_IDX 1
806354Swyllys #define	SETPIN_VERB "setpin"
816051Swyllys #define	SETPIN_SUMM gettext("changes user authentication passphrase "\
826051Swyllys 	"for keystore access")
836354Swyllys #define	SETPIN_SYN \
846051Swyllys 	"setpin [ keystore=pkcs11 ]\n\t\t" \
859126SWyllys.Ingersoll@Sun.COM 	"[ token=token[:manuf[:serial]]]\n\t\t" \
869126SWyllys.Ingersoll@Sun.COM 	"[ usertype=so|user ]\n\t" \
879126SWyllys.Ingersoll@Sun.COM \
886051Swyllys 	"setpin keystore=nss\n\t\t" \
896051Swyllys 	"[ token=token ]\n\t\t" \
906051Swyllys 	"[ dir=directory-path ]\n\t\t" \
916354Swyllys 	"[ prefix=DBprefix ]\n\t"
926051Swyllys 
936051Swyllys #define	LIST_IDX 2
946354Swyllys #define	LIST_VERB "list"
956051Swyllys #define	LIST_SUMM gettext("lists a summary of objects in the keystore")
966354Swyllys #define	LIST_SYN \
976051Swyllys 	"list [ token=token[:manuf[:serial]]]\n\t\t" \
986051Swyllys 	"[ objtype=private|public|both ]\n\t\t" \
996051Swyllys 	"[ label=label ]\n\t" \
1006051Swyllys  \
1016051Swyllys 	"list objtype=cert[:[public | private | both ]]\n\t\t" \
1026051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
1036051Swyllys 	"[ keystore=pkcs11 ]\n\t\t" \
1046051Swyllys 	"[ issuer=issuer-DN ]\n\t\t" \
1056051Swyllys 	"[ serial=serial number ]\n\t\t" \
1066051Swyllys 	"[ label=cert-label ]\n\t\t" \
1076051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
1086051Swyllys 	"[ criteria=valid|expired|both ]\n\t" \
1096051Swyllys  \
1106051Swyllys 	"list objtype=key[:[public | private | both ]]\n\t\t" \
1116051Swyllys 	"[ keystore=pkcs11 ]\n\t\t" \
1126051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
1136051Swyllys 	"[ label=key-label ]\n\t\t" \
1146051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t" \
1156051Swyllys  \
1166051Swyllys 	"list keystore=pkcs11 objtype=crl\n\t\t" \
1176669Swyllys 	"infile=crl-fn\n\t" \
1186051Swyllys  \
1196051Swyllys 	"list keystore=nss objtype=cert\n\t\t" \
1206051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
1216051Swyllys 	"[ issuer=issuer-DN ]\n\t\t" \
1226051Swyllys 	"[ serial=serial number ]\n\t\t" \
1236051Swyllys 	"[ nickname=cert-nickname ]\n\t\t" \
1246051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
1256051Swyllys 	"[ dir=directory-path ]\n\t\t" \
1266051Swyllys 	"[ prefix=DBprefix ]\n\t\t" \
1276051Swyllys 	"[ criteria=valid|expired|both ]\n\t" \
1286051Swyllys  \
1296051Swyllys 	"list keystore=nss objtype=key\n\t\t" \
1306051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
1316051Swyllys 	"[ dir=directory-path ]\n\t\t" \
1326051Swyllys 	"[ prefix=DBprefix ]\n\t\t" \
1336051Swyllys 	"[ nickname=key-nickname ]\n\t" \
1346051Swyllys  \
1356051Swyllys 	"list keystore=file objtype=cert\n\t\t" \
1366051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
1376051Swyllys 	"[ issuer=issuer-DN ]\n\t\t" \
1386051Swyllys 	"[ serial=serial number ]\n\t\t" \
1396051Swyllys 	"[ infile=cert-fn ]\n\t\t" \
1406051Swyllys 	"[ dir=directory-path ]\n\t\t" \
1416051Swyllys 	"[ criteria=valid|expired|both ]\n\t" \
1426051Swyllys  \
1436051Swyllys 	"list keystore=file objtype=key\n\t\t" \
1446051Swyllys 	"[ infile=key-fn ]\n\t\t" \
1456051Swyllys 	"[ dir=directory-path ]\n\t" \
1466051Swyllys  \
1476051Swyllys 	"list keystore=file objtype=crl\n\t\t" \
1486669Swyllys 	"infile=crl-fn\n\t"
1496051Swyllys 
1506051Swyllys #define	DELETE_IDX 3
1516354Swyllys #define	DELETE_VERB "delete"
1526051Swyllys #define	DELETE_SUMM gettext("deletes objects in the keystore")
1536354Swyllys #define	DELETE_SYN \
1546051Swyllys 	"delete [ token=token[:manuf[:serial]]]\n\t\t" \
1556051Swyllys 	"[ objtype=private|public|both ]\n\t\t" \
1566051Swyllys 	"[ label=object-label ]\n\t" \
1576051Swyllys  \
1586051Swyllys 	"delete keystore=nss objtype=cert\n\t\t" \
1596051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
1606051Swyllys 	"[ issuer=issuer-DN ]\n\t\t" \
1616051Swyllys 	"[ serial=serial number ]\n\t\t" \
1626051Swyllys 	"[ label=cert-label ]\n\t\t" \
1636051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
1646051Swyllys 	"[ dir=directory-path ]\n\t\t" \
1656051Swyllys 	"[ prefix=DBprefix ]\n\t\t" \
1666051Swyllys 	"[ criteria=valid|expired|both ]\n\t" \
1676051Swyllys  \
1686051Swyllys 	"delete keystore=nss objtype=key\n\t\t" \
1696051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
1706051Swyllys 	"[ dir=directory-path ]\n\t\t" \
1716051Swyllys 	"[ prefix=DBprefix ]\n\t\t" \
1726051Swyllys 	"[ nickname=key-nickname ]\n\t\t" \
1736051Swyllys  \
1746051Swyllys 	"delete keystore=nss objtype=crl\n\t\t" \
1756051Swyllys 	"[ nickname=issuer-nickname ]\n\t\t" \
1766051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
1776051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
1786051Swyllys 	"[ dir=directory-path ]\n\t\t" \
1796051Swyllys 	"[ prefix=DBprefix ]\n\t" \
1806051Swyllys  \
1816051Swyllys 	"delete keystore=pkcs11 " \
1826051Swyllys 	"objtype=cert[:[public | private | both]]\n\t\t" \
1836051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
1846051Swyllys 	"[ issuer=issuer-DN ]\n\t\t" \
1856051Swyllys 	"[ serial=serial number ]\n\t\t" \
1866051Swyllys 	"[ label=cert-label ]\n\t\t" \
1876051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
1886051Swyllys 	"[ criteria=valid|expired|both ]\n\t" \
1896051Swyllys  \
1906051Swyllys 	"delete keystore=pkcs11 " \
1916051Swyllys 	"objtype=key[:[public | private | both]]\n\t\t" \
1926051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
1936051Swyllys 	"[ label=key-label ]\n\t\t" \
1946051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t" \
1956051Swyllys  \
1966051Swyllys 	"delete keystore=pkcs11 objtype=crl\n\t\t" \
1976669Swyllys 	"infile=crl-fn\n\t" \
1986051Swyllys  \
1996051Swyllys 	"delete keystore=file objtype=cert\n\t\t" \
2006051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
2016051Swyllys 	"[ issuer=issuer-DN ]\n\t\t" \
2026051Swyllys 	"[ serial=serial number ]\n\t\t" \
2036051Swyllys 	"[ infile=cert-fn ]\n\t\t" \
2046051Swyllys 	"[ dir=directory-path ]\n\t\t" \
2056051Swyllys 	"[ criteria=valid|expired|both ]\n\t" \
2066051Swyllys  \
2076051Swyllys 	"delete keystore=file objtype=key\n\t\t" \
2086051Swyllys 	"[ infile=key-fn ]\n\t\t" \
2096051Swyllys 	"[ dir=directory-path ]\n\t" \
2106051Swyllys  \
2116051Swyllys 	"delete keystore=file objtype=crl\n\t\t" \
2126669Swyllys 	"infile=crl-fn\n\t"
2136051Swyllys 
2146051Swyllys #define	IMPORT_IDX 4
2156354Swyllys #define	IMPORT_VERB "import"
2166051Swyllys #define	IMPORT_SUMM gettext("imports objects from an external source")
2176354Swyllys #define	IMPORT_SYN \
2186051Swyllys 	"import [token=token[:manuf[:serial]]]\n\t\t" \
2196051Swyllys 	"infile=input-fn\n\t" \
2206051Swyllys  \
2216051Swyllys 	"import keystore=nss objtype=cert\n\t\t" \
2226051Swyllys 	"infile=input-fn\n\t\t" \
2236051Swyllys 	"label=cert-label\n\t\t" \
2246051Swyllys 	"[ trust=trust-value ]\n\t\t" \
2256051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
2266051Swyllys 	"[ dir=directory-path ]\n\t\t" \
2276051Swyllys 	"[ prefix=DBprefix ]\n\t" \
2286051Swyllys  \
2296051Swyllys 	"import keystore=nss objtype=crl\n\t\t" \
2306051Swyllys 	"infile=input-fn\n\t\t" \
2316051Swyllys 	"[ verifycrl=y|n ]\n\t\t" \
2326051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
2336051Swyllys 	"[ dir=directory-path ]\n\t\t" \
2346051Swyllys 	"[ prefix=DBprefix ]\n\t" \
2356051Swyllys  \
2366051Swyllys 	"import keystore=pkcs11\n\t\t" \
2376051Swyllys 	"infile=input-fn\n\t\t" \
2386051Swyllys 	"label=label\n\t\t" \
2396051Swyllys 	"[ objtype=cert|key ]\n\t\t" \
2406051Swyllys 	"[ keytype=aes|arcfour|des|3des|generic ]\n\t\t" \
2416051Swyllys 	"[ sensitive=y|n ]\n\t\t" \
2426051Swyllys 	"[ extractable=y|n ]\n\t\t" \
2436051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t" \
2446051Swyllys  \
2456051Swyllys 	"import keystore=pkcs11 objtype=crl\n\t\t" \
2466051Swyllys 	"infile=input-crl-fn\n\t\t" \
2476051Swyllys 	"outcrl=output-crl-fn\n\t\t" \
2486669Swyllys 	"outformat=pem|der\n\t" \
2496051Swyllys  \
2506051Swyllys 	"import keystore=file\n\t\t" \
2516051Swyllys 	"infile=input-fn\n\t\t" \
2526051Swyllys 	"outkey=output-key-fn\n\t\t" \
2536051Swyllys 	"outcert=output-cert-fn\n\t\t" \
2546051Swyllys 	"[ outformat=pem|der|pkcs12 ]\n\t" \
2556051Swyllys  \
2566051Swyllys 	"import keystore=file objtype=crl\n\t\t" \
2576051Swyllys 	"infile=input-crl-fn\n\t\t" \
2586051Swyllys 	"outcrl=output-crl-fn\n\t\t" \
2596669Swyllys 	"outformat=pem|der\n\t"
2606051Swyllys 
2616051Swyllys #define	EXPORT_IDX 5
2626354Swyllys #define	EXPORT_VERB "export"
2636051Swyllys #define	EXPORT_SUMM gettext("exports objects from the keystore to a file")
2646354Swyllys #define	EXPORT_SYN \
2656051Swyllys 	"export [token=token[:manuf[:serial]]]\n\t\t" \
2666051Swyllys 	"outfile=output-fn\n\t" \
2676051Swyllys  \
2686051Swyllys 	"export keystore=nss\n\t\t" \
2696051Swyllys 	"outfile=output-fn\n\t\t" \
2706051Swyllys 	"[ objtype=cert|key ]\n\t\t" \
2716051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
2726051Swyllys 	"[ issuer=issuer-DN ]\n\t\t" \
2736051Swyllys 	"[ serial=serial number ]\n\t\t" \
2746051Swyllys 	"[ nickname=cert-nickname ]\n\t\t" \
2756051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
2766051Swyllys 	"[ dir=directory-path ]\n\t\t" \
2776051Swyllys 	"[ prefix=DBPrefix ]\n\t\t" \
2786051Swyllys 	"[ outformat=pem|der|pkcs12 ]\n\t" \
2796051Swyllys  \
2806051Swyllys 	"export keystore=pkcs11\n\t\t" \
2816051Swyllys 	"outfile=output-fn\n\t\t" \
2826051Swyllys 	"[ objtype=cert|key ]\n\t\t" \
2836051Swyllys 	"[ label=label ]\n\t\t" \
2846051Swyllys 	"[ subject=subject-DN ]\n\t\t" \
2856051Swyllys 	"[ issuer=issuer-DN ]\n\t\t" \
2866051Swyllys 	"[ serial=serial number ]\n\t\t" \
2876051Swyllys 	"[ outformat=pem|der|pkcs12|raw ]\n\t\t" \
2886051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t" \
2896051Swyllys  \
2906051Swyllys 	"export keystore=file\n\t\t" \
2916051Swyllys 	"certfile=cert-input-fn\n\t\t" \
2926051Swyllys 	"keyfile=key-input-fn\n\t\t" \
2936669Swyllys 	"outfile=output-pkcs12-fn\n\t"
2946051Swyllys 
2956051Swyllys #define	GENCERT_IDX 6
2966354Swyllys #define	GENCERT_VERB "gencert"
2976051Swyllys #define	GENCERT_SUMM gettext("creates a self-signed X.509v3 certificate")
2986354Swyllys #define	GENCERT_SYN \
299*10241Swyllys.ingersoll@sun.com 	"gencert keystore=nss\n\t\t" \
3006051Swyllys 	"label=cert-nickname\n\t\t" \
3016051Swyllys 	"serial=serial number hex string]\n\t\t" \
302*10241Swyllys.ingersoll@sun.com 	"[ -i ] | [subject=subject-DN]\n\t\t" \
3036051Swyllys 	"[ altname=[critical:]SubjectAltName ]\n\t\t" \
3046051Swyllys 	"[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3056051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
3066051Swyllys 	"[ dir=directory-path ]\n\t\t" \
3076051Swyllys 	"[ prefix=DBprefix ]\n\t\t" \
3086051Swyllys 	"[ keytype=rsa|dsa ]\n\t\t" \
3096051Swyllys 	"[ keylen=key-size ]\n\t\t" \
3106051Swyllys 	"[ trust=trust-value ]\n\t\t" \
3116051Swyllys 	"[ eku=[critical:]EKU name,...]\n\t\t" \
3126051Swyllys 	"[ lifetime=number-hour|number-day|number-year ]\n\t" \
3136051Swyllys  \
314*10241Swyllys.ingersoll@sun.com 	"gencert [ keystore=pkcs11 ]\n\t\t" \
3156051Swyllys 	"label=key/cert-label\n\t\t" \
3166051Swyllys 	"serial=serial number hex string\n\t\t" \
317*10241Swyllys.ingersoll@sun.com 	"[ -i ] | [subject=subject-DN]\n\t\t" \
3186051Swyllys 	"[ altname=[critical:]SubjectAltName ]\n\t\t" \
3196051Swyllys 	"[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3206051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
3216051Swyllys 	"[ keytype=rsa|dsa ]\n\t\t" \
3226051Swyllys 	"[ keylen=key-size ]\n\t\t" \
3236051Swyllys 	"[ eku=[critical:]EKU name,...]\n\t\t" \
3246051Swyllys 	"[ lifetime=number-hour|number-day|number-year ]\n\t" \
3256051Swyllys  \
326*10241Swyllys.ingersoll@sun.com 	"gencert keystore=file\n\t\t" \
3276051Swyllys 	"outcert=cert_filename\n\t\t" \
3286051Swyllys 	"outkey=key_filename\n\t\t" \
3296051Swyllys 	"serial=serial number hex string\n\t\t" \
330*10241Swyllys.ingersoll@sun.com 	"[ -i ] | [subject=subject-DN]\n\t\t" \
3316051Swyllys 	"[ altname=[critical:]SubjectAltName ]\n\t\t" \
3326051Swyllys 	"[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3336051Swyllys 	"[ format=der|pem ]\n\t\t" \
3346051Swyllys 	"[ prefix=DBprefix ]\n\t\t" \
3356051Swyllys 	"[ keytype=rsa|dsa ]\n\t\t" \
3366051Swyllys 	"[ keylen=key-size ]\n\t\t" \
3376051Swyllys 	"[ eku=[critical:]EKU name,...]\n\t\t" \
3386354Swyllys 	"[ lifetime=number-hour|number-day|number-year ]\n\t"
3396051Swyllys 
3406051Swyllys #define	GENCSR_IDX 7
3416354Swyllys #define	GENCSR_VERB "gencsr"
3426051Swyllys #define	GENCSR_SUMM gettext("creates a PKCS#10 certificate signing " \
3436051Swyllys 	"request file")
3446051Swyllys 
3456354Swyllys #define	GENCSR_SYN \
346*10241Swyllys.ingersoll@sun.com 	"gencsr keystore=nss \n\t\t" \
3476051Swyllys 	"nickname=cert-nickname\n\t\t" \
3486051Swyllys 	"outcsr=csr-fn\n\t\t" \
349*10241Swyllys.ingersoll@sun.com 	"[ -i ] | [subject=subject-DN]\n\t\t" \
3506051Swyllys 	"[ altname=[critical:]SubjectAltName ]\n\t\t" \
3516051Swyllys 	"[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3526051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
3536051Swyllys 	"[ dir=directory-path ]\n\t\t" \
3546051Swyllys 	"[ prefix=DBprefix ]\n\t\t" \
3556051Swyllys 	"[ keytype=rsa|dsa ]\n\t\t" \
3566051Swyllys 	"[ keylen=key-size ]\n\t\t" \
3576051Swyllys 	"[ eku=[critical:]EKU name,...]\n\t\t" \
3586051Swyllys 	"[ format=pem|der ]\n\t" \
3596051Swyllys  \
360*10241Swyllys.ingersoll@sun.com 	"gencsr [ keystore=pkcs11 ]\n\t\t" \
3616051Swyllys 	"label=key-label\n\t\t" \
3626051Swyllys 	"outcsr=csr-fn\n\t\t" \
363*10241Swyllys.ingersoll@sun.com 	"[ -i ] | [subject=subject-DN]\n\t\t" \
3646051Swyllys 	"[ altname=[critical:]SubjectAltName ]\n\t\t" \
3656051Swyllys 	"[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3666051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
3676051Swyllys 	"[ keytype=rsa|dsa ]\n\t\t" \
3686051Swyllys 	"[ keylen=key-size ]\n\t\t" \
3696051Swyllys 	"[ eku=[critical:]EKU name,...]\n\t\t" \
3706051Swyllys 	"[ format=pem|der ]]\n\t" \
3716051Swyllys  \
372*10241Swyllys.ingersoll@sun.com 	"gencsr keystore=file\n\t\t" \
3736051Swyllys 	"outcsr=csr-fn\n\t\t" \
3746051Swyllys 	"outkey=key-fn\n\t\t" \
375*10241Swyllys.ingersoll@sun.com 	"[ -i ] | [subject=subject-DN]\n\t\t" \
3766051Swyllys 	"[ altname=[critical:]SubjectAltName ]\n\t\t" \
3776051Swyllys 	"[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3786051Swyllys 	"[ keytype=rsa|dsa ]\n\t\t" \
3796051Swyllys 	"[ keylen=key-size ]\n\t\t" \
3806051Swyllys 	"[ eku=[critical:]EKU name,...]\n\t\t" \
3816354Swyllys 	"[ format=pem|der ]\n\t"
3826051Swyllys 
3836051Swyllys #define	DOWNLOAD_IDX 8
3846354Swyllys #define	DOWNLOAD_VERB "download"
3856051Swyllys #define	DOWNLOAD_SUMM gettext("downloads a CRL or certificate file " \
3866051Swyllys 	"from an external source")
3876354Swyllys #define	DOWNLOAD_SYN \
3886051Swyllys 	"download url=url_str\n\t\t" \
3896051Swyllys 	"[ objtype=crl|cert ]\n\t\t" \
3906051Swyllys 	"[ http_proxy=proxy_str ]\n\t\t" \
3916354Swyllys 	"[ outfile = outfile ]\n\t"
3926051Swyllys 
3936051Swyllys #define	GENKEY_IDX 9
3946354Swyllys #define	GENKEY_VERB "genkey"
3956051Swyllys #define	GENKEY_SUMM gettext("creates a symmetric key in the keystore")
3966354Swyllys #define	GENKEY_SYN \
3976051Swyllys 	"genkey [ keystore=pkcs11 ]\n\t\t" \
3986051Swyllys 	"label=key-label\n\t\t" \
3996051Swyllys 	"[ keytype=aes|arcfour|des|3des|generic ]\n\t\t" \
4006051Swyllys 	"[ keylen=key-size (AES, ARCFOUR or GENERIC only)]\n\t\t" \
4016051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
4026051Swyllys 	"[ sensitive=y|n ]\n\t\t" \
4036051Swyllys 	"[ extractable=y|n ]\n\t\t" \
4046051Swyllys 	"[ print=y|n ]\n\t" \
4056051Swyllys  \
4066051Swyllys 	"genkey keystore=nss\n\t\t" \
4076051Swyllys 	"label=key-label\n\t\t" \
4086051Swyllys 	"[ keytype=aes|arcfour|des|3des|generic ]\n\t\t" \
4096051Swyllys 	"[ keylen=key-size (AES, ARCFOUR or GENERIC only)]\n\t\t" \
4106051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
4116051Swyllys 	"[ dir=directory-path ]\n\t\t" \
4126051Swyllys 	"[ prefix=DBprefix ]\n\t" \
4136051Swyllys  \
4146051Swyllys 	"genkey keystore=file\n\t\t" \
4156051Swyllys 	"outkey=key-fn\n\t\t" \
4166051Swyllys 	"[ keytype=aes|arcfour|des|3des|generic ]\n\t\t" \
4176051Swyllys 	"[ keylen=key-size (AES, ARCFOUR or GENERIC only)]\n\t\t" \
4186354Swyllys 	"[ print=y|n ]\n\t"
4196051Swyllys 
4206051Swyllys #define	SIGNCSR_IDX 10
4216354Swyllys #define	SIGNCSR_VERB "signcsr"
4226051Swyllys #define	SIGNCSR_SUMM gettext("Sign a PKCS#10 Certificate Signing Request")
4236354Swyllys #define	SIGNCSR_SYN \
4246051Swyllys 	"signcsr keystore=pkcs11\n\t\t" \
4256051Swyllys 	"signkey=label (label of signing key)\n\t\t" \
4266051Swyllys 	"csr=CSR filename\n\t\t" \
4276051Swyllys 	"serial=serial number hex string\n\t\t" \
4286051Swyllys 	"outcert=filename for final certificate\n\t\t" \
4296051Swyllys 	"issuer=issuer-DN\n\t\t" \
4306051Swyllys 	"[ store=y|n ] (store the new cert in NSS DB, default=n)\n\t\t" \
4316051Swyllys 	"[ outlabel=certificate label ]\n\t\t" \
4326051Swyllys 	"[ format=pem|der ] (output format)\n\t\t" \
4336051Swyllys 	"[ subject=subject-DN ] (new subject name)\n\t\t" \
4346051Swyllys 	"[ altname=subjectAltName ]\n\t\t" \
4356051Swyllys 	"[ keyusage=[critical:]usage,...]\n\t\t" \
4366051Swyllys 	"[ eku=[critical:]EKU Name,...]\n\t\t" \
4376051Swyllys 	"[ lifetime=number-hour|number-day|number-year ]\n\t\t" \
4386051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t" \
4396051Swyllys  \
4406051Swyllys 	"signcsr keystore=file\n\t\t" \
4416051Swyllys 	"signkey=filename\n\t\t" \
4426051Swyllys 	"csr=CSR filename\n\t\t" \
4436051Swyllys 	"serial=serial number hex string\n\t\t" \
4446051Swyllys 	"outcert=filename for final certificate\n\t\t" \
4456051Swyllys 	"issuer=issuer-DN\n\t\t" \
4466051Swyllys 	"[ format=pem|der ] (output format)\n\t\t" \
4476051Swyllys 	"[ subject=subject-DN ] (new subject name)\n\t\t" \
4486051Swyllys 	"[ altname=subjectAltName ]\n\t\t" \
4496051Swyllys 	"[ keyusage=[critical:]usage,...]\n\t\t" \
4506051Swyllys 	"[ lifetime=number-hour|number-day|number-year ]\n\t\t" \
4516051Swyllys 	"[ eku=[critical:]EKU Name,...]\n\t" \
4526051Swyllys  \
4536051Swyllys 	"signcsr keystore=nss\n\t\t" \
4546051Swyllys 	"signkey=label (label of signing key)\n\t\t" \
4556051Swyllys 	"csr=CSR filename\n\t\t" \
4566051Swyllys 	"serial=serial number hex string\n\t\t" \
4576051Swyllys 	"outcert=filename for final certificate\n\t\t" \
4586051Swyllys 	"issuer=issuer-DN\n\t\t" \
4596051Swyllys 	"[ store=y|n ] (store the new cert in NSS DB, default=n)\n\t\t" \
4606051Swyllys 	"[ outlabel=certificate label ]\n\t\t" \
4616051Swyllys 	"[ format=pem|der ] (output format)\n\t\t" \
4626051Swyllys 	"[ subject=subject-DN ] (new subject name)\n\t\t" \
4636051Swyllys 	"[ altname=subjectAltName ]\n\t\t" \
4646051Swyllys 	"[ keyusage=[critical:]usage,...]\n\t\t" \
4656051Swyllys 	"[ eku=[critical:]EKU Name,...]\n\t\t" \
4666051Swyllys 	"[ lifetime=number-hour|number-day|number-year ]\n\t\t" \
4676051Swyllys 	"[ token=token[:manuf[:serial]]]\n\t\t" \
4686051Swyllys 	"[ dir=directory-path ]\n\t\t" \
4696354Swyllys 	"[ prefix=DBprefix ]\n\t"
4706051Swyllys 
4719126SWyllys.Ingersoll@Sun.COM #define	INITTOKEN_IDX 11
4729126SWyllys.Ingersoll@Sun.COM #define	INITTOKEN_VERB "inittoken"
4739126SWyllys.Ingersoll@Sun.COM #define	INITTOKEN_SUMM gettext("Initialize a PKCS11 token")
4749126SWyllys.Ingersoll@Sun.COM #define	INITTOKEN_SYN \
4759126SWyllys.Ingersoll@Sun.COM 	"inittoken \n\t\t" \
4769126SWyllys.Ingersoll@Sun.COM 	"[ currlabel=token[:manuf[:serial]]]\n\t\t" \
4779126SWyllys.Ingersoll@Sun.COM 	"[ newlabel=new token label ]\n\t"
4789126SWyllys.Ingersoll@Sun.COM 
4799126SWyllys.Ingersoll@Sun.COM #define	HELP_IDX 12
4806354Swyllys #define	HELP_VERB "help"
4816051Swyllys #define	HELP_SUMM gettext("displays help message")
4826354Swyllys #define	HELP_SYN "help\t(help and usage)"
4836051Swyllys 
4840Sstevel@tonic-gate /* Command structure for verbs and their actions.  Do NOT i18n/l10n. */
4850Sstevel@tonic-gate static verbcmd	cmds[] = {
4866051Swyllys 	{ NULL,	pk_tokens, 0, NULL, NULL},
4876051Swyllys 	{ NULL,	pk_setpin, 0, NULL, NULL},
4886051Swyllys 	{ NULL, pk_list, 0, NULL, NULL},
4896051Swyllys 	{ NULL, pk_delete, 0, NULL, NULL},
4906051Swyllys 	{ NULL,	pk_import, 0, NULL, NULL},
4916051Swyllys 	{ NULL,	pk_export, 0, NULL, NULL},
4926051Swyllys 	{ NULL,	pk_gencert, 0, NULL, NULL},
4936051Swyllys 	{ NULL,	pk_gencsr, 0, NULL, NULL},
4946051Swyllys 	{ NULL,	pk_download, 0, NULL, NULL},
4956051Swyllys 	{ NULL,	pk_genkey, 0, NULL, NULL},
4966051Swyllys 	{ NULL, pk_signcsr, 0, NULL, NULL},
4979126SWyllys.Ingersoll@Sun.COM 	{ NULL, pk_inittoken, 0, NULL, NULL},
4986051Swyllys 	{ NULL,	pk_help, 0, NULL, NULL}
4990Sstevel@tonic-gate };
5003501Swyllys 
5010Sstevel@tonic-gate static int	num_cmds = sizeof (cmds) / sizeof (verbcmd);
5020Sstevel@tonic-gate 
5030Sstevel@tonic-gate static char	*prog;
5043089Swyllys static void	usage(int);
5050Sstevel@tonic-gate 
5066051Swyllys static void
5076051Swyllys init_command_list()
5086051Swyllys {
5096051Swyllys 	cmds[TOKEN_IDX].verb = TOKEN_VERB;
5106051Swyllys 	cmds[TOKEN_IDX].summary = TOKEN_SUMM;
5116051Swyllys 	cmds[TOKEN_IDX].synopsis = TOKEN_SYN;
5126051Swyllys 
5136051Swyllys 	cmds[SETPIN_IDX].verb = SETPIN_VERB;
5146051Swyllys 	cmds[SETPIN_IDX].summary = SETPIN_SUMM;
5156051Swyllys 	cmds[SETPIN_IDX].synopsis = SETPIN_SYN;
5166051Swyllys 
5176051Swyllys 	cmds[LIST_IDX].verb = LIST_VERB;
5186051Swyllys 	cmds[LIST_IDX].summary = LIST_SUMM;
5196051Swyllys 	cmds[LIST_IDX].synopsis = LIST_SYN;
5206051Swyllys 
5216051Swyllys 	cmds[DELETE_IDX].verb = DELETE_VERB;
5226051Swyllys 	cmds[DELETE_IDX].summary = DELETE_SUMM;
5236051Swyllys 	cmds[DELETE_IDX].synopsis = DELETE_SYN;
5246051Swyllys 
5256051Swyllys 	cmds[IMPORT_IDX].verb = IMPORT_VERB;
5266051Swyllys 	cmds[IMPORT_IDX].summary = IMPORT_SUMM;
5276051Swyllys 	cmds[IMPORT_IDX].synopsis = IMPORT_SYN;
5286051Swyllys 
5296051Swyllys 	cmds[EXPORT_IDX].verb = EXPORT_VERB;
5306051Swyllys 	cmds[EXPORT_IDX].summary = EXPORT_SUMM;
5316051Swyllys 	cmds[EXPORT_IDX].synopsis = EXPORT_SYN;
5326051Swyllys 
5336051Swyllys 	cmds[GENCERT_IDX].verb = GENCERT_VERB;
5346051Swyllys 	cmds[GENCERT_IDX].summary = GENCERT_SUMM;
5356051Swyllys 	cmds[GENCERT_IDX].synopsis = GENCERT_SYN;
5366051Swyllys 
5376051Swyllys 	cmds[GENCSR_IDX].verb = GENCSR_VERB;
5386051Swyllys 	cmds[GENCSR_IDX].summary = GENCSR_SUMM;
5396051Swyllys 	cmds[GENCSR_IDX].synopsis = GENCSR_SYN;
5406051Swyllys 
5416051Swyllys 	cmds[DOWNLOAD_IDX].verb = DOWNLOAD_VERB;
5426051Swyllys 	cmds[DOWNLOAD_IDX].summary = DOWNLOAD_SUMM;
5436051Swyllys 	cmds[DOWNLOAD_IDX].synopsis = DOWNLOAD_SYN;
5446051Swyllys 
5456051Swyllys 	cmds[GENKEY_IDX].verb = GENKEY_VERB;
5466051Swyllys 	cmds[GENKEY_IDX].summary = GENKEY_SUMM;
5476051Swyllys 	cmds[GENKEY_IDX].synopsis = GENKEY_SYN;
5486051Swyllys 
5496051Swyllys 	cmds[SIGNCSR_IDX].verb = SIGNCSR_VERB;
5506051Swyllys 	cmds[SIGNCSR_IDX].summary = SIGNCSR_SUMM;
5516051Swyllys 	cmds[SIGNCSR_IDX].synopsis = SIGNCSR_SYN;
5526051Swyllys 
5539126SWyllys.Ingersoll@Sun.COM 	cmds[INITTOKEN_IDX].verb = INITTOKEN_VERB;
5549126SWyllys.Ingersoll@Sun.COM 	cmds[INITTOKEN_IDX].summary = INITTOKEN_SUMM;
5559126SWyllys.Ingersoll@Sun.COM 	cmds[INITTOKEN_IDX].synopsis = INITTOKEN_SYN;
5569126SWyllys.Ingersoll@Sun.COM 
5576051Swyllys 	cmds[HELP_IDX].verb = HELP_VERB;
5586051Swyllys 	cmds[HELP_IDX].summary = HELP_SUMM;
5596051Swyllys 	cmds[HELP_IDX].synopsis = HELP_SYN;
5606051Swyllys }
5616051Swyllys 
5620Sstevel@tonic-gate /*
5630Sstevel@tonic-gate  * Usage information.  This function must be updated when new verbs or
5640Sstevel@tonic-gate  * options are added.
5650Sstevel@tonic-gate  */
5660Sstevel@tonic-gate static void
5673089Swyllys usage(int idx)
5680Sstevel@tonic-gate {
56917Sdinak 	int	i;
57017Sdinak 
57117Sdinak 	/* Display this block only in command-line mode. */
57217Sdinak 	(void) fprintf(stdout, gettext("Usage:\n"));
5733501Swyllys 	(void) fprintf(stdout, gettext("   %s -?\t(help and usage)\n"),
5744829Shylee 	    prog);
5753501Swyllys 	(void) fprintf(stdout, gettext("   %s -f option_file\n"), prog);
5763501Swyllys 	(void) fprintf(stdout, gettext("   %s subcommand [options...]\n"),
5774829Shylee 	    prog);
57817Sdinak 	(void) fprintf(stdout, gettext("where subcommands may be:\n"));
57917Sdinak 
58017Sdinak 	/* Display only those verbs that match the current tool mode. */
5813089Swyllys 	if (idx == -1) {
5823089Swyllys 		for (i = 0; i < num_cmds; i++) {
5833089Swyllys 			/* Do NOT i18n/l10n. */
5843501Swyllys 			(void) fprintf(stdout, "   %-8s	- %s\n",
5854829Shylee 			    cmds[i].verb, cmds[i].summary);
5863089Swyllys 		}
5876354Swyllys 		(void) fprintf(stdout, "%s \'help\'.\n"
5886354Swyllys 		    "Ex: pktool gencert help\n\n",
5896354Swyllys 		    gettext("\nFurther details on the "
5906354Swyllys 		    "subcommands can be found by adding"));
5913089Swyllys 	} else {
5923089Swyllys 		(void) fprintf(stdout, "\t%s\n", cmds[idx].synopsis);
59317Sdinak 	}
59417Sdinak }
59517Sdinak 
59617Sdinak /*
59717Sdinak  * Provide help, in the form of displaying the usage.
59817Sdinak  */
59917Sdinak static int
60017Sdinak pk_help(int argc, char *argv[])
60117Sdinak /* ARGSUSED */
60217Sdinak {
6033089Swyllys 	usage(-1);
6043089Swyllys 	return (0);
6053089Swyllys }
6063089Swyllys 
6073089Swyllys /*
6083089Swyllys  * Process arguments from the argfile and create a new
6093089Swyllys  * argv/argc list to be processed later.
6103089Swyllys  */
6113089Swyllys static int
6123089Swyllys process_arg_file(char *argfile, char ***argv, int *argc)
6133089Swyllys {
6143089Swyllys 	FILE *fp;
6153089Swyllys 	char argline[2 * BUFSIZ]; /* 2048 bytes should be plenty */
6163089Swyllys 	char *p;
6173089Swyllys 	int nargs = 0;
6183089Swyllys 
6193089Swyllys 	if ((fp = fopen(argfile, "rF")) == NULL) {
6203089Swyllys 		(void) fprintf(stderr,
6214829Shylee 		    gettext("Cannot read argfile %s: %s\n"),
6224829Shylee 		    argfile, strerror(errno));
6233089Swyllys 		return (errno);
6243089Swyllys 	}
62517Sdinak 
6263089Swyllys 	while (fgets(argline, sizeof (argline), fp) != NULL) {
6273089Swyllys 		int j;
6283089Swyllys 		/* remove trailing whitespace */
6293089Swyllys 		j = strlen(argline) - 1;
6303089Swyllys 		while (j >= 0 && isspace(argline[j])) {
6313089Swyllys 			argline[j] = 0;
6323089Swyllys 			j--;
6333089Swyllys 		}
6343089Swyllys 		/* If it was a blank line, get the next one. */
6353089Swyllys 		if (!strlen(argline))
6363089Swyllys 			continue;
6373089Swyllys 
6385051Swyllys 		(*argv) = realloc((*argv),
6395051Swyllys 		    (nargs + 1) * sizeof (char *));
6403089Swyllys 		if ((*argv) == NULL) {
6413089Swyllys 			perror("memory error");
6423089Swyllys 			(void) fclose(fp);
6433089Swyllys 			return (errno);
6443089Swyllys 		}
6453089Swyllys 		p = (char *)strdup(argline);
6463089Swyllys 		if (p == NULL) {
6473089Swyllys 			perror("memory error");
6483089Swyllys 			(void) fclose(fp);
6493089Swyllys 			return (errno);
6503089Swyllys 		}
6513089Swyllys 		(*argv)[nargs] = p;
6523089Swyllys 		nargs++;
6533089Swyllys 	}
6543089Swyllys 	*argc = nargs;
6553089Swyllys 	(void) fclose(fp);
65617Sdinak 	return (0);
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate 
6590Sstevel@tonic-gate /*
6600Sstevel@tonic-gate  * MAIN() -- where all the action is
6610Sstevel@tonic-gate  */
6620Sstevel@tonic-gate int
6630Sstevel@tonic-gate main(int argc, char *argv[], char *envp[])
6640Sstevel@tonic-gate /* ARGSUSED2 */
6650Sstevel@tonic-gate {
6660Sstevel@tonic-gate 	int	i, found = -1;
6670Sstevel@tonic-gate 	int	rv;
6680Sstevel@tonic-gate 	int	pk_argc = 0;
6690Sstevel@tonic-gate 	char	**pk_argv = NULL;
67017Sdinak 	int	save_errno = 0;
6710Sstevel@tonic-gate 
6720Sstevel@tonic-gate 	/* Set up for i18n/l10n. */
6730Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
6740Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)		/* Should be defined by cc -D. */
6750Sstevel@tonic-gate #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it isn't. */
6760Sstevel@tonic-gate #endif
6770Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
6780Sstevel@tonic-gate 
6796051Swyllys 	init_command_list();
6806051Swyllys 
6810Sstevel@tonic-gate 	/* Get program base name and move pointer over 0th arg. */
6820Sstevel@tonic-gate 	prog = basename(argv[0]);
6830Sstevel@tonic-gate 	argv++, argc--;
6840Sstevel@tonic-gate 
6850Sstevel@tonic-gate 	/* Set up for debug and error output. */
6860Sstevel@tonic-gate 	if (argc == 0) {
6873089Swyllys 		usage(-1);
6880Sstevel@tonic-gate 		return (1);
6890Sstevel@tonic-gate 	}
6900Sstevel@tonic-gate 
69117Sdinak 	/* Check for help options.  For CLIP-compliance. */
6923089Swyllys 	if (strcmp(argv[0], "-?") == 0) {
6933089Swyllys 		return (pk_help(argc, argv));
6943089Swyllys 	} else if (strcmp(argv[0], "-f") == 0 && argc == 2) {
6953089Swyllys 		rv = process_arg_file(argv[1], &pk_argv, &pk_argc);
6963089Swyllys 		if (rv)
6973089Swyllys 			return (rv);
6983089Swyllys 	} else if (argc >= 1 && argv[0][0] == '-') {
6993089Swyllys 		usage(-1);
7003089Swyllys 		return (1);
70117Sdinak 	}
70217Sdinak 
70317Sdinak 	/* Always turns off Metaslot so that we can see softtoken. */
7040Sstevel@tonic-gate 	if (setenv("METASLOT_ENABLED", "false", 1) < 0) {
70517Sdinak 		save_errno = errno;
7060Sstevel@tonic-gate 		cryptoerror(LOG_STDERR,
70717Sdinak 		    gettext("Disabling Metaslot failed (%s)."),
70817Sdinak 		    strerror(save_errno));
7090Sstevel@tonic-gate 		return (1);
7100Sstevel@tonic-gate 	}
7110Sstevel@tonic-gate 
7120Sstevel@tonic-gate 	/* Begin parsing command line. */
7133089Swyllys 	if (pk_argc == 0 && pk_argv == NULL) {
7143089Swyllys 		pk_argc = argc;
7153089Swyllys 		pk_argv = argv;
7163089Swyllys 	}
7170Sstevel@tonic-gate 
71817Sdinak 	/* Check for valid verb (or an abbreviation of it). */
7190Sstevel@tonic-gate 	found = -1;
7200Sstevel@tonic-gate 	for (i = 0; i < num_cmds; i++) {
7210Sstevel@tonic-gate 		if (strcmp(cmds[i].verb, pk_argv[0]) == 0) {
7220Sstevel@tonic-gate 			if (found < 0) {
7230Sstevel@tonic-gate 				found = i;
7240Sstevel@tonic-gate 				break;
7250Sstevel@tonic-gate 			}
7260Sstevel@tonic-gate 		}
7270Sstevel@tonic-gate 	}
7280Sstevel@tonic-gate 	/* Stop here if no valid verb found. */
7290Sstevel@tonic-gate 	if (found < 0) {
73017Sdinak 		cryptoerror(LOG_STDERR, gettext("Invalid verb: %s"),
73117Sdinak 		    pk_argv[0]);
7320Sstevel@tonic-gate 		return (1);
7330Sstevel@tonic-gate 	}
7340Sstevel@tonic-gate 
7350Sstevel@tonic-gate 	/* Get to work! */
7360Sstevel@tonic-gate 	rv = (*cmds[found].action)(pk_argc, pk_argv);
7370Sstevel@tonic-gate 	switch (rv) {
7380Sstevel@tonic-gate 	case PK_ERR_NONE:
7390Sstevel@tonic-gate 		break;		/* Command succeeded, do nothing. */
7400Sstevel@tonic-gate 	case PK_ERR_USAGE:
7413089Swyllys 		usage(found);
7420Sstevel@tonic-gate 		break;
7430Sstevel@tonic-gate 	case PK_ERR_QUIT:
7440Sstevel@tonic-gate 		exit(0);
7450Sstevel@tonic-gate 		/* NOTREACHED */
74617Sdinak 	case PK_ERR_PK11:
74717Sdinak 	case PK_ERR_SYSTEM:
74817Sdinak 	case PK_ERR_OPENSSL:
7493089Swyllys 	case PK_ERR_NSS:
7500Sstevel@tonic-gate 	default:
7510Sstevel@tonic-gate 		break;
7520Sstevel@tonic-gate 	}
7530Sstevel@tonic-gate 	return (rv);
7540Sstevel@tonic-gate }
755