Bug Summary

File:src/sbin/isakmpd/ike_quick_mode.c
Warning:line 356, column 7
Array access (from variable 'keynote_ids') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ike_quick_mode.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/llvm16/lib/clang/16 -I /usr/src/sbin/isakmpd -I . -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/sbin/isakmpd/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/sbin/isakmpd/ike_quick_mode.c
1/* $OpenBSD: ike_quick_mode.c,v 1.115 2023/03/31 20:16:55 tb 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;
22
'keynote_ids' initialized to a null pointer value
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 ||
23
Assuming 'ignore_policy' is 0
25
Taking false branch
103 strncmp("yes", conf_get_str("General", "Use-Keynote"), 3))
24
Assuming the condition is false
104 return 1;
105
106 /* Initialize if necessary -- e.g., if pre-shared key auth was used */
107 if (isakmp_sa->policy_id < 0) {
26
Assuming field 'policy_id' is >= 0
27
Taking false branch
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,
28
Assuming the condition is false
29
Taking false branch
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) {
30
Assuming 'policy_asserts_num' is 0
31
Taking false branch
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++)
32
Loop condition is false. Execution continues on line 142
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) {
33
Control jumps to the 'default' case at line 294
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;
34
Control jumps to line 348
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++)
35
Loop condition is false. Execution continues on line 352
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++) {
36
Assuming 'i' is < 'policy_asserts_num'
37
Loop condition is true. Entering loop body
356 if (keynote_ids[i] != -1)
38
Array access (from variable 'keynote_ids') results in a null pointer dereference
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 if (!ie->group)
897 return -1;
898 ie->g_x_len = dh_getlen(ie->group);
899
900 if (ipsec_gen_g_x(msg)) {
901 group_free(ie->group);
902 ie->group = 0;
903 return -1;
904 }
905 }
906 /* Generate optional client ID payloads. XXX Share with responder. */
907 local_id = conf_get_str(exchange->name, "Local-ID");
908 remote_id = conf_get_str(exchange->name, "Remote-ID");
909 if (local_id && remote_id) {
910 id = ipsec_build_id(local_id, &sz);
911 if (!id)
912 return -1;
913 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic"
, id, sz)
914 "initiator_send_HASH_SA_NONCE: IDic", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic"
, id, sz)
;
915 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
916 free(id);
917 return -1;
918 }
919 id = ipsec_build_id(remote_id, &sz);
920 if (!id)
921 return -1;
922 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc"
, id, sz)
923 "initiator_send_HASH_SA_NONCE: IDrc", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc"
, id, sz)
;
924 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
925 free(id);
926 return -1;
927 }
928 }
929 /* XXX I do not judge these as errors, are they? */
930 else if (local_id)
931 log_print("initiator_send_HASH_SA_NONCE: "
932 "Local-ID given without Remote-ID for \"%s\"",
933 exchange->name);
934 else if (remote_id)
935 /*
936 * This code supports the "road warrior" case, where the
937 * initiator doesn't have a fixed IP address, but wants to
938 * specify a particular remote network to talk to. -- Adrian
939 * Close <adrian@esec.com.au>
940 */
941 {
942 log_print("initiator_send_HASH_SA_NONCE: "
943 "Remote-ID given without Local-ID for \"%s\"",
944 exchange->name);
945
946 /*
947 * If we're here, then we are the initiator, so use initiator
948 * address for local ID
949 */
950 msg->transport->vtbl->get_src(msg->transport, &src);
951 sz = ISAKMP_ID_SZ8 + sockaddr_addrlen(src);
952
953 id = calloc(sz, sizeof(char));
954 if (!id) {
955 log_error("initiator_send_HASH_SA_NONCE: "
956 "calloc (%lu, %lu) failed", (unsigned long)sz,
957 (unsigned long)sizeof(char));
958 return -1;
959 }
960 switch (src->sa_family) {
961 case AF_INET624:
962 SET_ISAKMP_ID_TYPE(id, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, id, 5);
963 break;
964 case AF_INET2:
965 SET_ISAKMP_ID_TYPE(id, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, id, 1);
966 break;
967 default:
968 log_error("initiator_send_HASH_SA_NONCE: "
969 "unknown sa_family %d", src->sa_family);
970 free(id);
971 return -1;
972 }
973 memcpy(id + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(src),
974 sockaddr_addrlen(src));
975
976 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic"
, id, sz)
977 "initiator_send_HASH_SA_NONCE: IDic", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDic"
, id, sz)
;
978 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
979 free(id);
980 return -1;
981 }
982 /* Send supplied remote_id */
983 id = ipsec_build_id(remote_id, &sz);
984 if (!id)
985 return -1;
986 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc"
, id, sz)
987 "initiator_send_HASH_SA_NONCE: IDrc", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH_SA_NONCE: IDrc"
, id, sz)
;
988 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
989 free(id);
990 return -1;
991 }
992 }
993 if (ipsec_fill_in_hash(msg))
994 goto bail_out;
995
996 conf_free_list(suite_conf);
997 for (i = 0; i < prop_no; i++) {
998 free(transform[i]);
999 free(transform_len[i]);
1000 }
1001 free(proposal);
1002 free(transform);
1003 free(transforms_len);
1004 free(transform_len);
1005 free(transform_cnt);
1006 return 0;
1007
1008bail_out:
1009 free(sa_buf);
1010 if (proposal) {
1011 for (i = 0; i < prop_no; i++) {
1012 free(proposal[i]);
1013 if (transform[i]) {
1014 for (xf_no = 0; xf_no < transform_cnt[i];
1015 xf_no++)
1016 free(transform[i][xf_no]);
1017 free(transform[i]);
1018 }
1019 free(transform_len[i]);
1020 }
1021 free(proposal);
1022 free(transforms_len);
1023 free(transform);
1024 free(transform_len);
1025 free(transform_cnt);
1026 }
1027 if (xf_conf)
1028 conf_free_list(xf_conf);
1029 if (prot_conf)
1030 conf_free_list(prot_conf);
1031 conf_free_list(suite_conf);
1032 return -1;
1033}
1034
1035/* Figure out what transform the responder chose. */
1036static int
1037initiator_recv_HASH_SA_NONCE(struct message *msg)
1038{
1039 struct exchange *exchange = msg->exchange;
1040 struct ipsec_exch *ie = exchange->data;
1041 struct sa *sa;
1042 struct proto *proto, *next_proto;
1043 struct payload *sa_p = payload_first(msg, ISAKMP_PAYLOAD_SA1);
1044 struct payload *xf, *idp;
1045 struct payload *hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH8);
1046 struct payload *kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH4);
1047 struct prf *prf;
1048 struct sa *isakmp_sa = msg->isakmp_sa;
1049 struct ipsec_sa *isa = isakmp_sa->data;
1050 struct hash *hash = hash_get(isa->hash);
1051 u_int8_t *rest;
1052 size_t rest_len;
1053 struct sockaddr *src, *dst;
1054
1055 /* Allocate the prf and start calculating our HASH(1). XXX Share? */
1056 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
)
1057 "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
)
;
1058 prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a,
1059 isa->skeyid_len);
1060 if (!prf)
1
Assuming 'prf' is non-null
2
Taking false branch
1061 return -1;
1062
1063 prf->Init(prf->prfctx);
1064 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1065 "initiator_recv_HASH_SA_NONCE: message_id",log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1066 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)
;
1067 prf->Update(prf->prfctx, exchange->message_id,
1068 ISAKMP_HDR_MESSAGE_ID_LEN4);
1069 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)
1070 "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)
;
1071 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
1072 rest = hashp->p + GET_ISAKMP_GEN_LENGTH(hashp->p)field_get_num (isakmp_gen_fld + 2, hashp->p);
1073 rest_len = (GET_ISAKMP_HDR_LENGTH(msg->iov[0].iov_base)field_get_num (isakmp_hdr_fld + 7, msg->iov[0].iov_base)
1074 - (rest - (u_int8_t *)msg->iov[0].iov_base));
1075 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)"
, rest, rest_len)
1076 "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)
1077 rest_len))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_recv_HASH_SA_NONCE: payloads after HASH(2)"
, rest, rest_len)
;
1078 prf->Update(prf->prfctx, rest, rest_len);
1079 prf->Final(hash->digest, prf->prfctx);
1080 prf_free(prf);
1081 LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "initiator_recv_HASH_SA_NONCE: computed HASH(2)"
, hash->digest, hash->hashsize)
1082 "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)
1083 hash->hashsize))log_debug_buf (LOG_NEGOTIATION, 80, "initiator_recv_HASH_SA_NONCE: computed HASH(2)"
, hash->digest, hash->hashsize)
;
1084 if (memcmp(hashp->p + ISAKMP_HASH_DATA_OFF4, hash->digest,
3
Taking false branch
1085 hash->hashsize) != 0) {
1086 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION23, 0, 1,
1087 0);
1088 return -1;
1089 }
1090 /* Mark the HASH as handled. */
1091 hashp->flags |= PL_MARK1;
1092
1093 /* Mark message as authenticated. */
1094 msg->flags |= MSG_AUTHENTICATED0x10;
1095
1096 /*
1097 * As we are getting an answer on our transform offer, only one
1098 * transform should be given.
1099 *
1100 * XXX Currently we only support negotiating one SA per quick mode run.
1101 */
1102 if (TAILQ_NEXT(sa_p, link)((sa_p)->link.tqe_next)) {
4
Assuming field 'tqe_next' is null
5
Taking false branch
1103 log_print("initiator_recv_HASH_SA_NONCE: "
1104 "multiple SA payloads in quick mode not supported yet");
1105 return -1;
1106 }
1107 sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first);
1108
1109 /* This is here for the policy check */
1110 if (kep)
6
Assuming 'kep' is null
7
Taking false branch
1111 ie->pfs = 1;
1112
1113 /* Drop message when it contains ID types we do not implement yet. */
1114 TAILQ_FOREACH(idp, &msg->payload[ISAKMP_PAYLOAD_ID], link)for((idp) = ((&msg->payload[5])->tqh_first); (idp) !=
((void *)0); (idp) = ((idp)->link.tqe_next))
{
8
Assuming 'idp' is equal to null
9
Loop condition is false. Execution continues on line 1138
1115 switch (GET_ISAKMP_ID_TYPE(idp->p)field_get_num (isakmp_id_fld + 0, idp->p)) {
1116 case IPSEC_ID_IPV4_ADDR1:
1117 case IPSEC_ID_IPV4_ADDR_SUBNET4:
1118 case IPSEC_ID_IPV6_ADDR5:
1119 case IPSEC_ID_IPV6_ADDR_SUBNET6:
1120 break;
1121
1122 case IPSEC_ID_FQDN2:
1123 /*
1124 * FQDN may be used for in NAT-T with transport mode.
1125 * We can handle the message in this case. In the
1126 * other cases we'll drop the message later.
1127 */
1128 break;
1129
1130 default:
1131 message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION18,
1132 0, 1, 0);
1133 return -1;
1134 }
1135 }
1136
1137 /* Handle optional client ID payloads. */
1138 idp = payload_first(msg, ISAKMP_PAYLOAD_ID5);
1139 if (idp) {
10
Assuming 'idp' is null
11
Taking false branch
1140 /* If IDci is there, IDcr must be too. */
1141 if (!TAILQ_NEXT(idp, link)((idp)->link.tqe_next)) {
1142 /* XXX Is this a good notify type? */
1143 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0,
1144 1, 0);
1145 return -1;
1146 }
1147 /* XXX We should really compare, not override. */
1148 ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH(idp->p)field_get_num (isakmp_gen_fld + 2, idp->p);
1149 ie->id_ci = malloc(ie->id_ci_sz);
1150 if (!ie->id_ci) {
1151 log_error("initiator_recv_HASH_SA_NONCE: "
1152 "malloc (%lu) failed",
1153 (unsigned long)ie->id_ci_sz);
1154 return -1;
1155 }
1156 memcpy(ie->id_ci, idp->p, ie->id_ci_sz);
1157 idp->flags |= PL_MARK1;
1158 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)
1159 "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)
1160 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)
;
1161
1162 idp = TAILQ_NEXT(idp, link)((idp)->link.tqe_next);
1163 ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH(idp->p)field_get_num (isakmp_gen_fld + 2, idp->p);
1164 ie->id_cr = malloc(ie->id_cr_sz);
1165 if (!ie->id_cr) {
1166 log_error("initiator_recv_HASH_SA_NONCE: "
1167 "malloc (%lu) failed",
1168 (unsigned long)ie->id_cr_sz);
1169 return -1;
1170 }
1171 memcpy(ie->id_cr, idp->p, ie->id_cr_sz);
1172 idp->flags |= PL_MARK1;
1173 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)
1174 "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)
1175 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)
;
1176 } else {
1177 /*
1178 * If client identifiers are not present in the exchange,
1179 * we fake them. RFC 2409 states:
1180 * The identities of the SAs negotiated in Quick Mode are
1181 * implicitly assumed to be the IP addresses of the ISAKMP
1182 * peers, without any constraints on the protocol or port
1183 * numbers allowed, unless client identifiers are specified
1184 * in Quick Mode.
1185 *
1186 * -- Michael Paddon (mwp@aba.net.au)
1187 */
1188
1189 ie->flags = IPSEC_EXCH_FLAG_NO_ID1;
1190
1191 /* Get initiator and responder addresses. */
1192 msg->transport->vtbl->get_src(msg->transport, &src);
1193 msg->transport->vtbl->get_dst(msg->transport, &dst);
1194 ie->id_ci_sz = ISAKMP_ID_DATA_OFF8 + sockaddr_addrlen(src);
1195 ie->id_cr_sz = ISAKMP_ID_DATA_OFF8 + sockaddr_addrlen(dst);
1196 ie->id_ci = calloc(ie->id_ci_sz, sizeof(char));
1197 ie->id_cr = calloc(ie->id_cr_sz, sizeof(char));
1198
1199 if (!ie->id_ci || !ie->id_cr) {
12
Assuming field 'id_ci' is non-null
13
Assuming field 'id_cr' is non-null
14
Taking false branch
1200 log_error("initiator_recv_HASH_SA_NONCE: "
1201 "calloc (%lu, %lu) failed",
1202 (unsigned long)ie->id_cr_sz,
1203 (unsigned long)sizeof(char));
1204 free(ie->id_ci);
1205 ie->id_ci = 0;
1206 free(ie->id_cr);
1207 ie->id_cr = 0;
1208 return -1;
1209 }
1210 if (src->sa_family != dst->sa_family) {
15
Assuming 'src->sa_family' is equal to 'dst->sa_family'
16
Taking false branch
1211 log_error("initiator_recv_HASH_SA_NONCE: "
1212 "sa_family mismatch");
1213 free(ie->id_ci);
1214 ie->id_ci = 0;
1215 free(ie->id_cr);
1216 ie->id_cr = 0;
1217 return -1;
1218 }
1219 switch (src->sa_family) {
17
Control jumps to 'case 24:' at line 1225
1220 case AF_INET2:
1221 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_ci, 1);
1222 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_cr, 1);
1223 break;
1224
1225 case AF_INET624:
1226 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_ci, 5);
1227 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_cr, 5);
1228 break;
1229
1230 default:
1231 log_error("initiator_recv_HASH_SA_NONCE: "
1232 "unknown sa_family %d", src->sa_family);
1233 free(ie->id_ci);
1234 ie->id_ci = 0;
1235 free(ie->id_cr);
1236 ie->id_cr = 0;
1237 return -1;
1238 }
1239 memcpy(ie->id_ci + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(src),
1240 sockaddr_addrlen(src));
1241 memcpy(ie->id_cr + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(dst),
1242 sockaddr_addrlen(dst));
1243 }
1244
1245 /* Build the protection suite in our SA. */
1246 TAILQ_FOREACH(xf, &msg->payload[ISAKMP_PAYLOAD_TRANSFORM], link)for((xf) = ((&msg->payload[3])->tqh_first); (xf) !=
((void *)0); (xf) = ((xf)->link.tqe_next))
{
18
Assuming 'xf' is equal to null
19
Loop condition is false. Execution continues on line 1261
1247 /*
1248 * XXX We could check that the proposal each transform
1249 * belongs to is unique.
1250 */
1251
1252 if (sa_add_transform(sa, xf, exchange->initiator, &proto))
1253 return -1;
1254
1255 /* XXX Check that the chosen transform matches an offer. */
1256
1257 ipsec_decode_transform(msg, sa, proto, xf->p);
1258 }
1259
1260 /* Now remove offers that we don't need anymore. */
1261 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto; proto = next_proto) {
20
Loop condition is false. Execution continues on line 1267
1262 next_proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next);
1263 if (!proto->chosen)
1264 proto_free(proto);
1265 }
1266
1267 if (!check_policy(exchange, sa, msg->isakmp_sa)) {
21
Calling 'check_policy'
1268 message_drop(msg, ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN14, 0, 1, 0);
1269 log_print("initiator_recv_HASH_SA_NONCE: policy check failed");
1270 return -1;
1271 }
1272
1273 /* Mark the SA as handled. */
1274 sa_p->flags |= PL_MARK1;
1275
1276 isa = sa->data;
1277 if ((isa->group_desc &&
1278 (!ie->group || ie->group->id != isa->group_desc)) ||
1279 (!isa->group_desc && ie->group)) {
1280 log_print("initiator_recv_HASH_SA_NONCE: disagreement on PFS");
1281 return -1;
1282 }
1283 /* Copy out the initiator's nonce. */
1284 if (exchange_save_nonce(msg))
1285 return -1;
1286
1287 /* Handle the optional KEY_EXCH payload. */
1288 if (kep && ipsec_save_g_x(msg))
1289 return -1;
1290
1291 return 0;
1292}
1293
1294static int
1295initiator_send_HASH(struct message *msg)
1296{
1297 struct exchange *exchange = msg->exchange;
1298 struct ipsec_exch *ie = exchange->data;
1299 struct sa *isakmp_sa = msg->isakmp_sa;
1300 struct ipsec_sa *isa = isakmp_sa->data;
1301 struct prf *prf;
1302 u_int8_t *buf;
1303 struct hash *hash = hash_get(isa->hash);
1304
1305 /*
1306 * We want a HASH payload to start with. XXX Share with
1307 * ike_main_mode.c?
1308 */
1309 buf = malloc(ISAKMP_HASH_SZ4 + hash->hashsize);
1310 if (!buf) {
1311 log_error("initiator_send_HASH: malloc (%lu) failed",
1312 ISAKMP_HASH_SZ4 + (unsigned long)hash->hashsize);
1313 return -1;
1314 }
1315 if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH8, buf,
1316 ISAKMP_HASH_SZ4 + hash->hashsize, 1)) {
1317 free(buf);
1318 return -1;
1319 }
1320 /* Allocate the prf and start calculating our HASH(3). XXX Share? */
1321 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)
1322 isa->skeyid_a, isa->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: SKEYID_a"
, isa->skeyid_a, isa->skeyid_len)
;
1323 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a,
1324 isa->skeyid_len);
1325 if (!prf)
1326 return -1;
1327 prf->Init(prf->prfctx);
1328 prf->Update(prf->prfctx, (unsigned char *)"\0", 1);
1329 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)
1330 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: message_id"
, exchange->message_id, 4)
;
1331 prf->Update(prf->prfctx, exchange->message_id,
1332 ISAKMP_HDR_MESSAGE_ID_LEN4);
1333 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)
1334 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)
;
1335 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
1336 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)
1337 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)
;
1338 prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
1339 prf->Final(buf + ISAKMP_GEN_SZ4, prf->prfctx);
1340 prf_free(prf);
1341 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)
1342 buf + ISAKMP_GEN_SZ, hash->hashsize))log_debug_buf (LOG_NEGOTIATION, 90, "initiator_send_HASH: HASH(3)"
, buf + 4, hash->hashsize)
;
1343
1344 if (ie->group)
1345 message_register_post_send(msg, gen_g_xy);
1346
1347 message_register_post_send(msg, post_quick_mode);
1348
1349 return 0;
1350}
1351
1352static void
1353post_quick_mode(struct message *msg)
1354{
1355 struct sa *isakmp_sa = msg->isakmp_sa;
1356 struct ipsec_sa *isa = isakmp_sa->data;
1357 struct exchange *exchange = msg->exchange;
1358 struct ipsec_exch *ie = exchange->data;
1359 struct prf *prf;
1360 struct sa *sa;
1361 struct proto *proto;
1362 struct ipsec_proto *iproto;
1363 u_int8_t *keymat;
1364 int i;
1365
1366 /*
1367 * Loop over all SA negotiations and do both an in- and an outgoing SA
1368 * per protocol.
1369 */
1370 for (sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first); sa;
1371 sa = TAILQ_NEXT(sa, next)((sa)->next.tqe_next)) {
1372 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto;
1373 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next)) {
1374 if (proto->proto == IPSEC_PROTO_IPCOMP4)
1375 continue;
1376
1377 iproto = proto->data;
1378
1379 /*
1380 * There are two SAs for each SA negotiation,
1381 * incoming and outgoing.
1382 */
1383 for (i = 0; i < 2; i++) {
1384 prf = prf_alloc(isa->prf_type, isa->hash,
1385 isa->skeyid_d, isa->skeyid_len);
1386 if (!prf) {
1387 /* XXX What to do? */
1388 continue;
1389 }
1390 ie->keymat_len = ipsec_keymat_length(proto);
1391
1392 /*
1393 * We need to roundup the length of the key
1394 * material buffer to a multiple of the PRF's
1395 * blocksize as it is generated in chunks of
1396 * that blocksize.
1397 */
1398 iproto->keymat[i]
1399 = malloc(((ie->keymat_len + prf->blocksize - 1)
1400 / prf->blocksize) * prf->blocksize);
1401 if (!iproto->keymat[i]) {
1402 log_error("post_quick_mode: "
1403 "malloc (%lu) failed",
1404 (((unsigned long)ie->keymat_len +
1405 prf->blocksize - 1) / prf->blocksize) *
1406 prf->blocksize);
1407 /* XXX What more to do? */
1408 free(prf);
1409 continue;
1410 }
1411 for (keymat = iproto->keymat[i];
1412 keymat < iproto->keymat[i] + ie->keymat_len;
1413 keymat += prf->blocksize) {
1414 prf->Init(prf->prfctx);
1415
1416 if (keymat != iproto->keymat[i]) {
1417 /*
1418 * Hash in last round's
1419 * KEYMAT.
1420 */
1421 LOG_DBG_BUF((LOG_NEGOTIATION,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
1422 90, "post_quick_mode: "log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
1423 "last KEYMAT",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
1424 keymat - prf->blocksize,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
1425 prf->blocksize))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "last KEYMAT"
, keymat - prf->blocksize, prf->blocksize)
;
1426 prf->Update(prf->prfctx,
1427 keymat - prf->blocksize,
1428 prf->blocksize);
1429 }
1430 /* If PFS is used hash in g^xy. */
1431 if (ie->g_xy) {
1432 LOG_DBG_BUF((LOG_NEGOTIATION,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "g^xy"
, ie->g_xy, ie->g_xy_len)
1433 90, "post_quick_mode: "log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "g^xy"
, ie->g_xy, ie->g_xy_len)
1434 "g^xy", ie->g_xy,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "g^xy"
, ie->g_xy, ie->g_xy_len)
1435 ie->g_xy_len))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: " "g^xy"
, ie->g_xy, ie->g_xy_len)
;
1436 prf->Update(prf->prfctx,
1437 ie->g_xy, ie->g_xy_len);
1438 }
1439 LOG_DBG((LOG_NEGOTIATION, 90,log_debug (LOG_NEGOTIATION, 90, "post_quick_mode: " "suite %d proto %d"
, proto->no, proto->proto)
1440 "post_quick_mode: "log_debug (LOG_NEGOTIATION, 90, "post_quick_mode: " "suite %d proto %d"
, proto->no, proto->proto)
1441 "suite %d proto %d", proto->no,log_debug (LOG_NEGOTIATION, 90, "post_quick_mode: " "suite %d proto %d"
, proto->no, proto->proto)
1442 proto->proto))log_debug (LOG_NEGOTIATION, 90, "post_quick_mode: " "suite %d proto %d"
, proto->no, proto->proto)
;
1443 prf->Update(prf->prfctx, &proto->proto,
1444 1);
1445 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: SPI", proto
->spi[i], proto->spi_sz[i])
1446 "post_quick_mode: SPI",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: SPI", proto
->spi[i], proto->spi_sz[i])
1447 proto->spi[i], proto->spi_sz[i]))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: SPI", proto
->spi[i], proto->spi_sz[i])
;
1448 prf->Update(prf->prfctx,
1449 proto->spi[i], proto->spi_sz[i]);
1450 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b", exchange
->nonce_i, exchange->nonce_i_len)
1451 "post_quick_mode: Ni_b",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b", exchange
->nonce_i, exchange->nonce_i_len)
1452 exchange->nonce_i,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b", exchange
->nonce_i, exchange->nonce_i_len)
1453 exchange->nonce_i_len))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Ni_b", exchange
->nonce_i, exchange->nonce_i_len)
;
1454 prf->Update(prf->prfctx,
1455 exchange->nonce_i,
1456 exchange->nonce_i_len);
1457 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b", exchange
->nonce_r, exchange->nonce_r_len)
1458 "post_quick_mode: Nr_b",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b", exchange
->nonce_r, exchange->nonce_r_len)
1459 exchange->nonce_r,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b", exchange
->nonce_r, exchange->nonce_r_len)
1460 exchange->nonce_r_len))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: Nr_b", exchange
->nonce_r, exchange->nonce_r_len)
;
1461 prf->Update(prf->prfctx,
1462 exchange->nonce_r,
1463 exchange->nonce_r_len);
1464 prf->Final(keymat, prf->prfctx);
1465 }
1466 prf_free(prf);
1467 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: KEYMAT"
, iproto->keymat[i], ie->keymat_len)
1468 "post_quick_mode: KEYMAT",log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: KEYMAT"
, iproto->keymat[i], ie->keymat_len)
1469 iproto->keymat[i], ie->keymat_len))log_debug_buf (LOG_NEGOTIATION, 90, "post_quick_mode: KEYMAT"
, iproto->keymat[i], ie->keymat_len)
;
1470 }
1471 }
1472 }
1473
1474 log_verbose("isakmpd: quick mode done%s: %s",
1475 (exchange->initiator == 0) ? " (as responder)" : "",
1476 !msg->isakmp_sa || !msg->isakmp_sa->transport ? "<no transport>"
1477 : msg->isakmp_sa->transport->vtbl->decode_ids
1478 (msg->isakmp_sa->transport));
1479}
1480
1481/*
1482 * Accept a set of transforms offered by the initiator and chose one we can
1483 * handle.
1484 * XXX Describe in more detail.
1485 */
1486static int
1487responder_recv_HASH_SA_NONCE(struct message *msg)
1488{
1489 struct payload *hashp, *kep, *idp;
1490 struct sa *sa;
1491 struct sa *isakmp_sa = msg->isakmp_sa;
1492 struct ipsec_sa *isa = isakmp_sa->data;
1493 struct exchange *exchange = msg->exchange;
1494 struct ipsec_exch *ie = exchange->data;
1495 struct prf *prf;
1496 u_int8_t *hash, *my_hash = 0;
1497 size_t hash_len;
1498 u_int8_t *pkt = msg->iov[0].iov_base;
1499 u_int8_t group_desc = 0;
1500 int retval = -1;
1501 struct proto *proto;
1502 struct sockaddr *src, *dst;
1503 char *name;
1504
1505 hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH8);
1506 hash = hashp->p;
1507 hashp->flags |= PL_MARK1;
1508
1509 /* The HASH payload should be the first one. */
1510 if (hash != pkt + ISAKMP_HDR_SZ28) {
1511 /* XXX Is there a better notification type? */
1512 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0, 1, 0);
1513 goto cleanup;
1514 }
1515 hash_len = GET_ISAKMP_GEN_LENGTH(hash)field_get_num (isakmp_gen_fld + 2, hash);
1516 my_hash = malloc(hash_len - ISAKMP_GEN_SZ4);
1517 if (!my_hash) {
1518 log_error("responder_recv_HASH_SA_NONCE: malloc (%lu) failed",
1519 (unsigned long)hash_len - ISAKMP_GEN_SZ4);
1520 goto cleanup;
1521 }
1522 /*
1523 * Check the payload's integrity.
1524 * XXX Share with ipsec_fill_in_hash?
1525 */
1526 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)
1527 "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)
;
1528 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a,
1529 isa->skeyid_len);
1530 if (!prf)
1531 goto cleanup;
1532 prf->Init(prf->prfctx);
1533 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1534 "responder_recv_HASH_SA_NONCE: message_id",log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1535 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)
;
1536 prf->Update(prf->prfctx, exchange->message_id,
1537 ISAKMP_HDR_MESSAGE_ID_LEN4);
1538 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)
1539 "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)
1540 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)
1541 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)
;
1542 prf->Update(prf->prfctx, hash + hash_len,
1543 msg->iov[0].iov_len - ISAKMP_HDR_SZ28 - hash_len);
1544 prf->Final(my_hash, prf->prfctx);
1545 prf_free(prf);
1546 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)
1547 "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)
1548 hash_len - ISAKMP_GEN_SZ))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH_SA_NONCE: computed HASH(1)"
, my_hash, hash_len - 4)
;
1549 if (memcmp(hash + ISAKMP_GEN_SZ4, my_hash, hash_len - ISAKMP_GEN_SZ4)
1550 != 0) {
1551 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION23, 0,
1552 1, 0);
1553 goto cleanup;
1554 }
1555 free(my_hash);
1556 my_hash = 0;
1557
1558 /* Mark message as authenticated. */
1559 msg->flags |= MSG_AUTHENTICATED0x10;
1560
1561 kep = payload_first(msg, ISAKMP_PAYLOAD_KEY_EXCH4);
1562 if (kep)
1563 ie->pfs = 1;
1564
1565 /* Drop message when it contains ID types we do not implement yet. */
1566 TAILQ_FOREACH(idp, &msg->payload[ISAKMP_PAYLOAD_ID], link)for((idp) = ((&msg->payload[5])->tqh_first); (idp) !=
((void *)0); (idp) = ((idp)->link.tqe_next))
{
1567 switch (GET_ISAKMP_ID_TYPE(idp->p)field_get_num (isakmp_id_fld + 0, idp->p)) {
1568 case IPSEC_ID_IPV4_ADDR1:
1569 case IPSEC_ID_IPV4_ADDR_SUBNET4:
1570 case IPSEC_ID_IPV6_ADDR5:
1571 case IPSEC_ID_IPV6_ADDR_SUBNET6:
1572 break;
1573
1574 case IPSEC_ID_FQDN2:
1575 /*
1576 * FQDN may be used for in NAT-T with transport mode.
1577 * We can handle the message in this case. In the
1578 * other cases we'll drop the message later.
1579 */
1580 break;
1581
1582 default:
1583 message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION18,
1584 0, 1, 0);
1585 goto cleanup;
1586 }
1587 }
1588
1589 /* Handle optional client ID payloads. */
1590 idp = payload_first(msg, ISAKMP_PAYLOAD_ID5);
1591 if (idp) {
1592 /* If IDci is there, IDcr must be too. */
1593 if (!TAILQ_NEXT(idp, link)((idp)->link.tqe_next)) {
1594 /* XXX Is this a good notify type? */
1595 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0,
1596 1, 0);
1597 goto cleanup;
1598 }
1599 ie->id_ci_sz = GET_ISAKMP_GEN_LENGTH(idp->p)field_get_num (isakmp_gen_fld + 2, idp->p);
1600 ie->id_ci = malloc(ie->id_ci_sz);
1601 if (!ie->id_ci) {
1602 log_error("responder_recv_HASH_SA_NONCE: "
1603 "malloc (%lu) failed",
1604 (unsigned long)ie->id_ci_sz);
1605 goto cleanup;
1606 }
1607 memcpy(ie->id_ci, idp->p, ie->id_ci_sz);
1608 idp->flags |= PL_MARK1;
1609 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)
1610 "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)
1611 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)
;
1612
1613 idp = TAILQ_NEXT(idp, link)((idp)->link.tqe_next);
1614 ie->id_cr_sz = GET_ISAKMP_GEN_LENGTH(idp->p)field_get_num (isakmp_gen_fld + 2, idp->p);
1615 ie->id_cr = malloc(ie->id_cr_sz);
1616 if (!ie->id_cr) {
1617 log_error("responder_recv_HASH_SA_NONCE: "
1618 "malloc (%lu) failed",
1619 (unsigned long)ie->id_cr_sz);
1620 goto cleanup;
1621 }
1622 memcpy(ie->id_cr, idp->p, ie->id_cr_sz);
1623 idp->flags |= PL_MARK1;
1624 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)
1625 "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)
1626 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)
;
1627 } else {
1628 /*
1629 * If client identifiers are not present in the exchange,
1630 * we fake them. RFC 2409 states:
1631 * The identities of the SAs negotiated in Quick Mode are
1632 * implicitly assumed to be the IP addresses of the ISAKMP
1633 * peers, without any constraints on the protocol or port
1634 * numbers allowed, unless client identifiers are specified
1635 * in Quick Mode.
1636 *
1637 * -- Michael Paddon (mwp@aba.net.au)
1638 */
1639
1640 ie->flags = IPSEC_EXCH_FLAG_NO_ID1;
1641
1642 /* Get initiator and responder addresses. */
1643 msg->transport->vtbl->get_src(msg->transport, &src);
1644 msg->transport->vtbl->get_dst(msg->transport, &dst);
1645 ie->id_ci_sz = ISAKMP_ID_DATA_OFF8 + sockaddr_addrlen(src);
1646 ie->id_cr_sz = ISAKMP_ID_DATA_OFF8 + sockaddr_addrlen(dst);
1647 ie->id_ci = calloc(ie->id_ci_sz, sizeof(char));
1648 ie->id_cr = calloc(ie->id_cr_sz, sizeof(char));
1649
1650 if (!ie->id_ci || !ie->id_cr) {
1651 log_error("responder_recv_HASH_SA_NONCE: "
1652 "calloc (%lu, %lu) failed",
1653 (unsigned long)ie->id_ci_sz,
1654 (unsigned long)sizeof(char));
1655 goto cleanup;
1656 }
1657 if (src->sa_family != dst->sa_family) {
1658 log_error("initiator_recv_HASH_SA_NONCE: "
1659 "sa_family mismatch");
1660 goto cleanup;
1661 }
1662 switch (src->sa_family) {
1663 case AF_INET2:
1664 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_ci, 1);
1665 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_cr, 1);
1666 break;
1667
1668 case AF_INET624:
1669 SET_ISAKMP_ID_TYPE(ie->id_ci, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_ci, 5);
1670 SET_ISAKMP_ID_TYPE(ie->id_cr, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, ie->id_cr, 5);
1671 break;
1672
1673 default:
1674 log_error("initiator_recv_HASH_SA_NONCE: "
1675 "unknown sa_family %d", src->sa_family);
1676 goto cleanup;
1677 }
1678
1679 memcpy(ie->id_cr + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(src),
1680 sockaddr_addrlen(src));
1681 memcpy(ie->id_ci + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(dst),
1682 sockaddr_addrlen(dst));
1683 }
1684
1685 if (message_negotiate_sa(msg, check_policy))
1686 goto cleanup;
1687
1688 for (sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first); sa;
1689 sa = TAILQ_NEXT(sa, next)((sa)->next.tqe_next)) {
1690 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto;
1691 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next)) {
1692 /*
1693 * XXX we need to have some attributes per proto, not
1694 * all per SA.
1695 */
1696 ipsec_decode_transform(msg, sa, proto,
1697 proto->chosen->p);
1698 if (proto->proto == IPSEC_PROTO_IPSEC_AH2 &&
1699 !((struct ipsec_proto *)proto->data)->auth) {
1700 log_print("responder_recv_HASH_SA_NONCE: "
1701 "AH proposed without an algorithm "
1702 "attribute");
1703 message_drop(msg,
1704 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN14, 0, 1, 0);
1705 goto next_sa;
1706 }
1707 }
1708
1709 isa = sa->data;
1710
1711 /*
1712 * The group description is mandatory if we got a KEY_EXCH
1713 * payload.
1714 */
1715 if (kep) {
1716 if (!isa->group_desc) {
1717 log_print("responder_recv_HASH_SA_NONCE: "
1718 "KEY_EXCH payload without a group "
1719 "desc. attribute");
1720 message_drop(msg,
1721 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN14, 0, 1, 0);
1722 continue;
1723 }
1724 /* Also, all SAs must have equal groups. */
1725 if (!group_desc)
1726 group_desc = isa->group_desc;
1727 else if (group_desc != isa->group_desc) {
1728 log_print("responder_recv_HASH_SA_NONCE: "
1729 "differing group descriptions in one QM");
1730 message_drop(msg,
1731 ISAKMP_NOTIFY_NO_PROPOSAL_CHOSEN14, 0, 1, 0);
1732 continue;
1733 }
1734 }
1735 /* At least one SA was accepted. */
1736 retval = 0;
1737
1738next_sa:
1739 ; /* XXX gcc3 wants this. */
1740 }
1741
1742 if (kep) {
1743 ie->group = group_get(group_desc);
1744 if (!ie->group) {
1745 /*
1746 * XXX If the error was due to an out-of-range group
1747 * description we should notify our peer, but this
1748 * should probably be done by the attribute
1749 * validation. Is it?
1750 */
1751 goto cleanup;
1752 }
1753 }
1754 /* Copy out the initiator's nonce. */
1755 if (exchange_save_nonce(msg))
1756 goto cleanup;
1757
1758 /* Handle the optional KEY_EXCH payload. */
1759 if (kep && ipsec_save_g_x(msg))
1760 goto cleanup;
1761
1762 /*
1763 * Try to find and set the connection name on the exchange.
1764 */
1765
1766 /*
1767 * Check for accepted identities as well as lookup the connection
1768 * name and set it on the exchange.
1769 *
1770 * When not using policies make sure the peer proposes sane IDs.
1771 * Otherwise this is done by KeyNote.
1772 */
1773 name = connection_passive_lookup_by_ids(ie->id_ci, ie->id_cr);
1774 if (name) {
1775 exchange->name = strdup(name);
1776 if (!exchange->name) {
1777 log_error("responder_recv_HASH_SA_NONCE: "
1778 "strdup (\"%s\") failed", name);
1779 goto cleanup;
1780 }
1781 } else if (
1782 ignore_policy ||
1783 strncmp("yes", conf_get_str("General", "Use-Keynote"), 3)) {
1784 log_print("responder_recv_HASH_SA_NONCE: peer proposed "
1785 "invalid phase 2 IDs: %s",
1786 (exchange->doi->decode_ids("initiator id %s, responder"
1787 " id %s", ie->id_ci, ie->id_ci_sz, ie->id_cr,
1788 ie->id_cr_sz, 1)));
1789 message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION18, 0, 1,
1790 0);
1791 goto cleanup;
1792 }
1793
1794 return retval;
1795
1796cleanup:
1797 /* Remove all potential protocols that have been added to the SAs. */
1798 for (sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first); sa;
1799 sa = TAILQ_NEXT(sa, next)((sa)->next.tqe_next))
1800 while ((proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first)) != 0)
1801 proto_free(proto);
1802 free(my_hash);
1803 free(ie->id_ci);
1804 ie->id_ci = 0;
1805 free(ie->id_cr);
1806 ie->id_cr = 0;
1807 return -1;
1808}
1809
1810/* Reply with the transform we chose. */
1811static int
1812responder_send_HASH_SA_NONCE(struct message *msg)
1813{
1814 struct exchange *exchange = msg->exchange;
1815 struct ipsec_exch *ie = exchange->data;
1816 struct sa *isakmp_sa = msg->isakmp_sa;
1817 struct ipsec_sa *isa = isakmp_sa->data;
1818 struct prf *prf;
1819 struct hash *hash = hash_get(isa->hash);
1820 size_t nonce_sz = exchange->nonce_i_len;
1821 u_int8_t *buf;
1822 int initiator = exchange->initiator;
1823 char header[80];
1824 u_int32_t i;
1825 u_int8_t *id;
1826 size_t sz;
1827
1828 /*
1829 * We want a HASH payload to start with. XXX Share with
1830 * ike_main_mode.c?
1831 */
1832 buf = malloc(ISAKMP_HASH_SZ4 + hash->hashsize);
1833 if (!buf) {
1834 log_error("responder_send_HASH_SA_NONCE: malloc (%lu) failed",
1835 ISAKMP_HASH_SZ4 + (unsigned long)hash->hashsize);
1836 return -1;
1837 }
1838 if (message_add_payload(msg, ISAKMP_PAYLOAD_HASH8, buf,
1839 ISAKMP_HASH_SZ4 + hash->hashsize, 1)) {
1840 free(buf);
1841 return -1;
1842 }
1843 /* Add the SA payload(s) with the transform(s) that was/were chosen. */
1844 if (message_add_sa_payload(msg))
1845 return -1;
1846
1847 /* Generate a nonce, and add it to the message. */
1848 if (exchange_gen_nonce(msg, nonce_sz))
1849 return -1;
1850
1851 /* Generate optional KEY_EXCH payload. This is known as PFS. */
1852 if (ie->group && ipsec_gen_g_x(msg))
1853 return -1;
1854
1855 /*
1856 * If the initiator client ID's were acceptable, just mirror them
1857 * back.
1858 */
1859 if (!(ie->flags & IPSEC_EXCH_FLAG_NO_ID1)) {
1860 sz = ie->id_ci_sz;
1861 id = malloc(sz);
1862 if (!id) {
1863 log_error("responder_send_HASH_SA_NONCE: "
1864 "malloc (%lu) failed", (unsigned long)sz);
1865 return -1;
1866 }
1867 memcpy(id, ie->id_ci, sz);
1868 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDic"
, id, sz)
1869 "responder_send_HASH_SA_NONCE: IDic", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDic"
, id, sz)
;
1870 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
1871 free(id);
1872 return -1;
1873 }
1874 sz = ie->id_cr_sz;
1875 id = malloc(sz);
1876 if (!id) {
1877 log_error("responder_send_HASH_SA_NONCE: "
1878 "malloc (%lu) failed", (unsigned long)sz);
1879 return -1;
1880 }
1881 memcpy(id, ie->id_cr, sz);
1882 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDrc"
, id, sz)
1883 "responder_send_HASH_SA_NONCE: IDrc", id, sz))log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: IDrc"
, id, sz)
;
1884 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, id, sz, 1)) {
1885 free(id);
1886 return -1;
1887 }
1888 }
1889 /* Allocate the prf and start calculating our HASH(2). XXX Share? */
1890 LOG_DBG((LOG_NEGOTIATION, 90, "responder_recv_HASH: "log_debug (LOG_NEGOTIATION, 90, "responder_recv_HASH: " "isakmp_sa %p isa %p"
, isakmp_sa, isa)
1891 "isakmp_sa %p isa %p", isakmp_sa, isa))log_debug (LOG_NEGOTIATION, 90, "responder_recv_HASH: " "isakmp_sa %p isa %p"
, isakmp_sa, isa)
;
1892 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)
1893 "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)
;
1894 prf = prf_alloc(isa->prf_type, hash->type, isa->skeyid_a,
1895 isa->skeyid_len);
1896 if (!prf)
1897 return -1;
1898 prf->Init(prf->prfctx);
1899 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1900 "responder_send_HASH_SA_NONCE: message_id",log_debug_buf (LOG_NEGOTIATION, 90, "responder_send_HASH_SA_NONCE: message_id"
, exchange->message_id, 4)
1901 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)
;
1902 prf->Update(prf->prfctx, exchange->message_id,
1903 ISAKMP_HDR_MESSAGE_ID_LEN4);
1904 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)
1905 "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)
;
1906 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
1907
1908 /* Loop over all payloads after HASH(2). */
1909 for (i = 2; i < msg->iovlen; i++) {
1910 /* XXX Misleading payload type printouts. */
1911 snprintf(header, sizeof header,
1912 "responder_send_HASH_SA_NONCE: payload %d after HASH(2)",
1913 i - 1);
1914 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)
1915 msg->iov[i].iov_len))log_debug_buf (LOG_NEGOTIATION, 90, header, msg->iov[i].iov_base
, msg->iov[i].iov_len)
;
1916 prf->Update(prf->prfctx, msg->iov[i].iov_base,
1917 msg->iov[i].iov_len);
1918 }
1919 prf->Final(buf + ISAKMP_HASH_DATA_OFF4, prf->prfctx);
1920 prf_free(prf);
1921 snprintf(header, sizeof header, "responder_send_HASH_SA_NONCE: "
1922 "HASH_%c", initiator ? 'I' : 'R');
1923 LOG_DBG_BUF((LOG_NEGOTIATION, 80, header, buf + ISAKMP_HASH_DATA_OFF,log_debug_buf (LOG_NEGOTIATION, 80, header, buf + 4, hash->
hashsize)
1924 hash->hashsize))log_debug_buf (LOG_NEGOTIATION, 80, header, buf + 4, hash->
hashsize)
;
1925
1926 if (ie->group)
1927 message_register_post_send(msg, gen_g_xy);
1928
1929 return 0;
1930}
1931
1932static void
1933gen_g_xy(struct message *msg)
1934{
1935 struct exchange *exchange = msg->exchange;
1936 struct ipsec_exch *ie = exchange->data;
1937
1938 /* Compute Diffie-Hellman shared value. */
1939 ie->g_xy_len = dh_secretlen(ie->group);
1940 ie->g_xy = malloc(ie->g_xy_len);
1941 if (!ie->g_xy) {
1942 log_error("gen_g_xy: malloc (%lu) failed",
1943 (unsigned long)ie->g_xy_len);
1944 return;
1945 }
1946 if (dh_create_shared(ie->group, ie->g_xy,
1947 exchange->initiator ? ie->g_xr : ie->g_xi)) {
1948 log_print("gen_g_xy: dh_create_shared failed");
1949 return;
1950 }
1951 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)
1952 ie->g_xy_len))log_debug_buf (LOG_NEGOTIATION, 80, "gen_g_xy: g^xy", ie->
g_xy, ie->g_xy_len)
;
1953}
1954
1955static int
1956responder_recv_HASH(struct message *msg)
1957{
1958 struct exchange *exchange = msg->exchange;
1959 struct sa *isakmp_sa = msg->isakmp_sa;
1960 struct ipsec_sa *isa = isakmp_sa->data;
1961 struct prf *prf;
1962 u_int8_t *hash, *my_hash = 0;
1963 size_t hash_len;
1964 struct payload *hashp;
1965
1966 /* Find HASH(3) and create our own hash, just as big. */
1967 hashp = payload_first(msg, ISAKMP_PAYLOAD_HASH8);
1968 hash = hashp->p;
1969 hashp->flags |= PL_MARK1;
1970 hash_len = GET_ISAKMP_GEN_LENGTH(hash)field_get_num (isakmp_gen_fld + 2, hash);
1971 my_hash = malloc(hash_len - ISAKMP_GEN_SZ4);
1972 if (!my_hash) {
1973 log_error("responder_recv_HASH: malloc (%lu) failed",
1974 (unsigned long)hash_len - ISAKMP_GEN_SZ4);
1975 goto cleanup;
1976 }
1977 /* Allocate the prf and start calculating our HASH(3). XXX Share? */
1978 LOG_DBG((LOG_NEGOTIATION, 90, "responder_recv_HASH: "log_debug (LOG_NEGOTIATION, 90, "responder_recv_HASH: " "isakmp_sa %p isa %p"
, isakmp_sa, isa)
1979 "isakmp_sa %p isa %p", isakmp_sa, isa))log_debug (LOG_NEGOTIATION, 90, "responder_recv_HASH: " "isakmp_sa %p isa %p"
, isakmp_sa, isa)
;
1980 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)
1981 isa->skeyid_a, isa->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: SKEYID_a"
, isa->skeyid_a, isa->skeyid_len)
;
1982 prf = prf_alloc(isa->prf_type, isa->hash, isa->skeyid_a,
1983 isa->skeyid_len);
1984 if (!prf)
1985 goto cleanup;
1986 prf->Init(prf->prfctx);
1987 prf->Update(prf->prfctx, (unsigned char *)"\0", 1);
1988 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)
1989 exchange->message_id, ISAKMP_HDR_MESSAGE_ID_LEN))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: message_id"
, exchange->message_id, 4)
;
1990 prf->Update(prf->prfctx, exchange->message_id,
1991 ISAKMP_HDR_MESSAGE_ID_LEN4);
1992 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)
1993 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)
;
1994 prf->Update(prf->prfctx, exchange->nonce_i, exchange->nonce_i_len);
1995 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)
1996 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)
;
1997 prf->Update(prf->prfctx, exchange->nonce_r, exchange->nonce_r_len);
1998 prf->Final(my_hash, prf->prfctx);
1999 prf_free(prf);
2000 LOG_DBG_BUF((LOG_NEGOTIATION, 90,log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: computed HASH(3)"
, my_hash, hash_len - 4)
2001 "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)
2002 hash_len - ISAKMP_GEN_SZ))log_debug_buf (LOG_NEGOTIATION, 90, "responder_recv_HASH: computed HASH(3)"
, my_hash, hash_len - 4)
;
2003 if (memcmp(hash + ISAKMP_GEN_SZ4, my_hash, hash_len - ISAKMP_GEN_SZ4)
2004 != 0) {
2005 message_drop(msg, ISAKMP_NOTIFY_INVALID_HASH_INFORMATION23, 0,
2006 1, 0);
2007 goto cleanup;
2008 }
2009 free(my_hash);
2010
2011 /* Mark message as authenticated. */
2012 msg->flags |= MSG_AUTHENTICATED0x10;
2013
2014 post_quick_mode(msg);
2015
2016 return 0;
2017
2018cleanup:
2019 free(my_hash);
2020 return -1;
2021}