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