1/*	$NetBSD: dnssec.c,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
2
3/*	$KAME: dnssec.c,v 1.2 2001/08/05 18:46:07 itojun Exp $	*/
4
5/*
6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 *    may be used to endorse or promote products derived from this software
19 *    without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#include "config.h"
35
36#include <sys/types.h>
37#include <sys/param.h>
38#include <stdlib.h>
39#include <string.h>
40
41#include "var.h"
42#include "vmbuf.h"
43#include "misc.h"
44#include "plog.h"
45#include "debug.h"
46
47#include "isakmp_var.h"
48#include "isakmp.h"
49#include "ipsec_doi.h"
50#include "oakley.h"
51#include "netdb_dnssec.h"
52#include "strnames.h"
53#include "dnssec.h"
54#include "gcmalloc.h"
55
56extern int h_errno;
57
58cert_t *
59dnssec_getcert(id)
60	vchar_t *id;
61{
62	cert_t *cert = NULL;
63	struct certinfo *res = NULL;
64	struct ipsecdoi_id_b *id_b;
65	int type;
66	char *name = NULL;
67	int namelen;
68	int error;
69
70	id_b = ALIGNED_CAST(struct ipsecdoi_id_b *)id->v;
71
72	namelen = id->l - sizeof(*id_b);
73	name = racoon_malloc(namelen + 1);
74	if (!name) {
75		plog(ASL_LEVEL_ERR,
76			"failed to get buffer.\n");
77		return NULL;
78	}
79	memcpy(name, id_b + 1, namelen);
80	name[namelen] = '\0';
81
82	switch (id_b->type) {
83	case IPSECDOI_ID_FQDN:
84		error = getcertsbyname(name, &res);
85		if (error != 0) {
86			plog(ASL_LEVEL_ERR,
87				"getcertsbyname(\"%s\") failed.\n", name);
88			goto err;
89		}
90		break;
91	case IPSECDOI_ID_IPV4_ADDR:
92	case IPSECDOI_ID_IPV6_ADDR:
93		/* XXX should be processed to query PTR ? */
94	default:
95		plog(ASL_LEVEL_ERR,
96			"impropper ID type passed %s "
97			"though getcert method is dnssec.\n",
98			s_ipsecdoi_ident(id_b->type));
99		goto err;
100	}
101
102	/* check response */
103	if (res->ci_next != NULL) {
104		plog(ASL_LEVEL_WARNING,
105			"not supported multiple CERT RR.\n");
106	}
107	switch (res->ci_type) {
108	case DNSSEC_TYPE_PKIX:
109		/* XXX is it enough condition to set this type ? */
110		type = ISAKMP_CERT_X509SIGN;
111		break;
112	default:
113		plog(ASL_LEVEL_ERR,
114			"not supported CERT RR type %d.\n", res->ci_type);
115		goto err;
116	}
117
118	/* create cert holder */
119	cert = oakley_newcert();
120	if (cert == NULL) {
121		plog(ASL_LEVEL_ERR,
122			"failed to get cert buffer.\n");
123		goto err;
124	}
125	cert->pl = vmalloc(res->ci_certlen + 1);
126	if (cert->pl == NULL) {
127		plog(ASL_LEVEL_ERR,
128			"failed to get cert buffer.\n");
129		goto err;
130	}
131	memcpy(cert->pl->v + 1, res->ci_cert, res->ci_certlen);
132	cert->pl->v[0] = type;
133	cert->cert.v = cert->pl->v + 1;
134	cert->cert.l = cert->pl->l - 1;
135
136	plog(ASL_LEVEL_DEBUG, "created CERT payload:\n");
137
138end:
139	if (res)
140		freecertinfo(res);
141
142	return cert;
143
144err:
145	if (name)
146		racoon_free(name);
147	if (cert) {
148		oakley_delcert(cert);
149		cert = NULL;
150	}
151
152	goto end;
153}
154