xref: /onnv-gate/usr/src/cmd/cmd-crypto/kmfcfg/create.c (revision 12919:db25553c7f2e)
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  *
2112611SJan.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
kc_create(int argc,char * argv[])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)"
7112611SJan.Pechanec@Sun.COM 	    "m:(mapper-name)"
7212611SJan.Pechanec@Sun.COM 	    "M:(mapper-directory)"
7312611SJan.Pechanec@Sun.COM 	    "Q:(mapper-pathname)"
7412611SJan.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"));
143*12919Swyllys.ingersoll@sun.com 				} else if (strcasecmp(plc.ta_name,
144*12919Swyllys.ingersoll@sun.com 				    "search") != 0) {
1453089Swyllys 					KMF_X509_NAME taDN;
1463089Swyllys 					/* for syntax checking */
1475051Swyllys 					if (kmf_dn_parser(plc.ta_name,
1483089Swyllys 					    &taDN) != KMF_OK) {
1493089Swyllys 						(void) fprintf(stderr,
1503089Swyllys 						    gettext("Error name "
1513089Swyllys 						    "input.\n"));
1523089Swyllys 						rv = KC_ERR_USAGE;
1533089Swyllys 					} else {
1545051Swyllys 						kmf_free_dn(&taDN);
1553089Swyllys 					}
1563089Swyllys 				}
1573089Swyllys 				break;
1583089Swyllys 			case 's':
1593089Swyllys 				plc.ta_serial = get_string(optarg_av, &rv);
1603089Swyllys 				if (plc.ta_serial == NULL) {
1613089Swyllys 					(void) fprintf(stderr,
1623089Swyllys 					    gettext("Error serial input.\n"));
1633089Swyllys 				} else {
1643089Swyllys 					uchar_t *bytes = NULL;
1653089Swyllys 					size_t bytelen;
1663089Swyllys 
1675051Swyllys 					ret = kmf_hexstr_to_bytes(
1683089Swyllys 					    (uchar_t *)plc.ta_serial,
1693089Swyllys 					    &bytes, &bytelen);
1703089Swyllys 					if (ret != KMF_OK || bytes == NULL) {
1713089Swyllys 						(void) fprintf(stderr,
1723089Swyllys 						    gettext("serial number "
1733089Swyllys 						    "must be specified as a "
1743089Swyllys 						    "hex number "
1753089Swyllys 						    "(ex: 0x0102030405"
1763089Swyllys 						    "ffeeddee)\n"));
1773089Swyllys 						rv = KC_ERR_USAGE;
1783089Swyllys 					}
1793089Swyllys 					if (bytes != NULL)
1803089Swyllys 						free(bytes);
1813089Swyllys 				}
1823089Swyllys 				break;
1833089Swyllys 			case 'o':
1843089Swyllys 				plc.VAL_OCSP_RESPONDER_URI =
1853089Swyllys 				    get_string(optarg_av, &rv);
1863089Swyllys 				if (plc.VAL_OCSP_RESPONDER_URI == NULL) {
1873089Swyllys 					(void) fprintf(stderr, gettext(
1883089Swyllys 					    "Error responder input.\n"));
1893089Swyllys 				} else {
1903089Swyllys 					ocsp_set_attr++;
1913089Swyllys 				}
1923089Swyllys 				break;
1933089Swyllys 			case 'P':
1943089Swyllys 				plc.VAL_OCSP_PROXY =
1953089Swyllys 				    get_string(optarg_av, &rv);
1963089Swyllys 				if (plc.VAL_OCSP_PROXY == NULL) {
1973089Swyllys 					(void) fprintf(stderr,
1983089Swyllys 					    gettext("Error proxy input.\n"));
1993089Swyllys 				} else {
2003089Swyllys 					ocsp_set_attr++;
2013089Swyllys 				}
2023089Swyllys 				break;
2033089Swyllys 			case 'r':
2043089Swyllys 				plc.VAL_OCSP_URI_FROM_CERT =
2053089Swyllys 				    get_boolean(optarg_av);
2063089Swyllys 				if (plc.VAL_OCSP_URI_FROM_CERT == -1) {
2073089Swyllys 					(void) fprintf(stderr,
2083089Swyllys 					    gettext("Error boolean input.\n"));
2093089Swyllys 					rv = KC_ERR_USAGE;
2103089Swyllys 				} else {
2113089Swyllys 					ocsp_set_attr++;
2123089Swyllys 				}
2133089Swyllys 				break;
2143089Swyllys 			case 'T':
2153089Swyllys 				plc.VAL_OCSP_RESP_LIFETIME =
2163089Swyllys 				    get_string(optarg_av, &rv);
2173089Swyllys 				if (plc.VAL_OCSP_RESP_LIFETIME == NULL) {
2183089Swyllys 					(void) fprintf(stderr,
2193089Swyllys 					    gettext("Error time input.\n"));
2203089Swyllys 				} else {
2213089Swyllys 					uint32_t adj;
2223089Swyllys 					/* for syntax checking */
2233089Swyllys 					if (str2lifetime(
2243089Swyllys 					    plc.VAL_OCSP_RESP_LIFETIME,
2253089Swyllys 					    &adj) < 0) {
2263089Swyllys 						(void) fprintf(stderr,
2273089Swyllys 						    gettext("Error time "
2283089Swyllys 						    "input.\n"));
2293089Swyllys 						rv = KC_ERR_USAGE;
2303089Swyllys 					} else {
2313089Swyllys 						ocsp_set_attr++;
2323089Swyllys 					}
2333089Swyllys 				}
2343089Swyllys 				break;
2353089Swyllys 			case 'R':
2363089Swyllys 				plc.VAL_OCSP_IGNORE_RESP_SIGN =
2373089Swyllys 				    get_boolean(optarg_av);
2383089Swyllys 				if (plc.VAL_OCSP_IGNORE_RESP_SIGN == -1) {
2393089Swyllys 					(void) fprintf(stderr,
2403089Swyllys 					    gettext("Error boolean input.\n"));
2413089Swyllys 					rv = KC_ERR_USAGE;
2423089Swyllys 				} else {
2433089Swyllys 					ocsp_set_attr++;
2443089Swyllys 				}
2453089Swyllys 				break;
2463089Swyllys 			case 'n':
2473089Swyllys 				plc.VAL_OCSP_RESP_CERT_NAME =
2483089Swyllys 				    get_string(optarg_av, &rv);
2493089Swyllys 				if (plc.VAL_OCSP_RESP_CERT_NAME == NULL) {
2503089Swyllys 					(void) fprintf(stderr,
2513089Swyllys 					    gettext("Error name input.\n"));
2523089Swyllys 				} else {
2533089Swyllys 					KMF_X509_NAME respDN;
2543089Swyllys 					/* for syntax checking */
2555051Swyllys 					if (kmf_dn_parser(
2563089Swyllys 					    plc.VAL_OCSP_RESP_CERT_NAME,
2573089Swyllys 					    &respDN) != KMF_OK) {
2583089Swyllys 						(void) fprintf(stderr,
2593089Swyllys 						    gettext("Error name "
2603089Swyllys 						    "input.\n"));
2613089Swyllys 						rv = KC_ERR_USAGE;
2623089Swyllys 					} else {
2635051Swyllys 						kmf_free_dn(&respDN);
2643089Swyllys 						ocsp_set_attr++;
2653089Swyllys 					}
2663089Swyllys 				}
2673089Swyllys 				break;
2683089Swyllys 			case 'A':
2693089Swyllys 				plc.VAL_OCSP_RESP_CERT_SERIAL =
2703089Swyllys 				    get_string(optarg_av, &rv);
2713089Swyllys 				if (plc.VAL_OCSP_RESP_CERT_SERIAL == NULL) {
2723089Swyllys 					(void) fprintf(stderr,
2733089Swyllys 					    gettext("Error serial input.\n"));
2743089Swyllys 				} else {
2753089Swyllys 					uchar_t *bytes = NULL;
2763089Swyllys 					size_t bytelen;
2773089Swyllys 
2785051Swyllys 					ret = kmf_hexstr_to_bytes((uchar_t *)
2793089Swyllys 					    plc.VAL_OCSP_RESP_CERT_SERIAL,
2803089Swyllys 					    &bytes, &bytelen);
2813089Swyllys 					if (ret != KMF_OK || bytes == NULL) {
2823089Swyllys 						(void) fprintf(stderr,
2833089Swyllys 						    gettext("serial number "
2843089Swyllys 						    "must be specified as a "
2853089Swyllys 						    "hex number "
2863089Swyllys 						    "(ex: 0x0102030405"
2873089Swyllys 						    "ffeeddee)\n"));
2883089Swyllys 						rv = KC_ERR_USAGE;
2893089Swyllys 						break;
2903089Swyllys 					}
2913089Swyllys 					if (bytes != NULL)
2923089Swyllys 						free(bytes);
2933089Swyllys 					ocsp_set_attr++;
2943089Swyllys 				}
2953089Swyllys 				break;
2963089Swyllys 			case 'c':
2973089Swyllys 				plc.VAL_CRL_BASEFILENAME =
2983089Swyllys 				    get_string(optarg_av, &rv);
2993089Swyllys 				if (plc.VAL_CRL_BASEFILENAME == NULL) {
3003089Swyllys 					(void) fprintf(stderr,
3013089Swyllys 					    gettext("Error boolean input.\n"));
3023089Swyllys 				} else {
3033089Swyllys 					crl_set_attr++;
3043089Swyllys 				}
3053089Swyllys 				break;
3063089Swyllys 			case 'I':
3073089Swyllys 				plc.VAL_CRL_DIRECTORY =
3083089Swyllys 				    get_string(optarg_av, &rv);
3093089Swyllys 				if (plc.VAL_CRL_DIRECTORY == NULL) {
3103089Swyllys 					(void) fprintf(stderr,
3113089Swyllys 					    gettext("Error boolean input.\n"));
3123089Swyllys 				} else {
3133089Swyllys 					crl_set_attr++;
3143089Swyllys 				}
3153089Swyllys 				break;
3163089Swyllys 			case 'g':
3173089Swyllys 				plc.VAL_CRL_GET_URI = get_boolean(optarg_av);
3183089Swyllys 				if (plc.VAL_CRL_GET_URI == -1) {
3193089Swyllys 					(void) fprintf(stderr,
3203089Swyllys 					    gettext("Error boolean input.\n"));
3213089Swyllys 					rv = KC_ERR_USAGE;
3223089Swyllys 				} else {
3233089Swyllys 					crl_set_attr++;
3243089Swyllys 				}
3253089Swyllys 				break;
3263089Swyllys 			case 'X':
3273089Swyllys 				plc.VAL_CRL_PROXY = get_string(optarg_av, &rv);
3283089Swyllys 				if (plc.VAL_CRL_PROXY == NULL) {
3293089Swyllys 					(void) fprintf(stderr,
3303089Swyllys 					    gettext("Error proxy input.\n"));
3313089Swyllys 				} else {
3323089Swyllys 					crl_set_attr++;
3333089Swyllys 				}
3343089Swyllys 				break;
3353089Swyllys 			case 'S':
3363089Swyllys 				plc.VAL_CRL_IGNORE_SIGN =
3373089Swyllys 				    get_boolean(optarg_av);
3383089Swyllys 				if (plc.VAL_CRL_IGNORE_SIGN == -1) {
3393089Swyllys 					(void) fprintf(stderr,
3403089Swyllys 					    gettext("Error boolean input.\n"));
3413089Swyllys 					rv = KC_ERR_USAGE;
3423089Swyllys 				} else {
3433089Swyllys 					crl_set_attr++;
3443089Swyllys 				}
3453089Swyllys 				break;
3463089Swyllys 			case 'D':
3473089Swyllys 				plc.VAL_CRL_IGNORE_DATE =
3485051Swyllys 				    get_boolean(optarg_av);
3493089Swyllys 				if (plc.VAL_CRL_IGNORE_DATE == -1) {
3503089Swyllys 					(void) fprintf(stderr,
3513089Swyllys 					    gettext("Error boolean input.\n"));
3523089Swyllys 					rv = KC_ERR_USAGE;
3533089Swyllys 				} else {
3543089Swyllys 					crl_set_attr++;
3553089Swyllys 				}
3563089Swyllys 				break;
3573089Swyllys 			case 'u':
3583089Swyllys 				plc.ku_bits = parseKUlist(optarg_av);
3593089Swyllys 				if (plc.ku_bits == 0) {
3603089Swyllys 					(void) fprintf(stderr, gettext(
3613089Swyllys 					    "Error keyusage input.\n"));
3623089Swyllys 					rv = KC_ERR_USAGE;
3633089Swyllys 				}
3643089Swyllys 				break;
3653089Swyllys 			case 'E':
3663089Swyllys 				if (parseEKUNames(optarg_av, &plc) != 0) {
3673089Swyllys 					(void) fprintf(stderr,
3683089Swyllys 					    gettext("Error EKU input.\n"));
3693089Swyllys 					rv = KC_ERR_USAGE;
3703089Swyllys 				}
3713089Swyllys 				break;
3723089Swyllys 			case 'O':
3733089Swyllys 				if (parseEKUOIDs(optarg_av, &plc) != 0) {
3743089Swyllys 					(void) fprintf(stderr,
3753089Swyllys 					    gettext("Error EKU OID input.\n"));
3763089Swyllys 					rv = KC_ERR_USAGE;
3773089Swyllys 				}
3783089Swyllys 				break;
37912611SJan.Pechanec@Sun.COM 			case 'm':
38012611SJan.Pechanec@Sun.COM 				plc.mapper.mapname = get_string(optarg_av, &rv);
38112611SJan.Pechanec@Sun.COM 				if (plc.mapper.mapname == NULL) {
38212611SJan.Pechanec@Sun.COM 					(void) fprintf(stderr,
38312611SJan.Pechanec@Sun.COM 					    gettext("Error mapper-name "
38412611SJan.Pechanec@Sun.COM 					    "input.\n"));
38512611SJan.Pechanec@Sun.COM 				}
38612611SJan.Pechanec@Sun.COM 				break;
38712611SJan.Pechanec@Sun.COM 			case 'M':
38812611SJan.Pechanec@Sun.COM 				plc.mapper.dir = get_string(optarg_av, &rv);
38912611SJan.Pechanec@Sun.COM 				if (plc.mapper.dir == NULL) {
39012611SJan.Pechanec@Sun.COM 					(void) fprintf(stderr,
39112611SJan.Pechanec@Sun.COM 					    gettext("Error mapper-dir "
39212611SJan.Pechanec@Sun.COM 					    "input.\n"));
39312611SJan.Pechanec@Sun.COM 				}
39412611SJan.Pechanec@Sun.COM 				break;
39512611SJan.Pechanec@Sun.COM 			case 'Q':
39612611SJan.Pechanec@Sun.COM 				plc.mapper.pathname = get_string(optarg_av,
39712611SJan.Pechanec@Sun.COM 				    &rv);
39812611SJan.Pechanec@Sun.COM 				if (plc.mapper.pathname == NULL) {
39912611SJan.Pechanec@Sun.COM 					(void) fprintf(stderr,
40012611SJan.Pechanec@Sun.COM 					    gettext("Error mapper-pathname "
40112611SJan.Pechanec@Sun.COM 					    "input.\n"));
40212611SJan.Pechanec@Sun.COM 				}
40312611SJan.Pechanec@Sun.COM 				break;
40412611SJan.Pechanec@Sun.COM 			case 'q':
40512611SJan.Pechanec@Sun.COM 				plc.mapper.options = get_string(optarg_av, &rv);
40612611SJan.Pechanec@Sun.COM 				if (plc.mapper.options == NULL) {
40712611SJan.Pechanec@Sun.COM 					(void) fprintf(stderr,
40812611SJan.Pechanec@Sun.COM 					    gettext("Error mapper-options "
40912611SJan.Pechanec@Sun.COM 					    "input.\n"));
41012611SJan.Pechanec@Sun.COM 				}
41112611SJan.Pechanec@Sun.COM 				break;
4123089Swyllys 			default:
4133089Swyllys 				(void) fprintf(stderr,
4143089Swyllys 				    gettext("Error input option.\n"));
4153089Swyllys 				rv = KC_ERR_USAGE;
4163089Swyllys 				break;
4173089Swyllys 		}
4183089Swyllys 
4193089Swyllys 		if (rv != KC_OK)
4203089Swyllys 			goto out;
4213089Swyllys 	}
4223089Swyllys 
4233089Swyllys 	/* No additional args allowed. */
4243089Swyllys 	argc -= optind_av;
4253089Swyllys 	if (argc) {
4263089Swyllys 		(void) fprintf(stderr,
4273089Swyllys 		    gettext("Error input option\n"));
4283089Swyllys 		rv = KC_ERR_USAGE;
4293089Swyllys 		goto out;
4303089Swyllys 	}
4313089Swyllys 
4323089Swyllys 	if (filename == NULL) {
4333089Swyllys 		filename = strdup(KMF_DEFAULT_POLICY_FILE);
4343089Swyllys 		if (filename == NULL) {
4353089Swyllys 			rv = KC_ERR_MEMORY;
4363089Swyllys 			goto out;
4373089Swyllys 		}
4383089Swyllys 	}
4393089Swyllys 
4403089Swyllys 	/*
4413089Swyllys 	 * Must have a policy name. The policy name can not be default
4423089Swyllys 	 * if using the default policy file.
4433089Swyllys 	 */
4443089Swyllys 	if (plc.name == NULL) {
4453089Swyllys 		(void) fprintf(stderr,
4463089Swyllys 		    gettext("You must specify a policy name\n"));
4473089Swyllys 		rv = KC_ERR_USAGE;
4483089Swyllys 		goto out;
4493089Swyllys 	} else if (strcmp(filename, KMF_DEFAULT_POLICY_FILE) == 0 &&
4503089Swyllys 	    strcmp(plc.name, KMF_DEFAULT_POLICY_NAME) == 0) {
4513089Swyllys 		(void) fprintf(stderr,
4523089Swyllys 		    gettext("Can not create a default policy in the default "
4533089Swyllys 		    "policy file\n"));
4543089Swyllys 		rv = KC_ERR_USAGE;
4553089Swyllys 		goto out;
4563089Swyllys 	}
4573089Swyllys 
4583089Swyllys 	/*
4593089Swyllys 	 * If the policy file exists and the policy is in the policy file
4603089Swyllys 	 * already, we will not create it again.
4613089Swyllys 	 */
4623089Swyllys 	if (access(filename, R_OK) == 0) {
4633089Swyllys 		POLICY_LIST *plclist = NULL, *pnode;
4643089Swyllys 		int found = 0;
4653089Swyllys 
4663089Swyllys 		rv = load_policies(filename, &plclist);
4673089Swyllys 		if (rv != KMF_OK)
4683089Swyllys 			goto out;
4693089Swyllys 
4703089Swyllys 		pnode = plclist;
4713089Swyllys 		while (pnode != NULL && !found) {
4723089Swyllys 			if (strcmp(plc.name, pnode->plc.name) == 0)
4733089Swyllys 				found++;
4743089Swyllys 			pnode = pnode->next;
4753089Swyllys 		}
4763089Swyllys 		free_policy_list(plclist);
4773089Swyllys 
4783089Swyllys 		if (found) {
4793089Swyllys 			(void) fprintf(stderr,
4803089Swyllys 			    gettext("Could not create policy \"%s\" - exists "
4813089Swyllys 			    "already\n"), plc.name);
4823089Swyllys 			rv = KC_ERR_USAGE;
4833089Swyllys 			goto out;
4843089Swyllys 		}
4853089Swyllys 	}
4863089Swyllys 
4873089Swyllys 	/*
4883089Swyllys 	 * If any OCSP attribute is set, turn on the OCSP checking flag.
4893089Swyllys 	 * Also set "has_resp_cert" to be true, if the responder cert
4903089Swyllys 	 * is provided.
4913089Swyllys 	 */
4923089Swyllys 	if (ocsp_set_attr > 0)
4933089Swyllys 		plc.revocation |= KMF_REVOCATION_METHOD_OCSP;
4943089Swyllys 
4953089Swyllys 	if (plc.VAL_OCSP_RESP_CERT.name != NULL &&
4963089Swyllys 	    plc.VAL_OCSP_RESP_CERT.serial != NULL) {
4973089Swyllys 		plc.VAL_OCSP.has_resp_cert = B_TRUE;
4983089Swyllys 	}
4993089Swyllys 
5003089Swyllys 	/*
50112611SJan.Pechanec@Sun.COM 	 * Setting mapper-name (with optional mapper-dir) and mapper-pathname is
50212611SJan.Pechanec@Sun.COM 	 * mutually exclusive. Also, you cannot set options only, you need the
50312611SJan.Pechanec@Sun.COM 	 * name or pathname, and you can set the directory only with the name,
50412611SJan.Pechanec@Sun.COM 	 * not the pathname.
50512611SJan.Pechanec@Sun.COM 	 */
50612611SJan.Pechanec@Sun.COM 	if ((plc.mapper.mapname != NULL && plc.mapper.pathname != NULL) ||
50712611SJan.Pechanec@Sun.COM 	    (plc.mapper.dir != NULL && plc.mapper.pathname != NULL) ||
50812611SJan.Pechanec@Sun.COM 	    (plc.mapper.dir != NULL && plc.mapper.mapname == NULL) ||
50912611SJan.Pechanec@Sun.COM 	    (plc.mapper.options != NULL && plc.mapper.mapname == NULL &&
51012611SJan.Pechanec@Sun.COM 	    plc.mapper.pathname == NULL)) {
51112611SJan.Pechanec@Sun.COM 		(void) fprintf(stderr,
51212611SJan.Pechanec@Sun.COM 		    gettext("Error in mapper input options\n"));
51312611SJan.Pechanec@Sun.COM 		rv = KC_ERR_USAGE;
51412611SJan.Pechanec@Sun.COM 		goto out;
51512611SJan.Pechanec@Sun.COM 	}
51612611SJan.Pechanec@Sun.COM 
51712611SJan.Pechanec@Sun.COM 	/*
5183089Swyllys 	 * If any CRL attribute is set, turn on the CRL checking flag.
5193089Swyllys 	 */
5203089Swyllys 	if (crl_set_attr > 0)
5213089Swyllys 		plc.revocation |= KMF_REVOCATION_METHOD_CRL;
5223089Swyllys 
5233089Swyllys 	/*
5243089Swyllys 	 * Does a sanity check on the new policy.
5253089Swyllys 	 */
5265051Swyllys 	ret = kmf_verify_policy(&plc);
5273089Swyllys 	if (ret != KMF_OK) {
5283089Swyllys 		print_sanity_error(ret);
5293089Swyllys 		rv = KC_ERR_ADD_POLICY;
5303089Swyllys 		goto out;
5313089Swyllys 	}
5323089Swyllys 
5333089Swyllys 	/*
5343089Swyllys 	 * Add to the DB.
5353089Swyllys 	 */
5365051Swyllys 	ret = kmf_add_policy_to_db(&plc, filename, B_FALSE);
5373089Swyllys 	if (ret != KMF_OK) {
5383089Swyllys 		(void) fprintf(stderr,
5393089Swyllys 		    gettext("Error adding policy to database: 0x%04x\n"), ret);
5403089Swyllys 		rv = KC_ERR_ADD_POLICY;
5413089Swyllys 	}
5423089Swyllys 
5433089Swyllys out:
5443089Swyllys 	if (filename != NULL)
5453089Swyllys 		free(filename);
5463089Swyllys 
5475051Swyllys 	kmf_free_policy_record(&plc);
5483089Swyllys 
5493089Swyllys 	return (rv);
5503089Swyllys }
551