xref: /onnv-gate/usr/src/cmd/cmd-crypto/kmfcfg/create.c (revision 3089:8ddeb2ace8aa)
1*3089Swyllys /*
2*3089Swyllys  * CDDL HEADER START
3*3089Swyllys  *
4*3089Swyllys  * The contents of this file are subject to the terms of the
5*3089Swyllys  * Common Development and Distribution License (the "License").
6*3089Swyllys  * You may not use this file except in compliance with the License.
7*3089Swyllys  *
8*3089Swyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*3089Swyllys  * or http://www.opensolaris.org/os/licensing.
10*3089Swyllys  * See the License for the specific language governing permissions
11*3089Swyllys  * and limitations under the License.
12*3089Swyllys  *
13*3089Swyllys  * When distributing Covered Code, include this CDDL HEADER in each
14*3089Swyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*3089Swyllys  * If applicable, add the following below this CDDL HEADER, with the
16*3089Swyllys  * fields enclosed by brackets "[]" replaced with your own identifying
17*3089Swyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
18*3089Swyllys  *
19*3089Swyllys  * CDDL HEADER END
20*3089Swyllys  *
21*3089Swyllys  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
22*3089Swyllys  * Use is subject to license terms.
23*3089Swyllys  */
24*3089Swyllys 
25*3089Swyllys #pragma ident	"%Z%%M%	%I%	%E% SMI"
26*3089Swyllys 
27*3089Swyllys #include <stdio.h>
28*3089Swyllys #include <strings.h>
29*3089Swyllys #include <ctype.h>
30*3089Swyllys #include <libgen.h>
31*3089Swyllys #include <libintl.h>
32*3089Swyllys #include <errno.h>
33*3089Swyllys #include <kmfapiP.h>
34*3089Swyllys #include <cryptoutil.h>
35*3089Swyllys #include "util.h"
36*3089Swyllys 
37*3089Swyllys int
38*3089Swyllys kc_create(int argc, char *argv[])
39*3089Swyllys {
40*3089Swyllys 	KMF_RETURN	ret;
41*3089Swyllys 	int 		rv = KC_OK;
42*3089Swyllys 	int		opt;
43*3089Swyllys 	extern int	optind_av;
44*3089Swyllys 	extern char	*optarg_av;
45*3089Swyllys 	char		*filename = NULL;
46*3089Swyllys 	int		ocsp_set_attr = 0;
47*3089Swyllys 	boolean_t	crl_set_attr = 0;
48*3089Swyllys 	KMF_POLICY_RECORD plc;
49*3089Swyllys 
50*3089Swyllys 	(void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD));
51*3089Swyllys 
52*3089Swyllys 	while ((opt = getopt_av(argc, argv,
53*3089Swyllys 		"i:(dbfile)"
54*3089Swyllys 		"p:(policy)"
55*3089Swyllys 		"d:(ignore-date)"
56*3089Swyllys 		"e:(ignore-unknown-eku)"
57*3089Swyllys 		"a:(ignore-trust-anchor)"
58*3089Swyllys 		"v:(validity-adjusttime)"
59*3089Swyllys 		"t:(ta-name)"
60*3089Swyllys 		"s:(ta-serial)"
61*3089Swyllys 		"o:(ocsp-responder)"
62*3089Swyllys 		"P:(ocsp-proxy)"
63*3089Swyllys 		"r:(ocsp-use-cert-responder)"
64*3089Swyllys 		"T:(ocsp-response-lifetime)"
65*3089Swyllys 		"R:(ocsp-ignore-response-sign)"
66*3089Swyllys 		"n:(ocsp-responder-cert-name)"
67*3089Swyllys 		"A:(ocsp-responder-cert-serial)"
68*3089Swyllys 		"c:(crl-basefilename)"
69*3089Swyllys 		"I:(crl-directory)"
70*3089Swyllys 		"g:(crl-get-crl-uri)"
71*3089Swyllys 		"X:(crl-proxy)"
72*3089Swyllys 		"S:(crl-ignore-crl-sign)"
73*3089Swyllys 		"D:(crl-ignore-crl-date)"
74*3089Swyllys 		"u:(keyusage)"
75*3089Swyllys 		"E:(ekunames)"
76*3089Swyllys 		"O:(ekuoids)")) != EOF) {
77*3089Swyllys 		switch (opt) {
78*3089Swyllys 			case 'i':
79*3089Swyllys 				filename = get_string(optarg_av, &rv);
80*3089Swyllys 				if (filename == NULL) {
81*3089Swyllys 					(void) fprintf(stderr,
82*3089Swyllys 					    gettext("Error dbfile input.\n"));
83*3089Swyllys 				}
84*3089Swyllys 				break;
85*3089Swyllys 			case 'p':
86*3089Swyllys 				plc.name = get_string(optarg_av, &rv);
87*3089Swyllys 				if (plc.name == NULL) {
88*3089Swyllys 					(void) fprintf(stderr,
89*3089Swyllys 					    gettext("Error policy name.\n"));
90*3089Swyllys 				}
91*3089Swyllys 				break;
92*3089Swyllys 			case 'd':
93*3089Swyllys 				plc.ignore_date = get_boolean(optarg_av);
94*3089Swyllys 				if (plc.ignore_date == -1) {
95*3089Swyllys 					(void) fprintf(stderr,
96*3089Swyllys 					    gettext("Error boolean input.\n"));
97*3089Swyllys 					rv = KC_ERR_USAGE;
98*3089Swyllys 				}
99*3089Swyllys 				break;
100*3089Swyllys 			case 'e':
101*3089Swyllys 				plc.ignore_unknown_ekus =
102*3089Swyllys 				    get_boolean(optarg_av);
103*3089Swyllys 				if (plc.ignore_unknown_ekus == -1) {
104*3089Swyllys 					(void) fprintf(stderr,
105*3089Swyllys 					    gettext("Error boolean input.\n"));
106*3089Swyllys 					rv = KC_ERR_USAGE;
107*3089Swyllys 				}
108*3089Swyllys 				break;
109*3089Swyllys 			case 'a':
110*3089Swyllys 				plc.ignore_trust_anchor =
111*3089Swyllys 				    get_boolean(optarg_av);
112*3089Swyllys 				if (plc.ignore_trust_anchor == -1) {
113*3089Swyllys 					(void) fprintf(stderr,
114*3089Swyllys 					    gettext("Error boolean input.\n"));
115*3089Swyllys 					rv = KC_ERR_USAGE;
116*3089Swyllys 				}
117*3089Swyllys 				break;
118*3089Swyllys 			case 'v':
119*3089Swyllys 				plc.validity_adjusttime =
120*3089Swyllys 				    get_string(optarg_av, &rv);
121*3089Swyllys 				if (plc.validity_adjusttime == NULL) {
122*3089Swyllys 					(void) fprintf(stderr,
123*3089Swyllys 					    gettext("Error time input.\n"));
124*3089Swyllys 				} else {
125*3089Swyllys 					uint32_t adj;
126*3089Swyllys 					/* for syntax checking */
127*3089Swyllys 					if (str2lifetime(
128*3089Swyllys 					    plc.validity_adjusttime,
129*3089Swyllys 					    &adj) < 0) {
130*3089Swyllys 						(void) fprintf(stderr,
131*3089Swyllys 						    gettext("Error time "
132*3089Swyllys 						    "input.\n"));
133*3089Swyllys 						rv = KC_ERR_USAGE;
134*3089Swyllys 					}
135*3089Swyllys 				}
136*3089Swyllys 				break;
137*3089Swyllys 			case 't':
138*3089Swyllys 				plc.ta_name = get_string(optarg_av, &rv);
139*3089Swyllys 				if (plc.ta_name == NULL) {
140*3089Swyllys 					(void) fprintf(stderr,
141*3089Swyllys 					    gettext("Error name input.\n"));
142*3089Swyllys 				} else {
143*3089Swyllys 					KMF_X509_NAME taDN;
144*3089Swyllys 					/* for syntax checking */
145*3089Swyllys 					if (KMF_DNParser(plc.ta_name,
146*3089Swyllys 					    &taDN) != KMF_OK) {
147*3089Swyllys 						(void) fprintf(stderr,
148*3089Swyllys 						    gettext("Error name "
149*3089Swyllys 						    "input.\n"));
150*3089Swyllys 						rv = KC_ERR_USAGE;
151*3089Swyllys 					} else {
152*3089Swyllys 						KMF_FreeDN(&taDN);
153*3089Swyllys 					}
154*3089Swyllys 				}
155*3089Swyllys 				break;
156*3089Swyllys 			case 's':
157*3089Swyllys 				plc.ta_serial = get_string(optarg_av, &rv);
158*3089Swyllys 				if (plc.ta_serial == NULL) {
159*3089Swyllys 					(void) fprintf(stderr,
160*3089Swyllys 					    gettext("Error serial input.\n"));
161*3089Swyllys 				} else {
162*3089Swyllys 					uchar_t *bytes = NULL;
163*3089Swyllys 					size_t bytelen;
164*3089Swyllys 
165*3089Swyllys 					ret = KMF_HexString2Bytes(
166*3089Swyllys 					    (uchar_t *)plc.ta_serial,
167*3089Swyllys 					    &bytes, &bytelen);
168*3089Swyllys 					if (ret != KMF_OK || bytes == NULL) {
169*3089Swyllys 						(void) fprintf(stderr,
170*3089Swyllys 						    gettext("serial number "
171*3089Swyllys 						    "must be specified as a "
172*3089Swyllys 						    "hex number "
173*3089Swyllys 						    "(ex: 0x0102030405"
174*3089Swyllys 						    "ffeeddee)\n"));
175*3089Swyllys 						rv = KC_ERR_USAGE;
176*3089Swyllys 					}
177*3089Swyllys 					if (bytes != NULL)
178*3089Swyllys 						free(bytes);
179*3089Swyllys 				}
180*3089Swyllys 				break;
181*3089Swyllys 			case 'o':
182*3089Swyllys 				plc.VAL_OCSP_RESPONDER_URI =
183*3089Swyllys 				    get_string(optarg_av, &rv);
184*3089Swyllys 				if (plc.VAL_OCSP_RESPONDER_URI == NULL) {
185*3089Swyllys 					(void) fprintf(stderr, gettext(
186*3089Swyllys 					    "Error responder input.\n"));
187*3089Swyllys 				} else {
188*3089Swyllys 					ocsp_set_attr++;
189*3089Swyllys 				}
190*3089Swyllys 				break;
191*3089Swyllys 			case 'P':
192*3089Swyllys 				plc.VAL_OCSP_PROXY =
193*3089Swyllys 				    get_string(optarg_av, &rv);
194*3089Swyllys 				if (plc.VAL_OCSP_PROXY == NULL) {
195*3089Swyllys 					(void) fprintf(stderr,
196*3089Swyllys 					    gettext("Error proxy input.\n"));
197*3089Swyllys 				} else {
198*3089Swyllys 					ocsp_set_attr++;
199*3089Swyllys 				}
200*3089Swyllys 				break;
201*3089Swyllys 			case 'r':
202*3089Swyllys 				plc.VAL_OCSP_URI_FROM_CERT =
203*3089Swyllys 				    get_boolean(optarg_av);
204*3089Swyllys 				if (plc.VAL_OCSP_URI_FROM_CERT == -1) {
205*3089Swyllys 					(void) fprintf(stderr,
206*3089Swyllys 					    gettext("Error boolean input.\n"));
207*3089Swyllys 					rv = KC_ERR_USAGE;
208*3089Swyllys 				} else {
209*3089Swyllys 					ocsp_set_attr++;
210*3089Swyllys 				}
211*3089Swyllys 				break;
212*3089Swyllys 			case 'T':
213*3089Swyllys 				plc.VAL_OCSP_RESP_LIFETIME =
214*3089Swyllys 				    get_string(optarg_av, &rv);
215*3089Swyllys 				if (plc.VAL_OCSP_RESP_LIFETIME == NULL) {
216*3089Swyllys 					(void) fprintf(stderr,
217*3089Swyllys 					    gettext("Error time input.\n"));
218*3089Swyllys 				} else {
219*3089Swyllys 					uint32_t adj;
220*3089Swyllys 					/* for syntax checking */
221*3089Swyllys 					if (str2lifetime(
222*3089Swyllys 					    plc.VAL_OCSP_RESP_LIFETIME,
223*3089Swyllys 					    &adj) < 0) {
224*3089Swyllys 						(void) fprintf(stderr,
225*3089Swyllys 						    gettext("Error time "
226*3089Swyllys 						    "input.\n"));
227*3089Swyllys 						rv = KC_ERR_USAGE;
228*3089Swyllys 					} else {
229*3089Swyllys 						ocsp_set_attr++;
230*3089Swyllys 					}
231*3089Swyllys 				}
232*3089Swyllys 				break;
233*3089Swyllys 			case 'R':
234*3089Swyllys 				plc.VAL_OCSP_IGNORE_RESP_SIGN =
235*3089Swyllys 				    get_boolean(optarg_av);
236*3089Swyllys 				if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) {
237*3089Swyllys 					(void) fprintf(stderr,
238*3089Swyllys 					    gettext("Error boolean input.\n"));
239*3089Swyllys 					rv = KC_ERR_USAGE;
240*3089Swyllys 				} else {
241*3089Swyllys 					ocsp_set_attr++;
242*3089Swyllys 				}
243*3089Swyllys 				break;
244*3089Swyllys 			case 'n':
245*3089Swyllys 				plc.VAL_OCSP_RESP_CERT_NAME =
246*3089Swyllys 				    get_string(optarg_av, &rv);
247*3089Swyllys 				if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) {
248*3089Swyllys 					(void) fprintf(stderr,
249*3089Swyllys 					    gettext("Error name input.\n"));
250*3089Swyllys 				} else {
251*3089Swyllys 					KMF_X509_NAME respDN;
252*3089Swyllys 					/* for syntax checking */
253*3089Swyllys 					if (KMF_DNParser(
254*3089Swyllys 					    plc.VAL_OCSP_RESP_CERT_NAME,
255*3089Swyllys 					    &respDN) != KMF_OK) {
256*3089Swyllys 						(void) fprintf(stderr,
257*3089Swyllys 						    gettext("Error name "
258*3089Swyllys 						    "input.\n"));
259*3089Swyllys 						rv = KC_ERR_USAGE;
260*3089Swyllys 					} else {
261*3089Swyllys 						KMF_FreeDN(&respDN);
262*3089Swyllys 						ocsp_set_attr++;
263*3089Swyllys 					}
264*3089Swyllys 				}
265*3089Swyllys 				break;
266*3089Swyllys 			case 'A':
267*3089Swyllys 				plc.VAL_OCSP_RESP_CERT_SERIAL =
268*3089Swyllys 				    get_string(optarg_av, &rv);
269*3089Swyllys 				if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) {
270*3089Swyllys 					(void) fprintf(stderr,
271*3089Swyllys 					    gettext("Error serial input.\n"));
272*3089Swyllys 				} else {
273*3089Swyllys 					uchar_t *bytes = NULL;
274*3089Swyllys 					size_t bytelen;
275*3089Swyllys 
276*3089Swyllys 					ret = KMF_HexString2Bytes((uchar_t *)
277*3089Swyllys 					    plc.VAL_OCSP_RESP_CERT_SERIAL,
278*3089Swyllys 					    &bytes, &bytelen);
279*3089Swyllys 					if (ret != KMF_OK || bytes == NULL) {
280*3089Swyllys 						(void) fprintf(stderr,
281*3089Swyllys 						    gettext("serial number "
282*3089Swyllys 						    "must be specified as a "
283*3089Swyllys 						    "hex number "
284*3089Swyllys 						    "(ex: 0x0102030405"
285*3089Swyllys 						    "ffeeddee)\n"));
286*3089Swyllys 						rv = KC_ERR_USAGE;
287*3089Swyllys 						break;
288*3089Swyllys 					}
289*3089Swyllys 					if (bytes != NULL)
290*3089Swyllys 						free(bytes);
291*3089Swyllys 					ocsp_set_attr++;
292*3089Swyllys 				}
293*3089Swyllys 				break;
294*3089Swyllys 			case 'c':
295*3089Swyllys 				plc.VAL_CRL_BASEFILENAME =
296*3089Swyllys 				    get_string(optarg_av, &rv);
297*3089Swyllys 				if (plc.VAL_CRL_BASEFILENAME == NULL) {
298*3089Swyllys 					(void) fprintf(stderr,
299*3089Swyllys 					    gettext("Error boolean input.\n"));
300*3089Swyllys 				} else {
301*3089Swyllys 					crl_set_attr++;
302*3089Swyllys 				}
303*3089Swyllys 				break;
304*3089Swyllys 			case 'I':
305*3089Swyllys 				plc.VAL_CRL_DIRECTORY =
306*3089Swyllys 				    get_string(optarg_av, &rv);
307*3089Swyllys 				if (plc.VAL_CRL_DIRECTORY == NULL) {
308*3089Swyllys 					(void) fprintf(stderr,
309*3089Swyllys 					    gettext("Error boolean input.\n"));
310*3089Swyllys 				} else {
311*3089Swyllys 					crl_set_attr++;
312*3089Swyllys 				}
313*3089Swyllys 				break;
314*3089Swyllys 			case 'g':
315*3089Swyllys 				plc.VAL_CRL_GET_URI = get_boolean(optarg_av);
316*3089Swyllys 				if (plc.VAL_CRL_GET_URI == -1) {
317*3089Swyllys 					(void) fprintf(stderr,
318*3089Swyllys 					    gettext("Error boolean input.\n"));
319*3089Swyllys 					rv = KC_ERR_USAGE;
320*3089Swyllys 				} else {
321*3089Swyllys 					crl_set_attr++;
322*3089Swyllys 				}
323*3089Swyllys 				break;
324*3089Swyllys 			case 'X':
325*3089Swyllys 				plc.VAL_CRL_PROXY = get_string(optarg_av, &rv);
326*3089Swyllys 				if (plc.VAL_CRL_PROXY == NULL) {
327*3089Swyllys 					(void) fprintf(stderr,
328*3089Swyllys 					    gettext("Error proxy input.\n"));
329*3089Swyllys 				} else {
330*3089Swyllys 					crl_set_attr++;
331*3089Swyllys 				}
332*3089Swyllys 				break;
333*3089Swyllys 			case 'S':
334*3089Swyllys 				plc.VAL_CRL_IGNORE_SIGN =
335*3089Swyllys 				    get_boolean(optarg_av);
336*3089Swyllys 				if (plc.VAL_CRL_IGNORE_SIGN == -1) {
337*3089Swyllys 					(void) fprintf(stderr,
338*3089Swyllys 					    gettext("Error boolean input.\n"));
339*3089Swyllys 					rv = KC_ERR_USAGE;
340*3089Swyllys 				} else {
341*3089Swyllys 					crl_set_attr++;
342*3089Swyllys 				}
343*3089Swyllys 				break;
344*3089Swyllys 			case 'D':
345*3089Swyllys 				plc.VAL_CRL_IGNORE_DATE =
346*3089Swyllys 					get_boolean(optarg_av);
347*3089Swyllys 				if (plc.VAL_CRL_IGNORE_DATE == -1) {
348*3089Swyllys 					(void) fprintf(stderr,
349*3089Swyllys 					    gettext("Error boolean input.\n"));
350*3089Swyllys 					rv = KC_ERR_USAGE;
351*3089Swyllys 				} else {
352*3089Swyllys 					crl_set_attr++;
353*3089Swyllys 				}
354*3089Swyllys 				break;
355*3089Swyllys 			case 'u':
356*3089Swyllys 				plc.ku_bits = parseKUlist(optarg_av);
357*3089Swyllys 				if (plc.ku_bits == 0) {
358*3089Swyllys 					(void) fprintf(stderr, gettext(
359*3089Swyllys 					    "Error keyusage input.\n"));
360*3089Swyllys 					rv = KC_ERR_USAGE;
361*3089Swyllys 				}
362*3089Swyllys 				break;
363*3089Swyllys 			case 'E':
364*3089Swyllys 				if (parseEKUNames(optarg_av, &plc) != 0) {
365*3089Swyllys 					(void) fprintf(stderr,
366*3089Swyllys 					    gettext("Error EKU input.\n"));
367*3089Swyllys 					rv = KC_ERR_USAGE;
368*3089Swyllys 				}
369*3089Swyllys 				break;
370*3089Swyllys 			case 'O':
371*3089Swyllys 				if (parseEKUOIDs(optarg_av, &plc) != 0) {
372*3089Swyllys 					(void) fprintf(stderr,
373*3089Swyllys 					    gettext("Error EKU OID input.\n"));
374*3089Swyllys 					rv = KC_ERR_USAGE;
375*3089Swyllys 				}
376*3089Swyllys 				break;
377*3089Swyllys 			default:
378*3089Swyllys 				(void) fprintf(stderr,
379*3089Swyllys 				    gettext("Error input option.\n"));
380*3089Swyllys 				rv = KC_ERR_USAGE;
381*3089Swyllys 				break;
382*3089Swyllys 		}
383*3089Swyllys 
384*3089Swyllys 		if (rv != KC_OK)
385*3089Swyllys 			goto out;
386*3089Swyllys 	}
387*3089Swyllys 
388*3089Swyllys 	/* No additional args allowed. */
389*3089Swyllys 	argc -= optind_av;
390*3089Swyllys 	if (argc) {
391*3089Swyllys 		(void) fprintf(stderr,
392*3089Swyllys 		    gettext("Error input option\n"));
393*3089Swyllys 		rv = KC_ERR_USAGE;
394*3089Swyllys 		goto out;
395*3089Swyllys 	}
396*3089Swyllys 
397*3089Swyllys 	if (filename == NULL) {
398*3089Swyllys 		filename = strdup(KMF_DEFAULT_POLICY_FILE);
399*3089Swyllys 		if (filename == NULL) {
400*3089Swyllys 			rv = KC_ERR_MEMORY;
401*3089Swyllys 			goto out;
402*3089Swyllys 		}
403*3089Swyllys 	}
404*3089Swyllys 
405*3089Swyllys 	/*
406*3089Swyllys 	 * Must have a policy name. The policy name can not be default
407*3089Swyllys 	 * if using the default policy file.
408*3089Swyllys 	 */
409*3089Swyllys 	if (plc.name == NULL) {
410*3089Swyllys 		(void) fprintf(stderr,
411*3089Swyllys 		    gettext("You must specify a policy name\n"));
412*3089Swyllys 		rv = KC_ERR_USAGE;
413*3089Swyllys 		goto out;
414*3089Swyllys 	} else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 &&
415*3089Swyllys 	    strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) {
416*3089Swyllys 		(void) fprintf(stderr,
417*3089Swyllys 		    gettext("Can not create a default policy in the default "
418*3089Swyllys 		    "policy file\n"));
419*3089Swyllys 		rv = KC_ERR_USAGE;
420*3089Swyllys 		goto out;
421*3089Swyllys 	}
422*3089Swyllys 
423*3089Swyllys 	/*
424*3089Swyllys 	 * If the policy file exists and the policy is in the policy file
425*3089Swyllys 	 * already, we will not create it again.
426*3089Swyllys 	 */
427*3089Swyllys 	if (access(filename, R_OK) == 0) {
428*3089Swyllys 		POLICY_LIST *plclist = NULL, *pnode;
429*3089Swyllys 		int found = 0;
430*3089Swyllys 
431*3089Swyllys 		rv = load_policies(filename, &plclist);
432*3089Swyllys 		if (rv != KMF_OK)
433*3089Swyllys 			goto out;
434*3089Swyllys 
435*3089Swyllys 		pnode = plclist;
436*3089Swyllys 		while (pnode != NULL && !found) {
437*3089Swyllys 			if (strcmp(plc.name, pnode->plc.name) == 0)
438*3089Swyllys 				found++;
439*3089Swyllys 			pnode = pnode->next;
440*3089Swyllys 		}
441*3089Swyllys 		free_policy_list(plclist);
442*3089Swyllys 
443*3089Swyllys 		if (found) {
444*3089Swyllys 			(void) fprintf(stderr,
445*3089Swyllys 			    gettext("Could not create policy \"%s\" - exists "
446*3089Swyllys 			    "already\n"), plc.name);
447*3089Swyllys 			rv = KC_ERR_USAGE;
448*3089Swyllys 			goto out;
449*3089Swyllys 		}
450*3089Swyllys 	}
451*3089Swyllys 
452*3089Swyllys 	/*
453*3089Swyllys 	 * If any OCSP attribute is set, turn on the OCSP checking flag.
454*3089Swyllys 	 * Also set "has_resp_cert" to be true, if the responder cert
455*3089Swyllys 	 * is provided.
456*3089Swyllys 	 */
457*3089Swyllys 	if (ocsp_set_attr > 0)
458*3089Swyllys 		plc.revocation |= KMF_REVOCATION_METHOD_OCSP;
459*3089Swyllys 
460*3089Swyllys 	if (plc.VAL_OCSP_RESP_CERT.name != NULL &&
461*3089Swyllys 	    plc.VAL_OCSP_RESP_CERT.serial != NULL) {
462*3089Swyllys 		plc.VAL_OCSP.has_resp_cert = B_TRUE;
463*3089Swyllys 	}
464*3089Swyllys 
465*3089Swyllys 	/*
466*3089Swyllys 	 * If any CRL attribute is set, turn on the CRL checking flag.
467*3089Swyllys 	 */
468*3089Swyllys 	if (crl_set_attr > 0)
469*3089Swyllys 		plc.revocation |= KMF_REVOCATION_METHOD_CRL;
470*3089Swyllys 
471*3089Swyllys 	/*
472*3089Swyllys 	 * Does a sanity check on the new policy.
473*3089Swyllys 	 */
474*3089Swyllys 	ret = KMF_VerifyPolicy(&plc);
475*3089Swyllys 	if (ret != KMF_OK) {
476*3089Swyllys 		print_sanity_error(ret);
477*3089Swyllys 		rv = KC_ERR_ADD_POLICY;
478*3089Swyllys 		goto out;
479*3089Swyllys 	}
480*3089Swyllys 
481*3089Swyllys 	/*
482*3089Swyllys 	 * Add to the DB.
483*3089Swyllys 	 */
484*3089Swyllys 	ret = KMF_AddPolicyToDB(&plc, filename, B_FALSE);
485*3089Swyllys 	if (ret != KMF_OK) {
486*3089Swyllys 		(void) fprintf(stderr,
487*3089Swyllys 		    gettext("Error adding policy to database: 0x%04x\n"), ret);
488*3089Swyllys 		rv = KC_ERR_ADD_POLICY;
489*3089Swyllys 	}
490*3089Swyllys 
491*3089Swyllys out:
492*3089Swyllys 	if (filename != NULL)
493*3089Swyllys 		free(filename);
494*3089Swyllys 
495*3089Swyllys 	KMF_FreePolicyRecord(&plc);
496*3089Swyllys 
497*3089Swyllys 	return (rv);
498*3089Swyllys }
499