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