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