xref: /netbsd-src/crypto/dist/ipsec-tools/src/racoon/isakmp_base.c (revision ce666bb8ce77792a3948ca697c2fdad578a542a7)
1 /*	$NetBSD: isakmp_base.c,v 1.5 2005/11/21 14:20:29 manu Exp $	*/
2 
3 /*	$KAME: isakmp_base.c,v 1.49 2003/11/13 02:30:20 sakane 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 /* Base Exchange (Base Mode) */
35 
36 #include "config.h"
37 
38 #include <sys/types.h>
39 #include <sys/param.h>
40 
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <errno.h>
45 #if TIME_WITH_SYS_TIME
46 # include <sys/time.h>
47 # include <time.h>
48 #else
49 # if HAVE_SYS_TIME_H
50 #  include <sys/time.h>
51 # else
52 #  include <time.h>
53 # endif
54 #endif
55 
56 #include "var.h"
57 #include "misc.h"
58 #include "vmbuf.h"
59 #include "plog.h"
60 #include "sockmisc.h"
61 #include "schedule.h"
62 #include "debug.h"
63 
64 #include "localconf.h"
65 #include "remoteconf.h"
66 #include "isakmp_var.h"
67 #include "isakmp.h"
68 #include "evt.h"
69 #include "oakley.h"
70 #include "handler.h"
71 #include "ipsec_doi.h"
72 #include "crypto_openssl.h"
73 #include "pfkey.h"
74 #include "isakmp_base.h"
75 #include "isakmp_inf.h"
76 #include "vendorid.h"
77 #ifdef ENABLE_NATT
78 #include "nattraversal.h"
79 #endif
80 #ifdef ENABLE_FRAG
81 #include "isakmp_frag.h"
82 #endif
83 
84 /* %%%
85  * begin Identity Protection Mode as initiator.
86  */
87 /*
88  * send to responder
89  * 	psk: HDR, SA, Idii, Ni_b
90  * 	sig: HDR, SA, Idii, Ni_b
91  * 	rsa: HDR, SA, [HASH(1),] <IDii_b>Pubkey_r, <Ni_b>Pubkey_r
92  * 	rev: HDR, SA, [HASH(1),] <Ni_b>Pubkey_r, <IDii_b>Ke_i
93  */
94 int
95 base_i1send(iph1, msg)
96 	struct ph1handle *iph1;
97 	vchar_t *msg; /* must be null */
98 {
99 	struct payload_list *plist = NULL;
100 	int error = -1;
101 #ifdef ENABLE_NATT
102 	vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
103 	int i, vid_natt_i = 0;
104 #endif
105 #ifdef ENABLE_FRAG
106 	vchar_t *vid_frag = NULL;
107 #endif
108 
109 	/* validity check */
110 	if (msg != NULL) {
111 		plog(LLV_ERROR, LOCATION, NULL,
112 			"msg has to be NULL in this function.\n");
113 		goto end;
114 	}
115 	if (iph1->status != PHASE1ST_START) {
116 		plog(LLV_ERROR, LOCATION, NULL,
117 			"status mismatched %d.\n", iph1->status);
118 		goto end;
119 	}
120 
121 	/* create isakmp index */
122 	memset(&iph1->index, 0, sizeof(iph1->index));
123 	isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
124 
125 	/* make ID payload into isakmp status */
126 	if (ipsecdoi_setid1(iph1) < 0)
127 		goto end;
128 
129 	/* create SA payload for my proposal */
130 	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
131 	if (iph1->sa == NULL)
132 		goto end;
133 
134 	/* generate NONCE value */
135 	iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
136 	if (iph1->nonce == NULL)
137 		goto end;
138 
139 #ifdef ENABLE_FRAG
140 	if (iph1->rmconf->ike_frag) {
141 		vid_frag = set_vendorid(VENDORID_FRAG);
142 		if (vid_frag != NULL)
143 			vid_frag = isakmp_frag_addcap(vid_frag,
144 			    VENDORID_FRAG_BASE);
145 		if (vid_frag == NULL)
146 			plog(LLV_ERROR, LOCATION, NULL,
147 			    "Frag vendorID construction failed\n");
148 	}
149 #endif
150 #ifdef ENABLE_NATT
151 	/* Is NAT-T support allowed in the config file? */
152 	if (iph1->rmconf->nat_traversal) {
153 		/* Advertise NAT-T capability */
154 		memset (vid_natt, 0, sizeof (vid_natt));
155 #ifdef VENDORID_NATT_00
156 		if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL)
157 			vid_natt_i++;
158 #endif
159 #ifdef VENDORID_NATT_02
160 		if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL)
161 			vid_natt_i++;
162 #endif
163 #ifdef VENDORID_NATT_02_N
164 		if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL)
165 			vid_natt_i++;
166 #endif
167 #ifdef VENDORID_NATT_RFC
168 		if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL)
169 			vid_natt_i++;
170 #endif
171 	}
172 #endif
173 
174 	/* set SA payload to propose */
175 	plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
176 
177 	/* create isakmp ID payload */
178 	plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
179 
180 	/* create isakmp NONCE payload */
181 	plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
182 
183 #ifdef ENABLE_FRAG
184 	if (vid_frag)
185 		plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
186 #endif
187 #ifdef ENABLE_NATT
188 	/* set VID payload for NAT-T */
189 	for (i = 0; i < vid_natt_i; i++)
190 		plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID);
191 
192 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
193 #endif
194 
195 #ifdef HAVE_PRINT_ISAKMP_C
196 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
197 #endif
198 
199 	/* send the packet, add to the schedule to resend */
200 	iph1->retry_counter = iph1->rmconf->retry_counter;
201 	if (isakmp_ph1resend(iph1) == -1)
202 		goto end;
203 
204 	iph1->status = PHASE1ST_MSG1SENT;
205 
206 	error = 0;
207 
208 end:
209 #ifdef ENABLE_FRAG
210 	if (vid_frag)
211 		vfree(vid_frag);
212 #endif
213 #ifdef ENABLE_NATT
214 	for (i = 0; i < vid_natt_i; i++)
215 		vfree(vid_natt[i]);
216 #endif
217 
218 	return error;
219 }
220 
221 /*
222  * receive from responder
223  * 	psk: HDR, SA, Idir, Nr_b
224  * 	sig: HDR, SA, Idir, Nr_b, [ CR ]
225  * 	rsa: HDR, SA, <IDir_b>PubKey_i, <Nr_b>PubKey_i
226  * 	rev: HDR, SA, <Nr_b>PubKey_i, <IDir_b>Ke_r
227  */
228 int
229 base_i2recv(iph1, msg)
230 	struct ph1handle *iph1;
231 	vchar_t *msg;
232 {
233 	vchar_t *pbuf = NULL;
234 	struct isakmp_parse_t *pa;
235 	vchar_t *satmp = NULL;
236 	int error = -1;
237 	int vid_numeric;
238 
239 	/* validity check */
240 	if (iph1->status != PHASE1ST_MSG1SENT) {
241 		plog(LLV_ERROR, LOCATION, NULL,
242 			"status mismatched %d.\n", iph1->status);
243 		goto end;
244 	}
245 
246 	/* validate the type of next payload */
247 	pbuf = isakmp_parse(msg);
248 	if (pbuf == NULL)
249 		goto end;
250 	pa = (struct isakmp_parse_t *)pbuf->v;
251 
252 	/* SA payload is fixed postion */
253 	if (pa->type != ISAKMP_NPTYPE_SA) {
254 		plog(LLV_ERROR, LOCATION, iph1->remote,
255 			"received invalid next payload type %d, "
256 			"expecting %d.\n",
257 			pa->type, ISAKMP_NPTYPE_SA);
258 		goto end;
259 	}
260 	if (isakmp_p2ph(&satmp, pa->ptr) < 0)
261 		goto end;
262 	pa++;
263 
264 	for (/*nothing*/;
265 	     pa->type != ISAKMP_NPTYPE_NONE;
266 	     pa++) {
267 
268 		switch (pa->type) {
269 		case ISAKMP_NPTYPE_NONCE:
270 			if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
271 				goto end;
272 			break;
273 		case ISAKMP_NPTYPE_ID:
274 			if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
275 				goto end;
276 			break;
277 		case ISAKMP_NPTYPE_VID:
278 			vid_numeric = check_vendorid(pa->ptr);
279 #ifdef ENABLE_NATT
280 			if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
281 			  natt_handle_vendorid(iph1, vid_numeric);
282 #endif
283 			break;
284 		default:
285 			/* don't send information, see ident_r1recv() */
286 			plog(LLV_ERROR, LOCATION, iph1->remote,
287 				"ignore the packet, "
288 				"received unexpecting payload type %d.\n",
289 				pa->type);
290 			goto end;
291 		}
292 	}
293 
294 	if (iph1->nonce_p == NULL || iph1->id_p == NULL) {
295 		plog(LLV_ERROR, LOCATION, iph1->remote,
296 			"few isakmp message received.\n");
297 		goto end;
298 	}
299 
300 	/* verify identifier */
301 	if (ipsecdoi_checkid1(iph1) != 0) {
302 		plog(LLV_ERROR, LOCATION, iph1->remote,
303 			"invalid ID payload.\n");
304 		goto end;
305 	}
306 
307 #ifdef ENABLE_NATT
308 	if (NATT_AVAILABLE(iph1))
309 		plog(LLV_INFO, LOCATION, iph1->remote,
310 		     "Selected NAT-T version: %s\n",
311 		     vid_string_by_id(iph1->natt_options->version));
312 #endif
313 
314 	/* check SA payload and set approval SA for use */
315 	if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
316 		plog(LLV_ERROR, LOCATION, iph1->remote,
317 			"failed to get valid proposal.\n");
318 		/* XXX send information */
319 		goto end;
320 	}
321 	VPTRINIT(iph1->sa_ret);
322 
323 	iph1->status = PHASE1ST_MSG2RECEIVED;
324 
325 	error = 0;
326 
327 end:
328 	if (pbuf)
329 		vfree(pbuf);
330 	if (satmp)
331 		vfree(satmp);
332 
333 	if (error) {
334 		VPTRINIT(iph1->nonce_p);
335 		VPTRINIT(iph1->id_p);
336 	}
337 
338 	return error;
339 }
340 
341 /*
342  * send to responder
343  * 	psk: HDR, KE, HASH_I
344  * 	sig: HDR, KE, [ CR, ] [CERT,] SIG_I
345  * 	rsa: HDR, KE, HASH_I
346  * 	rev: HDR, <KE>Ke_i, HASH_I
347  */
348 int
349 base_i2send(iph1, msg)
350 	struct ph1handle *iph1;
351 	vchar_t *msg;
352 {
353 	struct payload_list *plist = NULL;
354 	vchar_t *vid = NULL;
355 	int need_cert = 0;
356 	int error = -1;
357 
358 	/* validity check */
359 	if (iph1->status != PHASE1ST_MSG2RECEIVED) {
360 		plog(LLV_ERROR, LOCATION, NULL,
361 			"status mismatched %d.\n", iph1->status);
362 		goto end;
363 	}
364 
365 	/* fix isakmp index */
366 	memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
367 		sizeof(cookie_t));
368 
369 	/* generate DH public value */
370 	if (oakley_dh_generate(iph1->approval->dhgrp,
371 				&iph1->dhpub, &iph1->dhpriv) < 0)
372 		goto end;
373 
374 	/* generate SKEYID to compute hash if not signature mode */
375 	if (iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_RSASIG
376 	 && iph1->approval->authmethod != OAKLEY_ATTR_AUTH_METHOD_DSSSIG) {
377 		if (oakley_skeyid(iph1) < 0)
378 			goto end;
379 	}
380 
381 	/* generate HASH to send */
382 	plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
383 	iph1->hash = oakley_ph1hash_base_i(iph1, GENERATE);
384 	if (iph1->hash == NULL)
385 		goto end;
386 
387 	switch (iph1->approval->authmethod) {
388 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
389 		vid = set_vendorid(iph1->approval->vendorid);
390 
391 		/* create isakmp KE payload */
392 		plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
393 
394 		/* create isakmp HASH payload */
395 		plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
396 
397 		/* append vendor id, if needed */
398 		if (vid)
399 			plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
400 		break;
401 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
402 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
403 		/* XXX if there is CR or not ? */
404 
405 		if (oakley_getmycert(iph1) < 0)
406 			goto end;
407 
408 		if (oakley_getsign(iph1) < 0)
409 			goto end;
410 
411 		if (iph1->cert && iph1->rmconf->send_cert)
412 			need_cert = 1;
413 
414 		/* create isakmp KE payload */
415 		plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
416 
417 		/* add CERT payload if there */
418 		if (need_cert)
419 			plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
420 
421 		/* add SIG payload */
422 		plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
423 		break;
424 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
425 		/* ... */
426 		break;
427 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
428 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
429 		break;
430 	default:
431 		plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n",
432 			iph1->approval->authmethod);
433 		goto end;
434 		break;
435 	}
436 
437 #ifdef ENABLE_NATT
438 	/* generate NAT-D payloads */
439 	if (NATT_AVAILABLE(iph1))
440 	{
441 		vchar_t *natd[2] = { NULL, NULL };
442 
443 		plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
444 		if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
445 			plog(LLV_ERROR, LOCATION, NULL,
446 				"NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
447 			goto end;
448 		}
449 
450 		if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
451 			plog(LLV_ERROR, LOCATION, NULL,
452 				"NAT-D hashing failed for %s\n", saddr2str(iph1->local));
453 			goto end;
454 		}
455 
456 		plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
457 		plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
458 	}
459 #endif
460 
461 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
462 
463 #ifdef HAVE_PRINT_ISAKMP_C
464 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
465 #endif
466 
467 	/* send the packet, add to the schedule to resend */
468 	iph1->retry_counter = iph1->rmconf->retry_counter;
469 	if (isakmp_ph1resend(iph1) == -1)
470 		goto end;
471 
472 	/* the sending message is added to the received-list. */
473 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
474 		plog(LLV_ERROR , LOCATION, NULL,
475 			"failed to add a response packet to the tree.\n");
476 		goto end;
477 	}
478 
479 	iph1->status = PHASE1ST_MSG2SENT;
480 
481 	error = 0;
482 
483 end:
484 	if (vid)
485 		vfree(vid);
486 	return error;
487 }
488 
489 /*
490  * receive from responder
491  * 	psk: HDR, KE, HASH_R
492  * 	sig: HDR, KE, [CERT,] SIG_R
493  * 	rsa: HDR, KE, HASH_R
494  * 	rev: HDR, <KE>_Ke_r, HASH_R
495  */
496 int
497 base_i3recv(iph1, msg)
498 	struct ph1handle *iph1;
499 	vchar_t *msg;
500 {
501 	vchar_t *pbuf = NULL;
502 	struct isakmp_parse_t *pa;
503 	int error = -1;
504 	int ptype;
505 #ifdef ENABLE_NATT
506 	vchar_t	*natd_received;
507 	int natd_seq = 0, natd_verified;
508 #endif
509 
510 	/* validity check */
511 	if (iph1->status != PHASE1ST_MSG2SENT) {
512 		plog(LLV_ERROR, LOCATION, NULL,
513 			"status mismatched %d.\n", iph1->status);
514 		goto end;
515 	}
516 
517 	/* validate the type of next payload */
518 	pbuf = isakmp_parse(msg);
519 	if (pbuf == NULL)
520 		goto end;
521 
522 	for (pa = (struct isakmp_parse_t *)pbuf->v;
523 	     pa->type != ISAKMP_NPTYPE_NONE;
524 	     pa++) {
525 
526 		switch (pa->type) {
527 		case ISAKMP_NPTYPE_KE:
528 			if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
529 				goto end;
530 			break;
531 		case ISAKMP_NPTYPE_HASH:
532 			iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
533 			break;
534 		case ISAKMP_NPTYPE_CERT:
535 			if (oakley_savecert(iph1, pa->ptr) < 0)
536 				goto end;
537 			break;
538 		case ISAKMP_NPTYPE_SIG:
539 			if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
540 				goto end;
541 			break;
542 		case ISAKMP_NPTYPE_VID:
543 			(void)check_vendorid(pa->ptr);
544 			break;
545 
546 #ifdef ENABLE_NATT
547 		case ISAKMP_NPTYPE_NATD_DRAFT:
548 		case ISAKMP_NPTYPE_NATD_RFC:
549 			if (NATT_AVAILABLE(iph1) && iph1->natt_options &&
550 			    pa->type == iph1->natt_options->payload_nat_d) {
551 				natd_received = NULL;
552 				if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
553 					goto end;
554 
555 				/* set both bits first so that we can clear them
556 				   upon verifying hashes */
557 				if (natd_seq == 0)
558 					iph1->natt_flags |= NAT_DETECTED;
559 
560 				/* this function will clear appropriate bits bits
561 				   from iph1->natt_flags */
562 				natd_verified = natt_compare_addr_hash (iph1,
563 					natd_received, natd_seq++);
564 
565 				plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
566 					natd_seq - 1,
567 					natd_verified ? "verified" : "doesn't match");
568 
569 				vfree (natd_received);
570 				break;
571 			}
572 			/* passthrough to default... */
573 #endif
574 
575 		default:
576 			/* don't send information, see ident_r1recv() */
577 			plog(LLV_ERROR, LOCATION, iph1->remote,
578 				"ignore the packet, "
579 				"received unexpecting payload type %d.\n",
580 				pa->type);
581 			goto end;
582 		}
583 	}
584 
585 #ifdef ENABLE_NATT
586 	if (NATT_AVAILABLE(iph1)) {
587 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
588 		      iph1->natt_flags & NAT_DETECTED ?
589 		      		"detected:" : "not detected",
590 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
591 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
592 		if (iph1->natt_flags & NAT_DETECTED)
593 			natt_float_ports (iph1);
594 	}
595 #endif
596 
597 	/* payload existency check */
598 	/* validate authentication value */
599 	ptype = oakley_validate_auth(iph1);
600 	if (ptype != 0) {
601 		if (ptype == -1) {
602 			/* message printed inner oakley_validate_auth() */
603 			goto end;
604 		}
605 		EVT_PUSH(iph1->local, iph1->remote,
606 		    EVTT_PEERPH1AUTH_FAILED, NULL);
607 		isakmp_info_send_n1(iph1, ptype, NULL);
608 		goto end;
609 	}
610 
611 	/* compute sharing secret of DH */
612 	if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
613 				iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
614 		goto end;
615 
616 	/* generate SKEYID to compute hash if signature mode */
617 	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_RSASIG
618 	 || iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_DSSSIG) {
619 		if (oakley_skeyid(iph1) < 0)
620 			goto end;
621 	}
622 
623 	/* generate SKEYIDs & IV & final cipher key */
624 	if (oakley_skeyid_dae(iph1) < 0)
625 		goto end;
626 	if (oakley_compute_enckey(iph1) < 0)
627 		goto end;
628 	if (oakley_newiv(iph1) < 0)
629 		goto end;
630 
631 	/* see handler.h about IV synchronization. */
632 	memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
633 
634 	/* set encryption flag */
635 	iph1->flags |= ISAKMP_FLAG_E;
636 
637 	iph1->status = PHASE1ST_MSG3RECEIVED;
638 
639 	error = 0;
640 
641 end:
642 	if (pbuf)
643 		vfree(pbuf);
644 
645 	if (error) {
646 		VPTRINIT(iph1->dhpub_p);
647 		oakley_delcert(iph1->cert_p);
648 		iph1->cert_p = NULL;
649 		oakley_delcert(iph1->crl_p);
650 		iph1->crl_p = NULL;
651 		VPTRINIT(iph1->sig_p);
652 	}
653 
654 	return error;
655 }
656 
657 /*
658  * status update and establish isakmp sa.
659  */
660 int
661 base_i3send(iph1, msg)
662 	struct ph1handle *iph1;
663 	vchar_t *msg;
664 {
665 	int error = -1;
666 
667 	/* validity check */
668 	if (iph1->status != PHASE1ST_MSG3RECEIVED) {
669 		plog(LLV_ERROR, LOCATION, NULL,
670 			"status mismatched %d.\n", iph1->status);
671 		goto end;
672 	}
673 
674 	iph1->status = PHASE1ST_ESTABLISHED;
675 
676 	error = 0;
677 
678 end:
679 	return error;
680 }
681 
682 /*
683  * receive from initiator
684  * 	psk: HDR, SA, Idii, Ni_b
685  * 	sig: HDR, SA, Idii, Ni_b
686  * 	rsa: HDR, SA, [HASH(1),] <IDii_b>Pubkey_r, <Ni_b>Pubkey_r
687  * 	rev: HDR, SA, [HASH(1),] <Ni_b>Pubkey_r, <IDii_b>Ke_i
688  */
689 int
690 base_r1recv(iph1, msg)
691 	struct ph1handle *iph1;
692 	vchar_t *msg;
693 {
694 	vchar_t *pbuf = NULL;
695 	struct isakmp_parse_t *pa;
696 	int error = -1;
697 	int vid_numeric;
698 
699 	/* validity check */
700 	if (iph1->status != PHASE1ST_START) {
701 		plog(LLV_ERROR, LOCATION, NULL,
702 			"status mismatched %d.\n", iph1->status);
703 		goto end;
704 	}
705 
706 	/* validate the type of next payload */
707 	/*
708 	 * NOTE: XXX even if multiple VID, we'll silently ignore those.
709 	 */
710 	pbuf = isakmp_parse(msg);
711 	if (pbuf == NULL)
712 		goto end;
713 	pa = (struct isakmp_parse_t *)pbuf->v;
714 
715 	/* check the position of SA payload */
716 	if (pa->type != ISAKMP_NPTYPE_SA) {
717 		plog(LLV_ERROR, LOCATION, iph1->remote,
718 			"received invalid next payload type %d, "
719 			"expecting %d.\n",
720 			pa->type, ISAKMP_NPTYPE_SA);
721 		goto end;
722 	}
723 	if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
724 		goto end;
725 	pa++;
726 
727 	for (/*nothing*/;
728 	     pa->type != ISAKMP_NPTYPE_NONE;
729 	     pa++) {
730 
731 		switch (pa->type) {
732 		case ISAKMP_NPTYPE_NONCE:
733 			if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
734 				goto end;
735 			break;
736 		case ISAKMP_NPTYPE_ID:
737 			if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
738 				goto end;
739 			break;
740 		case ISAKMP_NPTYPE_VID:
741 			vid_numeric = check_vendorid(pa->ptr);
742 #ifdef ENABLE_NATT
743 			if (iph1->rmconf->nat_traversal && natt_vendorid(vid_numeric))
744 				natt_handle_vendorid(iph1, vid_numeric);
745 #endif
746 #ifdef ENABLE_FRAG
747 			if ((vid_numeric == VENDORID_FRAG) &&
748 			    (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_BASE))
749 				iph1->frag = 1;
750 #endif
751 			break;
752 		default:
753 			/* don't send information, see ident_r1recv() */
754 			plog(LLV_ERROR, LOCATION, iph1->remote,
755 				"ignore the packet, "
756 				"received unexpecting payload type %d.\n",
757 				pa->type);
758 			goto end;
759 		}
760 	}
761 
762 	if (iph1->nonce_p == NULL || iph1->id_p == NULL) {
763 		plog(LLV_ERROR, LOCATION, iph1->remote,
764 			"few isakmp message received.\n");
765 		goto end;
766 	}
767 
768 	/* verify identifier */
769 	if (ipsecdoi_checkid1(iph1) != 0) {
770 		plog(LLV_ERROR, LOCATION, iph1->remote,
771 			"invalid ID payload.\n");
772 		goto end;
773 	}
774 
775 #ifdef ENABLE_NATT
776 	if (NATT_AVAILABLE(iph1))
777 		plog(LLV_INFO, LOCATION, iph1->remote,
778 		     "Selected NAT-T version: %s\n",
779 		     vid_string_by_id(iph1->natt_options->version));
780 #endif
781 
782 	/* check SA payload and set approval SA for use */
783 	if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
784 		plog(LLV_ERROR, LOCATION, iph1->remote,
785 			"failed to get valid proposal.\n");
786 		/* XXX send information */
787 		goto end;
788 	}
789 
790 	iph1->status = PHASE1ST_MSG1RECEIVED;
791 
792 	error = 0;
793 
794 end:
795 	if (pbuf)
796 		vfree(pbuf);
797 
798 	if (error) {
799 		VPTRINIT(iph1->sa);
800 		VPTRINIT(iph1->nonce_p);
801 		VPTRINIT(iph1->id_p);
802 	}
803 
804 	return error;
805 }
806 
807 /*
808  * send to initiator
809  * 	psk: HDR, SA, Idir, Nr_b
810  * 	sig: HDR, SA, Idir, Nr_b, [ CR ]
811  * 	rsa: HDR, SA, <IDir_b>PubKey_i, <Nr_b>PubKey_i
812  * 	rev: HDR, SA, <Nr_b>PubKey_i, <IDir_b>Ke_r
813  */
814 int
815 base_r1send(iph1, msg)
816 	struct ph1handle *iph1;
817 	vchar_t *msg;
818 {
819 	struct payload_list *plist = NULL;
820 	int error = -1;
821 #ifdef ENABLE_NATT
822 	vchar_t *vid_natt = NULL;
823 #endif
824 
825 	/* validity check */
826 	if (iph1->status != PHASE1ST_MSG1RECEIVED) {
827 		plog(LLV_ERROR, LOCATION, NULL,
828 			"status mismatched %d.\n", iph1->status);
829 		goto end;
830 	}
831 
832 	/* set responder's cookie */
833 	isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
834 
835 	/* make ID payload into isakmp status */
836 	if (ipsecdoi_setid1(iph1) < 0)
837 		goto end;
838 
839 	/* generate NONCE value */
840 	iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
841 	if (iph1->nonce == NULL)
842 		goto end;
843 
844 	/* set SA payload to reply */
845 	plist = isakmp_plist_append(plist, iph1->sa_ret, ISAKMP_NPTYPE_SA);
846 
847 	/* create isakmp ID payload */
848 	plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
849 
850 	/* create isakmp NONCE payload */
851 	plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
852 
853 #ifdef ENABLE_NATT
854 	/* has the peer announced nat-t? */
855 	if (NATT_AVAILABLE(iph1))
856 		vid_natt = set_vendorid(iph1->natt_options->version);
857 	if (vid_natt)
858 		plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
859 #endif
860 
861 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
862 
863 #ifdef HAVE_PRINT_ISAKMP_C
864 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
865 #endif
866 
867 	/* send the packet, add to the schedule to resend */
868 	iph1->retry_counter = iph1->rmconf->retry_counter;
869 	if (isakmp_ph1resend(iph1) == -1)
870 		goto end;
871 
872 	/* the sending message is added to the received-list. */
873 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
874 		plog(LLV_ERROR , LOCATION, NULL,
875 			"failed to add a response packet to the tree.\n");
876 		goto end;
877 	}
878 
879 	iph1->status = PHASE1ST_MSG1SENT;
880 
881 	error = 0;
882 
883 end:
884 #ifdef ENABLE_NATT
885 	if (vid_natt)
886 		vfree(vid_natt);
887 #endif
888 
889 	VPTRINIT(iph1->sa_ret);
890 
891 	return error;
892 }
893 
894 /*
895  * receive from initiator
896  * 	psk: HDR, KE, HASH_I
897  * 	sig: HDR, KE, [ CR, ] [CERT,] SIG_I
898  * 	rsa: HDR, KE, HASH_I
899  * 	rev: HDR, <KE>Ke_i, HASH_I
900  */
901 int
902 base_r2recv(iph1, msg)
903 	struct ph1handle *iph1;
904 	vchar_t *msg;
905 {
906 	vchar_t *pbuf = NULL;
907 	struct isakmp_parse_t *pa;
908 	int error = -1;
909 	int ptype;
910 #ifdef ENABLE_NATT
911 	int natd_seq = 0;
912 #endif
913 
914 	/* validity check */
915 	if (iph1->status != PHASE1ST_MSG1SENT) {
916 		plog(LLV_ERROR, LOCATION, NULL,
917 			"status mismatched %d.\n", iph1->status);
918 		goto end;
919 	}
920 
921 	/* validate the type of next payload */
922 	pbuf = isakmp_parse(msg);
923 	if (pbuf == NULL)
924 		goto end;
925 
926 	iph1->pl_hash = NULL;
927 
928 	for (pa = (struct isakmp_parse_t *)pbuf->v;
929 	     pa->type != ISAKMP_NPTYPE_NONE;
930 	     pa++) {
931 
932 		switch (pa->type) {
933 		case ISAKMP_NPTYPE_KE:
934 			if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
935 				goto end;
936 			break;
937 		case ISAKMP_NPTYPE_HASH:
938 			iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
939 			break;
940 		case ISAKMP_NPTYPE_CERT:
941 			if (oakley_savecert(iph1, pa->ptr) < 0)
942 				goto end;
943 			break;
944 		case ISAKMP_NPTYPE_SIG:
945 			if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
946 				goto end;
947 			break;
948 		case ISAKMP_NPTYPE_VID:
949 			(void)check_vendorid(pa->ptr);
950 			break;
951 
952 #ifdef ENABLE_NATT
953 		case ISAKMP_NPTYPE_NATD_DRAFT:
954 		case ISAKMP_NPTYPE_NATD_RFC:
955 			if (pa->type == iph1->natt_options->payload_nat_d)
956 			{
957 				vchar_t *natd_received = NULL;
958 				int natd_verified;
959 
960 				if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
961 					goto end;
962 
963 				if (natd_seq == 0)
964 					iph1->natt_flags |= NAT_DETECTED;
965 
966 				natd_verified = natt_compare_addr_hash (iph1,
967 					natd_received, natd_seq++);
968 
969 				plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
970 					natd_seq - 1,
971 					natd_verified ? "verified" : "doesn't match");
972 
973 				vfree (natd_received);
974 				break;
975 			}
976 			/* passthrough to default... */
977 #endif
978 
979 		default:
980 			/* don't send information, see ident_r1recv() */
981 			plog(LLV_ERROR, LOCATION, iph1->remote,
982 				"ignore the packet, "
983 				"received unexpecting payload type %d.\n",
984 				pa->type);
985 			goto end;
986 		}
987 	}
988 
989 	/* generate DH public value */
990 	if (oakley_dh_generate(iph1->approval->dhgrp,
991 				&iph1->dhpub, &iph1->dhpriv) < 0)
992 		goto end;
993 
994 	/* compute sharing secret of DH */
995 	if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
996 				iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
997 		goto end;
998 
999 	/* generate SKEYID */
1000 	if (oakley_skeyid(iph1) < 0)
1001 		goto end;
1002 
1003 #ifdef ENABLE_NATT
1004 	if (NATT_AVAILABLE(iph1))
1005 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
1006 		      iph1->natt_flags & NAT_DETECTED ?
1007 		      		"detected:" : "not detected",
1008 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
1009 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
1010 #endif
1011 
1012 	/* payload existency check */
1013 	/* validate authentication value */
1014 	ptype = oakley_validate_auth(iph1);
1015 	if (ptype != 0) {
1016 		if (ptype == -1) {
1017 			/* message printed inner oakley_validate_auth() */
1018 			goto end;
1019 		}
1020 		EVT_PUSH(iph1->local, iph1->remote,
1021 		    EVTT_PEERPH1AUTH_FAILED, NULL);
1022 		isakmp_info_send_n1(iph1, ptype, NULL);
1023 		goto end;
1024 	}
1025 
1026 	iph1->status = PHASE1ST_MSG2RECEIVED;
1027 
1028 	error = 0;
1029 
1030 end:
1031 	if (pbuf)
1032 		vfree(pbuf);
1033 
1034 	if (error) {
1035 		VPTRINIT(iph1->dhpub_p);
1036 		oakley_delcert(iph1->cert_p);
1037 		iph1->cert_p = NULL;
1038 		oakley_delcert(iph1->crl_p);
1039 		iph1->crl_p = NULL;
1040 		VPTRINIT(iph1->sig_p);
1041 	}
1042 
1043 	return error;
1044 }
1045 
1046 /*
1047  * send to initiator
1048  * 	psk: HDR, KE, HASH_R
1049  * 	sig: HDR, KE, [CERT,] SIG_R
1050  * 	rsa: HDR, KE, HASH_R
1051  * 	rev: HDR, <KE>_Ke_r, HASH_R
1052  */
1053 int
1054 base_r2send(iph1, msg)
1055 	struct ph1handle *iph1;
1056 	vchar_t *msg;
1057 {
1058 	struct payload_list *plist = NULL;
1059 	vchar_t *vid = NULL;
1060 	int need_cert = 0;
1061 	int error = -1;
1062 
1063 	/* validity check */
1064 	if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1065 		plog(LLV_ERROR, LOCATION, NULL,
1066 			"status mismatched %d.\n", iph1->status);
1067 		goto end;
1068 	}
1069 
1070 	/* generate HASH to send */
1071 	plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
1072 	switch (iph1->approval->authmethod) {
1073 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1074 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1075 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1076 		iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
1077 		break;
1078 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1079 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1080 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1081 		iph1->hash = oakley_ph1hash_base_r(iph1, GENERATE);
1082 		break;
1083 	default:
1084 		plog(LLV_ERROR, LOCATION, NULL,
1085 			"invalid authentication method %d\n",
1086 			iph1->approval->authmethod);
1087 		goto end;
1088 	}
1089 	if (iph1->hash == NULL)
1090 		goto end;
1091 
1092 	switch (iph1->approval->authmethod) {
1093 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1094 		vid = set_vendorid(iph1->approval->vendorid);
1095 
1096 		/* create isakmp KE payload */
1097 		plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
1098 
1099 		/* create isakmp HASH payload */
1100 		plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
1101 
1102 		/* append vendor id, if needed */
1103 		if (vid)
1104 			plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
1105 		break;
1106 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1107 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1108 		/* XXX if there is CR or not ? */
1109 
1110 		if (oakley_getmycert(iph1) < 0)
1111 			goto end;
1112 
1113 		if (oakley_getsign(iph1) < 0)
1114 			goto end;
1115 
1116 		if (iph1->cert && iph1->rmconf->send_cert)
1117 			need_cert = 1;
1118 
1119 		/* create isakmp KE payload */
1120 		plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
1121 
1122 		/* add CERT payload if there */
1123 		if (need_cert)
1124 			plist = isakmp_plist_append(plist, iph1->cert->pl, ISAKMP_NPTYPE_CERT);
1125 		/* add SIG payload */
1126 		plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
1127 		break;
1128 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1129 		/* ... */
1130 		break;
1131 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1132 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1133 		break;
1134 	default:
1135 		plog(LLV_ERROR, LOCATION, NULL, "invalid authmethod %d\n",
1136 			iph1->approval->authmethod);
1137 		goto end;
1138 		break;
1139 	}
1140 
1141 #ifdef ENABLE_NATT
1142 	/* generate NAT-D payloads */
1143 	if (NATT_AVAILABLE(iph1))
1144 	{
1145 		vchar_t *natd[2] = { NULL, NULL };
1146 
1147 		plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
1148 		if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
1149 			plog(LLV_ERROR, LOCATION, NULL,
1150 				"NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
1151 			goto end;
1152 		}
1153 
1154 		if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
1155 			plog(LLV_ERROR, LOCATION, NULL,
1156 				"NAT-D hashing failed for %s\n", saddr2str(iph1->local));
1157 			goto end;
1158 		}
1159 
1160 		plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
1161 		plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
1162 	}
1163 #endif
1164 
1165 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
1166 
1167 #ifdef HAVE_PRINT_ISAKMP_C
1168 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
1169 #endif
1170 
1171 	/* send HDR;KE;NONCE to responder */
1172 	if (isakmp_send(iph1, iph1->sendbuf) < 0)
1173 		goto end;
1174 
1175 	/* the sending message is added to the received-list. */
1176 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1177 		plog(LLV_ERROR , LOCATION, NULL,
1178 			"failed to add a response packet to the tree.\n");
1179 		goto end;
1180 	}
1181 
1182 	/* generate SKEYIDs & IV & final cipher key */
1183 	if (oakley_skeyid_dae(iph1) < 0)
1184 		goto end;
1185 	if (oakley_compute_enckey(iph1) < 0)
1186 		goto end;
1187 	if (oakley_newiv(iph1) < 0)
1188 		goto end;
1189 
1190 	/* set encryption flag */
1191 	iph1->flags |= ISAKMP_FLAG_E;
1192 
1193 	iph1->status = PHASE1ST_ESTABLISHED;
1194 
1195 	error = 0;
1196 
1197 end:
1198 	if (vid)
1199 		vfree(vid);
1200 	return error;
1201 }
1202