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 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
22 */
23
24 #include <stdio.h>
25 #include <strings.h>
26 #include <ctype.h>
27 #include <libgen.h>
28 #include <libintl.h>
29 #include <errno.h>
30 #include <sys/stat.h>
31 #include <kmfapiP.h>
32 #include "util.h"
33
34 #define LIB_NSS_PATH "/usr/lib/mps/libnss3.so"
35 #define LIB_NSPR_PATH "/usr/lib/mps/libnspr4.so"
36
37 static void
show_policy(KMF_POLICY_RECORD * plc)38 show_policy(KMF_POLICY_RECORD *plc)
39 {
40 int i;
41 if (plc == NULL)
42 return;
43
44 (void) printf("Name: %s\n", plc->name);
45
46 (void) printf(gettext("Ignore Date: %s\n"),
47 plc->ignore_date ? gettext("true") : gettext("false"));
48
49 (void) printf(gettext("Ignore Unknown EKUs: %s\n"),
50 plc->ignore_unknown_ekus ? gettext("true") : gettext("false"));
51
52 (void) printf(gettext("Ignore TA: %s\n"),
53 plc->ignore_trust_anchor ? gettext("true") : gettext("false"));
54
55 (void) printf(gettext("Validity Adjusted Time: %s\n"),
56 plc->validity_adjusttime ? plc->validity_adjusttime : "<null>");
57
58 if (plc->ta_name == NULL && plc->ta_serial == NULL) {
59 (void) printf(gettext("Trust Anchor Certificate: <null>\n"));
60 } else if (strcasecmp(plc->ta_name, "search") == 0) {
61 (void) printf(gettext("Trust Anchor Certificate: "
62 "Search by Issuer\n"));
63 } else {
64 (void) printf(gettext("Trust Anchor Certificate:\n"));
65 (void) printf(gettext("\tName: %s\n"),
66 plc->ta_name ? plc->ta_name : "<null>");
67 (void) printf(gettext("\tSerial Number: %s\n"),
68 plc->ta_serial ? plc->ta_serial : "<null>");
69 }
70
71 if (plc->ku_bits != 0) {
72 (void) printf(gettext("Key Usage Bits: "));
73 for (i = KULOWBIT; i <= KUHIGHBIT; i++) {
74 char *s = kmf_ku_to_string(
75 (plc->ku_bits & (1<<i)));
76 if (s != NULL) {
77 (void) printf("%s ", s);
78 }
79 }
80 (void) printf("\n");
81 } else {
82 (void) printf(gettext("Key Usage Bits: 0\n"));
83 }
84
85 if (plc->eku_set.eku_count > 0) {
86 (void) printf(gettext("Extended Key Usage Values:\n"));
87 for (i = 0; i < plc->eku_set.eku_count; i++) {
88 char *s = kmf_oid_to_ekuname(
89 &plc->eku_set.ekulist[i]);
90 (void) printf("\t%s\t(%s)\n",
91 kmf_oid_to_string(&plc->eku_set.ekulist[i]),
92 s ? s : "unknown");
93 }
94 } else {
95 (void) printf(gettext("Extended Key Usage Values: <null>\n"));
96 }
97
98 (void) printf(gettext("Validation Policy Information:\n"));
99
100 if (plc->revocation & KMF_REVOCATION_METHOD_OCSP) {
101 (void) printf(gettext(" OCSP:\n"));
102
103 (void) printf(gettext("\tResponder URI: %s\n"),
104 plc->VAL_OCSP_BASIC.responderURI ?
105 plc->VAL_OCSP_BASIC.responderURI : "<null>");
106
107 (void) printf(gettext("\tProxy: %s\n"),
108 plc->VAL_OCSP_BASIC.proxy ?
109 plc->VAL_OCSP_BASIC.proxy : "<null>");
110
111 (void) printf(gettext("\tUse ResponderURI from Certificate: "
112 "%s\n"), plc->VAL_OCSP_BASIC.uri_from_cert ?
113 gettext("true") : gettext("false"));
114
115 (void) printf(gettext("\tResponse lifetime: %s\n"),
116 plc->VAL_OCSP_BASIC.response_lifetime ?
117 plc->VAL_OCSP_BASIC.response_lifetime : "<null>");
118
119 (void) printf(gettext("\tIgnore Response signature: %s\n"),
120 plc->VAL_OCSP_BASIC.ignore_response_sign ?
121 gettext("true") : gettext("false"));
122
123 if (!plc->VAL_OCSP.has_resp_cert) {
124 (void) printf(gettext("\tResponder Certificate:"
125 " <null>\n"));
126 } else {
127 (void) printf(gettext("\tResponder Certificate:\n"));
128 (void) printf(gettext("\t\tName: %s\n"),
129 plc->VAL_OCSP_RESP_CERT.name ?
130 plc->VAL_OCSP_RESP_CERT.name : "<null>");
131 (void) printf(gettext("\t\tSerial: %s\n"),
132 plc->VAL_OCSP_RESP_CERT.serial ?
133 plc->VAL_OCSP_RESP_CERT.serial : "<null>");
134 }
135 }
136
137 if (plc->revocation & KMF_REVOCATION_METHOD_CRL) {
138 (void) printf(gettext(" CRL:\n"));
139
140 (void) printf(gettext("\tBase filename: %s\n"),
141 plc->validation_info.crl_info.basefilename ?
142 plc->validation_info.crl_info.basefilename : "<null>");
143
144 (void) printf(gettext("\tDirectory: %s\n"),
145 plc->validation_info.crl_info.directory ?
146 plc->validation_info.crl_info.directory : "<null>");
147
148 (void) printf(gettext("\tDownload and cache CRL: %s\n"),
149 plc->validation_info.crl_info.get_crl_uri ?
150 gettext("true") : gettext("false"));
151
152 (void) printf(gettext("\tProxy: %s\n"),
153 plc->validation_info.crl_info.proxy ?
154 plc->validation_info.crl_info.proxy : "<null>");
155
156 (void) printf(gettext("\tIgnore CRL signature: %s\n"),
157 plc->validation_info.crl_info.ignore_crl_sign ?
158 gettext("true") : gettext("false"));
159
160 (void) printf(gettext("\tIgnore CRL validity date: %s\n"),
161 plc->validation_info.crl_info.ignore_crl_date ?
162 gettext("true") : gettext("false"));
163 }
164 (void) printf(gettext("Mapper name: %s\n"),
165 plc->mapper.mapname ? plc->mapper.mapname : "<null>");
166 (void) printf(gettext("Mapper pathname: %s\n"),
167 plc->mapper.pathname ? plc->mapper.pathname : "<null>");
168 (void) printf(gettext("Mapper directory: %s\n"),
169 plc->mapper.dir ? plc->mapper.dir : "<null>");
170 (void) printf(gettext("Mapper options: %s\n"),
171 plc->mapper.options ? plc->mapper.options : "<null>");
172
173 (void) printf("\n");
174 }
175
176 void
show_plugin(void)177 show_plugin(void)
178 {
179 conf_entrylist_t *phead = NULL;
180 struct stat statbuf;
181
182 (void) printf(gettext("KMF plugin information:\n"));
183 (void) printf(gettext("-----------------------\n"));
184
185 /* List the built-in plugins */
186 (void) printf("pkcs11:kmf_pkcs11.so.1 (built-in)\n");
187 (void) printf("file:kmf_openssl.so.1 (built-in)\n");
188
189 /*
190 * If the NSS libraries are not installed in the system,
191 * then we will not show the nss plugin either.
192 */
193 if (stat(LIB_NSS_PATH, &statbuf) == 0 &&
194 stat(LIB_NSPR_PATH, &statbuf) == 0) {
195 (void) printf("nss:kmf_nss.so.1 (built-in)\n");
196 }
197
198 /* List non-default plugins, if there is any. */
199 if (get_entrylist(&phead) == KMF_OK) {
200 while (phead != NULL) {
201 (void) printf("%s:%s", phead->entry->keystore,
202 phead->entry->modulepath);
203
204 if (phead->entry->option == NULL)
205 (void) printf("\n");
206 else
207 (void) printf(";option=%s\n",
208 phead->entry->option);
209 phead = phead->next;
210 }
211 free_entrylist(phead);
212 }
213 }
214
215
216 int
kc_list(int argc,char * argv[])217 kc_list(int argc, char *argv[])
218 {
219 int rv = KC_OK;
220 int opt, found = 0;
221 extern int optind_av;
222 extern char *optarg_av;
223 char *filename = NULL;
224 char *policyname = NULL;
225 POLICY_LIST *plclist = NULL, *pnode;
226 int sanity_err = 0;
227 boolean_t list_plugin = B_FALSE;
228
229 while ((opt = getopt_av(argc, argv, "i:(dbfile)p:(policy)m(plugin)"))
230 != EOF) {
231 switch (opt) {
232 case 'i':
233 if (list_plugin)
234 rv = KC_ERR_USAGE;
235 else {
236 filename = get_string(optarg_av, &rv);
237 if (filename == NULL) {
238 (void) fprintf(stderr,
239 gettext("Error dbfile input.\n"));
240 }
241 }
242 break;
243 case 'p':
244 if (list_plugin)
245 rv = KC_ERR_USAGE;
246 else {
247 policyname = get_string(optarg_av, &rv);
248 if (policyname == NULL) {
249 (void) fprintf(stderr,
250 gettext("Error policy name.\n"));
251 }
252 }
253 break;
254 case 'm':
255 list_plugin = B_TRUE;
256 break;
257 default:
258 (void) fprintf(stderr,
259 gettext("Error input option.\n"));
260 rv = KC_ERR_USAGE;
261 break;
262 }
263 if (rv != KC_OK)
264 goto out;
265 }
266
267 /* No additional args allowed. */
268 argc -= optind_av;
269 if (argc) {
270 (void) fprintf(stderr,
271 gettext("Error input option\n"));
272 rv = KC_ERR_USAGE;
273 goto out;
274 }
275
276 if (list_plugin) {
277 show_plugin();
278 goto out;
279 }
280
281 if (filename == NULL) {
282 filename = strdup(KMF_DEFAULT_POLICY_FILE);
283 if (filename == NULL) {
284 rv = KC_ERR_MEMORY;
285 goto out;
286 }
287 }
288
289 /* Check the access permission of the policy DB */
290 if (access(filename, R_OK) < 0) {
291 int err = errno;
292 (void) fprintf(stderr,
293 gettext("Cannot access \"%s\" for list - %s\n"), filename,
294 strerror(err));
295 rv = KC_ERR_ACCESS;
296 goto out;
297 }
298
299 rv = load_policies(filename, &plclist);
300 if (rv != KMF_OK) {
301 goto out;
302 }
303
304 pnode = plclist;
305 while (pnode != NULL) {
306 if (policyname == NULL ||
307 strcmp(policyname, pnode->plc.name) == 0) {
308 KMF_POLICY_RECORD *plc = &pnode->plc;
309
310 found++;
311 rv = kmf_verify_policy(plc);
312 if (rv != KMF_OK) {
313 (void) fprintf(stderr, gettext(
314 "Policy Name: '%s' is invalid\n"),
315 plc->name);
316 sanity_err++;
317 } else {
318 show_policy(&pnode->plc);
319 }
320 }
321 pnode = pnode->next;
322 }
323
324 free_policy_list(plclist);
325
326 if (!found) {
327 if (policyname)
328 (void) fprintf(stderr, gettext(
329 "Cannot find policy '%s'\n"), policyname);
330 else
331 (void) fprintf(stderr, gettext("Cannot find "
332 "any policies to display\n"));
333 rv = KC_ERR_FIND_POLICY;
334 } else if (sanity_err) {
335 rv = KC_ERR_VERIFY_POLICY;
336 }
337
338 out:
339
340 if (filename != NULL)
341 free(filename);
342
343 if (policyname != NULL)
344 free(policyname);
345
346 return (rv);
347 }
348