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