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