Bug Summary

File:programs/pluto/ikev1_spdb_struct.c
Warning:line 145, column 7
Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ikev1_spdb_struct.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 -mrelocation-model pic -pic-level 2 -pic-is-pie -mthread-model posix -mdisable-fp-elim -relaxed-aliasing -fmath-errno -masm-verbose -mconstructor-aliases -munwind-tables -fuse-init-array -target-cpu x86-64 -dwarf-column-info -debugger-tuning=gdb -resource-dir /usr/lib64/clang/8.0.0 -D TimeZoneOffset=timezone -D linux -D PIE -D NSS_IPSEC_PROFILE -D XFRM_SUPPORT -D USE_XFRM_INTERFACE -D USE_DNSSEC -D DEFAULT_DNSSEC_ROOTKEY_FILE="/var/lib/unbound/root.key" -D HAVE_LABELED_IPSEC -D HAVE_SECCOMP -D LIBCURL -D USE_LINUX_AUDIT -D USE_SYSTEMD_WATCHDOG -D HAVE_NM -D XAUTH_HAVE_PAM -D USE_3DES -D USE_AES -D USE_CAMELLIA -D USE_CHACHA -D USE_DH31 -D USE_MD5 -D USE_SHA1 -D USE_SHA2 -D USE_PRF_AES_XCBC -D DEFAULT_RUNDIR="/run/pluto" -D IPSEC_CONF="/etc/ipsec.conf" -D IPSEC_CONFDDIR="/etc/ipsec.d" -D IPSEC_NSSDIR="/etc/ipsec.d" -D IPSEC_CONFDIR="/etc" -D IPSEC_EXECDIR="/usr/local/libexec/ipsec" -D IPSEC_SBINDIR="/usr/local/sbin" -D IPSEC_VARDIR="/var" -D POLICYGROUPSDIR="/etc/ipsec.d/policies" -D IPSEC_SECRETS_FILE="/etc/ipsec.secrets" -D FORCE_PR_ASSERT -D USE_FORK=1 -D USE_VFORK=0 -D USE_DAEMON=0 -D USE_PTHREAD_SETSCHEDPRIO=1 -D GCC_LINT -D HAVE_LIBCAP_NG -I . -I ../../OBJ.linux.x86_64/programs/pluto -I ../../include -I /usr/include/nss3 -I /usr/include/nspr4 -I /home/build/libreswan/programs/pluto/linux-copy -D HERE_BASENAME="ikev1_spdb_struct.c" -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/8.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wno-missing-field-initializers -std=gnu99 -fdebug-compilation-dir /home/build/libreswan/programs/pluto -ferror-limit 19 -fmessage-length 0 -stack-protector 3 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -o /tmp/scan-build-2020-09-09-193337-25440-1 -x c /home/build/libreswan/programs/pluto/ikev1_spdb_struct.c -faddrsig
1/* Security Policy Data Base (such as it is)
2 *
3 * Copyright (C) 1998-2001,2013 D. Hugh Redelmeier <hugh@mimosa.com>
4 * Copyright (C) 2012-2013 Paul Wouters <paul@libreswan.org>
5 * Copyright (C) 2012 Avesh Agarwal <avagarwa@redhat.com>
6 * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com>
7 * Copyright (C) 2016-2019 Andrew Cagney <cagney@gnu.org>
8 * Copyright (C) 2019 Paul Wouters <pwouters@redhat.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 * for more details.
19 */
20
21#include <stdio.h>
22#include <string.h>
23#include <stdlib.h>
24#include <sys/socket.h>
25#include <netinet/in.h>
26#include <arpa/inet.h>
27
28#include "sysdep.h"
29#include "constants.h"
30
31#include "defs.h"
32#include "id.h"
33#include "x509.h"
34#include "certs.h"
35#include "connections.h" /* needs id.h */
36#include "state.h"
37#include "packet.h"
38#include "keys.h"
39#include "kernel.h" /* needs connections.h */
40#include "log.h"
41#include "spdb.h"
42#include "whack.h" /* for RC_LOG_SERIOUS */
43#include "plutoalg.h"
44#include "crypto.h"
45
46#include "ikev1.h"
47#include "kernel_alg.h"
48#include "ike_alg.h"
49#include "ike_alg_encrypt.h"
50#include "ike_alg_integ.h"
51#include "db_ops.h"
52#include "lswfips.h" /* for libreswan_fipsmode */
53#include "crypt_prf.h"
54#include "ikev1_message.h"
55#include "ip_endpoint.h"
56#include "nat_traversal.h"
57
58
59#ifndef HAVE_LABELED_IPSEC1
60static bool_Bool parse_secctx_attr(pb_stream *pbs UNUSED__attribute__ ((unused)), struct state *st UNUSED__attribute__ ((unused)))
61{
62 /*
63 * We received a security label but don't support it,
64 * so fail the IKE negotiation
65 */
66 loglog(RC_LOG_SERIOUS, "Received Sec Ctx Textual Label but support for labeled ipsec not compiled in");
67 return FALSE0;
68}
69#else
70#include "security_selinux.h"
71static bool_Bool parse_secctx_attr(pb_stream *pbs, struct state *st)
72{
73 struct xfrm_user_sec_ctx_ike uctx;
74
75 if (!in_struct(&uctx.ctx, &sec_ctx_desc, pbs, NULL((void*)0)))
23
Assuming the condition is false
24
Taking false branch
76 return FALSE0;
77
78 if (pbs_left(pbs)((size_t)((pbs)->roof - (pbs)->cur)) != uctx.ctx.ctx_len) {
25
Assuming the condition is false
26
Taking false branch
79 /* ??? should we ignore padding? */
80 loglog(RC_LOG_SERIOUS, "Sec Ctx Textual Label length mismatch (length=%u; packet space = %u)",
81 uctx.ctx.ctx_len, (unsigned)pbs_left(pbs)((size_t)((pbs)->roof - (pbs)->cur)));
82 return FALSE0;
83 }
84
85 if (uctx.ctx.ctx_len > MAX_SECCTX_LEN4096) {
27
Assuming the condition is false
28
Taking false branch
86 loglog(RC_LOG_SERIOUS, "Sec Ctx Textual Label too long (%u > %u)",
87 uctx.ctx.ctx_len, MAX_SECCTX_LEN4096);
88 return FALSE0;
89 }
90
91 zero(&uctx.sec_ctx_value)memset((&uctx.sec_ctx_value), '\0', sizeof(*(&uctx.sec_ctx_value
)))
; /* abundance of caution */
92
93 if (!in_raw(uctx.sec_ctx_value, uctx.ctx.ctx_len, pbs,
29
Assuming the condition is false
30
Taking false branch
94 "Sec Ctx Textual Label"))
95 return FALSE0;
96
97 /*
98 * The label should have been NUL-terminated.
99 * We will generously add one if it is missing and there is room.
100 */
101 if (uctx.ctx.ctx_len == 0 ||
31
Assuming the condition is false
32
Taking false branch
102 uctx.sec_ctx_value[uctx.ctx.ctx_len - 1] != '\0') {
103 if (uctx.ctx.ctx_len == MAX_SECCTX_LEN4096) {
104 loglog(RC_LOG_SERIOUS, "Sec Ctx Textual Label missing terminal NUL and there is no space to add it");
105 return FALSE0;
106 }
107 DBG_log("Sec Ctx Textual Label missing terminal NUL; we are adding it");
108 uctx.sec_ctx_value[uctx.ctx.ctx_len] = '\0';
109 uctx.ctx.ctx_len++;
110 }
111
112 if (strlen(uctx.sec_ctx_value) + 1 != uctx.ctx.ctx_len) {
33
Assuming the condition is false
34
Taking false branch
113 loglog(RC_LOG_SERIOUS, "Error: Sec Ctx Textual Label contains embedded NUL");
114 return FALSE0;
115 }
116
117 if (st->sec_ctx == NULL((void*)0) && st->st_state->kind == STATE_QUICK_R0) {
35
Assuming the condition is true
36
Assuming the condition is false
37
Taking false branch
118 DBG_log("Received sec ctx in responder state");
119
120 /*
121 * verify that the received security label is
122 * within range of this connection's policy's security label
123 */
124 if (st->st_connection->policy_label == NULL((void*)0)) {
125 loglog(RC_LOG_SERIOUS, "This state (connection) is not labeled ipsec enabled, so cannot proceed");
126 return FALSE0;
127 } else if (within_range(uctx.sec_ctx_value,
128 st->st_connection->policy_label)) {
129 DBG_log("security context verification succeeded");
130 } else {
131 loglog(RC_LOG_SERIOUS, "security context verification failed");
132 return FALSE0;
133 }
134 /*
135 * Note: this clones the whole of uctx.sec_ctx_value.
136 * It would be reasonable to clone only the part that's used.
137 */
138 st->sec_ctx = clone_thing(uctx, "struct xfrm_user_sec_ctx_ike")((__typeof__(&(uctx))) clone_bytes((const void *)&(uctx
), sizeof(uctx), ("struct xfrm_user_sec_ctx_ike")))
;
139 } else if (st->st_state->kind == STATE_QUICK_R0) {
38
Taking false branch
140 /* ??? can this happen? */
141 /* ??? should we check that this label and first one match? */
142 DBG_log("Received sec ctx in responder state again: ignoring this one");
143 } else if (st->st_state->kind == STATE_QUICK_I1) {
39
Assuming the condition is true
40
Taking true branch
144 dbg("initiator state received security context from responder state, now verifying if both are same"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("initiator state received security context from responder state, now verifying if both are same"
); } }
;
41
Assuming the condition is false
42
Taking false branch
145 if (streq(st->sec_ctx->sec_ctx_value, uctx.sec_ctx_value)(strcmp((st->sec_ctx->sec_ctx_value), (uctx.sec_ctx_value
)) == 0)
) {
43
Null pointer passed as an argument to a 'nonnull' parameter
146 DBG_log("security contexts are verified in the initiator state");
147 } else {
148 loglog(RC_LOG_SERIOUS, "security context verification failed in the initiator state (shouldn't reach here unless responder (or something in between) is modifying the security context");
149 return FALSE0;
150 }
151 }
152 return TRUE1;
153}
154#endif
155
156/** output an attribute (within an SA) */
157/* Note: ikev2_out_attr is a clone, with the same bugs */
158static bool_Bool out_attr(int type,
159 unsigned long val,
160 struct_desc *attr_desc,
161 enum_names *const *attr_val_descs,
162 pb_stream *pbs)
163{
164 if (val >> 16 == 0) {
165 /* short value: use TV form */
166 struct isakmp_attribute attr = {
167 .isaat_af_type = type | ISAKMP_ATTR_AF_TV0x8000,
168 .isaat_lv = val,
169 };
170 if (!out_struct(&attr, attr_desc, pbs, NULL((void*)0)))
171 return FALSE0;
172 } else {
173 /* This is a real fudge! Since we rarely use long attributes
174 * and since this is the only place where we can cause an
175 * ISAKMP message length to be other than a multiple of 4 octets,
176 * we force the length of the value to be a multiple of 4 octets.
177 * Furthermore, we only handle values up to 4 octets in length.
178 * Voila: a fixed format!
179 */
180 pb_stream val_pbs;
181 uint32_t nval = htonl(val);
182
183 passert((type & ISAKMP_ATTR_AF_MASK) == 0){ _Bool assertion__ = (type & 0x8000) == 0; if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev1_spdb_struct.c" , .line = 183}, "%s", "(type & ISAKMP_ATTR_AF_MASK) == 0"
); } }
;
184 struct isakmp_attribute attr = {
185 .isaat_af_type = type | ISAKMP_ATTR_AF_TLV0,
186 .isaat_lv = sizeof(nval),
187 };
188 if (!out_struct(&attr, attr_desc, pbs, &val_pbs) ||
189 !out_raw(&nval, sizeof(nval), &val_pbs,
190 "long attribute value"))
191 return FALSE0;
192
193 close_output_pbs(&val_pbs);
194 }
195 if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) {
196 enum_names *d = attr_val_descs[type];
197 if (d != NULL((void*)0))
198 DBG_log(" [%lu is %s]",
199 val, enum_show(d, val));
200 }
201 return TRUE1;
202}
203
204/*
205 * Determine if the proposal is acceptable (or need to keep looking).
206 *
207 * As a rule, this doesn't log - instead it assumes things were
208 * reported earlier.
209 */
210
211static bool_Bool ikev1_verify_esp(const struct connection *c,
212 const struct trans_attrs *ta,
213 struct logger *logger)
214{
215 if (!(c->policy & POLICY_ENCRYPT((lset_t)1 << (POLICY_ENCRYPT_IX)))) {
216 dbg("ignoring ESP proposal as POLICY_ENCRYPT unset"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring ESP proposal as POLICY_ENCRYPT unset"
); } }
;
217 return false0; /* try another */
218 }
219
220 /*
221 * Check encryption.
222 *
223 * For the key-length, its assumed that the caller checked for
224 * and patched up either a missing or zero key-length, setting
225 * .enckeylen to the correct value (which might still be 0).
226 */
227 if (ta->ta_encrypt == NULL((void*)0)) {
228 /*
229 * No encryption. Either because its lookup failed or
230 * because it was NULLed to force the proposal's
231 * rejection.
232 */
233 dbg({ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring ESP proposal with NULLed or unknown encryption"
); } }
234 "ignoring ESP proposal with NULLed or unknown encryption"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring ESP proposal with NULLed or unknown encryption"
); } }
;
235 return false0; /* try another */
236 }
237 if (!kernel_alg_encrypt_ok(ta->ta_encrypt)) {
238 /*
239 * No kernel support. Needed because ALG_INFO==NULL
240 * will act as a wild card. XXX: but is ALG_INFO ever
241 * NULL?
242 */
243 dbg("ignoring ESP proposal with alg %s not present in kernel",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring ESP proposal with alg %s not present in kernel"
, ta->ta_encrypt->common.fqn); } }
244 ta->ta_encrypt->common.fqn){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring ESP proposal with alg %s not present in kernel"
, ta->ta_encrypt->common.fqn); } }
;
245 return false0;
246 }
247 if (!encrypt_has_key_bit_length(ta->ta_encrypt, ta->enckeylen)) {
248 loglog(RC_LOG_SERIOUS,
249 "kernel algorithm does not like: %s key_len %u is incorrect",
250 ta->ta_encrypt->common.fqn, ta->enckeylen);
251 endpoint_buf epb;
252 loglog(RC_LOG_SERIOUS,
253 "unsupported ESP Transform %s from %s",
254 ta->ta_encrypt->common.fqn,
255 str_sensitive_endpoint(&c->spd.that.host_addr, &epb));
256 return false0; /* try another */
257 }
258
259 /*
260 * Check integrity.
261 */
262 if (ta->ta_integ == NULL((void*)0)) {
263 /*
264 * No integrity. Since, for ESP, when integrity is
265 * missing, it is forced to .ta_integ=NONE (i.e., not
266 * NULL), a NULL here must indicate that integrity was
267 * present but the lookup failed.
268 */
269 dbg("ignoring ESP proposal with unknown integrity"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring ESP proposal with unknown integrity"
); } }
;
270 return false0; /* try another */
271 }
272 if (ta->ta_integ != &ike_alg_integ_none && !kernel_alg_integ_ok(ta->ta_integ)) {
273 /*
274 * No kernel support. Needed because ALG_INFO==NULL
275 * will act as a wild card.
276 *
277 * XXX: but is ALG_INFO ever NULL?
278 *
279 * XXX: check for NONE comes from old code just
280 * assumed NONE was supported.
281 */
282 dbg("ignoring ESP proposal with alg %s not present in kernel",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring ESP proposal with alg %s not present in kernel"
, ta->ta_integ->common.fqn); } }
283 ta->ta_integ->common.fqn){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring ESP proposal with alg %s not present in kernel"
, ta->ta_integ->common.fqn); } }
;
284 return false0;
285 }
286
287 /*
288 * Check for screwups. Perhaps the parser rejcts this, anyone
289 * know?
290 */
291 if (ta->ta_prf != NULL((void*)0)) {
292 pexpect_fail(logger, HERE(where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 292}
, "ESP IPsec Transform refused: contains unexpected PRF %s",
293 ta->ta_prf->common.fqn);
294 return false0;
295 }
296 if (ta->ta_dh != NULL((void*)0)) {
297 pexpect_fail(logger, HERE(where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 297}
, "ESP IPsec Transform refused: contains unexpected DH %s",
298 ta->ta_dh->common.fqn);
299 return false0;
300 }
301
302 if (c->child_proposals.p == NULL((void*)0)) {
303 dbg("ESP IPsec Transform verified unconditionally; no alg_info to check against"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ESP IPsec Transform verified unconditionally; no alg_info to check against"
); } }
;
304 return true1;
305 }
306
307 FOR_EACH_PROPOSAL(c->child_proposals.p, proposal)for (struct proposal *proposal = next_proposal(c->child_proposals
.p, ((void*)0)); proposal != ((void*)0); proposal = next_proposal
(c->child_proposals.p, proposal))
{
308 struct v1_proposal algs = v1_proposal(proposal);
309 if (algs.encrypt == ta->ta_encrypt &&
310 (algs.enckeylen == 0 ||
311 ta->enckeylen == 0 ||
312 algs.enckeylen == ta->enckeylen) &&
313 algs.integ == ta->ta_integ) {
314 dbg("ESP IPsec Transform verified; matches alg_info entry"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ESP IPsec Transform verified; matches alg_info entry"
); } }
;
315 return true1;
316 }
317 }
318 return false0;
319}
320
321static bool_Bool ikev1_verify_ah(const struct connection *c,
322 const struct trans_attrs *ta,
323 struct logger *logger)
324{
325 if (!(c->policy & POLICY_AUTHENTICATE((lset_t)1 << (POLICY_AUTHENTICATE_IX)))) {
326 dbg("ignoring AH proposal as POLICY_AUTHENTICATE unset"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring AH proposal as POLICY_AUTHENTICATE unset"
); } }
;
327 return false0; /* try another */
328 }
329 if (ta->ta_encrypt != NULL((void*)0)) {
330 pexpect_fail(logger, HERE(where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 330}
,
331 "AH IPsec Transform refused: contains unexpected encryption %s",
332 ta->ta_encrypt->common.fqn);
333 return false0;
334 }
335 if (ta->ta_prf != NULL((void*)0)) {
336 pexpect_fail(logger, HERE(where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 336}
, "AH IPsec Transform refused: contains unexpected PRF %s",
337 ta->ta_prf->common.fqn);
338 return false0;
339 }
340 if (ta->ta_integ == NULL((void*)0)) {
341 pexpect_fail(logger, HERE(where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 341}
, "AH IPsec Transform refused: missing integrity algorithm");
342 return false0;
343 }
344 if (ta->ta_dh != NULL((void*)0)) {
345 pexpect_fail(logger, HERE(where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 345}
, "AH IPsec Transform refused: contains unexpected DH %s",
346 ta->ta_dh->common.fqn);
347 return false0;
348 }
349 if (c->child_proposals.p == NULL((void*)0)) {
350 dbg("AH IPsec Transform verified unconditionally; no alg_info to check against"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("AH IPsec Transform verified unconditionally; no alg_info to check against"
); } }
;
351 return true1;
352 }
353
354 FOR_EACH_PROPOSAL(c->child_proposals.p, proposal)for (struct proposal *proposal = next_proposal(c->child_proposals
.p, ((void*)0)); proposal != ((void*)0); proposal = next_proposal
(c->child_proposals.p, proposal))
{ /* really AH */
355 struct v1_proposal algs = v1_proposal(proposal);
356 if (algs.integ == ta->ta_integ) {
357 dbg("ESP IPsec Transform verified; matches alg_info entry"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ESP IPsec Transform verified; matches alg_info entry"
); } }
;
358 return true1;
359 }
360 }
361
362 libreswan_log("AH IPsec Transform refused: %s",loglog(RC_LOG, "AH IPsec Transform refused: %s", ta->ta_integ
->common.fqn)
363 ta->ta_integ->common.fqn)loglog(RC_LOG, "AH IPsec Transform refused: %s", ta->ta_integ
->common.fqn)
;
364 return false0;
365}
366
367/**
368 * Output an SA, as described by a db_sa.
369 * This has the side-effect of allocating SPIs for us.
370 *
371 */
372bool_Bool ikev1_out_sa(pb_stream *outs,
373 const struct db_sa *sadb,
374 struct state *st,
375 bool_Bool oakley_mode,
376 bool_Bool aggressive_mode)
377{
378 struct db_sa *revised_sadb;
379
380 if (oakley_mode) {
381 /*
382 * Construct the proposals by combining ALG_INFO_IKE
383 * with the AUTH (proof of identity) extracted from
384 * the (default?) SADB. As if by magic, attrs[2] is
385 * always the authentication method.
386 *
387 * XXX: Should replace SADB with a simple map to the
388 * auth method.
389 */
390 struct db_attr *auth = &sadb->prop_conjs[0].props[0].trans[0].attrs[2];
391 passert(auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD){ _Bool assertion__ = auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD
; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 391}, "%s", "auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD"
); } }
;
392 enum ikev1_auth_method auth_method = auth->val;
393 /*
394 * Aggr-Mode - Max transforms == 2 - Multiple
395 * transforms, 1 DH group
396 */
397 revised_sadb = v1_ike_alg_make_sadb(st->st_connection->ike_proposals,
398 auth_method,
399 aggressive_mode,
400 st->st_logger);
401 } else {
402 revised_sadb = kernel_alg_makedb(st->st_connection->policy,
403 st->st_connection->child_proposals,
404 true1, st->st_logger);
405
406 /* add IPcomp proposal if policy asks for it */
407
408 if (revised_sadb != NULL((void*)0) && (st->st_policy & POLICY_COMPRESS((lset_t)1 << (POLICY_COMPRESS_IX)))) {
409 struct db_trans *ipcomp_trans = alloc_thing(((struct db_trans*) alloc_bytes(sizeof(struct db_trans), ("ipcomp_trans"
)))
410 struct db_trans, "ipcomp_trans")((struct db_trans*) alloc_bytes(sizeof(struct db_trans), ("ipcomp_trans"
)))
;
411
412 /* allocate space for 2 proposals */
413 struct db_prop *ipcomp_prop =
414 alloc_bytes(sizeof(struct db_prop) * 2,
415 "ipcomp_prop");
416
417 passert(revised_sadb->prop_conjs->prop_cnt == 1){ _Bool assertion__ = revised_sadb->prop_conjs->prop_cnt
== 1; if (!assertion__) { lsw_passert_fail((where_t) { .func
= __func__, .basename = "ikev1_spdb_struct.c" , .line = 417}
, "%s", "revised_sadb->prop_conjs->prop_cnt == 1"); } }
;
418
419 /* construct the IPcomp proposal */
420 ipcomp_trans->transid = IPCOMP_DEFLATE;
421 ipcomp_trans->attrs = NULL((void*)0);
422 ipcomp_trans->attr_cnt = 0;
423
424 /* copy the original proposal */
425 ipcomp_prop[0].protoid =
426 revised_sadb->prop_conjs->props->
427 protoid;
428 ipcomp_prop[0].trans =
429 revised_sadb->prop_conjs->props->trans;
430 ipcomp_prop[0].trans_cnt =
431 revised_sadb->prop_conjs->props->
432 trans_cnt;
433
434 /* and add our IPcomp proposal */
435 ipcomp_prop[1].protoid = PROTO_IPCOMP4;
436 ipcomp_prop[1].trans = ipcomp_trans;
437 ipcomp_prop[1].trans_cnt = 1;
438
439 /* free the old proposal, and ... */
440 pfree(revised_sadb->prop_conjs->props);
441
442 /* ... use our new one instead */
443 revised_sadb->prop_conjs->props = ipcomp_prop;
444 revised_sadb->prop_conjs->prop_cnt += 1;
445 }
446 }
447
448 /* more sanity */
449 if (revised_sadb != NULL((void*)0))
450 sadb = revised_sadb;
451
452 /* SA header out */
453 pb_stream sa_pbs;
454 {
455 struct isakmp_sa sa = {
456 .isasa_doi = ISAKMP_DOI_IPSEC1 /* all we know */
457 };
458 if (!out_struct(&sa, &isakmp_sa_desc, outs, &sa_pbs))
459 goto fail;
460 }
461
462 /* within SA: situation out */
463 {
464 static const uint32_t situation = SIT_IDENTITY_ONLY0x01;
465
466 if (!out_struct(&situation, &ipsec_sit_desc, &sa_pbs, NULL((void*)0)))
467 goto fail;
468 }
469
470 /* within SA: Proposal Payloads
471 *
472 * Multiple Proposals with the same number are simultaneous
473 * (conjuncts) and must deal with different protocols (AH or ESP).
474 * Proposals with different numbers are alternatives (disjuncts),
475 * in preference order.
476 * Proposal numbers must be monotonic.
477 * See RFC 2408 "ISAKMP" 4.2
478 */
479
480 bool_Bool ah_spi_generated = FALSE0,
481 esp_spi_generated = FALSE0,
482 ipcomp_cpi_generated = FALSE0;
483
484 for (unsigned pcn = 0; pcn < sadb->prop_conj_cnt; pcn++) {
485 const struct db_prop_conj *const pc = &sadb->prop_conjs[pcn];
486 int valid_prop_cnt = pc->prop_cnt;
487
488 dbg("%s() pcn: %d has %d valid proposals", __func__, pcn, valid_prop_cnt){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() pcn: %d has %d valid proposals", __func__
, pcn, valid_prop_cnt); } }
;
489
490 for (unsigned pn = 0; pn < pc->prop_cnt; pn++) {
491 const struct db_prop *const p = &pc->props[pn];
492 pb_stream proposal_pbs;
493
494 /*
495 * set the tunnel_mode bit on the last proposal only, and
496 * only if we are trying to negotiate tunnel mode in the first
497 * place.
498 */
499 const bool_Bool tunnel_mode = (valid_prop_cnt == 1) &&
500 (st->st_policy & POLICY_TUNNEL((lset_t)1 << (POLICY_TUNNEL_IX)));
501
502 /*
503 * pick the part of the proposal we are trying to work on
504 */
505
506 dbg("%s() pcn: %d pn: %d<%d valid_count: %d trans_cnt: %d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() pcn: %d pn: %d<%d valid_count: %d trans_cnt: %d"
, __func__, pcn, pn, pc->prop_cnt, valid_prop_cnt, p->trans_cnt
); } }
507 __func__, pcn, pn, pc->prop_cnt, valid_prop_cnt,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() pcn: %d pn: %d<%d valid_count: %d trans_cnt: %d"
, __func__, pcn, pn, pc->prop_cnt, valid_prop_cnt, p->trans_cnt
); } }
508 p->trans_cnt){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("%s() pcn: %d pn: %d<%d valid_count: %d trans_cnt: %d"
, __func__, pcn, pn, pc->prop_cnt, valid_prop_cnt, p->trans_cnt
); } }
;
509
510 /* but, skip things if the transform count is zero */
511 if (p->trans_cnt == 0)
512 continue;
513
514 /* Proposal header */
515 {
516 valid_prop_cnt--;
517
518 struct isakmp_proposal proposal = {
519 .isap_proposal = pcn,
520 .isap_protoid = p->protoid,
521 .isap_spisize = oakley_mode ? 0 :
522 p->protoid == PROTO_IPCOMP4 ?
523 IPCOMP_CPI_SIZE2 :
524 IPSEC_DOI_SPI_SIZE4,
525 .isap_pnp = valid_prop_cnt > 0 ?
526 ISAKMP_NEXT_P : ISAKMP_NEXT_NONE,
527 .isap_notrans = p->trans_cnt
528 };
529
530 if (!out_struct(&proposal, &isakmp_proposal_desc,
531 &sa_pbs, &proposal_pbs))
532 goto fail;
533 }
534
535 /* Per-protocols stuff:
536 * Set trans_desc.
537 * Set attr_desc.
538 * Set attr_val_descs.
539 * If not oakley_mode, emit SPI.
540 * We allocate SPIs on demand.
541 * All ESPs in an SA will share a single SPI.
542 * All AHs in an SAwill share a single SPI.
543 * AHs' SPI will be distinct from ESPs'.
544 * ??? If multiple ESPs are composed, how should their SPIs
545 * be allocated?
546 */
547 const struct_desc *trans_desc;
548 const struct_desc *attr_desc;
549 enum_names *const *attr_val_descs;
550
551 {
552 ipsec_spi_t *spi_ptr = NULL((void*)0);
553 const struct ip_protocol *proto = NULL((void*)0);
554 bool_Bool *spi_generated = NULL((void*)0);
555
556 switch (p->protoid) {
557 case PROTO_ISAKMP1:
558 passert(oakley_mode){ _Bool assertion__ = oakley_mode; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 558}, "%s", "oakley_mode"); } }
;
559 trans_desc =
560 &isakmp_isakmp_transform_desc;
561 attr_desc =
562 &isakmp_oakley_attribute_desc;
563 attr_val_descs = oakley_attr_val_descs;
564 /* no SPI needed */
565 break;
566
567 case PROTO_IPSEC_AH2:
568 passert(!oakley_mode){ _Bool assertion__ = !oakley_mode; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 568}, "%s", "!oakley_mode"); } }
;
569 trans_desc = &isakmp_ah_transform_desc;
570 attr_desc =
571 &isakmp_ipsec_attribute_desc;
572 attr_val_descs = ipsec_attr_val_descs;
573 spi_ptr = &st->st_ah.our_spi;
574 spi_generated = &ah_spi_generated;
575 proto = &ip_protocol_ah;
576 break;
577
578 case PROTO_IPSEC_ESP3:
579 passert(!oakley_mode){ _Bool assertion__ = !oakley_mode; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 579}, "%s", "!oakley_mode"); } }
;
580 trans_desc =
581 &isakmp_esp_transform_desc;
582 attr_desc =
583 &isakmp_ipsec_attribute_desc;
584 attr_val_descs = ipsec_attr_val_descs;
585 spi_ptr = &st->st_esp.our_spi;
586 spi_generated = &esp_spi_generated;
587 proto = &ip_protocol_esp;
588 break;
589
590 case PROTO_IPCOMP4:
591 passert(!oakley_mode){ _Bool assertion__ = !oakley_mode; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 591}, "%s", "!oakley_mode"); } }
;
592 trans_desc =
593 &isakmp_ipcomp_transform_desc;
594 attr_desc =
595 &isakmp_ipsec_attribute_desc;
596 attr_val_descs = ipsec_attr_val_descs;
597
598 /*
599 * a CPI isn't quite the same as an SPI
600 * so we use specialized code to emit it.
601 */
602 if (!ipcomp_cpi_generated) {
603 st->st_ipcomp.our_spi =
604 get_my_cpi(
605 &st->st_connection->spd,
606 tunnel_mode);
607 if (st->st_ipcomp.our_spi == 0)
608 goto fail; /* problem generating CPI */
609
610 ipcomp_cpi_generated = TRUE1;
611 }
612 /*
613 * CPI is stored in network low order end of an
614 * ipsec_spi_t. So we start a couple of bytes in.
615 */
616 if (!out_raw((u_char *)&st->st_ipcomp.our_spi +
617 IPSEC_DOI_SPI_SIZE4 -
618 IPCOMP_CPI_SIZE2,
619 IPCOMP_CPI_SIZE2,
620 &proposal_pbs, "CPI"))
621 goto fail;
622 break;
623
624 default:
625 bad_case(p->protoid)libreswan_bad_case("p->protoid", (p->protoid), (where_t
) { .func = __func__, .basename = "ikev1_spdb_struct.c" , .line
= 625})
;
626 }
627
628 if (spi_ptr != NULL((void*)0)) {
629 if (!*spi_generated) {
630 *spi_ptr = get_ipsec_spi(0,
631 proto,
632 &st->st_connection->spd,
633 tunnel_mode);
634 *spi_generated = TRUE1;
635 }
636 if (!out_raw((u_char *)spi_ptr,
637 IPSEC_DOI_SPI_SIZE4,
638 &proposal_pbs, "SPI"))
639 goto fail;
640 }
641 }
642
643 /* within proposal: Transform Payloads */
644 for (unsigned tn = 0; tn != p->trans_cnt; tn++) {
645 const struct db_trans *const t = &p->trans[tn];
646 pb_stream trans_pbs;
647
648 {
649 const struct isakmp_transform trans = {
650 .isat_tnp = (tn == p->trans_cnt - 1) ?
651 ISAKMP_NEXT_NONE :
652 ISAKMP_NEXT_T,
653 .isat_transnum = tn,
654 .isat_transid = t->transid
655 };
656
657 if (!out_struct(&trans, trans_desc,
658 &proposal_pbs, &trans_pbs))
659 goto fail;
660 }
661
662 /* Within transform: Attributes. */
663
664 /* For Phase 2 / Quick Mode, GROUP_DESCRIPTION is
665 * automatically generated because it must be the same
666 * in every transform. Except IPCOMP.
667 */
668 if (p->protoid != PROTO_IPCOMP4 &&
669 st->st_pfs_group != NULL((void*)0)) {
670 passert(!oakley_mode){ _Bool assertion__ = !oakley_mode; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 670}, "%s", "!oakley_mode"); } }
;
671 passert(st->st_pfs_group != &unset_group){ _Bool assertion__ = st->st_pfs_group != &unset_group
; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 671}, "%s", "st->st_pfs_group != &unset_group"
); } }
;
672 if (!out_attr(GROUP_DESCRIPTION,
673 st->st_pfs_group->group,
674 attr_desc,
675 attr_val_descs,
676 &trans_pbs))
677 goto fail;
678 }
679
680 /* automatically generate duration
681 * and, for Phase 2 / Quick Mode, encapsulation.
682 */
683 if (oakley_mode) {
684 if (!out_attr(OAKLEY_LIFE_TYPE,
685 OAKLEY_LIFE_SECONDS1,
686 attr_desc,
687 attr_val_descs,
688 &trans_pbs) ||
689 !out_attr(OAKLEY_LIFE_DURATION,
690 deltasecs(st->st_connection->sa_ike_life_seconds),
691 attr_desc,
692 attr_val_descs,
693 &trans_pbs))
694 goto fail;
695 } else {
696 /* RFC 2407 (IPSEC DOI) 4.5 specifies that
697 * the default is "unspecified (host-dependent)".
698 * This makes little sense, so we always specify it.
699 *
700 * Unlike other IPSEC transforms, IPCOMP defaults
701 * to Transport Mode, so we can exploit the default
702 * (draft-shacham-ippcp-rfc2393bis-05.txt 4.1).
703 */
704 if (p->protoid != PROTO_IPCOMP4 ||
705 st->st_policy & POLICY_TUNNEL((lset_t)1 << (POLICY_TUNNEL_IX))) {
706 if (!out_attr(
707 ENCAPSULATION_MODE,
708 NAT_T_ENCAPSULATION_MODE(( ((st)->hidden_variables.st_nat_traversal & ( ((lset_t
)1 << (NATED_HOST)) | ((lset_t)1 << (NATED_PEER))
)) ? ( ((st->st_policy) & ((lset_t)1 << (POLICY_TUNNEL_IX
))) ? ( ((st)->hidden_variables.st_nat_traversal & ( (
(lset_t)1 << (NAT_TRAVERSAL_METHOD_IETF_RFC)) )) ? 3 : 61443
) : ( ((st)->hidden_variables.st_nat_traversal & ( ((
lset_t)1 << (NAT_TRAVERSAL_METHOD_IETF_RFC)) )) ? 4 : 61444
) ) : ( ((st)->st_policy & ((lset_t)1 << (POLICY_TUNNEL_IX
))) ? 1 : 2 ) )
709 st,( ((st)->hidden_variables.st_nat_traversal & ( ((lset_t
)1 << (NATED_HOST)) | ((lset_t)1 << (NATED_PEER))
)) ? ( ((st->st_policy) & ((lset_t)1 << (POLICY_TUNNEL_IX
))) ? ( ((st)->hidden_variables.st_nat_traversal & ( (
(lset_t)1 << (NAT_TRAVERSAL_METHOD_IETF_RFC)) )) ? 3 : 61443
) : ( ((st)->hidden_variables.st_nat_traversal & ( ((
lset_t)1 << (NAT_TRAVERSAL_METHOD_IETF_RFC)) )) ? 4 : 61444
) ) : ( ((st)->st_policy & ((lset_t)1 << (POLICY_TUNNEL_IX
))) ? 1 : 2 ) )
710 st->st_policy)( ((st)->hidden_variables.st_nat_traversal & ( ((lset_t
)1 << (NATED_HOST)) | ((lset_t)1 << (NATED_PEER))
)) ? ( ((st->st_policy) & ((lset_t)1 << (POLICY_TUNNEL_IX
))) ? ( ((st)->hidden_variables.st_nat_traversal & ( (
(lset_t)1 << (NAT_TRAVERSAL_METHOD_IETF_RFC)) )) ? 3 : 61443
) : ( ((st)->hidden_variables.st_nat_traversal & ( ((
lset_t)1 << (NAT_TRAVERSAL_METHOD_IETF_RFC)) )) ? 4 : 61444
) ) : ( ((st)->st_policy & ((lset_t)1 << (POLICY_TUNNEL_IX
))) ? 1 : 2 ) )
,
711 attr_desc,
712 attr_val_descs,
713 &trans_pbs))
714 goto fail;
715 }
716 if (!out_attr(SA_LIFE_TYPE,
717 SA_LIFE_TYPE_SECONDS1,
718 attr_desc,
719 attr_val_descs,
720 &trans_pbs) ||
721 !out_attr(SA_LIFE_DURATION,
722 deltasecs(st->st_connection->sa_ipsec_life_seconds),
723 attr_desc,
724 attr_val_descs,
725 &trans_pbs))
726 goto fail;
727
728 if (st->sec_ctx != NULL((void*)0) &&
729 st->st_connection->policy_label != NULL((void*)0)) {
730 passert(st->sec_ctx->ctx.ctx_len <= MAX_SECCTX_LEN){ _Bool assertion__ = st->sec_ctx->ctx.ctx_len <= 4096
; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 730}, "%s", "st->sec_ctx->ctx.ctx_len <= MAX_SECCTX_LEN"
); } }
;
731
732 pb_stream val_pbs;
733 struct isakmp_attribute attr = {
734 .isaat_af_type = secctx_attr_type |
735 ISAKMP_ATTR_AF_TLV0,
736 };
737
738 if (!out_struct(&attr,
739 attr_desc,
740 &trans_pbs,
741 &val_pbs) ||
742 !out_struct(&st->sec_ctx->ctx,
743 &sec_ctx_desc,
744 &val_pbs,
745 NULL((void*)0)) ||
746 !out_raw(st->sec_ctx->
747 sec_ctx_value,
748 st->sec_ctx->ctx.ctx_len, &val_pbs,
749 " variable length sec ctx"))
750 goto fail;
751
752 close_output_pbs(&val_pbs);
753 }
754 }
755
756 /*
757 * spit out attributes from table
758 *
759 * XXX: Assume that the code
760 * constructing the attribute table
761 * handled optional and extra key
762 * lengths (and if it is wrong it is
763 * deliberate). I.e., don't try to
764 * also handle it here.
765 *
766 * OTOH, do completely override
767 * key-lengths when so impaired.
768 */
769 enum impair_emit impair_key_length_attribute =
770 (oakley_mode ? impair.ike_key_length_attribute
771 : impair.child_key_length_attribute);
772 long key_length_to_impair = -1;
773 for (unsigned an = 0; an != t->attr_cnt; an++) {
774 const struct db_attr *a = &t->attrs[an];
775 /*
776 * Strip out or duplicate
777 * key-length attribute?
778 */
779 if (impair_key_length_attribute > 0 &&
780 (oakley_mode ? a->type.oakley == OAKLEY_KEY_LENGTH
781 : a->type.ipsec == KEY_LENGTH)) {
782 key_length_to_impair = a->val;
783 libreswan_log("IMPAIR: stripping key-length")loglog(RC_LOG, "IMPAIR: stripping key-length");
784 continue;
785 }
786 if (!out_attr(oakley_mode ? a->type.oakley : a->type.ipsec ,
787 a->val,
788 attr_desc,
789 attr_val_descs,
790 &trans_pbs))
791 goto fail;
792 }
793 /*
794 * put back a key-length?
795 */
796 switch (impair_key_length_attribute) {
797 case IMPAIR_EMIT_NO:
798 break;
799 case IMPAIR_EMIT_EMPTY:
800 /*
801 * XXX: how? IKEv2 sends a
802 * long form packet of no
803 * length.
804 */
805 libreswan_log("IMPAIR: key-length-attribute:empty not implemented")loglog(RC_LOG, "IMPAIR: key-length-attribute:empty not implemented"
)
;
806 break;
807 case IMPAIR_EMIT_OMIT:
808 libreswan_log("IMPAIR: not sending key-length attribute")loglog(RC_LOG, "IMPAIR: not sending key-length attribute");
809 break;
810 case IMPAIR_EMIT_DUPLICATE:
811 if (key_length_to_impair >= 0) {
812 libreswan_log("IMPAIR: duplicating key-length")loglog(RC_LOG, "IMPAIR: duplicating key-length");
813 for (unsigned dup = 0; dup < 2; dup++) {
814 if (!out_attr(oakley_mode ? OAKLEY_KEY_LENGTH : KEY_LENGTH,
815 key_length_to_impair,
816 attr_desc,
817 attr_val_descs,
818 &trans_pbs))
819 goto fail;
820 }
821 } else {
822 libreswan_log("IMPAIR: no key-length to duplicate")loglog(RC_LOG, "IMPAIR: no key-length to duplicate");
823 }
824 break;
825 case IMPAIR_EMIT_ROOF:
826 default:
827 {
828 unsigned keylen = impair_key_length_attribute - IMPAIR_EMIT_ROOF;
829 libreswan_log("IMPAIR: sending key-length attribute value %u",loglog(RC_LOG, "IMPAIR: sending key-length attribute value %u"
, keylen)
830 keylen)loglog(RC_LOG, "IMPAIR: sending key-length attribute value %u"
, keylen)
;
831 if (!out_attr(oakley_mode ? OAKLEY_KEY_LENGTH : KEY_LENGTH,
832 keylen, attr_desc, attr_val_descs,
833 &trans_pbs))
834 goto fail;
835 break;
836 }
837 }
838 close_output_pbs(&trans_pbs);
839 }
840 close_output_pbs(&proposal_pbs);
841 }
842 /* end of a conjunction of proposals */
843 }
844 close_output_pbs(&sa_pbs);
845 free_sa(&revised_sadb);
846 return TRUE1;
847
848fail:
849 free_sa(&revised_sadb);
850 return FALSE0;
851}
852
853/** Handle long form of duration attribute.
854 * The code is can only handle values that can fit in unsigned long.
855 * "Clamping" is probably an acceptable way to impose this limitation.
856 *
857 * @param pbs PB Stream
858 * @return uint32_t duration, in seconds.
859 */
860static uint32_t decode_long_duration(pb_stream *pbs)
861{
862 uint32_t val = 0;
863
864 /* ignore leading zeros */
865 while (pbs_left(pbs)((size_t)((pbs)->roof - (pbs)->cur)) != 0 && *pbs->cur == '\0')
866 pbs->cur++;
867
868 if (pbs_left(pbs)((size_t)((pbs)->roof - (pbs)->cur)) > sizeof(val)) {
869 /* "clamp" too large value to max representable value */
870 val -= 1; /* portable way to get to maximum value */
871 dbg(" too large duration clamped to: %" PRIu32, val){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" too large duration clamped to: %" "u", val
); } }
;
872 } else {
873 /* decode number */
874 while (pbs_left(pbs)((size_t)((pbs)->roof - (pbs)->cur)) != 0)
875 val = (val << BITS_PER_BYTE8) | *pbs->cur++;
876 dbg(" long duration: %" PRIu32, val){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log(" long duration: %" "u", val); } }
;
877 }
878 return val;
879}
880
881/* Preparse the body of an IKEv1 ISAKMP SA Payload and find which policy is
882 * required to match the packet. Errors are just ignored and will be detected
883 * and handled later in parse_isakmp_sa_body().
884 *
885 * All we want for the moment is to know whether peer is using RSA or PSK.
886 * NOTE: sa_pbs is passed by value so the caller's PBS is unchanged!
887 */
888lset_t preparse_isakmp_sa_body(pb_stream sa_pbs /* by value! */)
889{
890 pb_stream proposal_pbs;
891 struct isakmp_proposal proposal;
892 pb_stream trans_pbs;
893 struct isakmp_transform trans;
894 struct isakmp_attribute a;
895 pb_stream attr_pbs;
896 uint32_t ipsecdoisit;
897 unsigned trans_left;
898 lset_t policy = LEMPTY((lset_t)0);
899
900 if (!in_struct(&ipsecdoisit, &ipsec_sit_desc, &sa_pbs, NULL((void*)0)))
901 return LEMPTY((lset_t)0);
902
903 if (!in_struct(&proposal, &isakmp_proposal_desc, &sa_pbs,
904 &proposal_pbs))
905 return LEMPTY((lset_t)0);
906
907 if (proposal.isap_spisize > MAX_ISAKMP_SPI_SIZE(2 * 8))
908 return LEMPTY((lset_t)0);
909
910 if (proposal.isap_spisize > 0) {
911 u_char junk_spi[MAX_ISAKMP_SPI_SIZE(2 * 8)];
912
913 if (!in_raw(junk_spi, proposal.isap_spisize, &proposal_pbs,
914 "Oakley SPI"))
915 return LEMPTY((lset_t)0);
916 }
917
918 trans_left = proposal.isap_notrans;
919 while (trans_left-- != 0) {
920 if (!in_struct(&trans, &isakmp_isakmp_transform_desc,
921 &proposal_pbs,
922 &trans_pbs))
923 return LEMPTY((lset_t)0);
924
925 while (pbs_left(&trans_pbs)((size_t)((&trans_pbs)->roof - (&trans_pbs)->cur
))
>= isakmp_oakley_attribute_desc.size) {
926 if (!in_struct(&a, &isakmp_oakley_attribute_desc,
927 &trans_pbs,
928 &attr_pbs))
929 return LEMPTY((lset_t)0);
930
931 switch (a.isaat_af_type) {
932 case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV0x8000:
933 switch (a.isaat_lv) {
934 case XAUTHInitPreShared:
935 policy |= POLICY_XAUTH((lset_t)1 << (POLICY_XAUTH_IX));
936 /* fallthrough */
937 case OAKLEY_PRESHARED_KEY:
938 policy |= POLICY_PSK((lset_t)1 << (POLICY_PSK_IX));
939 break;
940 case XAUTHInitRSA:
941 policy |= POLICY_XAUTH((lset_t)1 << (POLICY_XAUTH_IX));
942 /* fallthrough */
943 case OAKLEY_RSA_SIG:
944 policy |= POLICY_RSASIG((lset_t)1 << (POLICY_RSASIG_IX));
945 break;
946 }
947 break;
948 }
949 }
950 }
951
952 /*
953 * These policy bits will be used in a call to find_host_connection.
954 * The meaning is: each of these present bits must be present
955 * in a connection's policy.
956 *
957 * If both PSK and RSASIG are present now, that means that
958 * either is acceptable. The right way to express this is
959 * to turn both off!
960 */
961 if (LIN(POLICY_PSK | POLICY_RSASIG, policy)(((((lset_t)1 << (POLICY_PSK_IX)) | ((lset_t)1 <<
(POLICY_RSASIG_IX))) & (policy)) == (((lset_t)1 <<
(POLICY_PSK_IX)) | ((lset_t)1 << (POLICY_RSASIG_IX))))
)
962 policy &= ~(POLICY_PSK((lset_t)1 << (POLICY_PSK_IX)) | POLICY_RSASIG((lset_t)1 << (POLICY_RSASIG_IX)));
963
964 return policy;
965}
966
967static bool_Bool ikev1_verify_ike(const struct trans_attrs *ta,
968 struct ike_proposals ike_proposals,
969 struct logger *logger)
970{
971 if (ta->ta_encrypt == NULL((void*)0)) {
972 log_message(RC_LOG_SERIOUS, logger,
973 "OAKLEY proposal refused: missing encryption");
974 return false0;
975 }
976 if (ta->ta_prf == NULL((void*)0)) {
977 log_message(RC_LOG_SERIOUS, logger,
978 "OAKLEY proposal refused: missing PRF");
979 return false0;
980 }
981 if (ta->ta_integ != NULL((void*)0)) {
982 pexpect_fail(logger, HERE(where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 982}
, "OAKLEY proposal refused: contains unexpected integrity %s",
983 ta->ta_prf->common.fqn);
984 return false0;
985 }
986 if (ta->ta_dh == NULL((void*)0)) {
987 log_message(RC_LOG_SERIOUS, logger, "OAKLEY proposal refused: missing DH");
988 return false0;
989 }
990 if (ike_proposals.p == NULL((void*)0)) {
991 dbg("OAKLEY proposal verified unconditionally; no alg_info to check against"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("OAKLEY proposal verified unconditionally; no alg_info to check against"
); } }
;
992 return true1;
993 }
994
995 /*
996 * simple test to toss low key_len, will accept it only
997 * if specified in "esp" string
998 */
999 bool_Bool ealg_insecure = (ta->enckeylen < 128);
1000
1001 FOR_EACH_PROPOSAL(ike_proposals.p, proposal)for (struct proposal *proposal = next_proposal(ike_proposals.
p, ((void*)0)); proposal != ((void*)0); proposal = next_proposal
(ike_proposals.p, proposal))
{
1002 struct v1_proposal algs = v1_proposal(proposal);
1003 if (algs.encrypt == ta->ta_encrypt &&
1004 (algs.enckeylen == 0 ||
1005 ta->enckeylen == 0 ||
1006 algs.enckeylen == ta->enckeylen) &&
1007 algs.prf == ta->ta_prf &&
1008 algs.dh == ta->ta_dh) {
1009 if (ealg_insecure) {
1010 loglog(RC_LOG_SERIOUS,
1011 "You should NOT use insecure/broken IKE algorithms (%s)!",
1012 ta->ta_encrypt->common.fqn);
1013 } else {
1014 dbg("OAKLEY proposal verified; matching alg_info found"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("OAKLEY proposal verified; matching alg_info found"
); } }
;
1015 return true1;
1016 }
1017 }
1018 }
1019 libreswan_log("Oakley Transform [%s (%d), %s, %s] refused%s",loglog(RC_LOG, "Oakley Transform [%s (%d), %s, %s] refused%s"
, ta->ta_encrypt->common.fqn, ta->enckeylen, ta->
ta_prf->common.fqn, ta->ta_dh->common.fqn, ealg_insecure
? " due to insecure key_len and enc. alg. not listed in \"ike\" string"
: "")
1020 ta->ta_encrypt->common.fqn, ta->enckeylen,loglog(RC_LOG, "Oakley Transform [%s (%d), %s, %s] refused%s"
, ta->ta_encrypt->common.fqn, ta->enckeylen, ta->
ta_prf->common.fqn, ta->ta_dh->common.fqn, ealg_insecure
? " due to insecure key_len and enc. alg. not listed in \"ike\" string"
: "")
1021 ta->ta_prf->common.fqn, ta->ta_dh->common.fqn,loglog(RC_LOG, "Oakley Transform [%s (%d), %s, %s] refused%s"
, ta->ta_encrypt->common.fqn, ta->enckeylen, ta->
ta_prf->common.fqn, ta->ta_dh->common.fqn, ealg_insecure
? " due to insecure key_len and enc. alg. not listed in \"ike\" string"
: "")
1022 ealg_insecure ?loglog(RC_LOG, "Oakley Transform [%s (%d), %s, %s] refused%s"
, ta->ta_encrypt->common.fqn, ta->enckeylen, ta->
ta_prf->common.fqn, ta->ta_dh->common.fqn, ealg_insecure
? " due to insecure key_len and enc. alg. not listed in \"ike\" string"
: "")
1023 " due to insecure key_len and enc. alg. not listed in \"ike\" string" :loglog(RC_LOG, "Oakley Transform [%s (%d), %s, %s] refused%s"
, ta->ta_encrypt->common.fqn, ta->enckeylen, ta->
ta_prf->common.fqn, ta->ta_dh->common.fqn, ealg_insecure
? " due to insecure key_len and enc. alg. not listed in \"ike\" string"
: "")
1024 "")loglog(RC_LOG, "Oakley Transform [%s (%d), %s, %s] refused%s"
, ta->ta_encrypt->common.fqn, ta->enckeylen, ta->
ta_prf->common.fqn, ta->ta_dh->common.fqn, ealg_insecure
? " due to insecure key_len and enc. alg. not listed in \"ike\" string"
: "")
;
1025 return false0;
1026}
1027
1028/**
1029 * Parse the body of an ISAKMP SA Payload (i.e. Phase 1 / Main Mode).
1030 * Various shortcuts are taken. In particular, the policy, such as
1031 * it is, is hardwired.
1032 *
1033 * If r_sa is non-NULL, the body of an SA representing the selected
1034 * proposal is emitted.
1035 *
1036 * If "selection" is true, the SA is supposed to represent the
1037 * single transform that the peer has accepted.
1038 * ??? We only check that it is acceptable, not that it is one that we offered!
1039 *
1040 * It also means that we are inR1, and this as implications when we are
1041 * doing XAUTH, as it changes the meaning of the XAUTHInit/XAUTHResp.
1042 *
1043 * Only IPsec DOI is accepted (what is the ISAKMP DOI?).
1044 * Error response is rudimentary.
1045 *
1046 * This routine is used by main_inI1_outR1() and main_inR1_outI2().
1047 */
1048notification_t parse_isakmp_sa_body(pb_stream *sa_pbs, /* body of input SA Payload */
1049 const struct isakmp_sa *sa, /* header of input SA Payload */
1050 pb_stream *r_sa_pbs, /* if non-NULL, where to emit winning SA */
1051 bool_Bool selection, /* if this SA is a selection, only one transform
1052 * can appear. */
1053 struct state *const st) /* current state object */
1054{
1055 const struct connection *const c = st->st_connection;
1056 bool_Bool xauth_init = FALSE0,
1057 xauth_resp = FALSE0;
1058 const char *const role = selection ? "initiator" : "responder";
1059 const chunk_t *pss = &empty_chunk;
1060
1061 passert(c != NULL){ _Bool assertion__ = c != ((void*)0); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1061}, "%s", "c != NULL"); } }
;
1062
1063 /* calculate the per-end policy that might apply */
1064 const struct spd_route *spd;
1065
1066 for (spd = &c->spd; spd != NULL((void*)0); spd = spd->spd_next) {
1067 if (selection) {
1068 /*
1069 * this is the initiator, we have proposed, they have answered,
1070 * and we must decide if they proposed what we wanted.
1071 */
1072 xauth_init |= spd->this.xauth_client;
1073 xauth_resp |= spd->this.xauth_server;
1074 } else {
1075 /*
1076 * this is the responder, they have proposed to us, what
1077 * are we willing to be?
1078 */
1079 xauth_init |= spd->this.xauth_server;
1080 xauth_resp |= spd->this.xauth_client;
1081 }
1082 }
1083
1084 /* DOI */
1085 if (sa->isasa_doi != ISAKMP_DOI_IPSEC1) {
1086 log_state(RC_LOG_SERIOUS, st, "Unknown/unsupported DOI %s",
1087 enum_show(&doi_names, sa->isasa_doi));
1088 /* XXX Could send notification back */
1089 return DOI_NOT_SUPPORTED; /* reject whole SA */
1090 }
1091
1092 /* Situation */
1093 uint32_t ipsecdoisit;
1094
1095 if (!in_struct(&ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL((void*)0)))
1096 return SITUATION_NOT_SUPPORTED; /* reject whole SA */
1097
1098 if (ipsecdoisit != SIT_IDENTITY_ONLY0x01) {
1099 log_state(RC_LOG_SERIOUS, st, "unsupported IPsec DOI situation (%s)",
1100 bitnamesof(sit_bit_names, ipsecdoisit));
1101 /* XXX Could send notification back */
1102 return SITUATION_NOT_SUPPORTED; /* reject whole SA */
1103 }
1104
1105 /* The rules for ISAKMP SAs are scattered.
1106 * RFC 2409 "IKE" section 5 says that there
1107 * can only be one SA, and it can have only one proposal in it.
1108 * There may well be multiple transforms.
1109 */
1110 struct isakmp_proposal proposal;
1111 pb_stream proposal_pbs;
1112
1113 if (!in_struct(&proposal, &isakmp_proposal_desc, sa_pbs,
1114 &proposal_pbs)) {
1115 return PAYLOAD_MALFORMED; /* reject whole SA */
1116 }
1117
1118 if (proposal.isap_pnp != ISAKMP_NEXT_NONE) {
1119 log_state(RC_LOG_SERIOUS, st,
1120 "Proposal Payload must be alone in Oakley SA; found %s following Proposal",
1121 enum_show(&ikev1_payload_names, proposal.isap_pnp));
1122 return PAYLOAD_MALFORMED; /* reject whole SA */
1123 }
1124
1125 if (proposal.isap_protoid != PROTO_ISAKMP1) {
1126 log_state(RC_LOG_SERIOUS, st,
1127 "unexpected Protocol ID (%s) found in Oakley Proposal",
1128 enum_show(&ikev1_protocol_names, proposal.isap_protoid));
1129 return INVALID_PROTOCOL_ID; /* reject whole SA */
1130 }
1131
1132 /* Just what should we accept for the SPI field?
1133 * The RFC is sort of contradictory. We will ignore the SPI
1134 * as long as it is of the proper size.
1135 *
1136 * From RFC2408 2.4 Identifying Security Associations:
1137 * During phase 1 negotiations, the initiator and responder cookies
1138 * determine the ISAKMP SA. Therefore, the SPI field in the Proposal
1139 * payload is redundant and MAY be set to 0 or it MAY contain the
1140 * transmitting entity's cookie.
1141 *
1142 * From RFC2408 3.5 Proposal Payload:
1143 * o SPI Size (1 octet) - Length in octets of the SPI as defined by
1144 * the Protocol-Id. In the case of ISAKMP, the Initiator and
1145 * Responder cookie pair from the ISAKMP Header is the ISAKMP SPI,
1146 * therefore, the SPI Size is irrelevant and MAY be from zero (0) to
1147 * sixteen (16). If the SPI Size is non-zero, the content of the
1148 * SPI field MUST be ignored. If the SPI Size is not a multiple of
1149 * 4 octets it will have some impact on the SPI field and the
1150 * alignment of all payloads in the message. The Domain of
1151 * Interpretation (DOI) will dictate the SPI Size for other
1152 * protocols.
1153 */
1154 if (proposal.isap_spisize == 0) {
1155 /* empty (0) SPI -- fine */
1156 } else if (proposal.isap_spisize <= MAX_ISAKMP_SPI_SIZE(2 * 8)) {
1157 u_char junk_spi[MAX_ISAKMP_SPI_SIZE(2 * 8)];
1158 diag_t d = pbs_in_raw(&proposal_pbs, junk_spi, proposal.isap_spisize, "Oakley SPI");
1159 if (d != NULL((void*)0)) {
1160 log_diag(RC_LOG_SERIOUS, st->st_logger, &d, "%s", "");
1161 return PAYLOAD_MALFORMED; /* reject whole SA */
1162 }
1163 } else {
1164 log_state(RC_LOG_SERIOUS, st,
1165 "invalid SPI size (%u) in Oakley Proposal",
1166 (unsigned)proposal.isap_spisize);
1167 return INVALID_SPI; /* reject whole SA */
1168 }
1169
1170 if (selection && proposal.isap_notrans != 1) {
1171 log_state(RC_LOG_SERIOUS, st,
1172 "a single Transform is required in a selecting Oakley Proposal; found %u",
1173 (unsigned)proposal.isap_notrans);
1174 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1175 }
1176
1177 /* for each transform payload... */
1178
1179 int last_transnum = -1;
1180 unsigned no_trans_left = proposal.isap_notrans;
1181
1182 for (;;) {
1183 if (no_trans_left == 0) {
1184 log_state(RC_LOG_SERIOUS, st,
1185 "number of Transform Payloads disagrees with Oakley Proposal Payload");
1186 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1187 }
1188
1189 uint16_t life_type = 0; /* initialized to silence GCC */
1190
1191 /* initialize only optional field in ta */
1192 struct trans_attrs ta = {
1193 .life_seconds = deltatime(IKE_SA_LIFETIME_DEFAULTsecs_per_hour) /* When this SA expires (seconds) */
1194 };
1195
1196 struct isakmp_transform trans;
1197 pb_stream trans_pbs;
1198
1199 if (!in_struct(&trans, &isakmp_isakmp_transform_desc,
1200 &proposal_pbs, &trans_pbs)) {
1201 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1202 }
1203
1204 if (trans.isat_transnum <= last_transnum) {
1205 /* picky, picky, picky */
1206 log_state(RC_LOG_SERIOUS, st,
1207 "Transform Numbers are not monotonically increasing in Oakley Proposal");
1208 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1209 }
1210 last_transnum = trans.isat_transnum;
1211
1212 if (trans.isat_transid != KEY_IKE1) {
1213 log_state(RC_LOG_SERIOUS, st,
1214 "expected KEY_IKE but found %s in Oakley Transform",
1215 enum_show(&isakmp_transformid_names,
1216 trans.isat_transid));
1217 return INVALID_TRANSFORM_ID; /* reject whole SA */
1218 }
1219
1220 u_char *attr_start = trans_pbs.cur;
1221 size_t attr_len = pbs_left(&trans_pbs)((size_t)((&trans_pbs)->roof - (&trans_pbs)->cur
))
;
1222
1223 /* process all the attributes that make up the transform */
1224
1225 lset_t seen_attrs = LEMPTY((lset_t)0);
1226 lset_t seen_durations = LEMPTY((lset_t)0);
1227 bool_Bool ok = true1;
1228#define UGH(FMT, ...){ ok = 0; log_state(RC_LOG_SERIOUS, st, FMT". Attribute %s",
..., enum_show(&oakley_attr_names, a.isaat_af_type)); }
\
1229 { \
1230 ok = false0; \
1231 log_state(RC_LOG_SERIOUS, st, \
1232 FMT". Attribute %s", \
1233 ##__VA_ARGS__, \
1234 enum_show(&oakley_attr_names, a.isaat_af_type)); \
1235 }
1236
1237 while (pbs_left(&trans_pbs)((size_t)((&trans_pbs)->roof - (&trans_pbs)->cur
))
>= isakmp_oakley_attribute_desc.size) {
1238 struct isakmp_attribute a;
1239 pb_stream attr_pbs;
1240 uint32_t val; /* room for larger values */
1241
1242 diag_t d = pbs_in_struct(&trans_pbs, &isakmp_oakley_attribute_desc,
1243 &a, sizeof(a), &attr_pbs);
1244 if (d != NULL((void*)0)) {
1245 log_diag(RC_LOG_SERIOUS, st->st_logger, &d, "invalid transform: ");
1246 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1247 }
1248
1249 passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) <{ _Bool assertion__ = (a.isaat_af_type & 0x7FFF) < 64;
if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1250}, "%s", "(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < LELEM_ROOF"
); } }
1250 LELEM_ROOF){ _Bool assertion__ = (a.isaat_af_type & 0x7FFF) < 64;
if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1250}, "%s", "(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < LELEM_ROOF"
); } }
;
1251
1252 if (LHAS(seen_attrs, a.isaat_af_type &(((seen_attrs) & ((lset_t)1 << (a.isaat_af_type &
0x7FFF))) != ((lset_t)0))
1253 ISAKMP_ATTR_RTYPE_MASK)(((seen_attrs) & ((lset_t)1 << (a.isaat_af_type &
0x7FFF))) != ((lset_t)0))
) {
1254 log_state(RC_LOG_SERIOUS, st,
1255 "repeated %s attribute in Oakley Transform %u",
1256 enum_show(&oakley_attr_names,
1257 a.isaat_af_type),
1258 trans.isat_transnum);
1259 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1260 }
1261
1262 seen_attrs |= LELEM(((lset_t)1 << (a.isaat_af_type & 0x7FFF))
1263 a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK)((lset_t)1 << (a.isaat_af_type & 0x7FFF));
1264
1265 val = a.isaat_lv;
1266
1267 if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) {
1268 enum_names *vdesc = oakley_attr_val_descs
1269 [a.isaat_af_type &
1270 ISAKMP_ATTR_RTYPE_MASK0x7FFF];
1271
1272 if (vdesc != NULL((void*)0)) {
1273 const char *nm =
1274 enum_name(vdesc,
1275 val);
1276
1277 if (nm != NULL((void*)0)) {
1278 DBG_log(" [%u is %s]",
1279 (unsigned)val,
1280 nm);
1281 }
1282 }
1283 }
1284
1285 switch (a.isaat_af_type) {
1286 case OAKLEY_ENCRYPTION_ALGORITHM | ISAKMP_ATTR_AF_TV0x8000:
1287 {
1288 const struct encrypt_desc *encrypter = ikev1_get_ike_encrypt_desc(val);
1289 if (encrypter == NULL((void*)0)) {
1290 UGH("%s is not supported",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "%s is not supported"
". Attribute %s", enum_show(&oakley_enc_names, val), enum_show
(&oakley_attr_names, a.isaat_af_type)); }
1291 enum_show(&oakley_enc_names, val)){ ok = 0; log_state(RC_LOG_SERIOUS, st, "%s is not supported"
". Attribute %s", enum_show(&oakley_enc_names, val), enum_show
(&oakley_attr_names, a.isaat_af_type)); }
;
1292 break;
1293 }
1294 ta.ta_encrypt = encrypter;
1295 ta.enckeylen = ta.ta_encrypt->keydeflen;
1296 break;
1297 }
1298
1299 case OAKLEY_HASH_ALGORITHM | ISAKMP_ATTR_AF_TV0x8000:
1300 ta.ta_prf = ikev1_get_ike_prf_desc(val);
1301 if (ta.ta_prf == NULL((void*)0)) {
1302 UGH("%s is not supported",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "%s is not supported"
". Attribute %s", enum_show(&oakley_hash_names, val), enum_show
(&oakley_attr_names, a.isaat_af_type)); }
1303 enum_show(&oakley_hash_names, val)){ ok = 0; log_state(RC_LOG_SERIOUS, st, "%s is not supported"
". Attribute %s", enum_show(&oakley_hash_names, val), enum_show
(&oakley_attr_names, a.isaat_af_type)); }
;
1304 }
1305 break;
1306
1307 case OAKLEY_AUTHENTICATION_METHOD | ISAKMP_ATTR_AF_TV0x8000:
1308 {
1309 lset_t iap = st->st_policy &
1310 POLICY_ID_AUTH_MASK(((lset_t)1 << (POLICY_AUTH_NULL_IX)) - ((lset_t)1 <<
(POLICY_PSK_IX)) + ((lset_t)1 << (POLICY_AUTH_NULL_IX)
))
;
1311
1312 /* check that authentication method is acceptable */
1313 switch (val) {
1314 case XAUTHInitPreShared:
1315 if (!xauth_init) {
1316 UGH("policy does not allow Extended Authentication (XAUTH) of initiator (we are %s)",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow Extended Authentication (XAUTH) of initiator (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
1317 role){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow Extended Authentication (XAUTH) of initiator (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
;
1318 break;
1319 }
1320 ta.doing_xauth = TRUE1;
1321 goto psk_common;
1322
1323 case XAUTHRespPreShared:
1324 if (!xauth_resp) {
1325 UGH("policy does not allow Extended Authentication (XAUTH) of responder (we are %s)",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow Extended Authentication (XAUTH) of responder (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
1326 role){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow Extended Authentication (XAUTH) of responder (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
;
1327 break;
1328 }
1329 ta.doing_xauth = TRUE1;
1330 goto psk_common;
1331
1332 case OAKLEY_PRESHARED_KEY:
1333 if (xauth_init) {
1334 UGH("policy mandates Extended Authentication (XAUTH) with PSK of initiator (we are %s)",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy mandates Extended Authentication (XAUTH) with PSK of initiator (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
1335 role){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy mandates Extended Authentication (XAUTH) with PSK of initiator (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
;
1336 break;
1337 }
1338 if (xauth_resp) {
1339 UGH("policy mandates Extended Authentication (XAUTH) with PSK of responder (we are %s)",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy mandates Extended Authentication (XAUTH) with PSK of responder (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
1340 role){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy mandates Extended Authentication (XAUTH) with PSK of responder (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
;
1341 break;
1342 }
1343psk_common:
1344
1345 if ((iap & POLICY_PSK((lset_t)1 << (POLICY_PSK_IX))) == LEMPTY((lset_t)0)) {
1346 UGH("policy does not allow OAKLEY_PRESHARED_KEY authentication"){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow OAKLEY_PRESHARED_KEY authentication"
". Attribute %s", enum_show(&oakley_attr_names, a.isaat_af_type
)); }
;
1347 } else {
1348 /* check that we can find a proper preshared secret */
1349 pss = get_psk(c, st->st_logger);
1350
1351 if (pss == NULL((void*)0))
1352 {
1353 id_buf mid;
1354 id_buf hid;
1355
1356 UGH("Can't authenticate: no preshared key found for `%s' and `%s'",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "Can't authenticate: no preshared key found for `%s' and `%s'"
". Attribute %s", str_id(&c->spd.this.id, &mid), (
(c)->kind == CK_INSTANCE && ( !((&(c)->spd
.that.id)->kind == ID_IPV4_ADDR || (&(c)->spd.that.
id)->kind == ID_IPV6_ADDR) || sameaddr(&(c)->spd.that
.id.ip_addr, &(c)->spd.that.host_addr) ) ) ? "%any" : str_id
(&c->spd.that.id, &hid), enum_show(&oakley_attr_names
, a.isaat_af_type)); }
1357 str_id(&c->spd.this.id, &mid),{ ok = 0; log_state(RC_LOG_SERIOUS, st, "Can't authenticate: no preshared key found for `%s' and `%s'"
". Attribute %s", str_id(&c->spd.this.id, &mid), (
(c)->kind == CK_INSTANCE && ( !((&(c)->spd
.that.id)->kind == ID_IPV4_ADDR || (&(c)->spd.that.
id)->kind == ID_IPV6_ADDR) || sameaddr(&(c)->spd.that
.id.ip_addr, &(c)->spd.that.host_addr) ) ) ? "%any" : str_id
(&c->spd.that.id, &hid), enum_show(&oakley_attr_names
, a.isaat_af_type)); }
1358 remote_id_was_instantiated(c) ?{ ok = 0; log_state(RC_LOG_SERIOUS, st, "Can't authenticate: no preshared key found for `%s' and `%s'"
". Attribute %s", str_id(&c->spd.this.id, &mid), (
(c)->kind == CK_INSTANCE && ( !((&(c)->spd
.that.id)->kind == ID_IPV4_ADDR || (&(c)->spd.that.
id)->kind == ID_IPV6_ADDR) || sameaddr(&(c)->spd.that
.id.ip_addr, &(c)->spd.that.host_addr) ) ) ? "%any" : str_id
(&c->spd.that.id, &hid), enum_show(&oakley_attr_names
, a.isaat_af_type)); }
1359 "%any" :{ ok = 0; log_state(RC_LOG_SERIOUS, st, "Can't authenticate: no preshared key found for `%s' and `%s'"
". Attribute %s", str_id(&c->spd.this.id, &mid), (
(c)->kind == CK_INSTANCE && ( !((&(c)->spd
.that.id)->kind == ID_IPV4_ADDR || (&(c)->spd.that.
id)->kind == ID_IPV6_ADDR) || sameaddr(&(c)->spd.that
.id.ip_addr, &(c)->spd.that.host_addr) ) ) ? "%any" : str_id
(&c->spd.that.id, &hid), enum_show(&oakley_attr_names
, a.isaat_af_type)); }
1360 str_id(&c->spd.that.id, &hid)){ ok = 0; log_state(RC_LOG_SERIOUS, st, "Can't authenticate: no preshared key found for `%s' and `%s'"
". Attribute %s", str_id(&c->spd.this.id, &mid), (
(c)->kind == CK_INSTANCE && ( !((&(c)->spd
.that.id)->kind == ID_IPV4_ADDR || (&(c)->spd.that.
id)->kind == ID_IPV6_ADDR) || sameaddr(&(c)->spd.that
.id.ip_addr, &(c)->spd.that.host_addr) ) ) ? "%any" : str_id
(&c->spd.that.id, &hid), enum_show(&oakley_attr_names
, a.isaat_af_type)); }
;
1361 } else {
1362 DBG(DBG_PRIVATE, DBG_dump_hunk("User PSK:", *pss)){ if ((cur_debugging & (((lset_t)1 << (DBG_PRIVATE_IX
))))) { { typeof(*pss) hunk_ = *pss; DBG_dump("User PSK:", hunk_
.ptr, hunk_.len); }; } }
;
1363 }
1364 ta.auth = OAKLEY_PRESHARED_KEY;
1365 }
1366 break;
1367
1368 case XAUTHInitRSA:
1369 if (!xauth_init) {
1370 UGH("policy does not allow Extended Authentication (XAUTH) with RSA of initiator (we are %s)",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow Extended Authentication (XAUTH) with RSA of initiator (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
1371 role){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow Extended Authentication (XAUTH) with RSA of initiator (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
;
1372 break;
1373 }
1374 ta.doing_xauth = TRUE1;
1375 goto rsasig_common;
1376
1377 case XAUTHRespRSA:
1378 if (!xauth_resp) {
1379 UGH("policy does not allow Extended Authentication (XAUTH) with RSA of responder (we are %s)",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow Extended Authentication (XAUTH) with RSA of responder (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
1380 role){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow Extended Authentication (XAUTH) with RSA of responder (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
;
1381 break;
1382 }
1383 ta.doing_xauth = TRUE1;
1384 goto rsasig_common;
1385
1386 case OAKLEY_RSA_SIG:
1387 if (xauth_init) {
1388 UGH("policy mandates Extended Authentication (XAUTH) with RSA of initiator (we are %s)",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy mandates Extended Authentication (XAUTH) with RSA of initiator (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
1389 role){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy mandates Extended Authentication (XAUTH) with RSA of initiator (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
;
1390 break;
1391 }
1392 if (xauth_resp) {
1393 UGH("policy mandates Extended Authentication (XAUTH) with RSA of responder (we are %s)",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy mandates Extended Authentication (XAUTH) with RSA of responder (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
1394 role){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy mandates Extended Authentication (XAUTH) with RSA of responder (we are %s)"
". Attribute %s", role, enum_show(&oakley_attr_names, a.
isaat_af_type)); }
;
1395 break;
1396 }
1397rsasig_common:
1398 /* Accept if policy specifies RSASIG or is default */
1399 if ((iap & POLICY_RSASIG((lset_t)1 << (POLICY_RSASIG_IX))) == LEMPTY((lset_t)0)) {
1400 UGH("policy does not allow OAKLEY_RSA_SIG authentication"){ ok = 0; log_state(RC_LOG_SERIOUS, st, "policy does not allow OAKLEY_RSA_SIG authentication"
". Attribute %s", enum_show(&oakley_attr_names, a.isaat_af_type
)); }
;
1401 } else {
1402 /* We'd like to check
1403 * that we can find a
1404 * public key for peer
1405 * and a private key
1406 * for us that is
1407 * suitable, but we
1408 * don't yet have
1409 * peer's ID Payload,
1410 * so it seems futile
1411 * to try. We can
1412 * assume that if he
1413 * proposes it, he
1414 * thinks we've got
1415 * it. If we proposed
1416 * it, perhaps we know
1417 * what we're doing.
1418 */
1419 ta.auth = OAKLEY_RSA_SIG;
1420 }
1421 break;
1422
1423 default:
1424 UGH("Pluto does not support %s authentication",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "Pluto does not support %s authentication"
". Attribute %s", enum_show(&oakley_auth_names, val), enum_show
(&oakley_attr_names, a.isaat_af_type)); }
1425 enum_show(&oakley_auth_names, val)){ ok = 0; log_state(RC_LOG_SERIOUS, st, "Pluto does not support %s authentication"
". Attribute %s", enum_show(&oakley_auth_names, val), enum_show
(&oakley_attr_names, a.isaat_af_type)); }
;
1426 break;
1427 }
1428 }
1429 break;
1430
1431 case OAKLEY_GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV0x8000:
1432 ta.ta_dh = ikev1_get_ike_dh_desc(val);
1433 if (ta.ta_dh == NULL((void*)0)) {
1434 UGH("OAKLEY_GROUP %d not supported", val){ ok = 0; log_state(RC_LOG_SERIOUS, st, "OAKLEY_GROUP %d not supported"
". Attribute %s", val, enum_show(&oakley_attr_names, a.isaat_af_type
)); }
;
1435 break;
1436 }
1437 break;
1438
1439 case OAKLEY_LIFE_TYPE | ISAKMP_ATTR_AF_TV0x8000:
1440 switch (val) {
1441 case OAKLEY_LIFE_SECONDS1:
1442 case OAKLEY_LIFE_KILOBYTES2:
1443 if (LHAS(seen_durations, val)(((seen_durations) & ((lset_t)1 << (val))) != ((lset_t
)0))
) {
1444 log_state(RC_LOG_SERIOUS, st,
1445 "attribute OAKLEY_LIFE_TYPE value %s repeated",
1446 enum_show(&oakley_lifetime_names, val));
1447 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1448 }
1449 seen_durations |= LELEM(val)((lset_t)1 << (val));
1450 life_type = val;
1451 break;
1452 default:
1453 UGH("unknown value %s",{ ok = 0; log_state(RC_LOG_SERIOUS, st, "unknown value %s"". Attribute %s"
, enum_show(&oakley_lifetime_names, val), enum_show(&
oakley_attr_names, a.isaat_af_type)); }
1454 enum_show(&oakley_lifetime_names, val)){ ok = 0; log_state(RC_LOG_SERIOUS, st, "unknown value %s"". Attribute %s"
, enum_show(&oakley_lifetime_names, val), enum_show(&
oakley_attr_names, a.isaat_af_type)); }
;
1455 break;
1456 }
1457 break;
1458
1459 case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TLV0:
1460 val = decode_long_duration(&attr_pbs);
1461 /* FALL THROUGH */
1462 case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TV0x8000:
1463 if (!LHAS(seen_attrs, OAKLEY_LIFE_TYPE)(((seen_attrs) & ((lset_t)1 << (OAKLEY_LIFE_TYPE)))
!= ((lset_t)0))
) {
1464 UGH("OAKLEY_LIFE_DURATION attribute not preceded by OAKLEY_LIFE_TYPE attribute"){ ok = 0; log_state(RC_LOG_SERIOUS, st, "OAKLEY_LIFE_DURATION attribute not preceded by OAKLEY_LIFE_TYPE attribute"
". Attribute %s", enum_show(&oakley_attr_names, a.isaat_af_type
)); }
;
1465 break;
1466 }
1467 seen_attrs &=
1468 ~(LELEM(OAKLEY_LIFE_DURATION)((lset_t)1 << (OAKLEY_LIFE_DURATION)) |
1469 LELEM(OAKLEY_LIFE_TYPE)((lset_t)1 << (OAKLEY_LIFE_TYPE)));
1470
1471 switch (life_type) {
1472 case OAKLEY_LIFE_SECONDS1:
1473 if (val > IKE_SA_LIFETIME_MAXIMUMsecs_per_day) {
1474 log_state(RC_LOG, st,
1475 "warning: peer requested IKE lifetime of %" PRIu32"u" " seconds which we capped at our limit of %d seconds",
1476 val, IKE_SA_LIFETIME_MAXIMUMsecs_per_day);
1477 val = IKE_SA_LIFETIME_MAXIMUMsecs_per_day;
1478 }
1479 ta.life_seconds = deltatime(val);
1480 break;
1481 case OAKLEY_LIFE_KILOBYTES2:
1482 ta.life_kilobytes = val;
1483 break;
1484 default:
1485 bad_case(life_type)libreswan_bad_case("life_type", (life_type), (where_t) { .func
= __func__, .basename = "ikev1_spdb_struct.c" , .line = 1485
})
;
1486 }
1487 break;
1488
1489 case OAKLEY_KEY_LENGTH | ISAKMP_ATTR_AF_TV0x8000:
1490 if (!LHAS(seen_attrs, OAKLEY_ENCRYPTION_ALGORITHM)(((seen_attrs) & ((lset_t)1 << (OAKLEY_ENCRYPTION_ALGORITHM
))) != ((lset_t)0))
) {
1491 UGH("OAKLEY_KEY_LENGTH attribute not preceded by OAKLEY_ENCRYPTION_ALGORITHM attribute"){ ok = 0; log_state(RC_LOG_SERIOUS, st, "OAKLEY_KEY_LENGTH attribute not preceded by OAKLEY_ENCRYPTION_ALGORITHM attribute"
". Attribute %s", enum_show(&oakley_attr_names, a.isaat_af_type
)); }
;
1492 break;
1493 }
1494 /* because the encrypt algorithm wasn't valid? */
1495 if (ta.ta_encrypt == NULL((void*)0)) {
1496 UGH("NULL encrypter with seen OAKLEY_ENCRYPTION_ALGORITHM"){ ok = 0; log_state(RC_LOG_SERIOUS, st, "NULL encrypter with seen OAKLEY_ENCRYPTION_ALGORITHM"
". Attribute %s", enum_show(&oakley_attr_names, a.isaat_af_type
)); }
;
1497 break;
1498 }
1499 /*
1500 * check if this keylen is compatible
1501 * with specified ike_proposals.
1502 */
1503 if (!encrypt_has_key_bit_length(ta.ta_encrypt, val)) {
1504 UGH("peer proposed key_len not valid for encrypt algo setup specified"){ ok = 0; log_state(RC_LOG_SERIOUS, st, "peer proposed key_len not valid for encrypt algo setup specified"
". Attribute %s", enum_show(&oakley_attr_names, a.isaat_af_type
)); }
;
1505 break;
1506 }
1507
1508 ta.enckeylen = val;
1509 break;
1510
1511 default:
1512 UGH("unsupported OAKLEY attribute"){ ok = 0; log_state(RC_LOG_SERIOUS, st, "unsupported OAKLEY attribute"
". Attribute %s", enum_show(&oakley_attr_names, a.isaat_af_type
)); }
;
1513 break;
1514 }
1515
1516 if (!ok) {
1517 break;
1518 }
1519 }
1520
1521 /* If ugh != NULL, an attr error has been detected and reported */
1522
1523 /*
1524 * this do {} while (FALSE) construct allows code to use "break"
1525 * to reject this transform and to move on to next (if any).
1526 */
1527
1528 while (ok) {
1529
1530 if ((st->st_policy & POLICY_PSK((lset_t)1 << (POLICY_PSK_IX))) &&
1531 pss != &empty_chunk &&
1532 pss != NULL((void*)0) &&
1533 ta.ta_prf != NULL((void*)0)) {
1534 const size_t key_size_min = crypt_prf_fips_key_size_min(ta.ta_prf);
1535
1536 if (pss->len < key_size_min) {
1537 if (libreswan_fipsmode()) {
1538 log_state(RC_LOG_SERIOUS, st,
1539 "FIPS Error: connection %s PSK length of %zu bytes is too short for %s PRF in FIPS mode (%zu bytes required)",
1540 st->st_connection->name,
1541 pss->len,
1542 ta.ta_prf->common.fqn,
1543 key_size_min);
1544 break; /* reject transform */
1545 } else {
1546 log_state(RC_LOG, st,
1547 "WARNING: connection %s PSK length of %zu bytes is too short for %s PRF in FIPS mode (%zu bytes required)",
1548 st->st_connection->name,
1549 pss->len,
1550 ta.ta_prf->common.fqn,
1551 key_size_min);
1552 }
1553 }
1554 }
1555
1556 /*
1557 * ML: at last check for allowed transforms in ike_proposals
1558 */
1559 if (!ikev1_verify_ike(&ta, c->ike_proposals, st->st_logger)) {
1560 /*
1561 * already logged; UGH acts as a skip
1562 * rest of checks flag
1563 */
1564 break; /* reject transform */
1565 }
1566
1567 /* a little more checking is in order */
1568 {
1569 lset_t missing =
1570 ~seen_attrs &
1571 (LELEM(OAKLEY_ENCRYPTION_ALGORITHM)((lset_t)1 << (OAKLEY_ENCRYPTION_ALGORITHM)) |
1572 LELEM(OAKLEY_HASH_ALGORITHM)((lset_t)1 << (OAKLEY_HASH_ALGORITHM)) |
1573 LELEM(OAKLEY_AUTHENTICATION_METHOD)((lset_t)1 << (OAKLEY_AUTHENTICATION_METHOD)) |
1574 LELEM(OAKLEY_GROUP_DESCRIPTION)((lset_t)1 << (OAKLEY_GROUP_DESCRIPTION)));
1575
1576 if (missing) {
1577 log_state(RC_LOG_SERIOUS, st,
1578 "missing mandatory attribute(s) %s in Oakley Transform %u",
1579 bitnamesof(oakley_attr_bit_names, missing),
1580 trans.isat_transnum);
1581 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1582 }
1583 }
1584
1585 /*
1586 * We must have liked this transform.
1587 * Let's finish early and leave.
1588 */
1589
1590 dbg("Oakley Transform %u accepted", trans.isat_transnum){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("Oakley Transform %u accepted", trans.isat_transnum
); } }
;
1591
1592 if (r_sa_pbs != NULL((void*)0)) {
1593
1594 /* Situation */
1595 passert(out_struct(&ipsecdoisit, &ipsec_sit_desc,{ _Bool assertion__ = out_struct(&ipsecdoisit, &ipsec_sit_desc
, r_sa_pbs, ((void*)0)); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1596}, "%s", "out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL)"
); } }
1596 r_sa_pbs, NULL)){ _Bool assertion__ = out_struct(&ipsecdoisit, &ipsec_sit_desc
, r_sa_pbs, ((void*)0)); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1596}, "%s", "out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL)"
); } }
;
1597
1598 /* Proposal */
1599 struct isakmp_proposal r_proposal = proposal;
1600 r_proposal.isap_spisize = 0;
1601 r_proposal.isap_notrans = 1;
1602 pb_stream r_proposal_pbs;
1603 passert(out_struct(&r_proposal,{ _Bool assertion__ = out_struct(&r_proposal, &isakmp_proposal_desc
, r_sa_pbs, &r_proposal_pbs); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1606}, "%s", "out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs)"
); } }
1604 &isakmp_proposal_desc,{ _Bool assertion__ = out_struct(&r_proposal, &isakmp_proposal_desc
, r_sa_pbs, &r_proposal_pbs); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1606}, "%s", "out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs)"
); } }
1605 r_sa_pbs,{ _Bool assertion__ = out_struct(&r_proposal, &isakmp_proposal_desc
, r_sa_pbs, &r_proposal_pbs); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1606}, "%s", "out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs)"
); } }
1606 &r_proposal_pbs)){ _Bool assertion__ = out_struct(&r_proposal, &isakmp_proposal_desc
, r_sa_pbs, &r_proposal_pbs); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1606}, "%s", "out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs)"
); } }
;
1607
1608 /* Transform */
1609 struct isakmp_transform r_trans = trans;
1610 r_trans.isat_tnp = ISAKMP_NEXT_NONE;
1611 pb_stream r_trans_pbs;
1612 passert(out_struct(&r_trans,{ _Bool assertion__ = out_struct(&r_trans, &isakmp_isakmp_transform_desc
, &r_proposal_pbs, &r_trans_pbs); if (!assertion__) {
lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1615}, "%s", "out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs)"
); } }
1613 &isakmp_isakmp_transform_desc,{ _Bool assertion__ = out_struct(&r_trans, &isakmp_isakmp_transform_desc
, &r_proposal_pbs, &r_trans_pbs); if (!assertion__) {
lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1615}, "%s", "out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs)"
); } }
1614 &r_proposal_pbs,{ _Bool assertion__ = out_struct(&r_trans, &isakmp_isakmp_transform_desc
, &r_proposal_pbs, &r_trans_pbs); if (!assertion__) {
lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1615}, "%s", "out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs)"
); } }
1615 &r_trans_pbs)){ _Bool assertion__ = out_struct(&r_trans, &isakmp_isakmp_transform_desc
, &r_proposal_pbs, &r_trans_pbs); if (!assertion__) {
lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1615}, "%s", "out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs)"
); } }
;
1616
1617 passert(out_raw(attr_start, attr_len,{ _Bool assertion__ = out_raw(attr_start, attr_len, &r_trans_pbs
, "attributes"); if (!assertion__) { lsw_passert_fail((where_t
) { .func = __func__, .basename = "ikev1_spdb_struct.c" , .line
= 1618}, "%s", "out_raw(attr_start, attr_len, &r_trans_pbs, \"attributes\")"
); } }
1618 &r_trans_pbs, "attributes")){ _Bool assertion__ = out_raw(attr_start, attr_len, &r_trans_pbs
, "attributes"); if (!assertion__) { lsw_passert_fail((where_t
) { .func = __func__, .basename = "ikev1_spdb_struct.c" , .line
= 1618}, "%s", "out_raw(attr_start, attr_len, &r_trans_pbs, \"attributes\")"
); } }
;
1619 close_output_pbs(&r_trans_pbs);
1620 close_output_pbs(&r_proposal_pbs);
1621 close_output_pbs(r_sa_pbs);
1622 }
1623
1624 /* ??? If selection, we used to save the proposal in state.
1625 * We never used it. From proposal_pbs.start,
1626 * length pbs_room(&proposal_pbs)
1627 */
1628
1629 /* copy over the results */
1630 st->st_oakley = ta;
1631 return NOTHING_WRONG; /* accept SA */
1632 }
1633
1634 /* transform rejected: on to next transform */
1635
1636 no_trans_left--;
1637
1638 if (trans.isat_tnp == ISAKMP_NEXT_NONE) {
1639 if (no_trans_left != 0) {
1640 log_state(RC_LOG_SERIOUS, st,
1641 "number of Transform Payloads disagrees with Oakley Proposal Payload");
1642 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1643 }
1644 break;
1645 }
1646 if (trans.isat_tnp != ISAKMP_NEXT_T) {
1647 log_state(RC_LOG_SERIOUS, st,
1648 "unexpected %s payload in Oakley Proposal",
1649 enum_show(&ikev1_payload_names, proposal.isap_pnp));
1650 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
1651 }
1652 }
1653 log_state(RC_LOG_SERIOUS, st, "no acceptable Oakley Transform");
1654 return NO_PROPOSAL_CHOSEN; /* reject whole SA */
1655}
1656
1657/* Initialize st_oakley field of state for use when initiating in
1658 * aggressive mode.
1659 *
1660 * This should probably get more of its parameters, like what group to use,
1661 * from the connection specification, but it's not there yet.
1662 * This should ideally be done by passing them via whack.
1663 *
1664 */
1665
1666/* XXX MCR. I suspect that actually all of this is redundant */
1667bool_Bool init_aggr_st_oakley(struct state *st, lset_t policy)
1668{
1669 const struct connection *c = st->st_connection;
1670
1671 /*
1672 * Construct the proposals by combining IKE_PROPOSALS with the
1673 * AUTH (proof of identity) extracted from the aggressive mode
1674 * SADB. As if by magic, attrs[2] is always the
1675 * authentication method.
1676 *
1677 * XXX: Should replace IKEv1_oakley_am_sadb() with a simple
1678 * map to the auth method.
1679 */
1680 struct db_sa *revised_sadb;
1681 {
1682 const struct db_sa *sadb = IKEv1_oakley_am_sadb(policy, c);
1683 const struct db_attr *auth = &sadb->prop_conjs[0].props[0].trans[0].attrs[2];
1684 passert(auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD){ _Bool assertion__ = auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD
; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1684}, "%s", "auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD"
); } }
;
1685 enum ikev1_auth_method auth_method = auth->val;
1686 /*
1687 * Max transforms == 2 - Multiple transforms, 1 DH
1688 * group
1689 */
1690 revised_sadb = v1_ike_alg_make_sadb(c->ike_proposals,
1691 auth_method, TRUE1,
1692 st->st_logger);
1693 }
1694
1695 if (revised_sadb == NULL((void*)0))
1696 return FALSE0;
1697
1698 passert(revised_sadb->prop_conj_cnt == 1){ _Bool assertion__ = revised_sadb->prop_conj_cnt == 1; if
(!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1698}, "%s", "revised_sadb->prop_conj_cnt == 1"
); } }
;
1699 const struct db_prop_conj *cprop = &revised_sadb->prop_conjs[0];
1700
1701 passert(cprop->prop_cnt == 1){ _Bool assertion__ = cprop->prop_cnt == 1; if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev1_spdb_struct.c" , .line = 1701}, "%s", "cprop->prop_cnt == 1"
); } }
;
1702 const struct db_prop *prop = &cprop->props[0];
1703
1704 const struct db_trans *trans = &prop->trans[0];
1705
1706 passert(trans->attr_cnt == 4 || trans->attr_cnt == 5){ _Bool assertion__ = trans->attr_cnt == 4 || trans->attr_cnt
== 5; if (!assertion__) { lsw_passert_fail((where_t) { .func
= __func__, .basename = "ikev1_spdb_struct.c" , .line = 1706
}, "%s", "trans->attr_cnt == 4 || trans->attr_cnt == 5"
); } }
;
1707
1708 const struct db_attr *enc = &trans->attrs[0];
1709 const struct db_attr *hash = &trans->attrs[1];
1710 const struct db_attr *auth = &trans->attrs[2];
1711 const struct db_attr *grp = &trans->attrs[3];
1712
1713 dbg("initiating aggressive mode with IKE=E=%d-H=%d-M=%d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("initiating aggressive mode with IKE=E=%d-H=%d-M=%d"
, enc->val, hash->val, grp->val); } }
1714 enc->val, hash->val, grp->val){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("initiating aggressive mode with IKE=E=%d-H=%d-M=%d"
, enc->val, hash->val, grp->val); } }
;
1715
1716 passert(enc->type.oakley == OAKLEY_ENCRYPTION_ALGORITHM){ _Bool assertion__ = enc->type.oakley == OAKLEY_ENCRYPTION_ALGORITHM
; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1716}, "%s", "enc->type.oakley == OAKLEY_ENCRYPTION_ALGORITHM"
); } }
;
1717
1718
1719 struct trans_attrs ta = {
1720 /* When this SA expires (seconds) */
1721 .life_seconds = c->sa_ike_life_seconds,
1722 .life_kilobytes = 1000000,
1723 .ta_encrypt = ikev1_get_ike_encrypt_desc(enc->val)
1724 };
1725
1726 passert(ta.ta_encrypt != NULL){ _Bool assertion__ = ta.ta_encrypt != ((void*)0); if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev1_spdb_struct.c" , .line = 1726}, "%s", "ta.ta_encrypt != NULL"
); } }
;
1727
1728 if (trans->attr_cnt == 5) {
1729 struct db_attr *enc_keylen;
1730 enc_keylen = &trans->attrs[4];
1731 ta.enckeylen = enc_keylen->val;
1732 } else {
1733 ta.enckeylen = ta.ta_encrypt->keydeflen;
1734 }
1735
1736 passert(hash->type.oakley == OAKLEY_HASH_ALGORITHM){ _Bool assertion__ = hash->type.oakley == OAKLEY_HASH_ALGORITHM
; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1736}, "%s", "hash->type.oakley == OAKLEY_HASH_ALGORITHM"
); } }
;
1737 ta.ta_prf = ikev1_get_ike_prf_desc(hash->val);
1738 passert(ta.ta_prf != NULL){ _Bool assertion__ = ta.ta_prf != ((void*)0); if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev1_spdb_struct.c" , .line = 1738}, "%s", "ta.ta_prf != NULL"
); } }
;
1739
1740 passert(auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD){ _Bool assertion__ = auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD
; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1740}, "%s", "auth->type.oakley == OAKLEY_AUTHENTICATION_METHOD"
); } }
;
1741 ta.auth = auth->val; /* OAKLEY_AUTHENTICATION_METHOD */
1742
1743 passert(grp->type.oakley == OAKLEY_GROUP_DESCRIPTION){ _Bool assertion__ = grp->type.oakley == OAKLEY_GROUP_DESCRIPTION
; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1743}, "%s", "grp->type.oakley == OAKLEY_GROUP_DESCRIPTION"
); } }
;
1744 ta.ta_dh = ikev1_get_ike_dh_desc(grp->val); /* OAKLEY_GROUP_DESCRIPTION */
1745 passert(ta.ta_dh != NULL){ _Bool assertion__ = ta.ta_dh != ((void*)0); if (!assertion__
) { lsw_passert_fail((where_t) { .func = __func__, .basename =
"ikev1_spdb_struct.c" , .line = 1745}, "%s", "ta.ta_dh != NULL"
); } }
;
1746
1747 st->st_oakley = ta;
1748
1749 return TRUE1;
1750}
1751
1752/**
1753 * Parse the body of an IPsec SA Payload (i.e. Phase 2 / Quick Mode).
1754 *
1755 * The main routine is parse_ipsec_sa_body; other functions defined
1756 * between here and there are just helpers.
1757 *
1758 * Various shortcuts are taken. In particular, the policy, such as
1759 * it is, is hardwired.
1760 *
1761 * If r_sa is non-NULL, the body of an SA representing the selected
1762 * proposal is emitted into it.
1763 *
1764 * If "selection" is true, the SA is supposed to represent the
1765 * single transform that the peer has accepted.
1766 * ??? We only check that it is acceptable, not that it is one that we offered!
1767 *
1768 * Only IPsec DOI is accepted (what is the ISAKMP DOI?).
1769 * Error response is rudimentary.
1770 *
1771 * Since all ISAKMP groups in all SA Payloads must match, st->st_pfs_group
1772 * holds this across multiple payloads.
1773 * &unset_group signifies not yet "set"; NULL signifies NONE.
1774 *
1775 * This routine is used by quick_inI1_outR1() and quick_inR1_outI2().
1776 */
1777
1778static bool_Bool parse_ipsec_transform(struct isakmp_transform *trans,
1779 struct ipsec_trans_attrs *attrs,
1780 pb_stream *prop_pbs,
1781 pb_stream *trans_pbs,
1782 struct_desc *trans_desc,
1783 int previous_transnum, /* or -1 if none */
1784 bool_Bool selection,
1785 bool_Bool is_last,
1786 uint8_t proto,
1787 struct state *st) /* current state object */
1788{
1789 lset_t seen_attrs = LEMPTY((lset_t)0),
1790 seen_durations = LEMPTY((lset_t)0);
1791 bool_Bool seen_secctx_attr = FALSE0;
1792 uint16_t life_type = 0; /* initialized to silence GCC */
1793 const struct dh_desc *pfs_group = NULL((void*)0);
1794
1795 if (!in_struct(trans, trans_desc, prop_pbs, trans_pbs))
1
Assuming the condition is false
2
Taking false branch
1796 return FALSE0;
1797
1798 if (trans->isat_transnum <= previous_transnum) {
3
Assuming the condition is false
4
Taking false branch
1799 loglog(RC_LOG_SERIOUS,
1800 "Transform Numbers in Proposal are not monotonically increasing");
1801 return FALSE0;
1802 }
1803
1804 switch (trans->isat_tnp) {
5
Control jumps to 'case ISAKMP_NEXT_NONE:' at line 1812
1805 case ISAKMP_NEXT_T:
1806 if (is_last) {
1807 loglog(RC_LOG_SERIOUS,
1808 "Proposal Payload has more Transforms than specified");
1809 return FALSE0;
1810 }
1811 break;
1812 case ISAKMP_NEXT_NONE:
1813 if (!is_last) {
6
Assuming 'is_last' is not equal to 0
7
Taking false branch
1814 loglog(RC_LOG_SERIOUS,
1815 "Proposal Payload has fewer Transforms than specified");
1816 return FALSE0;
1817 }
1818 break;
8
Execution jumps to the end of the function
1819 default:
1820 loglog(RC_LOG_SERIOUS,
1821 "expecting Transform Payload, but found %s in Proposal",
1822 enum_show(&ikev1_payload_names, trans->isat_tnp));
1823 return FALSE0;
1824 }
1825
1826 *attrs = (struct ipsec_trans_attrs) {
1827 .spi = 0, /* spi */
1828 .life_seconds = DELTATIME_INIT(IPSEC_SA_LIFETIME_DEFAULT){ .dt = { .tv_sec = (secs_per_hour * 8), } }, /* life_seconds */
1829 .life_kilobytes = SA_LIFE_DURATION_K_DEFAULT0xFFFFFFFFlu, /* life_kilobytes */
1830 .mode = ENCAPSULATION_MODE_UNSPECIFIED0, /* encapsulation */
1831 };
1832
1833 switch (proto) {
9
Control jumps to 'case 2:' at line 1840
1834 case PROTO_IPCOMP4:
1835 attrs->transattrs.ta_comp = trans->isat_transid;
1836 break;
1837 case PROTO_IPSEC_ESP3:
1838 attrs->transattrs.ta_encrypt = ikev1_get_kernel_encrypt_desc(trans->isat_transid);
1839 break;
1840 case PROTO_IPSEC_AH2:
1841 break;
10
Execution continues on line 1846
1842 default:
1843 bad_case(proto)libreswan_bad_case("proto", (proto), (where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1843})
;
1844 }
1845
1846 while (pbs_left(trans_pbs)((size_t)((trans_pbs)->roof - (trans_pbs)->cur)) >= isakmp_ipsec_attribute_desc.size) {
11
Assuming the condition is true
12
Loop condition is true. Entering loop body
1847 struct isakmp_attribute a;
1848 pb_stream attr_pbs;
1849 enum_names *vdesc;
1850 uint16_t ty;
1851 uint32_t val; /* room for larger value */
1852 bool_Bool ipcomp_inappropriate = (proto == PROTO_IPCOMP4); /* will get reset if OK */
1853
1854 if (!in_struct(&a, &isakmp_ipsec_attribute_desc, trans_pbs,
13
Assuming the condition is false
14
Taking false branch
1855 &attr_pbs))
1856 return FALSE0;
1857
1858 ty = a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK0x7FFF;
1859 val = a.isaat_lv;
1860
1861 if (ty == secctx_attr_type) {
15
Assuming 'ty' is equal to 'secctx_attr_type'
16
Taking true branch
1862 if (seen_secctx_attr) {
17
Taking false branch
1863 loglog(RC_LOG_SERIOUS,
1864 "repeated SECCTX attribute in IPsec Transform %u",
1865 trans->isat_transnum);
1866 return FALSE0;
1867 }
1868 seen_secctx_attr = TRUE1;
1869 vdesc = NULL((void*)0);
1870 } else {
1871 passert(ty < LELEM_ROOF){ _Bool assertion__ = ty < 64; if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 1871}, "%s", "ty < LELEM_ROOF"); } }
;
1872 if (LHAS(seen_attrs, ty)(((seen_attrs) & ((lset_t)1 << (ty))) != ((lset_t)0
))
) {
1873 loglog(RC_LOG_SERIOUS,
1874 "repeated %s attribute in IPsec Transform %u",
1875 enum_show(&ipsec_attr_names, a.isaat_af_type),
1876 trans->isat_transnum);
1877 return FALSE0;
1878 }
1879
1880 seen_attrs |= LELEM(ty)((lset_t)1 << (ty));
1881 passert(ty < ipsec_attr_val_descs_roof){ _Bool assertion__ = ty < ipsec_attr_val_descs_roof; if (
!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 1881}, "%s", "ty < ipsec_attr_val_descs_roof"
); } }
;
1882 vdesc = ipsec_attr_val_descs[ty];
1883 }
1884
1885 if (vdesc != NULL((void*)0)) {
18
Taking false branch
1886 /* reject unknown enum values */
1887 if (enum_name(vdesc, val) == NULL((void*)0)) {
1888 loglog(RC_LOG_SERIOUS,
1889 "invalid value %" PRIu32"u" " for attribute %s in IPsec Transform",
1890 val,
1891 enum_show(&ipsec_attr_names,
1892 a.isaat_af_type));
1893 return FALSE0;
1894 }
1895 if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) {
1896 if ((a.isaat_af_type &
1897 ISAKMP_ATTR_AF_MASK0x8000) ==
1898 ISAKMP_ATTR_AF_TV0x8000) {
1899 DBG_log(" [%" PRIu32"u" " is %s]",
1900 val,
1901 enum_show(vdesc, val));
1902 }
1903 }
1904 }
1905
1906 switch (a.isaat_af_type) {
19
Control jumps to the 'default' case at line 2066
1907 case SA_LIFE_TYPE | ISAKMP_ATTR_AF_TV0x8000:
1908 ipcomp_inappropriate = FALSE0;
1909 if (LHAS(seen_durations, val)(((seen_durations) & ((lset_t)1 << (val))) != ((lset_t
)0))
) {
1910 loglog(RC_LOG_SERIOUS,
1911 "attribute SA_LIFE_TYPE value %s repeated in message",
1912 enum_show(&sa_lifetime_names, val));
1913 return FALSE0;
1914 }
1915 seen_durations |= LELEM(val)((lset_t)1 << (val));
1916 life_type = val;
1917 break;
1918
1919 case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TLV0:
1920 val = decode_long_duration(&attr_pbs);
1921 /* FALL THROUGH */
1922 case SA_LIFE_DURATION | ISAKMP_ATTR_AF_TV0x8000:
1923 ipcomp_inappropriate = FALSE0;
1924 if (!LHAS(seen_attrs, SA_LIFE_TYPE)(((seen_attrs) & ((lset_t)1 << (SA_LIFE_TYPE))) != (
(lset_t)0))
) {
1925 loglog(RC_LOG_SERIOUS,
1926 "SA_LIFE_DURATION IPsec attribute not preceded by SA_LIFE_TYPE attribute");
1927 return FALSE0;
1928 }
1929 seen_attrs &=
1930 ~(LELEM(SA_LIFE_DURATION)((lset_t)1 << (SA_LIFE_DURATION)) |
1931 LELEM(SA_LIFE_TYPE)((lset_t)1 << (SA_LIFE_TYPE)));
1932
1933 switch (life_type) {
1934 case SA_LIFE_TYPE_SECONDS1:
1935 {
1936 /*
1937 * Silently limit duration to our maximum.
1938 *
1939 * Note:
1940 *
1941 * GCC now complains about comparisons between
1942 * signed and unsigned values. This is good:
1943 * should the comparison be done as if the
1944 * unsigned representation were signed or as if
1945 * the signed representation were unsigned?
1946 * The C standard has an arbitrary answer.
1947 * So GCC's warning should be heeded.
1948 *
1949 * We know that time_t can represent all
1950 * values between 0 and SA_LIFE_DURATION_MAXIMUM.
1951 * It is safe to cast val (of type uint32_t)
1952 * to time_t (some signed type) AFTER checking
1953 * that val does not exceed
1954 * SA_LIFE_DURATION_MAXIMUM.
1955 */
1956 unsigned int lifemax = IPSEC_SA_LIFETIME_MAXIMUMsecs_per_day;
1957 if (libreswan_fipsmode())
1958 lifemax = FIPS_IPSEC_SA_LIFETIME_MAXIMUMsecs_per_hour * 8;
1959 attrs->life_seconds = val > lifemax ?
1960 deltatime(lifemax) :
1961 (time_t)val > deltasecs(st->st_connection->sa_ipsec_life_seconds) ?
1962 st->st_connection->sa_ipsec_life_seconds :
1963 deltatime(val);
1964 break;
1965 }
1966 case SA_LIFE_TYPE_KBYTES2:
1967 attrs->life_kilobytes = val;
1968 break;
1969 default:
1970 bad_case(life_type)libreswan_bad_case("life_type", (life_type), (where_t) { .func
= __func__, .basename = "ikev1_spdb_struct.c" , .line = 1970
})
;
1971 }
1972 break;
1973
1974 case GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV0x8000:
1975 if (proto == PROTO_IPCOMP4) {
1976 /* Accept reluctantly. Should not happen, according to
1977 * draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
1978 */
1979 ipcomp_inappropriate = FALSE0;
1980 loglog(RC_COMMENT,
1981 "IPCA (IPcomp SA) contains GROUP_DESCRIPTION. Ignoring inappropriate attribute.");
1982 }
1983 pfs_group = ikev1_get_ike_dh_desc(val);
1984 if (pfs_group == NULL((void*)0)) {
1985 loglog(RC_LOG_SERIOUS,
1986 "OAKLEY_GROUP %" PRIu32"u" " not supported for PFS",
1987 val);
1988 return FALSE0;
1989 }
1990 break;
1991
1992 case ENCAPSULATION_MODE | ISAKMP_ATTR_AF_TV0x8000:
1993 ipcomp_inappropriate = FALSE0;
1994 switch (val) {
1995 case ENCAPSULATION_MODE_TUNNEL1:
1996 case ENCAPSULATION_MODE_TRANSPORT2:
1997 dbg("NAT-T non-encap: Installing IPsec SA without ENCAP, st->hidden_variables.st_nat_traversal is %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-T non-encap: Installing IPsec SA without ENCAP, st->hidden_variables.st_nat_traversal is %s"
, bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal
)); } }
1998 bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-T non-encap: Installing IPsec SA without ENCAP, st->hidden_variables.st_nat_traversal is %s"
, bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal
)); } }
;
1999 break;
2000
2001 case ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS61444:
2002 case ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS61443:
2003 dbg("NAT-T draft: Installing IPsec SA with ENCAP, st->hidden_variables.st_nat_traversal is %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-T draft: Installing IPsec SA with ENCAP, st->hidden_variables.st_nat_traversal is %s"
, bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal
)); } }
2004 bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-T draft: Installing IPsec SA with ENCAP, st->hidden_variables.st_nat_traversal is %s"
, bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal
)); } }
;
2005 break;
2006
2007 case ENCAPSULATION_MODE_UDP_TRANSPORT_RFC4:
2008 case ENCAPSULATION_MODE_UDP_TUNNEL_RFC3:
2009 dbg("NAT-T RFC: Installing IPsec SA with ENCAP, st->hidden_variables.st_nat_traversal is %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-T RFC: Installing IPsec SA with ENCAP, st->hidden_variables.st_nat_traversal is %s"
, bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal
)); } }
2010 bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("NAT-T RFC: Installing IPsec SA with ENCAP, st->hidden_variables.st_nat_traversal is %s"
, bitnamesof(natt_bit_names, st->hidden_variables.st_nat_traversal
)); } }
;
2011 break;
2012
2013 default:
2014 /* should already be filtered out by enum checker */
2015 bad_case(val)libreswan_bad_case("val", (val), (where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 2015})
;
2016 }
2017
2018 /* normalize the actual attribute value */
2019 switch (val) {
2020 case ENCAPSULATION_MODE_TRANSPORT2:
2021 case ENCAPSULATION_MODE_UDP_TRANSPORT_DRAFTS61444:
2022 case ENCAPSULATION_MODE_UDP_TRANSPORT_RFC4:
2023 val = ENCAPSULATION_MODE_TRANSPORT2;
2024 break;
2025 case ENCAPSULATION_MODE_TUNNEL1:
2026 case ENCAPSULATION_MODE_UDP_TUNNEL_DRAFTS61443:
2027 case ENCAPSULATION_MODE_UDP_TUNNEL_RFC3:
2028 val = ENCAPSULATION_MODE_TUNNEL1;
2029 break;
2030 }
2031 attrs->mode = val;
2032 break;
2033
2034 case AUTH_ALGORITHM | ISAKMP_ATTR_AF_TV0x8000:
2035 attrs->transattrs.ta_integ = ikev1_get_kernel_integ_desc(val);
2036 if (attrs->transattrs.ta_integ == NULL((void*)0)) {
2037 /*
2038 * Caller will also see NULL and
2039 * assume that things should stumble
2040 * on to the next algorithm.
2041 *
2042 * Either straight AH, or ESP
2043 * containing AUTH; or what?
2044 */
2045 loglog(RC_LOG_SERIOUS,
2046 "IKEv1 %s integrity algorithm %s not supported",
2047 (proto == PROTO_IPSEC_ESP3 ? "ESP" : "AH"),
2048 enum_show(&ah_transformid_names, val));
2049 }
2050 break;
2051
2052 case KEY_LENGTH | ISAKMP_ATTR_AF_TV0x8000:
2053 if (attrs->transattrs.ta_encrypt == NULL((void*)0)) {
2054 loglog(RC_LOG_SERIOUS,
2055 "IKEv1 key-length attribute without encryption algorithm");
2056 return false0;
2057 }
2058 if (!encrypt_has_key_bit_length(attrs->transattrs.ta_encrypt, val)) {
2059 loglog(RC_LOG_SERIOUS,
2060 "IKEv1 key-length attribute without encryption algorithm");
2061 return false0;
2062 }
2063 attrs->transattrs.enckeylen = val;
2064 break;
2065
2066 default:
2067 if (a.isaat_af_type ==
20
Assuming the condition is true
21
Taking true branch
2068 (secctx_attr_type | ISAKMP_ATTR_AF_TLV0)) {
2069 pb_stream *pbs = &attr_pbs;
2070
2071 if (!parse_secctx_attr(pbs, st))
22
Calling 'parse_secctx_attr'
2072 return FALSE0;
2073 } else {
2074 loglog(RC_LOG_SERIOUS,
2075 "unsupported IPsec attribute %s",
2076 enum_show(&ipsec_attr_names, a.isaat_af_type));
2077 return FALSE0;
2078 }
2079 }
2080
2081 if (ipcomp_inappropriate) {
2082 loglog(RC_LOG_SERIOUS,
2083 "IPsec attribute %s inappropriate for IPCOMP",
2084 enum_show(&ipsec_attr_names, a.isaat_af_type));
2085 return FALSE0;
2086 }
2087 }
2088
2089 /* Although an IPCOMP SA (IPCA) ought not to have a pfs_group,
2090 * if it does, demand that it be consistent.
2091 * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1.
2092 */
2093 if (proto != PROTO_IPCOMP4 || pfs_group != NULL((void*)0)) {
2094 if (st->st_pfs_group == &unset_group)
2095 st->st_pfs_group = pfs_group;
2096
2097 if (st->st_pfs_group != pfs_group) {
2098 loglog(RC_LOG_SERIOUS,
2099 "GROUP_DESCRIPTION inconsistent with that of %s in IPsec SA",
2100 selection ? "the Proposal" : "a previous Transform");
2101 return FALSE0;
2102 }
2103 }
2104
2105 if (LHAS(seen_attrs, SA_LIFE_DURATION)(((seen_attrs) & ((lset_t)1 << (SA_LIFE_DURATION)))
!= ((lset_t)0))
) {
2106 loglog(RC_LOG_SERIOUS,
2107 "SA_LIFE_TYPE IPsec attribute not followed by SA_LIFE_DURATION attribute in message");
2108 return FALSE0;
2109 }
2110
2111 if (!LHAS(seen_attrs, ENCAPSULATION_MODE)(((seen_attrs) & ((lset_t)1 << (ENCAPSULATION_MODE)
)) != ((lset_t)0))
) {
2112 if (proto == PROTO_IPCOMP4) {
2113 /* draft-shacham-ippcp-rfc2393bis-05.txt 4.1:
2114 * "If the Encapsulation Mode is unspecified,
2115 * the default value of Transport Mode is assumed."
2116 * This contradicts/overrides the DOI (quoted below).
2117 */
2118 attrs->mode = ENCAPSULATION_MODE_TRANSPORT2;
2119 } else {
2120 /* ??? Technically, RFC 2407 (IPSEC DOI) 4.5 specifies that
2121 * the default is "unspecified (host-dependent)".
2122 * This makes little sense, so we demand that it be specified.
2123 */
2124 loglog(RC_LOG_SERIOUS,
2125 "IPsec Transform must specify ENCAPSULATION_MODE");
2126 return FALSE0;
2127 }
2128 }
2129
2130 /*
2131 * For ESP, check if the encryption key length is required.
2132 *
2133 * If a required key length was missing force the proposal to
2134 * be rejected by settinf .ta_encrypt=NULL.
2135 *
2136 * If an optional key-length is missing set it to the correct
2137 * value (.keydeflen) (which can be 0). This is safe since
2138 * the code echoing back the proposal never emits a keylen
2139 * when .keylen_omitted
2140 */
2141 if (proto == PROTO_IPSEC_ESP3 && !LHAS(seen_attrs, KEY_LENGTH)(((seen_attrs) & ((lset_t)1 << (KEY_LENGTH))) != ((
lset_t)0))
&&
2142 attrs->transattrs.ta_encrypt != NULL((void*)0)) {
2143 if (attrs->transattrs.ta_encrypt->keylen_omitted) {
2144 attrs->transattrs.enckeylen = attrs->transattrs.ta_encrypt->keydeflen;
2145 } else {
2146 /* ealg requires a key length attr */
2147 loglog(RC_LOG_SERIOUS,
2148 "IPsec encryption transform %s did not specify required KEY_LENGTH attribute",
2149 attrs->transattrs.ta_encrypt->common.fqn);
2150 attrs->transattrs.ta_encrypt = NULL((void*)0); /* force rejection */
2151 }
2152 }
2153
2154 /*
2155 * For ESP, if the integrity algorithm (AUTH_ALGORITHM) was
2156 * completely missing, set it to NONE.
2157 *
2158 * This way the caller has sufficient information to
2159 * differentiate between missing integrity (NONE) and unknown
2160 * integrity (NULL) and decide if the proposals combination of
2161 * ESP/AH AEAD and NONE is valid.
2162 *
2163 * For instance, AEAD+[NONE].
2164 */
2165 if (proto == PROTO_IPSEC_ESP3 && !LHAS(seen_attrs, AUTH_ALGORITHM)(((seen_attrs) & ((lset_t)1 << (AUTH_ALGORITHM))) !=
((lset_t)0))
) {
2166 dbg("ES missing INTEG aka AUTH, setting it to NONE"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ES missing INTEG aka AUTH, setting it to NONE"
); } }
;
2167 attrs->transattrs.ta_integ = &ike_alg_integ_none;
2168 }
2169
2170 if (proto == PROTO_IPSEC_AH2) {
2171 if (!LHAS(seen_attrs, AUTH_ALGORITHM)(((seen_attrs) & ((lset_t)1 << (AUTH_ALGORITHM))) !=
((lset_t)0))
) {
2172 loglog(RC_LOG_SERIOUS,
2173 "AUTH_ALGORITHM attribute missing in AH Transform");
2174 return false0;
2175 }
2176 }
2177
2178 return TRUE1;
2179}
2180
2181static void echo_proposal(struct isakmp_proposal r_proposal, /* proposal to emit */
2182 struct isakmp_transform r_trans, /* winning transformation within it */
2183 uint8_t pnp, /* Next Payload for proposal */
2184 pb_stream *r_sa_pbs, /* SA PBS into which to emit */
2185 struct ipsec_proto_info *pi, /* info about this protocol instance */
2186 struct_desc *trans_desc, /* descriptor for this transformation */
2187 pb_stream *trans_pbs, /* PBS for incoming transform */
2188 const struct spd_route *sr, /* host details for the association */
2189 bool_Bool tunnel_mode) /* true for inner most tunnel SA */
2190{
2191 pb_stream r_proposal_pbs;
2192 pb_stream r_trans_pbs;
2193
2194 /* Proposal */
2195 r_proposal.isap_pnp = pnp;
2196 r_proposal.isap_notrans = 1;
2197 passert(out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs,{ _Bool assertion__ = out_struct(&r_proposal, &isakmp_proposal_desc
, r_sa_pbs, &r_proposal_pbs); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2198}, "%s", "out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs)"
); } }
2198 &r_proposal_pbs)){ _Bool assertion__ = out_struct(&r_proposal, &isakmp_proposal_desc
, r_sa_pbs, &r_proposal_pbs); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2198}, "%s", "out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs)"
); } }
;
2199
2200 /* allocate and emit our CPI/SPI */
2201 if (r_proposal.isap_protoid == PROTO_IPCOMP4) {
2202 /* CPI is stored in network low order end of an
2203 * ipsec_spi_t. So we start a couple of bytes in.
2204 * Note: we may fail to generate a satisfactory CPI,
2205 * but we'll ignore that.
2206 */
2207 pi->our_spi = get_my_cpi(sr, tunnel_mode);
2208 passert(out_raw((u_char *) &pi->our_spi +{ _Bool assertion__ = out_raw((u_char *) &pi->our_spi +
4 - 2, 2, &r_proposal_pbs, "CPI"); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2211}, "%s", "out_raw((u_char *) &pi->our_spi + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE, IPCOMP_CPI_SIZE, &r_proposal_pbs, \"CPI\")"
); } }
2209 IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE,{ _Bool assertion__ = out_raw((u_char *) &pi->our_spi +
4 - 2, 2, &r_proposal_pbs, "CPI"); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2211}, "%s", "out_raw((u_char *) &pi->our_spi + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE, IPCOMP_CPI_SIZE, &r_proposal_pbs, \"CPI\")"
); } }
2210 IPCOMP_CPI_SIZE,{ _Bool assertion__ = out_raw((u_char *) &pi->our_spi +
4 - 2, 2, &r_proposal_pbs, "CPI"); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2211}, "%s", "out_raw((u_char *) &pi->our_spi + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE, IPCOMP_CPI_SIZE, &r_proposal_pbs, \"CPI\")"
); } }
2211 &r_proposal_pbs, "CPI")){ _Bool assertion__ = out_raw((u_char *) &pi->our_spi +
4 - 2, 2, &r_proposal_pbs, "CPI"); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2211}, "%s", "out_raw((u_char *) &pi->our_spi + IPSEC_DOI_SPI_SIZE - IPCOMP_CPI_SIZE, IPCOMP_CPI_SIZE, &r_proposal_pbs, \"CPI\")"
); } }
;
2212 } else {
2213 pi->our_spi = get_ipsec_spi(pi->attrs.spi,
2214 r_proposal.isap_protoid == PROTO_IPSEC_AH2 ?
2215 &ip_protocol_ah : &ip_protocol_esp,
2216 sr,
2217 tunnel_mode);
2218 /* XXX should check for errors */
2219 passert(out_raw((u_char *) &pi->our_spi, IPSEC_DOI_SPI_SIZE,{ _Bool assertion__ = out_raw((u_char *) &pi->our_spi,
4, &r_proposal_pbs, "SPI"); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2220}, "%s", "out_raw((u_char *) &pi->our_spi, IPSEC_DOI_SPI_SIZE, &r_proposal_pbs, \"SPI\")"
); } }
2220 &r_proposal_pbs, "SPI")){ _Bool assertion__ = out_raw((u_char *) &pi->our_spi,
4, &r_proposal_pbs, "SPI"); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2220}, "%s", "out_raw((u_char *) &pi->our_spi, IPSEC_DOI_SPI_SIZE, &r_proposal_pbs, \"SPI\")"
); } }
;
2221 }
2222
2223 /* Transform */
2224 r_trans.isat_tnp = ISAKMP_NEXT_NONE;
2225 passert(out_struct(&r_trans, trans_desc, &r_proposal_pbs, &r_trans_pbs)){ _Bool assertion__ = out_struct(&r_trans, trans_desc, &
r_proposal_pbs, &r_trans_pbs); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2225}, "%s", "out_struct(&r_trans, trans_desc, &r_proposal_pbs, &r_trans_pbs)"
); } }
;
2226
2227 /* Transform Attributes: pure echo */
2228 trans_pbs->cur = trans_pbs->start + sizeof(struct isakmp_transform);
2229 passert(out_raw(trans_pbs->cur, pbs_left(trans_pbs),{ _Bool assertion__ = out_raw(trans_pbs->cur, ((size_t)((trans_pbs
)->roof - (trans_pbs)->cur)), &r_trans_pbs, "attributes"
); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 2230}, "%s", "out_raw(trans_pbs->cur, pbs_left(trans_pbs), &r_trans_pbs, \"attributes\")"
); } }
2230 &r_trans_pbs, "attributes")){ _Bool assertion__ = out_raw(trans_pbs->cur, ((size_t)((trans_pbs
)->roof - (trans_pbs)->cur)), &r_trans_pbs, "attributes"
); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__
, .basename = "ikev1_spdb_struct.c" , .line = 2230}, "%s", "out_raw(trans_pbs->cur, pbs_left(trans_pbs), &r_trans_pbs, \"attributes\")"
); } }
;
2231
2232 close_output_pbs(&r_trans_pbs);
2233 close_output_pbs(&r_proposal_pbs);
2234}
2235
2236notification_t parse_ipsec_sa_body(pb_stream *sa_pbs, /* body of input SA Payload */
2237 const struct isakmp_sa *sa, /* header of input SA Payload */
2238 pb_stream *r_sa_pbs, /* if non-NULL, where to emit body of winning SA */
2239 bool_Bool selection, /* if this SA is a selection, only one transform may appear */
2240 struct state *st) /* current state object */
2241{
2242 const struct connection *c = st->st_connection;
2243 uint32_t ipsecdoisit;
2244 pb_stream next_proposal_pbs;
2245
2246 struct isakmp_proposal next_proposal;
2247 ipsec_spi_t next_spi;
2248
2249 bool_Bool next_full = TRUE1;
2250
2251 /* DOI */
2252 if (sa->isasa_doi != ISAKMP_DOI_IPSEC1) {
2253 loglog(RC_LOG_SERIOUS, "Unknown or unsupported DOI %s",
2254 enum_show(&doi_names, sa->isasa_doi));
2255 /* XXX Could send notification back */
2256 return DOI_NOT_SUPPORTED; /* reject whole SA */
2257 }
2258
2259 /* Situation */
2260 if (!in_struct(&ipsecdoisit, &ipsec_sit_desc, sa_pbs, NULL((void*)0)))
2261 return SITUATION_NOT_SUPPORTED; /* reject whole SA */
2262
2263 if (ipsecdoisit != SIT_IDENTITY_ONLY0x01) {
2264 loglog(RC_LOG_SERIOUS, "unsupported IPsec DOI situation (%s)",
2265 bitnamesof(sit_bit_names, ipsecdoisit));
2266 /* XXX Could send notification back */
2267 return SITUATION_NOT_SUPPORTED; /* reject whole SA */
2268 }
2269
2270 /* The rules for IPsec SAs are scattered.
2271 * RFC 2408 "ISAKMP" section 4.2 gives some info.
2272 * There may be multiple proposals. Those with identical proposal
2273 * numbers must be considered as conjuncts. Those with different
2274 * numbers are disjuncts.
2275 * Each proposal may have several transforms, each considered
2276 * an alternative.
2277 * Each transform may have several attributes, all applying.
2278 *
2279 * To handle the way proposals are combined, we need to do a
2280 * look-ahead.
2281 */
2282
2283 if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs,
2284 &next_proposal_pbs))
2285 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2286
2287 /* for each conjunction of proposals... */
2288 while (next_full) {
2289 int propno = next_proposal.isap_proposal;
2290 pb_stream
2291 ah_prop_pbs,
2292 esp_prop_pbs,
2293 ipcomp_prop_pbs;
2294 struct isakmp_proposal
2295 ah_proposal,
2296 esp_proposal,
2297 ipcomp_proposal;
2298 ipsec_spi_t
2299 ah_spi = 0,
2300 esp_spi = 0,
2301 ipcomp_cpi = 0;
2302 bool_Bool
2303 ah_seen = FALSE0,
2304 esp_seen = FALSE0,
2305 ipcomp_seen = FALSE0;
2306 const ip_protocol *inner_proto = NULL((void*)0);
2307 bool_Bool tunnel_mode = FALSE0;
2308 uint16_t well_known_cpi = 0;
2309
2310 pb_stream
2311 ah_trans_pbs,
2312 esp_trans_pbs,
2313 ipcomp_trans_pbs;
2314 struct isakmp_transform
2315 ah_trans,
2316 esp_trans,
2317 ipcomp_trans;
2318 struct ipsec_trans_attrs
2319 ah_attrs,
2320 esp_attrs,
2321 ipcomp_attrs;
2322
2323 zero(&ah_proposal)memset((&ah_proposal), '\0', sizeof(*(&ah_proposal))); /* OK: no pointer fields */
2324 zero(&esp_proposal)memset((&esp_proposal), '\0', sizeof(*(&esp_proposal)
))
; /* OK: no pointer fields */
2325 zero(&ipcomp_proposal)memset((&ipcomp_proposal), '\0', sizeof(*(&ipcomp_proposal
)))
; /* OK: no pointer fields */
2326
2327 /* for each proposal in the conjunction */
2328 do {
2329 if (next_proposal.isap_protoid == PROTO_IPCOMP4) {
2330 /* IPCOMP CPI */
2331 if (next_proposal.isap_spisize ==
2332 IPSEC_DOI_SPI_SIZE4) {
2333 /* This code is to accommodate those peculiar
2334 * implementations that send a CPI in the bottom of an
2335 * SPI-sized field.
2336 * See draft-shacham-ippcp-rfc2393bis-05.txt 4.1
2337 */
2338 uint8_t filler[IPSEC_DOI_SPI_SIZE4 -
2339 IPCOMP_CPI_SIZE2];
2340
2341 if (!in_raw(filler, sizeof(filler),
2342 &next_proposal_pbs,
2343 "CPI filler") ||
2344 !all_zero(filler, sizeof(filler)))
2345 return INVALID_SPI; /* reject whole SA */
2346 } else if (next_proposal.isap_spisize !=
2347 IPCOMP_CPI_SIZE2) {
2348 loglog(RC_LOG_SERIOUS,
2349 "IPsec Proposal with improper CPI size (%u)",
2350 next_proposal.isap_spisize);
2351 return INVALID_SPI; /* reject whole SA */
2352 }
2353
2354 /* We store CPI in the low order of a network order
2355 * ipsec_spi_t. So we start a couple of bytes in.
2356 */
2357 zero(&next_spi)memset((&next_spi), '\0', sizeof(*(&next_spi)));
2358 if (!in_raw((u_char *)&next_spi +
2359 IPSEC_DOI_SPI_SIZE4 -
2360 IPCOMP_CPI_SIZE2,
2361 IPCOMP_CPI_SIZE2,
2362 &next_proposal_pbs, "CPI"))
2363 return INVALID_SPI; /* reject whole SA */
2364
2365 /* If sanity ruled, CPIs would have to be such that
2366 * the SAID (the triple (CPI, IPCOM, destination IP))
2367 * would be unique, just like for SPIs. But there is a
2368 * perversion where CPIs can be well-known and consequently
2369 * the triple is not unique. We hide this fact from
2370 * ourselves by fudging the top 16 bits to make
2371 * the property true internally!
2372 */
2373 switch (ntohl(next_spi)) {
2374 case IPCOMP_DEFLATE:
2375 well_known_cpi = ntohl(next_spi);
2376 next_spi = uniquify_peer_cpi(next_spi, st, 0);
2377 if (next_spi == 0) {
2378 loglog(RC_LOG_SERIOUS,
2379 "IPsec Proposal contains well-known CPI that I cannot uniquify");
2380 return INVALID_SPI; /* reject whole SA */
2381 }
2382 break;
2383 default:
2384 if (ntohl(next_spi) <
2385 IPCOMP_FIRST_NEGOTIATED256 ||
2386 ntohl(next_spi) >
2387 IPCOMP_LAST_NEGOTIATED61439) {
2388 loglog(RC_LOG_SERIOUS,
2389 "IPsec Proposal contains CPI from non-negotiated range (0x%" PRIx32"x" ")",
2390 ntohl(next_spi));
2391 return INVALID_SPI; /* reject whole SA */
2392 }
2393 break;
2394 }
2395 /* end of IPCOMP CPI handling */
2396 } else {
2397 /* AH or ESP SPI */
2398 if (next_proposal.isap_spisize !=
2399 IPSEC_DOI_SPI_SIZE4) {
2400 loglog(RC_LOG_SERIOUS,
2401 "IPsec Proposal with improper SPI size (%u)",
2402 next_proposal.isap_spisize);
2403 return INVALID_SPI; /* reject whole SA */
2404 }
2405
2406 if (!in_raw((u_char *)&next_spi,
2407 sizeof(next_spi),
2408 &next_proposal_pbs, "SPI"))
2409 return INVALID_SPI; /* reject whole SA */
2410
2411 /* SPI value 0 is invalid and values 1-255 are reserved to IANA.
2412 * RFC 2402 (ESP) 2.4, RFC 2406 (AH) 2.1
2413 * IPCOMP???
2414 */
2415 if (ntohl(next_spi) < IPSEC_DOI_SPI_MIN0x100) {
2416 loglog(RC_LOG_SERIOUS,
2417 "IPsec Proposal contains invalid SPI (0x%" PRIx32"x" ")",
2418 ntohl(next_spi));
2419 return INVALID_SPI; /* reject whole SA */
2420 }
2421 }
2422
2423 if (next_proposal.isap_notrans == 0) {
2424 loglog(RC_LOG_SERIOUS,
2425 "IPsec Proposal contains no Transforms (skipped)");
2426 continue;
2427 }
2428
2429 switch (next_proposal.isap_protoid) {
2430 case PROTO_IPSEC_AH2:
2431 if (ah_seen) {
2432 loglog(RC_LOG_SERIOUS,
2433 "IPsec SA contains two simultaneous AH Proposals");
2434 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2435 }
2436 ah_seen = TRUE1;
2437 ah_prop_pbs = next_proposal_pbs;
2438 ah_proposal = next_proposal;
2439 ah_spi = next_spi;
2440 break;
2441
2442 case PROTO_IPSEC_ESP3:
2443 if (esp_seen) {
2444 loglog(RC_LOG_SERIOUS,
2445 "IPsec SA contains two simultaneous ESP Proposals");
2446 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2447 }
2448 esp_seen = TRUE1;
2449 esp_prop_pbs = next_proposal_pbs;
2450 esp_proposal = next_proposal;
2451 esp_spi = next_spi;
2452 break;
2453
2454 case PROTO_IPCOMP4:
2455 if (ipcomp_seen) {
2456 loglog(RC_LOG_SERIOUS,
2457 "IPsec SA contains two simultaneous IPCOMP Proposals");
2458 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2459 }
2460 ipcomp_seen = TRUE1;
2461 ipcomp_prop_pbs = next_proposal_pbs;
2462 ipcomp_proposal = next_proposal;
2463 ipcomp_cpi = next_spi;
2464 break;
2465
2466 default:
2467 loglog(RC_LOG_SERIOUS,
2468 "unexpected Protocol ID (%s) in IPsec Proposal",
2469 enum_show(&ikev1_protocol_names,
2470 next_proposal.isap_protoid));
2471 return INVALID_PROTOCOL_ID; /* reject whole SA */
2472 }
2473
2474 /* refill next_proposal */
2475 if (next_proposal.isap_pnp == ISAKMP_NEXT_NONE) {
2476 next_full = FALSE0;
2477 break;
2478 } else if (next_proposal.isap_pnp != ISAKMP_NEXT_P) {
2479 loglog(RC_LOG_SERIOUS,
2480 "unexpected in Proposal: %s",
2481 enum_show(&ikev1_payload_names,
2482 next_proposal.isap_pnp));
2483 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2484 }
2485
2486 if (!in_struct(&next_proposal, &isakmp_proposal_desc,
2487 sa_pbs, &next_proposal_pbs))
2488 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2489 } while (next_proposal.isap_proposal == propno);
2490
2491 /* Now that we have all conjuncts, we should try
2492 * the Cartesian product of each's transforms!
2493 * At the moment, we take short-cuts on account of
2494 * our rudimentary hard-wired policy.
2495 * For now, we find an acceptable AH (if any)
2496 * and then an acceptable ESP. The only interaction
2497 * is that the ESP acceptance can know whether there
2498 * was an acceptable AH and hence not require an AUTH.
2499 */
2500
2501 if (ah_seen) {
2502 int previous_transnum = -1;
2503 int tn;
2504
2505 for (tn = 0; tn != ah_proposal.isap_notrans; tn++) {
2506 if (!parse_ipsec_transform(&ah_trans,
2507 &ah_attrs,
2508 &ah_prop_pbs,
2509 &ah_trans_pbs,
2510 &isakmp_ah_transform_desc,
2511 previous_transnum,
2512 selection,
2513 tn == ah_proposal.isap_notrans - 1,
2514 PROTO_IPSEC_AH2,
2515 st))
2516 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2517
2518 previous_transnum = ah_trans.isat_transnum;
2519
2520 /*
2521 * Since, for AH, when integrity is
2522 * missing, the proposal gets rejected
2523 * outright, a NULL here must indicate
2524 * that integrity was present but the
2525 * lookup failed.
2526 */
2527 if (ah_attrs.transattrs.ta_integ == NULL((void*)0)) {
2528 /* error already logged */
2529 dbg("ignoring AH proposal with unknown integrity"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ignoring AH proposal with unknown integrity")
; } }
;
2530 continue; /* try another */
2531 }
2532
2533 /* we must understand ah_attrs.transid
2534 * COMBINED with ah_attrs.transattrs.ta_ikev1_integ_hash.
2535 * See RFC 2407 "IPsec DOI" section 4.4.3
2536 * The following combinations are legal,
2537 * but we don't implement all of them:
2538 * It seems as if each auth algorithm
2539 * only applies to one ah transid.
2540 * AH_MD5, AUTH_ALGORITHM_HMAC_MD5
2541 * AH_MD5, AUTH_ALGORITHM_KPDK (unimplemented)
2542 * AH_SHA, AUTH_ALGORITHM_HMAC_SHA1
2543 * AH_DES, AUTH_ALGORITHM_DES_MAC (unimplemented)
2544 */
2545 if (ah_trans.isat_transid != ah_attrs.transattrs.ta_integ->integ_ikev1_ah_transform) {
2546 loglog(RC_LOG_SERIOUS,
2547 "%s attribute inappropriate in %s Transform",
2548 ah_attrs.transattrs.ta_integ->common.fqn,
2549 enum_show(&ah_transformid_names,
2550 ah_trans.isat_transid));
2551 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2552 }
2553 break; /* we seem to be happy */
2554 }
2555 if (tn == ah_proposal.isap_notrans)
2556 continue; /* we didn't find a nice one */
2557
2558 /* Check AH proposal with configuration */
2559 if (!ikev1_verify_ah(c, &ah_attrs.transattrs, st->st_logger)) {
2560 continue;
2561 }
2562 ah_attrs.spi = ah_spi;
2563 inner_proto = &ip_protocol_ah;
2564 if (ah_attrs.mode ==
2565 ENCAPSULATION_MODE_TUNNEL1)
2566 tunnel_mode = TRUE1;
2567 }
2568
2569 if (esp_seen) {
2570 int previous_transnum = -1;
2571 int tn;
2572
2573 for (tn = 0; tn != esp_proposal.isap_notrans; tn++) {
2574 if (!parse_ipsec_transform(
2575 &esp_trans,
2576 &esp_attrs,
2577 &esp_prop_pbs,
2578 &esp_trans_pbs,
2579 &isakmp_esp_transform_desc,
2580 previous_transnum,
2581 selection,
2582 tn == esp_proposal.isap_notrans - 1,
2583 PROTO_IPSEC_ESP3,
2584 st))
2585 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2586
2587 previous_transnum = esp_trans.isat_transnum;
2588
2589 /*
2590 * check for allowed transforms in alg_info_esp
2591 */
2592 if (!ikev1_verify_esp(c, &esp_attrs.transattrs, st->st_logger)) {
2593 continue; /* try another */
2594 }
2595
2596 /*
2597 * XXX: this is testing for AH, is
2598 * conbining even supported? If not,
2599 * the test should be pushed into
2600 * ikev1_verify_esp().
2601 */
2602 if (esp_attrs.transattrs.ta_integ == &ike_alg_integ_none) {
2603 if (!encrypt_desc_is_aead(esp_attrs.transattrs.ta_encrypt) &&
2604 !ah_seen) {
2605 LSWDBGP(DBG_BASE, buf)for (_Bool lswlog_p = (cur_debugging & (((lset_t)1 <<
(DBG_BASE_IX)))); lswlog_p; lswlog_p = 0) for (char lswbuf[(
(size_t)1024)], *lswbuf_ = lswbuf; lswbuf_ != ((void*)0); lswbuf_
= ((void*)0)) for (struct jambuf jambuf = array_as_jambuf((lswbuf
), sizeof(lswbuf)), *buf = &jambuf; buf != ((void*)0); buf
= ((void*)0)) for (; buf != ((void*)0); jambuf_to_debug_stream
(buf), buf = ((void*)0))
{
2606 jam_string(buf, "ESP from ");
2607 jam_endpoint(buf, &c->spd.that.host_addr);
2608 jam_string(buf, " must either have AUTH or be combined with AH");
2609 }
2610 continue; /* try another */
2611 }
2612 }
2613
2614 if (ah_seen &&
2615 ah_attrs.mode !=
2616 esp_attrs.mode) {
2617 loglog(RC_LOG_SERIOUS,
2618 "Skipped bogus proposal where AH and ESP transforms disagree about mode");
2619 continue; /* try another */
2620 }
2621
2622 break; /* we seem to be happy */
2623 }
2624 if (tn == esp_proposal.isap_notrans)
2625 continue; /* we didn't find a nice one */
2626
2627 esp_attrs.spi = esp_spi;
2628 inner_proto = &ip_protocol_esp;
2629 if (esp_attrs.mode ==
2630 ENCAPSULATION_MODE_TUNNEL1)
2631 tunnel_mode = TRUE1;
2632 } else if (st->st_policy & POLICY_ENCRYPT((lset_t)1 << (POLICY_ENCRYPT_IX))) {
2633 connection_buf cib;
2634 address_buf b;
2635 dbg("policy for "PRI_CONNECTION" requires encryption but ESP not in Proposal from %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("policy for ""\"%s\"%s"" requires encryption but ESP not in Proposal from %s"
, (c)->name, str_connection_instance(c, &cib), str_address
(&c->spd.that.host_addr, &b)); } }
2636 pri_connection(c, &cib),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("policy for ""\"%s\"%s"" requires encryption but ESP not in Proposal from %s"
, (c)->name, str_connection_instance(c, &cib), str_address
(&c->spd.that.host_addr, &b)); } }
2637 str_address(&c->spd.that.host_addr, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("policy for ""\"%s\"%s"" requires encryption but ESP not in Proposal from %s"
, (c)->name, str_connection_instance(c, &cib), str_address
(&c->spd.that.host_addr, &b)); } }
;
2638 continue; /* we needed encryption, but didn't find ESP */
2639 } else if ((st->st_policy & POLICY_AUTHENTICATE((lset_t)1 << (POLICY_AUTHENTICATE_IX))) && !ah_seen) {
2640 connection_buf cib;
2641 address_buf b;
2642 dbg("policy for \"%s\"%s requires authentication but none in Proposal from %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("policy for \"%s\"%s requires authentication but none in Proposal from %s"
, (c)->name, str_connection_instance(c, &cib), str_address
(&c->spd.that.host_addr, &b)); } }
2643 pri_connection(c, &cib),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("policy for \"%s\"%s requires authentication but none in Proposal from %s"
, (c)->name, str_connection_instance(c, &cib), str_address
(&c->spd.that.host_addr, &b)); } }
2644 str_address(&c->spd.that.host_addr, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("policy for \"%s\"%s requires authentication but none in Proposal from %s"
, (c)->name, str_connection_instance(c, &cib), str_address
(&c->spd.that.host_addr, &b)); } }
;
2645 continue; /* we need authentication, but we found neither ESP nor AH */
2646 }
2647
2648 if (ipcomp_seen) {
2649 int previous_transnum = -1;
2650 int tn;
2651
2652 if (!(st->st_policy & POLICY_COMPRESS((lset_t)1 << (POLICY_COMPRESS_IX)))) {
2653 ipstr_buf b;
2654 char cib[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf
) + 3 + sizeof(subnet_buf) + 1 + 1)
];
2655
2656 libreswan_log(loglog(RC_LOG, "compression proposed by %s, but policy for \"%s\"%s forbids it"
, ipstr(&c->spd.that.host_addr, &b), c->name, fmt_conn_instance
(c, cib))
2657 "compression proposed by %s, but policy for \"%s\"%s forbids it",loglog(RC_LOG, "compression proposed by %s, but policy for \"%s\"%s forbids it"
, ipstr(&c->spd.that.host_addr, &b), c->name, fmt_conn_instance
(c, cib))
2658 ipstr(&c->spd.that.host_addr, &b),loglog(RC_LOG, "compression proposed by %s, but policy for \"%s\"%s forbids it"
, ipstr(&c->spd.that.host_addr, &b), c->name, fmt_conn_instance
(c, cib))
2659 c->name, fmt_conn_instance(c, cib))loglog(RC_LOG, "compression proposed by %s, but policy for \"%s\"%s forbids it"
, ipstr(&c->spd.that.host_addr, &b), c->name, fmt_conn_instance
(c, cib))
;
2660 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2661 }
2662
2663 if (!can_do_IPcomp) {
2664 ipstr_buf b;
2665
2666 libreswan_log(loglog(RC_LOG, "compression proposed by %s, but kernel has no IPCOMP support"
, ipstr(&c->spd.that.host_addr, &b))
2667 "compression proposed by %s, but kernel has no IPCOMP support",loglog(RC_LOG, "compression proposed by %s, but kernel has no IPCOMP support"
, ipstr(&c->spd.that.host_addr, &b))
2668 ipstr(&c->spd.that.host_addr, &b))loglog(RC_LOG, "compression proposed by %s, but kernel has no IPCOMP support"
, ipstr(&c->spd.that.host_addr, &b))
;
2669 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2670 }
2671
2672 if (well_known_cpi != 0 && !ah_seen && !esp_seen) {
2673 libreswan_log(loglog(RC_LOG, "illegal proposal: bare IPCOMP used with well-known CPI"
)
2674 "illegal proposal: bare IPCOMP used with well-known CPI")loglog(RC_LOG, "illegal proposal: bare IPCOMP used with well-known CPI"
)
;
2675 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2676 }
2677
2678 for (tn = 0; tn != ipcomp_proposal.isap_notrans;
2679 tn++) {
2680 if (!parse_ipsec_transform(
2681 &ipcomp_trans,
2682 &ipcomp_attrs,
2683 &ipcomp_prop_pbs,
2684 &ipcomp_trans_pbs,
2685 &isakmp_ipcomp_transform_desc,
2686 previous_transnum,
2687 selection,
2688 tn == ipcomp_proposal.isap_notrans - 1,
2689 PROTO_IPCOMP4,
2690 st))
2691 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2692
2693 previous_transnum = ipcomp_trans.isat_transnum;
2694
2695 if (well_known_cpi != 0 &&
2696 ipcomp_attrs.transattrs.ta_comp != well_known_cpi) {
2697 libreswan_log(loglog(RC_LOG, "illegal proposal: IPCOMP well-known CPI disagrees with transform"
)
2698 "illegal proposal: IPCOMP well-known CPI disagrees with transform")loglog(RC_LOG, "illegal proposal: IPCOMP well-known CPI disagrees with transform"
)
;
2699 return BAD_PROPOSAL_SYNTAX; /* reject whole SA */
2700 }
2701
2702 switch (ipcomp_attrs.transattrs.ta_comp) {
2703 case IPCOMP_DEFLATE: /* all we can handle! */
2704 break;
2705
2706 default:
2707 {
2708 address_buf b;
2709 dbg("unsupported IPCOMP Transform %d from %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("unsupported IPCOMP Transform %d from %s", ipcomp_attrs
.transattrs.ta_comp, str_address(&c->spd.that.host_addr
, &b)); } }
2710 ipcomp_attrs.transattrs.ta_comp,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("unsupported IPCOMP Transform %d from %s", ipcomp_attrs
.transattrs.ta_comp, str_address(&c->spd.that.host_addr
, &b)); } }
2711 str_address(&c->spd.that.host_addr, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("unsupported IPCOMP Transform %d from %s", ipcomp_attrs
.transattrs.ta_comp, str_address(&c->spd.that.host_addr
, &b)); } }
;
2712 continue; /* try another */
2713 }
2714 }
2715
2716 if (ah_seen &&
2717 ah_attrs.mode !=
2718 ipcomp_attrs.mode) {
2719 /* ??? This should be an error, but is it? */
2720 dbg("AH and IPCOMP transforms disagree about mode; TUNNEL presumed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("AH and IPCOMP transforms disagree about mode; TUNNEL presumed"
); } }
;
2721 } else if (esp_seen &&
2722 esp_attrs.mode !=
2723 ipcomp_attrs.mode) {
2724 /* ??? This should be an error, but is it? */
2725 dbg("ESP and IPCOMP transforms disagree about mode; TUNNEL presumed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX)
)))) { DBG_log("ESP and IPCOMP transforms disagree about mode; TUNNEL presumed"
); } }
;
2726 }
2727
2728 break; /* we seem to be happy */
2729 }
2730 if (tn == ipcomp_proposal.isap_notrans)
2731 continue; /* we didn't find a nice one */
2732 ipcomp_attrs.spi = ipcomp_cpi;
2733 inner_proto = &ip_protocol_comp;
2734 if (ipcomp_attrs.mode ==
2735 ENCAPSULATION_MODE_TUNNEL1)
2736 tunnel_mode = TRUE1;
2737 }
2738
2739 /* Eureka: we liked what we saw -- accept it. */
2740
2741 if (r_sa_pbs != NULL((void*)0)) {
2742 /* emit what we've accepted */
2743
2744 /* Situation */
2745 passert(out_struct(&ipsecdoisit, &ipsec_sit_desc,{ _Bool assertion__ = out_struct(&ipsecdoisit, &ipsec_sit_desc
, r_sa_pbs, ((void*)0)); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2746}, "%s", "out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL)"
); } }
2746 r_sa_pbs, NULL)){ _Bool assertion__ = out_struct(&ipsecdoisit, &ipsec_sit_desc
, r_sa_pbs, ((void*)0)); if (!assertion__) { lsw_passert_fail
((where_t) { .func = __func__, .basename = "ikev1_spdb_struct.c"
, .line = 2746}, "%s", "out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL)"
); } }
;
2747
2748 /* AH proposal */
2749 if (ah_seen) {
2750 echo_proposal(ah_proposal,
2751 ah_trans,
2752 esp_seen || ipcomp_seen ? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE,
2753 r_sa_pbs,
2754 &st->st_ah,
2755 &isakmp_ah_transform_desc,
2756 &ah_trans_pbs,
2757 &st->st_connection->spd,
2758 tunnel_mode &&
2759 inner_proto == &ip_protocol_ah);
2760 }
2761
2762 /* ESP proposal */
2763 if (esp_seen) {
2764 echo_proposal(esp_proposal,
2765 esp_trans,
2766 ipcomp_seen ? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE,
2767 r_sa_pbs,
2768 &st->st_esp,
2769 &isakmp_esp_transform_desc,
2770 &esp_trans_pbs,
2771 &st->st_connection->spd,
2772 tunnel_mode &&
2773 inner_proto == &ip_protocol_esp);
2774 }
2775
2776 /* IPCOMP proposal */
2777 if (ipcomp_seen) {
2778 echo_proposal(ipcomp_proposal,
2779 ipcomp_trans,
2780 ISAKMP_NEXT_NONE,
2781 r_sa_pbs,
2782 &st->st_ipcomp,
2783 &isakmp_ipcomp_transform_desc,
2784 &ipcomp_trans_pbs,
2785 &st->st_connection->spd,
2786 tunnel_mode &&
2787 inner_proto == &ip_protocol_comp);
2788 }
2789
2790 close_output_pbs(r_sa_pbs);
2791 }
2792
2793 /* save decoded version of winning SA in state */
2794
2795 st->st_ah.present = ah_seen;
2796 if (ah_seen) {
2797 st->st_ah.attrs = ah_attrs;
2798 st->st_ah.our_lastused = mononow();
2799 st->st_ah.peer_lastused = mononow();
2800 }
2801
2802 st->st_esp.present = esp_seen;
2803 if (esp_seen) {
2804 st->st_esp.attrs = esp_attrs;
2805 st->st_esp.our_lastused = mononow();
2806 st->st_esp.peer_lastused = mononow();
2807 }
2808
2809 st->st_ipcomp.present = ipcomp_seen;
2810 if (ipcomp_seen) {
2811 st->st_ipcomp.attrs = ipcomp_attrs;
2812 st->st_ipcomp.our_lastused = mononow();
2813 st->st_ipcomp.peer_lastused = mononow();
2814 }
2815
2816 return NOTHING_WRONG; /* accept this transform! */
2817 }
2818
2819 loglog(RC_LOG_SERIOUS, "no acceptable Proposal in IPsec SA");
2820 return NO_PROPOSAL_CHOSEN; /* reject whole SA */
2821}