1/* $KAME: isakmp_agg.c,v 1.55 2001/12/12 15:29:13 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/* Aggressive Exchange (Aggressive 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_agg.h" 70#include "isakmp_inf.h" 71#include "vendorid.h" 72#include "strnames.h" 73 74#ifdef HAVE_GSSAPI 75#include "gssapi.h" 76#endif 77 78/* 79 * begin Aggressive Mode as initiator. 80 */ 81/* 82 * send to responder 83 * psk: HDR, SA, KE, Ni, IDi1 84 * sig: HDR, SA, KE, Ni, IDi1 [, CR ] 85 * gssapi: HDR, SA, KE, Ni, IDi1, GSSi 86 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r 87 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i, 88 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ] 89 */ 90int 91agg_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 need_cr = 0; 99 vchar_t *cr = NULL, *gsstoken = NULL; 100 int error = -1; 101 int nptype; 102#ifdef HAVE_GSSAPI 103 int len; 104#endif 105 106 /* validity check */ 107 if (msg != NULL) { 108 plog(LLV_ERROR, LOCATION, NULL, 109 "msg has to be NULL in this function.\n"); 110 goto end; 111 } 112 if (iph1->status != PHASE1ST_START) { 113 plog(LLV_ERROR, LOCATION, NULL, 114 "status mismatched %d.\n", iph1->status); 115 goto end; 116 } 117 118 /* create isakmp index */ 119 memset(&iph1->index, 0, sizeof(iph1->index)); 120 isakmp_newcookie((caddr_t)&iph1->index, iph1->remote, iph1->local); 121 122 /* make ID payload into isakmp status */ 123 if (ipsecdoi_setid1(iph1) < 0) 124 goto end; 125 126 /* create SA payload for my proposal */ 127 iph1->sa = ipsecdoi_setph1proposal(iph1->rmconf->proposal); 128 if (iph1->sa == NULL) 129 goto end; 130 131 /* consistency check of proposals */ 132 if (iph1->rmconf->dhgrp == NULL) { 133 plog(LLV_ERROR, LOCATION, NULL, 134 "configuration failure about DH group.\n"); 135 goto end; 136 } 137 138 /* generate DH public value */ 139 if (oakley_dh_generate(iph1->rmconf->dhgrp, 140 &iph1->dhpub, &iph1->dhpriv) < 0) 141 goto end; 142 143 /* generate NONCE value */ 144 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); 145 if (iph1->nonce == NULL) 146 goto end; 147 148#ifdef HAVE_SIGNING_C 149 /* create CR if need */ 150 if (iph1->rmconf->send_cr 151 && oakley_needcr(iph1->rmconf->proposal->authmethod) 152 && iph1->rmconf->peerscertfile == NULL) { 153 need_cr = 1; 154 cr = oakley_getcr(iph1); 155 if (cr == NULL) { 156 plog(LLV_ERROR, LOCATION, NULL, 157 "failed to get cr buffer.\n"); 158 goto end; 159 } 160 } 161#endif 162 plog(LLV_DEBUG, LOCATION, NULL, "authmethod is %s\n", 163 s_oakley_attr_method(iph1->rmconf->proposal->authmethod)); 164 /* create buffer to send isakmp payload */ 165 tlen = sizeof(struct isakmp) 166 + sizeof(*gen) + iph1->sa->l 167 + sizeof(*gen) + iph1->dhpub->l 168 + sizeof(*gen) + iph1->nonce->l 169 + sizeof(*gen) + iph1->id->l; 170 if (need_cr) 171 tlen += sizeof(*gen) + cr->l; 172#ifdef HAVE_GSSAPI 173 if (iph1->rmconf->proposal->authmethod == 174 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { 175 gssapi_get_itoken(iph1, &len); 176 tlen += sizeof (*gen) + len; 177 } 178#endif 179 180 iph1->sendbuf = vmalloc(tlen); 181 if (iph1->sendbuf == NULL) { 182 plog(LLV_ERROR, LOCATION, NULL, 183 "failed to get buffer to send.\n"); 184 goto end; 185 } 186 187 /* set isakmp header */ 188 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA); 189 if (p == NULL) 190 goto end; 191 192 /* set SA payload to propose */ 193 p = set_isakmp_payload(p, iph1->sa, ISAKMP_NPTYPE_KE); 194 195 /* create isakmp KE payload */ 196 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE); 197 198 /* create isakmp NONCE payload */ 199 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID); 200 201 /* create isakmp ID payload */ 202#ifdef HAVE_GSSAPI 203 if (iph1->rmconf->proposal->authmethod == 204 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) 205 nptype = ISAKMP_NPTYPE_GSS; 206 else 207#endif 208 if (need_cr) 209 nptype = ISAKMP_NPTYPE_CR; 210 else 211 nptype = ISAKMP_NPTYPE_NONE; 212 213 p = set_isakmp_payload(p, iph1->id, nptype); 214 215#ifdef HAVE_GSSAPI 216 if (iph1->rmconf->proposal->authmethod == 217 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) { 218 gssapi_get_token_to_send(iph1, &gsstoken); 219 p = set_isakmp_payload(p, gsstoken, ISAKMP_NPTYPE_NONE); 220 } else 221#endif 222 if (need_cr) 223 /* create isakmp CR payload */ 224 p = set_isakmp_payload(p, cr, ISAKMP_NPTYPE_NONE); 225 226#ifdef HAVE_PRINT_ISAKMP_C 227 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); 228#endif 229 230 /* send the packet, add to the schedule to resend */ 231 iph1->retry_counter = iph1->rmconf->retry_counter; 232 if (isakmp_ph1resend(iph1) == -1) 233 goto end; 234 235 iph1->status = PHASE1ST_MSG1SENT; 236 237 error = 0; 238 239end: 240 if (cr) 241 vfree(cr); 242 if (gsstoken) 243 vfree(gsstoken); 244 245 return error; 246} 247 248/* 249 * receive from responder 250 * psk: HDR, SA, KE, Nr, IDr1, HASH_R 251 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R 252 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R 253 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R 254 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R 255 */ 256int 257agg_i2recv(iph1, msg) 258 struct ph1handle *iph1; 259 vchar_t *msg; 260{ 261 vchar_t *pbuf = NULL; 262 struct isakmp_parse_t *pa; 263 vchar_t *satmp = NULL; 264 int error = -1; 265#ifdef HAVE_GSSAPI 266 vchar_t *gsstoken = NULL; 267#endif 268 269 /* validity check */ 270 if (iph1->status != PHASE1ST_MSG1SENT) { 271 plog(LLV_ERROR, LOCATION, NULL, 272 "status mismatched %d.\n", iph1->status); 273 goto end; 274 } 275 276 /* validate the type of next payload */ 277 pbuf = isakmp_parse(msg); 278 if (pbuf == NULL) 279 goto end; 280 pa = (struct isakmp_parse_t *)pbuf->v; 281 282 iph1->pl_hash = NULL; 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_KE: 302 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) 303 goto end; 304 break; 305 case ISAKMP_NPTYPE_NONCE: 306 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) 307 goto end; 308 break; 309 case ISAKMP_NPTYPE_ID: 310 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) 311 goto end; 312 break; 313 case ISAKMP_NPTYPE_HASH: 314 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; 315 break; 316#ifdef HAVE_SIGNING_C 317 case ISAKMP_NPTYPE_CR: 318 if (oakley_savecr(iph1, pa->ptr) < 0) 319 goto end; 320 break; 321 case ISAKMP_NPTYPE_CERT: 322 if (oakley_savecert(iph1, pa->ptr) < 0) 323 goto end; 324 break; 325 case ISAKMP_NPTYPE_SIG: 326 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) 327 goto end; 328 break; 329#endif 330 case ISAKMP_NPTYPE_VID: 331 (void)check_vendorid(pa->ptr); 332 break; 333 case ISAKMP_NPTYPE_N: 334 isakmp_check_notify(pa->ptr, iph1); 335 break; 336#ifdef HAVE_GSSAPI 337 case ISAKMP_NPTYPE_GSS: 338 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) 339 goto end; 340 gssapi_save_received_token(iph1, gsstoken); 341 break; 342#endif 343 default: 344 /* don't send information, see isakmp_ident_r1() */ 345 plog(LLV_ERROR, LOCATION, iph1->remote, 346 "ignore the packet, " 347 "received unexpecting payload type %d.\n", 348 pa->type); 349 goto end; 350 } 351 } 352 353 /* payload existency check */ 354 355 /* verify identifier */ 356 if (ipsecdoi_checkid1(iph1) != 0) { 357 plog(LLV_ERROR, LOCATION, iph1->remote, 358 "invalid ID payload.\n"); 359 goto end; 360 } 361 362 /* check SA payload and set approval SA for use */ 363 if (ipsecdoi_checkph1proposal(satmp, iph1) < 0) { 364 plog(LLV_ERROR, LOCATION, iph1->remote, 365 "failed to get valid proposal.\n"); 366 goto end; 367 } 368 if (iph1->sa_ret) { 369 vfree(iph1->sa_ret); 370 iph1->sa_ret = NULL; 371 } 372 373 /* fix isakmp index */ 374 memcpy(&iph1->index.r_ck, &((struct isakmp *)msg->v)->r_ck, 375 sizeof(cookie_t)); 376 377 /* compute sharing secret of DH */ 378 if (oakley_dh_compute(iph1->rmconf->dhgrp, iph1->dhpub, 379 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) 380 goto end; 381 382 /* generate SKEYIDs & IV & final cipher key */ 383 if (oakley_skeyid(iph1) < 0) 384 goto end; 385 if (oakley_skeyid_dae(iph1) < 0) 386 goto end; 387 if (oakley_compute_enckey(iph1) < 0) 388 goto end; 389 if (oakley_newiv(iph1) < 0) 390 goto end; 391 392 /* validate authentication value */ 393 { 394 int type; 395 type = oakley_validate_auth(iph1); 396 if (type != 0) { 397 if (type == -1) { 398 /* message printed inner oakley_validate_auth() */ 399 goto end; 400 } 401 isakmp_info_send_n1(iph1, type, NULL); 402 goto end; 403 } 404 } 405 406#ifdef HAVE_SIGNING_C 407 if (oakley_checkcr(iph1) < 0) { 408 /* Ignore this error in order to be interoperability. */ 409 ; 410 } 411#endif 412 413 /* change status of isakmp status entry */ 414 iph1->status = PHASE1ST_MSG2RECEIVED; 415 416 error = 0; 417 418end: 419 if (pbuf) 420 vfree(pbuf); 421 if (satmp) 422 vfree(satmp); 423 if (error) { 424 VPTRINIT(iph1->dhpub_p); 425 VPTRINIT(iph1->nonce_p); 426 VPTRINIT(iph1->id_p); 427 oakley_delcert(iph1->cert_p); 428 iph1->cert_p = NULL; 429 oakley_delcert(iph1->crl_p); 430 iph1->crl_p = NULL; 431 VPTRINIT(iph1->sig_p); 432 oakley_delcert(iph1->cr_p); 433 iph1->cr_p = NULL; 434 } 435 436 return error; 437} 438 439/* 440 * send to responder 441 * psk: HDR, HASH_I 442 * gssapi: HDR, HASH_I 443 * sig: HDR, [ CERT, ] SIG_I 444 * rsa: HDR, HASH_I 445 * rev: HDR, HASH_I 446 */ 447int 448agg_i2send(iph1, msg) 449 struct ph1handle *iph1; 450 vchar_t *msg; 451{ 452 struct isakmp_gen *gen; 453 char *p; 454 int tlen; 455 int need_cert = 0; 456 int error = -1; 457 vchar_t *gsshash = NULL; 458 459 /* validity check */ 460 if (iph1->status != PHASE1ST_MSG2RECEIVED) { 461 plog(LLV_ERROR, LOCATION, NULL, 462 "status mismatched %d.\n", iph1->status); 463 goto end; 464 } 465 466 /* generate HASH to send */ 467 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_I\n"); 468 iph1->hash = oakley_ph1hash_common(iph1, GENERATE); 469 if (iph1->hash == NULL) { 470#ifdef HAVE_GSSAPI 471 if (gssapi_more_tokens(iph1)) 472 isakmp_info_send_n1(iph1, 473 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); 474#endif 475 goto end; 476 } 477 478 tlen = sizeof(struct isakmp); 479 480 switch (iph1->approval->authmethod) { 481 case OAKLEY_ATTR_AUTH_METHOD_PSKEY: 482 tlen += sizeof(*gen) + iph1->hash->l; 483 484 iph1->sendbuf = vmalloc(tlen); 485 if (iph1->sendbuf == NULL) { 486 plog(LLV_ERROR, LOCATION, NULL, 487 "failed to get buffer to send.\n"); 488 goto end; 489 } 490 491 /* set isakmp header */ 492 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_HASH); 493 if (p == NULL) 494 goto end; 495 496 /* set HASH payload */ 497 p = set_isakmp_payload(p, iph1->hash, ISAKMP_NPTYPE_NONE); 498 break; 499#ifdef HAVE_SIGNING_C 500 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: 501 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 502 503 if (oakley_getmycert(iph1) < 0) 504 goto end; 505 506 if (oakley_getsign(iph1) < 0) 507 goto end; 508 509 if (iph1->cert != NULL && iph1->rmconf->send_cert) 510 need_cert = 1; 511 512 tlen += sizeof(*gen) + iph1->sig->l; 513 if (need_cert) 514 tlen += sizeof(*gen) + iph1->cert->pl->l; 515 516 iph1->sendbuf = vmalloc(tlen); 517 if (iph1->sendbuf == NULL) { 518 plog(LLV_ERROR, LOCATION, NULL, 519 "failed to get buffer to send.\n"); 520 goto end; 521 } 522 523 /* set isakmp header */ 524 p = set_isakmp_header(iph1->sendbuf, iph1, need_cert 525 ? ISAKMP_NPTYPE_CERT 526 : ISAKMP_NPTYPE_SIG); 527 if (p == NULL) 528 goto end; 529 530 /* add CERT payload if there */ 531 if (need_cert) 532 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG); 533 /* add SIG payload */ 534 p = set_isakmp_payload(p, iph1->sig, ISAKMP_NPTYPE_NONE); 535 break; 536#endif 537 case OAKLEY_ATTR_AUTH_METHOD_RSAENC: 538 case OAKLEY_ATTR_AUTH_METHOD_RSAREV: 539 tlen += sizeof(*gen) + iph1->hash->l; 540 break; 541#ifdef HAVE_GSSAPI 542 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: 543 gsshash = gssapi_wraphash(iph1); 544 if (gsshash == NULL) { 545 plog(LLV_ERROR, LOCATION, NULL, 546 "failed to wrap hash\n"); 547 isakmp_info_send_n1(iph1, 548 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); 549 goto end; 550 } 551 tlen += sizeof(*gen) + gsshash->l; 552 553 iph1->sendbuf = vmalloc(tlen); 554 if (iph1->sendbuf == NULL) { 555 plog(LLV_ERROR, LOCATION, NULL, 556 "failed to get buffer to send.\n"); 557 goto end; 558 } 559 /* set isakmp header */ 560 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_HASH); 561 if (p == NULL) 562 goto end; 563 p = set_isakmp_payload(p, gsshash, ISAKMP_NPTYPE_NONE); 564 break; 565#endif 566 } 567 568#ifdef HAVE_PRINT_ISAKMP_C 569 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 0); 570#endif 571 572 /* send to responder */ 573 if (isakmp_send(iph1, iph1->sendbuf) < 0) 574 goto end; 575 576 /* the sending message is added to the received-list. */ 577 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { 578 plog(LLV_ERROR , LOCATION, NULL, 579 "failed to add a response packet to the tree.\n"); 580 goto end; 581 } 582 583 /* set encryption flag */ 584 iph1->flags |= ISAKMP_FLAG_E; 585 586 iph1->status = PHASE1ST_ESTABLISHED; 587 588 error = 0; 589 590end: 591 if (gsshash) 592 vfree(gsshash); 593 return error; 594} 595 596/* 597 * receive from initiator 598 * psk: HDR, SA, KE, Ni, IDi1 599 * sig: HDR, SA, KE, Ni, IDi1 [, CR ] 600 * gssapi: HDR, SA, KE, Ni, IDi1 , GSSi 601 * rsa: HDR, SA, [ HASH(1),] KE, <IDi1_b>Pubkey_r, <Ni_b>Pubkey_r 602 * rev: HDR, SA, [ HASH(1),] <Ni_b>Pubkey_r, <KE_b>Ke_i, 603 * <IDii_b>Ke_i [, <Cert-I_b>Ke_i ] 604 */ 605int 606agg_r1recv(iph1, msg) 607 struct ph1handle *iph1; 608 vchar_t *msg; 609{ 610 int error = -1; 611 vchar_t *pbuf = NULL; 612 struct isakmp_parse_t *pa; 613#ifdef HAVE_GSSAPI 614 vchar_t *gsstoken = NULL; 615#endif 616 617 /* validity check */ 618 if (iph1->status != PHASE1ST_START) { 619 plog(LLV_ERROR, LOCATION, NULL, 620 "status mismatched %d.\n", iph1->status); 621 goto end; 622 } 623 624 /* validate the type of next payload */ 625 pbuf = isakmp_parse(msg); 626 if (pbuf == NULL) 627 goto end; 628 pa = (struct isakmp_parse_t *)pbuf->v; 629 630 /* SA payload is fixed postion */ 631 if (pa->type != ISAKMP_NPTYPE_SA) { 632 plog(LLV_ERROR, LOCATION, iph1->remote, 633 "received invalid next payload type %d, " 634 "expecting %d.\n", 635 pa->type, ISAKMP_NPTYPE_SA); 636 goto end; 637 } 638 if (isakmp_p2ph(&iph1->sa, pa->ptr) < 0) 639 goto end; 640 pa++; 641 642 for (/*nothing*/; 643 pa->type != ISAKMP_NPTYPE_NONE; 644 pa++) { 645 646 plog(LLV_DEBUG, LOCATION, NULL, 647 "received payload of type %s\n", 648 s_isakmp_nptype(pa->type)); 649 650 switch (pa->type) { 651 case ISAKMP_NPTYPE_KE: 652 if (isakmp_p2ph(&iph1->dhpub_p, pa->ptr) < 0) 653 goto end; 654 break; 655 case ISAKMP_NPTYPE_NONCE: 656 if (isakmp_p2ph(&iph1->nonce_p, pa->ptr) < 0) 657 goto end; 658 break; 659 case ISAKMP_NPTYPE_ID: 660 if (isakmp_p2ph(&iph1->id_p, pa->ptr) < 0) 661 goto end; 662 break; 663 case ISAKMP_NPTYPE_VID: 664 (void)check_vendorid(pa->ptr); 665 break; 666#ifdef HAVE_SIGNING_C 667 case ISAKMP_NPTYPE_CR: 668 if (oakley_savecr(iph1, pa->ptr) < 0) 669 goto end; 670 break; 671#endif 672#ifdef HAVE_GSSAPI 673 case ISAKMP_NPTYPE_GSS: 674 if (isakmp_p2ph(&gsstoken, pa->ptr) < 0) 675 goto end; 676 gssapi_save_received_token(iph1, gsstoken); 677 break; 678#endif 679 default: 680 /* don't send information, see isakmp_ident_r1() */ 681 plog(LLV_ERROR, LOCATION, iph1->remote, 682 "ignore the packet, " 683 "received unexpecting payload type %d.\n", 684 pa->type); 685 goto end; 686 } 687 } 688 689 /* payload existency check */ 690 691 /* verify identifier */ 692 if (ipsecdoi_checkid1(iph1) != 0) { 693 plog(LLV_ERROR, LOCATION, iph1->remote, 694 "invalid ID payload.\n"); 695 goto end; 696 } 697 698 /* check SA payload and set approval SA for use */ 699 if (ipsecdoi_checkph1proposal(iph1->sa, iph1) < 0) { 700 plog(LLV_ERROR, LOCATION, iph1->remote, 701 "failed to get valid proposal.\n"); 702 goto end; 703 } 704 705#ifdef HAVE_SIGNING_C 706 if (oakley_checkcr(iph1) < 0) { 707 /* Ignore this error in order to be interoperability. */ 708 ; 709 } 710#endif 711 712 iph1->status = PHASE1ST_MSG1RECEIVED; 713 714 error = 0; 715 716end: 717 if (pbuf) 718 vfree(pbuf); 719 if (error) { 720 VPTRINIT(iph1->sa); 721 VPTRINIT(iph1->dhpub_p); 722 VPTRINIT(iph1->nonce_p); 723 VPTRINIT(iph1->id_p); 724 oakley_delcert(iph1->cr_p); 725 iph1->cr_p = NULL; 726 } 727 728 return error; 729} 730 731/* 732 * send to initiator 733 * psk: HDR, SA, KE, Nr, IDr1, HASH_R 734 * sig: HDR, SA, KE, Nr, IDr1, [ CR, ] [ CERT, ] SIG_R 735 * gssapi: HDR, SA, KE, Nr, IDr1, GSSr, HASH_R 736 * rsa: HDR, SA, KE, <IDr1_b>PubKey_i, <Nr_b>PubKey_i, HASH_R 737 * rev: HDR, SA, <Nr_b>PubKey_i, <KE_b>Ke_r, <IDir_b>Ke_r, HASH_R 738 */ 739int 740agg_r1send(iph1, msg) 741 struct ph1handle *iph1; 742 vchar_t *msg; 743{ 744 struct isakmp_gen *gen; 745 char *p; 746 int tlen; 747 int need_cr = 0; 748 int need_cert = 0; 749 vchar_t *cr = NULL; 750 vchar_t *vid = NULL; 751 int error = -1; 752#ifdef HAVE_GSSAPI 753 int gsslen; 754 vchar_t *gsstoken = NULL, *gsshash = NULL; 755 vchar_t *gss_sa = NULL; 756#endif 757 758 /* validity check */ 759 if (iph1->status != PHASE1ST_MSG1RECEIVED) { 760 plog(LLV_ERROR, LOCATION, NULL, 761 "status mismatched %d.\n", iph1->status); 762 goto end; 763 } 764 765 /* set responder's cookie */ 766 isakmp_newcookie((caddr_t)&iph1->index.r_ck, iph1->remote, iph1->local); 767 768 /* make ID payload into isakmp status */ 769 if (ipsecdoi_setid1(iph1) < 0) 770 goto end; 771 772 /* generate DH public value */ 773 if (oakley_dh_generate(iph1->rmconf->dhgrp, 774 &iph1->dhpub, &iph1->dhpriv) < 0) 775 goto end; 776 777 /* generate NONCE value */ 778 iph1->nonce = eay_set_random(iph1->rmconf->nonce_size); 779 if (iph1->nonce == NULL) 780 goto end; 781 782 /* compute sharing secret of DH */ 783 if (oakley_dh_compute(iph1->approval->dhgrp, iph1->dhpub, 784 iph1->dhpriv, iph1->dhpub_p, &iph1->dhgxy) < 0) 785 goto end; 786 787 /* generate SKEYIDs & IV & final cipher key */ 788 if (oakley_skeyid(iph1) < 0) 789 goto end; 790 if (oakley_skeyid_dae(iph1) < 0) 791 goto end; 792 if (oakley_compute_enckey(iph1) < 0) 793 goto end; 794 if (oakley_newiv(iph1) < 0) 795 goto end; 796 797#ifdef HAVE_GSSAPI 798 if (iph1->rmconf->proposal->authmethod == 799 OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB) 800 gssapi_get_rtoken(iph1, &gsslen); 801#endif 802 803 /* generate HASH to send */ 804 plog(LLV_DEBUG, LOCATION, NULL, "generate HASH_R\n"); 805 iph1->hash = oakley_ph1hash_common(iph1, GENERATE); 806 if (iph1->hash == NULL) { 807#ifdef HAVE_GSSAPI 808 if (gssapi_more_tokens(iph1)) 809 isakmp_info_send_n1(iph1, 810 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); 811#endif 812 goto end; 813 } 814 815#ifdef HAVE_SIGNING_C 816 /* create CR if need */ 817 if (iph1->rmconf->send_cr 818 && oakley_needcr(iph1->approval->authmethod) 819 && iph1->rmconf->peerscertfile == NULL) { 820 need_cr = 1; 821 cr = oakley_getcr(iph1); 822 if (cr == NULL) { 823 plog(LLV_ERROR, LOCATION, NULL, 824 "failed to get cr buffer.\n"); 825 goto end; 826 } 827 } 828#endif 829 830 tlen = sizeof(struct isakmp); 831 832 switch (iph1->approval->authmethod) { 833 case OAKLEY_ATTR_AUTH_METHOD_PSKEY: 834 /* create buffer to send isakmp payload */ 835 tlen += sizeof(*gen) + iph1->sa_ret->l 836 + sizeof(*gen) + iph1->dhpub->l 837 + sizeof(*gen) + iph1->nonce->l 838 + sizeof(*gen) + iph1->id->l 839 + sizeof(*gen) + iph1->hash->l; 840 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL) 841 tlen += sizeof(*gen) + vid->l; 842 if (need_cr) 843 tlen += sizeof(*gen) + cr->l; 844 845 iph1->sendbuf = vmalloc(tlen); 846 if (iph1->sendbuf == NULL) { 847 plog(LLV_ERROR, LOCATION, NULL, 848 "failed to get buffer to send\n"); 849 goto end; 850 } 851 852 /* set isakmp header */ 853 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA); 854 if (p == NULL) 855 goto end; 856 857 /* set SA payload to reply */ 858 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE); 859 860 /* create isakmp KE payload */ 861 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE); 862 863 /* create isakmp NONCE payload */ 864 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID); 865 866 /* create isakmp ID payload */ 867 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_HASH); 868 869 /* create isakmp HASH payload */ 870 p = set_isakmp_payload(p, iph1->hash, 871 vid ? ISAKMP_NPTYPE_VID 872 : (need_cr ? ISAKMP_NPTYPE_CR 873 : ISAKMP_NPTYPE_NONE)); 874 875 /* append vendor id, if needed */ 876 if (vid) 877 p = set_isakmp_payload(p, vid, 878 need_cr ? ISAKMP_NPTYPE_CR 879 : ISAKMP_NPTYPE_NONE); 880 881 /* create isakmp CR payload if needed */ 882 if (need_cr) 883 p = set_isakmp_payload(p, cr, ISAKMP_NPTYPE_NONE); 884 break; 885#ifdef HAVE_SIGNING_C 886 case OAKLEY_ATTR_AUTH_METHOD_DSSSIG: 887 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 888 889 if (oakley_getmycert(iph1) < 0) 890 goto end; 891 892 if (oakley_getsign(iph1) < 0) 893 goto end; 894 895 if (iph1->cert != NULL && iph1->rmconf->send_cert) 896 need_cert = 1; 897 898 tlen += sizeof(*gen) + iph1->sa_ret->l 899 + sizeof(*gen) + iph1->dhpub->l 900 + sizeof(*gen) + iph1->nonce->l 901 + sizeof(*gen) + iph1->id->l 902 + sizeof(*gen) + iph1->sig->l; 903 if (need_cert) 904 tlen += sizeof(*gen) + iph1->cert->pl->l; 905 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL) 906 tlen += sizeof(*gen) + vid->l; 907 if (need_cr) 908 tlen += sizeof(*gen) + cr->l; 909 910 iph1->sendbuf = vmalloc(tlen); 911 if (iph1->sendbuf == NULL) { 912 plog(LLV_ERROR, LOCATION, NULL, 913 "failed to get buffer to send.\n"); 914 goto end; 915 } 916 917 /* set isakmp header */ 918 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA); 919 if (p == NULL) 920 goto end; 921 922 /* set SA payload to reply */ 923 p = set_isakmp_payload(p, iph1->sa_ret, ISAKMP_NPTYPE_KE); 924 925 /* create isakmp KE payload */ 926 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE); 927 928 /* create isakmp NONCE payload */ 929 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID); 930 931 /* add ID payload */ 932 p = set_isakmp_payload(p, iph1->id, need_cert 933 ? ISAKMP_NPTYPE_CERT 934 : ISAKMP_NPTYPE_SIG); 935 936 /* add CERT payload if there */ 937 if (need_cert) 938 p = set_isakmp_payload(p, iph1->cert->pl, ISAKMP_NPTYPE_SIG); 939 /* add SIG payload */ 940 p = set_isakmp_payload(p, iph1->sig, 941 vid ? ISAKMP_NPTYPE_VID 942 : (need_cr ? ISAKMP_NPTYPE_CR 943 : ISAKMP_NPTYPE_NONE)); 944 945 /* append vendor id, if needed */ 946 if (vid) 947 p = set_isakmp_payload(p, vid, 948 need_cr ? ISAKMP_NPTYPE_CR 949 : ISAKMP_NPTYPE_NONE); 950 951 /* create isakmp CR payload if needed */ 952 if (need_cr) 953 p = set_isakmp_payload(p, cr, ISAKMP_NPTYPE_NONE); 954 break; 955#endif 956 case OAKLEY_ATTR_AUTH_METHOD_RSAENC: 957 case OAKLEY_ATTR_AUTH_METHOD_RSAREV: 958 tlen += sizeof(*gen) + iph1->hash->l; 959 break; 960#ifdef HAVE_GSSAPI 961 case OAKLEY_ATTR_AUTH_METHOD_GSSAPI_KRB: 962 /* create buffer to send isakmp payload */ 963 gsshash = gssapi_wraphash(iph1); 964 if (gsshash == NULL) { 965 plog(LLV_ERROR, LOCATION, NULL, 966 "failed to wrap hash\n"); 967 /* 968 * This is probably due to the GSS roundtrips not 969 * being finished yet. Return this error in 970 * the hope that a fallback to main mode will 971 * be done. 972 */ 973 isakmp_info_send_n1(iph1, 974 ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE, NULL); 975 goto end; 976 } 977 if (iph1->approval->gssid != NULL) 978 gss_sa = ipsecdoi_setph1proposal(iph1->approval); 979 else 980 gss_sa = iph1->sa_ret; 981 982 tlen += sizeof(*gen) + gss_sa->l 983 + sizeof(*gen) + iph1->dhpub->l 984 + sizeof(*gen) + iph1->nonce->l 985 + sizeof(*gen) + iph1->id->l 986 + sizeof(*gen) + gsslen 987 + sizeof(*gen) + gsshash->l; 988 if ((vid = set_vendorid(iph1->approval->vendorid)) != NULL) 989 tlen += sizeof(*gen) + vid->l; 990 iph1->sendbuf = vmalloc(tlen); 991 if (iph1->sendbuf == NULL) { 992 plog(LLV_ERROR, LOCATION, NULL, 993 "failed to get buffer to send\n"); 994 goto end; 995 } 996 997 /* set isakmp header */ 998 p = set_isakmp_header(iph1->sendbuf, iph1, ISAKMP_NPTYPE_SA); 999 if (p == NULL) 1000 goto end; 1001 1002 /* set SA payload to reply */ 1003 p = set_isakmp_payload(p, gss_sa, ISAKMP_NPTYPE_KE); 1004 1005 /* create isakmp KE payload */ 1006 p = set_isakmp_payload(p, iph1->dhpub, ISAKMP_NPTYPE_NONCE); 1007 1008 /* create isakmp NONCE payload */ 1009 p = set_isakmp_payload(p, iph1->nonce, ISAKMP_NPTYPE_ID); 1010 1011 /* create isakmp ID payload */ 1012 p = set_isakmp_payload(p, iph1->id, ISAKMP_NPTYPE_GSS); 1013 1014 /* create GSS payload */ 1015 gssapi_get_token_to_send(iph1, &gsstoken); 1016 p = set_isakmp_payload(p, gsstoken, ISAKMP_NPTYPE_HASH); 1017 1018 /* create isakmp HASH payload */ 1019 p = set_isakmp_payload(p, gsshash, 1020 vid != NULL ? ISAKMP_NPTYPE_VID 1021 : ISAKMP_NPTYPE_NONE); 1022 1023 /* append vendor id, if needed */ 1024 if (vid) 1025 p = set_isakmp_payload(p, vid, ISAKMP_NPTYPE_NONE); 1026 break; 1027#endif 1028 } 1029 1030 1031#ifdef HAVE_PRINT_ISAKMP_C 1032 isakmp_printpacket(iph1->sendbuf, iph1->local, iph1->remote, 1); 1033#endif 1034 1035 /* send the packet, add to the schedule to resend */ 1036 iph1->retry_counter = iph1->rmconf->retry_counter; 1037 if (isakmp_ph1resend(iph1) == -1) 1038 goto end; 1039 1040 /* the sending message is added to the received-list. */ 1041 if (add_recvdpkt(iph1->remote, iph1->local, iph1->sendbuf, msg) == -1) { 1042 plog(LLV_ERROR , LOCATION, NULL, 1043 "failed to add a response packet to the tree.\n"); 1044 goto end; 1045 } 1046 1047 iph1->status = PHASE1ST_MSG1SENT; 1048 1049 error = 0; 1050 1051end: 1052 if (cr) 1053 vfree(cr); 1054 if (vid) 1055 vfree(vid); 1056#ifdef HAVE_GSSAPI 1057 if (gsstoken) 1058 vfree(gsstoken); 1059 if (gsshash) 1060 vfree(gsshash); 1061 if (gss_sa != iph1->sa_ret) 1062 vfree(gss_sa); 1063#endif 1064 1065 return error; 1066} 1067 1068/* 1069 * receive from initiator 1070 * psk: HDR, HASH_I 1071 * gssapi: HDR, HASH_I 1072 * sig: HDR, [ CERT, ] SIG_I 1073 * rsa: HDR, HASH_I 1074 * rev: HDR, HASH_I 1075 */ 1076int 1077agg_r2recv(iph1, msg0) 1078 struct ph1handle *iph1; 1079 vchar_t *msg0; 1080{ 1081 vchar_t *msg = NULL; 1082 vchar_t *pbuf = NULL; 1083 struct isakmp_parse_t *pa; 1084 int error = -1; 1085 1086 /* validity check */ 1087 if (iph1->status != PHASE1ST_MSG1SENT) { 1088 plog(LLV_ERROR, LOCATION, NULL, 1089 "status mismatched %d.\n", iph1->status); 1090 goto end; 1091 } 1092 1093 /* decrypting if need. */ 1094 if (ISSET(((struct isakmp *)msg0->v)->flags, ISAKMP_FLAG_E)) { 1095 msg = oakley_do_decrypt(iph1, msg0, 1096 iph1->ivm->iv, iph1->ivm->ive); 1097 if (msg == NULL) 1098 goto end; 1099 } else 1100 msg = vdup(msg0); 1101 1102 /* validate the type of next payload */ 1103 pbuf = isakmp_parse(msg); 1104 if (pbuf == NULL) 1105 goto end; 1106 1107 iph1->pl_hash = NULL; 1108 1109 for (pa = (struct isakmp_parse_t *)pbuf->v; 1110 pa->type != ISAKMP_NPTYPE_NONE; 1111 pa++) { 1112 1113 switch (pa->type) { 1114 case ISAKMP_NPTYPE_HASH: 1115 iph1->pl_hash = (struct isakmp_pl_hash *)pa->ptr; 1116 break; 1117 case ISAKMP_NPTYPE_VID: 1118 (void)check_vendorid(pa->ptr); 1119 break; 1120#ifdef HAVE_SIGNING_C 1121 case ISAKMP_NPTYPE_CERT: 1122 if (oakley_savecert(iph1, pa->ptr) < 0) 1123 goto end; 1124 break; 1125 case ISAKMP_NPTYPE_SIG: 1126 if (isakmp_p2ph(&iph1->sig_p, pa->ptr) < 0) 1127 goto end; 1128 break; 1129#endif 1130 case ISAKMP_NPTYPE_N: 1131 isakmp_check_notify(pa->ptr, iph1); 1132 break; 1133 default: 1134 /* don't send information, see isakmp_ident_r1() */ 1135 plog(LLV_ERROR, LOCATION, iph1->remote, 1136 "ignore the packet, " 1137 "received unexpecting payload type %d.\n", 1138 pa->type); 1139 goto end; 1140 } 1141 } 1142 1143 /* validate authentication value */ 1144 { 1145 int type; 1146 type = oakley_validate_auth(iph1); 1147 if (type != 0) { 1148 if (type == -1) { 1149 /* message printed inner oakley_validate_auth() */ 1150 goto end; 1151 } 1152 isakmp_info_send_n1(iph1, type, NULL); 1153 goto end; 1154 } 1155 } 1156 1157 iph1->status = PHASE1ST_MSG2RECEIVED; 1158 1159 error = 0; 1160 1161end: 1162 if (pbuf) 1163 vfree(pbuf); 1164 if (msg) 1165 vfree(msg); 1166 if (error) { 1167 oakley_delcert(iph1->cert_p); 1168 iph1->cert_p = NULL; 1169 oakley_delcert(iph1->crl_p); 1170 iph1->crl_p = NULL; 1171 VPTRINIT(iph1->sig_p); 1172 } 1173 1174 return error; 1175} 1176 1177/* 1178 * status update and establish isakmp sa. 1179 */ 1180int 1181agg_r2send(iph1, msg) 1182 struct ph1handle *iph1; 1183 vchar_t *msg; 1184{ 1185 int error = -1; 1186 1187 /* validity check */ 1188 if (iph1->status != PHASE1ST_MSG2RECEIVED) { 1189 plog(LLV_ERROR, LOCATION, NULL, 1190 "status mismatched %d.\n", iph1->status); 1191 goto end; 1192 } 1193 1194 /* IV synchronized when packet encrypted. */ 1195 /* see handler.h about IV synchronization. */ 1196 if (ISSET(((struct isakmp *)msg->v)->flags, ISAKMP_FLAG_E)) 1197 memcpy(iph1->ivm->iv->v, iph1->ivm->ive->v, iph1->ivm->iv->l); 1198 1199 /* set encryption flag */ 1200 iph1->flags |= ISAKMP_FLAG_E; 1201 1202 iph1->status = PHASE1ST_ESTABLISHED; 1203 1204 error = 0; 1205 1206end: 1207 return error; 1208} 1209