199ebb4caSwyllys /*
299ebb4caSwyllys  * CDDL HEADER START
399ebb4caSwyllys  *
499ebb4caSwyllys  * The contents of this file are subject to the terms of the
599ebb4caSwyllys  * Common Development and Distribution License (the "License").
699ebb4caSwyllys  * You may not use this file except in compliance with the License.
799ebb4caSwyllys  *
899ebb4caSwyllys  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
999ebb4caSwyllys  * or http://www.opensolaris.org/os/licensing.
1099ebb4caSwyllys  * See the License for the specific language governing permissions
1199ebb4caSwyllys  * and limitations under the License.
1299ebb4caSwyllys  *
1399ebb4caSwyllys  * When distributing Covered Code, include this CDDL HEADER in each
1499ebb4caSwyllys  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1599ebb4caSwyllys  * If applicable, add the following below this CDDL HEADER, with the
1699ebb4caSwyllys  * fields enclosed by brackets "[]" replaced with your own identifying
1799ebb4caSwyllys  * information: Portions Copyright [yyyy] [name of copyright owner]
1899ebb4caSwyllys  *
1999ebb4caSwyllys  * CDDL HEADER END
2099ebb4caSwyllys  *
2130a5e8faSwyllys  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
2299ebb4caSwyllys  * Use is subject to license terms.
2399ebb4caSwyllys  */
2499ebb4caSwyllys 
2599ebb4caSwyllys #pragma ident	"%Z%%M%	%I%	%E% SMI"
2699ebb4caSwyllys 
2799ebb4caSwyllys #include <stdio.h>
2899ebb4caSwyllys #include <strings.h>
2999ebb4caSwyllys #include <ctype.h>
3099ebb4caSwyllys #include <libgen.h>
3199ebb4caSwyllys #include <libintl.h>
3299ebb4caSwyllys 
3399ebb4caSwyllys #include <libxml/tree.h>
3499ebb4caSwyllys #include <libxml/parser.h>
3599ebb4caSwyllys 
3699ebb4caSwyllys #include <kmfapiP.h>
3799ebb4caSwyllys #include "util.h"
3899ebb4caSwyllys 
39*431deaa0Shylee 
4099ebb4caSwyllys /* Supporting structures and global variables for getopt_av(). */
4199ebb4caSwyllys typedef struct	av_opts_s {
4299ebb4caSwyllys 	int		shortnm;	/* short name character */
4399ebb4caSwyllys 	char		*longnm;	/* long name string, NOT terminated */
4499ebb4caSwyllys 	int		longnm_len;	/* length of long name string */
4599ebb4caSwyllys 	boolean_t	has_arg;	/* takes optional argument */
4699ebb4caSwyllys } av_opts;
4799ebb4caSwyllys 
4899ebb4caSwyllys static av_opts		*opts_av = NULL;
4999ebb4caSwyllys static const char	*_save_optstr = NULL;
5099ebb4caSwyllys static int		_save_numopts = 0;
5199ebb4caSwyllys int			optind_av = 1;
5299ebb4caSwyllys char			*optarg_av = NULL;
5399ebb4caSwyllys 
5499ebb4caSwyllys void
5599ebb4caSwyllys free_policy_list(POLICY_LIST *plist)
5699ebb4caSwyllys {
5799ebb4caSwyllys 	POLICY_LIST *n = plist, *old;
5899ebb4caSwyllys 
5999ebb4caSwyllys 	if (plist == NULL)
6099ebb4caSwyllys 		return;
6199ebb4caSwyllys 
6299ebb4caSwyllys 	while (n != NULL) {
6399ebb4caSwyllys 		old = n;
6430a5e8faSwyllys 		kmf_free_policy_record(&n->plc);
6599ebb4caSwyllys 		n = n->next;
6699ebb4caSwyllys 		free(old);
6799ebb4caSwyllys 	}
6899ebb4caSwyllys 	plist = NULL;
6999ebb4caSwyllys }
7099ebb4caSwyllys 
7199ebb4caSwyllys int
7299ebb4caSwyllys load_policies(char *file, POLICY_LIST **policy_list)
7399ebb4caSwyllys {
7499ebb4caSwyllys 	int rv = KC_OK;
7599ebb4caSwyllys 	KMF_RETURN kmfrv = KMF_OK;
7699ebb4caSwyllys 	POLICY_LIST *newitem, *plist = NULL;
7799ebb4caSwyllys 	xmlParserCtxtPtr ctxt;
7899ebb4caSwyllys 	xmlDocPtr doc = NULL;
7999ebb4caSwyllys 	xmlNodePtr cur, node;
8099ebb4caSwyllys 
8199ebb4caSwyllys 	/* Create a parser context */
8299ebb4caSwyllys 	ctxt = xmlNewParserCtxt();
8399ebb4caSwyllys 	if (ctxt == NULL)
8499ebb4caSwyllys 		return (KMF_ERR_POLICY_DB_FORMAT);
8599ebb4caSwyllys 
8699ebb4caSwyllys 	/* Read the policy DB and verify it against the schema. */
8799ebb4caSwyllys 	doc = xmlCtxtReadFile(ctxt, file, NULL,
8899ebb4caSwyllys 	    XML_PARSE_DTDVALID | XML_PARSE_NOERROR | XML_PARSE_NOWARNING);
8999ebb4caSwyllys 	if (doc == NULL || ctxt->valid == 0) {
9099ebb4caSwyllys 		kmfrv = KMF_ERR_POLICY_DB_FORMAT;
9199ebb4caSwyllys 		goto end;
9299ebb4caSwyllys 	}
9399ebb4caSwyllys 
9499ebb4caSwyllys 	cur = xmlDocGetRootElement(doc);
9599ebb4caSwyllys 	if (cur == NULL) {
9699ebb4caSwyllys 		kmfrv = KMF_ERR_POLICY_DB_FORMAT;
9799ebb4caSwyllys 		goto end;
9899ebb4caSwyllys 	}
9999ebb4caSwyllys 
10099ebb4caSwyllys 	node = cur->xmlChildrenNode;
10199ebb4caSwyllys 	while (node != NULL) {
10299ebb4caSwyllys 		char *c;
10399ebb4caSwyllys 		/*
10499ebb4caSwyllys 		 * Search for the policy that matches the given name.
10599ebb4caSwyllys 		 */
10699ebb4caSwyllys 		if (!xmlStrcmp((const xmlChar *)node->name,
10730a5e8faSwyllys 		    (const xmlChar *)KMF_POLICY_ELEMENT)) {
10899ebb4caSwyllys 			/* Check the name attribute */
10999ebb4caSwyllys 			c = (char *)xmlGetProp(node,
11030a5e8faSwyllys 			    (const xmlChar *)KMF_POLICY_NAME_ATTR);
11199ebb4caSwyllys 
11299ebb4caSwyllys 			/* If a match, parse the rest of the data */
11399ebb4caSwyllys 			if (c != NULL) {
11499ebb4caSwyllys 				xmlFree(c);
11599ebb4caSwyllys 				newitem = malloc(sizeof (POLICY_LIST));
11699ebb4caSwyllys 				if (newitem != NULL) {
11799ebb4caSwyllys 					(void) memset(newitem, 0,
11830a5e8faSwyllys 					    sizeof (POLICY_LIST));
11999ebb4caSwyllys 					kmfrv = parsePolicyElement(node,
12030a5e8faSwyllys 					    &newitem->plc);
12199ebb4caSwyllys 				} else {
12299ebb4caSwyllys 					kmfrv = KMF_ERR_MEMORY;
12399ebb4caSwyllys 					goto end;
12499ebb4caSwyllys 				}
12599ebb4caSwyllys 				/* add to linked list */
12699ebb4caSwyllys 				if (plist == NULL) {
12799ebb4caSwyllys 					plist = newitem;
12899ebb4caSwyllys 				} else {
12999ebb4caSwyllys 					POLICY_LIST *n = plist;
13099ebb4caSwyllys 					while (n->next != NULL)
13199ebb4caSwyllys 						n = n->next;
13299ebb4caSwyllys 
13399ebb4caSwyllys 					n->next = newitem;
13499ebb4caSwyllys 					newitem->next = NULL;
13599ebb4caSwyllys 				}
13699ebb4caSwyllys 			}
13799ebb4caSwyllys 		}
13899ebb4caSwyllys 		node = node->next;
13999ebb4caSwyllys 	}
14099ebb4caSwyllys 
14199ebb4caSwyllys end:
14299ebb4caSwyllys 	if (ctxt != NULL)
14399ebb4caSwyllys 		xmlFreeParserCtxt(ctxt);
14499ebb4caSwyllys 
14599ebb4caSwyllys 	if (doc != NULL)
14699ebb4caSwyllys 		xmlFreeDoc(doc);
14799ebb4caSwyllys 
14899ebb4caSwyllys 	if (kmfrv != KMF_OK) {
14999ebb4caSwyllys 		free_policy_list(plist);
15099ebb4caSwyllys 		rv = KC_ERR_LOADDB;
15199ebb4caSwyllys 	} else {
15299ebb4caSwyllys 		*policy_list = plist;
15399ebb4caSwyllys 	}
15499ebb4caSwyllys 
15599ebb4caSwyllys 	return (rv);
15699ebb4caSwyllys }
15799ebb4caSwyllys 
15899ebb4caSwyllys /*
15999ebb4caSwyllys  * Return 0 if there is any error in the input string.
16099ebb4caSwyllys  */
16199ebb4caSwyllys uint16_t
16299ebb4caSwyllys parseKUlist(char *kustring)
16399ebb4caSwyllys {
16499ebb4caSwyllys 	uint16_t cur_bit;
16599ebb4caSwyllys 	uint16_t kubits = 0;
16699ebb4caSwyllys 	char *p;
16799ebb4caSwyllys 
16899ebb4caSwyllys 	p = strtok(kustring, ",");
16999ebb4caSwyllys 	while (p != NULL) {
17030a5e8faSwyllys 		cur_bit = kmf_string_to_ku(p);
17199ebb4caSwyllys 		if (cur_bit == 0) {
17299ebb4caSwyllys 			kubits = 0;
17399ebb4caSwyllys 			break;
17499ebb4caSwyllys 		}
17599ebb4caSwyllys 		kubits |= cur_bit;
17699ebb4caSwyllys 		p = strtok(NULL, ",");
17799ebb4caSwyllys 	}
17899ebb4caSwyllys 
17999ebb4caSwyllys 	return (kubits);
18099ebb4caSwyllys }
18199ebb4caSwyllys 
18299ebb4caSwyllys static void
18399ebb4caSwyllys addToEKUList(KMF_EKU_POLICY *ekus, KMF_OID *newoid)
18499ebb4caSwyllys {
18599ebb4caSwyllys 	if (newoid != NULL && ekus != NULL) {
18699ebb4caSwyllys 		ekus->eku_count++;
18799ebb4caSwyllys 		ekus->ekulist = realloc(
18830a5e8faSwyllys 		    ekus->ekulist, ekus->eku_count * sizeof (KMF_OID));
18999ebb4caSwyllys 		if (ekus->ekulist != NULL) {
19099ebb4caSwyllys 			ekus->ekulist[ekus->eku_count-1] = *newoid;
19199ebb4caSwyllys 		}
19299ebb4caSwyllys 	}
19399ebb4caSwyllys }
19499ebb4caSwyllys 
19599ebb4caSwyllys int
19699ebb4caSwyllys parseEKUNames(char *ekulist, KMF_POLICY_RECORD *plc)
19799ebb4caSwyllys {
19899ebb4caSwyllys 	int rv = KC_OK;
19999ebb4caSwyllys 	char *p;
20099ebb4caSwyllys 	KMF_OID *newoid;
20199ebb4caSwyllys 	KMF_EKU_POLICY *ekus = &plc->eku_set;
20299ebb4caSwyllys 
20399ebb4caSwyllys 	if (ekulist == NULL || !strlen(ekulist))
20499ebb4caSwyllys 		return (0);
20599ebb4caSwyllys 
20699ebb4caSwyllys 	/*
20799ebb4caSwyllys 	 * The list should be comma separated list of EKU Names.
20899ebb4caSwyllys 	 */
20999ebb4caSwyllys 	p = strtok(ekulist, ",");
21099ebb4caSwyllys 
21199ebb4caSwyllys 	/* If no tokens found, then maybe its just a single EKU value */
21299ebb4caSwyllys 	if (p == NULL) {
21330a5e8faSwyllys 		newoid = kmf_ekuname_to_oid(ekulist);
21499ebb4caSwyllys 		if (newoid != NULL) {
21599ebb4caSwyllys 			addToEKUList(ekus, newoid);
21699ebb4caSwyllys 			free(newoid);
21799ebb4caSwyllys 		} else {
21899ebb4caSwyllys 			rv = KC_ERR_USAGE;
21999ebb4caSwyllys 		}
22099ebb4caSwyllys 	}
22199ebb4caSwyllys 
22299ebb4caSwyllys 	while (p != NULL) {
22330a5e8faSwyllys 		newoid = kmf_ekuname_to_oid(p);
22499ebb4caSwyllys 		if (newoid != NULL) {
22599ebb4caSwyllys 			addToEKUList(ekus, newoid);
22699ebb4caSwyllys 			free(newoid);
22799ebb4caSwyllys 		} else {
22899ebb4caSwyllys 			rv = KC_ERR_USAGE;
22999ebb4caSwyllys 			break;
23099ebb4caSwyllys 		}
23199ebb4caSwyllys 		p = strtok(NULL, ",");
23299ebb4caSwyllys 	}
23399ebb4caSwyllys 
23499ebb4caSwyllys 	if (rv != KC_OK)
23530a5e8faSwyllys 		kmf_free_eku_policy(ekus);
23699ebb4caSwyllys 
23799ebb4caSwyllys 	return (rv);
23899ebb4caSwyllys }
23999ebb4caSwyllys 
24099ebb4caSwyllys int
24199ebb4caSwyllys parseEKUOIDs(char *ekulist, KMF_POLICY_RECORD *plc)
24299ebb4caSwyllys {
24399ebb4caSwyllys 	int rv = KC_OK;
24499ebb4caSwyllys 	char *p;
24530a5e8faSwyllys 	KMF_OID newoid = {NULL, 0};
24699ebb4caSwyllys 	KMF_EKU_POLICY *ekus = &plc->eku_set;
24799ebb4caSwyllys 
24899ebb4caSwyllys 	if (ekulist == NULL || !strlen(ekulist))
24999ebb4caSwyllys 		return (0);
25099ebb4caSwyllys 
25199ebb4caSwyllys 	/*
25299ebb4caSwyllys 	 * The list should be comma separated list of EKU Names.
25399ebb4caSwyllys 	 */
25499ebb4caSwyllys 	p = strtok(ekulist, ",");
25599ebb4caSwyllys 	if (p == NULL) {
25630a5e8faSwyllys 		if (kmf_string_to_oid(ekulist, &newoid) == KMF_OK) {
25730a5e8faSwyllys 			addToEKUList(ekus, &newoid);
25899ebb4caSwyllys 		} else {
25999ebb4caSwyllys 			rv = KC_ERR_USAGE;
26099ebb4caSwyllys 		}
26199ebb4caSwyllys 	}
26299ebb4caSwyllys 
26399ebb4caSwyllys 	while (p != NULL && rv == 0) {
26430a5e8faSwyllys 		if (kmf_string_to_oid(p, &newoid) == KMF_OK) {
26530a5e8faSwyllys 			addToEKUList(ekus, &newoid);
26699ebb4caSwyllys 		} else {
26799ebb4caSwyllys 			rv = KC_ERR_USAGE;
26899ebb4caSwyllys 			break;
26999ebb4caSwyllys 		}
27099ebb4caSwyllys 		p = strtok(NULL, ",");
27199ebb4caSwyllys 	}
27299ebb4caSwyllys 
27399ebb4caSwyllys 	if (rv != KC_OK)
27430a5e8faSwyllys 		kmf_free_eku_policy(ekus);
27599ebb4caSwyllys 
27699ebb4caSwyllys 	return (rv);
27799ebb4caSwyllys }
27899ebb4caSwyllys 
27999ebb4caSwyllys int
28099ebb4caSwyllys get_boolean(char *arg)
28199ebb4caSwyllys {
28299ebb4caSwyllys 	if (arg == NULL)
28399ebb4caSwyllys 		return (-1);
28499ebb4caSwyllys 	if (strcasecmp(arg, "true") == 0)
28599ebb4caSwyllys 		return (1);
28699ebb4caSwyllys 	if (strcasecmp(arg, "false") == 0)
28799ebb4caSwyllys 		return (0);
28899ebb4caSwyllys 	return (-1);
28999ebb4caSwyllys }
29099ebb4caSwyllys 
29199ebb4caSwyllys /*
29299ebb4caSwyllys  * This function processes the input string.  It removes the beginning
29399ebb4caSwyllys  * and ending blank's first, makes a copy of the resulting string and
29499ebb4caSwyllys  * return it.
29599ebb4caSwyllys  *
29699ebb4caSwyllys  * This function returns NULL, if there is an error in the
29799ebb4caSwyllys  * input string or when the system is out of memory.  The output
29899ebb4caSwyllys  * "err_flag" argument will record the error code, if it is not NULL.
29999ebb4caSwyllys  */
30099ebb4caSwyllys char *
30199ebb4caSwyllys get_string(char *str, int *err_flag)
30299ebb4caSwyllys {
30399ebb4caSwyllys 	char *p;
30499ebb4caSwyllys 	int len, i;
30599ebb4caSwyllys 	char *retstr = NULL;
30699ebb4caSwyllys 
30799ebb4caSwyllys 	if (str == NULL) {
30899ebb4caSwyllys 		if (err_flag != NULL)
30999ebb4caSwyllys 			*err_flag = KC_ERR_USAGE;
31099ebb4caSwyllys 		return (NULL);
31199ebb4caSwyllys 	}
31299ebb4caSwyllys 
31399ebb4caSwyllys 	/* Remove beginning whitespace */
31499ebb4caSwyllys 	p = str;
31599ebb4caSwyllys 	while (p != NULL && isspace(*p))
31699ebb4caSwyllys 		p++;
31799ebb4caSwyllys 
31899ebb4caSwyllys 	if (p == NULL) {
31999ebb4caSwyllys 		if (err_flag != NULL)
32099ebb4caSwyllys 			*err_flag = KC_ERR_USAGE;
32199ebb4caSwyllys 		return (NULL);
32299ebb4caSwyllys 	}
32399ebb4caSwyllys 
32499ebb4caSwyllys 	/* Remove the trailing blanks */
32599ebb4caSwyllys 	len = strlen(p);
32699ebb4caSwyllys 	while (len > 0 && isspace(p[len-1]))
32799ebb4caSwyllys 		len--;
32899ebb4caSwyllys 
32999ebb4caSwyllys 	if (len == 0) {
33099ebb4caSwyllys 		if (err_flag != NULL)
33199ebb4caSwyllys 			*err_flag = KC_ERR_USAGE;
33299ebb4caSwyllys 		return (NULL);
33399ebb4caSwyllys 	}
33499ebb4caSwyllys 
33599ebb4caSwyllys 	/* Check if there is any non-printable character */
33699ebb4caSwyllys 	i = 0;
33799ebb4caSwyllys 	while (i < len) {
33899ebb4caSwyllys 		if (isprint(p[i]))
33999ebb4caSwyllys 			i++;
34099ebb4caSwyllys 		else {
34199ebb4caSwyllys 			if (err_flag != NULL)
34299ebb4caSwyllys 				*err_flag = KC_ERR_USAGE;
34399ebb4caSwyllys 			return (NULL);
34499ebb4caSwyllys 		}
34599ebb4caSwyllys 	}
34699ebb4caSwyllys 
34799ebb4caSwyllys 	/* Make a copy of the string and return it */
34899ebb4caSwyllys 	retstr = malloc(len + 1);
34999ebb4caSwyllys 	if (retstr == NULL) {
35099ebb4caSwyllys 		if (err_flag != NULL)
35199ebb4caSwyllys 			*err_flag = KC_ERR_MEMORY;
35299ebb4caSwyllys 		return (NULL);
35399ebb4caSwyllys 	}
35499ebb4caSwyllys 
35599ebb4caSwyllys 	if (err_flag != NULL)
35699ebb4caSwyllys 		*err_flag = KC_OK;
35799ebb4caSwyllys 
35899ebb4caSwyllys 	(void) strncpy(retstr, p, len);
35999ebb4caSwyllys 	retstr[len] = '\0';
36099ebb4caSwyllys 	return (retstr);
36199ebb4caSwyllys }
36299ebb4caSwyllys 
36399ebb4caSwyllys /*
36499ebb4caSwyllys  * Breaks out the getopt-style option string into a structure that can be
36599ebb4caSwyllys  * traversed later for calls to getopt_av().  Option string is NOT altered,
36699ebb4caSwyllys  * but the struct fields point to locations within option string.
36799ebb4caSwyllys  */
36899ebb4caSwyllys static int
36999ebb4caSwyllys populate_opts(char *optstring)
37099ebb4caSwyllys {
37199ebb4caSwyllys 	int		i;
37299ebb4caSwyllys 	av_opts		*temp;
37399ebb4caSwyllys 	char		*marker;
37499ebb4caSwyllys 
37599ebb4caSwyllys 	if (optstring == NULL || *optstring == '\0')
37699ebb4caSwyllys 		return (0);
37799ebb4caSwyllys 
37899ebb4caSwyllys 	/*
37999ebb4caSwyllys 	 * This tries to imitate getopt(3c) Each option must conform to:
38099ebb4caSwyllys 	 * <short name char> [ ':' ] [ '(' <long name string> ')' ]
38199ebb4caSwyllys 	 * If long name is missing, the short name is used for long name.
38299ebb4caSwyllys 	 */
38399ebb4caSwyllys 	for (i = 0; *optstring != '\0'; i++) {
38499ebb4caSwyllys 		if ((temp = (av_opts *)((i == 0) ? malloc(sizeof (av_opts)) :
38599ebb4caSwyllys 		    realloc(opts_av, (i+1) * sizeof (av_opts)))) == NULL) {
38699ebb4caSwyllys 			free(opts_av);
38799ebb4caSwyllys 			opts_av = NULL;
38899ebb4caSwyllys 			return (0);
38999ebb4caSwyllys 		} else
39099ebb4caSwyllys 			opts_av = (av_opts *)temp;
39199ebb4caSwyllys 
39299ebb4caSwyllys 		marker = optstring;		/* may need optstring later */
39399ebb4caSwyllys 
39499ebb4caSwyllys 		opts_av[i].shortnm = *marker++;	/* set short name */
39599ebb4caSwyllys 
39699ebb4caSwyllys 		if (*marker == ':') {		/* check for opt arg */
39799ebb4caSwyllys 			marker++;
39899ebb4caSwyllys 			opts_av[i].has_arg = B_TRUE;
39999ebb4caSwyllys 		}
40099ebb4caSwyllys 
40199ebb4caSwyllys 		if (*marker == '(') {		/* check and set long name */
40299ebb4caSwyllys 			marker++;
40399ebb4caSwyllys 			opts_av[i].longnm = marker;
40499ebb4caSwyllys 			opts_av[i].longnm_len = strcspn(marker, ")");
40599ebb4caSwyllys 			optstring = marker + opts_av[i].longnm_len + 1;
40699ebb4caSwyllys 		} else {
40799ebb4caSwyllys 			/* use short name option character */
40899ebb4caSwyllys 			opts_av[i].longnm = optstring;
40999ebb4caSwyllys 			opts_av[i].longnm_len = 1;
41099ebb4caSwyllys 			optstring = marker;
41199ebb4caSwyllys 		}
41299ebb4caSwyllys 	}
41399ebb4caSwyllys 
41499ebb4caSwyllys 	return (i);
41599ebb4caSwyllys }
41699ebb4caSwyllys 
41799ebb4caSwyllys /*
41899ebb4caSwyllys  * getopt_av() is very similar to getopt(3c) in that the takes an option
41999ebb4caSwyllys  * string, compares command line arguments for matches, and returns a single
42099ebb4caSwyllys  * letter option when a match is found.  However, getopt_av() differs from
42199ebb4caSwyllys  * getopt(3c) by allowing both longname options and values be found
42299ebb4caSwyllys  * on the command line.
42399ebb4caSwyllys  */
42499ebb4caSwyllys int
42599ebb4caSwyllys getopt_av(int argc, char * const *argv, const char *optstring)
42699ebb4caSwyllys {
42799ebb4caSwyllys 	int	i;
42899ebb4caSwyllys 	int	len;
42999ebb4caSwyllys 
43099ebb4caSwyllys 	if (optind_av >= argc)
43199ebb4caSwyllys 		return (EOF);
43299ebb4caSwyllys 
43399ebb4caSwyllys 	/* First time or when optstring changes from previous one */
43499ebb4caSwyllys 	if (_save_optstr != optstring) {
43599ebb4caSwyllys 		if (opts_av != NULL)
43630a5e8faSwyllys 			free(opts_av);
43799ebb4caSwyllys 		opts_av = NULL;
43899ebb4caSwyllys 		_save_optstr = optstring;
43999ebb4caSwyllys 		_save_numopts = populate_opts((char *)optstring);
44099ebb4caSwyllys 	}
44199ebb4caSwyllys 
44299ebb4caSwyllys 	for (i = 0; i < _save_numopts; i++) {
44399ebb4caSwyllys 		if (strcmp(argv[optind_av], "--") == 0) {
44499ebb4caSwyllys 			optind_av++;
44599ebb4caSwyllys 			break;
44699ebb4caSwyllys 		}
44799ebb4caSwyllys 
44899ebb4caSwyllys 		len = strcspn(argv[optind_av], "=");
44999ebb4caSwyllys 
45099ebb4caSwyllys 		if (len == opts_av[i].longnm_len && strncmp(argv[optind_av],
45199ebb4caSwyllys 		    opts_av[i].longnm, opts_av[i].longnm_len) == 0) {
45299ebb4caSwyllys 			/* matched */
45399ebb4caSwyllys 			if (!opts_av[i].has_arg) {
45499ebb4caSwyllys 				optind_av++;
45599ebb4caSwyllys 				return (opts_av[i].shortnm);
45699ebb4caSwyllys 			}
45799ebb4caSwyllys 
45899ebb4caSwyllys 			/* needs optarg */
45999ebb4caSwyllys 			if (argv[optind_av][len] == '=') {
46099ebb4caSwyllys 				optarg_av = &(argv[optind_av][len+1]);
46199ebb4caSwyllys 				optind_av++;
46299ebb4caSwyllys 				return (opts_av[i].shortnm);
46399ebb4caSwyllys 			}
46499ebb4caSwyllys 
46599ebb4caSwyllys 			optarg_av = NULL;
46699ebb4caSwyllys 			optind_av++;
46799ebb4caSwyllys 			return ((int)'?');
46899ebb4caSwyllys 		}
46999ebb4caSwyllys 	}
47099ebb4caSwyllys 
47199ebb4caSwyllys 	return (EOF);
47299ebb4caSwyllys }
47399ebb4caSwyllys 
47499ebb4caSwyllys void
47599ebb4caSwyllys print_sanity_error(KMF_RETURN ret)
47699ebb4caSwyllys {
47799ebb4caSwyllys 	switch (ret) {
47899ebb4caSwyllys 	case KMF_ERR_POLICY_NAME:
47999ebb4caSwyllys 		(void) fprintf(stderr, gettext("Error in the policy name\n"));
48099ebb4caSwyllys 		break;
48199ebb4caSwyllys 	case KMF_ERR_TA_POLICY:
48299ebb4caSwyllys 		(void) fprintf(stderr,
48399ebb4caSwyllys 		    gettext("Error in trust anchor attributes\n"));
48499ebb4caSwyllys 		break;
48599ebb4caSwyllys 	case KMF_ERR_OCSP_POLICY:
48699ebb4caSwyllys 		(void) fprintf(stderr,
48799ebb4caSwyllys 		    gettext("Error in OCSP policy attributes\n"));
48899ebb4caSwyllys 		break;
48999ebb4caSwyllys 	default:
49099ebb4caSwyllys 		break;
49199ebb4caSwyllys 	}
49299ebb4caSwyllys }
493*431deaa0Shylee 
494*431deaa0Shylee 
495*431deaa0Shylee conf_entry_t *
496*431deaa0Shylee get_keystore_entry(char *kstore_name)
497*431deaa0Shylee {
498*431deaa0Shylee 	conf_entrylist_t *phead = NULL;
499*431deaa0Shylee 	conf_entrylist_t *ptr;
500*431deaa0Shylee 	conf_entry_t	*rtn_entry = NULL;
501*431deaa0Shylee 
502*431deaa0Shylee 	if (kstore_name == NULL)
503*431deaa0Shylee 		return (NULL);
504*431deaa0Shylee 
505*431deaa0Shylee 	if (get_entrylist(&phead) != KMF_OK)
506*431deaa0Shylee 		return (NULL);
507*431deaa0Shylee 
508*431deaa0Shylee 	ptr = phead;
509*431deaa0Shylee 	while (ptr != NULL) {
510*431deaa0Shylee 		if (strcmp(ptr->entry->keystore, kstore_name) == 0)
511*431deaa0Shylee 			break;
512*431deaa0Shylee 		ptr = ptr->next;
513*431deaa0Shylee 	}
514*431deaa0Shylee 
515*431deaa0Shylee 	if (ptr != NULL) /* found the entry */
516*431deaa0Shylee 		rtn_entry = dup_entry(ptr->entry);
517*431deaa0Shylee 
518*431deaa0Shylee 	free_entrylist(phead);
519*431deaa0Shylee 	return (rtn_entry);
520*431deaa0Shylee }
521