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 2006 Sun Microsystems, Inc.  All rights reserved.
22  * Use is subject to license terms.
23  */
24 
25 #pragma ident	"%Z%%M%	%I%	%E% SMI"
26 
27 #include <stdio.h>
28 #include <strings.h>
29 #include <ctype.h>
30 #include <libgen.h>
31 #include <libintl.h>
32 #include <errno.h>
33 #include <kmfapiP.h>
34 
35 #include "util.h"
36 
37 static void
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 ?
57 		    plc->validity_adjusttime : "<null>");
58 
59 	if (plc->ta_name == NULL && plc->ta_serial == NULL) {
60 		(void) printf(gettext("Trust Anchor Certificate: <null>\n"));
61 	} else {
62 		(void) printf(gettext("Trust Anchor Certificate:\n"));
63 		(void) printf(gettext("\tName: %s\n"),
64 			plc->ta_name ? plc->ta_name : "<null>");
65 		(void) printf(gettext("\tSerial Number: %s\n"),
66 			plc->ta_serial ? plc->ta_serial : "<null>");
67 	}
68 
69 	if (plc->ku_bits != 0) {
70 		(void) printf(gettext("Key Usage Bits: "));
71 		for (i = KULOWBIT; i <= KUHIGHBIT; i++) {
72 			char *s = ku2str((plc->ku_bits & (1<<i)));
73 			if (s != NULL) {
74 				(void) printf("%s ", s);
75 			}
76 		}
77 		(void) printf("\n");
78 	} else {
79 		(void) printf(gettext("Key Usage Bits: 0\n"));
80 	}
81 
82 	if (plc->eku_set.eku_count > 0) {
83 		(void) printf(gettext("Extended Key Usage Values:\n"));
84 		for (i = 0; i < plc->eku_set.eku_count; i++) {
85 			char *s = KMF_OID2EKUString(&plc->eku_set.ekulist[i]);
86 			(void) printf("\t%s\t(%s)\n",
87 				KMF_OID2String(&plc->eku_set.ekulist[i]),
88 				s ? s : "unknown");
89 		}
90 	} else {
91 		(void) printf(gettext("Extended Key Usage Values: <null>\n"));
92 	}
93 
94 	(void) printf(gettext("Validation Policy Information:\n"));
95 
96 	if (plc->revocation & KMF_REVOCATION_METHOD_OCSP) {
97 		(void) printf(gettext("    OCSP:\n"));
98 
99 		(void) printf(gettext("\tResponder URI: %s\n"),
100 		    plc->VAL_OCSP_BASIC.responderURI ?
101 		    plc->VAL_OCSP_BASIC.responderURI : "<null>");
102 
103 		(void) printf(gettext("\tProxy: %s\n"),
104 		    plc->VAL_OCSP_BASIC.proxy ?
105 		    plc->VAL_OCSP_BASIC.proxy : "<null>");
106 
107 		(void) printf(gettext("\tUse ResponderURI from Certificate: "
108 		    "%s\n"), plc->VAL_OCSP_BASIC.uri_from_cert ?
109 		    gettext("true") : gettext("false"));
110 
111 		(void) printf(gettext("\tResponse lifetime: %s\n"),
112 		    plc->VAL_OCSP_BASIC.response_lifetime ?
113 		    plc->VAL_OCSP_BASIC.response_lifetime : "<null>");
114 
115 		(void) printf(gettext("\tIgnore Response signature: %s\n"),
116 		    plc->VAL_OCSP_BASIC.ignore_response_sign ?
117 		    gettext("true") : gettext("false"));
118 
119 		if (!plc->VAL_OCSP.has_resp_cert) {
120 			(void) printf(gettext("\tResponder Certificate:"
121 			    " <null>\n"));
122 		} else {
123 			(void) printf(gettext("\tResponder Certificate:\n"));
124 			(void) printf(gettext("\t\tName: %s\n"),
125 			    plc->VAL_OCSP_RESP_CERT.name ?
126 			    plc->VAL_OCSP_RESP_CERT.name : "<null>");
127 			(void) printf(gettext("\t\tSerial: %s\n"),
128 			    plc->VAL_OCSP_RESP_CERT.serial ?
129 			    plc->VAL_OCSP_RESP_CERT.serial : "<null>");
130 		}
131 	}
132 
133 	if (plc->revocation & KMF_REVOCATION_METHOD_CRL) {
134 		(void) printf(gettext("    CRL:\n"));
135 
136 		(void) printf(gettext("\tBase filename: %s\n"),
137 		    plc->validation_info.crl_info.basefilename ?
138 		    plc->validation_info.crl_info.basefilename : "<null>");
139 
140 		(void) printf(gettext("\tDirectory: %s\n"),
141 		    plc->validation_info.crl_info.directory ?
142 		    plc->validation_info.crl_info.directory : "<null>");
143 
144 		(void) printf(gettext("\tDownload and cache CRL: %s\n"),
145 			plc->validation_info.crl_info.get_crl_uri ?
146 			gettext("true") : gettext("false"));
147 
148 		(void) printf(gettext("\tProxy: %s\n"),
149 		    plc->validation_info.crl_info.proxy ?
150 		    plc->validation_info.crl_info.proxy : "<null>");
151 
152 		(void) printf(gettext("\tIgnore CRL signature: %s\n"),
153 			plc->validation_info.crl_info.ignore_crl_sign ?
154 			gettext("true") : gettext("false"));
155 
156 		(void) printf(gettext("\tIgnore CRL validity date: %s\n"),
157 			plc->validation_info.crl_info.ignore_crl_date ?
158 			gettext("true") : gettext("false"));
159 	}
160 
161 	(void) printf("\n");
162 }
163 
164 int
165 kc_list(int argc, char *argv[])
166 {
167 	int 		rv = KC_OK;
168 	int		opt, found = 0;
169 	extern int	optind_av;
170 	extern char	*optarg_av;
171 	char		*filename = NULL;
172 	char		*policyname = NULL;
173 	POLICY_LIST	*plclist = NULL, *pnode;
174 	int		sanity_err = 0;
175 
176 	while ((opt = getopt_av(argc, argv, "i:(dbfile)p:(policy)")) != EOF) {
177 		switch (opt) {
178 			case 'i':
179 				filename = get_string(optarg_av, &rv);
180 				if (filename == NULL) {
181 					(void) fprintf(stderr,
182 					    gettext("Error dbfile input.\n"));
183 				}
184 				break;
185 			case 'p':
186 				policyname = get_string(optarg_av, &rv);
187 				if (policyname == NULL) {
188 					(void) fprintf(stderr,
189 					    gettext("Error policy name.\n"));
190 				}
191 				break;
192 			default:
193 				(void) fprintf(stderr,
194 				    gettext("Error input option.\n"));
195 				rv = KC_ERR_USAGE;
196 				break;
197 		}
198 		if (rv != KC_OK)
199 			goto out;
200 	}
201 
202 	/* No additional args allowed. */
203 	argc -= optind_av;
204 	if (argc) {
205 		(void) fprintf(stderr,
206 		    gettext("Error input option\n"));
207 		rv = KC_ERR_USAGE;
208 		goto out;
209 	}
210 
211 	if (filename == NULL) {
212 		filename = strdup(KMF_DEFAULT_POLICY_FILE);
213 		if (filename == NULL) {
214 			rv = KC_ERR_MEMORY;
215 			goto out;
216 		}
217 	}
218 
219 	/* Check the access permission of the policy DB */
220 	if (access(filename, R_OK) < 0) {
221 		int err = errno;
222 		(void) fprintf(stderr,
223 		    gettext("Cannot access \"%s\" for list - %s\n"), filename,
224 		    strerror(err));
225 		rv = KC_ERR_ACCESS;
226 		goto out;
227 	}
228 
229 	rv = load_policies(filename, &plclist);
230 	if (rv != KMF_OK) {
231 		goto out;
232 	}
233 
234 	pnode = plclist;
235 	while (pnode != NULL) {
236 		if (policyname == NULL ||
237 			strcmp(policyname, pnode->plc.name) == 0) {
238 			KMF_POLICY_RECORD *plc = &pnode->plc;
239 
240 			found++;
241 			rv = KMF_VerifyPolicy(plc);
242 			if (rv != KMF_OK) {
243 				(void) fprintf(stderr, gettext(
244 				    "Policy Name: '%s' is invalid\n"),
245 				    plc->name);
246 				sanity_err++;
247 			} else {
248 				show_policy(&pnode->plc);
249 			}
250 		}
251 		pnode = pnode->next;
252 	}
253 
254 	free_policy_list(plclist);
255 
256 	if (!found) {
257 		if (policyname)
258 			(void) fprintf(stderr, gettext(
259 			    "Cannot find policy '%s'\n"), policyname);
260 		else
261 			(void) fprintf(stderr, gettext("Cannot find "
262 			    "any policies to display\n"));
263 		rv = KC_ERR_FIND_POLICY;
264 	} else if (sanity_err) {
265 		rv = KC_ERR_VERIFY_POLICY;
266 	}
267 
268 out:
269 
270 	if (filename != NULL)
271 		free(filename);
272 
273 	if (policyname != NULL)
274 		free(policyname);
275 
276 	return (rv);
277 }
278