1 /* $OpenBSD: ike_quick_mode.c,v 1.102 2008/11/11 15:11:28 hshoexer Exp $ */ 2 /* $EOM: ike_quick_mode.c,v 1.139 2001/01/26 10:43:17 niklas Exp $ */ 3 4 /* 5 * Copyright (c) 1998, 1999, 2000, 2001 Niklas Hallqvist. All rights reserved. 6 * Copyright (c) 1999, 2000, 2001 Angelos D. Keromytis. All rights reserved. 7 * Copyright (c) 2000, 2001, 2004 H�kan Olsson. 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 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 /* 31 * This code was written under funding by Ericsson Radio Systems. 32 */ 33 34 #include <stdlib.h> 35 #include <string.h> 36 37 #include <sys/types.h> 38 #include <regex.h> 39 #include <keynote.h> 40 41 #include "attribute.h" 42 #include "conf.h" 43 #include "connection.h" 44 #include "dh.h" 45 #include "doi.h" 46 #include "exchange.h" 47 #include "hash.h" 48 #include "ike_quick_mode.h" 49 #include "ipsec.h" 50 #include "log.h" 51 #include "math_group.h" 52 #include "message.h" 53 #include "policy.h" 54 #include "prf.h" 55 #include "sa.h" 56 #include "transport.h" 57 #include "util.h" 58 #include "key.h" 59 #include "x509.h" 60 61 static void gen_g_xy(struct message *); 62 static int initiator_send_HASH_SA_NONCE(struct message *); 63 static int initiator_recv_HASH_SA_NONCE(struct message *); 64 static int initiator_send_HASH(struct message *); 65 static void post_quick_mode(struct message *); 66 static int responder_recv_HASH_SA_NONCE(struct message *); 67 static int responder_send_HASH_SA_NONCE(struct message *); 68 static int responder_recv_HASH(struct message *); 69 70 static int check_policy(struct exchange *, struct sa *, struct sa *); 71 72 int (*ike_quick_mode_initiator[])(struct message *) = { 73 initiator_send_HASH_SA_NONCE, 74 initiator_recv_HASH_SA_NONCE, 75 initiator_send_HASH 76 }; 77 78 int (*ike_quick_mode_responder[])(struct message *) = { 79 responder_recv_HASH_SA_NONCE, 80 responder_send_HASH_SA_NONCE, 81 responder_recv_HASH 82 }; 83 84 /* How many return values will policy handle -- true/false for now */ 85 #define RETVALUES_NUM 2 86 87 /* 88 * Given an exchange and our policy, check whether the SA and IDs are 89 * acceptable. 90 */ 91 static int 92 check_policy(struct exchange *exchange, struct sa *sa, struct sa *isakmp_sa) 93 { 94 char *return_values[RETVALUES_NUM]; 95 char **principal = 0; 96 int i, len, result = 0, nprinc = 0; 97 int *x509_ids = 0, *keynote_ids = 0; 98 unsigned char hashbuf[20]; /* Set to the largest digest result */ 99 struct keynote_deckey dc; 100 X509_NAME *subject; 101 102 /* Do we want to use keynote policies? */ 103 if (ignore_policy || 104 strncmp("yes", conf_get_str("General", "Use-Keynote"), 3)) 105 return 1; 106 107 /* Initialize if necessary -- e.g., if pre-shared key auth was used */ 108 if (isakmp_sa->policy_id < 0) { 109 if ((isakmp_sa->policy_id = kn_init()) == -1) { 110 log_print("check_policy: " 111 "failed to initialize policy session"); 112 return 0; 113 } 114 } 115 /* Add the callback that will handle attributes. */ 116 if (kn_add_action(isakmp_sa->policy_id, ".*", (char *)policy_callback, 117 ENVIRONMENT_FLAG_FUNC | ENVIRONMENT_FLAG_REGEX) == -1) { 118 log_print("check_policy: " 119 "kn_add_action (%d, \".*\", %p, FUNC | REGEX) failed", 120 isakmp_sa->policy_id, policy_callback); 121 kn_close(isakmp_sa->policy_id); 122 isakmp_sa->policy_id = -1; 123 return 0; 124 } 125 if (policy_asserts_num) { 126 keynote_ids = calloc(policy_asserts_num, sizeof *keynote_ids); 127 if (!keynote_ids) { 128 log_error("check_policy: calloc (%d, %lu) failed", 129 policy_asserts_num, 130 (unsigned long)sizeof *keynote_ids); 131 kn_close(isakmp_sa->policy_id); 132 isakmp_sa->policy_id = -1; 133 return 0; 134 } 135 } 136 /* Add the policy assertions */ 137 for (i = 0; i < policy_asserts_num; i++) 138 keynote_ids[i] = kn_add_assertion(isakmp_sa->policy_id, 139 policy_asserts[i], 140 strlen(policy_asserts[i]), ASSERT_FLAG_LOCAL); 141 142 /* Initialize -- we'll let the callback do all the work. */ 143 policy_exchange = exchange; 144 policy_sa = sa; 145 policy_isakmp_sa = isakmp_sa; 146 147 /* Set the return values; true/false for now at least. */ 148 return_values[0] = "false"; /* Order of values in array is 149 * important. */ 150 return_values[1] = "true"; 151 152 /* Create a principal (authorizer) for the SA/ID request. */ 153 switch (isakmp_sa->recv_certtype) { 154 case ISAKMP_CERTENC_NONE: 155 /* 156 * For shared keys, just duplicate the passphrase with the 157 * appropriate prefix tag. 158 */ 159 nprinc = 3; 160 principal = calloc(nprinc, sizeof *principal); 161 if (!principal) { 162 log_error("check_policy: calloc (%d, %lu) failed", 163 nprinc, (unsigned long)sizeof *principal); 164 goto policydone; 165 } 166 len = strlen(isakmp_sa->recv_key) + sizeof "passphrase:"; 167 principal[0] = calloc(len, sizeof(char)); 168 if (!principal[0]) { 169 log_error("check_policy: calloc (%d, %lu) failed", len, 170 (unsigned long)sizeof(char)); 171 goto policydone; 172 } 173 /* 174 * XXX Consider changing the magic hash lengths with 175 * constants. 176 */ 177 strlcpy(principal[0], "passphrase:", len); 178 memcpy(principal[0] + sizeof "passphrase:" - 1, 179 isakmp_sa->recv_key, strlen(isakmp_sa->recv_key)); 180 181 len = sizeof "passphrase-md5-hex:" + 2 * 16; 182 principal[1] = calloc(len, sizeof(char)); 183 if (!principal[1]) { 184 log_error("check_policy: calloc (%d, %lu) failed", len, 185 (unsigned long)sizeof(char)); 186 goto policydone; 187 } 188 strlcpy(principal[1], "passphrase-md5-hex:", len); 189 MD5(isakmp_sa->recv_key, strlen(isakmp_sa->recv_key), hashbuf); 190 for (i = 0; i < 16; i++) 191 snprintf(principal[1] + 2 * i + 192 sizeof "passphrase-md5-hex:" - 1, 3, "%02x", 193 hashbuf[i]); 194 195 len = sizeof "passphrase-sha1-hex:" + 2 * 20; 196 principal[2] = calloc(len, sizeof(char)); 197 if (!principal[2]) { 198 log_error("check_policy: calloc (%d, %lu) failed", len, 199 (unsigned long)sizeof(char)); 200 goto policydone; 201 } 202 strlcpy(principal[2], "passphrase-sha1-hex:", len); 203 SHA1(isakmp_sa->recv_key, strlen(isakmp_sa->recv_key), 204 hashbuf); 205 for (i = 0; i < 20; i++) 206 snprintf(principal[2] + 2 * i + 207 sizeof "passphrase-sha1-hex:" - 1, 3, "%02x", 208 hashbuf[i]); 209 break; 210 211 case ISAKMP_CERTENC_KEYNOTE: 212 nprinc = 1; 213 214 principal = calloc(nprinc, sizeof *principal); 215 if (!principal) { 216 log_error("check_policy: calloc (%d, %lu) failed", 217 nprinc, (unsigned long)sizeof *principal); 218 goto policydone; 219 } 220 /* Dup the keys */ 221 principal[0] = strdup(isakmp_sa->keynote_key); 222 if (!principal[0]) { 223 log_error("check_policy: calloc (%lu, %lu) failed", 224 (unsigned long)strlen(isakmp_sa->keynote_key), 225 (unsigned long)sizeof(char)); 226 goto policydone; 227 } 228 break; 229 230 case ISAKMP_CERTENC_X509_SIG: 231 principal = calloc(2, sizeof *principal); 232 if (!principal) { 233 log_error("check_policy: calloc (2, %lu) failed", 234 (unsigned long)sizeof *principal); 235 goto policydone; 236 } 237 if (isakmp_sa->recv_keytype == ISAKMP_KEY_RSA) 238 dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA; 239 else { 240 log_error("check_policy: " 241 "unknown/unsupported public key algorithm %d", 242 isakmp_sa->recv_keytype); 243 goto policydone; 244 } 245 246 dc.dec_key = isakmp_sa->recv_key; 247 principal[0] = kn_encode_key(&dc, INTERNAL_ENC_PKCS1, 248 ENCODING_HEX, KEYNOTE_PUBLIC_KEY); 249 if (keynote_errno == ERROR_MEMORY) { 250 log_print("check_policy: " 251 "failed to get memory for public key"); 252 goto policydone; 253 } 254 if (!principal[0]) { 255 log_print("check_policy: " 256 "failed to allocate memory for principal"); 257 goto policydone; 258 } 259 if (asprintf(&principal[1], "rsa-hex:%s", principal[0]) == -1) { 260 log_error("check_policy: asprintf() failed"); 261 goto policydone; 262 } 263 free(principal[0]); 264 principal[0] = principal[1]; 265 principal[1] = 0; 266 267 /* Generate a "DN:" principal. */ 268 subject = X509_get_subject_name(isakmp_sa->recv_cert); 269 if (subject) { 270 principal[1] = calloc(259, sizeof(char)); 271 if (!principal[1]) { 272 log_error("check_policy: " 273 "calloc (259, %lu) failed", 274 (unsigned long)sizeof(char)); 275 goto policydone; 276 } 277 strlcpy(principal[1], "DN:", 259); 278 X509_NAME_oneline(subject, principal[1] + 3, 256); 279 nprinc = 2; 280 } else { 281 nprinc = 1; 282 } 283 break; 284 285 /* XXX Eventually handle these. */ 286 case ISAKMP_CERTENC_PKCS: 287 case ISAKMP_CERTENC_PGP: 288 case ISAKMP_CERTENC_DNS: 289 case ISAKMP_CERTENC_X509_KE: 290 case ISAKMP_CERTENC_KERBEROS: 291 case ISAKMP_CERTENC_CRL: 292 case ISAKMP_CERTENC_ARL: 293 case ISAKMP_CERTENC_SPKI: 294 case ISAKMP_CERTENC_X509_ATTR: 295 default: 296 log_print("check_policy: " 297 "unknown/unsupported certificate/authentication method %d", 298 isakmp_sa->recv_certtype); 299 goto policydone; 300 } 301 302 /* 303 * Add the authorizer (who is requesting the SA/ID); 304 * this may be a public or a secret key, depending on 305 * what mode of authentication we used in Phase 1. 306 */ 307 for (i = 0; i < nprinc; i++) { 308 LOG_DBG((LOG_POLICY, 40, "check_policy: " 309 "adding authorizer [%s]", principal[i])); 310 311 if (kn_add_authorizer(isakmp_sa->policy_id, principal[i]) 312 == -1) { 313 int j; 314 315 for (j = 0; j < i; j++) 316 kn_remove_authorizer(isakmp_sa->policy_id, 317 principal[j]); 318 log_print("check_policy: kn_add_authorizer failed"); 319 goto policydone; 320 } 321 } 322 323 /* Ask policy */ 324 result = kn_do_query(isakmp_sa->policy_id, return_values, 325 RETVALUES_NUM); 326 LOG_DBG((LOG_POLICY, 40, "check_policy: kn_do_query returned %d", 327 result)); 328 329 /* Cleanup environment */ 330 kn_cleanup_action_environment(isakmp_sa->policy_id); 331 332 /* Remove authorizers from the session */ 333 for (i = 0; i < nprinc; i++) { 334 kn_remove_authorizer(isakmp_sa->policy_id, principal[i]); 335 free(principal[i]); 336 } 337 338 free(principal); 339 principal = 0; 340 nprinc = 0; 341 342 /* Check what policy said. */ 343 if (result < 0) { 344 LOG_DBG((LOG_POLICY, 40, "check_policy: proposal refused")); 345 result = 0; 346 goto policydone; 347 } 348 policydone: 349 for (i = 0; i < nprinc; i++) 350 if (principal && principal[i]) 351 free(principal[i]); 352 353 free(principal); 354 355 /* Remove the policies */ 356 for (i = 0; i < policy_asserts_num; i++) { 357 if (keynote_ids[i] != -1) 358 kn_remove_assertion(isakmp_sa->policy_id, 359 keynote_ids[i]); 360 } 361 362 free(keynote_ids); 363 364 free(x509_ids); 365 366 /* 367 * XXX Currently, check_policy() is only called from 368 * message_negotiate_sa(), and so this log message reflects this. 369 * Change to something better? 370 */ 371 if (result == 0) 372 log_print("check_policy: negotiated SA failed policy check"); 373 374 /* 375 * Given that we have only 2 return values from policy (true/false) 376 * we can just return the query result directly (no pre-processing 377 * needed). 378 */ 379 return result; 380 } 381 382 /* 383 * Offer several sets of transforms to the responder. 384 * XXX Split this huge function up and look for common code with main mode. 385 */ 386 static int 387 initiator_send_HASH_SA_NONCE(struct message *msg) 388 { 389 struct exchange *exchange = msg->exchange; 390 struct doi *doi = exchange->doi; 391 struct ipsec_exch *ie = exchange->data; 392 u_int8_t ***transform = 0, ***new_transform; 393 u_int8_t **proposal = 0, **new_proposal; 394 u_int8_t *sa_buf = 0, *attr, *saved_nextp_sa, *saved_nextp_prop, 395 *id, *spi; 396 size_t spi_sz, sz; 397 size_t proposal_len = 0, proposals_len = 0, sa_len; 398 size_t **transform_len = 0, **new_transform_len; 399 size_t *transforms_len = 0, *new_transforms_len; 400 u_int32_t *transform_cnt = 0, *new_transform_cnt; 401 u_int32_t suite_no, prop_no, prot_no, xf_no, prop_cnt = 0; 402 u_int32_t i; 403 int value, update_nextp, protocol_num, proto_id; 404 struct proto *proto; 405 struct conf_list *suite_conf, *prot_conf = 0, *xf_conf = 0, *life_conf; 406 struct conf_list_node *suite, *prot, *xf, *life; 407 struct constant_map *id_map; 408 char *protocol_id, *transform_id; 409 char *local_id, *remote_id; 410 int group_desc = -1, new_group_desc; 411 struct ipsec_sa *isa = msg->isakmp_sa->data; 412 struct hash *hash = hash_get(isa->hash); 413 struct sockaddr *src; 414 struct proto_attr *pa; 415 416 if (!ipsec_add_hash_payload(msg, hash->hashsize)) 417 return -1; 418 419 /* Get the list of protocol suites. */ 420 suite_conf = conf_get_list(exchange->policy, "Suites"); 421 if (!suite_conf) 422 return -1; 423 424 for (suite = TAILQ_FIRST(&suite_conf->fields), suite_no = prop_no = 0; 425 suite_no < suite_conf->cnt; 426 suite_no++, suite = TAILQ_NEXT(suite, link)) { 427 /* Now get each protocol in this specific protocol suite. */ 428 prot_conf = conf_get_list(suite->field, "Protocols"); 429 if (!prot_conf) 430 goto bail_out; 431 432 for (prot = TAILQ_FIRST(&prot_conf->fields), prot_no = 0; 433 prot_no < prot_conf->cnt; 434 prot_no++, prot = TAILQ_NEXT(prot, link)) { 435 /* Make sure we have a proposal/transform vectors. */ 436 if (prop_no >= prop_cnt) { 437 /* 438 * This resize algorithm is completely 439 * arbitrary. 440 */ 441 prop_cnt = 2 * prop_cnt + 10; 442 new_proposal = realloc(proposal, 443 prop_cnt * sizeof *proposal); 444 if (!new_proposal) { 445 log_error( 446 "initiator_send_HASH_SA_NONCE: " 447 "realloc (%p, %lu) failed", 448 proposal, 449 prop_cnt * (unsigned long)sizeof *proposal); 450 goto bail_out; 451 } 452 proposal = new_proposal; 453 454 new_transforms_len = realloc(transforms_len, 455 prop_cnt * sizeof *transforms_len); 456 if (!new_transforms_len) { 457 log_error( 458 "initiator_send_HASH_SA_NONCE: " 459 "realloc (%p, %lu) failed", 460 transforms_len, 461 prop_cnt * (unsigned long)sizeof *transforms_len); 462 goto bail_out; 463 } 464 transforms_len = new_transforms_len; 465 466 new_transform = realloc(transform, 467 prop_cnt * sizeof *transform); 468 if (!new_transform) { 469 log_error( 470 "initiator_send_HASH_SA_NONCE: " 471 "realloc (%p, %lu) failed", 472 transform, 473 prop_cnt * (unsigned long)sizeof *transform); 474 goto bail_out; 475 } 476 transform = new_transform; 477 478 new_transform_cnt = realloc(transform_cnt, 479 prop_cnt * sizeof *transform_cnt); 480 if (!new_transform_cnt) { 481 log_error( 482 "initiator_send_HASH_SA_NONCE: " 483 "realloc (%p, %lu) failed", 484 transform_cnt, 485 prop_cnt * (unsigned long)sizeof *transform_cnt); 486 goto bail_out; 487 } 488 transform_cnt = new_transform_cnt; 489 490 new_transform_len = realloc(transform_len, 491 prop_cnt * sizeof *transform_len); 492 if (!new_transform_len) { 493 log_error( 494 "initiator_send_HASH_SA_NONCE: " 495 "realloc (%p, %lu) failed", 496 transform_len, 497 prop_cnt * (unsigned long)sizeof *transform_len); 498 goto bail_out; 499 } 500 transform_len = new_transform_len; 501 } 502 protocol_id = conf_get_str(prot->field, "PROTOCOL_ID"); 503 if (!protocol_id) 504 goto bail_out; 505 506 proto_id = constant_value(ipsec_proto_cst, 507 protocol_id); 508 switch (proto_id) { 509 case IPSEC_PROTO_IPSEC_AH: 510 id_map = ipsec_ah_cst; 511 break; 512 513 case IPSEC_PROTO_IPSEC_ESP: 514 id_map = ipsec_esp_cst; 515 break; 516 517 case IPSEC_PROTO_IPCOMP: 518 id_map = ipsec_ipcomp_cst; 519 break; 520 521 default: 522 { 523 log_print("initiator_send_HASH_SA_NONCE: " 524 "invalid PROTCOL_ID: %s", protocol_id); 525 goto bail_out; 526 } 527 } 528 529 /* Now get each transform we offer for this protocol.*/ 530 xf_conf = conf_get_list(prot->field, "Transforms"); 531 if (!xf_conf) 532 goto bail_out; 533 transform_cnt[prop_no] = xf_conf->cnt; 534 535 transform[prop_no] = calloc(transform_cnt[prop_no], 536 sizeof **transform); 537 if (!transform[prop_no]) { 538 log_error("initiator_send_HASH_SA_NONCE: " 539 "calloc (%d, %lu) failed", 540 transform_cnt[prop_no], 541 (unsigned long)sizeof **transform); 542 goto bail_out; 543 } 544 transform_len[prop_no] = calloc(transform_cnt[prop_no], 545 sizeof **transform_len); 546 if (!transform_len[prop_no]) { 547 log_error("initiator_send_HASH_SA_NONCE: " 548 "calloc (%d, %lu) failed", 549 transform_cnt[prop_no], 550 (unsigned long)sizeof **transform_len); 551 goto bail_out; 552 } 553 transforms_len[prop_no] = 0; 554 for (xf = TAILQ_FIRST(&xf_conf->fields), xf_no = 0; 555 xf_no < transform_cnt[prop_no]; 556 xf_no++, xf = TAILQ_NEXT(xf, link)) { 557 558 /* XXX The sizing needs to be dynamic. */ 559 transform[prop_no][xf_no] = 560 calloc(ISAKMP_TRANSFORM_SA_ATTRS_OFF + 561 9 * ISAKMP_ATTR_VALUE_OFF, 1); 562 if (!transform[prop_no][xf_no]) { 563 log_error( 564 "initiator_send_HASH_SA_NONCE: " 565 "calloc (%d, 1) failed", 566 ISAKMP_TRANSFORM_SA_ATTRS_OFF + 567 9 * ISAKMP_ATTR_VALUE_OFF); 568 goto bail_out; 569 } 570 SET_ISAKMP_TRANSFORM_NO(transform[prop_no][xf_no], 571 xf_no + 1); 572 573 transform_id = conf_get_str(xf->field, 574 "TRANSFORM_ID"); 575 if (!transform_id) 576 goto bail_out; 577 SET_ISAKMP_TRANSFORM_ID(transform[prop_no][xf_no], 578 constant_value(id_map, transform_id)); 579 SET_ISAKMP_TRANSFORM_RESERVED(transform[prop_no][xf_no], 0); 580 581 attr = transform[prop_no][xf_no] + 582 ISAKMP_TRANSFORM_SA_ATTRS_OFF; 583 584 /* 585 * Life durations are special, we should be 586 * able to specify several, one per type. 587 */ 588 life_conf = conf_get_list(xf->field, "Life"); 589 if (life_conf) { 590 for (life = TAILQ_FIRST(&life_conf->fields); 591 life; life = TAILQ_NEXT(life, link)) { 592 attribute_set_constant( 593 life->field, "LIFE_TYPE", 594 ipsec_duration_cst, 595 IPSEC_ATTR_SA_LIFE_TYPE, 596 &attr); 597 598 /* 599 * XXX Deals with 16 and 32 600 * bit lifetimes only 601 */ 602 value = 603 conf_get_num(life->field, 604 "LIFE_DURATION", 0); 605 if (value) { 606 if (value <= 0xffff) 607 attr = 608 attribute_set_basic( 609 attr, 610 IPSEC_ATTR_SA_LIFE_DURATION, 611 value); 612 else { 613 value = htonl(value); 614 attr = 615 attribute_set_var( 616 attr, 617 IPSEC_ATTR_SA_LIFE_DURATION, 618 (u_int8_t *)&value, 619 sizeof value); 620 } 621 } 622 } 623 conf_free_list(life_conf); 624 } 625 attribute_set_constant(xf->field, 626 "ENCAPSULATION_MODE", ipsec_encap_cst, 627 IPSEC_ATTR_ENCAPSULATION_MODE, &attr); 628 629 if (proto_id != IPSEC_PROTO_IPCOMP) { 630 attribute_set_constant(xf->field, 631 "AUTHENTICATION_ALGORITHM", 632 ipsec_auth_cst, 633 IPSEC_ATTR_AUTHENTICATION_ALGORITHM, 634 &attr); 635 636 attribute_set_constant(xf->field, 637 "GROUP_DESCRIPTION", 638 ike_group_desc_cst, 639 IPSEC_ATTR_GROUP_DESCRIPTION, &attr); 640 641 value = conf_get_num(xf->field, 642 "KEY_LENGTH", 0); 643 if (value) 644 attr = attribute_set_basic( 645 attr, 646 IPSEC_ATTR_KEY_LENGTH, 647 value); 648 649 value = conf_get_num(xf->field, 650 "KEY_ROUNDS", 0); 651 if (value) 652 attr = attribute_set_basic( 653 attr, 654 IPSEC_ATTR_KEY_ROUNDS, 655 value); 656 } else { 657 value = conf_get_num(xf->field, 658 "COMPRESS_DICTIONARY_SIZE", 0); 659 if (value) 660 attr = attribute_set_basic( 661 attr, 662 IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE, 663 value); 664 665 value = conf_get_num(xf->field, 666 "COMPRESS_PRIVATE_ALGORITHM", 0); 667 if (value) 668 attr = attribute_set_basic( 669 attr, 670 IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM, 671 value); 672 } 673 674 value = conf_get_num(xf->field, "ECN_TUNNEL", 675 0); 676 if (value) 677 attr = attribute_set_basic(attr, 678 IPSEC_ATTR_ECN_TUNNEL, value); 679 680 /* Record the real transform size. */ 681 transforms_len[prop_no] += 682 (transform_len[prop_no][xf_no] 683 = attr - transform[prop_no][xf_no]); 684 685 if (proto_id != IPSEC_PROTO_IPCOMP) { 686 /* 687 * Make sure that if a group 688 * description is specified, it is 689 * specified for all transforms 690 * equally. 691 */ 692 attr = 693 (u_int8_t *)conf_get_str(xf->field, 694 "GROUP_DESCRIPTION"); 695 new_group_desc 696 = attr ? constant_value(ike_group_desc_cst, 697 (char *)attr) : 0; 698 if (group_desc == -1) 699 group_desc = new_group_desc; 700 else if (group_desc != new_group_desc) { 701 log_print("initiator_send_HASH_SA_NONCE: " 702 "differing group descriptions in a proposal"); 703 goto bail_out; 704 } 705 } 706 } 707 conf_free_list(xf_conf); 708 xf_conf = 0; 709 710 /* 711 * Get SPI from application. 712 * XXX Should we care about unknown constants? 713 */ 714 protocol_num = constant_value(ipsec_proto_cst, 715 protocol_id); 716 spi = doi->get_spi(&spi_sz, protocol_num, msg); 717 if (spi_sz && !spi) { 718 log_print("initiator_send_HASH_SA_NONCE: " 719 "doi->get_spi failed"); 720 goto bail_out; 721 } 722 proposal_len = ISAKMP_PROP_SPI_OFF + spi_sz; 723 proposals_len += 724 proposal_len + transforms_len[prop_no]; 725 proposal[prop_no] = malloc(proposal_len); 726 if (!proposal[prop_no]) { 727 log_error("initiator_send_HASH_SA_NONCE: " 728 "malloc (%lu) failed", 729 (unsigned long)proposal_len); 730 goto bail_out; 731 } 732 SET_ISAKMP_PROP_NO(proposal[prop_no], suite_no + 1); 733 SET_ISAKMP_PROP_PROTO(proposal[prop_no], protocol_num); 734 735 /* XXX I would like to see this factored out. */ 736 proto = calloc(1, sizeof *proto); 737 if (!proto) { 738 log_error("initiator_send_HASH_SA_NONCE: " 739 "calloc (1, %lu) failed", 740 (unsigned long)sizeof *proto); 741 goto bail_out; 742 } 743 if (doi->proto_size) { 744 proto->data = calloc(1, doi->proto_size); 745 if (!proto->data) { 746 log_error( 747 "initiator_send_HASH_SA_NONCE: " 748 "calloc (1, %lu) failed", 749 (unsigned long)doi->proto_size); 750 goto bail_out; 751 } 752 } 753 proto->no = suite_no + 1; 754 proto->proto = protocol_num; 755 proto->sa = TAILQ_FIRST(&exchange->sa_list); 756 proto->xf_cnt = transform_cnt[prop_no]; 757 TAILQ_INIT(&proto->xfs); 758 for (xf_no = 0; xf_no < proto->xf_cnt; xf_no++) { 759 pa = (struct proto_attr *)calloc(1, 760 sizeof *pa); 761 if (!pa) 762 goto bail_out; 763 pa->len = transform_len[prop_no][xf_no]; 764 pa->attrs = (u_int8_t *)malloc(pa->len); 765 if (!pa->attrs) { 766 free(pa); 767 goto bail_out; 768 } 769 memcpy(pa->attrs, transform[prop_no][xf_no], 770 pa->len); 771 TAILQ_INSERT_TAIL(&proto->xfs, pa, next); 772 } 773 TAILQ_INSERT_TAIL(&TAILQ_FIRST(&exchange->sa_list)->protos, 774 proto, link); 775 776 /* Setup the incoming SPI. */ 777 SET_ISAKMP_PROP_SPI_SZ(proposal[prop_no], spi_sz); 778 memcpy(proposal[prop_no] + ISAKMP_PROP_SPI_OFF, spi, 779 spi_sz); 780 proto->spi_sz[1] = spi_sz; 781 proto->spi[1] = spi; 782 783 /* 784 * Let the DOI get at proto for initializing its own 785 * data. 786 */ 787 if (doi->proto_init) 788 doi->proto_init(proto, prot->field); 789 790 SET_ISAKMP_PROP_NTRANSFORMS(proposal[prop_no], 791 transform_cnt[prop_no]); 792 prop_no++; 793 } 794 conf_free_list(prot_conf); 795 prot_conf = 0; 796 } 797 798 sa_len = ISAKMP_SA_SIT_OFF + IPSEC_SIT_SIT_LEN; 799 sa_buf = malloc(sa_len); 800 if (!sa_buf) { 801 log_error("initiator_send_HASH_SA_NONCE: malloc (%lu) failed", 802 (unsigned long)sa_len); 803 goto bail_out; 804 } 805 SET_ISAKMP_SA_DOI(sa_buf, IPSEC_DOI_IPSEC); 806 SET_IPSEC_SIT_SIT(sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY); 807 808 /* 809 * Add the payloads. As this is a SA, we need to recompute the 810 * lengths of the payloads containing others. We also need to 811 * reset these payload's "next payload type" field. 812 */ 813 if (message_add_payload(msg, ISAKMP_PAYLOAD_SA, sa_buf, sa_len, 1)) 814 goto bail_out; 815 SET_ISAKMP_GEN_LENGTH(sa_buf, sa_len + proposals_len); 816 sa_buf = 0; 817 818 update_nextp = 0; 819 saved_nextp_sa = msg->nextp; 820 for (i = 0; i < prop_no; i++) { 821 if (message_add_payload(msg, ISAKMP_PAYLOAD_PROPOSAL, 822 proposal[i], proposal_len, update_nextp)) 823 goto bail_out; 824 SET_ISAKMP_GEN_LENGTH(proposal[i], 825 proposal_len + transforms_len[i]); 826 proposal[i] = 0; 827 828 update_nextp = 0; 829 saved_nextp_prop = msg->nextp; 830 for (xf_no = 0; xf_no < transform_cnt[i]; xf_no++) { 831 if (message_add_payload(msg, ISAKMP_PAYLOAD_TRANSFORM, 832 transform[i][xf_no], 833 transform_len[i][xf_no], update_nextp)) 834 goto bail_out; 835 update_nextp = 1; 836 transform[i][xf_no] = 0; 837 } 838 msg->nextp = saved_nextp_prop; 839 update_nextp = 1; 840 } 841 msg->nextp = saved_nextp_sa; 842 843 /* 844 * Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len. 845 */ 846 ie->sa_i_b = message_copy(msg, ISAKMP_GEN_SZ, &ie->sa_i_b_len); 847 if (!ie->sa_i_b) 848 goto bail_out; 849 850 /* 851 * Generate a nonce, and add it to the message. 852 * XXX I want a better way to specify the nonce's size. 853 */ 854 if (exchange_gen_nonce(msg, 16)) 855 return -1; 856 857 /* Generate optional KEY_EXCH payload. */ 858 if (group_desc > 0) { 859 ie->group = group_get(group_desc); 860 ie->g_x_len = dh_getlen(ie->group); 861 862 if (ipsec_gen_g_x(msg)) { 863 group_free(ie->group); 864 ie->group = 0; 865 return -1; 866 } 867 } 868 /* Generate optional client ID payloads. XXX Share with responder. */ 869 local_id = conf_get_str(exchange->name, "Local-ID"); 870 remote_id = conf_get_str(exchange->name, "Remote-ID"); 871 if (local_id && remote_id) { 872 id = ipsec_build_id(local_id, &sz); 873 if (!id) 874 return -1; 875 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 876 "initiator_send_HASH_SA_NONCE: IDic", id, sz)); 877 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) { 878 free(id); 879 return -1; 880 } 881 id = ipsec_build_id(remote_id, &sz); 882 if (!id) 883 return -1; 884 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 885 "initiator_send_HASH_SA_NONCE: IDrc", id, sz)); 886 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) { 887 free(id); 888 return -1; 889 } 890 } 891 /* XXX I do not judge these as errors, are they? */ 892 else if (local_id) 893 log_print("initiator_send_HASH_SA_NONCE: " 894 "Local-ID given without Remote-ID for \"%s\"", 895 exchange->name); 896 else if (remote_id) 897 /* 898 * This code supports the "road warrior" case, where the 899 * initiator doesn't have a fixed IP address, but wants to 900 * specify a particular remote network to talk to. -- Adrian 901 * Close <adrian@esec.com.au> 902 */ 903 { 904 log_print("initiator_send_HASH_SA_NONCE: " 905 "Remote-ID given without Local-ID for \"%s\"", 906 exchange->name); 907 908 /* 909 * If we're here, then we are the initiator, so use initiator 910 * address for local ID 911 */ 912 msg->transport->vtbl->get_src(msg->transport, &src); 913 sz = ISAKMP_ID_SZ + sockaddr_addrlen(src); 914 915 id = calloc(sz, sizeof(char)); 916 if (!id) { 917 log_error("initiator_send_HASH_SA_NONCE: " 918 "calloc (%lu, %lu) failed", (unsigned long)sz, 919 (unsigned long)sizeof(char)); 920 return -1; 921 } 922 switch (src->sa_family) { 923 case AF_INET6: 924 SET_ISAKMP_ID_TYPE(id, IPSEC_ID_IPV6_ADDR); 925 break; 926 case AF_INET: 927 SET_ISAKMP_ID_TYPE(id, IPSEC_ID_IPV4_ADDR); 928 break; 929 default: 930 log_error("initiator_send_HASH_SA_NONCE: " 931 "unknown sa_family %d", src->sa_family); 932 free(id); 933 return -1; 934 } 935 memcpy(id + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(src), 936 sockaddr_addrlen(src)); 937 938 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 939 "initiator_send_HASH_SA_NONCE: IDic", id, sz)); 940 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) { 941 free(id); 942 return -1; 943 } 944 /* Send supplied remote_id */ 945 id = ipsec_build_id(remote_id, &sz); 946 if (!id) 947 return -1; 948 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 949 "initiator_send_HASH_SA_NONCE: IDrc", id, sz)); 950 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) { 951 free(id); 952 return -1; 953 } 954 } 955 if (ipsec_fill_in_hash(msg)) 956 goto bail_out; 957 958 conf_free_list(suite_conf); 959 for (i = 0; i < prop_no; i++) { 960 free(transform[i]); 961 free(transform_len[i]); 962 } 963 free(proposal); 964 free(transform); 965 free(transforms_len); 966 free(transform_len); 967 free(transform_cnt); 968 return 0; 969 970 bail_out: 971 free(sa_buf); 972 if (proposal) { 973 for (i = 0; i < prop_no; i++) { 974 free(proposal[i]); 975 if (transform[i]) { 976 for (xf_no = 0; xf_no < transform_cnt[i]; 977 xf_no++) 978 free(transform[i][xf_no]); 979 free(transform[i]); 980 } 981 free(transform_len[i]); 982 } 983 free(proposal); 984 free(transforms_len); 985 free(transform); 986 free(transform_len); 987 free(transform_cnt); 988 } 989 if (xf_conf) 990 conf_free_list(xf_conf); 991 if (prot_conf) 992 conf_free_list(prot_conf); 993 conf_free_list(suite_conf); 994 return -1; 995 } 996 997 /* Figure out what transform the responder chose. */ 998 static int 999 initiator_recv_HASH_SA_NONCE(struct message *msg) 1000 { 1001 struct exchange *exchange = msg->exchange; 1002 struct ipsec_exch *ie = exchange->data; 1003 struct sa *sa; 1004 struct proto *proto, *next_proto; 1005 struct payload *sa_p = payload_first(msg, ISAKMP_PAYLOAD_SA); 1006 struct payload *xf, *idp; 1007 struct payload *hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH); 1008 struct payload *kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH); 1009 struct prf *prf; 1010 struct sa *isakmp_sa = msg->isakmp_sa; 1011 struct ipsec_sa *isa = isakmp_sa->data; 1012 struct hash *hash = hash_get(isa->hash); 1013 u_int8_t *rest; 1014 size_t rest_len; 1015 struct sockaddr *src, *dst; 1016 1017 /* Allocate the prf and start calculating our HASH(1). XXX Share? */ 1018 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: " 1019 "SKEYID_a", (u_int8_t *)isa->skeyid_a, isa->skeyid_len)); 1020 prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a, 1021 isa->skeyid_len); 1022 if (!prf) 1023 return -1; 1024 1025 prf->Init(prf->prfctx); 1026 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1027 "initiator_recv_HASH_SA_NONCE: message_id", 1028 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN)); 1029 prf->Update(prf->prfctx, exchange->message_id, 1030 ISAKMP_HDR_MESSAGE_ID_LEN); 1031 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: " 1032 "NONCE_I_b", exchange->nonce_i, exchange->nonce_i_len)); 1033 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len); 1034 rest = hashp->p + GET_ISAKMP_GEN_LENGTH(hashp->p); 1035 rest_len = (GET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base) 1036 - (rest - (u_int8_t *)msg->iov[0].iov_base)); 1037 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1038 "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)", rest, 1039 rest_len)); 1040 prf->Update(prf->prfctx, rest, rest_len); 1041 prf->Final(hash->digest, prf->prfctx); 1042 prf_free(prf); 1043 LOG_DBG_BUF((LOG_NEGOTIATION, 80, 1044 "initiator_recv_HASH_SA_NONCE: computed HASH(2)", hash->digest, 1045 hash->hashsize)); 1046 if (memcmp(hashp->p + ISAKMP_HASH_DATA_OFF, hash->digest, 1047 hash->hashsize) != 0) { 1048 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1, 1049 0); 1050 return -1; 1051 } 1052 /* Mark the HASH as handled. */ 1053 hashp->flags |= PL_MARK; 1054 1055 /* Mark message as authenticated. */ 1056 msg->flags |= MSG_AUTHENTICATED; 1057 1058 /* 1059 * As we are getting an answer on our transform offer, only one 1060 * transform should be given. 1061 * 1062 * XXX Currently we only support negotiating one SA per quick mode run. 1063 */ 1064 if (TAILQ_NEXT(sa_p, link)) { 1065 log_print("initiator_recv_HASH_SA_NONCE: " 1066 "multiple SA payloads in quick mode not supported yet"); 1067 return -1; 1068 } 1069 sa = TAILQ_FIRST(&exchange->sa_list); 1070 1071 /* This is here for the policy check */ 1072 if (kep) 1073 ie->pfs = 1; 1074 1075 /* Handle optional client ID payloads. */ 1076 idp = payload_first(msg, ISAKMP_PAYLOAD_ID); 1077 if (idp) { 1078 /* If IDci is there, IDcr must be too. */ 1079 if (!TAILQ_NEXT(idp, link)) { 1080 /* XXX Is this a good notify type? */ 1081 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1082 1, 0); 1083 return -1; 1084 } 1085 /* XXX We should really compare, not override. */ 1086 ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH(idp->p); 1087 ie->id_ci = malloc(ie->id_ci_sz); 1088 if (!ie->id_ci) { 1089 log_error("initiator_recv_HASH_SA_NONCE: " 1090 "malloc (%lu) failed", 1091 (unsigned long)ie->id_ci_sz); 1092 return -1; 1093 } 1094 memcpy(ie->id_ci, idp->p, ie->id_ci_sz); 1095 idp->flags |= PL_MARK; 1096 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1097 "initiator_recv_HASH_SA_NONCE: IDci", 1098 ie->id_ci + ISAKMP_GEN_SZ, ie->id_ci_sz - ISAKMP_GEN_SZ)); 1099 1100 idp = TAILQ_NEXT(idp, link); 1101 ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH(idp->p); 1102 ie->id_cr = malloc(ie->id_cr_sz); 1103 if (!ie->id_cr) { 1104 log_error("initiator_recv_HASH_SA_NONCE: " 1105 "malloc (%lu) failed", 1106 (unsigned long)ie->id_cr_sz); 1107 return -1; 1108 } 1109 memcpy(ie->id_cr, idp->p, ie->id_cr_sz); 1110 idp->flags |= PL_MARK; 1111 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1112 "initiator_recv_HASH_SA_NONCE: IDcr", 1113 ie->id_cr + ISAKMP_GEN_SZ, ie->id_cr_sz - ISAKMP_GEN_SZ)); 1114 } else { 1115 /* 1116 * If client identifiers are not present in the exchange, 1117 * we fake them. RFC 2409 states: 1118 * The identities of the SAs negotiated in Quick Mode are 1119 * implicitly assumed to be the IP addresses of the ISAKMP 1120 * peers, without any constraints on the protocol or port 1121 * numbers allowed, unless client identifiers are specified 1122 * in Quick Mode. 1123 * 1124 * -- Michael Paddon (mwp@aba.net.au) 1125 */ 1126 1127 ie->flags = IPSEC_EXCH_FLAG_NO_ID; 1128 1129 /* Get initiator and responder addresses. */ 1130 msg->transport->vtbl->get_src(msg->transport, &src); 1131 msg->transport->vtbl->get_dst(msg->transport, &dst); 1132 ie->id_ci_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen(src); 1133 ie->id_cr_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen(dst); 1134 ie->id_ci = calloc(ie->id_ci_sz, sizeof(char)); 1135 ie->id_cr = calloc(ie->id_cr_sz, sizeof(char)); 1136 1137 if (!ie->id_ci || !ie->id_cr) { 1138 log_error("initiator_recv_HASH_SA_NONCE: " 1139 "calloc (%lu, %lu) failed", 1140 (unsigned long)ie->id_cr_sz, 1141 (unsigned long)sizeof(char)); 1142 free(ie->id_ci); 1143 ie->id_ci = 0; 1144 free(ie->id_cr); 1145 ie->id_cr = 0; 1146 return -1; 1147 } 1148 if (src->sa_family != dst->sa_family) { 1149 log_error("initiator_recv_HASH_SA_NONCE: " 1150 "sa_family mismatch"); 1151 free(ie->id_ci); 1152 ie->id_ci = 0; 1153 free(ie->id_cr); 1154 ie->id_cr = 0; 1155 return -1; 1156 } 1157 switch (src->sa_family) { 1158 case AF_INET: 1159 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV4_ADDR); 1160 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV4_ADDR); 1161 break; 1162 1163 case AF_INET6: 1164 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV6_ADDR); 1165 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV6_ADDR); 1166 break; 1167 1168 default: 1169 log_error("initiator_recv_HASH_SA_NONCE: " 1170 "unknown sa_family %d", src->sa_family); 1171 free(ie->id_ci); 1172 ie->id_ci = 0; 1173 free(ie->id_cr); 1174 ie->id_cr = 0; 1175 return -1; 1176 } 1177 memcpy(ie->id_ci + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(src), 1178 sockaddr_addrlen(src)); 1179 memcpy(ie->id_cr + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(dst), 1180 sockaddr_addrlen(dst)); 1181 } 1182 1183 /* Build the protection suite in our SA. */ 1184 TAILQ_FOREACH(xf, &msg->payload[ISAKMP_PAYLOAD_TRANSFORM], link) { 1185 /* 1186 * XXX We could check that the proposal each transform 1187 * belongs to is unique. 1188 */ 1189 1190 if (sa_add_transform(sa, xf, exchange->initiator, &proto)) 1191 return -1; 1192 1193 /* XXX Check that the chosen transform matches an offer. */ 1194 1195 ipsec_decode_transform(msg, sa, proto, xf->p); 1196 } 1197 1198 /* Now remove offers that we don't need anymore. */ 1199 for (proto = TAILQ_FIRST(&sa->protos); proto; proto = next_proto) { 1200 next_proto = TAILQ_NEXT(proto, link); 1201 if (!proto->chosen) 1202 proto_free(proto); 1203 } 1204 1205 if (!check_policy(exchange, sa, msg->isakmp_sa)) { 1206 message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0); 1207 log_print("initiator_recv_HASH_SA_NONCE: policy check failed"); 1208 return -1; 1209 } 1210 1211 /* Mark the SA as handled. */ 1212 sa_p->flags |= PL_MARK; 1213 1214 isa = sa->data; 1215 if ((isa->group_desc && 1216 (!ie->group || ie->group->id != isa->group_desc)) || 1217 (!isa->group_desc && ie->group)) { 1218 log_print("initiator_recv_HASH_SA_NONCE: disagreement on PFS"); 1219 return -1; 1220 } 1221 /* Copy out the initiator's nonce. */ 1222 if (exchange_save_nonce(msg)) 1223 return -1; 1224 1225 /* Handle the optional KEY_EXCH payload. */ 1226 if (kep && ipsec_save_g_x(msg)) 1227 return -1; 1228 1229 return 0; 1230 } 1231 1232 static int 1233 initiator_send_HASH(struct message *msg) 1234 { 1235 struct exchange *exchange = msg->exchange; 1236 struct ipsec_exch *ie = exchange->data; 1237 struct sa *isakmp_sa = msg->isakmp_sa; 1238 struct ipsec_sa *isa = isakmp_sa->data; 1239 struct prf *prf; 1240 u_int8_t *buf; 1241 struct hash *hash = hash_get(isa->hash); 1242 1243 /* 1244 * We want a HASH payload to start with. XXX Share with 1245 * ike_main_mode.c? 1246 */ 1247 buf = malloc(ISAKMP_HASH_SZ + hash->hashsize); 1248 if (!buf) { 1249 log_error("initiator_send_HASH: malloc (%lu) failed", 1250 ISAKMP_HASH_SZ + (unsigned long)hash->hashsize); 1251 return -1; 1252 } 1253 if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH, buf, 1254 ISAKMP_HASH_SZ + hash->hashsize, 1)) { 1255 free(buf); 1256 return -1; 1257 } 1258 /* Allocate the prf and start calculating our HASH(3). XXX Share? */ 1259 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: SKEYID_a", 1260 isa->skeyid_a, isa->skeyid_len)); 1261 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a, 1262 isa->skeyid_len); 1263 if (!prf) 1264 return -1; 1265 prf->Init(prf->prfctx); 1266 prf->Update(prf->prfctx, (unsigned char *)"\0", 1); 1267 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: message_id", 1268 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN)); 1269 prf->Update(prf->prfctx, exchange->message_id, 1270 ISAKMP_HDR_MESSAGE_ID_LEN); 1271 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_I_b", 1272 exchange->nonce_i, exchange->nonce_i_len)); 1273 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len); 1274 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_R_b", 1275 exchange->nonce_r, exchange->nonce_r_len)); 1276 prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len); 1277 prf->Final(buf + ISAKMP_GEN_SZ, prf->prfctx); 1278 prf_free(prf); 1279 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: HASH(3)", 1280 buf + ISAKMP_GEN_SZ, hash->hashsize)); 1281 1282 if (ie->group) 1283 message_register_post_send(msg, gen_g_xy); 1284 1285 message_register_post_send(msg, post_quick_mode); 1286 1287 return 0; 1288 } 1289 1290 static void 1291 post_quick_mode(struct message *msg) 1292 { 1293 struct sa *isakmp_sa = msg->isakmp_sa; 1294 struct ipsec_sa *isa = isakmp_sa->data; 1295 struct exchange *exchange = msg->exchange; 1296 struct ipsec_exch *ie = exchange->data; 1297 struct prf *prf; 1298 struct sa *sa; 1299 struct proto *proto; 1300 struct ipsec_proto *iproto; 1301 u_int8_t *keymat; 1302 int i; 1303 1304 /* 1305 * Loop over all SA negotiations and do both an in- and an outgoing SA 1306 * per protocol. 1307 */ 1308 for (sa = TAILQ_FIRST(&exchange->sa_list); sa; 1309 sa = TAILQ_NEXT(sa, next)) { 1310 for (proto = TAILQ_FIRST(&sa->protos); proto; 1311 proto = TAILQ_NEXT(proto, link)) { 1312 if (proto->proto == IPSEC_PROTO_IPCOMP) 1313 continue; 1314 1315 iproto = proto->data; 1316 1317 /* 1318 * There are two SAs for each SA negotiation, 1319 * incoming and outgoing. 1320 */ 1321 for (i = 0; i < 2; i++) { 1322 prf = prf_alloc(isa->prf_type, isa->hash, 1323 isa->skeyid_d, isa->skeyid_len); 1324 if (!prf) { 1325 /* XXX What to do? */ 1326 continue; 1327 } 1328 ie->keymat_len = ipsec_keymat_length(proto); 1329 1330 /* 1331 * We need to roundup the length of the key 1332 * material buffer to a multiple of the PRF's 1333 * blocksize as it is generated in chunks of 1334 * that blocksize. 1335 */ 1336 iproto->keymat[i] 1337 = malloc(((ie->keymat_len + prf->blocksize - 1) 1338 / prf->blocksize) * prf->blocksize); 1339 if (!iproto->keymat[i]) { 1340 log_error("post_quick_mode: " 1341 "malloc (%lu) failed", 1342 (((unsigned long)ie->keymat_len + 1343 prf->blocksize - 1) / prf->blocksize) * 1344 prf->blocksize); 1345 /* XXX What more to do? */ 1346 free(prf); 1347 continue; 1348 } 1349 for (keymat = iproto->keymat[i]; 1350 keymat < iproto->keymat[i] + ie->keymat_len; 1351 keymat += prf->blocksize) { 1352 prf->Init(prf->prfctx); 1353 1354 if (keymat != iproto->keymat[i]) { 1355 /* 1356 * Hash in last round's 1357 * KEYMAT. 1358 */ 1359 LOG_DBG_BUF((LOG_NEGOTIATION, 1360 90, "post_quick_mode: " 1361 "last KEYMAT", 1362 keymat - prf->blocksize, 1363 prf->blocksize)); 1364 prf->Update(prf->prfctx, 1365 keymat - prf->blocksize, 1366 prf->blocksize); 1367 } 1368 /* If PFS is used hash in g^xy. */ 1369 if (ie->g_xy) { 1370 LOG_DBG_BUF((LOG_NEGOTIATION, 1371 90, "post_quick_mode: " 1372 "g^xy", ie->g_xy, 1373 ie->g_x_len)); 1374 prf->Update(prf->prfctx, 1375 ie->g_xy, ie->g_x_len); 1376 } 1377 LOG_DBG((LOG_NEGOTIATION, 90, 1378 "post_quick_mode: " 1379 "suite %d proto %d", proto->no, 1380 proto->proto)); 1381 prf->Update(prf->prfctx, &proto->proto, 1382 1); 1383 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1384 "post_quick_mode: SPI", 1385 proto->spi[i], proto->spi_sz[i])); 1386 prf->Update(prf->prfctx, 1387 proto->spi[i], proto->spi_sz[i]); 1388 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1389 "post_quick_mode: Ni_b", 1390 exchange->nonce_i, 1391 exchange->nonce_i_len)); 1392 prf->Update(prf->prfctx, 1393 exchange->nonce_i, 1394 exchange->nonce_i_len); 1395 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1396 "post_quick_mode: Nr_b", 1397 exchange->nonce_r, 1398 exchange->nonce_r_len)); 1399 prf->Update(prf->prfctx, 1400 exchange->nonce_r, 1401 exchange->nonce_r_len); 1402 prf->Final(keymat, prf->prfctx); 1403 } 1404 prf_free(prf); 1405 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1406 "post_quick_mode: KEYMAT", 1407 iproto->keymat[i], ie->keymat_len)); 1408 } 1409 } 1410 } 1411 1412 log_verbose("isakmpd: quick mode done: %s", 1413 !msg->isakmp_sa || !msg->isakmp_sa->transport ? "<no transport>" 1414 : msg->isakmp_sa->transport->vtbl->decode_ids 1415 (msg->isakmp_sa->transport)); 1416 } 1417 1418 /* 1419 * Accept a set of transforms offered by the initiator and chose one we can 1420 * handle. 1421 * XXX Describe in more detail. 1422 */ 1423 static int 1424 responder_recv_HASH_SA_NONCE(struct message *msg) 1425 { 1426 struct payload *hashp, *kep, *idp; 1427 struct sa *sa; 1428 struct sa *isakmp_sa = msg->isakmp_sa; 1429 struct ipsec_sa *isa = isakmp_sa->data; 1430 struct exchange *exchange = msg->exchange; 1431 struct ipsec_exch *ie = exchange->data; 1432 struct prf *prf; 1433 u_int8_t *hash, *my_hash = 0; 1434 size_t hash_len; 1435 u_int8_t *pkt = msg->iov[0].iov_base; 1436 u_int8_t group_desc = 0; 1437 int retval = -1; 1438 struct proto *proto; 1439 struct sockaddr *src, *dst; 1440 char *name; 1441 1442 hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH); 1443 hash = hashp->p; 1444 hashp->flags |= PL_MARK; 1445 1446 /* The HASH payload should be the first one. */ 1447 if (hash != pkt + ISAKMP_HDR_SZ) { 1448 /* XXX Is there a better notification type? */ 1449 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1, 0); 1450 goto cleanup; 1451 } 1452 hash_len = GET_ISAKMP_GEN_LENGTH(hash); 1453 my_hash = malloc(hash_len - ISAKMP_GEN_SZ); 1454 if (!my_hash) { 1455 log_error("responder_recv_HASH_SA_NONCE: malloc (%lu) failed", 1456 (unsigned long)hash_len - ISAKMP_GEN_SZ); 1457 goto cleanup; 1458 } 1459 /* 1460 * Check the payload's integrity. 1461 * XXX Share with ipsec_fill_in_hash? 1462 */ 1463 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: " 1464 "SKEYID_a", isa->skeyid_a, isa->skeyid_len)); 1465 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a, 1466 isa->skeyid_len); 1467 if (!prf) 1468 goto cleanup; 1469 prf->Init(prf->prfctx); 1470 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1471 "responder_recv_HASH_SA_NONCE: message_id", 1472 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN)); 1473 prf->Update(prf->prfctx, exchange->message_id, 1474 ISAKMP_HDR_MESSAGE_ID_LEN); 1475 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1476 "responder_recv_HASH_SA_NONCE: message after HASH", 1477 hash + hash_len, 1478 msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len)); 1479 prf->Update(prf->prfctx, hash + hash_len, 1480 msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len); 1481 prf->Final(my_hash, prf->prfctx); 1482 prf_free(prf); 1483 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1484 "responder_recv_HASH_SA_NONCE: computed HASH(1)", my_hash, 1485 hash_len - ISAKMP_GEN_SZ)); 1486 if (memcmp(hash + ISAKMP_GEN_SZ, my_hash, hash_len - ISAKMP_GEN_SZ) 1487 != 0) { 1488 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1489 1, 0); 1490 goto cleanup; 1491 } 1492 free(my_hash); 1493 my_hash = 0; 1494 1495 /* Mark message as authenticated. */ 1496 msg->flags |= MSG_AUTHENTICATED; 1497 1498 kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH); 1499 if (kep) 1500 ie->pfs = 1; 1501 1502 /* Handle optional client ID payloads. */ 1503 idp = payload_first(msg, ISAKMP_PAYLOAD_ID); 1504 if (idp) { 1505 /* If IDci is there, IDcr must be too. */ 1506 if (!TAILQ_NEXT(idp, link)) { 1507 /* XXX Is this a good notify type? */ 1508 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED, 0, 1509 1, 0); 1510 goto cleanup; 1511 } 1512 ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH(idp->p); 1513 ie->id_ci = malloc(ie->id_ci_sz); 1514 if (!ie->id_ci) { 1515 log_error("responder_recv_HASH_SA_NONCE: " 1516 "malloc (%lu) failed", 1517 (unsigned long)ie->id_ci_sz); 1518 goto cleanup; 1519 } 1520 memcpy(ie->id_ci, idp->p, ie->id_ci_sz); 1521 idp->flags |= PL_MARK; 1522 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1523 "responder_recv_HASH_SA_NONCE: IDci", 1524 ie->id_ci + ISAKMP_GEN_SZ, ie->id_ci_sz - ISAKMP_GEN_SZ)); 1525 1526 idp = TAILQ_NEXT(idp, link); 1527 ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH(idp->p); 1528 ie->id_cr = malloc(ie->id_cr_sz); 1529 if (!ie->id_cr) { 1530 log_error("responder_recv_HASH_SA_NONCE: " 1531 "malloc (%lu) failed", 1532 (unsigned long)ie->id_cr_sz); 1533 goto cleanup; 1534 } 1535 memcpy(ie->id_cr, idp->p, ie->id_cr_sz); 1536 idp->flags |= PL_MARK; 1537 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1538 "responder_recv_HASH_SA_NONCE: IDcr", 1539 ie->id_cr + ISAKMP_GEN_SZ, ie->id_cr_sz - ISAKMP_GEN_SZ)); 1540 } else { 1541 /* 1542 * If client identifiers are not present in the exchange, 1543 * we fake them. RFC 2409 states: 1544 * The identities of the SAs negotiated in Quick Mode are 1545 * implicitly assumed to be the IP addresses of the ISAKMP 1546 * peers, without any constraints on the protocol or port 1547 * numbers allowed, unless client identifiers are specified 1548 * in Quick Mode. 1549 * 1550 * -- Michael Paddon (mwp@aba.net.au) 1551 */ 1552 1553 ie->flags = IPSEC_EXCH_FLAG_NO_ID; 1554 1555 /* Get initiator and responder addresses. */ 1556 msg->transport->vtbl->get_src(msg->transport, &src); 1557 msg->transport->vtbl->get_dst(msg->transport, &dst); 1558 ie->id_ci_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen(src); 1559 ie->id_cr_sz = ISAKMP_ID_DATA_OFF + sockaddr_addrlen(dst); 1560 ie->id_ci = calloc(ie->id_ci_sz, sizeof(char)); 1561 ie->id_cr = calloc(ie->id_cr_sz, sizeof(char)); 1562 1563 if (!ie->id_ci || !ie->id_cr) { 1564 log_error("responder_recv_HASH_SA_NONCE: " 1565 "calloc (%lu, %lu) failed", 1566 (unsigned long)ie->id_ci_sz, 1567 (unsigned long)sizeof(char)); 1568 goto cleanup; 1569 } 1570 if (src->sa_family != dst->sa_family) { 1571 log_error("initiator_recv_HASH_SA_NONCE: " 1572 "sa_family mismatch"); 1573 goto cleanup; 1574 } 1575 switch (src->sa_family) { 1576 case AF_INET: 1577 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV4_ADDR); 1578 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV4_ADDR); 1579 break; 1580 1581 case AF_INET6: 1582 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV6_ADDR); 1583 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV6_ADDR); 1584 break; 1585 1586 default: 1587 log_error("initiator_recv_HASH_SA_NONCE: " 1588 "unknown sa_family %d", src->sa_family); 1589 goto cleanup; 1590 } 1591 1592 memcpy(ie->id_cr + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(src), 1593 sockaddr_addrlen(src)); 1594 memcpy(ie->id_ci + ISAKMP_ID_DATA_OFF, sockaddr_addrdata(dst), 1595 sockaddr_addrlen(dst)); 1596 } 1597 1598 if (message_negotiate_sa(msg, check_policy)) 1599 goto cleanup; 1600 1601 for (sa = TAILQ_FIRST(&exchange->sa_list); sa; 1602 sa = TAILQ_NEXT(sa, next)) { 1603 for (proto = TAILQ_FIRST(&sa->protos); proto; 1604 proto = TAILQ_NEXT(proto, link)) { 1605 /* 1606 * XXX we need to have some attributes per proto, not 1607 * all per SA. 1608 */ 1609 ipsec_decode_transform(msg, sa, proto, 1610 proto->chosen->p); 1611 if (proto->proto == IPSEC_PROTO_IPSEC_AH && 1612 !((struct ipsec_proto *)proto->data)->auth) { 1613 log_print("responder_recv_HASH_SA_NONCE: " 1614 "AH proposed without an algorithm " 1615 "attribute"); 1616 message_drop(msg, 1617 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0); 1618 goto next_sa; 1619 } 1620 } 1621 1622 isa = sa->data; 1623 1624 /* 1625 * The group description is mandatory if we got a KEY_EXCH 1626 * payload. 1627 */ 1628 if (kep) { 1629 if (!isa->group_desc) { 1630 log_print("responder_recv_HASH_SA_NONCE: " 1631 "KEY_EXCH payload without a group " 1632 "desc. attribute"); 1633 message_drop(msg, 1634 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0); 1635 continue; 1636 } 1637 /* Also, all SAs must have equal groups. */ 1638 if (!group_desc) 1639 group_desc = isa->group_desc; 1640 else if (group_desc != isa->group_desc) { 1641 log_print("responder_recv_HASH_SA_NONCE: " 1642 "differing group descriptions in one QM"); 1643 message_drop(msg, 1644 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN, 0, 1, 0); 1645 continue; 1646 } 1647 } 1648 /* At least one SA was accepted. */ 1649 retval = 0; 1650 1651 next_sa: 1652 ; /* XXX gcc3 wants this. */ 1653 } 1654 1655 if (kep) { 1656 ie->group = group_get(group_desc); 1657 if (!ie->group) { 1658 /* 1659 * XXX If the error was due to an out-of-range group 1660 * description we should notify our peer, but this 1661 * should probably be done by the attribute 1662 * validation. Is it? 1663 */ 1664 goto cleanup; 1665 } 1666 } 1667 /* Copy out the initiator's nonce. */ 1668 if (exchange_save_nonce(msg)) 1669 goto cleanup; 1670 1671 /* Handle the optional KEY_EXCH payload. */ 1672 if (kep && ipsec_save_g_x(msg)) 1673 goto cleanup; 1674 1675 /* 1676 * Try to find and set the connection name on the exchange. 1677 */ 1678 1679 /* 1680 * Check for accepted identities as well as lookup the connection 1681 * name and set it on the exchange. 1682 * 1683 * When not using policies make sure the peer proposes sane IDs. 1684 * Otherwise this is done by KeyNote. 1685 */ 1686 name = connection_passive_lookup_by_ids(ie->id_ci, ie->id_cr); 1687 if (name) { 1688 exchange->name = strdup(name); 1689 if (!exchange->name) { 1690 log_error("responder_recv_HASH_SA_NONCE: " 1691 "strdup (\"%s\") failed", name); 1692 goto cleanup; 1693 } 1694 } else if ( 1695 ignore_policy || 1696 strncmp("yes", conf_get_str("General", "Use-Keynote"), 3)) { 1697 log_print("responder_recv_HASH_SA_NONCE: peer proposed " 1698 "invalid phase 2 IDs: %s", 1699 (exchange->doi->decode_ids("initiator id %s, responder" 1700 " id %s", ie->id_ci, ie->id_ci_sz, ie->id_cr, 1701 ie->id_cr_sz, 1))); 1702 message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION, 0, 1, 1703 0); 1704 goto cleanup; 1705 } 1706 1707 return retval; 1708 1709 cleanup: 1710 /* Remove all potential protocols that have been added to the SAs. */ 1711 for (sa = TAILQ_FIRST(&exchange->sa_list); sa; 1712 sa = TAILQ_NEXT(sa, next)) 1713 while ((proto = TAILQ_FIRST(&sa->protos)) != 0) 1714 proto_free(proto); 1715 free(my_hash); 1716 free(ie->id_ci); 1717 ie->id_ci = 0; 1718 free(ie->id_cr); 1719 ie->id_cr = 0; 1720 return -1; 1721 } 1722 1723 /* Reply with the transform we chose. */ 1724 static int 1725 responder_send_HASH_SA_NONCE(struct message *msg) 1726 { 1727 struct exchange *exchange = msg->exchange; 1728 struct ipsec_exch *ie = exchange->data; 1729 struct sa *isakmp_sa = msg->isakmp_sa; 1730 struct ipsec_sa *isa = isakmp_sa->data; 1731 struct prf *prf; 1732 struct hash *hash = hash_get(isa->hash); 1733 size_t nonce_sz = exchange->nonce_i_len; 1734 u_int8_t *buf; 1735 int initiator = exchange->initiator; 1736 char header[80]; 1737 u_int32_t i; 1738 u_int8_t *id; 1739 size_t sz; 1740 1741 /* 1742 * We want a HASH payload to start with. XXX Share with 1743 * ike_main_mode.c? 1744 */ 1745 buf = malloc(ISAKMP_HASH_SZ + hash->hashsize); 1746 if (!buf) { 1747 log_error("responder_send_HASH_SA_NONCE: malloc (%lu) failed", 1748 ISAKMP_HASH_SZ + (unsigned long)hash->hashsize); 1749 return -1; 1750 } 1751 if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH, buf, 1752 ISAKMP_HASH_SZ + hash->hashsize, 1)) { 1753 free(buf); 1754 return -1; 1755 } 1756 /* Add the SA payload(s) with the transform(s) that was/were chosen. */ 1757 if (message_add_sa_payload(msg)) 1758 return -1; 1759 1760 /* Generate a nonce, and add it to the message. */ 1761 if (exchange_gen_nonce(msg, nonce_sz)) 1762 return -1; 1763 1764 /* Generate optional KEY_EXCH payload. This is known as PFS. */ 1765 if (ie->group && ipsec_gen_g_x(msg)) 1766 return -1; 1767 1768 /* 1769 * If the initiator client ID's were acceptable, just mirror them 1770 * back. 1771 */ 1772 if (!(ie->flags & IPSEC_EXCH_FLAG_NO_ID)) { 1773 sz = ie->id_ci_sz; 1774 id = malloc(sz); 1775 if (!id) { 1776 log_error("responder_send_HASH_SA_NONCE: " 1777 "malloc (%lu) failed", (unsigned long)sz); 1778 return -1; 1779 } 1780 memcpy(id, ie->id_ci, sz); 1781 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1782 "responder_send_HASH_SA_NONCE: IDic", id, sz)); 1783 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) { 1784 free(id); 1785 return -1; 1786 } 1787 sz = ie->id_cr_sz; 1788 id = malloc(sz); 1789 if (!id) { 1790 log_error("responder_send_HASH_SA_NONCE: " 1791 "malloc (%lu) failed", (unsigned long)sz); 1792 return -1; 1793 } 1794 memcpy(id, ie->id_cr, sz); 1795 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1796 "responder_send_HASH_SA_NONCE: IDrc", id, sz)); 1797 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID, id, sz, 1)) { 1798 free(id); 1799 return -1; 1800 } 1801 } 1802 /* Allocate the prf and start calculating our HASH(2). XXX Share? */ 1803 LOG_DBG((LOG_NEGOTIATION, 90, "responder_recv_HASH: " 1804 "isakmp_sa %p isa %p", isakmp_sa, isa)); 1805 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: " 1806 "SKEYID_a", isa->skeyid_a, isa->skeyid_len)); 1807 prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a, 1808 isa->skeyid_len); 1809 if (!prf) 1810 return -1; 1811 prf->Init(prf->prfctx); 1812 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1813 "responder_send_HASH_SA_NONCE: message_id", 1814 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN)); 1815 prf->Update(prf->prfctx, exchange->message_id, 1816 ISAKMP_HDR_MESSAGE_ID_LEN); 1817 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: " 1818 "NONCE_I_b", exchange->nonce_i, exchange->nonce_i_len)); 1819 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len); 1820 1821 /* Loop over all payloads after HASH(2). */ 1822 for (i = 2; i < msg->iovlen; i++) { 1823 /* XXX Misleading payload type printouts. */ 1824 snprintf(header, sizeof header, 1825 "responder_send_HASH_SA_NONCE: payload %d after HASH(2)", 1826 i - 1); 1827 LOG_DBG_BUF((LOG_NEGOTIATION, 90, header, msg->iov[i].iov_base, 1828 msg->iov[i].iov_len)); 1829 prf->Update(prf->prfctx, msg->iov[i].iov_base, 1830 msg->iov[i].iov_len); 1831 } 1832 prf->Final(buf + ISAKMP_HASH_DATA_OFF, prf->prfctx); 1833 prf_free(prf); 1834 snprintf(header, sizeof header, "responder_send_HASH_SA_NONCE: " 1835 "HASH_%c", initiator ? 'I' : 'R'); 1836 LOG_DBG_BUF((LOG_NEGOTIATION, 80, header, buf + ISAKMP_HASH_DATA_OFF, 1837 hash->hashsize)); 1838 1839 if (ie->group) 1840 message_register_post_send(msg, gen_g_xy); 1841 1842 return 0; 1843 } 1844 1845 static void 1846 gen_g_xy(struct message *msg) 1847 { 1848 struct exchange *exchange = msg->exchange; 1849 struct ipsec_exch *ie = exchange->data; 1850 1851 /* Compute Diffie-Hellman shared value. */ 1852 ie->g_xy = malloc(ie->g_x_len); 1853 if (!ie->g_xy) { 1854 log_error("gen_g_xy: malloc (%lu) failed", 1855 (unsigned long)ie->g_x_len); 1856 return; 1857 } 1858 if (dh_create_shared(ie->group, ie->g_xy, 1859 exchange->initiator ? ie->g_xr : ie->g_xi)) { 1860 log_print("gen_g_xy: dh_create_shared failed"); 1861 return; 1862 } 1863 LOG_DBG_BUF((LOG_NEGOTIATION, 80, "gen_g_xy: g^xy", ie->g_xy, 1864 ie->g_x_len)); 1865 } 1866 1867 static int 1868 responder_recv_HASH(struct message *msg) 1869 { 1870 struct exchange *exchange = msg->exchange; 1871 struct sa *isakmp_sa = msg->isakmp_sa; 1872 struct ipsec_sa *isa = isakmp_sa->data; 1873 struct prf *prf; 1874 u_int8_t *hash, *my_hash = 0; 1875 size_t hash_len; 1876 struct payload *hashp; 1877 1878 /* Find HASH(3) and create our own hash, just as big. */ 1879 hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH); 1880 hash = hashp->p; 1881 hashp->flags |= PL_MARK; 1882 hash_len = GET_ISAKMP_GEN_LENGTH(hash); 1883 my_hash = malloc(hash_len - ISAKMP_GEN_SZ); 1884 if (!my_hash) { 1885 log_error("responder_recv_HASH: malloc (%lu) failed", 1886 (unsigned long)hash_len - ISAKMP_GEN_SZ); 1887 goto cleanup; 1888 } 1889 /* Allocate the prf and start calculating our HASH(3). XXX Share? */ 1890 LOG_DBG((LOG_NEGOTIATION, 90, "responder_recv_HASH: " 1891 "isakmp_sa %p isa %p", isakmp_sa, isa)); 1892 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: SKEYID_a", 1893 isa->skeyid_a, isa->skeyid_len)); 1894 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a, 1895 isa->skeyid_len); 1896 if (!prf) 1897 goto cleanup; 1898 prf->Init(prf->prfctx); 1899 prf->Update(prf->prfctx, (unsigned char *)"\0", 1); 1900 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: message_id", 1901 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN)); 1902 prf->Update(prf->prfctx, exchange->message_id, 1903 ISAKMP_HDR_MESSAGE_ID_LEN); 1904 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_I_b", 1905 exchange->nonce_i, exchange->nonce_i_len)); 1906 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len); 1907 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_R_b", 1908 exchange->nonce_r, exchange->nonce_r_len)); 1909 prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len); 1910 prf->Final(my_hash, prf->prfctx); 1911 prf_free(prf); 1912 LOG_DBG_BUF((LOG_NEGOTIATION, 90, 1913 "responder_recv_HASH: computed HASH(3)", my_hash, 1914 hash_len - ISAKMP_GEN_SZ)); 1915 if (memcmp(hash + ISAKMP_GEN_SZ, my_hash, hash_len - ISAKMP_GEN_SZ) 1916 != 0) { 1917 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION, 0, 1918 1, 0); 1919 goto cleanup; 1920 } 1921 free(my_hash); 1922 1923 /* Mark message as authenticated. */ 1924 msg->flags |= MSG_AUTHENTICATED; 1925 1926 post_quick_mode(msg); 1927 1928 return 0; 1929 1930 cleanup: 1931 free(my_hash); 1932 return -1; 1933 } 1934