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