199ebb4cwyllys/*
299ebb4cwyllys * CDDL HEADER START
399ebb4cwyllys *
499ebb4cwyllys * The contents of this file are subject to the terms of the
599ebb4cwyllys * Common Development and Distribution License (the "License").
699ebb4cwyllys * You may not use this file except in compliance with the License.
799ebb4cwyllys *
899ebb4cwyllys * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
999ebb4cwyllys * or http://www.opensolaris.org/os/licensing.
1099ebb4cwyllys * See the License for the specific language governing permissions
1199ebb4cwyllys * and limitations under the License.
1299ebb4cwyllys *
1399ebb4cwyllys * When distributing Covered Code, include this CDDL HEADER in each
1499ebb4cwyllys * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1599ebb4cwyllys * If applicable, add the following below this CDDL HEADER, with the
1699ebb4cwyllys * fields enclosed by brackets "[]" replaced with your own identifying
1799ebb4cwyllys * information: Portions Copyright [yyyy] [name of copyright owner]
1899ebb4cwyllys *
1999ebb4cwyllys * CDDL HEADER END
20269e59fJan Pechanec *
21269e59fJan Pechanec * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
2299ebb4cwyllys */
2399ebb4cwyllys
2499ebb4cwyllys#include <stdlib.h>
2599ebb4cwyllys#include <ctype.h>
2699ebb4cwyllys#include <strings.h>
2799ebb4cwyllys#include <unistd.h>
2899ebb4cwyllys#include <errno.h>
29269e59fJan Pechanec#include <libgen.h>
3099ebb4cwyllys#include <sys/param.h>
3199ebb4cwyllys#include <sys/stat.h>
3299ebb4cwyllys
3399ebb4cwyllys#include <kmfapiP.h>
3499ebb4cwyllys#include <libxml/tree.h>
3599ebb4cwyllys#include <libxml/parser.h>
3699ebb4cwyllys
3799ebb4cwyllystypedef struct {
3899ebb4cwyllys	char	*ekuname;
3999ebb4cwyllys	KMF_OID	*oid;
4099ebb4cwyllys} EKUName2OID;
4199ebb4cwyllys
4299ebb4cwyllysstatic EKUName2OID EKUList[] = {
4399ebb4cwyllys	{"serverAuth",		(KMF_OID *)&KMFOID_PKIX_KP_ServerAuth},
4499ebb4cwyllys	{"clientAuth",		(KMF_OID *)&KMFOID_PKIX_KP_ClientAuth},
4599ebb4cwyllys	{"codeSigning",		(KMF_OID *)&KMFOID_PKIX_KP_CodeSigning},
4699ebb4cwyllys	{"emailProtection",	(KMF_OID *)&KMFOID_PKIX_KP_EmailProtection},
4799ebb4cwyllys	{"ipsecEndSystem",	(KMF_OID *)&KMFOID_PKIX_KP_IPSecEndSystem},
4899ebb4cwyllys	{"ipsecTunnel",		(KMF_OID *)&KMFOID_PKIX_KP_IPSecTunnel},
4999ebb4cwyllys	{"ipsecUser",		(KMF_OID *)&KMFOID_PKIX_KP_IPSecUser},
5099ebb4cwyllys	{"timeStamping",	(KMF_OID *)&KMFOID_PKIX_KP_TimeStamping},
5172ca8ccWyllys Ingersoll	{"OCSPSigning", 	(KMF_OID *)&KMFOID_PKIX_KP_OCSPSigning},
5272ca8ccWyllys Ingersoll	{"KPClientAuth", 	(KMF_OID *)&KMFOID_PKINIT_ClientAuth},
5372ca8ccWyllys Ingersoll	{"KPKdc", 		(KMF_OID *)&KMFOID_PKINIT_Kdc},
5472ca8ccWyllys Ingersoll	{"scLogon", 		(KMF_OID *)&KMFOID_MS_KP_SCLogon}
5599ebb4cwyllys};
5699ebb4cwyllys
5799ebb4cwyllysstatic int num_ekus = sizeof (EKUList) / sizeof (EKUName2OID);
5899ebb4cwyllys
5999ebb4cwyllysstatic void
6099ebb4cwyllysaddFormatting(xmlNodePtr parent, char *text)
6199ebb4cwyllys{
6299ebb4cwyllys	xmlNodePtr snode;
6399ebb4cwyllys
6499ebb4cwyllys	if (parent == NULL || text == NULL)
6599ebb4cwyllys		return;
6699ebb4cwyllys
6799ebb4cwyllys	snode = xmlNewText((const xmlChar *)text);
6899ebb4cwyllys	if (snode != NULL) {
695ad42b1Surya Prakki		(void) xmlAddChild(parent, snode);
7099ebb4cwyllys	}
7199ebb4cwyllys}
7299ebb4cwyllys
7399ebb4cwyllysstatic void
7499ebb4cwyllysparseOCSPValidation(xmlNodePtr node, KMF_VALIDATION_POLICY *vinfo)
7599ebb4cwyllys{
7699ebb4cwyllys	xmlNodePtr n;
7799ebb4cwyllys	char *c;
7899ebb4cwyllys	n = node->children;
7999ebb4cwyllys	while (n != NULL) {
8099ebb4cwyllys		if (!xmlStrcmp((const xmlChar *)n->name,
8130a5e8fwyllys		    (const xmlChar *)KMF_OCSP_BASIC_ELEMENT)) {
8299ebb4cwyllys
8399ebb4cwyllys			vinfo->ocsp_info.basic.responderURI =
8499ebb4cwyllys			    (char *)xmlGetProp(n,
8599ebb4cwyllys			    (const xmlChar *)KMF_OCSP_RESPONDER_ATTR);
8699ebb4cwyllys
8799ebb4cwyllys			vinfo->ocsp_info.basic.proxy = (char *)xmlGetProp(n,
8899ebb4cwyllys			    (const xmlChar *)KMF_OCSP_PROXY_ATTR);
8999ebb4cwyllys
9099ebb4cwyllys			c = (char *)xmlGetProp(n,
9199ebb4cwyllys			    (const xmlChar *)KMF_OCSP_URI_ATTR);
9299ebb4cwyllys			if (c != NULL && !strcasecmp(c, "true")) {
9399ebb4cwyllys				vinfo->ocsp_info.basic.uri_from_cert = 1;
9499ebb4cwyllys				xmlFree(c);
9599ebb4cwyllys			}
9699ebb4cwyllys
9799ebb4cwyllys			vinfo->ocsp_info.basic.response_lifetime =
9899ebb4cwyllys			    (char *)xmlGetProp(n,
9999ebb4cwyllys			    (const xmlChar *)KMF_OCSP_RESPONSE_LIFETIME_ATTR);
10099ebb4cwyllys
10199ebb4cwyllys			c = (char *)xmlGetProp(n,
10299ebb4cwyllys			    (const xmlChar *)KMF_OCSP_IGNORE_SIGN_ATTR);
10399ebb4cwyllys			if (c != NULL && !strcasecmp(c, "true")) {
10499ebb4cwyllys				vinfo->ocsp_info.basic.ignore_response_sign = 1;
10599ebb4cwyllys				xmlFree(c);
10699ebb4cwyllys			}
10799ebb4cwyllys
10899ebb4cwyllys		} else if (!xmlStrcmp((const xmlChar *)n->name,
10999ebb4cwyllys		    (const xmlChar *)KMF_OCSP_RESPONDER_CERT_ELEMENT)) {
11099ebb4cwyllys
11199ebb4cwyllys			vinfo->ocsp_info.resp_cert.name =
11299ebb4cwyllys			    (char *)xmlGetProp(n,
11399ebb4cwyllys			    (const xmlChar *)KMF_CERT_NAME_ATTR);
11499ebb4cwyllys			vinfo->ocsp_info.resp_cert.serial =
11530a5e8fwyllys			    (char *)xmlGetProp(n,
11630a5e8fwyllys			    (const xmlChar *)KMF_CERT_SERIAL_ATTR);
11799ebb4cwyllys			vinfo->ocsp_info.has_resp_cert = 1;
11899ebb4cwyllys		}
11999ebb4cwyllys
12099ebb4cwyllys		n = n->next;
12199ebb4cwyllys	}
12299ebb4cwyllys
12399ebb4cwyllys}
12499ebb4cwyllys
12599ebb4cwyllys/*
12699ebb4cwyllys * Parse the "validation-methods" section of the policy.
12799ebb4cwyllys */
12899ebb4cwyllysstatic void
12999ebb4cwyllysparseValidation(xmlNodePtr node, KMF_VALIDATION_POLICY *vinfo,
13099ebb4cwyllys	KMF_POLICY_RECORD *policy)
13199ebb4cwyllys{
13299ebb4cwyllys	xmlNodePtr n;
13399ebb4cwyllys	char *c;
13499ebb4cwyllys	n = node->children;
13599ebb4cwyllys	while (n != NULL) {
13699ebb4cwyllys		if (!xmlStrcmp((const xmlChar *)n->name,
13730a5e8fwyllys		    (const xmlChar *)KMF_OCSP_ELEMENT)) {
13899ebb4cwyllys
13999ebb4cwyllys			parseOCSPValidation(n, &policy->validation_info);
14099ebb4cwyllys			policy->revocation |= KMF_REVOCATION_METHOD_OCSP;
14199ebb4cwyllys
14299ebb4cwyllys
14399ebb4cwyllys		} else if (!xmlStrcmp((const xmlChar *)n->name,
14430a5e8fwyllys		    (const xmlChar *)KMF_CRL_ELEMENT)) {
14599ebb4cwyllys
14699ebb4cwyllys			vinfo->crl_info.basefilename = (char *)xmlGetProp(n,
14730a5e8fwyllys			    (const xmlChar *)KMF_CRL_BASENAME_ATTR);
14899ebb4cwyllys
14999ebb4cwyllys			vinfo->crl_info.directory = (char *)xmlGetProp(n,
15030a5e8fwyllys			    (const xmlChar *)KMF_CRL_DIRECTORY_ATTR);
15199ebb4cwyllys
15299ebb4cwyllys			c = (char *)xmlGetProp(n,
15330a5e8fwyllys			    (const xmlChar *)KMF_CRL_GET_URI_ATTR);
15499ebb4cwyllys			if (c != NULL && !strcasecmp(c, "true")) {
15599ebb4cwyllys				vinfo->crl_info.get_crl_uri = 1;
15699ebb4cwyllys			} else {
15799ebb4cwyllys				vinfo->crl_info.get_crl_uri = 0;
15899ebb4cwyllys			}
15999ebb4cwyllys			xmlFree(c);
16099ebb4cwyllys
16199ebb4cwyllys			vinfo->crl_info.proxy = (char *)xmlGetProp(n,
16299ebb4cwyllys			    (const xmlChar *)KMF_CRL_PROXY_ATTR);
16399ebb4cwyllys
16499ebb4cwyllys			c = (char *)xmlGetProp(n,
16530a5e8fwyllys			    (const xmlChar *)KMF_CRL_IGNORE_SIGN_ATTR);
16699ebb4cwyllys			if (c != NULL && !strcasecmp(c, "true")) {
16799ebb4cwyllys				vinfo->crl_info.ignore_crl_sign = 1;
16899ebb4cwyllys			} else {
16999ebb4cwyllys				vinfo->crl_info.ignore_crl_sign = 0;
17099ebb4cwyllys			}
17199ebb4cwyllys			xmlFree(c);
17299ebb4cwyllys
17399ebb4cwyllys			c = (char *)xmlGetProp(n,
17430a5e8fwyllys			    (const xmlChar *)KMF_CRL_IGNORE_DATE_ATTR);
17599ebb4cwyllys			if (c != NULL && !strcasecmp(c, "true")) {
17699ebb4cwyllys				vinfo->crl_info.ignore_crl_date = 1;
17799ebb4cwyllys			} else {
17899ebb4cwyllys				vinfo->crl_info.ignore_crl_date = 0;
17999ebb4cwyllys			}
18099ebb4cwyllys			xmlFree(c);
18199ebb4cwyllys
18299ebb4cwyllys			policy->revocation |= KMF_REVOCATION_METHOD_CRL;
18399ebb4cwyllys		}
18499ebb4cwyllys
18599ebb4cwyllys		n = n->next;
18699ebb4cwyllys	}
18799ebb4cwyllys}
18899ebb4cwyllys
18999ebb4cwyllyschar *
19030a5e8fwyllyskmf_ku_to_string(uint32_t bitfield)
19199ebb4cwyllys{
19299ebb4cwyllys	if (bitfield & KMF_digitalSignature)
19399ebb4cwyllys		return ("digitalSignature");
19499ebb4cwyllys
19599ebb4cwyllys	if (bitfield & KMF_nonRepudiation)
19699ebb4cwyllys		return ("nonRepudiation");
19799ebb4cwyllys
19899ebb4cwyllys	if (bitfield & KMF_keyEncipherment)
19999ebb4cwyllys		return ("keyEncipherment");
20099ebb4cwyllys
20199ebb4cwyllys	if (bitfield & KMF_dataEncipherment)
20299ebb4cwyllys		return ("dataEncipherment");
20399ebb4cwyllys
20499ebb4cwyllys	if (bitfield & KMF_keyAgreement)
20599ebb4cwyllys		return ("keyAgreement");
20699ebb4cwyllys
20799ebb4cwyllys	if (bitfield & KMF_keyCertSign)
20899ebb4cwyllys		return ("keyCertSign");
20999ebb4cwyllys
21099ebb4cwyllys	if (bitfield & KMF_cRLSign)
21199ebb4cwyllys		return ("cRLSign");
21299ebb4cwyllys
21399ebb4cwyllys	if (bitfield & KMF_encipherOnly)
21499ebb4cwyllys		return ("encipherOnly");
21599ebb4cwyllys
21699ebb4cwyllys	if (bitfield & KMF_decipherOnly)
21799ebb4cwyllys		return ("decipherOnly");
21899ebb4cwyllys
21999ebb4cwyllys	return (NULL);
22099ebb4cwyllys}
22199ebb4cwyllys
22230a5e8fwyllysuint32_t
22330a5e8fwyllyskmf_string_to_ku(char *kustring)
22499ebb4cwyllys{
22599ebb4cwyllys	if (kustring == NULL || !strlen(kustring))
22699ebb4cwyllys		return (0);
22799ebb4cwyllys	if (strcasecmp(kustring, "digitalSignature") == 0)
22899ebb4cwyllys		return (KMF_digitalSignature);
22999ebb4cwyllys	if (strcasecmp(kustring, "nonRepudiation") == 0)
23099ebb4cwyllys		return (KMF_nonRepudiation);
23199ebb4cwyllys	if (strcasecmp(kustring, "keyEncipherment") == 0)
23299ebb4cwyllys		return (KMF_keyEncipherment);
23399ebb4cwyllys	if (strcasecmp(kustring, "dataEncipherment") == 0)
23499ebb4cwyllys		return (KMF_dataEncipherment);
23599ebb4cwyllys	if (strcasecmp(kustring, "keyAgreement") == 0)
23699ebb4cwyllys		return (KMF_keyAgreement);
23799ebb4cwyllys	if (strcasecmp(kustring, "keyCertSign") == 0)
23899ebb4cwyllys		return (KMF_keyCertSign);
23999ebb4cwyllys	if (strcasecmp(kustring, "cRLSign") == 0)
24099ebb4cwyllys		return (KMF_cRLSign);
24199ebb4cwyllys	if (strcasecmp(kustring, "encipherOnly") == 0)
24299ebb4cwyllys		return (KMF_encipherOnly);
24399ebb4cwyllys	if (strcasecmp(kustring, "decipherOnly") == 0)
24499ebb4cwyllys		return (KMF_decipherOnly);
24599ebb4cwyllys
24699ebb4cwyllys	return (0);
24799ebb4cwyllys}
24899ebb4cwyllys
24999ebb4cwyllysstatic void
25099ebb4cwyllysparseKeyUsageSet(xmlNodePtr node, uint32_t *kubits)
25199ebb4cwyllys{
25299ebb4cwyllys	xmlNodePtr n;
25399ebb4cwyllys	char *c;
25499ebb4cwyllys
25599ebb4cwyllys	n = node->children;
25699ebb4cwyllys	while (n != NULL) {
25799ebb4cwyllys		if (!xmlStrcmp((const xmlChar *)n->name,
25830a5e8fwyllys		    (const xmlChar *)KMF_KEY_USAGE_ELEMENT)) {
25999ebb4cwyllys			c = (char *)xmlGetProp(n,
26030a5e8fwyllys			    (const xmlChar *)KMF_KEY_USAGE_USE_ATTR);
26199ebb4cwyllys			if (c) {
26230a5e8fwyllys				*kubits |= kmf_string_to_ku(c);
26399ebb4cwyllys				xmlFree(c);
26499ebb4cwyllys			}
26599ebb4cwyllys		}
26699ebb4cwyllys
26799ebb4cwyllys		n = n->next;
26899ebb4cwyllys	}
26999ebb4cwyllys}
27099ebb4cwyllys
27199ebb4cwyllysstatic KMF_OID *
27299ebb4cwyllysdup_oid(KMF_OID *oldoid)
27399ebb4cwyllys{
27499ebb4cwyllys	KMF_OID *oid;
27599ebb4cwyllys
27699ebb4cwyllys	oid = malloc(sizeof (KMF_OID));
27799ebb4cwyllys	if (oid == NULL)
27899ebb4cwyllys		return (NULL);
27999ebb4cwyllys
28099ebb4cwyllys	oid->Length = oldoid->Length;
28199ebb4cwyllys	oid->Data = malloc(oid->Length);
28299ebb4cwyllys	if (oid->Data == NULL) {
28399ebb4cwyllys		free(oid);
28499ebb4cwyllys		return (NULL);
28599ebb4cwyllys	}
28699ebb4cwyllys	(void) memcpy(oid->Data, oldoid->Data, oid->Length);
28799ebb4cwyllys
28899ebb4cwyllys	return (oid);
28999ebb4cwyllys}
29099ebb4cwyllys
29199ebb4cwyllysKMF_OID *
29230a5e8fwyllyskmf_ekuname_to_oid(char *ekuname)
29399ebb4cwyllys{
29499ebb4cwyllys	KMF_OID *oid;
29599ebb4cwyllys	int i;
29699ebb4cwyllys
29799ebb4cwyllys	if (ekuname == NULL)
29899ebb4cwyllys		return (NULL);
29999ebb4cwyllys
30099ebb4cwyllys	for (i = 0; i < num_ekus; i++) {
30199ebb4cwyllys		if (strcasecmp(EKUList[i].ekuname, ekuname) == 0) {
30299ebb4cwyllys			oid = dup_oid(EKUList[i].oid);
30399ebb4cwyllys			return (oid);
30499ebb4cwyllys		}
30599ebb4cwyllys	}
30699ebb4cwyllys
30799ebb4cwyllys	return (NULL);
30899ebb4cwyllys}
30999ebb4cwyllys
31099ebb4cwyllyschar *
311d00756cwyllyskmf_oid_to_ekuname(KMF_OID *oid)
31299ebb4cwyllys{
31399ebb4cwyllys	int i;
31499ebb4cwyllys	for (i = 0; i < num_ekus; i++) {
31599ebb4cwyllys		if (oid->Length == EKUList[i].oid->Length &&
31630a5e8fwyllys		    !memcmp(oid->Data, EKUList[i].oid->Data, oid->Length)) {
31799ebb4cwyllys			return (EKUList[i].ekuname);
31899ebb4cwyllys		}
31999ebb4cwyllys	}
32099ebb4cwyllys	return (NULL);
32199ebb4cwyllys}
32299ebb4cwyllys
32399ebb4cwyllysstatic KMF_RETURN
32499ebb4cwyllysparseExtKeyUsage(xmlNodePtr node, KMF_EKU_POLICY *ekus)
32599ebb4cwyllys{
32699ebb4cwyllys	xmlNodePtr n;
32799ebb4cwyllys	char *c;
32899ebb4cwyllys	KMF_RETURN ret = KMF_OK;
32999ebb4cwyllys	boolean_t found = FALSE;
33099ebb4cwyllys
33199ebb4cwyllys	n = node->children;
33299ebb4cwyllys	while (n != NULL && ret == KMF_OK) {
33330a5e8fwyllys		KMF_OID newoid, *oidptr;
33430a5e8fwyllys
33530a5e8fwyllys		oidptr = NULL;
33630a5e8fwyllys		newoid.Data = NULL;
33730a5e8fwyllys		newoid.Length = 0;
33899ebb4cwyllys
33999ebb4cwyllys		if (!xmlStrcmp((const xmlChar *)n->name,
34030a5e8fwyllys		    (const xmlChar *)KMF_EKU_NAME_ELEMENT)) {
34199ebb4cwyllys			c = (char *)xmlGetProp(n,
34230a5e8fwyllys			    (const xmlChar *)KMF_EKU_NAME_ATTR);
34399ebb4cwyllys			if (c != NULL) {
34430a5e8fwyllys				oidptr = kmf_ekuname_to_oid(c);
34599ebb4cwyllys				xmlFree(c);
34699ebb4cwyllys				found = TRUE;
34730a5e8fwyllys				if (oidptr != NULL)
34830a5e8fwyllys					newoid = *oidptr;
34999ebb4cwyllys			}
35099ebb4cwyllys		} else if (!xmlStrcmp((const xmlChar *)n->name,
35130a5e8fwyllys		    (const xmlChar *)KMF_EKU_OID_ELEMENT)) {
35299ebb4cwyllys			c = (char *)xmlGetProp(n,
35330a5e8fwyllys			    (const xmlChar *)KMF_EKU_OID_ATTR);
35499ebb4cwyllys			if (c != NULL) {
35530a5e8fwyllys				(void) kmf_string_to_oid(c, &newoid);
35699ebb4cwyllys				xmlFree(c);
35799ebb4cwyllys				found = TRUE;
35899ebb4cwyllys			}
35999ebb4cwyllys		} else {
36099ebb4cwyllys			n = n->next;
36199ebb4cwyllys			if ((n == NULL) && (!found))
36299ebb4cwyllys				ret = KMF_ERR_POLICY_DB_FORMAT;
36399ebb4cwyllys			continue;
36499ebb4cwyllys		}
36599ebb4cwyllys
36630a5e8fwyllys		if (newoid.Data != NULL) {
36799ebb4cwyllys			ekus->eku_count++;
36899ebb4cwyllys			ekus->ekulist = realloc(ekus->ekulist,
36930a5e8fwyllys			    ekus->eku_count * sizeof (KMF_OID));
37099ebb4cwyllys			if (ekus->ekulist != NULL) {
37199ebb4cwyllys				ekus->ekulist[ekus->eku_count-1].Length =
37230a5e8fwyllys				    newoid.Length;
37399ebb4cwyllys				ekus->ekulist[ekus->eku_count-1].Data =
37430a5e8fwyllys				    newoid.Data;
37599ebb4cwyllys			} else {
37699ebb4cwyllys				ret = KMF_ERR_MEMORY;
37799ebb4cwyllys			}
37899ebb4cwyllys		} else {
37999ebb4cwyllys			ret = KMF_ERR_POLICY_DB_FORMAT;
38099ebb4cwyllys		}
38199ebb4cwyllys
38299ebb4cwyllys		n = n->next;
38399ebb4cwyllys	}
38499ebb4cwyllys
38599ebb4cwyllys	return (ret);
38699ebb4cwyllys}
38799ebb4cwyllys
388269e59fJan Pechanecstatic KMF_RETURN
389269e59fJan PechanecparseMapper(xmlNodePtr node, KMF_MAPPER_RECORD *mapper)
390269e59fJan Pechanec{
391269e59fJan Pechanec	xmlNodePtr n;
392269e59fJan Pechanec
393269e59fJan Pechanec	n = node;
394269e59fJan Pechanec	mapper->mapname = (char *)xmlGetProp(n,
395269e59fJan Pechanec	    (const xmlChar *)KMF_CERT_MAPPER_NAME_ATTR);
396269e59fJan Pechanec	mapper->dir = (char *)xmlGetProp(n,
397269e59fJan Pechanec	    (const xmlChar *)KMF_CERT_MAPPER_DIR_ATTR);
398269e59fJan Pechanec	mapper->pathname = (char *)xmlGetProp(n,
399269e59fJan Pechanec	    (const xmlChar *)KMF_CERT_MAPPER_PATH_ATTR);
400269e59fJan Pechanec	mapper->options = (char *)xmlGetProp(n,
401269e59fJan Pechanec	    (const xmlChar *)KMF_CERT_MAPPER_OPTIONS_ATTR);
402269e59fJan Pechanec
403269e59fJan Pechanec	/*
404269e59fJan Pechanec	 * These are set according to whether mapper setting is taken from the
405269e59fJan Pechanec	 * database or init function attributes.
406269e59fJan Pechanec	 */
407269e59fJan Pechanec	mapper->curpathname = NULL;
408269e59fJan Pechanec	mapper->curoptions = NULL;
409269e59fJan Pechanec
410269e59fJan Pechanec	return (KMF_OK);
411269e59fJan Pechanec}
412269e59fJan Pechanec
41399ebb4cwyllysint
41499ebb4cwyllysparsePolicyElement(xmlNodePtr node, KMF_POLICY_RECORD *policy)
41599ebb4cwyllys{
41699ebb4cwyllys	int ret = 0;
41799ebb4cwyllys	xmlNodePtr n = node->xmlChildrenNode;
41899ebb4cwyllys	char *c;
41999ebb4cwyllys
42099ebb4cwyllys	if (node->type == XML_ELEMENT_NODE) {
42199ebb4cwyllys		if (node->properties != NULL) {
42299ebb4cwyllys			policy->name = (char *)xmlGetProp(node,
42330a5e8fwyllys			    (const xmlChar *)KMF_POLICY_NAME_ATTR);
42499ebb4cwyllys
42599ebb4cwyllys			c = (char *)xmlGetProp(node,
42630a5e8fwyllys			    (const xmlChar *)KMF_OPTIONS_IGNORE_DATE_ATTR);
42799ebb4cwyllys			if (c && !strcasecmp(c, "true")) {
42899ebb4cwyllys				policy->ignore_date = 1;
42999ebb4cwyllys				xmlFree((xmlChar *)c);
43099ebb4cwyllys			}
43199ebb4cwyllys
43299ebb4cwyllys			c = (char *)xmlGetProp(node,
43399ebb4cwyllys			    (const xmlChar *)KMF_OPTIONS_IGNORE_UNKNOWN_EKUS);
43499ebb4cwyllys			if (c && !strcasecmp(c, "true")) {
43599ebb4cwyllys				policy->ignore_unknown_ekus = 1;
43699ebb4cwyllys				xmlFree(c);
43799ebb4cwyllys			}
43899ebb4cwyllys
43999ebb4cwyllys			c = (char *)xmlGetProp(node,
44099ebb4cwyllys			    (const xmlChar *)KMF_OPTIONS_IGNORE_TRUST_ANCHOR);
44199ebb4cwyllys			if (c && !strcasecmp(c, "true")) {
44299ebb4cwyllys				policy->ignore_trust_anchor = 1;
44399ebb4cwyllys				xmlFree(c);
44499ebb4cwyllys			}
44599ebb4cwyllys
44699ebb4cwyllys			c = (char *)xmlGetProp(node,
44799ebb4cwyllys			    (const xmlChar *)KMF_OPTIONS_VALIDITY_ADJUSTTIME);
44899ebb4cwyllys			if (c) {
44999ebb4cwyllys				policy->validity_adjusttime = c;
45099ebb4cwyllys			} else {
45199ebb4cwyllys				policy->validity_adjusttime = NULL;
45299ebb4cwyllys			}
45399ebb4cwyllys
45499ebb4cwyllys			policy->ta_name = (char *)xmlGetProp(node,
45530a5e8fwyllys			    (const xmlChar *)KMF_POLICY_TA_NAME_ATTR);
45699ebb4cwyllys
45799ebb4cwyllys			policy->ta_serial = (char *)xmlGetProp(node,
45830a5e8fwyllys			    (const xmlChar *)KMF_POLICY_TA_SERIAL_ATTR);
45999ebb4cwyllys		}
46099ebb4cwyllys
46199ebb4cwyllys		n = node->children;
46299ebb4cwyllys		while (n != NULL) {
46399ebb4cwyllys			if (!xmlStrcmp((const xmlChar *)n->name,
46430a5e8fwyllys			    (const xmlChar *)KMF_VALIDATION_METHODS_ELEMENT))
46599ebb4cwyllys				parseValidation(n, &policy->validation_info,
46699ebb4cwyllys				    policy);
46799ebb4cwyllys			else if (!xmlStrcmp((const xmlChar *)n->name,
46830a5e8fwyllys			    (const xmlChar *)KMF_KEY_USAGE_SET_ELEMENT))
46999ebb4cwyllys				parseKeyUsageSet(n, &policy->ku_bits);
47099ebb4cwyllys			else if (!xmlStrcmp((const xmlChar *)n->name,
47199ebb4cwyllys			    (const xmlChar *)KMF_EKU_ELEMENT)) {
47299ebb4cwyllys				ret = parseExtKeyUsage(n, &policy->eku_set);
47399ebb4cwyllys				if (ret != KMF_OK)
47499ebb4cwyllys					return (ret);
475269e59fJan Pechanec			} else if (!xmlStrcmp((const xmlChar *)n->name,
476269e59fJan Pechanec			    (const xmlChar *)KMF_CERT_MAPPER_ELEMENT)) {
477269e59fJan Pechanec				ret = parseMapper(n, &policy->mapper);
478269e59fJan Pechanec				if (ret != KMF_OK)
479269e59fJan Pechanec					return (ret);
48099ebb4cwyllys			}
48199ebb4cwyllys
48299ebb4cwyllys			n = n->next;
48399ebb4cwyllys		}
48499ebb4cwyllys	}
48599ebb4cwyllys
48699ebb4cwyllys	return (ret);
48799ebb4cwyllys}
48899ebb4cwyllys
48999ebb4cwyllysstatic int
49099ebb4cwyllysnewprop(xmlNodePtr node, char *attrname, char *src)
49199ebb4cwyllys{
49299ebb4cwyllys	xmlAttrPtr newattr;
49399ebb4cwyllys
49499ebb4cwyllys	if (src != NULL && strlen(src)) {
49599ebb4cwyllys		newattr = xmlNewProp(node, (const xmlChar *)attrname,
49630a5e8fwyllys		    (xmlChar *)src);
49799ebb4cwyllys		if (newattr == NULL) {
49899ebb4cwyllys			xmlUnlinkNode(node);
49999ebb4cwyllys			xmlFreeNode(node);
50099ebb4cwyllys			return (-1);
50199ebb4cwyllys		}
50299ebb4cwyllys	}
50399ebb4cwyllys	return (0);
50499ebb4cwyllys}
50599ebb4cwyllys
50699ebb4cwyllys/*
50799ebb4cwyllys * Add CRL policy information to the XML tree.
50899ebb4cwyllys * Return non-zero on any failure, else 0 for success.
50999ebb4cwyllys *
51099ebb4cwyllys * This function is called only when the KMF_REVOCATION_METHOD_CRL flag is on.
51199ebb4cwyllys */
51299ebb4cwyllysstatic int
51399ebb4cwyllysAddCRLNodes(xmlNodePtr node, KMF_CRL_POLICY *crlinfo)
51499ebb4cwyllys{
51599ebb4cwyllys	xmlNodePtr n;
51699ebb4cwyllys
51799ebb4cwyllys	addFormatting(node, "\t\t");
51899ebb4cwyllys	n = xmlNewChild(node, NULL, (const xmlChar *)"crl", NULL);
51999ebb4cwyllys	if (n == NULL)
52099ebb4cwyllys		return (-1);
52199ebb4cwyllys
52299ebb4cwyllys	if (crlinfo->basefilename &&
52399ebb4cwyllys	    newprop(n, KMF_CRL_BASENAME_ATTR, crlinfo->basefilename))
52499ebb4cwyllys		return (-1);
52599ebb4cwyllys
52699ebb4cwyllys	if (crlinfo->directory &&
52799ebb4cwyllys	    newprop(n, KMF_CRL_DIRECTORY_ATTR, crlinfo->directory))
52899ebb4cwyllys		return (-1);
52999ebb4cwyllys
53099ebb4cwyllys	if (crlinfo->get_crl_uri &&
53199ebb4cwyllys	    newprop(n, KMF_CRL_GET_URI_ATTR, "TRUE")) {
53299ebb4cwyllys		return (-1);
53399ebb4cwyllys	}
53499ebb4cwyllys
53599ebb4cwyllys	if (crlinfo->proxy &&
53699ebb4cwyllys	    newprop(n, KMF_CRL_PROXY_ATTR, crlinfo->proxy))
53799ebb4cwyllys		return (-1);
53899ebb4cwyllys
53999ebb4cwyllys	if (crlinfo->ignore_crl_sign &&
54099ebb4cwyllys	    newprop(n, KMF_CRL_IGNORE_SIGN_ATTR, "TRUE")) {
54199ebb4cwyllys		return (-1);
54299ebb4cwyllys	}
54399ebb4cwyllys
54499ebb4cwyllys	if (crlinfo->ignore_crl_date &&
54599ebb4cwyllys	    newprop(n, KMF_CRL_IGNORE_DATE_ATTR, "TRUE")) {
54699ebb4cwyllys		return (-1);
54799ebb4cwyllys	}
54899ebb4cwyllys
54999ebb4cwyllys	addFormatting(node, "\n");
55099ebb4cwyllys	return (0);
55199ebb4cwyllys}
55299ebb4cwyllys
55399ebb4cwyllys/*
554