xref: /titanic_50/usr/src/cmd/cmd-crypto/pktool/pktool.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
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, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * This file comprises the main driver for this tool.
31  */
32 
33 #include <stdio.h>
34 #include <string.h>
35 #include <ctype.h>
36 #include <malloc.h>
37 #include <libgen.h>
38 #include <errno.h>
39 #include <cryptoutil.h>
40 #include <security/cryptoki.h>
41 #include "common.h"
42 
43 /*
44  * The verbcmd construct allows genericizing information about a verb so
45  * that it is easier to manipulate.  Makes parsing code easier to read,
46  * fix, and extend with new verbs.
47  */
48 typedef struct verbcmd_s {
49 	char	*verb;
50 	int	(*action)(int, char *[]);
51 	int	mode;			/* reserved */
52 	char	*synopsis;		/* reserved */
53 } verbcmd;
54 
55 /* External declarations for supported verb actions. */
56 extern int	pk_setpin(int argc, char *argv[]);
57 
58 /* Command structure for verbs and their actions.  Do NOT i18n/l10n. */
59 static verbcmd	cmds[] = {
60 	{ "setpin",	pk_setpin,	0,	"" },
61 };
62 static int	num_cmds = sizeof (cmds) / sizeof (verbcmd);
63 
64 static char	*prog;
65 static void	usage(void);
66 
67 /*
68  * Usage information.  This function must be updated when new verbs or
69  * options are added.
70  */
71 static void
72 usage(void)
73 {
74 	(void) fprintf(stderr, gettext("Usage:\n"));
75 	(void) fprintf(stderr, gettext("\t%s setpin\n"), prog);
76 }
77 
78 /*
79  * MAIN() -- where all the action is
80  */
81 int
82 main(int argc, char *argv[], char *envp[])
83 /* ARGSUSED2 */
84 {
85 	int	i, found = -1;
86 	int	rv;
87 	int	pk_argc = 0;
88 	char	**pk_argv = NULL;
89 
90 	/* Set up for i18n/l10n. */
91 	(void) setlocale(LC_ALL, "");
92 #if !defined(TEXT_DOMAIN)		/* Should be defined by cc -D. */
93 #define	TEXT_DOMAIN	"SYS_TEST"	/* Use this only if it isn't. */
94 #endif
95 	(void) textdomain(TEXT_DOMAIN);
96 
97 	/* Get program base name and move pointer over 0th arg. */
98 	prog = basename(argv[0]);
99 	argv++, argc--;
100 
101 	/* Set up for debug and error output. */
102 	cryptodebug_init(prog);
103 
104 	/* There must be one remaining arg at this point */
105 	if (argc == 0) {
106 		usage();
107 		return (1);
108 	}
109 
110 	/*
111 	 * By default, metaslot is enabled, and pkcs11_softtoken is
112 	 * the keystore, so, pkcs11_softtoken is hidden.
113 	 * Always turns off Metaslot so that we can see pkcs11_softtoken.
114 	 */
115 	if (setenv("METASLOT_ENABLED", "false", 1) < 0) {
116 		pk11_errno = errno;
117 		cryptoerror(LOG_STDERR,
118 		    gettext("Disabling metaslot failed: %s"),
119 		    strerror(pk11_errno));
120 		return (1);
121 	}
122 
123 	/* Begin parsing command line. */
124 	pk_argc = argc;
125 	pk_argv = argv;
126 
127 	/* Check for valid verb */
128 	found = -1;
129 	for (i = 0; i < num_cmds; i++) {
130 		if (strcmp(cmds[i].verb, pk_argv[0]) == 0) {
131 			if (found < 0) {
132 				found = i;
133 				break;
134 			}
135 		}
136 	}
137 
138 	/* Stop here if no valid verb found. */
139 	if (found < 0) {
140 		cryptoerror(LOG_STDERR,
141 			gettext("Invalid verb: %s"), pk_argv[0]);
142 		return (1);
143 	}
144 
145 	/* Get to work! */
146 	rv = (*cmds[found].action)(pk_argc, pk_argv);
147 	switch (rv) {
148 	case PK_ERR_NONE:
149 		break;		/* Command succeeded, do nothing. */
150 	case PK_ERR_USAGE:
151 		usage();
152 		break;
153 	case PK_ERR_QUIT:
154 		exit(0);
155 		/* NOTREACHED */
156 	case PK_ERR_PK11INIT:
157 		cryptoerror(LOG_STDERR, "%s (%s)",
158 		    gettext("Unable to initialize PKCS#11"),
159 		    pkcs11_strerror(pk11_errno));
160 		cryptodebug("C_Initialize failed (%s)",
161 		    pkcs11_strerror(pk11_errno));
162 		break;
163 	case PK_ERR_PK11SLOTS:
164 		cryptoerror(LOG_STDERR, "%s (%s)",
165 		    gettext("Failed to find PKCS#11 slots"),
166 		    pkcs11_strerror(pk11_errno));
167 		cryptodebug("C_GetSlotList failed (%s)",
168 		    pkcs11_strerror(pk11_errno));
169 		break;
170 	case PK_ERR_PK11SESSION:
171 		cryptoerror(LOG_STDERR, "%s (%s)",
172 		    gettext("Unable to open PKCS#11 session"),
173 		    pkcs11_strerror(pk11_errno));
174 		cryptodebug("C_OpenSession failed (%s)",
175 		    pkcs11_strerror(pk11_errno));
176 		break;
177 	case PK_ERR_PK11LOGIN:
178 		if (pk11_errno == CKR_PIN_INCORRECT)
179 			cryptoerror(LOG_STDERR, "%s", gettext("Incorrect PIN"));
180 		else {
181 			cryptoerror(LOG_STDERR, "%s (%s)",
182 			    gettext("PKCS#11 authentication failed"),
183 			    pkcs11_strerror(pk11_errno));
184 			cryptodebug("C_Login failed (%s)",
185 			    pkcs11_strerror(pk11_errno));
186 		}
187 		break;
188 	case PK_ERR_PK11SETPIN:
189 		cryptoerror(LOG_STDERR, "%s (%s)",
190 		    gettext("Set PIN failed"), pkcs11_strerror(pk11_errno));
191 		break;
192 	case PK_ERR_NOSLOTS:
193 		cryptoerror(LOG_STDERR, "%s", gettext("No slots were found"));
194 		break;
195 	case PK_ERR_NOMEMORY:
196 		cryptoerror(LOG_STDERR, "%s", gettext("Out of memory"));
197 		break;
198 	case PK_ERR_NOTFOUND:
199 		cryptoerror(LOG_STDERR, "%s", gettext("Token name not found"));
200 		break;
201 	case PK_ERR_PASSPHRASE:
202 		cryptoerror(LOG_STDERR, "%s",
203 		    gettext("Unable to get token PIN"));
204 		break;
205 	case PK_ERR_NEWPIN:
206 		cryptoerror(LOG_STDERR, "%s", gettext("Failed to get new PIN"));
207 		break;
208 	case PK_ERR_PINCONFIRM:
209 		cryptoerror(LOG_STDERR, "%s",
210 		    gettext("Failed to confirm new PIN"));
211 		break;
212 	case PK_ERR_PINMATCH:
213 		cryptoerror(LOG_STDERR, "%s", gettext("PINs do not match"));
214 		break;
215 	case PK_ERR_CHANGEPIN:
216 		cryptoerror(LOG_STDERR, "%s", gettext("PIN must be changed"));
217 		break;
218 	default:
219 		cryptoerror(LOG_STDERR, "%s (%d)",
220 		    gettext("Unknown error value"), rv);
221 		break;
222 	}
223 	return (rv);
224 }
225