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