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 /*
22*12234Swyllys.ingersoll@sun.com * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate /*
260Sstevel@tonic-gate * This file comprises the main driver for this tool.
2717Sdinak * Upon parsing the command verbs from user input, it
2817Sdinak * branches to the appropriate modules to perform the
2917Sdinak * requested task.
300Sstevel@tonic-gate */
310Sstevel@tonic-gate
320Sstevel@tonic-gate #include <stdio.h>
330Sstevel@tonic-gate #include <string.h>
340Sstevel@tonic-gate #include <ctype.h>
350Sstevel@tonic-gate #include <malloc.h>
366051Swyllys #include <libintl.h>
370Sstevel@tonic-gate #include <libgen.h>
380Sstevel@tonic-gate #include <errno.h>
390Sstevel@tonic-gate #include <cryptoutil.h>
400Sstevel@tonic-gate #include <security/cryptoki.h>
410Sstevel@tonic-gate #include "common.h"
420Sstevel@tonic-gate
430Sstevel@tonic-gate /*
440Sstevel@tonic-gate * The verbcmd construct allows genericizing information about a verb so
450Sstevel@tonic-gate * that it is easier to manipulate. Makes parsing code easier to read,
460Sstevel@tonic-gate * fix, and extend with new verbs.
470Sstevel@tonic-gate */
480Sstevel@tonic-gate typedef struct verbcmd_s {
490Sstevel@tonic-gate char *verb;
500Sstevel@tonic-gate int (*action)(int, char *[]);
5117Sdinak int mode;
523501Swyllys char *summary;
5317Sdinak char *synopsis;
540Sstevel@tonic-gate } verbcmd;
550Sstevel@tonic-gate
560Sstevel@tonic-gate /* External declarations for supported verb actions. */
570Sstevel@tonic-gate extern int pk_setpin(int argc, char *argv[]);
5817Sdinak extern int pk_list(int argc, char *argv[]);
5917Sdinak extern int pk_delete(int argc, char *argv[]);
6017Sdinak extern int pk_import(int argc, char *argv[]);
6117Sdinak extern int pk_export(int argc, char *argv[]);
6217Sdinak extern int pk_tokens(int argc, char *argv[]);
633089Swyllys extern int pk_gencert(int argc, char *argv[]);
643089Swyllys extern int pk_gencsr(int argc, char *argv[]);
653089Swyllys extern int pk_download(int argc, char *argv[]);
663089Swyllys extern int pk_genkey(int argc, char *argv[]);
676051Swyllys extern int pk_signcsr(int argc, char *argv[]);
689126SWyllys.Ingersoll@Sun.COM extern int pk_inittoken(int argc, char *argv[]);
6911973Swyllys.ingersoll@sun.com extern int pk_genkeypair(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 "[ label=key-label ]\n\t\t" \
1136051Swyllys "[ token=token[:manuf[:serial]]]\n\t" \
1146051Swyllys \
1156051Swyllys "list keystore=pkcs11 objtype=crl\n\t\t" \
1166669Swyllys "infile=crl-fn\n\t" \
1176051Swyllys \
1186051Swyllys "list keystore=nss objtype=cert\n\t\t" \
1196051Swyllys "[ subject=subject-DN ]\n\t\t" \
1206051Swyllys "[ issuer=issuer-DN ]\n\t\t" \
1216051Swyllys "[ serial=serial number ]\n\t\t" \
1226051Swyllys "[ nickname=cert-nickname ]\n\t\t" \
1236051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
1246051Swyllys "[ dir=directory-path ]\n\t\t" \
1256051Swyllys "[ prefix=DBprefix ]\n\t\t" \
1266051Swyllys "[ criteria=valid|expired|both ]\n\t" \
1276051Swyllys \
1286051Swyllys "list keystore=nss objtype=key\n\t\t" \
1296051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
1306051Swyllys "[ dir=directory-path ]\n\t\t" \
1316051Swyllys "[ prefix=DBprefix ]\n\t\t" \
1326051Swyllys "[ nickname=key-nickname ]\n\t" \
1336051Swyllys \
1346051Swyllys "list keystore=file objtype=cert\n\t\t" \
1356051Swyllys "[ subject=subject-DN ]\n\t\t" \
1366051Swyllys "[ issuer=issuer-DN ]\n\t\t" \
1376051Swyllys "[ serial=serial number ]\n\t\t" \
1386051Swyllys "[ infile=cert-fn ]\n\t\t" \
1396051Swyllys "[ dir=directory-path ]\n\t\t" \
1406051Swyllys "[ criteria=valid|expired|both ]\n\t" \
1416051Swyllys \
1426051Swyllys "list keystore=file objtype=key\n\t\t" \
1436051Swyllys "[ infile=key-fn ]\n\t\t" \
1446051Swyllys "[ dir=directory-path ]\n\t" \
1456051Swyllys \
1466051Swyllys "list keystore=file objtype=crl\n\t\t" \
1476669Swyllys "infile=crl-fn\n\t"
1486051Swyllys
1496051Swyllys #define DELETE_IDX 3
1506354Swyllys #define DELETE_VERB "delete"
1516051Swyllys #define DELETE_SUMM gettext("deletes objects in the keystore")
1526354Swyllys #define DELETE_SYN \
1536051Swyllys "delete [ token=token[:manuf[:serial]]]\n\t\t" \
1546051Swyllys "[ objtype=private|public|both ]\n\t\t" \
1556051Swyllys "[ label=object-label ]\n\t" \
1566051Swyllys \
1576051Swyllys "delete keystore=nss objtype=cert\n\t\t" \
1586051Swyllys "[ subject=subject-DN ]\n\t\t" \
1596051Swyllys "[ issuer=issuer-DN ]\n\t\t" \
1606051Swyllys "[ serial=serial number ]\n\t\t" \
1616051Swyllys "[ label=cert-label ]\n\t\t" \
1626051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
1636051Swyllys "[ dir=directory-path ]\n\t\t" \
1646051Swyllys "[ prefix=DBprefix ]\n\t\t" \
1656051Swyllys "[ criteria=valid|expired|both ]\n\t" \
1666051Swyllys \
1676051Swyllys "delete keystore=nss objtype=key\n\t\t" \
1686051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
1696051Swyllys "[ dir=directory-path ]\n\t\t" \
1706051Swyllys "[ prefix=DBprefix ]\n\t\t" \
1716051Swyllys "[ nickname=key-nickname ]\n\t\t" \
1726051Swyllys \
1736051Swyllys "delete keystore=nss objtype=crl\n\t\t" \
1746051Swyllys "[ nickname=issuer-nickname ]\n\t\t" \
1756051Swyllys "[ subject=subject-DN ]\n\t\t" \
1766051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
1776051Swyllys "[ dir=directory-path ]\n\t\t" \
1786051Swyllys "[ prefix=DBprefix ]\n\t" \
1796051Swyllys \
1806051Swyllys "delete keystore=pkcs11 " \
1816051Swyllys "objtype=cert[:[public | private | both]]\n\t\t" \
1826051Swyllys "[ subject=subject-DN ]\n\t\t" \
1836051Swyllys "[ issuer=issuer-DN ]\n\t\t" \
1846051Swyllys "[ serial=serial number ]\n\t\t" \
1856051Swyllys "[ label=cert-label ]\n\t\t" \
1866051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
1876051Swyllys "[ criteria=valid|expired|both ]\n\t" \
1886051Swyllys \
1896051Swyllys "delete keystore=pkcs11 " \
1906051Swyllys "objtype=key[:[public | private | both]]\n\t\t" \
1916051Swyllys "[ label=key-label ]\n\t\t" \
1926051Swyllys "[ token=token[:manuf[:serial]]]\n\t" \
1936051Swyllys \
1946051Swyllys "delete keystore=pkcs11 objtype=crl\n\t\t" \
1956669Swyllys "infile=crl-fn\n\t" \
1966051Swyllys \
1976051Swyllys "delete keystore=file objtype=cert\n\t\t" \
1986051Swyllys "[ subject=subject-DN ]\n\t\t" \
1996051Swyllys "[ issuer=issuer-DN ]\n\t\t" \
2006051Swyllys "[ serial=serial number ]\n\t\t" \
2016051Swyllys "[ infile=cert-fn ]\n\t\t" \
2026051Swyllys "[ dir=directory-path ]\n\t\t" \
2036051Swyllys "[ criteria=valid|expired|both ]\n\t" \
2046051Swyllys \
2056051Swyllys "delete keystore=file objtype=key\n\t\t" \
2066051Swyllys "[ infile=key-fn ]\n\t\t" \
2076051Swyllys "[ dir=directory-path ]\n\t" \
2086051Swyllys \
2096051Swyllys "delete keystore=file objtype=crl\n\t\t" \
2106669Swyllys "infile=crl-fn\n\t"
2116051Swyllys
2126051Swyllys #define IMPORT_IDX 4
2136354Swyllys #define IMPORT_VERB "import"
2146051Swyllys #define IMPORT_SUMM gettext("imports objects from an external source")
2156354Swyllys #define IMPORT_SYN \
2166051Swyllys "import [token=token[:manuf[:serial]]]\n\t\t" \
2176051Swyllys "infile=input-fn\n\t" \
2186051Swyllys \
2196051Swyllys "import keystore=nss objtype=cert\n\t\t" \
2206051Swyllys "infile=input-fn\n\t\t" \
2216051Swyllys "label=cert-label\n\t\t" \
2226051Swyllys "[ trust=trust-value ]\n\t\t" \
2236051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
2246051Swyllys "[ dir=directory-path ]\n\t\t" \
2256051Swyllys "[ prefix=DBprefix ]\n\t" \
2266051Swyllys \
2276051Swyllys "import keystore=nss objtype=crl\n\t\t" \
2286051Swyllys "infile=input-fn\n\t\t" \
2296051Swyllys "[ verifycrl=y|n ]\n\t\t" \
2306051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
2316051Swyllys "[ dir=directory-path ]\n\t\t" \
2326051Swyllys "[ prefix=DBprefix ]\n\t" \
2336051Swyllys \
2346051Swyllys "import keystore=pkcs11\n\t\t" \
2356051Swyllys "infile=input-fn\n\t\t" \
2366051Swyllys "label=label\n\t\t" \
2376051Swyllys "[ objtype=cert|key ]\n\t\t" \
2386051Swyllys "[ keytype=aes|arcfour|des|3des|generic ]\n\t\t" \
2396051Swyllys "[ sensitive=y|n ]\n\t\t" \
2406051Swyllys "[ extractable=y|n ]\n\t\t" \
2416051Swyllys "[ token=token[:manuf[:serial]]]\n\t" \
2426051Swyllys \
2436051Swyllys "import keystore=pkcs11 objtype=crl\n\t\t" \
2446051Swyllys "infile=input-crl-fn\n\t\t" \
2456051Swyllys "outcrl=output-crl-fn\n\t\t" \
2466669Swyllys "outformat=pem|der\n\t" \
2476051Swyllys \
2486051Swyllys "import keystore=file\n\t\t" \
2496051Swyllys "infile=input-fn\n\t\t" \
2506051Swyllys "outkey=output-key-fn\n\t\t" \
2516051Swyllys "outcert=output-cert-fn\n\t\t" \
2526051Swyllys "[ outformat=pem|der|pkcs12 ]\n\t" \
2536051Swyllys \
2546051Swyllys "import keystore=file objtype=crl\n\t\t" \
2556051Swyllys "infile=input-crl-fn\n\t\t" \
2566051Swyllys "outcrl=output-crl-fn\n\t\t" \
2576669Swyllys "outformat=pem|der\n\t"
2586051Swyllys
2596051Swyllys #define EXPORT_IDX 5
2606354Swyllys #define EXPORT_VERB "export"
2616051Swyllys #define EXPORT_SUMM gettext("exports objects from the keystore to a file")
2626354Swyllys #define EXPORT_SYN \
2636051Swyllys "export [token=token[:manuf[:serial]]]\n\t\t" \
2646051Swyllys "outfile=output-fn\n\t" \
2656051Swyllys \
2666051Swyllys "export keystore=nss\n\t\t" \
2676051Swyllys "outfile=output-fn\n\t\t" \
2686051Swyllys "[ objtype=cert|key ]\n\t\t" \
2696051Swyllys "[ subject=subject-DN ]\n\t\t" \
2706051Swyllys "[ issuer=issuer-DN ]\n\t\t" \
2716051Swyllys "[ serial=serial number ]\n\t\t" \
2726051Swyllys "[ nickname=cert-nickname ]\n\t\t" \
2736051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
2746051Swyllys "[ dir=directory-path ]\n\t\t" \
2756051Swyllys "[ prefix=DBPrefix ]\n\t\t" \
2766051Swyllys "[ outformat=pem|der|pkcs12 ]\n\t" \
2776051Swyllys \
2786051Swyllys "export keystore=pkcs11\n\t\t" \
2796051Swyllys "outfile=output-fn\n\t\t" \
2806051Swyllys "[ objtype=cert|key ]\n\t\t" \
2816051Swyllys "[ label=label ]\n\t\t" \
2826051Swyllys "[ subject=subject-DN ]\n\t\t" \
2836051Swyllys "[ issuer=issuer-DN ]\n\t\t" \
2846051Swyllys "[ serial=serial number ]\n\t\t" \
2856051Swyllys "[ outformat=pem|der|pkcs12|raw ]\n\t\t" \
2866051Swyllys "[ token=token[:manuf[:serial]]]\n\t" \
2876051Swyllys \
2886051Swyllys "export keystore=file\n\t\t" \
2896051Swyllys "certfile=cert-input-fn\n\t\t" \
2906051Swyllys "keyfile=key-input-fn\n\t\t" \
2916669Swyllys "outfile=output-pkcs12-fn\n\t"
2926051Swyllys
2936051Swyllys #define GENCERT_IDX 6
2946354Swyllys #define GENCERT_VERB "gencert"
2956051Swyllys #define GENCERT_SUMM gettext("creates a self-signed X.509v3 certificate")
2966354Swyllys #define GENCERT_SYN \
29711973Swyllys.ingersoll@sun.com "gencert listcurves\n\t" \
29811973Swyllys.ingersoll@sun.com \
29910241Swyllys.ingersoll@sun.com "gencert keystore=nss\n\t\t" \
3006051Swyllys "label=cert-nickname\n\t\t" \
30111973Swyllys.ingersoll@sun.com "serial=serial number hex string\n\t\t" \
30210241Swyllys.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" \
30811973Swyllys.ingersoll@sun.com "[ keytype=rsa | ec [curve=ECC Curve Name] " \
30911973Swyllys.ingersoll@sun.com "[hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \
31011973Swyllys.ingersoll@sun.com "[ keytype=dsa [hash=sha1]]\n\t\t" \
3116051Swyllys "[ keylen=key-size ]\n\t\t" \
3126051Swyllys "[ trust=trust-value ]\n\t\t" \
3136051Swyllys "[ eku=[critical:]EKU name,...]\n\t\t" \
3146051Swyllys "[ lifetime=number-hour|number-day|number-year ]\n\t" \
3156051Swyllys \
31610241Swyllys.ingersoll@sun.com "gencert [ keystore=pkcs11 ]\n\t\t" \
3176051Swyllys "label=key/cert-label\n\t\t" \
3186051Swyllys "serial=serial number hex string\n\t\t" \
31910241Swyllys.ingersoll@sun.com "[ -i ] | [subject=subject-DN]\n\t\t" \
3206051Swyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" \
3216051Swyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3226051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
32311973Swyllys.ingersoll@sun.com "[ keytype=rsa | ec [curve=ECC Curve Name] " \
32411973Swyllys.ingersoll@sun.com "[hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \
32511973Swyllys.ingersoll@sun.com "[ keytype=dsa [hash=sha1 | sha256 ]]\n\t\t" \
3266051Swyllys "[ keylen=key-size ]\n\t\t" \
3276051Swyllys "[ eku=[critical:]EKU name,...]\n\t\t" \
3286051Swyllys "[ lifetime=number-hour|number-day|number-year ]\n\t" \
3296051Swyllys \
33010241Swyllys.ingersoll@sun.com "gencert keystore=file\n\t\t" \
3316051Swyllys "outcert=cert_filename\n\t\t" \
3326051Swyllys "outkey=key_filename\n\t\t" \
3336051Swyllys "serial=serial number hex string\n\t\t" \
33410241Swyllys.ingersoll@sun.com "[ -i ] | [subject=subject-DN]\n\t\t" \
3356051Swyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" \
3366051Swyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3376051Swyllys "[ format=der|pem ]\n\t\t" \
33811973Swyllys.ingersoll@sun.com "[ keytype=rsa [hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \
33911973Swyllys.ingersoll@sun.com "[ keytype=dsa [hash=sha1 | sha256 ]]\n\t\t" \
3406051Swyllys "[ keylen=key-size ]\n\t\t" \
3416051Swyllys "[ eku=[critical:]EKU name,...]\n\t\t" \
3426354Swyllys "[ lifetime=number-hour|number-day|number-year ]\n\t"
3436051Swyllys
3446051Swyllys #define GENCSR_IDX 7
3456354Swyllys #define GENCSR_VERB "gencsr"
3466051Swyllys #define GENCSR_SUMM gettext("creates a PKCS#10 certificate signing " \
3476051Swyllys "request file")
3486051Swyllys
3496354Swyllys #define GENCSR_SYN \
35011973Swyllys.ingersoll@sun.com "gencsr listcurves\n\t" \
35111973Swyllys.ingersoll@sun.com \
35210241Swyllys.ingersoll@sun.com "gencsr keystore=nss \n\t\t" \
3536051Swyllys "nickname=cert-nickname\n\t\t" \
3546051Swyllys "outcsr=csr-fn\n\t\t" \
35510241Swyllys.ingersoll@sun.com "[ -i ] | [subject=subject-DN]\n\t\t" \
3566051Swyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" \
3576051Swyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3586051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
3596051Swyllys "[ dir=directory-path ]\n\t\t" \
3606051Swyllys "[ prefix=DBprefix ]\n\t\t" \
36111973Swyllys.ingersoll@sun.com "[ keytype=rsa | ec [curve=ECC Curve Name] " \
36211973Swyllys.ingersoll@sun.com "[hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \
36311973Swyllys.ingersoll@sun.com "[ keytype=dsa [hash=sha1]]\n\t\t" \
3646051Swyllys "[ keylen=key-size ]\n\t\t" \
3656051Swyllys "[ eku=[critical:]EKU name,...]\n\t\t" \
3666051Swyllys "[ format=pem|der ]\n\t" \
3676051Swyllys \
36810241Swyllys.ingersoll@sun.com "gencsr [ keystore=pkcs11 ]\n\t\t" \
3696051Swyllys "label=key-label\n\t\t" \
3706051Swyllys "outcsr=csr-fn\n\t\t" \
37110241Swyllys.ingersoll@sun.com "[ -i ] | [subject=subject-DN]\n\t\t" \
3726051Swyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" \
3736051Swyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" \
3746051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
37511973Swyllys.ingersoll@sun.com "[ keytype=rsa | ec [curve=ECC Curve Name] " \
37611973Swyllys.ingersoll@sun.com "[hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \
37711973Swyllys.ingersoll@sun.com "[ keytype=dsa [hash=sha1 | sha256 ]]\n\t\t" \
3786051Swyllys "[ keylen=key-size ]\n\t\t" \
3796051Swyllys "[ eku=[critical:]EKU name,...]\n\t\t" \
3806051Swyllys "[ format=pem|der ]]\n\t" \
3816051Swyllys \
38210241Swyllys.ingersoll@sun.com "gencsr keystore=file\n\t\t" \
3836051Swyllys "outcsr=csr-fn\n\t\t" \
3846051Swyllys "outkey=key-fn\n\t\t" \
38510241Swyllys.ingersoll@sun.com "[ -i ] | [subject=subject-DN]\n\t\t" \
3866051Swyllys "[ altname=[critical:]SubjectAltName ]\n\t\t" \
3876051Swyllys "[ keyusage=[critical:]usage,usage,...]\n\t\t" \
38811973Swyllys.ingersoll@sun.com "[ keytype=rsa [hash=md5 | sha1 | sha256 | sha384 | sha512]]\n\t\t" \
38911973Swyllys.ingersoll@sun.com "[ keytype=dsa [hash=sha1 | sha256 ]]\n\t\t" \
3906051Swyllys "[ keylen=key-size ]\n\t\t" \
3916051Swyllys "[ eku=[critical:]EKU name,...]\n\t\t" \
3926354Swyllys "[ format=pem|der ]\n\t"
3936051Swyllys
3946051Swyllys #define DOWNLOAD_IDX 8
3956354Swyllys #define DOWNLOAD_VERB "download"
3966051Swyllys #define DOWNLOAD_SUMM gettext("downloads a CRL or certificate file " \
3976051Swyllys "from an external source")
3986354Swyllys #define DOWNLOAD_SYN \
3996051Swyllys "download url=url_str\n\t\t" \
4006051Swyllys "[ objtype=crl|cert ]\n\t\t" \
4016051Swyllys "[ http_proxy=proxy_str ]\n\t\t" \
4026354Swyllys "[ outfile = outfile ]\n\t"
4036051Swyllys
4046051Swyllys #define GENKEY_IDX 9
4056354Swyllys #define GENKEY_VERB "genkey"
4066051Swyllys #define GENKEY_SUMM gettext("creates a symmetric key in the keystore")
4076354Swyllys #define GENKEY_SYN \
4086051Swyllys "genkey [ keystore=pkcs11 ]\n\t\t" \
4096051Swyllys "label=key-label\n\t\t" \
4106051Swyllys "[ keytype=aes|arcfour|des|3des|generic ]\n\t\t" \
4116051Swyllys "[ keylen=key-size (AES, ARCFOUR or GENERIC only)]\n\t\t" \
4126051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
4136051Swyllys "[ sensitive=y|n ]\n\t\t" \
4146051Swyllys "[ extractable=y|n ]\n\t\t" \
4156051Swyllys "[ print=y|n ]\n\t" \
4166051Swyllys \
4176051Swyllys "genkey keystore=nss\n\t\t" \
4186051Swyllys "label=key-label\n\t\t" \
4196051Swyllys "[ keytype=aes|arcfour|des|3des|generic ]\n\t\t" \
4206051Swyllys "[ keylen=key-size (AES, ARCFOUR or GENERIC only)]\n\t\t" \
4216051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
4226051Swyllys "[ dir=directory-path ]\n\t\t" \
4236051Swyllys "[ prefix=DBprefix ]\n\t" \
4246051Swyllys \
4256051Swyllys "genkey keystore=file\n\t\t" \
4266051Swyllys "outkey=key-fn\n\t\t" \
4276051Swyllys "[ keytype=aes|arcfour|des|3des|generic ]\n\t\t" \
4286051Swyllys "[ keylen=key-size (AES, ARCFOUR or GENERIC only)]\n\t\t" \
4296354Swyllys "[ print=y|n ]\n\t"
4306051Swyllys
4316051Swyllys #define SIGNCSR_IDX 10
4326354Swyllys #define SIGNCSR_VERB "signcsr"
4336051Swyllys #define SIGNCSR_SUMM gettext("Sign a PKCS#10 Certificate Signing Request")
4346354Swyllys #define SIGNCSR_SYN \
4356051Swyllys "signcsr keystore=pkcs11\n\t\t" \
4366051Swyllys "signkey=label (label of signing key)\n\t\t" \
4376051Swyllys "csr=CSR filename\n\t\t" \
4386051Swyllys "serial=serial number hex string\n\t\t" \
4396051Swyllys "outcert=filename for final certificate\n\t\t" \
4406051Swyllys "issuer=issuer-DN\n\t\t" \
441*12234Swyllys.ingersoll@sun.com "[ store=y|n ] (store the new cert on the token, default=n)\n\t\t" \
4426051Swyllys "[ outlabel=certificate label ]\n\t\t" \
4436051Swyllys "[ format=pem|der ] (output format)\n\t\t" \
4446051Swyllys "[ subject=subject-DN ] (new subject name)\n\t\t" \
4456051Swyllys "[ altname=subjectAltName ]\n\t\t" \
4466051Swyllys "[ keyusage=[critical:]usage,...]\n\t\t" \
4476051Swyllys "[ eku=[critical:]EKU Name,...]\n\t\t" \
4486051Swyllys "[ lifetime=number-hour|number-day|number-year ]\n\t\t" \
4496051Swyllys "[ token=token[:manuf[:serial]]]\n\t" \
4506051Swyllys \
4516051Swyllys "signcsr keystore=file\n\t\t" \
4526051Swyllys "signkey=filename\n\t\t" \
4536051Swyllys "csr=CSR filename\n\t\t" \
4546051Swyllys "serial=serial number hex string\n\t\t" \
4556051Swyllys "outcert=filename for final certificate\n\t\t" \
4566051Swyllys "issuer=issuer-DN\n\t\t" \
4576051Swyllys "[ format=pem|der ] (output format)\n\t\t" \
4586051Swyllys "[ subject=subject-DN ] (new subject name)\n\t\t" \
4596051Swyllys "[ altname=subjectAltName ]\n\t\t" \
4606051Swyllys "[ keyusage=[critical:]usage,...]\n\t\t" \
4616051Swyllys "[ lifetime=number-hour|number-day|number-year ]\n\t\t" \
4626051Swyllys "[ eku=[critical:]EKU Name,...]\n\t" \
4636051Swyllys \
4646051Swyllys "signcsr keystore=nss\n\t\t" \
4656051Swyllys "signkey=label (label of signing key)\n\t\t" \
4666051Swyllys "csr=CSR filename\n\t\t" \
4676051Swyllys "serial=serial number hex string\n\t\t" \
4686051Swyllys "outcert=filename for final certificate\n\t\t" \
4696051Swyllys "issuer=issuer-DN\n\t\t" \
4706051Swyllys "[ store=y|n ] (store the new cert in NSS DB, default=n)\n\t\t" \
4716051Swyllys "[ outlabel=certificate label ]\n\t\t" \
4726051Swyllys "[ format=pem|der ] (output format)\n\t\t" \
4736051Swyllys "[ subject=subject-DN ] (new subject name)\n\t\t" \
4746051Swyllys "[ altname=subjectAltName ]\n\t\t" \
4756051Swyllys "[ keyusage=[critical:]usage,...]\n\t\t" \
4766051Swyllys "[ eku=[critical:]EKU Name,...]\n\t\t" \
4776051Swyllys "[ lifetime=number-hour|number-day|number-year ]\n\t\t" \
4786051Swyllys "[ token=token[:manuf[:serial]]]\n\t\t" \
4796051Swyllys "[ dir=directory-path ]\n\t\t" \
4806354Swyllys "[ prefix=DBprefix ]\n\t"
4816051Swyllys
4829126SWyllys.Ingersoll@Sun.COM #define INITTOKEN_IDX 11
4839126SWyllys.Ingersoll@Sun.COM #define INITTOKEN_VERB "inittoken"
4849126SWyllys.Ingersoll@Sun.COM #define INITTOKEN_SUMM gettext("Initialize a PKCS11 token")
4859126SWyllys.Ingersoll@Sun.COM #define INITTOKEN_SYN \
4869126SWyllys.Ingersoll@Sun.COM "inittoken \n\t\t" \
4879126SWyllys.Ingersoll@Sun.COM "[ currlabel=token[:manuf[:serial]]]\n\t\t" \
4889126SWyllys.Ingersoll@Sun.COM "[ newlabel=new token label ]\n\t"
4899126SWyllys.Ingersoll@Sun.COM
49011973Swyllys.ingersoll@sun.com #define GENKEYPAIR_IDX 12
49111973Swyllys.ingersoll@sun.com #define GENKEYPAIR_VERB "genkeypair"
49211973Swyllys.ingersoll@sun.com #define GENKEYPAIR_SUMM gettext("creates an asymmetric keypair")
49311973Swyllys.ingersoll@sun.com #define GENKEYPAIR_SYN \
49411973Swyllys.ingersoll@sun.com "genkeypair listcurves\n\t" \
49511973Swyllys.ingersoll@sun.com \
49611973Swyllys.ingersoll@sun.com "genkeypair keystore=nss\n\t\t" \
49711973Swyllys.ingersoll@sun.com "label=key-nickname\n\t\t" \
49811973Swyllys.ingersoll@sun.com "[ token=token[:manuf[:serial]]]\n\t\t" \
49911973Swyllys.ingersoll@sun.com "[ dir=directory-path ]\n\t\t" \
50011973Swyllys.ingersoll@sun.com "[ prefix=DBprefix ]\n\t\t" \
50111973Swyllys.ingersoll@sun.com "[ keytype=rsa | dsa | ec [curve=ECC Curve Name]]\n\t\t" \
50211973Swyllys.ingersoll@sun.com "[ keylen=key-size ]\n\t" \
50311973Swyllys.ingersoll@sun.com \
50411973Swyllys.ingersoll@sun.com "genkeypair [ keystore=pkcs11 ]\n\t\t" \
50511973Swyllys.ingersoll@sun.com "label=key-label\n\t\t" \
50611973Swyllys.ingersoll@sun.com "[ token=token[:manuf[:serial]]]\n\t\t" \
50711973Swyllys.ingersoll@sun.com "[ keytype=rsa | dsa | ec [curve=ECC Curve Name]]\n\t\t" \
50811973Swyllys.ingersoll@sun.com "[ keylen=key-size ]\n\t" \
50911973Swyllys.ingersoll@sun.com \
51011973Swyllys.ingersoll@sun.com "genkeypair keystore=file\n\t\t" \
51111973Swyllys.ingersoll@sun.com "outkey=key_filename\n\t\t" \
51211973Swyllys.ingersoll@sun.com "[ format=der|pem ]\n\t\t" \
51311973Swyllys.ingersoll@sun.com "[ keytype=rsa|dsa ]\n\t\t" \
51411973Swyllys.ingersoll@sun.com "[ keylen=key-size ]\n\t"
51511973Swyllys.ingersoll@sun.com
51611973Swyllys.ingersoll@sun.com #define HELP_IDX 13
5176354Swyllys #define HELP_VERB "help"
5186051Swyllys #define HELP_SUMM gettext("displays help message")
5196354Swyllys #define HELP_SYN "help\t(help and usage)"
5206051Swyllys
5210Sstevel@tonic-gate /* Command structure for verbs and their actions. Do NOT i18n/l10n. */
5220Sstevel@tonic-gate static verbcmd cmds[] = {
5236051Swyllys { NULL, pk_tokens, 0, NULL, NULL},
5246051Swyllys { NULL, pk_setpin, 0, NULL, NULL},
5256051Swyllys { NULL, pk_list, 0, NULL, NULL},
5266051Swyllys { NULL, pk_delete, 0, NULL, NULL},
5276051Swyllys { NULL, pk_import, 0, NULL, NULL},
5286051Swyllys { NULL, pk_export, 0, NULL, NULL},
5296051Swyllys { NULL, pk_gencert, 0, NULL, NULL},
5306051Swyllys { NULL, pk_gencsr, 0, NULL, NULL},
5316051Swyllys { NULL, pk_download, 0, NULL, NULL},
5326051Swyllys { NULL, pk_genkey, 0, NULL, NULL},
5336051Swyllys { NULL, pk_signcsr, 0, NULL, NULL},
5349126SWyllys.Ingersoll@Sun.COM { NULL, pk_inittoken, 0, NULL, NULL},
53511973Swyllys.ingersoll@sun.com { NULL, pk_genkeypair, 0, NULL, NULL},
5366051Swyllys { NULL, pk_help, 0, NULL, NULL}
5370Sstevel@tonic-gate };
5383501Swyllys
5390Sstevel@tonic-gate static int num_cmds = sizeof (cmds) / sizeof (verbcmd);
5400Sstevel@tonic-gate
5410Sstevel@tonic-gate static char *prog;
5423089Swyllys static void usage(int);
5430Sstevel@tonic-gate
5446051Swyllys static void
init_command_list()5456051Swyllys init_command_list()
5466051Swyllys {
5476051Swyllys cmds[TOKEN_IDX].verb = TOKEN_VERB;
5486051Swyllys cmds[TOKEN_IDX].summary = TOKEN_SUMM;
5496051Swyllys cmds[TOKEN_IDX].synopsis = TOKEN_SYN;
5506051Swyllys
5516051Swyllys cmds[SETPIN_IDX].verb = SETPIN_VERB;
5526051Swyllys cmds[SETPIN_IDX].summary = SETPIN_SUMM;
5536051Swyllys cmds[SETPIN_IDX].synopsis = SETPIN_SYN;
5546051Swyllys
5556051Swyllys cmds[LIST_IDX].verb = LIST_VERB;
5566051Swyllys cmds[LIST_IDX].summary = LIST_SUMM;
5576051Swyllys cmds[LIST_IDX].synopsis = LIST_SYN;
5586051Swyllys
5596051Swyllys cmds[DELETE_IDX].verb = DELETE_VERB;
5606051Swyllys cmds[DELETE_IDX].summary = DELETE_SUMM;
5616051Swyllys cmds[DELETE_IDX].synopsis = DELETE_SYN;
5626051Swyllys
5636051Swyllys cmds[IMPORT_IDX].verb = IMPORT_VERB;
5646051Swyllys cmds[IMPORT_IDX].summary = IMPORT_SUMM;
5656051Swyllys cmds[IMPORT_IDX].synopsis = IMPORT_SYN;
5666051Swyllys
5676051Swyllys cmds[EXPORT_IDX].verb = EXPORT_VERB;
5686051Swyllys cmds[EXPORT_IDX].summary = EXPORT_SUMM;
5696051Swyllys cmds[EXPORT_IDX].synopsis = EXPORT_SYN;
5706051Swyllys
5716051Swyllys cmds[GENCERT_IDX].verb = GENCERT_VERB;
5726051Swyllys cmds[GENCERT_IDX].summary = GENCERT_SUMM;
5736051Swyllys cmds[GENCERT_IDX].synopsis = GENCERT_SYN;
5746051Swyllys
5756051Swyllys cmds[GENCSR_IDX].verb = GENCSR_VERB;
5766051Swyllys cmds[GENCSR_IDX].summary = GENCSR_SUMM;
5776051Swyllys cmds[GENCSR_IDX].synopsis = GENCSR_SYN;
5786051Swyllys
5796051Swyllys cmds[DOWNLOAD_IDX].verb = DOWNLOAD_VERB;
5806051Swyllys cmds[DOWNLOAD_IDX].summary = DOWNLOAD_SUMM;
5816051Swyllys cmds[DOWNLOAD_IDX].synopsis = DOWNLOAD_SYN;
5826051Swyllys
5836051Swyllys cmds[GENKEY_IDX].verb = GENKEY_VERB;
5846051Swyllys cmds[GENKEY_IDX].summary = GENKEY_SUMM;
5856051Swyllys cmds[GENKEY_IDX].synopsis = GENKEY_SYN;
5866051Swyllys
5876051Swyllys cmds[SIGNCSR_IDX].verb = SIGNCSR_VERB;
5886051Swyllys cmds[SIGNCSR_IDX].summary = SIGNCSR_SUMM;
5896051Swyllys cmds[SIGNCSR_IDX].synopsis = SIGNCSR_SYN;
5906051Swyllys
5919126SWyllys.Ingersoll@Sun.COM cmds[INITTOKEN_IDX].verb = INITTOKEN_VERB;
5929126SWyllys.Ingersoll@Sun.COM cmds[INITTOKEN_IDX].summary = INITTOKEN_SUMM;
5939126SWyllys.Ingersoll@Sun.COM cmds[INITTOKEN_IDX].synopsis = INITTOKEN_SYN;
5949126SWyllys.Ingersoll@Sun.COM
59511973Swyllys.ingersoll@sun.com cmds[GENKEYPAIR_IDX].verb = GENKEYPAIR_VERB;
59611973Swyllys.ingersoll@sun.com cmds[GENKEYPAIR_IDX].summary = GENKEYPAIR_SUMM;
59711973Swyllys.ingersoll@sun.com cmds[GENKEYPAIR_IDX].synopsis = GENKEYPAIR_SYN;
59811973Swyllys.ingersoll@sun.com
5996051Swyllys cmds[HELP_IDX].verb = HELP_VERB;
6006051Swyllys cmds[HELP_IDX].summary = HELP_SUMM;
6016051Swyllys cmds[HELP_IDX].synopsis = HELP_SYN;
6026051Swyllys }
6036051Swyllys
6040Sstevel@tonic-gate /*
6050Sstevel@tonic-gate * Usage information. This function must be updated when new verbs or
6060Sstevel@tonic-gate * options are added.
6070Sstevel@tonic-gate */
6080Sstevel@tonic-gate static void
usage(int idx)6093089Swyllys usage(int idx)
6100Sstevel@tonic-gate {
61117Sdinak int i;
61217Sdinak
61317Sdinak /* Display this block only in command-line mode. */
61417Sdinak (void) fprintf(stdout, gettext("Usage:\n"));
6153501Swyllys (void) fprintf(stdout, gettext(" %s -?\t(help and usage)\n"),
6164829Shylee prog);
6173501Swyllys (void) fprintf(stdout, gettext(" %s -f option_file\n"), prog);
6183501Swyllys (void) fprintf(stdout, gettext(" %s subcommand [options...]\n"),
6194829Shylee prog);
62017Sdinak (void) fprintf(stdout, gettext("where subcommands may be:\n"));
62117Sdinak
62217Sdinak /* Display only those verbs that match the current tool mode. */
6233089Swyllys if (idx == -1) {
6243089Swyllys for (i = 0; i < num_cmds; i++) {
6253089Swyllys /* Do NOT i18n/l10n. */
6263501Swyllys (void) fprintf(stdout, " %-8s - %s\n",
6274829Shylee cmds[i].verb, cmds[i].summary);
6283089Swyllys }
6296354Swyllys (void) fprintf(stdout, "%s \'help\'.\n"
6306354Swyllys "Ex: pktool gencert help\n\n",
6316354Swyllys gettext("\nFurther details on the "
6326354Swyllys "subcommands can be found by adding"));
6333089Swyllys } else {
6343089Swyllys (void) fprintf(stdout, "\t%s\n", cmds[idx].synopsis);
63517Sdinak }
63617Sdinak }
63717Sdinak
63817Sdinak /*
63917Sdinak * Provide help, in the form of displaying the usage.
64017Sdinak */
64117Sdinak static int
pk_help(int argc,char * argv[])64217Sdinak pk_help(int argc, char *argv[])
64317Sdinak /* ARGSUSED */
64417Sdinak {
6453089Swyllys usage(-1);
6463089Swyllys return (0);
6473089Swyllys }
6483089Swyllys
6493089Swyllys /*
6503089Swyllys * Process arguments from the argfile and create a new
6513089Swyllys * argv/argc list to be processed later.
6523089Swyllys */
6533089Swyllys static int
process_arg_file(char * argfile,char *** argv,int * argc)6543089Swyllys process_arg_file(char *argfile, char ***argv, int *argc)
6553089Swyllys {
6563089Swyllys FILE *fp;
6573089Swyllys char argline[2 * BUFSIZ]; /* 2048 bytes should be plenty */
6583089Swyllys char *p;
6593089Swyllys int nargs = 0;
6603089Swyllys
6613089Swyllys if ((fp = fopen(argfile, "rF")) == NULL) {
6623089Swyllys (void) fprintf(stderr,
6634829Shylee gettext("Cannot read argfile %s: %s\n"),
6644829Shylee argfile, strerror(errno));
6653089Swyllys return (errno);
6663089Swyllys }
66717Sdinak
6683089Swyllys while (fgets(argline, sizeof (argline), fp) != NULL) {
6693089Swyllys int j;
6703089Swyllys /* remove trailing whitespace */
6713089Swyllys j = strlen(argline) - 1;
6723089Swyllys while (j >= 0 && isspace(argline[j])) {
6733089Swyllys argline[j] = 0;
6743089Swyllys j--;
6753089Swyllys }
6763089Swyllys /* If it was a blank line, get the next one. */
6773089Swyllys if (!strlen(argline))
6783089Swyllys continue;
6793089Swyllys
6805051Swyllys (*argv) = realloc((*argv),
6815051Swyllys (nargs + 1) * sizeof (char *));
6823089Swyllys if ((*argv) == NULL) {
6833089Swyllys perror("memory error");
6843089Swyllys (void) fclose(fp);
6853089Swyllys return (errno);
6863089Swyllys }
6873089Swyllys p = (char *)strdup(argline);
6883089Swyllys if (p == NULL) {
6893089Swyllys perror("memory error");
6903089Swyllys (void) fclose(fp);
6913089Swyllys return (errno);
6923089Swyllys }
6933089Swyllys (*argv)[nargs] = p;
6943089Swyllys nargs++;
6953089Swyllys }
6963089Swyllys *argc = nargs;
6973089Swyllys (void) fclose(fp);
69817Sdinak return (0);
6990Sstevel@tonic-gate }
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate /*
7020Sstevel@tonic-gate * MAIN() -- where all the action is
7030Sstevel@tonic-gate */
7040Sstevel@tonic-gate int
main(int argc,char * argv[],char * envp[])7050Sstevel@tonic-gate main(int argc, char *argv[], char *envp[])
7060Sstevel@tonic-gate /* ARGSUSED2 */
7070Sstevel@tonic-gate {
7080Sstevel@tonic-gate int i, found = -1;
7090Sstevel@tonic-gate int rv;
7100Sstevel@tonic-gate int pk_argc = 0;
7110Sstevel@tonic-gate char **pk_argv = NULL;
71217Sdinak int save_errno = 0;
7130Sstevel@tonic-gate
7140Sstevel@tonic-gate /* Set up for i18n/l10n. */
7150Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
7160Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D. */
7170Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it isn't. */
7180Sstevel@tonic-gate #endif
7190Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
7200Sstevel@tonic-gate
7216051Swyllys init_command_list();
7226051Swyllys
7230Sstevel@tonic-gate /* Get program base name and move pointer over 0th arg. */
7240Sstevel@tonic-gate prog = basename(argv[0]);
7250Sstevel@tonic-gate argv++, argc--;
7260Sstevel@tonic-gate
7270Sstevel@tonic-gate /* Set up for debug and error output. */
7280Sstevel@tonic-gate if (argc == 0) {
7293089Swyllys usage(-1);
7300Sstevel@tonic-gate return (1);
7310Sstevel@tonic-gate }
7320Sstevel@tonic-gate
73317Sdinak /* Check for help options. For CLIP-compliance. */
7343089Swyllys if (strcmp(argv[0], "-?") == 0) {
7353089Swyllys return (pk_help(argc, argv));
7363089Swyllys } else if (strcmp(argv[0], "-f") == 0 && argc == 2) {
7373089Swyllys rv = process_arg_file(argv[1], &pk_argv, &pk_argc);
7383089Swyllys if (rv)
7393089Swyllys return (rv);
7403089Swyllys } else if (argc >= 1 && argv[0][0] == '-') {
7413089Swyllys usage(-1);
7423089Swyllys return (1);
74317Sdinak }
74417Sdinak
74517Sdinak /* Always turns off Metaslot so that we can see softtoken. */
7460Sstevel@tonic-gate if (setenv("METASLOT_ENABLED", "false", 1) < 0) {
74717Sdinak save_errno = errno;
7480Sstevel@tonic-gate cryptoerror(LOG_STDERR,
74917Sdinak gettext("Disabling Metaslot failed (%s)."),
75017Sdinak strerror(save_errno));
7510Sstevel@tonic-gate return (1);
7520Sstevel@tonic-gate }
7530Sstevel@tonic-gate
7540Sstevel@tonic-gate /* Begin parsing command line. */
7553089Swyllys if (pk_argc == 0 && pk_argv == NULL) {
7563089Swyllys pk_argc = argc;
7573089Swyllys pk_argv = argv;
7583089Swyllys }
7590Sstevel@tonic-gate
76017Sdinak /* Check for valid verb (or an abbreviation of it). */
7610Sstevel@tonic-gate found = -1;
7620Sstevel@tonic-gate for (i = 0; i < num_cmds; i++) {
7630Sstevel@tonic-gate if (strcmp(cmds[i].verb, pk_argv[0]) == 0) {
7640Sstevel@tonic-gate if (found < 0) {
7650Sstevel@tonic-gate found = i;
7660Sstevel@tonic-gate break;
7670Sstevel@tonic-gate }
7680Sstevel@tonic-gate }
7690Sstevel@tonic-gate }
7700Sstevel@tonic-gate /* Stop here if no valid verb found. */
7710Sstevel@tonic-gate if (found < 0) {
77217Sdinak cryptoerror(LOG_STDERR, gettext("Invalid verb: %s"),
77317Sdinak pk_argv[0]);
7740Sstevel@tonic-gate return (1);
7750Sstevel@tonic-gate }
7760Sstevel@tonic-gate
7770Sstevel@tonic-gate /* Get to work! */
7780Sstevel@tonic-gate rv = (*cmds[found].action)(pk_argc, pk_argv);
7790Sstevel@tonic-gate switch (rv) {
7800Sstevel@tonic-gate case PK_ERR_NONE:
7810Sstevel@tonic-gate break; /* Command succeeded, do nothing. */
7820Sstevel@tonic-gate case PK_ERR_USAGE:
7833089Swyllys usage(found);
7840Sstevel@tonic-gate break;
7850Sstevel@tonic-gate case PK_ERR_QUIT:
7860Sstevel@tonic-gate exit(0);
7870Sstevel@tonic-gate /* NOTREACHED */
78817Sdinak case PK_ERR_PK11:
78917Sdinak case PK_ERR_SYSTEM:
79017Sdinak case PK_ERR_OPENSSL:
7913089Swyllys case PK_ERR_NSS:
7920Sstevel@tonic-gate default:
7930Sstevel@tonic-gate break;
7940Sstevel@tonic-gate }
7950Sstevel@tonic-gate return (rv);
7960Sstevel@tonic-gate }
797