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