Bug Summary

File:src/sbin/isakmpd/ike_phase_1.c
Warning:line 1235, column 3
1st function call argument is an uninitialized value

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_phase_1.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_phase_1.c
1/* $OpenBSD: ike_phase_1.c,v 1.78 2018/09/20 11:49:55 jsg Exp $ */
2/* $EOM: ike_phase_1.c,v 1.31 2000/12/11 23:47:56 niklas Exp $ */
3
4/*
5 * Copyright (c) 1999, 2000 Niklas Hallqvist. All rights reserved.
6 * Copyright (c) 1999, 2000 Angelos D. Keromytis. All rights reserved.
7 * Copyright (c) 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 <sys/types.h>
35#include <netinet/in.h>
36#include <arpa/inet.h>
37#include <stdlib.h>
38#include <string.h>
39
40#include "attribute.h"
41#include "conf.h"
42#include "constants.h"
43#include "crypto.h"
44#include "dh.h"
45#include "doi.h"
46#include "dpd.h"
47#include "exchange.h"
48#include "hash.h"
49#include "ike_auth.h"
50#include "ike_phase_1.h"
51#include "ipsec.h"
52#include "ipsec_doi.h"
53#include "isakmp.h"
54#include "log.h"
55#include "message.h"
56#include "nat_traversal.h"
57#include "prf.h"
58#include "sa.h"
59#include "transport.h"
60#include "util.h"
61#include "vendor.h"
62
63static int attribute_unacceptable(u_int16_t, u_int8_t *, u_int16_t,
64 void *);
65static int ike_phase_1_validate_prop(struct exchange *, struct sa *,
66 struct sa *);
67
68/* Offer a set of transforms to the responder in the MSG message. */
69int
70ike_phase_1_initiator_send_SA(struct message *msg)
71{
72 struct exchange *exchange = msg->exchange;
73 struct ipsec_exch *ie = exchange->data;
74 u_int8_t *proposal = 0, *sa_buf = 0, *saved_nextp, *attr;
75 u_int8_t **transform = 0;
76 size_t transforms_len = 0, proposal_len, sa_len;
77 size_t *transform_len = 0;
78 struct conf_list *conf, *life_conf;
79 struct conf_list_node *xf, *life;
80 int value, update_nextp;
81 size_t i;
82 struct payload *p;
83 struct proto *proto;
84 struct proto_attr *pa;
85 int group_desc = -1, new_group_desc;
86
87 /* Get the list of transforms. */
88 conf = conf_get_list(exchange->policy, "Transforms");
89 if (!conf)
90 return -1;
91
92 transform = calloc(conf->cnt, sizeof *transform);
93 if (!transform) {
94 log_error("ike_phase_1_initiator_send_SA: calloc (%lu, %lu) "
95 "failed", (u_long)conf->cnt, (u_long)sizeof *transform);
96 goto bail_out;
97 }
98 transform_len = calloc(conf->cnt, sizeof *transform_len);
99 if (!transform_len) {
100 log_error("ike_phase_1_initiator_send_SA: calloc (%lu, %lu) "
101 "failed", (u_long)conf->cnt,
102 (u_long)sizeof *transform_len);
103 goto bail_out;
104 }
105 for (xf = TAILQ_FIRST(&conf->fields)((&conf->fields)->tqh_first), i = 0; i < conf->cnt;
106 i++, xf = TAILQ_NEXT(xf, link)((xf)->link.tqe_next)) {
107 /* XXX The sizing needs to be dynamic. */
108 transform[i] = malloc(ISAKMP_TRANSFORM_SA_ATTRS_OFF8 +
109 16 * ISAKMP_ATTR_VALUE_OFF4);
110 if (!transform[i]) {
111 log_error("ike_phase_1_initiator_send_SA: malloc (%d) "
112 "failed", ISAKMP_TRANSFORM_SA_ATTRS_OFF8 +
113 16 * ISAKMP_ATTR_VALUE_OFF4);
114 goto bail_out;
115 }
116 SET_ISAKMP_TRANSFORM_NO(transform[i], i)field_set_num (isakmp_transform_fld + 0, transform[i], i);
117 SET_ISAKMP_TRANSFORM_ID(transform[i], IPSEC_TRANSFORM_KEY_IKE)field_set_num (isakmp_transform_fld + 1, transform[i], 1);
118 SET_ISAKMP_TRANSFORM_RESERVED(transform[i], 0)field_set_num (isakmp_transform_fld + 2, transform[i], 0);
119
120 attr = transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF8;
121
122 if (attribute_set_constant(xf->field, "ENCRYPTION_ALGORITHM",
123 ike_encrypt_cst, IKE_ATTR_ENCRYPTION_ALGORITHM1, &attr))
124 goto bail_out;
125
126 if (attribute_set_constant(xf->field, "HASH_ALGORITHM",
127 ike_hash_cst, IKE_ATTR_HASH_ALGORITHM2, &attr))
128 goto bail_out;
129
130 if (attribute_set_constant(xf->field, "AUTHENTICATION_METHOD",
131 ike_auth_cst, IKE_ATTR_AUTHENTICATION_METHOD3, &attr))
132 goto bail_out;
133
134 if (attribute_set_constant(xf->field, "GROUP_DESCRIPTION",
135 ike_group_desc_cst, IKE_ATTR_GROUP_DESCRIPTION4, &attr)) {
136 /*
137 * If no group description exists, try looking for
138 * a user-defined one.
139 */
140 if (attribute_set_constant(xf->field, "GROUP_TYPE",
141 ike_group_cst, IKE_ATTR_GROUP_TYPE5, &attr))
142 goto bail_out;
143
144#if 0
145 if (attribute_set_bignum(xf->field, "GROUP_PRIME",
146 IKE_ATTR_GROUP_PRIME6, &attr))
147 goto bail_out;
148
149 if (attribute_set_bignum(xf->field,
150 "GROUP_GENERATOR_2", IKE_ATTR_GROUP_GENERATOR_28,
151 &attr))
152 goto bail_out;
153
154 if (attribute_set_bignum(xf->field,
155 "GROUP_GENERATOR_2", IKE_ATTR_GROUP_GENERATOR_28,
156 &attr))
157 goto bail_out;
158
159 if (attribute_set_bignum(xf->field, "GROUP_CURVE_A",
160 IKE_ATTR_GROUP_CURVE_A9, &attr))
161 goto bail_out;
162
163 if (attribute_set_bignum(xf->field, "GROUP_CURVE_B",
164 IKE_ATTR_GROUP_CURVE_B10, &attr))
165 goto bail_out;
166#endif
167 }
168 /*
169 * Life durations are special, we should be able to specify
170 * several, one per type.
171 */
172 life_conf = conf_get_list(xf->field, "Life");
173 if (life_conf) {
174 for (life = TAILQ_FIRST(&life_conf->fields)((&life_conf->fields)->tqh_first); life;
175 life = TAILQ_NEXT(life, link)((life)->link.tqe_next)) {
176 attribute_set_constant(life->field,
177 "LIFE_TYPE", ike_duration_cst,
178 IKE_ATTR_LIFE_TYPE11, &attr);
179
180 /*
181 * XXX Deals with 16 and 32 bit lifetimes
182 * only
183 */
184 value = conf_get_num(life->field,
185 "LIFE_DURATION", 0);
186 if (value) {
187 if (value <= 0xffff)
188 attr = attribute_set_basic(
189 attr,
190 IKE_ATTR_LIFE_DURATION12,
191 value);
192 else {
193 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))
;
194 attr = attribute_set_var(attr,
195 IKE_ATTR_LIFE_DURATION12,
196 (u_int8_t *)&value,
197 sizeof value);
198 }
199 }
200 }
201 conf_free_list(life_conf);
202 }
203 attribute_set_constant(xf->field, "PRF", ike_prf_cst,
204 IKE_ATTR_PRF13, &attr);
205
206 value = conf_get_num(xf->field, "KEY_LENGTH", 0);
207 if (value)
208 attr = attribute_set_basic(attr, IKE_ATTR_KEY_LENGTH14,
209 value);
210
211 value = conf_get_num(xf->field, "FIELD_SIZE", 0);
212 if (value)
213 attr = attribute_set_basic(attr, IKE_ATTR_FIELD_SIZE15,
214 value);
215
216 value = conf_get_num(xf->field, "GROUP_ORDER", 0);
217 if (value)
218 attr = attribute_set_basic(attr, IKE_ATTR_GROUP_ORDER16,
219 value);
220
221 /* Record the real transform size. */
222 transforms_len += transform_len[i] = attr - transform[i];
223
224 /* XXX I don't like exchange-specific stuff in here. */
225 if (exchange->type == ISAKMP_EXCH_AGGRESSIVE4) {
226 /*
227 * Make sure that if a group description is specified,
228 * it is specified for all transforms equally.
229 */
230 attr = (u_int8_t *)conf_get_str(xf->field,
231 "GROUP_DESCRIPTION");
232 new_group_desc =
233 attr ? constant_value(ike_group_desc_cst,
234 (char *)attr) : 0;
235 if (group_desc == -1)
236 group_desc = new_group_desc;
237 else if (group_desc != new_group_desc) {
238 log_print("ike_phase_1_initiator_send_SA: "
239 "differing group descriptions in a "
240 "proposal");
241 goto bail_out;
242 }
243 }
244 /*
245 * We need to check that we actually support our
246 * configuration.
247 */
248 if (attribute_map(transform[i] + ISAKMP_TRANSFORM_SA_ATTRS_OFF8,
249 transform_len[i] - ISAKMP_TRANSFORM_SA_ATTRS_OFF8,
250 exchange->doi->is_attribute_incompatible, msg)) {
251 log_print("ike_phase_1_initiator_send_SA: "
252 "section [%s] has unsupported attribute(s)",
253 xf->field);
254 goto bail_out;
255 }
256 }
257
258 /* XXX I don't like exchange-specific stuff in here. */
259 if (exchange->type == ISAKMP_EXCH_AGGRESSIVE4)
260 ie->group = group_get(group_desc);
261
262 proposal_len = ISAKMP_PROP_SPI_OFF8;
263 proposal = malloc(proposal_len);
264 if (!proposal) {
265 log_error("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
266 (unsigned long)proposal_len);
267 goto bail_out;
268 }
269 SET_ISAKMP_PROP_NO(proposal, 1)field_set_num (isakmp_prop_fld + 0, proposal, 1);
270 SET_ISAKMP_PROP_PROTO(proposal, ISAKMP_PROTO_ISAKMP)field_set_num (isakmp_prop_fld + 1, proposal, 1);
271 SET_ISAKMP_PROP_SPI_SZ(proposal, 0)field_set_num (isakmp_prop_fld + 2, proposal, 0);
272 SET_ISAKMP_PROP_NTRANSFORMS(proposal, conf->cnt)field_set_num (isakmp_prop_fld + 3, proposal, conf->cnt);
273
274 /* XXX I would like to see this factored out. */
275 proto = calloc(1, sizeof *proto);
276 if (!proto) {
277 log_error("ike_phase_1_initiator_send_SA: "
278 "calloc (1, %lu) failed", (unsigned long)sizeof *proto);
279 goto bail_out;
280 }
281 proto->no = 1;
282 proto->proto = ISAKMP_PROTO_ISAKMP1;
283 proto->sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first);
284 proto->xf_cnt = conf->cnt;
285 TAILQ_INIT(&proto->xfs)do { (&proto->xfs)->tqh_first = ((void*)0); (&proto
->xfs)->tqh_last = &(&proto->xfs)->tqh_first
; } while (0)
;
286 for (i = 0; i < proto->xf_cnt; i++) {
287 pa = calloc(1, sizeof *pa);
288 if (!pa)
289 goto bail_out;
290 pa->len = transform_len[i];
291 pa->attrs = malloc(pa->len);
292 if (!pa->attrs) {
293 free(pa);
294 goto bail_out;
295 }
296 memcpy(pa->attrs, transform[i], pa->len);
297 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)
;
298 }
299 TAILQ_INSERT_TAIL(&TAILQ_FIRST(&exchange->sa_list)->protos, proto,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)
300 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)
;
301
302 sa_len = ISAKMP_SA_SIT_OFF8 + IPSEC_SIT_SIT_LEN4;
303 sa_buf = malloc(sa_len);
304 if (!sa_buf) {
305 log_error("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
306 (unsigned long)sa_len);
307 goto bail_out;
308 }
309 SET_ISAKMP_SA_DOI(sa_buf, IPSEC_DOI_IPSEC)field_set_num (isakmp_sa_fld + 0, sa_buf, 1);
310 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);
311
312 /*
313 * Add the payloads. As this is a SA, we need to recompute the
314 * lengths of the payloads containing others.
315 */
316 if (message_add_payload(msg, ISAKMP_PAYLOAD_SA1, sa_buf, sa_len, 1))
317 goto bail_out;
318 SET_ISAKMP_GEN_LENGTH(sa_buf,field_set_num (isakmp_gen_fld + 2, sa_buf, sa_len + proposal_len
+ transforms_len)
319 sa_len + proposal_len + transforms_len)field_set_num (isakmp_gen_fld + 2, sa_buf, sa_len + proposal_len
+ transforms_len)
;
320 sa_buf = 0;
321
322 saved_nextp = msg->nextp;
323 if (message_add_payload(msg, ISAKMP_PAYLOAD_PROPOSAL2, proposal,
324 proposal_len, 0))
325 goto bail_out;
326 SET_ISAKMP_GEN_LENGTH(proposal, proposal_len + transforms_len)field_set_num (isakmp_gen_fld + 2, proposal, proposal_len + transforms_len
)
;
327 proposal = 0;
328
329 update_nextp = 0;
330 for (i = 0; i < conf->cnt; i++) {
331 if (message_add_payload(msg, ISAKMP_PAYLOAD_TRANSFORM3,
332 transform[i], transform_len[i], update_nextp))
333 goto bail_out;
334 update_nextp = 1;
335 transform[i] = 0;
336 }
337 msg->nextp = saved_nextp;
338
339 /* Save SA payload body in ie->sa_i_b, length ie->sa_i_b_len. */
340 ie->sa_i_b_len = sa_len + proposal_len + transforms_len -
341 ISAKMP_GEN_SZ4;
342 ie->sa_i_b = malloc(ie->sa_i_b_len);
343 if (!ie->sa_i_b) {
344 log_error("ike_phase_1_initiator_send_SA: malloc (%lu) failed",
345 (unsigned long)ie->sa_i_b_len);
346 goto bail_out;
347 }
348 memcpy(ie->sa_i_b,
349 payload_first(msg, ISAKMP_PAYLOAD_SA1)->p + ISAKMP_GEN_SZ4,
350 sa_len - ISAKMP_GEN_SZ4);
351 memcpy(ie->sa_i_b + sa_len - ISAKMP_GEN_SZ4,
352 payload_first(msg, ISAKMP_PAYLOAD_PROPOSAL2)->p, proposal_len);
353 transforms_len = 0;
354 for (i = 0, p = TAILQ_FIRST(&msg->payload[ISAKMP_PAYLOAD_TRANSFORM])((&msg->payload[3])->tqh_first);
355 i < conf->cnt; i++, p = TAILQ_NEXT(p, link)((p)->link.tqe_next)) {
356 memcpy(ie->sa_i_b + sa_len + proposal_len + transforms_len -
357 ISAKMP_GEN_SZ4, p->p, transform_len[i]);
358 transforms_len += transform_len[i];
359 }
360
361 /* Advertise OpenBSD isakmpd. */
362 if (add_vendor_openbsd(msg))
363 goto bail_out;
364
365 /* Advertise NAT-T capability. */
366 if (nat_t_add_vendor_payloads(msg))
367 goto bail_out;
368
369 /* Advertise DPD capability. */
370 if (dpd_add_vendor_payload(msg))
371 goto bail_out;
372
373 conf_free_list(conf);
374 free(transform);
375 free(transform_len);
376 return 0;
377
378bail_out:
379 free(sa_buf);
380 free(proposal);
381 if (transform) {
382 for (i = 0; i < conf->cnt; i++)
383 free(transform[i]);
384 free(transform);
385 }
386 free(transform_len);
387 conf_free_list(conf);
388 return -1;
389}
390
391/* Figure out what transform the responder chose. */
392int
393ike_phase_1_initiator_recv_SA(struct message *msg)
394{
395 struct exchange *exchange = msg->exchange;
396 struct sa *sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first);
397 struct ipsec_exch *ie = exchange->data;
398 struct ipsec_sa *isa = sa->data;
399 struct payload *sa_p = payload_first(msg, ISAKMP_PAYLOAD_SA1);
400 struct payload *prop = payload_first(msg, ISAKMP_PAYLOAD_PROPOSAL2);
401 struct payload *xf = payload_first(msg, ISAKMP_PAYLOAD_TRANSFORM3);
402
403 /*
404 * IKE requires that only one SA with only one proposal exists and
405 * since we are getting an answer on our transform offer, only one
406 * transform.
407 */
408 if (TAILQ_NEXT(sa_p, link)((sa_p)->link.tqe_next) || TAILQ_NEXT(prop, link)((prop)->link.tqe_next) ||
409 TAILQ_NEXT(xf, link)((xf)->link.tqe_next)) {
410 log_print("ike_phase_1_initiator_recv_SA: "
411 "multiple SA, proposal or transform payloads in phase 1");
412 /* XXX Is there a better notification type? */
413 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0, 1, 0);
414 return -1;
415 }
416 /* Check that the chosen transform matches an offer. */
417 if (message_negotiate_sa(msg, ike_phase_1_validate_prop) ||
418 !TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first))
419 return -1;
420
421 ipsec_decode_transform(msg, sa, TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first), xf->p);
422
423 /* XXX I don't like exchange-specific stuff in here. */
424 if (exchange->type != ISAKMP_EXCH_AGGRESSIVE4)
425 ie->group = group_get(isa->group_desc);
426
427 /* Mark the SA as handled. */
428 sa_p->flags |= PL_MARK1;
429
430 return 0;
431}
432
433/* Send our public DH value and a nonce to the responder. */
434int
435ike_phase_1_initiator_send_KE_NONCE(struct message *msg)
436{
437 struct ipsec_exch *ie = msg->exchange->data;
438
439 ie->g_x_len = dh_getlen(ie->group);
440
441 /* XXX I want a better way to specify the nonce's size. */
442 return ike_phase_1_send_KE_NONCE(msg, 16);
443}
444
445/* Accept responder's public DH value and nonce. */
446int
447ike_phase_1_initiator_recv_KE_NONCE(struct message *msg)
448{
449 if (ike_phase_1_recv_KE_NONCE(msg))
450 return -1;
451
452 return ike_phase_1_post_exchange_KE_NONCE(msg);
453}
454
455/*
456 * Accept a set of transforms offered by the initiator and chose one we can
457 * handle.
458 */
459int
460ike_phase_1_responder_recv_SA(struct message *msg)
461{
462 struct exchange *exchange = msg->exchange;
463 struct sa *sa = TAILQ_FIRST(&exchange->sa_list)((&exchange->sa_list)->tqh_first);
464 struct ipsec_sa *isa = sa->data;
465 struct payload *sa_p = payload_first(msg, ISAKMP_PAYLOAD_SA1);
466 struct payload *prop = payload_first(msg, ISAKMP_PAYLOAD_PROPOSAL2);
467 struct ipsec_exch *ie = exchange->data;
468
469 /* Mark the SA as handled. */
470 sa_p->flags |= PL_MARK1;
471
472 /* IKE requires that only one SA with only one proposal exists. */
473 if (TAILQ_NEXT(sa_p, link)((sa_p)->link.tqe_next) || TAILQ_NEXT(prop, link)((prop)->link.tqe_next)) {
474 log_print("ike_phase_1_responder_recv_SA: "
475 "multiple SA or proposal payloads in phase 1");
476 /* XXX Is there a better notification type? */
477 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0, 1, 0);
478 return -1;
479 }
480 /* Chose a transform from the SA. */
481 if (message_negotiate_sa(msg, ike_phase_1_validate_prop) ||
482 !TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first))
483 return -1;
484
485 /* XXX Move into message_negotiate_sa? */
486 ipsec_decode_transform(msg, sa, TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first),
487 TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first)->chosen->p);
488
489 ie->group = group_get(isa->group_desc);
490
491 /*
492 * Check that the mandatory attributes: encryption, hash,
493 * authentication method and Diffie-Hellman group description, has
494 * been supplied.
495 */
496 if (!exchange->crypto || !ie->hash || !ie->ike_auth || !ie->group) {
497 message_drop(msg, ISAKMP_NOTIFY_PAYLOAD_MALFORMED16, 0, 1, 0);
498 return -1;
499 }
500 /* Save the body for later hash computation. */
501 ie->sa_i_b_len = GET_ISAKMP_GEN_LENGTH(sa_p->p)field_get_num (isakmp_gen_fld + 2, sa_p->p) - ISAKMP_GEN_SZ4;
502 ie->sa_i_b = malloc(ie->sa_i_b_len);
503 if (!ie->sa_i_b) {
504 /* XXX How to notify peer? */
505 log_error("ike_phase_1_responder_recv_SA: malloc (%lu) failed",
506 (unsigned long)ie->sa_i_b_len);
507 return -1;
508 }
509 memcpy(ie->sa_i_b, sa_p->p + ISAKMP_GEN_SZ4, ie->sa_i_b_len);
510 return 0;
511}
512
513/* Reply with the transform we chose. */
514int
515ike_phase_1_responder_send_SA(struct message *msg)
516{
517 /* Add the SA payload with the transform that was chosen. */
518 if (message_add_sa_payload(msg))
519 return -1;
520
521 /* Advertise OpenBSD isakmpd. */
522 if (add_vendor_openbsd(msg))
523 return -1;
524
525 /* Advertise NAT-T capability. */
526 if (nat_t_add_vendor_payloads(msg))
527 return -1;
528
529 /* Advertise DPD capability. */
530 if (dpd_add_vendor_payload(msg))
531 return -1;
532 return 0;
533}
534
535/* Send our public DH value and a nonce to the peer. */
536int
537ike_phase_1_send_KE_NONCE(struct message *msg, size_t nonce_sz)
538{
539 /* Public DH key. */
540 if (ipsec_gen_g_x(msg)) {
541 /* XXX How to log and notify peer? */
542 return -1;
543 }
544 /* Generate a nonce, and add it to the message. */
545 if (exchange_gen_nonce(msg, nonce_sz)) {
546 /* XXX Log? */
547 return -1;
548 }
549 /* Are there any CERTREQs to send? */
550 if (exchange_add_certreqs(msg)) {
551 /* XXX Log? */
552 return -1;
553 }
554 /* Try to add certificates which are acceptable for the CERTREQs */
555 if (exchange_add_certs(msg)) {
556 /* XXX Log? */
557 return -1;
558 }
559 /* If this exchange uses NAT-Traversal, add NAT-D payloads now. */
560 if (msg->exchange->flags & EXCHANGE_FLAG_NAT_T_CAP_PEER0x0008)
561 if (nat_t_exchange_add_nat_d(msg)) {
562 /* XXX Log? */
563 return -1;
564 }
565 return 0;
566}
567
568/* Receive our peer's public DH value and nonce. */
569int
570ike_phase_1_recv_KE_NONCE(struct message *msg)
571{
572 /* Copy out the initiator's DH public value. */
573 if (ipsec_save_g_x(msg)) {
574 /* XXX How to log and notify peer? */
575 return -1;
576 }
577 /* Copy out the initiator's nonce. */
578 if (exchange_save_nonce(msg)) {
579 /* XXX How to log and notify peer? */
580 return -1;
581 }
582 /* Copy out the initiator's cert requests. */
583 if (exchange_save_certreq(msg)) {
584 /* XXX How to log and notify peer? */
585 return -1;
586 }
587 /* MainMode: Check for NAT-D payloads and contents. */
588 if (msg->exchange->type == ISAKMP_EXCH_ID_PROT2 &&
589 msg->exchange->flags & EXCHANGE_FLAG_NAT_T_CAP_PEER0x0008)
590 (void)nat_t_exchange_check_nat_d(msg);
591 return 0;
592}
593
594/*
595 * Compute DH values and key material. This is done in a post-send function
596 * as that means we can do parallel work in both the initiator and responder
597 * thus speeding up exchanges.
598 */
599int
600ike_phase_1_post_exchange_KE_NONCE(struct message *msg)
601{
602 struct exchange *exchange = msg->exchange;
603 struct ipsec_exch *ie = exchange->data;
604 struct prf *prf;
605 struct hash *hash = ie->hash;
606 enum cryptoerr err;
607
608 /* Compute Diffie-Hellman shared value. */
609 ie->g_xy_len = dh_secretlen(ie->group);
610 ie->g_xy = malloc(ie->g_xy_len);
611 if (!ie->g_xy) {
612 /* XXX How to notify peer? */
613 log_error("ike_phase_1_post_exchange_KE_NONCE: "
614 "malloc (%lu) failed", (unsigned long)ie->g_xy_len);
615 return -1;
616 }
617 if (dh_create_shared(ie->group, ie->g_xy,
618 exchange->initiator ? ie->g_xr : ie->g_xi)) {
619 log_print("ike_phase_1_post_exchange_KE_NONCE: "
620 "dh_create_shared failed");
621 return -1;
622 }
623 LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: g^xy"
, ie->g_xy, ie->g_xy_len)
624 "ike_phase_1_post_exchange_KE_NONCE: g^xy", ie->g_xy,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: g^xy"
, ie->g_xy, ie->g_xy_len)
625 ie->g_xy_len))log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: g^xy"
, ie->g_xy, ie->g_xy_len)
;
626
627 /* Compute the SKEYID depending on the authentication method. */
628 ie->skeyid = ie->ike_auth->gen_skeyid(exchange, &ie->skeyid_len);
629 if (!ie->skeyid) {
630 /* XXX Log and teardown? */
631 return -1;
632 }
633 LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID"
, ie->skeyid, ie->skeyid_len)
634 "ike_phase_1_post_exchange_KE_NONCE: SKEYID", ie->skeyid,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID"
, ie->skeyid, ie->skeyid_len)
635 ie->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID"
, ie->skeyid, ie->skeyid_len)
;
636
637 /* SKEYID_d. */
638 ie->skeyid_d = malloc(ie->skeyid_len);
639 if (!ie->skeyid_d) {
640 /* XXX How to notify peer? */
641 log_error("ike_phase_1_post_exchange_KE_NONCE: "
642 "malloc (%lu) failed", (unsigned long)ie->skeyid_len);
643 return -1;
644 }
645 prf = prf_alloc(ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
646 if (!prf) {
647 /* XXX Log and teardown? */
648 return -1;
649 }
650 prf->Init(prf->prfctx);
651 prf->Update(prf->prfctx, ie->g_xy, ie->g_xy_len);
652 prf->Update(prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN(8 + 8));
653 prf->Update(prf->prfctx, (unsigned char *)"\0", 1);
654 prf->Final(ie->skeyid_d, prf->prfctx);
655 LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_d"
, ie->skeyid_d, ie->skeyid_len)
656 "ike_phase_1_post_exchange_KE_NONCE: SKEYID_d", ie->skeyid_d,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_d"
, ie->skeyid_d, ie->skeyid_len)
657 ie->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_d"
, ie->skeyid_d, ie->skeyid_len)
;
658
659 /* SKEYID_a. */
660 ie->skeyid_a = malloc(ie->skeyid_len);
661 if (!ie->skeyid_a) {
662 log_error("ike_phase_1_post_exchange_KE_NONCE: "
663 "malloc (%lu) failed", (unsigned long)ie->skeyid_len);
664 prf_free(prf);
665 return -1;
666 }
667 prf->Init(prf->prfctx);
668 prf->Update(prf->prfctx, ie->skeyid_d, ie->skeyid_len);
669 prf->Update(prf->prfctx, ie->g_xy, ie->g_xy_len);
670 prf->Update(prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN(8 + 8));
671 prf->Update(prf->prfctx, (unsigned char *)"\1", 1);
672 prf->Final(ie->skeyid_a, prf->prfctx);
673 LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_a"
, ie->skeyid_a, ie->skeyid_len)
674 "ike_phase_1_post_exchange_KE_NONCE: SKEYID_a", ie->skeyid_a,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_a"
, ie->skeyid_a, ie->skeyid_len)
675 ie->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_a"
, ie->skeyid_a, ie->skeyid_len)
;
676
677 /* SKEYID_e. */
678 ie->skeyid_e = malloc(ie->skeyid_len);
679 if (!ie->skeyid_e) {
680 /* XXX How to notify peer? */
681 log_error("ike_phase_1_post_exchange_KE_NONCE: "
682 "malloc (%lu) failed", (unsigned long)ie->skeyid_len);
683 prf_free(prf);
684 return -1;
685 }
686 prf->Init(prf->prfctx);
687 prf->Update(prf->prfctx, ie->skeyid_a, ie->skeyid_len);
688 prf->Update(prf->prfctx, ie->g_xy, ie->g_xy_len);
689 prf->Update(prf->prfctx, exchange->cookies, ISAKMP_HDR_COOKIES_LEN(8 + 8));
690 prf->Update(prf->prfctx, (unsigned char *)"\2", 1);
691 prf->Final(ie->skeyid_e, prf->prfctx);
692 prf_free(prf);
693 LOG_DBG_BUF((LOG_NEGOTIATION, 80,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_e"
, ie->skeyid_e, ie->skeyid_len)
694 "ike_phase_1_post_exchange_KE_NONCE: SKEYID_e", ie->skeyid_e,log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_e"
, ie->skeyid_e, ie->skeyid_len)
695 ie->skeyid_len))log_debug_buf (LOG_NEGOTIATION, 80, "ike_phase_1_post_exchange_KE_NONCE: SKEYID_e"
, ie->skeyid_e, ie->skeyid_len)
;
696
697 /* Key length determination. */
698 if (!exchange->key_length)
699 exchange->key_length = exchange->crypto->keymax;
700
701 /* Derive a longer key from skeyid_e */
702 if (ie->skeyid_len < exchange->key_length) {
703 u_int16_t len, keylen;
704 u_int8_t *key, *p;
705
706 prf = prf_alloc(ie->prf_type, hash->type, ie->skeyid_e,
707 ie->skeyid_len);
708 if (!prf) {
709 /* XXX - notify peer */
710 return -1;
711 }
712 /* Make keylen a multiple of prf->blocksize */
713 keylen = exchange->key_length;
714 if (keylen % prf->blocksize)
715 keylen += prf->blocksize - (keylen % prf->blocksize);
716
717 key = malloc(keylen);
718 if (!key) {
719 /* XXX - Notify peer. */
720 prf_free(prf);
721 log_error("ike_phase_1_post_exchange_KE_NONCE: "
722 "malloc (%d) failed", keylen);
723 return -1;
724 }
725 prf->Init(prf->prfctx);
726 prf->Update(prf->prfctx, (unsigned char *)"\0", 1);
727 prf->Final(key, prf->prfctx);
728
729 for (len = prf->blocksize, p = key; len < exchange->key_length;
730 len += prf->blocksize, p += prf->blocksize) {
731 prf->Init(prf->prfctx);
732 prf->Update(prf->prfctx, p, prf->blocksize);
733 prf->Final(p + prf->blocksize, prf->prfctx);
734 }
735 prf_free(prf);
736
737 /* Setup our keystate using the derived encryption key. */
738 exchange->keystate = crypto_init(exchange->crypto, key,
739 exchange->key_length, &err);
740
741 free(key);
742 } else
743 /* Setup our keystate using the raw skeyid_e. */
744 exchange->keystate = crypto_init(exchange->crypto,
745 ie->skeyid_e, exchange->key_length, &err);
746
747 /* Special handling for DES weak keys. */
748 if (!exchange->keystate && err == EWEAKKEY &&
749 (exchange->key_length << 1) <= ie->skeyid_len) {
750 log_print("ike_phase_1_post_exchange_KE_NONCE: "
751 "weak key, trying subseq. skeyid_e");
752 exchange->keystate = crypto_init(exchange->crypto,
753 ie->skeyid_e + exchange->key_length,
754 exchange->key_length, &err);
755 }
756 if (!exchange->keystate) {
757 log_print("ike_phase_1_post_exchange_KE_NONCE: "
758 "exchange->crypto->init () failed: %d", err);
759
760 /*
761 * XXX We really need to know if problems are of transient
762 * nature or fatal (like failed assertions etc.)
763 */
764 return -1;
765 }
766 /* Setup IV. XXX Only for CBC transforms, no? */
767 hash->Init(hash->ctx);
768 hash->Update(hash->ctx, ie->g_xi, ie->g_x_len);
769 hash->Update(hash->ctx, ie->g_xr, ie->g_x_len);
770 hash->Final(hash->digest, hash->ctx);
771 crypto_init_iv(exchange->keystate, hash->digest,
772 exchange->crypto->blocksize);
773 return 0;
774}
775
776int
777ike_phase_1_responder_send_ID_AUTH(struct message *msg)
778{
779 if (ike_phase_1_send_ID(msg))
780 return -1;
781
782 return ike_phase_1_send_AUTH(msg);
783}
784
785int
786ike_phase_1_send_ID(struct message *msg)
787{
788 struct exchange *exchange = msg->exchange;
789 u_int8_t *buf;
790 char header[80];
791 ssize_t sz;
792 struct sockaddr *src;
793 int initiator = exchange->initiator;
794 u_int8_t **id;
795 size_t *id_len;
796 char *my_id = 0, *data;
797 u_int8_t id_type;
798 sa_family_t af = 0;
799
800 /* Choose the right fields to fill-in. */
801 id = initiator ? &exchange->id_i : &exchange->id_r;
802 id_len = initiator ? &exchange->id_i_len : &exchange->id_r_len;
803
804 if (exchange->name)
805 my_id = conf_get_str(exchange->name, "ID");
806
807 if (!my_id)
808 my_id = conf_get_str("General", "Default-phase-1-ID");
809
810 msg->transport->vtbl->get_src(msg->transport, &src);
811 sz = my_id ? ipsec_id_size(my_id, &id_type) : sockaddr_addrlen(src);
812 if (sz == -1)
813 return -1;
814
815 sz += ISAKMP_ID_DATA_OFF8;
816 buf = malloc(sz);
817 if (!buf) {
818 log_error("ike_phase_1_send_ID: malloc (%lu) failed",
819 (unsigned long)sz);
820 return -1;
821 }
822 SET_IPSEC_ID_PROTO(buf + ISAKMP_ID_DOI_DATA_OFF, 0)field_set_num (ipsec_id_fld + 0, buf + 5, 0);
823 SET_IPSEC_ID_PORT(buf + ISAKMP_ID_DOI_DATA_OFF, 0)field_set_num (ipsec_id_fld + 1, buf + 5, 0);
824 if (my_id) {
825 SET_ISAKMP_ID_TYPE(buf, id_type)field_set_num (isakmp_id_fld + 0, buf, id_type);
826 switch (id_type) {
827 case IPSEC_ID_IPV4_ADDR1:
828 case IPSEC_ID_IPV4_ADDR_SUBNET4:
829 af = AF_INET2;
830 break;
831 case IPSEC_ID_IPV6_ADDR5:
832 case IPSEC_ID_IPV6_ADDR_SUBNET6:
833 af = AF_INET624;
834 break;
835 }
836 switch (id_type) {
837 case IPSEC_ID_IPV4_ADDR1:
838 case IPSEC_ID_IPV6_ADDR5:
839 data = conf_get_str(my_id, "Address");
840 if (!data) {
841 log_print("ike_phase_1_send_ID: section %s "
842 "has no \"Address\" tag", my_id);
843 free(buf);
844 return -1;
845 }
846 if (text2sockaddr(data, NULL((void*)0), &src, af, 0)) {
847 log_error("ike_phase_1_send_ID: "
848 "text2sockaddr() failed");
849 free(buf);
850 return -1;
851 }
852 memcpy(buf + ISAKMP_ID_DATA_OFF8,
853 sockaddr_addrdata(src), sockaddr_addrlen(src));
854 free(src);
855 break;
856
857 case IPSEC_ID_IPV4_ADDR_SUBNET4:
858 case IPSEC_ID_IPV6_ADDR_SUBNET6:
859 /* Network */
860 data = conf_get_str(my_id, "Network");
861 if (!data) {
862 log_print("ike_phase_1_send_ID: section %s "
863 "has no \"Network\" tag", my_id);
864 free(buf);
865 return -1;
866 }
867 if (text2sockaddr(data, NULL((void*)0), &src, af, 0)) {
868 log_error("ike_phase_1_send_ID: "
869 "text2sockaddr() failed");
870 free(buf);
871 return -1;
872 }
873 memcpy(buf + ISAKMP_ID_DATA_OFF8,
874 sockaddr_addrdata(src), sockaddr_addrlen(src));
875 free(src);
876 /* Netmask */
877 data = conf_get_str(my_id, "Netmask");
878 if (!data) {
879 log_print("ike_phase_1_send_ID: section %s "
880 "has no \"Netmask\" tag", my_id);
881 free(buf);
882 return -1;
883 }
884 if (text2sockaddr(data, NULL((void*)0), &src, af, 1)) {
885 log_error("ike_phase_1_send_ID: "
886 "text2sockaddr() failed");
887 free(buf);
888 return -1;
889 }
890 memcpy(buf + ISAKMP_ID_DATA_OFF8 +
891 sockaddr_addrlen(src), sockaddr_addrdata(src),
892 sockaddr_addrlen(src));
893 free(src);
894 break;
895
896 case IPSEC_ID_FQDN2:
897 case IPSEC_ID_USER_FQDN3:
898 case IPSEC_ID_KEY_ID11:
899 data = conf_get_str(my_id, "Name");
900 if (!data) {
901 log_print("ike_phase_1_send_ID: section %s "
902 "has no \"Name\" tag", my_id);
903 free(buf);
904 return -1;
905 }
906 memcpy(buf + ISAKMP_ID_DATA_OFF8, data,
907 sz - ISAKMP_ID_DATA_OFF8);
908 break;
909
910 default:
911 log_print("ike_phase_1_send_ID: "
912 "unsupported ID type %d", id_type);
913 free(buf);
914 return -1;
915 }
916 } else {
917 switch (src->sa_family) {
918 case AF_INET2:
919 SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV4_ADDR)field_set_num (isakmp_id_fld + 0, buf, 1);
920 break;
921 case AF_INET624:
922 SET_ISAKMP_ID_TYPE(buf, IPSEC_ID_IPV6_ADDR)field_set_num (isakmp_id_fld + 0, buf, 5);
923 break;
924 }
925 /* Already in network byteorder. */
926 memcpy(buf + ISAKMP_ID_DATA_OFF8, sockaddr_addrdata(src),
927 sockaddr_addrlen(src));
928 }
929
930 if (message_add_payload(msg, ISAKMP_PAYLOAD_ID5, buf, sz, 1)) {
931 free(buf);
932 return -1;
933 }
934 *id_len = sz - ISAKMP_GEN_SZ4;
935 *id = malloc(*id_len);
936 if (!*id) {
937 log_error("ike_phase_1_send_ID: malloc (%lu) failed",
938 (unsigned long)*id_len);
939 return -1;
940 }
941 memcpy(*id, buf + ISAKMP_GEN_SZ4, *id_len);
942 snprintf(header, sizeof header, "ike_phase_1_send_ID: %s",
943 constant_name(ipsec_id_cst, GET_ISAKMP_ID_TYPE(buf)field_get_num (isakmp_id_fld + 0, buf)));
944 LOG_DBG_BUF((LOG_NEGOTIATION, 40, header, buf + ISAKMP_ID_DATA_OFF,log_debug_buf (LOG_NEGOTIATION, 40, header, buf + 8, sz - 8)
945 sz - ISAKMP_ID_DATA_OFF))log_debug_buf (LOG_NEGOTIATION, 40, header, buf + 8, sz - 8);
946 return 0;
947}
948
949int
950ike_phase_1_send_AUTH(struct message *msg)
951{
952 struct exchange *exchange = msg->exchange;
953 struct ipsec_exch *ie = exchange->data;
954
955 if (ie->ike_auth->encode_hash(msg)) {
956 /* XXX Log? */
957 return -1;
958 }
959 /*
960 * XXX Many people say the COMMIT flag is just junk, especially in
961 * Phase 1.
962 */
963#ifdef notyet
964 if ((exchange->flags & EXCHANGE_FLAG_COMMITTED(0x0001 | 0x0002)) == 0)
965 exchange->flags |= EXCHANGE_FLAG_I_COMMITTED0x0001;
966#endif
967
968 return 0;
969}
970
971/* Receive ID and HASH and check that the exchange has been consistent. */
972int
973ike_phase_1_recv_ID_AUTH(struct message *msg)
974{
975 if (ike_phase_1_recv_ID(msg))
976 return -1;
977
978 return ike_phase_1_recv_AUTH(msg);
979}
980
981/* Receive ID. */
982int
983ike_phase_1_recv_ID(struct message *msg)
984{
985 struct exchange *exchange = msg->exchange;
986 struct payload *payload;
987 char header[80], *rs = 0, *rid = 0, *p;
988 int initiator = exchange->initiator;
989 u_int8_t **id, id_type;
990 size_t *id_len;
991 ssize_t sz;
992 struct sockaddr *sa;
993 sa_family_t af = 0;
994
995 payload = payload_first(msg, ISAKMP_PAYLOAD_ID5);
996
997 if (exchange->name)
998 rs = conf_get_str(exchange->name, "Remote-ID");
999
1000 if (rs) {
1001 sz = ipsec_id_size(rs, &id_type);
1002 if (sz == -1) {
1003 log_print("ike_phase_1_recv_ID: could not handle "
1004 "specified Remote-ID [%s]", rs);
1005 return -1;
1006 }
1007 rid = malloc(sz);
1008 if (!rid) {
1009 log_error("ike_phase_1_recv_ID: malloc (%lu) failed",
1010 (unsigned long)sz);
1011 return -1;
1012 }
1013 switch (id_type) {
1014 case IPSEC_ID_IPV4_ADDR1:
1015 af = AF_INET2;
1016 break;
1017 case IPSEC_ID_IPV6_ADDR5:
1018 af = AF_INET624;
1019 break;
1020 }
1021 switch (id_type) {
1022 case IPSEC_ID_IPV4_ADDR1:
1023 case IPSEC_ID_IPV6_ADDR5:
1024 p = conf_get_str(rs, "Address");
1025 if (!p) {
1026 log_print("ike_phase_1_recv_ID: failed to get "
1027 "Address in Remote-ID section [%s]", rs);
1028 free(rid);
1029 return -1;
1030 }
1031 if (text2sockaddr(p, 0, &sa, af, 0) == -1) {
1032 log_print("ike_phase_1_recv_ID: "
1033 "failed to parse address %s", p);
1034 free(rid);
1035 return -1;
1036 }
1037 if ((id_type == IPSEC_ID_IPV4_ADDR1 &&
1038 sa->sa_family != AF_INET2) ||
1039 (id_type == IPSEC_ID_IPV6_ADDR5 &&
1040 sa->sa_family != AF_INET624)) {
1041 log_print("ike_phase_1_recv_ID: "
1042 "address %s not of expected family", p);
1043 free(rid);
1044 free(sa);
1045 return -1;
1046 }
1047 memcpy(rid, sockaddr_addrdata(sa),
1048 sockaddr_addrlen(sa));
1049 free(sa);
1050 break;
1051
1052 case IPSEC_ID_FQDN2:
1053 case IPSEC_ID_USER_FQDN3:
1054 case IPSEC_ID_KEY_ID11:
1055 p = conf_get_str(rs, "Name");
1056 if (!p) {
1057 log_print("ike_phase_1_recv_ID: failed to "
1058 "get Name in Remote-ID section [%s]", rs);
1059 free(rid);
1060 return -1;
1061 }
1062 memcpy(rid, p, sz);
1063 break;
1064
1065 default:
1066 log_print("ike_phase_1_recv_ID: "
1067 "unsupported ID type %d", id_type);
1068 free(rid);
1069 return -1;
1070 }
1071
1072 /* Compare expected/desired and received remote ID */
1073 if (memcmp(rid, payload->p + ISAKMP_ID_DATA_OFF8, sz) != 0) {
1074 free(rid);
1075 log_print("ike_phase_1_recv_ID: "
1076 "received remote ID other than expected %s", p);
1077 return -1;
1078 }
1079 free(rid);
1080 }
1081 /* Choose the right fields to fill in */
1082 id = initiator ? &exchange->id_r : &exchange->id_i;
1083 id_len = initiator ? &exchange->id_r_len : &exchange->id_i_len;
1084
1085 *id_len = GET_ISAKMP_GEN_LENGTH(payload->p)field_get_num (isakmp_gen_fld + 2, payload->p) - ISAKMP_GEN_SZ4;
1086 *id = malloc(*id_len);
1087 if (!*id) {
1088 log_error("ike_phase_1_recv_ID: malloc (%lu) failed",
1089 (unsigned long)*id_len);
1090 return -1;
1091 }
1092 memcpy(*id, payload->p + ISAKMP_GEN_SZ4, *id_len);
1093 snprintf(header, sizeof header, "ike_phase_1_recv_ID: %s",
1094 constant_name(ipsec_id_cst, GET_ISAKMP_ID_TYPE(payload->p)field_get_num (isakmp_id_fld + 0, payload->p)));
1095 LOG_DBG_BUF((LOG_NEGOTIATION, 40, header,log_debug_buf (LOG_NEGOTIATION, 40, header, payload->p + 8
, *id_len + 4 - 8)
1096 payload->p + ISAKMP_ID_DATA_OFF,log_debug_buf (LOG_NEGOTIATION, 40, header, payload->p + 8
, *id_len + 4 - 8)
1097 *id_len + ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF))log_debug_buf (LOG_NEGOTIATION, 40, header, payload->p + 8
, *id_len + 4 - 8)
;
1098 payload->flags |= PL_MARK1;
1099 return 0;
1100}
1101
1102/* Receive HASH and check that the exchange has been consistent. */
1103int
1104ike_phase_1_recv_AUTH(struct message *msg)
1105{
1106 struct exchange *exchange = msg->exchange;
1107 struct ipsec_exch *ie = exchange->data;
1108 struct prf *prf;
1109 struct hash *hash = ie->hash;
1110 char header[80];
1111 size_t hashsize = hash->hashsize;
1112 int initiator = exchange->initiator;
1113 u_int8_t **hash_p, *id;
1114 size_t id_len;
1115
1116 /* Choose the right fields to fill in */
1117 hash_p = initiator ? &ie->hash_r : &ie->hash_i;
1118 id = initiator ? exchange->id_r : exchange->id_i;
1119 id_len = initiator ? exchange->id_r_len : exchange->id_i_len;
1120
1121 /* The decoded hash will be in ie->hash_r or ie->hash_i */
1122 if (ie->ike_auth->decode_hash(msg)) {
1123 message_drop(msg, ISAKMP_NOTIFY_INVALID_ID_INFORMATION18, 0, 1,
1124 0);
1125 return -1;
1126 }
1127 /* Allocate the prf and start calculating his HASH. */
1128 prf = prf_alloc(ie->prf_type, hash->type, ie->skeyid, ie->skeyid_len);
1129 if (!prf) {
1130 /* XXX Log? */
1131 return -1;
1132 }
1133 prf->Init(prf->prfctx);
1134 prf->Update(prf->prfctx, initiator ? ie->g_xr : ie->g_xi, ie->g_x_len);
1135 prf->Update(prf->prfctx, initiator ? ie->g_xi : ie->g_xr, ie->g_x_len);
1136 prf->Update(prf->prfctx, exchange->cookies +
1137 (initiator ? ISAKMP_HDR_RCOOKIE_OFF8 : ISAKMP_HDR_ICOOKIE_OFF0),
1138 ISAKMP_HDR_ICOOKIE_LEN8);
1139 prf->Update(prf->prfctx, exchange->cookies +
1140 (initiator ? ISAKMP_HDR_ICOOKIE_OFF0 : ISAKMP_HDR_RCOOKIE_OFF8),
1141 ISAKMP_HDR_ICOOKIE_LEN8);
1142 prf->Update(prf->prfctx, ie->sa_i_b, ie->sa_i_b_len);
1143 prf->Update(prf->prfctx, id, id_len);
1144 prf->Final(hash->digest, prf->prfctx);
1145 prf_free(prf);
1146 snprintf(header, sizeof header, "ike_phase_1_recv_AUTH: "
1147 "computed HASH_%c", initiator ? 'R' : 'I');
1148 LOG_DBG_BUF((LOG_NEGOTIATION, 80, header, hash->digest, hashsize))log_debug_buf (LOG_NEGOTIATION, 80, header, hash->digest, hashsize
)
;
1149
1150 /* Check that the hash we got matches the one we computed. */
1151 if (memcmp(*hash_p, hash->digest, hashsize) != 0) {
1152 /* XXX Log? */
1153 return -1;
1154 }
1155
1156 /* Mark message as authenticated. */
1157 msg->flags |= MSG_AUTHENTICATED0x10;
1158
1159 return 0;
1160}
1161
1162struct attr_node {
1163 LIST_ENTRY(attr_node)struct { struct attr_node *le_next; struct attr_node **le_prev
; }
link;
1164 u_int16_t type;
1165};
1166
1167struct validation_state {
1168 struct conf_list_node *xf;
1169 LIST_HEAD(attr_head, attr_node)struct attr_head { struct attr_node *lh_first; } attrs;
1170 char *life;
1171};
1172
1173/* Validate a proposal inside SA according to EXCHANGE's policy. */
1174static int
1175ike_phase_1_validate_prop(struct exchange *exchange, struct sa *sa,
1176 struct sa *isakmp_sa)
1177{
1178 struct conf_list *conf, *tags;
1179 struct conf_list_node *xf, *tag;
1180 struct proto *proto;
1181 struct validation_state vs;
1182 struct attr_node *node, *next_node;
1183
1184 /* Get the list of transforms. */
1185 conf = conf_get_list(exchange->policy, "Transforms");
1186 if (!conf)
1
Assuming 'conf' is non-null
2
Taking false branch
1187 return 0;
1188
1189 for (xf = TAILQ_FIRST(&conf->fields)((&conf->fields)->tqh_first); xf; xf = TAILQ_NEXT(xf, link)((xf)->link.tqe_next)) {
3
Loop condition is true. Entering loop body
1190 for (proto = TAILQ_FIRST(&sa->protos)((&sa->protos)->tqh_first); proto;
4
Loop condition is false. Execution continues on line 1232
1191 proto = TAILQ_NEXT(proto, link)((proto)->link.tqe_next)) {
1192 /* Mark all attributes in our policy as unseen. */
1193 LIST_INIT(&vs.attrs)do { ((&vs.attrs)->lh_first) = ((void*)0); } while (0);
1194 vs.xf = xf;
1195 vs.life = 0;
1196 if (attribute_map(proto->chosen->p +
1197 ISAKMP_TRANSFORM_SA_ATTRS_OFF8,
1198 GET_ISAKMP_GEN_LENGTH(proto->chosen->p)field_get_num (isakmp_gen_fld + 2, proto->chosen->p) -
1199 ISAKMP_TRANSFORM_SA_ATTRS_OFF8,
1200 attribute_unacceptable, &vs))
1201 goto try_next;
1202
1203 /* Sweep over unseen tags in this section. */
1204 tags = conf_get_tag_list(xf->field);
1205 if (tags) {
1206 for (tag = TAILQ_FIRST(&tags->fields)((&tags->fields)->tqh_first); tag;
1207 tag = TAILQ_NEXT(tag, link)((tag)->link.tqe_next))
1208 /*
1209 * XXX Should we care about attributes
1210 * we have, they do not provide?
1211 */
1212 for (node = LIST_FIRST(&vs.attrs)((&vs.attrs)->lh_first);
1213 node; node = next_node) {
1214 next_node =
1215 LIST_NEXT(node, link)((node)->link.le_next);
1216 if (node->type ==
1217 constant_value(ike_attr_cst,
1218 tag->field)) {
1219 LIST_REMOVE(node, link)do { if ((node)->link.le_next != ((void*)0)) (node)->link
.le_next->link.le_prev = (node)->link.le_prev; *(node)->
link.le_prev = (node)->link.le_next; ; ; } while (0)
;
1220 free(node);
1221 }
1222 }
1223 conf_free_list(tags);
1224 }
1225 /* Are there leftover tags in this section? */
1226 node = LIST_FIRST(&vs.attrs)((&vs.attrs)->lh_first);
1227 if (node)
1228 goto try_next;
1229 }
1230
1231 /* All protocols were OK, we succeeded. */
1232 LOG_DBG((LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: "log_debug (LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: "
"success")
1233 "success"))log_debug (LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: "
"success")
;
1234 conf_free_list(conf);
1235 free(vs.life);
5
1st function call argument is an uninitialized value
1236 return 1;
1237
1238try_next:
1239 /* Are there leftover tags in this section? */
1240 node = LIST_FIRST(&vs.attrs)((&vs.attrs)->lh_first);
1241 while (node) {
1242 LIST_REMOVE(node, link)do { if ((node)->link.le_next != ((void*)0)) (node)->link
.le_next->link.le_prev = (node)->link.le_prev; *(node)->
link.le_prev = (node)->link.le_next; ; ; } while (0)
;
1243 free(node);
1244 node = LIST_FIRST(&vs.attrs)((&vs.attrs)->lh_first);
1245 }
1246 free(vs.life);
1247 }
1248
1249 LOG_DBG((LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: failure"))log_debug (LOG_NEGOTIATION, 20, "ike_phase_1_validate_prop: failure"
)
;
1250 conf_free_list(conf);
1251 return 0;
1252}
1253
1254/*
1255 * Look at the attribute of type TYPE, located at VALUE for LEN bytes forward.
1256 * The VVS argument holds a validation state kept across invocations.
1257 * If the attribute is unacceptable to use, return non-zero, otherwise zero.
1258 */
1259static int
1260attribute_unacceptable(u_int16_t type, u_int8_t *value, u_int16_t len,
1261 void *vvs)
1262{
1263 struct validation_state *vs = vvs;
1264 struct conf_list *life_conf;
1265 struct conf_list_node *xf = vs->xf, *life;
1266 char *tag = constant_lookup(ike_attr_cst, type);
1267 char *str;
1268 struct constant_map *map;
1269 struct attr_node *node;
1270 int rv, dur = 0;
1271
1272 if (!tag) {
1273 log_print("attribute_unacceptable: "
1274 "attribute type %d not known", type);
1275 return 1;
1276 }
1277 switch (type) {
1278 case IKE_ATTR_ENCRYPTION_ALGORITHM1:
1279 case IKE_ATTR_HASH_ALGORITHM2:
1280 case IKE_ATTR_AUTHENTICATION_METHOD3:
1281 case IKE_ATTR_GROUP_DESCRIPTION4:
1282 case IKE_ATTR_GROUP_TYPE5:
1283 case IKE_ATTR_PRF13:
1284 str = conf_get_str(xf->field, tag);
1285 if (!str) {
1286 /* This attribute does not exist in this policy. */
1287 log_print("attribute_unacceptable: "
1288 "attr %s does not exist in %s", tag, xf->field);
1289 return 1;
1290 }
1291 map = constant_link_lookup(ike_attr_cst, type);
1292 if (!map)
1293 return 1;
1294
1295 if ((constant_value(map, str) == decode_16(value)) ||
1296 (!strcmp(str, "ANY"))) {
1297 /* Mark this attribute as seen. */
1298 node = malloc(sizeof *node);
1299 if (!node) {
1300 log_error("attribute_unacceptable: "
1301 "malloc (%lu) failed",
1302 (unsigned long)sizeof *node);
1303 return 1;
1304 }
1305 node->type = type;
1306 LIST_INSERT_HEAD(&vs->attrs, node, link)do { if (((node)->link.le_next = (&vs->attrs)->lh_first
) != ((void*)0)) (&vs->attrs)->lh_first->link.le_prev
= &(node)->link.le_next; (&vs->attrs)->lh_first
= (node); (node)->link.le_prev = &(&vs->attrs)
->lh_first; } while (0)
;
1307 return 0;
1308 }
1309 log_print("attribute_unacceptable: %s: got %s, expected %s",
1310 tag, constant_name(map, decode_16(value)), str);
1311 return 1;
1312
1313 case IKE_ATTR_GROUP_PRIME6:
1314 case IKE_ATTR_GROUP_GENERATOR_17:
1315 case IKE_ATTR_GROUP_GENERATOR_28:
1316 case IKE_ATTR_GROUP_CURVE_A9:
1317 case IKE_ATTR_GROUP_CURVE_B10:
1318 /* XXX Bignums not handled yet. */
1319 log_print("attribute_unacceptable: "
1320 "bignum type %d not supported", type);
1321 return 1;
1322
1323 case IKE_ATTR_LIFE_TYPE11:
1324 case IKE_ATTR_LIFE_DURATION12:
1325 life_conf = conf_get_list(xf->field, "Life");
1326 if (life_conf &&
1327 !strcmp(conf_get_str(xf->field, "Life"), "ANY")) {
1328 conf_free_list(life_conf);
1329 return 0;
1330 }
1331
1332 rv = 1;
1333 if (!life_conf) {
1334 /* Life attributes given, but not in our policy. */
1335 log_print("attribute_unacceptable: "
1336 "life attribute received, none in policy");
1337 return 1;
1338 }
1339 /*
1340 * Each lifetime type must match, otherwise we turn the
1341 * proposal down. In order to do this we need to find the
1342 * specific section of our policy's "Life" list and match
1343 * its duration.
1344 */
1345 switch (type) {
1346 case IKE_ATTR_LIFE_TYPE11:
1347 for (life = TAILQ_FIRST(&life_conf->fields)((&life_conf->fields)->tqh_first); life;
1348 life = TAILQ_NEXT(life, link)((life)->link.tqe_next)) {
1349 str = conf_get_str(life->field, "LIFE_TYPE");
1350 if (!str) {
1351 log_print("attribute_unacceptable: "
1352 "section [%s] has no LIFE_TYPE",
1353 life->field);
1354 continue;
1355 }
1356
1357 /*
1358 * If this is the type we are looking at,
1359 * save a pointer to this section in vs->life.
1360 */
1361 if (constant_value(ike_duration_cst, str) ==
1362 decode_16(value)) {
1363 vs->life = strdup(life->field);
1364 rv = 0;
1365 goto bail_out;
1366 }
1367 }
1368 log_print("attribute_unacceptable: "
1369 "unrecognized LIFE_TYPE %d", decode_16(value));
1370 vs->life = 0;
1371 break;
1372
1373 case IKE_ATTR_LIFE_DURATION12:
1374 if (!vs->life) {
1375 log_print("attribute_unacceptable: "
1376 "LIFE_DURATION without LIFE_TYPE");
1377 rv = 1;
1378 goto bail_out;
1379 }
1380 str = conf_get_str(vs->life, "LIFE_DURATION");
1381 if (str) {
1382 if (!strcmp(str, "ANY"))
1383 rv = 0;
1384 else {
1385 dur = (len == 4) ? decode_32(value) :
1386 decode_16(value);
1387 if ((rv = !conf_match_num(vs->life,
1388 "LIFE_DURATION", dur))) {
1389 log_print(
1390 "attribute_unacceptable: "
1391 "LIFE_DURATION: got %d, "
1392 " expected %s", dur, str);
1393 }
1394 }
1395 } else {
1396 log_print("attribute_unacceptable: "
1397 "section [%s] has no LIFE_DURATION",
1398 vs->life);
1399 rv = 1;
1400 }
1401
1402 free(vs->life);
1403 vs->life = 0;
1404 break;
1405 }
1406
1407bail_out:
1408 conf_free_list(life_conf);
1409 return rv;
1410
1411 case IKE_ATTR_KEY_LENGTH14:
1412 case IKE_ATTR_FIELD_SIZE15:
1413 case IKE_ATTR_GROUP_ORDER16:
1414 if (conf_match_num(xf->field, tag, decode_16(value))) {
1415 /* Mark this attribute as seen. */
1416 node = malloc(sizeof *node);
1417 if (!node) {
1418 log_error("attribute_unacceptable: "
1419 "malloc (%lu) failed",
1420 (unsigned long)sizeof *node);
1421 return 1;
1422 }
1423 node->type = type;
1424 LIST_INSERT_HEAD(&vs->attrs, node, link)do { if (((node)->link.le_next = (&vs->attrs)->lh_first
) != ((void*)0)) (&vs->attrs)->lh_first->link.le_prev
= &(node)->link.le_next; (&vs->attrs)->lh_first
= (node); (node)->link.le_prev = &(&vs->attrs)
->lh_first; } while (0)
;
1425 return 0;
1426 }
1427 return 1;
1428 default:
1429 log_print("attribute_unacceptable: unexpected type %d",
1430 type);
1431 }
1432 return 1;
1433}