xref: /netbsd-src/crypto/dist/ipsec-tools/src/racoon/isakmp_quick.c (revision ce666bb8ce77792a3948ca697c2fdad578a542a7)
1 /*	$NetBSD: isakmp_quick.c,v 1.8 2005/11/21 14:20:29 manu Exp $	*/
2 
3 /* Id: isakmp_quick.c,v 1.13.2.7 2005/07/20 08:02:05 vanhu 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 <sys/socket.h>
39 
40 #include <netinet/in.h>
41 
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
45 #include <errno.h>
46 #if TIME_WITH_SYS_TIME
47 # include <sys/time.h>
48 # include <time.h>
49 #else
50 # if HAVE_SYS_TIME_H
51 #  include <sys/time.h>
52 # else
53 #  include <time.h>
54 # endif
55 #endif
56 
57 #ifndef HAVE_NETINET6_IPSEC
58 #include <netinet/ipsec.h>
59 #else
60 #include <netinet6/ipsec.h>
61 #endif
62 
63 #include "var.h"
64 #include "vmbuf.h"
65 #include "schedule.h"
66 #include "misc.h"
67 #include "plog.h"
68 #include "debug.h"
69 
70 #include "localconf.h"
71 #include "remoteconf.h"
72 #include "isakmp_var.h"
73 #include "isakmp.h"
74 #include "isakmp_inf.h"
75 #include "isakmp_quick.h"
76 #include "oakley.h"
77 #include "handler.h"
78 #include "ipsec_doi.h"
79 #include "crypto_openssl.h"
80 #include "pfkey.h"
81 #include "policy.h"
82 #include "algorithm.h"
83 #include "sockmisc.h"
84 #include "proposal.h"
85 #include "sainfo.h"
86 #include "admin.h"
87 #include "strnames.h"
88 
89 /* quick mode */
90 static vchar_t *quick_ir1mx __P((struct ph2handle *, vchar_t *, vchar_t *));
91 static int get_sainfo_r __P((struct ph2handle *));
92 static int get_proposal_r __P((struct ph2handle *));
93 
94 /* %%%
95  * Quick Mode
96  */
97 /*
98  * begin Quick Mode as initiator.  send pfkey getspi message to kernel.
99  */
100 int
101 quick_i1prep(iph2, msg)
102 	struct ph2handle *iph2;
103 	vchar_t *msg; /* must be null pointer */
104 {
105 	int error = ISAKMP_INTERNAL_ERROR;
106 
107 	/* validity check */
108 	if (iph2->status != PHASE2ST_STATUS2) {
109 		plog(LLV_ERROR, LOCATION, NULL,
110 			"status mismatched %d.\n", iph2->status);
111 		goto end;
112 	}
113 
114 	iph2->msgid = isakmp_newmsgid2(iph2->ph1);
115 	iph2->ivm = oakley_newiv2(iph2->ph1, iph2->msgid);
116 	if (iph2->ivm == NULL)
117 		return 0;
118 
119 	iph2->status = PHASE2ST_GETSPISENT;
120 
121 	/* don't anything if local test mode. */
122 	if (f_local) {
123 		error = 0;
124 		goto end;
125 	}
126 
127 	/* send getspi message */
128 	if (pk_sendgetspi(iph2) < 0)
129 		goto end;
130 
131 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
132 
133 	iph2->sce = sched_new(lcconf->wait_ph2complete,
134 		pfkey_timeover_stub, iph2);
135 
136 	error = 0;
137 
138 end:
139 	return error;
140 }
141 
142 /*
143  * send to responder
144  * 	HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
145  */
146 int
147 quick_i1send(iph2, msg)
148 	struct ph2handle *iph2;
149 	vchar_t *msg; /* must be null pointer */
150 {
151 	vchar_t *body = NULL;
152 	vchar_t *hash = NULL;
153 	struct isakmp_gen *gen;
154 	char *p;
155 	int tlen;
156 	int error = ISAKMP_INTERNAL_ERROR;
157 	int pfsgroup, idci, idcr;
158 	int np;
159 	struct ipsecdoi_id_b *id, *id_p;
160 
161 	/* validity check */
162 	if (msg != NULL) {
163 		plog(LLV_ERROR, LOCATION, NULL,
164 			"msg has to be NULL in this function.\n");
165 		goto end;
166 	}
167 	if (iph2->status != PHASE2ST_GETSPIDONE) {
168 		plog(LLV_ERROR, LOCATION, NULL,
169 			"status mismatched %d.\n", iph2->status);
170 		goto end;
171 	}
172 
173 	/* create SA payload for my proposal */
174 	if (ipsecdoi_setph2proposal(iph2) < 0)
175 		goto end;
176 
177 	/* generate NONCE value */
178 	iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
179 	if (iph2->nonce == NULL)
180 		goto end;
181 
182 	/*
183 	 * DH value calculation is kicked out into cfparse.y.
184 	 * because pfs group can not be negotiated, it's only to be checked
185 	 * acceptable.
186 	 */
187 	/* generate KE value if need */
188 	pfsgroup = iph2->proposal->pfs_group;
189 	if (pfsgroup) {
190 		/* DH group settting if PFS is required. */
191 		if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
192 			plog(LLV_ERROR, LOCATION, NULL,
193 				"failed to set DH value.\n");
194 			goto end;
195 		}
196 		if (oakley_dh_generate(iph2->pfsgrp,
197 				&iph2->dhpub, &iph2->dhpriv) < 0) {
198 			goto end;
199 		}
200 	}
201 
202 	/* generate ID value */
203 	if (ipsecdoi_setid2(iph2) < 0) {
204 		plog(LLV_ERROR, LOCATION, NULL,
205 			"failed to get ID.\n");
206 		goto end;
207 	}
208 	plog(LLV_DEBUG, LOCATION, NULL, "IDci:");
209 	plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l);
210 	plog(LLV_DEBUG, LOCATION, NULL, "IDcr:");
211 	plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l);
212 
213 	/*
214 	 * we do not attach IDci nor IDcr, under the following condition:
215 	 * - all proposals are transport mode
216 	 * - no MIP6 or proxy
217 	 * - id payload suggests to encrypt all the traffic (no specific
218 	 *   protocol type)
219 	 */
220 	id = (struct ipsecdoi_id_b *)iph2->id->v;
221 	id_p = (struct ipsecdoi_id_b *)iph2->id_p->v;
222 	if (id->proto_id == 0
223 	 && id_p->proto_id == 0
224 	 && iph2->ph1->rmconf->support_proxy == 0
225 	 && ipsecdoi_transportmode(iph2->proposal)) {
226 		idci = idcr = 0;
227 	} else
228 		idci = idcr = 1;
229 
230 	/* create SA;NONCE payload, and KE if need, and IDii, IDir. */
231 	tlen = + sizeof(*gen) + iph2->sa->l
232 		+ sizeof(*gen) + iph2->nonce->l;
233 	if (pfsgroup)
234 		tlen += (sizeof(*gen) + iph2->dhpub->l);
235 	if (idci)
236 		tlen += sizeof(*gen) + iph2->id->l;
237 	if (idcr)
238 		tlen += sizeof(*gen) + iph2->id_p->l;
239 
240 	body = vmalloc(tlen);
241 	if (body == NULL) {
242 		plog(LLV_ERROR, LOCATION, NULL,
243 			"failed to get buffer to send.\n");
244 		goto end;
245 	}
246 
247 	p = body->v;
248 
249 	/* add SA payload */
250 	p = set_isakmp_payload(p, iph2->sa, ISAKMP_NPTYPE_NONCE);
251 
252 	/* add NONCE payload */
253 	if (pfsgroup)
254 		np = ISAKMP_NPTYPE_KE;
255 	else if (idci || idcr)
256 		np = ISAKMP_NPTYPE_ID;
257 	else
258 		np = ISAKMP_NPTYPE_NONE;
259 	p = set_isakmp_payload(p, iph2->nonce, np);
260 
261 	/* add KE payload if need. */
262 	np = (idci || idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
263 	if (pfsgroup)
264 		p = set_isakmp_payload(p, iph2->dhpub, np);
265 
266 	/* IDci */
267 	np = (idcr) ? ISAKMP_NPTYPE_ID : ISAKMP_NPTYPE_NONE;
268 	if (idci)
269 		p = set_isakmp_payload(p, iph2->id, np);
270 
271 	/* IDcr */
272 	if (idcr)
273 		p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_NONE);
274 
275 	/* generate HASH(1) */
276 	hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, body);
277 	if (hash == NULL)
278 		goto end;
279 
280 	/* send isakmp payload */
281 	iph2->sendbuf = quick_ir1mx(iph2, body, hash);
282 	if (iph2->sendbuf == NULL)
283 		goto end;
284 
285 	/* send the packet, add to the schedule to resend */
286 	iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
287 	if (isakmp_ph2resend(iph2) == -1)
288 		goto end;
289 
290 	/* change status of isakmp status entry */
291 	iph2->status = PHASE2ST_MSG1SENT;
292 
293 	error = 0;
294 
295 end:
296 	if (body != NULL)
297 		vfree(body);
298 	if (hash != NULL)
299 		vfree(hash);
300 
301 	return error;
302 }
303 
304 /*
305  * receive from responder
306  * 	HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
307  */
308 int
309 quick_i2recv(iph2, msg0)
310 	struct ph2handle *iph2;
311 	vchar_t *msg0;
312 {
313 	vchar_t *msg = NULL;
314 	vchar_t *hbuf = NULL;	/* for hash computing. */
315 	vchar_t *pbuf = NULL;	/* for payload parsing */
316 	struct isakmp_parse_t *pa;
317 	struct isakmp *isakmp = (struct isakmp *)msg0->v;
318 	struct isakmp_pl_hash *hash = NULL;
319 	int f_id;
320 	char *p;
321 	int tlen;
322 	int error = ISAKMP_INTERNAL_ERROR;
323 
324 	/* validity check */
325 	if (iph2->status != PHASE2ST_MSG1SENT) {
326 		plog(LLV_ERROR, LOCATION, NULL,
327 			"status mismatched %d.\n", iph2->status);
328 		goto end;
329 	}
330 
331 	/* decrypt packet */
332 	if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
333 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
334 			"Packet wasn't encrypted.\n");
335 		goto end;
336 	}
337 	msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
338 	if (msg == NULL)
339 		goto end;
340 
341 	/* create buffer for validating HASH(2) */
342 	/*
343 	 * ordering rule:
344 	 *	1. the first one must be HASH
345 	 *	2. the second one must be SA (added in isakmp-oakley-05!)
346 	 *	3. two IDs must be considered as IDci, then IDcr
347 	 */
348 	pbuf = isakmp_parse(msg);
349 	if (pbuf == NULL)
350 		goto end;
351 	pa = (struct isakmp_parse_t *)pbuf->v;
352 
353 	/* HASH payload is fixed postion */
354 	if (pa->type != ISAKMP_NPTYPE_HASH) {
355 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
356 			"received invalid next payload type %d, "
357 			"expecting %d.\n",
358 			pa->type, ISAKMP_NPTYPE_HASH);
359 		goto end;
360 	}
361 	hash = (struct isakmp_pl_hash *)pa->ptr;
362 	pa++;
363 
364 	/*
365 	 * this restriction was introduced in isakmp-oakley-05.
366 	 * we do not check this for backward compatibility.
367 	 * TODO: command line/config file option to enable/disable this code
368 	 */
369 	/* HASH payload is fixed postion */
370 	if (pa->type != ISAKMP_NPTYPE_SA) {
371 		plog(LLV_WARNING, LOCATION, iph2->ph1->remote,
372 			"received invalid next payload type %d, "
373 			"expecting %d.\n",
374 			pa->type, ISAKMP_NPTYPE_HASH);
375 	}
376 
377 	/* allocate buffer for computing HASH(2) */
378 	tlen = iph2->nonce->l
379 		+ ntohl(isakmp->len) - sizeof(*isakmp);
380 	hbuf = vmalloc(tlen);
381 	if (hbuf == NULL) {
382 		plog(LLV_ERROR, LOCATION, NULL,
383 			"failed to get hash buffer.\n");
384 		goto end;
385 	}
386 	p = hbuf->v + iph2->nonce->l;	/* retain the space for Ni_b */
387 
388 	/*
389 	 * parse the payloads.
390 	 * copy non-HASH payloads into hbuf, so that we can validate HASH.
391 	 */
392 	iph2->sa_ret = NULL;
393 	f_id = 0;	/* flag to use checking ID */
394 	tlen = 0;	/* count payload length except of HASH payload. */
395 	for (; pa->type; pa++) {
396 
397 		/* copy to buffer for HASH */
398 		/* Don't modify the payload */
399 		memcpy(p, pa->ptr, pa->len);
400 
401 		switch (pa->type) {
402 		case ISAKMP_NPTYPE_SA:
403 			if (iph2->sa_ret != NULL) {
404 				plog(LLV_ERROR, LOCATION, NULL,
405 					"Ignored, multiple SA "
406 					"isn't supported.\n");
407 				break;
408 			}
409 			if (isakmp_p2ph(&iph2->sa_ret, pa->ptr) < 0)
410 				goto end;
411 			break;
412 
413 		case ISAKMP_NPTYPE_NONCE:
414 			if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
415 				goto end;
416 			break;
417 
418 		case ISAKMP_NPTYPE_KE:
419 			if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
420 				goto end;
421 			break;
422 
423 		case ISAKMP_NPTYPE_ID:
424 		    {
425 			vchar_t *vp;
426 
427 			/* check ID value */
428 			if (f_id == 0) {
429 				/* for IDci */
430 				f_id = 1;
431 				vp = iph2->id;
432 			} else {
433 				/* for IDcr */
434 				vp = iph2->id_p;
435 			}
436 
437 			if (memcmp(vp->v, (caddr_t)pa->ptr + sizeof(struct isakmp_gen), vp->l)) {
438 
439 				plog(LLV_ERROR, LOCATION, NULL,
440 					"mismatched ID was returned.\n");
441 				error = ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED;
442 				goto end;
443 			}
444 		    }
445 			break;
446 
447 		case ISAKMP_NPTYPE_N:
448 			isakmp_check_notify(pa->ptr, iph2->ph1);
449 			break;
450 
451 #ifdef ENABLE_NATT
452 		case ISAKMP_NPTYPE_NATOA_DRAFT:
453 		case ISAKMP_NPTYPE_NATOA_RFC:
454 			/* Ignore original source/destination messages */
455 			break;
456 #endif
457 
458 		default:
459 			/* don't send information, see ident_r1recv() */
460 			plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
461 				"ignore the packet, "
462 				"received unexpecting payload type %d.\n",
463 				pa->type);
464 			goto end;
465 		}
466 
467 		p += pa->len;
468 
469 		/* compute true length of payload. */
470 		tlen += pa->len;
471 	}
472 
473 	/* payload existency check */
474 	if (hash == NULL || iph2->sa_ret == NULL || iph2->nonce_p == NULL) {
475 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
476 			"few isakmp message received.\n");
477 		goto end;
478 	}
479 
480 	/* Fixed buffer for calculating HASH */
481 	memcpy(hbuf->v, iph2->nonce->v, iph2->nonce->l);
482 	plog(LLV_DEBUG, LOCATION, NULL,
483 		"HASH allocated:hbuf->l=%zu actual:tlen=%zu\n",
484 		hbuf->l, tlen + iph2->nonce->l);
485 	/* adjust buffer length for HASH */
486 	hbuf->l = iph2->nonce->l + tlen;
487 
488 	/* validate HASH(2) */
489     {
490 	char *r_hash;
491 	vchar_t *my_hash = NULL;
492 	int result;
493 
494 	r_hash = (char *)hash + sizeof(*hash);
495 
496 	plog(LLV_DEBUG, LOCATION, NULL, "HASH(2) received:");
497 	plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
498 
499 	my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
500 	if (my_hash == NULL)
501 		goto end;
502 
503 	result = memcmp(my_hash->v, r_hash, my_hash->l);
504 	vfree(my_hash);
505 
506 	if (result) {
507 		plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
508 			"HASH(2) mismatch.\n");
509 		error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
510 		goto end;
511 	}
512     }
513 
514 	/* validity check SA payload sent from responder */
515 	if (ipsecdoi_checkph2proposal(iph2) < 0) {
516 		error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
517 		goto end;
518 	}
519 
520 	/* change status of isakmp status entry */
521 	iph2->status = PHASE2ST_STATUS6;
522 
523 	error = 0;
524 
525 end:
526 	if (hbuf)
527 		vfree(hbuf);
528 	if (pbuf)
529 		vfree(pbuf);
530 	if (msg)
531 		vfree(msg);
532 
533 	if (error) {
534 		VPTRINIT(iph2->sa_ret);
535 		VPTRINIT(iph2->nonce_p);
536 		VPTRINIT(iph2->dhpub_p);
537 		VPTRINIT(iph2->id);
538 		VPTRINIT(iph2->id_p);
539 	}
540 
541 	return error;
542 }
543 
544 /*
545  * send to responder
546  * 	HDR*, HASH(3)
547  */
548 int
549 quick_i2send(iph2, msg0)
550 	struct ph2handle *iph2;
551 	vchar_t *msg0;
552 {
553 	vchar_t *msg = NULL;
554 	vchar_t *buf = NULL;
555 	vchar_t *hash = NULL;
556 	char *p = NULL;
557 	int tlen;
558 	int error = ISAKMP_INTERNAL_ERROR;
559 
560 	/* validity check */
561 	if (iph2->status != PHASE2ST_STATUS6) {
562 		plog(LLV_ERROR, LOCATION, NULL,
563 			"status mismatched %d.\n", iph2->status);
564 		goto end;
565 	}
566 
567 	/* generate HASH(3) */
568     {
569 	vchar_t *tmp = NULL;
570 
571 	plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) generate\n");
572 
573 	tmp = vmalloc(iph2->nonce->l + iph2->nonce_p->l);
574 	if (tmp == NULL) {
575 		plog(LLV_ERROR, LOCATION, NULL,
576 			"failed to get hash buffer.\n");
577 		goto end;
578 	}
579 	memcpy(tmp->v, iph2->nonce->v, iph2->nonce->l);
580 	memcpy(tmp->v + iph2->nonce->l, iph2->nonce_p->v, iph2->nonce_p->l);
581 
582 	hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
583 	vfree(tmp);
584 
585 	if (hash == NULL)
586 		goto end;
587     }
588 
589 	/* create buffer for isakmp payload */
590 	tlen = sizeof(struct isakmp)
591 		+ sizeof(struct isakmp_gen) + hash->l;
592 	buf = vmalloc(tlen);
593 	if (buf == NULL) {
594 		plog(LLV_ERROR, LOCATION, NULL,
595 			"failed to get buffer to send.\n");
596 		goto end;
597 	}
598 
599 	/* create isakmp header */
600 	p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
601 	if (p == NULL)
602 		goto end;
603 
604 	/* add HASH(3) payload */
605 	p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_NONE);
606 
607 #ifdef HAVE_PRINT_ISAKMP_C
608 	isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
609 #endif
610 
611 	/* encoding */
612 	iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
613 	if (iph2->sendbuf == NULL)
614 		goto end;
615 
616 	/* if there is commit bit, need resending */
617 	if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
618 		/* send the packet, add to the schedule to resend */
619 		iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
620 		if (isakmp_ph2resend(iph2) == -1)
621 			goto end;
622 	} else {
623 		/* send the packet */
624 		if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
625 			goto end;
626 	}
627 
628 	/* the sending message is added to the received-list. */
629 	if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local,
630 			iph2->sendbuf, msg0) == -1) {
631 		plog(LLV_ERROR , LOCATION, NULL,
632 			"failed to add a response packet to the tree.\n");
633 		goto end;
634 	}
635 
636 	/* compute both of KEYMATs */
637 	if (oakley_compute_keymat(iph2, INITIATOR) < 0)
638 		goto end;
639 
640 	iph2->status = PHASE2ST_ADDSA;
641 
642 	/* don't anything if local test mode. */
643 	if (f_local) {
644 		error = 0;
645 		goto end;
646 	}
647 
648 	/* if there is commit bit don't set up SA now. */
649 	if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
650 		iph2->status = PHASE2ST_COMMIT;
651 		error = 0;
652 		goto end;
653 	}
654 
655 	/* Do UPDATE for initiator */
656 	plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
657 	if (pk_sendupdate(iph2) < 0) {
658 		plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
659 		goto end;
660 	}
661 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
662 
663 	/* Do ADD for responder */
664 	if (pk_sendadd(iph2) < 0) {
665 		plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
666 		goto end;
667 	}
668 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
669 
670 	error = 0;
671 
672 end:
673 	if (buf != NULL)
674 		vfree(buf);
675 	if (msg != NULL)
676 		vfree(msg);
677 	if (hash != NULL)
678 		vfree(hash);
679 
680 	return error;
681 }
682 
683 /*
684  * receive from responder
685  * 	HDR#*, HASH(4), notify
686  */
687 int
688 quick_i3recv(iph2, msg0)
689 	struct ph2handle *iph2;
690 	vchar_t *msg0;
691 {
692 	vchar_t *msg = NULL;
693 	vchar_t *pbuf = NULL;	/* for payload parsing */
694 	struct isakmp_parse_t *pa;
695 	struct isakmp_pl_hash *hash = NULL;
696 	vchar_t *notify = NULL;
697 	int error = ISAKMP_INTERNAL_ERROR;
698 
699 	/* validity check */
700 	if (iph2->status != PHASE2ST_COMMIT) {
701 		plog(LLV_ERROR, LOCATION, NULL,
702 			"status mismatched %d.\n", iph2->status);
703 		goto end;
704 	}
705 
706 	/* decrypt packet */
707 	if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
708 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
709 			"Packet wasn't encrypted.\n");
710 		goto end;
711 	}
712 	msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
713 	if (msg == NULL)
714 		goto end;
715 
716 	/* validate the type of next payload */
717 	pbuf = isakmp_parse(msg);
718 	if (pbuf == NULL)
719 		goto end;
720 
721 	for (pa = (struct isakmp_parse_t *)pbuf->v;
722 	     pa->type != ISAKMP_NPTYPE_NONE;
723 	     pa++) {
724 
725 		switch (pa->type) {
726 		case ISAKMP_NPTYPE_HASH:
727 			hash = (struct isakmp_pl_hash *)pa->ptr;
728 			break;
729 		case ISAKMP_NPTYPE_N:
730 			isakmp_check_notify(pa->ptr, iph2->ph1);
731 			notify = vmalloc(pa->len);
732 			if (notify == NULL) {
733 				plog(LLV_ERROR, LOCATION, NULL,
734 					"failed to get notify buffer.\n");
735 				goto end;
736 			}
737 			memcpy(notify->v, pa->ptr, notify->l);
738 			break;
739 		default:
740 			/* don't send information, see ident_r1recv() */
741 			plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
742 				"ignore the packet, "
743 				"received unexpecting payload type %d.\n",
744 				pa->type);
745 			goto end;
746 		}
747 	}
748 
749 	/* payload existency check */
750 	if (hash == NULL) {
751 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
752 			"few isakmp message received.\n");
753 		goto end;
754 	}
755 
756 	/* validate HASH(4) */
757     {
758 	char *r_hash;
759 	vchar_t *my_hash = NULL;
760 	vchar_t *tmp = NULL;
761 	int result;
762 
763 	r_hash = (char *)hash + sizeof(*hash);
764 
765 	plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) validate:");
766 	plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
767 
768 	my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
769 	vfree(tmp);
770 	if (my_hash == NULL)
771 		goto end;
772 
773 	result = memcmp(my_hash->v, r_hash, my_hash->l);
774 	vfree(my_hash);
775 
776 	if (result) {
777 		plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
778 			"HASH(4) mismatch.\n");
779 		error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
780 		goto end;
781 	}
782     }
783 
784 	iph2->status = PHASE2ST_ADDSA;
785 	iph2->flags ^= ISAKMP_FLAG_C;	/* reset bit */
786 
787 	/* don't anything if local test mode. */
788 	if (f_local) {
789 		error = 0;
790 		goto end;
791 	}
792 
793 	/* Do UPDATE for initiator */
794 	plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
795 	if (pk_sendupdate(iph2) < 0) {
796 		plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
797 		goto end;
798 	}
799 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
800 
801 	/* Do ADD for responder */
802 	if (pk_sendadd(iph2) < 0) {
803 		plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
804 		goto end;
805 	}
806 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
807 
808 	error = 0;
809 
810 end:
811 	if (msg != NULL)
812 		vfree(msg);
813 	if (pbuf != NULL)
814 		vfree(pbuf);
815 	if (notify != NULL)
816 		vfree(notify);
817 
818 	return error;
819 }
820 
821 /*
822  * receive from initiator
823  * 	HDR*, HASH(1), SA, Ni [, KE ] [, IDi2, IDr2 ]
824  */
825 int
826 quick_r1recv(iph2, msg0)
827 	struct ph2handle *iph2;
828 	vchar_t *msg0;
829 {
830 	vchar_t *msg = NULL;
831 	vchar_t *hbuf = NULL;	/* for hash computing. */
832 	vchar_t *pbuf = NULL;	/* for payload parsing */
833 	struct isakmp_parse_t *pa;
834 	struct isakmp *isakmp = (struct isakmp *)msg0->v;
835 	struct isakmp_pl_hash *hash = NULL;
836 	char *p;
837 	int tlen;
838 	int f_id_order;	/* for ID payload detection */
839 	int error = ISAKMP_INTERNAL_ERROR;
840 
841 	/* validity check */
842 	if (iph2->status != PHASE2ST_START) {
843 		plog(LLV_ERROR, LOCATION, NULL,
844 			"status mismatched %d.\n", iph2->status);
845 		goto end;
846 	}
847 
848 	/* decrypting */
849 	if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
850 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
851 			"Packet wasn't encrypted.\n");
852 		error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
853 		goto end;
854 	}
855 	/* decrypt packet */
856 	msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
857 	if (msg == NULL)
858 		goto end;
859 
860 	/* create buffer for using to validate HASH(1) */
861 	/*
862 	 * ordering rule:
863 	 *	1. the first one must be HASH
864 	 *	2. the second one must be SA (added in isakmp-oakley-05!)
865 	 *	3. two IDs must be considered as IDci, then IDcr
866 	 */
867 	pbuf = isakmp_parse(msg);
868 	if (pbuf == NULL)
869 		goto end;
870 	pa = (struct isakmp_parse_t *)pbuf->v;
871 
872 	/* HASH payload is fixed postion */
873 	if (pa->type != ISAKMP_NPTYPE_HASH) {
874 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
875 			"received invalid next payload type %d, "
876 			"expecting %d.\n",
877 			pa->type, ISAKMP_NPTYPE_HASH);
878 		error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
879 		goto end;
880 	}
881 	hash = (struct isakmp_pl_hash *)pa->ptr;
882 	pa++;
883 
884 	/*
885 	 * this restriction was introduced in isakmp-oakley-05.
886 	 * we do not check this for backward compatibility.
887 	 * TODO: command line/config file option to enable/disable this code
888 	 */
889 	/* HASH payload is fixed postion */
890 	if (pa->type != ISAKMP_NPTYPE_SA) {
891 		plog(LLV_WARNING, LOCATION, iph2->ph1->remote,
892 			"received invalid next payload type %d, "
893 			"expecting %d.\n",
894 			pa->type, ISAKMP_NPTYPE_SA);
895 		error = ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX;
896 	}
897 
898 	/* allocate buffer for computing HASH(1) */
899 	tlen = ntohl(isakmp->len) - sizeof(*isakmp);
900 	hbuf = vmalloc(tlen);
901 	if (hbuf == NULL) {
902 		plog(LLV_ERROR, LOCATION, NULL,
903 			"failed to get hash buffer.\n");
904 		goto end;
905 	}
906 	p = hbuf->v;
907 
908 	/*
909 	 * parse the payloads.
910 	 * copy non-HASH payloads into hbuf, so that we can validate HASH.
911 	 */
912 	iph2->sa = NULL;	/* we don't support multi SAs. */
913 	iph2->nonce_p = NULL;
914 	iph2->dhpub_p = NULL;
915 	iph2->id_p = NULL;
916 	iph2->id = NULL;
917 	tlen = 0;	/* count payload length except of HASH payload. */
918 
919 	/*
920 	 * IDi2 MUST be immediatelly followed by IDr2.  We allowed the
921 	 * illegal case, but logged.  First ID payload is to be IDi2.
922 	 * And next ID payload is to be IDr2.
923 	 */
924 	f_id_order = 0;
925 
926 	for (; pa->type; pa++) {
927 
928 		/* copy to buffer for HASH */
929 		/* Don't modify the payload */
930 		memcpy(p, pa->ptr, pa->len);
931 
932 		if (pa->type != ISAKMP_NPTYPE_ID)
933 			f_id_order = 0;
934 
935 		switch (pa->type) {
936 		case ISAKMP_NPTYPE_SA:
937 			if (iph2->sa != NULL) {
938 				plog(LLV_ERROR, LOCATION, NULL,
939 					"Multi SAs isn't supported.\n");
940 				goto end;
941 			}
942 			if (isakmp_p2ph(&iph2->sa, pa->ptr) < 0)
943 				goto end;
944 			break;
945 
946 		case ISAKMP_NPTYPE_NONCE:
947 			if (isakmp_p2ph(&iph2->nonce_p, pa->ptr) < 0)
948 				goto end;
949 			break;
950 
951 		case ISAKMP_NPTYPE_KE:
952 			if (isakmp_p2ph(&iph2->dhpub_p, pa->ptr) < 0)
953 				goto end;
954 			break;
955 
956 		case ISAKMP_NPTYPE_ID:
957 			if (iph2->id_p == NULL) {
958 				/* for IDci */
959 				f_id_order++;
960 
961 				if (isakmp_p2ph(&iph2->id_p, pa->ptr) < 0)
962 					goto end;
963 
964 			} else if (iph2->id == NULL) {
965 				/* for IDcr */
966 				if (f_id_order == 0) {
967 					plog(LLV_ERROR, LOCATION, NULL,
968 						"IDr2 payload is not "
969 						"immediatelly followed "
970 						"by IDi2. We allowed.\n");
971 					/* XXX we allowed in this case. */
972 				}
973 
974 				if (isakmp_p2ph(&iph2->id, pa->ptr) < 0)
975 					goto end;
976 			} else {
977 				plog(LLV_ERROR, LOCATION, NULL,
978 					"received too many ID payloads.\n");
979 				plogdump(LLV_ERROR, iph2->id->v, iph2->id->l);
980 				error = ISAKMP_NTYPE_INVALID_ID_INFORMATION;
981 				goto end;
982 			}
983 			break;
984 
985 		case ISAKMP_NPTYPE_N:
986 			isakmp_check_notify(pa->ptr, iph2->ph1);
987 			break;
988 
989 #ifdef ENABLE_NATT
990 		case ISAKMP_NPTYPE_NATOA_DRAFT:
991 		case ISAKMP_NPTYPE_NATOA_RFC:
992 			/* Ignore original source/destination messages */
993 			break;
994 #endif
995 
996 		default:
997 			plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
998 				"ignore the packet, "
999 				"received unexpecting payload type %d.\n",
1000 				pa->type);
1001 			error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1002 			goto end;
1003 		}
1004 
1005 		p += pa->len;
1006 
1007 		/* compute true length of payload. */
1008 		tlen += pa->len;
1009 	}
1010 
1011 	/* payload existency check */
1012 	if (hash == NULL || iph2->sa == NULL || iph2->nonce_p == NULL) {
1013 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1014 			"few isakmp message received.\n");
1015 		error = ISAKMP_NTYPE_PAYLOAD_MALFORMED;
1016 		goto end;
1017 	}
1018 
1019 	if (iph2->id_p) {
1020 		plog(LLV_DEBUG, LOCATION, NULL, "received IDci2:");
1021 		plogdump(LLV_DEBUG, iph2->id_p->v, iph2->id_p->l);
1022 	}
1023 	if (iph2->id) {
1024 		plog(LLV_DEBUG, LOCATION, NULL, "received IDcr2:");
1025 		plogdump(LLV_DEBUG, iph2->id->v, iph2->id->l);
1026 	}
1027 
1028 	/* adjust buffer length for HASH */
1029 	hbuf->l = tlen;
1030 
1031 	/* validate HASH(1) */
1032     {
1033 	char *r_hash;
1034 	vchar_t *my_hash = NULL;
1035 	int result;
1036 
1037 	r_hash = (caddr_t)hash + sizeof(*hash);
1038 
1039 	plog(LLV_DEBUG, LOCATION, NULL, "HASH(1) validate:");
1040 	plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
1041 
1042 	my_hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, hbuf);
1043 	if (my_hash == NULL)
1044 		goto end;
1045 
1046 	result = memcmp(my_hash->v, r_hash, my_hash->l);
1047 	vfree(my_hash);
1048 
1049 	if (result) {
1050 		plog(LLV_DEBUG, LOCATION, iph2->ph1->remote,
1051 			"HASH(1) mismatch.\n");
1052 		error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1053 		goto end;
1054 	}
1055     }
1056 
1057 	/* get sainfo */
1058 	error = get_sainfo_r(iph2);
1059 	if (error) {
1060 		plog(LLV_ERROR, LOCATION, NULL,
1061 			"failed to get sainfo.\n");
1062 		goto end;
1063 	}
1064 
1065 	/* check the existence of ID payload and create responder's proposal */
1066 	error = get_proposal_r(iph2);
1067 	switch (error) {
1068 	case -2:
1069 		/* generate a policy template from peer's proposal */
1070 		if (set_proposal_from_proposal(iph2)) {
1071 			plog(LLV_ERROR, LOCATION, NULL,
1072 				"failed to generate a proposal template "
1073 				"from client's proposal.\n");
1074 			return ISAKMP_INTERNAL_ERROR;
1075 		}
1076 		/*FALLTHROUGH*/
1077 	case 0:
1078 		/* select single proposal or reject it. */
1079 		if (ipsecdoi_selectph2proposal(iph2) < 0) {
1080 			error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1081 			goto end;
1082 		}
1083 		break;
1084 	default:
1085 		plog(LLV_ERROR, LOCATION, NULL,
1086 			"failed to get proposal for responder.\n");
1087 		goto end;
1088 	}
1089 
1090 	/* check KE and attribute of PFS */
1091 	if (iph2->dhpub_p != NULL && iph2->approval->pfs_group == 0) {
1092 		plog(LLV_ERROR, LOCATION, NULL,
1093 			"no PFS is specified, but peer sends KE.\n");
1094 		error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1095 		goto end;
1096 	}
1097 	if (iph2->dhpub_p == NULL && iph2->approval->pfs_group != 0) {
1098 		plog(LLV_ERROR, LOCATION, NULL,
1099 			"PFS is specified, but peer doesn't sends KE.\n");
1100 		error = ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN;
1101 		goto end;
1102 	}
1103 
1104 	/*
1105 	 * save the packet from the initiator in order to resend the
1106 	 * responder's first packet against this packet.
1107 	 */
1108 	iph2->msg1 = vdup(msg0);
1109 
1110 	/* change status of isakmp status entry */
1111 	iph2->status = PHASE2ST_STATUS2;
1112 
1113 	error = 0;
1114 
1115 end:
1116 	if (hbuf)
1117 		vfree(hbuf);
1118 	if (msg)
1119 		vfree(msg);
1120 	if (pbuf)
1121 		vfree(pbuf);
1122 
1123 	if (error) {
1124 		VPTRINIT(iph2->sa);
1125 		VPTRINIT(iph2->nonce_p);
1126 		VPTRINIT(iph2->dhpub_p);
1127 		VPTRINIT(iph2->id);
1128 		VPTRINIT(iph2->id_p);
1129 	}
1130 
1131 	return error;
1132 }
1133 
1134 /*
1135  * call pfkey_getspi.
1136  */
1137 int
1138 quick_r1prep(iph2, msg)
1139 	struct ph2handle *iph2;
1140 	vchar_t *msg;
1141 {
1142 	int error = ISAKMP_INTERNAL_ERROR;
1143 
1144 	/* validity check */
1145 	if (iph2->status != PHASE2ST_STATUS2) {
1146 		plog(LLV_ERROR, LOCATION, NULL,
1147 			"status mismatched %d.\n", iph2->status);
1148 		goto end;
1149 	}
1150 
1151 	iph2->status = PHASE2ST_GETSPISENT;
1152 
1153 	/* send getspi message */
1154 	if (pk_sendgetspi(iph2) < 0)
1155 		goto end;
1156 
1157 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey getspi sent.\n");
1158 
1159 	iph2->sce = sched_new(lcconf->wait_ph2complete,
1160 		pfkey_timeover_stub, iph2);
1161 
1162 	error = 0;
1163 
1164 end:
1165 	return error;
1166 }
1167 
1168 /*
1169  * send to initiator
1170  * 	HDR*, HASH(2), SA, Nr [, KE ] [, IDi2, IDr2 ]
1171  */
1172 int
1173 quick_r2send(iph2, msg)
1174 	struct ph2handle *iph2;
1175 	vchar_t *msg;
1176 {
1177 	vchar_t *body = NULL;
1178 	vchar_t *hash = NULL;
1179 	struct isakmp_gen *gen;
1180 	char *p;
1181 	int tlen;
1182 	int error = ISAKMP_INTERNAL_ERROR;
1183 	int pfsgroup;
1184 	u_int8_t *np_p = NULL;
1185 
1186 	/* validity check */
1187 	if (msg != NULL) {
1188 		plog(LLV_ERROR, LOCATION, NULL,
1189 			"msg has to be NULL in this function.\n");
1190 		goto end;
1191 	}
1192 	if (iph2->status != PHASE2ST_GETSPIDONE) {
1193 		plog(LLV_ERROR, LOCATION, NULL,
1194 			"status mismatched %d.\n", iph2->status);
1195 		goto end;
1196 	}
1197 
1198 	/* update responders SPI */
1199 	if (ipsecdoi_updatespi(iph2) < 0) {
1200 		plog(LLV_ERROR, LOCATION, NULL, "failed to update spi.\n");
1201 		goto end;
1202 	}
1203 
1204 	/* generate NONCE value */
1205 	iph2->nonce = eay_set_random(iph2->ph1->rmconf->nonce_size);
1206 	if (iph2->nonce == NULL)
1207 		goto end;
1208 
1209 	/* generate KE value if need */
1210 	pfsgroup = iph2->approval->pfs_group;
1211 	if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1212 		/* DH group settting if PFS is required. */
1213 		if (oakley_setdhgroup(pfsgroup, &iph2->pfsgrp) < 0) {
1214 			plog(LLV_ERROR, LOCATION, NULL,
1215 				"failed to set DH value.\n");
1216 			goto end;
1217 		}
1218 		/* generate DH public value */
1219 		if (oakley_dh_generate(iph2->pfsgrp,
1220 				&iph2->dhpub, &iph2->dhpriv) < 0) {
1221 			goto end;
1222 		}
1223 	}
1224 
1225 	/* create SA;NONCE payload, and KE and ID if need */
1226 	tlen = sizeof(*gen) + iph2->sa_ret->l
1227 		+ sizeof(*gen) + iph2->nonce->l;
1228 	if (iph2->dhpub_p != NULL && pfsgroup != 0)
1229 		tlen += (sizeof(*gen) + iph2->dhpub->l);
1230 	if (iph2->id_p != NULL)
1231 		tlen += (sizeof(*gen) + iph2->id_p->l
1232 			+ sizeof(*gen) + iph2->id->l);
1233 
1234 	body = vmalloc(tlen);
1235 	if (body == NULL) {
1236 		plog(LLV_ERROR, LOCATION, NULL,
1237 			"failed to get buffer to send.\n");
1238 		goto end;
1239 	}
1240 	p = body->v;
1241 
1242 	/* make SA payload */
1243 	p = set_isakmp_payload(body->v, iph2->sa_ret, ISAKMP_NPTYPE_NONCE);
1244 
1245 	/* add NONCE payload */
1246 	np_p = &((struct isakmp_gen *)p)->np;	/* XXX */
1247 	p = set_isakmp_payload(p, iph2->nonce,
1248 		(iph2->dhpub_p != NULL && pfsgroup != 0)
1249 				? ISAKMP_NPTYPE_KE
1250 				: (iph2->id_p != NULL
1251 					? ISAKMP_NPTYPE_ID
1252 					: ISAKMP_NPTYPE_NONE));
1253 
1254 	/* add KE payload if need. */
1255 	if (iph2->dhpub_p != NULL && pfsgroup != 0) {
1256 		np_p = &((struct isakmp_gen *)p)->np;	/* XXX */
1257 		p = set_isakmp_payload(p, iph2->dhpub,
1258 			(iph2->id_p == NULL)
1259 				? ISAKMP_NPTYPE_NONE
1260 				: ISAKMP_NPTYPE_ID);
1261 	}
1262 
1263 	/* add ID payloads received. */
1264 	if (iph2->id_p != NULL) {
1265 		/* IDci */
1266 		p = set_isakmp_payload(p, iph2->id_p, ISAKMP_NPTYPE_ID);
1267 		/* IDcr */
1268 		np_p = &((struct isakmp_gen *)p)->np;	/* XXX */
1269 		p = set_isakmp_payload(p, iph2->id, ISAKMP_NPTYPE_NONE);
1270 	}
1271 
1272 	/* add a RESPONDER-LIFETIME notify payload if needed */
1273     {
1274 	vchar_t *data = NULL;
1275 	struct saprop *pp = iph2->approval;
1276 	struct saproto *pr;
1277 
1278 	if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_SEC) {
1279 		u_int32_t v = htonl((u_int32_t)pp->lifetime);
1280 		data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1281 					IPSECDOI_ATTR_SA_LD_TYPE_SEC);
1282 		if (!data)
1283 			goto end;
1284 		data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1285 					(caddr_t)&v, sizeof(v));
1286 		if (!data)
1287 			goto end;
1288 	}
1289 	if (pp->claim & IPSECDOI_ATTR_SA_LD_TYPE_KB) {
1290 		u_int32_t v = htonl((u_int32_t)pp->lifebyte);
1291 		data = isakmp_add_attr_l(data, IPSECDOI_ATTR_SA_LD_TYPE,
1292 					IPSECDOI_ATTR_SA_LD_TYPE_KB);
1293 		if (!data)
1294 			goto end;
1295 		data = isakmp_add_attr_v(data, IPSECDOI_ATTR_SA_LD,
1296 					(caddr_t)&v, sizeof(v));
1297 		if (!data)
1298 			goto end;
1299 	}
1300 
1301 	/*
1302 	 * XXX Is there only single RESPONDER-LIFETIME payload in a IKE message
1303 	 * in the case of SA bundle ?
1304 	 */
1305 	if (data) {
1306 		for (pr = pp->head; pr; pr = pr->next) {
1307 			body = isakmp_add_pl_n(body, &np_p,
1308 					ISAKMP_NTYPE_RESPONDER_LIFETIME, pr, data);
1309 			if (!body) {
1310 				vfree(data);
1311 				return error;	/* XXX */
1312 			}
1313 		}
1314 		vfree(data);
1315 	}
1316     }
1317 
1318 	/* generate HASH(2) */
1319     {
1320 	vchar_t *tmp;
1321 
1322 	tmp = vmalloc(iph2->nonce_p->l + body->l);
1323 	if (tmp == NULL) {
1324 		plog(LLV_ERROR, LOCATION, NULL,
1325 			"failed to get hash buffer.\n");
1326 		goto end;
1327 	}
1328 	memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1329 	memcpy(tmp->v + iph2->nonce_p->l, body->v, body->l);
1330 
1331 	hash = oakley_compute_hash1(iph2->ph1, iph2->msgid, tmp);
1332 	vfree(tmp);
1333 
1334 	if (hash == NULL)
1335 		goto end;
1336     }
1337 
1338 	/* send isakmp payload */
1339 	iph2->sendbuf = quick_ir1mx(iph2, body, hash);
1340 	if (iph2->sendbuf == NULL)
1341 		goto end;
1342 
1343 	/* send the packet, add to the schedule to resend */
1344 	iph2->retry_counter = iph2->ph1->rmconf->retry_counter;
1345 	if (isakmp_ph2resend(iph2) == -1)
1346 		goto end;
1347 
1348 	/* the sending message is added to the received-list. */
1349 	if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, iph2->msg1) == -1) {
1350 		plog(LLV_ERROR , LOCATION, NULL,
1351 			"failed to add a response packet to the tree.\n");
1352 		goto end;
1353 	}
1354 
1355 	/* change status of isakmp status entry */
1356 	iph2->status = PHASE2ST_MSG1SENT;
1357 
1358 	error = 0;
1359 
1360 end:
1361 	if (body != NULL)
1362 		vfree(body);
1363 	if (hash != NULL)
1364 		vfree(hash);
1365 
1366 	return error;
1367 }
1368 
1369 /*
1370  * receive from initiator
1371  * 	HDR*, HASH(3)
1372  */
1373 int
1374 quick_r3recv(iph2, msg0)
1375 	struct ph2handle *iph2;
1376 	vchar_t *msg0;
1377 {
1378 	vchar_t *msg = NULL;
1379 	vchar_t *pbuf = NULL;	/* for payload parsing */
1380 	struct isakmp_parse_t *pa;
1381 	struct isakmp_pl_hash *hash = NULL;
1382 	int error = ISAKMP_INTERNAL_ERROR;
1383 
1384 	/* validity check */
1385 	if (iph2->status != PHASE2ST_MSG1SENT) {
1386 		plog(LLV_ERROR, LOCATION, NULL,
1387 			"status mismatched %d.\n", iph2->status);
1388 		goto end;
1389 	}
1390 
1391 	/* decrypt packet */
1392 	if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1393 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1394 			"Packet wasn't encrypted.\n");
1395 		goto end;
1396 	}
1397 	msg = oakley_do_decrypt(iph2->ph1, msg0, iph2->ivm->iv, iph2->ivm->ive);
1398 	if (msg == NULL)
1399 		goto end;
1400 
1401 	/* validate the type of next payload */
1402 	pbuf = isakmp_parse(msg);
1403 	if (pbuf == NULL)
1404 		goto end;
1405 
1406 	for (pa = (struct isakmp_parse_t *)pbuf->v;
1407 	     pa->type != ISAKMP_NPTYPE_NONE;
1408 	     pa++) {
1409 
1410 		switch (pa->type) {
1411 		case ISAKMP_NPTYPE_HASH:
1412 			hash = (struct isakmp_pl_hash *)pa->ptr;
1413 			break;
1414 		case ISAKMP_NPTYPE_N:
1415 			isakmp_check_notify(pa->ptr, iph2->ph1);
1416 			break;
1417 		default:
1418 			/* don't send information, see ident_r1recv() */
1419 			plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1420 				"ignore the packet, "
1421 				"received unexpecting payload type %d.\n",
1422 				pa->type);
1423 			goto end;
1424 		}
1425 	}
1426 
1427 	/* payload existency check */
1428 	if (hash == NULL) {
1429 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1430 			"few isakmp message received.\n");
1431 		goto end;
1432 	}
1433 
1434 	/* validate HASH(3) */
1435 	/* HASH(3) = prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) */
1436     {
1437 	char *r_hash;
1438 	vchar_t *my_hash = NULL;
1439 	vchar_t *tmp = NULL;
1440 	int result;
1441 
1442 	r_hash = (char *)hash + sizeof(*hash);
1443 
1444 	plog(LLV_DEBUG, LOCATION, NULL, "HASH(3) validate:");
1445 	plogdump(LLV_DEBUG, r_hash, ntohs(hash->h.len) - sizeof(*hash));
1446 
1447 	tmp = vmalloc(iph2->nonce_p->l + iph2->nonce->l);
1448 	if (tmp == NULL) {
1449 		plog(LLV_ERROR, LOCATION, NULL,
1450 			"failed to get hash buffer.\n");
1451 		goto end;
1452 	}
1453 	memcpy(tmp->v, iph2->nonce_p->v, iph2->nonce_p->l);
1454 	memcpy(tmp->v + iph2->nonce_p->l, iph2->nonce->v, iph2->nonce->l);
1455 
1456 	my_hash = oakley_compute_hash3(iph2->ph1, iph2->msgid, tmp);
1457 	vfree(tmp);
1458 	if (my_hash == NULL)
1459 		goto end;
1460 
1461 	result = memcmp(my_hash->v, r_hash, my_hash->l);
1462 	vfree(my_hash);
1463 
1464 	if (result) {
1465 		plog(LLV_ERROR, LOCATION, iph2->ph1->remote,
1466 			"HASH(3) mismatch.\n");
1467 		error = ISAKMP_NTYPE_INVALID_HASH_INFORMATION;
1468 		goto end;
1469 	}
1470     }
1471 
1472 	/* if there is commit bit, don't set up SA now. */
1473 	if (ISSET(iph2->flags, ISAKMP_FLAG_C)) {
1474 		iph2->status = PHASE2ST_COMMIT;
1475 	} else
1476 		iph2->status = PHASE2ST_STATUS6;
1477 
1478 	error = 0;
1479 
1480 end:
1481 	if (pbuf != NULL)
1482 		vfree(pbuf);
1483 	if (msg != NULL)
1484 		vfree(msg);
1485 
1486 	return error;
1487 }
1488 
1489 /*
1490  * send to initiator
1491  * 	HDR#*, HASH(4), notify
1492  */
1493 int
1494 quick_r3send(iph2, msg0)
1495 	struct ph2handle *iph2;
1496 	vchar_t *msg0;
1497 {
1498 	vchar_t *buf = NULL;
1499 	vchar_t *myhash = NULL;
1500 	struct isakmp_pl_n *n;
1501 	vchar_t *notify = NULL;
1502 	char *p;
1503 	int tlen;
1504 	int error = ISAKMP_INTERNAL_ERROR;
1505 
1506 	/* validity check */
1507 	if (iph2->status != PHASE2ST_COMMIT) {
1508 		plog(LLV_ERROR, LOCATION, NULL,
1509 			"status mismatched %d.\n", iph2->status);
1510 		goto end;
1511 	}
1512 
1513 	/* generate HASH(4) */
1514 	/* XXX What can I do in the case of multiple different SA */
1515 	plog(LLV_DEBUG, LOCATION, NULL, "HASH(4) generate\n");
1516 
1517 	/* XXX What should I do if there are multiple SAs ? */
1518 	tlen = sizeof(struct isakmp_pl_n) + iph2->approval->head->spisize;
1519 	notify = vmalloc(tlen);
1520 	if (notify == NULL) {
1521 		plog(LLV_ERROR, LOCATION, NULL,
1522 			"failed to get notify buffer.\n");
1523 		goto end;
1524 	}
1525 	n = (struct isakmp_pl_n *)notify->v;
1526 	n->h.np = ISAKMP_NPTYPE_NONE;
1527 	n->h.len = htons(tlen);
1528 	n->doi = htonl(IPSEC_DOI);
1529 	n->proto_id = iph2->approval->head->proto_id;
1530 	n->spi_size = sizeof(iph2->approval->head->spisize);
1531 	n->type = htons(ISAKMP_NTYPE_CONNECTED);
1532 	memcpy(n + 1, &iph2->approval->head->spi, iph2->approval->head->spisize);
1533 
1534 	myhash = oakley_compute_hash1(iph2->ph1, iph2->msgid, notify);
1535 	if (myhash == NULL)
1536 		goto end;
1537 
1538 	/* create buffer for isakmp payload */
1539 	tlen = sizeof(struct isakmp)
1540 		+ sizeof(struct isakmp_gen) + myhash->l
1541 		+ notify->l;
1542 	buf = vmalloc(tlen);
1543 	if (buf == NULL) {
1544 		plog(LLV_ERROR, LOCATION, NULL,
1545 			"failed to get buffer to send.\n");
1546 		goto end;
1547 	}
1548 
1549 	/* create isakmp header */
1550 	p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
1551 	if (p == NULL)
1552 		goto end;
1553 
1554 	/* add HASH(4) payload */
1555 	p = set_isakmp_payload(p, myhash, ISAKMP_NPTYPE_N);
1556 
1557 	/* add notify payload */
1558 	memcpy(p, notify->v, notify->l);
1559 
1560 #ifdef HAVE_PRINT_ISAKMP_C
1561 	isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
1562 #endif
1563 
1564 	/* encoding */
1565 	iph2->sendbuf = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
1566 	if (iph2->sendbuf == NULL)
1567 		goto end;
1568 
1569 	/* send the packet */
1570 	if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
1571 		goto end;
1572 
1573 	/* the sending message is added to the received-list. */
1574 	if (add_recvdpkt(iph2->ph1->remote, iph2->ph1->local, iph2->sendbuf, msg0) == -1) {
1575 		plog(LLV_ERROR , LOCATION, NULL,
1576 			"failed to add a response packet to the tree.\n");
1577 		goto end;
1578 	}
1579 
1580 	iph2->status = PHASE2ST_COMMIT;
1581 
1582 	error = 0;
1583 
1584 end:
1585 	if (buf != NULL)
1586 		vfree(buf);
1587 	if (myhash != NULL)
1588 		vfree(myhash);
1589 	if (notify != NULL)
1590 		vfree(notify);
1591 
1592 	return error;
1593 }
1594 
1595 /*
1596  * set SA to kernel.
1597  */
1598 int
1599 quick_r3prep(iph2, msg0)
1600 	struct ph2handle *iph2;
1601 	vchar_t *msg0;
1602 {
1603 	vchar_t *msg = NULL;
1604 	int error = ISAKMP_INTERNAL_ERROR;
1605 
1606 	/* validity check */
1607 	if (iph2->status != PHASE2ST_STATUS6) {
1608 		plog(LLV_ERROR, LOCATION, NULL,
1609 			"status mismatched %d.\n", iph2->status);
1610 		goto end;
1611 	}
1612 
1613 	/* compute both of KEYMATs */
1614 	if (oakley_compute_keymat(iph2, RESPONDER) < 0)
1615 		goto end;
1616 
1617 	iph2->status = PHASE2ST_ADDSA;
1618 	iph2->flags ^= ISAKMP_FLAG_C;	/* reset bit */
1619 
1620 	/* don't anything if local test mode. */
1621 	if (f_local) {
1622 		error = 0;
1623 		goto end;
1624 	}
1625 
1626 	/* Do UPDATE as responder */
1627 	plog(LLV_DEBUG, LOCATION, NULL, "call pk_sendupdate\n");
1628 	if (pk_sendupdate(iph2) < 0) {
1629 		plog(LLV_ERROR, LOCATION, NULL, "pfkey update failed.\n");
1630 		goto end;
1631 	}
1632 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey update sent.\n");
1633 
1634 	/* Do ADD for responder */
1635 	if (pk_sendadd(iph2) < 0) {
1636 		plog(LLV_ERROR, LOCATION, NULL, "pfkey add failed.\n");
1637 		goto end;
1638 	}
1639 	plog(LLV_DEBUG, LOCATION, NULL, "pfkey add sent.\n");
1640 
1641 	/*
1642 	 * set policies into SPD if the policy is generated
1643 	 * from peer's policy.
1644 	 */
1645 	if (iph2->spidx_gen) {
1646 
1647 		struct policyindex *spidx;
1648 		struct sockaddr_storage addr;
1649 		u_int8_t pref;
1650 		struct sockaddr *src = iph2->src;
1651 		struct sockaddr *dst = iph2->dst;
1652 
1653 		/* make inbound policy */
1654 		iph2->src = dst;
1655 		iph2->dst = src;
1656 		if (pk_sendspdupdate2(iph2) < 0) {
1657 			plog(LLV_ERROR, LOCATION, NULL,
1658 				"pfkey spdupdate2(inbound) failed.\n");
1659 			goto end;
1660 		}
1661 		plog(LLV_DEBUG, LOCATION, NULL,
1662 			"pfkey spdupdate2(inbound) sent.\n");
1663 
1664 		spidx = (struct policyindex *)iph2->spidx_gen;
1665 #ifdef HAVE_POLICY_FWD
1666 		/* make forward policy if required */
1667 		if (tunnel_mode_prop(iph2->approval)) {
1668 			spidx->dir = IPSEC_DIR_FWD;
1669 			if (pk_sendspdupdate2(iph2) < 0) {
1670 				plog(LLV_ERROR, LOCATION, NULL,
1671 					"pfkey spdupdate2(forward) failed.\n");
1672 				goto end;
1673 			}
1674 			plog(LLV_DEBUG, LOCATION, NULL,
1675 				"pfkey spdupdate2(forward) sent.\n");
1676 		}
1677 #endif
1678 
1679 		/* make outbound policy */
1680 		iph2->src = src;
1681 		iph2->dst = dst;
1682 		spidx->dir = IPSEC_DIR_OUTBOUND;
1683 		addr = spidx->src;
1684 		spidx->src = spidx->dst;
1685 		spidx->dst = addr;
1686 		pref = spidx->prefs;
1687 		spidx->prefs = spidx->prefd;
1688 		spidx->prefd = pref;
1689 
1690 		if (pk_sendspdupdate2(iph2) < 0) {
1691 			plog(LLV_ERROR, LOCATION, NULL,
1692 				"pfkey spdupdate2(outbound) failed.\n");
1693 			goto end;
1694 		}
1695 		plog(LLV_DEBUG, LOCATION, NULL,
1696 			"pfkey spdupdate2(outbound) sent.\n");
1697 
1698 		/* spidx_gen is unnecessary any more */
1699 		delsp_bothdir((struct policyindex *)iph2->spidx_gen);
1700 		racoon_free(iph2->spidx_gen);
1701 		iph2->spidx_gen = NULL;
1702 		iph2->generated_spidx=1;
1703 	}
1704 
1705 	error = 0;
1706 
1707 end:
1708 	if (msg != NULL)
1709 		vfree(msg);
1710 
1711 	return error;
1712 }
1713 
1714 /*
1715  * create HASH, body (SA, NONCE) payload with isakmp header.
1716  */
1717 static vchar_t *
1718 quick_ir1mx(iph2, body, hash)
1719 	struct ph2handle *iph2;
1720 	vchar_t *body, *hash;
1721 {
1722 	struct isakmp *isakmp;
1723 	vchar_t *buf = NULL, *new = NULL;
1724 	char *p;
1725 	int tlen;
1726 	struct isakmp_gen *gen;
1727 	int error = ISAKMP_INTERNAL_ERROR;
1728 
1729 	/* create buffer for isakmp payload */
1730 	tlen = sizeof(*isakmp)
1731 		+ sizeof(*gen) + hash->l
1732 		+ body->l;
1733 	buf = vmalloc(tlen);
1734 	if (buf == NULL) {
1735 		plog(LLV_ERROR, LOCATION, NULL,
1736 			"failed to get buffer to send.\n");
1737 		goto end;
1738 	}
1739 
1740 	/* re-set encryption flag, for serurity. */
1741 	iph2->flags |= ISAKMP_FLAG_E;
1742 
1743 	/* set isakmp header */
1744 	p = set_isakmp_header2(buf, iph2, ISAKMP_NPTYPE_HASH);
1745 	if (p == NULL)
1746 		goto end;
1747 
1748 	/* add HASH payload */
1749 	/* XXX is next type always SA ? */
1750 	p = set_isakmp_payload(p, hash, ISAKMP_NPTYPE_SA);
1751 
1752 	/* add body payload */
1753 	memcpy(p, body->v, body->l);
1754 
1755 #ifdef HAVE_PRINT_ISAKMP_C
1756 	isakmp_printpacket(buf, iph2->ph1->local, iph2->ph1->remote, 1);
1757 #endif
1758 
1759 	/* encoding */
1760 	new = oakley_do_encrypt(iph2->ph1, buf, iph2->ivm->ive, iph2->ivm->iv);
1761 	if (new == NULL)
1762 		goto end;
1763 
1764 	vfree(buf);
1765 
1766 	buf = new;
1767 
1768 	error = 0;
1769 
1770 end:
1771 	if (error && buf != NULL) {
1772 		vfree(buf);
1773 		buf = NULL;
1774 	}
1775 
1776 	return buf;
1777 }
1778 
1779 /*
1780  * get remote's sainfo.
1781  * NOTE: this function is for responder.
1782  */
1783 static int
1784 get_sainfo_r(iph2)
1785 	struct ph2handle *iph2;
1786 {
1787 	vchar_t *idsrc = NULL, *iddst = NULL;
1788 	int prefixlen;
1789 	int error = ISAKMP_INTERNAL_ERROR;
1790 
1791 	if (iph2->id_p == NULL) {
1792 		switch (iph2->src->sa_family) {
1793 		case AF_INET:
1794 			prefixlen = sizeof(struct in_addr) << 3;
1795 			break;
1796 		case AF_INET6:
1797 			prefixlen = sizeof(struct in6_addr) << 3;
1798 			break;
1799 		default:
1800 			plog(LLV_ERROR, LOCATION, NULL,
1801 				"invalid family: %d\n", iph2->src->sa_family);
1802 			goto end;
1803 		}
1804 		idsrc = ipsecdoi_sockaddr2id(iph2->src, prefixlen,
1805 					IPSEC_ULPROTO_ANY);
1806 	} else {
1807 		idsrc = vdup(iph2->id);
1808 	}
1809 	if (idsrc == NULL) {
1810 		plog(LLV_ERROR, LOCATION, NULL,
1811 			"failed to set ID for source.\n");
1812 		goto end;
1813 	}
1814 
1815 	if (iph2->id == NULL) {
1816 		switch (iph2->dst->sa_family) {
1817 		case AF_INET:
1818 			prefixlen = sizeof(struct in_addr) << 3;
1819 			break;
1820 		case AF_INET6:
1821 			prefixlen = sizeof(struct in6_addr) << 3;
1822 			break;
1823 		default:
1824 			plog(LLV_ERROR, LOCATION, NULL,
1825 				"invalid family: %d\n", iph2->dst->sa_family);
1826 			goto end;
1827 		}
1828 		iddst = ipsecdoi_sockaddr2id(iph2->dst, prefixlen,
1829 					IPSEC_ULPROTO_ANY);
1830 	} else {
1831 		iddst = vdup(iph2->id_p);
1832 	}
1833 	if (iddst == NULL) {
1834 		plog(LLV_ERROR, LOCATION, NULL,
1835 			"failed to set ID for destination.\n");
1836 		goto end;
1837 	}
1838 
1839 	iph2->sainfo = getsainfo(idsrc, iddst, iph2->ph1->id_p);
1840 	if (iph2->sainfo == NULL) {
1841 		plog(LLV_ERROR, LOCATION, NULL,
1842 			"failed to get sainfo.\n");
1843 		goto end;
1844 	}
1845 
1846 	plog(LLV_DEBUG, LOCATION, NULL,
1847 		"get sa info: %s\n", sainfo2str(iph2->sainfo));
1848 
1849 	error = 0;
1850 end:
1851 	if (idsrc)
1852 		vfree(idsrc);
1853 	if (iddst)
1854 		vfree(iddst);
1855 
1856 	return error;
1857 }
1858 
1859 /*
1860  * Copy both IP addresses in ID payloads into [src,dst]_id if both ID types
1861  * are IP address and same address family.
1862  * Then get remote's policy from SPD copied from kernel.
1863  * If the type of ID payload is address or subnet type, then the index is
1864  * made from the payload.  If there is no ID payload, or the type of ID
1865  * payload is NOT address type, then the index is made from the address
1866  * pair of phase 1.
1867  * NOTE: This function is only for responder.
1868  */
1869 static int
1870 get_proposal_r(iph2)
1871 	struct ph2handle *iph2;
1872 {
1873 	struct policyindex spidx;
1874 	struct secpolicy *sp_in, *sp_out;
1875 	int idi2type = 0;	/* switch whether copy IDs into id[src,dst]. */
1876 	int error = ISAKMP_INTERNAL_ERROR;
1877 
1878 	/* check the existence of ID payload */
1879 	if ((iph2->id_p != NULL && iph2->id == NULL)
1880 	 || (iph2->id_p == NULL && iph2->id != NULL)) {
1881 		plog(LLV_ERROR, LOCATION, NULL,
1882 			"Both IDs wasn't found in payload.\n");
1883 		return ISAKMP_NTYPE_INVALID_ID_INFORMATION;
1884 	}
1885 
1886 	/* make sure if id[src,dst] is null. */
1887 	if (iph2->src_id || iph2->dst_id) {
1888 		plog(LLV_ERROR, LOCATION, NULL,
1889 			"Why do ID[src,dst] exist already.\n");
1890 		return ISAKMP_INTERNAL_ERROR;
1891 	}
1892 
1893 	memset(&spidx, 0, sizeof(spidx));
1894 
1895 #define _XIDT(d) ((struct ipsecdoi_id_b *)(d)->v)->type
1896 
1897 	/* make a spidx; a key to search SPD */
1898 	spidx.dir = IPSEC_DIR_INBOUND;
1899 	spidx.ul_proto = 0;
1900 
1901 	/*
1902 	 * make destination address in spidx from either ID payload
1903 	 * or phase 1 address into a address in spidx.
1904 	 */
1905 	if (iph2->id != NULL
1906 	 && (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
1907 	  || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR
1908 	  || _XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR_SUBNET
1909 	  || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
1910 		/* get a destination address of a policy */
1911 		error = ipsecdoi_id2sockaddr(iph2->id,
1912 				(struct sockaddr *)&spidx.dst,
1913 				&spidx.prefd, &spidx.ul_proto);
1914 		if (error)
1915 			return error;
1916 
1917 #ifdef INET6
1918 		/*
1919 		 * get scopeid from the SA address.
1920 		 * note that the phase 1 source address is used as
1921 		 * a destination address to search for a inbound policy entry
1922 		 * because rcoon is responder.
1923 		 */
1924 		if (_XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR) {
1925 			error = setscopeid((struct sockaddr *)&spidx.dst,
1926 			                    iph2->src);
1927 			if (error)
1928 				return error;
1929 		}
1930 #endif
1931 
1932 		if (_XIDT(iph2->id) == IPSECDOI_ID_IPV4_ADDR
1933 		 || _XIDT(iph2->id) == IPSECDOI_ID_IPV6_ADDR)
1934 			idi2type = _XIDT(iph2->id);
1935 
1936 	} else {
1937 
1938 		plog(LLV_DEBUG, LOCATION, NULL,
1939 			"get a destination address of SP index "
1940 			"from phase1 address "
1941 			"due to no ID payloads found "
1942 			"OR because ID type is not address.\n");
1943 
1944 		/*
1945 		 * copy the SOURCE address of IKE into the DESTINATION address
1946 		 * of the key to search the SPD because the direction of policy
1947 		 * is inbound.
1948 		 */
1949 		memcpy(&spidx.dst, iph2->src, sysdep_sa_len(iph2->src));
1950 		switch (spidx.dst.ss_family) {
1951 		case AF_INET:
1952 			spidx.prefd = sizeof(struct in_addr) << 3;
1953 			break;
1954 #ifdef INET6
1955 		case AF_INET6:
1956 			spidx.prefd = sizeof(struct in6_addr) << 3;
1957 			break;
1958 #endif
1959 		default:
1960 			spidx.prefd = 0;
1961 			break;
1962 		}
1963 	}
1964 
1965 	/* make source address in spidx */
1966 	if (iph2->id_p != NULL
1967 	 && (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR
1968 	  || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR
1969 	  || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV4_ADDR_SUBNET
1970 	  || _XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR_SUBNET)) {
1971 		/* get a source address of inbound SA */
1972 		error = ipsecdoi_id2sockaddr(iph2->id_p,
1973 				(struct sockaddr *)&spidx.src,
1974 				&spidx.prefs, &spidx.ul_proto);
1975 		if (error)
1976 			return error;
1977 
1978 #ifdef INET6
1979 		/*
1980 		 * get scopeid from the SA address.
1981 		 * for more detail, see above of this function.
1982 		 */
1983 		if (_XIDT(iph2->id_p) == IPSECDOI_ID_IPV6_ADDR) {
1984 			error = setscopeid((struct sockaddr *)&spidx.src,
1985 			                    iph2->dst);
1986 			if (error)
1987 				return error;
1988 		}
1989 #endif
1990 
1991 		/* make id[src,dst] if both ID types are IP address and same */
1992 		if (_XIDT(iph2->id_p) == idi2type
1993 		 && spidx.dst.ss_family == spidx.src.ss_family) {
1994 			iph2->src_id = dupsaddr((struct sockaddr *)&spidx.dst);
1995 			iph2->dst_id = dupsaddr((struct sockaddr *)&spidx.src);
1996 		}
1997 
1998 	} else {
1999 		plog(LLV_DEBUG, LOCATION, NULL,
2000 			"get a source address of SP index "
2001 			"from phase1 address "
2002 			"due to no ID payloads found "
2003 			"OR because ID type is not address.\n");
2004 
2005 		/* see above comment. */
2006 		memcpy(&spidx.src, iph2->dst, sysdep_sa_len(iph2->dst));
2007 		switch (spidx.src.ss_family) {
2008 		case AF_INET:
2009 			spidx.prefs = sizeof(struct in_addr) << 3;
2010 			break;
2011 #ifdef INET6
2012 		case AF_INET6:
2013 			spidx.prefs = sizeof(struct in6_addr) << 3;
2014 			break;
2015 #endif
2016 		default:
2017 			spidx.prefs = 0;
2018 			break;
2019 		}
2020 	}
2021 
2022 #undef _XIDT
2023 
2024 	plog(LLV_DEBUG, LOCATION, NULL,
2025 		"get a src address from ID payload "
2026 		"%s prefixlen=%u ul_proto=%u\n",
2027 		saddr2str((struct sockaddr *)&spidx.src),
2028 		spidx.prefs, spidx.ul_proto);
2029 	plog(LLV_DEBUG, LOCATION, NULL,
2030 		"get dst address from ID payload "
2031 		"%s prefixlen=%u ul_proto=%u\n",
2032 		saddr2str((struct sockaddr *)&spidx.dst),
2033 		spidx.prefd, spidx.ul_proto);
2034 
2035 	/*
2036 	 * convert the ul_proto if it is 0
2037 	 * because 0 in ID payload means a wild card.
2038 	 */
2039 	if (spidx.ul_proto == 0)
2040 		spidx.ul_proto = IPSEC_ULPROTO_ANY;
2041 
2042 	/* get inbound policy */
2043 	sp_in = getsp_r(&spidx);
2044 	if (sp_in == NULL) {
2045 		if (iph2->ph1->rmconf->gen_policy) {
2046 			plog(LLV_INFO, LOCATION, NULL,
2047 				"no policy found, "
2048 				"try to generate the policy : %s\n",
2049 				spidx2str(&spidx));
2050 			iph2->spidx_gen = racoon_malloc(sizeof(spidx));
2051 			if (!iph2->spidx_gen) {
2052 				plog(LLV_ERROR, LOCATION, NULL,
2053 					"buffer allocation failed.\n");
2054 				return ISAKMP_INTERNAL_ERROR;
2055 			}
2056 			memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
2057 			return -2;	/* special value */
2058 		}
2059 		plog(LLV_ERROR, LOCATION, NULL,
2060 			"no policy found: %s\n", spidx2str(&spidx));
2061 		return ISAKMP_INTERNAL_ERROR;
2062 	}
2063 	/* Refresh existing generated policies
2064 	 */
2065 	if (iph2->ph1->rmconf->gen_policy) {
2066 		plog(LLV_INFO, LOCATION, NULL,
2067 			 "Update the generated policy : %s\n",
2068 			 spidx2str(&spidx));
2069 		iph2->spidx_gen = racoon_malloc(sizeof(spidx));
2070 		if (!iph2->spidx_gen) {
2071 			plog(LLV_ERROR, LOCATION, NULL,
2072 				 "buffer allocation failed.\n");
2073 			return ISAKMP_INTERNAL_ERROR;
2074 		}
2075 		memcpy(iph2->spidx_gen, &spidx, sizeof(spidx));
2076 	}
2077 
2078 	/* get outbound policy */
2079     {
2080 	struct sockaddr_storage addr;
2081 	u_int8_t pref;
2082 
2083 	spidx.dir = IPSEC_DIR_OUTBOUND;
2084 	addr = spidx.src;
2085 	spidx.src = spidx.dst;
2086 	spidx.dst = addr;
2087 	pref = spidx.prefs;
2088 	spidx.prefs = spidx.prefd;
2089 	spidx.prefd = pref;
2090 
2091 	sp_out = getsp_r(&spidx);
2092 	if (!sp_out) {
2093 		plog(LLV_WARNING, LOCATION, NULL,
2094 			"no outbound policy found: %s\n",
2095 			spidx2str(&spidx));
2096 	}
2097     }
2098 
2099 	plog(LLV_DEBUG, LOCATION, NULL,
2100 		"suitable SP found:%s\n", spidx2str(&spidx));
2101 
2102 	/*
2103 	 * In the responder side, the inbound policy should be using IPsec.
2104 	 * outbound policy is not checked currently.
2105 	 */
2106 	if (sp_in->policy != IPSEC_POLICY_IPSEC) {
2107 		plog(LLV_ERROR, LOCATION, NULL,
2108 			"policy found, but no IPsec required: %s\n",
2109 			spidx2str(&spidx));
2110 		return ISAKMP_INTERNAL_ERROR;
2111 	}
2112 
2113 	/* set new proposal derived from a policy into the iph2->proposal. */
2114 	if (set_proposal_from_policy(iph2, sp_in, sp_out) < 0) {
2115 		plog(LLV_ERROR, LOCATION, NULL,
2116 			"failed to create saprop.\n");
2117 		return ISAKMP_INTERNAL_ERROR;
2118 	}
2119 
2120 	return 0;
2121 }
2122