Annotation of embedaddon/ipsec-tools/src/racoon/isakmp_agg.c, revision 1.1
1.1 ! misho 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>