| File: | programs/pluto/ikev2_parent.c | 
| Warning: | line 4156, column 2 Dereference of null pointer  | 
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 | * | |||
| 20 | * This program is free software; you can redistribute it and/or modify it | |||
| 21 | * under the terms of the GNU General Public License as published by the | |||
| 22 | * Free Software Foundation; either version 2 of the License, or (at your | |||
| 23 | * option) any later version. See <https://www.gnu.org/licenses/gpl2.txt>. | |||
| 24 | * | |||
| 25 | * This program is distributed in the hope that it will be useful, but | |||
| 26 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |||
| 27 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |||
| 28 | * for more details. | |||
| 29 | * | |||
| 30 | */ | |||
| 31 | ||||
| 32 | #include <unistd.h> | |||
| 33 | ||||
| 34 | ||||
| 35 | #include "sysdep.h" | |||
| 36 | #include "constants.h" | |||
| 37 | #include "defs.h" | |||
| 38 | #include "state.h" | |||
| 39 | #include "keys.h" /* needs state.h */ | |||
| 40 | #include "id.h" | |||
| 41 | #include "connections.h" | |||
| 42 | #include "crypt_prf.h" | |||
| 43 | #include "crypto.h" | |||
| 44 | #include "x509.h" | |||
| 45 | #include "pluto_x509.h" | |||
| 46 | #include "ike_alg.h" | |||
| 47 | #include "ike_alg_hash.h" | |||
| 48 | #include "ike_alg_dh.h" | |||
| 49 | #include "kernel_alg.h" | |||
| 50 | #include "plutoalg.h" | |||
| 51 | #include "pluto_crypt.h" | |||
| 52 | #include "packet.h" | |||
| 53 | #include "demux.h" | |||
| 54 | #include "ikev2.h" | |||
| 55 | #include "log.h" | |||
| 56 | #include "spdb.h" /* for out_sa */ | |||
| 57 | #include "ipsec_doi.h" | |||
| 58 | #include "vendor.h" | |||
| 59 | #include "timer.h" | |||
| 60 | #include "ike_spi.h" | |||
| 61 | #include "rnd.h" | |||
| 62 | #include "pending.h" | |||
| 63 | #include "kernel.h" | |||
| 64 | #include "nat_traversal.h" | |||
| 65 | #include "keyhi.h" /* for SECKEY_DestroyPublicKey */ | |||
| 66 | #include "vendor.h" | |||
| 67 | #include "crypt_hash.h" | |||
| 68 | #include "ikev2_ipseckey.h" | |||
| 69 | #include "ikev2_ppk.h" | |||
| 70 | #include "ikev2_redirect.h" | |||
| 71 | #include "xauth.h" | |||
| 72 | #include "crypt_dh.h" | |||
| 73 | #include "crypt_prf.h" | |||
| 74 | #include "ietf_constants.h" | |||
| 75 | #include "ip_address.h" | |||
| 76 | #include "hostpair.h" | |||
| 77 | #include "send.h" | |||
| 78 | #include "ikev2_send.h" | |||
| 79 | #include "pluto_stats.h" | |||
| 80 | #include "retry.h" | |||
| 81 | #include "ipsecconf/confread.h" /* for struct starter_end */ | |||
| 82 | #include "addr_lookup.h" | |||
| 83 | #include "impair.h" | |||
| 84 | #include "ikev2_message.h" | |||
| 85 | #include "ikev2_notify.h" | |||
| 86 | #include "ikev2_ts.h" | |||
| 87 | #include "ikev2_msgid.h" | |||
| 88 | #include "state_db.h" | |||
| 89 | #ifdef USE_XFRM_INTERFACE1 | |||
| 90 | # include "kernel_xfrm_interface.h" | |||
| 91 | #endif | |||
| 92 | ||||
| 93 | #include "crypt_symkey.h" /* for release_symkey */ | |||
| 94 | #include "ip_info.h" | |||
| 95 | #include "iface.h" | |||
| 96 | #include "ikev2_auth.h" | |||
| 97 | #include "secrets.h" | |||
| 98 | #include "cert_decode_helper.h" | |||
| 99 | #include "addresspool.h" | |||
| 100 | ||||
| 101 | struct mobike { | |||
| 102 | ip_endpoint remote; | |||
| 103 | const struct iface_port *interface; | |||
| 104 | }; | |||
| 105 | ||||
| 106 | static stf_status ikev2_parent_inI2outR2_auth_tail(struct state *st, | |||
| 107 | struct msg_digest *md, | |||
| 108 | bool_Bool pam_status); | |||
| 109 | ||||
| 110 | static stf_status ikev2_child_out_tail(struct ike_sa *ike, | |||
| 111 | struct child_sa *child, | |||
| 112 | struct msg_digest *request_md); | |||
| 113 | ||||
| 114 | static bool_Bool accept_v2_nonce(struct logger *logger, struct msg_digest *md, | |||
| 115 | chunk_t *dest, const char *name) | |||
| 116 | { | |||
| 117 | /* | |||
| 118 | * note ISAKMP_NEXT_v2Ni == ISAKMP_NEXT_v2Nr | |||
| 119 | * so when we refer to ISAKMP_NEXT_v2Ni, it might be ISAKMP_NEXT_v2Nr | |||
| 120 | */ | |||
| 121 | pb_stream *nonce_pbs = &md->chain[ISAKMP_NEXT_v2Ni]->pbs; | |||
| 122 | shunk_t nonce = pbs_in_left_as_shunk(nonce_pbs); | |||
| 123 | ||||
| 124 | /* | |||
| 125 | * RFC 7296 Section 2.10: | |||
| 126 | * Nonces used in IKEv2 MUST be randomly chosen, MUST be at least 128 | |||
| 127 | * bits in size, and MUST be at least half the key size of the | |||
| 128 | * negotiated pseudorandom function (PRF). However, the initiator | |||
| 129 | * chooses the nonce before the outcome of the negotiation is known. | |||
| 130 | * Because of that, the nonce has to be long enough for all the PRFs | |||
| 131 | * being proposed. | |||
| 132 | * | |||
| 133 | * We will check for a minimum/maximum here - not meeting that | |||
| 134 | * requirement is a syntax error(?). Once the PRF is | |||
| 135 | * selected, we verify the nonce is big enough. | |||
| 136 | */ | |||
| 137 | ||||
| 138 | if (nonce.len < IKEv2_MINIMUM_NONCE_SIZE16 || nonce.len > IKEv2_MAXIMUM_NONCE_SIZE256) { | |||
| 139 | log_message(RC_LOG_SERIOUS, logger, "%s length %zu not between %d and %d", | |||
| 140 | name, nonce.len, IKEv2_MINIMUM_NONCE_SIZE16, IKEv2_MAXIMUM_NONCE_SIZE256); | |||
| 141 | return false0; | |||
| 142 | } | |||
| 143 | free_chunk_content(dest); | |||
| 144 | 	*dest = clone_hunk(nonce, name)({ typeof(nonce) hunk_ = nonce; clone_bytes_as_chunk(hunk_.ptr , hunk_.len, name); });  | |||
| 145 | return true1; | |||
| 146 | } | |||
| 147 | ||||
| 148 | static bool_Bool negotiate_hash_algo_from_notification(const struct pbs_inpacket_byte_stream *payload_pbs, | |||
| 149 | struct ike_sa *ike) | |||
| 150 | { | |||
| 151 | lset_t sighash_policy = ike->sa.st_connection->sighash_policy; | |||
| 152 | ||||
| 153 | struct pbs_inpacket_byte_stream pbs = *payload_pbs; | |||
| 154 | while (pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)) > 0) { | |||
| 155 | ||||
| 156 | uint16_t nh_value; | |||
| 157 | 		passert(sizeof(nh_value) == RFC_7427_HASH_ALGORITHM_IDENTIFIER_SIZE){ _Bool assertion__ = sizeof(nh_value) == 2; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 157}, "%s", "sizeof(nh_value) == RFC_7427_HASH_ALGORITHM_IDENTIFIER_SIZE" ); } };  | |||
| 158 | diag_t d = pbs_in_raw(&pbs, &nh_value, sizeof(nh_value), | |||
| 159 | "hash algorithm identifier (network ordered)"); | |||
| 160 | if (d != NULL((void*)0)) { | |||
| 161 | log_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, "%s", ""); | |||
| 162 | return false0; | |||
| 163 | } | |||
| 164 | uint16_t h_value = ntohs(nh_value); | |||
| 165 | ||||
| 166 | switch (h_value) { | |||
| 167 | /* We no longer support SHA1 (as per RFC 8247) */ | |||
| 168 | case IKEv2_HASH_ALGORITHM_SHA2_256: | |||
| 169 | if (sighash_policy & POL_SIGHASH_SHA2_256((lset_t)1 << (POL_SIGHASH_SHA2_256_IX))) { | |||
| 170 | ike->sa.st_hash_negotiated |= NEGOTIATE_AUTH_HASH_SHA2_256((lset_t)1 << (IKEv2_HASH_ALGORITHM_SHA2_256)); | |||
| 171 | 				dbg("received HASH_ALGORITHM_SHA2_256 which is allowed by local policy"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received HASH_ALGORITHM_SHA2_256 which is allowed by local policy" ); } };  | |||
| 172 | } | |||
| 173 | break; | |||
| 174 | case IKEv2_HASH_ALGORITHM_SHA2_384: | |||
| 175 | if (sighash_policy & POL_SIGHASH_SHA2_384((lset_t)1 << (POL_SIGHASH_SHA2_384_IX))) { | |||
| 176 | ike->sa.st_hash_negotiated |= NEGOTIATE_AUTH_HASH_SHA2_384((lset_t)1 << (IKEv2_HASH_ALGORITHM_SHA2_384)); | |||
| 177 | 				dbg("received HASH_ALGORITHM_SHA2_384 which is allowed by local policy"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received HASH_ALGORITHM_SHA2_384 which is allowed by local policy" ); } };  | |||
| 178 | } | |||
| 179 | break; | |||
| 180 | case IKEv2_HASH_ALGORITHM_SHA2_512: | |||
| 181 | if (sighash_policy & POL_SIGHASH_SHA2_512((lset_t)1 << (POL_SIGHASH_SHA2_512_IX))) { | |||
| 182 | ike->sa.st_hash_negotiated |= NEGOTIATE_AUTH_HASH_SHA2_512((lset_t)1 << (IKEv2_HASH_ALGORITHM_SHA2_512)); | |||
| 183 | 				dbg("received HASH_ALGORITHM_SHA2_512 which is allowed by local policy"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received HASH_ALGORITHM_SHA2_512 which is allowed by local policy" ); } };  | |||
| 184 | } | |||
| 185 | break; | |||
| 186 | case IKEv2_HASH_ALGORITHM_SHA1: | |||
| 187 | 			dbg("received and ignored IKEv2_HASH_ALGORITHM_SHA1 - it is no longer allowed as per RFC 8247"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received and ignored IKEv2_HASH_ALGORITHM_SHA1 - it is no longer allowed as per RFC 8247" ); } };  | |||
| 188 | break; | |||
| 189 | case IKEv2_HASH_ALGORITHM_IDENTITY: | |||
| 190 | /* ike->sa.st_hash_negotiated |= NEGOTIATE_HASH_ALGORITHM_IDENTITY; */ | |||
| 191 | 			dbg("received unsupported HASH_ALGORITHM_IDENTITY - ignored"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received unsupported HASH_ALGORITHM_IDENTITY - ignored" ); } };  | |||
| 192 | break; | |||
| 193 | default: | |||
| 194 | log_state(RC_LOG, &ike->sa, "received and ignored unknown hash algorithm %d", h_value); | |||
| 195 | } | |||
| 196 | } | |||
| 197 | return true1; | |||
| 198 | } | |||
| 199 | ||||
| 200 | /* check for ASN.1 blob; if found, consume it */ | |||
| 201 | static bool_Bool ikev2_try_asn1_hash_blob(const struct hash_desc *hash_algo, | |||
| 202 | pb_stream *a_pbs, | |||
| 203 | enum keyword_authby authby) | |||
| 204 | { | |||
| 205 | shunk_t b = authby_asn1_hash_blob(hash_algo, authby); | |||
| 206 | ||||
| 207 | uint8_t in_blob[ASN1_LEN_ALGO_IDENTIFIER1 + | |||
| 208 | 		PMAX(ASN1_SHA1_ECDSA_SIZE,((11) >= (((67) >= (12) ? (67) : (12))) ? (11) : (((67) >= (12) ? (67) : (12))))  | |||
| 209 | 			PMAX(ASN1_SHA2_RSA_PSS_SIZE, ASN1_SHA2_ECDSA_SIZE))((11) >= (((67) >= (12) ? (67) : (12))) ? (11) : (((67) >= (12) ? (67) : (12))))];  | |||
| 210 | 	dbg("looking for ASN.1 blob for method %s for hash_algo %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("looking for ASN.1 blob for method %s for hash_algo %s" , enum_name(&keyword_authby_names, authby), hash_algo-> common.fqn); } }  | |||
| 211 | 	    enum_name(&keyword_authby_names, authby), hash_algo->common.fqn){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("looking for ASN.1 blob for method %s for hash_algo %s" , enum_name(&keyword_authby_names, authby), hash_algo-> common.fqn); } };  | |||
| 212 | return | |||
| 213 | 		pexpect(b.ptr != NULL)({ _Bool assertion__ = b.ptr != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 213}, "%s", "b.ptr != NULL"); } assertion__; }) && /* we know this hash */  | |||
| 214 | pbs_left(a_pbs)((size_t)((a_pbs)->roof - (a_pbs)->cur)) >= b.len && /* the stream has enough octets */ | |||
| 215 | memeq(a_pbs->cur, b.ptr, b.len)(memcmp((a_pbs->cur), (b.ptr), (b.len)) == 0) && /* they are the right octets */ | |||
| 216 | 		pexpect(b.len <= sizeof(in_blob))({ _Bool assertion__ = b.len <= sizeof(in_blob); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 216}, "%s", "b.len <= sizeof(in_blob)"); } assertion__ ; }) && /* enough space in in_blob[] */  | |||
| 217 | 		pexpect(in_raw(in_blob, b.len, a_pbs, "ASN.1 blob for hash algo"))({ _Bool assertion__ = in_raw(in_blob, b.len, a_pbs, "ASN.1 blob for hash algo" ); if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 217}, "%s", "in_raw(in_blob, b.len, a_pbs, \"ASN.1 blob for hash algo\")" ); } assertion__; }); /* can eat octets */  | |||
| 218 | } | |||
| 219 | ||||
| 220 | void ikev2_ike_sa_established(struct ike_sa *ike, | |||
| 221 | const struct state_v2_microcode *svm, | |||
| 222 | enum state_kind new_state) | |||
| 223 | { | |||
| 224 | struct connection *c = ike->sa.st_connection; | |||
| 225 | /* | |||
| 226 | * Taking it (what???) current from current state I2/R1. | |||
| 227 | * The parent has advanced but not the svm??? | |||
| 228 | * Ideally this should be timeout of I3/R2 state svm. | |||
| 229 | * How to find that svm??? | |||
| 230 | * I wonder what this comment means? Needs rewording. | |||
| 231 | * | |||
| 232 | * XXX: .timeout_event is tied to a state transition. Does | |||
| 233 | * that mean it applies to the transition or to the final | |||
| 234 | * state? It is kind of treated as all three (the third case | |||
| 235 | * is where a transition gets shared between the parent and | |||
| 236 | * child). | |||
| 237 | */ | |||
| 238 | 	pexpect(svm->timeout_event == EVENT_SA_REPLACE)({ _Bool assertion__ = svm->timeout_event == EVENT_SA_REPLACE ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 238}, "%s", "svm->timeout_event == EVENT_SA_REPLACE" ); } assertion__; });  | |||
| 239 | ||||
| 240 | /* | |||
| 241 | * update the parent state to make sure that it knows we have | |||
| 242 | * authenticated properly. | |||
| 243 | */ | |||
| 244 | change_state(&ike->sa, new_state); | |||
| 245 | c->newest_isakmp_sa = ike->sa.st_serialno; | |||
| 246 | v2_schedule_replace_event(&ike->sa); | |||
| 247 | ike->sa.st_viable_parent = TRUE1; | |||
| 248 | linux_audit_conn(&ike->sa, LAK_PARENT_START); | |||
| 249 | pstat_sa_established(&ike->sa); | |||
| 250 | } | |||
| 251 | ||||
| 252 | /* | |||
| 253 | * Check that the bundled keying material (KE) matches the accepted | |||
| 254 | * proposal and if it doesn't record a response and return false. | |||
| 255 | */ | |||
| 256 | ||||
| 257 | static bool_Bool v2_accept_ke_for_proposal(struct ike_sa *ike, | |||
| 258 | struct state *st, | |||
| 259 | struct msg_digest *md, | |||
| 260 | const struct dh_desc *accepted_dh, | |||
| 261 | enum payload_security security) | |||
| 262 | { | |||
| 263 | 	passert(md->chain[ISAKMP_NEXT_v2KE] != NULL){ _Bool assertion__ = md->chain[ISAKMP_NEXT_v2KE] != ((void *)0); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 263}, "%s", "md->chain[ISAKMP_NEXT_v2KE] != NULL"); } };  | |||
| 264 | int ke_group = md->chain[ISAKMP_NEXT_v2KE]->payload.v2ke.isak_group; | |||
| 265 | if (accepted_dh->common.id[IKEv2_ALG_ID] == ke_group) { | |||
| 266 | return true1; | |||
| 267 | } | |||
| 268 | ||||
| 269 | struct esb_buf ke_esb; | |||
| 270 | log_message(RC_LOG, st->st_logger, | |||
| 271 | "initiator guessed wrong keying material group (%s); responding with INVALID_KE_PAYLOAD requesting %s", | |||
| 272 | enum_show_shortb(&oakley_group_names, ke_group, &ke_esb), | |||
| 273 | accepted_dh->common.fqn); | |||
| 274 | 	pstats(invalidke_sent_u, ke_group){ const unsigned __pstat = (ke_group); if (__pstat < (sizeof (pstats_invalidke_sent_u) / sizeof(*(pstats_invalidke_sent_u) ))) { pstats_invalidke_sent_u[__pstat]++; } else if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { DBG_log("pstats %s %d" , "invalidke_sent_u", __pstat); } };  | |||
| 275 | 	pstats(invalidke_sent_s, accepted_dh->common.id[IKEv2_ALG_ID]){ const unsigned __pstat = (accepted_dh->common.id[IKEv2_ALG_ID ]); if (__pstat < (sizeof(pstats_invalidke_sent_s) / sizeof (*(pstats_invalidke_sent_s)))) { pstats_invalidke_sent_s[__pstat ]++; } else if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX ))))) { DBG_log("pstats %s %d", "invalidke_sent_s", __pstat); } };  | |||
| 276 | /* convert group to a raw buffer */ | |||
| 277 | uint16_t gr = htons(accepted_dh->group); | |||
| 278 | chunk_t nd = THING_AS_CHUNK(gr)chunk2(&(gr), sizeof(gr)); | |||
| 279 | record_v2N_response(st->st_logger, ike, md, | |||
| 280 | v2N_INVALID_KE_PAYLOAD, &nd, | |||
| 281 | security); | |||
| 282 | return false0; | |||
| 283 | } | |||
| 284 | ||||
| 285 | /* | |||
| 286 | * Called by ikev2_parent_inI2outR2_tail() and ikev2_parent_inR2() | |||
| 287 | * Do the actual AUTH payload verification | |||
| 288 | */ | |||
| 289 | /* | |||
| 290 | * ??? Several verify routines return an stf_status and yet we just return a bool. | |||
| 291 | * We perhaps should return an stf_status so distinctions don't get lost. | |||
| 292 | * | |||
| 293 | * XXX: this is answering a simple yes/no question. Did auth succeed. | |||
| 294 | * Caller needs to decide what response is appropriate. | |||
| 295 | */ | |||
| 296 | static bool_Bool v2_check_auth(enum ikev2_auth_method recv_auth, | |||
| 297 | struct ike_sa *ike, | |||
| 298 | const struct crypt_mac *idhash_in, | |||
| 299 | pb_stream *pbs, | |||
| 300 | const enum keyword_authby that_authby, | |||
| 301 | const char *context) | |||
| 302 | { | |||
| 303 | switch (recv_auth) { | |||
| 304 | case IKEv2_AUTH_RSA: | |||
| 305 | { | |||
| 306 | if (that_authby != AUTHBY_RSASIG) { | |||
| 307 | log_state(RC_LOG, &ike->sa, | |||
| 308 | "peer attempted RSA authentication but we want %s in %s", | |||
| 309 | enum_name(&keyword_authby_names, that_authby), | |||
| 310 | context); | |||
| 311 | return false0; | |||
| 312 | } | |||
| 313 | ||||
| 314 | stf_status authstat = ikev2_verify_rsa_hash(ike, idhash_in, pbs, | |||
| 315 | &ike_alg_hash_sha1); | |||
| 316 | ||||
| 317 | if (authstat != STF_OK) { | |||
| 318 | log_state(RC_LOG, &ike->sa, | |||
| 319 | "RSA authentication of %s failed", context); | |||
| 320 | return false0; | |||
| 321 | } | |||
| 322 | return true1; | |||
| 323 | } | |||
| 324 | ||||
| 325 | case IKEv2_AUTH_PSK: | |||
| 326 | { | |||
| 327 | if (that_authby != AUTHBY_PSK) { | |||
| 328 | log_state(RC_LOG, &ike->sa, | |||
| 329 | "peer attempted PSK authentication but we want %s in %s", | |||
| 330 | enum_name(&keyword_authby_names, that_authby), | |||
| 331 | context); | |||
| 332 | return FALSE0; | |||
| 333 | } | |||
| 334 | ||||
| 335 | if (!ikev2_verify_psk_auth(AUTHBY_PSK, ike, idhash_in, pbs)) { | |||
| 336 | log_state(RC_LOG, &ike->sa, | |||
| 337 | "PSK Authentication failed: AUTH mismatch in %s!", | |||
| 338 | context); | |||
| 339 | return FALSE0; | |||
| 340 | } | |||
| 341 | return TRUE1; | |||
| 342 | } | |||
| 343 | ||||
| 344 | case IKEv2_AUTH_NULL: | |||
| 345 | { | |||
| 346 | if (!(that_authby == AUTHBY_NULL || | |||
| 347 | 		      (that_authby == AUTHBY_RSASIG && 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 ))))))) {  | |||
| 348 | log_state(RC_LOG, &ike->sa, | |||
| 349 | "peer attempted NULL authentication but we want %s in %s", | |||
| 350 | enum_name(&keyword_authby_names, that_authby), | |||
| 351 | context); | |||
| 352 | return FALSE0; | |||
| 353 | } | |||
| 354 | ||||
| 355 | if (!ikev2_verify_psk_auth(AUTHBY_NULL, ike, idhash_in, pbs)) { | |||
| 356 | log_state(RC_LOG, &ike->sa, | |||
| 357 | "NULL authentication failed: AUTH mismatch in %s! (implementation bug?)", | |||
| 358 | context); | |||
| 359 | return FALSE0; | |||
| 360 | } | |||
| 361 | ike->sa.st_ikev2_anon = TRUE1; | |||
| 362 | return TRUE1; | |||
| 363 | } | |||
| 364 | ||||
| 365 | case IKEv2_AUTH_DIGSIG: | |||
| 366 | { | |||
| 367 | if (that_authby != AUTHBY_ECDSA && that_authby != AUTHBY_RSASIG) { | |||
| 368 | log_state(RC_LOG, &ike->sa, | |||
| 369 | "peer attempted Authentication through Digital Signature but we want %s in %s", | |||
| 370 | enum_name(&keyword_authby_names, that_authby), | |||
| 371 | context); | |||
| 372 | return FALSE0; | |||
| 373 | } | |||
| 374 | ||||
| 375 | /* try to match ASN.1 blob designating the hash algorithm */ | |||
| 376 | ||||
| 377 | lset_t hn = ike->sa.st_hash_negotiated; | |||
| 378 | ||||
| 379 | struct hash_alts { | |||
| 380 | lset_t neg; | |||
| 381 | const struct hash_desc *algo; | |||
| 382 | }; | |||
| 383 | ||||
| 384 | static const struct hash_alts ha[] = { | |||
| 385 | { NEGOTIATE_AUTH_HASH_SHA2_512((lset_t)1 << (IKEv2_HASH_ALGORITHM_SHA2_512)), &ike_alg_hash_sha2_512 }, | |||
| 386 | { NEGOTIATE_AUTH_HASH_SHA2_384((lset_t)1 << (IKEv2_HASH_ALGORITHM_SHA2_384)), &ike_alg_hash_sha2_384 }, | |||
| 387 | { NEGOTIATE_AUTH_HASH_SHA2_256((lset_t)1 << (IKEv2_HASH_ALGORITHM_SHA2_256)), &ike_alg_hash_sha2_256 }, | |||
| 388 | /* { NEGOTIATE_AUTH_HASH_IDENTITY, IKEv2_HASH_ALGORITHM_IDENTITY }, */ | |||
| 389 | }; | |||
| 390 | ||||
| 391 | const struct hash_alts *hap; | |||
| 392 | ||||
| 393 | for (hap = ha; ; hap++) { | |||
| 394 | if (hap == &ha[elemsof(ha)(sizeof(ha) / sizeof(*(ha)))]) { | |||
| 395 | log_state(RC_LOG, &ike->sa, | |||
| 396 | "no acceptable ECDSA/RSA-PSS ASN.1 signature hash proposal included for %s in %s", | |||
| 397 | enum_name(&keyword_authby_names, that_authby), context); | |||
| 398 | 				DBG(DBG_BASE, {{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { { size_t dl = ({ typeof(((size_t)((pbs)->roof - (pbs )->cur))) _min1 = (((size_t)((pbs)->roof - (pbs)->cur ))); typeof((size_t) (1 + ((11) >= (((67) >= (12) ? (67 ) : (12))) ? (11) : (((67) >= (12) ? (67) : (12)))))) _min2 = ((size_t) (1 + ((11) >= (((67) >= (12) ? (67) : (12) )) ? (11) : (((67) >= (12) ? (67) : (12)))))); (void) (& _min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); DBG_dump ("offered blob", pbs->cur, dl); }; } }  | |||
| 399 | 					size_t dl = min(pbs_left(pbs),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { { size_t dl = ({ typeof(((size_t)((pbs)->roof - (pbs )->cur))) _min1 = (((size_t)((pbs)->roof - (pbs)->cur ))); typeof((size_t) (1 + ((11) >= (((67) >= (12) ? (67 ) : (12))) ? (11) : (((67) >= (12) ? (67) : (12)))))) _min2 = ((size_t) (1 + ((11) >= (((67) >= (12) ? (67) : (12) )) ? (11) : (((67) >= (12) ? (67) : (12)))))); (void) (& _min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); DBG_dump ("offered blob", pbs->cur, dl); }; } }  | |||
| 400 | 						(size_t) (ASN1_LEN_ALGO_IDENTIFIER +{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { { size_t dl = ({ typeof(((size_t)((pbs)->roof - (pbs )->cur))) _min1 = (((size_t)((pbs)->roof - (pbs)->cur ))); typeof((size_t) (1 + ((11) >= (((67) >= (12) ? (67 ) : (12))) ? (11) : (((67) >= (12) ? (67) : (12)))))) _min2 = ((size_t) (1 + ((11) >= (((67) >= (12) ? (67) : (12) )) ? (11) : (((67) >= (12) ? (67) : (12)))))); (void) (& _min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); DBG_dump ("offered blob", pbs->cur, dl); }; } }  | |||
| 401 | 							PMAX(ASN1_SHA1_ECDSA_SIZE,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { { size_t dl = ({ typeof(((size_t)((pbs)->roof - (pbs )->cur))) _min1 = (((size_t)((pbs)->roof - (pbs)->cur ))); typeof((size_t) (1 + ((11) >= (((67) >= (12) ? (67 ) : (12))) ? (11) : (((67) >= (12) ? (67) : (12)))))) _min2 = ((size_t) (1 + ((11) >= (((67) >= (12) ? (67) : (12) )) ? (11) : (((67) >= (12) ? (67) : (12)))))); (void) (& _min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); DBG_dump ("offered blob", pbs->cur, dl); }; } }  | |||
| 402 | 							PMAX(ASN1_SHA2_RSA_PSS_SIZE,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { { size_t dl = ({ typeof(((size_t)((pbs)->roof - (pbs )->cur))) _min1 = (((size_t)((pbs)->roof - (pbs)->cur ))); typeof((size_t) (1 + ((11) >= (((67) >= (12) ? (67 ) : (12))) ? (11) : (((67) >= (12) ? (67) : (12)))))) _min2 = ((size_t) (1 + ((11) >= (((67) >= (12) ? (67) : (12) )) ? (11) : (((67) >= (12) ? (67) : (12)))))); (void) (& _min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); DBG_dump ("offered blob", pbs->cur, dl); }; } }  | |||
| 403 | 								ASN1_SHA2_ECDSA_SIZE))));{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { { size_t dl = ({ typeof(((size_t)((pbs)->roof - (pbs )->cur))) _min1 = (((size_t)((pbs)->roof - (pbs)->cur ))); typeof((size_t) (1 + ((11) >= (((67) >= (12) ? (67 ) : (12))) ? (11) : (((67) >= (12) ? (67) : (12)))))) _min2 = ((size_t) (1 + ((11) >= (((67) >= (12) ? (67) : (12) )) ? (11) : (((67) >= (12) ? (67) : (12)))))); (void) (& _min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); DBG_dump ("offered blob", pbs->cur, dl); }; } }  | |||
| 404 | 					DBG_dump("offered blob", pbs->cur, dl);{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { { size_t dl = ({ typeof(((size_t)((pbs)->roof - (pbs )->cur))) _min1 = (((size_t)((pbs)->roof - (pbs)->cur ))); typeof((size_t) (1 + ((11) >= (((67) >= (12) ? (67 ) : (12))) ? (11) : (((67) >= (12) ? (67) : (12)))))) _min2 = ((size_t) (1 + ((11) >= (((67) >= (12) ? (67) : (12) )) ? (11) : (((67) >= (12) ? (67) : (12)))))); (void) (& _min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); DBG_dump ("offered blob", pbs->cur, dl); }; } }  | |||
| 405 | 					}){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { { size_t dl = ({ typeof(((size_t)((pbs)->roof - (pbs )->cur))) _min1 = (((size_t)((pbs)->roof - (pbs)->cur ))); typeof((size_t) (1 + ((11) >= (((67) >= (12) ? (67 ) : (12))) ? (11) : (((67) >= (12) ? (67) : (12)))))) _min2 = ((size_t) (1 + ((11) >= (((67) >= (12) ? (67) : (12) )) ? (11) : (((67) >= (12) ? (67) : (12)))))); (void) (& _min1 == &_min2); _min1 < _min2 ? _min1 : _min2; }); DBG_dump ("offered blob", pbs->cur, dl); }; } }  | |||
| 406 | return FALSE0; /* none recognized */ | |||
| 407 | } | |||
| 408 | ||||
| 409 | if ((hn & hap->neg) && ikev2_try_asn1_hash_blob(hap->algo, pbs, that_authby)) | |||
| 410 | break; | |||
| 411 | ||||
| 412 | 			dbg("st_hash_negotiated policy does not match hash algorithm %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("st_hash_negotiated policy does not match hash algorithm %s" , hap->algo->common.fqn); } }  | |||
| 413 | 			    hap->algo->common.fqn){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("st_hash_negotiated policy does not match hash algorithm %s" , hap->algo->common.fqn); } };  | |||
| 414 | } | |||
| 415 | ||||
| 416 | /* try to match the hash */ | |||
| 417 | stf_status authstat; | |||
| 418 | ||||
| 419 | switch (that_authby) { | |||
| 420 | case AUTHBY_RSASIG: | |||
| 421 | authstat = ikev2_verify_rsa_hash(ike, idhash_in, pbs, | |||
| 422 | hap->algo); | |||
| 423 | break; | |||
| 424 | ||||
| 425 | case AUTHBY_ECDSA: | |||
| 426 | authstat = ikev2_verify_ecdsa_hash(ike, idhash_in, pbs, | |||
| 427 | hap->algo); | |||
| 428 | break; | |||
| 429 | ||||
| 430 | default: | |||
| 431 | 			bad_case(that_authby)libreswan_bad_case("that_authby", (that_authby), (where_t) { . func = __func__, .basename = "ikev2_parent.c" , .line = 431});  | |||
| 432 | } | |||
| 433 | ||||
| 434 | if (authstat != STF_OK) { | |||
| 435 | log_state(RC_LOG, &ike->sa, | |||
| 436 | "Digital Signature authentication using %s failed in %s", | |||
| 437 | enum_name(&keyword_authby_names, that_authby), | |||
| 438 | context); | |||
| 439 | return FALSE0; | |||
| 440 | } | |||
| 441 | return TRUE1; | |||
| 442 | } | |||
| 443 | ||||
| 444 | default: | |||
| 445 | log_state(RC_LOG, &ike->sa, | |||
| 446 | "authentication method: %s not supported in %s", | |||
| 447 | enum_name(&ikev2_auth_names, recv_auth), | |||
| 448 | context); | |||
| 449 | return FALSE0; | |||
| 450 | } | |||
| 451 | } | |||
| 452 | ||||
| 453 | static bool_Bool id_ipseckey_allowed(struct state *st, enum ikev2_auth_method atype) | |||
| 454 | { | |||
| 455 | const struct connection *c = st->st_connection; | |||
| 456 | struct id id = st->st_connection->spd.that.id; | |||
| 457 | ||||
| 458 | ||||
| 459 | if (!c->spd.that.key_from_DNS_on_demand) | |||
| 460 | return FALSE0; | |||
| 461 | ||||
| 462 | if (c->spd.that.authby == AUTHBY_RSASIG && | |||
| 463 | 	    (id.kind == ID_FQDN || id_is_ipaddr(&id)((&id)->kind == ID_IPV4_ADDR || (&id)->kind == ID_IPV6_ADDR )))  | |||
| 464 | { | |||
| 465 | switch (atype) { | |||
| 466 | case IKEv2_AUTH_RESERVED: | |||
| 467 | case IKEv2_AUTH_DIGSIG: | |||
| 468 | case IKEv2_AUTH_RSA: | |||
| 469 | return TRUE1; /* success */ | |||
| 470 | default: | |||
| 471 | break; /* failure */ | |||
| 472 | } | |||
| 473 | } | |||
| 474 | ||||
| 475 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 476 | const char *err1 = "%dnsondemand"; | |||
| 477 | const char *err2 = ""; | |||
| 478 | ||||
| 479 | if (atype != IKEv2_AUTH_RESERVED && !(atype == IKEv2_AUTH_RSA || | |||
| 480 | atype == IKEv2_AUTH_DIGSIG)) { | |||
| 481 | err1 = " initiator IKEv2 Auth Method mismatched "; | |||
| 482 | err2 = enum_name(&ikev2_auth_names, atype); | |||
| 483 | } | |||
| 484 | ||||
| 485 | if (id.kind != ID_FQDN && | |||
| 486 | id.kind != ID_IPV4_ADDR && | |||
| 487 | id.kind != ID_IPV6_ADDR) { | |||
| 488 | err1 = " mismatched ID type, that ID is not a FQDN, IPV4_ADDR, or IPV6_ADDR id type="; | |||
| 489 | err2 = enum_show(&ike_idtype_names, id.kind); | |||
| 490 | } | |||
| 491 | ||||
| 492 | id_buf thatid; | |||
| 493 | ipstr_buf ra; | |||
| 494 | DBG_log("%s #%lu not fetching ipseckey %s%s remote=%s thatid=%s", | |||
| 495 | c->name, st->st_serialno, | |||
| 496 | err1, err2, | |||
| 497 | ipstr(&st->st_remote_endpoint, &ra), | |||
| 498 | str_id(&id, &thatid)); | |||
| 499 | } | |||
| 500 | return FALSE0; | |||
| 501 | } | |||
| 502 | ||||
| 503 | /* | |||
| 504 | * | |||
| 505 | *************************************************************** | |||
| 506 | ***** PARENT_OUTI1 ***** | |||
| 507 | *************************************************************** | |||
| 508 | * | |||
| 509 | * | |||
| 510 | * Initiate an Oakley Main Mode exchange. | |||
| 511 | * HDR, SAi1, KEi, Ni --> | |||
| 512 | * | |||
| 513 | * Note: this is not called from demux.c, but from ipsecdoi_initiate(). | |||
| 514 | * | |||
| 515 | */ | |||
| 516 | static crypto_req_cont_func ikev2_parent_outI1_continue; | |||
| 517 | ||||
| 518 | /* extern initiator_function ikev2_parent_outI1; */ /* type assertion */ | |||
| 519 | ||||
| 520 | void ikev2_parent_outI1(struct fd *whack_sock, | |||
| 521 | struct connection *c, | |||
| 522 | struct state *predecessor, | |||
| 523 | lset_t policy, | |||
| 524 | unsigned long try, | |||
| 525 | const threadtime_t *inception, | |||
| 526 | struct xfrm_user_sec_ctx_ike *uctx | |||
| 527 | ) | |||
| 528 | { | |||
| 529 | if (drop_new_exchanges()) { | |||
| 530 | /* Only drop outgoing opportunistic connections */ | |||
| 531 | if (c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) { | |||
| 532 | return; | |||
| 533 | } | |||
| 534 | } | |||
| 535 | ||||
| 536 | const struct finite_state *fs = finite_states[STATE_PARENT_I0]; | |||
| 537 | 	pexpect(fs->nr_transitions == 1)({ _Bool assertion__ = fs->nr_transitions == 1; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 537}, "%s", "fs->nr_transitions == 1"); } assertion__ ; });  | |||
| 538 | const struct state_v2_microcode *transition = &fs->v2_transitions[0]; | |||
| 539 | struct ike_sa *ike = new_v2_ike_state(transition, SA_INITIATOR, | |||
| 540 | ike_initiator_spi(), zero_ike_spi, | |||
| 541 | c, policy, try, whack_sock); | |||
| 542 | statetime_t start = statetime_backdate(&ike->sa, inception); | |||
| 543 | ||||
| 544 | 	push_cur_state(&ike->sa)log_push_state(&ike->sa, (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 544});  | |||
| 545 | /* set up new state */ | |||
| 546 | struct state *st = &ike->sa; | |||
| 547 | 	passert(st->st_ike_version == IKEv2){ _Bool assertion__ = st->st_ike_version == IKEv2; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 547}, "%s", "st->st_ike_version == IKEv2" ); } };  | |||
| 548 | 	passert(st->st_state->kind == STATE_PARENT_I0){ _Bool assertion__ = st->st_state->kind == STATE_PARENT_I0 ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 548}, "%s", "st->st_state->kind == STATE_PARENT_I0" ); } };  | |||
| 549 | 	passert(st->st_sa_role == SA_INITIATOR){ _Bool assertion__ = st->st_sa_role == SA_INITIATOR; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 549}, "%s", "st->st_sa_role == SA_INITIATOR" ); } };  | |||
| 550 | st->st_try = try; | |||
| 551 | ||||
| 552 | if ((c->iketcp == IKE_TCP_ONLY) || (try > 1 && c->iketcp != IKE_TCP_NO)) { | |||
| 553 | 		dbg("TCP: forcing #%lu remote endpoint port to %d",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("TCP: forcing #%lu remote endpoint port to %d" , st->st_serialno, c->remote_tcpport); } }  | |||
| 554 | 		    st->st_serialno, c->remote_tcpport){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("TCP: forcing #%lu remote endpoint port to %d" , st->st_serialno, c->remote_tcpport); } };  | |||
| 555 | st->st_remote_endpoint = set_endpoint_hport(&st->st_remote_endpoint, | |||
| 556 | c->remote_tcpport); | |||
| 557 | stf_status ret = create_tcp_interface(st); | |||
| 558 | if (ret != STF_OK) { | |||
| 559 | /* TCP: already logged? */ | |||
| 560 | delete_state(st); | |||
| 561 | return; | |||
| 562 | } | |||
| 563 | } | |||
| 564 | ||||
| 565 | 	if (HAS_IPSEC_POLICY(policy)(((policy) & (((lset_t)1 << (POLICY_NOPMTUDISC_IX)) - ((lset_t)1 << (POLICY_ENCRYPT_IX)) + ((lset_t)1 << (POLICY_NOPMTUDISC_IX)))) != 0)) {  | |||
| 566 | st->sec_ctx = NULL((void*)0); | |||
| 567 | if (uctx != NULL((void*)0)) | |||
| 568 | 			libreswan_log(loglog(RC_LOG, "Labeled ipsec is not supported with ikev2 yet" )  | |||
| 569 | 				"Labeled ipsec is not supported with ikev2 yet")loglog(RC_LOG, "Labeled ipsec is not supported with ikev2 yet" );  | |||
| 570 | add_pending(whack_sock, ike, c, policy, 1, | |||
| 571 | predecessor == NULL((void*)0) ? SOS_NOBODY0 : predecessor->st_serialno, | |||
| 572 | st->sec_ctx, | |||
| 573 | true1/*part of initiate*/); | |||
| 574 | } | |||
| 575 | ||||
| 576 | /* | |||
| 577 | * XXX: why limit this log line to whack when opportunistic? | |||
| 578 | * This was, after all, triggered by something that happened | |||
| 579 | * at this end. | |||
| 580 | */ | |||
| 581 | enum stream logger = ((c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) == LEMPTY((lset_t)0)) ? ALL_STREAMS : WHACK_STREAM; | |||
| 582 | ||||
| 583 | if (predecessor != NULL((void*)0)) { | |||
| 584 | /* | |||
| 585 | * XXX: can PREDECESSOR be a child? Idle speculation | |||
| 586 | * would suggest it can: perhaps it's a state that | |||
| 587 | * hasn't yet emancipated, or the child from a must | |||
| 588 | * remain up connection. | |||
| 589 | */ | |||
| 590 | 		dbg("predecessor #%lu: %s SA; %s %s; %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("predecessor #%lu: %s SA; %s %s; %s", predecessor ->st_serialno, ((predecessor)->st_clonedfrom != 0) ? "CHILD" : "IKE", ((predecessor->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (predecessor->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA ) ? "established" : "establishing?", enum_enum_name(&sa_type_names , predecessor->st_ike_version, predecessor->st_establishing_sa ), predecessor->st_state->name); } }  | |||
| 591 | 		    predecessor->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("predecessor #%lu: %s SA; %s %s; %s", predecessor ->st_serialno, ((predecessor)->st_clonedfrom != 0) ? "CHILD" : "IKE", ((predecessor->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (predecessor->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA ) ? "established" : "establishing?", enum_enum_name(&sa_type_names , predecessor->st_ike_version, predecessor->st_establishing_sa ), predecessor->st_state->name); } }  | |||
| 592 | 		    IS_CHILD_SA(predecessor) ? "CHILD" : "IKE",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("predecessor #%lu: %s SA; %s %s; %s", predecessor ->st_serialno, ((predecessor)->st_clonedfrom != 0) ? "CHILD" : "IKE", ((predecessor->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (predecessor->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA ) ? "established" : "establishing?", enum_enum_name(&sa_type_names , predecessor->st_ike_version, predecessor->st_establishing_sa ), predecessor->st_state->name); } }  | |||
| 593 | 		    IS_V2_ESTABLISHED(predecessor->st_state) ? "established" : "establishing?",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("predecessor #%lu: %s SA; %s %s; %s", predecessor ->st_serialno, ((predecessor)->st_clonedfrom != 0) ? "CHILD" : "IKE", ((predecessor->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (predecessor->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA ) ? "established" : "establishing?", enum_enum_name(&sa_type_names , predecessor->st_ike_version, predecessor->st_establishing_sa ), predecessor->st_state->name); } }  | |||
| 594 | 		    enum_enum_name(&sa_type_names, predecessor->st_ike_version,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("predecessor #%lu: %s SA; %s %s; %s", predecessor ->st_serialno, ((predecessor)->st_clonedfrom != 0) ? "CHILD" : "IKE", ((predecessor->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (predecessor->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA ) ? "established" : "establishing?", enum_enum_name(&sa_type_names , predecessor->st_ike_version, predecessor->st_establishing_sa ), predecessor->st_state->name); } }  | |||
| 595 | 				   predecessor->st_establishing_sa),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("predecessor #%lu: %s SA; %s %s; %s", predecessor ->st_serialno, ((predecessor)->st_clonedfrom != 0) ? "CHILD" : "IKE", ((predecessor->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (predecessor->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA ) ? "established" : "establishing?", enum_enum_name(&sa_type_names , predecessor->st_ike_version, predecessor->st_establishing_sa ), predecessor->st_state->name); } }  | |||
| 596 | 		    predecessor->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("predecessor #%lu: %s SA; %s %s; %s", predecessor ->st_serialno, ((predecessor)->st_clonedfrom != 0) ? "CHILD" : "IKE", ((predecessor->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (predecessor->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA ) ? "established" : "establishing?", enum_enum_name(&sa_type_names , predecessor->st_ike_version, predecessor->st_establishing_sa ), predecessor->st_state->name); } };  | |||
| 597 | log_state(logger | (RC_NEW_V2_STATE + STATE_PARENT_I1), &ike->sa, | |||
| 598 | "initiating IKEv2 connection to replace #%lu", | |||
| 599 | predecessor->st_serialno); | |||
| 600 | 		if (IS_V2_ESTABLISHED(predecessor->st_state)((predecessor->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (predecessor->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA )) {  | |||
| 601 | if (IS_CHILD_SA(st)((st)->st_clonedfrom != 0)) | |||
| 602 | st->st_ipsec_pred = predecessor->st_serialno; | |||
| 603 | else | |||
| 604 | st->st_ike_pred = predecessor->st_serialno; | |||
| 605 | } | |||
| 606 | 		update_pending(ike_sa(predecessor, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 606}), pexpect_ike_sa(st));  | |||
| 607 | } else { | |||
| 608 | log_state(logger | (RC_NEW_V2_STATE + STATE_PARENT_I1), &ike->sa, | |||
| 609 | "initiating IKEv2 connection"); | |||
| 610 | } | |||
| 611 | ||||
| 612 | if (IS_LIBUNBOUND1 && id_ipseckey_allowed(st, IKEv2_AUTH_RESERVED)) { | |||
| 613 | stf_status ret = idr_ipseckey_fetch(st); | |||
| 614 | if (ret != STF_OK) { | |||
| 615 | 			reset_globals()log_reset_globals((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 615});  | |||
| 616 | return; | |||
| 617 | } | |||
| 618 | } | |||
| 619 | ||||
| 620 | /* | |||
| 621 | * Initialize st->st_oakley, including the group number. | |||
| 622 | * Grab the DH group from the first configured proposal and build KE. | |||
| 623 | */ | |||
| 624 | struct ikev2_proposals *ike_proposals = | |||
| 625 | get_v2_ike_proposals(c, "IKE SA initiator selecting KE", ike->sa.st_logger); | |||
| 626 | st->st_oakley.ta_dh = ikev2_proposals_first_dh(ike_proposals, ike->sa.st_logger); | |||
| 627 | if (st->st_oakley.ta_dh == NULL((void*)0)) { | |||
| 628 | libreswan_log("proposals do not contain a valid DH")loglog(RC_LOG, "proposals do not contain a valid DH"); | |||
| 629 | delete_state(st); /* pops state? */ | |||
| 630 | return; | |||
| 631 | } | |||
| 632 | ||||
| 633 | /* | |||
| 634 | * Calculate KE and Nonce. | |||
| 635 | */ | |||
| 636 | request_ke_and_nonce("ikev2_outI1 KE", st, | |||
| 637 | st->st_oakley.ta_dh, | |||
| 638 | ikev2_parent_outI1_continue); | |||
| 639 | statetime_stop(&start, "%s()", __func__); | |||
| 640 | 	reset_globals()log_reset_globals((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 640});  | |||
| 641 | } | |||
| 642 | ||||
| 643 | /* | |||
| 644 | * package up the calculated KE value, and emit it as a KE payload. | |||
| 645 | * used by IKEv2: parent, child (PFS) | |||
| 646 | */ | |||
| 647 | bool_Bool emit_v2KE(chunk_t *g, const struct dh_desc *group, | |||
| 648 | pb_stream *outs) | |||
| 649 | { | |||
| 650 | if (impair.ke_payload == IMPAIR_EMIT_OMIT) { | |||
| 651 | libreswan_log("IMPAIR: omitting KE payload")loglog(RC_LOG, "IMPAIR: omitting KE payload"); | |||
| 652 | return true1; | |||
| 653 | } | |||
| 654 | ||||
| 655 | pb_stream kepbs; | |||
| 656 | ||||
| 657 | struct ikev2_ke v2ke = { | |||
| 658 | .isak_group = group->common.id[IKEv2_ALG_ID], | |||
| 659 | }; | |||
| 660 | ||||
| 661 | if (!out_struct(&v2ke, &ikev2_ke_desc, outs, &kepbs)) | |||
| 662 | return FALSE0; | |||
| 663 | ||||
| 664 | if (impair.ke_payload >= IMPAIR_EMIT_ROOF) { | |||
| 665 | uint8_t byte = impair.ke_payload - IMPAIR_EMIT_ROOF; | |||
| 666 | log_message(RC_LOG, outs->out_logger, | |||
| 667 | "IMPAIR: sending bogus KE (g^x) == %u value to break DH calculations", byte); | |||
| 668 | /* Only used to test sending/receiving bogus g^x */ | |||
| 669 | diag_t d = pbs_out_repeated_byte(&kepbs, byte, g->len, "ikev2 impair KE (g^x) == 0"); | |||
| 670 | if (d != NULL((void*)0)) { | |||
| 671 | log_diag(RC_LOG_SERIOUS, outs->out_logger, &d, "%s", ""); | |||
| 672 | return false0; | |||
| 673 | } | |||
| 674 | } else if (impair.ke_payload == IMPAIR_EMIT_EMPTY) { | |||
| 675 | log_message(RC_LOG, outs->out_logger, "IMPAIR: sending an empty KE value"); | |||
| 676 | diag_t d = pbs_out_zero(&kepbs, 0, "ikev2 impair KE (g^x) == empty"); | |||
| 677 | if (d != NULL((void*)0)) { | |||
| 678 | log_diag(RC_LOG_SERIOUS, outs->out_logger, &d, "%s", ""); | |||
| 679 | return false0; | |||
| 680 | } | |||
| 681 | } else { | |||
| 682 | 		if (!pbs_out_hunk(*g, &kepbs, "ikev2 g^x")({ typeof(*g) hunk_ = *g; struct packet_byte_stream *outs_ = & kepbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_.len, ( "ikev2 g^x")); if (d_ != ((void*)0)) { log_diag(RC_LOG_SERIOUS , outs_->out_logger, &d_, "%s", ""); } d_ == ((void*)0 ); }))  | |||
| 683 | return FALSE0; | |||
| 684 | } | |||
| 685 | ||||
| 686 | close_output_pbs(&kepbs); | |||
| 687 | return TRUE1; | |||
| 688 | } | |||
| 689 | ||||
| 690 | void ikev2_parent_outI1_continue(struct state *st, struct msg_digest *unused_md, | |||
| 691 | struct pluto_crypto_req *r) | |||
| 692 | { | |||
| 693 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 694 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 695 | ||||
| 696 | 	pexpect(unused_md == NULL)({ _Bool assertion__ = unused_md == ((void*)0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 696}, "%s", "unused_md == NULL"); } assertion__; } );  | |||
| 697 | ||||
| 698 | struct ike_sa *ike = pexpect_ike_sa(st); | |||
| 699 |  	pexpect(ike->sa.st_sa_role == SA_INITIATOR)({ _Bool assertion__ = ike->sa.st_sa_role == SA_INITIATOR; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 699}, "%s", "ike->sa.st_sa_role == SA_INITIATOR" ); } assertion__; });  | |||
| 700 | ||||
| 701 | /* I1 is from INVALID KE */ | |||
| 702 | 	pexpect(st->st_state->kind == STATE_PARENT_I0 ||({ _Bool assertion__ = st->st_state->kind == STATE_PARENT_I0 || st->st_state->kind == STATE_PARENT_I1; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 703}, "%s", "st->st_state->kind == STATE_PARENT_I0 || st->st_state->kind == STATE_PARENT_I1" ); } assertion__; })  | |||
| 703 | 		st->st_state->kind == STATE_PARENT_I1)({ _Bool assertion__ = st->st_state->kind == STATE_PARENT_I0 || st->st_state->kind == STATE_PARENT_I1; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 703}, "%s", "st->st_state->kind == STATE_PARENT_I0 || st->st_state->kind == STATE_PARENT_I1" ); } assertion__; });  | |||
| 704 | ||||
| 705 | unpack_KE_from_helper(st, r, &st->st_gi); | |||
| 706 | unpack_nonce(&st->st_ni, r); | |||
| 707 | stf_status e = record_v2_IKE_SA_INIT_request(ike) ? STF_OK : STF_INTERNAL_ERROR; | |||
| 708 | complete_v2_state_transition(st, NULL((void*)0)/*initiator*/, e); | |||
| 709 | } | |||
| 710 | ||||
| 711 | bool_Bool record_v2_IKE_SA_INIT_request(struct ike_sa *ike) | |||
| 712 | { | |||
| 713 | struct connection *c = ike->sa.st_connection; | |||
| 714 | ||||
| 715 | /* set up reply */ | |||
| 716 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
| 717 | reply_buffer, sizeof(reply_buffer), | |||
| 718 | ike->sa.st_logger); | |||
| 719 | ||||
| 720 | if (impair.send_bogus_dcookie) { | |||
| 721 | /* add or mangle a dcookie so what we will send is bogus */ | |||
| 722 | DBG_log("Mangling dcookie because --impair-send-bogus-dcookie is set"); | |||
| 723 | free_chunk_content(&ike->sa.st_dcookie); | |||
| 724 | ike->sa.st_dcookie.ptr = alloc_bytes(1, "mangled dcookie"); | |||
| 725 | ike->sa.st_dcookie.len = 1; | |||
| 726 | messupn(ike->sa.st_dcookie.ptr, 1)memset((ike->sa.st_dcookie.ptr), 0xFB, (1)); | |||
| 727 | } | |||
| 728 | ||||
| 729 | /* HDR out */ | |||
| 730 | ||||
| 731 | pb_stream rbody = open_v2_message(&reply_stream, ike, NULL((void*)0) /* request */, | |||
| 732 | ISAKMP_v2_IKE_SA_INIT); | |||
| 733 | if (!pbs_ok(&rbody)((&rbody)->start != ((void*)0))) { | |||
| 734 | return false0; | |||
| 735 | } | |||
| 736 | ||||
| 737 | /* | |||
| 738 | * https://tools.ietf.org/html/rfc5996#section-2.6 | |||
| 739 | * reply with the anti DDOS cookie if we received one (remote is under attack) | |||
| 740 | */ | |||
| 741 | if (ike->sa.st_dcookie.ptr != NULL((void*)0)) { | |||
| 742 | /* In v2, for parent, protoid must be 0 and SPI must be empty */ | |||
| 743 | 		if (!emit_v2N_hunk(v2N_COOKIE, ike->sa.st_dcookie, &rbody)emit_v2N_bytes(v2N_COOKIE, (ike->sa.st_dcookie).ptr, (ike-> sa.st_dcookie).len, &rbody)) {  | |||
| 744 | return false0; | |||
| 745 | } | |||
| 746 | } | |||
| 747 | ||||
| 748 | /* SA out */ | |||
| 749 | ||||
| 750 | struct ikev2_proposals *ike_proposals = | |||
| 751 | get_v2_ike_proposals(c, "IKE SA initiator emitting local proposals", ike->sa.st_logger); | |||
| 752 | if (!ikev2_emit_sa_proposals(&rbody, ike_proposals, | |||
| 753 | (chunk_t*)NULL((void*)0) /* IKE - no CHILD SPI */)) { | |||
| 754 | return false0; | |||
| 755 | } | |||
| 756 | ||||
| 757 | /* ??? from here on, this looks a lot like the end of ikev2_parent_inI1outR1_tail */ | |||
| 758 | ||||
| 759 | /* send KE */ | |||
| 760 | if (!emit_v2KE(&ike->sa.st_gi, ike->sa.st_oakley.ta_dh, &rbody)) | |||
| 761 | return false0; | |||
| 762 | ||||
| 763 | /* send NONCE */ | |||
| 764 | { | |||
| 765 | pb_stream pb; | |||
| 766 | struct ikev2_generic in = { | |||
| 767 | .isag_critical = build_ikev2_critical(false0), | |||
| 768 | }; | |||
| 769 | ||||
| 770 | if (!out_struct(&in, &ikev2_nonce_desc, &rbody, &pb) || | |||
| 771 | 		    !pbs_out_hunk(ike->sa.st_ni, &pb, "IKEv2 nonce")({ typeof(ike->sa.st_ni) hunk_ = ike->sa.st_ni; struct packet_byte_stream *outs_ = &pb; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_ .len, ("IKEv2 nonce")); if (d_ != ((void*)0)) { log_diag(RC_LOG_SERIOUS , outs_->out_logger, &d_, "%s", ""); } d_ == ((void*)0 ); }))  | |||
| 772 | return false0; | |||
| 773 | ||||
| 774 | close_output_pbs(&pb); | |||
| 775 | } | |||
| 776 | ||||
| 777 | /* Send fragmentation support notification */ | |||
| 778 | if (c->policy & POLICY_IKE_FRAG_ALLOW((lset_t)1 << (POLICY_IKE_FRAG_ALLOW_IX))) { | |||
| 779 | if (!emit_v2N(v2N_IKEV2_FRAGMENTATION_SUPPORTED, &rbody)) | |||
| 780 | return false0; | |||
| 781 | } | |||
| 782 | ||||
| 783 | /* Send USE_PPK Notify payload */ | |||
| 784 | 	if (LIN(POLICY_PPK_ALLOW, c->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) {  | |||
| 785 | if (!emit_v2N(v2N_USE_PPK, &rbody)) | |||
| 786 | return false0; | |||
| 787 | } | |||
| 788 | ||||
| 789 | /* first check if this IKE_SA_INIT came from redirect | |||
| 790 | * instruction. | |||
| 791 | * - if yes, send the v2N_REDIRECTED_FROM | |||
| 792 | * with the identity of previous gateway | |||
| 793 | * - if not, check if we support redirect mechanism | |||
| 794 | * and send v2N_REDIRECT_SUPPORTED if we do | |||
| 795 | */ | |||
| 796 | if (address_is_specified(&c->temp_vars.redirect_ip)) { | |||
| 797 | if (!emit_redirected_from_notification(&c->temp_vars.old_gw_address, &rbody)) | |||
| 798 | return false0; | |||
| 799 | 	} else if (LIN(POLICY_ACCEPT_REDIRECT_YES, c->policy)(((((lset_t)1 << (POLICY_ACCEPT_REDIRECT_YES_IX))) & (c->policy)) == (((lset_t)1 << (POLICY_ACCEPT_REDIRECT_YES_IX ))))) {  | |||
| 800 | if (!emit_v2N(v2N_REDIRECT_SUPPORTED, &rbody)) | |||
| 801 | return false0; | |||
| 802 | } | |||
| 803 | ||||
| 804 | /* Send SIGNATURE_HASH_ALGORITHMS Notify payload */ | |||
| 805 | if (!impair.omit_hash_notify_request) { | |||
| 806 | if (((c->policy & POLICY_RSASIG((lset_t)1 << (POLICY_RSASIG_IX))) || (c->policy & POLICY_ECDSA((lset_t)1 << (POLICY_ECDSA_IX)))) | |||
| 807 | && (c->sighash_policy != LEMPTY((lset_t)0))) { | |||
| 808 | if (!emit_v2N_signature_hash_algorithms(c->sighash_policy, &rbody)) | |||
| 809 | return false0; | |||
| 810 | } | |||
| 811 | } else { | |||
| 812 | 		libreswan_log("Impair: Skipping the Signature hash notify in IKE_SA_INIT Request")loglog(RC_LOG, "Impair: Skipping the Signature hash notify in IKE_SA_INIT Request" );  | |||
| 813 | } | |||
| 814 | ||||
| 815 | /* Send NAT-T Notify payloads */ | |||
| 816 | if (!ikev2_out_nat_v2n(&rbody, &ike->sa, &zero_ike_spi/*responder unknown*/)) | |||
| 817 | return false0; | |||
| 818 | ||||
| 819 | /* From here on, only payloads left are Vendor IDs */ | |||
| 820 | if (c->send_vendorid) { | |||
| 821 | if (!emit_v2V(pluto_vendorid, &rbody)) | |||
| 822 | return false0; | |||
| 823 | } | |||
| 824 | ||||
| 825 | if (c->fake_strongswan) { | |||
| 826 | if (!emit_v2V("strongSwan", &rbody)) | |||
| 827 | return false0; | |||
| 828 | } | |||
| 829 | ||||
| 830 | if (c->policy & POLICY_AUTH_NULL((lset_t)1 << (POLICY_AUTH_NULL_IX))) { | |||
| 831 | if (!emit_v2V("Opportunistic IPsec", &rbody)) | |||
| 832 | return STF_INTERNAL_ERROR; | |||
| 833 | } | |||
| 834 | ||||
| 835 | close_output_pbs(&rbody); | |||
| 836 | close_output_pbs(&reply_stream); | |||
| 837 | ||||
| 838 | /* save packet for later signing */ | |||
| 839 | free_chunk_content(&ike->sa.st_firstpacket_me); | |||
| 840 | ike->sa.st_firstpacket_me = clone_out_pbs_as_chunk(&reply_stream, | |||
| 841 | "saved first packet"); | |||
| 842 | ||||
| 843 | /* Transmit */ | |||
| 844 | record_v2_message(ike, &reply_stream, "IKE_SA_INIT request", | |||
| 845 | MESSAGE_REQUEST); | |||
| 846 | return true1; | |||
| 847 | } | |||
| 848 | ||||
| 849 | /* | |||
| 850 | * | |||
| 851 | *************************************************************** | |||
| 852 | * PARENT_INI1 ***** | |||
| 853 | *************************************************************** | |||
| 854 | * - | |||
| 855 | * | |||
| 856 | * | |||
| 857 | */ | |||
| 858 | ||||
| 859 | /* no state: none I1 --> R1 | |||
| 860 | * <-- HDR, SAi1, KEi, Ni | |||
| 861 | * HDR, SAr1, KEr, Nr, [CERTREQ] --> | |||
| 862 | */ | |||
| 863 | ||||
| 864 | static crypto_req_cont_func ikev2_parent_inI1outR1_continue; /* forward decl and type assertion */ | |||
| 865 | static crypto_transition_fn ikev2_parent_inI1outR1_continue_tail; /* forward decl and type assertion */ | |||
| 866 | ||||
| 867 | stf_status ikev2_parent_inI1outR1(struct ike_sa *ike, | |||
| 868 | struct child_sa *child, | |||
| 869 | struct msg_digest *md) | |||
| 870 | { | |||
| 871 | 	pexpect(child == NULL)({ _Bool assertion__ = child == ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 871}, "%s", "child == NULL"); } assertion__; });  | |||
| 872 | struct connection *c = ike->sa.st_connection; | |||
| 873 | /* set up new state */ | |||
| 874 | update_ike_endpoints(ike, md); | |||
| 875 | 	passert(ike->sa.st_ike_version == IKEv2){ _Bool assertion__ = ike->sa.st_ike_version == IKEv2; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 875}, "%s", "ike->sa.st_ike_version == IKEv2" ); } };  | |||
| 876 | 	passert(ike->sa.st_state->kind == STATE_PARENT_R0){ _Bool assertion__ = ike->sa.st_state->kind == STATE_PARENT_R0 ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 876}, "%s", "ike->sa.st_state->kind == STATE_PARENT_R0" ); } };  | |||
| 877 | 	passert(ike->sa.st_sa_role == SA_RESPONDER){ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 877}, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } };  | |||
| 878 | /* set by caller */ | |||
| 879 | 	pexpect(md->svm == finite_states[STATE_PARENT_R0]->v2_transitions)({ _Bool assertion__ = md->svm == finite_states[STATE_PARENT_R0 ]->v2_transitions; if (!assertion__) { log_pexpect((where_t ) { .func = __func__, .basename = "ikev2_parent.c" , .line = 879 }, "%s", "md->svm == finite_states[STATE_PARENT_R0]->v2_transitions" ); } assertion__; });  | |||
| 880 | 	pexpect(md->svm->state == STATE_PARENT_R0)({ _Bool assertion__ = md->svm->state == STATE_PARENT_R0 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 880}, "%s", "md->svm->state == STATE_PARENT_R0" ); } assertion__; });  | |||
| 881 | ||||
| 882 | /* Vendor ID processing */ | |||
| 883 | for (struct payload_digest *v = md->chain[ISAKMP_NEXT_v2V]; v != NULL((void*)0); v = v->next) { | |||
| 884 | 		handle_vendorid(md, (char *)v->pbs.cur, pbs_left(&v->pbs)((size_t)((&v->pbs)->roof - (&v->pbs)->cur )), TRUE1);  | |||
| 885 | } | |||
| 886 | ||||
| 887 | /* Get the proposals ready. */ | |||
| 888 | struct ikev2_proposals *ike_proposals = | |||
| 889 | get_v2_ike_proposals(c, "IKE SA responder matching remote proposals", ike->sa.st_logger); | |||
| 890 | ||||
| 891 | /* | |||
| 892 | * Select the proposal. | |||
| 893 | */ | |||
| 894 | stf_status ret = ikev2_process_sa_payload("IKE responder", | |||
| 895 | &md->chain[ISAKMP_NEXT_v2SA]->pbs, | |||
| 896 | /*expect_ike*/ TRUE1, | |||
| 897 | /*expect_spi*/ FALSE0, | |||
| 898 | /*expect_accepted*/ FALSE0, | |||
| 899 | 						  LIN(POLICY_OPPORTUNISTIC, c->policy)(((((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))),  | |||
| 900 | &ike->sa.st_accepted_ike_proposal, | |||
| 901 | ike_proposals, ike->sa.st_logger); | |||
| 902 | if (ret != STF_OK) { | |||
| 903 | 		pexpect(ike->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 903}, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } assertion__; });  | |||
| 904 | 		pexpect(ret > STF_FAIL)({ _Bool assertion__ = ret > STF_FAIL; if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 904}, "%s", "ret > STF_FAIL"); } assertion__; } );  | |||
| 905 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 906 | ret - STF_FAIL, NULL((void*)0), | |||
| 907 | UNENCRYPTED_PAYLOAD); | |||
| 908 | return STF_FAIL; | |||
| 909 | } | |||
| 910 | ||||
| 911 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 912 | DBG_log_ikev2_proposal("accepted IKE proposal", | |||
| 913 | ike->sa.st_accepted_ike_proposal); | |||
| 914 | } | |||
| 915 | ||||
| 916 | /* | |||
| 917 | * Convert what was accepted to internal form and apply some | |||
| 918 | * basic validation. If this somehow fails (it shouldn't but | |||
| 919 | * ...), drop everything. | |||
| 920 | */ | |||
| 921 | if (!ikev2_proposal_to_trans_attrs(ike->sa.st_accepted_ike_proposal, | |||
| 922 | &ike->sa.st_oakley, ike->sa.st_logger)) { | |||
| 923 | loglog(RC_LOG_SERIOUS, "IKE responder accepted an unsupported algorithm"); | |||
| 924 | /* STF_INTERNAL_ERROR doesn't delete ST */ | |||
| 925 | return STF_FATAL; | |||
| 926 | } | |||
| 927 | ||||
| 928 | /* | |||
| 929 | * Check the MODP group in the payload matches the accepted | |||
| 930 | * proposal. | |||
| 931 | */ | |||
| 932 | if (!v2_accept_ke_for_proposal(ike, &ike->sa, md, | |||
| 933 | ike->sa.st_oakley.ta_dh, | |||
| 934 | UNENCRYPTED_PAYLOAD)) { | |||
| 935 | /* pexpect(reply-recorded) */ | |||
| 936 | return STF_FAIL; | |||
| 937 | } | |||
| 938 | ||||
| 939 | /* | |||
| 940 | * Check and read the KE contents. | |||
| 941 | */ | |||
| 942 | /* note: v1 notification! */ | |||
| 943 | if (!accept_KE(&ike->sa.st_gi, "Gi", ike->sa.st_oakley.ta_dh, | |||
| 944 | md->chain[ISAKMP_NEXT_v2KE])) { | |||
| 945 | send_v2N_response_from_md(md, v2N_INVALID_SYNTAX, NULL((void*)0)); | |||
| 946 | return STF_FATAL; | |||
| 947 | } | |||
| 948 | ||||
| 949 | /* extract results */ | |||
| 950 | ike->sa.st_seen_fragmentation_supported = md->pbs[PBS_v2N_IKEV2_FRAGMENTATION_SUPPORTED] != NULL((void*)0); | |||
| 951 | ike->sa.st_seen_ppk = md->pbs[PBS_v2N_USE_PPK] != NULL((void*)0); | |||
| 952 | ike->sa.st_seen_redirect_sup = (md->pbs[PBS_v2N_REDIRECTED_FROM] != NULL((void*)0) || | |||
| 953 | md->pbs[PBS_v2N_REDIRECT_SUPPORTED] != NULL((void*)0)); | |||
| 954 | ||||
| 955 | /* | |||
| 956 | * Responder: check v2N_NAT_DETECTION_DESTINATION_IP or/and | |||
| 957 | * v2N_NAT_DETECTION_SOURCE_IP. | |||
| 958 | * | |||
| 959 | * 2.23. NAT Traversal | |||
| 960 | * | |||
| 961 | * The IKE initiator MUST check the NAT_DETECTION_SOURCE_IP | |||
| 962 | * or NAT_DETECTION_DESTINATION_IP payloads if present, and | |||
| 963 | * if they do not match the addresses in the outer packet, | |||
| 964 | * MUST tunnel all future IKE and ESP packets associated | |||
| 965 | * with this IKE SA over UDP port 4500. | |||
| 966 | * | |||
| 967 | * Since this is the responder, there's really not much to do. | |||
| 968 | * It is the initiator that will switch to port 4500 (float | |||
| 969 | * away) when necessary. | |||
| 970 | */ | |||
| 971 | if (v2_nat_detected(ike, md)) { | |||
| 972 | 		dbg("NAT: responder so initiator gets to switch ports"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NAT: responder so initiator gets to switch ports" ); } };  | |||
| 973 | /* should this check that a port is available? */ | |||
| 974 | } | |||
| 975 | ||||
| 976 | if (md->pbs[PBS_v2N_SIGNATURE_HASH_ALGORITHMS] != NULL((void*)0)) { | |||
| 977 | if (impair.ignore_hash_notify_response) { | |||
| 978 | log_state(RC_LOG, &ike->sa, "IMPAIR: ignoring the hash notify in IKE_SA_INIT request"); | |||
| 979 | } else if (!negotiate_hash_algo_from_notification(md->pbs[PBS_v2N_SIGNATURE_HASH_ALGORITHMS], ike)) { | |||
| 980 | return STF_FATAL; | |||
| 981 | } | |||
| 982 | ike->sa.st_seen_hashnotify = true1; | |||
| 983 | } | |||
| 984 | ||||
| 985 | /* calculate the nonce and the KE */ | |||
| 986 | request_ke_and_nonce("ikev2_inI1outR1 KE", &ike->sa, | |||
| 987 | ike->sa.st_oakley.ta_dh, | |||
| 988 | ikev2_parent_inI1outR1_continue); | |||
| 989 | return STF_SUSPEND; | |||
| 990 | } | |||
| 991 | ||||
| 992 | static void ikev2_parent_inI1outR1_continue(struct state *st, | |||
| 993 | struct msg_digest *md, | |||
| 994 | struct pluto_crypto_req *r) | |||
| 995 | { | |||
| 996 | 	dbg("%s() for #%lu %s: calculated ke+nonce, sending R1",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: calculated ke+nonce, sending R1" , __func__, st->st_serialno, st->st_state->name); } }  | |||
| 997 | 	    __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: calculated ke+nonce, sending R1" , __func__, st->st_serialno, st->st_state->name); } };  | |||
| 998 | ||||
| 999 | 	pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 999}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */  | |||
| 1000 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 1000}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 1001 | ||||
| 1002 | struct ike_sa *ike = pexpect_ike_sa(st); | |||
| 1003 | 	pexpect(ike->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 1003}, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } assertion__; });  | |||
| 1004 | ||||
| 1005 | 	pexpect(st->st_state->kind == STATE_PARENT_R0)({ _Bool assertion__ = st->st_state->kind == STATE_PARENT_R0 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 1005}, "%s", "st->st_state->kind == STATE_PARENT_R0" ); } assertion__; });  | |||
| 1006 | ||||
| 1007 | /* | |||
| 1008 | * XXX: sanity check that this call does not screw around with | |||
| 1009 | * MD.ST (it isn't creating a child, and can return STF_FATAL | |||
| 1010 | * et.al.) | |||
| 1011 | */ | |||
| 1012 | md->st = st; | |||
| 1013 | ||||
| 1014 | stf_status e = ikev2_parent_inI1outR1_continue_tail(st, md, r); | |||
| 1015 | ||||
| 1016 | 	if (!pexpect(md->st == st)({ _Bool assertion__ = md->st == st; if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1016}, "%s", "md->st == st"); } assertion__; })) {  | |||
| 1017 | st = md->st; | |||
| 1018 | } | |||
| 1019 | complete_v2_state_transition(st, md, e); | |||
| 1020 | } | |||
| 1021 | ||||
| 1022 | /* | |||
| 1023 | * ikev2_parent_inI1outR1_tail: do what's left after all the crypto | |||
| 1024 | * | |||
| 1025 | * Called from: | |||
| 1026 | * ikev2_parent_inI1outR1: if KE and Nonce were already calculated | |||
| 1027 | * ikev2_parent_inI1outR1_continue: if they needed to be calculated | |||
| 1028 | */ | |||
| 1029 | static stf_status ikev2_parent_inI1outR1_continue_tail(struct state *st, | |||
| 1030 | struct msg_digest *md, | |||
| 1031 | struct pluto_crypto_req *r) | |||
| 1032 | { | |||
| 1033 | struct ike_sa *ike = pexpect_ike_sa(st); | |||
| 1034 | struct connection *c = st->st_connection; | |||
| 1035 | bool_Bool send_certreq = FALSE0; | |||
| 1036 | ||||
| 1037 | /* note that we don't update the state here yet */ | |||
| 1038 | ||||
| 1039 | /* | |||
| 1040 | * XXX: | |||
| 1041 | * | |||
| 1042 | * Should this code use clone_in_pbs_as_chunk() which uses | |||
| 1043 | * pbs_room() (.roof-.start)? The original code: | |||
| 1044 | * | |||
| 1045 | * clonetochunk(st->st_firstpacket_peer, md->message_pbs.start, | |||
| 1046 | * pbs_offset(&md->message_pbs), | |||
| 1047 | * "saved first received packet"); | |||
| 1048 | * | |||
| 1049 | * and clone_out_pbs_as_chunk() both use pbs_offset() | |||
| 1050 | * (.cur-.start). | |||
| 1051 | * | |||
| 1052 | * Suspect it doesn't matter as the code initializing | |||
| 1053 | * .message_pbs forces .roof==.cur - look for the comment | |||
| 1054 | * "trim padding (not actually legit)". | |||
| 1055 | */ | |||
| 1056 | /* record first packet for later checking of signature */ | |||
| 1057 | st->st_firstpacket_peer = clone_out_pbs_as_chunk(&md->message_pbs, | |||
| 1058 | "saved first received packet"); | |||
| 1059 | ||||
| 1060 | /* make sure HDR is at start of a clean buffer */ | |||
| 1061 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
| 1062 | reply_buffer, sizeof(reply_buffer), | |||
| 1063 | ike->sa.st_logger); | |||
| 1064 | ||||
| 1065 | /* HDR out */ | |||
| 1066 | 	pb_stream rbody = open_v2_message(&reply_stream, ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 1066}),  | |||
| 1067 | md /* response */, | |||
| 1068 | ISAKMP_v2_IKE_SA_INIT); | |||
| 1069 | if (!pbs_ok(&rbody)((&rbody)->start != ((void*)0))) { | |||
| 1070 | return STF_INTERNAL_ERROR; | |||
| 1071 | } | |||
| 1072 | ||||
| 1073 | /* start of SA out */ | |||
| 1074 | { | |||
| 1075 | /* | |||
| 1076 | * Since this is the initial IKE exchange, the SPI is | |||
| 1077 | * emitted as part of the packet header and not as | |||
| 1078 | * part of the proposal. Hence the NULL SPI. | |||
| 1079 | */ | |||
| 1080 | 		passert(st->st_accepted_ike_proposal != NULL){ _Bool assertion__ = st->st_accepted_ike_proposal != ((void *)0); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1080}, "%s" , "st->st_accepted_ike_proposal != NULL"); } };  | |||
| 1081 | if (!ikev2_emit_sa_proposal(&rbody, st->st_accepted_ike_proposal, NULL((void*)0))) { | |||
| 1082 | 			dbg("problem emitting accepted proposal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("problem emitting accepted proposal"); } };  | |||
| 1083 | return STF_INTERNAL_ERROR; | |||
| 1084 | } | |||
| 1085 | } | |||
| 1086 | ||||
| 1087 | /* Ni in */ | |||
| 1088 | if (!accept_v2_nonce(st->st_logger, md, &st->st_ni, "Ni")) { | |||
| 1089 | /* | |||
| 1090 | * Presumably not our fault. Syntax errors kill the | |||
| 1091 | * family, hence FATAL. | |||
| 1092 | */ | |||
| 1093 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 1094 | v2N_INVALID_SYNTAX, NULL((void*)0)/*no-data*/, | |||
| 1095 | UNENCRYPTED_PAYLOAD); | |||
| 1096 | return STF_FATAL; | |||
| 1097 | } | |||
| 1098 | ||||
| 1099 | /* ??? from here on, this looks a lot like the end of ikev2_parent_outI1_common */ | |||
| 1100 | ||||
| 1101 | /* | |||
| 1102 | * Unpack and send KE | |||
| 1103 | * | |||
| 1104 | * Pass the crypto helper's oakley group so that it is | |||
| 1105 | * consistent with what was unpacked. | |||
| 1106 | * | |||
| 1107 | * IKEv2 code (arguably, incorrectly) uses st_oakley.ta_dh to | |||
| 1108 | * track the most recent KE sent out. It should instead be | |||
| 1109 | * maintaining a list of KEs sent out (so that they can be | |||
| 1110 | * reused should the initial responder flip-flop) and only set | |||
| 1111 | * st_oakley.ta_dh once the proposal has been accepted. | |||
| 1112 | */ | |||
| 1113 | 	pexpect(st->st_oakley.ta_dh == r->pcr_d.kn.group)({ _Bool assertion__ = st->st_oakley.ta_dh == r->pcr_d. kn.group; if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1113}, "%s" , "st->st_oakley.ta_dh == r->pcr_d.kn.group"); } assertion__ ; });  | |||
| 1114 | unpack_KE_from_helper(st, r, &st->st_gr); | |||
| 1115 | if (!emit_v2KE(&st->st_gr, r->pcr_d.kn.group, &rbody)) { | |||
| 1116 | return STF_INTERNAL_ERROR; | |||
| 1117 | } | |||
| 1118 | ||||
| 1119 | /* send NONCE */ | |||
| 1120 | unpack_nonce(&st->st_nr, r); | |||
| 1121 | { | |||
| 1122 | pb_stream pb; | |||
| 1123 | struct ikev2_generic in = { | |||
| 1124 | .isag_critical = build_ikev2_critical(false0), | |||
| 1125 | }; | |||
| 1126 | ||||
| 1127 | if (!out_struct(&in, &ikev2_nonce_desc, &rbody, &pb) || | |||
| 1128 | 		    !pbs_out_hunk(st->st_nr, &pb, "IKEv2 nonce")({ typeof(st->st_nr) hunk_ = st->st_nr; struct packet_byte_stream *outs_ = &pb; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr, hunk_ .len, ("IKEv2 nonce")); if (d_ != ((void*)0)) { log_diag(RC_LOG_SERIOUS , outs_->out_logger, &d_, "%s", ""); } d_ == ((void*)0 ); }))  | |||
| 1129 | return STF_INTERNAL_ERROR; | |||
| 1130 | ||||
| 1131 | close_output_pbs(&pb); | |||
| 1132 | } | |||
| 1133 | ||||
| 1134 | /* decide to send a CERTREQ - for RSASIG or GSSAPI */ | |||
| 1135 | send_certreq = (((c->policy & POLICY_RSASIG((lset_t)1 << (POLICY_RSASIG_IX))) && | |||
| 1136 | !has_preloaded_public_key(st)) | |||
| 1137 | ); | |||
| 1138 | ||||
| 1139 | /* Send fragmentation support notification */ | |||
| 1140 | if (c->policy & POLICY_IKE_FRAG_ALLOW((lset_t)1 << (POLICY_IKE_FRAG_ALLOW_IX))) { | |||
| 1141 | if (!emit_v2N(v2N_IKEV2_FRAGMENTATION_SUPPORTED, &rbody)) | |||
| 1142 | return STF_INTERNAL_ERROR; | |||
| 1143 | } | |||
| 1144 | ||||
| 1145 | /* Send USE_PPK Notify payload */ | |||
| 1146 | if (st->st_seen_ppk) { | |||
| 1147 | if (!emit_v2N(v2N_USE_PPK, &rbody)) | |||
| 1148 | return STF_INTERNAL_ERROR; | |||
| 1149 | } | |||
| 1150 | ||||
| 1151 | /* Send SIGNATURE_HASH_ALGORITHMS notification only if we received one */ | |||
| 1152 | if (!impair.ignore_hash_notify_request) { | |||
| 1153 | if (st->st_seen_hashnotify && ((c->policy & POLICY_RSASIG((lset_t)1 << (POLICY_RSASIG_IX))) || (c->policy & POLICY_ECDSA((lset_t)1 << (POLICY_ECDSA_IX)))) | |||
| 1154 | && (c->sighash_policy != LEMPTY((lset_t)0))) { | |||
| 1155 | if (!emit_v2N_signature_hash_algorithms(c->sighash_policy, &rbody)) | |||
| 1156 | return STF_INTERNAL_ERROR; | |||
| 1157 | } | |||
| 1158 | } else { | |||
| 1159 | 		libreswan_log("Impair: Not sending out signature hash notify")loglog(RC_LOG, "Impair: Not sending out signature hash notify" );  | |||
| 1160 | } | |||
| 1161 | ||||
| 1162 | /* Send NAT-T Notify payloads */ | |||
| 1163 | if (!ikev2_out_nat_v2n(&rbody, st, &st->st_ike_spis.responder)) { | |||
| 1164 | return STF_INTERNAL_ERROR; | |||
| 1165 | } | |||
| 1166 | ||||
| 1167 | /* something the other end won't like */ | |||
| 1168 | ||||
| 1169 | /* send CERTREQ */ | |||
| 1170 | if (send_certreq) { | |||
| 1171 | 		dbg("going to send a certreq"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("going to send a certreq"); } };  | |||
| 1172 | ikev2_send_certreq(st, md, &rbody); | |||
| 1173 | } | |||
| 1174 | ||||
| 1175 | if (c->send_vendorid) { | |||
| 1176 | if (!emit_v2V(pluto_vendorid, &rbody)) | |||
| 1177 | return STF_INTERNAL_ERROR; | |||
| 1178 | } | |||
| 1179 | ||||
| 1180 | if (c->fake_strongswan) { | |||
| 1181 | if (!emit_v2V("strongSwan", &rbody)) | |||
| 1182 | return STF_INTERNAL_ERROR; | |||
| 1183 | } | |||
| 1184 | ||||
| 1185 | if (c->policy & POLICY_AUTH_NULL((lset_t)1 << (POLICY_AUTH_NULL_IX))) { | |||
| 1186 | if (!emit_v2V("Opportunistic IPsec", &rbody)) | |||
| 1187 | return STF_INTERNAL_ERROR; | |||
| 1188 | } | |||
| 1189 | ||||
| 1190 | close_output_pbs(&rbody); | |||
| 1191 | close_output_pbs(&reply_stream); | |||
| 1192 | ||||
| 1193 | record_v2_message(ike, &reply_stream, | |||
| 1194 | "reply packet for ikev2_parent_inI1outR1_tail", | |||
| 1195 | MESSAGE_RESPONSE); | |||
| 1196 | ||||
| 1197 | /* save packet for later signing */ | |||
| 1198 | free_chunk_content(&st->st_firstpacket_me); | |||
| 1199 | st->st_firstpacket_me = clone_out_pbs_as_chunk(&reply_stream, | |||
| 1200 | "saved first packet"); | |||
| 1201 | ||||
| 1202 | /* note: retransmission is driven by initiator, not us */ | |||
| 1203 | ||||
| 1204 | return STF_OK; | |||
| 1205 | } | |||
| 1206 | ||||
| 1207 | /* | |||
| 1208 | * | |||
| 1209 | *************************************************************** | |||
| 1210 | * PARENT_inR1 ***** | |||
| 1211 | *************************************************************** | |||
| 1212 | * - | |||
| 1213 | * | |||
| 1214 | * | |||
| 1215 | */ | |||
| 1216 | /* STATE_PARENT_I1: R1B --> I1B | |||
| 1217 | * <-- HDR, N | |||
| 1218 | * HDR, N(COOKIE), SAi1, KEi, Ni --> | |||
| 1219 | */ | |||
| 1220 | ||||
| 1221 | static stf_status rerequest_ke_and_nonce(struct ike_sa *ike) | |||
| 1222 | { | |||
| 1223 | request_ke_and_nonce("rekey outI", &ike->sa, | |||
| 1224 | ike->sa.st_oakley.ta_dh, | |||
| 1225 | ikev2_parent_outI1_continue); | |||
| 1226 | return STF_SUSPEND; | |||
| 1227 | } | |||
| 1228 | ||||
| 1229 | stf_status process_IKE_SA_INIT_v2N_INVALID_KE_PAYLOAD_response(struct ike_sa *ike, | |||
| 1230 | struct child_sa *child, | |||
| 1231 | struct msg_digest *md) | |||
| 1232 | { | |||
| 1233 | struct connection *c = ike->sa.st_connection; | |||
| 1234 | ||||
| 1235 | 	pexpect(child == NULL)({ _Bool assertion__ = child == ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1235}, "%s", "child == NULL"); } assertion__; });  | |||
| 1236 | 	if (!pexpect(md->pbs[PBS_v2N_INVALID_KE_PAYLOAD] != NULL)({ _Bool assertion__ = md->pbs[PBS_v2N_INVALID_KE_PAYLOAD] != ((void*)0); if (!assertion__) { log_pexpect((where_t) { . func = __func__, .basename = "ikev2_parent.c" , .line = 1236} , "%s", "md->pbs[PBS_v2N_INVALID_KE_PAYLOAD] != NULL"); } assertion__ ; })) {  | |||
| 1237 | return STF_INTERNAL_ERROR; | |||
| 1238 | } | |||
| 1239 | struct pbs_inpacket_byte_stream invalid_ke_pbs = *md->pbs[PBS_v2N_INVALID_KE_PAYLOAD]; | |||
| 1240 | ||||
| 1241 | /* careful of DDOS, only log with debugging on? */ | |||
| 1242 | /* we treat this as a "retransmit" event to rate limit these */ | |||
| 1243 | if (!count_duplicate(&ike->sa, MAXIMUM_INVALID_KE_RETRANS3)) { | |||
| 1244 | 		dbg("ignoring received INVALID_KE packets - received too many (DoS?)"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring received INVALID_KE packets - received too many (DoS?)" ); } };  | |||
| 1245 | return STF_IGNORE; | |||
| 1246 | } | |||
| 1247 | ||||
| 1248 | /* | |||
| 1249 | * There's at least this notify payload, is there more than | |||
| 1250 | * one? | |||
| 1251 | */ | |||
| 1252 | if (md->chain[ISAKMP_NEXT_v2N]->next != NULL((void*)0)) { | |||
| 1253 | 		dbg("ignoring other notify payloads"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring other notify payloads"); } };  | |||
| 1254 | } | |||
| 1255 | ||||
| 1256 | struct suggested_group sg; | |||
| 1257 | if (!in_struct(&sg, &suggested_group_desc, &invalid_ke_pbs, NULL((void*)0))) { | |||
| 1258 | /* already logged */ | |||
| 1259 | return STF_IGNORE; | |||
| 1260 | } | |||
| 1261 | ||||
| 1262 | 	pstats(invalidke_recv_s, sg.sg_group){ const unsigned __pstat = (sg.sg_group); if (__pstat < (sizeof (pstats_invalidke_recv_s) / sizeof(*(pstats_invalidke_recv_s) ))) { pstats_invalidke_recv_s[__pstat]++; } else if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { DBG_log("pstats %s %d" , "invalidke_recv_s", __pstat); } };  | |||
| 1263 | 	pstats(invalidke_recv_u, ike->sa.st_oakley.ta_dh->group){ const unsigned __pstat = (ike->sa.st_oakley.ta_dh->group ); if (__pstat < (sizeof(pstats_invalidke_recv_u) / sizeof (*(pstats_invalidke_recv_u)))) { pstats_invalidke_recv_u[__pstat ]++; } else if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX ))))) { DBG_log("pstats %s %d", "invalidke_recv_u", __pstat); } };  | |||
| 1264 | ||||
| 1265 | struct ikev2_proposals *ike_proposals = | |||
| 1266 | get_v2_ike_proposals(c, "IKE SA initiator validating remote's suggested KE", ike->sa.st_logger); | |||
| 1267 | if (!ikev2_proposals_include_modp(ike_proposals, sg.sg_group)) { | |||
| 1268 | struct esb_buf esb; | |||
| 1269 | log_state(RC_LOG, &ike->sa, | |||
| 1270 | "Discarding unauthenticated INVALID_KE_PAYLOAD response to DH %s; suggested DH %s is not acceptable", | |||
| 1271 | ike->sa.st_oakley.ta_dh->common.fqn, | |||
| 1272 | enum_show_shortb(&oakley_group_names, | |||
| 1273 | sg.sg_group, &esb)); | |||
| 1274 | return STF_IGNORE; | |||
| 1275 | } | |||
| 1276 | ||||
| 1277 | 	dbg("Suggested modp group is acceptable"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Suggested modp group is acceptable"); } };  | |||
| 1278 | /* | |||
| 1279 | * Since there must be a group object for every local | |||
| 1280 | * proposal, and sg.sg_group matches one of the local proposal | |||
| 1281 | * groups, a lookup of sg.sg_group must succeed. | |||
| 1282 | */ | |||
| 1283 | const struct dh_desc *new_group = ikev2_get_dh_desc(sg.sg_group); | |||
| 1284 | 	passert(new_group != NULL){ _Bool assertion__ = new_group != ((void*)0); if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1284}, "%s", "new_group != NULL") ; } };  | |||
| 1285 | log_state(RC_LOG, &ike->sa, | |||
| 1286 | "Received unauthenticated INVALID_KE_PAYLOAD response to DH %s; resending with suggested DH %s", | |||
| 1287 | ike->sa.st_oakley.ta_dh->common.fqn, | |||
| 1288 | new_group->common.fqn); | |||
| 1289 | ike->sa.st_oakley.ta_dh = new_group; | |||
| 1290 | /* wipe our mismatched KE */ | |||
| 1291 | free_dh_secret(&ike->sa.st_dh_secret); | |||
| 1292 | /* | |||
| 1293 | * get a new KE | |||
| 1294 | */ | |||
| 1295 | schedule_reinitiate_v2_ike_sa_init(ike, rerequest_ke_and_nonce); | |||
| 1296 | return STF_OK; | |||
| 1297 | } | |||
| 1298 | ||||
| 1299 | stf_status ikev2_auth_initiator_process_failure_notification(struct ike_sa *ike, | |||
| 1300 | struct child_sa *child, | |||
| 1301 | struct msg_digest *md) | |||
| 1302 | { | |||
| 1303 | /* | |||
| 1304 | * XXX: ST here should be the IKE SA. The state machine, | |||
| 1305 | * however, directs the AUTH response to the CHILD! | |||
| 1306 | */ | |||
| 1307 | 	pexpect(child != NULL)({ _Bool assertion__ = child != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1307}, "%s", "child != NULL"); } assertion__; });  | |||
| 1308 | struct state *st = &child->sa; | |||
| 1309 | ||||
| 1310 | v2_notification_t n = md->svm->encrypted_payloads.notification; | |||
| 1311 | 	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 ]++; } };  | |||
| 1312 | /* | |||
| 1313 | * Always log the notification error and fail; | |||
| 1314 | * but do it in slightly different ways so it | |||
| 1315 | * is possible to figure out which code path | |||
| 1316 | * was taken. | |||
| 1317 | */ | |||
| 1318 | log_state(RC_LOG, &ike->sa, "IKE SA authentication request rejected by peer: %s", | |||
| 1319 | enum_short_name(&ikev2_notify_names, n)); | |||
| 1320 | ||||
| 1321 | /* | |||
| 1322 | * XXX: ST here should be the IKE SA. The state machine, | |||
| 1323 | * however, directs the AUTH response to the CHILD! Find the | |||
| 1324 | * IKE SA and mark it as failing. | |||
| 1325 | */ | |||
| 1326 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 1327 | ||||
| 1328 | /* | |||
| 1329 | * 2.21.2. Error Handling in IKE_AUTH | |||
| 1330 | * | |||
| 1331 | * ... If the error occurred on the responder, the | |||
| 1332 | * notification is returned in the protected response, and is usually | |||
| 1333 | * the only payload in that response. Although the IKE_AUTH messages | |||
| 1334 | * are encrypted and integrity protected, if the peer receiving this | |||
| 1335 | * notification has not authenticated the other end yet, that peer needs | |||
| 1336 | * to treat the information with caution. | |||
| 1337 | * | |||
| 1338 | * So assume MITM and schedule a retry. | |||
| 1339 | */ | |||
| 1340 | if (ikev2_schedule_retry(st)) { | |||
| 1341 | return STF_IGNORE; /* drop packet */ | |||
| 1342 | } else { | |||
| 1343 | return STF_FATAL; | |||
| 1344 | } | |||
| 1345 | } | |||
| 1346 | ||||
| 1347 | stf_status ikev2_auth_initiator_process_unknown_notification(struct ike_sa *unused_ike UNUSED__attribute__ ((unused)), | |||
| 1348 | struct child_sa *child, | |||
| 1349 | struct msg_digest *md) | |||
| 1350 | { | |||
| 1351 | /* | |||
| 1352 | * XXX: ST here should be the IKE SA. The state machine, | |||
| 1353 | * however, directs the AUTH response to the CHILD! | |||
| 1354 | */ | |||
| 1355 | 	pexpect(child != NULL)({ _Bool assertion__ = child != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1355}, "%s", "child != NULL"); } assertion__; });  | |||
| 1356 | struct state *st = &child->sa; | |||
| 1357 | ||||
| 1358 | /* | |||
| 1359 | * 3.10.1. Notify Message Types: | |||
| 1360 | * | |||
| 1361 | * Types in the range 0 - 16383 are intended for reporting errors. An | |||
| 1362 | * implementation receiving a Notify payload with one of these types | |||
| 1363 | * that it does not recognize in a response MUST assume that the | |||
| 1364 | * corresponding request has failed entirely. Unrecognized error types | |||
| 1365 | * in a request and status types in a request or response MUST be | |||
| 1366 | * ignored, and they should be logged. | |||
| 1367 | */ | |||
| 1368 | ||||
| 1369 | bool_Bool ignore = true1; | |||
| 1370 | for (struct payload_digest *ntfy = md->chain[ISAKMP_NEXT_v2N]; ntfy != NULL((void*)0); ntfy = ntfy->next) { | |||
| 1371 | v2_notification_t n = ntfy->payload.v2n.isan_type; | |||
| 1372 | const char *name = enum_short_name(&ikev2_notify_names, n); | |||
| 1373 | ||||
| 1374 | if (ntfy->payload.v2n.isan_spisize != 0) { | |||
| 1375 | /* invalid-syntax, but can't do anything about it */ | |||
| 1376 | 			libreswan_log("received an encrypted %s notification with an unexpected non-empty SPI; deleting IKE SA",loglog(RC_LOG, "received an encrypted %s notification with an unexpected non-empty SPI; deleting IKE SA" , name)  | |||
| 1377 | 				 name)loglog(RC_LOG, "received an encrypted %s notification with an unexpected non-empty SPI; deleting IKE SA" , name);  | |||
| 1378 | return STF_FATAL; | |||
| 1379 | } | |||
| 1380 | ||||
| 1381 | if (n >= v2N_STATUS_FLOOR) { | |||
| 1382 | /* just log */ | |||
| 1383 | 			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 ]++; } };  | |||
| 1384 | if (name == NULL((void*)0)) { | |||
| 1385 | 				libreswan_log("IKE_AUTH response contained an unknown status notification (%d)", n)loglog(RC_LOG, "IKE_AUTH response contained an unknown status notification (%d)" , n);  | |||
| 1386 | } else { | |||
| 1387 | 				libreswan_log("IKE_AUTH response contained the status notification %s", name)loglog(RC_LOG, "IKE_AUTH response contained the status notification %s" , name);  | |||
| 1388 | } | |||
| 1389 | } else { | |||
| 1390 | 			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 ]++; } };  | |||
| 1391 | ignore = false0; | |||
| 1392 | if (name == NULL((void*)0)) { | |||
| 1393 | 				libreswan_log("IKE_AUTH response contained an unknown error notification (%d)", n)loglog(RC_LOG, "IKE_AUTH response contained an unknown error notification (%d)" , n);  | |||
| 1394 | } else { | |||
| 1395 | 				libreswan_log("IKE_AUTH response contained the error notification %s", name)loglog(RC_LOG, "IKE_AUTH response contained the error notification %s" , name);  | |||
| 1396 | /* | |||
| 1397 | * There won't be a child state transition, so log if error is child related. | |||
| 1398 | * see RFC 7296 Section 1.2 | |||
| 1399 | */ | |||
| 1400 | switch(n) { | |||
| 1401 | case v2N_NO_PROPOSAL_CHOSEN: | |||
| 1402 | case v2N_SINGLE_PAIR_REQUIRED: | |||
| 1403 | case v2N_NO_ADDITIONAL_SAS: | |||
| 1404 | case v2N_INTERNAL_ADDRESS_FAILURE: | |||
| 1405 | case v2N_FAILED_CP_REQUIRED: | |||
| 1406 | case v2N_TS_UNACCEPTABLE: | |||
| 1407 | case v2N_INVALID_SELECTORS: | |||
| 1408 | /* fallthrough */ | |||
| 1409 | linux_audit_conn(st, LAK_CHILD_FAIL); | |||
| 1410 | break; | |||
| 1411 | default: | |||
| 1412 | break; | |||
| 1413 | } | |||
| 1414 | } | |||
| 1415 | } | |||
| 1416 | } | |||
| 1417 | if (ignore) { | |||
| 1418 | return STF_IGNORE; | |||
| 1419 | } | |||
| 1420 | /* | |||
| 1421 | * 2.21.2. Error Handling in IKE_AUTH | |||
| 1422 | * | |||
| 1423 | * ... If the error occurred on the responder, the | |||
| 1424 | * notification is returned in the protected response, and is usually | |||
| 1425 | * the only payload in that response. Although the IKE_AUTH messages | |||
| 1426 | * are encrypted and integrity protected, if the peer receiving this | |||
| 1427 | * notification has not authenticated the other end yet, that peer needs | |||
| 1428 | * to treat the information with caution. | |||
| 1429 | * | |||
| 1430 | * So assume MITM and schedule a retry. | |||
| 1431 | */ | |||
| 1432 | if (ikev2_schedule_retry(st)) { | |||
| 1433 | return STF_IGNORE; /* drop packet */ | |||
| 1434 | } else { | |||
| 1435 | return STF_FATAL; | |||
| 1436 | } | |||
| 1437 | } | |||
| 1438 | ||||
| 1439 | /* STATE_PARENT_I1: R1 --> I2 | |||
| 1440 | * <-- HDR, SAr1, KEr, Nr, [CERTREQ] | |||
| 1441 | * HDR, SK {IDi, [CERT,] [CERTREQ,] | |||
| 1442 | * [IDr,] AUTH, SAi2, | |||
| 1443 | * TSi, TSr} --> | |||
| 1444 | */ | |||
| 1445 | ||||
| 1446 | static crypto_req_cont_func ikev2_parent_inR1outI2_continue; /* forward decl and type assertion */ | |||
| 1447 | static crypto_transition_fn ikev2_parent_inR1outI2_tail; /* forward decl and type assertion */ | |||
| 1448 | ||||
| 1449 | stf_status ikev2_parent_inR1outI2(struct ike_sa *ike, | |||
| 1450 | struct child_sa *unused_child UNUSED__attribute__ ((unused)), | |||
| 1451 | struct msg_digest *md) | |||
| 1452 | { | |||
| 1453 | struct state *st = &ike->sa; | |||
| 1454 | struct connection *c = st->st_connection; | |||
| 1455 | ||||
| 1456 | /* for testing only */ | |||
| 1457 | if (impair.send_no_ikev2_auth) { | |||
| 1458 | 		libreswan_log(loglog(RC_LOG, "IMPAIR_SEND_NO_IKEV2_AUTH set - not sending IKE_AUTH packet" )  | |||
| 1459 | 			"IMPAIR_SEND_NO_IKEV2_AUTH set - not sending IKE_AUTH packet")loglog(RC_LOG, "IMPAIR_SEND_NO_IKEV2_AUTH set - not sending IKE_AUTH packet" );  | |||
| 1460 | return STF_IGNORE; | |||
| 1461 | } | |||
| 1462 | ||||
| 1463 | /* | |||
| 1464 | * if this connection has a newer Child SA than this state | |||
| 1465 | * this negotiation is not relevant any more. would this | |||
| 1466 | * cover if there are multiple CREATE_CHILD_SA pending on this | |||
| 1467 | * IKE negotiation ??? | |||
| 1468 | * | |||
| 1469 | * XXX: this is testing for an IKE SA that's been superseed by | |||
| 1470 | * a newer IKE SA (not child). Suspect this is to handle a | |||
| 1471 | * race where the other end brings up the IKE SA first? For | |||
| 1472 | * that case, shouldn't this state have been deleted? | |||
| 1473 | */ | |||
| 1474 | if (c->newest_ipsec_sa > st->st_serialno) { | |||
| 1475 | 		libreswan_log("state superseded by #%lu try=%lu, drop this negotiation",loglog(RC_LOG, "state superseded by #%lu try=%lu, drop this negotiation" , c->newest_ipsec_sa, st->st_try)  | |||
| 1476 | 			      c->newest_ipsec_sa, st->st_try)loglog(RC_LOG, "state superseded by #%lu try=%lu, drop this negotiation" , c->newest_ipsec_sa, st->st_try);  | |||
| 1477 | return STF_FATAL; | |||
| 1478 | } | |||
| 1479 | ||||
| 1480 | /* | |||
| 1481 | * XXX: this iteration over the notifies modifies state | |||
| 1482 | * _before_ the code's committed to creating an SA. Hack this | |||
| 1483 | * by resetting any flags that might be set. | |||
| 1484 | */ | |||
| 1485 | ike->sa.st_seen_fragmentation_supported = false0; | |||
| 1486 | ike->sa.st_seen_ppk = false0; | |||
| 1487 | ||||
| 1488 | ike->sa.st_seen_fragmentation_supported = md->pbs[PBS_v2N_IKEV2_FRAGMENTATION_SUPPORTED] != NULL((void*)0); | |||
| 1489 | ike->sa.st_seen_ppk = md->pbs[PBS_v2N_USE_PPK] != NULL((void*)0); | |||
| 1490 | if (md->pbs[PBS_v2N_SIGNATURE_HASH_ALGORITHMS] != NULL((void*)0)) { | |||
| 1491 | if (impair.ignore_hash_notify_request) { | |||
| 1492 | log_state(RC_LOG, &ike->sa, | |||
| 1493 | "IMPAIR: ignoring the Signature hash notify in IKE_SA_INIT response"); | |||
| 1494 | } else if (!negotiate_hash_algo_from_notification(md->pbs[PBS_v2N_SIGNATURE_HASH_ALGORITHMS], ike)) { | |||
| 1495 | return STF_FATAL; | |||
| 1496 | } | |||
| 1497 | ike->sa.st_seen_hashnotify = true1; | |||
| 1498 | } | |||
| 1499 | ||||
| 1500 | /* | |||
| 1501 | * the responder sent us back KE, Gr, Nr, and it's our time to calculate | |||
| 1502 | * the shared key values. | |||
| 1503 | */ | |||
| 1504 | ||||
| 1505 | 	dbg("ikev2 parent inR1: calculating g^{xy} in order to send I2"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ikev2 parent inR1: calculating g^{xy} in order to send I2" ); } };  | |||
| 1506 | ||||
| 1507 | /* KE in */ | |||
| 1508 | if (!accept_KE(&st->st_gr, "Gr", st->st_oakley.ta_dh, | |||
| 1509 | md->chain[ISAKMP_NEXT_v2KE])) { | |||
| 1510 | /* | |||
| 1511 | * XXX: Initiator - so this code will not trigger a | |||
| 1512 | * notify. Since packet isn't trusted, should it be | |||
| 1513 | * ignored? | |||
| 1514 | */ | |||
| 1515 | return STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 1516 | } | |||
| 1517 | ||||
| 1518 | /* Ni in */ | |||
| 1519 | if (!accept_v2_nonce(st->st_logger, md, &st->st_nr, "Nr")) { | |||
| 1520 | /* | |||
| 1521 | * Presumably not our fault. Syntax errors in a | |||
| 1522 | * response kill the family (and trigger no further | |||
| 1523 | * exchange). | |||
| 1524 | */ | |||
| 1525 | return STF_FATAL; | |||
| 1526 | } | |||
| 1527 | ||||
| 1528 | /* We're missing processing a CERTREQ in here */ | |||
| 1529 | ||||
| 1530 | /* process and confirm the SA selected */ | |||
| 1531 | { | |||
| 1532 | /* SA body in and out */ | |||
| 1533 | struct payload_digest *const sa_pd = | |||
| 1534 | md->chain[ISAKMP_NEXT_v2SA]; | |||
| 1535 | struct ikev2_proposals *ike_proposals = | |||
| 1536 | get_v2_ike_proposals(c, "IKE SA initiator accepting remote proposal", ike->sa.st_logger); | |||
| 1537 | ||||
| 1538 | stf_status ret = ikev2_process_sa_payload("IKE initiator (accepting)", | |||
| 1539 | &sa_pd->pbs, | |||
| 1540 | /*expect_ike*/ TRUE1, | |||
| 1541 | /*expect_spi*/ FALSE0, | |||
| 1542 | /*expect_accepted*/ TRUE1, | |||
| 1543 | 							  LIN(POLICY_OPPORTUNISTIC, c->policy)(((((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))),  | |||
| 1544 | &st->st_accepted_ike_proposal, | |||
| 1545 | ike_proposals, ike->sa.st_logger); | |||
| 1546 | if (ret != STF_OK) { | |||
| 1547 | 			dbg("ikev2_parse_parent_sa_body() failed in ikev2_parent_inR1outI2()"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ikev2_parse_parent_sa_body() failed in ikev2_parent_inR1outI2()" ); } };  | |||
| 1548 | return ret; /* initiator; no response */ | |||
| 1549 | } | |||
| 1550 | ||||
| 1551 | if (!ikev2_proposal_to_trans_attrs(st->st_accepted_ike_proposal, | |||
| 1552 | &st->st_oakley, ike->sa.st_logger)) { | |||
| 1553 | loglog(RC_LOG_SERIOUS, "IKE initiator proposed an unsupported algorithm"); | |||
| 1554 | free_ikev2_proposal(&st->st_accepted_ike_proposal); | |||
| 1555 | 			passert(st->st_accepted_ike_proposal == NULL){ _Bool assertion__ = st->st_accepted_ike_proposal == ((void *)0); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1555}, "%s" , "st->st_accepted_ike_proposal == NULL"); } };  | |||
| 1556 | /* | |||
| 1557 | * Assume caller et.al. will clean up the | |||
| 1558 | * reset of the mess? | |||
| 1559 | */ | |||
| 1560 | return STF_FAIL; | |||
| 1561 | } | |||
| 1562 | } | |||
| 1563 | ||||
| 1564 | /* | |||
| 1565 | * Initiator: check v2N_NAT_DETECTION_DESTINATION_IP or/and | |||
| 1566 | * v2N_NAT_DETECTION_SOURCE_IP. | |||
| 1567 | * | |||
| 1568 | * 2.23. NAT Traversal | |||
| 1569 | * | |||
| 1570 | * The IKE initiator MUST check the NAT_DETECTION_SOURCE_IP | |||
| 1571 | * or NAT_DETECTION_DESTINATION_IP payloads if present, and | |||
| 1572 | * if they do not match the addresses in the outer packet, | |||
| 1573 | * MUST tunnel all future IKE and ESP packets associated | |||
| 1574 | * with this IKE SA over UDP port 4500. | |||
| 1575 | * | |||
| 1576 | * When detected, float to the NAT port as needed (*ikeport | |||
| 1577 | * can't float but already supports NAT). When the ports | |||
| 1578 | * can't support NAT, give up. | |||
| 1579 | */ | |||
| 1580 | ||||
| 1581 | if (v2_nat_detected(ike, md)) { | |||
| 1582 | 		pexpect(ike->sa.hidden_variables.st_nat_traversal & NAT_T_DETECTED)({ _Bool assertion__ = ike->sa.hidden_variables.st_nat_traversal & ( ((lset_t)1 << (NATED_HOST)) | ((lset_t)1 << (NATED_PEER)) ); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1582 }, "%s", "ike->sa.hidden_variables.st_nat_traversal & NAT_T_DETECTED" ); } assertion__; });  | |||
| 1583 | 		if (!v2_natify_initiator_endpoints(ike, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 1583})) {  | |||
| 1584 | /* already logged */ | |||
| 1585 | return STF_FATAL; | |||
| 1586 | } | |||
| 1587 | } | |||
| 1588 | ||||
| 1589 | /* | |||
| 1590 | * Initiate the calculation of g^xy. | |||
| 1591 | * | |||
| 1592 | * Form and pass in the full SPI[ir] that will eventually be | |||
| 1593 | * used by this IKE SA. Only once DH has been computed and | |||
| 1594 | * the SA is secure (but not authenticated) should the state's | |||
| 1595 | * IKE SPIr be updated. | |||
| 1596 | */ | |||
| 1597 | 	pexpect(ike_spi_is_zero(&ike->sa.st_ike_spis.responder))({ _Bool assertion__ = ike_spi_is_zero(&ike->sa.st_ike_spis .responder); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 1597}, "%s" , "ike_spi_is_zero(&ike->sa.st_ike_spis.responder)"); } assertion__; });  | |||
| 1598 | ike->sa.st_ike_rekey_spis = (ike_spis_t) { | |||
| 1599 | .initiator = ike->sa.st_ike_spis.initiator, | |||
| 1600 | .responder = md->hdr.isa_ike_responder_spiisa_ike_spis.responder, | |||
| 1601 | }; | |||
| 1602 | start_dh_v2(st, "ikev2_inR1outI2 KE", | |||
| 1603 | SA_INITIATOR, | |||
| 1604 | NULL((void*)0), NULL((void*)0), &st->st_ike_rekey_spis, | |||
| 1605 | ikev2_parent_inR1outI2_continue); | |||
| 1606 | return STF_SUSPEND; | |||
| 1607 | } | |||
| 1608 | ||||
| 1609 | static void ikev2_parent_inR1outI2_continue(struct state *st, | |||
| 1610 | struct msg_digest *md, | |||
| 1611 | struct pluto_crypto_req *r) | |||
| 1612 | { | |||
| 1613 | 	dbg("%s() for #%lu %s: g^{xy} calculated, sending I2",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: g^{xy} calculated, sending I2" , __func__, st->st_serialno, st->st_state->name); } }  | |||
| 1614 | 	    __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: g^{xy} calculated, sending I2" , __func__, st->st_serialno, st->st_state->name); } };  | |||
| 1615 | ||||
| 1616 | 	pexpect(v2_msg_role(md) == MESSAGE_RESPONSE)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 1616}, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } assertion__; }); /* i.e., MD!=NULL */  | |||
| 1617 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 1617}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 1618 | ||||
| 1619 | struct ike_sa *ike = pexpect_ike_sa(st); | |||
| 1620 |  	pexpect(ike->sa.st_sa_role == SA_INITIATOR)({ _Bool assertion__ = ike->sa.st_sa_role == SA_INITIATOR; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 1620}, "%s", "ike->sa.st_sa_role == SA_INITIATOR" ); } assertion__; });  | |||
| 1621 | ||||
| 1622 | stf_status e = ikev2_parent_inR1outI2_tail(st, md, r); | |||
| 1623 | /* replace (*mdp)->st with st ... */ | |||
| 1624 | complete_v2_state_transition(md->st, md, e); | |||
| 1625 | } | |||
| 1626 | ||||
| 1627 | /* Misleading name, also used for NULL sized type's */ | |||
| 1628 | static stf_status ikev2_ship_cp_attr_ip(uint16_t type, ip_address *ip, | |||
| 1629 | const char *story, pb_stream *outpbs) | |||
| 1630 | { | |||
| 1631 | pb_stream a_pbs; | |||
| 1632 | ||||
| 1633 | struct ikev2_cp_attribute attr; | |||
| 1634 | attr.type = type; | |||
| 1635 | if (ip == NULL((void*)0)) { | |||
| 1636 | attr.len = 0; | |||
| 1637 | } else { | |||
| 1638 | if (address_type(ip)->af == AF_INET2) | |||
| 1639 | attr.len = address_type(ip)->ip_size; | |||
| 1640 | else | |||
| 1641 | attr.len = INTERNAL_IP6_ADDRESS_SIZE17; /* RFC hack to append IPv6 prefix len */ | |||
| 1642 | } | |||
| 1643 | ||||
| 1644 | if (!out_struct(&attr, &ikev2_cp_attribute_desc, outpbs, | |||
| 1645 | &a_pbs)) | |||
| 1646 | return STF_INTERNAL_ERROR; | |||
| 1647 | ||||
| 1648 | if (attr.len > 0) { | |||
| 1649 | diag_t d = pbs_out_address(&a_pbs, ip, story); | |||
| 1650 | if (d != NULL((void*)0)) { | |||
| 1651 | log_diag(RC_LOG_SERIOUS, a_pbs.out_logger, &d, "%s", ""); | |||
| 1652 | return STF_INTERNAL_ERROR; | |||
| 1653 | } | |||
| 1654 | } | |||
| 1655 | ||||
| 1656 | if (attr.len == INTERNAL_IP6_ADDRESS_SIZE17) { /* IPv6 address add prefix */ | |||
| 1657 | uint8_t ipv6_prefix_len = INTERNL_IP6_PREFIX_LEN128; | |||
| 1658 | diag_t d = pbs_out_raw(&a_pbs, &ipv6_prefix_len, sizeof(uint8_t), "INTERNL_IP6_PREFIX_LEN"); | |||
| 1659 | if (d != NULL((void*)0)) { | |||
| 1660 | log_diag(RC_LOG_SERIOUS, outpbs->out_logger, &d, "%s", ""); | |||
| 1661 | return STF_INTERNAL_ERROR; | |||
| 1662 | } | |||
| 1663 | } | |||
| 1664 | ||||
| 1665 | close_output_pbs(&a_pbs); | |||
| 1666 | return STF_OK; | |||
| 1667 | } | |||
| 1668 | ||||
| 1669 | static stf_status ikev2_ship_cp_attr_str(uint16_t type, char *str, | |||
| 1670 | const char *story, pb_stream *outpbs) | |||
| 1671 | { | |||
| 1672 | pb_stream a_pbs; | |||
| 1673 | struct ikev2_cp_attribute attr = { | |||
| 1674 | .type = type, | |||
| 1675 | .len = (str == NULL((void*)0)) ? 0 : strlen(str), | |||
| 1676 | }; | |||
| 1677 | ||||
| 1678 | if (!out_struct(&attr, &ikev2_cp_attribute_desc, outpbs, | |||
| 1679 | &a_pbs)) | |||
| 1680 | return STF_INTERNAL_ERROR; | |||
| 1681 | ||||
| 1682 | if (attr.len > 0) { | |||
| 1683 | diag_t d = pbs_out_raw(&a_pbs, str, attr.len, story); | |||
| 1684 | if (d != NULL((void*)0)) { | |||
| 1685 | log_diag(RC_LOG_SERIOUS, outpbs->out_logger, &d, "%s", ""); | |||
| 1686 | return STF_INTERNAL_ERROR; | |||
| 1687 | } | |||
| 1688 | } | |||
| 1689 | ||||
| 1690 | close_output_pbs(&a_pbs); | |||
| 1691 | return STF_OK; | |||
| 1692 | } | |||
| 1693 | ||||
| 1694 | /* | |||
| 1695 | * CHILD is asking for configuration; hence log against child. | |||
| 1696 | */ | |||
| 1697 | ||||
| 1698 | bool_Bool emit_v2_child_configuration_payload(struct connection *c, | |||
| 1699 | struct child_sa *child, | |||
| 1700 | pb_stream *outpbs) | |||
| 1701 | { | |||
| 1702 | pb_stream cp_pbs; | |||
| 1703 | bool_Bool cfg_reply = c->spd.that.has_lease; | |||
| 1704 | struct ikev2_cp cp = { | |||
| 1705 | .isacp_critical = ISAKMP_PAYLOAD_NONCRITICAL0x00, | |||
| 1706 | .isacp_type = cfg_reply ? IKEv2_CP_CFG_REPLY : IKEv2_CP_CFG_REQUEST, | |||
| 1707 | }; | |||
| 1708 | ||||
| 1709 | 	dbg("Send Configuration Payload %s ",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Send Configuration Payload %s ", cfg_reply ? "reply" : "request"); } }  | |||
| 1710 | 	    cfg_reply ? "reply" : "request"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Send Configuration Payload %s ", cfg_reply ? "reply" : "request"); } };  | |||
| 1711 | ||||
| 1712 | if (!out_struct(&cp, &ikev2_cp_desc, outpbs, &cp_pbs)) | |||
| 1713 | return false0; | |||
| 1714 | ||||
| 1715 | if (cfg_reply) { | |||
| 1716 | ikev2_ship_cp_attr_ip(subnet_type(&c->spd.that.client) == &ipv4_info ? | |||
| 1717 | IKEv2_INTERNAL_IP4_ADDRESS : IKEv2_INTERNAL_IP6_ADDRESS, | |||
| 1718 | &c->spd.that.client.addr, "Internal IP Address", &cp_pbs); | |||
| 1719 | ||||
| 1720 | if (c->modecfg_dns != NULL((void*)0)) { | |||
| 1721 | char *ipstr; | |||
| 1722 | ||||
| 1723 | ipstr = strtok(c->modecfg_dns, ", "); | |||
| 1724 | while (ipstr != NULL((void*)0)) { | |||
| 1725 | if (strchr(ipstr, '.') != NULL((void*)0)) { | |||
| 1726 | ip_address ip; | |||
| 1727 | err_t e = ttoaddr_num(ipstr, 0, AF_INET2, &ip); | |||
| 1728 | if (e != NULL((void*)0)) { | |||
| 1729 | log_state(RC_LOG_SERIOUS, &child->sa, | |||
| 1730 | "Ignored bogus DNS IP address '%s'", ipstr); | |||
| 1731 | } else { | |||
| 1732 | if (ikev2_ship_cp_attr_ip(IKEv2_INTERNAL_IP4_DNS, &ip, | |||
| 1733 | "IP4_DNS", &cp_pbs) != STF_OK) | |||
| 1734 | return false0; | |||
| 1735 | } | |||
| 1736 | } else if (strchr(ipstr, ':') != NULL((void*)0)) { | |||
| 1737 | ip_address ip; | |||
| 1738 | err_t e = ttoaddr_num(ipstr, 0, AF_INET610, &ip); | |||
| 1739 | if (e != NULL((void*)0)) { | |||
| 1740 | log_state(RC_LOG_SERIOUS, &child->sa, | |||
| 1741 | "Ignored bogus DNS IP address '%s'", ipstr); | |||
| 1742 | } else { | |||
| 1743 | if (ikev2_ship_cp_attr_ip(IKEv2_INTERNAL_IP6_DNS, &ip, | |||
| 1744 | "IP6_DNS", &cp_pbs) != STF_OK) | |||
| 1745 | return false0; | |||
| 1746 | } | |||
| 1747 | } else { | |||
| 1748 | loglog(RC_LOG_SERIOUS, "Ignored bogus DNS IP address '%s'", ipstr); | |||
| 1749 | } | |||
| 1750 | ipstr = strtok(NULL((void*)0), ", "); | |||
| 1751 | } | |||
| 1752 | } | |||
| 1753 | ||||
| 1754 | if (c->modecfg_domains != NULL((void*)0)) { | |||
| 1755 | char *domain; | |||
| 1756 | ||||
| 1757 | domain = strtok(c->modecfg_domains, ", "); | |||
| 1758 | while (domain != NULL((void*)0)) { | |||
| 1759 | if (ikev2_ship_cp_attr_str(IKEv2_INTERNAL_DNS_DOMAIN, domain, | |||
| 1760 | "IKEv2_INTERNAL_DNS_DOMAIN", &cp_pbs) != STF_OK) | |||
| 1761 | return false0; | |||
| 1762 | domain = strtok(NULL((void*)0), ", "); | |||
| 1763 | } | |||
| 1764 | } | |||
| 1765 | } else { /* cfg request */ | |||
| 1766 | ikev2_ship_cp_attr_ip(IKEv2_INTERNAL_IP4_ADDRESS, NULL((void*)0), "IPV4 Address", &cp_pbs); | |||
| 1767 | ikev2_ship_cp_attr_ip(IKEv2_INTERNAL_IP4_DNS, NULL((void*)0), "DNSv4", &cp_pbs); | |||
| 1768 | ikev2_ship_cp_attr_ip(IKEv2_INTERNAL_IP6_ADDRESS, NULL((void*)0), "IPV6 Address", &cp_pbs); | |||
| 1769 | ikev2_ship_cp_attr_ip(IKEv2_INTERNAL_IP6_DNS, NULL((void*)0), "DNSv6", &cp_pbs); | |||
| 1770 | ikev2_ship_cp_attr_ip(IKEv2_INTERNAL_DNS_DOMAIN, NULL((void*)0), "Domain", &cp_pbs); | |||
| 1771 | } | |||
| 1772 | ||||
| 1773 | close_output_pbs(&cp_pbs); | |||
| 1774 | return true1; | |||
| 1775 | } | |||
| 1776 | ||||
| 1777 | static bool_Bool need_configuration_payload(const struct connection *const pc, | |||
| 1778 | const lset_t st_nat_traversal) | |||
| 1779 | { | |||
| 1780 | return (pc->spd.this.modecfg_client && | |||
| 1781 | 		(!pc->spd.this.cat || LHAS(st_nat_traversal, NATED_HOST)(((st_nat_traversal) & ((lset_t)1 << (NATED_HOST))) != ((lset_t)0))));  | |||
| 1782 | } | |||
| 1783 | ||||
| 1784 | static struct crypt_mac v2_hash_id_payload(const char *id_name, struct ike_sa *ike, | |||
| 1785 | const char *key_name, PK11SymKey *key) | |||
| 1786 | { | |||
| 1787 | /* | |||
| 1788 | * InitiatorIDPayload = PayloadHeader | RestOfInitIDPayload | |||
| 1789 | * RestOfInitIDPayload = IDType | RESERVED | InitIDData | |||
| 1790 | * MACedIDForR = prf(SK_pr, RestOfInitIDPayload) | |||
| 1791 | */ | |||
| 1792 | struct crypt_prf *id_ctx = crypt_prf_init_symkey(id_name, ike->sa.st_oakley.ta_prf, | |||
| 1793 | key_name, key, ike->sa.st_logger); | |||
| 1794 | /* skip PayloadHeader; hash: IDType | RESERVED */ | |||
| 1795 | crypt_prf_update_bytes(id_ctx, "IDType", &ike->sa.st_v2_id_payload.header.isai_type, | |||
| 1796 | sizeof(ike->sa.st_v2_id_payload.header.isai_type)); | |||
| 1797 | /* note that res1+res2 is 3 zero bytes */ | |||
| 1798 | crypt_prf_update_byte(id_ctx, "RESERVED 1", ike->sa.st_v2_id_payload.header.isai_res1); | |||
| 1799 | crypt_prf_update_byte(id_ctx, "RESERVED 2", ike->sa.st_v2_id_payload.header.isai_res2); | |||
| 1800 | crypt_prf_update_byte(id_ctx, "RESERVED 3", ike->sa.st_v2_id_payload.header.isai_res3); | |||
| 1801 | /* hash: InitIDData */ | |||
| 1802 | 	crypt_prf_update_hunk(id_ctx, "InitIDData", ike->sa.st_v2_id_payload.data){ typeof(ike->sa.st_v2_id_payload.data) hunk_ = ike->sa .st_v2_id_payload.data; crypt_prf_update_bytes(id_ctx, "InitIDData" , hunk_.ptr, hunk_.len); };  | |||
| 1803 | return crypt_prf_final_mac(&id_ctx, NULL((void*)0)/*no-truncation*/); | |||
| 1804 | } | |||
| 1805 | ||||
| 1806 | static struct crypt_mac v2_id_hash(struct ike_sa *ike, const char *why, | |||
| 1807 | const char *id_name, shunk_t id_payload, | |||
| 1808 | const char *key_name, PK11SymKey *key) | |||
| 1809 | { | |||
| 1810 | const uint8_t *id_start = id_payload.ptr; | |||
| 1811 | size_t id_size = id_payload.len; | |||
| 1812 | /* HASH of ID is not done over common header */ | |||
| 1813 | id_start += NSIZEOF_isakmp_generic4; | |||
| 1814 | id_size -= NSIZEOF_isakmp_generic4; | |||
| 1815 | struct crypt_prf *id_ctx = crypt_prf_init_symkey(why, ike->sa.st_oakley.ta_prf, | |||
| 1816 | key_name, key, ike->sa.st_logger); | |||
| 1817 | crypt_prf_update_bytes(id_ctx, id_name, id_start, id_size); | |||
| 1818 | return crypt_prf_final_mac(&id_ctx, NULL((void*)0)/*no-truncation*/); | |||
| 1819 | } | |||
| 1820 | ||||
| 1821 | static stf_status ikev2_parent_inR1outI2_auth_signature_continue(struct ike_sa *ike, | |||
| 1822 | struct msg_digest *md, | |||
| 1823 | const struct hash_signature *sig); | |||
| 1824 | ||||
| 1825 | static stf_status ikev2_parent_inR1outI2_tail(struct state *pst, struct msg_digest *md, | |||
| 1826 | struct pluto_crypto_req *r) | |||
| 1827 | { | |||
| 1828 | struct connection *const pc = pst->st_connection; /* parent connection */ | |||
| 1829 | struct ike_sa *ike = pexpect_ike_sa(pst); | |||
| 1830 | ||||
| 1831 | if (!finish_dh_v2(pst, r, FALSE0)) { | |||
| 1832 | /* | |||
| 1833 | * XXX: this is the initiator so returning a | |||
| 1834 | * notification is kind of useless. | |||
| 1835 | */ | |||
| 1836 | pstat_sa_failed(pst, REASON_CRYPTO_FAILED); | |||
| 1837 | return STF_FAIL + v2N_INVALID_SYNTAX; /* STF_FATAL? */ | |||
| 1838 | } | |||
| 1839 | ||||
| 1840 | /* | |||
| 1841 | * All systems are go. | |||
| 1842 | * | |||
| 1843 | * Since DH succeeded, a secure (but unauthenticated) SA | |||
| 1844 | * (channel) is available. From this point on, should things | |||
| 1845 | * go south, the state needs to be abandoned (but it shouldn't | |||
| 1846 | * happen). | |||
| 1847 | */ | |||
| 1848 | ||||
| 1849 | /* | |||
| 1850 | * Since systems are go, start updating the state, starting | |||
| 1851 | * with SPIr. | |||
| 1852 | */ | |||
| 1853 | rehash_state(&ike->sa, &md->hdr.isa_ike_responder_spiisa_ike_spis.responder); | |||
| 1854 | ||||
| 1855 | /* | |||
| 1856 | * If we and responder are willing to use a PPK, we need to | |||
| 1857 | * generate NO_PPK_AUTH as well as PPK-based AUTH payload. | |||
| 1858 | * | |||
| 1859 | * Stash the no-ppk keys in st_skey_*_no_ppk, and then | |||
| 1860 | * scramble the st_skey_* keys with PPK. | |||
| 1861 | */ | |||
| 1862 | 	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) {  | |||
| 1863 | chunk_t *ppk_id; | |||
| 1864 | chunk_t *ppk = get_ppk(ike->sa.st_connection, &ppk_id, | |||
| 1865 | ike->sa.st_logger); | |||
| 1866 | ||||
| 1867 | if (ppk != NULL((void*)0)) { | |||
| 1868 | 			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"); } };  | |||
| 1869 | ||||
| 1870 | 			pexpect(ike->sa.st_sk_d_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_d_no_ppk == ((void*)0 ); if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 1870}, "%s", "ike->sa.st_sk_d_no_ppk == NULL" ); } assertion__; });  | |||
| 1871 | ike->sa.st_sk_d_no_ppk = reference_symkey(__func__, "sk_d_no_ppk", ike->sa.st_skey_d_nss); | |||
| 1872 | ||||
| 1873 | 			pexpect(ike->sa.st_sk_pi_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_pi_no_ppk == ((void*) 0); if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 1873}, "%s", "ike->sa.st_sk_pi_no_ppk == NULL" ); } assertion__; });  | |||
| 1874 | ike->sa.st_sk_pi_no_ppk = reference_symkey(__func__, "sk_pi_no_ppk", ike->sa.st_skey_pi_nss); | |||
| 1875 | ||||
| 1876 | 			pexpect(ike->sa.st_sk_pr_no_ppk == NULL)({ _Bool assertion__ = ike->sa.st_sk_pr_no_ppk == ((void*) 0); if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 1876}, "%s", "ike->sa.st_sk_pr_no_ppk == NULL" ); } assertion__; });  | |||
| 1877 | ike->sa.st_sk_pr_no_ppk = reference_symkey(__func__, "sk_pr_no_ppk", ike->sa.st_skey_pr_nss); | |||
| 1878 | ||||
| 1879 | ppk_recalculate(ppk, ike->sa.st_oakley.ta_prf, | |||
| 1880 | &ike->sa.st_skey_d_nss, | |||
| 1881 | &ike->sa.st_skey_pi_nss, | |||
| 1882 | &ike->sa.st_skey_pr_nss, | |||
| 1883 | ike->sa.st_logger); | |||
| 1884 | libreswan_log("PPK AUTH calculated as initiator")loglog(RC_LOG, "PPK AUTH calculated as initiator"); | |||
| 1885 | } else { | |||
| 1886 | if (pc->policy & POLICY_PPK_INSIST((lset_t)1 << (POLICY_PPK_INSIST_IX))) { | |||
| 1887 | log_state(RC_LOG_SERIOUS, &ike->sa, | |||
| 1888 | "connection requires PPK, but we didn't find one"); | |||
| 1889 | return STF_FATAL; | |||
| 1890 | } else { | |||
| 1891 | log_state(RC_LOG, &ike->sa, | |||
| 1892 | "failed to find PPK and PPK_ID, continuing without PPK"); | |||
| 1893 | /* we should omit sending any PPK Identity, so we pretend we didn't see USE_PPK */ | |||
| 1894 | ike->sa.st_seen_ppk = FALSE0; | |||
| 1895 | } | |||
| 1896 | } | |||
| 1897 | } | |||
| 1898 | ||||
| 1899 | /* | |||
| 1900 | * Construct the IDi payload and store it in state so that it | |||
| 1901 | * can be emitted later. Then use that to construct the | |||
| 1902 | * "MACedIDFor[I]". | |||
| 1903 | * | |||
| 1904 | * Code assumes that struct ikev2_id's "IDType|RESERVED" is | |||
| 1905 | * laid out the same as the packet. | |||
| 1906 | */ | |||
| 1907 | ||||
| 1908 | { | |||
| 1909 | shunk_t data; | |||
| 1910 | ike->sa.st_v2_id_payload.header = build_v2_id_payload(&pc->spd.this, &data, | |||
| 1911 | "my IDi", ike->sa.st_logger); | |||
| 1912 | 		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"); });  | |||
| 1913 | } | |||
| 1914 | ||||
| 1915 | ike->sa.st_v2_id_payload.mac = v2_hash_id_payload("IDi", ike, | |||
| 1916 | "st_skey_pi_nss", | |||
| 1917 | ike->sa.st_skey_pi_nss); | |||
| 1918 | 	if (pst->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))))) {  | |||
| 1919 | /* ID payload that we've build is the same */ | |||
| 1920 | ike->sa.st_v2_id_payload.mac_no_ppk_auth = | |||
| 1921 | v2_hash_id_payload("IDi (no-PPK)", ike, | |||
| 1922 | "sk_pi_no_pkk", | |||
| 1923 | ike->sa.st_sk_pi_no_ppk); | |||
| 1924 | } | |||
| 1925 | ||||
| 1926 | { | |||
| 1927 | enum keyword_authby authby = v2_auth_by(ike); | |||
| 1928 | enum ikev2_auth_method auth_method = v2_auth_method(ike, authby); | |||
| 1929 | switch (auth_method) { | |||
| 1930 | case IKEv2_AUTH_RSA: | |||
| 1931 | { | |||
| 1932 | const struct hash_desc *hash_algo = &ike_alg_hash_sha1; | |||
| 1933 | struct crypt_mac hash_to_sign = | |||
| 1934 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
| 1935 | hash_algo, LOCAL_PERSPECTIVE); | |||
| 1936 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
| 1937 | authby, auth_method, | |||
| 1938 | ikev2_parent_inR1outI2_auth_signature_continue)) { | |||
| 1939 | 				dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } };  | |||
| 1940 | return STF_FATAL; | |||
| 1941 | } | |||
| 1942 | return STF_SUSPEND; | |||
| 1943 | } | |||
| 1944 | case IKEv2_AUTH_DIGSIG: | |||
| 1945 | { | |||
| 1946 | const struct hash_desc *hash_algo = v2_auth_negotiated_signature_hash(ike); | |||
| 1947 | if (hash_algo == NULL((void*)0)) { | |||
| 1948 | return STF_FATAL; | |||
| 1949 | } | |||
| 1950 | struct crypt_mac hash_to_sign = | |||
| 1951 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
| 1952 | hash_algo, LOCAL_PERSPECTIVE); | |||
| 1953 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
| 1954 | authby, auth_method, | |||
| 1955 | ikev2_parent_inR1outI2_auth_signature_continue)) { | |||
| 1956 | 				dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } };  | |||
| 1957 | return STF_FATAL; | |||
| 1958 | } | |||
| 1959 | return STF_SUSPEND; | |||
| 1960 | } | |||
| 1961 | case IKEv2_AUTH_PSK: | |||
| 1962 | case IKEv2_AUTH_NULL: | |||
| 1963 | { | |||
| 1964 | struct hash_signature sig = { .len = 0, }; | |||
| 1965 | return ikev2_parent_inR1outI2_auth_signature_continue(ike, md, &sig); | |||
| 1966 | } | |||
| 1967 | default: | |||
| 1968 | log_state(RC_LOG, &ike->sa, | |||
| 1969 | "authentication method %s not supported", | |||
| 1970 | enum_name(&ikev2_auth_names, auth_method)); | |||
| 1971 | return STF_FATAL; | |||
| 1972 | } | |||
| 1973 | } | |||
| 1974 | } | |||
| 1975 | ||||
| 1976 | static stf_status ikev2_parent_inR1outI2_auth_signature_continue(struct ike_sa *ike, | |||
| 1977 | struct msg_digest *md, | |||
| 1978 | const struct hash_signature *auth_sig) | |||
| 1979 | { | |||
| 1980 | struct state *pst = &ike->sa; | |||
| 1981 | struct connection *const pc = pst->st_connection; /* parent connection */ | |||
| 1982 | ||||
| 1983 | ikev2_log_parentSA(pst); | |||
| 1984 | ||||
| 1985 | /* | |||
| 1986 | * XXX This is too early and many failures could lead to not | |||
| 1987 | * needing a child state. | |||
| 1988 | * | |||
| 1989 | * XXX: The problem isn't so much that the child state is | |||
| 1990 | * created - it provides somewhere to store all the child's | |||
| 1991 | * state - but that things switch to the child before the IKE | |||
| 1992 | * SA is finished. Consequently, code is forced to switch | |||
| 1993 | * back to the IKE SA. | |||
| 1994 | * | |||
| 1995 | * Start with the CHILD SA bound to the same whackfd as it IKE | |||
| 1996 | * SA. It might later change when its discovered that the | |||
| 1997 | * child is for something pending? | |||
| 1998 | */ | |||
| 1999 | struct child_sa *child = new_v2_child_state(pexpect_ike_sa(pst), | |||
| 2000 | IPSEC_SA, | |||
| 2001 | SA_INITIATOR, | |||
| 2002 | STATE_V2_IKE_AUTH_CHILD_I0, | |||
| 2003 | ike->sa.st_whack_sockst_logger->object_whackfd); | |||
| 2004 | struct state *cst = &child->sa; | |||
| 2005 | ||||
| 2006 | /* XXX because the early child state ends up with the try counter check, we need to copy it */ | |||
| 2007 | cst->st_try = pst->st_try; | |||
| 2008 | ||||
| 2009 | /* | |||
| 2010 | * XXX: This is so lame. Need to move the current initiator | |||
| 2011 | * from IKE to the CHILD so that the post processor doesn't | |||
| 2012 | * get confused. If the IKE->CHILD switch didn't happen this | |||
| 2013 | * wouldn't be needed. | |||
| 2014 | */ | |||
| 2015 | v2_msgid_switch_initiator(ike, child, md); | |||
| 2016 | ||||
| 2017 | binlog_refresh_state(cst)binlog_state((cst), (cst)->st_state->kind); | |||
| 2018 | 	switch_md_st(md, &child->sa, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 2018});  | |||
| 2019 | ||||
| 2020 | /* | |||
| 2021 | * XXX: Danger! | |||
| 2022 | * | |||
| 2023 | * Because the code above has blatted MD->ST with the child | |||
| 2024 | * state (CST) and this function's caller is going to try to | |||
| 2025 | * complete the V2 state transition on MD->ST (i.e., CST) and | |||
| 2026 | * using the state-transition MD->SVM the IKE SA (PST) will | |||
| 2027 | * never get to complete its state transition. | |||
| 2028 | * | |||
| 2029 | * Get around this by forcing the state transition here. | |||
| 2030 | * | |||
| 2031 | * But what should happen? A guess is to just leave MD->ST | |||
| 2032 | * alone. The CHILD SA doesn't really exist until after the | |||
| 2033 | * IKE SA has processed and approved of the response to this | |||
| 2034 | * IKE_AUTH request. | |||
| 2035 | * | |||
| 2036 | * XXX: Danger! | |||
| 2037 | * | |||
| 2038 | * Set the replace timeout but ensure it is larger than the | |||
| 2039 | * retransmit timeout (the default for both is 60-seconds and | |||
| 2040 | * it would appear that libevent can sometimes deliver the | |||
| 2041 | * retransmit before the replay). This way the retransmit | |||
| 2042 | * will timeout and initiate the replace (but if things really | |||
| 2043 | * really screw up the replace will kick in). | |||
| 2044 | * | |||
| 2045 | * XXX: Danger: | |||
| 2046 | * | |||
| 2047 | * In success_v2_state_transition() there's a call to | |||
| 2048 | * clear_retransmits() however, because of the IKE->CHILD | |||
| 2049 | * switch it ends up clearing the CHILD letting the retransmit | |||
| 2050 | * timer expire. Making things worse, the retransmit code | |||
| 2051 | * doesn't know how to properly replace an IKE family - | |||
| 2052 | * flush_incomplete_child() schedules replace events for the | |||
| 2053 | * CHILD states that trigger _after_ the IKE SA has been | |||
| 2054 | * deleted leaving them orphaned. | |||
| 2055 | */ | |||
| 2056 | ||||
| 2057 | 	pexpect(md->svm->timeout_event == EVENT_RETRANSMIT)({ _Bool assertion__ = md->svm->timeout_event == EVENT_RETRANSMIT ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 2057}, "%s", "md->svm->timeout_event == EVENT_RETRANSMIT" ); } assertion__; }); /* for CST */  | |||
| 2058 | delete_event(&ike->sa); | |||
| 2059 | clear_retransmits(&ike->sa); | |||
| 2060 | deltatime_t halfopen = deltatime_max(deltatime_mulu(ike->sa.st_connection->r_timeout, 2), | |||
| 2061 | deltatime(PLUTO_HALFOPEN_SA_LIFE(secs_per_minute ))); | |||
| 2062 | event_schedule(EVENT_SA_REPLACE, halfopen, &ike->sa); | |||
| 2063 | change_state(&ike->sa, STATE_PARENT_I2); | |||
| 2064 | ||||
| 2065 | /* | |||
| 2066 | * XXX: | |||
| 2067 | * | |||
| 2068 | * Should this code use clone_in_pbs_as_chunk() which uses | |||
| 2069 | * pbs_room() (.roof-.start)? The original code: | |||
| 2070 | * | |||
| 2071 | * clonetochunk(st->st_firstpacket_peer, md->message_pbs.start, | |||
| 2072 | * pbs_offset(&md->message_pbs), | |||
| 2073 | * "saved first received packet"); | |||
| 2074 | * | |||
| 2075 | * and clone_out_pbs_as_chunk() both use pbs_offset() | |||
| 2076 | * (.cur-.start). | |||
| 2077 | * | |||
| 2078 | * Suspect it doesn't matter as the code initializing | |||
| 2079 | * .message_pbs forces .roof==.cur - look for the comment | |||
| 2080 | * "trim padding (not actually legit)". | |||
| 2081 | */ | |||
| 2082 | /* record first packet for later checking of signature */ | |||
| 2083 | pst->st_firstpacket_peer = clone_out_pbs_as_chunk(&md->message_pbs, | |||
| 2084 | "saved first received packet"); | |||
| 2085 | ||||
| 2086 | /* beginning of data going out */ | |||
| 2087 | ||||
| 2088 | /* make sure HDR is at start of a clean buffer */ | |||
| 2089 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
| 2090 | reply_buffer, sizeof(reply_buffer), | |||
| 2091 | ike->sa.st_logger); | |||
| 2092 | ||||
| 2093 | /* HDR out */ | |||
| 2094 | ||||
| 2095 | 	pb_stream rbody = open_v2_message(&reply_stream, ike_sa(pst, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 2095}),  | |||
| 2096 | NULL((void*)0) /* request */, | |||
| 2097 | ISAKMP_v2_IKE_AUTH); | |||
| 2098 | if (!pbs_ok(&rbody)((&rbody)->start != ((void*)0))) { | |||
| 2099 | return STF_INTERNAL_ERROR; | |||
| 2100 | } | |||
| 2101 | ||||
| 2102 | /* insert an Encryption payload header (SK) */ | |||
| 2103 | ||||
| 2104 | 	v2SK_payload_t sk = open_v2SK_payload(child->sa.st_logger, &rbody, ike_sa(pst, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 2104}));  | |||
| 2105 | if (!pbs_ok(&sk.pbs)((&sk.pbs)->start != ((void*)0))) { | |||
| 2106 | return STF_INTERNAL_ERROR; | |||
| 2107 | } | |||
| 2108 | ||||
| 2109 | /* actual data */ | |||
| 2110 | ||||
| 2111 | /* decide whether to send CERT payload */ | |||
| 2112 | ||||
| 2113 | /* it should use parent not child state */ | |||
| 2114 | bool_Bool send_cert = ikev2_send_cert_decision(cst); | |||
| 2115 | bool_Bool ic = pc->initial_contact && (pst->st_ike_pred == SOS_NOBODY0); | |||
| 2116 | bool_Bool send_idr = ((pc->spd.that.id.kind != ID_NULL && pc->spd.that.id.name.len != 0) || | |||
| 2117 | pc->spd.that.id.kind == ID_NULL); /* me tarzan, you jane */ | |||
| 2118 | ||||
| 2119 | 	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 " ); } };  | |||
| 2120 | ||||
| 2121 | /* send out the IDi payload */ | |||
| 2122 | ||||
| 2123 | { | |||
| 2124 | pb_stream i_id_pbs; | |||
| 2125 | if (!out_struct(&ike->sa.st_v2_id_payload.header, | |||
| 2126 | &ikev2_id_i_desc, | |||
| 2127 | &sk.pbs, | |||
| 2128 | &i_id_pbs) || | |||
| 2129 | 		    !pbs_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)) { log_diag(RC_LOG_SERIOUS , outs_->out_logger, &d_, "%s", ""); } d_ == ((void*)0 ); }))  | |||
| 2130 | return STF_INTERNAL_ERROR; | |||
| 2131 | close_output_pbs(&i_id_pbs); | |||
| 2132 | } | |||
| 2133 | ||||
| 2134 | if (impair.add_unknown_v2_payload_to_sk == ISAKMP_v2_IKE_AUTH) { | |||
| 2135 | if (!emit_v2UNKNOWN("SK request", | |||
| 2136 | impair.add_unknown_v2_payload_to_sk, | |||
| 2137 | &sk.pbs)) { | |||
| 2138 | return STF_INTERNAL_ERROR; | |||
| 2139 | } | |||
| 2140 | } | |||
| 2141 | ||||
| 2142 | /* send [CERT,] payload RFC 4306 3.6, 1.2) */ | |||
| 2143 | if (send_cert) { | |||
| 2144 | stf_status certstat = ikev2_send_cert(cst, &sk.pbs); | |||
| 2145 | if (certstat != STF_OK) | |||
| 2146 | return certstat; | |||
| 2147 | ||||
| 2148 | /* send CERTREQ */ | |||
| 2149 | bool_Bool send_certreq = ikev2_send_certreq_INIT_decision(cst, SA_INITIATOR); | |||
| 2150 | if (send_certreq) { | |||
| 2151 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 2152 | dn_buf buf; | |||
| 2153 | DBG_log("Sending [CERTREQ] of %s", | |||
| 2154 | str_dn(cst->st_connection->spd.that.ca, &buf)); | |||
| 2155 | } | |||
| 2156 | ikev2_send_certreq(cst, md, &sk.pbs); | |||
| 2157 | } | |||
| 2158 | } | |||
| 2159 | ||||
| 2160 | /* you Tarzan, me Jane support */ | |||
| 2161 | if (send_idr) { | |||
| 2162 | switch (pc->spd.that.id.kind) { | |||
| 2163 | case ID_DER_ASN1_DN: | |||
| 2164 | case ID_FQDN: | |||
| 2165 | case ID_USER_FQDN: | |||
| 2166 | case ID_KEY_ID: | |||
| 2167 | case ID_NULL: | |||
| 2168 | { | |||
| 2169 | shunk_t id_b; | |||
| 2170 | struct ikev2_id r_id = build_v2_id_payload(&pc->spd.that, &id_b, | |||
| 2171 | "their IDr", | |||
| 2172 | ike->sa.st_logger); | |||
| 2173 | pb_stream r_id_pbs; | |||
| 2174 | if (!out_struct(&r_id, &ikev2_id_r_desc, &sk.pbs, | |||
| 2175 | &r_id_pbs) || | |||
| 2176 | 			    !pbs_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)) { log_diag(RC_LOG_SERIOUS , outs_->out_logger, &d_, "%s", ""); } d_ == ((void*)0 ); }))  | |||
| 2177 | return STF_INTERNAL_ERROR; | |||
| 2178 | ||||
| 2179 | close_output_pbs(&r_id_pbs); | |||
| 2180 | break; | |||
| 2181 | } | |||
| 2182 | default: | |||
| 2183 | 			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_idtype_names, pc->spd.that.id.kind)); } }  | |||
| 2184 | 			    enum_show(&ike_idtype_names, pc->spd.that.id.kind)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Not sending IDr payload for remote ID type %s" , enum_show(&ike_idtype_names, pc->spd.that.id.kind)); } };  | |||
| 2185 | break; | |||
| 2186 | } | |||
| 2187 | } | |||
| 2188 | ||||
| 2189 | if (ic) { | |||
| 2190 | libreswan_log("sending INITIAL_CONTACT")loglog(RC_LOG, "sending INITIAL_CONTACT"); | |||
| 2191 | if (!emit_v2N(v2N_INITIAL_CONTACT, &sk.pbs)) | |||
| 2192 | return STF_INTERNAL_ERROR; | |||
| 2193 | } else { | |||
| 2194 | 		dbg("not sending INITIAL_CONTACT"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("not sending INITIAL_CONTACT"); } };  | |||
| 2195 | } | |||
| 2196 | ||||
| 2197 | /* send out the AUTH payload */ | |||
| 2198 | ||||
| 2199 | if (!emit_v2_auth(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, &sk.pbs)) { | |||
| 2200 | 		v2_msgid_switch_responder_from_aborted_child(ike, &child, md, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 2200});  | |||
| 2201 | return STF_INTERNAL_ERROR; | |||
| 2202 | } | |||
| 2203 | ||||
| 2204 | if (need_configuration_payload(pc, pst->hidden_variables.st_nat_traversal)) { | |||
| 2205 | /* | |||
| 2206 | * XXX: should this be passed the CHILD SA's | |||
| 2207 | * .st_connection? Here CHILD and IKE SAs share a | |||
| 2208 | * connection? | |||
| 2209 | */ | |||
| 2210 | if (!emit_v2_child_configuration_payload(ike->sa.st_connection, | |||
| 2211 | child, &sk.pbs)) { | |||
| 2212 | return STF_INTERNAL_ERROR; | |||
| 2213 | } | |||
| 2214 | } | |||
| 2215 | ||||
| 2216 | /* | |||
| 2217 | * Switch to first pending child request for this host pair. | |||
| 2218 | * ??? Why so late in this game? | |||
| 2219 | * | |||
| 2220 | * Then emit SA2i, TSi and TSr and NOTIFY payloads related | |||
| 2221 | * to the IPsec SA. | |||
| 2222 | */ | |||
| 2223 | ||||
| 2224 | /* so far child's connection is same as parent's */ | |||
| 2225 | 	passert(pc == cst->st_connection){ _Bool assertion__ = pc == cst->st_connection; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2225}, "%s", "pc == cst->st_connection" ); } };  | |||
| 2226 | ||||
| 2227 | lset_t policy = pc->policy; | |||
| 2228 | ||||
| 2229 | /* child connection */ | |||
| 2230 | struct connection *cc = first_pending(pexpect_ike_sa(pst), | |||
| 2231 | &policy, &cst->st_whack_sockst_logger->object_whackfd); | |||
| 2232 | ||||
| 2233 | if (cc == NULL((void*)0)) { | |||
| 2234 | cc = pc; | |||
| 2235 | 		dbg("no pending CHILD SAs found for %s Reauthentication so use the original policy",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no pending CHILD SAs found for %s Reauthentication so use the original policy" , cc->name); } }  | |||
| 2236 | 		    cc->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no pending CHILD SAs found for %s Reauthentication so use the original policy" , cc->name); } };  | |||
| 2237 | } | |||
| 2238 | ||||
| 2239 | if (cc != cst->st_connection) { | |||
| 2240 | /* ??? DBG_log not conditional on some DBG selector */ | |||
| 2241 | 		char cib[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf ) + 3 + sizeof(subnet_buf) + 1 + 1)];  | |||
| 2242 | DBG_log("Switching Child connection for #%lu to \"%s\"%s from \"%s\"%s", | |||
| 2243 | cst->st_serialno, cc->name, | |||
| 2244 | fmt_conn_instance(cc, cib), | |||
| 2245 | pc->name, fmt_conn_instance(pc, cib)); | |||
| 2246 | } | |||
| 2247 | /* ??? this seems very late to change the connection */ | |||
| 2248 | update_state_connection(cst, cc); | |||
| 2249 | ||||
| 2250 | /* code does not support AH+ESP, which not recommended as per RFC 8247 */ | |||
| 2251 | struct ipsec_proto_info *proto_info | |||
| 2252 | = ikev2_child_sa_proto_info(pexpect_child_sa(cst), cc->policy); | |||
| 2253 | proto_info->our_spi = ikev2_child_sa_spi(&cc->spd, cc->policy); | |||
| 2254 | 	const chunk_t local_spi = THING_AS_CHUNK(proto_info->our_spi)chunk2(&(proto_info->our_spi), sizeof(proto_info->our_spi ));  | |||
| 2255 | ||||
| 2256 | /* | |||
| 2257 | * A CHILD_SA established during an AUTH exchange does | |||
| 2258 | * not propose DH - the IKE SA's SKEYSEED is always | |||
| 2259 | * used. | |||
| 2260 | */ | |||
| 2261 | struct ikev2_proposals *child_proposals = | |||
| 2262 | get_v2_ike_auth_child_proposals(cc, "IKE SA initiator emitting ESP/AH proposals", | |||
| 2263 | child->sa.st_logger); | |||
| 2264 | if (!ikev2_emit_sa_proposals(&sk.pbs, child_proposals, &local_spi)) { | |||
| 2265 | return STF_INTERNAL_ERROR; | |||
| 2266 | } | |||
| 2267 | ||||
| 2268 | cst->st_ts_this = ikev2_end_to_ts(&cc->spd.this); | |||
| 2269 | cst->st_ts_that = ikev2_end_to_ts(&cc->spd.that); | |||
| 2270 | ||||
| 2271 | v2_emit_ts_payloads(pexpect_child_sa(cst), &sk.pbs, cc); | |||
| 2272 | ||||
| 2273 | if ((cc->policy & POLICY_TUNNEL((lset_t)1 << (POLICY_TUNNEL_IX))) == LEMPTY((lset_t)0)) { | |||
| 2274 | 		dbg("Initiator child policy is transport mode, sending v2N_USE_TRANSPORT_MODE"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initiator child policy is transport mode, sending v2N_USE_TRANSPORT_MODE" ); } };  | |||
| 2275 | /* In v2, for parent, protoid must be 0 and SPI must be empty */ | |||
| 2276 | if (!emit_v2N(v2N_USE_TRANSPORT_MODE, &sk.pbs)) { | |||
| 2277 | return STF_INTERNAL_ERROR; | |||
| 2278 | } | |||
| 2279 | } else { | |||
| 2280 | 		dbg("Initiator child policy is tunnel mode, NOT sending v2N_USE_TRANSPORT_MODE"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initiator child policy is tunnel mode, NOT sending v2N_USE_TRANSPORT_MODE" ); } };  | |||
| 2281 | } | |||
| 2282 | ||||
| 2283 | if (!emit_v2N_compression(cst, true1, &sk.pbs)) { | |||
| 2284 | return STF_INTERNAL_ERROR; | |||
| 2285 | } | |||
| 2286 | ||||
| 2287 | if (cc->send_no_esp_tfc) { | |||
| 2288 | if (!emit_v2N(v2N_ESP_TFC_PADDING_NOT_SUPPORTED, &sk.pbs)) { | |||
| 2289 | return STF_INTERNAL_ERROR; | |||
| 2290 | } | |||
| 2291 | } | |||
| 2292 | ||||
| 2293 | 	if (LIN(POLICY_MOBIKE, cc->policy)(((((lset_t)1 << (POLICY_MOBIKE_IX))) & (cc->policy )) == (((lset_t)1 << (POLICY_MOBIKE_IX))))) {  | |||
| 2294 | cst->st_sent_mobike = pst->st_sent_mobike = TRUE1; | |||
| 2295 | if (!emit_v2N(v2N_MOBIKE_SUPPORTED, &sk.pbs)) { | |||
| 2296 | return STF_INTERNAL_ERROR; | |||
| 2297 | } | |||
| 2298 | } | |||
| 2299 | ||||
| 2300 | /* | |||
| 2301 | * If we and responder are willing to use a PPK, we need to | |||
| 2302 | * generate NO_PPK_AUTH as well as PPK-based AUTH payload | |||
| 2303 | */ | |||
| 2304 | if (pst->st_seen_ppk) { | |||
| 2305 | chunk_t *ppk_id; | |||
| 2306 | get_ppk(ike->sa.st_connection, &ppk_id, | |||
| 2307 | ike->sa.st_logger); | |||
| 2308 | struct ppk_id_payload ppk_id_p = { .type = 0, }; | |||
| 2309 | create_ppk_id_payload(ppk_id, &ppk_id_p); | |||
| 2310 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 2311 | DBG_log("ppk type: %d", (int) ppk_id_p.type); | |||
| 2312 | 			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); };  | |||
| 2313 | } | |||
| 2314 | ||||
| 2315 | pb_stream ppks; | |||
| 2316 | if (!emit_v2Npl(v2N_PPK_IDENTITY, &sk.pbs, &ppks) || | |||
| 2317 | !emit_unified_ppk_id(&ppk_id_p, &ppks)) { | |||
| 2318 | return STF_INTERNAL_ERROR; | |||
| 2319 | } | |||
| 2320 | close_output_pbs(&ppks); | |||
| 2321 | ||||
| 2322 | 		if (!LIN(POLICY_PPK_INSIST, cc->policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (cc-> policy)) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) {  | |||
| 2323 | if (!ikev2_calc_no_ppk_auth(ike, &ike->sa.st_v2_id_payload.mac_no_ppk_auth, | |||
| 2324 | &ike->sa.st_no_ppk_auth)) { | |||
| 2325 | 				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"); } };  | |||
| 2326 | return STF_FATAL; | |||
| 2327 | } | |||
| 2328 | ||||
| 2329 | 			if (!emit_v2N_hunk(v2N_NO_PPK_AUTH,emit_v2N_bytes(v2N_NO_PPK_AUTH, (pst->st_no_ppk_auth).ptr, (pst->st_no_ppk_auth).len, &sk.pbs)  | |||
| 2330 | 					   pst->st_no_ppk_auth, &sk.pbs)emit_v2N_bytes(v2N_NO_PPK_AUTH, (pst->st_no_ppk_auth).ptr, (pst->st_no_ppk_auth).len, &sk.pbs)) {  | |||
| 2331 | return STF_INTERNAL_ERROR; | |||
| 2332 | } | |||
| 2333 | } | |||
| 2334 | } | |||
| 2335 | ||||
| 2336 | /* | |||
| 2337 | * The initiator: | |||
| 2338 | * | |||
| 2339 | * We sent normal IKEv2_AUTH_RSA but if the policy also allows | |||
| 2340 | * AUTH_NULL, we will send a Notify with NULL_AUTH in separate | |||
| 2341 | * chunk. This is only done on the initiator in IKE_AUTH, and | |||
| 2342 | * not repeated in rekeys. | |||
| 2343 | */ | |||
| 2344 | if (v2_auth_by(ike) == AUTHBY_RSASIG && pc->policy & POLICY_AUTH_NULL((lset_t)1 << (POLICY_AUTH_NULL_IX))) { | |||
| 2345 | /* store in null_auth */ | |||
| 2346 | chunk_t null_auth = NULL_HUNK{ .ptr = ((void*)0), .len = 0, }; | |||
| 2347 | if (!ikev2_create_psk_auth(AUTHBY_NULL, ike, | |||
| 2348 | &ike->sa.st_v2_id_payload.mac, | |||
| 2349 | &null_auth)) { | |||
| 2350 | loglog(RC_LOG_SERIOUS, "Failed to calculate additional NULL_AUTH"); | |||
| 2351 | return STF_FATAL; | |||
| 2352 | } | |||
| 2353 | 		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)) {  | |||
| 2354 | free_chunk_content(&null_auth); | |||
| 2355 | return STF_INTERNAL_ERROR; | |||
| 2356 | } | |||
| 2357 | free_chunk_content(&null_auth); | |||
| 2358 | } | |||
| 2359 | ||||
| 2360 | /* send CP payloads */ | |||
| 2361 | if (pc->modecfg_domains != NULL((void*)0) || pc->modecfg_dns != NULL((void*)0)) { | |||
| 2362 | /* | |||
| 2363 | * XXX: should this be passed the CHILD SA's | |||
| 2364 | * .st_connection? Here IKE and CHILD SAs share a | |||
| 2365 | * connection? | |||
| 2366 | */ | |||
| 2367 | if (!emit_v2_child_configuration_payload(ike->sa.st_connection, | |||
| 2368 | child, &sk.pbs)) { | |||
| 2369 | return STF_INTERNAL_ERROR; | |||
| 2370 | } | |||
| 2371 | } | |||
| 2372 | ||||
| 2373 | if (!close_v2SK_payload(&sk)) { | |||
| 2374 | return STF_INTERNAL_ERROR; | |||
| 2375 | } | |||
| 2376 | close_output_pbs(&rbody); | |||
| 2377 | close_output_pbs(&reply_stream); | |||
| 2378 | ||||
| 2379 | /* | |||
| 2380 | * For AUTH exchange, store the message in the IKE SA. The | |||
| 2381 | * attempt to create the CHILD SA could have failed. | |||
| 2382 | */ | |||
| 2383 | return record_v2SK_message(&reply_stream, &sk, | |||
| 2384 | "sending IKE_AUTH request", | |||
| 2385 | MESSAGE_REQUEST); | |||
| 2386 | } | |||
| 2387 | ||||
| 2388 | #ifdef XAUTH_HAVE_PAM1 | |||
| 2389 | ||||
| 2390 | static xauth_callback_t ikev2_pam_continue; /* type assertion */ | |||
| 2391 | ||||
| 2392 | static void ikev2_pam_continue(struct state *st, | |||
| 2393 | struct msg_digest *md, | |||
| 2394 | const char *name UNUSED__attribute__ ((unused)), | |||
| 2395 | bool_Bool success) | |||
| 2396 | { | |||
| 2397 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 2398 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 2399 | ||||
| 2400 | 	pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 2400}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */  | |||
| 2401 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 2401}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 2402 | ||||
| 2403 | struct ike_sa *ike = pexpect_ike_sa(st); | |||
| 2404 |  	pexpect(ike->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 2404}, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } assertion__; });  | |||
| 2405 | ||||
| 2406 | 	pexpect(st->st_state->kind == STATE_PARENT_R1)({ _Bool assertion__ = st->st_state->kind == STATE_PARENT_R1 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 2406}, "%s", "st->st_state->kind == STATE_PARENT_R1" ); } assertion__; });  | |||
| 2407 | ||||
| 2408 | stf_status stf; | |||
| 2409 | if (success) { | |||
| 2410 | stf = ikev2_parent_inI2outR2_auth_tail(&ike->sa, md, success); | |||
| 2411 | } else { | |||
| 2412 | /* | |||
| 2413 | * XXX: better would be to record the message and | |||
| 2414 | * return STF_ZOMBIFY. | |||
| 2415 | * | |||
| 2416 | * That way compute_v2_state_transition() could send | |||
| 2417 | * the recorded message and then transition the state | |||
| 2418 | * to ZOMBIE (aka *_DEL*). There it can linger while | |||
| 2419 | * dealing with any duplicate IKE_AUTH requests. | |||
| 2420 | */ | |||
| 2421 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2422 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no-data*/, | |||
| 2423 | ENCRYPTED_PAYLOAD); | |||
| 2424 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 2425 | stf = STF_FATAL; /* STF_ZOMBIFY */ | |||
| 2426 | } | |||
| 2427 | ||||
| 2428 | /* replace (*mdp)->st with st ... */ | |||
| 2429 | complete_v2_state_transition(md->st, md, stf); | |||
| 2430 | } | |||
| 2431 | ||||
| 2432 | /* | |||
| 2433 | * In the middle of IKEv2 AUTH exchange, the AUTH payload is verified succsfully. | |||
| 2434 | * Now invoke the PAM helper to authorize connection (based on name only, not password) | |||
| 2435 | * When pam helper is done state will be woken up and continue. | |||
| 2436 | * | |||
| 2437 | * This routine "suspends" MD/ST; once PAM finishes it will be | |||
| 2438 | * unsuspended. | |||
| 2439 | */ | |||
| 2440 | ||||
| 2441 | static stf_status ikev2_start_pam_authorize(struct state *st) | |||
| 2442 | { | |||
| 2443 | id_buf thatidb; | |||
| 2444 | const char *thatid = str_id(&st->st_connection->spd.that.id, &thatidb); | |||
| 2445 | 	libreswan_log("IKEv2: [XAUTH]PAM method requested to authorize '%s'",loglog(RC_LOG, "IKEv2: [XAUTH]PAM method requested to authorize '%s'" , thatid)  | |||
| 2446 | 		      thatid)loglog(RC_LOG, "IKEv2: [XAUTH]PAM method requested to authorize '%s'" , thatid);  | |||
| 2447 | xauth_fork_pam_process(st, | |||
| 2448 | thatid, "password", | |||
| 2449 | "IKEv2", | |||
| 2450 | ikev2_pam_continue); | |||
| 2451 | return STF_SUSPEND; | |||
| 2452 | } | |||
| 2453 | ||||
| 2454 | #endif /* XAUTH_HAVE_PAM */ | |||
| 2455 | ||||
| 2456 | /* | |||
| 2457 | * | |||
| 2458 | *************************************************************** | |||
| 2459 | * PARENT_inI2 ***** | |||
| 2460 | *************************************************************** | |||
| 2461 | * - | |||
| 2462 | * | |||
| 2463 | * | |||
| 2464 | */ | |||
| 2465 | ||||
| 2466 | /* STATE_PARENT_R1: I2 --> R2 | |||
| 2467 | * <-- HDR, SK {IDi, [CERT,] [CERTREQ,] | |||
| 2468 | * [IDr,] AUTH, SAi2, | |||
| 2469 | * TSi, TSr} | |||
| 2470 | * HDR, SK {IDr, [CERT,] AUTH, | |||
| 2471 | * SAr2, TSi, TSr} --> | |||
| 2472 | * | |||
| 2473 | * [Parent SA established] | |||
| 2474 | */ | |||
| 2475 | ||||
| 2476 | static crypto_req_cont_func ikev2_ike_sa_process_auth_request_no_skeyid_continue; /* type assertion */ | |||
| 2477 | ||||
| 2478 | stf_status ikev2_ike_sa_process_auth_request_no_skeyid(struct ike_sa *ike, | |||
| 2479 | struct child_sa *child, | |||
| 2480 | struct msg_digest *md UNUSED__attribute__ ((unused))) | |||
| 2481 | { | |||
| 2482 | 	pexpect(child == NULL)({ _Bool assertion__ = child == ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2482}, "%s", "child == NULL"); } assertion__; });  | |||
| 2483 | struct state *st = &ike->sa; | |||
| 2484 | ||||
| 2485 | /* | |||
| 2486 | * the initiator sent us an encrypted payload. We need to calculate | |||
| 2487 | * our g^xy, and skeyseed values, and then decrypt the payload. | |||
| 2488 | */ | |||
| 2489 | ||||
| 2490 | 	dbg("ikev2 parent inI2outR2: calculating g^{xy} in order to decrypt I2"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ikev2 parent inI2outR2: calculating g^{xy} in order to decrypt I2" ); } };  | |||
| 2491 | ||||
| 2492 | /* initiate calculation of g^xy */ | |||
| 2493 | start_dh_v2(st, "ikev2_inI2outR2 KE", | |||
| 2494 | SA_RESPONDER, | |||
| 2495 | NULL((void*)0), NULL((void*)0), &st->st_ike_spis, | |||
| 2496 | ikev2_ike_sa_process_auth_request_no_skeyid_continue); | |||
| 2497 | return STF_SUSPEND; | |||
| 2498 | } | |||
| 2499 | ||||
| 2500 | static void ikev2_ike_sa_process_auth_request_no_skeyid_continue(struct state *st, | |||
| 2501 | struct msg_digest *md, | |||
| 2502 | struct pluto_crypto_req *r) | |||
| 2503 | { | |||
| 2504 | 	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__, st->st_serialno, st->st_state->name); } }  | |||
| 2505 | 	    __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s: calculating g^{xy}, sending R2" , __func__, st->st_serialno, st->st_state->name); } };  | |||
| 2506 | ||||
| 2507 | 	pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 2507}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */  | |||
| 2508 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 2508}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 2509 | ||||
| 2510 | struct ike_sa *ike = pexpect_ike_sa(st); | |||
| 2511 |  	pexpect(ike->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = ike->sa.st_sa_role == SA_RESPONDER; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 2511}, "%s", "ike->sa.st_sa_role == SA_RESPONDER" ); } assertion__; });  | |||
| 2512 | ||||
| 2513 | 	pexpect(st->st_state->kind == STATE_PARENT_R1)({ _Bool assertion__ = st->st_state->kind == STATE_PARENT_R1 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 2513}, "%s", "st->st_state->kind == STATE_PARENT_R1" ); } assertion__; });  | |||
| 2514 | ||||
| 2515 | /* extract calculated values from r */ | |||
| 2516 | ||||
| 2517 | if (!finish_dh_v2(st, r, FALSE0)) { | |||
| 2518 | /* | |||
| 2519 | * Since dh failed, the channel isn't end-to-end | |||
| 2520 | * encrypted. Send back a clear text notify and then | |||
| 2521 | * abandon the connection. | |||
| 2522 | */ | |||
| 2523 | 		dbg("aborting IKE SA: DH failed"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("aborting IKE SA: DH failed"); } };  | |||
| 2524 | send_v2N_response_from_md(md, v2N_INVALID_SYNTAX, NULL((void*)0)); | |||
| 2525 | /* replace (*mdp)->st with st ... */ | |||
| 2526 | complete_v2_state_transition(md->st, md, STF_FATAL); | |||
| 2527 | return; | |||
| 2528 | } | |||
| 2529 | ||||
| 2530 | ikev2_process_state_packet(pexpect_ike_sa(st), st, md); | |||
| 2531 | } | |||
| 2532 | ||||
| 2533 | static stf_status ikev2_parent_inI2outR2_continue_tail(struct state *st, | |||
| 2534 | struct msg_digest *md); | |||
| 2535 | ||||
| 2536 | stf_status ikev2_ike_sa_process_auth_request(struct ike_sa *ike, | |||
| 2537 | struct child_sa *child, | |||
| 2538 | struct msg_digest *md) | |||
| 2539 | { | |||
| 2540 | /* The connection is "up", start authenticating it */ | |||
| 2541 | 	pexpect(child == NULL)({ _Bool assertion__ = child == ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2541}, "%s", "child == NULL"); } assertion__; });  | |||
| 2542 | 	pexpect(md->st == NULL || md->st == &ike->sa)({ _Bool assertion__ = md->st == ((void*)0) || md->st == &ike->sa; if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2542 }, "%s", "md->st == NULL || md->st == &ike->sa") ; } assertion__; });  | |||
| 2543 | ||||
| 2544 | /* for testing only */ | |||
| 2545 | if (impair.send_no_ikev2_auth) { | |||
| 2546 | log_state(RC_LOG, &ike->sa, | |||
| 2547 | "IMPAIR_SEND_NO_IKEV2_AUTH set - not sending IKE_AUTH packet"); | |||
| 2548 | return STF_IGNORE; | |||
| 2549 | } | |||
| 2550 | ||||
| 2551 | /* | |||
| 2552 | * This log line establishes that the packet's been decrypted | |||
| 2553 | * and now it is being processed for real. | |||
| 2554 | * | |||
| 2555 | * XXX: move this into ikev2.c? | |||
| 2556 | */ | |||
| 2557 | 	LSWLOG(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 (jam_cur_prefix(buf ); buf != ((void*)0); jambuf_to_default_streams(buf, RC_LOG), buf = ((void*)0)) {  | |||
| 2558 | jam(buf, "processing decrypted "); | |||
| 2559 | lswlog_msg_digest(buf, md); | |||
| 2560 | } | |||
| 2561 | ||||
| 2562 | stf_status e = ikev2_parent_inI2outR2_continue_tail(&ike->sa, md); | |||
| 2563 | 	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)) {  | |||
| 2564 | jam(buf, "ikev2_parent_inI2outR2_continue_tail returned "); | |||
| 2565 | jam_v2_stf_status(buf, e); | |||
| 2566 | } | |||
| 2567 | ||||
| 2568 | /* | |||
| 2569 | * if failed OE, delete state completely, no create_child_sa | |||
| 2570 | * allowed so childless parent makes no sense. That is also | |||
| 2571 | * the reason why we send v2N_AUTHENTICATION_FAILED, even | |||
| 2572 | * though authenticated succeeded. It shows the remote end | |||
| 2573 | * we have deleted the SA from our end. | |||
| 2574 | */ | |||
| 2575 | if (e >= STF_FAIL && | |||
| 2576 | (ike->sa.st_connection->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))) { | |||
| 2577 | 		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" ); } };  | |||
| 2578 | 		pexpect(md->st == &ike->sa)({ _Bool assertion__ = md->st == &ike->sa; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2578}, "%s", "md->st == &ike->sa"); } assertion__ ; });  | |||
| 2579 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2580 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2581 | ENCRYPTED_PAYLOAD); | |||
| 2582 | return STF_FATAL; /* STF_ZOMBIFY */ | |||
| 2583 | } | |||
| 2584 | ||||
| 2585 | return e; | |||
| 2586 | } | |||
| 2587 | ||||
| 2588 | static stf_status v2_inI2outR2_post_cert_decode(struct state *st, | |||
| 2589 | struct msg_digest *md); | |||
| 2590 | ||||
| 2591 | static stf_status ikev2_parent_inI2outR2_continue_tail(struct state *st, | |||
| 2592 | struct msg_digest *md) | |||
| 2593 | { | |||
| 2594 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 2594});  | |||
| 2595 | ||||
| 2596 | struct payload_digest *cert_payloads = md->chain[ISAKMP_NEXT_v2CERT]; | |||
| 2597 | if (cert_payloads != NULL((void*)0)) { | |||
| 2598 | submit_cert_decode(ike, st, md, cert_payloads, | |||
| 2599 | v2_inI2outR2_post_cert_decode, | |||
| 2600 | "responder decoding certificates"); | |||
| 2601 | return STF_SUSPEND; | |||
| 2602 | } else { | |||
| 2603 | 		dbg("no certs to decode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no certs to decode"); } };  | |||
| 2604 | ike->sa.st_remote_certs.processed = true1; | |||
| 2605 | ike->sa.st_remote_certs.harmless = true1; | |||
| 2606 | } | |||
| 2607 | return v2_inI2outR2_post_cert_decode(st, md); | |||
| 2608 | } | |||
| 2609 | ||||
| 2610 | static stf_status v2_inI2outR2_post_cert_decode(struct state *st, | |||
| 2611 | struct msg_digest *md) | |||
| 2612 | { | |||
| 2613 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 2613});  | |||
| 2614 | ||||
| 2615 | ikev2_log_parentSA(st); | |||
| 2616 | ||||
| 2617 | struct state *pst = IS_CHILD_SA(md->st)((md->st)->st_clonedfrom != 0) ? | |||
| 2618 | state_with_serialno(md->st->st_clonedfrom) : md->st; | |||
| 2619 | /* going to switch to child st. before that update parent */ | |||
| 2620 | 	if (!LHAS(pst->hidden_variables.st_nat_traversal, NATED_HOST)(((pst->hidden_variables.st_nat_traversal) & ((lset_t) 1 << (NATED_HOST))) != ((lset_t)0)))  | |||
| 2621 | update_ike_endpoints(ike, md); | |||
| 2622 | ||||
| 2623 | nat_traversal_change_port_lookup(md, st); /* shouldn't this be pst? */ | |||
| 2624 | ||||
| 2625 | /* this call might update connection in md->st */ | |||
| 2626 | if (!ikev2_decode_peer_id(md)) { | |||
| 2627 | event_force(EVENT_SA_EXPIRE, st); | |||
| 2628 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 2629 | release_pending_whacks(st, "Authentication failed"); | |||
| 2630 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2631 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no-data*/, | |||
| 2632 | ENCRYPTED_PAYLOAD); | |||
| 2633 | return STF_FATAL; | |||
| 2634 | } | |||
| 2635 | ||||
| 2636 | enum ikev2_auth_method atype = md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method; | |||
| 2637 | if (IS_LIBUNBOUND1 && id_ipseckey_allowed(st, atype)) { | |||
| 2638 | stf_status ret = idi_ipseckey_fetch(md); | |||
| 2639 | if (ret != STF_OK) { | |||
| 2640 | loglog(RC_LOG_SERIOUS, "DNS: IPSECKEY not found or usable"); | |||
| 2641 | return ret; | |||
| 2642 | } | |||
| 2643 | } | |||
| 2644 | ||||
| 2645 | return ikev2_parent_inI2outR2_id_tail(md); | |||
| 2646 | } | |||
| 2647 | ||||
| 2648 | stf_status ikev2_parent_inI2outR2_id_tail(struct msg_digest *md) | |||
| 2649 | { | |||
| 2650 | struct state *const st = md->st; | |||
| 2651 | struct ike_sa *ike = pexpect_ike_sa(st); | |||
| 2652 | lset_t policy = st->st_connection->policy; | |||
| 2653 | bool_Bool found_ppk = FALSE0; | |||
| 2654 | chunk_t null_auth = EMPTY_CHUNK((const chunk_t) { .ptr = ((void*)0), .len = 0 }); | |||
| 2655 | ||||
| 2656 | /* | |||
| 2657 | * The NOTIFY payloads we receive in the IKE_AUTH request are | |||
| 2658 | * either related to the IKE SA, or the Child SA. Here we only | |||
| 2659 | * process the ones related to the IKE SA. | |||
| 2660 | */ | |||
| 2661 | if (md->pbs[PBS_v2N_PPK_IDENTITY] != NULL((void*)0)) { | |||
| 2662 | 		dbg("received PPK_IDENTITY"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received PPK_IDENTITY"); } };  | |||
| 2663 | struct ppk_id_payload payl; | |||
| 2664 | if (!extract_v2N_ppk_identity(md->pbs[PBS_v2N_PPK_IDENTITY], &payl, ike)) { | |||
| 2665 | 			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!" ); } };  | |||
| 2666 | return STF_FATAL; | |||
| 2667 | } | |||
| 2668 | ||||
| 2669 | const chunk_t *ppk = get_ppk_by_id(&payl.ppk_id); | |||
| 2670 | free_chunk_content(&payl.ppk_id); | |||
| 2671 | if (ppk != NULL((void*)0)) { | |||
| 2672 | found_ppk = TRUE1; | |||
| 2673 | } | |||
| 2674 | ||||
| 2675 | 		if (found_ppk && LIN(POLICY_PPK_ALLOW, policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (policy) ) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) {  | |||
| 2676 | ppk_recalculate(ppk, st->st_oakley.ta_prf, | |||
| 2677 | &st->st_skey_d_nss, | |||
| 2678 | &st->st_skey_pi_nss, | |||
| 2679 | &st->st_skey_pr_nss, | |||
| 2680 | st->st_logger); | |||
| 2681 | st->st_ppk_used = TRUE1; | |||
| 2682 | libreswan_log("PPK AUTH calculated as responder")loglog(RC_LOG, "PPK AUTH calculated as responder"); | |||
| 2683 | } else { | |||
| 2684 | 			libreswan_log("ignored received PPK_IDENTITY - connection does not require PPK or PPKID not found")loglog(RC_LOG, "ignored received PPK_IDENTITY - connection does not require PPK or PPKID not found" );  | |||
| 2685 | } | |||
| 2686 | } | |||
| 2687 | if (md->pbs[PBS_v2N_NO_PPK_AUTH] != NULL((void*)0)) { | |||
| 2688 | pb_stream pbs = *md->pbs[PBS_v2N_NO_PPK_AUTH]; | |||
| 2689 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
| 2690 | 		dbg("received NO_PPK_AUTH"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received NO_PPK_AUTH"); } };  | |||
| 2691 | 		if (LIN(POLICY_PPK_INSIST, policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (policy )) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) {  | |||
| 2692 | 			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" ); } };  | |||
| 2693 | } else { | |||
| 2694 | ||||
| 2695 | chunk_t no_ppk_auth = alloc_chunk(len, "NO_PPK_AUTH"); | |||
| 2696 | ||||
| 2697 | if (!in_raw(no_ppk_auth.ptr, len, &pbs, "NO_PPK_AUTH extract")) { | |||
| 2698 | loglog(RC_LOG_SERIOUS, "Failed to extract %zd bytes of NO_PPK_AUTH from Notify payload", len); | |||
| 2699 | free_chunk_content(&no_ppk_auth); | |||
| 2700 | return STF_FATAL; | |||
| 2701 | } | |||
| 2702 | free_chunk_content(&st->st_no_ppk_auth); /* in case this was already occupied */ | |||
| 2703 | st->st_no_ppk_auth = no_ppk_auth; | |||
| 2704 | } | |||
| 2705 | } | |||
| 2706 | if (md->pbs[PBS_v2N_MOBIKE_SUPPORTED] != NULL((void*)0)) { | |||
| 2707 | 		dbg("received v2N_MOBIKE_SUPPORTED %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", st->st_sent_mobike ? "and sent" : "while it did not sent"); } }  | |||
| 2708 | 		    st->st_sent_mobike ?{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", st->st_sent_mobike ? "and sent" : "while it did not sent"); } }  | |||
| 2709 | 		    "and sent" : "while it did not sent"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", st->st_sent_mobike ? "and sent" : "while it did not sent"); } };  | |||
| 2710 | st->st_seen_mobike = true1; | |||
| 2711 | } | |||
| 2712 | if (md->pbs[PBS_v2N_NULL_AUTH] != NULL((void*)0)) { | |||
| 2713 | pb_stream pbs = *md->pbs[PBS_v2N_NULL_AUTH]; | |||
| 2714 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
| 2715 | ||||
| 2716 | 		dbg("received v2N_NULL_AUTH"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_NULL_AUTH"); } };  | |||
| 2717 | null_auth = alloc_chunk(len, "NULL_AUTH"); | |||
| 2718 | diag_t d = pbs_in_raw(&pbs, null_auth.ptr, len, "NULL_AUTH extract"); | |||
| 2719 | if (d != NULL((void*)0)) { | |||
| 2720 | log_diag(RC_LOG_SERIOUS, ike->sa.st_logger, &d, | |||
| 2721 | "failed to extract %zd bytes of NULL_AUTH from Notify payload: ", len); | |||
| 2722 | free_chunk_content(&null_auth); | |||
| 2723 | return STF_FATAL; | |||
| 2724 | } | |||
| 2725 | } | |||
| 2726 | st->st_seen_initialc = md->pbs[PBS_v2N_INITIAL_CONTACT] != NULL((void*)0); | |||
| 2727 | ||||
| 2728 | /* | |||
| 2729 | * If we found proper PPK ID and policy allows PPK, use that. | |||
| 2730 | * Otherwise use NO_PPK_AUTH | |||
| 2731 | */ | |||
| 2732 | 	if (found_ppk && LIN(POLICY_PPK_ALLOW, policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (policy) ) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX)))))  | |||
| 2733 | free_chunk_content(&st->st_no_ppk_auth); | |||
| 2734 | ||||
| 2735 | 	if (!found_ppk && LIN(POLICY_PPK_INSIST, policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (policy )) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) {  | |||
| 2736 | log_state(RC_LOG_SERIOUS, &ike->sa, "Requested PPK_ID not found and connection requires a valid PPK"); | |||
| 2737 | free_chunk_content(&null_auth); | |||
| 2738 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2739 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2740 | ENCRYPTED_PAYLOAD); | |||
| 2741 | return STF_FATAL; | |||
| 2742 | } | |||
| 2743 | ||||
| 2744 | /* calculate hash of IDi for AUTH below */ | |||
| 2745 | struct crypt_mac idhash_in = v2_id_hash(ike, "IDi verify hash", | |||
| 2746 | "IDi", pbs_in_as_shunk(&md->chain[ISAKMP_NEXT_v2IDi]->pbs), | |||
| 2747 | "skey_pi", st->st_skey_pi_nss); | |||
| 2748 | ||||
| 2749 | /* process CERTREQ payload */ | |||
| 2750 | if (md->chain[ISAKMP_NEXT_v2CERTREQ] != NULL((void*)0)) { | |||
| 2751 | 		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" ); } };  | |||
| 2752 | ikev2_decode_cr(md); | |||
| 2753 | } | |||
| 2754 | ||||
| 2755 | /* process AUTH payload */ | |||
| 2756 | ||||
| 2757 | enum keyword_authby that_authby = st->st_connection->spd.that.authby; | |||
| 2758 | ||||
| 2759 | 	passert(that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET){ _Bool assertion__ = that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET; if (!assertion__) { lsw_passert_fail((where_t ) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2759 }, "%s", "that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET" ); } };  | |||
| 2760 | ||||
| 2761 | if (!ike->sa.st_ppk_used && ike->sa.st_no_ppk_auth.ptr != NULL((void*)0)) { | |||
| 2762 | /* | |||
| 2763 | * we didn't recalculate keys with PPK, but we found NO_PPK_AUTH | |||
| 2764 | * (meaning that initiator did use PPK) so we try to verify NO_PPK_AUTH. | |||
| 2765 | */ | |||
| 2766 | 		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."); } };  | |||
| 2767 | /* making a dummy pb_stream so we could pass it to v2_check_auth */ | |||
| 2768 | pb_stream pbs_no_ppk_auth; | |||
| 2769 | pb_stream pbs = md->chain[ISAKMP_NEXT_v2AUTH]->pbs; | |||
| 2770 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
| 2771 | init_pbs(&pbs_no_ppk_auth, ike->sa.st_no_ppk_auth.ptr, len, "pb_stream for verifying NO_PPK_AUTH"); | |||
| 2772 | ||||
| 2773 | if (!v2_check_auth(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
| 2774 | ike, &idhash_in, &pbs_no_ppk_auth, | |||
| 2775 | ike->sa.st_connection->spd.that.authby, "no-PPK-auth")) { | |||
| 2776 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2777 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2778 | ENCRYPTED_PAYLOAD); | |||
| 2779 | free_chunk_content(&null_auth); /* ??? necessary? */ | |||
| 2780 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 2781 | return STF_FATAL; | |||
| 2782 | } | |||
| 2783 | 		dbg("NO_PPK_AUTH verified"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NO_PPK_AUTH verified"); } };  | |||
| 2784 | } else { | |||
| 2785 | 		bool_Bool policy_null = LIN(POLICY_AUTH_NULL, st->st_connection->policy)(((((lset_t)1 << (POLICY_AUTH_NULL_IX))) & (st-> st_connection->policy)) == (((lset_t)1 << (POLICY_AUTH_NULL_IX ))));  | |||
| 2786 | 		bool_Bool policy_rsasig = LIN(POLICY_RSASIG, st->st_connection->policy)(((((lset_t)1 << (POLICY_RSASIG_IX))) & (st->st_connection ->policy)) == (((lset_t)1 << (POLICY_RSASIG_IX))));  | |||
| 2787 | ||||
| 2788 | /* | |||
| 2789 | * if received NULL_AUTH in Notify payload and we only allow NULL Authentication, | |||
| 2790 | * proceed with verifying that payload, else verify AUTH normally | |||
| 2791 | */ | |||
| 2792 | if (null_auth.ptr != NULL((void*)0) && policy_null && !policy_rsasig) { | |||
| 2793 | /* making a dummy pb_stream so we could pass it to v2_check_auth */ | |||
| 2794 | pb_stream pbs_null_auth; | |||
| 2795 | size_t len = null_auth.len; | |||
| 2796 | ||||
| 2797 | 			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" ); } };  | |||
| 2798 | init_pbs(&pbs_null_auth, null_auth.ptr, len, "pb_stream for verifying NULL_AUTH"); | |||
| 2799 | if (!v2_check_auth(IKEv2_AUTH_NULL, ike, &idhash_in, | |||
| 2800 | &pbs_null_auth, AUTHBY_NULL, "NULL_auth from Notify Payload")) { | |||
| 2801 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2802 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2803 | ENCRYPTED_PAYLOAD); | |||
| 2804 | free_chunk_content(&null_auth); | |||
| 2805 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 2806 | return STF_FATAL; | |||
| 2807 | } | |||
| 2808 | 			dbg("NULL_AUTH verified"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("NULL_AUTH verified"); } };  | |||
| 2809 | } else { | |||
| 2810 | 			dbg("verifying AUTH payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("verifying AUTH payload"); } };  | |||
| 2811 | if (!v2_check_auth(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
| 2812 | ike, &idhash_in, &md->chain[ISAKMP_NEXT_v2AUTH]->pbs, | |||
| 2813 | st->st_connection->spd.that.authby, "I2 Auth Payload")) { | |||
| 2814 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2815 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2816 | ENCRYPTED_PAYLOAD); | |||
| 2817 | free_chunk_content(&null_auth); | |||
| 2818 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 2819 | return STF_FATAL; | |||
| 2820 | } | |||
| 2821 | } | |||
| 2822 | } | |||
| 2823 | ||||
| 2824 | /* AUTH succeeded */ | |||
| 2825 | ||||
| 2826 | free_chunk_content(&null_auth); | |||
| 2827 | ||||
| 2828 | #ifdef XAUTH_HAVE_PAM1 | |||
| 2829 | if (st->st_connection->policy & POLICY_IKEV2_PAM_AUTHORIZE((lset_t)1 << (POLICY_IKEV2_PAM_AUTHORIZE_IX))) | |||
| 2830 | return ikev2_start_pam_authorize(st); | |||
| 2831 | #endif | |||
| 2832 | return ikev2_parent_inI2outR2_auth_tail(st, md, TRUE1); | |||
| 2833 | } | |||
| 2834 | ||||
| 2835 | static v2_auth_signature_cb ikev2_parent_inI2outR2_auth_signature_continue; /* type check */ | |||
| 2836 | ||||
| 2837 | static stf_status ikev2_parent_inI2outR2_auth_tail(struct state *st, | |||
| 2838 | struct msg_digest *md, | |||
| 2839 | bool_Bool pam_status) | |||
| 2840 | { | |||
| 2841 | struct connection *const c = st->st_connection; | |||
| 2842 | struct ike_sa *ike = pexpect_ike_sa(st); | |||
| 2843 | ||||
| 2844 | if (!pam_status) { | |||
| 2845 | /* | |||
| 2846 | * TBD: send this notification encrypted because the | |||
| 2847 | * AUTH payload succeed | |||
| 2848 | */ | |||
| 2849 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2850 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2851 | ENCRYPTED_PAYLOAD); | |||
| 2852 | return STF_FATAL; | |||
| 2853 | } | |||
| 2854 | ||||
| 2855 | /* | |||
| 2856 | * Construct the IDr payload and store it in state so that it | |||
| 2857 | * can be emitted later. Then use that to construct the | |||
| 2858 | * "MACedIDFor[R]". | |||
| 2859 | * | |||
| 2860 | * Code assumes that struct ikev2_id's "IDType|RESERVED" is | |||
| 2861 | * laid out the same as the packet. | |||
| 2862 | */ | |||
| 2863 | ||||
| 2864 | if (ike->sa.st_peer_wants_null) { | |||
| 2865 | /* make it the Null ID */ | |||
| 2866 | ike->sa.st_v2_id_payload.header.isai_type = ID_NULL; | |||
| 2867 | ike->sa.st_v2_id_payload.data = empty_chunk; | |||
| 2868 | } else { | |||
| 2869 | shunk_t data; | |||
| 2870 | ike->sa.st_v2_id_payload.header = build_v2_id_payload(&c->spd.this, &data, | |||
| 2871 | "my IDr", | |||
| 2872 | ike->sa.st_logger); | |||
| 2873 | 		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"); });  | |||
| 2874 | } | |||
| 2875 | ||||
| 2876 | /* will be signed in auth payload */ | |||
| 2877 | ike->sa.st_v2_id_payload.mac = v2_hash_id_payload("IDr", ike, "st_skey_pr_nss", | |||
| 2878 | ike->sa.st_skey_pr_nss); | |||
| 2879 | ||||
| 2880 | { | |||
| 2881 | enum keyword_authby authby = v2_auth_by(ike); | |||
| 2882 | enum ikev2_auth_method auth_method = v2_auth_method(ike, authby); | |||
| 2883 | switch (auth_method) { | |||
| 2884 | case IKEv2_AUTH_RSA: | |||
| 2885 | { | |||
| 2886 | const struct hash_desc *hash_algo = &ike_alg_hash_sha1; | |||
| 2887 | struct crypt_mac hash_to_sign = | |||
| 2888 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
| 2889 | hash_algo, LOCAL_PERSPECTIVE); | |||
| 2890 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
| 2891 | authby, auth_method, | |||
| 2892 | ikev2_parent_inI2outR2_auth_signature_continue)) { | |||
| 2893 | 				dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } };  | |||
| 2894 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2895 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2896 | ENCRYPTED_PAYLOAD); | |||
| 2897 | return STF_FATAL; | |||
| 2898 | } | |||
| 2899 | return STF_SUSPEND; | |||
| 2900 | } | |||
| 2901 | case IKEv2_AUTH_DIGSIG: | |||
| 2902 | { | |||
| 2903 | const struct hash_desc *hash_algo = v2_auth_negotiated_signature_hash(ike); | |||
| 2904 | if (hash_algo == NULL((void*)0)) { | |||
| 2905 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2906 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2907 | ENCRYPTED_PAYLOAD); | |||
| 2908 | return STF_FATAL; | |||
| 2909 | } | |||
| 2910 | struct crypt_mac hash_to_sign = | |||
| 2911 | v2_calculate_sighash(ike, &ike->sa.st_v2_id_payload.mac, | |||
| 2912 | hash_algo, LOCAL_PERSPECTIVE); | |||
| 2913 | if (!submit_v2_auth_signature(ike, &hash_to_sign, hash_algo, | |||
| 2914 | authby, auth_method, | |||
| 2915 | ikev2_parent_inI2outR2_auth_signature_continue)) { | |||
| 2916 | 				dbg("submit_v2_auth_signature() died, fatal"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("submit_v2_auth_signature() died, fatal"); } };  | |||
| 2917 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 2918 | v2N_AUTHENTICATION_FAILED, NULL((void*)0)/*no data*/, | |||
| 2919 | ENCRYPTED_PAYLOAD); | |||
| 2920 | return STF_FATAL; | |||
| 2921 | } | |||
| 2922 | return STF_SUSPEND; | |||
| 2923 | } | |||
| 2924 | case IKEv2_AUTH_PSK: | |||
| 2925 | case IKEv2_AUTH_NULL: | |||
| 2926 | { | |||
| 2927 | struct hash_signature sig = { .len = 0, }; | |||
| 2928 | return ikev2_parent_inI2outR2_auth_signature_continue(ike, md, &sig); | |||
| 2929 | } | |||
| 2930 | default: | |||
| 2931 | log_state(RC_LOG, st, | |||
| 2932 | "authentication method %s not supported", | |||
| 2933 | enum_name(&ikev2_auth_names, auth_method)); | |||
| 2934 | return STF_FATAL; | |||
| 2935 | } | |||
| 2936 | } | |||
| 2937 | } | |||
| 2938 | ||||
| 2939 | /* | |||
| 2940 | * Deal with either CP or TS. | |||
| 2941 | * | |||
| 2942 | * A CREATE_CHILD_SA can, technically, include a CP (Configuration) | |||
| 2943 | * payload. However no one does it. Allow it here so that the code | |||
| 2944 | * paths are consistent (and it seems that pluto has supported it). | |||
| 2945 | */ | |||
| 2946 | ||||
| 2947 | static bool_Bool assign_child_responder_client(struct ike_sa *ike, | |||
| 2948 | struct child_sa *child, | |||
| 2949 | struct msg_digest *md) | |||
| 2950 | { | |||
| 2951 | 	pexpect(md->st == &child->sa)({ _Bool assertion__ = md->st == &child->sa; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2951}, "%s", "md->st == &child->sa"); } assertion__ ; });  | |||
| 2952 | struct connection *c = child->sa.st_connection; | |||
| 2953 | ||||
| 2954 | if (c->pool != NULL((void*)0) && md->chain[ISAKMP_NEXT_v2CP] != NULL((void*)0)) { | |||
| 2955 | struct spd_route *spd = &child->sa.st_connection->spd; | |||
| 2956 | /* | |||
| 2957 | * See ikev2-hostpair-02 where the connection is | |||
| 2958 | * constantly clawed back as the SA keeps trying to | |||
| 2959 | * establish / replace / rekey. | |||
| 2960 | */ | |||
| 2961 | err_t e = lease_that_address(c, md->st); | |||
| 2962 | if (e != NULL((void*)0)) { | |||
| 2963 | log_state(RC_LOG, &child->sa, "ikev2 lease_an_address failure %s", e); | |||
| 2964 | /* XXX: record what? */ | |||
| 2965 | record_v2N_response(child->sa.st_logger, ike, md, | |||
| 2966 | v2N_INTERNAL_ADDRESS_FAILURE, NULL((void*)0)/*no data*/, | |||
| 2967 | ENCRYPTED_PAYLOAD); | |||
| 2968 | return false0; | |||
| 2969 | } | |||
| 2970 | child->sa.st_ts_this = ikev2_end_to_ts(&spd->this); | |||
| 2971 | child->sa.st_ts_that = ikev2_end_to_ts(&spd->that); | |||
| 2972 | } else { | |||
| 2973 | if (!v2_process_ts_request(child, md)) { | |||
| 2974 | /* already logged? */ | |||
| 2975 | record_v2N_response(child->sa.st_logger, ike, md, | |||
| 2976 | v2N_TS_UNACCEPTABLE, NULL((void*)0)/*no data*/, | |||
| 2977 | ENCRYPTED_PAYLOAD); | |||
| 2978 | return false0; | |||
| 2979 | } | |||
| 2980 | } | |||
| 2981 | return true1; | |||
| 2982 | } | |||
| 2983 | ||||
| 2984 | /* | |||
| 2985 | * The caller could have done the linux_audit_conn() call, except one case | |||
| 2986 | * here deletes the state before returning an STF error | |||
| 2987 | */ | |||
| 2988 | ||||
| 2989 | static stf_status ike_auth_child_responder(struct ike_sa *ike, | |||
| 2990 | struct child_sa **child_out, | |||
| 2991 | struct msg_digest *md) | |||
| 2992 | { | |||
| 2993 | 	pexpect(md->st != NULL)({ _Bool assertion__ = md->st != ((void*)0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2993}, "%s", "md->st != NULL"); } assertion__; } );  | |||
| 2994 | 	pexpect(md->st == &ike->sa)({ _Bool assertion__ = md->st == &ike->sa; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 2994}, "%s", "md->st == &ike->sa"); } assertion__ ; }); /* passed in parent */  | |||
| 2995 | struct connection *c = md->st->st_connection; | |||
| 2996 | 	pexpect(md->hdr.isa_xchg == ISAKMP_v2_IKE_AUTH)({ _Bool assertion__ = md->hdr.isa_xchg == ISAKMP_v2_IKE_AUTH ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 2996}, "%s", "md->hdr.isa_xchg == ISAKMP_v2_IKE_AUTH" ); } assertion__; }); /* redundant */  | |||
| 2997 | ||||
| 2998 | struct child_sa *child = new_v2_child_state(ike, IPSEC_SA, SA_RESPONDER, | |||
| 2999 | STATE_V2_IKE_AUTH_CHILD_R0, | |||
| 3000 | null_fd((struct fd *) ((void*)0))); | |||
| 3001 | update_state_connection(&child->sa, c); | |||
| 3002 | 	binlog_refresh_state(&child->sa)binlog_state((&child->sa), (&child->sa)->st_state ->kind);  | |||
| 3003 | ||||
| 3004 | /* | |||
| 3005 | * XXX: This is to hack around the broken responder code that | |||
| 3006 | * switches from the IKE SA to the CHILD SA before sending the | |||
| 3007 | * reply. Instead, because the CHILD SA can fail, the IKE SA | |||
| 3008 | * should be the one processing the message? | |||
| 3009 | */ | |||
| 3010 | 	v2_msgid_switch_responder_to_child(ike, child, md, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 3010});  | |||
| 3011 | ||||
| 3012 | if (!assign_child_responder_client(ike, child, md)) { | |||
| 3013 | /* already logged; already recorded */ | |||
| 3014 | /* | |||
| 3015 | * XXX: while the CHILD SA failed, the IKE SA should | |||
| 3016 | * continue to exist. This STF_FAIL will blame MD->ST | |||
| 3017 | * aka the IKE SA. | |||
| 3018 | */ | |||
| 3019 | 		v2_msgid_switch_responder_from_aborted_child(ike, &child, md, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 3019});  | |||
| 3020 | return STF_FAIL; /* XXX: better? */ | |||
| 3021 | } | |||
| 3022 | *child_out = child; | |||
| 3023 | return STF_OK; | |||
| 3024 | } | |||
| 3025 | ||||
| 3026 | static stf_status ikev2_parent_inI2outR2_auth_signature_continue(struct ike_sa *ike, | |||
| 3027 | struct msg_digest *md, | |||
| 3028 | const struct hash_signature *auth_sig) | |||
| 3029 | { | |||
| 3030 | struct connection *c = ike->sa.st_connection; | |||
| 3031 | struct state *st = &ike->sa; /* avoid rename for now */ | |||
| 3032 | /* | |||
| 3033 | * Now create child state. | |||
| 3034 | * As we will switch to child state, force the parent to the | |||
| 3035 | * new state now. | |||
| 3036 | * | |||
| 3037 | * XXX: Danger! md->svm points to a state transition that | |||
| 3038 | * mashes the IKE SA's initial state in and the CHILD SA's | |||
| 3039 | * final state. Hence, the need to explicitly force the final | |||
| 3040 | * IKE SA state. There should instead be separate state | |||
| 3041 | * transitions for the IKE and CHILD SAs and then have the IKE | |||
| 3042 | * SA invoke the CHILD SA's transition. | |||
| 3043 | */ | |||
| 3044 | 	pexpect(md->svm->next_state == STATE_V2_ESTABLISHED_CHILD_SA)({ _Bool assertion__ = md->svm->next_state == STATE_V2_ESTABLISHED_CHILD_SA ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 3044}, "%s", "md->svm->next_state == STATE_V2_ESTABLISHED_CHILD_SA" ); } assertion__; });  | |||
| 3045 | ikev2_ike_sa_established(ike, md->svm, STATE_V2_ESTABLISHED_IKE_SA); | |||
| 3046 | ||||
| 3047 | 	if (LHAS(st->hidden_variables.st_nat_traversal, NATED_HOST)(((st->hidden_variables.st_nat_traversal) & ((lset_t)1 << (NATED_HOST))) != ((lset_t)0))) {  | |||
| 3048 | /* ensure we run keepalives if needed */ | |||
| 3049 | if (c->nat_keepalive) { | |||
| 3050 | /* XXX: just trigger this event? */ | |||
| 3051 | nat_traversal_ka_event(null_fd((struct fd *) ((void*)0))); | |||
| 3052 | } | |||
| 3053 | } | |||
| 3054 | ||||
| 3055 | /* send response */ | |||
| 3056 | 	if (LIN(POLICY_MOBIKE, c->policy)(((((lset_t)1 << (POLICY_MOBIKE_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_MOBIKE_IX)))) && st->st_seen_mobike) {  | |||
| 3057 | if (c->spd.that.host_type == KH_ANY) { | |||
| 3058 | /* only allow %any connection to mobike */ | |||
| 3059 | st->st_sent_mobike = TRUE1; | |||
| 3060 | } else { | |||
| 3061 | 			libreswan_log("not responding with v2N_MOBIKE_SUPPORTED, that end is not %%any")loglog(RC_LOG, "not responding with v2N_MOBIKE_SUPPORTED, that end is not %%any" );  | |||
| 3062 | } | |||
| 3063 | } | |||
| 3064 | ||||
| 3065 | bool_Bool send_redirect = FALSE0; | |||
| 3066 | ||||
| 3067 | if (st->st_seen_redirect_sup && | |||
| 3068 | 	    (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 )))) ||  | |||
| 3069 | 	     (!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 )))) &&  | |||
| 3070 | require_ddos_cookies()))) { | |||
| 3071 | if (c->redirect_to == NULL((void*)0)) { | |||
| 3072 | loglog(RC_LOG_SERIOUS, "redirect-to is not specified, can't redirect requests"); | |||
| 3073 | } else { | |||
| 3074 | send_redirect = TRUE1; | |||
| 3075 | } | |||
| 3076 | } | |||
| 3077 | ||||
| 3078 | /* make sure HDR is at start of a clean buffer */ | |||
| 3079 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
| 3080 | reply_buffer, sizeof(reply_buffer), | |||
| 3081 | ike->sa.st_logger); | |||
| 3082 | ||||
| 3083 | /* HDR out */ | |||
| 3084 | ||||
| 3085 | 	pb_stream rbody = open_v2_message(&reply_stream, ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 3085}),  | |||
| 3086 | md /* response */, | |||
| 3087 | ISAKMP_v2_IKE_AUTH); | |||
| 3088 | ||||
| 3089 | /* decide to send CERT payload before we generate IDr */ | |||
| 3090 | bool_Bool send_cert = ikev2_send_cert_decision(st); | |||
| 3091 | ||||
| 3092 | /* insert an Encryption payload header */ | |||
| 3093 | ||||
| 3094 | v2SK_payload_t sk = open_v2SK_payload(st->st_logger, &rbody, ike); | |||
| 3095 | if (!pbs_ok(&sk.pbs)((&sk.pbs)->start != ((void*)0))) { | |||
| 3096 | return STF_INTERNAL_ERROR; | |||
| 3097 | } | |||
| 3098 | ||||
| 3099 | if (impair.add_unknown_v2_payload_to_sk == ISAKMP_v2_IKE_AUTH) { | |||
| 3100 | if (!emit_v2UNKNOWN("SK reply", | |||
| 3101 | impair.add_unknown_v2_payload_to_sk, | |||
| 3102 | &sk.pbs)) { | |||
| 3103 | return STF_INTERNAL_ERROR; | |||
| 3104 | } | |||
| 3105 | } | |||
| 3106 | ||||
| 3107 | /* send any NOTIFY payloads */ | |||
| 3108 | if (st->st_sent_mobike) { | |||
| 3109 | if (!emit_v2N(v2N_MOBIKE_SUPPORTED, &sk.pbs)) | |||
| 3110 | return STF_INTERNAL_ERROR; | |||
| 3111 | } | |||
| 3112 | ||||
| 3113 | if (st->st_ppk_used) { | |||
| 3114 | if (!emit_v2N(v2N_PPK_IDENTITY, &sk.pbs)) | |||
| 3115 | return STF_INTERNAL_ERROR; | |||
| 3116 | } | |||
| 3117 | ||||
| 3118 | if (send_redirect) { | |||
| 3119 | if (!emit_redirect_notification(shunk1(c->redirect_to), &sk.pbs)) | |||
| 3120 | return STF_INTERNAL_ERROR; | |||
| 3121 | ||||
| 3122 | st->st_sent_redirect = TRUE1; /* mark that we have sent REDIRECT in IKE_AUTH */ | |||
| 3123 | } | |||
| 3124 | ||||
| 3125 | 	if (LIN(POLICY_TUNNEL, c->policy)(((((lset_t)1 << (POLICY_TUNNEL_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_TUNNEL_IX)))) == LEMPTY((lset_t)0) && st->st_seen_use_transport) {  | |||
| 3126 | if (!emit_v2N(v2N_USE_TRANSPORT_MODE, &sk.pbs)) | |||
| 3127 | return STF_INTERNAL_ERROR; | |||
| 3128 | } | |||
| 3129 | ||||
| 3130 | if (!emit_v2N_compression(st, st->st_seen_use_ipcomp, &sk.pbs)) | |||
| 3131 | return STF_INTERNAL_ERROR; | |||
| 3132 | ||||
| 3133 | if (c->send_no_esp_tfc) { | |||
| 3134 | if (!emit_v2N(v2N_ESP_TFC_PADDING_NOT_SUPPORTED, &sk.pbs)) | |||
| 3135 | return STF_INTERNAL_ERROR; | |||
| 3136 | } | |||
| 3137 | ||||
| 3138 | /* send out the IDr payload */ | |||
| 3139 | ||||
| 3140 | { | |||
| 3141 | pb_stream r_id_pbs; | |||
| 3142 | if (!out_struct(&ike->sa.st_v2_id_payload.header, | |||
| 3143 | &ikev2_id_r_desc, &sk.pbs, &r_id_pbs) || | |||
| 3144 | 		    !pbs_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)) { log_diag(RC_LOG_SERIOUS , outs_->out_logger, &d_, "%s", ""); } d_ == ((void*)0 ); })  | |||
| 3145 | 				  &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)) { log_diag(RC_LOG_SERIOUS , outs_->out_logger, &d_, "%s", ""); } d_ == ((void*)0 ); }))  | |||
| 3146 | return STF_INTERNAL_ERROR; | |||
| 3147 | close_output_pbs(&r_id_pbs); | |||
| 3148 | } | |||
| 3149 | ||||
| 3150 | 	dbg("assembled IDr payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("assembled IDr payload"); } };  | |||
| 3151 | ||||
| 3152 | /* | |||
| 3153 | * send CERT payload RFC 4306 3.6, 1.2:([CERT,] ) | |||
| 3154 | * upon which our received I2 CERTREQ is ignored, | |||
| 3155 | * but ultimately should go into the CERT decision | |||
| 3156 | */ | |||
| 3157 | if (send_cert) { | |||
| 3158 | stf_status certstat = ikev2_send_cert(st, &sk.pbs); | |||
| 3159 | if (certstat != STF_OK) | |||
| 3160 | return certstat; | |||
| 3161 | } | |||
| 3162 | ||||
| 3163 | /* authentication good, see if there is a child SA being proposed */ | |||
| 3164 | unsigned int auth_np; | |||
| 3165 | ||||
| 3166 | if (md->chain[ISAKMP_NEXT_v2SA] == NULL((void*)0) || | |||
| 3167 | md->chain[ISAKMP_NEXT_v2TSi] == NULL((void*)0) || | |||
| 3168 | md->chain[ISAKMP_NEXT_v2TSr] == NULL((void*)0)) { | |||
| 3169 | /* initiator didn't propose anything. Weird. Try unpending our end. */ | |||
| 3170 | /* UNPEND XXX */ | |||
| 3171 | if ((c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) == LEMPTY((lset_t)0)) { | |||
| 3172 | libreswan_log("No CHILD SA proposals received.")loglog(RC_LOG, "No CHILD SA proposals received."); | |||
| 3173 | } else { | |||
| 3174 | 			dbg("no CHILD SA proposals received"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no CHILD SA proposals received"); } };  | |||
| 3175 | } | |||
| 3176 | auth_np = ISAKMP_NEXT_v2NONE; | |||
| 3177 | } else { | |||
| 3178 | 		dbg("CHILD SA proposals received"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("CHILD SA proposals received"); } };  | |||
| 3179 | auth_np = (c->pool != NULL((void*)0) && md->chain[ISAKMP_NEXT_v2CP] != NULL((void*)0)) ? | |||
| 3180 | ISAKMP_NEXT_v2CP : ISAKMP_NEXT_v2SA; | |||
| 3181 | } | |||
| 3182 | ||||
| 3183 | 	dbg("going to assemble AUTH payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("going to assemble AUTH payload"); } };  | |||
| 3184 | ||||
| 3185 | /* now send AUTH payload */ | |||
| 3186 | ||||
| 3187 | if (!emit_v2_auth(ike, auth_sig, &ike->sa.st_v2_id_payload.mac, &sk.pbs)) { | |||
| 3188 | return STF_INTERNAL_ERROR; | |||
| 3189 | } | |||
| 3190 | ||||
| 3191 | if (auth_np == ISAKMP_NEXT_v2SA || auth_np == ISAKMP_NEXT_v2CP) { | |||
| 3192 | /* must have enough to build an CHILD_SA */ | |||
| 3193 | struct child_sa *child = NULL((void*)0); | |||
| 3194 | stf_status ret; | |||
| 3195 | ret = ike_auth_child_responder(ike, &child, md); | |||
| 3196 | if (ret != STF_OK) { | |||
| 3197 | 			pexpect(child == NULL)({ _Bool assertion__ = child == ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3197}, "%s", "child == NULL"); } assertion__; });  | |||
| 3198 | 			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)) {  | |||
| 3199 | jam(buf, "ike_auth_child_responder() returned "); | |||
| 3200 | jam_v2_stf_status(buf, ret); | |||
| 3201 | } | |||
| 3202 | return ret; /* we should continue building a valid reply packet */ | |||
| 3203 | } | |||
| 3204 | 		pexpect(child != NULL)({ _Bool assertion__ = child != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3204}, "%s", "child != NULL"); } assertion__; });  | |||
| 3205 | ret = ikev2_child_sa_respond(ike, child, md, &sk.pbs, | |||
| 3206 | ISAKMP_v2_IKE_AUTH); | |||
| 3207 | /* note: st: parent; md->st: child */ | |||
| 3208 | if (ret != STF_OK) { | |||
| 3209 | 			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)) {  | |||
| 3210 | jam(buf, "ikev2_child_sa_respond returned "); | |||
| 3211 | jam_v2_stf_status(buf, ret); | |||
| 3212 | } | |||
| 3213 | return ret; /* we should continue building a valid reply packet */ | |||
| 3214 | } | |||
| 3215 | } | |||
| 3216 | ||||
| 3217 | if (!close_v2SK_payload(&sk)) { | |||
| 3218 | return STF_INTERNAL_ERROR; | |||
| 3219 | } | |||
| 3220 | close_output_pbs(&rbody); | |||
| 3221 | close_output_pbs(&reply_stream); | |||
| 3222 | ||||
| 3223 | /* | |||
| 3224 | * For AUTH exchange, store the message in the IKE SA. | |||
| 3225 | * The attempt to create the CHILD SA could have | |||
| 3226 | * failed. | |||
| 3227 | */ | |||
| 3228 | return record_v2SK_message(&reply_stream, &sk, | |||
| 3229 | "replying to IKE_AUTH request", | |||
| 3230 | MESSAGE_RESPONSE); | |||
| 3231 | } | |||
| 3232 | ||||
| 3233 | stf_status ikev2_process_child_sa_pl(struct ike_sa *ike, struct child_sa *child, | |||
| 3234 | struct msg_digest *md, bool_Bool expect_accepted_proposal) | |||
| 3235 | { | |||
| 3236 | struct connection *c = child->sa.st_connection; | |||
| 3237 | struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_v2SA]; | |||
| 3238 | enum isakmp_xchg_types isa_xchg = md->hdr.isa_xchg; | |||
| 3239 | struct ipsec_proto_info *proto_info = | |||
| 3240 | ikev2_child_sa_proto_info(child, c->policy); | |||
| 3241 | stf_status ret; | |||
| 3242 | ||||
| 3243 | const char *what; | |||
| 3244 | struct ikev2_proposals *child_proposals; | |||
| 3245 | if (isa_xchg == ISAKMP_v2_CREATE_CHILD_SA) { | |||
| 3246 | if (child->sa.st_state->kind == STATE_V2_NEW_CHILD_I1) { | |||
| 3247 | what = "CREATE_CHILD_SA initiator accepting remote ESP/AH proposal"; | |||
| 3248 | } else { | |||
| 3249 | what = "CREATE_CHILD_SA responder matching remote ESP/AH proposals"; | |||
| 3250 | } | |||
| 3251 | const struct dh_desc *default_dh = (c->policy & POLICY_PFS((lset_t)1 << (POLICY_PFS_IX))) != LEMPTY((lset_t)0) | |||
| 3252 | ? ike->sa.st_oakley.ta_dh | |||
| 3253 | : &ike_alg_dh_none; | |||
| 3254 | child_proposals = get_v2_create_child_proposals(c, what, default_dh, | |||
| 3255 | child->sa.st_logger); | |||
| 3256 | } else if (expect_accepted_proposal) { | |||
| 3257 | what = "IKE_AUTH initiator accepting remote ESP/AH proposal"; | |||
| 3258 | child_proposals = get_v2_ike_auth_child_proposals(c, what, | |||
| 3259 | child->sa.st_logger); | |||
| 3260 | } else { | |||
| 3261 | what = "IKE_AUTH responder matching remote ESP/AH proposals"; | |||
| 3262 | child_proposals = get_v2_ike_auth_child_proposals(c, what, | |||
| 3263 | child->sa.st_logger); | |||
| 3264 | } | |||
| 3265 | ||||
| 3266 | ret = ikev2_process_sa_payload(what, | |||
| 3267 | &sa_pd->pbs, | |||
| 3268 | /*expect_ike*/ FALSE0, | |||
| 3269 | /*expect_spi*/ TRUE1, | |||
| 3270 | expect_accepted_proposal, | |||
| 3271 | 				       LIN(POLICY_OPPORTUNISTIC, c->policy)(((((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))),  | |||
| 3272 | &child->sa.st_accepted_esp_or_ah_proposal, | |||
| 3273 | child_proposals, child->sa.st_logger); | |||
| 3274 | ||||
| 3275 | if (ret != STF_OK) { | |||
| 3276 | 		LOG_JAMBUF(RC_LOG_SERIOUS, child->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_SERIOUS ) & STREAM_MASK) != DEBUG_STREAM || (cur_debugging & ( ((lset_t)1 << (DBG_ADD_PREFIX_IX))))) { (child->sa.st_logger )->object_vec->jam_object_prefix(buf, (child->sa.st_logger )->object); } }); buf != ((void*)0); jambuf_to_logger(buf, (child->sa.st_logger), RC_LOG_SERIOUS), buf = ((void*)0)) {  | |||
| 3277 | jam_string(buf, what); | |||
| 3278 | jam(buf, " failed, responder SA processing returned "); | |||
| 3279 | jam_v2_stf_status(buf, ret); | |||
| 3280 | } | |||
| 3281 | if (child->sa.st_sa_role == SA_RESPONDER) { | |||
| 3282 | 			pexpect(ret > STF_FAIL)({ _Bool assertion__ = ret > STF_FAIL; if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3282}, "%s", "ret > STF_FAIL"); } assertion__; } );  | |||
| 3283 | record_v2N_response(child->sa.st_logger, ike, md, | |||
| 3284 | ret - STF_FAIL, NULL((void*)0), | |||
| 3285 | ENCRYPTED_PAYLOAD); | |||
| 3286 | return STF_FAIL; | |||
| 3287 | } | |||
| 3288 | /* XXX: return RET? */ | |||
| 3289 | return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN; | |||
| 3290 | } | |||
| 3291 | ||||
| 3292 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 3293 | DBG_log_ikev2_proposal(what, child->sa.st_accepted_esp_or_ah_proposal); | |||
| 3294 | } | |||
| 3295 | if (!ikev2_proposal_to_proto_info(child->sa.st_accepted_esp_or_ah_proposal, proto_info, | |||
| 3296 | child->sa.st_logger)) { | |||
| 3297 | loglog(RC_LOG_SERIOUS, "%s proposed/accepted a proposal we don't actually support!", what); | |||
| 3298 | return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN; | |||
| 3299 | } | |||
| 3300 | ||||
| 3301 | /* | |||
| 3302 | * Update/check the PFS. | |||
| 3303 | * | |||
| 3304 | * For the responder, go with what ever was negotiated. For | |||
| 3305 | * the initiator, check what was negotiated against what was | |||
| 3306 | * sent. | |||
| 3307 | * | |||
| 3308 | * Because code expects .st_pfs_group to use NULL, and not | |||
| 3309 | * &ike_alg_dh_none, to indicate no-DH algorithm, the value | |||
| 3310 | * returned by the proposal parser needs to be patched up. | |||
| 3311 | */ | |||
| 3312 | const struct dh_desc *accepted_dh = | |||
| 3313 | proto_info->attrs.transattrs.ta_dh == &ike_alg_dh_none ? NULL((void*)0) | |||
| 3314 | : proto_info->attrs.transattrs.ta_dh; | |||
| 3315 | switch (child->sa.st_sa_role) { | |||
| 3316 | case SA_INITIATOR: | |||
| 3317 | 		pexpect(expect_accepted_proposal)({ _Bool assertion__ = expect_accepted_proposal; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3317}, "%s", "expect_accepted_proposal"); } assertion__ ; });  | |||
| 3318 | if (accepted_dh != NULL((void*)0) && accepted_dh != child->sa.st_pfs_group) { | |||
| 3319 | loglog(RC_LOG_SERIOUS, | |||
| 3320 | "expecting %s but remote's accepted proposal includes %s", | |||
| 3321 | child->sa.st_pfs_group == NULL((void*)0) ? "no DH" : child->sa.st_pfs_group->common.fqn, | |||
| 3322 | accepted_dh->common.fqn); | |||
| 3323 | return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN; | |||
| 3324 | } | |||
| 3325 | child->sa.st_pfs_group = accepted_dh; | |||
| 3326 | break; | |||
| 3327 | case SA_RESPONDER: | |||
| 3328 | 		pexpect(!expect_accepted_proposal)({ _Bool assertion__ = !expect_accepted_proposal; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3328}, "%s", "!expect_accepted_proposal"); } assertion__ ; });  | |||
| 3329 | 		pexpect(child->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = child->sa.st_sa_role == SA_RESPONDER ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 3329}, "%s", "child->sa.st_sa_role == SA_RESPONDER" ); } assertion__; });  | |||
| 3330 | 		pexpect(child->sa.st_pfs_group == NULL)({ _Bool assertion__ = child->sa.st_pfs_group == ((void*)0 ); if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 3330}, "%s", "child->sa.st_pfs_group == NULL" ); } assertion__; });  | |||
| 3331 | child->sa.st_pfs_group = accepted_dh; | |||
| 3332 | break; | |||
| 3333 | default: | |||
| 3334 | 		bad_case(child->sa.st_sa_role)libreswan_bad_case("child->sa.st_sa_role", (child->sa.st_sa_role ), (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3334});  | |||
| 3335 | } | |||
| 3336 | ||||
| 3337 | /* | |||
| 3338 | * Update the state's st_oakley parameters from the proposal, | |||
| 3339 | * but retain the previous PRF. A CHILD_SA always uses the | |||
| 3340 | * PRF negotiated when creating initial IKE SA. | |||
| 3341 | * | |||
| 3342 | * XXX: The mystery is, why is .st_oakley even being updated? | |||
| 3343 | * Perhaps it is to prop up code getting the CHILD_SA's PRF | |||
| 3344 | * from the child when that code should use the CHILD_SA's IKE | |||
| 3345 | * SA; or perhaps it is getting things ready for an IKE SA | |||
| 3346 | * re-key? | |||
| 3347 | */ | |||
| 3348 | if (isa_xchg == ISAKMP_v2_CREATE_CHILD_SA && child->sa.st_pfs_group != NULL((void*)0)) { | |||
| 3349 | 		dbg("updating #%lu's .st_oakley with preserved PRF, but why update?",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("updating #%lu's .st_oakley with preserved PRF, but why update?" , child->sa.st_serialno); } }  | |||
| 3350 | 			child->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("updating #%lu's .st_oakley with preserved PRF, but why update?" , child->sa.st_serialno); } };  | |||
| 3351 | struct trans_attrs accepted_oakley = proto_info->attrs.transattrs; | |||
| 3352 | 		pexpect(accepted_oakley.ta_prf == NULL)({ _Bool assertion__ = accepted_oakley.ta_prf == ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 3352}, "%s", "accepted_oakley.ta_prf == NULL" ); } assertion__; });  | |||
| 3353 | accepted_oakley.ta_prf = child->sa.st_oakley.ta_prf; | |||
| 3354 | child->sa.st_oakley = accepted_oakley; | |||
| 3355 | } | |||
| 3356 | ||||
| 3357 | return STF_OK; | |||
| 3358 | } | |||
| 3359 | ||||
| 3360 | static stf_status ikev2_process_cp_respnse(struct msg_digest *md) | |||
| 3361 | { | |||
| 3362 | struct state *st = md->st; | |||
| 3363 | struct connection *c = st->st_connection; | |||
| 3364 | ||||
| 3365 | if (st->st_state->kind == STATE_V2_REKEY_CHILD_I1) | |||
| 3366 | return STF_OK; /* CP response is not allowed in a REKEY response */ | |||
| 3367 | ||||
| 3368 | if (need_configuration_payload(c, st->hidden_variables.st_nat_traversal)) { | |||
| 3369 | if (md->chain[ISAKMP_NEXT_v2CP] == NULL((void*)0)) { | |||
| 3370 | /* not really anything to here... but it would be worth unpending again */ | |||
| 3371 | loglog(RC_LOG_SERIOUS, "missing v2CP reply, not attempting to setup child SA"); | |||
| 3372 | /* | |||
| 3373 | * ??? this isn't really a failure, is it? | |||
| 3374 | * If none of those payloads appeared, isn't this is a | |||
| 3375 | * legitimate negotiation of a parent? | |||
| 3376 | */ | |||
| 3377 | return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN; | |||
| 3378 | } | |||
| 3379 | if (!ikev2_parse_cp_r_body(md->chain[ISAKMP_NEXT_v2CP], st)) | |||
| 3380 | { | |||
| 3381 | return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN; | |||
| 3382 | } | |||
| 3383 | } | |||
| 3384 | ||||
| 3385 | return STF_OK; | |||
| 3386 | } | |||
| 3387 | ||||
| 3388 | static void ikev2_rekey_expire_pred(const struct state *st, so_serial_t pred) | |||
| 3389 | { | |||
| 3390 | struct state *rst = state_with_serialno(pred); | |||
| 3391 | deltatime_t lifetime = deltatime(0); /* .lt. EXPIRE_OLD_SA_DELAY */ | |||
| 3392 | ||||
| 3393 | 	if (rst !=  NULL((void*)0) && IS_V2_ESTABLISHED(rst->st_state)((rst->st_state->kind) == STATE_V2_ESTABLISHED_IKE_SA || (rst->st_state->kind) == STATE_V2_ESTABLISHED_CHILD_SA )) {  | |||
| 3394 | /* on initiator, delete st_ipsec_pred. The responder should not */ | |||
| 3395 | monotime_t now = mononow(); | |||
| 3396 | const struct pluto_event *ev = rst->st_event; | |||
| 3397 | ||||
| 3398 | if (ev != NULL((void*)0)) | |||
| 3399 | lifetime = monotimediff(ev->ev_time, now); | |||
| 3400 | } | |||
| 3401 | ||||
| 3402 | deltatime_buf lb; | |||
| 3403 | log_state(RC_LOG, st, "rekeyed #%lu %s %s remaining life %ss", pred, | |||
| 3404 | st->st_state->name, | |||
| 3405 | rst == NULL((void*)0) ? "and the state is gone" : "and expire it", | |||
| 3406 | str_deltatime(lifetime, &lb)); | |||
| 3407 | ||||
| 3408 | if (deltatime_cmp(lifetime, >, EXPIRE_OLD_SA_DELAY)(deltatime_cmp_sign(lifetime, deltatime(1)) > 0)) { | |||
| 3409 | delete_event(rst); | |||
| 3410 | event_schedule(EVENT_SA_EXPIRE, EXPIRE_OLD_SA_DELAYdeltatime(1), rst); | |||
| 3411 | } | |||
| 3412 | /* else it should be on its way to expire no need to kick dead state */ | |||
| 3413 | } | |||
| 3414 | ||||
| 3415 | static stf_status ikev2_process_ts_and_rest(struct msg_digest *md) | |||
| 3416 | { | |||
| 3417 | struct child_sa *child = pexpect_child_sa(md->st); | |||
| 3418 | struct state *st = &child->sa; | |||
| 3419 | struct connection *c = st->st_connection; | |||
| 3420 | 	struct ike_sa *ike = ike_sa(&child->sa, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 3420});  | |||
| 3421 | ||||
| 3422 | 	RETURN_STF_FAILURE_STATUS(ikev2_process_cp_respnse(md)){ stf_status res = (ikev2_process_cp_respnse(md)); if (res != STF_OK) { return res; } };  | |||
| 3423 | if (!v2_process_ts_response(child, md)) { | |||
| 3424 | /* | |||
| 3425 | * XXX: will this will cause the state machine to | |||
| 3426 | * overwrite the AUTH part of the message - which is | |||
| 3427 | * wrong. XXX: does this delete the child state? | |||
| 3428 | */ | |||
| 3429 | return STF_FAIL + v2N_TS_UNACCEPTABLE; | |||
| 3430 | } | |||
| 3431 | ||||
| 3432 | /* examine and accept SA ESP/AH proposals */ | |||
| 3433 | if (md->hdr.isa_xchg != ISAKMP_v2_CREATE_CHILD_SA) | |||
| 3434 | 		RETURN_STF_FAILURE_STATUS(ikev2_process_child_sa_pl(ike, child, md, TRUE)){ stf_status res = (ikev2_process_child_sa_pl(ike, child, md, 1)); if (res != STF_OK) { return res; } };  | |||
| 3435 | ||||
| 3436 | /* | |||
| 3437 | * examine notification payloads for Child SA errors | |||
| 3438 | * (presumably any error reaching this point is for the | |||
| 3439 | * child?). | |||
| 3440 | * | |||
| 3441 | * https://tools.ietf.org/html/rfc7296#section-3.10.1 | |||
| 3442 | * | |||
| 3443 | * Types in the range 0 - 16383 are intended for reporting | |||
| 3444 | * errors. An implementation receiving a Notify payload | |||
| 3445 | * with one of these types that it does not recognize in a | |||
| 3446 | * response MUST assume that the corresponding request has | |||
| 3447 | * failed entirely. Unrecognized error types in a request | |||
| 3448 | * and status types in a request or response MUST be | |||
| 3449 | * ignored, and they should be logged. | |||
| 3450 | */ | |||
| 3451 | if (md->v2N_error != v2N_NOTHING_WRONG) { | |||
| 3452 | struct esb_buf esb; | |||
| 3453 | log_state(RC_LOG_SERIOUS, &child->sa, "received ERROR NOTIFY (%d): %s ", | |||
| 3454 | md->v2N_error, | |||
| 3455 | enum_showb(&ikev2_notify_names, md->v2N_error, &esb)); | |||
| 3456 | return STF_FATAL; | |||
| 3457 | } | |||
| 3458 | ||||
| 3459 | /* check for Child SA related NOTIFY payloads */ | |||
| 3460 | if (md->pbs[PBS_v2N_USE_TRANSPORT_MODE] != NULL((void*)0)) { | |||
| 3461 | if (c->policy & POLICY_TUNNEL((lset_t)1 << (POLICY_TUNNEL_IX))) { | |||
| 3462 | /* This means we did not send v2N_USE_TRANSPORT, however responder is sending it in now, seems incorrect */ | |||
| 3463 | 			dbg("Initiator policy is tunnel, responder sends v2N_USE_TRANSPORT_MODE notification in inR2, ignoring it"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initiator policy is tunnel, responder sends v2N_USE_TRANSPORT_MODE notification in inR2, ignoring it" ); } };  | |||
| 3464 | } else { | |||
| 3465 | 			dbg("Initiator policy is transport, responder sends v2N_USE_TRANSPORT_MODE, setting CHILD SA to transport mode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initiator policy is transport, responder sends v2N_USE_TRANSPORT_MODE, setting CHILD SA to transport mode" ); } };  | |||
| 3466 | if (st->st_esp.present) { | |||
| 3467 | st->st_esp.attrs.mode = ENCAPSULATION_MODE_TRANSPORT2; | |||
| 3468 | } | |||
| 3469 | if (st->st_ah.present) { | |||
| 3470 | st->st_ah.attrs.mode = ENCAPSULATION_MODE_TRANSPORT2; | |||
| 3471 | } | |||
| 3472 | } | |||
| 3473 | } | |||
| 3474 | st->st_seen_no_tfc = md->pbs[PBS_v2N_ESP_TFC_PADDING_NOT_SUPPORTED] != NULL((void*)0); | |||
| 3475 | if (md->pbs[PBS_v2N_IPCOMP_SUPPORTED] != NULL((void*)0)) { | |||
| 3476 | pb_stream pbs = *md->pbs[PBS_v2N_IPCOMP_SUPPORTED]; | |||
| 3477 | size_t len = pbs_left(&pbs)((size_t)((&pbs)->roof - (&pbs)->cur)); | |||
| 3478 | struct ikev2_notify_ipcomp_data n_ipcomp; | |||
| 3479 | ||||
| 3480 | 		dbg("received v2N_IPCOMP_SUPPORTED of length %zd", len){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_IPCOMP_SUPPORTED of length %zd", len); } };  | |||
| 3481 | if ((c->policy & POLICY_COMPRESS((lset_t)1 << (POLICY_COMPRESS_IX))) == LEMPTY((lset_t)0)) { | |||
| 3482 | loglog(RC_LOG_SERIOUS, "Unexpected IPCOMP request as our connection policy did not indicate support for it"); | |||
| 3483 | return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN; | |||
| 3484 | } | |||
| 3485 | ||||
| 3486 | if (!in_struct(&n_ipcomp, &ikev2notify_ipcomp_data_desc, &pbs, NULL((void*)0))) { | |||
| 3487 | return STF_FATAL; | |||
| 3488 | } | |||
| 3489 | ||||
| 3490 | if (n_ipcomp.ikev2_notify_ipcomp_trans != IPCOMP_DEFLATE) { | |||
| 3491 | loglog(RC_LOG_SERIOUS, "Unsupported IPCOMP compression method %d", | |||
| 3492 | n_ipcomp.ikev2_notify_ipcomp_trans); /* enum_name this later */ | |||
| 3493 | return STF_FATAL; | |||
| 3494 | } | |||
| 3495 | ||||
| 3496 | if (n_ipcomp.ikev2_cpi < IPCOMP_FIRST_NEGOTIATED256) { | |||
| 3497 | loglog(RC_LOG_SERIOUS, "Illegal IPCOMP CPI %d", n_ipcomp.ikev2_cpi); | |||
| 3498 | return STF_FATAL; | |||
| 3499 | } | |||
| 3500 | 		dbg("Received compression CPI=%d", n_ipcomp.ikev2_cpi){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Received compression CPI=%d", n_ipcomp.ikev2_cpi ); } };  | |||
| 3501 | ||||
| 3502 | //st->st_ipcomp.attrs.spi = uniquify_peer_cpi((ipsec_spi_t)htonl(n_ipcomp.ikev2_cpi), st, 0); | |||
| 3503 | st->st_ipcomp.attrs.spi = htonl((ipsec_spi_t)n_ipcomp.ikev2_cpi); | |||
| 3504 | st->st_ipcomp.attrs.transattrs.ta_comp = n_ipcomp.ikev2_notify_ipcomp_trans; | |||
| 3505 | st->st_ipcomp.attrs.mode = ENCAPSULATION_MODE_TUNNEL1; /* always? */ | |||
| 3506 | st->st_ipcomp.present = TRUE1; | |||
| 3507 | st->st_seen_use_ipcomp = TRUE1; | |||
| 3508 | } | |||
| 3509 | ||||
| 3510 | ikev2_derive_child_keys(child); | |||
| 3511 | ||||
| 3512 | #ifdef USE_XFRM_INTERFACE1 | |||
| 3513 | /* before calling do_command() */ | |||
| 3514 | if (st->st_state->kind != STATE_V2_REKEY_CHILD_I1) | |||
| 3515 | if (c->xfrmi != NULL((void*)0) && | |||
| 3516 | c->xfrmi->if_id != yn_no) | |||
| 3517 | if (add_xfrmi(c, child->sa.st_logger)) | |||
| 3518 | return STF_FATAL; | |||
| 3519 | #endif | |||
| 3520 | /* now install child SAs */ | |||
| 3521 | if (!install_ipsec_sa(st, TRUE1)) | |||
| 3522 | return STF_FATAL; /* does this affect/kill the IKE SA ? */ | |||
| 3523 | ||||
| 3524 | set_newest_ipsec_sa("inR2", st); | |||
| 3525 | ||||
| 3526 | if (st->st_state->kind == STATE_V2_REKEY_CHILD_I1) | |||
| 3527 | ikev2_rekey_expire_pred(st, st->st_ipsec_pred); | |||
| 3528 | ||||
| 3529 | return STF_OK; | |||
| 3530 | } | |||
| 3531 | ||||
| 3532 | /* | |||
| 3533 | s | |||
| 3534 | *************************************************************** | |||
| 3535 | * PARENT_inR2 (I3 state) ***** | |||
| 3536 | *************************************************************** | |||
| 3537 | * - there are no cryptographic continuations, but be certain | |||
| 3538 | * that there will have to be DNS continuations, but they | |||
| 3539 | * just aren't implemented yet. | |||
| 3540 | * | |||
| 3541 | */ | |||
| 3542 | ||||
| 3543 | /* STATE_PARENT_I2: R2 --> I3 | |||
| 3544 | * <-- HDR, SK {IDr, [CERT,] AUTH, | |||
| 3545 | * SAr2, TSi, TSr} | |||
| 3546 | * [Parent SA established] | |||
| 3547 | * | |||
| 3548 | * For error handling in this function, please read: | |||
| 3549 | * https://tools.ietf.org/html/rfc7296#section-2.21.2 | |||
| 3550 | */ | |||
| 3551 | ||||
| 3552 | static stf_status v2_inR2_post_cert_decode(struct state *st, struct msg_digest *md); | |||
| 3553 | ||||
| 3554 | stf_status ikev2_parent_inR2(struct ike_sa *ike, struct child_sa *child, struct msg_digest *md) | |||
| 3555 | { | |||
| 3556 | 	pexpect(child != NULL)({ _Bool assertion__ = child != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3556}, "%s", "child != NULL"); } assertion__; });  | |||
| 3557 | struct state *st = &child->sa; | |||
| 3558 | struct state *pst = &ike->sa; | |||
| 3559 | ||||
| 3560 | if (md->pbs[PBS_v2N_MOBIKE_SUPPORTED] != NULL((void*)0)) { | |||
| 3561 | 		dbg("received v2N_MOBIKE_SUPPORTED %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", pst->st_sent_mobike ? "and sent" : "while it did not sent"); } }  | |||
| 3562 | 		    pst->st_sent_mobike ? "and sent" : "while it did not sent"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_MOBIKE_SUPPORTED %s", pst->st_sent_mobike ? "and sent" : "while it did not sent"); } };  | |||
| 3563 | st->st_seen_mobike = pst->st_seen_mobike = true1; | |||
| 3564 | } | |||
| 3565 | if (md->pbs[PBS_v2N_REDIRECT] != NULL((void*)0)) { | |||
| 3566 | 		dbg("received v2N_REDIRECT in IKE_AUTH reply"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_REDIRECT in IKE_AUTH reply"); } };  | |||
| 3567 | 		if (!LIN(POLICY_ACCEPT_REDIRECT_YES, st->st_connection->policy)(((((lset_t)1 << (POLICY_ACCEPT_REDIRECT_YES_IX))) & (st->st_connection->policy)) == (((lset_t)1 << ( POLICY_ACCEPT_REDIRECT_YES_IX))))) {  | |||
| 3568 | 			dbg("ignoring v2N_REDIRECT, we don't accept being redirected"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ignoring v2N_REDIRECT, we don't accept being redirected" ); } };  | |||
| 3569 | } else { | |||
| 3570 | ip_address redirect_ip; | |||
| 3571 | err_t err = parse_redirect_payload(md->pbs[PBS_v2N_REDIRECT], | |||
| 3572 | st->st_connection->accept_redirect_to, | |||
| 3573 | NULL((void*)0), | |||
| 3574 | &redirect_ip, | |||
| 3575 | ike->sa.st_logger); | |||
| 3576 | if (err != NULL((void*)0)) { | |||
| 3577 | 				dbg("warning: parsing of v2N_REDIRECT payload failed: %s", err){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("warning: parsing of v2N_REDIRECT payload failed: %s" , err); } };  | |||
| 3578 | } else { | |||
| 3579 | /* initiate later, because we need to wait for AUTH success */ | |||
| 3580 | st->st_connection->temp_vars.redirect_ip = redirect_ip; | |||
| 3581 | } | |||
| 3582 | } | |||
| 3583 | } | |||
| 3584 | st->st_seen_no_tfc = md->pbs[PBS_v2N_ESP_TFC_PADDING_NOT_SUPPORTED] != NULL((void*)0); /* Technically, this should be only on the child state */ | |||
| 3585 | ||||
| 3586 | /* | |||
| 3587 | * On the initiator, we can STF_FATAL on IKE SA errors, because no | |||
| 3588 | * packet needs to be sent anymore. And we cannot recover. Unlike | |||
| 3589 | * IKEv1, we cannot send an updated IKE_AUTH request that would use | |||
| 3590 | * different credentials. | |||
| 3591 | * | |||
| 3592 | * On responder (code elsewhere), we have to STF_FAIL to get out | |||
| 3593 | * the response packet (we need a zombie state for these) | |||
| 3594 | * | |||
| 3595 | * Note: once AUTH succeeds, we can still return STF_FAIL's because | |||
| 3596 | * those apply to the Child SA and should not tear down the IKE SA. | |||
| 3597 | */ | |||
| 3598 | struct payload_digest *cert_payloads = md->chain[ISAKMP_NEXT_v2CERT]; | |||
| 3599 | if (cert_payloads != NULL((void*)0)) { | |||
| 3600 | submit_cert_decode(ike, st, md, cert_payloads, | |||
| 3601 | v2_inR2_post_cert_decode, | |||
| 3602 | "initiator decoding certificates"); | |||
| 3603 | return STF_SUSPEND; | |||
| 3604 | } else { | |||
| 3605 | 		dbg("no certs to decode"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("no certs to decode"); } };  | |||
| 3606 | ike->sa.st_remote_certs.processed = true1; | |||
| 3607 | ike->sa.st_remote_certs.harmless = true1; | |||
| 3608 | return v2_inR2_post_cert_decode(st, md); | |||
| 3609 | } | |||
| 3610 | } | |||
| 3611 | ||||
| 3612 | static stf_status v2_inR2_post_cert_decode(struct state *st, struct msg_digest *md) | |||
| 3613 | { | |||
| 3614 | 	passert(md != NULL){ _Bool assertion__ = md != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3614}, "%s", "md != NULL"); } };  | |||
| 3615 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 3615});  | |||
| 3616 | struct state *pst = &ike->sa; | |||
| 3617 | ||||
| 3618 | if (!ikev2_decode_peer_id(md)) { | |||
| 3619 | event_force(EVENT_SA_EXPIRE, st); | |||
| 3620 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 3621 | release_pending_whacks(st, "Authentication failed"); | |||
| 3622 | return STF_FATAL; | |||
| 3623 | } | |||
| 3624 | ||||
| 3625 | struct connection *c = st->st_connection; | |||
| 3626 | enum keyword_authby that_authby = c->spd.that.authby; | |||
| 3627 | ||||
| 3628 | 	passert(that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET){ _Bool assertion__ = that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET; if (!assertion__) { lsw_passert_fail((where_t ) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3628 }, "%s", "that_authby != AUTHBY_NEVER && that_authby != AUTHBY_UNSET" ); } };  | |||
| 3629 | ||||
| 3630 | if (md->pbs[PBS_v2N_PPK_IDENTITY] != NULL((void*)0)) { | |||
| 3631 | 		if (!LIN(POLICY_PPK_ALLOW, c->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) {  | |||
| 3632 | loglog(RC_LOG_SERIOUS, "Received PPK_IDENTITY but connection does not allow PPK"); | |||
| 3633 | return STF_FATAL; | |||
| 3634 | } | |||
| 3635 | } else { | |||
| 3636 | 		if (LIN(POLICY_PPK_INSIST, c->policy)(((((lset_t)1 << (POLICY_PPK_INSIST_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_PPK_INSIST_IX))))) {  | |||
| 3637 | loglog(RC_LOG_SERIOUS, "failed to receive PPK confirmation and connection has ppk=insist"); | |||
| 3638 | 			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" ); } };  | |||
| 3639 | pstat_sa_failed(&ike->sa, REASON_AUTH_FAILED); | |||
| 3640 | return STF_FATAL; | |||
| 3641 | } | |||
| 3642 | } | |||
| 3643 | ||||
| 3644 | /* | |||
| 3645 | * If we sent USE_PPK and we did not receive a PPK_IDENTITY, | |||
| 3646 | * it means the responder failed to find our PPK ID, but allowed | |||
| 3647 | * the connection to continue without PPK by using our NO_PPK_AUTH | |||
| 3648 | * payload. We should revert our key material to NO_PPK versions. | |||
| 3649 | */ | |||
| 3650 | if (ike->sa.st_seen_ppk && | |||
| 3651 | md->pbs[PBS_v2N_PPK_IDENTITY] == NULL((void*)0) && | |||
| 3652 | 	    LIN(POLICY_PPK_ALLOW, c->policy)(((((lset_t)1 << (POLICY_PPK_ALLOW_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_PPK_ALLOW_IX))))) {  | |||
| 3653 | /* discard the PPK based calculations */ | |||
| 3654 | ||||
| 3655 | 		libreswan_log("Peer wants to continue without PPK - switching to NO_PPK")loglog(RC_LOG, "Peer wants to continue without PPK - switching to NO_PPK" );  | |||
| 3656 | ||||
| 3657 | release_symkey(__func__, "st_skey_d_nss", &pst->st_skey_d_nss); | |||
| 3658 | pst->st_skey_d_nss = reference_symkey(__func__, "used sk_d from no ppk", pst->st_sk_d_no_ppk); | |||
| 3659 | ||||
| 3660 | release_symkey(__func__, "st_skey_pi_nss", &pst->st_skey_pi_nss); | |||
| 3661 | pst->st_skey_pi_nss = reference_symkey(__func__, "used sk_pi from no ppk", pst->st_sk_pi_no_ppk); | |||
| 3662 | ||||
| 3663 | release_symkey(__func__, "st_skey_pr_nss", &pst->st_skey_pr_nss); | |||
| 3664 | pst->st_skey_pr_nss = reference_symkey(__func__, "used sk_pr from no ppk", pst->st_sk_pr_no_ppk); | |||
| 3665 | ||||
| 3666 | if (pst != st) { | |||
| 3667 | release_symkey(__func__, "st_skey_d_nss", &st->st_skey_d_nss); | |||
| 3668 | st->st_skey_d_nss = reference_symkey(__func__, "used sk_d from no ppk", st->st_sk_d_no_ppk); | |||
| 3669 | ||||
| 3670 | release_symkey(__func__, "st_skey_pi_nss", &st->st_skey_pi_nss); | |||
| 3671 | st->st_skey_pi_nss = reference_symkey(__func__, "used sk_pi from no ppk", st->st_sk_pi_no_ppk); | |||
| 3672 | ||||
| 3673 | release_symkey(__func__, "st_skey_pr_nss", &st->st_skey_pr_nss); | |||
| 3674 | st->st_skey_pr_nss = reference_symkey(__func__, "used sk_pr from no ppk", st->st_sk_pr_no_ppk); | |||
| 3675 | } | |||
| 3676 | } | |||
| 3677 | ||||
| 3678 | struct crypt_mac idhash_in = v2_id_hash(ike, "idhash auth R2", | |||
| 3679 | "IDr", pbs_in_as_shunk(&md->chain[ISAKMP_NEXT_v2IDr]->pbs), | |||
| 3680 | "skey_pr", pst->st_skey_pr_nss); | |||
| 3681 | ||||
| 3682 | /* process AUTH payload */ | |||
| 3683 | ||||
| 3684 | 	dbg("verifying AUTH payload"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("verifying AUTH payload"); } };  | |||
| 3685 | if (!v2_check_auth(md->chain[ISAKMP_NEXT_v2AUTH]->payload.v2auth.isaa_auth_method, | |||
| 3686 | ike, &idhash_in, &md->chain[ISAKMP_NEXT_v2AUTH]->pbs, | |||
| 3687 | that_authby, "R2 Auth Payload")) | |||
| 3688 | { | |||
| 3689 | /* | |||
| 3690 | * We cannot send a response as we are processing IKE_AUTH reply | |||
| 3691 | * the RFC states we should pretend IKE_AUTH was okay, and then | |||
| 3692 | * send an INFORMATIONAL DELETE IKE SA but we have not implemented | |||
| 3693 | * that yet. | |||
| 3694 | */ | |||
| 3695 | return STF_FATAL; | |||
| 3696 | } | |||
| 3697 | st->st_ikev2_anon = pst->st_ikev2_anon; /* was set after duplicate_state() */ | |||
| 3698 | ||||
| 3699 | /* AUTH succeeded */ | |||
| 3700 | ||||
| 3701 | /* | |||
| 3702 | * update the parent state to make sure that it knows we have | |||
| 3703 | * authenticated properly. | |||
| 3704 | * | |||
| 3705 | * XXX: Danger! md->svm points to a state transition that | |||
| 3706 | * mashes the IKE SA's initial state in and the CHILD SA's | |||
| 3707 | * final state. Hence, the need to explicitly force the final | |||
| 3708 | * IKE SA state. There should instead be separate state | |||
| 3709 | * transitions for the IKE and CHILD SAs and then have the IKE | |||
| 3710 | * SA invoke the CHILD SA's transition. | |||
| 3711 | */ | |||
| 3712 | 	pexpect(md->svm->next_state == STATE_V2_ESTABLISHED_CHILD_SA)({ _Bool assertion__ = md->svm->next_state == STATE_V2_ESTABLISHED_CHILD_SA ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 3712}, "%s", "md->svm->next_state == STATE_V2_ESTABLISHED_CHILD_SA" ); } assertion__; });  | |||
| 3713 | ikev2_ike_sa_established(pexpect_ike_sa(pst), md->svm, STATE_V2_ESTABLISHED_IKE_SA); | |||
| 3714 | ||||
| 3715 | 	if (LHAS(st->hidden_variables.st_nat_traversal, NATED_HOST)(((st->hidden_variables.st_nat_traversal) & ((lset_t)1 << (NATED_HOST))) != ((lset_t)0))) {  | |||
| 3716 | /* ensure we run keepalives if needed */ | |||
| 3717 | if (c->nat_keepalive) { | |||
| 3718 | /* XXX: just trigger this event */ | |||
| 3719 | nat_traversal_ka_event(null_fd((struct fd *) ((void*)0))); | |||
| 3720 | } | |||
| 3721 | } | |||
| 3722 | ||||
| 3723 | /* AUTH is ok, we can trust the notify payloads */ | |||
| 3724 | if (md->pbs[PBS_v2N_USE_TRANSPORT_MODE] != NULL((void*)0)) { /* FIXME: use new RFC logic turning this into a request, not requirement */ | |||
| 3725 | 		if (LIN(POLICY_TUNNEL, st->st_connection->policy)(((((lset_t)1 << (POLICY_TUNNEL_IX))) & (st->st_connection ->policy)) == (((lset_t)1 << (POLICY_TUNNEL_IX))))) {  | |||
| 3726 | log_state(RC_LOG_SERIOUS, st, "local policy requires Tunnel Mode but peer requires required Transport Mode"); | |||
| 3727 | return STF_V2_DELETE_EXCHANGE_INITIATOR_IKE_SA; /* should just delete child */ | |||
| 3728 | ||||
| 3729 | } | |||
| 3730 | } else { | |||
| 3731 | 		if (!LIN(POLICY_TUNNEL, st->st_connection->policy)(((((lset_t)1 << (POLICY_TUNNEL_IX))) & (st->st_connection ->policy)) == (((lset_t)1 << (POLICY_TUNNEL_IX))))) {  | |||
| 3732 | log_state(RC_LOG_SERIOUS, st, "local policy requires Transport Mode but peer requires required Tunnel Mode"); | |||
| 3733 | return STF_V2_DELETE_EXCHANGE_INITIATOR_IKE_SA; /* should just delete child */ | |||
| 3734 | } | |||
| 3735 | } | |||
| 3736 | ||||
| 3737 | if (md->pbs[PBS_v2N_REDIRECT] != NULL((void*)0)) { | |||
| 3738 | st->st_redirected_in_auth = true1; | |||
| 3739 | event_force(EVENT_v2_REDIRECT, st); | |||
| 3740 | return STF_SUSPEND; | |||
| 3741 | } | |||
| 3742 | ||||
| 3743 | /* See if there is a child SA available */ | |||
| 3744 | if (md->chain[ISAKMP_NEXT_v2SA] == NULL((void*)0) || | |||
| 3745 | md->chain[ISAKMP_NEXT_v2TSi] == NULL((void*)0) || | |||
| 3746 | md->chain[ISAKMP_NEXT_v2TSr] == NULL((void*)0)) { | |||
| 3747 | /* not really anything to here... but it would be worth unpending again */ | |||
| 3748 | loglog(RC_LOG_SERIOUS, "missing v2SA, v2TSi or v2TSr: not attempting to setup child SA"); | |||
| 3749 | /* | |||
| 3750 | * ??? this isn't really a failure, is it? | |||
| 3751 | * If none of those payloads appeared, isn't this is a | |||
| 3752 | * legitimate negotiation of a parent? | |||
| 3753 | * Paul: this notify is never sent because w | |||
| 3754 | */ | |||
| 3755 | return STF_FAIL + v2N_NO_PROPOSAL_CHOSEN; | |||
| 3756 | } | |||
| 3757 | ||||
| 3758 | return ikev2_process_ts_and_rest(md); | |||
| 3759 | } | |||
| 3760 | ||||
| 3761 | static bool_Bool ikev2_rekey_child_req(struct child_sa *child, | |||
| 3762 | enum ikev2_sec_proto_id *rekey_protoid, | |||
| 3763 | ipsec_spi_t *rekey_spi) | |||
| 3764 | { | |||
| 3765 | 	if (!pexpect(child->sa.st_establishing_sa == IPSEC_SA)({ _Bool assertion__ = child->sa.st_establishing_sa == IPSEC_SA ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 3765}, "%s", "child->sa.st_establishing_sa == IPSEC_SA" ); } assertion__; }) ||  | |||
| 3766 | 	    !pexpect(child->sa.st_ipsec_pred != SOS_NOBODY)({ _Bool assertion__ = child->sa.st_ipsec_pred != 0; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3766}, "%s", "child->sa.st_ipsec_pred != SOS_NOBODY" ); } assertion__; }) ||  | |||
| 3767 | 	    !pexpect(child->sa.st_state->kind == STATE_V2_REKEY_CHILD_I0)({ _Bool assertion__ = child->sa.st_state->kind == STATE_V2_REKEY_CHILD_I0 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 3767}, "%s", "child->sa.st_state->kind == STATE_V2_REKEY_CHILD_I0" ); } assertion__; })) {  | |||
| 3768 | return false0; | |||
| 3769 | } | |||
| 3770 | ||||
| 3771 | struct state *rst = state_with_serialno(child->sa.st_ipsec_pred); | |||
| 3772 | if (rst == NULL((void*)0)) { | |||
| 3773 | /* | |||
| 3774 | * XXX: For instance: | |||
| 3775 | * | |||
| 3776 | * - the old child initiated this replacement | |||
| 3777 | * | |||
| 3778 | * - this child wondered off to perform DH | |||
| 3779 | * | |||
| 3780 | * - the old child expires itself (or it gets sent a | |||
| 3781 | * delete) | |||
| 3782 | * | |||
| 3783 | * - this child finds it has no older sibling | |||
| 3784 | * | |||
| 3785 | * The older child should have discarded this state. | |||
| 3786 | */ | |||
| 3787 | log_state(LOG_STREAM/*not-whack*/, &child->sa, | |||
| 3788 | "CHILD SA to rekey #%lu vanished abort this exchange", | |||
| 3789 | child->sa.st_ipsec_pred); | |||
| 3790 | return false0; | |||
| 3791 | } | |||
| 3792 | ||||
| 3793 | /* | |||
| 3794 | * 1.3.3. Rekeying Child SAs with the CREATE_CHILD_SA | |||
| 3795 | * Exchange: The SA being rekeyed is identified by the SPI | |||
| 3796 | * field in the Notify payload; this is the SPI the exchange | |||
| 3797 | * initiator would expect in inbound ESP or AH packets. | |||
| 3798 | */ | |||
| 3799 | if (rst->st_esp.present) { | |||
| 3800 | *rekey_spi = rst->st_esp.our_spi; | |||
| 3801 | *rekey_protoid = PROTO_IPSEC_ESP3; | |||
| 3802 | } else if (rst->st_ah.present) { | |||
| 3803 | *rekey_spi = rst->st_ah.our_spi; | |||
| 3804 | *rekey_protoid = PROTO_IPSEC_AH2; | |||
| 3805 | } else { | |||
| 3806 | 		pexpect_fail(child->sa.st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 3806},  | |||
| 3807 | "CHILD SA to rekey #%lu is not ESP/AH", | |||
| 3808 | child->sa.st_ipsec_pred); | |||
| 3809 | return false0; | |||
| 3810 | } | |||
| 3811 | ||||
| 3812 | child->sa.st_ts_this = rst->st_ts_this; | |||
| 3813 | child->sa.st_ts_that = rst->st_ts_that; | |||
| 3814 | ||||
| 3815 | 	char cib[CONN_INST_BUF(2 + 10 + 1 + sizeof(subnet_buf) + 7 + sizeof(address_reversed_buf ) + 3 + sizeof(subnet_buf) + 1 + 1)];  | |||
| 3816 | ||||
| 3817 | 	dbg("#%lu initiate rekey request for \"%s\"%s #%lu SPI 0x%x TSi TSr",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu initiate rekey request for \"%s\"%s #%lu SPI 0x%x TSi TSr" , child->sa.st_serialno, rst->st_connection->name, fmt_conn_instance (rst->st_connection, cib), rst->st_serialno, ntohl(*rekey_spi )); } }  | |||
| 3818 | 	    child->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu initiate rekey request for \"%s\"%s #%lu SPI 0x%x TSi TSr" , child->sa.st_serialno, rst->st_connection->name, fmt_conn_instance (rst->st_connection, cib), rst->st_serialno, ntohl(*rekey_spi )); } }  | |||
| 3819 | 	    rst->st_connection->name,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu initiate rekey request for \"%s\"%s #%lu SPI 0x%x TSi TSr" , child->sa.st_serialno, rst->st_connection->name, fmt_conn_instance (rst->st_connection, cib), rst->st_serialno, ntohl(*rekey_spi )); } }  | |||
| 3820 | 	    fmt_conn_instance(rst->st_connection, cib),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu initiate rekey request for \"%s\"%s #%lu SPI 0x%x TSi TSr" , child->sa.st_serialno, rst->st_connection->name, fmt_conn_instance (rst->st_connection, cib), rst->st_serialno, ntohl(*rekey_spi )); } }  | |||
| 3821 | 	    rst->st_serialno, ntohl(*rekey_spi)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu initiate rekey request for \"%s\"%s #%lu SPI 0x%x TSi TSr" , child->sa.st_serialno, rst->st_connection->name, fmt_conn_instance (rst->st_connection, cib), rst->st_serialno, ntohl(*rekey_spi )); } };  | |||
| 3822 | ||||
| 3823 | ikev2_print_ts(&child->sa.st_ts_this); | |||
| 3824 | ikev2_print_ts(&child->sa.st_ts_that); | |||
| 3825 | ||||
| 3826 | return true1; | |||
| 3827 | } | |||
| 3828 | ||||
| 3829 | static bool_Bool ikev2_rekey_child_resp(struct ike_sa *ike, struct child_sa *child, | |||
| 3830 | struct msg_digest *md) | |||
| 3831 | { | |||
| 3832 | struct payload_digest *rekey_sa_payload = NULL((void*)0); | |||
| 3833 | for (struct payload_digest *ntfy = md->chain[ISAKMP_NEXT_v2N]; ntfy != NULL((void*)0); ntfy = ntfy->next) { | |||
| 3834 | switch (ntfy->payload.v2n.isan_type) { | |||
| 3835 | case v2N_REKEY_SA: | |||
| 3836 | if (rekey_sa_payload != NULL((void*)0)) { | |||
| 3837 | /* will tolerate multiple */ | |||
| 3838 | log_state(RC_LOG_SERIOUS, &child->sa, | |||
| 3839 | "ignoring duplicate v2N_REKEY_SA in exchange"); | |||
| 3840 | break; | |||
| 3841 | } | |||
| 3842 | 			dbg("received v2N_REKEY_SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_REKEY_SA"); } };  | |||
| 3843 | rekey_sa_payload = ntfy; | |||
| 3844 | break; | |||
| 3845 | default: | |||
| 3846 | /* | |||
| 3847 | * there is another pass of notify payloads | |||
| 3848 | * after this that will handle all other but | |||
| 3849 | * REKEY | |||
| 3850 | */ | |||
| 3851 | break; | |||
| 3852 | } | |||
| 3853 | } | |||
| 3854 | ||||
| 3855 | if (rekey_sa_payload == NULL((void*)0)) { | |||
| 3856 | 		pexpect_fail(child->sa.st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 3856},  | |||
| 3857 | "rekey child can't find its rekey_sa payload"); | |||
| 3858 | return STF_INTERNAL_ERROR; | |||
| 3859 | } | |||
| 3860 | ||||
| 3861 | struct ikev2_notify *rekey_notify = &rekey_sa_payload->payload.v2n; | |||
| 3862 | /* | |||
| 3863 | * find old state to rekey | |||
| 3864 | */ | |||
| 3865 | 	dbg("CREATE_CHILD_SA IPsec SA rekey Protocol %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("CREATE_CHILD_SA IPsec SA rekey Protocol %s", enum_show (&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid )); } }  | |||
| 3866 | 	    enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("CREATE_CHILD_SA IPsec SA rekey Protocol %s", enum_show (&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid )); } };  | |||
| 3867 | ||||
| 3868 | if (rekey_notify->isan_spisize != sizeof(ipsec_spi_t)) { | |||
| 3869 | log_state(RC_LOG, &child->sa, | |||
| 3870 | "CREATE_CHILD_SA IPsec SA rekey invalid spi size %u", | |||
| 3871 | rekey_notify->isan_spisize); | |||
| 3872 | record_v2N_response(child->sa.st_logger, ike, md, v2N_INVALID_SYNTAX, | |||
| 3873 | NULL((void*)0)/*empty data*/, ENCRYPTED_PAYLOAD); | |||
| 3874 | return false0; | |||
| 3875 | } | |||
| 3876 | ||||
| 3877 | ipsec_spi_t spi = 0; | |||
| 3878 | if (!in_raw(&spi, sizeof(spi), &rekey_sa_payload->pbs, "SPI")) { | |||
| 3879 | /* already logged */ | |||
| 3880 | record_v2N_response(child->sa.st_logger, ike, md, v2N_INVALID_SYNTAX, | |||
| 3881 | NULL((void*)0)/*empty data*/, ENCRYPTED_PAYLOAD); | |||
| 3882 | return false0; /* cannot happen; XXX: why? */ | |||
| 3883 | } | |||
| 3884 | ||||
| 3885 | if (spi == 0) { | |||
| 3886 | log_state(RC_LOG, &child->sa, | |||
| 3887 | "CREATE_CHILD_SA IPsec SA rekey contains zero SPI"); | |||
| 3888 | record_v2N_response(child->sa.st_logger, ike, md, v2N_INVALID_SYNTAX, | |||
| 3889 | NULL((void*)0)/*empty data*/, ENCRYPTED_PAYLOAD); | |||
| 3890 | return false0; | |||
| 3891 | } | |||
| 3892 | ||||
| 3893 | if (rekey_notify->isan_protoid != PROTO_IPSEC_ESP3 && | |||
| 3894 | rekey_notify->isan_protoid != PROTO_IPSEC_AH2) { | |||
| 3895 | log_state(RC_LOG, &child->sa, | |||
| 3896 | "CREATE_CHILD_SA IPsec SA rekey invalid Protocol ID %s", | |||
| 3897 | enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid)); | |||
| 3898 | record_v2N_spi_response(child->sa.st_logger, ike, md, | |||
| 3899 | rekey_notify->isan_protoid, &spi, | |||
| 3900 | v2N_CHILD_SA_NOT_FOUND, | |||
| 3901 | NULL((void*)0)/*empty data*/, ENCRYPTED_PAYLOAD); | |||
| 3902 | return false0; | |||
| 3903 | } | |||
| 3904 | ||||
| 3905 | 	dbg("CREATE_CHILD_S to rekey IPsec SA(0x%08" PRIx32 ") Protocol %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("CREATE_CHILD_S to rekey IPsec SA(0x%08" "x" ") Protocol %s" , ntohl((uint32_t) spi), enum_show(&ikev2_notify_protocol_id_names , rekey_notify->isan_protoid)); } }  | |||
| 3906 | 	    ntohl((uint32_t) spi),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("CREATE_CHILD_S to rekey IPsec SA(0x%08" "x" ") Protocol %s" , ntohl((uint32_t) spi), enum_show(&ikev2_notify_protocol_id_names , rekey_notify->isan_protoid)); } }  | |||
| 3907 | 	    enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("CREATE_CHILD_S to rekey IPsec SA(0x%08" "x" ") Protocol %s" , ntohl((uint32_t) spi), enum_show(&ikev2_notify_protocol_id_names , rekey_notify->isan_protoid)); } };  | |||
| 3908 | ||||
| 3909 | /* | |||
| 3910 | * From 1.3.3. Rekeying Child SAs with the CREATE_CHILD_SA | |||
| 3911 | * Exchange: The SA being rekeyed is identified by the SPI | |||
| 3912 | * field in the [REKEY_SA] Notify payload; this is the SPI the | |||
| 3913 | * exchange initiator would expect in inbound ESP or AH | |||
| 3914 | * packets. | |||
| 3915 | * | |||
| 3916 | * From our POV, that's the outbound SPI. | |||
| 3917 | */ | |||
| 3918 | struct child_sa *replaced_child = find_v2_child_sa_by_outbound_spi(ike, rekey_notify->isan_protoid, spi); | |||
| 3919 | if (replaced_child == NULL((void*)0)) { | |||
| 3920 | log_state(RC_LOG, &child->sa, | |||
| 3921 | "CREATE_CHILD_SA no such IPsec SA to rekey SA(0x%08" PRIx32"x" ") Protocol %s", | |||
| 3922 | ntohl((uint32_t) spi), | |||
| 3923 | enum_show(&ikev2_notify_protocol_id_names, rekey_notify->isan_protoid)); | |||
| 3924 | record_v2N_spi_response(child->sa.st_logger, ike, md, | |||
| 3925 | rekey_notify->isan_protoid, &spi, | |||
| 3926 | v2N_CHILD_SA_NOT_FOUND, | |||
| 3927 | NULL((void*)0)/*empty data*/, ENCRYPTED_PAYLOAD); | |||
| 3928 | return false0; | |||
| 3929 | } | |||
| 3930 | ||||
| 3931 | child->sa.st_ipsec_pred = replaced_child->sa.st_serialno; | |||
| 3932 | ||||
| 3933 | connection_buf cb; | |||
| 3934 | 	dbg("#%lu rekey request for "PRI_CONNECTION" #%lu TSi TSr",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu rekey request for ""\"%s\"%s"" #%lu TSi TSr" , child->sa.st_serialno, (replaced_child->sa.st_connection )->name, str_connection_instance(replaced_child->sa.st_connection , &cb), replaced_child->sa.st_serialno); } }  | |||
| 3935 | 	    child->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu rekey request for ""\"%s\"%s"" #%lu TSi TSr" , child->sa.st_serialno, (replaced_child->sa.st_connection )->name, str_connection_instance(replaced_child->sa.st_connection , &cb), replaced_child->sa.st_serialno); } }  | |||
| 3936 | 	    pri_connection(replaced_child->sa.st_connection, &cb),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu rekey request for ""\"%s\"%s"" #%lu TSi TSr" , child->sa.st_serialno, (replaced_child->sa.st_connection )->name, str_connection_instance(replaced_child->sa.st_connection , &cb), replaced_child->sa.st_serialno); } }  | |||
| 3937 | 	    replaced_child->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu rekey request for ""\"%s\"%s"" #%lu TSi TSr" , child->sa.st_serialno, (replaced_child->sa.st_connection )->name, str_connection_instance(replaced_child->sa.st_connection , &cb), replaced_child->sa.st_serialno); } };  | |||
| 3938 | ikev2_print_ts(&replaced_child->sa.st_ts_this); | |||
| 3939 | ikev2_print_ts(&replaced_child->sa.st_ts_that); | |||
| 3940 | update_state_connection(&child->sa, replaced_child->sa.st_connection); | |||
| 3941 | ||||
| 3942 | return true1; | |||
| 3943 | } | |||
| 3944 | ||||
| 3945 | static bool_Bool ikev2_rekey_child_copy_ts(struct child_sa *child) | |||
| 3946 | { | |||
| 3947 | 	passert(child->sa.st_ipsec_pred != SOS_NOBODY){ _Bool assertion__ = child->sa.st_ipsec_pred != 0; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3947}, "%s", "child->sa.st_ipsec_pred != SOS_NOBODY" ); } };  | |||
| 3948 | ||||
| 3949 | /* old child state being rekeyed */ | |||
| 3950 | struct child_sa *rchild = child_sa_by_serialno(child->sa.st_ipsec_pred); | |||
| 3951 | 	if (!pexpect(rchild != NULL)({ _Bool assertion__ = rchild != ((void*)0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 3951}, "%s", "rchild != NULL"); } assertion__; })) {  | |||
| 3952 | /* | |||
| 3953 | * Something screwed up - can't even start to rekey a | |||
| 3954 | * CHILD SA when there's no predicessor. | |||
| 3955 | */ | |||
| 3956 | return false0; | |||
| 3957 | } | |||
| 3958 | ||||
| 3959 | /* | |||
| 3960 | * RFC 7296 #2.9.2 the exact or the superset. | |||
| 3961 | * exact is a should. Here libreswan only allow the exact. | |||
| 3962 | * Inherit the TSi TSr from old state, IPsec SA. | |||
| 3963 | */ | |||
| 3964 | ||||
| 3965 | connection_buf cib; | |||
| 3966 | 	dbg("#%lu inherit spd, TSi TSr, from "PRI_CONNECTION" #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu inherit spd, TSi TSr, from ""\"%s\"%s"" #%lu" , child->sa.st_serialno, (rchild->sa.st_connection)-> name, str_connection_instance(rchild->sa.st_connection, & cib), rchild->sa.st_serialno); } }  | |||
| 3967 | 	    child->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu inherit spd, TSi TSr, from ""\"%s\"%s"" #%lu" , child->sa.st_serialno, (rchild->sa.st_connection)-> name, str_connection_instance(rchild->sa.st_connection, & cib), rchild->sa.st_serialno); } }  | |||
| 3968 | 	    pri_connection(rchild->sa.st_connection, &cib),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu inherit spd, TSi TSr, from ""\"%s\"%s"" #%lu" , child->sa.st_serialno, (rchild->sa.st_connection)-> name, str_connection_instance(rchild->sa.st_connection, & cib), rchild->sa.st_serialno); } }  | |||
| 3969 | 	    rchild->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu inherit spd, TSi TSr, from ""\"%s\"%s"" #%lu" , child->sa.st_serialno, (rchild->sa.st_connection)-> name, str_connection_instance(rchild->sa.st_connection, & cib), rchild->sa.st_serialno); } };  | |||
| 3970 | ||||
| 3971 | struct spd_route *spd = &rchild->sa.st_connection->spd; | |||
| 3972 | child->sa.st_ts_this = ikev2_end_to_ts(&spd->this); | |||
| 3973 | child->sa.st_ts_that = ikev2_end_to_ts(&spd->that); | |||
| 3974 | ikev2_print_ts(&child->sa.st_ts_this); | |||
| 3975 | ikev2_print_ts(&child->sa.st_ts_that); | |||
| 3976 | ||||
| 3977 | return true1; | |||
| 3978 | } | |||
| 3979 | ||||
| 3980 | /* once done use the same function in ikev2_parent_inR1outI2_tail too */ | |||
| 3981 | static stf_status ikev2_child_add_ipsec_payloads(struct child_sa *child, | |||
| 3982 | pb_stream *outpbs) | |||
| 3983 | { | |||
| 3984 | 	if (!pexpect(child->sa.st_establishing_sa == IPSEC_SA)({ _Bool assertion__ = child->sa.st_establishing_sa == IPSEC_SA ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 3984}, "%s", "child->sa.st_establishing_sa == IPSEC_SA" ); } assertion__; })) {  | |||
| 3985 | return STF_INTERNAL_ERROR; | |||
| 3986 | } | |||
| 3987 | struct connection *cc = child->sa.st_connection; | |||
| 3988 | bool_Bool send_use_transport = (cc->policy & POLICY_TUNNEL((lset_t)1 << (POLICY_TUNNEL_IX))) == LEMPTY((lset_t)0); | |||
| 3989 | ||||
| 3990 | /* ??? this code won't support AH + ESP */ | |||
| 3991 | struct ipsec_proto_info *proto_info | |||
| 3992 | = ikev2_child_sa_proto_info(child, cc->policy); | |||
| 3993 | proto_info->our_spi = ikev2_child_sa_spi(&cc->spd, cc->policy); | |||
| 3994 | 	chunk_t local_spi = THING_AS_CHUNK(proto_info->our_spi)chunk2(&(proto_info->our_spi), sizeof(proto_info->our_spi ));  | |||
| 3995 | ||||
| 3996 | /* | |||
| 3997 | * HACK: Use the CREATE_CHILD_SA proposal suite hopefully | |||
| 3998 | * generated during the CHILD SA's initiation. | |||
| 3999 | * | |||
| 4000 | * XXX: this code should be either using get_v2...() (hard to | |||
| 4001 | * figure out what DEFAULT_DH is) or saving the proposal in | |||
| 4002 | * the state. | |||
| 4003 | */ | |||
| 4004 | 	passert(cc->v2_create_child_proposals != NULL){ _Bool assertion__ = cc->v2_create_child_proposals != ((void *)0); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4004}, "%s" , "cc->v2_create_child_proposals != NULL"); } };  | |||
| 4005 | if (!ikev2_emit_sa_proposals(outpbs, cc->v2_create_child_proposals, &local_spi)) | |||
| 4006 | return STF_INTERNAL_ERROR; | |||
| 4007 | ||||
| 4008 | /* | |||
| 4009 | * If rekeying, get the old SPI and protocol. | |||
| 4010 | */ | |||
| 4011 | ipsec_spi_t rekey_spi = 0; | |||
| 4012 | enum ikev2_sec_proto_id rekey_protoid = PROTO_v2_RESERVEDIKEv2_SEC_PROTO_NONE; | |||
| 4013 | if (child->sa.st_ipsec_pred != SOS_NOBODY0) { | |||
| 4014 | if (!ikev2_rekey_child_req(child, &rekey_protoid, &rekey_spi)) { | |||
| 4015 | /* | |||
| 4016 | * XXX: For instance: | |||
| 4017 | * | |||
| 4018 | * - the old child initiated this replacement | |||
| 4019 | * | |||
| 4020 | * - this child wondered off to perform DH | |||
| 4021 | * | |||
| 4022 | * - the old child expires itself (or it gets | |||
| 4023 | * sent a delete) | |||
| 4024 | * | |||
| 4025 | * - this child finds it has no older sibling | |||
| 4026 | * | |||
| 4027 | * The older child should have discarded this | |||
| 4028 | * state. | |||
| 4029 | */ | |||
| 4030 | return STF_INTERNAL_ERROR; | |||
| 4031 | } | |||
| 4032 | } | |||
| 4033 | ||||
| 4034 | struct ikev2_generic in = { | |||
| 4035 | .isag_critical = build_ikev2_critical(false0), | |||
| 4036 | }; | |||
| 4037 | pb_stream pb_nr; | |||
| 4038 | if (!out_struct(&in, &ikev2_nonce_desc, outpbs, &pb_nr) || | |||
| 4039 | 	    !pbs_out_hunk(child->sa.st_ni, &pb_nr, "IKEv2 nonce")({ typeof(child->sa.st_ni) hunk_ = child->sa.st_ni; struct packet_byte_stream *outs_ = &pb_nr; diag_t d_ = pbs_out_raw (outs_, hunk_.ptr, hunk_.len, ("IKEv2 nonce")); if (d_ != ((void *)0)) { log_diag(RC_LOG_SERIOUS, outs_->out_logger, &d_ , "%s", ""); } d_ == ((void*)0); }))  | |||
| 4040 | return STF_INTERNAL_ERROR; | |||
| 4041 | close_output_pbs(&pb_nr); | |||
| 4042 | ||||
| 4043 | if (child->sa.st_pfs_group != NULL((void*)0)) { | |||
| 4044 | if (!emit_v2KE(&child->sa.st_gi, child->sa.st_pfs_group, outpbs)) { | |||
| 4045 | return STF_INTERNAL_ERROR; | |||
| 4046 | } | |||
| 4047 | } | |||
| 4048 | ||||
| 4049 | if (rekey_spi != 0) { | |||
| 4050 | if (!emit_v2Nsa_pl(v2N_REKEY_SA, | |||
| 4051 | rekey_protoid, &rekey_spi, | |||
| 4052 | outpbs, NULL((void*)0))) | |||
| 4053 | return STF_INTERNAL_ERROR; | |||
| 4054 | } | |||
| 4055 | ||||
| 4056 | if (rekey_spi == 0) { | |||
| 4057 | /* not rekey */ | |||
| 4058 | child->sa.st_ts_this = ikev2_end_to_ts(&cc->spd.this); | |||
| 4059 | child->sa.st_ts_that = ikev2_end_to_ts(&cc->spd.that); | |||
| 4060 | } | |||
| 4061 | ||||
| 4062 | v2_emit_ts_payloads(child, outpbs, cc); | |||
| 4063 | ||||
| 4064 | if (send_use_transport) { | |||
| 4065 | 		dbg("Initiator child policy is transport mode, sending v2N_USE_TRANSPORT_MODE"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initiator child policy is transport mode, sending v2N_USE_TRANSPORT_MODE" ); } };  | |||
| 4066 | if (!emit_v2N(v2N_USE_TRANSPORT_MODE, outpbs)) | |||
| 4067 | return STF_INTERNAL_ERROR; | |||
| 4068 | } else { | |||
| 4069 | 		dbg("Initiator child policy is tunnel mode, NOT sending v2N_USE_TRANSPORT_MODE"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Initiator child policy is tunnel mode, NOT sending v2N_USE_TRANSPORT_MODE" ); } };  | |||
| 4070 | } | |||
| 4071 | ||||
| 4072 | if (cc->send_no_esp_tfc) { | |||
| 4073 | if (!emit_v2N(v2N_ESP_TFC_PADDING_NOT_SUPPORTED, outpbs)) | |||
| 4074 | return STF_INTERNAL_ERROR; | |||
| 4075 | } | |||
| 4076 | return STF_OK; | |||
| 4077 | } | |||
| 4078 | ||||
| 4079 | static stf_status ikev2_child_add_ike_payloads(struct child_sa *child, | |||
| 4080 | pb_stream *outpbs) | |||
| 4081 | { | |||
| 4082 | struct state *st = &child->sa; | |||
| 4083 | struct connection *c = st->st_connection; | |||
| 4084 | chunk_t local_nonce; | |||
| 4085 | chunk_t *local_g; | |||
| 4086 | ||||
| 4087 | switch (st->st_state->kind) { | |||
| 4088 | case STATE_V2_REKEY_IKE_R0: | |||
| 4089 | { | |||
| 4090 | local_g = &st->st_gr; | |||
| 4091 | local_nonce = st->st_nr; | |||
| 4092 | 		chunk_t local_spi = THING_AS_CHUNK(st->st_ike_rekey_spis.responder)chunk2(&(st->st_ike_rekey_spis.responder), sizeof(st-> st_ike_rekey_spis.responder));  | |||
| 4093 | ||||
| 4094 | /* send selected v2 IKE SA */ | |||
| 4095 | if (!ikev2_emit_sa_proposal(outpbs, st->st_accepted_ike_proposal, | |||
| 4096 | &local_spi)) { | |||
| 4097 | 			dbg("problem emitting accepted ike proposal in CREATE_CHILD_SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("problem emitting accepted ike proposal in CREATE_CHILD_SA" ); } };  | |||
| 4098 | return STF_INTERNAL_ERROR; | |||
| 4099 | } | |||
| 4100 | break; | |||
| 4101 | } | |||
| 4102 | case STATE_V2_REKEY_IKE_I0: | |||
| 4103 | { | |||
| 4104 | local_g = &st->st_gi; | |||
| 4105 | local_nonce = st->st_ni; | |||
| 4106 | 		chunk_t local_spi = THING_AS_CHUNK(st->st_ike_rekey_spis.initiator)chunk2(&(st->st_ike_rekey_spis.initiator), sizeof(st-> st_ike_rekey_spis.initiator));  | |||
| 4107 | ||||
| 4108 | struct ikev2_proposals *ike_proposals = | |||
| 4109 | get_v2_ike_proposals(c, "IKE SA initiating rekey", | |||
| 4110 | child->sa.st_logger); | |||
| 4111 | ||||
| 4112 | /* send v2 IKE SAs*/ | |||
| 4113 | if (!ikev2_emit_sa_proposals(outpbs, ike_proposals, | |||
| 4114 | &local_spi)) { | |||
| 4115 | libreswan_log("outsa fail")loglog(RC_LOG, "outsa fail"); | |||
| 4116 | 			dbg("problem emitting connection ike proposals in CREATE_CHILD_SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("problem emitting connection ike proposals in CREATE_CHILD_SA" ); } };  | |||
| 4117 | return STF_INTERNAL_ERROR; | |||
| 4118 | } | |||
| 4119 | break; | |||
| 4120 | } | |||
| 4121 | default: | |||
| 4122 | 		bad_case(st->st_state->kind)libreswan_bad_case("st->st_state->kind", (st->st_state ->kind), (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4122});  | |||
| 4123 | } | |||
| 4124 | ||||
| 4125 | /* send NONCE */ | |||
| 4126 | { | |||
| 4127 | struct ikev2_generic in = { | |||
| 4128 | .isag_critical = build_ikev2_critical(false0), | |||
| 4129 | }; | |||
| 4130 | pb_stream nr_pbs; | |||
| 4131 | if (!out_struct(&in, &ikev2_nonce_desc, outpbs, &nr_pbs) || | |||
| 4132 | 		    !pbs_out_hunk(local_nonce, &nr_pbs, "IKEv2 nonce")({ typeof(local_nonce) hunk_ = local_nonce; struct packet_byte_stream *outs_ = &nr_pbs; diag_t d_ = pbs_out_raw(outs_, hunk_.ptr , hunk_.len, ("IKEv2 nonce")); if (d_ != ((void*)0)) { log_diag (RC_LOG_SERIOUS, outs_->out_logger, &d_, "%s", ""); } d_ == ((void*)0); }))  | |||
| 4133 | return STF_INTERNAL_ERROR; | |||
| 4134 | close_output_pbs(&nr_pbs); | |||
| 4135 | } | |||
| 4136 | ||||
| 4137 | if (!emit_v2KE(local_g, st->st_oakley.ta_dh, outpbs)) | |||
| 4138 | return STF_INTERNAL_ERROR; | |||
| 4139 | ||||
| 4140 | return STF_OK; | |||
| 4141 | } | |||
| 4142 | ||||
| 4143 | /* | |||
| 4144 | * initiator received Rekey IKE SA (RFC 7296 1.3.3) response | |||
| 4145 | */ | |||
| 4146 | ||||
| 4147 | static crypto_req_cont_func ikev2_child_ike_inR_continue; | |||
| 4148 | ||||
| 4149 | stf_status ikev2_child_ike_inR(struct ike_sa *ike, | |||
| 4150 | struct child_sa *child, | |||
| 4151 | struct msg_digest *md) | |||
| 4152 | { | |||
| 4153 | 	pexpect(child != NULL)({ _Bool assertion__ = child != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4153}, "%s", "child != NULL"); } assertion__; });  | |||
  | ||||
| 4154 | struct state *st = &child->sa; | |||
| 4155 | 	pexpect(ike != NULL)({ _Bool assertion__ = ike != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4155}, "%s", "ike != NULL"); } assertion__; });  | |||
| 4156 | 	pexpect(ike->sa.st_serialno == st->st_clonedfrom)({ _Bool assertion__ = ike->sa.st_serialno == st->st_clonedfrom ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4156}, "%s", "ike->sa.st_serialno == st->st_clonedfrom" ); } assertion__; });  | |||
  | ||||
| 4157 | struct connection *c = st->st_connection; | |||
| 4158 | ||||
| 4159 | /* Ni in */ | |||
| 4160 | if (!accept_v2_nonce(st->st_logger, md, &st->st_nr, "Nr")) { | |||
| 4161 | /* | |||
| 4162 | * Presumably not our fault. Syntax errors in a | |||
| 4163 | * response kill the family and trigger no further | |||
| 4164 | * exchange. | |||
| 4165 | */ | |||
| 4166 | return STF_FATAL; /* NEED RESTART? */ | |||
| 4167 | } | |||
| 4168 | ||||
| 4169 | /* Get the proposals ready. */ | |||
| 4170 | struct ikev2_proposals *ike_proposals = | |||
| 4171 | get_v2_ike_proposals(c, "IKE SA accept response to rekey", | |||
| 4172 | child->sa.st_logger); | |||
| 4173 | ||||
| 4174 | struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_v2SA]; | |||
| 4175 | stf_status ret = ikev2_process_sa_payload("IKE initiator (accepting)", | |||
| 4176 | &sa_pd->pbs, | |||
| 4177 | /*expect_ike*/ TRUE1, | |||
| 4178 | /*expect_spi*/ TRUE1, | |||
| 4179 | /*expect_accepted*/ TRUE1, | |||
| 4180 | 						  LIN(POLICY_OPPORTUNISTIC, c->policy)(((((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))),  | |||
| 4181 | &st->st_accepted_ike_proposal, | |||
| 4182 | ike_proposals, child->sa.st_logger); | |||
| 4183 | if (ret != STF_OK) { | |||
| 4184 | 		dbg("failed to accept IKE SA, REKEY, response, in ikev2_child_ike_inR"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("failed to accept IKE SA, REKEY, response, in ikev2_child_ike_inR" ); } };  | |||
| 4185 | return ret; /* initiator; no response */ | |||
| 4186 | } | |||
| 4187 | ||||
| 4188 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 4189 | DBG_log_ikev2_proposal("accepted IKE proposal", | |||
| 4190 | st->st_accepted_ike_proposal); | |||
| 4191 | } | |||
| 4192 | if (!ikev2_proposal_to_trans_attrs(st->st_accepted_ike_proposal, | |||
| 4193 | &st->st_oakley, st->st_logger)) { | |||
| 4194 | loglog(RC_LOG_SERIOUS, "IKE responder accepted an unsupported algorithm"); | |||
| 4195 | /* free early return items */ | |||
| 4196 | free_ikev2_proposal(&st->st_accepted_ike_proposal); | |||
| 4197 | 		passert(st->st_accepted_ike_proposal == NULL){ _Bool assertion__ = st->st_accepted_ike_proposal == ((void *)0); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4197}, "%s" , "st->st_accepted_ike_proposal == NULL"); } };  | |||
| 4198 | 		switch_md_st(md, &ike->sa, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4198});  | |||
| 4199 | return STF_FAIL; | |||
| 4200 | } | |||
| 4201 | ||||
| 4202 | /* KE in */ | |||
| 4203 | if (!accept_KE(&st->st_gr, "Gr", st->st_oakley.ta_dh, | |||
| 4204 | md->chain[ISAKMP_NEXT_v2KE])) { | |||
| 4205 | /* | |||
| 4206 | * XXX: Initiator so returning this notification will | |||
| 4207 | * go no where. Need to check RFC for what to do | |||
| 4208 | * next. The packet is trusted but the re-key has | |||
| 4209 | * failed. | |||
| 4210 | */ | |||
| 4211 | return STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 4212 | } | |||
| 4213 | ||||
| 4214 | /* fill in the missing responder SPI */ | |||
| 4215 | 	passert(!ike_spi_is_zero(&st->st_ike_rekey_spis.initiator)){ _Bool assertion__ = !ike_spi_is_zero(&st->st_ike_rekey_spis .initiator); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4215 }, "%s", "!ike_spi_is_zero(&st->st_ike_rekey_spis.initiator)" ); } };  | |||
| 4216 | 	passert(ike_spi_is_zero(&st->st_ike_rekey_spis.responder)){ _Bool assertion__ = ike_spi_is_zero(&st->st_ike_rekey_spis .responder); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4216 }, "%s", "ike_spi_is_zero(&st->st_ike_rekey_spis.responder)" ); } };  | |||
| 4217 | ikev2_copy_cookie_from_sa(st->st_accepted_ike_proposal, | |||
| 4218 | &st->st_ike_rekey_spis.responder); | |||
| 4219 | ||||
| 4220 | /* initiate calculation of g^xy for rekey */ | |||
| 4221 | start_dh_v2(st, "DHv2 for IKE sa rekey initiator", | |||
| 4222 | SA_INITIATOR, | |||
| 4223 | ike->sa.st_skey_d_nss, /* only IKE has SK_d */ | |||
| 4224 | ike->sa.st_oakley.ta_prf, /* for IKE/ESP/AH */ | |||
| 4225 | &child->sa.st_ike_rekey_spis, /* new SPIs */ | |||
| 4226 | ikev2_child_ike_inR_continue); | |||
| 4227 | return STF_SUSPEND; | |||
| 4228 | } | |||
| 4229 | ||||
| 4230 | static void ikev2_child_ike_inR_continue(struct state *st, | |||
| 4231 | struct msg_digest *md, | |||
| 4232 | struct pluto_crypto_req *r) | |||
| 4233 | { | |||
| 4234 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 4235 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 4236 | ||||
| 4237 | 	pexpect(v2_msg_role(md) == MESSAGE_RESPONSE)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 4237}, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } assertion__; }); /* i.e., MD!=NULL */  | |||
| 4238 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4238}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 4239 | ||||
| 4240 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4240});  | |||
| 4241 | struct child_sa *child = pexpect_child_sa(st); /* not yet emancipated */ | |||
| 4242 | 	pexpect(child->sa.st_sa_role == SA_INITIATOR)({ _Bool assertion__ = child->sa.st_sa_role == SA_INITIATOR ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4242}, "%s", "child->sa.st_sa_role == SA_INITIATOR" ); } assertion__; });  | |||
| 4243 | ||||
| 4244 | 	pexpect(st->st_state->kind == STATE_V2_REKEY_IKE_I1)({ _Bool assertion__ = st->st_state->kind == STATE_V2_REKEY_IKE_I1 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4244}, "%s", "st->st_state->kind == STATE_V2_REKEY_IKE_I1" ); } assertion__; });  | |||
| 4245 | ||||
| 4246 | /* and a parent? */ | |||
| 4247 | if (ike == NULL((void*)0)) { | |||
| 4248 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4248},  | |||
| 4249 | "sponsoring child state #%lu has no parent state #%lu", | |||
| 4250 | st->st_serialno, st->st_clonedfrom); | |||
| 4251 | /* XXX: release what? */ | |||
| 4252 | return; | |||
| 4253 | } | |||
| 4254 | ||||
| 4255 | stf_status e = STF_OK; | |||
| 4256 | bool_Bool only_shared_false = false0; | |||
| 4257 | if (!finish_dh_v2(st, r, only_shared_false)) { | |||
| 4258 | /* | |||
| 4259 | * XXX: this is the initiator so returning a | |||
| 4260 | * notification is kind of useless. | |||
| 4261 | */ | |||
| 4262 | e = STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 4263 | } | |||
| 4264 | if (e == STF_OK) { | |||
| 4265 | ikev2_rekey_expire_pred(st, st->st_ike_pred); | |||
| 4266 | e = STF_OK; | |||
| 4267 | } | |||
| 4268 | ||||
| 4269 | complete_v2_state_transition(st, md, e); | |||
| 4270 | } | |||
| 4271 | ||||
| 4272 | /* | |||
| 4273 | * initiator received a create Child SA Response (RFC 7296 1.3.1, 1.3.2) | |||
| 4274 | * | |||
| 4275 | * Note: "when rekeying, the new Child SA SHOULD NOT have different Traffic | |||
| 4276 | * Selectors and algorithms than the old one." | |||
| 4277 | */ | |||
| 4278 | ||||
| 4279 | static dh_cb ikev2_child_inR_continue; | |||
| 4280 | ||||
| 4281 | stf_status ikev2_child_inR(struct ike_sa *ike, | |||
| 4282 | struct child_sa *child, struct msg_digest *md) | |||
| 4283 | { | |||
| 4284 | 	pexpect(child != NULL)({ _Bool assertion__ = child != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4284}, "%s", "child != NULL"); } assertion__; });  | |||
| 4285 | struct state *st = &child->sa; | |||
| 4286 | ||||
| 4287 | /* Ni in */ | |||
| 4288 | if (!accept_v2_nonce(st->st_logger, md, &st->st_nr, "Nr")) { | |||
| 4289 | /* | |||
| 4290 | * Presumably not our fault. Syntax errors in a | |||
| 4291 | * response kill the family (and trigger no further | |||
| 4292 | * exchange). | |||
| 4293 | */ | |||
| 4294 | return STF_FATAL; | |||
| 4295 | } | |||
| 4296 | ||||
| 4297 | 	RETURN_STF_FAILURE_STATUS(ikev2_process_child_sa_pl(ike, child, md, TRUE)){ stf_status res = (ikev2_process_child_sa_pl(ike, child, md, 1)); if (res != STF_OK) { return res; } };  | |||
| 4298 | ||||
| 4299 | /* XXX: only for rekey child? */ | |||
| 4300 | if (st->st_pfs_group == NULL((void*)0)) | |||
| 4301 | return ikev2_process_ts_and_rest(md); | |||
| 4302 | ||||
| 4303 | /* | |||
| 4304 | * This is the initiator, accept responder's KE. | |||
| 4305 | * | |||
| 4306 | * XXX: Above checks st_pfs_group but this uses | |||
| 4307 | * st_oakley.ta_dh, presumably they are the same? Lets find | |||
| 4308 | * out. | |||
| 4309 | */ | |||
| 4310 | 	pexpect(st->st_oakley.ta_dh == st->st_pfs_group)({ _Bool assertion__ = st->st_oakley.ta_dh == st->st_pfs_group ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4310}, "%s", "st->st_oakley.ta_dh == st->st_pfs_group" ); } assertion__; });  | |||
| 4311 | if (!accept_KE(&st->st_gr, "Gr", st->st_oakley.ta_dh, | |||
| 4312 | md->chain[ISAKMP_NEXT_v2KE])) { | |||
| 4313 | /* | |||
| 4314 | * XXX: Initiator so this notification result is going | |||
| 4315 | * no where. What should happen? | |||
| 4316 | */ | |||
| 4317 | return STF_FAIL + v2N_INVALID_SYNTAX; /* XXX: STF_FATAL? */ | |||
| 4318 | } | |||
| 4319 | chunk_t remote_ke = st->st_gr; | |||
| 4320 | ||||
| 4321 | /* | |||
| 4322 | * XXX: other than logging, these two cases are identical. | |||
| 4323 | */ | |||
| 4324 | const char *desc; | |||
| 4325 | switch (st->st_state->kind) { | |||
| 4326 | case STATE_V2_NEW_CHILD_I1: | |||
| 4327 | desc = "ikev2 Child SA initiator pfs=yes"; | |||
| 4328 | break; | |||
| 4329 | case STATE_V2_REKEY_CHILD_I1: | |||
| 4330 | desc = "ikev2 Child Rekey SA initiator pfs=yes"; | |||
| 4331 | break; | |||
| 4332 | default: | |||
| 4333 | 		bad_case(st->st_state->kind)libreswan_bad_case("st->st_state->kind", (st->st_state ->kind), (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4333});  | |||
| 4334 | } | |||
| 4335 | submit_dh(st, remote_ke, ikev2_child_inR_continue, desc); | |||
| 4336 | return STF_SUSPEND; | |||
| 4337 | } | |||
| 4338 | ||||
| 4339 | static stf_status ikev2_child_inR_continue(struct state *st, | |||
| 4340 | struct msg_digest *md) | |||
| 4341 | { | |||
| 4342 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 4343 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 4344 | ||||
| 4345 | /* initiator getting back an answer */ | |||
| 4346 | 	pexpect(v2_msg_role(md) == MESSAGE_RESPONSE)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_RESPONSE; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 4346}, "%s", "v2_msg_role(md) == MESSAGE_RESPONSE" ); } assertion__; }); /* i.e., MD!=NULL */  | |||
| 4347 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4347}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 4348 | ||||
| 4349 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4349});  | |||
| 4350 | struct child_sa *child = pexpect_child_sa(st); | |||
| 4351 | 	pexpect(child->sa.st_sa_role == SA_INITIATOR)({ _Bool assertion__ = child->sa.st_sa_role == SA_INITIATOR ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4351}, "%s", "child->sa.st_sa_role == SA_INITIATOR" ); } assertion__; });  | |||
| 4352 | ||||
| 4353 | /* | |||
| 4354 | * XXX: Should this routine be split so that each instance | |||
| 4355 | * handles only one state transition. If there's commonality | |||
| 4356 | * then the per-transition functions can all call common code. | |||
| 4357 | */ | |||
| 4358 | 	pexpect(st->st_state->kind == STATE_V2_NEW_CHILD_I1 ||({ _Bool assertion__ = st->st_state->kind == STATE_V2_NEW_CHILD_I1 || st->st_state->kind == STATE_V2_REKEY_CHILD_I1; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4359}, "%s", "st->st_state->kind == STATE_V2_NEW_CHILD_I1 || st->st_state->kind == STATE_V2_REKEY_CHILD_I1" ); } assertion__; })  | |||
| 4359 | 		st->st_state->kind == STATE_V2_REKEY_CHILD_I1)({ _Bool assertion__ = st->st_state->kind == STATE_V2_NEW_CHILD_I1 || st->st_state->kind == STATE_V2_REKEY_CHILD_I1; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4359}, "%s", "st->st_state->kind == STATE_V2_NEW_CHILD_I1 || st->st_state->kind == STATE_V2_REKEY_CHILD_I1" ); } assertion__; });  | |||
| 4360 | ||||
| 4361 | /* and a parent? */ | |||
| 4362 | if (ike == NULL((void*)0)) { | |||
| 4363 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4363},  | |||
| 4364 | "sponsoring child state #%lu has no parent state #%lu", | |||
| 4365 | st->st_serialno, st->st_clonedfrom); | |||
| 4366 | /* XXX: release what? */ | |||
| 4367 | return STF_FATAL; | |||
| 4368 | } | |||
| 4369 | ||||
| 4370 | if (st->st_shared_nss == NULL((void*)0)) { | |||
| 4371 | /* | |||
| 4372 | * XXX: this is the initiator so returning a | |||
| 4373 | * notification is kind of useless. | |||
| 4374 | */ | |||
| 4375 | return STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 4376 | } | |||
| 4377 | ||||
| 4378 | return ikev2_process_ts_and_rest(md); | |||
| 4379 | } | |||
| 4380 | ||||
| 4381 | /* | |||
| 4382 | * processing a new Child SA (RFC 7296 1.3.1 or 1.3.3) request | |||
| 4383 | */ | |||
| 4384 | ||||
| 4385 | static crypto_req_cont_func ikev2_child_inIoutR_continue; | |||
| 4386 | ||||
| 4387 | stf_status ikev2_child_inIoutR(struct ike_sa *ike, | |||
| 4388 | struct child_sa *child, | |||
| 4389 | struct msg_digest *md) | |||
| 4390 | { | |||
| 4391 | stf_status status; | |||
| 4392 | 	pexpect(child != NULL)({ _Bool assertion__ = child != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4392}, "%s", "child != NULL"); } assertion__; });  | |||
| 4393 | ||||
| 4394 | free_chunk_content(&child->sa.st_ni); /* this is from the parent. */ | |||
| 4395 | free_chunk_content(&child->sa.st_nr); /* this is from the parent. */ | |||
| 4396 | ||||
| 4397 | /* Ni in */ | |||
| 4398 | if (!accept_v2_nonce(child->sa.st_logger, md, &child->sa.st_ni, "Ni")) { | |||
| 4399 | /* | |||
| 4400 | * Presumably not our fault. Syntax error response | |||
| 4401 | * impicitly kills the family. | |||
| 4402 | */ | |||
| 4403 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 4404 | v2N_INVALID_SYNTAX, NULL((void*)0)/*no-data*/, | |||
| 4405 | ENCRYPTED_PAYLOAD); | |||
| 4406 | return STF_FATAL; /* invalid syntax means we're dead */ | |||
| 4407 | } | |||
| 4408 | ||||
| 4409 | status = ikev2_process_child_sa_pl(ike, child, md, FALSE0); | |||
| 4410 | if (status != STF_OK) { | |||
| 4411 | return status; | |||
| 4412 | } | |||
| 4413 | ||||
| 4414 | /* | |||
| 4415 | * KE in with old(pst) and matching accepted_oakley from | |||
| 4416 | * proposals | |||
| 4417 | * | |||
| 4418 | * XXX: does this code need to insist that the IKE SA | |||
| 4419 | * replacement has KE or has SA processor handled that by only | |||
| 4420 | * accepting a proposal with KE? | |||
| 4421 | */ | |||
| 4422 | if (child->sa.st_pfs_group != NULL((void*)0)) { | |||
| 4423 | 		pexpect(child->sa.st_oakley.ta_dh == child->sa.st_pfs_group)({ _Bool assertion__ = child->sa.st_oakley.ta_dh == child-> sa.st_pfs_group; if (!assertion__) { log_pexpect((where_t) { . func = __func__, .basename = "ikev2_parent.c" , .line = 4423} , "%s", "child->sa.st_oakley.ta_dh == child->sa.st_pfs_group" ); } assertion__; });  | |||
| 4424 | if (!accept_KE(&child->sa.st_gi, "Gi", child->sa.st_oakley.ta_dh, | |||
| 4425 | md->chain[ISAKMP_NEXT_v2KE])) { | |||
| 4426 | record_v2N_response(child->sa.st_logger, ike, md, v2N_INVALID_SYNTAX, | |||
| 4427 | NULL((void*)0)/*no data*/, ENCRYPTED_PAYLOAD); | |||
| 4428 | return STF_FAIL; | |||
| 4429 | } | |||
| 4430 | } | |||
| 4431 | ||||
| 4432 | /* check N_REKEY_SA in the negotiation */ | |||
| 4433 | switch (child->sa.st_state->kind) { | |||
| 4434 | case STATE_V2_REKEY_CHILD_R0: | |||
| 4435 | if (!ikev2_rekey_child_resp(ike, child, md)) { | |||
| 4436 | /* already logged; already recorded */ | |||
| 4437 | return STF_FAIL; | |||
| 4438 | } | |||
| 4439 | 		pexpect(child->sa.st_ipsec_pred != SOS_NOBODY)({ _Bool assertion__ = child->sa.st_ipsec_pred != 0; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4439}, "%s", "child->sa.st_ipsec_pred != SOS_NOBODY" ); } assertion__; });  | |||
| 4440 | break; | |||
| 4441 | case STATE_V2_NEW_CHILD_R0: | |||
| 4442 | /* state m/c created CHILD SA */ | |||
| 4443 | 		pexpect(child->sa.st_ipsec_pred == SOS_NOBODY)({ _Bool assertion__ = child->sa.st_ipsec_pred == 0; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4443}, "%s", "child->sa.st_ipsec_pred == SOS_NOBODY" ); } assertion__; });  | |||
| 4444 | if (!assign_child_responder_client(ike, child, md)) { | |||
| 4445 | /* already logged; already recorded */ | |||
| 4446 | return STF_FAIL; | |||
| 4447 | } | |||
| 4448 | break; | |||
| 4449 | default: | |||
| 4450 | 		bad_case(child->sa.st_state->kind)libreswan_bad_case("child->sa.st_state->kind", (child-> sa.st_state->kind), (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4450});  | |||
| 4451 | } | |||
| 4452 | ||||
| 4453 | /* | |||
| 4454 | * XXX: a quick eyeball suggests that the only difference | |||
| 4455 | * between these two cases is the description. | |||
| 4456 | * | |||
| 4457 | * ??? if we don't have an md (see above) why are we referencing it? | |||
| 4458 | * ??? clang 6.0.0 warns md might be NULL | |||
| 4459 | * | |||
| 4460 | * XXX: 'see above' is lost; this is a responder state | |||
| 4461 | * which _always_ has an MD. | |||
| 4462 | */ | |||
| 4463 | switch (child->sa.st_state->kind) { | |||
| 4464 | case STATE_V2_NEW_CHILD_R0: | |||
| 4465 | if (child->sa.st_pfs_group != NULL((void*)0)) { | |||
| 4466 | request_ke_and_nonce("Child Responder KE and nonce nr", | |||
| 4467 | &child->sa, child->sa.st_oakley.ta_dh, | |||
| 4468 | ikev2_child_inIoutR_continue); | |||
| 4469 | } else { | |||
| 4470 | request_nonce("Child Responder nonce nr", | |||
| 4471 | &child->sa, ikev2_child_inIoutR_continue); | |||
| 4472 | } | |||
| 4473 | return STF_SUSPEND; | |||
| 4474 | case STATE_V2_REKEY_CHILD_R0: | |||
| 4475 | if (child->sa.st_pfs_group != NULL((void*)0)) { | |||
| 4476 | request_ke_and_nonce("Child Rekey Responder KE and nonce nr", | |||
| 4477 | &child->sa, child->sa.st_oakley.ta_dh, | |||
| 4478 | ikev2_child_inIoutR_continue); | |||
| 4479 | } else { | |||
| 4480 | request_nonce("Child Rekey Responder nonce nr", | |||
| 4481 | &child->sa, ikev2_child_inIoutR_continue); | |||
| 4482 | } | |||
| 4483 | return STF_SUSPEND; | |||
| 4484 | default: | |||
| 4485 | 		bad_case(child->sa.st_state->kind)libreswan_bad_case("child->sa.st_state->kind", (child-> sa.st_state->kind), (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4485});  | |||
| 4486 | } | |||
| 4487 | } | |||
| 4488 | ||||
| 4489 | static dh_cb ikev2_child_inIoutR_continue_continue; | |||
| 4490 | ||||
| 4491 | static void ikev2_child_inIoutR_continue(struct state *st, | |||
| 4492 | struct msg_digest *md, | |||
| 4493 | struct pluto_crypto_req *r) | |||
| 4494 | { | |||
| 4495 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 4496 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 4497 | ||||
| 4498 | /* responder processing request */ | |||
| 4499 | 	pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 4499}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */  | |||
| 4500 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4500}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 4501 | ||||
| 4502 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4502});  | |||
| 4503 | struct child_sa *child = pexpect_child_sa(st); | |||
| 4504 | 	pexpect(child->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = child->sa.st_sa_role == SA_RESPONDER ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4504}, "%s", "child->sa.st_sa_role == SA_RESPONDER" ); } assertion__; });  | |||
| 4505 | ||||
| 4506 | /* | |||
| 4507 | * XXX: Should this routine be split so that each instance | |||
| 4508 | * handles only one state transition. If there's commonality | |||
| 4509 | * then the per-transition functions can all call common code. | |||
| 4510 | * | |||
| 4511 | * Instead of computing the entire DH as a single crypto task, | |||
| 4512 | * does a second continue. Yuck! | |||
| 4513 | */ | |||
| 4514 | 	pexpect(st->st_state->kind == STATE_V2_NEW_CHILD_R0 ||({ _Bool assertion__ = st->st_state->kind == STATE_V2_NEW_CHILD_R0 || st->st_state->kind == STATE_V2_REKEY_CHILD_R0; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4515}, "%s", "st->st_state->kind == STATE_V2_NEW_CHILD_R0 || st->st_state->kind == STATE_V2_REKEY_CHILD_R0" ); } assertion__; })  | |||
| 4515 | 		st->st_state->kind == STATE_V2_REKEY_CHILD_R0)({ _Bool assertion__ = st->st_state->kind == STATE_V2_NEW_CHILD_R0 || st->st_state->kind == STATE_V2_REKEY_CHILD_R0; if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4515}, "%s", "st->st_state->kind == STATE_V2_NEW_CHILD_R0 || st->st_state->kind == STATE_V2_REKEY_CHILD_R0" ); } assertion__; });  | |||
| 4516 | ||||
| 4517 | /* and a parent? */ | |||
| 4518 | if (ike == NULL((void*)0)) { | |||
| 4519 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4519},  | |||
| 4520 | "sponsoring child state #%lu has no parent state #%lu", | |||
| 4521 | st->st_serialno, st->st_clonedfrom); | |||
| 4522 | /* XXX: release what? */ | |||
| 4523 | return; | |||
| 4524 | } | |||
| 4525 | ||||
| 4526 | stf_status e; | |||
| 4527 | unpack_nonce(&st->st_nr, r); | |||
| 4528 | if (r->pcr_type == pcr_build_ke_and_nonce) { | |||
| 4529 | 		pexpect(md->chain[ISAKMP_NEXT_v2KE] != NULL)({ _Bool assertion__ = md->chain[ISAKMP_NEXT_v2KE] != ((void *)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4529}, "%s", "md->chain[ISAKMP_NEXT_v2KE] != NULL" ); } assertion__; });  | |||
| 4530 | unpack_KE_from_helper(st, r, &st->st_gr); | |||
| 4531 | /* initiate calculation of g^xy */ | |||
| 4532 | submit_dh(st, st->st_gi, ikev2_child_inIoutR_continue_continue, | |||
| 4533 | "DHv2 for child sa"); | |||
| 4534 | e = STF_SUSPEND; | |||
| 4535 | } else { | |||
| 4536 | e = ikev2_child_out_tail(ike, child, md); | |||
| 4537 | } | |||
| 4538 | ||||
| 4539 | complete_v2_state_transition(st, md, e); | |||
| 4540 | } | |||
| 4541 | ||||
| 4542 | static stf_status ikev2_child_inIoutR_continue_continue(struct state *st, | |||
| 4543 | struct msg_digest *md) | |||
| 4544 | { | |||
| 4545 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 4546 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 4547 | ||||
| 4548 | /* 'child' responding to request */ | |||
| 4549 | 	passert(v2_msg_role(md) == MESSAGE_REQUEST){ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4549}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } }; /* i.e., MD!=NULL */  | |||
| 4550 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4550}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 4551 | ||||
| 4552 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4552});  | |||
| 4553 | struct child_sa *child = pexpect_child_sa(st); | |||
| 4554 | 	passert(child->sa.st_sa_role == SA_RESPONDER){ _Bool assertion__ = child->sa.st_sa_role == SA_RESPONDER ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4554}, "%s", "child->sa.st_sa_role == SA_RESPONDER" ); } };  | |||
| 4555 | ||||
| 4556 | /* | |||
| 4557 | * XXX: Should this routine be split so that each instance | |||
| 4558 | * handles only one state transition. If there's commonality | |||
| 4559 | * then the per-transition functions can all call common code. | |||
| 4560 | */ | |||
| 4561 | 	pexpect(child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 ||({ _Bool assertion__ = child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4562}, "%s", "child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0" ); } assertion__; })  | |||
| 4562 | 		child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0)({ _Bool assertion__ = child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4562}, "%s", "child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0" ); } assertion__; });  | |||
| 4563 | ||||
| 4564 | /* didn't loose parent? */ | |||
| 4565 | if (ike == NULL((void*)0)) { | |||
| 4566 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4566},  | |||
| 4567 | "sponsoring child state #%lu has no parent state #%lu", | |||
| 4568 | st->st_serialno, st->st_clonedfrom); | |||
| 4569 | /* XXX: release child? */ | |||
| 4570 | return STF_FATAL; | |||
| 4571 | } | |||
| 4572 | ||||
| 4573 | if (st->st_shared_nss == NULL((void*)0)) { | |||
| 4574 | log_state(RC_LOG, &child->sa, "DH failed"); | |||
| 4575 | record_v2N_response(child->sa.st_logger, ike, md, | |||
| 4576 | v2N_INVALID_SYNTAX, NULL((void*)0), | |||
| 4577 | ENCRYPTED_PAYLOAD); | |||
| 4578 | return STF_FATAL; /* kill family */ | |||
| 4579 | } | |||
| 4580 | return ikev2_child_out_tail(ike, child, md); | |||
| 4581 | } | |||
| 4582 | ||||
| 4583 | /* | |||
| 4584 | * processing a new Rekey IKE SA (RFC 7296 1.3.2) request | |||
| 4585 | */ | |||
| 4586 | ||||
| 4587 | static crypto_req_cont_func ikev2_child_ike_inIoutR_continue; | |||
| 4588 | ||||
| 4589 | stf_status ikev2_child_ike_inIoutR(struct ike_sa *ike, | |||
| 4590 | struct child_sa *child, | |||
| 4591 | struct msg_digest *md) | |||
| 4592 | { | |||
| 4593 | 	pexpect(child != NULL)({ _Bool assertion__ = child != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4593}, "%s", "child != NULL"); } assertion__; }); /* not yet emancipated */  | |||
| 4594 | struct state *st = &child->sa; | |||
| 4595 | 	pexpect(ike != NULL)({ _Bool assertion__ = ike != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4595}, "%s", "ike != NULL"); } assertion__; });  | |||
| 4596 | struct connection *c = st->st_connection; | |||
| 4597 | ||||
| 4598 | free_chunk_content(&st->st_ni); /* this is from the parent. */ | |||
| 4599 | free_chunk_content(&st->st_nr); /* this is from the parent. */ | |||
| 4600 | ||||
| 4601 | /* Ni in */ | |||
| 4602 | if (!accept_v2_nonce(st->st_logger, md, &st->st_ni, "Ni")) { | |||
| 4603 | /* | |||
| 4604 | * Presumably not our fault. A syntax error response | |||
| 4605 | * implicitly kills the entire family. | |||
| 4606 | */ | |||
| 4607 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 4608 | v2N_INVALID_SYNTAX, NULL((void*)0)/*no-data*/, | |||
| 4609 | ENCRYPTED_PAYLOAD); | |||
| 4610 | return STF_FATAL; /* we're doomed */ | |||
| 4611 | } | |||
| 4612 | ||||
| 4613 | /* Get the proposals ready. */ | |||
| 4614 | struct ikev2_proposals *ike_proposals = | |||
| 4615 | get_v2_ike_proposals(c, "IKE SA responding to rekey", ike->sa.st_logger); | |||
| 4616 | ||||
| 4617 | struct payload_digest *const sa_pd = md->chain[ISAKMP_NEXT_v2SA]; | |||
| 4618 | stf_status ret = ikev2_process_sa_payload("IKE Rekey responder child", | |||
| 4619 | &sa_pd->pbs, | |||
| 4620 | /*expect_ike*/ TRUE1, | |||
| 4621 | /*expect_spi*/ TRUE1, | |||
| 4622 | /*expect_accepted*/ FALSE0, | |||
| 4623 | 						  LIN(POLICY_OPPORTUNISTIC, c->policy)(((((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) & (c-> policy)) == (((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))),  | |||
| 4624 | &st->st_accepted_ike_proposal, | |||
| 4625 | ike_proposals, child->sa.st_logger); | |||
| 4626 | if (ret != STF_OK) { | |||
| 4627 | 		pexpect(child->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = child->sa.st_sa_role == SA_RESPONDER ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4627}, "%s", "child->sa.st_sa_role == SA_RESPONDER" ); } assertion__; });  | |||
| 4628 | 		pexpect(ret > STF_FAIL)({ _Bool assertion__ = ret > STF_FAIL; if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4628}, "%s", "ret > STF_FAIL"); } assertion__; } );  | |||
| 4629 | record_v2N_response(child->sa.st_logger, ike, md, ret - STF_FAIL, NULL((void*)0), | |||
| 4630 | ENCRYPTED_PAYLOAD); | |||
| 4631 | return STF_FAIL; | |||
| 4632 | } | |||
| 4633 | ||||
| 4634 | if (DBGP(DBG_BASE)(cur_debugging & (((lset_t)1 << (DBG_BASE_IX))))) { | |||
| 4635 | DBG_log_ikev2_proposal("accepted IKE proposal", | |||
| 4636 | st->st_accepted_ike_proposal); | |||
| 4637 | } | |||
| 4638 | ||||
| 4639 | if (!ikev2_proposal_to_trans_attrs(st->st_accepted_ike_proposal, | |||
| 4640 | &st->st_oakley, st->st_logger)) { | |||
| 4641 | loglog(RC_LOG_SERIOUS, "IKE responder accepted an unsupported algorithm"); | |||
| 4642 | /* | |||
| 4643 | * XXX; where is 'st' freed? Should the code instead | |||
| 4644 | * tunnel back md.st==st and return STF_FATAL which | |||
| 4645 | * will delete the child state? Or perhaps there a | |||
| 4646 | * lurking SO_DISPOSE to clean it up? | |||
| 4647 | */ | |||
| 4648 | 		switch_md_st(md, &ike->sa, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4648});  | |||
| 4649 | return STF_IGNORE; | |||
| 4650 | } | |||
| 4651 | ||||
| 4652 | if (!v2_accept_ke_for_proposal(ike, &child->sa, md, | |||
| 4653 | st->st_oakley.ta_dh, | |||
| 4654 | ENCRYPTED_PAYLOAD)) { | |||
| 4655 | /* passert(reply-recorded) */ | |||
| 4656 | return STF_FAIL; | |||
| 4657 | } | |||
| 4658 | ||||
| 4659 | /* | |||
| 4660 | * Check and read the KE contents. | |||
| 4661 | * | |||
| 4662 | * responder, so accept initiator's KE in with new | |||
| 4663 | * accepted_oakley for IKE. | |||
| 4664 | */ | |||
| 4665 | 	pexpect(st->st_oakley.ta_dh != NULL)({ _Bool assertion__ = st->st_oakley.ta_dh != ((void*)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 4665}, "%s", "st->st_oakley.ta_dh != NULL" ); } assertion__; });  | |||
| 4666 | 	pexpect(st->st_pfs_group == NULL)({ _Bool assertion__ = st->st_pfs_group == ((void*)0); if ( !assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4666}, "%s", "st->st_pfs_group == NULL" ); } assertion__; });  | |||
| 4667 | if (!accept_KE(&st->st_gi, "Gi", st->st_oakley.ta_dh, | |||
| 4668 | md->chain[ISAKMP_NEXT_v2KE])) { | |||
| 4669 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 4670 | v2N_INVALID_SYNTAX, NULL((void*)0)/*no data*/, | |||
| 4671 | ENCRYPTED_PAYLOAD); | |||
| 4672 | return STF_FATAL; /* kill family */ | |||
| 4673 | } | |||
| 4674 | ||||
| 4675 | request_ke_and_nonce("IKE rekey KE response gir", st, | |||
| 4676 | st->st_oakley.ta_dh, | |||
| 4677 | ikev2_child_ike_inIoutR_continue); | |||
| 4678 | return STF_SUSPEND; | |||
| 4679 | } | |||
| 4680 | ||||
| 4681 | static void ikev2_child_ike_inIoutR_continue_continue(struct state *st, | |||
| 4682 | struct msg_digest *md, | |||
| 4683 | struct pluto_crypto_req *r); | |||
| 4684 | ||||
| 4685 | static void ikev2_child_ike_inIoutR_continue(struct state *st, | |||
| 4686 | struct msg_digest *md, | |||
| 4687 | struct pluto_crypto_req *r) | |||
| 4688 | { | |||
| 4689 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 4690 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 4691 | ||||
| 4692 | /* responder processing request */ | |||
| 4693 | ||||
| 4694 | 	pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 4694}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; }); /* i.e., MD!=NULL */  | |||
| 4695 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4695}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 4696 | ||||
| 4697 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4697});  | |||
| 4698 | struct child_sa *child = pexpect_child_sa(st); /* not yet emancipated */ | |||
| 4699 | 	pexpect(child->sa.st_sa_role == SA_RESPONDER)({ _Bool assertion__ = child->sa.st_sa_role == SA_RESPONDER ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4699}, "%s", "child->sa.st_sa_role == SA_RESPONDER" ); } assertion__; });  | |||
| 4700 | ||||
| 4701 | 	pexpect(st->st_state->kind == STATE_V2_REKEY_IKE_R0)({ _Bool assertion__ = st->st_state->kind == STATE_V2_REKEY_IKE_R0 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4701}, "%s", "st->st_state->kind == STATE_V2_REKEY_IKE_R0" ); } assertion__; });  | |||
| 4702 | ||||
| 4703 | /* and a parent? */ | |||
| 4704 | if (ike == NULL((void*)0)) { | |||
| 4705 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4705},  | |||
| 4706 | "sponsoring child state #%lu has no parent state #%lu", | |||
| 4707 | st->st_serialno, st->st_clonedfrom); | |||
| 4708 | /* XXX: release what? */ | |||
| 4709 | return; | |||
| 4710 | } | |||
| 4711 | ||||
| 4712 | 	pexpect(r->pcr_type == pcr_build_ke_and_nonce)({ _Bool assertion__ = r->pcr_type == pcr_build_ke_and_nonce ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4712}, "%s", "r->pcr_type == pcr_build_ke_and_nonce" ); } assertion__; });  | |||
| 4713 | 	pexpect(md->chain[ISAKMP_NEXT_v2KE] != NULL)({ _Bool assertion__ = md->chain[ISAKMP_NEXT_v2KE] != ((void *)0); if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4713}, "%s", "md->chain[ISAKMP_NEXT_v2KE] != NULL" ); } assertion__; });  | |||
| 4714 | unpack_nonce(&st->st_nr, r); | |||
| 4715 | unpack_KE_from_helper(st, r, &st->st_gr); | |||
| 4716 | ||||
| 4717 | /* initiate calculation of g^xy */ | |||
| 4718 | 	passert(ike_spi_is_zero(&st->st_ike_rekey_spis.initiator)){ _Bool assertion__ = ike_spi_is_zero(&st->st_ike_rekey_spis .initiator); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4718 }, "%s", "ike_spi_is_zero(&st->st_ike_rekey_spis.initiator)" ); } };  | |||
| 4719 | 	passert(ike_spi_is_zero(&st->st_ike_rekey_spis.responder)){ _Bool assertion__ = ike_spi_is_zero(&st->st_ike_rekey_spis .responder); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4719 }, "%s", "ike_spi_is_zero(&st->st_ike_rekey_spis.responder)" ); } };  | |||
| 4720 | ikev2_copy_cookie_from_sa(st->st_accepted_ike_proposal, | |||
| 4721 | &st->st_ike_rekey_spis.initiator); | |||
| 4722 | st->st_ike_rekey_spis.responder = ike_responder_spi(&md->sender, | |||
| 4723 | st->st_logger); | |||
| 4724 | start_dh_v2(st, "DHv2 for REKEY IKE SA", SA_RESPONDER, | |||
| 4725 | ike->sa.st_skey_d_nss, /* only IKE has SK_d */ | |||
| 4726 | ike->sa.st_oakley.ta_prf, /* for IKE/ESP/AH */ | |||
| 4727 | &st->st_ike_rekey_spis, | |||
| 4728 | ikev2_child_ike_inIoutR_continue_continue); | |||
| 4729 | ||||
| 4730 | complete_v2_state_transition(st, md, STF_SUSPEND); | |||
| 4731 | } | |||
| 4732 | ||||
| 4733 | static void ikev2_child_ike_inIoutR_continue_continue(struct state *st, | |||
| 4734 | struct msg_digest *md, | |||
| 4735 | struct pluto_crypto_req *r) | |||
| 4736 | { | |||
| 4737 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 4738 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 4739 | ||||
| 4740 | /* 'child' responding to request */ | |||
| 4741 | 	passert(v2_msg_role(md) == MESSAGE_REQUEST){ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4741}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } }; /* i.e., MD!=NULL */  | |||
| 4742 | 	pexpect(md->st == NULL || md->st == st)({ _Bool assertion__ = md->st == ((void*)0) || md->st == st; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4742}, "%s", "md->st == NULL || md->st == st" ); } assertion__; });  | |||
| 4743 | ||||
| 4744 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4744});  | |||
| 4745 | struct child_sa *child = pexpect_child_sa(st); /* not yet emancipated */ | |||
| 4746 | 	passert(child->sa.st_sa_role == SA_RESPONDER){ _Bool assertion__ = child->sa.st_sa_role == SA_RESPONDER ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4746}, "%s", "child->sa.st_sa_role == SA_RESPONDER" ); } };  | |||
| 4747 | ||||
| 4748 | 	pexpect(st->st_state->kind == STATE_V2_REKEY_IKE_R0)({ _Bool assertion__ = st->st_state->kind == STATE_V2_REKEY_IKE_R0 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4748}, "%s", "st->st_state->kind == STATE_V2_REKEY_IKE_R0" ); } assertion__; });  | |||
| 4749 | ||||
| 4750 | /* didn't loose parent? */ | |||
| 4751 | if (ike == NULL((void*)0)) { | |||
| 4752 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4752},  | |||
| 4753 | "sponsoring child state #%lu has no parent state #%lu", | |||
| 4754 | st->st_serialno, st->st_clonedfrom); | |||
| 4755 | /* XXX: release child? */ | |||
| 4756 | return; | |||
| 4757 | } | |||
| 4758 | ||||
| 4759 | 	pexpect(r->pcr_type == pcr_compute_dh_v2)({ _Bool assertion__ = r->pcr_type == pcr_compute_dh_v2; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 4759}, "%s", "r->pcr_type == pcr_compute_dh_v2" ); } assertion__; });  | |||
| 4760 | bool_Bool only_shared_false = false0; | |||
| 4761 | stf_status e; | |||
| 4762 | if (!finish_dh_v2(st, r, only_shared_false)) { | |||
| 4763 | record_v2N_response(ike->sa.st_logger, ike, md, | |||
| 4764 | v2N_INVALID_SYNTAX, NULL((void*)0), | |||
| 4765 | ENCRYPTED_PAYLOAD); | |||
| 4766 | e = STF_FATAL; /* kill family */ | |||
| 4767 | } else { | |||
| 4768 | e = ikev2_child_out_tail(ike, child, md); | |||
| 4769 | } | |||
| 4770 | ||||
| 4771 | complete_v2_state_transition(st, md, e); | |||
| 4772 | } | |||
| 4773 | ||||
| 4774 | static stf_status ikev2_child_out_tail(struct ike_sa *ike, struct child_sa *child, | |||
| 4775 | struct msg_digest *request_md) | |||
| 4776 | { | |||
| 4777 | stf_status ret; | |||
| 4778 | ||||
| 4779 | 	passert(ike != NULL){ _Bool assertion__ = ike != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4779}, "%s", "ike != NULL"); } };  | |||
| 4780 | 	pexpect((request_md != NULL) == (child->sa.st_sa_role == SA_RESPONDER))({ _Bool assertion__ = (request_md != ((void*)0)) == (child-> sa.st_sa_role == SA_RESPONDER); if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4780}, "%s", "(request_md != NULL) == (child->sa.st_sa_role == SA_RESPONDER)" ); } assertion__; });  | |||
| 4781 | /* 3 initiator initiating states */ | |||
| 4782 | 	pexpect((request_md == NULL) == (child->sa.st_state->kind == STATE_V2_REKEY_IKE_I0 ||({ _Bool assertion__ = (request_md == ((void*)0)) == (child-> sa.st_state->kind == STATE_V2_REKEY_IKE_I0 || child->sa .st_state->kind == STATE_V2_NEW_CHILD_I0 || child->sa.st_state ->kind == STATE_V2_REKEY_CHILD_I0); if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4784}, "%s", "(request_md == NULL) == (child->sa.st_state->kind == STATE_V2_REKEY_IKE_I0 || child->sa.st_state->kind == STATE_V2_NEW_CHILD_I0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_I0)" ); } assertion__; })  | |||
| 4783 | 					 child->sa.st_state->kind == STATE_V2_NEW_CHILD_I0 ||({ _Bool assertion__ = (request_md == ((void*)0)) == (child-> sa.st_state->kind == STATE_V2_REKEY_IKE_I0 || child->sa .st_state->kind == STATE_V2_NEW_CHILD_I0 || child->sa.st_state ->kind == STATE_V2_REKEY_CHILD_I0); if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4784}, "%s", "(request_md == NULL) == (child->sa.st_state->kind == STATE_V2_REKEY_IKE_I0 || child->sa.st_state->kind == STATE_V2_NEW_CHILD_I0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_I0)" ); } assertion__; })  | |||
| 4784 | 					 child->sa.st_state->kind == STATE_V2_REKEY_CHILD_I0))({ _Bool assertion__ = (request_md == ((void*)0)) == (child-> sa.st_state->kind == STATE_V2_REKEY_IKE_I0 || child->sa .st_state->kind == STATE_V2_NEW_CHILD_I0 || child->sa.st_state ->kind == STATE_V2_REKEY_CHILD_I0); if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4784}, "%s", "(request_md == NULL) == (child->sa.st_state->kind == STATE_V2_REKEY_IKE_I0 || child->sa.st_state->kind == STATE_V2_NEW_CHILD_I0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_I0)" ); } assertion__; });  | |||
| 4785 | /* 3 responder replying states */ | |||
| 4786 | 	pexpect((request_md != NULL) == (child->sa.st_state->kind == STATE_V2_REKEY_IKE_R0 ||({ _Bool assertion__ = (request_md != ((void*)0)) == (child-> sa.st_state->kind == STATE_V2_REKEY_IKE_R0 || child->sa .st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state ->kind == STATE_V2_REKEY_CHILD_R0); if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4788}, "%s", "(request_md != NULL) == (child->sa.st_state->kind == STATE_V2_REKEY_IKE_R0 || child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0)" ); } assertion__; })  | |||
| 4787 | 					 child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 ||({ _Bool assertion__ = (request_md != ((void*)0)) == (child-> sa.st_state->kind == STATE_V2_REKEY_IKE_R0 || child->sa .st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state ->kind == STATE_V2_REKEY_CHILD_R0); if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4788}, "%s", "(request_md != NULL) == (child->sa.st_state->kind == STATE_V2_REKEY_IKE_R0 || child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0)" ); } assertion__; })  | |||
| 4788 | 					 child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0))({ _Bool assertion__ = (request_md != ((void*)0)) == (child-> sa.st_state->kind == STATE_V2_REKEY_IKE_R0 || child->sa .st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state ->kind == STATE_V2_REKEY_CHILD_R0); if (!assertion__) { log_pexpect ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4788}, "%s", "(request_md != NULL) == (child->sa.st_state->kind == STATE_V2_REKEY_IKE_R0 || child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 || child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0)" ); } assertion__; });  | |||
| 4789 | /* 3 initiator receiving; can't happen here */ | |||
| 4790 | 	pexpect(child->sa.st_state->kind != STATE_V2_REKEY_IKE_I1 &&({ _Bool assertion__ = child->sa.st_state->kind != STATE_V2_REKEY_IKE_I1 && child->sa.st_state->kind != STATE_V2_NEW_CHILD_I1 && child->sa.st_state->kind != STATE_V2_REKEY_CHILD_I1 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4792}, "%s", "child->sa.st_state->kind != STATE_V2_REKEY_IKE_I1 && child->sa.st_state->kind != STATE_V2_NEW_CHILD_I1 && child->sa.st_state->kind != STATE_V2_REKEY_CHILD_I1" ); } assertion__; })  | |||
| 4791 | 		child->sa.st_state->kind != STATE_V2_NEW_CHILD_I1 &&({ _Bool assertion__ = child->sa.st_state->kind != STATE_V2_REKEY_IKE_I1 && child->sa.st_state->kind != STATE_V2_NEW_CHILD_I1 && child->sa.st_state->kind != STATE_V2_REKEY_CHILD_I1 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4792}, "%s", "child->sa.st_state->kind != STATE_V2_REKEY_IKE_I1 && child->sa.st_state->kind != STATE_V2_NEW_CHILD_I1 && child->sa.st_state->kind != STATE_V2_REKEY_CHILD_I1" ); } assertion__; })  | |||
| 4792 | 		child->sa.st_state->kind != STATE_V2_REKEY_CHILD_I1)({ _Bool assertion__ = child->sa.st_state->kind != STATE_V2_REKEY_IKE_I1 && child->sa.st_state->kind != STATE_V2_NEW_CHILD_I1 && child->sa.st_state->kind != STATE_V2_REKEY_CHILD_I1 ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 4792}, "%s", "child->sa.st_state->kind != STATE_V2_REKEY_IKE_I1 && child->sa.st_state->kind != STATE_V2_NEW_CHILD_I1 && child->sa.st_state->kind != STATE_V2_REKEY_CHILD_I1" ); } assertion__; });  | |||
| 4793 | ||||
| 4794 | ikev2_log_parentSA(&child->sa); | |||
| 4795 | ||||
| 4796 | struct pbs_outpacket_byte_stream reply_stream = open_pbs_out("reply packet", | |||
| 4797 | reply_buffer, sizeof(reply_buffer), | |||
| 4798 | child->sa.st_logger); | |||
| 4799 | ||||
| 4800 | /* HDR out Start assembling respone message */ | |||
| 4801 | ||||
| 4802 | pb_stream rbody = open_v2_message(&reply_stream, ike, request_md, | |||
| 4803 | ISAKMP_v2_CREATE_CHILD_SA); | |||
| 4804 | ||||
| 4805 | /* insert an Encryption payload header */ | |||
| 4806 | ||||
| 4807 | v2SK_payload_t sk = open_v2SK_payload(child->sa.st_logger, &rbody, ike); | |||
| 4808 | if (!pbs_ok(&sk.pbs)((&sk.pbs)->start != ((void*)0))) { | |||
| 4809 | return STF_INTERNAL_ERROR; | |||
| 4810 | } | |||
| 4811 | ||||
| 4812 | switch (child->sa.st_state->kind) { | |||
| 4813 | case STATE_V2_REKEY_IKE_R0: | |||
| 4814 | case STATE_V2_REKEY_IKE_I0: | |||
| 4815 | ret = ikev2_child_add_ike_payloads(child, &sk.pbs); | |||
| 4816 | break; | |||
| 4817 | case STATE_V2_NEW_CHILD_I0: | |||
| 4818 | case STATE_V2_REKEY_CHILD_I0: | |||
| 4819 | ret = ikev2_child_add_ipsec_payloads(child, &sk.pbs); | |||
| 4820 | break; | |||
| 4821 | case STATE_V2_NEW_CHILD_R0: | |||
| 4822 | 		if (!pexpect(child->sa.st_ipsec_pred == SOS_NOBODY)({ _Bool assertion__ = child->sa.st_ipsec_pred == 0; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4822}, "%s", "child->sa.st_ipsec_pred == SOS_NOBODY" ); } assertion__; })) {  | |||
| 4823 | return STF_INTERNAL_ERROR; | |||
| 4824 | } | |||
| 4825 | ret = ikev2_child_sa_respond(ike, child, | |||
| 4826 | request_md, &sk.pbs, | |||
| 4827 | ISAKMP_v2_CREATE_CHILD_SA); | |||
| 4828 | break; | |||
| 4829 | case STATE_V2_REKEY_CHILD_R0: | |||
| 4830 | 		if (!pexpect(child->sa.st_ipsec_pred != SOS_NOBODY)({ _Bool assertion__ = child->sa.st_ipsec_pred != 0; if (! assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4830}, "%s", "child->sa.st_ipsec_pred != SOS_NOBODY" ); } assertion__; })) {  | |||
| 4831 | return STF_INTERNAL_ERROR; | |||
| 4832 | } | |||
| 4833 | if (!ikev2_rekey_child_copy_ts(child)) { | |||
| 4834 | /* Should "just work", not working is a screw up */ | |||
| 4835 | return STF_INTERNAL_ERROR; | |||
| 4836 | } | |||
| 4837 | ret = ikev2_child_sa_respond(ike, child, | |||
| 4838 | request_md, &sk.pbs, | |||
| 4839 | ISAKMP_v2_CREATE_CHILD_SA); | |||
| 4840 | break; | |||
| 4841 | case STATE_V2_REKEY_IKE_I1: | |||
| 4842 | case STATE_V2_NEW_CHILD_I1: | |||
| 4843 | case STATE_V2_REKEY_CHILD_I1: | |||
| 4844 | return STF_INTERNAL_ERROR; | |||
| 4845 | default: | |||
| 4846 | 		bad_case(child->sa.st_state->kind)libreswan_bad_case("child->sa.st_state->kind", (child-> sa.st_state->kind), (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4846});  | |||
| 4847 | } | |||
| 4848 | ||||
| 4849 | if (ret != STF_OK) { | |||
| 4850 | 		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)) {  | |||
| 4851 | jam(buf, "ikev2_child_sa_respond returned "); | |||
| 4852 | jam_v2_stf_status(buf, ret); | |||
| 4853 | } | |||
| 4854 | return ret; /* abort building the response message */ | |||
| 4855 | } | |||
| 4856 | ||||
| 4857 | /* | |||
| 4858 | * RFC 7296 https://tools.ietf.org/html/rfc7296#section-2.8 | |||
| 4859 | * "when rekeying, the new Child SA SHOULD NOT have different Traffic | |||
| 4860 | * Selectors and algorithms than the old one." | |||
| 4861 | */ | |||
| 4862 | if (child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0) { | |||
| 4863 | if (!child_rekey_ts_verify(child, request_md)) { | |||
| 4864 | /* logged; but not recorded */ | |||
| 4865 | record_v2N_response(child->sa.st_logger, ike, request_md, v2N_TS_UNACCEPTABLE, | |||
| 4866 | NULL((void*)0), ENCRYPTED_PAYLOAD); | |||
| 4867 | return STF_FAIL; | |||
| 4868 | } | |||
| 4869 | } | |||
| 4870 | ||||
| 4871 | /* note: pst: parent; md->st: child */ | |||
| 4872 | ||||
| 4873 | /* const unsigned int len = pbs_offset(&sk.pbs); */ | |||
| 4874 | if (!close_v2SK_payload(&sk)) { | |||
| 4875 | return STF_INTERNAL_ERROR; | |||
| 4876 | } | |||
| 4877 | close_output_pbs(&rbody); | |||
| 4878 | close_output_pbs(&reply_stream); | |||
| 4879 | ||||
| 4880 | ret = encrypt_v2SK_payload(&sk); | |||
| 4881 | if (ret != STF_OK) | |||
| 4882 | return ret; | |||
| 4883 | ||||
| 4884 | /* | |||
| 4885 | * CREATE_CHILD_SA request and response are small 300 - 750 bytes. | |||
| 4886 | * ??? Should we support fragmenting? Maybe one day. | |||
| 4887 | */ | |||
| 4888 | record_v2_message(ike, &reply_stream, | |||
| 4889 | "packet from ikev2_child_out_cont", | |||
| 4890 | request_md != NULL((void*)0) ? MESSAGE_RESPONSE : MESSAGE_REQUEST); | |||
| 4891 | ||||
| 4892 | if (child->sa.st_state->kind == STATE_V2_NEW_CHILD_R0 || | |||
| 4893 | child->sa.st_state->kind == STATE_V2_REKEY_CHILD_R0) { | |||
| 4894 | log_ipsec_sa_established("negotiated new IPsec SA", &child->sa); | |||
| 4895 | } | |||
| 4896 | ||||
| 4897 | return STF_OK; | |||
| 4898 | } | |||
| 4899 | ||||
| 4900 | static stf_status ikev2_start_new_exchange(struct ike_sa *ike, | |||
| 4901 | struct child_sa *child) | |||
| 4902 | { | |||
| 4903 | switch (child->sa.st_establishing_sa) { /* where we're going */ | |||
| 4904 | case IKE_SA: | |||
| 4905 | return STF_OK; | |||
| 4906 | case IPSEC_SA: /* CHILD_SA */ | |||
| 4907 | if (!ike->sa.st_viable_parent) { | |||
| 4908 | child->sa.st_policy = child->sa.st_connection->policy; /* for pick_initiator */ | |||
| 4909 | ||||
| 4910 | loglog(RC_LOG_SERIOUS, "no viable to parent to initiate CREATE_CHILD_EXCHANGE %s; trying replace", | |||
| 4911 | child->sa.st_state->name); | |||
| 4912 | delete_event(&child->sa); | |||
| 4913 | event_schedule(EVENT_SA_REPLACE, REPLACE_ORPHAN_DELAYdeltatime(1), &child->sa); | |||
| 4914 | /* ??? surely this isn't yet a failure or a success */ | |||
| 4915 | return STF_FAIL; | |||
| 4916 | } | |||
| 4917 | return STF_OK; | |||
| 4918 | default: | |||
| 4919 | 		bad_case(child->sa.st_establishing_sa)libreswan_bad_case("child->sa.st_establishing_sa", (child-> sa.st_establishing_sa), (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 4919});  | |||
| 4920 | } | |||
| 4921 | ||||
| 4922 | } | |||
| 4923 | ||||
| 4924 | static void delete_or_replace_state(struct state *st) { | |||
| 4925 | struct connection *c = st->st_connection; | |||
| 4926 | ||||
| 4927 | if (st->st_event == NULL((void*)0)) { | |||
| 4928 | /* ??? should this be an assert/expect? */ | |||
| 4929 | loglog(RC_LOG_SERIOUS, "received Delete SA payload: delete IPsec State #%lu. st_event == NULL", | |||
| 4930 | st->st_serialno); | |||
| 4931 | delete_state(st); | |||
| 4932 | } else if (st->st_event->ev_type == EVENT_SA_EXPIRE) { | |||
| 4933 | /* this state was going to EXPIRE: hurry it along */ | |||
| 4934 | /* ??? why is this treated specially. Can we not delete_state()? */ | |||
| 4935 | loglog(RC_LOG_SERIOUS, "received Delete SA payload: expire IPsec State #%lu now", | |||
| 4936 | st->st_serialno); | |||
| 4937 | event_force(EVENT_SA_EXPIRE, st); | |||
| 4938 | } else if (c->newest_ipsec_sa == st->st_serialno && | |||
| 4939 | (c->policy & POLICY_UP((lset_t)1 << (POLICY_UP_IX)))) { | |||
| 4940 | /* | |||
| 4941 | * Last IPsec SA for a permanent connection that we have initiated. | |||
| 4942 | * Replace it now. Useful if the other peer is rebooting. | |||
| 4943 | */ | |||
| 4944 | loglog(RC_LOG_SERIOUS, "received Delete SA payload: replace IPsec State #%lu now", | |||
| 4945 | st->st_serialno); | |||
| 4946 | st->st_replace_margin = deltatime(0); | |||
| 4947 | event_force(EVENT_SA_REPLACE, st); | |||
| 4948 | } else { | |||
| 4949 | loglog(RC_LOG_SERIOUS, "received Delete SA payload: delete IPsec State #%lu now", | |||
| 4950 | st->st_serialno); | |||
| 4951 | delete_state(st); | |||
| 4952 | } | |||
| 4953 | } | |||
| 4954 | ||||
| 4955 | /* can an established state initiate or respond to mobike probe */ | |||
| 4956 | static bool_Bool mobike_check_established(const struct state *st) | |||
| 4957 | { | |||
| 4958 | struct connection *c = st->st_connection; | |||
| 4959 | /* notice tricky use of & on booleans */ | |||
| 4960 | 	bool_Bool ret = LIN(POLICY_MOBIKE, c->policy)(((((lset_t)1 << (POLICY_MOBIKE_IX))) & (c->policy )) == (((lset_t)1 << (POLICY_MOBIKE_IX)))) &  | |||
| 4961 | st->st_seen_mobike & st->st_sent_mobike & | |||
| 4962 | 		   IS_ISAKMP_SA_ESTABLISHED(st->st_state)((((lset_t)1 << (st->st_state->kind)) & (((lset_t )1 << (STATE_MAIN_R3)) | ((lset_t)1 << (STATE_MAIN_I4 )) | ((lset_t)1 << (STATE_AGGR_I2)) | ((lset_t)1 << (STATE_AGGR_R2)) | ((lset_t)1 << (STATE_XAUTH_R0)) | ( (lset_t)1 << (STATE_XAUTH_R1)) | ((lset_t)1 << (STATE_MODE_CFG_R0 )) | ((lset_t)1 << (STATE_MODE_CFG_R1)) | ((lset_t)1 << (STATE_MODE_CFG_R2)) | ((lset_t)1 << (STATE_MODE_CFG_I1 )) | ((lset_t)1 << (STATE_XAUTH_I0)) | ((lset_t)1 << (STATE_XAUTH_I1)) | ((lset_t)1 << (STATE_V2_ESTABLISHED_IKE_SA )))) != ((lset_t)0));  | |||
| 4963 | ||||
| 4964 | return ret; | |||
| 4965 | } | |||
| 4966 | ||||
| 4967 | static bool_Bool process_mobike_resp(struct msg_digest *md) | |||
| 4968 | { | |||
| 4969 | struct state *st = md->st; | |||
| 4970 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 4970});  | |||
| 4971 | bool_Bool may_mobike = mobike_check_established(st); | |||
| 4972 | /* ??? there is currently no need for separate natd_[sd] variables */ | |||
| 4973 | bool_Bool natd_s = FALSE0; | |||
| 4974 | bool_Bool natd_d = FALSE0; | |||
| 4975 | struct payload_digest *ntfy; | |||
| 4976 | ||||
| 4977 | if (!may_mobike) { | |||
| 4978 | return FALSE0; | |||
| 4979 | } | |||
| 4980 | ||||
| 4981 | for (ntfy = md->chain[ISAKMP_NEXT_v2N]; ntfy != NULL((void*)0); ntfy = ntfy->next) { | |||
| 4982 | switch (ntfy->payload.v2n.isan_type) { | |||
| 4983 | case v2N_NAT_DETECTION_DESTINATION_IP: | |||
| 4984 | natd_d = TRUE1; | |||
| 4985 | 			dbg("TODO: process %s in MOBIKE response ",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("TODO: process %s in MOBIKE response ", enum_name (&ikev2_notify_names, ntfy->payload.v2n.isan_type)); } }  | |||
| 4986 | 			    enum_name(&ikev2_notify_names, ntfy->payload.v2n.isan_type)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("TODO: process %s in MOBIKE response ", enum_name (&ikev2_notify_names, ntfy->payload.v2n.isan_type)); } };  | |||
| 4987 | break; | |||
| 4988 | case v2N_NAT_DETECTION_SOURCE_IP: | |||
| 4989 | natd_s = TRUE1; | |||
| 4990 | 			dbg("TODO: process %s in MOBIKE response ",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("TODO: process %s in MOBIKE response ", enum_name (&ikev2_notify_names, ntfy->payload.v2n.isan_type)); } }  | |||
| 4991 | 			    enum_name(&ikev2_notify_names, ntfy->payload.v2n.isan_type)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("TODO: process %s in MOBIKE response ", enum_name (&ikev2_notify_names, ntfy->payload.v2n.isan_type)); } };  | |||
| 4992 | ||||
| 4993 | break; | |||
| 4994 | } | |||
| 4995 | } | |||
| 4996 | ||||
| 4997 | /* use of bitwise & on bool values is correct but odd */ | |||
| 4998 | bool_Bool ret = natd_s & natd_d; | |||
| 4999 | ||||
| 5000 | if (ret && !update_mobike_endpoints(ike, md)) { | |||
| 5001 | /* IPs already updated from md */ | |||
| 5002 | return FALSE0; | |||
| 5003 | } | |||
| 5004 | update_ike_endpoints(ike, md); /* update state sender so we can find it for IPsec SA */ | |||
| 5005 | ||||
| 5006 | return ret; | |||
| 5007 | } | |||
| 5008 | ||||
| 5009 | /* currently we support only MOBIKE notifies and v2N_REDIRECT notify */ | |||
| 5010 | static void process_informational_notify_req(struct msg_digest *md, bool_Bool *redirect, bool_Bool *ntfy_natd, | |||
| 5011 | chunk_t *cookie2) | |||
| 5012 | { | |||
| 5013 | struct payload_digest *ntfy; | |||
| 5014 | struct state *st = md->st; | |||
| 5015 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 5015});  | |||
| 5016 | bool_Bool may_mobike = mobike_check_established(st); | |||
| 5017 | bool_Bool ntfy_update_sa = FALSE0; | |||
| 5018 | ip_address redirect_ip; | |||
| 5019 | ||||
| 5020 | for (ntfy = md->chain[ISAKMP_NEXT_v2N]; ntfy != NULL((void*)0); ntfy = ntfy->next) { | |||
| 5021 | switch (ntfy->payload.v2n.isan_type) { | |||
| 5022 | case v2N_REDIRECT: | |||
| 5023 | 			dbg("received v2N_REDIRECT in informational"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("received v2N_REDIRECT in informational"); } };  | |||
| 5024 | err_t e = parse_redirect_payload(&ntfy->pbs, | |||
| 5025 | st->st_connection->accept_redirect_to, | |||
| 5026 | NULL((void*)0), | |||
| 5027 | &redirect_ip, | |||
| 5028 | ike->sa.st_logger); | |||
| 5029 | if (e != NULL((void*)0)) { | |||
| 5030 | loglog(RC_LOG_SERIOUS, "warning: parsing of v2N_REDIRECT payload failed: %s", e); | |||
| 5031 | } else { | |||
| 5032 | *redirect = TRUE1; | |||
| 5033 | st->st_connection->temp_vars.redirect_ip = redirect_ip; | |||
| 5034 | } | |||
| 5035 | return; | |||
| 5036 | ||||
| 5037 | case v2N_UPDATE_SA_ADDRESSES: | |||
| 5038 | if (may_mobike) { | |||
| 5039 | ntfy_update_sa = TRUE1; | |||
| 5040 | 				dbg("Need to process v2N_UPDATE_SA_ADDRESSES"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Need to process v2N_UPDATE_SA_ADDRESSES"); } };  | |||
| 5041 | } else { | |||
| 5042 | 				libreswan_log("Connection does not allow MOBIKE, ignoring UPDATE_SA_ADDRESSES")loglog(RC_LOG, "Connection does not allow MOBIKE, ignoring UPDATE_SA_ADDRESSES" );  | |||
| 5043 | } | |||
| 5044 | break; | |||
| 5045 | ||||
| 5046 | case v2N_NO_NATS_ALLOWED: | |||
| 5047 | if (may_mobike) | |||
| 5048 | st->st_seen_nonats = TRUE1; | |||
| 5049 | else | |||
| 5050 | 				libreswan_log("Connection does not allow MOBIKE, ignoring v2N_NO_NATS_ALLOWED")loglog(RC_LOG, "Connection does not allow MOBIKE, ignoring v2N_NO_NATS_ALLOWED" );  | |||
| 5051 | break; | |||
| 5052 | ||||
| 5053 | case v2N_NAT_DETECTION_DESTINATION_IP: | |||
| 5054 | case v2N_NAT_DETECTION_SOURCE_IP: | |||
| 5055 | *ntfy_natd = TRUE1; | |||
| 5056 | 			dbg("TODO: Need to process NAT DETECTION payload if we are initiator"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("TODO: Need to process NAT DETECTION payload if we are initiator" ); } };  | |||
| 5057 | break; | |||
| 5058 | ||||
| 5059 | case v2N_NO_ADDITIONAL_ADDRESSES: | |||
| 5060 | if (may_mobike) { | |||
| 5061 | 				dbg("Received NO_ADDITIONAL_ADDRESSES - no need to act on this"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Received NO_ADDITIONAL_ADDRESSES - no need to act on this" ); } };  | |||
| 5062 | } else { | |||
| 5063 | 				libreswan_log("Connection does not allow MOBIKE, ignoring NO_ADDITIONAL_ADDRESSES payload")loglog(RC_LOG, "Connection does not allow MOBIKE, ignoring NO_ADDITIONAL_ADDRESSES payload" );  | |||
| 5064 | } | |||
| 5065 | break; | |||
| 5066 | ||||
| 5067 | case v2N_COOKIE2: | |||
| 5068 | if (may_mobike) { | |||
| 5069 | /* copy cookie */ | |||
| 5070 | if (ntfy->payload.v2n.isan_length > IKEv2_MAX_COOKIE_SIZE64) { | |||
| 5071 | 					dbg("MOBIKE COOKIE2 notify payload too big - ignored"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("MOBIKE COOKIE2 notify payload too big - ignored" ); } };  | |||
| 5072 | } else { | |||
| 5073 | const pb_stream *dc_pbs = &ntfy->pbs; | |||
| 5074 | ||||
| 5075 | *cookie2 = clone_bytes_as_chunk(dc_pbs->cur, pbs_left(dc_pbs)((size_t)((dc_pbs)->roof - (dc_pbs)->cur)), | |||
| 5076 | "saved cookie2"); | |||
| 5077 | 					DBG_dump_hunk("MOBIKE COOKIE2 received:", *cookie2){ typeof(*cookie2) hunk_ = *cookie2; DBG_dump("MOBIKE COOKIE2 received:" , hunk_.ptr, hunk_.len); };  | |||
| 5078 | } | |||
| 5079 | } else { | |||
| 5080 | 				libreswan_log("Connection does not allow MOBIKE, ignoring COOKIE2")loglog(RC_LOG, "Connection does not allow MOBIKE, ignoring COOKIE2" );  | |||
| 5081 | } | |||
| 5082 | break; | |||
| 5083 | ||||
| 5084 | case v2N_ADDITIONAL_IP4_ADDRESS: | |||
| 5085 | 			dbg("ADDITIONAL_IP4_ADDRESS payload ignored (not yet supported)"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ADDITIONAL_IP4_ADDRESS payload ignored (not yet supported)" ); } };  | |||
| 5086 | /* not supported yet */ | |||
| 5087 | break; | |||
| 5088 | case v2N_ADDITIONAL_IP6_ADDRESS: | |||
| 5089 | 			dbg("ADDITIONAL_IP6_ADDRESS payload ignored (not yet supported)"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("ADDITIONAL_IP6_ADDRESS payload ignored (not yet supported)" ); } };  | |||
| 5090 | /* not supported yet */ | |||
| 5091 | break; | |||
| 5092 | ||||
| 5093 | default: | |||
| 5094 | 			dbg("Received unexpected %s notify - ignored",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Received unexpected %s notify - ignored", enum_name (&ikev2_notify_names, ntfy->payload.v2n.isan_type)); } }  | |||
| 5095 | 			    enum_name(&ikev2_notify_names, ntfy->payload.v2n.isan_type)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Received unexpected %s notify - ignored", enum_name (&ikev2_notify_names, ntfy->payload.v2n.isan_type)); } };  | |||
| 5096 | break; | |||
| 5097 | } | |||
| 5098 | } | |||
| 5099 | ||||
| 5100 | if (ntfy_update_sa) { | |||
| 5101 | 		if (LHAS(st->hidden_variables.st_nat_traversal, NATED_HOST)(((st->hidden_variables.st_nat_traversal) & ((lset_t)1 << (NATED_HOST))) != ((lset_t)0))) {  | |||
| 5102 | 			libreswan_log("Ignoring MOBIKE UPDATE_SA since we are behind NAT")loglog(RC_LOG, "Ignoring MOBIKE UPDATE_SA since we are behind NAT" );  | |||
| 5103 | } else { | |||
| 5104 | if (!update_mobike_endpoints(ike, md)) | |||
| 5105 | *ntfy_natd = FALSE0; | |||
| 5106 | update_ike_endpoints(ike, md); /* update state sender so we can find it for IPsec SA */ | |||
| 5107 | } | |||
| 5108 | } | |||
| 5109 | ||||
| 5110 | if (may_mobike && !ntfy_update_sa && *ntfy_natd && | |||
| 5111 | 	    !LHAS(st->hidden_variables.st_nat_traversal, NATED_HOST)(((st->hidden_variables.st_nat_traversal) & ((lset_t)1 << (NATED_HOST))) != ((lset_t)0))) {  | |||
| 5112 | /* | |||
| 5113 | * If this is a MOBIKE probe, use the received IP:port | |||
| 5114 | * for only this reply packet, without updating IKE | |||
| 5115 | * endpoint and without UPDATE_SA. | |||
| 5116 | */ | |||
| 5117 | st->st_mobike_remote_endpoint = md->sender; | |||
| 5118 | } | |||
| 5119 | ||||
| 5120 | if (ntfy_update_sa) | |||
| 5121 | 		libreswan_log("MOBIKE request: updating IPsec SA by request")loglog(RC_LOG, "MOBIKE request: updating IPsec SA by request" );  | |||
| 5122 | else | |||
| 5123 | 		dbg("MOBIKE request: not updating IPsec SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("MOBIKE request: not updating IPsec SA"); } };  | |||
| 5124 | } | |||
| 5125 | ||||
| 5126 | static void mobike_reset_remote(struct state *st, struct mobike *est_remote) | |||
| 5127 | { | |||
| 5128 | if (est_remote->interface == NULL((void*)0)) | |||
| 5129 | return; | |||
| 5130 | ||||
| 5131 | st->st_remote_endpoint = est_remote->remote; | |||
| 5132 | st->st_interface = est_remote->interface; | |||
| 5133 | pexpect_st_local_endpoint(st); | |||
| 5134 | st->st_mobike_remote_endpoint = unset_endpoint; | |||
| 5135 | } | |||
| 5136 | ||||
| 5137 | /* MOBIKE liveness/update response. set temp remote address/interface */ | |||
| 5138 | static void mobike_switch_remote(struct msg_digest *md, struct mobike *est_remote) | |||
| 5139 | { | |||
| 5140 | struct state *st = md->st; | |||
| 5141 | ||||
| 5142 | est_remote->interface = NULL((void*)0); | |||
| 5143 | ||||
| 5144 | if (mobike_check_established(st) && | |||
| 5145 | 	    !LHAS(st->hidden_variables.st_nat_traversal, NATED_HOST)(((st->hidden_variables.st_nat_traversal) & ((lset_t)1 << (NATED_HOST))) != ((lset_t)0)) &&  | |||
| 5146 | (!sameaddr(&md->sender, &st->st_remote_endpoint) || | |||
| 5147 | endpoint_hport(&md->sender) != endpoint_hport(&st->st_remote_endpoint))) { | |||
| 5148 | /* remember the established/old address and interface */ | |||
| 5149 | est_remote->remote = st->st_remote_endpoint; | |||
| 5150 | est_remote->interface = st->st_interface; | |||
| 5151 | ||||
| 5152 | /* set temp one and after the message sent reset it */ | |||
| 5153 | st->st_remote_endpoint = md->sender; | |||
| 5154 | st->st_interface = md->iface; | |||
| 5155 | pexpect_st_local_endpoint(st); | |||
| 5156 | } | |||
| 5157 | } | |||
| 5158 | ||||
| 5159 | static stf_status add_mobike_response_payloads( | |||
| 5160 | chunk_t *cookie2, /* freed by us */ | |||
| 5161 | struct msg_digest *md, | |||
| 5162 | pb_stream *pbs) | |||
| 5163 | { | |||
| 5164 | 	dbg("adding NATD%s payloads to MOBIKE response",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("adding NATD%s payloads to MOBIKE response", cookie2 ->len != 0 ? " and cookie2" : ""); } }  | |||
| 5165 | 	    cookie2->len != 0 ? " and cookie2" : ""){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("adding NATD%s payloads to MOBIKE response", cookie2 ->len != 0 ? " and cookie2" : ""); } };  | |||
| 5166 | ||||
| 5167 | stf_status r = STF_INTERNAL_ERROR; | |||
| 5168 | ||||
| 5169 | struct state *st = md->st; | |||
| 5170 | /* assumptions from ikev2_out_nat_v2n() and caller */ | |||
| 5171 | 	pexpect(v2_msg_role(md) == MESSAGE_REQUEST)({ _Bool assertion__ = v2_msg_role(md) == MESSAGE_REQUEST; if (!assertion__) { log_pexpect((where_t) { .func = __func__, . basename = "ikev2_parent.c" , .line = 5171}, "%s", "v2_msg_role(md) == MESSAGE_REQUEST" ); } assertion__; });  | |||
| 5172 | 	pexpect(!ike_spi_is_zero(&st->st_ike_spis.responder))({ _Bool assertion__ = !ike_spi_is_zero(&st->st_ike_spis .responder); if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5172}, "%s" , "!ike_spi_is_zero(&st->st_ike_spis.responder)"); } assertion__ ; });  | |||
| 5173 | if (ikev2_out_nat_v2n(pbs, st, &st->st_ike_spis.responder) && | |||
| 5174 | 	    (cookie2->len == 0 || emit_v2N_hunk(v2N_COOKIE2, *cookie2, pbs)emit_v2N_bytes(v2N_COOKIE2, (*cookie2).ptr, (*cookie2).len, pbs )))  | |||
| 5175 | r = STF_OK; | |||
| 5176 | ||||
| 5177 | free_chunk_content(cookie2); | |||
| 5178 | return r; | |||
| 5179 | } | |||
| 5180 | /* | |||
| 5181 | * | |||
| 5182 | *************************************************************** | |||
| 5183 | * INFORMATIONAL ***** | |||
| 5184 | *************************************************************** | |||
| 5185 | * - | |||
| 5186 | * | |||
| 5187 | * | |||
| 5188 | */ | |||
| 5189 | ||||
| 5190 | /* RFC 5996 1.4 "The INFORMATIONAL Exchange" | |||
| 5191 | * | |||
| 5192 | * HDR, SK {[N,] [D,] [CP,] ...} --> | |||
| 5193 | * <-- HDR, SK {[N,] [D,] [CP], ...} | |||
| 5194 | */ | |||
| 5195 | ||||
| 5196 | stf_status process_encrypted_informational_ikev2(struct ike_sa *ike, | |||
| 5197 | struct child_sa *null_child, | |||
| 5198 | struct msg_digest *md) | |||
| 5199 | { | |||
| 5200 | 	pexpect(null_child == NULL)({ _Bool assertion__ = null_child == ((void*)0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5200}, "%s", "null_child == NULL"); } assertion__; });  | |||
| 5201 | int ndp = 0; /* number Delete payloads for IPsec protocols */ | |||
| 5202 | bool_Bool del_ike = false0; /* any IKE SA Deletions? */ | |||
| 5203 | bool_Bool seen_and_parsed_redirect = FALSE0; | |||
| 5204 | ||||
| 5205 | /* | |||
| 5206 | * we need connection and boolean below | |||
| 5207 | * in a separate variables because we | |||
| 5208 | * do something with them after we delete | |||
| 5209 | * the state. | |||
| 5210 | * | |||
| 5211 | * XXX: which is of course broken; code should return | |||
| 5212 | * STF_ZOMBIFY and and let state machine clean things up. | |||
| 5213 | */ | |||
| 5214 | struct connection *c = ike->sa.st_connection; | |||
| 5215 | bool_Bool do_unroute = ike->sa.st_sent_redirect && c->kind == CK_PERMANENT; | |||
| 5216 | chunk_t cookie2 = empty_chunk; | |||
| 5217 | ||||
| 5218 | /* Are we responding (as opposed to processing a response)? */ | |||
| 5219 | const bool_Bool responding = v2_msg_role(md) == MESSAGE_REQUEST; | |||
| 5220 | 	dbg("an informational %s ", responding ? "request should send a response" : "response"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("an informational %s ", responding ? "request should send a response" : "response"); } };  | |||
| 5221 | ||||
| 5222 | /* | |||
| 5223 | * Process NOTIFY payloads - ignore MOBIKE when deleting | |||
| 5224 | */ | |||
| 5225 | bool_Bool send_mobike_resp = false0; /* only if responding */ | |||
| 5226 | ||||
| 5227 | if (md->chain[ISAKMP_NEXT_v2D] == NULL((void*)0)) { | |||
| 5228 | if (responding) { | |||
| 5229 | process_informational_notify_req(md, &seen_and_parsed_redirect, &send_mobike_resp, &cookie2); | |||
| 5230 | } else { | |||
| 5231 | if (process_mobike_resp(md)) { | |||
| 5232 | libreswan_log("MOBIKE response: updating IPsec SA")loglog(RC_LOG, "MOBIKE response: updating IPsec SA"); | |||
| 5233 | } else { | |||
| 5234 | 				dbg("MOBIKE response: not updating IPsec SA"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("MOBIKE response: not updating IPsec SA"); } };  | |||
| 5235 | } | |||
| 5236 | } | |||
| 5237 | } else { | |||
| 5238 | /* | |||
| 5239 | * RFC 7296 1.4.1 "Deleting an SA with INFORMATIONAL Exchanges" | |||
| 5240 | */ | |||
| 5241 | ||||
| 5242 | /* | |||
| 5243 | * Pass 1 over Delete Payloads: | |||
| 5244 | * | |||
| 5245 | * - Count number of IPsec SA Delete Payloads | |||
| 5246 | * - notice any IKE SA Delete Payload | |||
| 5247 | * - sanity checking | |||
| 5248 | */ | |||
| 5249 | ||||
| 5250 | for (struct payload_digest *p = md->chain[ISAKMP_NEXT_v2D]; | |||
| 5251 | p != NULL((void*)0); p = p->next) { | |||
| 5252 | struct ikev2_delete *v2del = &p->payload.v2delete; | |||
| 5253 | ||||
| 5254 | switch (v2del->isad_protoid) { | |||
| 5255 | case PROTO_ISAKMP1: | |||
| 5256 | if (!responding) { | |||
| 5257 | 					libreswan_log("Response to Delete improperly includes IKE SA")loglog(RC_LOG, "Response to Delete improperly includes IKE SA" );  | |||
| 5258 | return STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 5259 | } | |||
| 5260 | ||||
| 5261 | if (del_ike) { | |||
| 5262 | 					libreswan_log("Error: INFORMATIONAL Exchange with more than one Delete Payload for the IKE SA")loglog(RC_LOG, "Error: INFORMATIONAL Exchange with more than one Delete Payload for the IKE SA" );  | |||
| 5263 | return STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 5264 | } | |||
| 5265 | ||||
| 5266 | if (v2del->isad_nrspi != 0 || v2del->isad_spisize != 0) { | |||
| 5267 | 					libreswan_log("IKE SA Delete has non-zero SPI size or number of SPIs")loglog(RC_LOG, "IKE SA Delete has non-zero SPI size or number of SPIs" );  | |||
| 5268 | return STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 5269 | } | |||
| 5270 | ||||
| 5271 | del_ike = true1; | |||
| 5272 | break; | |||
| 5273 | ||||
| 5274 | case PROTO_IPSEC_AH2: | |||
| 5275 | case PROTO_IPSEC_ESP3: | |||
| 5276 | if (v2del->isad_spisize != sizeof(ipsec_spi_t)) { | |||
| 5277 | 					libreswan_log("IPsec Delete Notification has invalid SPI size %u",loglog(RC_LOG, "IPsec Delete Notification has invalid SPI size %u" , v2del->isad_spisize)  | |||
| 5278 | 						v2del->isad_spisize)loglog(RC_LOG, "IPsec Delete Notification has invalid SPI size %u" , v2del->isad_spisize);  | |||
| 5279 | return STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 5280 | } | |||
| 5281 | ||||
| 5282 | 				if (v2del->isad_nrspi * v2del->isad_spisize != pbs_left(&p->pbs)((size_t)((&p->pbs)->roof - (&p->pbs)->cur ))) {  | |||
| 5283 | 					libreswan_log("IPsec Delete Notification payload size is %zu but %u is required",loglog(RC_LOG, "IPsec Delete Notification payload size is %zu but %u is required" , ((size_t)((&p->pbs)->roof - (&p->pbs)-> cur)), v2del->isad_nrspi * v2del->isad_spisize)  | |||
| 5284 | 						pbs_left(&p->pbs),loglog(RC_LOG, "IPsec Delete Notification payload size is %zu but %u is required" , ((size_t)((&p->pbs)->roof - (&p->pbs)-> cur)), v2del->isad_nrspi * v2del->isad_spisize)  | |||
| 5285 | 						v2del->isad_nrspi * v2del->isad_spisize)loglog(RC_LOG, "IPsec Delete Notification payload size is %zu but %u is required" , ((size_t)((&p->pbs)->roof - (&p->pbs)-> cur)), v2del->isad_nrspi * v2del->isad_spisize);  | |||
| 5286 | return STF_FAIL + v2N_INVALID_SYNTAX; | |||
| 5287 | } | |||
| 5288 | ||||
| 5289 | ndp++; | |||
| 5290 | break; | |||
| 5291 | ||||
| 5292 | default: | |||
| 5293 | 				libreswan_log("Ignored bogus delete protoid '%d'", v2del->isad_protoid)loglog(RC_LOG, "Ignored bogus delete protoid '%d'", v2del-> isad_protoid);  | |||
| 5294 | } | |||
| 5295 | } | |||
| 5296 | ||||
| 5297 | if (del_ike && ndp != 0) | |||
| 5298 | 			libreswan_log("Odd: INFORMATIONAL Exchange deletes IKE SA and yet also deletes some IPsec SA")loglog(RC_LOG, "Odd: INFORMATIONAL Exchange deletes IKE SA and yet also deletes some IPsec SA" );  | |||
| 5299 | } | |||
| 5300 | ||||
| 5301 | /* | |||
| 5302 | * response packet preparation: DELETE or non-delete (eg MOBIKE/keepalive/REDIRECT) | |||
| 5303 | * | |||
| 5304 | * There can be at most one Delete Payload for an IKE SA. | |||
| 5305 | * It means that this very SA is to be deleted. | |||
| 5306 | * | |||
| 5307 | * For each non-IKE Delete Payload we receive, | |||
| 5308 | * we respond with a corresponding Delete Payload. | |||
| 5309 | * Note that that means we will have an empty response | |||
| 5310 | * if no Delete Payloads came in or if the only | |||
| 5311 | * Delete Payload is for an IKE SA. | |||
| 5312 | * | |||
| 5313 | * If we received NAT detection payloads as per MOBIKE, send answers | |||
| 5314 | */ | |||
| 5315 | ||||
| 5316 | /* | |||
| 5317 | * Variables for generating response. | |||
| 5318 | * NOTE: only meaningful if "responding" is true! | |||
| 5319 | * These declarations must be placed so early because they must be in scope for | |||
| 5320 | * all of the several chunks of code that handle responding. | |||
| 5321 | * | |||
| 5322 | * XXX: in terms of readability and reliability, this | |||
| 5323 | * interleaving of initiator vs response code paths is pretty | |||
| 5324 | * screwed up. | |||
| 5325 | */ | |||
| 5326 | ||||
| 5327 | struct pbs_outpacket_byte_stream reply_stream; | |||
| 5328 | pb_stream rbody; | |||
| 5329 | v2SK_payload_t sk; | |||
| 5330 | zero(&rbody)memset((&rbody), '\0', sizeof(*(&rbody))); | |||
| 5331 | zero(&sk)memset((&sk), '\0', sizeof(*(&sk))); | |||
| 5332 | ||||
| 5333 | if (responding) { | |||
| 5334 | /* make sure HDR is at start of a clean buffer */ | |||
| 5335 | reply_stream = open_pbs_out("information exchange reply packet", | |||
| 5336 | reply_buffer, sizeof(reply_buffer), | |||
| 5337 | ike->sa.st_logger); | |||
| 5338 | ||||
| 5339 | ||||
| 5340 | /* authenticated decrypted response - It's alive, alive! */ | |||
| 5341 | 		dbg("Received an INFORMATIONAL response, updating st_last_liveness, no pending_liveness"){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Received an INFORMATIONAL response, updating st_last_liveness, no pending_liveness" ); } };  | |||
| 5342 | ike->sa.st_last_liveness = mononow(); | |||
| 5343 | ike->sa.st_pend_liveness = false0; | |||
| 5344 | ||||
| 5345 | /* HDR out */ | |||
| 5346 | ||||
| 5347 | rbody = open_v2_message(&reply_stream, ike, | |||
| 5348 | md /* response */, | |||
| 5349 | ISAKMP_v2_INFORMATIONAL); | |||
| 5350 | if (!pbs_ok(&rbody)((&rbody)->start != ((void*)0))) { | |||
| 5351 | return STF_INTERNAL_ERROR; | |||
| 5352 | } | |||
| 5353 | ||||
| 5354 | /* insert an Encryption payload header */ | |||
| 5355 | ||||
| 5356 | sk = open_v2SK_payload(ike->sa.st_logger, &rbody, ike); | |||
| 5357 | if (!pbs_ok(&sk.pbs)((&sk.pbs)->start != ((void*)0))) { | |||
| 5358 | return STF_INTERNAL_ERROR; | |||
| 5359 | } | |||
| 5360 | ||||
| 5361 | if (send_mobike_resp) { | |||
| 5362 | stf_status e = add_mobike_response_payloads( | |||
| 5363 | &cookie2, /* will be freed */ | |||
| 5364 | md, &sk.pbs); | |||
| 5365 | if (e != STF_OK) | |||
| 5366 | return e; | |||
| 5367 | } | |||
| 5368 | } | |||
| 5369 | ||||
| 5370 | /* | |||
| 5371 | * This happens when we are original initiator, | |||
| 5372 | * and we received REDIRECT payload during the active | |||
| 5373 | * session. | |||
| 5374 | */ | |||
| 5375 | if (seen_and_parsed_redirect) | |||
| 5376 | event_force(EVENT_v2_REDIRECT, &ike->sa); | |||
| 5377 | ||||
| 5378 | /* | |||
| 5379 | * Do the actual deletion. | |||
| 5380 | * If responding, build the body of the response. | |||
| 5381 | */ | |||
| 5382 | ||||
| 5383 | if (!responding && ike->sa.st_state->kind == STATE_IKESA_DEL) { | |||
| 5384 | /* | |||
| 5385 | * this must be a response to our IKE SA delete request | |||
| 5386 | * Even if there are are other Delete Payloads, | |||
| 5387 | * they cannot matter: we delete the family. | |||
| 5388 | */ | |||
| 5389 | delete_ike_family(ike, DONT_SEND_DELETE); | |||
| 5390 | md->st = NULL((void*)0); | |||
| 5391 | ike = NULL((void*)0); | |||
| 5392 | } else if (!responding && md->chain[ISAKMP_NEXT_v2D] == NULL((void*)0)) { | |||
| 5393 | /* | |||
| 5394 | * A liveness update response is handled here | |||
| 5395 | */ | |||
| 5396 | 		dbg("Received an INFORMATIONAL non-delete request; updating liveness, no longer pending."){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("Received an INFORMATIONAL non-delete request; updating liveness, no longer pending." ); } };  | |||
| 5397 | ike->sa.st_last_liveness = mononow(); | |||
| 5398 | ike->sa.st_pend_liveness = false0; | |||
| 5399 | } else if (del_ike) { | |||
| 5400 | /* | |||
| 5401 | * If we are deleting the Parent SA, the Child SAs will be torn down as well, | |||
| 5402 | * so no point processing the other Delete SA payloads. | |||
| 5403 | * We won't catch nonsense in those payloads. | |||
| 5404 | * | |||
| 5405 | * But wait: we cannot delete the IKE SA until after | |||
| 5406 | * we've sent the response packet. To be continued | |||
| 5407 | * below ... | |||
| 5408 | */ | |||
| 5409 | 		passert(responding){ _Bool assertion__ = responding; if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5409}, "%s", "responding"); } };  | |||
| 5410 | } else { | |||
| 5411 | /* | |||
| 5412 | * Pass 2 over the Delete Payloads: | |||
| 5413 | * Actual IPsec SA deletion. | |||
| 5414 | * If responding, build response Delete Payloads. | |||
| 5415 | * If there is no payload, this loop is a no-op. | |||
| 5416 | */ | |||
| 5417 | for (struct payload_digest *p = md->chain[ISAKMP_NEXT_v2D]; | |||
| 5418 | p != NULL((void*)0); p = p->next) { | |||
| 5419 | struct ikev2_delete *v2del = &p->payload.v2delete; | |||
| 5420 | ||||
| 5421 | switch (v2del->isad_protoid) { | |||
| 5422 | case PROTO_ISAKMP1: | |||
| 5423 | 				passert_fail(ike->sa.st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 5423}, "unexpected IKE delete");  | |||
| 5424 | ||||
| 5425 | case PROTO_IPSEC_AH2: /* Child SAs */ | |||
| 5426 | case PROTO_IPSEC_ESP3: /* Child SAs */ | |||
| 5427 | { | |||
| 5428 | /* stuff for responding */ | |||
| 5429 | ipsec_spi_t spi_buf[128]; | |||
| 5430 | uint16_t j = 0; /* number of SPIs in spi_buf */ | |||
| 5431 | uint16_t i; | |||
| 5432 | ||||
| 5433 | for (i = 0; i < v2del->isad_nrspi; i++) { | |||
| 5434 | ipsec_spi_t spi; | |||
| 5435 | ||||
| 5436 | if (!in_raw(&spi, sizeof(spi), &p->pbs, "SPI")) | |||
| 5437 | return STF_INTERNAL_ERROR; /* cannot happen */ | |||
| 5438 | ||||
| 5439 | 					dbg("delete %s SA(0x%08" PRIx32 ")",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("delete %s SA(0x%08" "x" ")", enum_show(&ikev2_delete_protocol_id_names , v2del->isad_protoid), ntohl((uint32_t) spi)); } }  | |||
| 5440 | 					    enum_show(&ikev2_delete_protocol_id_names,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("delete %s SA(0x%08" "x" ")", enum_show(&ikev2_delete_protocol_id_names , v2del->isad_protoid), ntohl((uint32_t) spi)); } }  | |||
| 5441 | 						      v2del->isad_protoid),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("delete %s SA(0x%08" "x" ")", enum_show(&ikev2_delete_protocol_id_names , v2del->isad_protoid), ntohl((uint32_t) spi)); } }  | |||
| 5442 | 					    ntohl((uint32_t) spi)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("delete %s SA(0x%08" "x" ")", enum_show(&ikev2_delete_protocol_id_names , v2del->isad_protoid), ntohl((uint32_t) spi)); } };  | |||
| 5443 | ||||
| 5444 | /* | |||
| 5445 | * From 3.11. Delete Payload: | |||
| 5446 | * [the delete payload will] | |||
| 5447 | * contain the IPsec protocol | |||
| 5448 | * ID of that protocol (2 for | |||
| 5449 | * AH, 3 for ESP), and the SPI | |||
| 5450 | * is the SPI the sending | |||
| 5451 | * endpoint would expect in | |||
| 5452 | * inbound ESP or AH packets. | |||
| 5453 | * | |||
| 5454 | * From our POV, that's the | |||
| 5455 | * outbound SPI. | |||
| 5456 | */ | |||
| 5457 | struct child_sa *dst = find_v2_child_sa_by_outbound_spi(ike, | |||
| 5458 | v2del->isad_protoid, | |||
| 5459 | spi); | |||
| 5460 | ||||
| 5461 | if (dst == NULL((void*)0)) { | |||
| 5462 | 						libreswan_log(loglog(RC_LOG, "received delete request for %s SA(0x%08" "x" ") but corresponding state not found" , enum_show(&ikev2_delete_protocol_id_names, v2del->isad_protoid ), ntohl((uint32_t)spi))  | |||
| 5463 | 						    "received delete request for %s SA(0x%08" PRIx32 ") but corresponding state not found",loglog(RC_LOG, "received delete request for %s SA(0x%08" "x" ") but corresponding state not found" , enum_show(&ikev2_delete_protocol_id_names, v2del->isad_protoid ), ntohl((uint32_t)spi))  | |||
| 5464 | 							    enum_show(&ikev2_delete_protocol_id_names,loglog(RC_LOG, "received delete request for %s SA(0x%08" "x" ") but corresponding state not found" , enum_show(&ikev2_delete_protocol_id_names, v2del->isad_protoid ), ntohl((uint32_t)spi))  | |||
| 5465 | 								      v2del->isad_protoid),loglog(RC_LOG, "received delete request for %s SA(0x%08" "x" ") but corresponding state not found" , enum_show(&ikev2_delete_protocol_id_names, v2del->isad_protoid ), ntohl((uint32_t)spi))  | |||
| 5466 | 						    ntohl((uint32_t)spi))loglog(RC_LOG, "received delete request for %s SA(0x%08" "x" ") but corresponding state not found" , enum_show(&ikev2_delete_protocol_id_names, v2del->isad_protoid ), ntohl((uint32_t)spi));  | |||
| 5467 | } else { | |||
| 5468 | 						dbg("our side SPI that needs to be deleted: %s SA(0x%08" PRIx32 ")",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("our side SPI that needs to be deleted: %s SA(0x%08" "x" ")", enum_show(&ikev2_delete_protocol_id_names, v2del ->isad_protoid), ntohl((uint32_t)spi)); } }  | |||
| 5469 | 						    enum_show(&ikev2_delete_protocol_id_names,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("our side SPI that needs to be deleted: %s SA(0x%08" "x" ")", enum_show(&ikev2_delete_protocol_id_names, v2del ->isad_protoid), ntohl((uint32_t)spi)); } }  | |||
| 5470 | 							      v2del->isad_protoid), ntohl((uint32_t)spi)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("our side SPI that needs to be deleted: %s SA(0x%08" "x" ")", enum_show(&ikev2_delete_protocol_id_names, v2del ->isad_protoid), ntohl((uint32_t)spi)); } };  | |||
| 5471 | ||||
| 5472 | /* we just received a delete, don't send another delete */ | |||
| 5473 | dst->sa.st_dont_send_delete = true1; | |||
| 5474 | /* st is a parent */ | |||
| 5475 | 						passert(&ike->sa != &dst->sa){ _Bool assertion__ = &ike->sa != &dst->sa; if ( !assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 5475}, "%s", "&ike->sa != &dst->sa" ); } };  | |||
| 5476 | 						passert(ike->sa.st_serialno == dst->sa.st_clonedfrom){ _Bool assertion__ = ike->sa.st_serialno == dst->sa.st_clonedfrom ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 5476}, "%s", "ike->sa.st_serialno == dst->sa.st_clonedfrom" ); } };  | |||
| 5477 | if (!del_ike && responding) { | |||
| 5478 | struct ipsec_proto_info *pr = | |||
| 5479 | v2del->isad_protoid == PROTO_IPSEC_AH2 ? | |||
| 5480 | &dst->sa.st_ah : | |||
| 5481 | &dst->sa.st_esp; | |||
| 5482 | ||||
| 5483 | if (j < elemsof(spi_buf)(sizeof(spi_buf) / sizeof(*(spi_buf)))) { | |||
| 5484 | spi_buf[j] = pr->our_spi; | |||
| 5485 | j++; | |||
| 5486 | } else { | |||
| 5487 | 								libreswan_log("too many SPIs in Delete Notification payload; ignoring 0x%08" PRIx32,loglog(RC_LOG, "too many SPIs in Delete Notification payload; ignoring 0x%08" "x", ntohl(spi))  | |||
| 5488 | 									      ntohl(spi))loglog(RC_LOG, "too many SPIs in Delete Notification payload; ignoring 0x%08" "x", ntohl(spi));  | |||
| 5489 | } | |||
| 5490 | } | |||
| 5491 | delete_or_replace_state(&dst->sa); | |||
| 5492 | /* note: md->st != dst */ | |||
| 5493 | } | |||
| 5494 | } /* for each spi */ | |||
| 5495 | ||||
| 5496 | if (!del_ike && responding) { | |||
| 5497 | /* build output Delete Payload */ | |||
| 5498 | struct ikev2_delete v2del_tmp = { | |||
| 5499 | .isad_protoid = v2del->isad_protoid, | |||
| 5500 | .isad_spisize = v2del->isad_spisize, | |||
| 5501 | .isad_nrspi = j, | |||
| 5502 | }; | |||
| 5503 | ||||
| 5504 | /* Emit delete payload header and SPI values */ | |||
| 5505 | pb_stream del_pbs; /* output stream */ | |||
| 5506 | ||||
| 5507 | if (!out_struct(&v2del_tmp, | |||
| 5508 | &ikev2_delete_desc, | |||
| 5509 | &sk.pbs, | |||
| 5510 | &del_pbs)) | |||
| 5511 | return false0; | |||
| 5512 | diag_t d = pbs_out_raw(&del_pbs, | |||
| 5513 | spi_buf, | |||
| 5514 | j * sizeof(spi_buf[0]), | |||
| 5515 | "local SPIs"); | |||
| 5516 | if (d != NULL((void*)0)) { | |||
| 5517 | log_diag(RC_LOG_SERIOUS, sk.logger, &d, "%s", ""); | |||
| 5518 | return STF_INTERNAL_ERROR; | |||
| 5519 | } | |||
| 5520 | ||||
| 5521 | close_output_pbs(&del_pbs); | |||
| 5522 | } | |||
| 5523 | } | |||
| 5524 | break; | |||
| 5525 | ||||
| 5526 | default: | |||
| 5527 | /* ignore unrecognized protocol */ | |||
| 5528 | break; | |||
| 5529 | } | |||
| 5530 | } /* for each Delete Payload */ | |||
| 5531 | } | |||
| 5532 | ||||
| 5533 | if (responding) { | |||
| 5534 | /* | |||
| 5535 | * We've now build up the content (if any) of the Response: | |||
| 5536 | * | |||
| 5537 | * - empty, if there were no Delete Payloads or if we are | |||
| 5538 | * responding to v2N_REDIRECT payload (RFC 5685 Chapter 5). | |||
| 5539 | * Treat as a check for liveness. Correct response is this | |||
| 5540 | * empty Response. | |||
| 5541 | * | |||
| 5542 | * - if an ISAKMP SA is mentioned in input message, | |||
| 5543 | * we are sending an empty Response, as per standard. | |||
| 5544 | * | |||
| 5545 | * - for IPsec SA mentioned, we are sending its mate. | |||
| 5546 | * | |||
| 5547 | * - for MOBIKE, we send NAT NOTIFY payloads and optionally a COOKIE2 | |||
| 5548 | * | |||
| 5549 | * Close up the packet and send it. | |||
| 5550 | */ | |||
| 5551 | ||||
| 5552 | /* const size_t len = pbs_offset(&sk.pbs); */ | |||
| 5553 | if (!close_v2SK_payload(&sk)) { | |||
| 5554 | return STF_INTERNAL_ERROR; | |||
| 5555 | } | |||
| 5556 | close_output_pbs(&rbody); | |||
| 5557 | close_output_pbs(&reply_stream); | |||
| 5558 | ; | |||
| 5559 | stf_status ret = encrypt_v2SK_payload(&sk); | |||
| 5560 | if (ret != STF_OK) | |||
| 5561 | return ret; | |||
| 5562 | ||||
| 5563 | struct mobike mobike_remote; | |||
| 5564 | ||||
| 5565 | mobike_switch_remote(md, &mobike_remote); | |||
| 5566 | ||||
| 5567 | /* ??? should we support fragmenting? Maybe one day. */ | |||
| 5568 | record_v2_message(ike, &reply_stream, "reply packet for process_encrypted_informational_ikev2", | |||
| 5569 | MESSAGE_RESPONSE); | |||
| 5570 | send_recorded_v2_message(ike, "reply packet for process_encrypted_informational_ikev2", | |||
| 5571 | MESSAGE_RESPONSE); | |||
| 5572 | ||||
| 5573 | /* | |||
| 5574 | * XXX: This code should be neither using record 'n' | |||
| 5575 | * send (which leads to RFC violations because it | |||
| 5576 | * doesn't wait for an ACK) and/or be deleting the | |||
| 5577 | * state midway through a state transition. | |||
| 5578 | * | |||
| 5579 | * When DEL_IKE, the update isn't needed but what | |||
| 5580 | * ever. | |||
| 5581 | */ | |||
| 5582 | dbg_v2_msgid(ike, &ike->sa, "XXX: in %s() hacking around record 'n' send bypassing send queue hacking around delete_ike_family()", | |||
| 5583 | __func__); | |||
| 5584 | v2_msgid_update_sent(ike, &ike->sa, md, MESSAGE_RESPONSE); | |||
| 5585 | ||||
| 5586 | mobike_reset_remote(&ike->sa, &mobike_remote); | |||
| 5587 | ||||
| 5588 | /* | |||
| 5589 | * ... now we can delete the IKE SA if we want to. | |||
| 5590 | * | |||
| 5591 | * The response is hopefully empty. | |||
| 5592 | */ | |||
| 5593 | if (del_ike) { | |||
| 5594 | delete_ike_family(ike, DONT_SEND_DELETE); | |||
| 5595 | md->st = NULL((void*)0); | |||
| 5596 | ike = NULL((void*)0); | |||
| 5597 | } | |||
| 5598 | } | |||
| 5599 | ||||
| 5600 | /* | |||
| 5601 | * This is a special case. When we have site to site connection | |||
| 5602 | * and one site redirects other in IKE_AUTH reply, he doesn't | |||
| 5603 | * unroute. It seems like it was easier to add here this part | |||
| 5604 | * than in delete_ipsec_sa() in kernel.c where it should be | |||
| 5605 | * (at least it seems like it should be there). | |||
| 5606 | * | |||
| 5607 | * The need for this special case was discovered by running | |||
| 5608 | * various test cases. | |||
| 5609 | */ | |||
| 5610 | if (do_unroute) { | |||
| 5611 | unroute_connection(c); | |||
| 5612 | } | |||
| 5613 | ||||
| 5614 | /* count as DPD/liveness only if there was no Delete */ | |||
| 5615 | if (!del_ike && ndp == 0) { | |||
| 5616 | if (responding) | |||
| 5617 | pstats_ike_dpd_replied++; | |||
| 5618 | else | |||
| 5619 | pstats_ike_dpd_recv++; | |||
| 5620 | } | |||
| 5621 | return STF_OK; | |||
| 5622 | } | |||
| 5623 | ||||
| 5624 | #ifdef XFRM_SUPPORT1 | |||
| 5625 | static payload_emitter_fn add_mobike_payloads; | |||
| 5626 | static bool_Bool add_mobike_payloads(struct state *st, pb_stream *pbs) | |||
| 5627 | { | |||
| 5628 | ip_endpoint local_endpoint = st->st_mobike_local_endpoint; | |||
| 5629 | ip_endpoint remote_endpoint = st->st_remote_endpoint; | |||
| 5630 | return emit_v2N(v2N_UPDATE_SA_ADDRESSES, pbs) && | |||
| 5631 | ikev2_out_natd(&local_endpoint, &remote_endpoint, | |||
| 5632 | &st->st_ike_spis, pbs); | |||
| 5633 | } | |||
| 5634 | #endif | |||
| 5635 | ||||
| 5636 | void ikev2_rekey_ike_start(struct ike_sa *ike) | |||
| 5637 | { | |||
| 5638 | struct pending p = { | |||
| 5639 | .whack_sock = ike->sa.st_whack_sockst_logger->object_whackfd,/*on-stack*/ | |||
| 5640 | .ike = ike, | |||
| 5641 | .connection = ike->sa.st_connection, | |||
| 5642 | .policy = LEMPTY((lset_t)0), | |||
| 5643 | .try = 1, | |||
| 5644 | .replacing = ike->sa.st_serialno, | |||
| 5645 | .uctx = ike->sa.sec_ctx, | |||
| 5646 | }; | |||
| 5647 | ikev2_initiate_child_sa(&p); | |||
| 5648 | } | |||
| 5649 | ||||
| 5650 | void ikev2_initiate_child_sa(struct pending *p) | |||
| 5651 | { | |||
| 5652 | struct ike_sa *ike = p->ike; | |||
| 5653 | struct connection *c = p->connection; | |||
| 5654 | 	passert(c != NULL){ _Bool assertion__ = c != ((void*)0); if (!assertion__) { lsw_passert_fail ((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5654}, "%s", "c != NULL"); } };  | |||
| 5655 | ||||
| 5656 | enum sa_type sa_type; | |||
| 5657 | if (p->replacing == ike->sa.st_serialno) { /* IKE rekey exchange */ | |||
| 5658 | sa_type = IKE_SA; | |||
| 5659 | ike->sa.st_viable_parent = FALSE0; | |||
| 5660 | } else { | |||
| 5661 | if (find_pending_phase2(ike->sa.st_serialno, | |||
| 5662 | 					c, IPSECSA_PENDING_STATES(((lset_t)1 << (STATE_V2_NEW_CHILD_I1)) | ((lset_t)1 << (STATE_V2_NEW_CHILD_I0)) | ((lset_t)1 << (STATE_V2_NEW_CHILD_R0 )) | ((lset_t)1 << (STATE_PARENT_I2))))) {  | |||
| 5663 | return; | |||
| 5664 | } | |||
| 5665 | sa_type = IPSEC_SA; | |||
| 5666 | } | |||
| 5667 | ||||
| 5668 | struct child_sa *child; /* to be determined */ | |||
| 5669 | const struct child_sa *child_being_replaced; | |||
| 5670 | if (sa_type == IPSEC_SA) { | |||
| 5671 | child_being_replaced = pexpect_child_sa(state_with_serialno(p->replacing)); | |||
| 5672 | if (child_being_replaced != NULL((void*)0) && | |||
| 5673 | 		    !IS_CHILD_SA_ESTABLISHED(&child_being_replaced->sa)((&child_being_replaced->sa)->st_state->kind == STATE_V2_ESTABLISHED_CHILD_SA && ((&child_being_replaced->sa)->st_clonedfrom != 0))) {  | |||
| 5674 | /* can't replace a state that isn't established */ | |||
| 5675 | child_being_replaced = NULL((void*)0); | |||
| 5676 | } | |||
| 5677 | child = new_v2_child_state(ike, IPSEC_SA, | |||
| 5678 | SA_INITIATOR, | |||
| 5679 | (child_being_replaced != NULL((void*)0) ? STATE_V2_REKEY_CHILD_I0 : | |||
| 5680 | STATE_V2_NEW_CHILD_I0), | |||
| 5681 | p->whack_sock); | |||
| 5682 | } else { | |||
| 5683 | child_being_replaced = NULL((void*)0); /* obviously the IKE SA */ | |||
| 5684 | child = new_v2_child_state(ike, IKE_SA, | |||
| 5685 | SA_INITIATOR, | |||
| 5686 | STATE_V2_REKEY_IKE_I0, | |||
| 5687 | p->whack_sock); | |||
| 5688 | child->sa.st_oakley = ike->sa.st_oakley; | |||
| 5689 | child->sa.st_ike_rekey_spis.initiator = ike_initiator_spi(); | |||
| 5690 | child->sa.st_ike_pred = ike->sa.st_serialno; | |||
| 5691 | } | |||
| 5692 | update_state_connection(&child->sa, c); | |||
| 5693 | ||||
| 5694 | 	set_cur_state(&child->sa)log_push_state(&child->sa, (where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 5694}); /* we must reset before exit */  | |||
| 5695 | child->sa.st_try = p->try; | |||
| 5696 | ||||
| 5697 | free_chunk_content(&child->sa.st_ni); /* this is from the parent. */ | |||
| 5698 | free_chunk_content(&child->sa.st_nr); /* this is from the parent. */ | |||
| 5699 | ||||
| 5700 | if (child_being_replaced != NULL((void*)0)) { | |||
| 5701 | 		pexpect(sa_type == IPSEC_SA)({ _Bool assertion__ = sa_type == IPSEC_SA; if (!assertion__) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5701}, "%s", "sa_type == IPSEC_SA"); } assertion__ ; });  | |||
| 5702 | 		pexpect(IS_CHILD_SA_ESTABLISHED(&child_being_replaced->sa))({ _Bool assertion__ = ((&child_being_replaced->sa)-> st_state->kind == STATE_V2_ESTABLISHED_CHILD_SA && ((&child_being_replaced->sa)->st_clonedfrom != 0)) ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 5702}, "%s", "IS_CHILD_SA_ESTABLISHED(&child_being_replaced->sa)" ); } assertion__; });  | |||
| 5703 | child->sa.st_ipsec_pred = child_being_replaced->sa.st_serialno; | |||
| 5704 | 		passert(child->sa.st_connection == child_being_replaced->sa.st_connection){ _Bool assertion__ = child->sa.st_connection == child_being_replaced ->sa.st_connection; if (!assertion__) { lsw_passert_fail(( where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 5704}, "%s", "child->sa.st_connection == child_being_replaced->sa.st_connection" ); } };  | |||
| 5705 | 		if (HAS_IPSEC_POLICY(child_being_replaced->sa.st_policy)(((child_being_replaced->sa.st_policy) & (((lset_t)1 << (POLICY_NOPMTUDISC_IX)) - ((lset_t)1 << (POLICY_ENCRYPT_IX )) + ((lset_t)1 << (POLICY_NOPMTUDISC_IX)))) != 0))  | |||
| 5706 | child->sa.st_policy = child_being_replaced->sa.st_policy; | |||
| 5707 | else | |||
| 5708 | p->policy = c->policy; /* where did child_being_replaced->sa.st_policy go? */ | |||
| 5709 | } | |||
| 5710 | ||||
| 5711 | child->sa.st_policy = p->policy; | |||
| 5712 | ||||
| 5713 | child->sa.sec_ctx = NULL((void*)0); | |||
| 5714 | if (p->uctx != NULL((void*)0)) { | |||
| 5715 | 		child->sa.sec_ctx = clone_thing(*p->uctx, "sec ctx structure")((__typeof__(&(*p->uctx))) clone_bytes((const void *)& (*p->uctx), sizeof(*p->uctx), ("sec ctx structure")));  | |||
| 5716 | 		dbg("pending phase 2 with security context \"%s\"",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("pending phase 2 with security context \"%s\"" , child->sa.sec_ctx->sec_ctx_value); } }  | |||
| 5717 | 		    child->sa.sec_ctx->sec_ctx_value){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("pending phase 2 with security context \"%s\"" , child->sa.sec_ctx->sec_ctx_value); } };  | |||
| 5718 | } | |||
| 5719 | ||||
| 5720 | 	binlog_refresh_state(&child->sa)binlog_state((&child->sa), (&child->sa)->st_state ->kind);  | |||
| 5721 | ||||
| 5722 | char replacestr[256] = ""; | |||
| 5723 | if (p->replacing != SOS_NOBODY0) { | |||
| 5724 | snprintf(replacestr, sizeof(replacestr), " to replace #%lu", | |||
| 5725 | p->replacing); | |||
| 5726 | } | |||
| 5727 | ||||
| 5728 | 	passert(child->sa.st_connection != NULL){ _Bool assertion__ = child->sa.st_connection != ((void*)0 ); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 5728}, "%s", "child->sa.st_connection != NULL" ); } };  | |||
| 5729 | ||||
| 5730 | if (sa_type == IPSEC_SA) { | |||
| 5731 | ||||
| 5732 | /* | |||
| 5733 | * Use the CREATE_CHILD_SA proposal suite - the | |||
| 5734 | * proposal generated during IKE_AUTH will have been | |||
| 5735 | * stripped of DH. | |||
| 5736 | * | |||
| 5737 | * XXX: If the IKE SA's DH changes, then the child | |||
| 5738 | * proposals will be re-generated. Should the child | |||
| 5739 | * proposals instead be somehow stored in state and | |||
| 5740 | * dragged around? | |||
| 5741 | */ | |||
| 5742 | const struct dh_desc *default_dh = | |||
| 5743 | c->policy & POLICY_PFS((lset_t)1 << (POLICY_PFS_IX)) ? ike->sa.st_oakley.ta_dh : NULL((void*)0); | |||
| 5744 | struct ikev2_proposals *child_proposals = | |||
| 5745 | get_v2_create_child_proposals(c, | |||
| 5746 | "ESP/AH initiator emitting proposals", | |||
| 5747 | default_dh, | |||
| 5748 | child->sa.st_logger); | |||
| 5749 | /* see ikev2_child_add_ipsec_payloads */ | |||
| 5750 | 		passert(c->v2_create_child_proposals != NULL){ _Bool assertion__ = c->v2_create_child_proposals != ((void *)0); if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5750}, "%s" , "c->v2_create_child_proposals != NULL"); } };  | |||
| 5751 | ||||
| 5752 | child->sa.st_pfs_group = ikev2_proposals_first_dh(child_proposals, child->sa.st_logger); | |||
| 5753 | ||||
| 5754 | 		dbg("#%lu schedule %s IPsec SA %s%s using IKE# %lu pfs=%s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule %s IPsec SA %s%s using IKE# %lu pfs=%s" , child->sa.st_serialno, child_being_replaced != ((void*)0 ) ? "rekey initiate" : "initiate", prettypolicy(p->policy) , replacestr, ike->sa.st_serialno, child->sa.st_pfs_group == ((void*)0) ? "no-pfs" : child->sa.st_pfs_group->common .fqn); } }  | |||
| 5755 | 		    child->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule %s IPsec SA %s%s using IKE# %lu pfs=%s" , child->sa.st_serialno, child_being_replaced != ((void*)0 ) ? "rekey initiate" : "initiate", prettypolicy(p->policy) , replacestr, ike->sa.st_serialno, child->sa.st_pfs_group == ((void*)0) ? "no-pfs" : child->sa.st_pfs_group->common .fqn); } }  | |||
| 5756 | 		    child_being_replaced != NULL ? "rekey initiate" : "initiate",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule %s IPsec SA %s%s using IKE# %lu pfs=%s" , child->sa.st_serialno, child_being_replaced != ((void*)0 ) ? "rekey initiate" : "initiate", prettypolicy(p->policy) , replacestr, ike->sa.st_serialno, child->sa.st_pfs_group == ((void*)0) ? "no-pfs" : child->sa.st_pfs_group->common .fqn); } }  | |||
| 5757 | 		    prettypolicy(p->policy),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule %s IPsec SA %s%s using IKE# %lu pfs=%s" , child->sa.st_serialno, child_being_replaced != ((void*)0 ) ? "rekey initiate" : "initiate", prettypolicy(p->policy) , replacestr, ike->sa.st_serialno, child->sa.st_pfs_group == ((void*)0) ? "no-pfs" : child->sa.st_pfs_group->common .fqn); } }  | |||
| 5758 | 		    replacestr,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule %s IPsec SA %s%s using IKE# %lu pfs=%s" , child->sa.st_serialno, child_being_replaced != ((void*)0 ) ? "rekey initiate" : "initiate", prettypolicy(p->policy) , replacestr, ike->sa.st_serialno, child->sa.st_pfs_group == ((void*)0) ? "no-pfs" : child->sa.st_pfs_group->common .fqn); } }  | |||
| 5759 | 		    ike->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule %s IPsec SA %s%s using IKE# %lu pfs=%s" , child->sa.st_serialno, child_being_replaced != ((void*)0 ) ? "rekey initiate" : "initiate", prettypolicy(p->policy) , replacestr, ike->sa.st_serialno, child->sa.st_pfs_group == ((void*)0) ? "no-pfs" : child->sa.st_pfs_group->common .fqn); } }  | |||
| 5760 | 		    child->sa.st_pfs_group == NULL ? "no-pfs" : child->sa.st_pfs_group->common.fqn){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule %s IPsec SA %s%s using IKE# %lu pfs=%s" , child->sa.st_serialno, child_being_replaced != ((void*)0 ) ? "rekey initiate" : "initiate", prettypolicy(p->policy) , replacestr, ike->sa.st_serialno, child->sa.st_pfs_group == ((void*)0) ? "no-pfs" : child->sa.st_pfs_group->common .fqn); } };  | |||
| 5761 | } else { | |||
| 5762 | 		dbg("#%lu schedule initiate IKE Rekey SA %s to replace IKE# %lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule initiate IKE Rekey SA %s to replace IKE# %lu" , child->sa.st_serialno, prettypolicy(p->policy), ike-> sa.st_serialno); } }  | |||
| 5763 | 		    child->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule initiate IKE Rekey SA %s to replace IKE# %lu" , child->sa.st_serialno, prettypolicy(p->policy), ike-> sa.st_serialno); } }  | |||
| 5764 | 		    prettypolicy(p->policy),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule initiate IKE Rekey SA %s to replace IKE# %lu" , child->sa.st_serialno, prettypolicy(p->policy), ike-> sa.st_serialno); } }  | |||
| 5765 | 		    ike->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu schedule initiate IKE Rekey SA %s to replace IKE# %lu" , child->sa.st_serialno, prettypolicy(p->policy), ike-> sa.st_serialno); } };  | |||
| 5766 | } | |||
| 5767 | ||||
| 5768 | event_force(EVENT_v2_INITIATE_CHILD, &child->sa); | |||
| 5769 | 	reset_globals()log_reset_globals((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5769});  | |||
| 5770 | } | |||
| 5771 | ||||
| 5772 | static crypto_req_cont_func ikev2_child_outI_continue; | |||
| 5773 | ||||
| 5774 | void ikev2_child_outI(struct state *st) | |||
| 5775 | { | |||
| 5776 | switch (st->st_state->kind) { | |||
| 5777 | ||||
| 5778 | case STATE_V2_REKEY_CHILD_I0: | |||
| 5779 | if (st->st_pfs_group == NULL((void*)0)) { | |||
| 5780 | request_nonce("Child Rekey Initiator nonce ni", | |||
| 5781 | st, ikev2_child_outI_continue); | |||
| 5782 | } else { | |||
| 5783 | request_ke_and_nonce("Child Rekey Initiator KE and nonce ni", | |||
| 5784 | st, st->st_pfs_group, | |||
| 5785 | ikev2_child_outI_continue); | |||
| 5786 | } | |||
| 5787 | break; /* return STF_SUSPEND; */ | |||
| 5788 | ||||
| 5789 | case STATE_V2_NEW_CHILD_I0: | |||
| 5790 | if (st->st_pfs_group == NULL((void*)0)) { | |||
| 5791 | request_nonce("Child Initiator nonce ni", | |||
| 5792 | st, ikev2_child_outI_continue); | |||
| 5793 | } else { | |||
| 5794 | request_ke_and_nonce("Child Initiator KE and nonce ni", | |||
| 5795 | st, st->st_pfs_group, | |||
| 5796 | ikev2_child_outI_continue); | |||
| 5797 | } | |||
| 5798 | break; /* return STF_SUSPEND; */ | |||
| 5799 | ||||
| 5800 | case STATE_V2_REKEY_IKE_I0: | |||
| 5801 | request_ke_and_nonce("IKE REKEY Initiator KE and nonce ni", | |||
| 5802 | st, st->st_oakley.ta_dh, | |||
| 5803 | ikev2_child_outI_continue); | |||
| 5804 | break; /* return STF_SUSPEND; */ | |||
| 5805 | ||||
| 5806 | default: | |||
| 5807 | 		bad_case(st->st_state->kind)libreswan_bad_case("st->st_state->kind", (st->st_state ->kind), (where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5807});  | |||
| 5808 | } | |||
| 5809 | } | |||
| 5810 | ||||
| 5811 | static v2_msgid_pending_cb ikev2_child_outI_continue_2; | |||
| 5812 | ||||
| 5813 | static void ikev2_child_outI_continue(struct state *st, | |||
| 5814 | struct msg_digest *unused_md, | |||
| 5815 | struct pluto_crypto_req *r) | |||
| 5816 | { | |||
| 5817 | 	dbg("%s() for #%lu %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } }  | |||
| 5818 | 	     __func__, st->st_serialno, st->st_state->name){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("%s() for #%lu %s", __func__, st->st_serialno , st->st_state->name); } };  | |||
| 5819 | ||||
| 5820 | /* child initiating exchange */ | |||
| 5821 | 	pexpect(unused_md == NULL)({ _Bool assertion__ = unused_md == ((void*)0); if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5821}, "%s", "unused_md == NULL"); } assertion__; } );  | |||
| 5822 | ||||
| 5823 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 5823});  | |||
| 5824 | struct child_sa *child = pexpect_child_sa(st); | |||
| 5825 | 	pexpect(child->sa.st_sa_role == SA_INITIATOR)({ _Bool assertion__ = child->sa.st_sa_role == SA_INITIATOR ; if (!assertion__) { log_pexpect((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 5825}, "%s", "child->sa.st_sa_role == SA_INITIATOR" ); } assertion__; });  | |||
| 5826 | ||||
| 5827 | /* | |||
| 5828 | * XXX: Should this routine be split so that each instance | |||
| 5829 | * handles only one state transition. If there's commonality | |||
| 5830 | * then the per-transition functions can all call common code. | |||
| 5831 | */ | |||
| 5832 | 	pexpect(st->st_state->kind == STATE_V2_NEW_CHILD_I0 ||({ _Bool assertion__ = st->st_state->kind == STATE_V2_NEW_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_CHILD_I0 || st ->st_state->kind == STATE_V2_REKEY_IKE_I0; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5834}, "%s", "st->st_state->kind == STATE_V2_NEW_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_IKE_I0" ); } assertion__; })  | |||
| 5833 | 		st->st_state->kind == STATE_V2_REKEY_CHILD_I0 ||({ _Bool assertion__ = st->st_state->kind == STATE_V2_NEW_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_CHILD_I0 || st ->st_state->kind == STATE_V2_REKEY_IKE_I0; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5834}, "%s", "st->st_state->kind == STATE_V2_NEW_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_IKE_I0" ); } assertion__; })  | |||
| 5834 | 		st->st_state->kind == STATE_V2_REKEY_IKE_I0)({ _Bool assertion__ = st->st_state->kind == STATE_V2_NEW_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_CHILD_I0 || st ->st_state->kind == STATE_V2_REKEY_IKE_I0; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5834}, "%s", "st->st_state->kind == STATE_V2_NEW_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_CHILD_I0 || st->st_state->kind == STATE_V2_REKEY_IKE_I0" ); } assertion__; });  | |||
| 5835 | ||||
| 5836 | /* and a parent? */ | |||
| 5837 | if (ike == NULL((void*)0)) { | |||
| 5838 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 5838},  | |||
| 5839 | "sponsoring child state #%lu has no parent state #%lu", | |||
| 5840 | st->st_serialno, st->st_clonedfrom); | |||
| 5841 | /* XXX: release child? */ | |||
| 5842 | return; | |||
| 5843 | } | |||
| 5844 | ||||
| 5845 | /* IKE SA => DH */ | |||
| 5846 | 	pexpect(st->st_state->kind == STATE_V2_REKEY_IKE_I0 ? r->pcr_type == pcr_build_ke_and_nonce : true)({ _Bool assertion__ = st->st_state->kind == STATE_V2_REKEY_IKE_I0 ? r->pcr_type == pcr_build_ke_and_nonce : 1; if (!assertion__ ) { log_pexpect((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 5846}, "%s", "st->st_state->kind == STATE_V2_REKEY_IKE_I0 ? r->pcr_type == pcr_build_ke_and_nonce : true" ); } assertion__; });  | |||
| 5847 | ||||
| 5848 | unpack_nonce(&st->st_ni, r); | |||
| 5849 | if (r->pcr_type == pcr_build_ke_and_nonce) { | |||
| 5850 | unpack_KE_from_helper(st, r, &st->st_gi); | |||
| 5851 | } | |||
| 5852 | ||||
| 5853 | 	dbg("adding CHILD SA #%lu to IKE SA #%lu message initiator queue",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("adding CHILD SA #%lu to IKE SA #%lu message initiator queue" , child->sa.st_serialno, ike->sa.st_serialno); } }  | |||
| 5854 | 	    child->sa.st_serialno, ike->sa.st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("adding CHILD SA #%lu to IKE SA #%lu message initiator queue" , child->sa.st_serialno, ike->sa.st_serialno); } };  | |||
| 5855 | v2_msgid_queue_initiator(ike, &child->sa, ISAKMP_v2_CREATE_CHILD_SA, | |||
| 5856 | NULL((void*)0), ikev2_child_outI_continue_2); | |||
| 5857 | ||||
| 5858 | /* return STF_SUSPEND */ | |||
| 5859 | complete_v2_state_transition(&child->sa, NULL((void*)0)/*initiator*/, STF_SUSPEND); | |||
| 5860 | } | |||
| 5861 | ||||
| 5862 | stf_status ikev2_child_outI_continue_2(struct ike_sa *ike, struct state *st, | |||
| 5863 | struct msg_digest *md UNUSED__attribute__ ((unused))) | |||
| 5864 | { | |||
| 5865 | struct child_sa *child = pexpect_child_sa(st); | |||
| 5866 | stf_status e = ikev2_start_new_exchange(ike, child); | |||
| 5867 | if (e != STF_OK) { | |||
| 5868 | return e; | |||
| 5869 | } | |||
| 5870 | return ikev2_child_out_tail(ike, child, NULL((void*)0)); | |||
| 5871 | } | |||
| 5872 | ||||
| 5873 | void ikev2_record_newaddr(struct state *st, void *arg_ip) | |||
| 5874 | { | |||
| 5875 | ip_address *ip = arg_ip; | |||
| 5876 | ||||
| 5877 | if (!mobike_check_established(st)) | |||
| 5878 | return; | |||
| 5879 | ||||
| 5880 | if (address_is_specified(&st->st_deleted_local_addr)) { | |||
| 5881 | /* | |||
| 5882 | * A work around for delay between new address and new route | |||
| 5883 | * A better fix would be listen to RTM_NEWROUTE, RTM_DELROUTE | |||
| 5884 | */ | |||
| 5885 | if (st->st_addr_change_event == NULL((void*)0)) { | |||
| 5886 | event_schedule(EVENT_v2_ADDR_CHANGE, | |||
| 5887 | RTM_NEWADDR_ROUTE_DELAYdeltatime(3), st); | |||
| 5888 | } else { | |||
| 5889 | ipstr_buf b; | |||
| 5890 | 			dbg("#%lu MOBIKE ignore address %s change pending previous",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu MOBIKE ignore address %s change pending previous" , st->st_serialno, sensitive_ipstr(ip, &b)); } }  | |||
| 5891 | 			    st->st_serialno, sensitive_ipstr(ip, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu MOBIKE ignore address %s change pending previous" , st->st_serialno, sensitive_ipstr(ip, &b)); } };  | |||
| 5892 | } | |||
| 5893 | } | |||
| 5894 | } | |||
| 5895 | ||||
| 5896 | void ikev2_record_deladdr(struct state *st, void *arg_ip) | |||
| 5897 | { | |||
| 5898 | ip_address *ip = arg_ip; | |||
| 5899 | ||||
| 5900 | if (!mobike_check_established(st)) | |||
| 5901 | return; | |||
| 5902 | ||||
| 5903 | pexpect_st_local_endpoint(st); | |||
| 5904 | ip_address local_address = endpoint_address(&st->st_interface->local_endpoint); | |||
| 5905 | /* ignore port */ | |||
| 5906 | if (sameaddr(ip, &local_address)) { | |||
| 5907 | ip_address ip_p = st->st_deleted_local_addr; | |||
| 5908 | st->st_deleted_local_addr = local_address; | |||
| 5909 | struct state *cst = state_with_serialno(st->st_connection->newest_ipsec_sa); | |||
| 5910 | migration_down(cst->st_connection, cst); | |||
| 5911 | unroute_connection(st->st_connection); | |||
| 5912 | ||||
| 5913 | event_delete(EVENT_v2_LIVENESS, cst); | |||
| 5914 | ||||
| 5915 | if (st->st_addr_change_event == NULL((void*)0)) { | |||
| 5916 | event_schedule(EVENT_v2_ADDR_CHANGE, deltatime(0), st); | |||
| 5917 | } else { | |||
| 5918 | ipstr_buf o, n; | |||
| 5919 | 			dbg("#%lu MOBIKE new RTM_DELADDR %s pending previous %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu MOBIKE new RTM_DELADDR %s pending previous %s" , st->st_serialno, ipstr(ip, &n), ipstr(&ip_p, & o)); } }  | |||
| 5920 | 			    st->st_serialno, ipstr(ip, &n), ipstr(&ip_p, &o)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu MOBIKE new RTM_DELADDR %s pending previous %s" , st->st_serialno, ipstr(ip, &n), ipstr(&ip_p, & o)); } };  | |||
| 5921 | } | |||
| 5922 | } | |||
| 5923 | } | |||
| 5924 | ||||
| 5925 | #ifdef XFRM_SUPPORT1 | |||
| 5926 | static void initiate_mobike_probe(struct state *st, struct starter_end *this, | |||
| 5927 | const struct iface_port *iface) | |||
| 5928 | { | |||
| 5929 | 	struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 5929});  | |||
| 5930 | /* | |||
| 5931 | * caveat: could a CP initiator find an address received | |||
| 5932 | * from the pool as a new source address? | |||
| 5933 | */ | |||
| 5934 | ||||
| 5935 | ipstr_buf s, g; | |||
| 5936 | endpoint_buf b; | |||
| 5937 | 	dbg("#%lu MOBIKE new source address %s remote %s and gateway %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu MOBIKE new source address %s remote %s and gateway %s" , st->st_serialno, ipstr(&this->addr, &s), str_endpoint (&st->st_remote_endpoint, &b), ipstr(&this-> nexthop, &g)); } }  | |||
| 5938 | 	    st->st_serialno, ipstr(&this->addr, &s),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu MOBIKE new source address %s remote %s and gateway %s" , st->st_serialno, ipstr(&this->addr, &s), str_endpoint (&st->st_remote_endpoint, &b), ipstr(&this-> nexthop, &g)); } }  | |||
| 5939 | 	    str_endpoint(&st->st_remote_endpoint, &b),{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu MOBIKE new source address %s remote %s and gateway %s" , st->st_serialno, ipstr(&this->addr, &s), str_endpoint (&st->st_remote_endpoint, &b), ipstr(&this-> nexthop, &g)); } }  | |||
| 5940 | 	    ipstr(&this->nexthop, &g)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu MOBIKE new source address %s remote %s and gateway %s" , st->st_serialno, ipstr(&this->addr, &s), str_endpoint (&st->st_remote_endpoint, &b), ipstr(&this-> nexthop, &g)); } };  | |||
| 5941 | pexpect_st_local_endpoint(st); | |||
| 5942 | /* | |||
| 5943 | * XXX: why not local_endpoint or is this redundant? | |||
| 5944 | * | |||
| 5945 | * The interface changed (new address in .address) but | |||
| 5946 | * continue to use the existing port. | |||
| 5947 | */ | |||
| 5948 | ip_port port = endpoint_port(&st->st_interface->local_endpoint); | |||
| 5949 | st->st_mobike_local_endpoint = endpoint3(st->st_interface->protocol, | |||
| 5950 | &this->addr, port); | |||
| 5951 | st->st_mobike_host_nexthop = this->nexthop; /* for updown, after xfrm migration */ | |||
| 5952 | const struct iface_port *o_iface = st->st_interface; | |||
| 5953 | /* notice how it gets set back below */ | |||
| 5954 | st->st_interface = iface; | |||
| 5955 | ||||
| 5956 | stf_status e = record_v2_informational_request("mobike informational request", | |||
| 5957 | ike, st/*sender*/, | |||
| 5958 | add_mobike_payloads); | |||
| 5959 | if (e == STF_OK) { | |||
| 5960 | send_recorded_v2_message(ike, "mobike informational request", | |||
| 5961 | MESSAGE_REQUEST); | |||
| 5962 | /* | |||
| 5963 | * XXX: record 'n' send violates the RFC. This code should | |||
| 5964 | * instead let success_v2_state_transition() deal with things. | |||
| 5965 | */ | |||
| 5966 | dbg_v2_msgid(ike, st, "XXX: in %s() hacking around record'n'send bypassing send queue", | |||
| 5967 | __func__); | |||
| 5968 | v2_msgid_update_sent(ike, &ike->sa, NULL((void*)0) /* new exchange */, MESSAGE_REQUEST); | |||
| 5969 | } | |||
| 5970 | st->st_interface = o_iface; | |||
| 5971 | pexpect_st_local_endpoint(st); | |||
| 5972 | } | |||
| 5973 | #endif | |||
| 5974 | ||||
| 5975 | #ifdef XFRM_SUPPORT1 | |||
| 5976 | static const struct iface_port *ikev2_src_iface(struct state *st, | |||
| 5977 | struct starter_end *this) | |||
| 5978 | { | |||
| 5979 | struct fd *whackfd = whack_log_fd; /* placeholder */ | |||
| 5980 | /* success found a new source address */ | |||
| 5981 | pexpect_st_local_endpoint(st); | |||
| 5982 | ip_port port = endpoint_port(&st->st_interface->local_endpoint); | |||
| 5983 | ip_endpoint local_endpoint = endpoint3(st->st_interface->protocol, | |||
| 5984 | &this->addr, port); | |||
| 5985 | const struct iface_port *iface = find_iface_port_by_local_endpoint(&local_endpoint); | |||
| 5986 | if (iface == NULL((void*)0)) { | |||
| 5987 | endpoint_buf b; | |||
| 5988 | 		dbg("#%lu no interface for %s try to initialize",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu no interface for %s try to initialize", st ->st_serialno, str_endpoint(&local_endpoint, &b)); } }  | |||
| 5989 | 		    st->st_serialno, str_endpoint(&local_endpoint, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu no interface for %s try to initialize", st ->st_serialno, str_endpoint(&local_endpoint, &b)); } };  | |||
| 5990 | find_ifaces(false0, whackfd); | |||
| 5991 | iface = find_iface_port_by_local_endpoint(&local_endpoint); | |||
| 5992 | if (iface == NULL((void*)0)) { | |||
| 5993 | return NULL((void*)0); | |||
| 5994 | } | |||
| 5995 | } | |||
| 5996 | ||||
| 5997 | return iface; | |||
| 5998 | } | |||
| 5999 | #endif | |||
| 6000 | ||||
| 6001 | void ikev2_addr_change(struct state *st) | |||
| 6002 | { | |||
| 6003 | if (!mobike_check_established(st)) | |||
| 6004 | return; | |||
| 6005 | ||||
| 6006 | #ifdef XFRM_SUPPORT1 | |||
| 6007 | ||||
| 6008 | /* let's re-discover local address */ | |||
| 6009 | ||||
| 6010 | struct starter_end this = { | |||
| 6011 | .addrtype = KH_DEFAULTROUTE, | |||
| 6012 | .nexttype = KH_DEFAULTROUTE, | |||
| 6013 | .host_family = endpoint_type(&st->st_remote_endpoint), | |||
| 6014 | }; | |||
| 6015 | ||||
| 6016 | struct starter_end that = { | |||
| 6017 | .addrtype = KH_IPADDR, | |||
| 6018 | .host_family = endpoint_type(&st->st_remote_endpoint), | |||
| 6019 | .addr = st->st_remote_endpoint | |||
| 6020 | }; | |||
| 6021 | ||||
| 6022 | /* | |||
| 6023 | * mobike need two lookups. one for the gateway and | |||
| 6024 | * the one for the source address | |||
| 6025 | */ | |||
| 6026 | switch (resolve_defaultroute_one(&this, &that, true1, st->st_logger)) { | |||
| 6027 | case 0: /* success */ | |||
| 6028 | /* cannot happen */ | |||
| 6029 | /* ??? original code treated this as failure */ | |||
| 6030 | /* bad_case(0); */ | |||
| 6031 | 		libreswan_log("unexpected SUCCESS from first resolve_defaultroute_one")loglog(RC_LOG, "unexpected SUCCESS from first resolve_defaultroute_one" );  | |||
| 6032 | /* FALL THROUGH */ | |||
| 6033 | case -1: /* failure */ | |||
| 6034 | { | |||
| 6035 | /* keep this DEBUG, if a libreswan log, too many false +ve */ | |||
| 6036 | address_buf b; | |||
| 6037 | 		dbg("#%lu no local gatway to reach %s",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu no local gatway to reach %s", st->st_serialno , str_address(&that.addr, &b)); } }  | |||
| 6038 | 		    st->st_serialno, str_address(&that.addr, &b)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu no local gatway to reach %s", st->st_serialno , str_address(&that.addr, &b)); } };  | |||
| 6039 | break; | |||
| 6040 | } | |||
| 6041 | ||||
| 6042 | case 1: /* please call again: more to do */ | |||
| 6043 | switch (resolve_defaultroute_one(&this, &that, true1, st->st_logger)) { | |||
| 6044 | case 1: /* please call again: more to do */ | |||
| 6045 | /* cannot happen */ | |||
| 6046 | /* ??? original code treated this as failure */ | |||
| 6047 | /* bad_case(1); */ | |||
| 6048 | 			libreswan_log("unexpected TRY AGAIN from second resolve_defaultroute_one")loglog(RC_LOG, "unexpected TRY AGAIN from second resolve_defaultroute_one" );  | |||
| 6049 | /* FALL THROUGH */ | |||
| 6050 | case -1: /* failure */ | |||
| 6051 | { | |||
| 6052 | ipstr_buf g, b; | |||
| 6053 | 			libreswan_log("no local source address to reach remote %s, local gateway %s",loglog(RC_LOG, "no local source address to reach remote %s, local gateway %s" , sensitive_ipstr(&that.addr, &b), ipstr(&this.nexthop , &g))  | |||
| 6054 | 					sensitive_ipstr(&that.addr, &b),loglog(RC_LOG, "no local source address to reach remote %s, local gateway %s" , sensitive_ipstr(&that.addr, &b), ipstr(&this.nexthop , &g))  | |||
| 6055 | 					ipstr(&this.nexthop, &g))loglog(RC_LOG, "no local source address to reach remote %s, local gateway %s" , sensitive_ipstr(&that.addr, &b), ipstr(&this.nexthop , &g));  | |||
| 6056 | break; | |||
| 6057 | } | |||
| 6058 | ||||
| 6059 | case 0: /* success */ | |||
| 6060 | { | |||
| 6061 | const struct iface_port *iface = ikev2_src_iface(st, &this); | |||
| 6062 | if (iface != NULL((void*)0)) | |||
| 6063 | initiate_mobike_probe(st, &this, iface); | |||
| 6064 | break; | |||
| 6065 | } | |||
| 6066 | ||||
| 6067 | } | |||
| 6068 | break; | |||
| 6069 | } | |||
| 6070 | ||||
| 6071 | #else /* !defined(XFRM_SUPPORT) */ | |||
| 6072 | ||||
| 6073 | 	libreswan_log("without NETKEY we cannot ikev2_addr_change()")loglog(RC_LOG, "without NETKEY we cannot ikev2_addr_change()" );  | |||
| 6074 | ||||
| 6075 | #endif | |||
| 6076 | } | |||
| 6077 | ||||
| 6078 | /* | |||
| 6079 | * For opportunistic IPsec, we want to delete idle connections, so we | |||
| 6080 | * are not gaining an infinite amount of unused IPsec SAs. | |||
| 6081 | * | |||
| 6082 | * NOTE: Soon we will accept an idletime= configuration option that | |||
| 6083 | * replaces this check. | |||
| 6084 | * | |||
| 6085 | * Only replace the SA when it's been in use (checking for in-use is a | |||
| 6086 | * separate operation). | |||
| 6087 | */ | |||
| 6088 | ||||
| 6089 | static bool_Bool expire_ike_because_child_not_used(struct state *st) | |||
| 6090 | { | |||
| 6091 | 	if (!(IS_PARENT_SA_ESTABLISHED(st)(((st)->st_state->kind == STATE_V2_ESTABLISHED_IKE_SA) && !((st)->st_clonedfrom != 0)) ||  | |||
| 6092 | 	      IS_CHILD_SA_ESTABLISHED(st)((st)->st_state->kind == STATE_V2_ESTABLISHED_CHILD_SA && ((st)->st_clonedfrom != 0)))) {  | |||
| 6093 | /* for instance, too many retransmits trigger replace */ | |||
| 6094 | return false0; | |||
| 6095 | } | |||
| 6096 | ||||
| 6097 | struct connection *c = st->st_connection; | |||
| 6098 | ||||
| 6099 | if (!(c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX)))) { | |||
| 6100 | /* killing idle IPsec SA's is only for opportunistic SA's */ | |||
| 6101 | return false0; | |||
| 6102 | } | |||
| 6103 | ||||
| 6104 | if (c->spd.that.has_lease) { | |||
| 6105 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 6105},  | |||
| 6106 | "#%lu has lease; should not be trying to replace", | |||
| 6107 | st->st_serialno); | |||
| 6108 | return true1; | |||
| 6109 | } | |||
| 6110 | ||||
| 6111 | /* see of (most recent) child is busy */ | |||
| 6112 | struct state *cst; | |||
| 6113 | struct ike_sa *ike; | |||
| 6114 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0)) { | |||
| 6115 | ike = pexpect_ike_sa(st); | |||
| 6116 | cst = state_with_serialno(c->newest_ipsec_sa); | |||
| 6117 | if (cst == NULL((void*)0)) { | |||
| 6118 | 			pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 6118},  | |||
| 6119 | "can't check usage as IKE SA #%lu has no newest child", | |||
| 6120 | ike->sa.st_serialno); | |||
| 6121 | return true1; | |||
| 6122 | } | |||
| 6123 | } else { | |||
| 6124 | cst = st; | |||
| 6125 | 		ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 6125});  | |||
| 6126 | } | |||
| 6127 | ||||
| 6128 | 	dbg("#%lu check last used on newest CHILD SA #%lu",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu check last used on newest CHILD SA #%lu" , ike->sa.st_serialno, cst->st_serialno); } }  | |||
| 6129 | 	    ike->sa.st_serialno, cst->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu check last used on newest CHILD SA #%lu" , ike->sa.st_serialno, cst->st_serialno); } };  | |||
| 6130 | ||||
| 6131 | /* not sure why idleness is set to rekey margin? */ | |||
| 6132 | if (was_eroute_idle(cst, c->sa_rekey_margin)) { | |||
| 6133 | /* we observed no traffic, let IPSEC SA and IKE SA expire */ | |||
| 6134 | 		dbg("expiring IKE SA #%lu as CHILD SA #%lu has been idle for more than %jds",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("expiring IKE SA #%lu as CHILD SA #%lu has been idle for more than %jds" , ike->sa.st_serialno, ike->sa.st_serialno, deltasecs(c ->sa_rekey_margin)); } }  | |||
| 6135 | 		    ike->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("expiring IKE SA #%lu as CHILD SA #%lu has been idle for more than %jds" , ike->sa.st_serialno, ike->sa.st_serialno, deltasecs(c ->sa_rekey_margin)); } }  | |||
| 6136 | 		    ike->sa.st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("expiring IKE SA #%lu as CHILD SA #%lu has been idle for more than %jds" , ike->sa.st_serialno, ike->sa.st_serialno, deltasecs(c ->sa_rekey_margin)); } }  | |||
| 6137 | 		    deltasecs(c->sa_rekey_margin)){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("expiring IKE SA #%lu as CHILD SA #%lu has been idle for more than %jds" , ike->sa.st_serialno, ike->sa.st_serialno, deltasecs(c ->sa_rekey_margin)); } };  | |||
| 6138 | return true1; | |||
| 6139 | } | |||
| 6140 | return false0; | |||
| 6141 | } | |||
| 6142 | ||||
| 6143 | void v2_schedule_replace_event(struct state *st) | |||
| 6144 | { | |||
| 6145 | struct connection *c = st->st_connection; | |||
| 6146 | ||||
| 6147 | /* unwrapped deltatime_t in seconds */ | |||
| 6148 | intmax_t delay = deltasecs(IS_IKE_SA(st)((st)->st_clonedfrom == 0) ? c->sa_ike_life_seconds | |||
| 6149 | : c->sa_ipsec_life_seconds); | |||
| 6150 | st->st_replace_by = monotime_add(mononow(), deltatime(delay)); | |||
| 6151 | ||||
| 6152 | /* | |||
| 6153 | * Important policy lies buried here. For example, we favour | |||
| 6154 | * the initiator over the responder by making the initiator | |||
| 6155 | * start rekeying sooner. Also, fuzz is only added to the | |||
| 6156 | * initiator's margin. | |||
| 6157 | */ | |||
| 6158 | ||||
| 6159 | enum event_type kind; | |||
| 6160 | const char *story; | |||
| 6161 | intmax_t marg; | |||
| 6162 | if ((c->policy & POLICY_OPPORTUNISTIC((lset_t)1 << (POLICY_OPPORTUNISTIC_IX))) && | |||
| 6163 | st->st_connection->spd.that.has_lease) { | |||
| 6164 | marg = 0; | |||
| 6165 | kind = EVENT_SA_EXPIRE; | |||
| 6166 | story = "always expire opportunistic SA with lease"; | |||
| 6167 | } else if (c->policy & POLICY_DONT_REKEY((lset_t)1 << (POLICY_DONT_REKEY_IX))) { | |||
| 6168 | marg = 0; | |||
| 6169 | kind = EVENT_SA_EXPIRE; | |||
| 6170 | story = "policy doesn't allow re-key"; | |||
| 6171 | 	} else if (IS_IKE_SA(st)((st)->st_clonedfrom == 0) && LIN(POLICY_REAUTH, st->st_connection->policy)(((((lset_t)1 << (POLICY_REAUTH_IX))) & (st->st_connection ->policy)) == (((lset_t)1 << (POLICY_REAUTH_IX))))) {  | |||
| 6172 | marg = 0; | |||
| 6173 | kind = EVENT_SA_REPLACE; | |||
| 6174 | story = "IKE SA with policy re-authenticate"; | |||
| 6175 | } else { | |||
| 6176 | /* unwrapped deltatime_t in seconds */ | |||
| 6177 | marg = deltasecs(c->sa_rekey_margin); | |||
| 6178 | ||||
| 6179 | switch (st->st_sa_role) { | |||
| 6180 | case SA_INITIATOR: | |||
| 6181 | marg += marg * | |||
| 6182 | c->sa_rekey_fuzz / 100.E0 * | |||
| 6183 | (rand() / (RAND_MAX2147483647 + 1.E0)); | |||
| 6184 | break; | |||
| 6185 | case SA_RESPONDER: | |||
| 6186 | marg /= 2; | |||
| 6187 | break; | |||
| 6188 | default: | |||
| 6189 | 			bad_case(st->st_sa_role)libreswan_bad_case("st->st_sa_role", (st->st_sa_role), ( where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 6189});  | |||
| 6190 | } | |||
| 6191 | ||||
| 6192 | if (delay > marg) { | |||
| 6193 | delay -= marg; | |||
| 6194 | kind = EVENT_SA_REKEY; | |||
| 6195 | story = "attempting re-key"; | |||
| 6196 | } else { | |||
| 6197 | marg = 0; | |||
| 6198 | kind = EVENT_SA_REPLACE; | |||
| 6199 | story = "margin to small for re-key"; | |||
| 6200 | } | |||
| 6201 | } | |||
| 6202 | ||||
| 6203 | st->st_replace_margin = deltatime(marg); | |||
| 6204 | if (marg > 0) { | |||
| 6205 | 		passert(kind == EVENT_SA_REKEY){ _Bool assertion__ = kind == EVENT_SA_REKEY; if (!assertion__ ) { lsw_passert_fail((where_t) { .func = __func__, .basename = "ikev2_parent.c" , .line = 6205}, "%s", "kind == EVENT_SA_REKEY" ); } };  | |||
| 6206 | 		dbg("#%lu will start re-keying in %jd seconds with margin of %jd seconds (%s)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu will start re-keying in %jd seconds with margin of %jd seconds (%s)" , st->st_serialno, delay, marg, story); } }  | |||
| 6207 | 		    st->st_serialno, delay, marg, story){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu will start re-keying in %jd seconds with margin of %jd seconds (%s)" , st->st_serialno, delay, marg, story); } };  | |||
| 6208 | } else { | |||
| 6209 | 		passert(kind == EVENT_SA_REPLACE || kind == EVENT_SA_EXPIRE){ _Bool assertion__ = kind == EVENT_SA_REPLACE || kind == EVENT_SA_EXPIRE ; if (!assertion__) { lsw_passert_fail((where_t) { .func = __func__ , .basename = "ikev2_parent.c" , .line = 6209}, "%s", "kind == EVENT_SA_REPLACE || kind == EVENT_SA_EXPIRE" ); } };  | |||
| 6210 | 		dbg("#%lu will %s in %jd seconds (%s)",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu will %s in %jd seconds (%s)", st->st_serialno , kind == EVENT_SA_EXPIRE ? "expire" : "be replaced", delay, story ); } }  | |||
| 6211 | 		    st->st_serialno,{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu will %s in %jd seconds (%s)", st->st_serialno , kind == EVENT_SA_EXPIRE ? "expire" : "be replaced", delay, story ); } }  | |||
| 6212 | 		    kind == EVENT_SA_EXPIRE ? "expire" : "be replaced",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu will %s in %jd seconds (%s)", st->st_serialno , kind == EVENT_SA_EXPIRE ? "expire" : "be replaced", delay, story ); } }  | |||
| 6213 | 		    delay, story){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu will %s in %jd seconds (%s)", st->st_serialno , kind == EVENT_SA_EXPIRE ? "expire" : "be replaced", delay, story ); } };  | |||
| 6214 | } | |||
| 6215 | ||||
| 6216 | delete_event(st); | |||
| 6217 | event_schedule(kind, deltatime(delay), st); | |||
| 6218 | } | |||
| 6219 | ||||
| 6220 | void v2_event_sa_rekey(struct state *st) | |||
| 6221 | { | |||
| 6222 | monotime_t now = mononow(); | |||
| 6223 | const char *satype = IS_IKE_SA(st)((st)->st_clonedfrom == 0) ? "IKE" : "CHILD"; | |||
| 6224 | ||||
| 6225 | so_serial_t newer_sa = get_newer_sa_from_connection(st); | |||
| 6226 | if (newer_sa != SOS_NOBODY0) { | |||
| 6227 | /* implies a double re-key? */ | |||
| 6228 | 		pexpect_fail(st->st_logger, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 6228},  | |||
| 6229 | "not replacing stale %s SA #%lu; as already got a newer #%lu", | |||
| 6230 | satype, st->st_serialno, newer_sa); | |||
| 6231 | event_force(EVENT_SA_EXPIRE, st); | |||
| 6232 | return; | |||
| 6233 | } | |||
| 6234 | ||||
| 6235 | if (expire_ike_because_child_not_used(st)) { | |||
| 6236 | 		struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 6236});  | |||
| 6237 | event_force(EVENT_SA_EXPIRE, &ike->sa); | |||
| 6238 | return; | |||
| 6239 | } | |||
| 6240 | ||||
| 6241 | if (monobefore(st->st_replace_by, now)) { | |||
| 6242 | 		dbg("#%lu has no time to re-key, will replace",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu has no time to re-key, will replace", st ->st_serialno); } }  | |||
| 6243 | 		    st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("#%lu has no time to re-key, will replace", st ->st_serialno); } };  | |||
| 6244 | event_force(EVENT_SA_REPLACE, st); | |||
| 6245 | } | |||
| 6246 | ||||
| 6247 | 	dbg("rekeying stale %s SA", satype){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("rekeying stale %s SA", satype); } };  | |||
| 6248 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0)) { | |||
| 6249 | 		libreswan_log("initiate rekey of IKEv2 CREATE_CHILD_SA IKE Rekey")loglog(RC_LOG, "initiate rekey of IKEv2 CREATE_CHILD_SA IKE Rekey" );  | |||
| 6250 | ikev2_rekey_ike_start(pexpect_ike_sa(st)); | |||
| 6251 | } else { | |||
| 6252 | /* | |||
| 6253 | * XXX: Don't be fooled, ipsecdoi_replace() is magic - | |||
| 6254 | * if the old state still exists it morphs things into | |||
| 6255 | * a child re-key. | |||
| 6256 | */ | |||
| 6257 | ipsecdoi_replace(st, 1); | |||
| 6258 | } | |||
| 6259 | /* | |||
| 6260 | * Should the rekey go into the weeds this replace will kick | |||
| 6261 | * in. | |||
| 6262 | * | |||
| 6263 | * XXX: should the next event be SA_EXPIRE instead of | |||
| 6264 | * SA_REPLACE? For an IKE SA it breaks ikev2-32-nat-rw-rekey. | |||
| 6265 | * For a CHILD SA perhaps - there is a mystery around what | |||
| 6266 | * happens to the new child if the old one disappears. | |||
| 6267 | */ | |||
| 6268 | 	dbg("scheduling drop-dead replace event for #%lu", st->st_serialno){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("scheduling drop-dead replace event for #%lu", st->st_serialno); } };  | |||
| 6269 | event_delete(EVENT_v2_LIVENESS, st); | |||
| 6270 | event_schedule(EVENT_SA_REPLACE, monotimediff(st->st_replace_by, now), st); | |||
| 6271 | } | |||
| 6272 | ||||
| 6273 | void v2_event_sa_replace(struct state *st) | |||
| 6274 | { | |||
| 6275 | const char *satype = IS_IKE_SA(st)((st)->st_clonedfrom == 0) ? "IKE" : "CHILD"; | |||
| 6276 | ||||
| 6277 | so_serial_t newer_sa = get_newer_sa_from_connection(st); | |||
| 6278 | if (newer_sa != SOS_NOBODY0) { | |||
| 6279 | /* | |||
| 6280 | * For some reason the rekey, above, hasn't completed. | |||
| 6281 | * For an IKE SA blow away the entire family | |||
| 6282 | * (including the in-progress rekey). For a CHILD SA | |||
| 6283 | * this will delete the old SA but leave the rekey | |||
| 6284 | * alone. Confusing. | |||
| 6285 | */ | |||
| 6286 | if (IS_IKE_SA(st)((st)->st_clonedfrom == 0)) { | |||
| 6287 | 			dbg("replacing entire stale IKE SA #%lu family; rekey #%lu will be deleted",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("replacing entire stale IKE SA #%lu family; rekey #%lu will be deleted" , st->st_serialno, newer_sa); } }  | |||
| 6288 | 			    st->st_serialno, newer_sa){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("replacing entire stale IKE SA #%lu family; rekey #%lu will be deleted" , st->st_serialno, newer_sa); } };  | |||
| 6289 | ipsecdoi_replace(st, 1); | |||
| 6290 | } else { | |||
| 6291 | 			dbg("expiring stale CHILD SA #%lu; newer #%lu will replace?",{ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("expiring stale CHILD SA #%lu; newer #%lu will replace?" , st->st_serialno, newer_sa); } }  | |||
| 6292 | 			    st->st_serialno, newer_sa){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("expiring stale CHILD SA #%lu; newer #%lu will replace?" , st->st_serialno, newer_sa); } };  | |||
| 6293 | } | |||
| 6294 | /* XXX: are these calls needed? it's about to die */ | |||
| 6295 | event_delete(EVENT_v2_LIVENESS, st); | |||
| 6296 | event_force(EVENT_SA_EXPIRE, st); | |||
| 6297 | return; | |||
| 6298 | } | |||
| 6299 | ||||
| 6300 | if (expire_ike_because_child_not_used(st)) { | |||
| 6301 | 		struct ike_sa *ike = ike_sa(st, HERE(where_t) { .func = __func__, .basename = "ikev2_parent.c" , . line = 6301});  | |||
| 6302 | event_force(EVENT_SA_EXPIRE, &ike->sa); | |||
| 6303 | return; | |||
| 6304 | } | |||
| 6305 | ||||
| 6306 | /* | |||
| 6307 | * XXX: For a CHILD SA, will this result in a re-key attempt? | |||
| 6308 | */ | |||
| 6309 | 	dbg("replacing stale %s SA", satype){ if ((cur_debugging & (((lset_t)1 << (DBG_BASE_IX) )))) { DBG_log("replacing stale %s SA", satype); } };  | |||
| 6310 | ipsecdoi_replace(st, 1); | |||
| 6311 | event_delete(EVENT_v2_LIVENESS, st); | |||
| 6312 | event_force(EVENT_SA_EXPIRE, st); | |||
| 6313 | } |