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