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