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