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