1/* $NetBSD: oakley.c,v 1.9.6.2 2007/04/04 13:08:28 vanhu Exp $ */ 2 3/* Id: oakley.c,v 1.32 2006/05/26 12:19:46 manubsd Exp */ 4 5/* 6 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 7 * All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the project nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#include "config.h" 35 36#include <sys/types.h> 37#include <sys/param.h> 38#include <sys/socket.h> /* XXX for subjectaltname */ 39#include <netinet/in.h> /* XXX for subjectaltname */ 40 41#ifdef HAVE_OPENSSL 42#include <openssl/pkcs7.h> 43#include <openssl/x509.h> 44#endif 45 46#include <stdlib.h> 47#include <stdio.h> 48#include <string.h> 49#include <errno.h> 50#include <arpa/inet.h> 51#include <TargetConditionals.h> 52 53#if TIME_WITH_SYS_TIME 54# include <sys/time.h> 55# include <time.h> 56#else 57# if HAVE_SYS_TIME_H 58# include <sys/time.h> 59# else 60# include <time.h> 61# endif 62#endif 63#ifdef ENABLE_HYBRID 64#include <resolv.h> 65#endif 66 67#include "var.h" 68#include "misc.h" 69#include "vmbuf.h" 70#include "str2val.h" 71#include "plog.h" 72#include "debug.h" 73 74#include "isakmp_var.h" 75#include "isakmp.h" 76#ifdef ENABLE_HYBRID 77#include "isakmp_xauth.h" 78#include "isakmp_cfg.h" 79#endif 80#include "oakley.h" 81#include "localconf.h" 82#include "policy.h" 83#include "handler.h" 84#include "ipsec_doi.h" 85#include "algorithm.h" 86#include "dhgroup.h" 87#include "sainfo.h" 88#include "proposal.h" 89#include "crypto_openssl.h" 90#include "crypto_cssm.h" 91#if HAVE_OPENDIR 92#include "open_dir.h" 93#endif 94#include "dnssec.h" 95#include "sockmisc.h" 96#include "strnames.h" 97#include "gcmalloc.h" 98#include <CoreFoundation/CoreFoundation.h> 99#include "remoteconf.h" 100#include "vpn_control.h" 101#if TARGET_OS_EMBEDDED 102#include <Security/SecCertificate.h> 103#include <Security/SecCertificatePriv.h> 104#endif 105#include "vpn_control_var.h" 106#include "extern.h" 107 108#define OUTBOUND_SA 0 109#define INBOUND_SA 1 110 111#define CERT_CHECKID_FROM_PEER 0 112#define CERT_CHECKID_FROM_RMCONFIG 1 113 114#ifdef HAVE_OPENSSL 115#define INITDHVAL(a, s, d, t) \ 116do { \ 117vchar_t buf; \ 118buf.v = str2val((s), 16, &buf.l); \ 119memset(&a, 0, sizeof(struct dhgroup)); \ 120a.type = (t); \ 121a.prime = vdup(&buf); \ 122a.gen1 = 2; \ 123a.gen2 = 0; \ 124racoon_free(buf.v); \ 125} while(0); 126#else /* HAVE_OPENSSL */ 127#define INITDHVAL(a, s, d, t) \ 128do { \ 129vchar_t buf; \ 130buf.v = str2val((s), 16, &buf.l); \ 131memset(&a, 0, sizeof(struct dhgroup)); \ 132a.desc = (d); \ 133a.type = (t); \ 134a.prime = vdup(&buf); \ 135a.gen1 = 2; \ 136a.gen2 = 0; \ 137racoon_free(buf.v); \ 138} while(0); 139#endif /* HAVE_OPENSSL */ 140 141struct dhgroup dh_modp768; 142struct dhgroup dh_modp1024; 143struct dhgroup dh_modp1536; 144struct dhgroup dh_modp2048; 145struct dhgroup dh_modp3072; 146struct dhgroup dh_modp4096; 147struct dhgroup dh_modp6144; 148struct dhgroup dh_modp8192; 149 150 151static int oakley_check_dh_pub (vchar_t *, vchar_t **); 152static int oakley_compute_keymat_x (phase2_handle_t *, int, int); 153static int get_cert_fromlocal (phase1_handle_t *, int); 154static int oakley_check_certid (phase1_handle_t *iph1); 155static int oakley_check_certid_1 (vchar_t *, int, int, void*, cert_status_t *certStatus); 156#ifdef HAVE_OPENSSL 157static int check_typeofcertname (int, int); 158#endif 159static cert_t *save_certbuf (struct isakmp_gen *); 160static int oakley_padlen (int, int); 161 162static int base64toCFData (vchar_t *, CFDataRef*); 163static cert_t *oakley_appendcert_to_certchain (cert_t *, cert_t *); 164 165int 166oakley_get_defaultlifetime() 167{ 168 return OAKLEY_ATTR_SA_LD_SEC_DEFAULT; 169} 170 171int 172oakley_dhinit() 173{ 174 /* set DH MODP */ 175 INITDHVAL(dh_modp768, OAKLEY_PRIME_MODP768, 176 OAKLEY_ATTR_GRP_DESC_MODP768, OAKLEY_ATTR_GRP_TYPE_MODP); 177 INITDHVAL(dh_modp1024, OAKLEY_PRIME_MODP1024, 178 OAKLEY_ATTR_GRP_DESC_MODP1024, OAKLEY_ATTR_GRP_TYPE_MODP); 179 INITDHVAL(dh_modp1536, OAKLEY_PRIME_MODP1536, 180 OAKLEY_ATTR_GRP_DESC_MODP1536, OAKLEY_ATTR_GRP_TYPE_MODP); 181 INITDHVAL(dh_modp2048, OAKLEY_PRIME_MODP2048, 182 OAKLEY_ATTR_GRP_DESC_MODP2048, OAKLEY_ATTR_GRP_TYPE_MODP); 183 INITDHVAL(dh_modp3072, OAKLEY_PRIME_MODP3072, 184 OAKLEY_ATTR_GRP_DESC_MODP3072, OAKLEY_ATTR_GRP_TYPE_MODP); 185 INITDHVAL(dh_modp4096, OAKLEY_PRIME_MODP4096, 186 OAKLEY_ATTR_GRP_DESC_MODP4096, OAKLEY_ATTR_GRP_TYPE_MODP); 187 INITDHVAL(dh_modp6144, OAKLEY_PRIME_MODP6144, 188 OAKLEY_ATTR_GRP_DESC_MODP6144, OAKLEY_ATTR_GRP_TYPE_MODP); 189 INITDHVAL(dh_modp8192, OAKLEY_PRIME_MODP8192, 190 OAKLEY_ATTR_GRP_DESC_MODP8192, OAKLEY_ATTR_GRP_TYPE_MODP); 191 192 return 0; 193} 194 195void 196oakley_dhgrp_free(struct dhgroup *dhgrp) 197{ 198 VPTRINIT(dhgrp->prime); 199 VPTRINIT(dhgrp->curve_a); 200 VPTRINIT(dhgrp->curve_b); 201 VPTRINIT(dhgrp->order); 202 racoon_free(dhgrp); 203} 204 205/* 206 * RFC2409 5 207 * The length of the Diffie-Hellman public value MUST be equal to the 208 * length of the prime modulus over which the exponentiation was 209 * performed, prepending zero bits to the value if necessary. 210 */ 211static int 212oakley_check_dh_pub(vchar_t *prime, vchar_t **pub0) 213{ 214 vchar_t *tmp; 215 vchar_t *pub = *pub0; 216 217 if (prime->l == pub->l) 218 return 0; 219 220 if (prime->l < pub->l) { 221 /* what should i do ? */ 222 plog(ASL_LEVEL_ERR, 223 "invalid public information was generated.\n"); 224 return -1; 225 } 226 227 /* prime->l > pub->l */ 228 tmp = vmalloc(prime->l); 229 if (tmp == NULL) { 230 plog(ASL_LEVEL_ERR, 231 "failed to get DH buffer.\n"); 232 return -1; 233 } 234 memcpy(tmp->v + prime->l - pub->l, pub->v, pub->l); 235 236 vfree(*pub0); 237 *pub0 = tmp; 238 239 return 0; 240} 241 242/* 243 * compute sharing secret of DH 244 * IN: *dh, *pub, *priv, *pub_p 245 * OUT: **gxy 246 */ 247#ifdef HAVE_OPENSSL 248int 249oakley_dh_compute(const struct dhgroup *dh, vchar_t *pub, vchar_t *priv, vchar_t *pub_p, vchar_t **gxy) 250{ 251#ifdef ENABLE_STATS 252 struct timeval start, end; 253#endif 254 if ((*gxy = vmalloc(dh->prime->l)) == NULL) { 255 plog(ASL_LEVEL_ERR, 256 "failed to get DH buffer.\n"); 257 return -1; 258 } 259 260#ifdef ENABLE_STATS 261 gettimeofday(&start, NULL); 262#endif 263 switch (dh->type) { 264 case OAKLEY_ATTR_GRP_TYPE_MODP: 265 if (eay_dh_compute(dh->prime, dh->gen1, pub, priv, pub_p, gxy) < 0) { 266 plog(ASL_LEVEL_ERR, 267 "failed to compute dh value.\n"); 268 return -1; 269 } 270 break; 271 case OAKLEY_ATTR_GRP_TYPE_ECP: 272 case OAKLEY_ATTR_GRP_TYPE_EC2N: 273 plog(ASL_LEVEL_ERR, 274 "dh type %d isn't supported.\n", dh->type); 275 return -1; 276 default: 277 plog(ASL_LEVEL_ERR, 278 "invalid dh type %d.\n", dh->type); 279 return -1; 280 } 281 282#ifdef ENABLE_STATS 283 gettimeofday(&end, NULL); 284 plog(ASL_LEVEL_NOTICE, "%s(%s%d): %8.6f", __func__, 285 s_attr_isakmp_group(dh->type), dh->prime->l << 3, 286 timedelta(&start, &end)); 287#endif 288 289 plog(ASL_LEVEL_DEBUG, "compute DH's shared.\n"); 290 291 return 0; 292} 293#else 294int 295oakley_dh_compute(const struct dhgroup *dh, vchar_t *pub_p, size_t publicKeySize, vchar_t **gxy, SecDHContext *dhC) 296{ 297 298 vchar_t *computed_key = NULL; 299 size_t computed_keylen; 300 size_t maxKeyLen; 301 302#ifdef ENABLE_STATS 303 struct timeval start, end; 304 gettimeofday(&start, NULL); 305#endif 306 307 plog(ASL_LEVEL_DEBUG, "compute DH result.\n"); 308 309 maxKeyLen = SecDHGetMaxKeyLength(*dhC); 310 computed_key = vmalloc(maxKeyLen); 311 if (computed_key == NULL) { 312 plog(ASL_LEVEL_ERR, "memory error.\n"); 313 goto fail; 314 } 315 computed_keylen = computed_key->l; 316 if (SecDHComputeKey(*dhC, (uint8_t*)pub_p->v + (maxKeyLen - publicKeySize), publicKeySize, 317 (uint8_t*)computed_key->v, &computed_keylen)) { 318 plog(ASL_LEVEL_ERR, "failed to compute dh value.\n"); 319 goto fail; 320 } 321 322#ifdef ENABLE_STATS 323 gettimeofday(&end, NULL); 324 plog(ASL_LEVEL_NOTICE, "%s(%s%d): %8.6f", __func__, 325 s_attr_isakmp_group(dh->type), dh->prime->l << 3, 326 timedelta(&start, &end)); 327#endif 328 329 *gxy = vmalloc(maxKeyLen); 330 if (*gxy == NULL) { 331 plog(ASL_LEVEL_ERR, "memory error.\n"); 332 goto fail; 333 } 334 memcpy((*gxy)->v + (maxKeyLen - computed_keylen), computed_key->v, computed_keylen); 335 plog(ASL_LEVEL_DEBUG, "compute DH's shared.\n"); 336 if (*dhC) { 337 SecDHDestroy(*dhC); 338 *dhC = NULL; 339 } 340 vfree(computed_key); 341 return 0; 342 343fail: 344 if (*dhC) { 345 SecDHDestroy(*dhC); 346 *dhC = NULL; 347 } 348 vfree(*gxy); 349 vfree(computed_key); 350 return -1; 351} 352 353#endif 354 355/* 356 * generate values of DH 357 * IN: *dh 358 * OUT: **pub, **priv 359 */ 360#ifdef HAVE_OPENSSL 361int 362oakley_dh_generate(const struct dhgroup *dh, vchar_t **pub, vchar_t **priv) 363{ 364#ifdef ENABLE_STATS 365 struct timeval start, end; 366 gettimeofday(&start, NULL); 367#endif 368 switch (dh->type) { 369 case OAKLEY_ATTR_GRP_TYPE_MODP: 370 if (eay_dh_generate(dh->prime, dh->gen1, dh->gen2, pub, priv) < 0) { 371 plog(ASL_LEVEL_ERR, 372 "failed to compute dh value.\n"); 373 return -1; 374 } 375 break; 376 377 case OAKLEY_ATTR_GRP_TYPE_ECP: 378 case OAKLEY_ATTR_GRP_TYPE_EC2N: 379 plog(ASL_LEVEL_ERR, 380 "dh type %d isn't supported.\n", dh->type); 381 return -1; 382 default: 383 plog(ASL_LEVEL_ERR, 384 "invalid dh type %d.\n", dh->type); 385 return -1; 386 } 387 388#ifdef ENABLE_STATS 389 gettimeofday(&end, NULL); 390 plog(ASL_LEVEL_NOTICE, "%s(%s%d): %8.6f", __func__, 391 s_attr_isakmp_group(dh->type), dh->prime->l << 3, 392 timedelta(&start, &end)); 393#endif 394 395 if (oakley_check_dh_pub(dh->prime, pub) != 0) 396 return -1; 397 398 plog(ASL_LEVEL_DEBUG, "compute DH's private.\n"); 399 plog(ASL_LEVEL_DEBUG, "compute DH's public.\n"); 400 401 return 0; 402} 403#else 404int 405oakley_dh_generate(const struct dhgroup *dh, vchar_t **pub, size_t *publicKeySize, SecDHContext *dhC) 406{ 407 vchar_t *public = NULL; 408 size_t maxKeyLen; 409 410#ifdef ENABLE_STATS 411 struct timeval start, end; 412 gettimeofday(&start, NULL); 413#endif 414 415 plog(ASL_LEVEL_DEBUG, "generate DH key pair.\n"); 416 *pub = NULL; 417 switch (dh->type) { 418 case OAKLEY_ATTR_GRP_TYPE_MODP: 419#define SECDH_MODP_GENERATOR 2 420 if (SecDHCreate(SECDH_MODP_GENERATOR, (uint8_t*)dh->prime->v, dh->prime->l, 0, NULL, 0, dhC)) { 421 plog(ASL_LEVEL_ERR, "failed to create dh context.\n"); 422 goto fail; 423 } 424 maxKeyLen = SecDHGetMaxKeyLength(*dhC); 425 public = vmalloc(maxKeyLen); 426 *publicKeySize = public->l; 427 if (public == NULL) { 428 plog(ASL_LEVEL_ERR, "memory error.\n"); 429 goto fail; 430 } 431 if (SecDHGenerateKeypair(*dhC, (uint8_t*)public->v, publicKeySize)) { 432 plog(ASL_LEVEL_ERR, "failed to generate dh key pair.\n"); 433 goto fail; 434 } 435 plog(ASL_LEVEL_DEBUG, "got DH key pair.\n"); 436 437 *pub = vmalloc(maxKeyLen); 438 if (*pub == NULL) { 439 plog(ASL_LEVEL_ERR, "memory error.\n"); 440 goto fail; 441 } 442 /* copy and fill with leading zeros */ 443 memcpy((*pub)->v + (maxKeyLen - *publicKeySize), public->v, *publicKeySize); 444 break; 445 446 case OAKLEY_ATTR_GRP_TYPE_ECP: 447 case OAKLEY_ATTR_GRP_TYPE_EC2N: 448 plog(ASL_LEVEL_ERR, 449 "dh type %d isn't supported.\n", dh->type); 450 goto fail; 451 default: 452 plog(ASL_LEVEL_ERR, 453 "invalid dh type %d.\n", dh->type); 454 goto fail; 455 } 456 457#ifdef ENABLE_STATS 458 gettimeofday(&end, NULL); 459 plog(ASL_LEVEL_NOTICE, "%s(%s%d): %8.6f", __func__, 460 s_attr_isakmp_group(dh->type), dh->prime->l << 3, 461 timedelta(&start, &end)); 462#endif 463 464 if (oakley_check_dh_pub(dh->prime, pub) != 0) { 465 plog(ASL_LEVEL_DEBUG, "failed DH public key size check.\n"); 466 goto fail; 467 } 468 469 //plogdump(ASL_LEVEL_DEBUG, (*pub)->v, (*pub)->l, "compute DH's public.\n"); 470 471 vfree(public); 472 return 0; 473 474fail: 475 if (*dhC) { 476 SecDHDestroy(*dhC); 477 *dhC = NULL; 478 } 479 vfree(*pub); 480 vfree(public); 481 return -1; 482 483} 484#endif 485 486/* 487 * copy pre-defined dhgroup values. 488 */ 489int 490oakley_setdhgroup(int group, struct dhgroup **dhgrp) 491{ 492 struct dhgroup *g; 493 494 *dhgrp = NULL; /* just make sure, initialize */ 495 496 g = alg_oakley_dhdef_group(group); 497 if (g == NULL) { 498 plog(ASL_LEVEL_ERR, 499 "invalid DH parameter grp=%d.\n", group); 500 return -1; 501 } 502 503 if (!g->type || !g->prime || !g->gen1) { 504 /* unsuported */ 505 plog(ASL_LEVEL_ERR, 506 "unsupported DH parameters grp=%d.\n", group); 507 return -1; 508 } 509 510 *dhgrp = racoon_calloc(1, sizeof(struct dhgroup)); 511 if (*dhgrp == NULL) { 512 plog(ASL_LEVEL_ERR, 513 "failed to get DH buffer.\n"); 514 return 0; 515 } 516 517 /* set defined dh vlaues */ 518 memcpy(*dhgrp, g, sizeof(*g)); 519 (*dhgrp)->prime = vdup(g->prime); 520 521 return 0; 522} 523 524/* 525 * PRF 526 * 527 * NOTE: we do not support prf with different input/output bitwidth, 528 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example) in 529 * oakley_compute_keymat(). If you add support for such prf function, 530 * modify oakley_compute_keymat() accordingly. 531 */ 532vchar_t * 533oakley_prf(vchar_t *key, vchar_t *buf, phase1_handle_t *iph1) 534{ 535 vchar_t *res = NULL; 536 int type = OAKLEY_ATTR_HASH_ALG_MD5; 537 538 if (iph1->approval == NULL) { 539 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 540 /* 541 * it's before negotiating hash algorithm. 542 * We use md5 as default. 543 */ 544 type = OAKLEY_ATTR_HASH_ALG_MD5; 545 } 546 } else 547 { 548 type = iph1->approval->hashtype; 549 } 550 res = alg_oakley_hmacdef_one(type, key, buf); 551 if (res == NULL) { 552 plog(ASL_LEVEL_ERR, 553 "invalid hmac algorithm %d.\n", type); 554 return NULL; 555 } 556 557 return res; 558} 559 560/* 561 * hash 562 */ 563vchar_t * 564oakley_hash(vchar_t *buf, phase1_handle_t *iph1) 565{ 566 vchar_t *res = NULL; 567 int type = OAKLEY_ATTR_HASH_ALG_MD5; 568 569 if (iph1->approval == NULL) { 570 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 571 /* 572 * it's before negotiating hash algorithm. 573 * We use md5 as default. 574 */ 575 type = OAKLEY_ATTR_HASH_ALG_MD5; 576 } 577 } else { 578 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 579 type = iph1->approval->hashtype; 580 } 581 } 582 583 res = alg_oakley_hashdef_one(type, buf); 584 if (res == NULL) { 585 plog(ASL_LEVEL_ERR, 586 "invalid hash algorithm %d.\n", type); 587 return NULL; 588 } 589 590 return res; 591} 592 593/* 594 * compute KEYMAT 595 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05. 596 */ 597int 598oakley_compute_keymat(phase2_handle_t *iph2, int side) 599{ 600 int error = -1; 601 602 /* compute sharing secret of DH when PFS */ 603 if (iph2->approval->pfs_group && iph2->dhpub_p) { 604#ifdef HAVE_OPENSSL 605 if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub, 606 iph2->dhpriv, iph2->dhpub_p, &iph2->dhgxy) < 0) 607#else 608 if (oakley_dh_compute(iph2->pfsgrp, iph2->dhpub_p, iph2->publicKeySize, &iph2->dhgxy, &iph2->dhC) < 0) 609#endif 610 goto end; 611 } 612 613 /* compute keymat */ 614 if (oakley_compute_keymat_x(iph2, side, INBOUND_SA) < 0 615 || oakley_compute_keymat_x(iph2, side, OUTBOUND_SA) < 0) 616 goto end; 617 618 plog(ASL_LEVEL_DEBUG, "KEYMAT computed.\n"); 619 620 error = 0; 621 622end: 623 return error; 624} 625 626/* 627 * compute KEYMAT. 628 * KEYMAT = prf(SKEYID_d, protocol | SPI | Ni_b | Nr_b). 629 * If PFS is desired and KE payloads were exchanged, 630 * KEYMAT = prf(SKEYID_d, g(qm)^xy | protocol | SPI | Ni_b | Nr_b) 631 * 632 * NOTE: we do not support prf with different input/output bitwidth, 633 * so we do not implement RFC2409 Appendix B (DOORAK-MAC example). 634 */ 635static int 636oakley_compute_keymat_x(phase2_handle_t *iph2, int side, int sa_dir) 637{ 638 vchar_t *buf = NULL, *res = NULL, *bp; 639 char *p; 640 int len; 641 int error = -1; 642 int pfs = 0; 643 int dupkeymat; /* generate K[1-dupkeymat] */ 644 struct saproto *pr; 645 struct satrns *tr; 646 int encklen, authklen, l; 647 648 pfs = ((iph2->approval->pfs_group && iph2->dhgxy) ? 1 : 0); 649 650 len = pfs ? iph2->dhgxy->l : 0; 651 len += (1 652 + sizeof(u_int32_t) /* XXX SPI size */ 653 + iph2->nonce->l 654 + iph2->nonce_p->l); 655 buf = vmalloc(len); 656 if (buf == NULL) { 657 plog(ASL_LEVEL_ERR, 658 "failed to get keymat buffer.\n"); 659 goto end; 660 } 661 662 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 663 p = buf->v; 664 665 /* if PFS */ 666 if (pfs) { 667 memcpy(p, iph2->dhgxy->v, iph2->dhgxy->l); 668 p += iph2->dhgxy->l; 669 } 670 671 p[0] = pr->proto_id; 672 p += 1; 673 674 memcpy(p, (sa_dir == INBOUND_SA ? &pr->spi : &pr->spi_p), 675 sizeof(pr->spi)); 676 p += sizeof(pr->spi); 677 678 bp = (side == INITIATOR ? iph2->nonce : iph2->nonce_p); 679 memcpy(p, bp->v, bp->l); 680 p += bp->l; 681 682 bp = (side == INITIATOR ? iph2->nonce_p : iph2->nonce); 683 memcpy(p, bp->v, bp->l); 684 p += bp->l; 685 686 /* compute IV */ 687 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "KEYMAT compute with\n"); 688 689 /* res = K1 */ 690 res = oakley_prf(iph2->ph1->skeyid_d, buf, iph2->ph1); 691 if (res == NULL) 692 goto end; 693 694 /* compute key length needed */ 695 encklen = authklen = 0; 696 switch (pr->proto_id) { 697 case IPSECDOI_PROTO_IPSEC_ESP: 698 for (tr = pr->head; tr; tr = tr->next) { 699 l = alg_ipsec_encdef_keylen(tr->trns_id, 700 tr->encklen); 701 if (l > encklen) 702 encklen = l; 703 704 l = alg_ipsec_hmacdef_hashlen(tr->authtype); 705 if (l > authklen) 706 authklen = l; 707 } 708 break; 709 case IPSECDOI_PROTO_IPSEC_AH: 710 for (tr = pr->head; tr; tr = tr->next) { 711 l = alg_ipsec_hmacdef_hashlen(tr->trns_id); 712 if (l > authklen) 713 authklen = l; 714 } 715 break; 716 default: 717 break; 718 } 719 plog(ASL_LEVEL_DEBUG, "encklen=%d authklen=%d\n", 720 encklen, authklen); 721 722 dupkeymat = (encklen + authklen) / 8 / res->l; 723 dupkeymat += 2; /* safety mergin */ 724 if (dupkeymat < 3) 725 dupkeymat = 3; 726 //plog(ASL_LEVEL_DEBUG, 727 // "generating %zu bits of key (dupkeymat=%d)\n", 728 // dupkeymat * 8 * res->l, dupkeymat); 729 if (0 < --dupkeymat) { 730 vchar_t *prev = res; /* K(n-1) */ 731 vchar_t *seed = NULL; /* seed for Kn */ 732 size_t l; 733 734 /* 735 * generating long key (isakmp-oakley-08 5.5) 736 * KEYMAT = K1 | K2 | K3 | ... 737 * where 738 * src = [ g(qm)^xy | ] protocol | SPI | Ni_b | Nr_b 739 * K1 = prf(SKEYID_d, src) 740 * K2 = prf(SKEYID_d, K1 | src) 741 * K3 = prf(SKEYID_d, K2 | src) 742 * Kn = prf(SKEYID_d, K(n-1) | src) 743 */ 744 //plog(ASL_LEVEL_DEBUG, 745 // "generating K1...K%d for KEYMAT.\n", 746 // dupkeymat + 1); 747 748 seed = vmalloc(prev->l + buf->l); 749 if (seed == NULL) { 750 plog(ASL_LEVEL_ERR, 751 "failed to get keymat buffer.\n"); 752 if (prev && prev != res) 753 vfree(prev); 754 goto end; 755 } 756 757 while (dupkeymat--) { 758 vchar_t *this = NULL; /* Kn */ 759 int update_prev; 760 761 memcpy(seed->v, prev->v, prev->l); 762 memcpy(seed->v + prev->l, buf->v, buf->l); 763 this = oakley_prf(iph2->ph1->skeyid_d, seed, 764 iph2->ph1); 765 if (!this) { 766 plog(ASL_LEVEL_ERR, 767 "oakley_prf memory overflow\n"); 768 if (prev && prev != res) 769 vfree(prev); 770 vfree(this); 771 vfree(seed); 772 goto end; 773 } 774 775 update_prev = (prev && prev == res) ? 1 : 0; 776 777 l = res->l; 778 res = vrealloc(res, l + this->l); 779 780 if (update_prev) 781 prev = res; 782 783 if (res == NULL) { 784 plog(ASL_LEVEL_ERR, 785 "failed to get keymat buffer.\n"); 786 if (prev && prev != res) 787 vfree(prev); 788 vfree(this); 789 vfree(seed); 790 goto end; 791 } 792 memcpy(res->v + l, this->v, this->l); 793 794 if (prev && prev != res) 795 vfree(prev); 796 prev = this; 797 this = NULL; 798 } 799 800 if (prev && prev != res) 801 vfree(prev); 802 vfree(seed); 803 } 804 805 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, ""); 806 807 if (sa_dir == INBOUND_SA) 808 pr->keymat = res; 809 else 810 pr->keymat_p = res; 811 res = NULL; 812 } 813 814 error = 0; 815 816end: 817 if (error) { 818 for (pr = iph2->approval->head; pr != NULL; pr = pr->next) { 819 if (pr->keymat) { 820 vfree(pr->keymat); 821 pr->keymat = NULL; 822 } 823 if (pr->keymat_p) { 824 vfree(pr->keymat_p); 825 pr->keymat_p = NULL; 826 } 827 } 828 } 829 830 if (buf != NULL) 831 vfree(buf); 832 if (res) 833 vfree(res); 834 835 return error; 836} 837 838 839/* 840 * compute HASH(3) prf(SKEYID_a, 0 | M-ID | Ni_b | Nr_b) 841 * see seciton 5.5 Phase 2 - Quick Mode in isakmp-oakley-05. 842 */ 843vchar_t * 844oakley_compute_hash3(phase1_handle_t *iph1, u_int32_t msgid, vchar_t *body) 845{ 846 vchar_t *buf = 0, *res = 0; 847 int len; 848 int error = -1; 849 850 /* create buffer */ 851 len = 1 + sizeof(u_int32_t) + body->l; 852 buf = vmalloc(len); 853 if (buf == NULL) { 854 plog(ASL_LEVEL_DEBUG, 855 "failed to get hash buffer\n"); 856 goto end; 857 } 858 859 buf->v[0] = 0; 860 861 memcpy(buf->v + 1, (char *)&msgid, sizeof(msgid)); 862 863 memcpy(buf->v + 1 + sizeof(u_int32_t), body->v, body->l); 864 865 /* compute HASH */ 866 res = oakley_prf(iph1->skeyid_a, buf, iph1); 867 if (res == NULL) 868 goto end; 869 870 error = 0; 871 872 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH computed:\n"); 873 874end: 875 if (buf != NULL) 876 vfree(buf); 877 return res; 878} 879 880/* 881 * compute HASH type of prf(SKEYID_a, M-ID | buffer) 882 * e.g. 883 * for quick mode HASH(1): 884 * prf(SKEYID_a, M-ID | SA | Ni [ | KE ] [ | IDci | IDcr ]) 885 * for quick mode HASH(2): 886 * prf(SKEYID_a, M-ID | Ni_b | SA | Nr [ | KE ] [ | IDci | IDcr ]) 887 * for Informational exchange: 888 * prf(SKEYID_a, M-ID | N/D) 889 */ 890vchar_t * 891oakley_compute_hash1(phase1_handle_t *iph1, u_int32_t msgid, vchar_t *body) 892{ 893 vchar_t *buf = NULL, *res = NULL; 894 char *p; 895 int len; 896 int error = -1; 897 898 /* create buffer */ 899 len = sizeof(u_int32_t) + body->l; 900 buf = vmalloc(len); 901 if (buf == NULL) { 902 plog(ASL_LEVEL_DEBUG, 903 "failed to get hash buffer\n"); 904 goto end; 905 } 906 907 p = buf->v; 908 909 memcpy(buf->v, (char *)&msgid, sizeof(msgid)); 910 p += sizeof(u_int32_t); 911 912 memcpy(p, body->v, body->l); 913 914 /* compute HASH */ 915 res = oakley_prf(iph1->skeyid_a, buf, iph1); 916 if (res == NULL) 917 goto end; 918 919 error = 0; 920 921 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH computed:\n"); 922 923end: 924 if (buf != NULL) 925 vfree(buf); 926 return res; 927} 928 929/* 930 * compute phase1 HASH 931 * main/aggressive 932 * I-digest = prf(SKEYID, g^i | g^r | CKY-I | CKY-R | SAi_b | ID_i1_b) 933 * R-digest = prf(SKEYID, g^r | g^i | CKY-R | CKY-I | SAi_b | ID_r1_b) 934 * for gssapi, also include all GSS tokens, and call gss_wrap on the result 935 */ 936vchar_t * 937oakley_ph1hash_common(phase1_handle_t *iph1, int sw) 938{ 939 vchar_t *buf = NULL, *res = NULL, *bp; 940 char *p, *bp2; 941 int len, bl; 942 int error = -1; 943 944 /* create buffer */ 945 len = iph1->dhpub->l 946 + iph1->dhpub_p->l 947 + sizeof(cookie_t) * 2 948 + iph1->sa->l 949 + (sw == GENERATE ? iph1->id->l : iph1->id_p->l); 950 951 buf = vmalloc(len); 952 if (buf == NULL) { 953 plog(ASL_LEVEL_ERR, 954 "failed to get hash buffer\n"); 955 goto end; 956 } 957 958 p = buf->v; 959 960 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p); 961 memcpy(p, bp->v, bp->l); 962 p += bp->l; 963 964 bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub); 965 memcpy(p, bp->v, bp->l); 966 p += bp->l; 967 968 if (iph1->side == INITIATOR) 969 bp2 = (sw == GENERATE ? 970 (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck); 971 else 972 bp2 = (sw == GENERATE ? 973 (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck); 974 bl = sizeof(cookie_t); 975 memcpy(p, bp2, bl); 976 p += bl; 977 978 if (iph1->side == INITIATOR) 979 bp2 = (sw == GENERATE ? 980 (char *)&iph1->index.r_ck : (char *)&iph1->index.i_ck); 981 else 982 bp2 = (sw == GENERATE ? 983 (char *)&iph1->index.i_ck : (char *)&iph1->index.r_ck); 984 bl = sizeof(cookie_t); 985 memcpy(p, bp2, bl); 986 p += bl; 987 988 bp = iph1->sa; 989 memcpy(p, bp->v, bp->l); 990 p += bp->l; 991 992 bp = (sw == GENERATE ? iph1->id : iph1->id_p); 993 memcpy(p, bp->v, bp->l); 994 p += bp->l; 995 996 /* compute HASH */ 997 res = oakley_prf(iph1->skeyid, buf, iph1); 998 if (res == NULL) 999 goto end; 1000 1001 error = 0; 1002 1003end: 1004 if (buf != NULL) 1005 vfree(buf); 1006 return res; 1007} 1008 1009/* 1010 * compute HASH_I on base mode. 1011 * base:psk,rsa 1012 * HASH_I = prf(SKEYID, g^xi | CKY-I | CKY-R | SAi_b | IDii_b) 1013 * base:sig 1014 * HASH_I = prf(hash(Ni_b | Nr_b), g^xi | CKY-I | CKY-R | SAi_b | IDii_b) 1015 */ 1016vchar_t * 1017oakley_ph1hash_base_i(phase1_handle_t *iph1, int sw) 1018{ 1019 vchar_t *buf = NULL, *res = NULL, *bp; 1020 vchar_t *hashkey = NULL; 1021 vchar_t *hash = NULL; /* for signature mode */ 1022 char *p; 1023 int len; 1024 int error = -1; 1025 1026 /* sanity check */ 1027 if (iph1->etype != ISAKMP_ETYPE_BASE) { 1028 plog(ASL_LEVEL_ERR, 1029 "invalid etype for this hash function\n"); 1030 return NULL; 1031 } 1032 1033 switch (AUTHMETHOD(iph1)) { 1034 case OAKLEY_ATTR_AUTH_METHOD_PSKEY: 1035 case OAKLEY_ATTR_AUTH_METHOD_RSAENC: 1036 case OAKLEY_ATTR_AUTH_METHOD_RSAREV: 1037#ifdef ENABLE_HYBRID 1038 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: 1039 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 1040 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: 1041 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 1042 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: 1043 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 1044#endif 1045 if (iph1->skeyid == NULL) { 1046 plog(ASL_LEVEL_ERR, "no SKEYID found.\n"); 1047 return NULL; 1048 } 1049 hashkey = iph1->skeyid; 1050 break; 1051 1052 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 1053#ifdef ENABLE_HYBRID 1054 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 1055 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 1056 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: 1057 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 1058#endif 1059 /* make hash for seed */ 1060 len = iph1->nonce->l + iph1->nonce_p->l; 1061 buf = vmalloc(len); 1062 if (buf == NULL) { 1063 plog(ASL_LEVEL_ERR, 1064 "failed to get hash buffer\n"); 1065 goto end; 1066 } 1067 p = buf->v; 1068 1069 bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce); 1070 memcpy(p, bp->v, bp->l); 1071 p += bp->l; 1072 1073 bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p); 1074 memcpy(p, bp->v, bp->l); 1075 p += bp->l; 1076 1077 hash = oakley_hash(buf, iph1); 1078 if (hash == NULL) 1079 goto end; 1080 vfree(buf); 1081 buf = NULL; 1082 1083 hashkey = hash; 1084 break; 1085 1086 default: 1087 plog(ASL_LEVEL_ERR, 1088 "not supported authentication method %d\n", 1089 iph1->approval->authmethod); 1090 return NULL; 1091 1092 } 1093 1094 len = (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l) 1095 + sizeof(cookie_t) * 2 1096 + iph1->sa->l 1097 + (sw == GENERATE ? iph1->id->l : iph1->id_p->l); 1098 buf = vmalloc(len); 1099 if (buf == NULL) { 1100 plog(ASL_LEVEL_ERR, 1101 "failed to get hash buffer\n"); 1102 goto end; 1103 } 1104 p = buf->v; 1105 1106 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p); 1107 memcpy(p, bp->v, bp->l); 1108 p += bp->l; 1109 1110 memcpy(p, &iph1->index.i_ck, sizeof(cookie_t)); 1111 p += sizeof(cookie_t); 1112 memcpy(p, &iph1->index.r_ck, sizeof(cookie_t)); 1113 p += sizeof(cookie_t); 1114 1115 memcpy(p, iph1->sa->v, iph1->sa->l); 1116 p += iph1->sa->l; 1117 1118 bp = (sw == GENERATE ? iph1->id : iph1->id_p); 1119 memcpy(p, bp->v, bp->l); 1120 p += bp->l; 1121 1122 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "HASH_I with:\n"); 1123 1124 /* compute HASH */ 1125 res = oakley_prf(hashkey, buf, iph1); 1126 if (res == NULL) 1127 goto end; 1128 1129 error = 0; 1130 1131 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH_I computed:\n"); 1132 1133end: 1134 if (hash != NULL) 1135 vfree(hash); 1136 if (buf != NULL) 1137 vfree(buf); 1138 return res; 1139} 1140 1141/* 1142 * compute HASH_R on base mode for signature method. 1143 * base: 1144 * HASH_R = prf(hash(Ni_b | Nr_b), g^xi | g^xr | CKY-I | CKY-R | SAi_b | IDii_b) 1145 */ 1146vchar_t * 1147oakley_ph1hash_base_r(phase1_handle_t *iph1, int sw) 1148{ 1149 vchar_t *buf = NULL, *res = NULL, *bp; 1150 vchar_t *hash = NULL; 1151 char *p; 1152 int len; 1153 int error = -1; 1154 1155 /* sanity check */ 1156 if (iph1->etype != ISAKMP_ETYPE_BASE) { 1157 plog(ASL_LEVEL_ERR, 1158 "invalid etype for this hash function\n"); 1159 return NULL; 1160 } 1161 1162 switch(AUTHMETHOD(iph1)) { 1163 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 1164#ifdef ENABLE_HYBRID 1165 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 1166 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 1167 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: 1168 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 1169 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: 1170#endif 1171 break; 1172 default: 1173 plog(ASL_LEVEL_ERR, 1174 "not supported authentication method %d\n", 1175 iph1->approval->authmethod); 1176 return NULL; 1177 break; 1178 } 1179 1180 /* make hash for seed */ 1181 len = iph1->nonce->l + iph1->nonce_p->l; 1182 buf = vmalloc(len); 1183 if (buf == NULL) { 1184 plog(ASL_LEVEL_ERR, 1185 "failed to get hash buffer\n"); 1186 goto end; 1187 } 1188 p = buf->v; 1189 1190 bp = (sw == GENERATE ? iph1->nonce_p : iph1->nonce); 1191 memcpy(p, bp->v, bp->l); 1192 p += bp->l; 1193 1194 bp = (sw == GENERATE ? iph1->nonce : iph1->nonce_p); 1195 memcpy(p, bp->v, bp->l); 1196 p += bp->l; 1197 1198 hash = oakley_hash(buf, iph1); 1199 if (hash == NULL) 1200 goto end; 1201 vfree(buf); 1202 buf = NULL; 1203 1204 /* make really hash */ 1205 len = (sw == GENERATE ? iph1->dhpub_p->l : iph1->dhpub->l) 1206 + (sw == GENERATE ? iph1->dhpub->l : iph1->dhpub_p->l) 1207 + sizeof(cookie_t) * 2 1208 + iph1->sa->l 1209 + (sw == GENERATE ? iph1->id_p->l : iph1->id->l); 1210 buf = vmalloc(len); 1211 if (buf == NULL) { 1212 plog(ASL_LEVEL_ERR, 1213 "failed to get hash buffer\n"); 1214 goto end; 1215 } 1216 p = buf->v; 1217 1218 1219 bp = (sw == GENERATE ? iph1->dhpub_p : iph1->dhpub); 1220 memcpy(p, bp->v, bp->l); 1221 p += bp->l; 1222 1223 bp = (sw == GENERATE ? iph1->dhpub : iph1->dhpub_p); 1224 memcpy(p, bp->v, bp->l); 1225 p += bp->l; 1226 1227 memcpy(p, &iph1->index.i_ck, sizeof(cookie_t)); 1228 p += sizeof(cookie_t); 1229 memcpy(p, &iph1->index.r_ck, sizeof(cookie_t)); 1230 p += sizeof(cookie_t); 1231 1232 memcpy(p, iph1->sa->v, iph1->sa->l); 1233 p += iph1->sa->l; 1234 1235 bp = (sw == GENERATE ? iph1->id_p : iph1->id); 1236 memcpy(p, bp->v, bp->l); 1237 p += bp->l; 1238 1239 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "HASH_R with:\n"); 1240 1241 /* compute HASH */ 1242 res = oakley_prf(hash, buf, iph1); 1243 if (res == NULL) 1244 goto end; 1245 1246 error = 0; 1247 1248 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, "HASH_R computed:\n"); 1249 1250end: 1251 if (buf != NULL) 1252 vfree(buf); 1253 if (hash) 1254 vfree(hash); 1255 return res; 1256} 1257 1258#if HAVE_OPENDIR 1259static int 1260oakley_verify_userid(phase1_handle_t *iph1) 1261{ 1262 cert_t *p; 1263 vchar_t *user_id; 1264 int user_id_found = 0; 1265 1266 for (p = iph1->cert_p; p; p = p->chain) { 1267 user_id = eay_get_x509_common_name(&p->cert); //%%%%%%%% fix this 1268 if (user_id) { 1269 user_id_found = 1; 1270 // the following functions will check if user_id == 0 1271 if (open_dir_authorize_id(user_id, iph1->rmconf->open_dir_auth_group)) { 1272 vfree(user_id); 1273 return 0; 1274 } 1275 vfree(user_id); 1276 } 1277 } 1278 if (user_id_found) { 1279 plog(ASL_LEVEL_ERR, 1280 "the peer is not authorized for access.\n"); 1281 } else { 1282 plog(ASL_LEVEL_ERR, 1283 "the peer is not authorized for access - user ID not found.\n"); 1284 } 1285 return ISAKMP_NTYPE_AUTHENTICATION_FAILED; 1286} 1287#endif /* HAVE_OPENDIR */ 1288 1289/* 1290 * compute each authentication method in phase 1. 1291 * OUT: 1292 * 0: OK 1293 * -1: error 1294 * other: error to be reply with notification. 1295 * the value is notification type. 1296 */ 1297int 1298oakley_validate_auth(phase1_handle_t *iph1) 1299{ 1300 vchar_t *my_hash = NULL; 1301 int result; 1302#ifdef ENABLE_STATS 1303 struct timeval start, end; 1304#endif 1305 SecKeyRef publicKeyRef = NULL; 1306 1307#ifdef ENABLE_STATS 1308 gettimeofday(&start, NULL); 1309#endif 1310 1311 switch (AUTHMETHOD(iph1)) { 1312 case OAKLEY_ATTR_AUTH_METHOD_PSKEY: 1313#ifdef ENABLE_HYBRID 1314 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: 1315 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 1316#endif 1317 /* validate HASH */ 1318 { 1319 char *r_hash; 1320 1321 if (iph1->id_p == NULL || iph1->pl_hash == NULL) { 1322 plog(ASL_LEVEL_ERR, 1323 "few isakmp message received.\n"); 1324 return ISAKMP_NTYPE_PAYLOAD_MALFORMED; 1325 } 1326#ifdef ENABLE_HYBRID 1327 if (AUTHMETHOD(iph1) == FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I && 1328 ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0)) 1329 { 1330 plog(ASL_LEVEL_ERR, "No SIG was passed, " 1331 "hybrid auth is enabled, " 1332 "but peer is no Xauth compliant\n"); 1333 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED; 1334 break; 1335 } 1336#endif 1337 r_hash = (caddr_t)(iph1->pl_hash + 1); 1338 1339 //plogdump(ASL_LEVEL_DEBUG, r_hash, 1340 // ntohs(iph1->pl_hash->h.len) - sizeof(*iph1->pl_hash), "HASH received:\n"); 1341 1342 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 1343 switch (iph1->etype) { 1344 case ISAKMP_ETYPE_IDENT: 1345 case ISAKMP_ETYPE_AGG: 1346 my_hash = oakley_ph1hash_common(iph1, VALIDATE); 1347 break; 1348 case ISAKMP_ETYPE_BASE: 1349 if (iph1->side == INITIATOR) 1350 my_hash = oakley_ph1hash_common(iph1, VALIDATE); 1351 else 1352 my_hash = oakley_ph1hash_base_i(iph1, VALIDATE); 1353 break; 1354 default: 1355 plog(ASL_LEVEL_ERR, 1356 "invalid etype %d\n", iph1->etype); 1357 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE; 1358 } 1359 } 1360 if (my_hash == NULL) 1361 return ISAKMP_INTERNAL_ERROR; 1362 1363 result = memcmp(my_hash->v, r_hash, my_hash->l); 1364 vfree(my_hash); 1365 1366 if (result) { 1367 plog(ASL_LEVEL_ERR, "HASH mismatched\n"); 1368 return ISAKMP_NTYPE_INVALID_HASH_INFORMATION; 1369 } 1370 1371 plog(ASL_LEVEL_DEBUG, "HASH for PSK validated.\n"); 1372 } 1373 break; 1374 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 1375#ifdef ENABLE_HYBRID 1376 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 1377 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: 1378 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 1379#endif 1380 { 1381 int error = 0; 1382 int certtype = 0; 1383 1384 /* validation */ 1385 if (iph1->id_p == NULL) { 1386 plog(ASL_LEVEL_ERR, 1387 "no ID payload was passed.\n"); 1388 return ISAKMP_NTYPE_PAYLOAD_MALFORMED; 1389 } 1390 if (iph1->sig_p == NULL) { 1391 plog(ASL_LEVEL_ERR, 1392 "no SIG payload was passed.\n"); 1393 return ISAKMP_NTYPE_PAYLOAD_MALFORMED; 1394 } 1395 1396 plog(ASL_LEVEL_DEBUG, "*** SIGN passed\n"); 1397 1398 /* get peer's cert */ 1399 switch (iph1->rmconf->getcert_method) { 1400 case ISAKMP_GETCERT_PAYLOAD: 1401 if (iph1->cert_p == NULL) { 1402 plog(ASL_LEVEL_ERR, 1403 "no peer's CERT payload found.\n"); 1404 return ISAKMP_INTERNAL_ERROR; 1405 } 1406 break; 1407 default: 1408 plog(ASL_LEVEL_ERR, 1409 "invalid getcert_mothod: %d\n", 1410 iph1->rmconf->getcert_method); 1411 return ISAKMP_INTERNAL_ERROR; 1412 } 1413 1414 /* compare ID payload and certificate name */ 1415 if (iph1->rmconf->verify_cert && 1416 (error = oakley_check_certid(iph1)) != 0) 1417 return error; 1418 1419#if HAVE_OPENDIR 1420 /* check cert common name against Open Directory authentication group */ 1421 if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_OPEN_DIR) { 1422 if (oakley_verify_userid(iph1)) { 1423 return ISAKMP_NTYPE_AUTHENTICATION_FAILED; 1424 } 1425 } 1426#endif /* HAVE_OPENDIR */ 1427 1428 /* verify certificate */ 1429 if (iph1->rmconf->verify_cert 1430 && iph1->rmconf->getcert_method == ISAKMP_GETCERT_PAYLOAD) { 1431 certtype = iph1->rmconf->certtype; 1432#ifdef ENABLE_HYBRID 1433 switch (AUTHMETHOD(iph1)) { 1434 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 1435 certtype = iph1->cert_p->type; 1436 break; 1437 default: 1438 break; 1439 } 1440#endif 1441 switch (certtype) { 1442 case ISAKMP_CERT_X509SIGN: 1443 { 1444 /* use ID from remote configuration */ 1445 /* check each ID in list */ 1446 struct idspec *id_spec; 1447 CFStringRef hostname = NULL; 1448 char *peers_id; 1449 struct genlist_entry *gpb = NULL; 1450 1451 if (iph1->rmconf->cert_verification_option == VERIFICATION_OPTION_PEERS_IDENTIFIER) { 1452 id_spec = genlist_next(iph1->rmconf->idvl_p, &gpb); /* expect only one id */ 1453 if (id_spec->idtype == IDTYPE_ADDRESS) { 1454 switch ((ALIGNED_CAST(struct sockaddr_storage *)(id_spec->id->v))->ss_family) { 1455 case AF_INET: 1456 peers_id = inet_ntoa((ALIGNED_CAST(struct sockaddr_in *)(id_spec->id->v))->sin_addr); 1457 hostname = CFStringCreateWithCString(NULL, peers_id, kCFStringEncodingUTF8); 1458 break; 1459#ifdef INET6 1460 case AF_INET6: 1461 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; /* not currently supported for embedded */ 1462 break; 1463#endif 1464 default: 1465 plog(ASL_LEVEL_ERR, 1466 "unknown address type for peers identifier.\n"); 1467 return ISAKMP_NTYPE_AUTHENTICATION_FAILED; 1468 break; 1469 } 1470 } else 1471 hostname = CFStringCreateWithBytes(NULL, (u_int8_t *)id_spec->id->v, id_spec->id->l, kCFStringEncodingUTF8, FALSE); 1472 } 1473 error = crypto_cssm_check_x509cert(oakley_get_peer_cert_from_certchain(iph1), iph1->cert_p, hostname, &publicKeyRef); 1474 if (hostname) 1475 CFRelease(hostname); 1476 } 1477 break; 1478 1479 default: 1480 plog(ASL_LEVEL_ERR, 1481 "no supported certtype %d\n", certtype); 1482 return ISAKMP_INTERNAL_ERROR; 1483 } 1484 if (error != 0) { 1485 plog(ASL_LEVEL_ERR, 1486 "the peer's certificate is not verified.\n"); 1487 return ISAKMP_NTYPE_INVALID_CERT_AUTHORITY; 1488 } 1489 } 1490 1491 plog(ASL_LEVEL_DEBUG, "CERT validated\n"); 1492 1493 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 1494 /* compute hash */ 1495 switch (iph1->etype) { 1496 case ISAKMP_ETYPE_IDENT: 1497 case ISAKMP_ETYPE_AGG: 1498 my_hash = oakley_ph1hash_common(iph1, VALIDATE); 1499 break; 1500 case ISAKMP_ETYPE_BASE: 1501 if (iph1->side == INITIATOR) 1502 my_hash = oakley_ph1hash_base_r(iph1, VALIDATE); 1503 else 1504 my_hash = oakley_ph1hash_base_i(iph1, VALIDATE); 1505 break; 1506 default: 1507 plog(ASL_LEVEL_ERR, 1508 "invalid etype %d\n", iph1->etype); 1509 return ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE; 1510 } 1511 } 1512 if (my_hash == NULL) 1513 return ISAKMP_INTERNAL_ERROR; 1514 1515 1516 certtype = iph1->rmconf->certtype; 1517#ifdef ENABLE_HYBRID 1518 switch (AUTHMETHOD(iph1)) { 1519 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 1520 certtype = iph1->cert_p->type; 1521 break; 1522 default: 1523 break; 1524 } 1525#endif 1526 /* check signature */ 1527 switch (certtype) { 1528 case ISAKMP_CERT_X509SIGN: 1529 if (publicKeyRef == NULL) { 1530 plog(ASL_LEVEL_ERR, "@@@@@@ publicKeyRef is NULL\n"); 1531 } 1532 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 1533 error = crypto_cssm_verify_x509sign(publicKeyRef, my_hash, iph1->sig_p, FALSE); 1534 } 1535 if (error) { 1536 plog(ASL_LEVEL_ERR, "error verifying signature %s\n", GetSecurityErrorString(error)); 1537 } 1538 1539 CFRelease(publicKeyRef); 1540 break; 1541 default: 1542 plog(ASL_LEVEL_ERR, 1543 "no supported certtype %d\n", 1544 certtype); 1545 vfree(my_hash); 1546 return ISAKMP_INTERNAL_ERROR; 1547 } 1548 1549 vfree(my_hash); 1550 if (error != 0) { 1551 plog(ASL_LEVEL_ERR, 1552 "Invalid SIG.\n"); 1553 return ISAKMP_NTYPE_INVALID_SIGNATURE; 1554 } 1555 plog(ASL_LEVEL_DEBUG, "SIG authenticated\n"); 1556 } 1557 break; 1558#ifdef ENABLE_HYBRID 1559 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 1560 { 1561 if ((iph1->mode_cfg->flags & ISAKMP_CFG_VENDORID_XAUTH) == 0) { 1562 plog(ASL_LEVEL_ERR, "No SIG was passed, " 1563 "hybrid auth is enabled, " 1564 "but peer is no Xauth compliant\n"); 1565 return ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED; 1566 break; 1567 } 1568 plog(ASL_LEVEL_INFO, "No SIG was passed, " 1569 "but hybrid auth is enabled\n"); 1570 1571 return 0; 1572 break; 1573 } 1574#endif 1575 case OAKLEY_ATTR_AUTH_METHOD_RSAENC: 1576 case OAKLEY_ATTR_AUTH_METHOD_RSAREV: 1577#ifdef ENABLE_HYBRID 1578 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: 1579 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 1580 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: 1581 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 1582#endif 1583 if (iph1->id_p == NULL || iph1->pl_hash == NULL) { 1584 plog(ASL_LEVEL_ERR, 1585 "few isakmp message received.\n"); 1586 return ISAKMP_NTYPE_PAYLOAD_MALFORMED; 1587 } 1588 plog(ASL_LEVEL_ERR, 1589 "not supported authmethod type %s\n", 1590 s_oakley_attr_method(iph1->approval->authmethod)); 1591 return ISAKMP_INTERNAL_ERROR; 1592 default: 1593 plog(ASL_LEVEL_ERR, 1594 "invalid authmethod %d why ?\n", 1595 iph1->approval->authmethod); 1596 return ISAKMP_INTERNAL_ERROR; 1597 } 1598#ifdef ENABLE_STATS 1599 gettimeofday(&end, NULL); 1600 plog(ASL_LEVEL_NOTICE, "%s(%s): %8.6f", __func__, 1601 s_oakley_attr_method(iph1->approval->authmethod), 1602 timedelta(&start, &end)); 1603#endif 1604 1605 return 0; 1606} 1607 1608int 1609oakley_find_status_in_certchain (cert_t *certchain, cert_status_t certStatus) 1610{ 1611 cert_t *p; 1612 1613 for (p = certchain; p; p = p->chain) { 1614 if (p->status == certStatus) { 1615 return 1; 1616 } 1617 } 1618 return 0; 1619} 1620 1621static 1622int 1623oakley_vpncontrol_notify_ike_failed_if_mycert_invalid (phase1_handle_t *iph1, int notify_initiator) 1624{ 1625#if TARGET_OS_EMBEDDED 1626 int premature = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_PREMATURE); 1627 int expired = oakley_find_status_in_certchain(iph1->cert, CERT_STATUS_EXPIRED); 1628 if (premature || expired) { 1629 u_int32_t address; 1630 u_int32_t fail_reason; 1631 1632 if (iph1->remote->ss_family == AF_INET) 1633 address = ((struct sockaddr_in *)(iph1->remote))->sin_addr.s_addr; 1634 else 1635 address = 0; 1636 if (premature) { 1637 fail_reason = VPNCTL_NTYPE_LOCAL_CERT_PREMATURE; 1638 } else { 1639 fail_reason = VPNCTL_NTYPE_LOCAL_CERT_EXPIRED; 1640 } 1641 vpncontrol_notify_ike_failed(fail_reason, notify_initiator, address, 0, NULL); 1642 return -1; 1643 } 1644#endif /* TARGET_OS_EMBEDDED */ 1645 return 0; 1646} 1647 1648/* get my certificate 1649 * NOTE: include certificate type. 1650 */ 1651int 1652oakley_getmycert(phase1_handle_t *iph1) 1653{ 1654 int err; 1655 1656 switch (iph1->rmconf->certtype) { 1657 case ISAKMP_CERT_X509SIGN: 1658 if (iph1->cert) 1659 return 0; 1660 if ( !(err = get_cert_fromlocal(iph1, 1))){ 1661 if (oakley_vpncontrol_notify_ike_failed_if_mycert_invalid(iph1, FROM_LOCAL)) { 1662 return -1; 1663 } 1664 } 1665 return err; 1666 default: 1667 plog(ASL_LEVEL_ERR, 1668 "Unknown certtype #%d\n", 1669 iph1->rmconf->certtype); 1670 return -1; 1671 } 1672 1673} 1674 1675/* 1676 * get a CERT from local file. 1677 * IN: 1678 * my != 0 my cert. 1679 * my == 0 peer's cert. 1680 */ 1681static int 1682get_cert_fromlocal(phase1_handle_t *iph1, int my) 1683{ 1684 vchar_t *cert = NULL; 1685 cert_t **certpl; 1686 int error = -1; 1687 cert_status_t status = CERT_STATUS_OK; 1688 1689 if (my) 1690 certpl = &iph1->cert; 1691 else 1692 certpl = &iph1->cert_p; 1693 if (iph1->rmconf->identity_in_keychain == 0) { 1694 plog(ASL_LEVEL_ERR, "no CERT defined.\n"); 1695 return 0; 1696 } 1697 1698 switch (iph1->rmconf->certtype) { 1699 case ISAKMP_CERT_X509SIGN: 1700 if (iph1->rmconf->identity_in_keychain) { 1701 CFDataRef dataRef; 1702 1703 if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef)) 1704 goto end; 1705 cert = crypto_cssm_get_x509cert(dataRef, &status); 1706 plog(ASL_LEVEL_DEBUG, "done with chking cert status %d\n",status); 1707 CFRelease(dataRef); 1708 break; 1709 } // else fall thru 1710 default: 1711 plog(ASL_LEVEL_ERR, 1712 "not supported certtype %d\n", 1713 iph1->rmconf->certtype); 1714 goto end; 1715 } 1716 1717 if (!cert) { 1718 plog(ASL_LEVEL_ERR, 1719 "failed to get %s CERT.\n", 1720 my ? "my" : "peers"); 1721 goto end; 1722 } 1723 1724 *certpl = oakley_newcert(); 1725 if (!*certpl) { 1726 plog(ASL_LEVEL_ERR, 1727 "failed to get cert buffer.\n"); 1728 goto end; 1729 } 1730 (*certpl)->pl = vmalloc(cert->l + 1); 1731 if ((*certpl)->pl == NULL) { 1732 plog(ASL_LEVEL_ERR, 1733 "failed to get cert buffer\n"); 1734 oakley_delcert(*certpl); 1735 *certpl = NULL; 1736 goto end; 1737 } 1738 memcpy((*certpl)->pl->v + 1, cert->v, cert->l); 1739 (*certpl)->pl->v[0] = iph1->rmconf->certtype; 1740 (*certpl)->type = iph1->rmconf->certtype; 1741 (*certpl)->status = status; 1742 (*certpl)->cert.v = (*certpl)->pl->v + 1; 1743 (*certpl)->cert.l = (*certpl)->pl->l - 1; 1744 1745 plog(ASL_LEVEL_DEBUG, "created CERT payload\n"); 1746 1747 error = 0; 1748 1749end: 1750 if (cert != NULL) 1751 vfree(cert); 1752 1753 return error; 1754} 1755 1756 1757/* get signature */ 1758int 1759oakley_getsign(phase1_handle_t *iph1) 1760{ 1761 vchar_t *privkey = NULL; 1762 int error = -1; 1763 1764 switch (iph1->rmconf->certtype) { 1765 case ISAKMP_CERT_X509SIGN: 1766 // cert in keychain - use cssm to sign 1767 if (iph1->rmconf->identity_in_keychain) { 1768 CFDataRef dataRef; 1769 1770 if (iph1->rmconf->keychainCertRef == NULL || base64toCFData(iph1->rmconf->keychainCertRef, &dataRef)) 1771 goto end; 1772 iph1->sig = crypto_cssm_getsign(dataRef, iph1->hash); 1773 CFRelease(dataRef); 1774 break; 1775 } // else fall thru 1776 default: 1777 plog(ASL_LEVEL_ERR, 1778 "Unknown certtype #%d\n", 1779 iph1->rmconf->certtype); 1780 goto end; 1781 } 1782 1783 if (iph1->sig == NULL) { 1784 plog(ASL_LEVEL_ERR, "failed to sign.\n"); 1785 goto end; 1786 } 1787 1788 //plogdump(ASL_LEVEL_DEBUG, iph1->sig->v, iph1->sig->l, "SIGN computed:\n"); 1789 1790 error = 0; 1791 1792end: 1793 if (privkey != NULL) 1794 vfree(privkey); 1795 1796 return error; 1797} 1798 1799void 1800oakley_verify_certid(phase1_handle_t *iph1) 1801{ 1802 if (iph1->rmconf->verify_cert && 1803 oakley_check_certid(iph1)){ 1804 plog(ASL_LEVEL_DEBUG, 1805 "Discarding CERT: does not match ID:\n"); 1806 oakley_delcert(iph1->cert_p); 1807 iph1->cert_p = NULL; 1808 } 1809} 1810 1811static int 1812oakley_check_certid_in_certchain(cert_t *certchain, int idtype, int idlen, void *id) 1813{ 1814 cert_t *p; 1815 1816 for (p = certchain; p; p = p->chain) { 1817 if (oakley_check_certid_1(&p->cert, idtype, idlen, id, &p->status) == 0) { 1818 return 0; 1819 } 1820 } 1821 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 1822} 1823 1824cert_t * 1825oakley_get_peer_cert_from_certchain(phase1_handle_t * iph1) 1826{ 1827 cert_t *p; 1828 struct ipsecdoi_id_b *id_b; 1829 int idlen; 1830 void *peers_id; 1831 1832 if (!iph1->id_p || !iph1->cert_p) { 1833 plog(ASL_LEVEL_ERR, "no ID nor CERT found.\n"); 1834 return NULL; 1835 } 1836 if (!iph1->cert_p->chain) { 1837 // no chain: simply return the only cert 1838 return iph1->cert_p; 1839 } 1840 1841 id_b = ALIGNED_CAST(struct ipsecdoi_id_b *)iph1->id_p->v; 1842 peers_id = id_b + 1; 1843 idlen = iph1->id_p->l - sizeof(*id_b); 1844 for (p = iph1->cert_p; p; p = p->chain) { 1845 if (oakley_check_certid_1(&p->cert, id_b->type, idlen, peers_id, &p->status) == 0) { 1846 return p; 1847 } 1848 } 1849 return NULL; 1850} 1851 1852/* 1853 * compare certificate name and ID value. 1854 */ 1855static int 1856oakley_check_certid(phase1_handle_t *iph1) 1857{ 1858 struct ipsecdoi_id_b *id_b; 1859 int idlen; 1860 u_int8_t doi_type = 255; 1861 void *peers_id = NULL; 1862 1863 /* use ID from peer */ 1864 if (iph1->id_p == NULL || iph1->cert_p == NULL) { 1865 plog(ASL_LEVEL_ERR, "no ID nor CERT found.\n"); 1866 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 1867 } 1868 id_b = ALIGNED_CAST(struct ipsecdoi_id_b *)iph1->id_p->v; 1869 doi_type = id_b->type; 1870 peers_id = id_b + 1; 1871 idlen = iph1->id_p->l - sizeof(*id_b); 1872 1873 return oakley_check_certid_in_certchain(iph1->cert_p, doi_type, idlen, peers_id); 1874 1875} 1876 1877static int 1878oakley_check_certid_1(vchar_t *cert, int idtype, int idlen, void *id, cert_status_t *certStatus) 1879{ 1880 1881 int len; 1882 int error = 0; 1883 1884#if !TARGET_OS_EMBEDDED 1885 int type; 1886 char *altname = NULL; 1887#endif 1888 1889 switch (idtype) { 1890 case IPSECDOI_ID_DER_ASN1_DN: 1891 { 1892 CFDataRef subject; 1893 SecCertificateRef certificate; 1894 UInt8* namePtr; 1895 1896 certificate = crypto_cssm_x509cert_CreateSecCertificateRef(cert); 1897 if (certificate == NULL) { 1898 plog(ASL_LEVEL_ERR, 1899 "failed to get SecCertificateRef\n"); 1900 if (certStatus && !*certStatus) { 1901 *certStatus = CERT_STATUS_INVALID; 1902 } 1903 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 1904 } 1905 subject = crypto_cssm_CopySubjectSequence(certificate); 1906 if (subject == NULL) { 1907 plog(ASL_LEVEL_ERR, "failed to get certificate subjectName\n"); 1908 if (certStatus && !*certStatus) { 1909 *certStatus = CERT_STATUS_INVALID_SUBJNAME; 1910 } 1911 error = ISAKMP_NTYPE_INVALID_CERTIFICATE; 1912 } else { 1913 len = CFDataGetLength(subject); 1914 namePtr = (UInt8*)CFDataGetBytePtr(subject); 1915 if (namePtr) { 1916 if (idlen != len || memcmp(id, namePtr, idlen)) { 1917 plog(ASL_LEVEL_ERR, "ID mismatched with certificate subjectName\n"); 1918 error =ISAKMP_NTYPE_INVALID_ID_INFORMATION; 1919 } 1920 } else { 1921 plog(ASL_LEVEL_ERR, "no certificate subjectName found\n"); 1922 error = ISAKMP_NTYPE_INVALID_CERTIFICATE; 1923 } 1924 } 1925 if (error) { 1926 plog(ASL_LEVEL_ERR, 1927 "ID mismatched with certificate subjectName\n"); 1928 plogdump(ASL_LEVEL_ERR, namePtr, len, "subjectName (type %s):\n", 1929 s_ipsecdoi_ident(idtype)); 1930 plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n"); 1931 if (certStatus && !*certStatus) { 1932 *certStatus = CERT_STATUS_INVALID_SUBJNAME; 1933 } 1934 } 1935 CFRelease(certificate); 1936 if (subject != NULL) { 1937 CFRelease(subject); 1938 } 1939 return 0; 1940 } 1941 break; 1942 1943 case IPSECDOI_ID_IPV4_ADDR: 1944 case IPSECDOI_ID_IPV6_ADDR: 1945 { 1946#if TARGET_OS_EMBEDDED 1947 CFIndex pos, count; 1948 SecCertificateRef certificate; 1949 CFArrayRef addresses; 1950#define ADDRESS_BUF_SIZE 64 1951 1952 certificate = crypto_cssm_x509cert_CreateSecCertificateRef(cert); 1953 if (certificate == NULL) { 1954 plog(ASL_LEVEL_ERR, 1955 "failed to get SecCertificateRef\n"); 1956 if (certStatus && !*certStatus) { 1957 *certStatus = CERT_STATUS_INVALID; 1958 } 1959 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 1960 } 1961 addresses = SecCertificateCopyIPAddresses(certificate); 1962 if (addresses == NULL) { 1963 plog(ASL_LEVEL_ERR, "failed to get subjectName\n"); 1964 if (certStatus && !*certStatus) { 1965 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 1966 } 1967 CFRelease(certificate); 1968 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 1969 } 1970 count = CFArrayGetCount(addresses); 1971 for (pos = 0; pos < count; pos++) { 1972 1973 CFStringRef address; 1974 CFIndex addressLen; 1975 char *addressBuf, numAddress[128]; 1976 int result; 1977 1978 address = CFArrayGetValueAtIndex(addresses, pos); 1979 addressLen = CFStringGetLength(address); 1980 if (addressLen == 0) 1981 continue; 1982 addressBuf = racoon_malloc(ADDRESS_BUF_SIZE); 1983 if (addressBuf == NULL) { 1984 plog(ASL_LEVEL_ERR, "out of memory\n"); 1985 CFRelease(addresses); 1986 CFRelease(certificate); 1987 return -1; 1988 } 1989 if (CFStringGetCString(address, addressBuf, ADDRESS_BUF_SIZE, kCFStringEncodingUTF8) == TRUE) { 1990 result = inet_pton(idtype == IPSECDOI_ID_IPV4_ADDR ? AF_INET : AF_INET6, addressBuf, numAddress); 1991 racoon_free(addressBuf); 1992 if (result == 0) 1993 continue; // wrong type or invalid address 1994 if (!memcmp(id, numAddress, idtype == IPSECDOI_ID_IPV4_ADDR ? 32 : 128) == 0) { // found a match ? 1995 CFRelease(addresses); 1996 CFRelease(certificate); 1997 return 0; 1998 } 1999 } else 2000 racoon_free(addressBuf); 2001 } 2002 plog(ASL_LEVEL_ERR, "ID mismatched with subjectAltName.\n"); 2003 plog(ASL_LEVEL_ERR, 2004 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype)); 2005 plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n"); 2006 CFRelease(addresses); 2007 CFRelease(certificate); 2008 if (certStatus && !*certStatus) { 2009 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2010 } 2011 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2012#else 2013 /* 2014 * Openssl returns the IPAddress as an ASN1 octet string (binary format) 2015 * followed by a trailing NULL. 5 bytes for IPv4 and 17 bytes for IPv6 2016 */ 2017 #define SUBJ_ALT_NAME_IPV4_ADDRESS_LEN 5 2018 #define SUBJ_ALT_NAME_IPV6_ADDRESS_LEN 17 2019 2020 int pos; 2021 2022 if ((idtype == IPSECDOI_ID_IPV4_ADDR && idlen != sizeof(struct in_addr)) 2023 || (idtype == IPSECDOI_ID_IPV6_ADDR && idlen != sizeof(struct in6_addr))) { 2024 plog(ASL_LEVEL_ERR, 2025 "invalid address length passed.\n"); 2026 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2027 } 2028 2029 for (pos = 1; ; pos++) { 2030 if (eay_get_x509subjectaltname(cert, &altname, &type, pos, &len) !=0) { 2031 plog(ASL_LEVEL_ERR, 2032 "failed to get subjectAltName\n"); 2033 if (certStatus && !*certStatus) { 2034 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2035 } 2036 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 2037 } 2038 2039 /* it's the end condition of the loop. */ 2040 if (!altname) { 2041 plog(ASL_LEVEL_ERR, 2042 "invalid subjectAltName\n"); 2043 if (certStatus && !*certStatus) { 2044 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2045 } 2046 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2047 } 2048 2049 if (check_typeofcertname(idtype, type) != 0) { 2050 /* wrong type - skip this one */ 2051 racoon_free(altname); 2052 altname = NULL; 2053 continue; 2054 } 2055 2056 if (len == SUBJ_ALT_NAME_IPV4_ADDRESS_LEN) { /* IPv4 */ 2057 if (idtype != IPSECDOI_ID_IPV4_ADDR) { 2058 /* wrong IP address type - skip this one */ 2059 racoon_free(altname); 2060 altname = NULL; 2061 continue; 2062 } 2063 } 2064#ifdef INET6 2065 else if (len == SUBJ_ALT_NAME_IPV6_ADDRESS_LEN) { /* IPv6 */ 2066 if (idtype != IPSECDOI_ID_IPV6_ADDR) { 2067 /* wrong IP address type - skip this one */ 2068 racoon_free(altname); 2069 altname = NULL; 2070 continue; 2071 } 2072 } 2073#endif 2074 else { 2075 /* invalid IP address length in certificate - bad or bogus certificate */ 2076 plog(ASL_LEVEL_ERR, 2077 "invalid IP address in certificate.\n"); 2078 plogdump(ASL_LEVEL_ERR, altname, len, "subjectAltName (expected type %s, got type %s):\n", 2079 s_ipsecdoi_ident(idtype), 2080 s_ipsecdoi_ident(type)); 2081 racoon_free(altname); 2082 altname = NULL; 2083 if (certStatus && !*certStatus) { 2084 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2085 } 2086 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 2087 } 2088 2089 /* compare the addresses */ 2090 error = memcmp(id, altname, idlen); 2091 if (error) 2092 continue; 2093 racoon_free(altname); 2094 return 0; 2095 } 2096 /* failed to find a match */ 2097 plog(ASL_LEVEL_ERR, 2098 "ID mismatched with subjectAltName.\n"); 2099 plogdump(ASL_LEVEL_ERR, altname, len, "subjectAltName (expected type %s, got type %s):\n", 2100 s_ipsecdoi_ident(idtype), 2101 s_ipsecdoi_ident(type)); 2102 plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n"); 2103 racoon_free(altname); 2104 if (certStatus && !*certStatus) 2105 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2106 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2107 2108#endif /* TARGET_OS_EMBEDDED */ 2109 } 2110 2111#if TARGET_OS_EMBEDDED 2112 case IPSECDOI_ID_FQDN: 2113 { 2114 CFIndex pos, count; 2115 SecCertificateRef certificate; 2116 CFArrayRef names; 2117 CFStringRef name, ID; 2118 2119 certificate = crypto_cssm_x509cert_CreateSecCertificateRef(cert); 2120 if (certificate == NULL) { 2121 plog(ASL_LEVEL_ERR, 2122 "failed to get SecCertificateRef\n"); 2123 if (certStatus && !*certStatus) { 2124 *certStatus = CERT_STATUS_INVALID; 2125 } 2126 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 2127 } 2128 names = SecCertificateCopyDNSNames(certificate); 2129 if (names == NULL) { 2130 plog(ASL_LEVEL_ERR, 2131 "failed to get subjectName\n"); 2132 if (certStatus && !*certStatus) { 2133 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2134 } 2135 CFRelease(certificate); 2136 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 2137 } 2138 count = CFArrayGetCount(names); 2139 ID = CFStringCreateWithBytes(kCFAllocatorDefault, id, idlen, kCFStringEncodingUTF8, FALSE); 2140 if (ID== NULL) { 2141 plog(ASL_LEVEL_ERR, "memory error\n"); 2142 CFRelease(names); 2143 CFRelease(certificate); 2144 return 0; 2145 } 2146 for (pos = 0; pos < count; pos++) { 2147 name = CFArrayGetValueAtIndex(names, pos); 2148 if (CFStringCompare(name, ID, 0) == kCFCompareEqualTo) { 2149 CFRelease(ID); 2150 CFRelease(names); 2151 CFRelease(certificate); 2152 return 0; 2153 } 2154 } 2155 plog(ASL_LEVEL_ERR, "ID mismatched with subjectAltName.\n"); 2156 plog(ASL_LEVEL_ERR, 2157 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype)); 2158 plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n"); 2159 CFRelease(ID); 2160 CFRelease(names); 2161 CFRelease(certificate); 2162 if (certStatus && !*certStatus) { 2163 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2164 } 2165 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2166 } 2167 2168 case IPSECDOI_ID_USER_FQDN: 2169 { 2170 CFIndex pos, count; 2171 2172 SecCertificateRef certificate; 2173 CFArrayRef names; 2174 CFStringRef name, ID; 2175 2176 certificate = crypto_cssm_x509cert_CreateSecCertificateRef(cert); 2177 if (certificate == NULL) { 2178 plog(ASL_LEVEL_ERR, 2179 "failed to get SecCertificateRef\n"); 2180 if (certStatus && !*certStatus) { 2181 *certStatus = CERT_STATUS_INVALID; 2182 } 2183 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 2184 } 2185 names = SecCertificateCopyRFC822Names(certificate); 2186 if (names == NULL) { 2187 plog(ASL_LEVEL_ERR, 2188 "failed to get subjectName\n"); 2189 if (certStatus && !*certStatus) { 2190 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2191 } 2192 CFRelease(certificate); 2193 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 2194 } 2195 count = CFArrayGetCount(names); 2196 ID = CFStringCreateWithBytes(kCFAllocatorDefault, id, idlen, kCFStringEncodingUTF8, FALSE); 2197 if (ID == NULL) { 2198 plog(ASL_LEVEL_ERR, 2199 "memory error\n"); 2200 if (certStatus && !*certStatus) { 2201 *certStatus = CERT_STATUS_INVALID; 2202 } 2203 CFRelease(names); 2204 CFRelease(certificate); 2205 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 2206 } 2207 for (pos = 0; pos < count; pos++) { 2208 name = CFArrayGetValueAtIndex(names, pos); 2209 if (CFStringCompare(name, ID, 0) == kCFCompareEqualTo) { 2210 CFRelease(ID); 2211 CFRelease(names); 2212 CFRelease(certificate); 2213 return 0; 2214 } 2215 } 2216 plog(ASL_LEVEL_ERR, "ID mismatched with subjectAltName.\n"); 2217 plog(ASL_LEVEL_ERR, 2218 "subjectAltName (expected type %s):\n", s_ipsecdoi_ident(idtype)); 2219 plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n"); 2220 CFRelease(ID); 2221 CFRelease(names); 2222 CFRelease(certificate); 2223 if (certStatus && !*certStatus) { 2224 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2225 } 2226 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2227 } 2228#else 2229 case IPSECDOI_ID_FQDN: 2230 case IPSECDOI_ID_USER_FQDN: 2231 { 2232 int pos; 2233 2234 for (pos = 1; ; pos++) { 2235 if (eay_get_x509subjectaltname(cert, &altname, &type, pos, &len) != 0) { 2236 plog(ASL_LEVEL_ERR, 2237 "failed to get subjectAltName\n"); 2238 if (certStatus && !*certStatus) { 2239 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2240 } 2241 return ISAKMP_NTYPE_INVALID_CERTIFICATE; 2242 } 2243 2244 /* it's the end condition of the loop. */ 2245 if (!altname) { 2246 plog(ASL_LEVEL_ERR, 2247 "invalid subjectAltName\n"); 2248 if (certStatus && !*certStatus) { 2249 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2250 } 2251 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2252 } 2253 2254 if (check_typeofcertname(idtype, type) != 0) { 2255 /* wrong general type - skip this one */ 2256 racoon_free(altname); 2257 altname = NULL; 2258 continue; 2259 } 2260 2261 if (idlen != strlen(altname)) { 2262 /* wrong length - skip this one */ 2263 racoon_free(altname); 2264 altname = NULL; 2265 continue; 2266 } 2267 error = memcmp(id, altname, idlen); 2268 if (error) 2269 continue; 2270 racoon_free(altname); 2271 return 0; 2272 } 2273 plog(ASL_LEVEL_ERR, "ID mismatched with subjectAltName.\n"); 2274 plog(ASL_LEVEL_ERR, 2275 "subjectAltName (expected type %s, got type %s):\n", 2276 s_ipsecdoi_ident(idtype), 2277 s_ipsecdoi_ident(type)); 2278 plogdump(ASL_LEVEL_ERR, altname, len, "subjectAltName (expected type %s, got type %s):\n", 2279 s_ipsecdoi_ident(idtype), 2280 s_ipsecdoi_ident(type)); 2281 plogdump(ASL_LEVEL_ERR, id, idlen, "ID:\n"); 2282 racoon_free(altname); 2283 if (certStatus && !*certStatus) 2284 *certStatus = CERT_STATUS_INVALID_SUBJALTNAME; 2285 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2286 } 2287#endif 2288 default: 2289 plog(ASL_LEVEL_ERR, 2290 "Impropper ID type passed: %s.\n", 2291 s_ipsecdoi_ident(idtype)); 2292 return ISAKMP_NTYPE_INVALID_ID_INFORMATION; 2293 } 2294 /*NOTREACHED*/ 2295} 2296#ifdef HAVE_OPENSSL 2297static int 2298check_typeofcertname(int doi, int genid) 2299{ 2300 switch (doi) { 2301 case IPSECDOI_ID_IPV4_ADDR: 2302 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 2303 case IPSECDOI_ID_IPV6_ADDR: 2304 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 2305 case IPSECDOI_ID_IPV4_ADDR_RANGE: 2306 case IPSECDOI_ID_IPV6_ADDR_RANGE: 2307 if (genid != GENT_IPADD) 2308 return -1; 2309 return 0; 2310 case IPSECDOI_ID_FQDN: 2311 if (genid != GENT_DNS) 2312 return -1; 2313 return 0; 2314 case IPSECDOI_ID_USER_FQDN: 2315 if (genid != GENT_EMAIL) 2316 return -1; 2317 return 0; 2318 case IPSECDOI_ID_DER_ASN1_DN: /* should not be passed to this function*/ 2319 case IPSECDOI_ID_DER_ASN1_GN: 2320 case IPSECDOI_ID_KEY_ID: 2321 default: 2322 return -1; 2323 } 2324 /*NOTREACHED*/ 2325} 2326#endif 2327 2328/* 2329 * save certificate including certificate type. 2330 */ 2331int 2332oakley_savecert(phase1_handle_t *iph1, struct isakmp_gen *gen) 2333{ 2334 cert_t **c; 2335 u_int8_t type; 2336 type = *(u_int8_t *)(gen + 1) & 0xff; 2337 2338 switch (type) { 2339 case ISAKMP_CERT_X509SIGN: 2340 c = &iph1->cert_p; 2341 break; 2342 default: 2343 plog(ASL_LEVEL_ERR, 2344 "Invalid CERT type %d\n", type); 2345 return -1; 2346 } 2347 2348 if (*c) { 2349 plog(ASL_LEVEL_WARNING, 2350 "preexisting CERT payload... chaining.\n"); 2351 } 2352 2353 cert_t *new; 2354 new = save_certbuf(gen); 2355 if (!new) { 2356 plog(ASL_LEVEL_ERR, 2357 "Failed to get CERT buffer.\n"); 2358 return -1; 2359 } 2360 2361 switch (new->type) { 2362 case ISAKMP_CERT_X509SIGN: 2363 /* Ignore cert if it doesn't match identity 2364 * XXX If verify cert is disabled, we still just take 2365 * the first certificate.... 2366 */ 2367 *c = oakley_appendcert_to_certchain(*c, new); 2368 plog(ASL_LEVEL_DEBUG, "CERT saved:\n"); 2369 break; 2370 default: 2371 /* XXX */ 2372 oakley_delcert(new); 2373 return 0; 2374 } 2375 2376 return 0; 2377} 2378 2379/* 2380 * save certificate including certificate type. 2381 */ 2382int 2383oakley_savecr(phase1_handle_t *iph1, struct isakmp_gen *gen) 2384{ 2385 cert_t **c; 2386 u_int8_t type; 2387 cert_t *new; 2388 2389 type = *(u_int8_t *)(gen + 1) & 0xff; 2390 2391 switch (type) { 2392 case ISAKMP_CERT_X509SIGN: 2393 if (iph1->cr_p) { 2394 oakley_delcert(iph1->cr_p); 2395 iph1->cr_p = NULL; 2396 } 2397 c = &iph1->cr_p; 2398 break; 2399 default: 2400 plog(ASL_LEVEL_ERR, 2401 "Invalid CR type %d\n", type); 2402 return -1; 2403 } 2404 2405 new = save_certbuf(gen); 2406 if (!new) { 2407 plog(ASL_LEVEL_ERR, 2408 "Failed to get CR buffer.\n"); 2409 return -1; 2410 } 2411 *c = oakley_appendcert_to_certchain(*c, new); 2412 plog(ASL_LEVEL_DEBUG, "CR saved\n"); 2413 2414 return 0; 2415} 2416 2417static cert_t * 2418save_certbuf(struct isakmp_gen *gen) 2419{ 2420 cert_t *new; 2421 2422 if(ntohs(gen->len) <= sizeof(*gen)){ 2423 plog(ASL_LEVEL_ERR, 2424 "Len is too small !!.\n"); 2425 return NULL; 2426 } 2427 2428 new = oakley_newcert(); 2429 if (!new) { 2430 plog(ASL_LEVEL_ERR, 2431 "Failed to get CERT buffer.\n"); 2432 return NULL; 2433 } 2434 2435 new->pl = vmalloc(ntohs(gen->len) - sizeof(*gen)); 2436 if (new->pl == NULL) { 2437 plog(ASL_LEVEL_ERR, 2438 "Failed to copy CERT from packet.\n"); 2439 oakley_delcert(new); 2440 new = NULL; 2441 return NULL; 2442 } 2443 memcpy(new->pl->v, gen + 1, new->pl->l); 2444 new->type = new->pl->v[0] & 0xff; 2445 new->cert.v = new->pl->v + 1; 2446 new->cert.l = new->pl->l - 1; 2447 2448 return new; 2449} 2450 2451/* 2452 * get my CR. 2453 * NOTE: No Certificate Authority field is included to CR payload at the 2454 * moment. Becuase any certificate authority are accepted without any check. 2455 * The section 3.10 in RFC2408 says that this field SHOULD not be included, 2456 * if there is no specific certificate authority requested. 2457 */ 2458vchar_t * 2459oakley_getcr(phase1_handle_t *iph1) 2460{ 2461 vchar_t *buf; 2462 2463 buf = vmalloc(1); 2464 if (buf == NULL) { 2465 plog(ASL_LEVEL_ERR, 2466 "failed to get cr buffer\n"); 2467 return NULL; 2468 } 2469 if(iph1->rmconf->certtype == ISAKMP_CERT_NONE) { 2470 buf->v[0] = iph1->rmconf->cacerttype; 2471 plog(ASL_LEVEL_DEBUG, "create my CR: NONE, using %s instead\n", 2472 s_isakmp_certtype(iph1->rmconf->cacerttype)); 2473 } else { 2474 buf->v[0] = iph1->rmconf->certtype; 2475 plog(ASL_LEVEL_DEBUG, "create my CR: %s\n", 2476 s_isakmp_certtype(iph1->rmconf->certtype)); 2477 } 2478 //if (buf->l > 1) 2479 // plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, ""); 2480 2481 return buf; 2482} 2483 2484/* 2485 * check peer's CR. 2486 */ 2487int 2488oakley_checkcr(phase1_handle_t *iph1) 2489{ 2490 if (iph1->cr_p == NULL) 2491 return 0; 2492 2493 plog(ASL_LEVEL_DEBUG, 2494 "peer transmitted CR: %s\n", 2495 s_isakmp_certtype(iph1->cr_p->type)); 2496 2497 if (iph1->cr_p->type != iph1->rmconf->certtype) { 2498 plog(ASL_LEVEL_ERR, 2499 "such a cert type isn't supported: %d\n", 2500 (char)iph1->cr_p->type); 2501 return -1; 2502 } 2503 2504 return 0; 2505} 2506 2507/* 2508 * check to need CR payload. 2509 */ 2510int 2511oakley_needcr(int type) 2512{ 2513 switch (type) { 2514 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 2515#ifdef ENABLE_HYBRID 2516 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 2517 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: 2518 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 2519#endif 2520 return 1; 2521 default: 2522 return 0; 2523 } 2524 /*NOTREACHED*/ 2525} 2526 2527vchar_t * 2528oakley_getpskall(phase1_handle_t *iph1) 2529{ 2530 vchar_t *secret = NULL; 2531 2532 if (iph1->rmconf->shared_secret) { 2533 2534 switch (iph1->rmconf->secrettype) { 2535 case SECRETTYPE_KEY: 2536 /* in psk file - use KEY from remote configuration to locate it */ 2537 secret = getpsk(iph1->rmconf->shared_secret->v, iph1->rmconf->shared_secret->l-1); 2538 break; 2539#if HAVE_KEYCHAIN 2540 case SECRETTYPE_KEYCHAIN: 2541 /* in the system keychain */ 2542 secret = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, NULL); 2543 break; 2544 case SECRETTYPE_KEYCHAIN_BY_ID: 2545 /* in the system keychain - use peer id */ 2546 secret = getpskfromkeychain(iph1->rmconf->shared_secret->v, iph1->etype, iph1->rmconf->secrettype, iph1->id_p); 2547 break; 2548#endif // HAVE_KEYCHAIN 2549 case SECRETTYPE_USE: 2550 /* in the remote configuration */ 2551 default: 2552 /* rmconf->shared_secret is a string and contains a NULL character that must be removed */ 2553 secret = vmalloc(iph1->rmconf->shared_secret->l - 1); 2554 if (secret == NULL) { 2555 plog(ASL_LEVEL_ERR, "memory error.\n"); 2556 goto end; 2557 } 2558 memcpy(secret->v, iph1->rmconf->shared_secret->v, secret->l); 2559 } 2560 } else if (iph1->etype != ISAKMP_ETYPE_IDENT) { 2561 secret = getpskbyname(iph1->id_p); 2562 if (!secret) { 2563 if (iph1->rmconf->verify_identifier) { 2564 plog(ASL_LEVEL_ERR, "couldn't find pskey by peer's ID.\n"); 2565 goto end; 2566 } 2567 } 2568 } 2569 if (!secret) { 2570 plog(ASL_LEVEL_NOTICE, "try to get pskey by the peer's address.\n"); 2571 secret = getpskbyaddr(iph1->remote); 2572 if (!secret) { 2573 plog(ASL_LEVEL_ERR, 2574 "couldn't find the pskey by address %s.\n", 2575 saddrwop2str((struct sockaddr *)iph1->remote)); 2576 } 2577 } 2578 2579end: 2580 return secret; 2581} 2582 2583/* 2584 * compute SKEYID 2585 * see seciton 5. Exchanges in RFC 2409 2586 * psk: SKEYID = prf(pre-shared-key, Ni_b | Nr_b) 2587 * sig: SKEYID = prf(Ni_b | Nr_b, g^ir) 2588 * enc: SKEYID = prf(H(Ni_b | Nr_b), CKY-I | CKY-R) 2589 */ 2590int 2591oakley_skeyid(phase1_handle_t *iph1) 2592{ 2593 vchar_t *key = NULL; 2594 vchar_t *buf = NULL; 2595 vchar_t *bp; 2596 char *p; 2597 int len; 2598 int error = -1; 2599 2600 /* SKEYID */ 2601 switch (AUTHMETHOD(iph1)) { 2602 case OAKLEY_ATTR_AUTH_METHOD_PSKEY: 2603#ifdef ENABLE_HYBRID 2604 case FICTIVE_AUTH_METHOD_XAUTH_PSKEY_I: 2605 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_PSKEY_R: 2606#endif 2607 key = oakley_getpskall(iph1); 2608 if (key == NULL) { 2609 plog(ASL_LEVEL_ERR, 2610 "couldn't find the pskey for %s.\n", 2611 saddrwop2str((struct sockaddr *)iph1->remote)); 2612 goto end; 2613 } 2614 plog(ASL_LEVEL_DEBUG, "the psk found.\n"); 2615 /* should be secret PSK */ 2616 plogdump(ASL_LEVEL_DEBUG, key->v, key->l, "psk: "); 2617 2618 len = iph1->nonce->l + iph1->nonce_p->l; 2619 buf = vmalloc(len); 2620 if (buf == NULL) { 2621 plog(ASL_LEVEL_ERR, 2622 "failed to get skeyid buffer\n"); 2623 goto end; 2624 } 2625 p = buf->v; 2626 2627 bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p); 2628 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce 1: "); 2629 memcpy(p, bp->v, bp->l); 2630 p += bp->l; 2631 2632 bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce); 2633 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce 2: "); 2634 memcpy(p, bp->v, bp->l); 2635 p += bp->l; 2636 2637 iph1->skeyid = oakley_prf(key, buf, iph1); 2638 2639 if (iph1->skeyid == NULL) 2640 goto end; 2641 break; 2642 2643 case OAKLEY_ATTR_AUTH_METHOD_RSASIG: 2644#ifdef ENABLE_HYBRID 2645 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_I: 2646 case OAKLEY_ATTR_AUTH_METHOD_HYBRID_RSA_R: 2647 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_I: 2648 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSASIG_R: 2649#endif 2650 len = iph1->nonce->l + iph1->nonce_p->l; 2651 buf = vmalloc(len); 2652 if (buf == NULL) { 2653 plog(ASL_LEVEL_ERR, 2654 "failed to get nonce buffer\n"); 2655 goto end; 2656 } 2657 p = buf->v; 2658 2659 bp = (iph1->side == INITIATOR ? iph1->nonce : iph1->nonce_p); 2660 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce1: "); 2661 memcpy(p, bp->v, bp->l); 2662 p += bp->l; 2663 2664 bp = (iph1->side == INITIATOR ? iph1->nonce_p : iph1->nonce); 2665 //plogdump(ASL_LEVEL_DEBUG, bp->v, bp->l, "nonce2: "); 2666 memcpy(p, bp->v, bp->l); 2667 p += bp->l; 2668 2669 iph1->skeyid = oakley_prf(buf, iph1->dhgxy, iph1); 2670 if (iph1->skeyid == NULL) 2671 goto end; 2672 break; 2673 case OAKLEY_ATTR_AUTH_METHOD_RSAENC: 2674 case OAKLEY_ATTR_AUTH_METHOD_RSAREV: 2675#ifdef ENABLE_HYBRID 2676 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_I: 2677 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAENC_R: 2678 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_I: 2679 case OAKLEY_ATTR_AUTH_METHOD_XAUTH_RSAREV_R: 2680#endif 2681 plog(ASL_LEVEL_WARNING, 2682 "not supported authentication method %s\n", 2683 s_oakley_attr_method(iph1->approval->authmethod)); 2684 goto end; 2685 default: 2686 plog(ASL_LEVEL_ERR, 2687 "invalid authentication method %d\n", 2688 iph1->approval->authmethod); 2689 goto end; 2690 } 2691 2692 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid->v, iph1->skeyid->l, "IKEv1 SKEYID computed:\n"); 2693 2694 error = 0; 2695 2696end: 2697 if (key != NULL) 2698 vfree(key); 2699 if (buf != NULL) 2700 vfree(buf); 2701 return error; 2702} 2703 2704/* 2705 * compute SKEYID_[dae] 2706 */ 2707int 2708oakley_skeyid_dae(phase1_handle_t *iph1) 2709{ 2710 vchar_t *buf = NULL; 2711 char *p; 2712 int len; 2713 int error = -1; 2714 2715 if (iph1->skeyid == NULL) { 2716 plog(ASL_LEVEL_ERR, "no SKEYID found.\n"); 2717 goto end; 2718 } 2719 2720 /* 2721 * see seciton 5. Exchanges in RFC 2409 2722 * SKEYID_d = prf(SKEYID, g^ir | CKY-I | CKY-R | 0) 2723 * SKEYID_a = prf(SKEYID, SKEYID_d | g^ir | CKY-I | CKY-R | 1) 2724 * SKEYID_e = prf(SKEYID, SKEYID_a | g^ir | CKY-I | CKY-R | 2) 2725 */ 2726 /* SKEYID D */ 2727 /* SKEYID_d = prf(SKEYID, g^xy | CKY-I | CKY-R | 0) */ 2728 len = iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1; 2729 buf = vmalloc(len); 2730 if (buf == NULL) { 2731 plog(ASL_LEVEL_ERR, 2732 "failed to get skeyid buffer\n"); 2733 goto end; 2734 } 2735 p = buf->v; 2736 2737 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l); 2738 p += iph1->dhgxy->l; 2739 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t)); 2740 p += sizeof(cookie_t); 2741 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t)); 2742 p += sizeof(cookie_t); 2743 *p = 0; 2744 iph1->skeyid_d = oakley_prf(iph1->skeyid, buf, iph1); 2745 if (iph1->skeyid_d == NULL) 2746 goto end; 2747 2748 vfree(buf); 2749 buf = NULL; 2750 2751 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_d->v, iph1->skeyid_d->l, "SKEYID_d computed:\n"); 2752 2753 /* SKEYID A */ 2754 /* SKEYID_a = prf(SKEYID, SKEYID_d | g^xy | CKY-I | CKY-R | 1) */ 2755 len = iph1->skeyid_d->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1; 2756 buf = vmalloc(len); 2757 if (buf == NULL) { 2758 plog(ASL_LEVEL_ERR, 2759 "failed to get skeyid buffer\n"); 2760 goto end; 2761 } 2762 p = buf->v; 2763 memcpy(p, iph1->skeyid_d->v, iph1->skeyid_d->l); 2764 p += iph1->skeyid_d->l; 2765 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l); 2766 p += iph1->dhgxy->l; 2767 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t)); 2768 p += sizeof(cookie_t); 2769 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t)); 2770 p += sizeof(cookie_t); 2771 *p = 1; 2772 iph1->skeyid_a = oakley_prf(iph1->skeyid, buf, iph1); 2773 if (iph1->skeyid_a == NULL) 2774 goto end; 2775 2776 vfree(buf); 2777 buf = NULL; 2778 2779 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_a->v, iph1->skeyid_a->l, "SKEYID_a computed:\n"); 2780 2781 /* SKEYID E */ 2782 /* SKEYID_e = prf(SKEYID, SKEYID_a | g^xy | CKY-I | CKY-R | 2) */ 2783 len = iph1->skeyid_a->l + iph1->dhgxy->l + sizeof(cookie_t) * 2 + 1; 2784 buf = vmalloc(len); 2785 if (buf == NULL) { 2786 plog(ASL_LEVEL_ERR, 2787 "failed to get skeyid buffer\n"); 2788 goto end; 2789 } 2790 p = buf->v; 2791 memcpy(p, iph1->skeyid_a->v, iph1->skeyid_a->l); 2792 p += iph1->skeyid_a->l; 2793 memcpy(p, iph1->dhgxy->v, iph1->dhgxy->l); 2794 p += iph1->dhgxy->l; 2795 memcpy(p, (caddr_t)&iph1->index.i_ck, sizeof(cookie_t)); 2796 p += sizeof(cookie_t); 2797 memcpy(p, (caddr_t)&iph1->index.r_ck, sizeof(cookie_t)); 2798 p += sizeof(cookie_t); 2799 *p = 2; 2800 iph1->skeyid_e = oakley_prf(iph1->skeyid, buf, iph1); 2801 if (iph1->skeyid_e == NULL) 2802 goto end; 2803 2804 vfree(buf); 2805 buf = NULL; 2806 2807 //plogdump(ASL_LEVEL_DEBUG, iph1->skeyid_e->v, iph1->skeyid_e->l, "SKEYID_e computed:\n"); 2808 2809 error = 0; 2810 2811end: 2812 if (buf != NULL) 2813 vfree(buf); 2814 return error; 2815} 2816 2817/* 2818 * compute final encryption key. 2819 * see Appendix B. 2820 */ 2821int 2822oakley_compute_enckey(phase1_handle_t *iph1) 2823{ 2824 u_int keylen, prflen; 2825 int error = -1; 2826 2827 /* RFC2409 p39 */ 2828 keylen = alg_oakley_encdef_keylen(iph1->approval->enctype, 2829 iph1->approval->encklen); 2830 if (keylen == -1) { 2831 plog(ASL_LEVEL_ERR, 2832 "invalid encryption algoritym %d, " 2833 "or invalid key length %d.\n", 2834 iph1->approval->enctype, 2835 iph1->approval->encklen); 2836 goto end; 2837 } 2838 iph1->key = vmalloc(keylen >> 3); 2839 if (iph1->key == NULL) { 2840 plog(ASL_LEVEL_ERR, 2841 "failed to get key buffer\n"); 2842 goto end; 2843 } 2844 2845 /* set prf length */ 2846 prflen = alg_oakley_hashdef_hashlen(iph1->approval->hashtype); 2847 if (prflen == -1) { 2848 plog(ASL_LEVEL_ERR, 2849 "invalid hash type %d.\n", iph1->approval->hashtype); 2850 goto end; 2851 } 2852 2853 /* see isakmp-oakley-08 5.3. */ 2854 if (iph1->key->l <= iph1->skeyid_e->l) { 2855 /* 2856 * if length(Ka) <= length(SKEYID_e) 2857 * Ka = first length(K) bit of SKEYID_e 2858 */ 2859 memcpy(iph1->key->v, iph1->skeyid_e->v, iph1->key->l); 2860 } else { 2861 vchar_t *buf = NULL, *res = NULL; 2862 u_char *p, *ep; 2863 int cplen; 2864 int subkey; 2865 2866 /* 2867 * otherwise, 2868 * Ka = K1 | K2 | K3 2869 * where 2870 * K1 = prf(SKEYID_e, 0) 2871 * K2 = prf(SKEYID_e, K1) 2872 * K3 = prf(SKEYID_e, K2) 2873 */ 2874 plog(ASL_LEVEL_DEBUG, 2875 "len(SKEYID_e) < len(Ka) (%zu < %zu), " 2876 "generating long key (Ka = K1 | K2 | ...)\n", 2877 iph1->skeyid_e->l, iph1->key->l); 2878 2879 if ((buf = vmalloc(prflen >> 3)) == 0) { 2880 plog(ASL_LEVEL_ERR, 2881 "failed to get key buffer\n"); 2882 goto end; 2883 } 2884 p = (u_char *)iph1->key->v; 2885 ep = p + iph1->key->l; 2886 2887 subkey = 1; 2888 while (p < ep) { 2889 if (p == (u_char *)iph1->key->v) { 2890 /* just for computing K1 */ 2891 buf->v[0] = 0; 2892 buf->l = 1; 2893 } 2894 res = oakley_prf(iph1->skeyid_e, buf, iph1); 2895 if (res == NULL) { 2896 vfree(buf); 2897 goto end; 2898 } 2899 plog(ASL_LEVEL_DEBUG, 2900 "compute intermediate encryption key K%d\n", 2901 subkey); 2902 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, ""); 2903 //plogdump(ASL_LEVEL_DEBUG, res->v, res->l, ""); 2904 2905 cplen = (res->l < ep - p) ? res->l : ep - p; 2906 memcpy(p, res->v, cplen); 2907 p += cplen; 2908 2909 buf->l = prflen >> 3; /* to cancel K1 speciality */ 2910 if (res->l != buf->l) { 2911 plog(ASL_LEVEL_ERR, 2912 "internal error: res->l=%zu buf->l=%zu\n", 2913 res->l, buf->l); 2914 vfree(res); 2915 vfree(buf); 2916 goto end; 2917 } 2918 memcpy(buf->v, res->v, res->l); 2919 vfree(res); 2920 subkey++; 2921 } 2922 2923 vfree(buf); 2924 } 2925 2926 /* 2927 * don't check any weak key or not. 2928 * draft-ietf-ipsec-ike-01.txt Appendix B. 2929 * draft-ietf-ipsec-ciph-aes-cbc-00.txt Section 2.3. 2930 */ 2931 2932 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "final encryption key computed:\n"); 2933 2934 error = 0; 2935 2936end: 2937 return error; 2938} 2939 2940/* allocated new buffer for CERT */ 2941cert_t * 2942oakley_newcert(void) 2943{ 2944 cert_t *new; 2945 2946 new = racoon_calloc(1, sizeof(*new)); 2947 if (new == NULL) { 2948 plog(ASL_LEVEL_ERR, 2949 "failed to get cert's buffer\n"); 2950 return NULL; 2951 } 2952 2953 new->pl = NULL; 2954 new->chain = NULL; 2955 2956 return new; 2957} 2958 2959/* delete buffer for CERT */ 2960void 2961oakley_delcert_1(cert_t *cert) 2962{ 2963 if (!cert) 2964 return; 2965 if (cert->pl) 2966 VPTRINIT(cert->pl); 2967 racoon_free(cert); 2968} 2969 2970/* delete buffer for CERT */ 2971void 2972oakley_delcert(cert_t *cert) 2973{ 2974 cert_t *p, *to_delete; 2975 2976 if (!cert) 2977 return; 2978 2979 for (p = cert; p;) { 2980 to_delete = p; 2981 p = p->chain; 2982 oakley_delcert_1(to_delete); 2983 } 2984} 2985 2986/* delete buffer for CERT */ 2987static cert_t * 2988oakley_appendcert_to_certchain(cert_t *certchain, cert_t *new) 2989{ 2990 cert_t *p; 2991 2992 if (!certchain) 2993 return new; 2994 2995 for (p = certchain; p; p = p->chain) { 2996 if (!p->chain) { 2997 p->chain = new; 2998 return certchain; 2999 } 3000 } 3001 return NULL; 3002} 3003 3004/* 3005 * compute IV and set to ph1handle 3006 * IV = hash(g^xi | g^xr) 3007 * see 4.1 Phase 1 state in draft-ietf-ipsec-ike. 3008 */ 3009int 3010oakley_newiv(phase1_handle_t *iph1) 3011{ 3012 struct isakmp_ivm *newivm = NULL; 3013 vchar_t *buf = NULL, *bp; 3014 char *p; 3015 int len; 3016 3017 /* create buffer */ 3018 len = iph1->dhpub->l + iph1->dhpub_p->l; 3019 buf = vmalloc(len); 3020 if (buf == NULL) { 3021 plog(ASL_LEVEL_ERR, 3022 "Failed to get IV buffer\n"); 3023 return -1; 3024 } 3025 3026 p = buf->v; 3027 3028 bp = (iph1->side == INITIATOR ? iph1->dhpub : iph1->dhpub_p); 3029 memcpy(p, bp->v, bp->l); 3030 p += bp->l; 3031 3032 bp = (iph1->side == INITIATOR ? iph1->dhpub_p : iph1->dhpub); 3033 memcpy(p, bp->v, bp->l); 3034 p += bp->l; 3035 3036 /* allocate IVm */ 3037 newivm = racoon_calloc(1, sizeof(struct isakmp_ivm)); 3038 if (newivm == NULL) { 3039 plog(ASL_LEVEL_ERR, 3040 "Failed to get IV buffer\n"); 3041 vfree(buf); 3042 return -1; 3043 } 3044 3045 /* compute IV */ 3046 newivm->iv = oakley_hash(buf, iph1); 3047 if (newivm->iv == NULL) { 3048 vfree(buf); 3049 oakley_delivm(newivm); 3050 return -1; 3051 } 3052 3053 /* adjust length of iv */ 3054 newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype); 3055 if (newivm->iv->l == -1) { 3056 plog(ASL_LEVEL_ERR, 3057 "Invalid encryption algorithm %d.\n", 3058 iph1->approval->enctype); 3059 vfree(buf); 3060 oakley_delivm(newivm); 3061 return -1; 3062 } 3063 3064 /* create buffer to save iv */ 3065 if ((newivm->ive = vdup(newivm->iv)) == NULL) { 3066 plog(ASL_LEVEL_ERR, 3067 "vdup (%s)\n", strerror(errno)); 3068 vfree(buf); 3069 oakley_delivm(newivm); 3070 return -1; 3071 } 3072 3073 vfree(buf); 3074 3075 //plogdump(ASL_LEVEL_DEBUG, newivm->iv->v, newivm->iv->l, "IV computed:\n"); 3076 3077 if (iph1->ivm != NULL) 3078 oakley_delivm(iph1->ivm); 3079 3080 iph1->ivm = newivm; 3081 3082 return 0; 3083} 3084 3085/* 3086 * compute IV for the payload after phase 1. 3087 * It's not limited for phase 2. 3088 * if pahse 1 was encrypted. 3089 * IV = hash(last CBC block of Phase 1 | M-ID) 3090 * if phase 1 was not encrypted. 3091 * IV = hash(phase 1 IV | M-ID) 3092 * see 4.2 Phase 2 state in draft-ietf-ipsec-ike. 3093 */ 3094struct isakmp_ivm * 3095oakley_newiv2(phase1_handle_t *iph1, u_int32_t msgid) 3096{ 3097 struct isakmp_ivm *newivm = NULL; 3098 vchar_t *buf = NULL; 3099 char *p; 3100 int len; 3101 int error = -1; 3102 3103 /* create buffer */ 3104 len = iph1->ivm->iv->l + sizeof(msgid_t); 3105 buf = vmalloc(len); 3106 if (buf == NULL) { 3107 plog(ASL_LEVEL_ERR, 3108 "Failed to get IV buffer\n"); 3109 goto end; 3110 } 3111 3112 p = buf->v; 3113 3114 memcpy(p, iph1->ivm->iv->v, iph1->ivm->iv->l); 3115 p += iph1->ivm->iv->l; 3116 3117 memcpy(p, &msgid, sizeof(msgid)); 3118 3119 plog(ASL_LEVEL_DEBUG, "Compute IV for Phase 2\n"); 3120 //plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "Phase 1 last IV:\n"); 3121 3122 /* allocate IVm */ 3123 newivm = racoon_calloc(1, sizeof(struct isakmp_ivm)); 3124 if (newivm == NULL) { 3125 plog(ASL_LEVEL_ERR, 3126 "Failed to get IV buffer\n"); 3127 goto end; 3128 } 3129 3130 /* compute IV */ 3131 if ((newivm->iv = oakley_hash(buf, iph1)) == NULL) 3132 goto end; 3133 3134 /* adjust length of iv */ 3135 newivm->iv->l = alg_oakley_encdef_blocklen(iph1->approval->enctype); 3136 if (newivm->iv->l == -1) { 3137 plog(ASL_LEVEL_ERR, 3138 "Invalid encryption algorithm %d.\n", 3139 iph1->approval->enctype); 3140 goto end; 3141 } 3142 3143 /* create buffer to save new iv */ 3144 if ((newivm->ive = vdup(newivm->iv)) == NULL) { 3145 plog(ASL_LEVEL_ERR, "vdup (%s)\n", strerror(errno)); 3146 goto end; 3147 } 3148 3149 error = 0; 3150 3151 //plogdump(ASL_LEVEL_DEBUG, newivm->iv->v, newivm->iv->l, "Phase 2 IV computed:\n"); 3152 3153end: 3154 if (error && newivm != NULL){ 3155 oakley_delivm(newivm); 3156 newivm=NULL; 3157 } 3158 if (buf != NULL) 3159 vfree(buf); 3160 return newivm; 3161} 3162 3163void 3164oakley_delivm(struct isakmp_ivm *ivm) 3165{ 3166 if (ivm == NULL) 3167 return; 3168 3169 if (ivm->iv != NULL) 3170 vfree(ivm->iv); 3171 if (ivm->ive != NULL) 3172 vfree(ivm->ive); 3173 racoon_free(ivm); 3174 plog(ASL_LEVEL_DEBUG, "IV freed\n"); 3175 3176 return; 3177} 3178 3179/* 3180 * decrypt packet. 3181 * save new iv and old iv. 3182 */ 3183vchar_t * 3184oakley_do_ikev1_decrypt(phase1_handle_t *iph1, vchar_t *msg, vchar_t *ivdp, vchar_t *ivep) 3185{ 3186 vchar_t *buf = NULL, *new = NULL; 3187 char *pl; 3188 int len; 3189 u_int8_t padlen; 3190 int blen; 3191 int error = -1; 3192 3193 plog(ASL_LEVEL_DEBUG, "Begin decryption.\n"); 3194 3195 blen = alg_oakley_encdef_blocklen(iph1->approval->enctype); 3196 if (blen == -1) { 3197 plog(ASL_LEVEL_ERR, 3198 "Invalid encryption algorithm %d.\n", 3199 iph1->approval->enctype); 3200 goto end; 3201 } 3202 3203 /* save IV for next, but not sync. */ 3204 memset(ivep->v, 0, ivep->l); 3205 memcpy(ivep->v, (caddr_t)&msg->v[msg->l - blen], blen); 3206 3207 plogdump(ASL_LEVEL_DEBUG, ivep->v, ivep->l, "IV was saved for next processing:\n"); 3208 3209 pl = msg->v + sizeof(struct isakmp); 3210 3211 len = msg->l - sizeof(struct isakmp); 3212 3213 /* create buffer */ 3214 buf = vmalloc(len); 3215 if (buf == NULL) { 3216 plog(ASL_LEVEL_ERR, 3217 "Failed to get buffer to decrypt.\n"); 3218 goto end; 3219 } 3220 memcpy(buf->v, pl, len); 3221 3222 /* do decrypt */ 3223 new = alg_oakley_encdef_decrypt(iph1->approval->enctype, 3224 buf, iph1->key, ivdp); 3225 if (new == NULL || new->v == NULL || new->l == 0) { 3226 plog(ASL_LEVEL_ERR, 3227 "Decryption %d failed.\n", iph1->approval->enctype); 3228 goto end; 3229 } 3230 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "with key:\n"); 3231 3232 vfree(buf); 3233 buf = NULL; 3234 if (new == NULL) 3235 goto end; 3236 3237 plog(ASL_LEVEL_DEBUG, "decrypted payload by IV:\n"); 3238 3239 /* get padding length */ 3240 if (lcconf->pad_excltail) 3241 padlen = new->v[new->l - 1] + 1; 3242 else 3243 padlen = new->v[new->l - 1]; 3244 plog(ASL_LEVEL_DEBUG, "padding len=%u\n", padlen); 3245 3246 /* trim padding */ 3247 if (lcconf->pad_strict) { 3248 if (padlen > new->l) { 3249 plog(ASL_LEVEL_ERR, "invalid padding len=%u, buflen=%zu.\n", 3250 padlen, new->l); 3251 goto end; 3252 } 3253 new->l -= padlen; 3254 plog(ASL_LEVEL_DEBUG, "trimmed padding\n"); 3255 } else { 3256 plog(ASL_LEVEL_DEBUG, "skip to trim padding.\n"); 3257 } 3258 3259 /* create new buffer */ 3260 len = sizeof(struct isakmp) + new->l; 3261 buf = vmalloc(len); 3262 if (buf == NULL) { 3263 plog(ASL_LEVEL_ERR, 3264 "failed to get buffer to decrypt.\n"); 3265 goto end; 3266 } 3267 memcpy(buf->v, msg->v, sizeof(struct isakmp)); 3268 memcpy(buf->v + sizeof(struct isakmp), new->v, new->l); 3269 ((struct isakmp *)buf->v)->len = htonl(buf->l); 3270 3271 plog(ASL_LEVEL_DEBUG, "decrypted.\n"); 3272 3273#ifdef HAVE_PRINT_ISAKMP_C 3274 isakmp_printpacket(buf, iph1->remote, iph1->local, 1); 3275#endif 3276 3277 error = 0; 3278 3279end: 3280 if (error && buf != NULL) { 3281 vfree(buf); 3282 buf = NULL; 3283 } 3284 if (new != NULL) 3285 vfree(new); 3286 3287 return buf; 3288} 3289 3290/* 3291 * decrypt packet. 3292 */ 3293vchar_t * 3294oakley_do_decrypt(phase1_handle_t *iph1, vchar_t *msg, vchar_t *ivdp, vchar_t *ivep) 3295{ 3296 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 3297 return(oakley_do_ikev1_decrypt(iph1, msg, ivdp, ivep)); 3298 } 3299 3300 plog(ASL_LEVEL_ERR, "Failed to decrypt invalid IKE version"); 3301 return NULL; 3302} 3303 3304/* 3305 * encrypt packet. 3306 */ 3307vchar_t * 3308oakley_do_ikev1_encrypt(phase1_handle_t *iph1, vchar_t *msg, vchar_t *ivep, vchar_t *ivp) 3309{ 3310 vchar_t *buf = 0, *new = 0; 3311 char *pl; 3312 int len; 3313 u_int padlen; 3314 int blen; 3315 int error = -1; 3316 3317 plog(ASL_LEVEL_DEBUG, "Begin encryption.\n"); 3318 3319 /* set cbc block length */ 3320 blen = alg_oakley_encdef_blocklen(iph1->approval->enctype); 3321 if (blen == -1) { 3322 plog(ASL_LEVEL_ERR, 3323 "Invalid encryption algorithm %d.\n", 3324 iph1->approval->enctype); 3325 goto end; 3326 } 3327 3328 pl = msg->v + sizeof(struct isakmp); 3329 len = msg->l - sizeof(struct isakmp); 3330 3331 /* add padding */ 3332 padlen = oakley_padlen(len, blen); 3333 plog(ASL_LEVEL_DEBUG, "pad length = %u\n", padlen); 3334 3335 /* create buffer */ 3336 buf = vmalloc(len + padlen); 3337 if (buf == NULL) { 3338 plog(ASL_LEVEL_ERR, 3339 "Failed to get buffer to encrypt.\n"); 3340 goto end; 3341 } 3342 if (padlen) { 3343 int i; 3344 char *p = &buf->v[len]; 3345 if (lcconf->pad_random) { 3346 for (i = 0; i < padlen; i++) 3347 *p++ = eay_random() & 0xff; 3348 } 3349 } 3350 memcpy(buf->v, pl, len); 3351 3352 /* make pad into tail */ 3353 if (lcconf->pad_excltail) 3354 buf->v[len + padlen - 1] = padlen - 1; 3355 else 3356 buf->v[len + padlen - 1] = padlen; 3357 3358 plogdump(ASL_LEVEL_DEBUG, buf->v, buf->l, "About to encrypt %d bytes", buf->l); 3359 3360 /* do encrypt */ 3361 new = alg_oakley_encdef_encrypt(iph1->approval->enctype, 3362 buf, iph1->key, ivep); 3363 if (new == NULL) { 3364 plog(ASL_LEVEL_ERR, 3365 "Encryption %d failed.\n", iph1->approval->enctype); 3366 goto end; 3367 } 3368 //plogdump(ASL_LEVEL_DEBUG, iph1->key->v, iph1->key->l, "with key:\n"); 3369 3370 vfree(buf); 3371 buf = NULL; 3372 if (new == NULL) 3373 goto end; 3374 3375 //plogdump(ASL_LEVEL_DEBUG, ivep->v, ivep->l, "encrypted payload by IV:\n"); 3376 3377 /* save IV for next */ 3378 memset(ivp->v, 0, ivp->l); 3379 memcpy(ivp->v, (caddr_t)&new->v[new->l - blen], blen); 3380 3381 //plogdump(ASL_LEVEL_DEBUG, ivp->v, ivp->l, "save IV for next:\n"); 3382 3383 /* create new buffer */ 3384 len = sizeof(struct isakmp) + new->l; 3385 buf = vmalloc(len); 3386 if (buf == NULL) { 3387 plog(ASL_LEVEL_ERR, 3388 "Failed to get buffer to encrypt.\n"); 3389 goto end; 3390 } 3391 memcpy(buf->v, msg->v, sizeof(struct isakmp)); 3392 memcpy(buf->v + sizeof(struct isakmp), new->v, new->l); 3393 ((struct isakmp *)buf->v)->len = htonl(buf->l); 3394 3395 error = 0; 3396 3397 plog(ASL_LEVEL_DEBUG, "Encrypted.\n"); 3398 3399end: 3400 if (error && buf != NULL) { 3401 vfree(buf); 3402 buf = NULL; 3403 } 3404 if (new != NULL) 3405 vfree(new); 3406 3407 return buf; 3408} 3409 3410/* 3411 * encrypt packet. 3412 */ 3413vchar_t * 3414oakley_do_encrypt(phase1_handle_t *iph1, vchar_t *msg, vchar_t *ivep, vchar_t *ivp) 3415{ 3416 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) { 3417 return(oakley_do_ikev1_encrypt(iph1, msg, ivep, ivp)); 3418 } 3419 3420 plog(ASL_LEVEL_ERR, "Failed to encrypt invalid IKE version"); 3421 return NULL; 3422} 3423 3424/* culculate padding length */ 3425static int 3426oakley_padlen(int len, int base) 3427{ 3428 int padlen; 3429 3430 padlen = base - (len % base); 3431 3432 if (lcconf->pad_randomlen) 3433 padlen += ((eay_random() % (lcconf->pad_maxsize + 1) + 1) * 3434 base); 3435 3436 return padlen; 3437} 3438 3439/* ----------------------------------------------------------------------------- 3440The base-64 encoding packs three 8-bit bytes into four 7-bit ASCII 3441characters. If the number of bytes in the original data isn't divisable 3442by three, "=" characters are used to pad the encoded data. The complete 3443set of characters used in base-64 are: 3444 'A'..'Z' => 00..25 3445 'a'..'z' => 26..51 3446 '0'..'9' => 52..61 3447 '+' => 62 3448 '/' => 63 3449 '=' => pad 3450 3451----------------------------------------------------------------------------- */ 3452static const signed char base64_DecodeTable[128] = { 3453 /* 000 */ -1, -1, -1, -1, -1, -1, -1, -1, 3454 /* 010 */ -1, -1, -1, -1, -1, -1, -1, -1, 3455 /* 020 */ -1, -1, -1, -1, -1, -1, -1, -1, 3456 /* 030 */ -1, -1, -1, -1, -1, -1, -1, -1, 3457 /* ' ' */ -1, -1, -1, -1, -1, -1, -1, -1, 3458 /* '(' */ -1, -1, -1, 62, -1, -1, -1, 63, 3459 /* '0' */ 52, 53, 54, 55, 56, 57, 58, 59, 3460 /* '8' */ 60, 61, -1, -1, -1, 0, -1, -1, 3461 /* '@' */ -1, 0, 1, 2, 3, 4, 5, 6, 3462 /* 'H' */ 7, 8, 9, 10, 11, 12, 13, 14, 3463 /* 'P' */ 15, 16, 17, 18, 19, 20, 21, 22, 3464 /* 'X' */ 23, 24, 25, -1, -1, -1, -1, -1, 3465 /* '`' */ -1, 26, 27, 28, 29, 30, 31, 32, 3466 /* 'h' */ 33, 34, 35, 36, 37, 38, 39, 40, 3467 /* 'p' */ 41, 42, 43, 44, 45, 46, 47, 48, 3468 /* 'x' */ 49, 50, 51, -1, -1, -1, -1, -1 3469}; 3470 3471static int base64toCFData(vchar_t *textin, CFDataRef *dataRef) 3472{ 3473 uint8_t *tmpbuf; 3474 uint8_t c; 3475 int tmpbufpos = 0; 3476 int numeq = 0; 3477 int acc = 0; 3478 int cntr = 0; 3479 uint8_t *textcur = (__typeof__(textcur))textin->v; 3480 int len = textin->l; 3481 int i; 3482 3483 tmpbuf = malloc(len); // len of result will be less than encoded len 3484 if (tmpbuf == NULL) { 3485 yyerror("memory error - could not allocate buffer for certificate reference conversion from base-64."); 3486 return -1; 3487 } 3488 3489 for (i = 0; i < len; i++) { 3490 c = *(textcur++); 3491 if (c == '=') 3492 numeq++; 3493 else if (!isspace(c)) 3494 numeq = 0; 3495 if (base64_DecodeTable[c] < 0) 3496 continue; 3497 cntr++; 3498 acc <<= 6; 3499 acc += base64_DecodeTable[c]; 3500 if (0 == (cntr & 0x3)) { 3501 tmpbuf[tmpbufpos++] = (acc >> 16) & 0xff; 3502 if (numeq < 2) 3503 tmpbuf[tmpbufpos++] = (acc >> 8) & 0xff; 3504 if (numeq < 1) 3505 tmpbuf[tmpbufpos++] = acc & 0xff; 3506 } 3507 } 3508 *dataRef = CFDataCreate(NULL, tmpbuf, tmpbufpos); 3509 free(tmpbuf); 3510 if (*dataRef) 3511 return 0; 3512 else 3513 return -1; 3514 3515} 3516 3517