xref: /onnv-gate/usr/src/cmd/cmd-crypto/kmfcfg/create.c (revision 12611:d9f75b73c5fd)
13089Swyllys /*
23089Swyllys  * CDDL HEADER START
33089Swyllys  *
43089Swyllys  * 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.
73089Swyllys  *
83089Swyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
93089Swyllys  * or http://www.opensolaris.org/os/licensing.
103089Swyllys  * See the License for the specific language governing permissions
113089Swyllys  * and limitations under the License.
123089Swyllys  *
133089Swyllys  * When distributing Covered Code, include this CDDL HEADER in each
143089Swyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
153089Swyllys  * If applicable, add the following below this CDDL HEADER, with the
163089Swyllys  * fields enclosed by brackets "[]" replaced with your own identifying
173089Swyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
183089Swyllys  *
193089Swyllys  * CDDL HEADER END
203089Swyllys  *
21*12611SJan.Pechanec@Sun.COM  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
223089Swyllys  */
233089Swyllys 
243089Swyllys #include <stdio.h>
253089Swyllys #include <strings.h>
263089Swyllys #include <ctype.h>
273089Swyllys #include <libgen.h>
283089Swyllys #include <libintl.h>
293089Swyllys #include <errno.h>
303089Swyllys #include <kmfapiP.h>
313089Swyllys #include <cryptoutil.h>
323089Swyllys #include "util.h"
333089Swyllys 
343089Swyllys int
353089Swyllys kc_create(int argc, char *argv[])
363089Swyllys {
373089Swyllys 	KMF_RETURN	ret;
383089Swyllys 	int 		rv = KC_OK;
393089Swyllys 	int		opt;
403089Swyllys 	extern int	optind_av;
413089Swyllys 	extern char	*optarg_av;
423089Swyllys 	char		*filename = NULL;
433089Swyllys 	int		ocsp_set_attr = 0;
443089Swyllys 	boolean_t	crl_set_attr = 0;
453089Swyllys 	KMF_POLICY_RECORD plc;
463089Swyllys 
473089Swyllys 	(void) memset(&plc, 0, sizeof (KMF_POLICY_RECORD));
483089Swyllys 
493089Swyllys 	while ((opt = getopt_av(argc, argv,
505051Swyllys 	    "i:(dbfile)"
515051Swyllys 	    "p:(policy)"
525051Swyllys 	    "d:(ignore-date)"
535051Swyllys 	    "e:(ignore-unknown-eku)"
545051Swyllys 	    "a:(ignore-trust-anchor)"
555051Swyllys 	    "v:(validity-adjusttime)"
565051Swyllys 	    "t:(ta-name)"
575051Swyllys 	    "s:(ta-serial)"
585051Swyllys 	    "o:(ocsp-responder)"
595051Swyllys 	    "P:(ocsp-proxy)"
605051Swyllys 	    "r:(ocsp-use-cert-responder)"
615051Swyllys 	    "T:(ocsp-response-lifetime)"
625051Swyllys 	    "R:(ocsp-ignore-response-sign)"
635051Swyllys 	    "n:(ocsp-responder-cert-name)"
645051Swyllys 	    "A:(ocsp-responder-cert-serial)"
655051Swyllys 	    "c:(crl-basefilename)"
665051Swyllys 	    "I:(crl-directory)"
675051Swyllys 	    "g:(crl-get-crl-uri)"
685051Swyllys 	    "X:(crl-proxy)"
695051Swyllys 	    "S:(crl-ignore-crl-sign)"
705051Swyllys 	    "D:(crl-ignore-crl-date)"
71*12611SJan.Pechanec@Sun.COM 	    "m:(mapper-name)"
72*12611SJan.Pechanec@Sun.COM 	    "M:(mapper-directory)"
73*12611SJan.Pechanec@Sun.COM 	    "Q:(mapper-pathname)"
74*12611SJan.Pechanec@Sun.COM 	    "q:(mapper-options)"
755051Swyllys 	    "u:(keyusage)"
765051Swyllys 	    "E:(ekunames)"
775051Swyllys 	    "O:(ekuoids)")) != EOF) {
783089Swyllys 		switch (opt) {
793089Swyllys 			case 'i':
803089Swyllys 				filename = get_string(optarg_av, &rv);
813089Swyllys 				if (filename == NULL) {
823089Swyllys 					(void) fprintf(stderr,
833089Swyllys 					    gettext("Error dbfile input.\n"));
843089Swyllys 				}
853089Swyllys 				break;
863089Swyllys 			case 'p':
873089Swyllys 				plc.name = get_string(optarg_av, &rv);
883089Swyllys 				if (plc.name == NULL) {
893089Swyllys 					(void) fprintf(stderr,
903089Swyllys 					    gettext("Error policy name.\n"));
913089Swyllys 				}
923089Swyllys 				break;
933089Swyllys 			case 'd':
943089Swyllys 				plc.ignore_date = get_boolean(optarg_av);
953089Swyllys 				if (plc.ignore_date == -1) {
963089Swyllys 					(void) fprintf(stderr,
973089Swyllys 					    gettext("Error boolean input.\n"));
983089Swyllys 					rv = KC_ERR_USAGE;
993089Swyllys 				}
1003089Swyllys 				break;
1013089Swyllys 			case 'e':
1023089Swyllys 				plc.ignore_unknown_ekus =
1033089Swyllys 				    get_boolean(optarg_av);
1043089Swyllys 				if (plc.ignore_unknown_ekus == -1) {
1053089Swyllys 					(void) fprintf(stderr,
1063089Swyllys 					    gettext("Error boolean input.\n"));
1073089Swyllys 					rv = KC_ERR_USAGE;
1083089Swyllys 				}
1093089Swyllys 				break;
1103089Swyllys 			case 'a':
1113089Swyllys 				plc.ignore_trust_anchor =
1123089Swyllys 				    get_boolean(optarg_av);
1133089Swyllys 				if (plc.ignore_trust_anchor == -1) {
1143089Swyllys 					(void) fprintf(stderr,
1153089Swyllys 					    gettext("Error boolean input.\n"));
1163089Swyllys 					rv = KC_ERR_USAGE;
1173089Swyllys 				}
1183089Swyllys 				break;
1193089Swyllys 			case 'v':
1203089Swyllys 				plc.validity_adjusttime =
1213089Swyllys 				    get_string(optarg_av, &rv);
1223089Swyllys 				if (plc.validity_adjusttime == NULL) {
1233089Swyllys 					(void) fprintf(stderr,
1243089Swyllys 					    gettext("Error time input.\n"));
1253089Swyllys 				} else {
1263089Swyllys 					uint32_t adj;
1273089Swyllys 					/* for syntax checking */
1283089Swyllys 					if (str2lifetime(
1293089Swyllys 					    plc.validity_adjusttime,
1303089Swyllys 					    &adj) < 0) {
1313089Swyllys 						(void) fprintf(stderr,
1323089Swyllys 						    gettext("Error time "
1333089Swyllys 						    "input.\n"));
1343089Swyllys 						rv = KC_ERR_USAGE;
1353089Swyllys 					}
1363089Swyllys 				}
1373089Swyllys 				break;
1383089Swyllys 			case 't':
1393089Swyllys 				plc.ta_name = get_string(optarg_av, &rv);
1403089Swyllys 				if (plc.ta_name == NULL) {
1413089Swyllys 					(void) fprintf(stderr,
1423089Swyllys 					    gettext("Error name input.\n"));
1433089Swyllys 				} else {
1443089Swyllys 					KMF_X509_NAME taDN;
1453089Swyllys 					/* for syntax checking */
1465051Swyllys 					if (kmf_dn_parser(plc.ta_name,
1473089Swyllys 					    &taDN) != KMF_OK) {
1483089Swyllys 						(void) fprintf(stderr,
1493089Swyllys 						    gettext("Error name "
1503089Swyllys 						    "input.\n"));
1513089Swyllys 						rv = KC_ERR_USAGE;
1523089Swyllys 					} else {
1535051Swyllys 						kmf_free_dn(&taDN);
1543089Swyllys 					}
1553089Swyllys 				}
1563089Swyllys 				break;
1573089Swyllys 			case 's':
1583089Swyllys 				plc.ta_serial = get_string(optarg_av, &rv);
1593089Swyllys 				if (plc.ta_serial == NULL) {
1603089Swyllys 					(void) fprintf(stderr,
1613089Swyllys 					    gettext("Error serial input.\n"));
1623089Swyllys 				} else {
1633089Swyllys 					uchar_t *bytes = NULL;
1643089Swyllys 					size_t bytelen;
1653089Swyllys 
1665051Swyllys 					ret = kmf_hexstr_to_bytes(
1673089Swyllys 					    (uchar_t *)plc.ta_serial,
1683089Swyllys 					    &bytes, &bytelen);
1693089Swyllys 					if (ret != KMF_OK || bytes == NULL) {
1703089Swyllys 						(void) fprintf(stderr,
1713089Swyllys 						    gettext("serial number "
1723089Swyllys 						    "must be specified as a "
1733089Swyllys 						    "hex number "
1743089Swyllys 						    "(ex: 0x0102030405"
1753089Swyllys 						    "ffeeddee)\n"));
1763089Swyllys 						rv = KC_ERR_USAGE;
1773089Swyllys 					}
1783089Swyllys 					if (bytes != NULL)
1793089Swyllys 						free(bytes);
1803089Swyllys 				}
1813089Swyllys 				break;
1823089Swyllys 			case 'o':
1833089Swyllys 				plc.VAL_OCSP_RESPONDER_URI =
1843089Swyllys 				    get_string(optarg_av, &rv);
1853089Swyllys 				if (plc.VAL_OCSP_RESPONDER_URI == NULL) {
1863089Swyllys 					(void) fprintf(stderr, gettext(
1873089Swyllys 					    "Error responder input.\n"));
1883089Swyllys 				} else {
1893089Swyllys 					ocsp_set_attr++;
1903089Swyllys 				}
1913089Swyllys 				break;
1923089Swyllys 			case 'P':
1933089Swyllys 				plc.VAL_OCSP_PROXY =
1943089Swyllys 				    get_string(optarg_av, &rv);
1953089Swyllys 				if (plc.VAL_OCSP_PROXY == NULL) {
1963089Swyllys 					(void) fprintf(stderr,
1973089Swyllys 					    gettext("Error proxy input.\n"));
1983089Swyllys 				} else {
1993089Swyllys 					ocsp_set_attr++;
2003089Swyllys 				}
2013089Swyllys 				break;
2023089Swyllys 			case 'r':
2033089Swyllys 				plc.VAL_OCSP_URI_FROM_CERT =
2043089Swyllys 				    get_boolean(optarg_av);
2053089Swyllys 				if (plc.VAL_OCSP_URI_FROM_CERT == -1) {
2063089Swyllys 					(void) fprintf(stderr,
2073089Swyllys 					    gettext("Error boolean input.\n"));
2083089Swyllys 					rv = KC_ERR_USAGE;
2093089Swyllys 				} else {
2103089Swyllys 					ocsp_set_attr++;
2113089Swyllys 				}
2123089Swyllys 				break;
2133089Swyllys 			case 'T':
2143089Swyllys 				plc.VAL_OCSP_RESP_LIFETIME =
2153089Swyllys 				    get_string(optarg_av, &rv);
2163089Swyllys 				if (plc.VAL_OCSP_RESP_LIFETIME == NULL) {
2173089Swyllys 					(void) fprintf(stderr,
2183089Swyllys 					    gettext("Error time input.\n"));
2193089Swyllys 				} else {
2203089Swyllys 					uint32_t adj;
2213089Swyllys 					/* for syntax checking */
2223089Swyllys 					if (str2lifetime(
2233089Swyllys 					    plc.VAL_OCSP_RESP_LIFETIME,
2243089Swyllys 					    &adj) < 0) {
2253089Swyllys 						(void) fprintf(stderr,
2263089Swyllys 						    gettext("Error time "
2273089Swyllys 						    "input.\n"));
2283089Swyllys 						rv = KC_ERR_USAGE;
2293089Swyllys 					} else {
2303089Swyllys 						ocsp_set_attr++;
2313089Swyllys 					}
2323089Swyllys 				}
2333089Swyllys 				break;
2343089Swyllys 			case 'R':
2353089Swyllys 				plc.VAL_OCSP_IGNORE_RESP_SIGN =
2363089Swyllys 				    get_boolean(optarg_av);
2373089Swyllys 				if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) {
2383089Swyllys 					(void) fprintf(stderr,
2393089Swyllys 					    gettext("Error boolean input.\n"));
2403089Swyllys 					rv = KC_ERR_USAGE;
2413089Swyllys 				} else {
2423089Swyllys 					ocsp_set_attr++;
2433089Swyllys 				}
2443089Swyllys 				break;
2453089Swyllys 			case 'n':
2463089Swyllys 				plc.VAL_OCSP_RESP_CERT_NAME =
2473089Swyllys 				    get_string(optarg_av, &rv);
2483089Swyllys 				if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) {
2493089Swyllys 					(void) fprintf(stderr,
2503089Swyllys 					    gettext("Error name input.\n"));
2513089Swyllys 				} else {
2523089Swyllys 					KMF_X509_NAME respDN;
2533089Swyllys 					/* for syntax checking */
2545051Swyllys 					if (kmf_dn_parser(
2553089Swyllys 					    plc.VAL_OCSP_RESP_CERT_NAME,
2563089Swyllys 					    &respDN) != KMF_OK) {
2573089Swyllys 						(void) fprintf(stderr,
2583089Swyllys 						    gettext("Error name "
2593089Swyllys 						    "input.\n"));
2603089Swyllys 						rv = KC_ERR_USAGE;
2613089Swyllys 					} else {
2625051Swyllys 						kmf_free_dn(&respDN);
2633089Swyllys 						ocsp_set_attr++;
2643089Swyllys 					}
2653089Swyllys 				}
2663089Swyllys 				break;
2673089Swyllys 			case 'A':
2683089Swyllys 				plc.VAL_OCSP_RESP_CERT_SERIAL =
2693089Swyllys 				    get_string(optarg_av, &rv);
2703089Swyllys 				if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) {
2713089Swyllys 					(void) fprintf(stderr,
2723089Swyllys 					    gettext("Error serial input.\n"));
2733089Swyllys 				} else {
2743089Swyllys 					uchar_t *bytes = NULL;
2753089Swyllys 					size_t bytelen;
2763089Swyllys 
2775051Swyllys 					ret = kmf_hexstr_to_bytes((uchar_t *)
2783089Swyllys 					    plc.VAL_OCSP_RESP_CERT_SERIAL,
2793089Swyllys 					    &bytes, &bytelen);
2803089Swyllys 					if (ret != KMF_OK || bytes == NULL) {
2813089Swyllys 						(void) fprintf(stderr,
2823089Swyllys 						    gettext("serial number "
2833089Swyllys 						    "must be specified as a "
2843089Swyllys 						    "hex number "
2853089Swyllys 						    "(ex: 0x0102030405"
2863089Swyllys 						    "ffeeddee)\n"));
2873089Swyllys 						rv = KC_ERR_USAGE;
2883089Swyllys 						break;
2893089Swyllys 					}
2903089Swyllys 					if (bytes != NULL)
2913089Swyllys 						free(bytes);
2923089Swyllys 					ocsp_set_attr++;
2933089Swyllys 				}
2943089Swyllys 				break;
2953089Swyllys 			case 'c':
2963089Swyllys 				plc.VAL_CRL_BASEFILENAME =
2973089Swyllys 				    get_string(optarg_av, &rv);
2983089Swyllys 				if (plc.VAL_CRL_BASEFILENAME == NULL) {
2993089Swyllys 					(void) fprintf(stderr,
3003089Swyllys 					    gettext("Error boolean input.\n"));
3013089Swyllys 				} else {
3023089Swyllys 					crl_set_attr++;
3033089Swyllys 				}
3043089Swyllys 				break;
3053089Swyllys 			case 'I':
3063089Swyllys 				plc.VAL_CRL_DIRECTORY =
3073089Swyllys 				    get_string(optarg_av, &rv);
3083089Swyllys 				if (plc.VAL_CRL_DIRECTORY == NULL) {
3093089Swyllys 					(void) fprintf(stderr,
3103089Swyllys 					    gettext("Error boolean input.\n"));
3113089Swyllys 				} else {
3123089Swyllys 					crl_set_attr++;
3133089Swyllys 				}
3143089Swyllys 				break;
3153089Swyllys 			case 'g':
3163089Swyllys 				plc.VAL_CRL_GET_URI = get_boolean(optarg_av);
3173089Swyllys 				if (plc.VAL_CRL_GET_URI == -1) {
3183089Swyllys 					(void) fprintf(stderr,
3193089Swyllys 					    gettext("Error boolean input.\n"));
3203089Swyllys 					rv = KC_ERR_USAGE;
3213089Swyllys 				} else {
3223089Swyllys 					crl_set_attr++;
3233089Swyllys 				}
3243089Swyllys 				break;
3253089Swyllys 			case 'X':
3263089Swyllys 				plc.VAL_CRL_PROXY = get_string(optarg_av, &rv);
3273089Swyllys 				if (plc.VAL_CRL_PROXY == NULL) {
3283089Swyllys 					(void) fprintf(stderr,
3293089Swyllys 					    gettext("Error proxy input.\n"));
3303089Swyllys 				} else {
3313089Swyllys 					crl_set_attr++;
3323089Swyllys 				}
3333089Swyllys 				break;
3343089Swyllys 			case 'S':
3353089Swyllys 				plc.VAL_CRL_IGNORE_SIGN =
3363089Swyllys 				    get_boolean(optarg_av);
3373089Swyllys 				if (plc.VAL_CRL_IGNORE_SIGN == -1) {
3383089Swyllys 					(void) fprintf(stderr,
3393089Swyllys 					    gettext("Error boolean input.\n"));
3403089Swyllys 					rv = KC_ERR_USAGE;
3413089Swyllys 				} else {
3423089Swyllys 					crl_set_attr++;
3433089Swyllys 				}
3443089Swyllys 				break;
3453089Swyllys 			case 'D':
3463089Swyllys 				plc.VAL_CRL_IGNORE_DATE =
3475051Swyllys 				    get_boolean(optarg_av);
3483089Swyllys 				if (plc.VAL_CRL_IGNORE_DATE == -1) {
3493089Swyllys 					(void) fprintf(stderr,
3503089Swyllys 					    gettext("Error boolean input.\n"));
3513089Swyllys 					rv = KC_ERR_USAGE;
3523089Swyllys 				} else {
3533089Swyllys 					crl_set_attr++;
3543089Swyllys 				}
3553089Swyllys 				break;
3563089Swyllys 			case 'u':
3573089Swyllys 				plc.ku_bits = parseKUlist(optarg_av);
3583089Swyllys 				if (plc.ku_bits == 0) {
3593089Swyllys 					(void) fprintf(stderr, gettext(
3603089Swyllys 					    "Error keyusage input.\n"));
3613089Swyllys 					rv = KC_ERR_USAGE;
3623089Swyllys 				}
3633089Swyllys 				break;
3643089Swyllys 			case 'E':
3653089Swyllys 				if (parseEKUNames(optarg_av, &plc) != 0) {
3663089Swyllys 					(void) fprintf(stderr,
3673089Swyllys 					    gettext("Error EKU input.\n"));
3683089Swyllys 					rv = KC_ERR_USAGE;
3693089Swyllys 				}
3703089Swyllys 				break;
3713089Swyllys 			case 'O':
3723089Swyllys 				if (parseEKUOIDs(optarg_av, &plc) != 0) {
3733089Swyllys 					(void) fprintf(stderr,
3743089Swyllys 					    gettext("Error EKU OID input.\n"));
3753089Swyllys 					rv = KC_ERR_USAGE;
3763089Swyllys 				}
3773089Swyllys 				break;
378*12611SJan.Pechanec@Sun.COM 			case 'm':
379*12611SJan.Pechanec@Sun.COM 				plc.mapper.mapname = get_string(optarg_av, &rv);
380*12611SJan.Pechanec@Sun.COM 				if (plc.mapper.mapname == NULL) {
381*12611SJan.Pechanec@Sun.COM 					(void) fprintf(stderr,
382*12611SJan.Pechanec@Sun.COM 					    gettext("Error mapper-name "
383*12611SJan.Pechanec@Sun.COM 					    "input.\n"));
384*12611SJan.Pechanec@Sun.COM 				}
385*12611SJan.Pechanec@Sun.COM 				break;
386*12611SJan.Pechanec@Sun.COM 			case 'M':
387*12611SJan.Pechanec@Sun.COM 				plc.mapper.dir = get_string(optarg_av, &rv);
388*12611SJan.Pechanec@Sun.COM 				if (plc.mapper.dir == NULL) {
389*12611SJan.Pechanec@Sun.COM 					(void) fprintf(stderr,
390*12611SJan.Pechanec@Sun.COM 					    gettext("Error mapper-dir "
391*12611SJan.Pechanec@Sun.COM 					    "input.\n"));
392*12611SJan.Pechanec@Sun.COM 				}
393*12611SJan.Pechanec@Sun.COM 				break;
394*12611SJan.Pechanec@Sun.COM 			case 'Q':
395*12611SJan.Pechanec@Sun.COM 				plc.mapper.pathname = get_string(optarg_av,
396*12611SJan.Pechanec@Sun.COM 				    &rv);
397*12611SJan.Pechanec@Sun.COM 				if (plc.mapper.pathname == NULL) {
398*12611SJan.Pechanec@Sun.COM 					(void) fprintf(stderr,
399*12611SJan.Pechanec@Sun.COM 					    gettext("Error mapper-pathname "
400*12611SJan.Pechanec@Sun.COM 					    "input.\n"));
401*12611SJan.Pechanec@Sun.COM 				}
402*12611SJan.Pechanec@Sun.COM 				break;
403*12611SJan.Pechanec@Sun.COM 			case 'q':
404*12611SJan.Pechanec@Sun.COM 				plc.mapper.options = get_string(optarg_av, &rv);
405*12611SJan.Pechanec@Sun.COM 				if (plc.mapper.options == NULL) {
406*12611SJan.Pechanec@Sun.COM 					(void) fprintf(stderr,
407*12611SJan.Pechanec@Sun.COM 					    gettext("Error mapper-options "
408*12611SJan.Pechanec@Sun.COM 					    "input.\n"));
409*12611SJan.Pechanec@Sun.COM 				}
410*12611SJan.Pechanec@Sun.COM 				break;
4113089Swyllys 			default:
4123089Swyllys 				(void) fprintf(stderr,
4133089Swyllys 				    gettext("Error input option.\n"));
4143089Swyllys 				rv = KC_ERR_USAGE;
4153089Swyllys 				break;
4163089Swyllys 		}
4173089Swyllys 
4183089Swyllys 		if (rv != KC_OK)
4193089Swyllys 			goto out;
4203089Swyllys 	}
4213089Swyllys 
4223089Swyllys 	/* No additional args allowed. */
4233089Swyllys 	argc -= optind_av;
4243089Swyllys 	if (argc) {
4253089Swyllys 		(void) fprintf(stderr,
4263089Swyllys 		    gettext("Error input option\n"));
4273089Swyllys 		rv = KC_ERR_USAGE;
4283089Swyllys 		goto out;
4293089Swyllys 	}
4303089Swyllys 
4313089Swyllys 	if (filename == NULL) {
4323089Swyllys 		filename = strdup(KMF_DEFAULT_POLICY_FILE);
4333089Swyllys 		if (filename == NULL) {
4343089Swyllys 			rv = KC_ERR_MEMORY;
4353089Swyllys 			goto out;
4363089Swyllys 		}
4373089Swyllys 	}
4383089Swyllys 
4393089Swyllys 	/*
4403089Swyllys 	 * Must have a policy name. The policy name can not be default
4413089Swyllys 	 * if using the default policy file.
4423089Swyllys 	 */
4433089Swyllys 	if (plc.name == NULL) {
4443089Swyllys 		(void) fprintf(stderr,
4453089Swyllys 		    gettext("You must specify a policy name\n"));
4463089Swyllys 		rv = KC_ERR_USAGE;
4473089Swyllys 		goto out;
4483089Swyllys 	} else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 &&
4493089Swyllys 	    strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) {
4503089Swyllys 		(void) fprintf(stderr,
4513089Swyllys 		    gettext("Can not create a default policy in the default "
4523089Swyllys 		    "policy file\n"));
4533089Swyllys 		rv = KC_ERR_USAGE;
4543089Swyllys 		goto out;
4553089Swyllys 	}
4563089Swyllys 
4573089Swyllys 	/*
4583089Swyllys 	 * If the policy file exists and the policy is in the policy file
4593089Swyllys 	 * already, we will not create it again.
4603089Swyllys 	 */
4613089Swyllys 	if (access(filename, R_OK) == 0) {
4623089Swyllys 		POLICY_LIST *plclist = NULL, *pnode;
4633089Swyllys 		int found = 0;
4643089Swyllys 
4653089Swyllys 		rv = load_policies(filename, &plclist);
4663089Swyllys 		if (rv != KMF_OK)
4673089Swyllys 			goto out;
4683089Swyllys 
4693089Swyllys 		pnode = plclist;
4703089Swyllys 		while (pnode != NULL && !found) {
4713089Swyllys 			if (strcmp(plc.name, pnode->plc.name) == 0)
4723089Swyllys 				found++;
4733089Swyllys 			pnode = pnode->next;
4743089Swyllys 		}
4753089Swyllys 		free_policy_list(plclist);
4763089Swyllys 
4773089Swyllys 		if (found) {
4783089Swyllys 			(void) fprintf(stderr,
4793089Swyllys 			    gettext("Could not create policy \"%s\" - exists "
4803089Swyllys 			    "already\n"), plc.name);
4813089Swyllys 			rv = KC_ERR_USAGE;
4823089Swyllys 			goto out;
4833089Swyllys 		}
4843089Swyllys 	}
4853089Swyllys 
4863089Swyllys 	/*
4873089Swyllys 	 * If any OCSP attribute is set, turn on the OCSP checking flag.
4883089Swyllys 	 * Also set "has_resp_cert" to be true, if the responder cert
4893089Swyllys 	 * is provided.
4903089Swyllys 	 */
4913089Swyllys 	if (ocsp_set_attr > 0)
4923089Swyllys 		plc.revocation |= KMF_REVOCATION_METHOD_OCSP;
4933089Swyllys 
4943089Swyllys 	if (plc.VAL_OCSP_RESP_CERT.name != NULL &&
4953089Swyllys 	    plc.VAL_OCSP_RESP_CERT.serial != NULL) {
4963089Swyllys 		plc.VAL_OCSP.has_resp_cert = B_TRUE;
4973089Swyllys 	}
4983089Swyllys 
4993089Swyllys 	/*
500*12611SJan.Pechanec@Sun.COM 	 * Setting mapper-name (with optional mapper-dir) and mapper-pathname is
501*12611SJan.Pechanec@Sun.COM 	 * mutually exclusive. Also, you cannot set options only, you need the
502*12611SJan.Pechanec@Sun.COM 	 * name or pathname, and you can set the directory only with the name,
503*12611SJan.Pechanec@Sun.COM 	 * not the pathname.
504*12611SJan.Pechanec@Sun.COM 	 */
505*12611SJan.Pechanec@Sun.COM 	if ((plc.mapper.mapname != NULL && plc.mapper.pathname != NULL) ||
506*12611SJan.Pechanec@Sun.COM 	    (plc.mapper.dir != NULL && plc.mapper.pathname != NULL) ||
507*12611SJan.Pechanec@Sun.COM 	    (plc.mapper.dir != NULL && plc.mapper.mapname == NULL) ||
508*12611SJan.Pechanec@Sun.COM 	    (plc.mapper.options != NULL && plc.mapper.mapname == NULL &&
509*12611SJan.Pechanec@Sun.COM 	    plc.mapper.pathname == NULL)) {
510*12611SJan.Pechanec@Sun.COM 		(void) fprintf(stderr,
511*12611SJan.Pechanec@Sun.COM 		    gettext("Error in mapper input options\n"));
512*12611SJan.Pechanec@Sun.COM 		rv = KC_ERR_USAGE;
513*12611SJan.Pechanec@Sun.COM 		goto out;
514*12611SJan.Pechanec@Sun.COM 	}
515*12611SJan.Pechanec@Sun.COM 
516*12611SJan.Pechanec@Sun.COM 	/*
5173089Swyllys 	 * If any CRL attribute is set, turn on the CRL checking flag.
5183089Swyllys 	 */
5193089Swyllys 	if (crl_set_attr > 0)
5203089Swyllys 		plc.revocation |= KMF_REVOCATION_METHOD_CRL;
5213089Swyllys 
5223089Swyllys 	/*
5233089Swyllys 	 * Does a sanity check on the new policy.
5243089Swyllys 	 */
5255051Swyllys 	ret = kmf_verify_policy(&plc);
5263089Swyllys 	if (ret != KMF_OK) {
5273089Swyllys 		print_sanity_error(ret);
5283089Swyllys 		rv = KC_ERR_ADD_POLICY;
5293089Swyllys 		goto out;
5303089Swyllys 	}
5313089Swyllys 
5323089Swyllys 	/*
5333089Swyllys 	 * Add to the DB.
5343089Swyllys 	 */
5355051Swyllys 	ret = kmf_add_policy_to_db(&plc, filename, B_FALSE);
5363089Swyllys 	if (ret != KMF_OK) {
5373089Swyllys 		(void) fprintf(stderr,
5383089Swyllys 		    gettext("Error adding policy to database: 0x%04x\n"), ret);
5393089Swyllys 		rv = KC_ERR_ADD_POLICY;
5403089Swyllys 	}
5413089Swyllys 
5423089Swyllys out:
5433089Swyllys 	if (filename != NULL)
5443089Swyllys 		free(filename);
5453089Swyllys 
5465051Swyllys 	kmf_free_policy_record(&plc);
5473089Swyllys 
5483089Swyllys 	return (rv);
5493089Swyllys }
550