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