• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*	$NetBSD: isakmp_agg.c,v 1.9 2006/09/30 21:49:37 manu Exp $	*/
2 
3 /* Id: isakmp_agg.c,v 1.28 2006/04/06 16:46:08 manubsd 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 /* Aggressive Exchange (Aggressive 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 #ifdef ENABLE_HYBRID
65 #include <resolv.h>
66 #endif
67 
68 #include "localconf.h"
69 #include "remoteconf.h"
70 #include "isakmp_var.h"
71 #include "isakmp.h"
72 #include "evt.h"
73 #include "oakley.h"
74 #include "handler.h"
75 #include "ipsec_doi.h"
76 #include "crypto_openssl.h"
77 #include "pfkey.h"
78 #include "isakmp_agg.h"
79 #include "isakmp_inf.h"
80 #ifdef ENABLE_HYBRID
81 #include "isakmp_xauth.h"
82 #include "isakmp_cfg.h"
83 #endif
84 #ifdef ENABLE_FRAG
85 #include "isakmp_frag.h"
86 #endif
87 #include "vendorid.h"
88 #include "strnames.h"
89 
90 #ifdef ENABLE_NATT
91 #include "nattraversal.h"
92 #endif
93 
94 #ifdef HAVE_GSSAPI
95 #include "gssapi.h"
96 #endif
97 
98 /*
99  * begin Aggressive Mode as initiator.
100  */
101 /*
102  * send to responder
103  * 	psk: HDR, SA, KE, Ni, IDi1
104  * 	sig: HDR, SA, KE, Ni, IDi1 [, CR ]
105  *   gssapi: HDR, SA, KE, Ni, IDi1, GSSi
106  * 	rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
107  * 	rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
108  * 	     <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
109  */
110 int
agg_i1send(iph1,msg)111 agg_i1send(iph1, msg)
112 	struct ph1handle *iph1;
113 	vchar_t *msg; /* must be null */
114 {
115 	struct payload_list *plist = NULL;
116 	int need_cr = 0;
117 	vchar_t *cr = NULL;
118 	int error = -1;
119 #ifdef ENABLE_NATT
120 	vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
121 	int i;
122 #endif
123 #ifdef ENABLE_HYBRID
124 	vchar_t *vid_xauth = NULL;
125 	vchar_t *vid_unity = NULL;
126 #endif
127 #ifdef ENABLE_FRAG
128 	vchar_t *vid_frag = NULL;
129 #endif
130 #ifdef HAVE_GSSAPI
131 	vchar_t *gsstoken = NULL;
132 	int len;
133 #endif
134 #ifdef ENABLE_DPD
135 	vchar_t *vid_dpd = NULL;
136 #endif
137 
138 
139 	/* validity check */
140 	if (msg != NULL) {
141 		plog(LLV_ERROR, LOCATION, NULL,
142 			"msg has to be NULL in this function.\n");
143 		goto end;
144 	}
145 	if (iph1->status != PHASE1ST_START) {
146 		plog(LLV_ERROR, LOCATION, NULL,
147 			"status mismatched %d.\n", iph1->status);
148 		goto end;
149 	}
150 
151 	/* create isakmp index */
152 	memset(&iph1->index, 0, sizeof(iph1->index));
153 	isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
154 
155 	/* make ID payload into isakmp status */
156 	if (ipsecdoi_setid1(iph1) < 0)
157 		goto end;
158 
159 	/* create SA payload for my proposal */
160 	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal);
161 	if (iph1->sa == NULL)
162 		goto end;
163 
164 	/* consistency check of proposals */
165 	if (iph1->rmconf->dhgrp == NULL) {
166 		plog(LLV_ERROR, LOCATION, NULL,
167 			"configuration failure about DH group.\n");
168 		goto end;
169 	}
170 
171 	/* generate DH public value */
172 	if (oakley_dh_generate(iph1->rmconf->dhgrp,
173 				&iph1->dhpub, &iph1->dhpriv) < 0)
174 		goto end;
175 
176 	/* generate NONCE value */
177 	iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
178 	if (iph1->nonce == NULL)
179 		goto end;
180 
181 #ifdef ENABLE_HYBRID
182 	/* Do we need Xauth VID? */
183 	switch (RMAUTHMETHOD(iph1)) {
184 	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
185 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
186 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
187 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
188 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
189 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
190 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
191 		if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL)
192 			plog(LLV_ERROR, LOCATION, NULL,
193 			     "Xauth vendor ID generation failed\n");
194 		if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
195 			plog(LLV_ERROR, LOCATION, NULL,
196 			     "Unity vendor ID generation failed\n");
197 		break;
198 	default:
199 		break;
200 	}
201 #endif
202 
203 #ifdef ENABLE_FRAG
204 	if (iph1->rmconf->ike_frag) {
205 		vid_frag = set_vendorid(VENDORID_FRAG);
206 		if (vid_frag != NULL)
207 			vid_frag = isakmp_frag_addcap(vid_frag,
208 			    VENDORID_FRAG_AGG);
209 		if (vid_frag == NULL)
210 			plog(LLV_ERROR, LOCATION, NULL,
211 			    "Frag vendorID construction failed\n");
212 	}
213 #endif
214 
215 	/* create CR if need */
216 	if (iph1->rmconf->send_cr
217 	 && oakley_needcr(iph1->rmconf->proposal->authmethod)
218 	 && iph1->rmconf->peerscertfile == NULL) {
219 		need_cr = 1;
220 		cr = oakley_getcr(iph1);
221 		if (cr == NULL) {
222 			plog(LLV_ERROR, LOCATION, NULL,
223 				"failed to get cr buffer.\n");
224 			goto end;
225 		}
226 	}
227 
228 	plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n",
229 		s_oakley_attr_method(iph1->rmconf->proposal->authmethod));
230 #ifdef HAVE_GSSAPI
231 	if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
232 		gssapi_get_itoken(iph1, &len);
233 #endif
234 
235 	/* set SA payload to propose */
236 	plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
237 
238 	/* create isakmp KE payload */
239 	plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
240 
241 	/* create isakmp NONCE payload */
242 	plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
243 
244 	/* create isakmp ID payload */
245 	plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
246 
247 #ifdef HAVE_GSSAPI
248 	if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
249 		gssapi_get_token_to_send(iph1, &gsstoken);
250 		plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
251 	}
252 #endif
253 	/* create isakmp CR payload */
254 	if (need_cr)
255 		plist = isakmp_plist_append(plist, cr, ISAKMP_NPTYPE_CR);
256 
257 #ifdef ENABLE_FRAG
258 	if (vid_frag)
259 		plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
260 #endif
261 #ifdef ENABLE_NATT
262 	/*
263 	 * set VID payload for NAT-T if NAT-T
264 	 * support allowed in the config file
265 	 */
266 	if (iph1->rmconf->nat_traversal)
267 		plist = isakmp_plist_append_natt_vids(plist, vid_natt);
268 #endif
269 #ifdef ENABLE_HYBRID
270 	if (vid_xauth)
271 		plist = isakmp_plist_append(plist,
272 		    vid_xauth, ISAKMP_NPTYPE_VID);
273 	if (vid_unity)
274 		plist = isakmp_plist_append(plist,
275 		    vid_unity, ISAKMP_NPTYPE_VID);
276 #endif
277 #ifdef ENABLE_DPD
278 	if(iph1->rmconf->dpd){
279 		vid_dpd = set_vendorid(VENDORID_DPD);
280 		if (vid_dpd != NULL)
281 			plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
282 	}
283 #endif
284 
285 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
286 
287 #ifdef HAVE_PRINT_ISAKMP_C
288 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
289 #endif
290 
291 	/* send the packet, add to the schedule to resend */
292 	iph1->retry_counter = iph1->rmconf->retry_counter;
293 	if (isakmp_ph1resend(iph1) == -1)
294 		goto end;
295 
296 	iph1->status = PHASE1ST_MSG1SENT;
297 
298 	error = 0;
299 
300 end:
301 	if (cr)
302 		vfree(cr);
303 #ifdef HAVE_GSSAPI
304 	if (gsstoken)
305 		vfree(gsstoken);
306 #endif
307 #ifdef ENABLE_FRAG
308 	if (vid_frag)
309 		vfree(vid_frag);
310 #endif
311 #ifdef ENABLE_NATT
312 	for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++)
313 		vfree(vid_natt[i]);
314 #endif
315 #ifdef ENABLE_HYBRID
316 	if (vid_xauth != NULL)
317 		vfree(vid_xauth);
318 	if (vid_unity != NULL)
319 		vfree(vid_unity);
320 #endif
321 #ifdef ENABLE_DPD
322 	if (vid_dpd != NULL)
323 		vfree(vid_dpd);
324 #endif
325 
326 	return error;
327 }
328 
329 /*
330  * receive from responder
331  * 	psk: HDR, SA, KE, Nr, IDr1, HASH_R
332  * 	sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
333  *   gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
334  * 	rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
335  * 	rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
336  */
337 int
agg_i2recv(iph1,msg)338 agg_i2recv(iph1, msg)
339 	struct ph1handle *iph1;
340 	vchar_t *msg;
341 {
342 	vchar_t *pbuf = NULL;
343 	struct isakmp_parse_t *pa;
344 	vchar_t *satmp = NULL;
345 	int error = -1;
346 	int vid_numeric;
347 	int ptype;
348 #ifdef ENABLE_HYBRID
349 	vchar_t *unity_vid;
350 	vchar_t *xauth_vid;
351 #endif
352 #ifdef HAVE_GSSAPI
353 	vchar_t *gsstoken = NULL;
354 #endif
355 
356 #ifdef ENABLE_NATT
357 	int natd_seq = 0;
358 	struct natd_payload {
359 		int seq;
360 		vchar_t *payload;
361 		TAILQ_ENTRY(natd_payload) chain;
362 	};
363 	TAILQ_HEAD(_natd_payload, natd_payload) natd_tree;
364 	TAILQ_INIT(&natd_tree);
365 #endif
366 
367 	/* validity check */
368 	if (iph1->status != PHASE1ST_MSG1SENT) {
369 		plog(LLV_ERROR, LOCATION, NULL,
370 			"status mismatched %d.\n", iph1->status);
371 		goto end;
372 	}
373 
374 	/* validate the type of next payload */
375 	pbuf = isakmp_parse(msg);
376 	if (pbuf == NULL)
377 		goto end;
378 	pa = (struct isakmp_parse_t *)pbuf->v;
379 
380 	iph1->pl_hash = NULL;
381 
382 	/* SA payload is fixed postion */
383 	if (pa->type != ISAKMP_NPTYPE_SA) {
384 		plog(LLV_ERROR, LOCATION, iph1->remote,
385 			"received invalid next payload type %d, "
386 			"expecting %d.\n",
387 			pa->type, ISAKMP_NPTYPE_SA);
388 		goto end;
389 	}
390 
391 	if (isakmp_p2ph(&satmp, pa->ptr) < 0)
392 		goto end;
393 	pa++;
394 
395 	for (/*nothing*/;
396 	     pa->type != ISAKMP_NPTYPE_NONE;
397 	     pa++) {
398 
399 		switch (pa->type) {
400 		case ISAKMP_NPTYPE_KE:
401 			if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
402 				goto end;
403 			break;
404 		case ISAKMP_NPTYPE_NONCE:
405 			if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
406 				goto end;
407 			break;
408 		case ISAKMP_NPTYPE_ID:
409 			if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
410 				goto end;
411 			break;
412 		case ISAKMP_NPTYPE_HASH:
413 			iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
414 			break;
415 		case ISAKMP_NPTYPE_CR:
416 			if (oakley_savecr(iph1, pa->ptr) < 0)
417 				goto end;
418 			break;
419 		case ISAKMP_NPTYPE_CERT:
420 			if (oakley_savecert(iph1, pa->ptr) < 0)
421 				goto end;
422 			break;
423 		case ISAKMP_NPTYPE_SIG:
424 			if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
425 				goto end;
426 			break;
427 		case ISAKMP_NPTYPE_VID:
428 			vid_numeric = check_vendorid(pa->ptr);
429 #ifdef ENABLE_NATT
430 			if (iph1->rmconf->nat_traversal &&
431 			    natt_vendorid(vid_numeric))
432 				natt_handle_vendorid(iph1, vid_numeric);
433 #endif
434 #ifdef ENABLE_HYBRID
435 			switch (vid_numeric) {
436 			case VENDORID_XAUTH:
437 				iph1->mode_cfg->flags |=
438 				    ISAKMP_CFG_VENDORID_XAUTH;
439 				break;
440 
441 			case VENDORID_UNITY:
442 				iph1->mode_cfg->flags |=
443 				    ISAKMP_CFG_VENDORID_UNITY;
444 				break;
445 			default:
446 				break;
447 			}
448 #endif
449 #ifdef ENABLE_DPD
450 			if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) {
451 				iph1->dpd_support=1;
452 				plog(LLV_DEBUG, LOCATION, NULL,
453 					 "remote supports DPD\n");
454 			}
455 #endif
456 			break;
457 		case ISAKMP_NPTYPE_N:
458 			isakmp_check_notify(pa->ptr, iph1);
459 			break;
460 #ifdef HAVE_GSSAPI
461 		case ISAKMP_NPTYPE_GSS:
462 			if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
463 				goto end;
464 			gssapi_save_received_token(iph1, gsstoken);
465 			break;
466 #endif
467 
468 #ifdef ENABLE_NATT
469 		case ISAKMP_NPTYPE_NATD_DRAFT:
470 		case ISAKMP_NPTYPE_NATD_RFC:
471 			if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
472 			    pa->type == iph1->natt_options->payload_nat_d) {
473 				struct natd_payload *natd;
474 				natd = (struct natd_payload *)racoon_malloc(sizeof(*natd));
475 				if (!natd)
476 					goto end;
477 
478 				natd->payload = NULL;
479 
480 				if (isakmp_p2ph (&natd->payload, pa->ptr) < 0)
481 					goto end;
482 
483 				natd->seq = natd_seq++;
484 
485 				TAILQ_INSERT_TAIL(&natd_tree, natd, chain);
486 				break;
487 			}
488 			/* passthrough to default... */
489 #endif
490 
491 		default:
492 			/* don't send information, see isakmp_ident_r1() */
493 			plog(LLV_ERROR, LOCATION, iph1->remote,
494 				"ignore the packet, "
495 				"received unexpecting payload type %d.\n",
496 				pa->type);
497 			goto end;
498 		}
499 	}
500 
501 	/* payload existency check */
502 	if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
503 		plog(LLV_ERROR, LOCATION, iph1->remote,
504 			"few isakmp message received.\n");
505 		goto end;
506 	}
507 
508 	/* verify identifier */
509 	if (ipsecdoi_checkid1(iph1) != 0) {
510 		plog(LLV_ERROR, LOCATION, iph1->remote,
511 			"invalid ID payload.\n");
512 		goto end;
513 	}
514 
515 	/* check SA payload and set approval SA for use */
516 	if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
517 		plog(LLV_ERROR, LOCATION, iph1->remote,
518 			"failed to get valid proposal.\n");
519 		/* XXX send information */
520 		goto end;
521 	}
522 	VPTRINIT(iph1->sa_ret);
523 
524 	/* fix isakmp index */
525 	memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
526 		sizeof(cookie_t));
527 
528 #ifdef ENABLE_NATT
529 	if (NATT_AVAILABLE(iph1)) {
530 		struct natd_payload *natd = NULL;
531 		int natd_verified;
532 
533 		plog(LLV_INFO, LOCATION, iph1->remote,
534 		     "Selected NAT-T version: %s\n",
535 		     vid_string_by_id(iph1->natt_options->version));
536 
537 		/* set both bits first so that we can clear them
538 		   upon verifying hashes */
539 		iph1->natt_flags |= NAT_DETECTED;
540 
541 		while ((natd = TAILQ_FIRST(&natd_tree)) != NULL) {
542 			/* this function will clear appropriate bits bits
543 			   from iph1->natt_flags */
544 			natd_verified = natt_compare_addr_hash (iph1,
545 				natd->payload, natd->seq);
546 
547 			plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
548 				natd->seq - 1,
549 				natd_verified ? "verified" : "doesn't match");
550 
551 			vfree (natd->payload);
552 
553 			TAILQ_REMOVE(&natd_tree, natd, chain);
554 			racoon_free (natd);
555 		}
556 
557 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
558 		      iph1->natt_flags & NAT_DETECTED ?
559 		      		"detected:" : "not detected",
560 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
561 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
562 
563 		if (iph1->natt_flags & NAT_DETECTED)
564 			natt_float_ports (iph1);
565 	}
566 #endif
567 
568 	/* compute sharing secret of DH */
569 	if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub,
570 				iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
571 		goto end;
572 
573 	/* generate SKEYIDs & IV & final cipher key */
574 	if (oakley_skeyid(iph1) < 0)
575 		goto end;
576 	if (oakley_skeyid_dae(iph1) < 0)
577 		goto end;
578 	if (oakley_compute_enckey(iph1) < 0)
579 		goto end;
580 	if (oakley_newiv(iph1) < 0)
581 		goto end;
582 
583 	/* validate authentication value */
584 	ptype = oakley_validate_auth(iph1);
585 	if (ptype != 0) {
586 		if (ptype == -1) {
587 			/* message printed inner oakley_validate_auth() */
588 			goto end;
589 		}
590 		EVT_PUSH(iph1->local, iph1->remote,
591 		    EVTT_PEERPH1AUTH_FAILED, NULL);
592 		isakmp_info_send_n1(iph1, ptype, NULL);
593 		goto end;
594 	}
595 
596 	if (oakley_checkcr(iph1) < 0) {
597 		/* Ignore this error in order to be interoperability. */
598 		;
599 	}
600 
601 	/* change status of isakmp status entry */
602 	iph1->status = PHASE1ST_MSG2RECEIVED;
603 
604 	error = 0;
605 
606 end:
607 #ifdef HAVE_GSSAPI
608 	if (gsstoken)
609 		vfree(gsstoken);
610 #endif
611 	if (pbuf)
612 		vfree(pbuf);
613 	if (satmp)
614 		vfree(satmp);
615 	if (error) {
616 		VPTRINIT(iph1->dhpub_p);
617 		VPTRINIT(iph1->nonce_p);
618 		VPTRINIT(iph1->id_p);
619 		oakley_delcert(iph1->cert_p);
620 		iph1->cert_p = NULL;
621 		oakley_delcert(iph1->crl_p);
622 		iph1->crl_p = NULL;
623 		VPTRINIT(iph1->sig_p);
624 		oakley_delcert(iph1->cr_p);
625 		iph1->cr_p = NULL;
626 	}
627 
628 	return error;
629 }
630 
631 /*
632  * send to responder
633  * 	psk: HDR, HASH_I
634  *   gssapi: HDR, HASH_I
635  * 	sig: HDR, [ CERT, ] SIG_I
636  * 	rsa: HDR, HASH_I
637  * 	rev: HDR, HASH_I
638  */
639 int
agg_i2send(iph1,msg)640 agg_i2send(iph1, msg)
641 	struct ph1handle *iph1;
642 	vchar_t *msg;
643 {
644 	struct payload_list *plist = NULL;
645 	int need_cert = 0;
646 	int error = -1;
647 	vchar_t *gsshash = NULL;
648 
649 	/* validity check */
650 	if (iph1->status != PHASE1ST_MSG2RECEIVED) {
651 		plog(LLV_ERROR, LOCATION, NULL,
652 			"status mismatched %d.\n", iph1->status);
653 		goto end;
654 	}
655 
656 	/* generate HASH to send */
657 	plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n");
658 	iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
659 	if (iph1->hash == NULL) {
660 #ifdef HAVE_GSSAPI
661 		if (gssapi_more_tokens(iph1) &&
662 #ifdef ENABLE_HYBRID
663 		    !iph1->rmconf->xauth &&
664 #endif
665 		    1)
666 			isakmp_info_send_n1(iph1,
667 			    ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
668 #endif
669 		goto end;
670 	}
671 
672 	switch (AUTHMETHOD(iph1)) {
673 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
674 #ifdef ENABLE_HYBRID
675 	case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I:
676 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
677 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
678 #endif
679 		/* set HASH payload */
680 		plist = isakmp_plist_append(plist,
681 		    iph1->hash, ISAKMP_NPTYPE_HASH);
682 		break;
683 
684 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
685 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
686 #ifdef ENABLE_HYBRID
687 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
688 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
689 #endif
690 		/* XXX if there is CR or not ? */
691 
692 		if (oakley_getmycert(iph1) < 0)
693 			goto end;
694 
695 		if (oakley_getsign(iph1) < 0)
696 			goto end;
697 
698 		if (iph1->cert != NULL && iph1->rmconf->send_cert)
699 			need_cert = 1;
700 
701 		/* add CERT payload if there */
702 		if (need_cert)
703 			plist = isakmp_plist_append(plist,
704 			    iph1->cert->pl, ISAKMP_NPTYPE_CERT);
705 
706 		/* add SIG payload */
707 		plist = isakmp_plist_append(plist,
708 		    iph1->sig, ISAKMP_NPTYPE_SIG);
709 		break;
710 
711 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
712 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
713 #ifdef ENABLE_HYBRID
714 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
715 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
716 #endif
717 		break;
718 #ifdef HAVE_GSSAPI
719 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
720 		gsshash = gssapi_wraphash(iph1);
721 		if (gsshash == NULL) {
722 			plog(LLV_ERROR, LOCATION, NULL,
723 				"failed to wrap hash\n");
724 			isakmp_info_send_n1(iph1,
725 				ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
726 			goto end;
727 		}
728 
729 		plist = isakmp_plist_append(plist,
730 		    gsshash, ISAKMP_NPTYPE_HASH);
731 		break;
732 #endif
733 	}
734 
735 #ifdef ENABLE_NATT
736 	/* generate NAT-D payloads */
737 	if (NATT_AVAILABLE(iph1)) {
738 		vchar_t *natd[2] = { NULL, NULL };
739 
740 		plog(LLV_INFO, LOCATION,
741 		    NULL, "Adding remote and local NAT-D payloads.\n");
742 
743 		if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
744 			plog(LLV_ERROR, LOCATION, NULL,
745 			    "NAT-D hashing failed for %s\n",
746 			    saddr2str(iph1->remote));
747 			goto end;
748 		}
749 
750 		if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
751 			plog(LLV_ERROR, LOCATION, NULL,
752 			    "NAT-D hashing failed for %s\n",
753 			    saddr2str(iph1->local));
754 			goto end;
755 		}
756 
757 		plist = isakmp_plist_append(plist,
758 		    natd[0], iph1->natt_options->payload_nat_d);
759 		plist = isakmp_plist_append(plist,
760 		    natd[1], iph1->natt_options->payload_nat_d);
761 	}
762 #endif
763 
764 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
765 
766 #ifdef HAVE_PRINT_ISAKMP_C
767 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
768 #endif
769 
770 	/* send to responder */
771 	if (isakmp_send(iph1, iph1->sendbuf) < 0)
772 		goto end;
773 
774 	/* the sending message is added to the received-list. */
775 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
776 		plog(LLV_ERROR , LOCATION, NULL,
777 			"failed to add a response packet to the tree.\n");
778 		goto end;
779 	}
780 
781 	/* set encryption flag */
782 	iph1->flags |= ISAKMP_FLAG_E;
783 
784 	iph1->status = PHASE1ST_ESTABLISHED;
785 
786 	error = 0;
787 
788 end:
789 	if (gsshash)
790 		vfree(gsshash);
791 	return error;
792 }
793 
794 /*
795  * receive from initiator
796  * 	psk: HDR, SA, KE, Ni, IDi1
797  * 	sig: HDR, SA, KE, Ni, IDi1 [, CR ]
798  *   gssapi: HDR, SA, KE, Ni, IDi1 , GSSi
799  * 	rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r
800  * 	rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i,
801  * 	     <IDii_b>Ke_i [, <Cert-I_b>Ke_i ]
802  */
803 int
agg_r1recv(iph1,msg)804 agg_r1recv(iph1, msg)
805 	struct ph1handle *iph1;
806 	vchar_t *msg;
807 {
808 	int error = -1;
809 	vchar_t *pbuf = NULL;
810 	struct isakmp_parse_t *pa;
811 	int vid_numeric;
812 #ifdef HAVE_GSSAPI
813 	vchar_t *gsstoken = NULL;
814 #endif
815 
816 	/* validity check */
817 	if (iph1->status != PHASE1ST_START) {
818 		plog(LLV_ERROR, LOCATION, NULL,
819 			"status mismatched %d.\n", iph1->status);
820 		goto end;
821 	}
822 
823 	/* validate the type of next payload */
824 	pbuf = isakmp_parse(msg);
825 	if (pbuf == NULL)
826 		goto end;
827 	pa = (struct isakmp_parse_t *)pbuf->v;
828 
829 	/* SA payload is fixed postion */
830 	if (pa->type != ISAKMP_NPTYPE_SA) {
831 		plog(LLV_ERROR, LOCATION, iph1->remote,
832 			"received invalid next payload type %d, "
833 			"expecting %d.\n",
834 			pa->type, ISAKMP_NPTYPE_SA);
835 		goto end;
836 	}
837 	if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
838 		goto end;
839 	pa++;
840 
841 	for (/*nothing*/;
842 	     pa->type != ISAKMP_NPTYPE_NONE;
843 	     pa++) {
844 
845 		plog(LLV_DEBUG, LOCATION, NULL,
846 			"received payload of type %s\n",
847 			s_isakmp_nptype(pa->type));
848 
849 		switch (pa->type) {
850 		case ISAKMP_NPTYPE_KE:
851 			if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
852 				goto end;
853 			break;
854 		case ISAKMP_NPTYPE_NONCE:
855 			if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
856 				goto end;
857 			break;
858 		case ISAKMP_NPTYPE_ID:
859 			if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
860 				goto end;
861 			break;
862 		case ISAKMP_NPTYPE_VID:
863 			vid_numeric = check_vendorid(pa->ptr);
864 
865 #ifdef ENABLE_NATT
866 			if (iph1->rmconf->nat_traversal &&
867 			    natt_vendorid(vid_numeric)) {
868 				natt_handle_vendorid(iph1, vid_numeric);
869 				break;
870 			}
871 #endif
872 #ifdef ENABLE_HYBRID
873 			switch (vid_numeric) {
874 			case VENDORID_XAUTH:
875 				iph1->mode_cfg->flags |=
876 				    ISAKMP_CFG_VENDORID_XAUTH;
877 				break;
878 
879 			case VENDORID_UNITY:
880 				iph1->mode_cfg->flags |=
881 				    ISAKMP_CFG_VENDORID_UNITY;
882 				break;
883 			default:
884 				break;
885 			}
886 #endif
887 #ifdef ENABLE_DPD
888 			if (vid_numeric == VENDORID_DPD && iph1->rmconf->dpd) {
889 				iph1->dpd_support=1;
890 				plog(LLV_DEBUG, LOCATION, NULL,
891 					 "remote supports DPD\n");
892 			}
893 #endif
894 #ifdef ENABLE_FRAG
895 			if ((vid_numeric == VENDORID_FRAG) &&
896 			    (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_AGG))
897 				iph1->frag = 1;
898 #endif
899 			break;
900 
901 		case ISAKMP_NPTYPE_CR:
902 			if (oakley_savecr(iph1, pa->ptr) < 0)
903 				goto end;
904 			break;
905 
906 #ifdef HAVE_GSSAPI
907 		case ISAKMP_NPTYPE_GSS:
908 			if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
909 				goto end;
910 			gssapi_save_received_token(iph1, gsstoken);
911 			break;
912 #endif
913 		default:
914 			/* don't send information, see isakmp_ident_r1() */
915 			plog(LLV_ERROR, LOCATION, iph1->remote,
916 				"ignore the packet, "
917 				"received unexpecting payload type %d.\n",
918 				pa->type);
919 			goto end;
920 		}
921 	}
922 
923 	/* payload existency check */
924 	if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
925 		plog(LLV_ERROR, LOCATION, iph1->remote,
926 			"few isakmp message received.\n");
927 		goto end;
928 	}
929 
930 	/* verify identifier */
931 	if (ipsecdoi_checkid1(iph1) != 0) {
932 		plog(LLV_ERROR, LOCATION, iph1->remote,
933 			"invalid ID payload.\n");
934 		goto end;
935 	}
936 
937 #ifdef ENABLE_NATT
938 	if (NATT_AVAILABLE(iph1))
939 		plog(LLV_INFO, LOCATION, iph1->remote,
940 		     "Selected NAT-T version: %s\n",
941 		     vid_string_by_id(iph1->natt_options->version));
942 #endif
943 
944 	/* check SA payload and set approval SA for use */
945 	if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
946 		plog(LLV_ERROR, LOCATION, iph1->remote,
947 			"failed to get valid proposal.\n");
948 		/* XXX send information */
949 		goto end;
950 	}
951 
952 	if (oakley_checkcr(iph1) < 0) {
953 		/* Ignore this error in order to be interoperability. */
954 		;
955 	}
956 
957 	iph1->status = PHASE1ST_MSG1RECEIVED;
958 
959 	error = 0;
960 
961 end:
962 #ifdef HAVE_GSSAPI
963 	if (gsstoken)
964 		vfree(gsstoken);
965 #endif
966 	if (pbuf)
967 		vfree(pbuf);
968 	if (error) {
969 		VPTRINIT(iph1->sa);
970 		VPTRINIT(iph1->dhpub_p);
971 		VPTRINIT(iph1->nonce_p);
972 		VPTRINIT(iph1->id_p);
973 		oakley_delcert(iph1->cr_p);
974 		iph1->cr_p = NULL;
975 	}
976 
977 	return error;
978 }
979 
980 /*
981  * send to initiator
982  * 	psk: HDR, SA, KE, Nr, IDr1, HASH_R
983  * 	sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R
984  *   gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R
985  * 	rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R
986  * 	rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R
987  */
988 int
agg_r1send(iph1,msg)989 agg_r1send(iph1, msg)
990 	struct ph1handle *iph1;
991 	vchar_t *msg;
992 {
993 	struct payload_list *plist = NULL;
994 	int need_cr = 0;
995 	int need_cert = 0;
996 	vchar_t *cr = NULL;
997 	int error = -1;
998 #ifdef ENABLE_HYBRID
999 	vchar_t *xauth_vid = NULL;
1000 	vchar_t *unity_vid = NULL;
1001 #endif
1002 #ifdef ENABLE_NATT
1003 	vchar_t *vid_natt = NULL;
1004 	vchar_t *natd[2] = { NULL, NULL };
1005 #endif
1006 #ifdef ENABLE_DPD
1007 	vchar_t *vid_dpd = NULL;
1008 #endif
1009 #ifdef ENABLE_FRAG
1010 	vchar_t *vid_frag = NULL;
1011 #endif
1012 
1013 #ifdef HAVE_GSSAPI
1014 	int gsslen;
1015 	vchar_t *gsstoken = NULL, *gsshash = NULL;
1016 	vchar_t *gss_sa = NULL;
1017 	int free_gss_sa = 0;
1018 #endif
1019 
1020 	/* validity check */
1021 	if (iph1->status != PHASE1ST_MSG1RECEIVED) {
1022 		plog(LLV_ERROR, LOCATION, NULL,
1023 			"status mismatched %d.\n", iph1->status);
1024 		goto end;
1025 	}
1026 
1027 	/* set responder's cookie */
1028 	isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
1029 
1030 	/* make ID payload into isakmp status */
1031 	if (ipsecdoi_setid1(iph1) < 0)
1032 		goto end;
1033 
1034 	/* generate DH public value */
1035 	if (oakley_dh_generate(iph1->rmconf->dhgrp,
1036 				&iph1->dhpub, &iph1->dhpriv) < 0)
1037 		goto end;
1038 
1039 	/* generate NONCE value */
1040 	iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
1041 	if (iph1->nonce == NULL)
1042 		goto end;
1043 
1044 	/* compute sharing secret of DH */
1045 	if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
1046 				iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
1047 		goto end;
1048 
1049 	/* generate SKEYIDs & IV & final cipher key */
1050 	if (oakley_skeyid(iph1) < 0)
1051 		goto end;
1052 	if (oakley_skeyid_dae(iph1) < 0)
1053 		goto end;
1054 	if (oakley_compute_enckey(iph1) < 0)
1055 		goto end;
1056 	if (oakley_newiv(iph1) < 0)
1057 		goto end;
1058 
1059 #ifdef HAVE_GSSAPI
1060 	if (RMAUTHMETHOD(iph1) == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
1061 		gssapi_get_rtoken(iph1, &gsslen);
1062 #endif
1063 
1064 	/* generate HASH to send */
1065 	plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
1066 	iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
1067 	if (iph1->hash == NULL) {
1068 #ifdef HAVE_GSSAPI
1069 		if (gssapi_more_tokens(iph1))
1070 			isakmp_info_send_n1(iph1,
1071 			    ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
1072 #endif
1073 		goto end;
1074 	}
1075 
1076 	/* create CR if need */
1077 	if (iph1->rmconf->send_cr
1078 	 && oakley_needcr(iph1->approval->authmethod)
1079 	 && iph1->rmconf->peerscertfile == NULL) {
1080 		need_cr = 1;
1081 		cr = oakley_getcr(iph1);
1082 		if (cr == NULL) {
1083 			plog(LLV_ERROR, LOCATION, NULL,
1084 				"failed to get cr buffer.\n");
1085 			goto end;
1086 		}
1087 	}
1088 
1089 #ifdef ENABLE_NATT
1090 	/* Has the peer announced NAT-T? */
1091 	if (NATT_AVAILABLE(iph1)) {
1092 	  	/* set chosen VID */
1093 		vid_natt = set_vendorid(iph1->natt_options->version);
1094 
1095 		/* generate NAT-D payloads */
1096 		plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
1097 		if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
1098 			plog(LLV_ERROR, LOCATION, NULL,
1099 				"NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
1100 			goto end;
1101 		}
1102 
1103 		if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
1104 			plog(LLV_ERROR, LOCATION, NULL,
1105 				"NAT-D hashing failed for %s\n", saddr2str(iph1->local));
1106 			goto end;
1107 		}
1108 	}
1109 #endif
1110 #ifdef ENABLE_DPD
1111 	/* Only send DPD support if remote announced DPD and if DPD support is active */
1112 	if (iph1->dpd_support && iph1->rmconf->dpd)
1113 		vid_dpd = set_vendorid(VENDORID_DPD);
1114 #endif
1115 #ifdef ENABLE_FRAG
1116 	if (iph1->frag) {
1117 		vid_frag = set_vendorid(VENDORID_FRAG);
1118 		if (vid_frag != NULL)
1119 			vid_frag = isakmp_frag_addcap(vid_frag,
1120 			    VENDORID_FRAG_AGG);
1121 		if (vid_frag == NULL)
1122 			plog(LLV_ERROR, LOCATION, NULL,
1123 			    "Frag vendorID construction failed\n");
1124 	}
1125 #endif
1126 
1127 	switch (AUTHMETHOD(iph1)) {
1128 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
1129 #ifdef ENABLE_HYBRID
1130 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
1131 #endif
1132 		/* set SA payload to reply */
1133 		plist = isakmp_plist_append(plist,
1134 		    iph1->sa_ret, ISAKMP_NPTYPE_SA);
1135 
1136 		/* create isakmp KE payload */
1137 		plist = isakmp_plist_append(plist,
1138 		    iph1->dhpub, ISAKMP_NPTYPE_KE);
1139 
1140 		/* create isakmp NONCE payload */
1141 		plist = isakmp_plist_append(plist,
1142 		    iph1->nonce, ISAKMP_NPTYPE_NONCE);
1143 
1144 		/* create isakmp ID payload */
1145 		plist = isakmp_plist_append(plist,
1146 		    iph1->id, ISAKMP_NPTYPE_ID);
1147 
1148 		/* create isakmp HASH payload */
1149 		plist = isakmp_plist_append(plist,
1150 		    iph1->hash, ISAKMP_NPTYPE_HASH);
1151 
1152 		/* create isakmp CR payload if needed */
1153 		if (need_cr)
1154 			plist = isakmp_plist_append(plist,
1155 			    cr, ISAKMP_NPTYPE_CR);
1156 		break;
1157 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
1158 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
1159 #ifdef ENABLE_HYBRID
1160 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
1161 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
1162 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
1163 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
1164 #endif
1165 		/* XXX if there is CR or not ? */
1166 
1167 		if (oakley_getmycert(iph1) < 0)
1168 			goto end;
1169 
1170 		if (oakley_getsign(iph1) < 0)
1171 			goto end;
1172 
1173 		if (iph1->cert != NULL && iph1->rmconf->send_cert)
1174 			need_cert = 1;
1175 
1176 		/* set SA payload to reply */
1177 		plist = isakmp_plist_append(plist,
1178 		    iph1->sa_ret, ISAKMP_NPTYPE_SA);
1179 
1180 		/* create isakmp KE payload */
1181 		plist = isakmp_plist_append(plist,
1182 		    iph1->dhpub, ISAKMP_NPTYPE_KE);
1183 
1184 		/* create isakmp NONCE payload */
1185 		plist = isakmp_plist_append(plist,
1186 		    iph1->nonce, ISAKMP_NPTYPE_NONCE);
1187 
1188 		/* add ID payload */
1189 		plist = isakmp_plist_append(plist,
1190 		    iph1->id, ISAKMP_NPTYPE_ID);
1191 
1192 		/* add CERT payload if there */
1193 		if (need_cert)
1194 			plist = isakmp_plist_append(plist,
1195 			    iph1->cert->pl, ISAKMP_NPTYPE_CERT);
1196 
1197 		/* add SIG payload */
1198 		plist = isakmp_plist_append(plist,
1199 		    iph1->sig, ISAKMP_NPTYPE_SIG);
1200 
1201 		/* create isakmp CR payload if needed */
1202 		if (need_cr)
1203 			plist = isakmp_plist_append(plist,
1204 			    cr, ISAKMP_NPTYPE_CR);
1205 		break;
1206 
1207 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
1208 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
1209 #ifdef ENABLE_HYBRID
1210 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
1211 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
1212 #endif
1213 		break;
1214 #ifdef HAVE_GSSAPI
1215 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
1216 			/* create buffer to send isakmp payload */
1217 			gsshash = gssapi_wraphash(iph1);
1218 			if (gsshash == NULL) {
1219 				plog(LLV_ERROR, LOCATION, NULL,
1220 					"failed to wrap hash\n");
1221 				/*
1222 				 * This is probably due to the GSS
1223 				 * roundtrips not being finished yet.
1224 				 * Return this error in the hope that
1225 				 * a fallback to main mode will be done.
1226 				 */
1227 				isakmp_info_send_n1(iph1,
1228 				    ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL);
1229 				goto end;
1230 			}
1231 			if (iph1->approval->gssid != NULL)
1232 				gss_sa =
1233 				    ipsecdoi_setph1proposal(iph1->approval);
1234 			else
1235 				gss_sa = iph1->sa_ret;
1236 
1237 			if (gss_sa != iph1->sa_ret)
1238 				free_gss_sa = 1;
1239 
1240 			/* set SA payload to reply */
1241 			plist = isakmp_plist_append(plist,
1242 			    gss_sa, ISAKMP_NPTYPE_SA);
1243 
1244 			/* create isakmp KE payload */
1245 			plist = isakmp_plist_append(plist,
1246 			    iph1->dhpub, ISAKMP_NPTYPE_KE);
1247 
1248 			/* create isakmp NONCE payload */
1249 			plist = isakmp_plist_append(plist,
1250 			    iph1->nonce, ISAKMP_NPTYPE_NONCE);
1251 
1252 			/* create isakmp ID payload */
1253 			plist = isakmp_plist_append(plist,
1254 			    iph1->id, ISAKMP_NPTYPE_ID);
1255 
1256 			/* create GSS payload */
1257 			gssapi_get_token_to_send(iph1, &gsstoken);
1258 			plist = isakmp_plist_append(plist,
1259 			    gsstoken, ISAKMP_NPTYPE_GSS);
1260 
1261 			/* create isakmp HASH payload */
1262 			plist = isakmp_plist_append(plist,
1263 			    gsshash, ISAKMP_NPTYPE_HASH);
1264 
1265 			/* append vendor id, if needed */
1266 			break;
1267 #endif
1268 	}
1269 
1270 #ifdef ENABLE_HYBRID
1271 	if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
1272 		plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n");
1273 		if ((xauth_vid = set_vendorid(VENDORID_XAUTH)) == NULL) {
1274 			plog(LLV_ERROR, LOCATION, NULL,
1275 			    "Cannot create Xauth vendor ID\n");
1276 			goto end;
1277 		}
1278 		plist = isakmp_plist_append(plist,
1279 		    xauth_vid, ISAKMP_NPTYPE_VID);
1280 	}
1281 
1282 	if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) {
1283 		if ((unity_vid = set_vendorid(VENDORID_UNITY)) == NULL) {
1284 			plog(LLV_ERROR, LOCATION, NULL,
1285 			    "Cannot create Unity vendor ID\n");
1286 			goto end;
1287 		}
1288 		plist = isakmp_plist_append(plist,
1289 		    unity_vid, ISAKMP_NPTYPE_VID);
1290 	}
1291 #endif
1292 
1293 #ifdef ENABLE_NATT
1294 	/* append NAT-T payloads */
1295 	if (vid_natt) {
1296 		/* chosen VID */
1297 		plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
1298 		/* NAT-D */
1299 		plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
1300 		plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
1301 	}
1302 #endif
1303 
1304 #ifdef ENABLE_FRAG
1305 	if (vid_frag)
1306 		plist = isakmp_plist_append(plist, vid_frag, ISAKMP_NPTYPE_VID);
1307 #endif
1308 
1309 #ifdef ENABLE_DPD
1310 	if (vid_dpd)
1311 		plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
1312 #endif
1313 
1314 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
1315 
1316 #ifdef HAVE_PRINT_ISAKMP_C
1317 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 1);
1318 #endif
1319 
1320 	/* send the packet, add to the schedule to resend */
1321 	iph1->retry_counter = iph1->rmconf->retry_counter;
1322 	if (isakmp_ph1resend(iph1) == -1)
1323 		goto end;
1324 
1325 	/* the sending message is added to the received-list. */
1326 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
1327 		plog(LLV_ERROR , LOCATION, NULL,
1328 			"failed to add a response packet to the tree.\n");
1329 		goto end;
1330 	}
1331 
1332 	iph1->status = PHASE1ST_MSG1SENT;
1333 
1334 	error = 0;
1335 
1336 end:
1337 	if (cr)
1338 		vfree(cr);
1339 #ifdef ENABLE_HYBRID
1340 	if (xauth_vid)
1341 		vfree(xauth_vid);
1342 	if (unity_vid)
1343 		vfree(unity_vid);
1344 #endif
1345 #ifdef HAVE_GSSAPI
1346 	if (gsstoken)
1347 		vfree(gsstoken);
1348 	if (gsshash)
1349 		vfree(gsshash);
1350 	if (free_gss_sa)
1351 		vfree(gss_sa);
1352 #endif
1353 #ifdef ENABLE_DPD
1354 	if (vid_dpd)
1355 		vfree(vid_dpd);
1356 #endif
1357 #ifdef ENABLE_FRAG
1358 	if (vid_frag)
1359 		vfree(vid_frag);
1360 #endif
1361 
1362 	return error;
1363 }
1364 
1365 /*
1366  * receive from initiator
1367  * 	psk: HDR, HASH_I
1368  *   gssapi: HDR, HASH_I
1369  * 	sig: HDR, [ CERT, ] SIG_I
1370  * 	rsa: HDR, HASH_I
1371  * 	rev: HDR, HASH_I
1372  */
1373 int
agg_r2recv(iph1,msg0)1374 agg_r2recv(iph1, msg0)
1375 	struct ph1handle *iph1;
1376 	vchar_t *msg0;
1377 {
1378 	vchar_t *msg = NULL;
1379 	vchar_t *pbuf = NULL;
1380 	struct isakmp_parse_t *pa;
1381 	int error = -1;
1382 	int ptype;
1383 
1384 #ifdef ENABLE_NATT
1385 	int natd_seq = 0;
1386 #endif
1387 
1388 	/* validity check */
1389 	if (iph1->status != PHASE1ST_MSG1SENT) {
1390 		plog(LLV_ERROR, LOCATION, NULL,
1391 			"status mismatched %d.\n", iph1->status);
1392 		goto end;
1393 	}
1394 
1395 	/* decrypting if need. */
1396 	/* XXX configurable ? */
1397 	if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
1398 		msg = oakley_do_decrypt(iph1, msg0,
1399 					iph1->ivm->iv, iph1->ivm->ive);
1400 		if (msg == NULL)
1401 			goto end;
1402 	} else
1403 		msg = vdup(msg0);
1404 
1405 	/* validate the type of next payload */
1406 	pbuf = isakmp_parse(msg);
1407 	if (pbuf == NULL)
1408 		goto end;
1409 
1410 	iph1->pl_hash = NULL;
1411 
1412 	for (pa = (struct isakmp_parse_t *)pbuf->v;
1413 	     pa->type != ISAKMP_NPTYPE_NONE;
1414 	     pa++) {
1415 
1416 		switch (pa->type) {
1417 		case ISAKMP_NPTYPE_HASH:
1418 			iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
1419 			break;
1420 		case ISAKMP_NPTYPE_VID:
1421 			(void)check_vendorid(pa->ptr);
1422 			break;
1423 		case ISAKMP_NPTYPE_CERT:
1424 			if (oakley_savecert(iph1, pa->ptr) < 0)
1425 				goto end;
1426 			break;
1427 		case ISAKMP_NPTYPE_SIG:
1428 			if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
1429 				goto end;
1430 			break;
1431 		case ISAKMP_NPTYPE_N:
1432 			isakmp_check_notify(pa->ptr, iph1);
1433 			break;
1434 
1435 #ifdef ENABLE_NATT
1436 		case ISAKMP_NPTYPE_NATD_DRAFT:
1437 		case ISAKMP_NPTYPE_NATD_RFC:
1438 			if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
1439 				pa->type == iph1->natt_options->payload_nat_d)
1440 			{
1441 				vchar_t *natd_received = NULL;
1442 				int natd_verified;
1443 
1444 				if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
1445 					goto end;
1446 
1447 				if (natd_seq == 0)
1448 					iph1->natt_flags |= NAT_DETECTED;
1449 
1450 				natd_verified = natt_compare_addr_hash (iph1,
1451 					natd_received, natd_seq++);
1452 
1453 				plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
1454 					natd_seq - 1,
1455 					natd_verified ? "verified" : "doesn't match");
1456 
1457 				vfree (natd_received);
1458 				break;
1459 			}
1460 			/* passthrough to default... */
1461 #endif
1462 
1463 		default:
1464 			/* don't send information, see isakmp_ident_r1() */
1465 			plog(LLV_ERROR, LOCATION, iph1->remote,
1466 				"ignore the packet, "
1467 				"received unexpecting payload type %d.\n",
1468 				pa->type);
1469 			goto end;
1470 		}
1471 	}
1472 
1473 #ifdef ENABLE_NATT
1474 	if (NATT_AVAILABLE(iph1))
1475 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
1476 		      iph1->natt_flags & NAT_DETECTED ?
1477 		      		"detected:" : "not detected",
1478 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
1479 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
1480 #endif
1481 
1482 	/* validate authentication value */
1483 	ptype = oakley_validate_auth(iph1);
1484 	if (ptype != 0) {
1485 		if (ptype == -1) {
1486 			/* message printed inner oakley_validate_auth() */
1487 			goto end;
1488 		}
1489 		EVT_PUSH(iph1->local, iph1->remote,
1490 		    EVTT_PEERPH1AUTH_FAILED, NULL);
1491 		isakmp_info_send_n1(iph1, ptype, NULL);
1492 		goto end;
1493 	}
1494 
1495 	iph1->status = PHASE1ST_MSG2RECEIVED;
1496 
1497 	error = 0;
1498 
1499 end:
1500 	if (pbuf)
1501 		vfree(pbuf);
1502 	if (msg)
1503 		vfree(msg);
1504 	if (error) {
1505 		oakley_delcert(iph1->cert_p);
1506 		iph1->cert_p = NULL;
1507 		oakley_delcert(iph1->crl_p);
1508 		iph1->crl_p = NULL;
1509 		VPTRINIT(iph1->sig_p);
1510 	}
1511 
1512 	return error;
1513 }
1514 
1515 /*
1516  * status update and establish isakmp sa.
1517  */
1518 int
agg_r2send(iph1,msg)1519 agg_r2send(iph1, msg)
1520 	struct ph1handle *iph1;
1521 	vchar_t *msg;
1522 {
1523 	int error = -1;
1524 
1525 	/* validity check */
1526 	if (iph1->status != PHASE1ST_MSG2RECEIVED) {
1527 		plog(LLV_ERROR, LOCATION, NULL,
1528 			"status mismatched %d.\n", iph1->status);
1529 		goto end;
1530 	}
1531 
1532 	/* IV synchronized when packet encrypted. */
1533 	/* see handler.h about IV synchronization. */
1534 	if (ISSET(((struct isakmp *)msg->v)->flags, ISAKMP_FLAG_E))
1535 		memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
1536 
1537 	/* set encryption flag */
1538 	iph1->flags |= ISAKMP_FLAG_E;
1539 
1540 	iph1->status = PHASE1ST_ESTABLISHED;
1541 
1542 	error = 0;
1543 
1544 end:
1545 	return error;
1546 }
1547