Bug Summary

File:src/sbin/isakmpd/ike_quick_mode.c
Warning:line 1195, column 15
Result of 'calloc' is converted to a pointer of type 'u_int8_t', which is incompatible with sizeof operand type 'char'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ike_quick_mode.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/sbin/isakmpd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/sbin/isakmpd -I . -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/isakmpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/sbin/isakmpd/ike_quick_mode.c
1/* $OpenBSD: ike_quick_mode.c,v 1.114 2018/01/15 09:54:48 mpi 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 "message.h"
52#include "policy.h"
53#include "prf.h"
54#include "sa.h"
55#include "transport.h"
56#include "util.h"
57#include "key.h"
58#include "x509.h"
59
60static void gen_g_xy(struct message *);
61static int initiator_send_HASH_SA_NONCE(struct message *);
62static int initiator_recv_HASH_SA_NONCE(struct message *);
63static int initiator_send_HASH(struct message *);
64static void post_quick_mode(struct message *);
65static int responder_recv_HASH_SA_NONCE(struct message *);
66static int responder_send_HASH_SA_NONCE(struct message *);
67static int responder_recv_HASH(struct message *);
68
69static int check_policy(struct exchange *, struct sa *, struct sa *);
70
71int (*ike_quick_mode_initiator[])(struct message *) = {
72 initiator_send_HASH_SA_NONCE,
73 initiator_recv_HASH_SA_NONCE,
74 initiator_send_HASH
75};
76
77int (*ike_quick_mode_responder[])(struct message *) = {
78 responder_recv_HASH_SA_NONCE,
79 responder_send_HASH_SA_NONCE,
80 responder_recv_HASH
81};
82
83/* How many return values will policy handle -- true/false for now */
84#define RETVALUES_NUM2 2
85
86/*
87 * Given an exchange and our policy, check whether the SA and IDs are
88 * acceptable.
89 */
90static int
91check_policy(struct exchange *exchange, struct sa *sa, struct sa *isakmp_sa)
92{
93 char *return_values[RETVALUES_NUM2];
94 char **principal = 0;
95 int i, len, result = 0, nprinc = 0;
96 int *x509_ids = 0, *keynote_ids = 0;
97 unsigned char hashbuf[20]; /* Set to the largest digest result */
98 struct keynote_deckey dc;
99 X509_NAME *subject;
100
101 /* Do we want to use keynote policies? */
102 if (ignore_policy ||
103 strncmp("yes", conf_get_str("General", "Use-Keynote"), 3))
104 return 1;
105
106 /* Initialize if necessary -- e.g., if pre-shared key auth was used */
107 if (isakmp_sa->policy_id < 0) {
108 if ((isakmp_sa->policy_id = kn_init()) == -1) {
109 log_print("check_policy: "
110 "failed to initialize policy session");
111 return 0;
112 }
113 }
114 /* Add the callback that will handle attributes. */
115 if (kn_add_action(isakmp_sa->policy_id, ".*", (char *)policy_callback,
116 ENVIRONMENT_FLAG_FUNC0x0001 | ENVIRONMENT_FLAG_REGEX0x0002) == -1) {
117 log_print("check_policy: "
118 "kn_add_action (%d, \".*\", %p, FUNC | REGEX) failed",
119 isakmp_sa->policy_id, policy_callback);
120 kn_close(isakmp_sa->policy_id);
121 isakmp_sa->policy_id = -1;
122 return 0;
123 }
124 if (policy_asserts_num) {
125 keynote_ids = calloc(policy_asserts_num, sizeof *keynote_ids);
126 if (!keynote_ids) {
127 log_error("check_policy: calloc (%d, %lu) failed",
128 policy_asserts_num,
129 (unsigned long)sizeof *keynote_ids);
130 kn_close(isakmp_sa->policy_id);
131 isakmp_sa->policy_id = -1;
132 return 0;
133 }
134 }
135 /* Add the policy assertions */
136 for (i = 0; i < policy_asserts_num; i++)
137 keynote_ids[i] = kn_add_assertion(isakmp_sa->policy_id,
138 policy_asserts[i],
139 strlen(policy_asserts[i]), ASSERT_FLAG_LOCAL0x0001);
140
141 /* Initialize -- we'll let the callback do all the work. */
142 policy_exchange = exchange;
143 policy_sa = sa;
144 policy_isakmp_sa = isakmp_sa;
145
146 /* Set the return values; true/false for now at least. */
147 return_values[0] = "false"; /* Order of values in array is
148 * important. */
149 return_values[1] = "true";
150
151 /* Create a principal (authorizer) for the SA/ID request. */
152 switch (isakmp_sa->recv_certtype) {
153 case ISAKMP_CERTENC_NONE0:
154 /*
155 * For shared keys, just duplicate the passphrase with the
156 * appropriate prefix tag.
157 */
158 nprinc = 3;
159 principal = calloc(nprinc, sizeof *principal);
160 if (!principal) {
161 log_error("check_policy: calloc (%d, %lu) failed",
162 nprinc, (unsigned long)sizeof *principal);
163 goto policydone;
164 }
165 len = strlen(isakmp_sa->recv_key) + sizeof "passphrase:";
166 principal[0] = calloc(len, sizeof(char));
167 if (!principal[0]) {
168 log_error("check_policy: calloc (%d, %lu) failed", len,
169 (unsigned long)sizeof(char));
170 goto policydone;
171 }
172 /*
173 * XXX Consider changing the magic hash lengths with
174 * constants.
175 */
176 strlcpy(principal[0], "passphrase:", len);
177 memcpy(principal[0] + sizeof "passphrase:" - 1,
178 isakmp_sa->recv_key, strlen(isakmp_sa->recv_key));
179
180 len = sizeof "passphrase-md5-hex:" + 2 * 16;
181 principal[1] = calloc(len, sizeof(char));
182 if (!principal[1]) {
183 log_error("check_policy: calloc (%d, %lu) failed", len,
184 (unsigned long)sizeof(char));
185 goto policydone;
186 }
187 strlcpy(principal[1], "passphrase-md5-hex:", len);
188 MD5(isakmp_sa->recv_key, strlen(isakmp_sa->recv_key), hashbuf);
189 for (i = 0; i < 16; i++)
190 snprintf(principal[1] + 2 * i +
191 sizeof "passphrase-md5-hex:" - 1, 3, "%02x",
192 hashbuf[i]);
193
194 len = sizeof "passphrase-sha1-hex:" + 2 * 20;
195 principal[2] = calloc(len, sizeof(char));
196 if (!principal[2]) {
197 log_error("check_policy: calloc (%d, %lu) failed", len,
198 (unsigned long)sizeof(char));
199 goto policydone;
200 }
201 strlcpy(principal[2], "passphrase-sha1-hex:", len);
202 SHA1(isakmp_sa->recv_key, strlen(isakmp_sa->recv_key),
203 hashbuf);
204 for (i = 0; i < 20; i++)
205 snprintf(principal[2] + 2 * i +
206 sizeof "passphrase-sha1-hex:" - 1, 3, "%02x",
207 hashbuf[i]);
208 break;
209
210 case ISAKMP_CERTENC_KEYNOTE11:
211 nprinc = 1;
212
213 principal = calloc(nprinc, sizeof *principal);
214 if (!principal) {
215 log_error("check_policy: calloc (%d, %lu) failed",
216 nprinc, (unsigned long)sizeof *principal);
217 goto policydone;
218 }
219 /* Dup the keys */
220 principal[0] = strdup(isakmp_sa->keynote_key);
221 if (!principal[0]) {
222 log_error("check_policy: calloc (%lu, %lu) failed",
223 (unsigned long)strlen(isakmp_sa->keynote_key),
224 (unsigned long)sizeof(char));
225 goto policydone;
226 }
227 break;
228
229 case ISAKMP_CERTENC_X509_SIG4:
230 principal = calloc(2, sizeof *principal);
231 if (!principal) {
232 log_error("check_policy: calloc (2, %lu) failed",
233 (unsigned long)sizeof *principal);
234 goto policydone;
235 }
236 if (isakmp_sa->recv_keytype == ISAKMP_KEY_RSA2)
237 dc.dec_algorithm = KEYNOTE_ALGORITHM_RSA6;
238 else {
239 log_error("check_policy: "
240 "unknown/unsupported public key algorithm %d",
241 isakmp_sa->recv_keytype);
242 goto policydone;
243 }
244
245 dc.dec_key = isakmp_sa->recv_key;
246 principal[0] = kn_encode_key(&dc, INTERNAL_ENC_PKCS11,
247 ENCODING_HEX1, KEYNOTE_PUBLIC_KEY0);
248 if (keynote_errno == ERROR_MEMORY-1) {
249 log_print("check_policy: "
250 "failed to get memory for public key");
251 goto policydone;
252 }
253 if (!principal[0]) {
254 log_print("check_policy: "
255 "failed to allocate memory for principal");
256 goto policydone;
257 }
258 if (asprintf(&principal[1], "rsa-hex:%s", principal[0]) == -1) {
259 log_error("check_policy: asprintf() failed");
260 goto policydone;
261 }
262 free(principal[0]);
263 principal[0] = principal[1];
264 principal[1] = 0;
265
266 /* Generate a "DN:" principal. */
267 subject = X509_get_subject_name(isakmp_sa->recv_cert);
268 if (subject) {
269 principal[1] = calloc(259, sizeof(char));
270 if (!principal[1]) {
271 log_error("check_policy: "
272 "calloc (259, %lu) failed",
273 (unsigned long)sizeof(char));
274 goto policydone;
275 }
276 strlcpy(principal[1], "DN:", 259);
277 X509_NAME_oneline(subject, principal[1] + 3, 256);
278 nprinc = 2;
279 } else {
280 nprinc = 1;
281 }
282 break;
283
284 /* XXX Eventually handle these. */
285 case ISAKMP_CERTENC_PKCS1:
286 case ISAKMP_CERTENC_PGP2:
287 case ISAKMP_CERTENC_DNS3:
288 case ISAKMP_CERTENC_X509_KE5:
289 case ISAKMP_CERTENC_KERBEROS6:
290 case ISAKMP_CERTENC_CRL7:
291 case ISAKMP_CERTENC_ARL8:
292 case ISAKMP_CERTENC_SPKI9:
293 case ISAKMP_CERTENC_X509_ATTR10:
294 default:
295 log_print("check_policy: "
296 "unknown/unsupported certificate/authentication method %d",
297 isakmp_sa->recv_certtype);
298 goto policydone;
299 }
300
301 /*
302 * Add the authorizer (who is requesting the SA/ID);
303 * this may be a public or a secret key, depending on
304 * what mode of authentication we used in Phase 1.
305 */
306 for (i = 0; i < nprinc; i++) {
307 LOG_DBG((LOG_POLICY, 40, "check_policy: "log_debug (LOG_POLICY, 40, "check_policy: " "adding authorizer [%s]"
, principal[i])
308 "adding authorizer [%s]", principal[i]))log_debug (LOG_POLICY, 40, "check_policy: " "adding authorizer [%s]"
, principal[i])
;
309
310 if (kn_add_authorizer(isakmp_sa->policy_id, principal[i])
311 == -1) {
312 int j;
313
314 for (j = 0; j < i; j++)
315 kn_remove_authorizer(isakmp_sa->policy_id,
316 principal[j]);
317 log_print("check_policy: kn_add_authorizer failed");
318 goto policydone;
319 }
320 }
321
322 /* Ask policy */
323 result = kn_do_query(isakmp_sa->policy_id, return_values,
324 RETVALUES_NUM2);
325 LOG_DBG((LOG_POLICY, 40, "check_policy: kn_do_query returned %d",log_debug (LOG_POLICY, 40, "check_policy: kn_do_query returned %d"
, result)
326 result))log_debug (LOG_POLICY, 40, "check_policy: kn_do_query returned %d"
, result)
;
327
328 /* Cleanup environment */
329 kn_cleanup_action_environment(isakmp_sa->policy_id);
330
331 /* Remove authorizers from the session */
332 for (i = 0; i < nprinc; i++) {
333 kn_remove_authorizer(isakmp_sa->policy_id, principal[i]);
334 free(principal[i]);
335 }
336
337 free(principal);
338 principal = 0;
339 nprinc = 0;
340
341 /* Check what policy said. */
342 if (result < 0) {
343 LOG_DBG((LOG_POLICY, 40, "check_policy: proposal refused"))log_debug (LOG_POLICY, 40, "check_policy: proposal refused");
344 result = 0;
345 goto policydone;
346 }
347policydone:
348 for (i = 0; i < nprinc; i++)
349 if (principal && principal[i])
350 free(principal[i]);
351
352 free(principal);
353
354 /* Remove the policies */
355 for (i = 0; i < policy_asserts_num; i++) {
356 if (keynote_ids[i] != -1)
357 kn_remove_assertion(isakmp_sa->policy_id,
358 keynote_ids[i]);
359 }
360
361 free(keynote_ids);
362
363 free(x509_ids);
364
365 /*
366 * XXX Currently, check_policy() is only called from
367 * message_negotiate_sa(), and so this log message reflects this.
368 * Change to something better?
369 */
370 if (result == 0)
371 log_print("check_policy: negotiated SA failed policy check");
372
373 /*
374 * Given that we have only 2 return values from policy (true/false)
375 * we can just return the query result directly (no pre-processing
376 * needed).
377 */
378 return result;
379}
380
381/*
382 * Offer several sets of transforms to the responder.
383 * XXX Split this huge function up and look for common code with main mode.
384 */
385static int
386initiator_send_HASH_SA_NONCE(struct message *msg)
387{
388 struct exchange *exchange = msg->exchange;
389 struct doi *doi = exchange->doi;
390 struct ipsec_exch *ie = exchange->data;
391 u_int8_t ***transform = 0, ***new_transform;
392 u_int8_t **proposal = 0, **new_proposal;
393 u_int8_t *sa_buf = 0, *attr, *saved_nextp_sa, *saved_nextp_prop,
394 *id, *spi;
395 size_t spi_sz, sz;
396 size_t proposal_len = 0, proposals_len = 0, sa_len;
397 size_t **transform_len = 0, **new_transform_len;
398 size_t *transforms_len = 0, *new_transforms_len;
399 u_int32_t *transform_cnt = 0, *new_transform_cnt;
400 u_int32_t suite_no, prop_no, prot_no, xf_no, prop_cnt = 0;
401 u_int32_t i;
402 int value, update_nextp, protocol_num, proto_id;
403 struct proto *proto;
404 struct conf_list *suite_conf, *prot_conf = 0, *xf_conf = 0, *life_conf;
405 struct conf_list_node *suite, *prot, *xf, *life;
406 struct constant_map *id_map;
407 char *protocol_id, *transform_id;
408 char *local_id, *remote_id;
409 char *name;
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_conf->fields)->tqh_first), suite_no = prop_no = 0;
425 suite_no < suite_conf->cnt;
426 suite_no++, suite = TAILQ_NEXT(suite, link)((suite)->link.tqe_next)) {
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_conf->fields)->tqh_first), prot_no = 0;
433 prot_no < prot_conf->cnt;
434 prot_no++, prot = TAILQ_NEXT(prot, link)((prot)->link.tqe_next)) {
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 = reallocarray(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 = reallocarray(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 = reallocarray(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 = reallocarray(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 = reallocarray(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_AH2:
510 id_map = ipsec_ah_cst;
511 break;
512
513 case IPSEC_PROTO_IPSEC_ESP3:
514 id_map = ipsec_esp_cst;
515 break;
516
517 case IPSEC_PROTO_IPCOMP4:
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_conf->fields)->tqh_first), xf_no = 0;
555 xf_no < transform_cnt[prop_no];
556 xf_no++, xf = TAILQ_NEXT(xf, link)((xf)->link.tqe_next)) {
557
558 /* XXX The sizing needs to be dynamic. */
559 transform[prop_no][xf_no] =
560 calloc(ISAKMP_TRANSFORM_SA_ATTRS_OFF8 +
561 9 * ISAKMP_ATTR_VALUE_OFF4, 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_OFF8 +
567 9 * ISAKMP_ATTR_VALUE_OFF4);
568 goto bail_out;
569 }
570 SET_ISAKMP_TRANSFORM_NO(transform[prop_no][xf_no],field_set_num (isakmp_transform_fld + 0, transform[prop_no][xf_no
], xf_no + 1)
571 xf_no + 1)field_set_num (isakmp_transform_fld + 0, transform[prop_no][xf_no
], 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],field_set_num (isakmp_transform_fld + 1, transform[prop_no][xf_no
], constant_value(id_map, transform_id))
578 constant_value(id_map, transform_id))field_set_num (isakmp_transform_fld + 1, transform[prop_no][xf_no
], constant_value(id_map, transform_id))
;
579 SET_ISAKMP_TRANSFORM_RESERVED(transform[prop_no][xf_no], 0)field_set_num (isakmp_transform_fld + 2, transform[prop_no][xf_no
], 0)
;
580
581 attr = transform[prop_no][xf_no] +
582 ISAKMP_TRANSFORM_SA_ATTRS_OFF8;
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)((&life_conf->fields)->tqh_first);
591 life; life = TAILQ_NEXT(life, link)((life)->link.tqe_next)) {
592 attribute_set_constant(
593 life->field, "LIFE_TYPE",
594 ipsec_duration_cst,
595 IPSEC_ATTR_SA_LIFE_TYPE1,
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_DURATION2,
611 value);
612 else {
613 value = htonl(value)(__uint32_t)(__builtin_constant_p(value) ? (__uint32_t)(((__uint32_t
)(value) & 0xff) << 24 | ((__uint32_t)(value) &
0xff00) << 8 | ((__uint32_t)(value) & 0xff0000) >>
8 | ((__uint32_t)(value) & 0xff000000) >> 24) : __swap32md
(value))
;
614 attr =
615 attribute_set_var(
616 attr,
617 IPSEC_ATTR_SA_LIFE_DURATION2,
618 (u_int8_t *)&value,
619 sizeof value);
620 }
621 }
622 }
623 conf_free_list(life_conf);
624 }
625
626 if (proto_id == IPSEC_PROTO_IPSEC_ESP3 &&
627 (exchange->flags &
628 EXCHANGE_FLAG_NAT_T_ENABLE0x0010)) {
629 name = conf_get_str(xf->field,
630 "ENCAPSULATION_MODE");
631 if (name) {
632 value = constant_value(
633 ipsec_encap_cst,
634 name);
635 switch (value) {
636 case IPSEC_ENCAP_TUNNEL1:
637 value = exchange->flags & EXCHANGE_FLAG_NAT_T_DRAFT0x0100 ?
638 IPSEC_ENCAP_UDP_ENCAP_TUNNEL_DRAFT61443 :
639 IPSEC_ENCAP_UDP_ENCAP_TUNNEL3;
640 break;
641 case IPSEC_ENCAP_TRANSPORT2:
642 value = exchange->flags & EXCHANGE_FLAG_NAT_T_DRAFT0x0100 ?
643 IPSEC_ENCAP_UDP_ENCAP_TRANSPORT_DRAFT61444 :
644 IPSEC_ENCAP_UDP_ENCAP_TRANSPORT4;
645 break;
646 }
647 attr = attribute_set_basic(
648 attr,
649 IPSEC_ATTR_ENCAPSULATION_MODE4,
650 value);
651 }
652 } else {
653 attribute_set_constant(xf->field,
654 "ENCAPSULATION_MODE",
655 ipsec_encap_cst,
656 IPSEC_ATTR_ENCAPSULATION_MODE4,
657 &attr);
658 }
659
660 if (proto_id != IPSEC_PROTO_IPCOMP4) {
661 attribute_set_constant(xf->field,
662 "AUTHENTICATION_ALGORITHM",
663 ipsec_auth_cst,
664 IPSEC_ATTR_AUTHENTICATION_ALGORITHM5,
665 &attr);
666
667 attribute_set_constant(xf->field,
668 "GROUP_DESCRIPTION",
669 ike_group_desc_cst,
670 IPSEC_ATTR_GROUP_DESCRIPTION3, &attr);
671
672 value = conf_get_num(xf->field,
673 "KEY_LENGTH", 0);
674 if (value)
675 attr = attribute_set_basic(
676 attr,
677 IPSEC_ATTR_KEY_LENGTH6,
678 value);
679
680 value = conf_get_num(xf->field,
681 "KEY_ROUNDS", 0);
682 if (value)
683 attr = attribute_set_basic(
684 attr,
685 IPSEC_ATTR_KEY_ROUNDS7,
686 value);
687 } else {
688 value = conf_get_num(xf->field,
689 "COMPRESS_DICTIONARY_SIZE", 0);
690 if (value)
691 attr = attribute_set_basic(
692 attr,
693 IPSEC_ATTR_COMPRESS_DICTIONARY_SIZE8,
694 value);
695
696 value = conf_get_num(xf->field,
697 "COMPRESS_PRIVATE_ALGORITHM", 0);
698 if (value)
699 attr = attribute_set_basic(
700 attr,
701 IPSEC_ATTR_COMPRESS_PRIVATE_ALGORITHM9,
702 value);
703 }
704
705 value = conf_get_num(xf->field, "ECN_TUNNEL",
706 0);
707 if (value)
708 attr = attribute_set_basic(attr,
709 IPSEC_ATTR_ECN_TUNNEL10, value);
710
711 /* Record the real transform size. */
712 transforms_len[prop_no] +=
713 (transform_len[prop_no][xf_no]
714 = attr - transform[prop_no][xf_no]);
715
716 if (proto_id != IPSEC_PROTO_IPCOMP4) {
717 /*
718 * Make sure that if a group
719 * description is specified, it is
720 * specified for all transforms
721 * equally.
722 */
723 attr =
724 (u_int8_t *)conf_get_str(xf->field,
725 "GROUP_DESCRIPTION");
726 new_group_desc
727 = attr ? constant_value(ike_group_desc_cst,
728 (char *)attr) : 0;
729 if (group_desc == -1)
730 group_desc = new_group_desc;
731 else if (group_desc != new_group_desc) {
732 log_print("initiator_send_HASH_SA_NONCE: "
733 "differing group descriptions in a proposal");
734 goto bail_out;
735 }
736 }
737 }
738 conf_free_list(xf_conf);
739 xf_conf = 0;
740
741 /*
742 * Get SPI from application.
743 * XXX Should we care about unknown constants?
744 */
745 protocol_num = constant_value(ipsec_proto_cst,
746 protocol_id);
747 spi = doi->get_spi(&spi_sz, protocol_num, msg);
748 if (spi_sz && !spi) {
749 log_print("initiator_send_HASH_SA_NONCE: "
750 "doi->get_spi failed");
751 goto bail_out;
752 }
753 proposal_len = ISAKMP_PROP_SPI_OFF8 + spi_sz;
754 proposals_len +=
755 proposal_len + transforms_len[prop_no];
756 proposal[prop_no] = malloc(proposal_len);
757 if (!proposal[prop_no]) {
758 log_error("initiator_send_HASH_SA_NONCE: "
759 "malloc (%lu) failed",
760 (unsigned long)proposal_len);
761 goto bail_out;
762 }
763 SET_ISAKMP_PROP_NO(proposal[prop_no], suite_no + 1)field_set_num (isakmp_prop_fld + 0, proposal[prop_no], suite_no
+ 1)
;
764 SET_ISAKMP_PROP_PROTO(proposal[prop_no], protocol_num)field_set_num (isakmp_prop_fld + 1, proposal[prop_no], protocol_num
)
;
765
766 /* XXX I would like to see this factored out. */
767 proto = calloc(1, sizeof *proto);
768 if (!proto) {
769 log_error("initiator_send_HASH_SA_NONCE: "
770 "calloc (1, %lu) failed",
771 (unsigned long)sizeof *proto);
772 goto bail_out;
773 }
774 if (doi->proto_size) {
775 proto->data = calloc(1, doi->proto_size);
776 if (!proto->data) {
777 free(proto);
778 log_error(
779 "initiator_send_HASH_SA_NONCE: "
780 "calloc (1, %lu) failed",
781 (unsigned long)doi->proto_size);
782 goto bail_out;
783 }
784 }
785 proto->no = suite_no + 1;
786 proto->proto = protocol_num;
787 proto->sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first);
788 proto->xf_cnt = transform_cnt[prop_no];
789 TAILQ_INIT(&proto->xfs)do { (&proto->xfs)->tqh_first = ((void*)0); (&proto
->xfs)->tqh_last = &(&proto->xfs)->tqh_first
; } while (0)
;
790 for (xf_no = 0; xf_no < proto->xf_cnt; xf_no++) {
791 pa = calloc(1, sizeof *pa);
792 if (!pa) {
793 free(proto->data);
794 free(proto);
795 goto bail_out;
796 }
797 pa->len = transform_len[prop_no][xf_no];
798 pa->attrs = malloc(pa->len);
799 if (!pa->attrs) {
800 free(proto->data);
801 free(proto);
802 free(pa);
803 goto bail_out;
804 }
805 memcpy(pa->attrs, transform[prop_no][xf_no],
806 pa->len);
807 TAILQ_INSERT_TAIL(&proto->xfs, pa, next)do { (pa)->next.tqe_next = ((void*)0); (pa)->next.tqe_prev
= (&proto->xfs)->tqh_last; *(&proto->xfs)->
tqh_last = (pa); (&proto->xfs)->tqh_last = &(pa
)->next.tqe_next; } while (0)
;
808 }
809 TAILQ_INSERT_TAIL(&TAILQ_FIRST(&exchange->sa_list)->protos,do { (proto)->link.tqe_next = ((void*)0); (proto)->link
.tqe_prev = (&((&exchange->sa_list)->tqh_first)
->protos)->tqh_last; *(&((&exchange->sa_list
)->tqh_first)->protos)->tqh_last = (proto); (&((
&exchange->sa_list)->tqh_first)->protos)->tqh_last
= &(proto)->link.tqe_next; } while (0)
810 proto, link)do { (proto)->link.tqe_next = ((void*)0); (proto)->link
.tqe_prev = (&((&exchange->sa_list)->tqh_first)
->protos)->tqh_last; *(&((&exchange->sa_list
)->tqh_first)->protos)->tqh_last = (proto); (&((
&exchange->sa_list)->tqh_first)->protos)->tqh_last
= &(proto)->link.tqe_next; } while (0)
;
811
812 /* Setup the incoming SPI. */
813 SET_ISAKMP_PROP_SPI_SZ(proposal[prop_no], spi_sz)field_set_num (isakmp_prop_fld + 2, proposal[prop_no], spi_sz
)
;
814 memcpy(proposal[prop_no] + ISAKMP_PROP_SPI_OFF8, spi,
815 spi_sz);
816 proto->spi_sz[1] = spi_sz;
817 proto->spi[1] = spi;
818
819 /*
820 * Let the DOI get at proto for initializing its own
821 * data.
822 */
823 if (doi->proto_init)
824 doi->proto_init(proto, prot->field);
825
826 SET_ISAKMP_PROP_NTRANSFORMS(proposal[prop_no],field_set_num (isakmp_prop_fld + 3, proposal[prop_no], transform_cnt
[prop_no])
827 transform_cnt[prop_no])field_set_num (isakmp_prop_fld + 3, proposal[prop_no], transform_cnt
[prop_no])
;
828 prop_no++;
829 }
830 conf_free_list(prot_conf);
831 prot_conf = 0;
832 }
833
834 sa_len = ISAKMP_SA_SIT_OFF8 + IPSEC_SIT_SIT_LEN4;
835 sa_buf = malloc(sa_len);
836 if (!sa_buf) {
837 log_error("initiator_send_HASH_SA_NONCE: malloc (%lu) failed",
838 (unsigned long)sa_len);
839 goto bail_out;
840 }
841 SET_ISAKMP_SA_DOI(sa_buf, IPSEC_DOI_IPSEC)field_set_num (isakmp_sa_fld + 0, sa_buf, 1);
842 SET_IPSEC_SIT_SIT(sa_buf + ISAKMP_SA_SIT_OFF, IPSEC_SIT_IDENTITY_ONLY)field_set_num (ipsec_sit_fld + 0, sa_buf + 8, 1);
843
844 /*
845 * Add the payloads. As this is a SA, we need to recompute the
846 * lengths of the payloads containing others. We also need to
847 * reset these payload's "next payload type" field.
848 */
849 if (message_add_payload(msg, ISAKMP_PAYLOAD_SA1, sa_buf, sa_len, 1))
850 goto bail_out;
851 SET_ISAKMP_GEN_LENGTH(sa_buf, sa_len + proposals_len)field_set_num (isakmp_gen_fld + 2, sa_buf, sa_len + proposals_len
)
;
852 sa_buf = 0;
853
854 update_nextp = 0;
855 saved_nextp_sa = msg->nextp;
856 for (i = 0; i < prop_no; i++) {
857 if (message_add_payload(msg, ISAKMP_PAYLOAD_PROPOSAL2,
858 proposal[i], proposal_len, update_nextp))
859 goto bail_out;
860 SET_ISAKMP_GEN_LENGTH(proposal[i],field_set_num (isakmp_gen_fld + 2, proposal[i], proposal_len +
transforms_len[i])
861 proposal_len + transforms_len[i])field_set_num (isakmp_gen_fld + 2, proposal[i], proposal_len +
transforms_len[i])
;
862 proposal[i] = 0;
863
864 update_nextp = 0;
865 saved_nextp_prop = msg->nextp;
866 for (xf_no = 0; xf_no < transform_cnt[i]; xf_no++) {
867 if (message_add_payload(msg, ISAKMP_PAYLOAD_TRANSFORM3,
868 transform[i][xf_no],
869 transform_len[i][xf_no], update_nextp))
870 goto bail_out;
871 update_nextp = 1;
872 transform[i][xf_no] = 0;
873 }
874 msg->nextp = saved_nextp_prop;
875 update_nextp = 1;
876 }
877 msg->nextp = saved_nextp_sa;
878
879 /*
880 * Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len.
881 */
882 ie->sa_i_b = message_copy(msg, ISAKMP_GEN_SZ4, &ie->sa_i_b_len);
883 if (!ie->sa_i_b)
884 goto bail_out;
885
886 /*
887 * Generate a nonce, and add it to the message.
888 * XXX I want a better way to specify the nonce's size.
889 */
890 if (exchange_gen_nonce(msg, 16))
891 return -1;
892
893 /* Generate optional KEY_EXCH payload. */
894 if (group_desc > 0) {
895 ie->group = group_get(group_desc);
896 ie->g_x_len = dh_getlen(ie->group);
897
898 if (ipsec_gen_g_x(msg)) {
899 group_free(ie->group);
900 ie->group = 0;
901 return -1;
902 }
903 }
904 /* Generate optional client ID payloads. XXX Share with responder. */
905 local_id = conf_get_str(exchange->name, "Local-ID");
906 remote_id = conf_get_str(exchange->name, "Remote-ID");
907 if (local_id && remote_id) {
908 id = ipsec_build_id(local_id, &sz);
909 if (!id)
910 return -1;
911 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic"
, id, sz)
912 "initiator_send_HASH_SA_NONCE: IDic", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic"
, id, sz)
;
913 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
914 free(id);
915 return -1;
916 }
917 id = ipsec_build_id(remote_id, &sz);
918 if (!id)
919 return -1;
920 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc"
, id, sz)
921 "initiator_send_HASH_SA_NONCE: IDrc", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc"
, id, sz)
;
922 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
923 free(id);
924 return -1;
925 }
926 }
927 /* XXX I do not judge these as errors, are they? */
928 else if (local_id)
929 log_print("initiator_send_HASH_SA_NONCE: "
930 "Local-ID given without Remote-ID for \"%s\"",
931 exchange->name);
932 else if (remote_id)
933 /*
934 * This code supports the "road warrior" case, where the
935 * initiator doesn't have a fixed IP address, but wants to
936 * specify a particular remote network to talk to. -- Adrian
937 * Close <adrian@esec.com.au>
938 */
939 {
940 log_print("initiator_send_HASH_SA_NONCE: "
941 "Remote-ID given without Local-ID for \"%s\"",
942 exchange->name);
943
944 /*
945 * If we're here, then we are the initiator, so use initiator
946 * address for local ID
947 */
948 msg->transport->vtbl->get_src(msg->transport, &src);
949 sz = ISAKMP_ID_SZ8 + sockaddr_addrlen(src);
950
951 id = calloc(sz, sizeof(char));
952 if (!id) {
953 log_error("initiator_send_HASH_SA_NONCE: "
954 "calloc (%lu, %lu) failed", (unsigned long)sz,
955 (unsigned long)sizeof(char));
956 return -1;
957 }
958 switch (src->sa_family) {
959 case AF_INET624:
960 SET_ISAKMP_ID_TYPE(id, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, id, 5);
961 break;
962 case AF_INET2:
963 SET_ISAKMP_ID_TYPE(id, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, id, 1);
964 break;
965 default:
966 log_error("initiator_send_HASH_SA_NONCE: "
967 "unknown sa_family %d", src->sa_family);
968 free(id);
969 return -1;
970 }
971 memcpy(id + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(src),
972 sockaddr_addrlen(src));
973
974 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic"
, id, sz)
975 "initiator_send_HASH_SA_NONCE: IDic", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic"
, id, sz)
;
976 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
977 free(id);
978 return -1;
979 }
980 /* Send supplied remote_id */
981 id = ipsec_build_id(remote_id, &sz);
982 if (!id)
983 return -1;
984 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc"
, id, sz)
985 "initiator_send_HASH_SA_NONCE: IDrc", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc"
, id, sz)
;
986 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
987 free(id);
988 return -1;
989 }
990 }
991 if (ipsec_fill_in_hash(msg))
992 goto bail_out;
993
994 conf_free_list(suite_conf);
995 for (i = 0; i < prop_no; i++) {
996 free(transform[i]);
997 free(transform_len[i]);
998 }
999 free(proposal);
1000 free(transform);
1001 free(transforms_len);
1002 free(transform_len);
1003 free(transform_cnt);
1004 return 0;
1005
1006bail_out:
1007 free(sa_buf);
1008 if (proposal) {
1009 for (i = 0; i < prop_no; i++) {
1010 free(proposal[i]);
1011 if (transform[i]) {
1012 for (xf_no = 0; xf_no < transform_cnt[i];
1013 xf_no++)
1014 free(transform[i][xf_no]);
1015 free(transform[i]);
1016 }
1017 free(transform_len[i]);
1018 }
1019 free(proposal);
1020 free(transforms_len);
1021 free(transform);
1022 free(transform_len);
1023 free(transform_cnt);
1024 }
1025 if (xf_conf)
1026 conf_free_list(xf_conf);
1027 if (prot_conf)
1028 conf_free_list(prot_conf);
1029 conf_free_list(suite_conf);
1030 return -1;
1031}
1032
1033/* Figure out what transform the responder chose. */
1034static int
1035initiator_recv_HASH_SA_NONCE(struct message *msg)
1036{
1037 struct exchange *exchange = msg->exchange;
1038 struct ipsec_exch *ie = exchange->data;
1039 struct sa *sa;
1040 struct proto *proto, *next_proto;
1041 struct payload *sa_p = payload_first(msg, ISAKMP_PAYLOAD_SA1);
1042 struct payload *xf, *idp;
1043 struct payload *hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH8);
1044 struct payload *kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH4);
1045 struct prf *prf;
1046 struct sa *isakmp_sa = msg->isakmp_sa;
1047 struct ipsec_sa *isa = isakmp_sa->data;
1048 struct hash *hash = hash_get(isa->hash);
1049 u_int8_t *rest;
1050 size_t rest_len;
1051 struct sockaddr *src, *dst;
1052
1053 /* Allocate the prf and start calculating our HASH(1). XXX Share? */
1054 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: "log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: "
"SKEYID_a", (u_int8_t *)isa->skeyid_a, isa->skeyid_len
)
1055 "SKEYID_a", (u_int8_t *)isa->skeyid_a, isa->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: "
"SKEYID_a", (u_int8_t *)isa->skeyid_a, isa->skeyid_len
)
;
1056 prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a,
1057 isa->skeyid_len);
1058 if (!prf)
1059 return -1;
1060
1061 prf->Init(prf->prfctx);
1062 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1063 "initiator_recv_HASH_SA_NONCE: message_id",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1064 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
;
1065 prf->Update(prf->prfctx, exchange->message_id,
1066 ISAKMP_HDR_MESSAGE_ID_LEN4);
1067 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: "log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: "
"NONCE_I_b", exchange->nonce_i, exchange->nonce_i_len)
1068 "NONCE_I_b", exchange->nonce_i, exchange->nonce_i_len))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: "
"NONCE_I_b", exchange->nonce_i, exchange->nonce_i_len)
;
1069 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
1070 rest = hashp->p + GET_ISAKMP_GEN_LENGTH(hashp->p)field_get_num (isakmp_gen_fld + 2, hashp->p);
1071 rest_len = (GET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base)field_get_num (isakmp_hdr_fld + 7, msg->iov[0].iov_base)
1072 - (rest - (u_int8_t *)msg->iov[0].iov_base));
1073 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)"
, rest, rest_len)
1074 "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)", rest,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)"
, rest, rest_len)
1075 rest_len))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)"
, rest, rest_len)
;
1076 prf->Update(prf->prfctx, rest, rest_len);
1077 prf->Final(hash->digest, prf->prfctx);
1078 prf_free(prf);
1079 LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "initiator_recv_HASH_SA_NONCE: computed HASH(2)"
, hash->digest, hash->hashsize)
1080 "initiator_recv_HASH_SA_NONCE: computed HASH(2)", hash->digest,log_debug_buf (LOG_NEGOTIATION, 80, "initiator_recv_HASH_SA_NONCE: computed HASH(2)"
, hash->digest, hash->hashsize)
1081 hash->hashsize))log_debug_buf (LOG_NEGOTIATION, 80, "initiator_recv_HASH_SA_NONCE: computed HASH(2)"
, hash->digest, hash->hashsize)
;
1082 if (memcmp(hashp->p + ISAKMP_HASH_DATA_OFF4, hash->digest,
1083 hash->hashsize) != 0) {
1084 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION23, 0, 1,
1085 0);
1086 return -1;
1087 }
1088 /* Mark the HASH as handled. */
1089 hashp->flags |= PL_MARK1;
1090
1091 /* Mark message as authenticated. */
1092 msg->flags |= MSG_AUTHENTICATED0x10;
1093
1094 /*
1095 * As we are getting an answer on our transform offer, only one
1096 * transform should be given.
1097 *
1098 * XXX Currently we only support negotiating one SA per quick mode run.
1099 */
1100 if (TAILQ_NEXT(sa_p, link)((sa_p)->link.tqe_next)) {
1101 log_print("initiator_recv_HASH_SA_NONCE: "
1102 "multiple SA payloads in quick mode not supported yet");
1103 return -1;
1104 }
1105 sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first);
1106
1107 /* This is here for the policy check */
1108 if (kep)
1109 ie->pfs = 1;
1110
1111 /* Drop message when it contains ID types we do not implement yet. */
1112 TAILQ_FOREACH(idp, &msg->payload[ISAKMP_PAYLOAD_ID], link)for((idp) = ((&msg->payload[5])->tqh_first); (idp) !=
((void*)0); (idp) = ((idp)->link.tqe_next))
{
1113 switch (GET_ISAKMP_ID_TYPE(idp->p)field_get_num (isakmp_id_fld + 0, idp->p)) {
1114 case IPSEC_ID_IPV4_ADDR1:
1115 case IPSEC_ID_IPV4_ADDR_SUBNET4:
1116 case IPSEC_ID_IPV6_ADDR5:
1117 case IPSEC_ID_IPV6_ADDR_SUBNET6:
1118 break;
1119
1120 case IPSEC_ID_FQDN2:
1121 /*
1122 * FQDN may be used for in NAT-T with transport mode.
1123 * We can handle the message in this case. In the
1124 * other cases we'll drop the message later.
1125 */
1126 break;
1127
1128 default:
1129 message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION18,
1130 0, 1, 0);
1131 return -1;
1132 }
1133 }
1134
1135 /* Handle optional client ID payloads. */
1136 idp = payload_first(msg, ISAKMP_PAYLOAD_ID5);
1137 if (idp) {
1138 /* If IDci is there, IDcr must be too. */
1139 if (!TAILQ_NEXT(idp, link)((idp)->link.tqe_next)) {
1140 /* XXX Is this a good notify type? */
1141 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0,
1142 1, 0);
1143 return -1;
1144 }
1145 /* XXX We should really compare, not override. */
1146 ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH(idp->p)field_get_num (isakmp_gen_fld + 2, idp->p);
1147 ie->id_ci = malloc(ie->id_ci_sz);
1148 if (!ie->id_ci) {
1149 log_error("initiator_recv_HASH_SA_NONCE: "
1150 "malloc (%lu) failed",
1151 (unsigned long)ie->id_ci_sz);
1152 return -1;
1153 }
1154 memcpy(ie->id_ci, idp->p, ie->id_ci_sz);
1155 idp->flags |= PL_MARK1;
1156 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: IDci"
, ie->id_ci + 4, ie->id_ci_sz - 4)
1157 "initiator_recv_HASH_SA_NONCE: IDci",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: IDci"
, ie->id_ci + 4, ie->id_ci_sz - 4)
1158 ie->id_ci + ISAKMP_GEN_SZ, ie->id_ci_sz - ISAKMP_GEN_SZ))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: IDci"
, ie->id_ci + 4, ie->id_ci_sz - 4)
;
1159
1160 idp = TAILQ_NEXT(idp, link)((idp)->link.tqe_next);
1161 ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH(idp->p)field_get_num (isakmp_gen_fld + 2, idp->p);
1162 ie->id_cr = malloc(ie->id_cr_sz);
1163 if (!ie->id_cr) {
1164 log_error("initiator_recv_HASH_SA_NONCE: "
1165 "malloc (%lu) failed",
1166 (unsigned long)ie->id_cr_sz);
1167 return -1;
1168 }
1169 memcpy(ie->id_cr, idp->p, ie->id_cr_sz);
1170 idp->flags |= PL_MARK1;
1171 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: IDcr"
, ie->id_cr + 4, ie->id_cr_sz - 4)
1172 "initiator_recv_HASH_SA_NONCE: IDcr",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: IDcr"
, ie->id_cr + 4, ie->id_cr_sz - 4)
1173 ie->id_cr + ISAKMP_GEN_SZ, ie->id_cr_sz - ISAKMP_GEN_SZ))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: IDcr"
, ie->id_cr + 4, ie->id_cr_sz - 4)
;
1174 } else {
1175 /*
1176 * If client identifiers are not present in the exchange,
1177 * we fake them. RFC 2409 states:
1178 * The identities of the SAs negotiated in Quick Mode are
1179 * implicitly assumed to be the IP addresses of the ISAKMP
1180 * peers, without any constraints on the protocol or port
1181 * numbers allowed, unless client identifiers are specified
1182 * in Quick Mode.
1183 *
1184 * -- Michael Paddon (mwp@aba.net.au)
1185 */
1186
1187 ie->flags = IPSEC_EXCH_FLAG_NO_ID1;
1188
1189 /* Get initiator and responder addresses. */
1190 msg->transport->vtbl->get_src(msg->transport, &src);
1191 msg->transport->vtbl->get_dst(msg->transport, &dst);
1192 ie->id_ci_sz = ISAKMP_ID_DATA_OFF8 + sockaddr_addrlen(src);
1193 ie->id_cr_sz = ISAKMP_ID_DATA_OFF8 + sockaddr_addrlen(dst);
1194 ie->id_ci = calloc(ie->id_ci_sz, sizeof(char));
1195 ie->id_cr = calloc(ie->id_cr_sz, sizeof(char));
Result of 'calloc' is converted to a pointer of type 'u_int8_t', which is incompatible with sizeof operand type 'char'
1196
1197 if (!ie->id_ci || !ie->id_cr) {
1198 log_error("initiator_recv_HASH_SA_NONCE: "
1199 "calloc (%lu, %lu) failed",
1200 (unsigned long)ie->id_cr_sz,
1201 (unsigned long)sizeof(char));
1202 free(ie->id_ci);
1203 ie->id_ci = 0;
1204 free(ie->id_cr);
1205 ie->id_cr = 0;
1206 return -1;
1207 }
1208 if (src->sa_family != dst->sa_family) {
1209 log_error("initiator_recv_HASH_SA_NONCE: "
1210 "sa_family mismatch");
1211 free(ie->id_ci);
1212 ie->id_ci = 0;
1213 free(ie->id_cr);
1214 ie->id_cr = 0;
1215 return -1;
1216 }
1217 switch (src->sa_family) {
1218 case AF_INET2:
1219 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_ci, 1);
1220 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_cr, 1);
1221 break;
1222
1223 case AF_INET624:
1224 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_ci, 5);
1225 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_cr, 5);
1226 break;
1227
1228 default:
1229 log_error("initiator_recv_HASH_SA_NONCE: "
1230 "unknown sa_family %d", src->sa_family);
1231 free(ie->id_ci);
1232 ie->id_ci = 0;
1233 free(ie->id_cr);
1234 ie->id_cr = 0;
1235 return -1;
1236 }
1237 memcpy(ie->id_ci + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(src),
1238 sockaddr_addrlen(src));
1239 memcpy(ie->id_cr + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(dst),
1240 sockaddr_addrlen(dst));
1241 }
1242
1243 /* Build the protection suite in our SA. */
1244 TAILQ_FOREACH(xf, &msg->payload[ISAKMP_PAYLOAD_TRANSFORM], link)for((xf) = ((&msg->payload[3])->tqh_first); (xf) !=
((void*)0); (xf) = ((xf)->link.tqe_next))
{
1245 /*
1246 * XXX We could check that the proposal each transform
1247 * belongs to is unique.
1248 */
1249
1250 if (sa_add_transform(sa, xf, exchange->initiator, &proto))
1251 return -1;
1252
1253 /* XXX Check that the chosen transform matches an offer. */
1254
1255 ipsec_decode_transform(msg, sa, proto, xf->p);
1256 }
1257
1258 /* Now remove offers that we don't need anymore. */
1259 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto; proto = next_proto) {
1260 next_proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next);
1261 if (!proto->chosen)
1262 proto_free(proto);
1263 }
1264
1265 if (!check_policy(exchange, sa, msg->isakmp_sa)) {
1266 message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN14, 0, 1, 0);
1267 log_print("initiator_recv_HASH_SA_NONCE: policy check failed");
1268 return -1;
1269 }
1270
1271 /* Mark the SA as handled. */
1272 sa_p->flags |= PL_MARK1;
1273
1274 isa = sa->data;
1275 if ((isa->group_desc &&
1276 (!ie->group || ie->group->id != isa->group_desc)) ||
1277 (!isa->group_desc && ie->group)) {
1278 log_print("initiator_recv_HASH_SA_NONCE: disagreement on PFS");
1279 return -1;
1280 }
1281 /* Copy out the initiator's nonce. */
1282 if (exchange_save_nonce(msg))
1283 return -1;
1284
1285 /* Handle the optional KEY_EXCH payload. */
1286 if (kep && ipsec_save_g_x(msg))
1287 return -1;
1288
1289 return 0;
1290}
1291
1292static int
1293initiator_send_HASH(struct message *msg)
1294{
1295 struct exchange *exchange = msg->exchange;
1296 struct ipsec_exch *ie = exchange->data;
1297 struct sa *isakmp_sa = msg->isakmp_sa;
1298 struct ipsec_sa *isa = isakmp_sa->data;
1299 struct prf *prf;
1300 u_int8_t *buf;
1301 struct hash *hash = hash_get(isa->hash);
1302
1303 /*
1304 * We want a HASH payload to start with. XXX Share with
1305 * ike_main_mode.c?
1306 */
1307 buf = malloc(ISAKMP_HASH_SZ4 + hash->hashsize);
1308 if (!buf) {
1309 log_error("initiator_send_HASH: malloc (%lu) failed",
1310 ISAKMP_HASH_SZ4 + (unsigned long)hash->hashsize);
1311 return -1;
1312 }
1313 if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH8, buf,
1314 ISAKMP_HASH_SZ4 + hash->hashsize, 1)) {
1315 free(buf);
1316 return -1;
1317 }
1318 /* Allocate the prf and start calculating our HASH(3). XXX Share? */
1319 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: SKEYID_a",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: SKEYID_a"
, isa->skeyid_a, isa->skeyid_len)
1320 isa->skeyid_a, isa->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: SKEYID_a"
, isa->skeyid_a, isa->skeyid_len)
;
1321 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a,
1322 isa->skeyid_len);
1323 if (!prf)
1324 return -1;
1325 prf->Init(prf->prfctx);
1326 prf->Update(prf->prfctx, (unsigned char *)"\0", 1);
1327 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: message_id",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: message_id"
, exchange->message_id, 4)
1328 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: message_id"
, exchange->message_id, 4)
;
1329 prf->Update(prf->prfctx, exchange->message_id,
1330 ISAKMP_HDR_MESSAGE_ID_LEN4);
1331 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_I_b",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_I_b"
, exchange->nonce_i, exchange->nonce_i_len)
1332 exchange->nonce_i, exchange->nonce_i_len))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_I_b"
, exchange->nonce_i, exchange->nonce_i_len)
;
1333 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
1334 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_R_b",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_R_b"
, exchange->nonce_r, exchange->nonce_r_len)
1335 exchange->nonce_r, exchange->nonce_r_len))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: NONCE_R_b"
, exchange->nonce_r, exchange->nonce_r_len)
;
1336 prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
1337 prf->Final(buf + ISAKMP_GEN_SZ4, prf->prfctx);
1338 prf_free(prf);
1339 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "initiator_send_HASH: HASH(3)",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: HASH(3)"
, buf + 4, hash->hashsize)
1340 buf + ISAKMP_GEN_SZ, hash->hashsize))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: HASH(3)"
, buf + 4, hash->hashsize)
;
1341
1342 if (ie->group)
1343 message_register_post_send(msg, gen_g_xy);
1344
1345 message_register_post_send(msg, post_quick_mode);
1346
1347 return 0;
1348}
1349
1350static void
1351post_quick_mode(struct message *msg)
1352{
1353 struct sa *isakmp_sa = msg->isakmp_sa;
1354 struct ipsec_sa *isa = isakmp_sa->data;
1355 struct exchange *exchange = msg->exchange;
1356 struct ipsec_exch *ie = exchange->data;
1357 struct prf *prf;
1358 struct sa *sa;
1359 struct proto *proto;
1360 struct ipsec_proto *iproto;
1361 u_int8_t *keymat;
1362 int i;
1363
1364 /*
1365 * Loop over all SA negotiations and do both an in- and an outgoing SA
1366 * per protocol.
1367 */
1368 for (sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first); sa;
1369 sa = TAILQ_NEXT(sa, next)((sa)->next.tqe_next)) {
1370 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto;
1371 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next)) {
1372 if (proto->proto == IPSEC_PROTO_IPCOMP4)
1373 continue;
1374
1375 iproto = proto->data;
1376
1377 /*
1378 * There are two SAs for each SA negotiation,
1379 * incoming and outgoing.
1380 */
1381 for (i = 0; i < 2; i++) {
1382 prf = prf_alloc(isa->prf_type, isa->hash,
1383 isa->skeyid_d, isa->skeyid_len);
1384 if (!prf) {
1385 /* XXX What to do? */
1386 continue;
1387 }
1388 ie->keymat_len = ipsec_keymat_length(proto);
1389
1390 /*
1391 * We need to roundup the length of the key
1392 * material buffer to a multiple of the PRF's
1393 * blocksize as it is generated in chunks of
1394 * that blocksize.
1395 */
1396 iproto->keymat[i]
1397 = malloc(((ie->keymat_len + prf->blocksize - 1)
1398 / prf->blocksize) * prf->blocksize);
1399 if (!iproto->keymat[i]) {
1400 log_error("post_quick_mode: "
1401 "malloc (%lu) failed",
1402 (((unsigned long)ie->keymat_len +
1403 prf->blocksize - 1) / prf->blocksize) *
1404 prf->blocksize);
1405 /* XXX What more to do? */
1406 free(prf);
1407 continue;
1408 }
1409 for (keymat = iproto->keymat[i];
1410 keymat < iproto->keymat[i] + ie->keymat_len;
1411 keymat += prf->blocksize) {
1412 prf->Init(prf->prfctx);
1413
1414 if (keymat != iproto->keymat[i]) {
1415 /*
1416 * Hash in last round's
1417 * KEYMAT.
1418 */
1419 LOG_DBG_BUF((LOG_NEGOTIATION,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
1420 90, "post_quick_mode: "log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
1421 "last KEYMAT",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
1422 keymat - prf->blocksize,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
1423 prf->blocksize))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
;
1424 prf->Update(prf->prfctx,
1425 keymat - prf->blocksize,
1426 prf->blocksize);
1427 }
1428 /* If PFS is used hash in g^xy. */
1429 if (ie->g_xy) {
1430 LOG_DBG_BUF((LOG_NEGOTIATION,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "g^xy"
, ie->g_xy, ie->g_xy_len)
1431 90, "post_quick_mode: "log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "g^xy"
, ie->g_xy, ie->g_xy_len)
1432 "g^xy", ie->g_xy,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "g^xy"
, ie->g_xy, ie->g_xy_len)
1433 ie->g_xy_len))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "g^xy"
, ie->g_xy, ie->g_xy_len)
;
1434 prf->Update(prf->prfctx,
1435 ie->g_xy, ie->g_xy_len);
1436 }
1437 LOG_DBG((LOG_NEGOTIATION, 90,log_debug (LOG_NEGOTIATION, 90, "post_quick_mode: " "suite %d proto %d"
, proto->no, proto->proto)
1438 "post_quick_mode: "log_debug (LOG_NEGOTIATION, 90, "post_quick_mode: " "suite %d proto %d"
, proto->no, proto->proto)
1439 "suite %d proto %d", proto->no,log_debug (LOG_NEGOTIATION, 90, "post_quick_mode: " "suite %d proto %d"
, proto->no, proto->proto)
1440 proto->proto))log_debug (LOG_NEGOTIATION, 90, "post_quick_mode: " "suite %d proto %d"
, proto->no, proto->proto)
;
1441 prf->Update(prf->prfctx, &proto->proto,
1442 1);
1443 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: SPI", proto
->spi[i], proto->spi_sz[i])
1444 "post_quick_mode: SPI",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: SPI", proto
->spi[i], proto->spi_sz[i])
1445 proto->spi[i], proto->spi_sz[i]))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: SPI", proto
->spi[i], proto->spi_sz[i])
;
1446 prf->Update(prf->prfctx,
1447 proto->spi[i], proto->spi_sz[i]);
1448 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b", exchange
->nonce_i, exchange->nonce_i_len)
1449 "post_quick_mode: Ni_b",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b", exchange
->nonce_i, exchange->nonce_i_len)
1450 exchange->nonce_i,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b", exchange
->nonce_i, exchange->nonce_i_len)
1451 exchange->nonce_i_len))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b", exchange
->nonce_i, exchange->nonce_i_len)
;
1452 prf->Update(prf->prfctx,
1453 exchange->nonce_i,
1454 exchange->nonce_i_len);
1455 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b", exchange
->nonce_r, exchange->nonce_r_len)
1456 "post_quick_mode: Nr_b",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b", exchange
->nonce_r, exchange->nonce_r_len)
1457 exchange->nonce_r,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b", exchange
->nonce_r, exchange->nonce_r_len)
1458 exchange->nonce_r_len))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b", exchange
->nonce_r, exchange->nonce_r_len)
;
1459 prf->Update(prf->prfctx,
1460 exchange->nonce_r,
1461 exchange->nonce_r_len);
1462 prf->Final(keymat, prf->prfctx);
1463 }
1464 prf_free(prf);
1465 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: KEYMAT"
, iproto->keymat[i], ie->keymat_len)
1466 "post_quick_mode: KEYMAT",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: KEYMAT"
, iproto->keymat[i], ie->keymat_len)
1467 iproto->keymat[i], ie->keymat_len))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: KEYMAT"
, iproto->keymat[i], ie->keymat_len)
;
1468 }
1469 }
1470 }
1471
1472 log_verbose("isakmpd: quick mode done%s: %s",
1473 (exchange->initiator == 0) ? " (as responder)" : "",
1474 !msg->isakmp_sa || !msg->isakmp_sa->transport ? "<no transport>"
1475 : msg->isakmp_sa->transport->vtbl->decode_ids
1476 (msg->isakmp_sa->transport));
1477}
1478
1479/*
1480 * Accept a set of transforms offered by the initiator and chose one we can
1481 * handle.
1482 * XXX Describe in more detail.
1483 */
1484static int
1485responder_recv_HASH_SA_NONCE(struct message *msg)
1486{
1487 struct payload *hashp, *kep, *idp;
1488 struct sa *sa;
1489 struct sa *isakmp_sa = msg->isakmp_sa;
1490 struct ipsec_sa *isa = isakmp_sa->data;
1491 struct exchange *exchange = msg->exchange;
1492 struct ipsec_exch *ie = exchange->data;
1493 struct prf *prf;
1494 u_int8_t *hash, *my_hash = 0;
1495 size_t hash_len;
1496 u_int8_t *pkt = msg->iov[0].iov_base;
1497 u_int8_t group_desc = 0;
1498 int retval = -1;
1499 struct proto *proto;
1500 struct sockaddr *src, *dst;
1501 char *name;
1502
1503 hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH8);
1504 hash = hashp->p;
1505 hashp->flags |= PL_MARK1;
1506
1507 /* The HASH payload should be the first one. */
1508 if (hash != pkt + ISAKMP_HDR_SZ28) {
1509 /* XXX Is there a better notification type? */
1510 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0, 1, 0);
1511 goto cleanup;
1512 }
1513 hash_len = GET_ISAKMP_GEN_LENGTH(hash)field_get_num (isakmp_gen_fld + 2, hash);
1514 my_hash = malloc(hash_len - ISAKMP_GEN_SZ4);
1515 if (!my_hash) {
1516 log_error("responder_recv_HASH_SA_NONCE: malloc (%lu) failed",
1517 (unsigned long)hash_len - ISAKMP_GEN_SZ4);
1518 goto cleanup;
1519 }
1520 /*
1521 * Check the payload's integrity.
1522 * XXX Share with ipsec_fill_in_hash?
1523 */
1524 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: "log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: "
"SKEYID_a", isa->skeyid_a, isa->skeyid_len)
1525 "SKEYID_a", isa->skeyid_a, isa->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: "
"SKEYID_a", isa->skeyid_a, isa->skeyid_len)
;
1526 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a,
1527 isa->skeyid_len);
1528 if (!prf)
1529 goto cleanup;
1530 prf->Init(prf->prfctx);
1531 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1532 "responder_recv_HASH_SA_NONCE: message_id",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1533 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
;
1534 prf->Update(prf->prfctx, exchange->message_id,
1535 ISAKMP_HDR_MESSAGE_ID_LEN4);
1536 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message after HASH"
, hash + hash_len, msg->iov[0].iov_len - 28 - hash_len)
1537 "responder_recv_HASH_SA_NONCE: message after HASH",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message after HASH"
, hash + hash_len, msg->iov[0].iov_len - 28 - hash_len)
1538 hash + hash_len,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message after HASH"
, hash + hash_len, msg->iov[0].iov_len - 28 - hash_len)
1539 msg->iov[0].iov_len - ISAKMP_HDR_SZ - hash_len))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message after HASH"
, hash + hash_len, msg->iov[0].iov_len - 28 - hash_len)
;
1540 prf->Update(prf->prfctx, hash + hash_len,
1541 msg->iov[0].iov_len - ISAKMP_HDR_SZ28 - hash_len);
1542 prf->Final(my_hash, prf->prfctx);
1543 prf_free(prf);
1544 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: computed HASH(1)"
, my_hash, hash_len - 4)
1545 "responder_recv_HASH_SA_NONCE: computed HASH(1)", my_hash,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: computed HASH(1)"
, my_hash, hash_len - 4)
1546 hash_len - ISAKMP_GEN_SZ))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: computed HASH(1)"
, my_hash, hash_len - 4)
;
1547 if (memcmp(hash + ISAKMP_GEN_SZ4, my_hash, hash_len - ISAKMP_GEN_SZ4)
1548 != 0) {
1549 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION23, 0,
1550 1, 0);
1551 goto cleanup;
1552 }
1553 free(my_hash);
1554 my_hash = 0;
1555
1556 /* Mark message as authenticated. */
1557 msg->flags |= MSG_AUTHENTICATED0x10;
1558
1559 kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH4);
1560 if (kep)
1561 ie->pfs = 1;
1562
1563 /* Drop message when it contains ID types we do not implement yet. */
1564 TAILQ_FOREACH(idp, &msg->payload[ISAKMP_PAYLOAD_ID], link)for((idp) = ((&msg->payload[5])->tqh_first); (idp) !=
((void*)0); (idp) = ((idp)->link.tqe_next))
{
1565 switch (GET_ISAKMP_ID_TYPE(idp->p)field_get_num (isakmp_id_fld + 0, idp->p)) {
1566 case IPSEC_ID_IPV4_ADDR1:
1567 case IPSEC_ID_IPV4_ADDR_SUBNET4:
1568 case IPSEC_ID_IPV6_ADDR5:
1569 case IPSEC_ID_IPV6_ADDR_SUBNET6:
1570 break;
1571
1572 case IPSEC_ID_FQDN2:
1573 /*
1574 * FQDN may be used for in NAT-T with transport mode.
1575 * We can handle the message in this case. In the
1576 * other cases we'll drop the message later.
1577 */
1578 break;
1579
1580 default:
1581 message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION18,
1582 0, 1, 0);
1583 goto cleanup;
1584 }
1585 }
1586
1587 /* Handle optional client ID payloads. */
1588 idp = payload_first(msg, ISAKMP_PAYLOAD_ID5);
1589 if (idp) {
1590 /* If IDci is there, IDcr must be too. */
1591 if (!TAILQ_NEXT(idp, link)((idp)->link.tqe_next)) {
1592 /* XXX Is this a good notify type? */
1593 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0,
1594 1, 0);
1595 goto cleanup;
1596 }
1597 ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH(idp->p)field_get_num (isakmp_gen_fld + 2, idp->p);
1598 ie->id_ci = malloc(ie->id_ci_sz);
1599 if (!ie->id_ci) {
1600 log_error("responder_recv_HASH_SA_NONCE: "
1601 "malloc (%lu) failed",
1602 (unsigned long)ie->id_ci_sz);
1603 goto cleanup;
1604 }
1605 memcpy(ie->id_ci, idp->p, ie->id_ci_sz);
1606 idp->flags |= PL_MARK1;
1607 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: IDci"
, ie->id_ci + 4, ie->id_ci_sz - 4)
1608 "responder_recv_HASH_SA_NONCE: IDci",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: IDci"
, ie->id_ci + 4, ie->id_ci_sz - 4)
1609 ie->id_ci + ISAKMP_GEN_SZ, ie->id_ci_sz - ISAKMP_GEN_SZ))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: IDci"
, ie->id_ci + 4, ie->id_ci_sz - 4)
;
1610
1611 idp = TAILQ_NEXT(idp, link)((idp)->link.tqe_next);
1612 ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH(idp->p)field_get_num (isakmp_gen_fld + 2, idp->p);
1613 ie->id_cr = malloc(ie->id_cr_sz);
1614 if (!ie->id_cr) {
1615 log_error("responder_recv_HASH_SA_NONCE: "
1616 "malloc (%lu) failed",
1617 (unsigned long)ie->id_cr_sz);
1618 goto cleanup;
1619 }
1620 memcpy(ie->id_cr, idp->p, ie->id_cr_sz);
1621 idp->flags |= PL_MARK1;
1622 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: IDcr"
, ie->id_cr + 4, ie->id_cr_sz - 4)
1623 "responder_recv_HASH_SA_NONCE: IDcr",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: IDcr"
, ie->id_cr + 4, ie->id_cr_sz - 4)
1624 ie->id_cr + ISAKMP_GEN_SZ, ie->id_cr_sz - ISAKMP_GEN_SZ))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: IDcr"
, ie->id_cr + 4, ie->id_cr_sz - 4)
;
1625 } else {
1626 /*
1627 * If client identifiers are not present in the exchange,
1628 * we fake them. RFC 2409 states:
1629 * The identities of the SAs negotiated in Quick Mode are
1630 * implicitly assumed to be the IP addresses of the ISAKMP
1631 * peers, without any constraints on the protocol or port
1632 * numbers allowed, unless client identifiers are specified
1633 * in Quick Mode.
1634 *
1635 * -- Michael Paddon (mwp@aba.net.au)
1636 */
1637
1638 ie->flags = IPSEC_EXCH_FLAG_NO_ID1;
1639
1640 /* Get initiator and responder addresses. */
1641 msg->transport->vtbl->get_src(msg->transport, &src);
1642 msg->transport->vtbl->get_dst(msg->transport, &dst);
1643 ie->id_ci_sz = ISAKMP_ID_DATA_OFF8 + sockaddr_addrlen(src);
1644 ie->id_cr_sz = ISAKMP_ID_DATA_OFF8 + sockaddr_addrlen(dst);
1645 ie->id_ci = calloc(ie->id_ci_sz, sizeof(char));
1646 ie->id_cr = calloc(ie->id_cr_sz, sizeof(char));
1647
1648 if (!ie->id_ci || !ie->id_cr) {
1649 log_error("responder_recv_HASH_SA_NONCE: "
1650 "calloc (%lu, %lu) failed",
1651 (unsigned long)ie->id_ci_sz,
1652 (unsigned long)sizeof(char));
1653 goto cleanup;
1654 }
1655 if (src->sa_family != dst->sa_family) {
1656 log_error("initiator_recv_HASH_SA_NONCE: "
1657 "sa_family mismatch");
1658 goto cleanup;
1659 }
1660 switch (src->sa_family) {
1661 case AF_INET2:
1662 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_ci, 1);
1663 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_cr, 1);
1664 break;
1665
1666 case AF_INET624:
1667 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_ci, 5);
1668 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_cr, 5);
1669 break;
1670
1671 default:
1672 log_error("initiator_recv_HASH_SA_NONCE: "
1673 "unknown sa_family %d", src->sa_family);
1674 goto cleanup;
1675 }
1676
1677 memcpy(ie->id_cr + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(src),
1678 sockaddr_addrlen(src));
1679 memcpy(ie->id_ci + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(dst),
1680 sockaddr_addrlen(dst));
1681 }
1682
1683 if (message_negotiate_sa(msg, check_policy))
1684 goto cleanup;
1685
1686 for (sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first); sa;
1687 sa = TAILQ_NEXT(sa, next)((sa)->next.tqe_next)) {
1688 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto;
1689 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next)) {
1690 /*
1691 * XXX we need to have some attributes per proto, not
1692 * all per SA.
1693 */
1694 ipsec_decode_transform(msg, sa, proto,
1695 proto->chosen->p);
1696 if (proto->proto == IPSEC_PROTO_IPSEC_AH2 &&
1697 !((struct ipsec_proto *)proto->data)->auth) {
1698 log_print("responder_recv_HASH_SA_NONCE: "
1699 "AH proposed without an algorithm "
1700 "attribute");
1701 message_drop(msg,
1702 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN14, 0, 1, 0);
1703 goto next_sa;
1704 }
1705 }
1706
1707 isa = sa->data;
1708
1709 /*
1710 * The group description is mandatory if we got a KEY_EXCH
1711 * payload.
1712 */
1713 if (kep) {
1714 if (!isa->group_desc) {
1715 log_print("responder_recv_HASH_SA_NONCE: "
1716 "KEY_EXCH payload without a group "
1717 "desc. attribute");
1718 message_drop(msg,
1719 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN14, 0, 1, 0);
1720 continue;
1721 }
1722 /* Also, all SAs must have equal groups. */
1723 if (!group_desc)
1724 group_desc = isa->group_desc;
1725 else if (group_desc != isa->group_desc) {
1726 log_print("responder_recv_HASH_SA_NONCE: "
1727 "differing group descriptions in one QM");
1728 message_drop(msg,
1729 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN14, 0, 1, 0);
1730 continue;
1731 }
1732 }
1733 /* At least one SA was accepted. */
1734 retval = 0;
1735
1736next_sa:
1737 ; /* XXX gcc3 wants this. */
1738 }
1739
1740 if (kep) {
1741 ie->group = group_get(group_desc);
1742 if (!ie->group) {
1743 /*
1744 * XXX If the error was due to an out-of-range group
1745 * description we should notify our peer, but this
1746 * should probably be done by the attribute
1747 * validation. Is it?
1748 */
1749 goto cleanup;
1750 }
1751 }
1752 /* Copy out the initiator's nonce. */
1753 if (exchange_save_nonce(msg))
1754 goto cleanup;
1755
1756 /* Handle the optional KEY_EXCH payload. */
1757 if (kep && ipsec_save_g_x(msg))
1758 goto cleanup;
1759
1760 /*
1761 * Try to find and set the connection name on the exchange.
1762 */
1763
1764 /*
1765 * Check for accepted identities as well as lookup the connection
1766 * name and set it on the exchange.
1767 *
1768 * When not using policies make sure the peer proposes sane IDs.
1769 * Otherwise this is done by KeyNote.
1770 */
1771 name = connection_passive_lookup_by_ids(ie->id_ci, ie->id_cr);
1772 if (name) {
1773 exchange->name = strdup(name);
1774 if (!exchange->name) {
1775 log_error("responder_recv_HASH_SA_NONCE: "
1776 "strdup (\"%s\") failed", name);
1777 goto cleanup;
1778 }
1779 } else if (
1780 ignore_policy ||
1781 strncmp("yes", conf_get_str("General", "Use-Keynote"), 3)) {
1782 log_print("responder_recv_HASH_SA_NONCE: peer proposed "
1783 "invalid phase 2 IDs: %s",
1784 (exchange->doi->decode_ids("initiator id %s, responder"
1785 " id %s", ie->id_ci, ie->id_ci_sz, ie->id_cr,
1786 ie->id_cr_sz, 1)));
1787 message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION18, 0, 1,
1788 0);
1789 goto cleanup;
1790 }
1791
1792 return retval;
1793
1794cleanup:
1795 /* Remove all potential protocols that have been added to the SAs. */
1796 for (sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first); sa;
1797 sa = TAILQ_NEXT(sa, next)((sa)->next.tqe_next))
1798 while ((proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first)) != 0)
1799 proto_free(proto);
1800 free(my_hash);
1801 free(ie->id_ci);
1802 ie->id_ci = 0;
1803 free(ie->id_cr);
1804 ie->id_cr = 0;
1805 return -1;
1806}
1807
1808/* Reply with the transform we chose. */
1809static int
1810responder_send_HASH_SA_NONCE(struct message *msg)
1811{
1812 struct exchange *exchange = msg->exchange;
1813 struct ipsec_exch *ie = exchange->data;
1814 struct sa *isakmp_sa = msg->isakmp_sa;
1815 struct ipsec_sa *isa = isakmp_sa->data;
1816 struct prf *prf;
1817 struct hash *hash = hash_get(isa->hash);
1818 size_t nonce_sz = exchange->nonce_i_len;
1819 u_int8_t *buf;
1820 int initiator = exchange->initiator;
1821 char header[80];
1822 u_int32_t i;
1823 u_int8_t *id;
1824 size_t sz;
1825
1826 /*
1827 * We want a HASH payload to start with. XXX Share with
1828 * ike_main_mode.c?
1829 */
1830 buf = malloc(ISAKMP_HASH_SZ4 + hash->hashsize);
1831 if (!buf) {
1832 log_error("responder_send_HASH_SA_NONCE: malloc (%lu) failed",
1833 ISAKMP_HASH_SZ4 + (unsigned long)hash->hashsize);
1834 return -1;
1835 }
1836 if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH8, buf,
1837 ISAKMP_HASH_SZ4 + hash->hashsize, 1)) {
1838 free(buf);
1839 return -1;
1840 }
1841 /* Add the SA payload(s) with the transform(s) that was/were chosen. */
1842 if (message_add_sa_payload(msg))
1843 return -1;
1844
1845 /* Generate a nonce, and add it to the message. */
1846 if (exchange_gen_nonce(msg, nonce_sz))
1847 return -1;
1848
1849 /* Generate optional KEY_EXCH payload. This is known as PFS. */
1850 if (ie->group && ipsec_gen_g_x(msg))
1851 return -1;
1852
1853 /*
1854 * If the initiator client ID's were acceptable, just mirror them
1855 * back.
1856 */
1857 if (!(ie->flags & IPSEC_EXCH_FLAG_NO_ID1)) {
1858 sz = ie->id_ci_sz;
1859 id = malloc(sz);
1860 if (!id) {
1861 log_error("responder_send_HASH_SA_NONCE: "
1862 "malloc (%lu) failed", (unsigned long)sz);
1863 return -1;
1864 }
1865 memcpy(id, ie->id_ci, sz);
1866 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDic"
, id, sz)
1867 "responder_send_HASH_SA_NONCE: IDic", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDic"
, id, sz)
;
1868 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
1869 free(id);
1870 return -1;
1871 }
1872 sz = ie->id_cr_sz;
1873 id = malloc(sz);
1874 if (!id) {
1875 log_error("responder_send_HASH_SA_NONCE: "
1876 "malloc (%lu) failed", (unsigned long)sz);
1877 return -1;
1878 }
1879 memcpy(id, ie->id_cr, sz);
1880 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDrc"
, id, sz)
1881 "responder_send_HASH_SA_NONCE: IDrc", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDrc"
, id, sz)
;
1882 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
1883 free(id);
1884 return -1;
1885 }
1886 }
1887 /* Allocate the prf and start calculating our HASH(2). XXX Share? */
1888 LOG_DBG((LOG_NEGOTIATION, 90, "responder_recv_HASH: "log_debug (LOG_NEGOTIATION, 90, "responder_recv_HASH: " "isakmp_sa %p isa %p"
, isakmp_sa, isa)
1889 "isakmp_sa %p isa %p", isakmp_sa, isa))log_debug (LOG_NEGOTIATION, 90, "responder_recv_HASH: " "isakmp_sa %p isa %p"
, isakmp_sa, isa)
;
1890 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: "log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: "
"SKEYID_a", isa->skeyid_a, isa->skeyid_len)
1891 "SKEYID_a", isa->skeyid_a, isa->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: "
"SKEYID_a", isa->skeyid_a, isa->skeyid_len)
;
1892 prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a,
1893 isa->skeyid_len);
1894 if (!prf)
1895 return -1;
1896 prf->Init(prf->prfctx);
1897 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1898 "responder_send_HASH_SA_NONCE: message_id",log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1899 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN))log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
;
1900 prf->Update(prf->prfctx, exchange->message_id,
1901 ISAKMP_HDR_MESSAGE_ID_LEN4);
1902 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: "log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: "
"NONCE_I_b", exchange->nonce_i, exchange->nonce_i_len)
1903 "NONCE_I_b", exchange->nonce_i, exchange->nonce_i_len))log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: "
"NONCE_I_b", exchange->nonce_i, exchange->nonce_i_len)
;
1904 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
1905
1906 /* Loop over all payloads after HASH(2). */
1907 for (i = 2; i < msg->iovlen; i++) {
1908 /* XXX Misleading payload type printouts. */
1909 snprintf(header, sizeof header,
1910 "responder_send_HASH_SA_NONCE: payload %d after HASH(2)",
1911 i - 1);
1912 LOG_DBG_BUF((LOG_NEGOTIATION, 90, header, msg->iov[i].iov_base,log_debug_buf (LOG_NEGOTIATION, 90, header, msg->iov[i].iov_base
, msg->iov[i].iov_len)
1913 msg->iov[i].iov_len))log_debug_buf (LOG_NEGOTIATION, 90, header, msg->iov[i].iov_base
, msg->iov[i].iov_len)
;
1914 prf->Update(prf->prfctx, msg->iov[i].iov_base,
1915 msg->iov[i].iov_len);
1916 }
1917 prf->Final(buf + ISAKMP_HASH_DATA_OFF4, prf->prfctx);
1918 prf_free(prf);
1919 snprintf(header, sizeof header, "responder_send_HASH_SA_NONCE: "
1920 "HASH_%c", initiator ? 'I' : 'R');
1921 LOG_DBG_BUF((LOG_NEGOTIATION, 80, header, buf + ISAKMP_HASH_DATA_OFF,log_debug_buf (LOG_NEGOTIATION, 80, header, buf + 4, hash->
hashsize)
1922 hash->hashsize))log_debug_buf (LOG_NEGOTIATION, 80, header, buf + 4, hash->
hashsize)
;
1923
1924 if (ie->group)
1925 message_register_post_send(msg, gen_g_xy);
1926
1927 return 0;
1928}
1929
1930static void
1931gen_g_xy(struct message *msg)
1932{
1933 struct exchange *exchange = msg->exchange;
1934 struct ipsec_exch *ie = exchange->data;
1935
1936 /* Compute Diffie-Hellman shared value. */
1937 ie->g_xy_len = dh_secretlen(ie->group);
1938 ie->g_xy = malloc(ie->g_xy_len);
1939 if (!ie->g_xy) {
1940 log_error("gen_g_xy: malloc (%lu) failed",
1941 (unsigned long)ie->g_xy_len);
1942 return;
1943 }
1944 if (dh_create_shared(ie->group, ie->g_xy,
1945 exchange->initiator ? ie->g_xr : ie->g_xi)) {
1946 log_print("gen_g_xy: dh_create_shared failed");
1947 return;
1948 }
1949 LOG_DBG_BUF((LOG_NEGOTIATION, 80, "gen_g_xy: g^xy", ie->g_xy,log_debug_buf (LOG_NEGOTIATION, 80, "gen_g_xy: g^xy", ie->
g_xy, ie->g_xy_len)
1950 ie->g_xy_len))log_debug_buf (LOG_NEGOTIATION, 80, "gen_g_xy: g^xy", ie->
g_xy, ie->g_xy_len)
;
1951}
1952
1953static int
1954responder_recv_HASH(struct message *msg)
1955{
1956 struct exchange *exchange = msg->exchange;
1957 struct sa *isakmp_sa = msg->isakmp_sa;
1958 struct ipsec_sa *isa = isakmp_sa->data;
1959 struct prf *prf;
1960 u_int8_t *hash, *my_hash = 0;
1961 size_t hash_len;
1962 struct payload *hashp;
1963
1964 /* Find HASH(3) and create our own hash, just as big. */
1965 hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH8);
1966 hash = hashp->p;
1967 hashp->flags |= PL_MARK1;
1968 hash_len = GET_ISAKMP_GEN_LENGTH(hash)field_get_num (isakmp_gen_fld + 2, hash);
1969 my_hash = malloc(hash_len - ISAKMP_GEN_SZ4);
1970 if (!my_hash) {
1971 log_error("responder_recv_HASH: malloc (%lu) failed",
1972 (unsigned long)hash_len - ISAKMP_GEN_SZ4);
1973 goto cleanup;
1974 }
1975 /* Allocate the prf and start calculating our HASH(3). XXX Share? */
1976 LOG_DBG((LOG_NEGOTIATION, 90, "responder_recv_HASH: "log_debug (LOG_NEGOTIATION, 90, "responder_recv_HASH: " "isakmp_sa %p isa %p"
, isakmp_sa, isa)
1977 "isakmp_sa %p isa %p", isakmp_sa, isa))log_debug (LOG_NEGOTIATION, 90, "responder_recv_HASH: " "isakmp_sa %p isa %p"
, isakmp_sa, isa)
;
1978 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: SKEYID_a",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: SKEYID_a"
, isa->skeyid_a, isa->skeyid_len)
1979 isa->skeyid_a, isa->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: SKEYID_a"
, isa->skeyid_a, isa->skeyid_len)
;
1980 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a,
1981 isa->skeyid_len);
1982 if (!prf)
1983 goto cleanup;
1984 prf->Init(prf->prfctx);
1985 prf->Update(prf->prfctx, (unsigned char *)"\0", 1);
1986 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: message_id",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: message_id"
, exchange->message_id, 4)
1987 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: message_id"
, exchange->message_id, 4)
;
1988 prf->Update(prf->prfctx, exchange->message_id,
1989 ISAKMP_HDR_MESSAGE_ID_LEN4);
1990 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_I_b",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_I_b"
, exchange->nonce_i, exchange->nonce_i_len)
1991 exchange->nonce_i, exchange->nonce_i_len))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_I_b"
, exchange->nonce_i, exchange->nonce_i_len)
;
1992 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
1993 LOG_DBG_BUF((LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_R_b",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_R_b"
, exchange->nonce_r, exchange->nonce_r_len)
1994 exchange->nonce_r, exchange->nonce_r_len))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: NONCE_R_b"
, exchange->nonce_r, exchange->nonce_r_len)
;
1995 prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
1996 prf->Final(my_hash, prf->prfctx);
1997 prf_free(prf);
1998 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: computed HASH(3)"
, my_hash, hash_len - 4)
1999 "responder_recv_HASH: computed HASH(3)", my_hash,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: computed HASH(3)"
, my_hash, hash_len - 4)
2000 hash_len - ISAKMP_GEN_SZ))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: computed HASH(3)"
, my_hash, hash_len - 4)
;
2001 if (memcmp(hash + ISAKMP_GEN_SZ4, my_hash, hash_len - ISAKMP_GEN_SZ4)
2002 != 0) {
2003 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION23, 0,
2004 1, 0);
2005 goto cleanup;
2006 }
2007 free(my_hash);
2008
2009 /* Mark message as authenticated. */
2010 msg->flags |= MSG_AUTHENTICATED0x10;
2011
2012 post_quick_mode(msg);
2013
2014 return 0;
2015
2016cleanup:
2017 free(my_hash);
2018 return -1;
2019}