Home | History | Annotate | Line # | Download | only in racoon
      1 /*	$NetBSD: isakmp_ident.c,v 1.17 2025/03/07 15:55:29 christos Exp $	*/
      2 
      3 /* Id: isakmp_ident.c,v 1.21 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 /* Identity Protecion Exchange (Main Mode) */
     35 
     36 #include "config.h"
     37 
     38 #include <sys/types.h>
     39 #include <sys/param.h>
     40 
     41 #include <stdlib.h>
     42 #include <stdio.h>
     43 #include <string.h>
     44 #include <errno.h>
     45 #if TIME_WITH_SYS_TIME
     46 # include <sys/time.h>
     47 # include <time.h>
     48 #else
     49 # if HAVE_SYS_TIME_H
     50 #  include <sys/time.h>
     51 # else
     52 #  include <time.h>
     53 # endif
     54 #endif
     55 
     56 #include "var.h"
     57 #include "misc.h"
     58 #include "vmbuf.h"
     59 #include "plog.h"
     60 #include "sockmisc.h"
     61 #include "schedule.h"
     62 #include "debug.h"
     63 
     64 #include "localconf.h"
     65 #include "remoteconf.h"
     66 #include "isakmp_var.h"
     67 #include "isakmp.h"
     68 #include "evt.h"
     69 #include "oakley.h"
     70 #include "handler.h"
     71 #include "ipsec_doi.h"
     72 #include "crypto_openssl.h"
     73 #include "pfkey.h"
     74 #include "isakmp_ident.h"
     75 #include "isakmp_inf.h"
     76 #include "vendorid.h"
     77 
     78 #ifdef ENABLE_NATT
     79 #include "nattraversal.h"
     80 #endif
     81 #ifdef HAVE_GSSAPI
     82 #include "gssapi.h"
     83 #endif
     84 #ifdef ENABLE_HYBRID
     85 #include <resolv.h>
     86 #include "isakmp_xauth.h"
     87 #include "isakmp_cfg.h"
     88 #endif
     89 #ifdef ENABLE_FRAG
     90 #include "isakmp_frag.h"
     91 #endif
     92 
     93 static vchar_t *ident_ir2mx(struct ph1handle *);
     94 static vchar_t *ident_ir3mx(struct ph1handle *);
     95 static int ident_recv_n(struct ph1handle *, struct isakmp_gen *);
     96 
     97 /* %%%
     98  * begin Identity Protection Mode as initiator.
     99  */
    100 /*
    101  * send to responder
    102  * 	psk: HDR, SA
    103  * 	sig: HDR, SA
    104  * 	rsa: HDR, SA
    105  * 	rev: HDR, SA
    106  */
    107 int
    108 ident_i1send(struct ph1handle *iph1, vchar_t *msg) /* must be null */
    109 {
    110 	struct payload_list *plist = NULL;
    111 	int error = -1;
    112 #ifdef ENABLE_NATT
    113 	vchar_t *vid_natt[MAX_NATT_VID_COUNT] = { NULL };
    114 	int i;
    115 #endif
    116 #ifdef ENABLE_HYBRID
    117 	vchar_t *vid_xauth = NULL;
    118 	vchar_t *vid_unity = NULL;
    119 #endif
    120 #ifdef ENABLE_FRAG
    121 	vchar_t *vid_frag = NULL;
    122 #endif
    123 #ifdef ENABLE_DPD
    124 	vchar_t *vid_dpd = NULL;
    125 #endif
    126 	/* validity check */
    127 	if (msg != NULL) {
    128 		plog(LLV_ERROR, LOCATION, NULL,
    129 			"msg has to be NULL in this function.\n");
    130 		goto end;
    131 	}
    132 	if (iph1->status != PHASE1ST_START) {
    133 		plog(LLV_ERROR, LOCATION, NULL,
    134 			"status mismatched %d.\n", iph1->status);
    135 		goto end;
    136 	}
    137 
    138 	/* create isakmp index */
    139 	memset(&iph1->index, 0, sizeof(iph1->index));
    140 	isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local);
    141 
    142 	/* create SA payload for my proposal */
    143 	iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf,
    144 					   iph1->rmconf->proposal);
    145 	if (iph1->sa == NULL)
    146 		goto end;
    147 
    148 	/* set SA payload to propose */
    149 	plist = isakmp_plist_append(plist, iph1->sa, ISAKMP_NPTYPE_SA);
    150 
    151 #ifdef ENABLE_NATT
    152 	/* set VID payload for NAT-T if NAT-T support allowed in the config file */
    153 	if (iph1->rmconf->nat_traversal)
    154 		plist = isakmp_plist_append_natt_vids(plist, vid_natt);
    155 #endif
    156 #ifdef ENABLE_HYBRID
    157 	/* Do we need Xauth VID? */
    158 	switch (iph1->rmconf->proposal->authmethod) {
    159 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
    160 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
    161 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
    162 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
    163 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
    164 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
    165 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
    166 		if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL)
    167 			plog(LLV_ERROR, LOCATION, NULL,
    168 			     "Xauth vendor ID generation failed\n");
    169 		else
    170 			plist = isakmp_plist_append(plist,
    171 			    vid_xauth, ISAKMP_NPTYPE_VID);
    172 		/*FALLTHROUGH*/
    173 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
    174 		if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL)
    175 			plog(LLV_ERROR, LOCATION, NULL,
    176 			     "Unity vendor ID generation failed\n");
    177 		else
    178 			plist = isakmp_plist_append(plist,
    179 			    vid_unity, ISAKMP_NPTYPE_VID);
    180 		break;
    181 	default:
    182 		break;
    183 	}
    184 #endif
    185 #ifdef ENABLE_FRAG
    186 	if (iph1->rmconf->ike_frag) {
    187 		if ((vid_frag = set_vendorid(VENDORID_FRAG)) == NULL) {
    188 			plog(LLV_ERROR, LOCATION, NULL,
    189 			    "Frag vendorID construction failed\n");
    190 		} else {
    191 			vid_frag = isakmp_frag_addcap(vid_frag,
    192 			    VENDORID_FRAG_IDENT);
    193 			plist = isakmp_plist_append(plist,
    194 			    vid_frag, ISAKMP_NPTYPE_VID);
    195 		}
    196 	}
    197 #endif
    198 #ifdef ENABLE_DPD
    199 	if(iph1->rmconf->dpd){
    200 		vid_dpd = set_vendorid(VENDORID_DPD);
    201 		if (vid_dpd != NULL)
    202 			plist = isakmp_plist_append(plist, vid_dpd,
    203 			    ISAKMP_NPTYPE_VID);
    204 	}
    205 #endif
    206 
    207 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
    208 
    209 #ifdef HAVE_PRINT_ISAKMP_C
    210 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
    211 #endif
    212 
    213 	/* send the packet, add to the schedule to resend */
    214 	if (isakmp_ph1send(iph1) == -1)
    215 		goto end;
    216 
    217 	iph1->status = PHASE1ST_MSG1SENT;
    218 
    219 	error = 0;
    220 
    221 end:
    222 #ifdef ENABLE_FRAG
    223 	if (vid_frag)
    224 		vfree(vid_frag);
    225 #endif
    226 #ifdef ENABLE_NATT
    227 	for (i = 0; i < MAX_NATT_VID_COUNT && vid_natt[i] != NULL; i++)
    228 		vfree(vid_natt[i]);
    229 #endif
    230 #ifdef ENABLE_HYBRID
    231 	if (vid_xauth != NULL)
    232 		vfree(vid_xauth);
    233 	if (vid_unity != NULL)
    234 		vfree(vid_unity);
    235 #endif
    236 #ifdef ENABLE_DPD
    237 	if (vid_dpd != NULL)
    238 		vfree(vid_dpd);
    239 #endif
    240 
    241 	return error;
    242 }
    243 
    244 /*
    245  * receive from responder
    246  * 	psk: HDR, SA
    247  * 	sig: HDR, SA
    248  * 	rsa: HDR, SA
    249  * 	rev: HDR, SA
    250  */
    251 int
    252 ident_i2recv(struct ph1handle *iph1, vchar_t *msg)
    253 {
    254 	vchar_t *pbuf = NULL;
    255 	struct isakmp_parse_t *pa;
    256 	vchar_t *satmp = NULL;
    257 	int error = -1;
    258 
    259 	/* validity check */
    260 	if (iph1->status != PHASE1ST_MSG1SENT) {
    261 		plog(LLV_ERROR, LOCATION, NULL,
    262 			"status mismatched %d.\n", iph1->status);
    263 		goto end;
    264 	}
    265 
    266 	/* validate the type of next payload */
    267 	/*
    268 	 * NOTE: RedCreek(as responder) attaches N[responder-lifetime] here,
    269 	 *	if proposal-lifetime > lifetime-redcreek-wants.
    270 	 *	(see doi-08 4.5.4)
    271 	 *	=> According to the seciton 4.6.3 in RFC 2407, This is illegal.
    272 	 * NOTE: we do not really care about ordering of VID and N.
    273 	 *	does it matters?
    274 	 * NOTE: even if there's multiple VID/N, we'll ignore them.
    275 	 */
    276 	pbuf = isakmp_parse(msg);
    277 	if (pbuf == NULL)
    278 		goto end;
    279 	pa = (struct isakmp_parse_t *)pbuf->v;
    280 
    281 	/* SA payload is fixed postion */
    282 	if (pa->type != ISAKMP_NPTYPE_SA) {
    283 		plog(LLV_ERROR, LOCATION, iph1->remote,
    284 			"received invalid next payload type %d, "
    285 			"expecting %d.\n",
    286 			pa->type, ISAKMP_NPTYPE_SA);
    287 		goto end;
    288 	}
    289 	if (isakmp_p2ph(&satmp, pa->ptr) < 0)
    290 		goto end;
    291 	pa++;
    292 
    293 	for (/*nothing*/;
    294 	     pa->type != ISAKMP_NPTYPE_NONE;
    295 	     pa++) {
    296 
    297 		switch (pa->type) {
    298 		case ISAKMP_NPTYPE_VID:
    299 			handle_vendorid(iph1, pa->ptr);
    300 			break;
    301 		default:
    302 			/* don't send information, see ident_r1recv() */
    303 			plog(LLV_ERROR, LOCATION, iph1->remote,
    304 				"ignore the packet, "
    305 				"received unexpecting payload type %d.\n",
    306 				pa->type);
    307 			goto end;
    308 		}
    309 	}
    310 
    311 #ifdef ENABLE_NATT
    312 	if (NATT_AVAILABLE(iph1))
    313 		plog(LLV_INFO, LOCATION, iph1->remote,
    314 		     "Selected NAT-T version: %s\n",
    315 		     vid_string_by_id(iph1->natt_options->version));
    316 #endif
    317 
    318 	/* check SA payload and set approval SA for use */
    319 	if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) {
    320 		plog(LLV_ERROR, LOCATION, iph1->remote,
    321 			"failed to get valid proposal.\n");
    322 		/* XXX send information */
    323 		goto end;
    324 	}
    325 	VPTRINIT(iph1->sa_ret);
    326 
    327 	iph1->status = PHASE1ST_MSG2RECEIVED;
    328 
    329 	error = 0;
    330 
    331 end:
    332 	if (pbuf)
    333 		vfree(pbuf);
    334 	if (satmp)
    335 		vfree(satmp);
    336 	return error;
    337 }
    338 
    339 /*
    340  * send to responder
    341  * 	psk: HDR, KE, Ni
    342  * 	sig: HDR, KE, Ni
    343  *   gssapi: HDR, KE, Ni, GSSi
    344  * 	rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
    345  * 	rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
    346  * 	          <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
    347  */
    348 int
    349 ident_i2send(struct ph1handle *iph1, vchar_t *msg)
    350 {
    351 	int error = -1;
    352 
    353 	/* validity check */
    354 	if (iph1->status != PHASE1ST_MSG2RECEIVED) {
    355 		plog(LLV_ERROR, LOCATION, NULL,
    356 			"status mismatched %d.\n", iph1->status);
    357 		goto end;
    358 	}
    359 
    360 	/* fix isakmp index */
    361 	memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck,
    362 		sizeof(cookie_t));
    363 
    364 	/* generate DH public value */
    365 	if (oakley_dh_generate(iph1->approval->dhgrp,
    366 				&iph1->dhpub, &iph1->dhpriv) < 0)
    367 		goto end;
    368 
    369 	/* generate NONCE value */
    370 	iph1->nonce = eay_set_random(iph1->rmconf->nonce_size);
    371 	if (iph1->nonce == NULL)
    372 		goto end;
    373 
    374 #ifdef HAVE_GSSAPI
    375 	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
    376 	    gssapi_get_itoken(iph1, NULL) < 0)
    377 		goto end;
    378 #endif
    379 
    380 	/* create buffer to send isakmp payload */
    381 	iph1->sendbuf = ident_ir2mx(iph1);
    382 	if (iph1->sendbuf == NULL)
    383 		goto end;
    384 
    385 #ifdef HAVE_PRINT_ISAKMP_C
    386 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
    387 #endif
    388 
    389 	/* send the packet, add to the schedule to resend */
    390 	if (isakmp_ph1send(iph1) == -1)
    391 		goto end;
    392 
    393 	/* the sending message is added to the received-list. */
    394 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
    395 		plog(LLV_ERROR , LOCATION, NULL,
    396 			"failed to add a response packet to the tree.\n");
    397 		goto end;
    398 	}
    399 
    400 	iph1->status = PHASE1ST_MSG2SENT;
    401 
    402 	error = 0;
    403 
    404 end:
    405 	return error;
    406 }
    407 
    408 /*
    409  * receive from responder
    410  * 	psk: HDR, KE, Nr
    411  * 	sig: HDR, KE, Nr [, CR ]
    412  *   gssapi: HDR, KE, Nr, GSSr
    413  * 	rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
    414  * 	rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
    415  */
    416 int
    417 ident_i3recv(struct ph1handle *iph1, vchar_t *msg)
    418 {
    419 	vchar_t *pbuf = NULL;
    420 	struct isakmp_parse_t *pa;
    421 	int error = -1;
    422 #ifdef HAVE_GSSAPI
    423 	vchar_t *gsstoken = NULL;
    424 #endif
    425 #ifdef ENABLE_NATT
    426 	vchar_t	*natd_received;
    427 	int natd_seq = 0, natd_verified;
    428 #endif
    429 
    430 	/* validity check */
    431 	if (iph1->status != PHASE1ST_MSG2SENT) {
    432 		plog(LLV_ERROR, LOCATION, NULL,
    433 			"status mismatched %d.\n", iph1->status);
    434 		goto end;
    435 	}
    436 
    437 	/* validate the type of next payload */
    438 	pbuf = isakmp_parse(msg);
    439 	if (pbuf == NULL)
    440 		goto end;
    441 
    442 	for (pa = (struct isakmp_parse_t *)pbuf->v;
    443 	     pa->type != ISAKMP_NPTYPE_NONE;
    444 	     pa++) {
    445 
    446 		switch (pa->type) {
    447 		case ISAKMP_NPTYPE_KE:
    448 			if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
    449 				goto end;
    450 			break;
    451 		case ISAKMP_NPTYPE_NONCE:
    452 			if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
    453 				goto end;
    454 			break;
    455 		case ISAKMP_NPTYPE_VID:
    456 			handle_vendorid(iph1, pa->ptr);
    457 			break;
    458 		case ISAKMP_NPTYPE_CR:
    459 			if (oakley_savecr(iph1, pa->ptr) < 0)
    460 				goto end;
    461 			break;
    462 #ifdef HAVE_GSSAPI
    463 		case ISAKMP_NPTYPE_GSS:
    464 			if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
    465 				goto end;
    466 			gssapi_save_received_token(iph1, gsstoken);
    467 			break;
    468 #endif
    469 
    470 #ifdef ENABLE_NATT
    471 		case ISAKMP_NPTYPE_NATD_DRAFT:
    472 		case ISAKMP_NPTYPE_NATD_RFC:
    473 			if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
    474 			    pa->type == iph1->natt_options->payload_nat_d) {
    475 				natd_received = NULL;
    476 				if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
    477 					goto end;
    478 
    479 				/* set both bits first so that we can clear them
    480 				   upon verifying hashes */
    481 				if (natd_seq == 0)
    482 					iph1->natt_flags |= NAT_DETECTED;
    483 
    484 				/* this function will clear appropriate bits bits
    485 				   from iph1->natt_flags */
    486 				natd_verified = natt_compare_addr_hash (iph1,
    487 					natd_received, natd_seq++);
    488 
    489 				plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
    490 					natd_seq - 1,
    491 					natd_verified ? "verified" : "doesn't match");
    492 
    493 				vfree (natd_received);
    494 				break;
    495 			}
    496 			/* passthrough to default... */
    497 #endif
    498 			/*FALLTHROUGH*/
    499 		default:
    500 			/* don't send information, see ident_r1recv() */
    501 			plog(LLV_ERROR, LOCATION, iph1->remote,
    502 				"ignore the packet, "
    503 				"received unexpecting payload type %d.\n",
    504 				pa->type);
    505 			goto end;
    506 		}
    507 	}
    508 
    509 #ifdef ENABLE_NATT
    510 	if (NATT_AVAILABLE(iph1)) {
    511 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
    512 		      iph1->natt_flags & NAT_DETECTED ?
    513 		      		"detected:" : "not detected",
    514 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
    515 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
    516 		if (iph1->natt_flags & NAT_DETECTED)
    517 			natt_float_ports (iph1);
    518 	}
    519 #endif
    520 
    521 	/* payload existency check */
    522 	if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
    523 		plog(LLV_ERROR, LOCATION, iph1->remote,
    524 			"few isakmp message received.\n");
    525 		goto end;
    526 	}
    527 
    528 	if (oakley_checkcr(iph1) < 0) {
    529 		/* Ignore this error in order to be interoperability. */
    530 		;
    531 	}
    532 
    533 	iph1->status = PHASE1ST_MSG3RECEIVED;
    534 
    535 	error = 0;
    536 
    537 end:
    538 #ifdef HAVE_GSSAPI
    539 	if (gsstoken)
    540 		vfree(gsstoken);
    541 #endif
    542 	if (pbuf)
    543 		vfree(pbuf);
    544 	if (error) {
    545 		VPTRINIT(iph1->dhpub_p);
    546 		VPTRINIT(iph1->nonce_p);
    547 		VPTRINIT(iph1->id_p);
    548 		VPTRINIT(iph1->cr_p);
    549 	}
    550 
    551 	return error;
    552 }
    553 
    554 /*
    555  * send to responder
    556  * 	psk: HDR*, IDi1, HASH_I
    557  * 	sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
    558  *   gssapi: HDR*, IDi1, < Gssi(n) | HASH_I >
    559  * 	rsa: HDR*, HASH_I
    560  * 	rev: HDR*, HASH_I
    561  */
    562 int
    563 ident_i3send(struct ph1handle *iph1, vchar_t *msg0)
    564 {
    565 	int error = -1;
    566 	int dohash = 1;
    567 #ifdef HAVE_GSSAPI
    568 	int len;
    569 #endif
    570 
    571 	/* validity check */
    572 	if (iph1->status != PHASE1ST_MSG3RECEIVED) {
    573 		plog(LLV_ERROR, LOCATION, NULL,
    574 			"status mismatched %d.\n", iph1->status);
    575 		goto end;
    576 	}
    577 
    578 	/* compute sharing secret of DH */
    579 	if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
    580 				iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
    581 		goto end;
    582 
    583 	/* generate SKEYIDs & IV & final cipher key */
    584 	if (oakley_skeyid(iph1) < 0)
    585 		goto end;
    586 	if (oakley_skeyid_dae(iph1) < 0)
    587 		goto end;
    588 	if (oakley_compute_enckey(iph1) < 0)
    589 		goto end;
    590 	if (oakley_newiv(iph1) < 0)
    591 		goto end;
    592 
    593 	/* make ID payload into isakmp status */
    594 	if (ipsecdoi_setid1(iph1) < 0)
    595 		goto end;
    596 
    597 #ifdef HAVE_GSSAPI
    598 	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
    599 	    gssapi_more_tokens(iph1)) {
    600 		plog(LLV_DEBUG, LOCATION, NULL, "calling get_itoken\n");
    601 		if (gssapi_get_itoken(iph1, &len) < 0)
    602 			goto end;
    603 		if (len != 0)
    604 			dohash = 0;
    605 	}
    606 #endif
    607 
    608 	/* generate HASH to send */
    609 	if (dohash) {
    610 		iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
    611 		if (iph1->hash == NULL)
    612 			goto end;
    613 	} else
    614 		iph1->hash = NULL;
    615 
    616 	/* set encryption flag */
    617 	iph1->flags |= ISAKMP_FLAG_E;
    618 
    619 	/* create HDR;ID;HASH payload */
    620 	iph1->sendbuf = ident_ir3mx(iph1);
    621 	if (iph1->sendbuf == NULL)
    622 		goto end;
    623 
    624 	/* send the packet, add to the schedule to resend */
    625 	if (isakmp_ph1send(iph1) == -1)
    626 		goto end;
    627 
    628 	/* the sending message is added to the received-list. */
    629 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg0) == -1) {
    630 		plog(LLV_ERROR , LOCATION, NULL,
    631 			"failed to add a response packet to the tree.\n");
    632 		goto end;
    633 	}
    634 
    635 	/* see handler.h about IV synchronization. */
    636 	memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l);
    637 
    638 	iph1->status = PHASE1ST_MSG3SENT;
    639 
    640 	error = 0;
    641 
    642 end:
    643 	return error;
    644 }
    645 
    646 /*
    647  * receive from responder
    648  * 	psk: HDR*, IDr1, HASH_R
    649  * 	sig: HDR*, IDr1, [ CERT, ] SIG_R
    650  *   gssapi: HDR*, IDr1, < GSSr(n) | HASH_R >
    651  * 	rsa: HDR*, HASH_R
    652  * 	rev: HDR*, HASH_R
    653  */
    654 int
    655 ident_i4recv(struct ph1handle *iph1, vchar_t *msg0)
    656 {
    657 	vchar_t *pbuf = NULL;
    658 	struct isakmp_parse_t *pa;
    659 	vchar_t *msg = NULL;
    660 	int error = -1;
    661 	int type;
    662 #ifdef HAVE_GSSAPI
    663 	vchar_t *gsstoken = NULL;
    664 #endif
    665 
    666 	/* validity check */
    667 	if (iph1->status != PHASE1ST_MSG3SENT) {
    668 		plog(LLV_ERROR, LOCATION, NULL,
    669 			"status mismatched %d.\n", iph1->status);
    670 		goto end;
    671 	}
    672 
    673 	/* decrypting */
    674 	if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
    675 		plog(LLV_ERROR, LOCATION, iph1->remote,
    676 			"ignore the packet, "
    677 			"expecting the packet encrypted.\n");
    678 		goto end;
    679 	}
    680 	msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive);
    681 	if (msg == NULL)
    682 		goto end;
    683 
    684 	/* validate the type of next payload */
    685 	pbuf = isakmp_parse(msg);
    686 	if (pbuf == NULL)
    687 		goto end;
    688 
    689 	iph1->pl_hash = NULL;
    690 
    691 	for (pa = (struct isakmp_parse_t *)pbuf->v;
    692 	     pa->type != ISAKMP_NPTYPE_NONE;
    693 	     pa++) {
    694 
    695 		switch (pa->type) {
    696 		case ISAKMP_NPTYPE_ID:
    697 			if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
    698 				goto end;
    699 			break;
    700 		case ISAKMP_NPTYPE_HASH:
    701 			iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
    702 			break;
    703 		case ISAKMP_NPTYPE_CERT:
    704 			if (oakley_savecert(iph1, pa->ptr) < 0)
    705 				goto end;
    706 			break;
    707 		case ISAKMP_NPTYPE_SIG:
    708 			if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
    709 				goto end;
    710 			break;
    711 #ifdef HAVE_GSSAPI
    712 		case ISAKMP_NPTYPE_GSS:
    713 			if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
    714 				goto end;
    715 			gssapi_save_received_token(iph1, gsstoken);
    716 			break;
    717 #endif
    718 		case ISAKMP_NPTYPE_VID:
    719 			handle_vendorid(iph1, pa->ptr);
    720 			break;
    721 		case ISAKMP_NPTYPE_N:
    722 			ident_recv_n(iph1, pa->ptr);
    723 			break;
    724 		default:
    725 			/* don't send information, see ident_r1recv() */
    726 			plog(LLV_ERROR, LOCATION, iph1->remote,
    727 				"ignore the packet, "
    728 				"received unexpecting payload type %d.\n",
    729 				pa->type);
    730 			goto end;
    731 		}
    732 	}
    733 
    734 	/* payload existency check */
    735 
    736 	/* verify identifier */
    737 	if (ipsecdoi_checkid1(iph1) != 0) {
    738 		plog(LLV_ERROR, LOCATION, iph1->remote,
    739 			"invalid ID payload.\n");
    740 		goto end;
    741 	}
    742 
    743 	/* validate authentication value */
    744 #ifdef HAVE_GSSAPI
    745 	if (gsstoken == NULL) {
    746 #endif
    747 		type = oakley_validate_auth(iph1);
    748 		if (type != 0) {
    749 			if (type == -1) {
    750 				/* msg printed inner oakley_validate_auth() */
    751 				goto end;
    752 			}
    753 			evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
    754 			isakmp_info_send_n1(iph1, type, NULL);
    755 			goto end;
    756 		}
    757 #ifdef HAVE_GSSAPI
    758 	}
    759 #endif
    760 
    761 	/*
    762 	 * XXX: Should we do compare two addresses, ph1handle's and ID
    763 	 * payload's.
    764 	 */
    765 
    766 	plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID:");
    767 	plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l);
    768 
    769 	/* see handler.h about IV synchronization. */
    770 	memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l);
    771 
    772 	/*
    773 	 * If we got a GSS token, we need to this roundtrip again.
    774 	 */
    775 #ifdef HAVE_GSSAPI
    776 	iph1->status = gsstoken != 0 ? PHASE1ST_MSG3RECEIVED :
    777 	    PHASE1ST_MSG4RECEIVED;
    778 #else
    779 	iph1->status = PHASE1ST_MSG4RECEIVED;
    780 #endif
    781 
    782 	error = 0;
    783 
    784 end:
    785 	if (pbuf)
    786 		vfree(pbuf);
    787 	if (msg)
    788 		vfree(msg);
    789 #ifdef HAVE_GSSAPI
    790 	if (gsstoken)
    791 		vfree(gsstoken);
    792 #endif
    793 
    794 	if (error) {
    795 		VPTRINIT(iph1->id_p);
    796 		VPTRINIT(iph1->cert_p);
    797 		VPTRINIT(iph1->crl_p);
    798 		VPTRINIT(iph1->sig_p);
    799 	}
    800 
    801 	return error;
    802 }
    803 
    804 /*
    805  * status update and establish isakmp sa.
    806  */
    807 /*ARGSUSED*/
    808 int
    809 ident_i4send(struct ph1handle *iph1, vchar_t *msg __unused)
    810 {
    811 	int error = -1;
    812 
    813 	/* validity check */
    814 	if (iph1->status != PHASE1ST_MSG4RECEIVED) {
    815 		plog(LLV_ERROR, LOCATION, NULL,
    816 			"status mismatched %d.\n", iph1->status);
    817 		goto end;
    818 	}
    819 
    820 	/* see handler.h about IV synchronization. */
    821 	memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l);
    822 
    823 	iph1->status = PHASE1ST_ESTABLISHED;
    824 
    825 	error = 0;
    826 
    827 end:
    828 	return error;
    829 }
    830 
    831 /*
    832  * receive from initiator
    833  * 	psk: HDR, SA
    834  * 	sig: HDR, SA
    835  * 	rsa: HDR, SA
    836  * 	rev: HDR, SA
    837  */
    838 int
    839 ident_r1recv(struct ph1handle *iph1, vchar_t *msg)
    840 {
    841 	vchar_t *pbuf = NULL;
    842 	struct isakmp_parse_t *pa;
    843 	int error = -1;
    844 	int vid_numeric;
    845 
    846 	/* validity check */
    847 	if (iph1->status != PHASE1ST_START) {
    848 		plog(LLV_ERROR, LOCATION, NULL,
    849 			"status mismatched %d.\n", iph1->status);
    850 		goto end;
    851 	}
    852 
    853 	/* validate the type of next payload */
    854 	/*
    855 	 * NOTE: XXX even if multiple VID, we'll silently ignore those.
    856 	 */
    857 	pbuf = isakmp_parse(msg);
    858 	if (pbuf == NULL)
    859 		goto end;
    860 	pa = (struct isakmp_parse_t *)pbuf->v;
    861 
    862 	/* check the position of SA payload */
    863 	if (pa->type != ISAKMP_NPTYPE_SA) {
    864 		plog(LLV_ERROR, LOCATION, iph1->remote,
    865 			"received invalid next payload type %d, "
    866 			"expecting %d.\n",
    867 			pa->type, ISAKMP_NPTYPE_SA);
    868 		goto end;
    869 	}
    870 	if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0)
    871 		goto end;
    872 	pa++;
    873 
    874 	for (/*nothing*/;
    875 	     pa->type != ISAKMP_NPTYPE_NONE;
    876 	     pa++) {
    877 
    878 		switch (pa->type) {
    879 		case ISAKMP_NPTYPE_VID:
    880 			vid_numeric = handle_vendorid(iph1, pa->ptr);
    881 #ifdef ENABLE_FRAG
    882 			if ((vid_numeric == VENDORID_FRAG) &&
    883 			    (vendorid_frag_cap(pa->ptr) & VENDORID_FRAG_IDENT))
    884 				iph1->frag = 1;
    885 #endif
    886 			break;
    887 		default:
    888 			/*
    889 			 * We don't send information to the peer even
    890 			 * if we received malformed packet.  Because we
    891 			 * can't distinguish the malformed packet and
    892 			 * the re-sent packet.  And we do same behavior
    893 			 * when we expect encrypted packet.
    894 			 */
    895 			plog(LLV_ERROR, LOCATION, iph1->remote,
    896 				"ignore the packet, "
    897 				"received unexpecting payload type %d.\n",
    898 				pa->type);
    899 			goto end;
    900 		}
    901 	}
    902 
    903 #ifdef ENABLE_NATT
    904 	if (NATT_AVAILABLE(iph1))
    905 		plog(LLV_INFO, LOCATION, iph1->remote,
    906 		     "Selected NAT-T version: %s\n",
    907 		     vid_string_by_id(iph1->natt_options->version));
    908 #endif
    909 
    910 	/* check SA payload and set approval SA for use */
    911 	if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) {
    912 		plog(LLV_ERROR, LOCATION, iph1->remote,
    913 			"failed to get valid proposal.\n");
    914 		/* XXX send information */
    915 		goto end;
    916 	}
    917 
    918 	iph1->status = PHASE1ST_MSG1RECEIVED;
    919 
    920 	error = 0;
    921 
    922 end:
    923 	if (pbuf)
    924 		vfree(pbuf);
    925 	if (error) {
    926 		VPTRINIT(iph1->sa);
    927 	}
    928 
    929 	return error;
    930 }
    931 
    932 /*
    933  * send to initiator
    934  * 	psk: HDR, SA
    935  * 	sig: HDR, SA
    936  * 	rsa: HDR, SA
    937  * 	rev: HDR, SA
    938  */
    939 int
    940 ident_r1send(struct ph1handle *iph1, vchar_t *msg)
    941 {
    942 	struct payload_list *plist = NULL;
    943 	int error = -1;
    944 	vchar_t *gss_sa = NULL;
    945 #ifdef HAVE_GSSAPI
    946 	int free_gss_sa = 0;
    947 #endif
    948 #ifdef ENABLE_NATT
    949 	vchar_t *vid_natt = NULL;
    950 #endif
    951 #ifdef ENABLE_HYBRID
    952         vchar_t *vid_xauth = NULL;
    953         vchar_t *vid_unity = NULL;
    954 #endif
    955 #ifdef ENABLE_DPD
    956 	vchar_t *vid_dpd = NULL;
    957 #endif
    958 #ifdef ENABLE_FRAG
    959 	vchar_t *vid_frag = NULL;
    960 #endif
    961 
    962 	/* validity check */
    963 	if (iph1->status != PHASE1ST_MSG1RECEIVED) {
    964 		plog(LLV_ERROR, LOCATION, NULL,
    965 			"status mismatched %d.\n", iph1->status);
    966 		goto end;
    967 	}
    968 
    969 	/* set responder's cookie */
    970 	isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local);
    971 
    972 #ifdef HAVE_GSSAPI
    973 	if (iph1->approval->gssid != NULL) {
    974 		gss_sa = ipsecdoi_setph1proposal(iph1->rmconf, iph1->approval);
    975 		if (gss_sa != iph1->sa_ret)
    976 			free_gss_sa = 1;
    977 	} else
    978 #endif
    979 		gss_sa = iph1->sa_ret;
    980 
    981 	/* set SA payload to reply */
    982 	plist = isakmp_plist_append(plist, gss_sa, ISAKMP_NPTYPE_SA);
    983 
    984 #ifdef ENABLE_HYBRID
    985 	if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) {
    986 		plog (LLV_INFO, LOCATION, NULL, "Adding xauth VID payload.\n");
    987 		if ((vid_xauth = set_vendorid(VENDORID_XAUTH)) == NULL) {
    988 			plog(LLV_ERROR, LOCATION, NULL,
    989 			    "Cannot create Xauth vendor ID\n");
    990 			goto end;
    991 		}
    992 		plist = isakmp_plist_append(plist,
    993 		    vid_xauth, ISAKMP_NPTYPE_VID);
    994 	}
    995 
    996 	if (iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_UNITY) {
    997 		if ((vid_unity = set_vendorid(VENDORID_UNITY)) == NULL) {
    998 			plog(LLV_ERROR, LOCATION, NULL,
    999 			    "Cannot create Unity vendor ID\n");
   1000 			goto end;
   1001 		}
   1002 		plist = isakmp_plist_append(plist,
   1003 		    vid_unity, ISAKMP_NPTYPE_VID);
   1004 	}
   1005 #endif
   1006 #ifdef ENABLE_NATT
   1007 	/* Has the peer announced NAT-T? */
   1008 	if (NATT_AVAILABLE(iph1))
   1009 		vid_natt = set_vendorid(iph1->natt_options->version);
   1010 
   1011 	if (vid_natt)
   1012 		plist = isakmp_plist_append(plist, vid_natt, ISAKMP_NPTYPE_VID);
   1013 #endif
   1014 #ifdef ENABLE_DPD
   1015 	if (iph1->dpd_support) {
   1016 		vid_dpd = set_vendorid(VENDORID_DPD);
   1017 		if (vid_dpd != NULL)
   1018 			plist = isakmp_plist_append(plist, vid_dpd, ISAKMP_NPTYPE_VID);
   1019 	}
   1020 #endif
   1021 #ifdef ENABLE_FRAG
   1022 	if (iph1->frag) {
   1023 		vid_frag = set_vendorid(VENDORID_FRAG);
   1024 		if (vid_frag != NULL)
   1025 			vid_frag = isakmp_frag_addcap(vid_frag,
   1026 			    VENDORID_FRAG_IDENT);
   1027 		if (vid_frag == NULL)
   1028 			plog(LLV_ERROR, LOCATION, NULL,
   1029 			    "Frag vendorID construction failed\n");
   1030 		else
   1031 			plist = isakmp_plist_append(plist,
   1032 			     vid_frag, ISAKMP_NPTYPE_VID);
   1033 	}
   1034 #endif
   1035 
   1036 	iph1->sendbuf = isakmp_plist_set_all (&plist, iph1);
   1037 
   1038 #ifdef HAVE_PRINT_ISAKMP_C
   1039 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
   1040 #endif
   1041 
   1042 	/* send the packet, add to the schedule to resend */
   1043 	if (isakmp_ph1send(iph1) == -1)
   1044 		goto end;
   1045 
   1046 	/* the sending message is added to the received-list. */
   1047 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
   1048 		plog(LLV_ERROR , LOCATION, NULL,
   1049 			"failed to add a response packet to the tree.\n");
   1050 		goto end;
   1051 	}
   1052 
   1053 	iph1->status = PHASE1ST_MSG1SENT;
   1054 
   1055 	error = 0;
   1056 
   1057 end:
   1058 #ifdef HAVE_GSSAPI
   1059 	if (free_gss_sa)
   1060 		vfree(gss_sa);
   1061 #endif
   1062 #ifdef ENABLE_NATT
   1063 	if (vid_natt)
   1064 		vfree(vid_natt);
   1065 #endif
   1066 #ifdef ENABLE_HYBRID
   1067 	if (vid_xauth != NULL)
   1068 		vfree(vid_xauth);
   1069 	if (vid_unity != NULL)
   1070 		vfree(vid_unity);
   1071 #endif
   1072 #ifdef ENABLE_DPD
   1073 	if (vid_dpd != NULL)
   1074 		vfree(vid_dpd);
   1075 #endif
   1076 #ifdef ENABLE_FRAG
   1077 	if (vid_frag != NULL)
   1078 		vfree(vid_frag);
   1079 #endif
   1080 
   1081 	return error;
   1082 }
   1083 
   1084 /*
   1085  * receive from initiator
   1086  * 	psk: HDR, KE, Ni
   1087  * 	sig: HDR, KE, Ni
   1088  *   gssapi: HDR, KE, Ni, GSSi
   1089  * 	rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
   1090  * 	rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
   1091  * 	          <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
   1092  */
   1093 int
   1094 ident_r2recv(struct ph1handle *iph1, vchar_t *msg)
   1095 {
   1096 	vchar_t *pbuf = NULL;
   1097 	struct isakmp_parse_t *pa;
   1098 	int error = -1;
   1099 #ifdef HAVE_GSSAPI
   1100 	vchar_t *gsstoken = NULL;
   1101 #endif
   1102 #ifdef ENABLE_NATT
   1103 	int natd_seq = 0;
   1104 #endif
   1105 
   1106 	/* validity check */
   1107 	if (iph1->status != PHASE1ST_MSG1SENT) {
   1108 		plog(LLV_ERROR, LOCATION, NULL,
   1109 			"status mismatched %d.\n", iph1->status);
   1110 		goto end;
   1111 	}
   1112 
   1113 	/* validate the type of next payload */
   1114 	pbuf = isakmp_parse(msg);
   1115 	if (pbuf == NULL)
   1116 		goto end;
   1117 
   1118 	for (pa = (struct isakmp_parse_t *)pbuf->v;
   1119 	     pa->type != ISAKMP_NPTYPE_NONE;
   1120 	     pa++) {
   1121 		switch (pa->type) {
   1122 		case ISAKMP_NPTYPE_KE:
   1123 			if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0)
   1124 				goto end;
   1125 			break;
   1126 		case ISAKMP_NPTYPE_NONCE:
   1127 			if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0)
   1128 				goto end;
   1129 			break;
   1130 		case ISAKMP_NPTYPE_VID:
   1131 			handle_vendorid(iph1, pa->ptr);
   1132 			break;
   1133 		case ISAKMP_NPTYPE_CR:
   1134 			plog(LLV_WARNING, LOCATION, iph1->remote,
   1135 				"CR received, ignore it. "
   1136 				"It should be in other exchange.\n");
   1137 			break;
   1138 #ifdef HAVE_GSSAPI
   1139 		case ISAKMP_NPTYPE_GSS:
   1140 			if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
   1141 				goto end;
   1142 			gssapi_save_received_token(iph1, gsstoken);
   1143 			break;
   1144 #endif
   1145 
   1146 #ifdef ENABLE_NATT
   1147 		case ISAKMP_NPTYPE_NATD_DRAFT:
   1148 		case ISAKMP_NPTYPE_NATD_RFC:
   1149 			if (NATT_AVAILABLE(iph1) && iph1->natt_options != NULL &&
   1150 				pa->type == iph1->natt_options->payload_nat_d)
   1151 			{
   1152 				vchar_t *natd_received = NULL;
   1153 				int natd_verified;
   1154 
   1155 				if (isakmp_p2ph (&natd_received, pa->ptr) < 0)
   1156 					goto end;
   1157 
   1158 				if (natd_seq == 0)
   1159 					iph1->natt_flags |= NAT_DETECTED;
   1160 
   1161 				natd_verified = natt_compare_addr_hash (iph1,
   1162 					natd_received, natd_seq++);
   1163 
   1164 				plog (LLV_INFO, LOCATION, NULL, "NAT-D payload #%d %s\n",
   1165 					natd_seq - 1,
   1166 					natd_verified ? "verified" : "doesn't match");
   1167 
   1168 				vfree (natd_received);
   1169 				break;
   1170 			}
   1171 			/* passthrough to default... */
   1172 #endif
   1173 			/*FALLTHROUGH*/
   1174 		default:
   1175 			/* don't send information, see ident_r1recv() */
   1176 			plog(LLV_ERROR, LOCATION, iph1->remote,
   1177 				"ignore the packet, "
   1178 				"received unexpecting payload type %d.\n",
   1179 				pa->type);
   1180 			goto end;
   1181 		}
   1182 	}
   1183 
   1184 #ifdef ENABLE_NATT
   1185 	if (NATT_AVAILABLE(iph1))
   1186 		plog (LLV_INFO, LOCATION, NULL, "NAT %s %s%s\n",
   1187 		      iph1->natt_flags & NAT_DETECTED ?
   1188 		      		"detected:" : "not detected",
   1189 		      iph1->natt_flags & NAT_DETECTED_ME ? "ME " : "",
   1190 		      iph1->natt_flags & NAT_DETECTED_PEER ? "PEER" : "");
   1191 #endif
   1192 
   1193 	/* payload existency check */
   1194 	if (iph1->dhpub_p == NULL || iph1->nonce_p == NULL) {
   1195 		plog(LLV_ERROR, LOCATION, iph1->remote,
   1196 			"few isakmp message received.\n");
   1197 		goto end;
   1198 	}
   1199 
   1200 	iph1->status = PHASE1ST_MSG2RECEIVED;
   1201 
   1202 	error = 0;
   1203 
   1204 end:
   1205 	if (pbuf)
   1206 		vfree(pbuf);
   1207 #ifdef HAVE_GSSAPI
   1208 	if (gsstoken)
   1209 		vfree(gsstoken);
   1210 #endif
   1211 
   1212 	if (error) {
   1213 		VPTRINIT(iph1->dhpub_p);
   1214 		VPTRINIT(iph1->nonce_p);
   1215 		VPTRINIT(iph1->id_p);
   1216 	}
   1217 
   1218 	return error;
   1219 }
   1220 
   1221 /*
   1222  * send to initiator
   1223  * 	psk: HDR, KE, Nr
   1224  * 	sig: HDR, KE, Nr [, CR ]
   1225  *   gssapi: HDR, KE, Nr, GSSr
   1226  * 	rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
   1227  * 	rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
   1228  */
   1229 int
   1230 ident_r2send(struct ph1handle *iph1, vchar_t *msg)
   1231 {
   1232 	int error = -1;
   1233 
   1234 	/* validity check */
   1235 	if (iph1->status != PHASE1ST_MSG2RECEIVED) {
   1236 		plog(LLV_ERROR, LOCATION, NULL,
   1237 			"status mismatched %d.\n", iph1->status);
   1238 		goto end;
   1239 	}
   1240 
   1241 	/* generate DH public value */
   1242 	if (oakley_dh_generate(iph1->approval->dhgrp,
   1243 				&iph1->dhpub, &iph1->dhpriv) < 0)
   1244 		goto end;
   1245 
   1246 	/* generate NONCE value */
   1247 	iph1->nonce = eay_set_random(RMCONF_NONCE_SIZE(iph1->rmconf));
   1248 	if (iph1->nonce == NULL)
   1249 		goto end;
   1250 
   1251 #ifdef HAVE_GSSAPI
   1252 	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
   1253 		gssapi_get_rtoken(iph1, NULL);
   1254 #endif
   1255 
   1256 	/* create HDR;KE;NONCE payload */
   1257 	iph1->sendbuf = ident_ir2mx(iph1);
   1258 	if (iph1->sendbuf == NULL)
   1259 		goto end;
   1260 
   1261 #ifdef HAVE_PRINT_ISAKMP_C
   1262 	isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0);
   1263 #endif
   1264 
   1265 	/* send the packet, add to the schedule to resend */
   1266 	if (isakmp_ph1send(iph1) == -1)
   1267 		goto end;
   1268 
   1269 	/* the sending message is added to the received-list. */
   1270 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
   1271 		plog(LLV_ERROR , LOCATION, NULL,
   1272 			"failed to add a response packet to the tree.\n");
   1273 		goto end;
   1274 	}
   1275 
   1276 	/* compute sharing secret of DH */
   1277 	if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub,
   1278 				iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0)
   1279 		goto end;
   1280 
   1281 	/* generate SKEYIDs & IV & final cipher key */
   1282 	if (oakley_skeyid(iph1) < 0)
   1283 		goto end;
   1284 	if (oakley_skeyid_dae(iph1) < 0)
   1285 		goto end;
   1286 	if (oakley_compute_enckey(iph1) < 0)
   1287 		goto end;
   1288 	if (oakley_newiv(iph1) < 0)
   1289 		goto end;
   1290 
   1291 	iph1->status = PHASE1ST_MSG2SENT;
   1292 
   1293 	error = 0;
   1294 
   1295 end:
   1296 	return error;
   1297 }
   1298 
   1299 /*
   1300  * receive from initiator
   1301  * 	psk: HDR*, IDi1, HASH_I
   1302  * 	sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
   1303  *   gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I >
   1304  * 	rsa: HDR*, HASH_I
   1305  * 	rev: HDR*, HASH_I
   1306  */
   1307 int
   1308 ident_r3recv(struct ph1handle *iph1, vchar_t *msg0)
   1309 {
   1310 	vchar_t *msg = NULL;
   1311 	vchar_t *pbuf = NULL;
   1312 	struct isakmp_parse_t *pa;
   1313 	int error = -1;
   1314 	int type;
   1315 #ifdef HAVE_GSSAPI
   1316 	vchar_t *gsstoken = NULL;
   1317 #endif
   1318 
   1319 	/* validity check */
   1320 	if (iph1->status != PHASE1ST_MSG2SENT) {
   1321 		plog(LLV_ERROR, LOCATION, NULL,
   1322 			"status mismatched %d.\n", iph1->status);
   1323 		goto end;
   1324 	}
   1325 
   1326 	/* decrypting */
   1327 	if (!ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) {
   1328 		plog(LLV_ERROR, LOCATION, iph1->remote,
   1329 			"reject the packet, "
   1330 			"expecting the packet encrypted.\n");
   1331 		goto end;
   1332 	}
   1333 	msg = oakley_do_decrypt(iph1, msg0, iph1->ivm->iv, iph1->ivm->ive);
   1334 	if (msg == NULL)
   1335 		goto end;
   1336 
   1337 	/* validate the type of next payload */
   1338 	pbuf = isakmp_parse(msg);
   1339 	if (pbuf == NULL)
   1340 		goto end;
   1341 
   1342 	iph1->pl_hash = NULL;
   1343 
   1344 	for (pa = (struct isakmp_parse_t *)pbuf->v;
   1345 	     pa->type != ISAKMP_NPTYPE_NONE;
   1346 	     pa++) {
   1347 
   1348 		switch (pa->type) {
   1349 		case ISAKMP_NPTYPE_ID:
   1350 			if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0)
   1351 				goto end;
   1352 			if (resolveph1rmconf(iph1) < 0)
   1353 				goto end;
   1354 			break;
   1355 		case ISAKMP_NPTYPE_HASH:
   1356 			iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr;
   1357 			break;
   1358 		case ISAKMP_NPTYPE_CR:
   1359 			if (oakley_savecr(iph1, pa->ptr) < 0)
   1360 				goto end;
   1361 			break;
   1362 		case ISAKMP_NPTYPE_CERT:
   1363 			if (oakley_savecert(iph1, pa->ptr) < 0)
   1364 				goto end;
   1365 			break;
   1366 		case ISAKMP_NPTYPE_SIG:
   1367 			if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0)
   1368 				goto end;
   1369 			break;
   1370 #ifdef HAVE_GSSAPI
   1371 		case ISAKMP_NPTYPE_GSS:
   1372 			if (isakmp_p2ph(&gsstoken, pa->ptr) < 0)
   1373 				goto end;
   1374 			gssapi_save_received_token(iph1, gsstoken);
   1375 			break;
   1376 #endif
   1377 		case ISAKMP_NPTYPE_VID:
   1378 			handle_vendorid(iph1, pa->ptr);
   1379 			break;
   1380 		case ISAKMP_NPTYPE_N:
   1381 			ident_recv_n(iph1, pa->ptr);
   1382 			break;
   1383 		default:
   1384 			/* don't send information, see ident_r1recv() */
   1385 			plog(LLV_ERROR, LOCATION, iph1->remote,
   1386 				"ignore the packet, "
   1387 				"received unexpecting payload type %d.\n",
   1388 				pa->type);
   1389 			goto end;
   1390 		}
   1391 	}
   1392 
   1393 	/* payload existency check */
   1394 	/* XXX same as ident_i4recv(), should be merged. */
   1395     {
   1396 	int ng = 0;
   1397 
   1398 	switch (iph1->approval->authmethod) {
   1399 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
   1400 #ifdef ENABLE_HYBRID
   1401 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
   1402 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
   1403 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
   1404 #endif
   1405 		if (iph1->id_p == NULL || iph1->pl_hash == NULL)
   1406 			ng++;
   1407 		break;
   1408 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
   1409 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
   1410 #ifdef ENABLE_HYBRID
   1411 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
   1412 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
   1413 #endif
   1414 		if (iph1->id_p == NULL || iph1->sig_p == NULL)
   1415 			ng++;
   1416 		break;
   1417 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
   1418 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
   1419 #ifdef ENABLE_HYBRID
   1420 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
   1421 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
   1422 #endif
   1423 		if (iph1->pl_hash == NULL)
   1424 			ng++;
   1425 		break;
   1426 #ifdef HAVE_GSSAPI
   1427 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
   1428 		if (gsstoken == NULL && iph1->pl_hash == NULL)
   1429 			ng++;
   1430 		break;
   1431 #endif
   1432 	default:
   1433 		plog(LLV_ERROR, LOCATION, iph1->remote,
   1434 			"invalid authmethod %d why ?\n",
   1435 			iph1->approval->authmethod);
   1436 		goto end;
   1437 	}
   1438 	if (ng) {
   1439 		plog(LLV_ERROR, LOCATION, iph1->remote,
   1440 			"few isakmp message received.\n");
   1441 		goto end;
   1442 	}
   1443     }
   1444 
   1445 	/* verify identifier */
   1446 	if (ipsecdoi_checkid1(iph1) != 0) {
   1447 		plog(LLV_ERROR, LOCATION, iph1->remote,
   1448 			"invalid ID payload.\n");
   1449 		goto end;
   1450 	}
   1451 
   1452 	/* validate authentication value */
   1453 #ifdef HAVE_GSSAPI
   1454 	if (gsstoken == NULL) {
   1455 #endif
   1456 		type = oakley_validate_auth(iph1);
   1457 		if (type != 0) {
   1458 			if (type == -1) {
   1459 				/* msg printed inner oakley_validate_auth() */
   1460 				goto end;
   1461 			}
   1462 			evt_phase1(iph1, EVT_PHASE1_AUTH_FAILED, NULL);
   1463 			isakmp_info_send_n1(iph1, type, NULL);
   1464 			goto end;
   1465 		}
   1466 #ifdef HAVE_GSSAPI
   1467 	}
   1468 #endif
   1469 
   1470 	if (oakley_checkcr(iph1) < 0) {
   1471 		/* Ignore this error in order to be interoperability. */
   1472 		;
   1473 	}
   1474 
   1475 	/*
   1476 	 * XXX: Should we do compare two addresses, ph1handle's and ID
   1477 	 * payload's.
   1478 	 */
   1479 
   1480 	plog(LLV_DEBUG, LOCATION, iph1->remote, "peer's ID\n");
   1481 	plogdump(LLV_DEBUG, iph1->id_p->v, iph1->id_p->l);
   1482 
   1483 	/* see handler.h about IV synchronization. */
   1484 	memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->ive->l);
   1485 
   1486 #ifdef HAVE_GSSAPI
   1487 	iph1->status = gsstoken != NULL ? PHASE1ST_MSG2RECEIVED :
   1488 	    PHASE1ST_MSG3RECEIVED;
   1489 #else
   1490 	iph1->status = PHASE1ST_MSG3RECEIVED;
   1491 #endif
   1492 
   1493 	error = 0;
   1494 
   1495 end:
   1496 	if (pbuf)
   1497 		vfree(pbuf);
   1498 	if (msg)
   1499 		vfree(msg);
   1500 #ifdef HAVE_GSSAPI
   1501 	if (gsstoken)
   1502 		vfree(gsstoken);
   1503 #endif
   1504 
   1505 	if (error) {
   1506 		VPTRINIT(iph1->id_p);
   1507 		VPTRINIT(iph1->cert_p);
   1508 		VPTRINIT(iph1->crl_p);
   1509 		VPTRINIT(iph1->sig_p);
   1510 		VPTRINIT(iph1->cr_p);
   1511 	}
   1512 
   1513 	return error;
   1514 }
   1515 
   1516 /*
   1517  * send to initiator
   1518  * 	psk: HDR*, IDr1, HASH_R
   1519  * 	sig: HDR*, IDr1, [ CERT, ] SIG_R
   1520  *   gssapi: HDR*, IDr1, < GSSr(n) | HASH_R >
   1521  * 	rsa: HDR*, HASH_R
   1522  * 	rev: HDR*, HASH_R
   1523  */
   1524 int
   1525 ident_r3send(struct ph1handle *iph1, vchar_t *msg)
   1526 {
   1527 	int error = -1;
   1528 	int dohash = 1;
   1529 #ifdef HAVE_GSSAPI
   1530 	int len;
   1531 #endif
   1532 
   1533 	/* validity check */
   1534 	if (iph1->status != PHASE1ST_MSG3RECEIVED) {
   1535 		plog(LLV_ERROR, LOCATION, NULL,
   1536 			"status mismatched %d.\n", iph1->status);
   1537 		goto end;
   1538 	}
   1539 
   1540 	/* make ID payload into isakmp status */
   1541 	if (ipsecdoi_setid1(iph1) < 0)
   1542 		goto end;
   1543 
   1544 #ifdef HAVE_GSSAPI
   1545 	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB &&
   1546 	    gssapi_more_tokens(iph1)) {
   1547 		gssapi_get_rtoken(iph1, &len);
   1548 		if (len != 0)
   1549 			dohash = 0;
   1550 	}
   1551 #endif
   1552 
   1553 	if (dohash) {
   1554 		/* generate HASH to send */
   1555 		plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n");
   1556 		iph1->hash = oakley_ph1hash_common(iph1, GENERATE);
   1557 		if (iph1->hash == NULL)
   1558 			goto end;
   1559 	} else
   1560 		iph1->hash = NULL;
   1561 
   1562 	/* set encryption flag */
   1563 	iph1->flags |= ISAKMP_FLAG_E;
   1564 
   1565 	/* create HDR;ID;HASH payload */
   1566 	iph1->sendbuf = ident_ir3mx(iph1);
   1567 	if (iph1->sendbuf == NULL)
   1568 		goto end;
   1569 
   1570 	/* send HDR;ID;HASH to responder */
   1571 	if (isakmp_send(iph1, iph1->sendbuf) < 0)
   1572 		goto end;
   1573 
   1574 	/* the sending message is added to the received-list. */
   1575 	if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) {
   1576 		plog(LLV_ERROR , LOCATION, NULL,
   1577 			"failed to add a response packet to the tree.\n");
   1578 		goto end;
   1579 	}
   1580 
   1581 	/* see handler.h about IV synchronization. */
   1582 	memcpy(iph1->ivm->ive->v, iph1->ivm->iv->v, iph1->ivm->iv->l);
   1583 
   1584 	iph1->status = PHASE1ST_ESTABLISHED;
   1585 
   1586 	error = 0;
   1587 
   1588 end:
   1589 
   1590 	return error;
   1591 }
   1592 
   1593 /*
   1594  * This is used in main mode for:
   1595  * initiator's 3rd exchange send to responder
   1596  * 	psk: HDR, KE, Ni
   1597  * 	sig: HDR, KE, Ni
   1598  * 	rsa: HDR, KE, [ HASH(1), ] <IDi1_b>PubKey_r, <Ni_b>PubKey_r
   1599  * 	rev: HDR, [ HASH(1), ] <Ni_b>Pubkey_r, <KE_b>Ke_i,
   1600  * 	          <IDi1_b>Ke_i, [<<Cert-I_b>Ke_i]
   1601  * responders 2nd exchnage send to initiator
   1602  * 	psk: HDR, KE, Nr
   1603  * 	sig: HDR, KE, Nr [, CR ]
   1604  * 	rsa: HDR, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i
   1605  * 	rev: HDR, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDr1_b>Ke_r,
   1606  */
   1607 static vchar_t *
   1608 ident_ir2mx(struct ph1handle *iph1)
   1609 {
   1610 	vchar_t *buf = 0;
   1611 	struct payload_list *plist = NULL;
   1612 	vchar_t *vid = NULL;
   1613 	int error = -1;
   1614 #ifdef HAVE_GSSAPI
   1615 	vchar_t *gsstoken = NULL;
   1616 #endif
   1617 #ifdef ENABLE_NATT
   1618 	vchar_t *natd[2] = { NULL, NULL };
   1619 #endif
   1620 
   1621 #ifdef HAVE_GSSAPI
   1622 	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) {
   1623 		if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) {
   1624 			plog(LLV_ERROR, LOCATION, NULL,
   1625 			     "Failed to get gssapi token.\n");
   1626 			goto end;
   1627 		}
   1628 	}
   1629 #endif
   1630 
   1631 	/* create isakmp KE payload */
   1632 	plist = isakmp_plist_append(plist, iph1->dhpub, ISAKMP_NPTYPE_KE);
   1633 
   1634 	/* create isakmp NONCE payload */
   1635 	plist = isakmp_plist_append(plist, iph1->nonce, ISAKMP_NPTYPE_NONCE);
   1636 
   1637 #ifdef HAVE_GSSAPI
   1638 	if (iph1->approval->authmethod == OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB)
   1639 		plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
   1640 #endif
   1641 
   1642 	/* append vendor id, if needed */
   1643 	if (vid)
   1644 		plist = isakmp_plist_append(plist, vid, ISAKMP_NPTYPE_VID);
   1645 
   1646 	/* create CR if need */
   1647 	if (iph1->side == RESPONDER &&
   1648 	    oakley_needcr(iph1->approval->authmethod))
   1649 		plist = oakley_append_cr(plist, iph1);
   1650 
   1651 #ifdef ENABLE_NATT
   1652 	/* generate and append NAT-D payloads */
   1653 	if (NATT_AVAILABLE(iph1) && iph1->status == PHASE1ST_MSG2RECEIVED)
   1654 	{
   1655 		if ((natd[0] = natt_hash_addr (iph1, iph1->remote)) == NULL) {
   1656 			plog(LLV_ERROR, LOCATION, NULL,
   1657 				"NAT-D hashing failed for %s\n", saddr2str(iph1->remote));
   1658 			goto end;
   1659 		}
   1660 
   1661 		if ((natd[1] = natt_hash_addr (iph1, iph1->local)) == NULL) {
   1662 			plog(LLV_ERROR, LOCATION, NULL,
   1663 				"NAT-D hashing failed for %s\n", saddr2str(iph1->local));
   1664 			goto end;
   1665 		}
   1666 
   1667 		plog (LLV_INFO, LOCATION, NULL, "Adding remote and local NAT-D payloads.\n");
   1668 		plist = isakmp_plist_append(plist, natd[0], iph1->natt_options->payload_nat_d);
   1669 		plist = isakmp_plist_append(plist, natd[1], iph1->natt_options->payload_nat_d);
   1670 	}
   1671 #endif
   1672 
   1673 	buf = isakmp_plist_set_all (&plist, iph1);
   1674 
   1675 	error = 0;
   1676 
   1677 end:
   1678 	if (error && buf != NULL) {
   1679 		vfree(buf);
   1680 		buf = NULL;
   1681 	}
   1682 #ifdef HAVE_GSSAPI
   1683 	if (gsstoken)
   1684 		vfree(gsstoken);
   1685 #endif
   1686 	if (vid)
   1687 		vfree(vid);
   1688 
   1689 #ifdef ENABLE_NATT
   1690 	if (natd[0])
   1691 		vfree(natd[0]);
   1692 	if (natd[1])
   1693 		vfree(natd[1]);
   1694 #endif
   1695 
   1696 	return buf;
   1697 }
   1698 
   1699 /*
   1700  * This is used in main mode for:
   1701  * initiator's 4th exchange send to responder
   1702  * 	psk: HDR*, IDi1, HASH_I
   1703  * 	sig: HDR*, IDi1, [ CR, ] [ CERT, ] SIG_I
   1704  *   gssapi: HDR*, [ IDi1, ] < GSSi(n) | HASH_I >
   1705  * 	rsa: HDR*, HASH_I
   1706  * 	rev: HDR*, HASH_I
   1707  * responders 3rd exchnage send to initiator
   1708  * 	psk: HDR*, IDr1, HASH_R
   1709  * 	sig: HDR*, IDr1, [ CERT, ] SIG_R
   1710  *   gssapi: HDR*, [ IDr1, ] < GSSr(n) | HASH_R >
   1711  * 	rsa: HDR*, HASH_R
   1712  * 	rev: HDR*, HASH_R
   1713  */
   1714 static vchar_t *
   1715 ident_ir3mx(struct ph1handle *iph1)
   1716 {
   1717 	struct payload_list *plist = NULL;
   1718 	vchar_t *buf = NULL, *new = NULL;
   1719 	int need_cert = 0;
   1720 	int error = -1;
   1721 #ifdef HAVE_GSSAPI
   1722 	vchar_t *gsstoken = NULL;
   1723 	vchar_t *gsshash = NULL;
   1724 #endif
   1725 
   1726 	switch (iph1->approval->authmethod) {
   1727 	case OAKLEY_ATTR_AUTH_METHOD_PSKEY:
   1728 #ifdef ENABLE_HYBRID
   1729 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_I:
   1730 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R:
   1731 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I:
   1732 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_I:
   1733 #endif
   1734 		/* create isakmp ID payload */
   1735 		plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
   1736 
   1737 		/* create isakmp HASH payload */
   1738 		plist = isakmp_plist_append(plist, iph1->hash, ISAKMP_NPTYPE_HASH);
   1739 		break;
   1740 	case OAKLEY_ATTR_AUTH_METHOD_DSSSIG:
   1741 	case OAKLEY_ATTR_AUTH_METHOD_RSASIG:
   1742 #ifdef ENABLE_HYBRID
   1743 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R:
   1744 	case OAKLEY_ATTR_AUTH_METHOD_HYBRID_DSS_R:
   1745 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I:
   1746 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R:
   1747 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_I:
   1748 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_DSSSIG_R:
   1749 #endif
   1750 		if (oakley_getmycert(iph1) < 0)
   1751 			goto end;
   1752 
   1753 		if (oakley_getsign(iph1) < 0)
   1754 			goto end;
   1755 
   1756 		if (iph1->cert != NULL && iph1->rmconf->send_cert)
   1757 			need_cert = 1;
   1758 
   1759 		/* add ID payload */
   1760 		plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
   1761 
   1762 		/* add CERT payload if there */
   1763 		if (need_cert)
   1764 			plist = isakmp_plist_append(plist, iph1->cert,
   1765 						    ISAKMP_NPTYPE_CERT);
   1766 		/* add SIG payload */
   1767 		plist = isakmp_plist_append(plist, iph1->sig, ISAKMP_NPTYPE_SIG);
   1768 
   1769 		/* create isakmp CR payload */
   1770 		if (iph1->side == INITIATOR &&
   1771 		    oakley_needcr(iph1->approval->authmethod))
   1772 			plist = oakley_append_cr(plist, iph1);
   1773 		break;
   1774 #ifdef HAVE_GSSAPI
   1775 	case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB:
   1776 		if (iph1->hash != NULL) {
   1777 			gsshash = gssapi_wraphash(iph1);
   1778 			if (gsshash == NULL)
   1779 				goto end;
   1780 		} else {
   1781 			if (gssapi_get_token_to_send(iph1, &gsstoken) < 0) {
   1782 				plog(LLV_ERROR, LOCATION, NULL,
   1783 					"Failed to get gssapi token.\n");
   1784 				goto end;
   1785 			}
   1786 		}
   1787 
   1788 		if (!gssapi_id_sent(iph1)) {
   1789 			/* create isakmp ID payload */
   1790 			plist = isakmp_plist_append(plist, iph1->id, ISAKMP_NPTYPE_ID);
   1791 			gssapi_set_id_sent(iph1);
   1792 		}
   1793 
   1794 		if (iph1->hash != NULL)
   1795 			/* create isakmp HASH payload */
   1796 			plist = isakmp_plist_append(plist, gsshash, ISAKMP_NPTYPE_HASH);
   1797 		else
   1798 			plist = isakmp_plist_append(plist, gsstoken, ISAKMP_NPTYPE_GSS);
   1799 		break;
   1800 #endif
   1801 	case OAKLEY_ATTR_AUTH_METHOD_RSAENC:
   1802 	case OAKLEY_ATTR_AUTH_METHOD_RSAREV:
   1803 #ifdef ENABLE_HYBRID
   1804 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I:
   1805 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R:
   1806 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I:
   1807 	case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R:
   1808 #endif
   1809 		plog(LLV_ERROR, LOCATION, NULL,
   1810 			"not supported authentication type %d\n",
   1811 			iph1->approval->authmethod);
   1812 		goto end;
   1813 	default:
   1814 		plog(LLV_ERROR, LOCATION, NULL,
   1815 			"invalid authentication type %d\n",
   1816 			iph1->approval->authmethod);
   1817 		goto end;
   1818 	}
   1819 
   1820 	buf = isakmp_plist_set_all (&plist, iph1);
   1821 
   1822 #ifdef HAVE_PRINT_ISAKMP_C
   1823 	isakmp_printpacket(buf, iph1->local, iph1->remote, 1);
   1824 #endif
   1825 
   1826 	/* encoding */
   1827 	new = oakley_do_encrypt(iph1, buf, iph1->ivm->ive, iph1->ivm->iv);
   1828 	if (new == NULL)
   1829 		goto end;
   1830 
   1831 	vfree(buf);
   1832 
   1833 	buf = new;
   1834 
   1835 	error = 0;
   1836 
   1837 end:
   1838 #ifdef HAVE_GSSAPI
   1839 	if (gsstoken)
   1840 		vfree(gsstoken);
   1841 #endif
   1842 	if (error && buf != NULL) {
   1843 		vfree(buf);
   1844 		buf = NULL;
   1845 	}
   1846 
   1847 	return buf;
   1848 }
   1849 
   1850 /*
   1851  * handle a notification payload inside identity exchange.
   1852  * called only when the packet has been verified to be encrypted.
   1853  */
   1854 static int
   1855 ident_recv_n(struct ph1handle *iph1, struct isakmp_gen *gen)
   1856 {
   1857 	struct isakmp_pl_n *notify = (struct isakmp_pl_n *) gen;
   1858 	u_int type;
   1859 
   1860 	type = ntohs(notify->type);
   1861 	switch (type) {
   1862 	case ISAKMP_NTYPE_INITIAL_CONTACT:
   1863 		iph1->initial_contact_received = TRUE;
   1864 		break;
   1865 	default:
   1866 		isakmp_log_notify(iph1, notify, "identity exchange");
   1867 		break;
   1868 	}
   1869 	return 0;
   1870 }
   1871