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