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