File: | programs/pluto/ikev2_ike_auth.c |
Warning: | line 494, column 8 Access to field 'policy' results in a dereference of a null pointer (loaded from variable 'cc') |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||
2 | * IKEv2 parent SA creation routines, for Libreswan | |||
3 | * | |||
4 | * Copyright (C) 2007-2008 Michael Richardson <mcr@xelerance.com> | |||
5 | * Copyright (C) 2008-2011 Paul Wouters <paul@xelerance.com> | |||
6 | * Copyright (C) 2008 Antony Antony <antony@xelerance.com> | |||
7 | * Copyright (C) 2008-2009 David McCullough <david_mccullough@securecomputing.com> | |||
8 | * Copyright (C) 2010,2012 Avesh Agarwal <avagarwa@redhat.com> | |||
9 | * Copyright (C) 2010-2019 Tuomo Soini <tis@foobar.fi | |||
10 | * Copyright (C) 2012-2019 Paul Wouters <pwouters@redhat.com> | |||
11 | * Copyright (C) 2012-2018 Antony Antony <antony@phenome.org> | |||
12 | * Copyright (C) 2013-2019 D. Hugh Redelmeier <hugh@mimosa.com> | |||
13 | * Copyright (C) 2013 David McCullough <ucdevel@gmail.com> | |||
14 | * Copyright (C) 2013 Matt Rogers <mrogers@redhat.com> | |||
15 | * Copyright (C) 2015-2019 Andrew Cagney <cagney@gnu.org> | |||
16 | * Copyright (C) 2017-2018 Sahana Prasad <sahana.prasad07@gmail.com> | |||
17 | * Copyright (C) 2017-2018 Vukasin Karadzic <vukasin.karadzic@gmail.com> | |||
18 | * Copyright (C) 2017 Mayank Totale <mtotale@gmail.com> | |||
19 | * Copyright (C) 2020 Yulia Kuzovkova <ukuzovkova@gmail.com> | |||
20 | * | |||
21 | * This program is free software; you can redistribute it and/or modify it | |||
22 | * under the terms of the GNU General Public License as published by the | |||
23 | * Free Software Foundation; either version 2 of the License, or (at your | |||
24 | * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>. | |||
25 | * | |||
26 | * This program is distributed in the hope that it will be useful, but | |||
27 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |||
28 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
29 | * for more details. | |||
30 | * | |||
31 | */ | |||
32 | ||||
33 | #include "defs.h" | |||
34 | #include "log.h" | |||
35 | #include "demux.h" | |||
36 | #include "state.h" | |||
37 | #include "crypt_dh.h" | |||
38 | #include "ikev2_send.h" | |||
39 | #include "ikev2.h" | |||
40 | #include "connections.h" | |||
41 | #include "secrets.h" | |||
42 | #include "ikev2_message.h" | |||
43 | #ifdef USE_PAM_AUTH1 | |||
44 | #include "pam_auth.h" | |||
45 | #endif | |||
46 | #include "pluto_x509.h" | |||
47 | #include "ikev2_ike_auth.h" | |||
48 | #include "pending.h" | |||
49 | #include "pluto_stats.h" | |||
50 | #include "cert_decode_helper.h" | |||
51 | #include "ikev2_child.h" | |||
52 | #include "ikev2_peer_id.h" | |||
53 | #include "crypt_symkey.h" | |||
54 | #include "nat_traversal.h" | |||
55 | #include "ikev2_auth.h" | |||
56 | #include "ikev2_redirect.h" | |||
57 | #include "ikev2_ipseckey.h" | |||
58 | #include "ikev2_ppk.h" | |||
59 | #include "keys.h" | |||
60 | #include "ike_alg_hash.h" | |||
61 | #include "ikev2_cp.h" | |||
62 | #include "kernel.h" /* for raw_policy() */ | |||
63 | #include "ikev2_delete.h" /* for submit_v2_delete_exchange() */ | |||
64 | ||||
65 | static stf_status process_v2_IKE_AUTH_request_tail(struct state *st, | |||
66 | struct msg_digest *md, | |||
67 | bool_Bool pam_status); | |||
68 | ||||
69 | static stf_status ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue(struct ike_sa *ike, | |||
70 | struct msg_digest *md, | |||
71 | const struct hash_signature *sig); | |||
72 | ||||
73 | ||||
74 | stf_status ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_continue(struct state *ike_st, | |||
75 | struct msg_digest *md) | |||
76 | { | |||
77 | struct ike_sa *ike = pexpect_ike_sa(ike_st); | |||
78 | pexpect(ike->sa.st_sa_role == SA_INITIATOR)({ _Bool assertion__ = ike->sa.st_sa_role == SA_INITIATOR; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 78, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sa_role == SA_INITIATOR" ); } assertion__; }); | |||
| ||||
79 | pexpect(v2_msg_role(md) == MESSAGE_RESPONSE)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 79, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } assertion__; }); /* i.e., MD!=NULL */ | |||
80 | dbg("%s() for #%lu %s: g^{xy} calculated, sending IKE_AUTH",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: g^{xy} calculated, sending IKE_AUTH" , __func__, ike->sa.st_serialno, ike->sa.st_state->name ); } } | |||
81 | __func__, ike->sa.st_serialno, ike->sa.st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: g^{xy} calculated, sending IKE_AUTH" , __func__, ike->sa.st_serialno, ike->sa.st_state->name ); } }; | |||
82 | ||||
83 | struct connection *const pc = ike->sa.st_connection; /* parent connection */ | |||
84 | ||||
85 | if (!(md->hdr.isa_xchg == ISAKMP_v2_IKE_INTERMEDIATE)) { | |||
86 | if (ike->sa.st_dh_shared_secret == NULL((void*)0)) { | |||
87 | /* | |||
88 | * XXX: this is the initiator so returning a | |||
89 | * notification is kind of useless. | |||
90 | */ | |||
91 | pstat_sa_failed(&ike->sa, REASON_CRYPTO_FAILED); | |||
92 | return STF_FAIL; | |||
93 | } | |||
94 | calc_v2_keymat(&ike->sa, NULL((void*)0), NULL((void*)0), /*no old keymat*/ | |||
95 | &ike->sa.st_ike_rekey_spis); | |||
96 | } | |||
97 | ||||
98 | /* | |||
99 | * All systems are go. | |||
100 | * | |||
101 | * Since DH succeeded, a secure (but unauthenticated) SA | |||
102 | * (channel) is available. From this point on, should things | |||
103 | * go south, the state needs to be abandoned (but it shouldn't | |||
104 | * happen). | |||
105 | */ | |||
106 | ||||
107 | /* | |||
108 | * Since systems are go, start updating the state, starting | |||
109 | * with SPIr. | |||
110 | */ | |||
111 | rehash_state(&ike->sa, &md->hdr.isa_ike_responder_spiisa_ike_spis.responder); | |||
112 | ||||
113 | /* | |||
114 | * If we and responder are willing to use a PPK, we need to | |||
115 | * generate NO_PPK_AUTH as well as PPK-based AUTH payload. | |||
116 | * | |||
117 | * Stash the no-ppk keys in st_skey_*_no_ppk, and then | |||
118 | * scramble the st_skey_* keys with PPK. | |||
119 | */ | |||
120 | if (LIN(POLICY_PPK_ALLOW, pc->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (pc-> policy)) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX)))) && ike->sa.st_seen_ppk) { | |||
121 | chunk_t *ppk_id; | |||
122 | chunk_t *ppk = get_connection_ppk(ike->sa.st_connection, &ppk_id); | |||
123 | ||||
124 | if (ppk != NULL((void*)0)) { | |||
125 | dbg("found PPK and PPK_ID for our connection"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("found PPK and PPK_ID for our connection"); } }; | |||
126 | ||||
127 | pexpect(ike->sa.st_sk_d_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_d_no_ppk == ((void*)0 ); if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 127, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sk_d_no_ppk == ((void*)0)" ); } assertion__; }); | |||
128 | ike->sa.st_sk_d_no_ppk = reference_symkey(__func__, "sk_d_no_ppk", ike->sa.st_skey_d_nss); | |||
129 | ||||
130 | pexpect(ike->sa.st_sk_pi_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_pi_no_ppk == ((void*) 0); if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 130, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sk_pi_no_ppk == ((void*)0)" ); } assertion__; }); | |||
131 | ike->sa.st_sk_pi_no_ppk = reference_symkey(__func__, "sk_pi_no_ppk", ike->sa.st_skey_pi_nss); | |||
132 | ||||
133 | pexpect(ike->sa.st_sk_pr_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_pr_no_ppk == ((void*) 0); if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 133, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sk_pr_no_ppk == ((void*)0)" ); } assertion__; }); | |||
134 | ike->sa.st_sk_pr_no_ppk = reference_symkey(__func__, "sk_pr_no_ppk", ike->sa.st_skey_pr_nss); | |||
135 | ||||
136 | ppk_recalculate(ppk, ike->sa.st_oakley.ta_prf, | |||
137 | &ike->sa.st_skey_d_nss, | |||
138 | &ike->sa.st_skey_pi_nss, | |||
139 | &ike->sa.st_skey_pr_nss, | |||
140 | ike->sa.st_logger); | |||
141 | log_state(RC_LOG, &ike->sa, | |||
142 | "PPK AUTH calculated as initiator"); | |||
143 | } else { | |||
144 | if (pc->policy & POLICY_PPK_INSIST((lset_t)1 << (POLICY_PPK_INSIST_IX))) { | |||
145 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
146 | "connection requires PPK, but we didn't find one"); | |||
147 | return STF_FATAL; | |||
148 | } else { | |||
149 | log_state(RC_LOG, &ike->sa, | |||
150 | "failed to find PPK and PPK_ID, continuing without PPK"); | |||
151 | /* we should omit sending any PPK Identity, so we pretend we didn't see USE_PPK */ | |||
152 | ike->sa.st_seen_ppk = false0; | |||
153 | } | |||
154 | } | |||
155 | } | |||
156 | ||||
157 | /* | |||
158 | * Construct the IDi payload and store it in state so that it | |||
159 | * can be emitted later. Then use that to construct the | |||
160 | * "MACedIDFor[I]". | |||
161 | * | |||
162 | * Code assumes that struct ikev2_id's "IDType|RESERVED" is | |||
163 | * laid out the same as the packet. | |||
164 | */ | |||
165 | ||||
166 | { | |||
167 | shunk_t data; | |||
168 | ike->sa.st_v2_id_payload.header = build_v2_id_payload(&pc->spd.this, &data, | |||
169 | "my IDi", ike->sa.st_logger); | |||
170 | ike->sa.st_v2_id_payload.data = clone_hunk(data, "my IDi")({ typeof(data) hunk_ = data; clone_bytes_as_chunk(hunk_.ptr, hunk_.len, "my IDi"); }); | |||
171 | } | |||
172 | ||||
173 | ike->sa.st_v2_id_payload.mac = v2_hash_id_payload("IDi", ike, | |||
174 | "st_skey_pi_nss", | |||
175 | ike->sa.st_skey_pi_nss); | |||
176 | if (ike->sa.st_seen_ppk && !LIN(POLICY_PPK_INSIST, pc->policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (pc-> policy)) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
177 | /* ID payload that we've build is the same */ | |||
178 | ike->sa.st_v2_id_payload.mac_no_ppk_auth = | |||
179 | v2_hash_id_payload("IDi (no-PPK)", ike, | |||
180 | "sk_pi_no_pkk", | |||
181 | ike->sa.st_sk_pi_no_ppk); | |||
182 | } | |||
183 | ||||
184 | { | |||
185 | enum keyword_authby authby = v2_auth_by(ike); | |||
186 | enum ikev2_auth_method auth_method = v2_auth_method(ike, authby); | |||
187 | switch (auth_method) { | |||
188 | case IKEv2_AUTH_RSA: | |||
189 | { | |||
190 | const struct hash_desc *hash_algo = &ike_alg_hash_sha1; | |||
191 | struct crypt_mac hash_to_sign = | |||
192 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
193 | hash_algo, LOCAL_PERSPECTIVE); | |||
194 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
195 | authby, auth_method, | |||
196 | ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue)) { | |||
197 | dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } }; | |||
198 | return STF_FATAL; | |||
199 | } | |||
200 | return STF_SUSPEND; | |||
201 | } | |||
202 | case IKEv2_AUTH_DIGSIG: | |||
203 | { | |||
204 | const struct hash_desc *hash_algo = v2_auth_negotiated_signature_hash(ike); | |||
205 | if (hash_algo == NULL((void*)0)) { | |||
206 | return STF_FATAL; | |||
207 | } | |||
208 | struct crypt_mac hash_to_sign = | |||
209 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
210 | hash_algo, LOCAL_PERSPECTIVE); | |||
211 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
212 | authby, auth_method, | |||
213 | ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue)) { | |||
214 | dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } }; | |||
215 | return STF_FATAL; | |||
216 | } | |||
217 | return STF_SUSPEND; | |||
218 | } | |||
219 | case IKEv2_AUTH_PSK: | |||
220 | case IKEv2_AUTH_NULL: | |||
221 | { | |||
222 | struct hash_signature sig = { .len = 0, }; | |||
223 | return ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue(ike, md, &sig); | |||
224 | } | |||
225 | default: | |||
226 | log_state(RC_LOG, &ike->sa, | |||
227 | "authentication method %s not supported", | |||
228 | enum_name(&ikev2_auth_names, auth_method)); | |||
229 | return STF_FATAL; | |||
230 | } | |||
231 | } | |||
232 | } | |||
233 | ||||
234 | static stf_status ikev2_in_IKE_SA_INIT_R_or_IKE_INTERMEDIATE_R_out_IKE_AUTH_I_signature_continue(struct ike_sa *ike, | |||
235 | struct msg_digest *md, | |||
236 | const struct hash_signature *auth_sig) | |||
237 | { | |||
238 | struct connection *const pc = ike->sa.st_connection; /* parent connection */ | |||
239 | ikev2_log_parentSA(&ike->sa); | |||
240 | ||||
241 | /* | |||
242 | * XXX: | |||
243 | * | |||
244 | * Should this code use clone_in_pbs_as_chunk() which uses | |||
245 | * pbs_room() (.roof-.start)? The original code: | |||
246 | * | |||
247 | * clonetochunk(st->st_firstpacket_peer, md->message_pbs.start, | |||
248 | * pbs_offset(&md->message_pbs), | |||
249 | * "saved first received packet"); | |||
250 | * | |||
251 | * and clone_out_pbs_as_chunk() both use pbs_offset() | |||
252 | * (.cur-.start). | |||
253 | * | |||
254 | * Suspect it doesn't matter as the code initializing | |||
255 | * .message_pbs forces .roof==.cur - look for the comment | |||
256 | * "trim padding (not actually legit)". | |||
257 | */ | |||
258 | /* record first packet for later checking of signature */ | |||
259 | if (md->hdr.isa_xchg
| |||
260 | replace_chunk(&ike->sa.st_firstpacket_peer, | |||
261 | clone_pbs_out_as_chunk(&md->message_pbs, "saved first received non-intermediate packet")); | |||
262 | } | |||
263 | /* beginning of data going out */ | |||
264 | ||||
265 | /* make sure HDR is at start of a clean buffer */ | |||
266 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
267 | reply_buffer, sizeof(reply_buffer), | |||
268 | ike->sa.st_logger); | |||
269 | ||||
270 | /* HDR out */ | |||
271 | ||||
272 | struct pbs_outpacket_byte_stream rbody = open_v2_message(&reply_stream, ike, | |||
273 | NULL((void*)0) /* request */, | |||
274 | ISAKMP_v2_IKE_AUTH); | |||
275 | if (!pbs_ok(&rbody)((&rbody)->start != ((void*)0))) { | |||
276 | return STF_INTERNAL_ERROR; | |||
277 | } | |||
278 | ||||
279 | /* insert an Encryption payload header (SK) */ | |||
280 | ||||
281 | struct v2SK_payload sk = open_v2SK_payload(ike->sa.st_logger, &rbody, ike); | |||
282 | if (!pbs_ok(&sk.pbs)((&sk.pbs)->start != ((void*)0))) { | |||
283 | return STF_INTERNAL_ERROR; | |||
284 | } | |||
285 | ||||
286 | /* actual data */ | |||
287 | ||||
288 | /* decide whether to send CERT payload */ | |||
289 | ||||
290 | bool_Bool send_cert = ikev2_send_cert_decision(ike); | |||
291 | bool_Bool ic = pc->initial_contact && (ike->sa.st_ike_pred == SOS_NOBODY0); | |||
292 | bool_Bool send_idr = ((pc->spd.that.id.kind != ID_NULL && pc->spd.that.id.name.len != 0) || | |||
293 | pc->spd.that.id.kind == ID_NULL); /* me tarzan, you jane */ | |||
294 | ||||
295 | if (impair.send_no_idr) { | |||
296 | log_state(RC_LOG, &ike->sa, "IMPAIR: omitting IDr payload"); | |||
297 | send_idr = false0; | |||
298 | } | |||
299 | ||||
300 | dbg("IDr payload will %sbe sent", send_idr ? "" : "NOT "){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("IDr payload will %sbe sent", send_idr ? "" : "NOT " ); } }; | |||
301 | ||||
302 | /* send out the IDi payload */ | |||
303 | ||||
304 | { | |||
305 | pb_stream i_id_pbs; | |||
306 | if (!out_struct(&ike->sa.st_v2_id_payload.header, | |||
307 | &ikev2_id_i_desc, | |||
308 | &sk.pbs, | |||
309 | &i_id_pbs) || | |||
310 | !out_hunk(ike->sa.st_v2_id_payload.data, &i_id_pbs, "my identity")({ typeof(ike->sa.st_v2_id_payload.data) hunk_ = ike->sa .st_v2_id_payload.data; struct packet_byte_stream *outs_ = & i_id_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_.len , ("my identity")); if (d_ != ((void*)0)) { llog_diag(RC_LOG_SERIOUS , outs_->outs_logger, &d_, "%s", ""); } d_ == ((void*) 0); })) | |||
311 | return STF_INTERNAL_ERROR; | |||
312 | close_output_pbs(&i_id_pbs); | |||
313 | } | |||
314 | ||||
315 | if (impair.add_unknown_v2_payload_to_sk == ISAKMP_v2_IKE_AUTH) { | |||
316 | if (!emit_v2UNKNOWN("SK request", | |||
317 | impair.add_unknown_v2_payload_to_sk, | |||
318 | &sk.pbs)) { | |||
319 | return STF_INTERNAL_ERROR; | |||
320 | } | |||
321 | } | |||
322 | ||||
323 | /* send [CERT,] payload RFC 4306 3.6, 1.2) */ | |||
324 | if (send_cert) { | |||
325 | stf_status certstat = ikev2_send_cert(ike->sa.st_connection, &sk.pbs); | |||
326 | if (certstat != STF_OK) | |||
327 | return certstat; | |||
328 | ||||
329 | /* send CERTREQ */ | |||
330 | bool_Bool send_certreq = ikev2_send_certreq_INIT_decision(&ike->sa, SA_INITIATOR); | |||
331 | if (send_certreq) { | |||
332 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
333 | dn_buf buf; | |||
334 | DBG_log("Sending [CERTREQ] of %s", | |||
335 | str_dn(ike->sa.st_connection->spd.that.ca, &buf)); | |||
336 | } | |||
337 | ikev2_send_certreq(&ike->sa, md, &sk.pbs); | |||
338 | } | |||
339 | } | |||
340 | ||||
341 | /* you Tarzan, me Jane support */ | |||
342 | if (send_idr
| |||
343 | switch (pc->spd.that.id.kind) { | |||
344 | case ID_DER_ASN1_DN: | |||
345 | case ID_FQDN: | |||
346 | case ID_USER_FQDN: | |||
347 | case ID_KEY_ID: | |||
348 | case ID_NULL: | |||
349 | { | |||
350 | shunk_t id_b; | |||
351 | struct ikev2_id r_id = build_v2_id_payload(&pc->spd.that, &id_b, | |||
352 | "their IDr", | |||
353 | ike->sa.st_logger); | |||
354 | pb_stream r_id_pbs; | |||
355 | if (!out_struct(&r_id, &ikev2_id_r_desc, &sk.pbs, | |||
356 | &r_id_pbs) || | |||
357 | !out_hunk(id_b, &r_id_pbs, "their IDr")({ typeof(id_b) hunk_ = id_b; struct packet_byte_stream *outs_ = &r_id_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_ .len, ("their IDr")); if (d_ != ((void*)0)) { llog_diag(RC_LOG_SERIOUS , outs_->outs_logger, &d_, "%s", ""); } d_ == ((void*) 0); })) | |||
358 | return STF_INTERNAL_ERROR; | |||
359 | ||||
360 | close_output_pbs(&r_id_pbs); | |||
361 | break; | |||
362 | } | |||
363 | default: | |||
364 | { | |||
365 | esb_buf b; | |||
366 | dbg("Not sending IDr payload for remote ID type %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Not sending IDr payload for remote ID type %s" , enum_show(&ike_id_type_names, pc->spd.that.id.kind, & b)); } } | |||
367 | enum_show(&ike_id_type_names, pc->spd.that.id.kind, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Not sending IDr payload for remote ID type %s" , enum_show(&ike_id_type_names, pc->spd.that.id.kind, & b)); } }; | |||
368 | break; | |||
369 | } | |||
370 | } | |||
371 | } | |||
372 | ||||
373 | if (ic
| |||
374 | log_state(RC_LOG, &ike->sa, "sending INITIAL_CONTACT"); | |||
375 | if (!emit_v2N(v2N_INITIAL_CONTACT, &sk.pbs)) | |||
376 | return STF_INTERNAL_ERROR; | |||
377 | } else { | |||
378 | dbg("not sending INITIAL_CONTACT"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("not sending INITIAL_CONTACT"); } }; | |||
379 | } | |||
380 | ||||
381 | /* send out the AUTH payload */ | |||
382 | ||||
383 | if (!emit_v2_auth(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, &sk.pbs)) { | |||
384 | return STF_INTERNAL_ERROR; | |||
385 | } | |||
386 | ||||
387 | if (LIN(POLICY_MOBIKE, ike->sa.st_connection->policy)(((((lset_t)1 << (POLICY_MOBIKE_IX))) & (ike->sa .st_connection->policy)) == (((lset_t)1 << (POLICY_MOBIKE_IX ))))) { | |||
388 | ike->sa.st_ike_sent_v2n_mobike_supported = true1; | |||
389 | if (!emit_v2N(v2N_MOBIKE_SUPPORTED, &sk.pbs)) { | |||
390 | return STF_INTERNAL_ERROR; | |||
391 | } | |||
392 | } | |||
393 | ||||
394 | /* | |||
395 | * Now that the AUTH payload is done(?), create and emit the | |||
396 | * child using the first pending connection (or the IKE SA's | |||
397 | * connection) if there isn't one. | |||
398 | * | |||
399 | * Then emit SA2i, TSi and TSr and NOTIFY payloads related to | |||
400 | * the IPsec SA. | |||
401 | */ | |||
402 | ||||
403 | /* Child Connection */ | |||
404 | lset_t unused_policy = pc->policy; /* unused */ | |||
405 | struct fd *child_whackfd = null_fd((struct fd *) ((void*)0)); /* must-free */ | |||
406 | struct connection *cc = first_pending(ike, &unused_policy, &child_whackfd); | |||
407 | if (cc == NULL((void*)0)) { | |||
408 | llog_sa(RC_LOG, ike, "omitting CHILD SA payloads")llog(RC_LOG, (ike)->sa.st_logger, "omitting CHILD SA payloads" ); | |||
409 | } else { | |||
410 | /* | |||
411 | * XXX: The problem isn't so much that the child state is | |||
412 | * created - it provides somewhere to store all the child's | |||
413 | * state - but that things switch to the child before the IKE | |||
414 | * SA is finished. Consequently, code is forced to switch | |||
415 | * back to the IKE SA. | |||
416 | */ | |||
417 | struct child_sa *child = new_v2_child_state(cc, ike, IPSEC_SA, | |||
418 | SA_INITIATOR, | |||
419 | STATE_V2_IKE_AUTH_CHILD_I0, | |||
420 | child_whackfd); | |||
421 | close_any(&child_whackfd)close_any_fd((&child_whackfd), ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 421, }; &here; })); | |||
422 | ike->sa.st_v2_larval_initiator_sa = child; | |||
423 | ||||
424 | /* | |||
425 | * XXX because the early child state ends up with the | |||
426 | * try counter check, we need to copy it. | |||
427 | * | |||
428 | * XXX: huh?!? | |||
429 | */ | |||
430 | child->sa.st_try = ike->sa.st_try; | |||
431 | ||||
432 | if (cc != pc) { | |||
433 | /* lie */ | |||
434 | connection_buf cib; | |||
435 | log_state(RC_LOG, &ike->sa, | |||
436 | "switching CHILD #%lu to pending connection "PRI_CONNECTION"\"%s\"%s", | |||
437 | child->sa.st_serialno, pri_connection(cc, &cib)(cc)->name, str_connection_instance(cc, &cib)); | |||
438 | } | |||
439 | ||||
440 | if (!prep_v2_child_for_request(child)) { | |||
441 | return STF_INTERNAL_ERROR; | |||
442 | } | |||
443 | ||||
444 | /* XXX: look further down you're seeing double */ | |||
445 | if (need_v2_configuration_payload(child->sa.st_connection, | |||
446 | ike->sa.hidden_variables.st_nat_traversal)) { | |||
447 | if (!emit_v2_child_configuration_payload(child, &sk.pbs)) { | |||
448 | return STF_INTERNAL_ERROR; | |||
449 | } | |||
450 | } | |||
451 | ||||
452 | /* | |||
453 | * A CHILD_SA established during an AUTH exchange does | |||
454 | * not propose DH - the IKE SA's SKEYSEED is always | |||
455 | * used. | |||
456 | */ | |||
457 | struct ikev2_proposals *child_proposals = | |||
458 | get_v2_ike_auth_child_proposals(cc, "IKE SA initiator emitting ESP/AH proposals", | |||
459 | child->sa.st_logger); | |||
460 | ||||
461 | if (!emit_v2_child_request_payloads(child, child_proposals, &sk.pbs)) { | |||
462 | return STF_INTERNAL_ERROR; | |||
463 | } | |||
464 | ||||
465 | /* send CP payloads */ | |||
466 | if (cc->modecfg_domains != NULL((void*)0) || cc->modecfg_dns != NULL((void*)0)) { | |||
467 | if (!emit_v2_child_configuration_payload(child, &sk.pbs)) { | |||
468 | return STF_INTERNAL_ERROR; | |||
469 | } | |||
470 | } | |||
471 | } | |||
472 | ||||
473 | /* | |||
474 | * If we and responder are willing to use a PPK, we need to | |||
475 | * generate NO_PPK_AUTH as well as PPK-based AUTH payload | |||
476 | */ | |||
477 | if (ike->sa.st_seen_ppk) { | |||
478 | chunk_t *ppk_id; | |||
479 | get_connection_ppk(ike->sa.st_connection, &ppk_id); | |||
480 | struct ppk_id_payload ppk_id_p = { .type = 0, }; | |||
481 | create_ppk_id_payload(ppk_id, &ppk_id_p); | |||
482 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
483 | DBG_log("ppk type: %d", (int) ppk_id_p.type); | |||
484 | DBG_dump_hunk("ppk_id from payload:", ppk_id_p.ppk_id){ typeof(ppk_id_p.ppk_id) hunk_ = ppk_id_p.ppk_id; DBG_dump("ppk_id from payload:" , hunk_.ptr, hunk_.len); }; | |||
485 | } | |||
486 | ||||
487 | pb_stream ppks; | |||
488 | if (!emit_v2Npl(v2N_PPK_IDENTITY, &sk.pbs, &ppks) || | |||
489 | !emit_unified_ppk_id(&ppk_id_p, &ppks)) { | |||
490 | return STF_INTERNAL_ERROR; | |||
491 | } | |||
492 | close_output_pbs(&ppks); | |||
493 | ||||
494 | if (!LIN(POLICY_PPK_INSIST, cc->policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (cc-> policy)) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
| ||||
495 | if (!ikev2_calc_no_ppk_auth(ike, &ike->sa.st_v2_id_payload.mac_no_ppk_auth, | |||
496 | &ike->sa.st_no_ppk_auth)) { | |||
497 | dbg("ikev2_calc_no_ppk_auth() failed dying"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ikev2_calc_no_ppk_auth() failed dying"); } }; | |||
498 | return STF_FATAL; | |||
499 | } | |||
500 | ||||
501 | if (!emit_v2N_hunk(v2N_NO_PPK_AUTH,emit_v2N_bytes(v2N_NO_PPK_AUTH, (ike->sa.st_no_ppk_auth).ptr , (ike->sa.st_no_ppk_auth).len, &sk.pbs) | |||
502 | ike->sa.st_no_ppk_auth, &sk.pbs)emit_v2N_bytes(v2N_NO_PPK_AUTH, (ike->sa.st_no_ppk_auth).ptr , (ike->sa.st_no_ppk_auth).len, &sk.pbs)) { | |||
503 | return STF_INTERNAL_ERROR; | |||
504 | } | |||
505 | } | |||
506 | } | |||
507 | ||||
508 | /* | |||
509 | * The initiator: | |||
510 | * | |||
511 | * We sent normal IKEv2_AUTH_RSA but if the policy also allows | |||
512 | * AUTH_NULL, we will send a Notify with NULL_AUTH in separate | |||
513 | * chunk. This is only done on the initiator in IKE_AUTH, and | |||
514 | * not repeated in rekeys. | |||
515 | */ | |||
516 | if (v2_auth_by(ike) == AUTHBY_RSASIG && pc->policy & POLICY_AUTH_NULL((lset_t)1 << (POLICY_AUTH_NULL_IX))) { | |||
517 | /* store in null_auth */ | |||
518 | chunk_t null_auth = NULL_HUNK{ .ptr = ((void*)0), .len = 0, }; | |||
519 | if (!ikev2_create_psk_auth(AUTHBY_NULL, ike, | |||
520 | &ike->sa.st_v2_id_payload.mac, | |||
521 | &null_auth)) { | |||
522 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
523 | "Failed to calculate additional NULL_AUTH"); | |||
524 | return STF_FATAL; | |||
525 | } | |||
526 | ike->sa.st_v2_ike_intermediate_used = false0; | |||
527 | if (!emit_v2N_hunk(v2N_NULL_AUTH, null_auth, &sk.pbs)emit_v2N_bytes(v2N_NULL_AUTH, (null_auth).ptr, (null_auth).len , &sk.pbs)) { | |||
528 | free_chunk_content(&null_auth); | |||
529 | return STF_INTERNAL_ERROR; | |||
530 | } | |||
531 | free_chunk_content(&null_auth); | |||
532 | } | |||
533 | ||||
534 | if (!close_v2SK_payload(&sk)) { | |||
535 | return STF_INTERNAL_ERROR; | |||
536 | } | |||
537 | close_output_pbs(&rbody); | |||
538 | close_output_pbs(&reply_stream); | |||
539 | ||||
540 | /* | |||
541 | * For AUTH exchange, store the message in the IKE SA. The | |||
542 | * attempt to create the CHILD SA could have failed. | |||
543 | */ | |||
544 | return record_v2SK_message(&reply_stream, &sk, | |||
545 | "sending IKE_AUTH request", | |||
546 | MESSAGE_REQUEST); | |||
547 | } | |||
548 | ||||
549 | /* STATE_V2_PARENT_R1: I2 --> R2 | |||
550 | * <-- HDR, SK {IDi, [CERT,] [CERTREQ,] | |||
551 | * [IDr,] AUTH, SAi2, | |||
552 | * TSi, TSr} | |||
553 | * HDR, SK {IDr, [CERT,] AUTH, | |||
554 | * SAr2, TSi, TSr} --> | |||
555 | * | |||
556 | * [Parent SA established] | |||
557 | */ | |||
558 | ||||
559 | static dh_shared_secret_cb process_v2_IKE_AUTH_request_no_skeyseed_continue; /* type assertion */ | |||
560 | ||||
561 | stf_status process_v2_IKE_AUTH_request_no_skeyseed(struct ike_sa *ike, | |||
562 | struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
563 | struct msg_digest *md UNUSED__attribute__ ((unused))) | |||
564 | { | |||
565 | /* | |||
566 | * the initiator sent us an encrypted payload. We need to calculate | |||
567 | * our g^xy, and skeyseed values, and then decrypt the payload. | |||
568 | */ | |||
569 | ||||
570 | dbg("ikev2 parent %s(): calculating g^{xy} in order to decrypt I2", __func__){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ikev2 parent %s(): calculating g^{xy} in order to decrypt I2" , __func__); } }; | |||
571 | ||||
572 | /* initiate calculation of g^xy */ | |||
573 | submit_dh_shared_secret(&ike->sa, ike->sa.st_gi/*responder needs initiator KE*/, | |||
574 | process_v2_IKE_AUTH_request_no_skeyseed_continue, | |||
575 | HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 575, }; &here ; })); | |||
576 | return STF_SUSPEND; | |||
577 | } | |||
578 | ||||
579 | static stf_status process_v2_IKE_AUTH_request_no_skeyseed_continue(struct state *ike_st, | |||
580 | struct msg_digest *md) | |||
581 | { | |||
582 | struct ike_sa *ike = pexpect_ike_sa(ike_st); | |||
583 | pexpect(ike->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 583, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } assertion__; }); | |||
584 | pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 584, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */ | |||
585 | pexpect(ike->sa.st_state->kind == STATE_V2_PARENT_R1)({ _Bool assertion__ = ike->sa.st_state->kind == STATE_V2_PARENT_R1 ; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 585, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_state->kind == STATE_V2_PARENT_R1" ); } assertion__; }); | |||
586 | dbg("%s() for #%lu %s: calculating g^{xy}, sending R2",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: calculating g^{xy}, sending R2" , __func__, ike->sa.st_serialno, ike->sa.st_state->name ); } } | |||
587 | __func__, ike->sa.st_serialno, ike->sa.st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: calculating g^{xy}, sending R2" , __func__, ike->sa.st_serialno, ike->sa.st_state->name ); } }; | |||
588 | ||||
589 | /* extract calculated values from r */ | |||
590 | ||||
591 | if (ike->sa.st_dh_shared_secret == NULL((void*)0)) { | |||
592 | /* | |||
593 | * Since dh failed, the channel isn't end-to-end | |||
594 | * encrypted. Send back a clear text notify and then | |||
595 | * abandon the connection. | |||
596 | */ | |||
597 | dbg("aborting IKE SA: DH failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("aborting IKE SA: DH failed"); } }; | |||
598 | send_v2N_response_from_md(md, v2N_INVALID_SYNTAX, NULL((void*)0)); | |||
599 | return STF_FATAL; | |||
600 | } | |||
601 | ||||
602 | calc_v2_keymat(&ike->sa, NULL((void*)0)/*old_skey_d*/, NULL((void*)0)/*old_prf*/, | |||
603 | &ike->sa.st_ike_spis/*new SPIs*/); | |||
604 | ||||
605 | ikev2_process_state_packet(ike, &ike->sa, md); | |||
606 | /* above does complete state transition */ | |||
607 | return STF_SKIP_COMPLETE_STATE_TRANSITION; | |||
608 | } | |||
609 | ||||
610 | #ifdef USE_PAM_AUTH1 | |||
611 | ||||
612 | static pam_auth_callback_fn ikev2_pam_continue; /* type assertion */ | |||
613 | ||||
614 | static stf_status ikev2_pam_continue(struct state *ike_st, | |||
615 | struct msg_digest *md, | |||
616 | const char *name UNUSED__attribute__ ((unused)), | |||
617 | bool_Bool success) | |||
618 | { | |||
619 | struct ike_sa *ike = pexpect_ike_sa(ike_st); | |||
620 | pexpect(ike->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 620, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } assertion__; }); | |||
621 | pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 621, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */ | |||
622 | pexpect(ike->sa.st_state->kind == STATE_V2_PARENT_R1)({ _Bool assertion__ = ike->sa.st_state->kind == STATE_V2_PARENT_R1 ; if (!assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 622, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "ike->sa.st_state->kind == STATE_V2_PARENT_R1" ); } assertion__; }); | |||
623 | dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, ike->sa.st_serialno , ike->sa.st_state->name); } } | |||
624 | __func__, ike->sa.st_serialno, ike->sa.st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, ike->sa.st_serialno , ike->sa.st_state->name); } }; | |||
625 | ||||
626 | if (!success) { | |||
627 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
628 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no-data*/, | |||
629 | ENCRYPTED_PAYLOAD); | |||
630 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
631 | return STF_FATAL; /* STF_ZOMBIFY */ | |||
632 | } | |||
633 | ||||
634 | return process_v2_IKE_AUTH_request_tail(&ike->sa, md, success); | |||
635 | } | |||
636 | ||||
637 | #endif /* USE_PAM_AUTH */ | |||
638 | ||||
639 | static stf_status process_v2_IKE_AUTH_request_continue_tail(struct state *st, | |||
640 | struct msg_digest *md); | |||
641 | ||||
642 | stf_status process_v2_IKE_AUTH_request(struct ike_sa *ike, | |||
643 | struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
644 | struct msg_digest *md) | |||
645 | { | |||
646 | ||||
647 | /* for testing only */ | |||
648 | if (impair.send_no_ikev2_auth) { | |||
649 | log_state(RC_LOG, &ike->sa, | |||
650 | "IMPAIR_SEND_NO_IKEV2_AUTH set - not sending IKE_AUTH packet"); | |||
651 | return STF_IGNORE; | |||
652 | } | |||
653 | ||||
654 | /* | |||
655 | * This log line establishes that the packet's been decrypted | |||
656 | * and now it is being processed for real. | |||
657 | * | |||
658 | * XXX: move this into ikev2.c? | |||
659 | */ | |||
660 | LLOG_JAMBUF(RC_LOG, ike->sa.st_logger, buf)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 (({ if (((RC_LOG) & NO_PREFIX) == ((lset_t)0) && (((RC_LOG) & STREAM_MASK ) != DEBUG_STREAM || (cur_debugging & (((lset_t)1 << (DBG_ADD_PREFIX_IX)))))) { (ike->sa.st_logger)->object_vec ->jam_object_prefix(buf, (ike->sa.st_logger)->object ); } }); buf != ((void*)0); jambuf_to_logger(buf, (ike->sa .st_logger), RC_LOG), buf = ((void*)0)) { | |||
661 | jam(buf, "processing decrypted "); | |||
662 | lswlog_msg_digest(buf, md); | |||
663 | } | |||
664 | ||||
665 | stf_status e = process_v2_IKE_AUTH_request_continue_tail(&ike->sa, md); | |||
666 | 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_logger(buf , &failsafe_logger, DEBUG_STREAM), buf = ((void*)0)) { | |||
667 | jam(buf, "process_v2_IKE_AUTH_request_continue_tail returned "); | |||
668 | jam_v2_stf_status(buf, e); | |||
669 | } | |||
670 | ||||
671 | /* | |||
672 | * if failed OE, delete state completely, no create_child_sa | |||
673 | * allowed so childless parent makes no sense. That is also | |||
674 | * the reason why we send v2N_AUTHENTICATION_FAILED, even | |||
675 | * though authenticated succeeded. It shows the remote end | |||
676 | * we have deleted the SA from our end. | |||
677 | */ | |||
678 | if (e >= STF_FAIL && | |||
679 | (ike->sa.st_connection->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))) { | |||
680 | dbg("deleting opportunistic IKE SA with no Child SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("deleting opportunistic IKE SA with no Child SA" ); } }; | |||
681 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
682 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
683 | ENCRYPTED_PAYLOAD); | |||
684 | return STF_FATAL; /* STF_ZOMBIFY */ | |||
685 | } | |||
686 | ||||
687 | return e; | |||
688 | } | |||
689 | ||||
690 | static stf_status process_v2_IKE_AUTH_request_post_cert_decode(struct state *st, | |||
691 | struct msg_digest *md); | |||
692 | ||||
693 | static stf_status process_v2_IKE_AUTH_request_continue_tail(struct state *st, | |||
694 | struct msg_digest *md) | |||
695 | { | |||
696 | struct ike_sa *ike = ike_sa(st, HERE({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 696, }; &here ; })); | |||
697 | ||||
698 | struct payload_digest *cert_payloads = md->chain[ISAKMP_NEXT_v2CERT]; | |||
699 | if (cert_payloads != NULL((void*)0)) { | |||
700 | submit_cert_decode(ike, st, md, cert_payloads, | |||
701 | process_v2_IKE_AUTH_request_post_cert_decode, | |||
702 | "responder decoding certificates"); | |||
703 | return STF_SUSPEND; | |||
704 | } else { | |||
705 | dbg("no certs to decode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no certs to decode"); } }; | |||
706 | ike->sa.st_remote_certs.processed = true1; | |||
707 | ike->sa.st_remote_certs.harmless = true1; | |||
708 | } | |||
709 | return process_v2_IKE_AUTH_request_post_cert_decode(st, md); | |||
710 | } | |||
711 | ||||
712 | static stf_status process_v2_IKE_AUTH_request_ipseckey_continue(struct ike_sa *ike, | |||
713 | struct msg_digest *md, | |||
714 | bool_Bool err); | |||
715 | ||||
716 | static stf_status process_v2_IKE_AUTH_request_id_tail(struct ike_sa *ike, struct msg_digest *md); | |||
717 | ||||
718 | static stf_status process_v2_IKE_AUTH_request_post_cert_decode(struct state *ike_sa, | |||
719 | struct msg_digest *md) | |||
720 | { | |||
721 | struct ike_sa *ike = pexpect_ike_sa(ike_sa); | |||
722 | ikev2_log_parentSA(&ike->sa); | |||
723 | ||||
724 | /* going to switch to child st. before that update parent */ | |||
725 | if (!LHAS(ike->sa.hidden_variables.st_nat_traversal, NATED_HOST)(((ike->sa.hidden_variables.st_nat_traversal) & ((lset_t )1 << (NATED_HOST))) != ((lset_t)0))) | |||
726 | update_ike_endpoints(ike, md); | |||
727 | ||||
728 | nat_traversal_change_port_lookup(md, &ike->sa); /* shouldn't this be ike? */ | |||
729 | ||||
730 | diag_t d = ikev2_responder_decode_initiator_id(ike, md); | |||
731 | if (d != NULL((void*)0)) { | |||
732 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
733 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
734 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
735 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no-data*/, | |||
736 | ENCRYPTED_PAYLOAD); | |||
737 | return STF_FATAL; | |||
738 | } | |||
739 | ||||
740 | enum ikev2_auth_method atype = md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method; | |||
741 | if (IS_LIBUNBOUND1 && id_ipseckey_allowed(ike, atype)) { | |||
742 | dns_status ret = responder_fetch_idi_ipseckey(ike, process_v2_IKE_AUTH_request_ipseckey_continue); | |||
743 | switch (ret) { | |||
744 | case DNS_SUSPEND: | |||
745 | return STF_SUSPEND; | |||
746 | case DNS_FATAL: | |||
747 | llog_sa(RC_LOG_SERIOUS, ike, "DNS: IPSECKEY not found or usable")llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "DNS: IPSECKEY not found or usable" ); | |||
748 | return STF_FATAL; | |||
749 | case DNS_OK: | |||
750 | break; | |||
751 | } | |||
752 | } | |||
753 | ||||
754 | return process_v2_IKE_AUTH_request_id_tail(ike, md); | |||
755 | } | |||
756 | ||||
757 | stf_status process_v2_IKE_AUTH_request_ipseckey_continue(struct ike_sa *ike, | |||
758 | struct msg_digest *md, | |||
759 | bool_Bool err) | |||
760 | { | |||
761 | if (err) { | |||
762 | /* already logged?! */ | |||
763 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
764 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no-data*/, | |||
765 | ENCRYPTED_PAYLOAD); | |||
766 | return STF_FATAL; | |||
767 | } | |||
768 | return process_v2_IKE_AUTH_request_id_tail(ike, md); | |||
769 | } | |||
770 | ||||
771 | stf_status process_v2_IKE_AUTH_request_id_tail(struct ike_sa *ike, struct msg_digest *md) | |||
772 | { | |||
773 | lset_t policy = ike->sa.st_connection->policy; | |||
774 | bool_Bool found_ppk = false0; | |||
775 | chunk_t null_auth = EMPTY_CHUNK((const chunk_t) { .ptr = ((void*)0), .len = 0 }); | |||
776 | ||||
777 | /* | |||
778 | * The NOTIFY payloads we receive in the IKE_AUTH request are | |||
779 | * either related to the IKE SA, or the Child SA. Here we only | |||
780 | * process the ones related to the IKE SA. | |||
781 | */ | |||
782 | if (md->pd[PD_v2N_PPK_IDENTITY] != NULL((void*)0)) { | |||
783 | dbg("received PPK_IDENTITY"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received PPK_IDENTITY"); } }; | |||
784 | struct ppk_id_payload payl; | |||
785 | if (!extract_v2N_ppk_identity(&md->pd[PD_v2N_PPK_IDENTITY]->pbs, &payl, ike)) { | |||
786 | dbg("failed to extract PPK_ID from PPK_IDENTITY payload. Abort!"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("failed to extract PPK_ID from PPK_IDENTITY payload. Abort!" ); } }; | |||
787 | return STF_FATAL; | |||
788 | } | |||
789 | ||||
790 | const chunk_t *ppk = get_ppk_by_id(&payl.ppk_id); | |||
791 | free_chunk_content(&payl.ppk_id); | |||
792 | if (ppk != NULL((void*)0)) { | |||
793 | found_ppk = true1; | |||
794 | } | |||
795 | ||||
796 | if (found_ppk && LIN(POLICY_PPK_ALLOW, policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (policy) ) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) { | |||
797 | ppk_recalculate(ppk, ike->sa.st_oakley.ta_prf, | |||
798 | &ike->sa.st_skey_d_nss, | |||
799 | &ike->sa.st_skey_pi_nss, | |||
800 | &ike->sa.st_skey_pr_nss, | |||
801 | ike->sa.st_logger); | |||
802 | ike->sa.st_ppk_used = true1; | |||
803 | log_state(RC_LOG, &ike->sa, | |||
804 | "PPK AUTH calculated as responder"); | |||
805 | } else { | |||
806 | log_state(RC_LOG, &ike->sa, | |||
807 | "ignored received PPK_IDENTITY - connection does not require PPK or PPKID not found"); | |||
808 | } | |||
809 | } | |||
810 | if (md->pd[PD_v2N_NO_PPK_AUTH] != NULL((void*)0)) { | |||
811 | pb_stream pbs = md->pd[PD_v2N_NO_PPK_AUTH]->pbs; | |||
812 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
813 | dbg("received NO_PPK_AUTH"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received NO_PPK_AUTH"); } }; | |||
814 | if (LIN(POLICY_PPK_INSIST, policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (policy )) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
815 | dbg("Ignored NO_PPK_AUTH data - connection insists on PPK"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Ignored NO_PPK_AUTH data - connection insists on PPK" ); } }; | |||
816 | } else { | |||
817 | ||||
818 | chunk_t no_ppk_auth = alloc_chunk(len, "NO_PPK_AUTH"); | |||
819 | diag_t d = pbs_in_raw(&pbs, no_ppk_auth.ptr, len, "NO_PPK_AUTH extract"); | |||
820 | if (d != NULL((void*)0)) { | |||
821 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, | |||
822 | "failed to extract %zd bytes of NO_PPK_AUTH from Notify payload", len); | |||
823 | free_chunk_content(&no_ppk_auth); | |||
824 | return STF_FATAL; | |||
825 | } | |||
826 | replace_chunk(&ike->sa.st_no_ppk_auth, no_ppk_auth); | |||
827 | } | |||
828 | } | |||
829 | ike->sa.st_ike_seen_v2n_mobike_supported = md->pd[PD_v2N_MOBIKE_SUPPORTED] != NULL((void*)0); | |||
830 | if (ike->sa.st_ike_seen_v2n_mobike_supported) { | |||
831 | dbg("received v2N_MOBIKE_SUPPORTED %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" ); } } | |||
832 | ike->sa.st_ike_sent_v2n_mobike_supported ?{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" ); } } | |||
833 | "and sent" : "while it did not sent"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" ); } }; | |||
834 | } | |||
835 | if (md->pd[PD_v2N_NULL_AUTH] != NULL((void*)0)) { | |||
836 | pb_stream pbs = md->pd[PD_v2N_NULL_AUTH]->pbs; | |||
837 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
838 | ||||
839 | dbg("received v2N_NULL_AUTH"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_NULL_AUTH"); } }; | |||
840 | null_auth = alloc_chunk(len, "NULL_AUTH"); | |||
841 | diag_t d = pbs_in_raw(&pbs, null_auth.ptr, len, "NULL_AUTH extract"); | |||
842 | if (d != NULL((void*)0)) { | |||
843 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, | |||
844 | "failed to extract %zd bytes of NULL_AUTH from Notify payload: ", len); | |||
845 | free_chunk_content(&null_auth); | |||
846 | return STF_FATAL; | |||
847 | } | |||
848 | } | |||
849 | ike->sa.st_ike_seen_v2n_initial_contact = md->pd[PD_v2N_INITIAL_CONTACT] != NULL((void*)0); | |||
850 | ||||
851 | /* | |||
852 | * If we found proper PPK ID and policy allows PPK, use that. | |||
853 | * Otherwise use NO_PPK_AUTH | |||
854 | */ | |||
855 | if (found_ppk && LIN(POLICY_PPK_ALLOW, policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (policy) ) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) | |||
856 | free_chunk_content(&ike->sa.st_no_ppk_auth); | |||
857 | ||||
858 | if (!found_ppk && LIN(POLICY_PPK_INSIST, policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (policy )) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
859 | log_state(RC_LOG_SERIOUS, &ike->sa, "Requested PPK_ID not found and connection requires a valid PPK"); | |||
860 | free_chunk_content(&null_auth); | |||
861 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
862 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
863 | ENCRYPTED_PAYLOAD); | |||
864 | return STF_FATAL; | |||
865 | } | |||
866 | ||||
867 | /* calculate hash of IDi for AUTH below */ | |||
868 | struct crypt_mac idhash_in = v2_id_hash(ike, "IDi verify hash", "IDi", | |||
869 | same_pbs_in_as_shunk(&md->chain[ISAKMP_NEXT_v2IDi]->pbs), | |||
870 | "skey_pi", ike->sa.st_skey_pi_nss); | |||
871 | ||||
872 | /* process CERTREQ payload */ | |||
873 | if (md->chain[ISAKMP_NEXT_v2CERTREQ] != NULL((void*)0)) { | |||
874 | dbg("received CERTREQ payload; going to decode it"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received CERTREQ payload; going to decode it" ); } }; | |||
875 | ikev2_decode_cr(md, ike->sa.st_logger); | |||
876 | } | |||
877 | ||||
878 | /* process AUTH payload */ | |||
879 | ||||
880 | enum keyword_authby that_authby = ike->sa.st_connection->spd.that.authby; | |||
881 | ||||
882 | passert(that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET)({ _Bool assertion__ = that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET; if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 882, }; &here ; }); const struct logger *logger_ = &failsafe_logger; llog_passert (logger_, here, "%s", "that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET" ); } (void) 1; }); | |||
883 | ||||
884 | if (!ike->sa.st_ppk_used && ike->sa.st_no_ppk_auth.ptr != NULL((void*)0)) { | |||
885 | /* | |||
886 | * we didn't recalculate keys with PPK, but we found NO_PPK_AUTH | |||
887 | * (meaning that initiator did use PPK) so we try to verify NO_PPK_AUTH. | |||
888 | */ | |||
889 | dbg("going to try to verify NO_PPK_AUTH."){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("going to try to verify NO_PPK_AUTH."); } }; | |||
890 | /* making a dummy pb_stream so we could pass it to v2_check_auth */ | |||
891 | pb_stream pbs_no_ppk_auth; | |||
892 | pb_stream pbs = md->chain[ISAKMP_NEXT_v2AUTH]->pbs; | |||
893 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
894 | init_pbs(&pbs_no_ppk_auth, ike->sa.st_no_ppk_auth.ptr, len, "pb_stream for verifying NO_PPK_AUTH"); | |||
895 | ||||
896 | diag_t d = v2_authsig_and_log(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
897 | ike, &idhash_in, &pbs_no_ppk_auth, | |||
898 | ike->sa.st_connection->spd.that.authby); | |||
899 | if (d != NULL((void*)0)) { | |||
900 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
901 | dbg("no PPK auth failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no PPK auth failed"); } }; | |||
902 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
903 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
904 | ENCRYPTED_PAYLOAD); | |||
905 | free_chunk_content(&null_auth); /* ??? necessary? */ | |||
906 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
907 | return STF_FATAL; | |||
908 | } | |||
909 | dbg("NO_PPK_AUTH verified"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NO_PPK_AUTH verified"); } }; | |||
910 | } else { | |||
911 | bool_Bool policy_null = LIN(POLICY_AUTH_NULL, ike->sa.st_connection->policy)(((((lset_t)1 << (POLICY_AUTH_NULL_IX))) & (ike-> sa.st_connection->policy)) == (((lset_t)1 << (POLICY_AUTH_NULL_IX )))); | |||
912 | bool_Bool policy_rsasig = LIN(POLICY_RSASIG, ike->sa.st_connection->policy)(((((lset_t)1 << (POLICY_RSASIG_IX))) & (ike->sa .st_connection->policy)) == (((lset_t)1 << (POLICY_RSASIG_IX )))); | |||
913 | ||||
914 | /* | |||
915 | * if received NULL_AUTH in Notify payload and we only allow NULL Authentication, | |||
916 | * proceed with verifying that payload, else verify AUTH normally | |||
917 | */ | |||
918 | if (null_auth.ptr != NULL((void*)0) && policy_null && !policy_rsasig) { | |||
919 | /* making a dummy pb_stream so we could pass it to v2_check_auth */ | |||
920 | pb_stream pbs_null_auth; | |||
921 | size_t len = null_auth.len; | |||
922 | ||||
923 | dbg("going to try to verify NULL_AUTH from Notify payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("going to try to verify NULL_AUTH from Notify payload" ); } }; | |||
924 | init_pbs(&pbs_null_auth, null_auth.ptr, len, "pb_stream for verifying NULL_AUTH"); | |||
925 | diag_t d = v2_authsig_and_log(IKEv2_AUTH_NULL, ike, &idhash_in, | |||
926 | &pbs_null_auth, AUTHBY_NULL); | |||
927 | if (d != NULL((void*)0)) { | |||
928 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
929 | dbg("NULL_auth from Notify Payload failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NULL_auth from Notify Payload failed"); } }; | |||
930 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
931 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
932 | ENCRYPTED_PAYLOAD); | |||
933 | free_chunk_content(&null_auth); | |||
934 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
935 | return STF_FATAL; | |||
936 | } | |||
937 | dbg("NULL_AUTH verified"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NULL_AUTH verified"); } }; | |||
938 | } else { | |||
939 | dbg("responder verifying AUTH payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("responder verifying AUTH payload"); } }; | |||
940 | diag_t d = v2_authsig_and_log(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
941 | ike, &idhash_in, &md->chain[ISAKMP_NEXT_v2AUTH]->pbs, | |||
942 | ike->sa.st_connection->spd.that.authby); | |||
943 | if (d != NULL((void*)0)) { | |||
944 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
945 | dbg("I2 Auth Payload failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("I2 Auth Payload failed"); } }; | |||
946 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
947 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
948 | ENCRYPTED_PAYLOAD); | |||
949 | free_chunk_content(&null_auth); | |||
950 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
951 | return STF_FATAL; | |||
952 | } | |||
953 | } | |||
954 | } | |||
955 | ||||
956 | /* AUTH succeeded */ | |||
957 | ||||
958 | free_chunk_content(&null_auth); | |||
959 | ||||
960 | #ifdef USE_PAM_AUTH1 | |||
961 | /* | |||
962 | * The AUTH payload is verified succsfully. Now invoke the | |||
963 | * PAM helper to authorize connection (based on name only, not | |||
964 | * password) When pam helper is done state will be woken up | |||
965 | * and continue. | |||
966 | */ | |||
967 | if (ike->sa.st_connection->policy & POLICY_IKEV2_PAM_AUTHORIZE((lset_t)1 << (POLICY_IKEV2_PAM_AUTHORIZE_IX))) { | |||
968 | id_buf thatidb; | |||
969 | const char *thatid = str_id(&ike->sa.st_connection->spd.that.id, &thatidb)str_id_bytes(&ike->sa.st_connection->spd.that.id, jam_raw_bytes , &thatidb); | |||
970 | llog_sa(RC_LOG, ike,llog(RC_LOG, (ike)->sa.st_logger, "IKEv2: [XAUTH]PAM method requested to authorize '%s'" , thatid) | |||
971 | "IKEv2: [XAUTH]PAM method requested to authorize '%s'",llog(RC_LOG, (ike)->sa.st_logger, "IKEv2: [XAUTH]PAM method requested to authorize '%s'" , thatid) | |||
972 | thatid)llog(RC_LOG, (ike)->sa.st_logger, "IKEv2: [XAUTH]PAM method requested to authorize '%s'" , thatid); | |||
973 | if (!pam_auth_fork_request(&ike->sa, thatid, "password", | |||
974 | "IKEv2", ikev2_pam_continue)) { | |||
975 | return STF_FATAL; | |||
976 | } | |||
977 | return STF_SUSPEND; | |||
978 | } | |||
979 | #endif | |||
980 | ||||
981 | return process_v2_IKE_AUTH_request_tail(&ike->sa, md, true1); | |||
982 | } | |||
983 | ||||
984 | static v2_auth_signature_cb process_v2_IKE_AUTH_request_auth_signature_continue; /* type check */ | |||
985 | ||||
986 | static stf_status process_v2_IKE_AUTH_request_tail(struct state *ike_st, | |||
987 | struct msg_digest *md, | |||
988 | bool_Bool pam_status) | |||
989 | { | |||
990 | struct ike_sa *ike = pexpect_ike_sa(ike_st); | |||
991 | struct connection *const c = ike->sa.st_connection; | |||
992 | ||||
993 | if (!pam_status) { | |||
994 | /* | |||
995 | * TBD: send this notification encrypted because the | |||
996 | * AUTH payload succeed | |||
997 | */ | |||
998 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
999 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
1000 | ENCRYPTED_PAYLOAD); | |||
1001 | return STF_FATAL; | |||
1002 | } | |||
1003 | ||||
1004 | /* | |||
1005 | * Construct the IDr payload and store it in state so that it | |||
1006 | * can be emitted later. Then use that to construct the | |||
1007 | * "MACedIDFor[R]". | |||
1008 | * | |||
1009 | * Code assumes that struct ikev2_id's "IDType|RESERVED" is | |||
1010 | * laid out the same as the packet. | |||
1011 | */ | |||
1012 | ||||
1013 | if (ike->sa.st_peer_wants_null) { | |||
1014 | /* make it the Null ID */ | |||
1015 | ike->sa.st_v2_id_payload.header.isai_type = ID_NULL; | |||
1016 | ike->sa.st_v2_id_payload.data = empty_chunk; | |||
1017 | } else { | |||
1018 | shunk_t data; | |||
1019 | ike->sa.st_v2_id_payload.header = build_v2_id_payload(&c->spd.this, &data, | |||
1020 | "my IDr", | |||
1021 | ike->sa.st_logger); | |||
1022 | ike->sa.st_v2_id_payload.data = clone_hunk(data, "my IDr")({ typeof(data) hunk_ = data; clone_bytes_as_chunk(hunk_.ptr, hunk_.len, "my IDr"); }); | |||
1023 | } | |||
1024 | ||||
1025 | /* will be signed in auth payload */ | |||
1026 | ike->sa.st_v2_id_payload.mac = v2_hash_id_payload("IDr", ike, "st_skey_pr_nss", | |||
1027 | ike->sa.st_skey_pr_nss); | |||
1028 | ||||
1029 | { | |||
1030 | enum keyword_authby authby = v2_auth_by(ike); | |||
1031 | enum ikev2_auth_method auth_method = v2_auth_method(ike, authby); | |||
1032 | switch (auth_method) { | |||
1033 | case IKEv2_AUTH_RSA: | |||
1034 | { | |||
1035 | const struct hash_desc *hash_algo = &ike_alg_hash_sha1; | |||
1036 | struct crypt_mac hash_to_sign = | |||
1037 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
1038 | hash_algo, LOCAL_PERSPECTIVE); | |||
1039 | ike->sa.st_v2_ike_intermediate_used = false0; | |||
1040 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
1041 | authby, auth_method, | |||
1042 | process_v2_IKE_AUTH_request_auth_signature_continue)) { | |||
1043 | dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } }; | |||
1044 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
1045 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
1046 | ENCRYPTED_PAYLOAD); | |||
1047 | return STF_FATAL; | |||
1048 | } | |||
1049 | return STF_SUSPEND; | |||
1050 | } | |||
1051 | case IKEv2_AUTH_DIGSIG: | |||
1052 | { | |||
1053 | const struct hash_desc *hash_algo = v2_auth_negotiated_signature_hash(ike); | |||
1054 | if (hash_algo == NULL((void*)0)) { | |||
1055 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
1056 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
1057 | ENCRYPTED_PAYLOAD); | |||
1058 | return STF_FATAL; | |||
1059 | } | |||
1060 | struct crypt_mac hash_to_sign = | |||
1061 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
1062 | hash_algo, LOCAL_PERSPECTIVE); | |||
1063 | ike->sa.st_v2_ike_intermediate_used = false0; | |||
1064 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
1065 | authby, auth_method, | |||
1066 | process_v2_IKE_AUTH_request_auth_signature_continue)) { | |||
1067 | dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } }; | |||
1068 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
1069 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
1070 | ENCRYPTED_PAYLOAD); | |||
1071 | return STF_FATAL; | |||
1072 | } | |||
1073 | return STF_SUSPEND; | |||
1074 | } | |||
1075 | case IKEv2_AUTH_PSK: | |||
1076 | case IKEv2_AUTH_NULL: | |||
1077 | { | |||
1078 | struct hash_signature sig = { .len = 0, }; | |||
1079 | return process_v2_IKE_AUTH_request_auth_signature_continue(ike, md, &sig); | |||
1080 | } | |||
1081 | default: | |||
1082 | log_state(RC_LOG, &ike->sa, | |||
1083 | "authentication method %s not supported", | |||
1084 | enum_name(&ikev2_auth_names, auth_method)); | |||
1085 | return STF_FATAL; | |||
1086 | } | |||
1087 | } | |||
1088 | } | |||
1089 | ||||
1090 | static stf_status process_v2_IKE_AUTH_request_auth_signature_continue(struct ike_sa *ike, | |||
1091 | struct msg_digest *md, | |||
1092 | const struct hash_signature *auth_sig) | |||
1093 | { | |||
1094 | struct connection *c = ike->sa.st_connection; | |||
1095 | ||||
1096 | /* | |||
1097 | * Update the parent state to make sure that it knows we have | |||
1098 | * authenticated properly. | |||
1099 | * | |||
1100 | * XXX: is this double book keeping? Same action happens in | |||
1101 | * success_v2_state_transition() and almost happens in | |||
1102 | * ikev2_ike_sa_established(). | |||
1103 | */ | |||
1104 | c->newest_ike_sa = ike->sa.st_serialno; | |||
1105 | ike->sa.st_viable_parent = true1; | |||
1106 | linux_audit_conn(&ike->sa, LAK_PARENT_START); | |||
1107 | pstat_sa_established(&ike->sa); | |||
1108 | ||||
1109 | if (LHAS(ike->sa.hidden_variables.st_nat_traversal, NATED_HOST)(((ike->sa.hidden_variables.st_nat_traversal) & ((lset_t )1 << (NATED_HOST))) != ((lset_t)0))) { | |||
1110 | /* ensure we run keepalives if needed */ | |||
1111 | if (c->nat_keepalive) { | |||
1112 | /* XXX: just trigger this event? */ | |||
1113 | nat_traversal_ka_event(ike->sa.st_logger); | |||
1114 | } | |||
1115 | } | |||
1116 | ||||
1117 | /* send response */ | |||
1118 | if (LIN(POLICY_MOBIKE, c->policy)(((((lset_t)1 << (POLICY_MOBIKE_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_MOBIKE_IX)))) && ike->sa.st_ike_seen_v2n_mobike_supported) { | |||
1119 | if (c->spd.that.host_type == KH_ANY) { | |||
1120 | /* only allow %any connection to mobike */ | |||
1121 | ike->sa.st_ike_sent_v2n_mobike_supported = true1; | |||
1122 | } else { | |||
1123 | log_state(RC_LOG, &ike->sa, | |||
1124 | "not responding with v2N_MOBIKE_SUPPORTED, that end is not %%any"); | |||
1125 | } | |||
1126 | } | |||
1127 | ||||
1128 | bool_Bool send_redirect = false0; | |||
1129 | ||||
1130 | if (ike->sa.st_seen_redirect_sup && | |||
1131 | (LIN(POLICY_SEND_REDIRECT_ALWAYS, c->policy)(((((lset_t)1 << (POLICY_SEND_REDIRECT_ALWAYS_IX))) & (c->policy)) == (((lset_t)1 << (POLICY_SEND_REDIRECT_ALWAYS_IX )))) || | |||
1132 | (!LIN(POLICY_SEND_REDIRECT_NEVER, c->policy)(((((lset_t)1 << (POLICY_SEND_REDIRECT_NEVER_IX))) & (c->policy)) == (((lset_t)1 << (POLICY_SEND_REDIRECT_NEVER_IX )))) && | |||
1133 | require_ddos_cookies()))) { | |||
1134 | if (c->redirect_to == NULL((void*)0)) { | |||
1135 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
1136 | "redirect-to is not specified, can't redirect requests"); | |||
1137 | } else { | |||
1138 | send_redirect = true1; | |||
1139 | } | |||
1140 | } | |||
1141 | ||||
1142 | /* | |||
1143 | * Wipes any connections that were using an old version of | |||
1144 | * this SA? Is this too early or too late? | |||
1145 | * | |||
1146 | * XXX: The call was originally sandwiched vis: | |||
1147 | * | |||
1148 | * - create child sa() | |||
1149 | * - add_xfrmi() | |||
1150 | * - IKE_SA_established() | |||
1151 | * - install_ipsec_sa() | |||
1152 | * | |||
1153 | * which means things were deleted after the child sa was | |||
1154 | * created. But now it happens before. Is this a problem? | |||
1155 | */ | |||
1156 | IKE_SA_established(ike); | |||
1157 | ||||
1158 | /* make sure HDR is at start of a clean buffer */ | |||
1159 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
1160 | reply_buffer, sizeof(reply_buffer), | |||
1161 | ike->sa.st_logger); | |||
1162 | ||||
1163 | /* HDR out */ | |||
1164 | ||||
1165 | struct pbs_outpacket_byte_stream rbody = open_v2_message(&reply_stream, ike, | |||
1166 | md /* response */, | |||
1167 | ISAKMP_v2_IKE_AUTH); | |||
1168 | ||||
1169 | /* decide to send CERT payload before we generate IDr */ | |||
1170 | bool_Bool send_cert = ikev2_send_cert_decision(ike); | |||
1171 | ||||
1172 | /* insert an Encryption payload header */ | |||
1173 | ||||
1174 | struct v2SK_payload sk = open_v2SK_payload(ike->sa.st_logger, &rbody, ike); | |||
1175 | if (!pbs_ok(&sk.pbs)((&sk.pbs)->start != ((void*)0))) { | |||
1176 | return STF_INTERNAL_ERROR; | |||
1177 | } | |||
1178 | ||||
1179 | if (impair.add_unknown_v2_payload_to_sk == ISAKMP_v2_IKE_AUTH) { | |||
1180 | if (!emit_v2UNKNOWN("SK reply", | |||
1181 | impair.add_unknown_v2_payload_to_sk, | |||
1182 | &sk.pbs)) { | |||
1183 | return STF_INTERNAL_ERROR; | |||
1184 | } | |||
1185 | } | |||
1186 | ||||
1187 | /* send any NOTIFY payloads */ | |||
1188 | if (ike->sa.st_ike_sent_v2n_mobike_supported) { | |||
1189 | if (!emit_v2N(v2N_MOBIKE_SUPPORTED, &sk.pbs)) | |||
1190 | return STF_INTERNAL_ERROR; | |||
1191 | } | |||
1192 | ||||
1193 | if (ike->sa.st_ppk_used) { | |||
1194 | if (!emit_v2N(v2N_PPK_IDENTITY, &sk.pbs)) | |||
1195 | return STF_INTERNAL_ERROR; | |||
1196 | } | |||
1197 | ||||
1198 | /* | |||
1199 | * A redirect does not tear down the IKE SA; instead that is | |||
1200 | * left to the initiator: | |||
1201 | * | |||
1202 | * https://datatracker.ietf.org/doc/html/rfc5685#section-6 | |||
1203 | * 6. Redirect during IKE_AUTH Exchange | |||
1204 | * | |||
1205 | * When the client receives the IKE_AUTH response with the | |||
1206 | * REDIRECT payload, it SHOULD delete the IKEv2 security | |||
1207 | * association with the gateway by sending an INFORMATIONAL | |||
1208 | * message with a DELETE payload. | |||
1209 | */ | |||
1210 | if (send_redirect) { | |||
1211 | if (!emit_redirect_notification(shunk1(c->redirect_to), &sk.pbs)) | |||
1212 | return STF_INTERNAL_ERROR; | |||
1213 | ike->sa.st_sent_redirect = true1; /* mark that we have sent REDIRECT in IKE_AUTH */ | |||
1214 | } | |||
1215 | ||||
1216 | /* send out the IDr payload */ | |||
1217 | { | |||
1218 | pb_stream r_id_pbs; | |||
1219 | if (!out_struct(&ike->sa.st_v2_id_payload.header, | |||
1220 | &ikev2_id_r_desc, &sk.pbs, &r_id_pbs) || | |||
1221 | !out_hunk(ike->sa.st_v2_id_payload.data,({ typeof(ike->sa.st_v2_id_payload.data) hunk_ = ike->sa .st_v2_id_payload.data; struct packet_byte_stream *outs_ = & r_id_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_.len , ("my identity")); if (d_ != ((void*)0)) { llog_diag(RC_LOG_SERIOUS , outs_->outs_logger, &d_, "%s", ""); } d_ == ((void*) 0); }) | |||
1222 | &r_id_pbs, "my identity")({ typeof(ike->sa.st_v2_id_payload.data) hunk_ = ike->sa .st_v2_id_payload.data; struct packet_byte_stream *outs_ = & r_id_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_.len , ("my identity")); if (d_ != ((void*)0)) { llog_diag(RC_LOG_SERIOUS , outs_->outs_logger, &d_, "%s", ""); } d_ == ((void*) 0); })) | |||
1223 | return STF_INTERNAL_ERROR; | |||
1224 | close_output_pbs(&r_id_pbs); | |||
1225 | dbg("added IDr payload to packet"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("added IDr payload to packet"); } }; | |||
1226 | } | |||
1227 | ||||
1228 | /* | |||
1229 | * send CERT payload RFC 4306 3.6, 1.2:([CERT,] ) | |||
1230 | * upon which our received I2 CERTREQ is ignored, | |||
1231 | * but ultimately should go into the CERT decision | |||
1232 | */ | |||
1233 | if (send_cert) { | |||
1234 | stf_status certstat = ikev2_send_cert(ike->sa.st_connection, &sk.pbs); | |||
1235 | if (certstat != STF_OK) | |||
1236 | return certstat; | |||
1237 | } | |||
1238 | ||||
1239 | /* now send AUTH payload */ | |||
1240 | ||||
1241 | if (!emit_v2_auth(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, &sk.pbs)) { | |||
1242 | return STF_INTERNAL_ERROR; | |||
1243 | } | |||
1244 | ike->sa.st_v2_ike_intermediate_used = false0; | |||
1245 | ||||
1246 | if (c->config->sec_label.len > 0) { | |||
1247 | pexpect(c->kind == CK_TEMPLATE)({ _Bool assertion__ = c->kind == CK_TEMPLATE; if (!assertion__ ) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 1247, }; &here; }); const struct logger *logger_ = & failsafe_logger; llog_pexpect(logger_, here_, "%s", "c->kind == CK_TEMPLATE" ); } assertion__; }); | |||
1248 | pexpect(c->spd.this.sec_label.len == 0)({ _Bool assertion__ = c->spd.this.sec_label.len == 0; if ( !assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 1248, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "c->spd.this.sec_label.len == 0" ); } assertion__; }); | |||
1249 | if (!install_se_connection_policies(c, ike->sa.st_logger)) { | |||
1250 | return STF_FATAL; | |||
1251 | } | |||
1252 | } | |||
1253 | ||||
1254 | /* | |||
1255 | * Try to build a child. | |||
1256 | * | |||
1257 | * The result can be fatal, or just doesn't create the child. | |||
1258 | */ | |||
1259 | ||||
1260 | if (send_redirect) { | |||
1261 | dbg("skipping child; redirect response"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("skipping child; redirect response"); } }; | |||
1262 | } else { | |||
1263 | v2_notification_t cn = process_v2_IKE_AUTH_request_child_sa_payloads(ike, md, &sk.pbs); | |||
1264 | if (v2_notification_fatal(cn)) { | |||
1265 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
1266 | cn, NULL((void*)0)/*no-data*/, | |||
1267 | ENCRYPTED_PAYLOAD); | |||
1268 | return STF_FATAL; | |||
1269 | } else if (cn != v2N_NOTHING_WRONG) { | |||
1270 | emit_v2N(cn, &sk.pbs); | |||
1271 | } | |||
1272 | } | |||
1273 | ||||
1274 | if (!close_v2SK_payload(&sk)) { | |||
1275 | return STF_INTERNAL_ERROR; | |||
1276 | } | |||
1277 | close_output_pbs(&rbody); | |||
1278 | close_output_pbs(&reply_stream); | |||
1279 | ||||
1280 | /* | |||
1281 | * For AUTH exchange, store the message in the IKE SA. | |||
1282 | * The attempt to create the CHILD SA could have | |||
1283 | * failed. | |||
1284 | */ | |||
1285 | stf_status status = record_v2SK_message(&reply_stream, &sk, | |||
1286 | "replying to IKE_AUTH request", | |||
1287 | MESSAGE_RESPONSE); | |||
1288 | ||||
1289 | return status; | |||
1290 | } | |||
1291 | ||||
1292 | /* STATE_V2_PARENT_I2: R2 --> I3 | |||
1293 | * <-- HDR, SK {IDr, [CERT,] AUTH, | |||
1294 | * [SAr2,] [TSi,] [TSr,]} | |||
1295 | * [Parent SA established] | |||
1296 | * | |||
1297 | * For error handling in this function, please read: | |||
1298 | * https://tools.ietf.org/html/rfc7296#section-2.21.2 | |||
1299 | */ | |||
1300 | ||||
1301 | static stf_status process_v2_IKE_AUTH_response_post_cert_decode(struct state *st, struct msg_digest *md); | |||
1302 | ||||
1303 | stf_status process_v2_IKE_AUTH_response(struct ike_sa *ike, struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
1304 | struct msg_digest *md) | |||
1305 | { | |||
1306 | /* | |||
1307 | * If the initiator rejects the responders authentication it | |||
1308 | * should immediately send a delete notification and wipe the SA. | |||
1309 | * | |||
1310 | * This doesn't happen. Instead the SA is deleted. | |||
1311 | */ | |||
1312 | struct payload_digest *cert_payloads = md->chain[ISAKMP_NEXT_v2CERT]; | |||
1313 | if (cert_payloads != NULL((void*)0)) { | |||
1314 | submit_cert_decode(ike, &ike->sa, md, cert_payloads, | |||
1315 | process_v2_IKE_AUTH_response_post_cert_decode, | |||
1316 | "initiator decoding certificates"); | |||
1317 | return STF_SUSPEND; | |||
1318 | } else { | |||
1319 | dbg("no certs to decode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no certs to decode"); } }; | |||
1320 | ike->sa.st_remote_certs.processed = true1; | |||
1321 | ike->sa.st_remote_certs.harmless = true1; | |||
1322 | return process_v2_IKE_AUTH_response_post_cert_decode(&ike->sa, md); | |||
1323 | } | |||
1324 | } | |||
1325 | ||||
1326 | static stf_status process_v2_IKE_AUTH_response_post_cert_decode(struct state *ike_sa, struct msg_digest *md) | |||
1327 | { | |||
1328 | passert(v2_msg_role(md) == MESSAGE_RESPONSE)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 1328, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_passert(logger_, here, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } (void) 1; }); | |||
1329 | struct ike_sa *ike = pexpect_ike_sa(ike_sa); | |||
1330 | ||||
1331 | diag_t d = ikev2_initiator_decode_responder_id(ike, md); | |||
1332 | if (d != NULL((void*)0)) { | |||
1333 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
1334 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
1335 | /* | |||
1336 | * We cannot send a response as we are processing | |||
1337 | * IKE_AUTH reply the RFC states we should pretend | |||
1338 | * IKE_AUTH was okay, and then send an INFORMATIONAL | |||
1339 | * DELETE IKE SA but we have not implemented that yet. | |||
1340 | */ | |||
1341 | return STF_V2_DELETE_IKE_AUTH_INITIATOR; | |||
1342 | } | |||
1343 | ||||
1344 | struct connection *c = ike->sa.st_connection; | |||
1345 | enum keyword_authby that_authby = c->spd.that.authby; | |||
1346 | ||||
1347 | passert(that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET)({ _Bool assertion__ = that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET; if (!assertion__) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 1347, }; &here ; }); const struct logger *logger_ = &failsafe_logger; llog_passert (logger_, here, "%s", "that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET" ); } (void) 1; }); | |||
1348 | ||||
1349 | if (md->pd[PD_v2N_PPK_IDENTITY] != NULL((void*)0)) { | |||
1350 | if (!LIN(POLICY_PPK_ALLOW, c->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) { | |||
1351 | llog_sa(RC_LOG_SERIOUS, ike, "received PPK_IDENTITY but connection does not allow PPK")llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "received PPK_IDENTITY but connection does not allow PPK" ); | |||
1352 | return STF_FATAL; | |||
1353 | } | |||
1354 | } else { | |||
1355 | if (LIN(POLICY_PPK_INSIST, c->policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) { | |||
1356 | llog_sa(RC_LOG_SERIOUS, ike,llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "failed to receive PPK confirmation and connection has ppk=insist" ) | |||
1357 | "failed to receive PPK confirmation and connection has ppk=insist")llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "failed to receive PPK confirmation and connection has ppk=insist" ); | |||
1358 | dbg("should be initiating a notify that kills the state"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("should be initiating a notify that kills the state" ); } }; | |||
1359 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
1360 | return STF_FATAL; | |||
1361 | } | |||
1362 | } | |||
1363 | ||||
1364 | /* | |||
1365 | * If we sent USE_PPK and we did not receive a PPK_IDENTITY, | |||
1366 | * it means the responder failed to find our PPK ID, but allowed | |||
1367 | * the connection to continue without PPK by using our NO_PPK_AUTH | |||
1368 | * payload. We should revert our key material to NO_PPK versions. | |||
1369 | */ | |||
1370 | if (ike->sa.st_seen_ppk && | |||
1371 | md->pd[PD_v2N_PPK_IDENTITY] == NULL((void*)0) && | |||
1372 | LIN(POLICY_PPK_ALLOW, c->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) { | |||
1373 | /* discard the PPK based calculations */ | |||
1374 | ||||
1375 | log_state(RC_LOG, &ike->sa, "peer wants to continue without PPK - switching to NO_PPK"); | |||
1376 | ||||
1377 | release_symkey(__func__, "st_skey_d_nss", &ike->sa.st_skey_d_nss); | |||
1378 | ike->sa.st_skey_d_nss = reference_symkey(__func__, "used sk_d from no ppk", ike->sa.st_sk_d_no_ppk); | |||
1379 | ||||
1380 | release_symkey(__func__, "st_skey_pi_nss", &ike->sa.st_skey_pi_nss); | |||
1381 | ike->sa.st_skey_pi_nss = reference_symkey(__func__, "used sk_pi from no ppk", ike->sa.st_sk_pi_no_ppk); | |||
1382 | ||||
1383 | release_symkey(__func__, "st_skey_pr_nss", &ike->sa.st_skey_pr_nss); | |||
1384 | ike->sa.st_skey_pr_nss = reference_symkey(__func__, "used sk_pr from no ppk", ike->sa.st_sk_pr_no_ppk); | |||
1385 | } | |||
1386 | ||||
1387 | struct crypt_mac idhash_in = v2_id_hash(ike, "idhash auth R2", "IDr", | |||
1388 | same_pbs_in_as_shunk(&md->chain[ISAKMP_NEXT_v2IDr]->pbs), | |||
1389 | "skey_pr", ike->sa.st_skey_pr_nss); | |||
1390 | ||||
1391 | /* process AUTH payload */ | |||
1392 | ||||
1393 | dbg("initiator verifying AUTH payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("initiator verifying AUTH payload"); } }; | |||
1394 | d = v2_authsig_and_log(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
1395 | ike, &idhash_in, &md->chain[ISAKMP_NEXT_v2AUTH]->pbs, that_authby); | |||
1396 | if (d != NULL((void*)0)) { | |||
1397 | llog_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
1398 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
1399 | /* | |||
1400 | * We cannot send a response as we are processing | |||
1401 | * IKE_AUTH reply the RFC states we should pretend | |||
1402 | * IKE_AUTH was okay, and then send an INFORMATIONAL | |||
1403 | * DELETE IKE SA but we have not implemented that yet. | |||
1404 | */ | |||
1405 | return STF_V2_DELETE_IKE_AUTH_INITIATOR; | |||
1406 | } | |||
1407 | ||||
1408 | /* | |||
1409 | * AUTH succeeed | |||
1410 | * | |||
1411 | * update the parent state to make sure that it knows we have | |||
1412 | * authenticated properly. | |||
1413 | */ | |||
1414 | ikev2_ike_sa_established(ike, md->svm, STATE_V2_ESTABLISHED_IKE_SA); | |||
1415 | ||||
1416 | /* | |||
1417 | * IF there's a redirect, process it and return immediately. | |||
1418 | * Function gets to decide status. | |||
1419 | */ | |||
1420 | stf_status redirect_status = STF_OK; | |||
1421 | if (redirect_ike_auth(ike, md, &redirect_status)) { | |||
1422 | return redirect_status; | |||
1423 | } | |||
1424 | ||||
1425 | ike->sa.st_ike_seen_v2n_mobike_supported = (md->pd[PD_v2N_MOBIKE_SUPPORTED] != NULL((void*)0)); | |||
1426 | if (ike->sa.st_ike_seen_v2n_mobike_supported) { | |||
1427 | dbg("received v2N_MOBIKE_SUPPORTED %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", (ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" )); } } | |||
1428 | (ike->sa.st_ike_sent_v2n_mobike_supported ? "and sent" :{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", (ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" )); } } | |||
1429 | "while it did not sent")){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", (ike->sa .st_ike_sent_v2n_mobike_supported ? "and sent" : "while it did not sent" )); } }; | |||
1430 | } | |||
1431 | ||||
1432 | /* | |||
1433 | * Keep the portal open ... | |||
1434 | */ | |||
1435 | if (LHAS(ike->sa.hidden_variables.st_nat_traversal, NATED_HOST)(((ike->sa.hidden_variables.st_nat_traversal) & ((lset_t )1 << (NATED_HOST))) != ((lset_t)0))) { | |||
1436 | /* ensure we run keepalives if needed */ | |||
1437 | if (c->nat_keepalive) { | |||
1438 | /* | |||
1439 | * Trigger a keep alive for all states. | |||
1440 | * | |||
1441 | * XXX: call nat_traversal_new_ka_event() | |||
1442 | * instead? There's no hurry right? | |||
1443 | */ | |||
1444 | nat_traversal_ka_event(ike->sa.st_logger); | |||
1445 | } | |||
1446 | } | |||
1447 | ||||
1448 | if (c->config->sec_label.len > 0) { | |||
1449 | pexpect(c->kind == CK_TEMPLATE)({ _Bool assertion__ = c->kind == CK_TEMPLATE; if (!assertion__ ) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 1449, }; &here; }); const struct logger *logger_ = & failsafe_logger; llog_pexpect(logger_, here_, "%s", "c->kind == CK_TEMPLATE" ); } assertion__; }); | |||
1450 | pexpect(c->spd.this.sec_label.len == 0)({ _Bool assertion__ = c->spd.this.sec_label.len == 0; if ( !assertion__) { where_t here_ = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c" , .line = 1450, }; &here; }); const struct logger *logger_ = &failsafe_logger; llog_pexpect(logger_, here_, "%s", "c->spd.this.sec_label.len == 0" ); } assertion__; }); | |||
1451 | if (!install_se_connection_policies(c, ike->sa.st_logger)) { | |||
1452 | return STF_FATAL; | |||
1453 | } | |||
1454 | } | |||
1455 | ||||
1456 | /* | |||
1457 | * Figure out of the child is both expected and viable. | |||
1458 | * | |||
1459 | * See 2.21.2. Error Handling in IKE_AUTH | |||
1460 | */ | |||
1461 | ||||
1462 | v2_notification_t n = process_v2_IKE_AUTH_response_child_sa_payloads(ike, md); | |||
1463 | ||||
1464 | if (v2_notification_fatal(n)) { | |||
1465 | /* already logged */ | |||
1466 | /* | |||
1467 | * XXX: there was something "really bad" about the | |||
1468 | * child. Should be sending the fatal notification in | |||
1469 | * a new exchange (see RFC); returning STF_FATAL just | |||
1470 | * causes the IKE SA to silently self-destruct. | |||
1471 | */ | |||
1472 | return STF_FATAL; | |||
1473 | } | |||
1474 | ||||
1475 | if(n != v2N_NOTHING_WRONG) { | |||
1476 | /* already logged */ | |||
1477 | /* | |||
1478 | * This end (the initiator) did not like something | |||
1479 | * about the Child SA. | |||
1480 | * | |||
1481 | * (If the responder sent back an error notification | |||
1482 | * to reject the Child SA, then the above call would | |||
1483 | * have cleaned up the mess and return | |||
1484 | * v2N_NOTHING_WRONG. After all, problem solved. | |||
1485 | */ | |||
1486 | llog_sa(RC_LOG_SERIOUS, ike, "IKE SA established but initiator rejected Child SA response")llog(RC_LOG_SERIOUS, (ike)->sa.st_logger, "IKE SA established but initiator rejected Child SA response" ); | |||
1487 | struct child_sa *larval_child = ike->sa.st_v2_larval_initiator_sa; | |||
1488 | ike->sa.st_v2_larval_initiator_sa = NULL((void*)0); | |||
1489 | passert(larval_child != NULL)({ _Bool assertion__ = larval_child != ((void*)0); if (!assertion__ ) { where_t here = ({ static const struct where here = { .func = __func__, .file = "programs/pluto/ikev2_ike_auth.c", .line = 1489, }; &here; }); const struct logger *logger_ = & failsafe_logger; llog_passert(logger_, here, "%s", "larval_child != ((void*)0)" ); } (void) 1; }); | |||
1490 | /* | |||
1491 | * Needed to un-plug the pending queue. Without this | |||
1492 | * the next pending exchange is never started. | |||
1493 | * | |||
1494 | * While not obvious from the name - unpend() - the | |||
1495 | * code is doing two things: removing LARVAL_CHILD's | |||
1496 | * pending connection; and submitting a request to | |||
1497 | * initiate the next pending connection, if any. | |||
1498 | * | |||
1499 | * The key thing here is that unpend() delays creating | |||
1500 | * the next child until after the previous child is | |||
1501 | * done. Avoiding a race for which child goes next. | |||
1502 | * | |||
1503 | * For IKEv2, should merge the pending queue into the | |||
1504 | * Message ID queue. Have a queue of exchanges, and a | |||
1505 | * queue of things to do when there are no exchanges. | |||
1506 | */ | |||
1507 | unpend(ike, larval_child->sa.st_connection); | |||
1508 | /* | |||
1509 | * Quickly delete this larval SA. | |||
1510 | */ | |||
1511 | submit_v2_delete_exchange(ike, larval_child); | |||
1512 | } | |||
1513 | ||||
1514 | return STF_OK; | |||
1515 | } | |||
1516 | ||||
1517 | /* | |||
1518 | * 2.21.2. Error Handling in IKE_AUTH | |||
1519 | * | |||
1520 | * ... If the error occurred on the responder, the | |||
1521 | * notification is returned in the protected response, and is | |||
1522 | * usually the only payload in that response. Although the IKE_AUTH | |||
1523 | * messages are encrypted and integrity protected, if the peer | |||
1524 | * receiving this notification has not authenticated the other end | |||
1525 | * yet, that peer needs to treat the information with caution. | |||
1526 | * | |||
1527 | * Continuing to retransmit is pointless - it will get back | |||
1528 | * the same response. | |||
1529 | */ | |||
1530 | ||||
1531 | stf_status process_v2_IKE_AUTH_failure_response(struct ike_sa *ike, | |||
1532 | struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
1533 | struct msg_digest *md) | |||
1534 | { | |||
1535 | struct child_sa *child = ike->sa.st_v2_larval_initiator_sa; | |||
1536 | ||||
1537 | /* | |||
1538 | * Mark IKE SA as failing. | |||
1539 | */ | |||
1540 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
1541 | ||||
1542 | /* | |||
1543 | * Try to print a meaningful log of the notification error; | |||
1544 | * but do it in slightly different ways so it is possible to | |||
1545 | * figure out which code path was taken. | |||
1546 | */ | |||
1547 | ||||
1548 | /* | |||
1549 | * These are all IKE SA failures - try to blame IKE first. | |||
1550 | */ | |||
1551 | ||||
1552 | bool_Bool logged_something_serious = false0; | |||
1553 | FOR_EACH_THING(pd, PD_v2N_INVALID_SYNTAX, PD_v2N_AUTHENTICATION_FAILED,for (typeof(PD_v2N_INVALID_SYNTAX) things_[] = { PD_v2N_INVALID_SYNTAX , PD_v2N_AUTHENTICATION_FAILED, PD_v2N_UNSUPPORTED_CRITICAL_PAYLOAD }, *thingp_ = things_, pd; thingp_ < things_ + (sizeof(things_ ) / sizeof(*(things_))) ? (pd = *thingp_, 1) : 0; thingp_++) | |||
1554 | PD_v2N_UNSUPPORTED_CRITICAL_PAYLOAD)for (typeof(PD_v2N_INVALID_SYNTAX) things_[] = { PD_v2N_INVALID_SYNTAX , PD_v2N_AUTHENTICATION_FAILED, PD_v2N_UNSUPPORTED_CRITICAL_PAYLOAD }, *thingp_ = things_, pd; thingp_ < things_ + (sizeof(things_ ) / sizeof(*(things_))) ? (pd = *thingp_, 1) : 0; thingp_++) { | |||
1555 | if (md->pd[pd] != NULL((void*)0)) { | |||
1556 | v2_notification_t n = md->pd[pd]->payload.v2n.isan_type; | |||
1557 | pstat(ikev2_recv_notifies_e, n){ const unsigned pstat_ = (n); const struct pluto_stat *ps_ = &pstats_ikev2_recv_notifies_e; if (pstat_ < ps_->floor || pstat_ >= ps_->roof) { ps_->count[ps_->roof - ps_->floor]++; } else { ps_->count[pstat_-ps_->floor ]++; } }; | |||
1558 | const char *why = enum_name_short(&ikev2_notify_names, n); | |||
1559 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
1560 | "IKE SA authentication request rejected by peer: %s", why); | |||
1561 | logged_something_serious = true1; | |||
1562 | break; | |||
1563 | } | |||
1564 | } | |||
1565 | ||||
1566 | if (!logged_something_serious) { | |||
1567 | /* | |||
1568 | * Dump as much information as possible. | |||
1569 | */ | |||
1570 | for (struct payload_digest *ntfy = md->chain[ISAKMP_NEXT_v2N]; | |||
1571 | ntfy != NULL((void*)0); ntfy = ntfy->next) { | |||
1572 | v2_notification_t n = ntfy->payload.v2n.isan_type; | |||
1573 | /* same scope */ | |||
1574 | esb_buf esb; | |||
1575 | const char *name = enum_show_short(&ikev2_notify_names, n, &esb); | |||
1576 | ||||
1577 | if (ntfy->payload.v2n.isan_spisize != 0) { | |||
1578 | /* invalid-syntax, but can't do anything about it */ | |||
1579 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
1580 | "received an encrypted %s notification with an unexpected non-empty SPI; deleting IKE SA", | |||
1581 | name); | |||
1582 | logged_something_serious = true1; | |||
1583 | break; | |||
1584 | } | |||
1585 | ||||
1586 | if (n >= v2N_STATUS_FLOOR) { | |||
1587 | /* just log */ | |||
1588 | pstat(ikev2_recv_notifies_s, n){ const unsigned pstat_ = (n); const struct pluto_stat *ps_ = &pstats_ikev2_recv_notifies_s; if (pstat_ < ps_->floor || pstat_ >= ps_->roof) { ps_->count[ps_->roof - ps_->floor]++; } else { ps_->count[pstat_-ps_->floor ]++; } }; | |||
1589 | log_state(RC_LOG, &ike->sa, | |||
1590 | "IKE_AUTH response contained the status notification %s", name); | |||
1591 | } else { | |||
1592 | pstat(ikev2_recv_notifies_e, n){ const unsigned pstat_ = (n); const struct pluto_stat *ps_ = &pstats_ikev2_recv_notifies_e; if (pstat_ < ps_->floor || pstat_ >= ps_->roof) { ps_->count[ps_->roof - ps_->floor]++; } else { ps_->count[pstat_-ps_->floor ]++; } }; | |||
1593 | logged_something_serious = true1; | |||
1594 | /* | |||
1595 | * There won't be a child state | |||
1596 | * transition, so log if error is | |||
1597 | * child related. | |||
1598 | * | |||
1599 | * see RFC 7296 Section 1.2 | |||
1600 | */ | |||
1601 | switch(n) { | |||
1602 | case v2N_NO_PROPOSAL_CHOSEN: | |||
1603 | case v2N_SINGLE_PAIR_REQUIRED: | |||
1604 | case v2N_NO_ADDITIONAL_SAS: | |||
1605 | case v2N_INTERNAL_ADDRESS_FAILURE: | |||
1606 | case v2N_FAILED_CP_REQUIRED: | |||
1607 | case v2N_TS_UNACCEPTABLE: | |||
1608 | case v2N_INVALID_SELECTORS: | |||
1609 | if (child == NULL((void*)0)) { | |||
1610 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
1611 | "IKE_AUTH response contained the CHILD SA error notification '%s' but there is no child", name); | |||
1612 | } else { | |||
1613 | log_state(RC_LOG_SERIOUS, &child->sa, | |||
1614 | "IKE_AUTH response contained the error notification %s", name); | |||
1615 | } | |||
1616 | break; | |||
1617 | default: | |||
1618 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
1619 | "IKE_AUTH response contained the error notification %s", name); | |||
1620 | break; | |||
1621 | } | |||
1622 | /* first is enough */ | |||
1623 | break; | |||
1624 | } | |||
1625 | } | |||
1626 | } | |||
1627 | ||||
1628 | if (!logged_something_serious) { | |||
1629 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
1630 | "IKE SA authentication request rejected by peer: unrecognized response"); | |||
1631 | } | |||
1632 | ||||
1633 | return STF_FATAL; | |||
1634 | } |