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