File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / ipsec-tools / src / racoon / isakmp_agg.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:39:10 2012 UTC (12 years, 4 months ago) by misho
Branches: ipsec-tools, MAIN
CVS tags: v0_8_2p2, v0_8_1p0, v0_8_1, v0_8_0p0, v0_8_0, HEAD
ipsec-tools

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>