|
|
1b7fd5 |
diff -Naur libreswan-3.8-orig/include/ietf_constants.h libreswan-3.8/include/ietf_constants.h
|
|
|
dbd905 |
--- libreswan-3.8-orig/include/ietf_constants.h 2014-01-16 02:46:24.000000000 -0500
|
|
|
dbd905 |
+++ libreswan-3.8/include/ietf_constants.h 2014-04-10 15:55:22.303340560 -0400
|
|
|
1b7fd5 |
@@ -607,7 +607,7 @@
|
|
|
1b7fd5 |
/* IKEv2 things */
|
|
|
1b7fd5 |
ISAKMP_v2_SA_INIT = 34,
|
|
|
1b7fd5 |
ISAKMP_v2_AUTH = 35,
|
|
|
1b7fd5 |
- ISAKMP_v2_CHILD_SA = 36,
|
|
|
1b7fd5 |
+ ISAKMP_v2_CREATE_CHILD_SA = 36,
|
|
|
1b7fd5 |
ISAKMP_v2_INFORMATIONAL = 37,
|
|
|
1b7fd5 |
ISAKMP_v2_IKE_SESSION_RESUME = 38, /* RFC 5723 */
|
|
|
1b7fd5 |
|
|
|
1b7fd5 |
diff -Naur libreswan-3.8-orig/include/pluto_constants.h libreswan-3.8/include/pluto_constants.h
|
|
|
dbd905 |
--- libreswan-3.8-orig/include/pluto_constants.h 2014-01-16 02:46:24.000000000 -0500
|
|
|
dbd905 |
+++ libreswan-3.8/include/pluto_constants.h 2014-04-10 15:55:22.303340560 -0400
|
|
|
1b7fd5 |
@@ -424,6 +424,11 @@
|
|
|
1b7fd5 |
|
|
|
1b7fd5 |
#define IS_PARENT_SA_ESTABLISHED(s) ((s) == STATE_PARENT_I2 || (s) == \
|
|
|
1b7fd5 |
STATE_PARENT_R1 || (s) == STATE_IKESA_DEL)
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+#define IS_V2_INITIATOR(s) ((s) == STATE_PARENT_I1 || \
|
|
|
1b7fd5 |
+ (s) == STATE_PARENT_I2 || \
|
|
|
1b7fd5 |
+ (s) == STATE_PARENT_I3)
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
/*
|
|
|
1b7fd5 |
* Issue here is that our child sa appears as a STATE_PARENT_I3/STATE_PARENT_R2 state which it should not
|
|
|
1b7fd5 |
* So we fall back to checking if it is cloned, and therefor really a child
|
|
|
1b7fd5 |
diff -Naur libreswan-3.8-orig/lib/libswan/constants.c libreswan-3.8/lib/libswan/constants.c
|
|
|
dbd905 |
--- libreswan-3.8-orig/lib/libswan/constants.c 2014-01-16 02:46:24.000000000 -0500
|
|
|
dbd905 |
+++ libreswan-3.8/lib/libswan/constants.c 2014-04-10 15:55:22.303340560 -0400
|
|
|
1b7fd5 |
@@ -269,7 +269,7 @@
|
|
|
1b7fd5 |
static const char *const exchange_name_ikev2[] = {
|
|
|
1b7fd5 |
"ISAKMP_v2_SA_INIT",
|
|
|
1b7fd5 |
"ISAKMP_v2_AUTH",
|
|
|
1b7fd5 |
- "ISAKMP_v2_CHILD_SA",
|
|
|
1b7fd5 |
+ "ISAKMP_v2_CREATE_CHILD_SA",
|
|
|
1b7fd5 |
"ISAKMP_v2_INFORMATIONAL",
|
|
|
1b7fd5 |
"ISAKMP_v2_IKE_SESSION_RESUME",
|
|
|
1b7fd5 |
};
|
|
|
1b7fd5 |
diff -Naur libreswan-3.8-orig/programs/pluto/ikev2.c libreswan-3.8/programs/pluto/ikev2.c
|
|
|
dbd905 |
--- libreswan-3.8-orig/programs/pluto/ikev2.c 2014-01-16 02:46:24.000000000 -0500
|
|
|
dbd905 |
+++ libreswan-3.8/programs/pluto/ikev2.c 2014-04-10 15:55:37.668690909 -0400
|
|
|
1b7fd5 |
@@ -150,6 +150,31 @@
|
|
|
1b7fd5 |
* TSi, TSr}
|
|
|
1b7fd5 |
* [Child SA established]
|
|
|
1b7fd5 |
*
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * CREATE_CHILD_SA Exchanges:
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * New Child SA
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * HDR, SK {SA, Ni, [KEi],
|
|
|
1b7fd5 |
+ * TSi, TSr} -->
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * <-- HDR, SK {SA, Nr, [KEr],
|
|
|
1b7fd5 |
+ * TSi, TSr}
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * Rekey Child SA
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * HDR, SK {N(REKEY_SA), SA, Ni, [KEi],
|
|
|
1b7fd5 |
+ * TSi, TSr} -->
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * <-- HDR, SK {SA, Nr, [KEr],
|
|
|
1b7fd5 |
+ * TSi, TSr}
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * Rekey IKE SA (yes, IKE SA can be rekeyed using CREATE_CHILD_SA)
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * HDR, SK {SA, Ni, KEi} -->
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * <-- HDR, SK {SA, Nr, KEr}
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
*/
|
|
|
1b7fd5 |
|
|
|
1b7fd5 |
/* Short forms for building payload type sets */
|
|
|
1b7fd5 |
@@ -287,6 +312,36 @@
|
|
|
1b7fd5 |
.processor = process_informational_ikev2,
|
|
|
1b7fd5 |
.recv_type = ISAKMP_v2_INFORMATIONAL, },
|
|
|
1b7fd5 |
|
|
|
1b7fd5 |
+ /*
|
|
|
1b7fd5 |
+ * There are three different CREATE_CHILD_SA's invocations,
|
|
|
1b7fd5 |
+ * this is the combined write up (not in RFC). See above for
|
|
|
1b7fd5 |
+ * individual cases from RFC
|
|
|
1b7fd5 |
+ *
|
|
|
1b7fd5 |
+ * HDR, SK {SA, Ni, [KEi], [N(REKEY_SA)], [TSi, TSr]} -->
|
|
|
1b7fd5 |
+ * <-- HDR, SK {N}
|
|
|
1b7fd5 |
+ * <-- HDR, SK {SA, Nr, [KEr], [TSi, TSr]}
|
|
|
1b7fd5 |
+ */
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ /* Create Child SA Exchange*/
|
|
|
1b7fd5 |
+ { .state = STATE_PARENT_I3,
|
|
|
1b7fd5 |
+ .next_state = STATE_PARENT_I3,
|
|
|
1b7fd5 |
+ .flags = SMF2_STATENEEDED | SMF2_REPLY,
|
|
|
1b7fd5 |
+ .req_clear_payloads = P(E),
|
|
|
1b7fd5 |
+ .req_enc_payloads = P(SA) | P(Ni),
|
|
|
1b7fd5 |
+ .opt_enc_payloads = P(KE) | P(N) | P(TSi) | P(TSr),
|
|
|
1b7fd5 |
+ .processor = ikev2_in_create_child_sa,
|
|
|
1b7fd5 |
+ .recv_type = ISAKMP_v2_CREATE_CHILD_SA, },
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ /* Create Child SA Exchange*/
|
|
|
1b7fd5 |
+ { .state = STATE_PARENT_R2,
|
|
|
1b7fd5 |
+ .next_state = STATE_PARENT_R2,
|
|
|
1b7fd5 |
+ .flags = SMF2_STATENEEDED | SMF2_REPLY,
|
|
|
1b7fd5 |
+ .req_clear_payloads = P(E),
|
|
|
1b7fd5 |
+ .req_enc_payloads = P(SA) | P(Ni),
|
|
|
1b7fd5 |
+ .opt_enc_payloads = P(KE) | P(N) | P(TSi) | P(TSr),
|
|
|
1b7fd5 |
+ .processor = ikev2_in_create_child_sa,
|
|
|
1b7fd5 |
+ .recv_type = ISAKMP_v2_CREATE_CHILD_SA, },
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
/* Informational Exchange*/
|
|
|
1b7fd5 |
{ .state = STATE_PARENT_R2,
|
|
|
1b7fd5 |
.next_state = STATE_PARENT_R2,
|
|
|
dbd905 |
@@ -607,7 +662,11 @@
|
|
|
dbd905 |
continue;
|
|
|
dbd905 |
|
|
|
dbd905 |
/* ??? not sure that this is necessary, but it ought to be correct */
|
|
|
dbd905 |
- if ( ((svm->flags&SMF2_INITIATOR) != 0) != ((md->hdr.isa_flags & ISAKMP_FLAGS_R) != 0) )
|
|
|
dbd905 |
+ /* This check cannot apply for an informational exchange since one
|
|
|
dbd905 |
+ * can be initiated by the initial responder.
|
|
|
dbd905 |
+ */
|
|
|
dbd905 |
+ if (ix != ISAKMP_v2_INFORMATIONAL &&
|
|
|
dbd905 |
+ (((svm->flags&SMF2_INITIATOR) != 0) != ((md->hdr.isa_flags & ISAKMP_FLAGS_R) != 0)))
|
|
|
dbd905 |
continue;
|
|
|
dbd905 |
|
|
|
dbd905 |
/* must be the right state */
|
|
|
dbd905 |
@@ -832,6 +891,10 @@
|
|
|
dbd905 |
|
|
|
dbd905 |
case RESPONDER:
|
|
|
dbd905 |
pst->st_msgid_lastrecv = md->msgid_received;
|
|
|
dbd905 |
+ /* the responder requires msgid_nextuse if it ever needs to
|
|
|
dbd905 |
+ * initiate an informational exchange
|
|
|
dbd905 |
+ */
|
|
|
dbd905 |
+ pst->st_msgid_nextuse = md->msgid_received + 1;
|
|
|
dbd905 |
break;
|
|
|
dbd905 |
}
|
|
|
dbd905 |
}
|
|
|
1b7fd5 |
diff -Naur libreswan-3.8-orig/programs/pluto/ikev2.h libreswan-3.8/programs/pluto/ikev2.h
|
|
|
dbd905 |
--- libreswan-3.8-orig/programs/pluto/ikev2.h 2014-01-16 02:46:24.000000000 -0500
|
|
|
dbd905 |
+++ libreswan-3.8/programs/pluto/ikev2.h 2014-04-10 15:55:22.304340582 -0400
|
|
|
1b7fd5 |
@@ -35,6 +35,8 @@
|
|
|
1b7fd5 |
extern stf_status ikev2_send_informational(struct state *st);
|
|
|
1b7fd5 |
|
|
|
1b7fd5 |
extern stf_status process_informational_ikev2(struct msg_digest *md);
|
|
|
1b7fd5 |
+extern stf_status ikev2_in_create_child_sa(struct msg_digest *md);
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
extern stf_status ikev2parent_inI1outR1(struct msg_digest *md);
|
|
|
1b7fd5 |
extern stf_status ikev2parent_inR1(struct msg_digest *md);
|
|
|
1b7fd5 |
extern stf_status ikev2parent_inR1outI2(struct msg_digest *md);
|
|
|
1b7fd5 |
diff -Naur libreswan-3.8-orig/programs/pluto/ikev2_parent.c libreswan-3.8/programs/pluto/ikev2_parent.c
|
|
|
dbd905 |
--- libreswan-3.8-orig/programs/pluto/ikev2_parent.c 2014-01-16 02:46:24.000000000 -0500
|
|
|
dbd905 |
+++ libreswan-3.8/programs/pluto/ikev2_parent.c 2014-04-10 15:55:37.668690909 -0400
|
|
|
dbd905 |
@@ -2722,8 +2722,125 @@
|
|
|
1b7fd5 |
delete_state(pst);
|
|
|
1b7fd5 |
}
|
|
|
1b7fd5 |
|
|
|
1b7fd5 |
+static stf_status ikev2_in_create_child_sa_refuse(struct msg_digest *md)
|
|
|
1b7fd5 |
+{
|
|
|
1b7fd5 |
+ struct state *st = md->st;
|
|
|
1b7fd5 |
+ struct state *pst = st;
|
|
|
1b7fd5 |
+ {
|
|
|
1b7fd5 |
+ unsigned char *authstart;
|
|
|
1b7fd5 |
+ unsigned char *encstart;
|
|
|
1b7fd5 |
+ unsigned char *iv;
|
|
|
1b7fd5 |
+ int ivsize;
|
|
|
1b7fd5 |
+ struct ikev2_generic e;
|
|
|
1b7fd5 |
+ pb_stream e_pbs, e_pbs_cipher;
|
|
|
1b7fd5 |
+ pb_stream request;
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ zero(&reply_buffer);
|
|
|
1b7fd5 |
+ init_pbs(&request, reply_buffer, sizeof(reply_buffer),
|
|
|
1b7fd5 |
+ "create child SA exchange request response");
|
|
|
1b7fd5 |
+ authstart = request.cur;
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ /* HDR out */
|
|
|
1b7fd5 |
+ {
|
|
|
1b7fd5 |
+ struct isakmp_hdr r_hdr;
|
|
|
1b7fd5 |
+ zero(&r_hdr);
|
|
|
1b7fd5 |
+ r_hdr.isa_version = build_ike_version();
|
|
|
1b7fd5 |
+ memcpy(r_hdr.isa_rcookie, pst->st_rcookie,
|
|
|
1b7fd5 |
+ COOKIE_SIZE);
|
|
|
1b7fd5 |
+ memcpy(r_hdr.isa_icookie, pst->st_icookie,
|
|
|
1b7fd5 |
+ COOKIE_SIZE);
|
|
|
1b7fd5 |
+ r_hdr.isa_xchg = ISAKMP_v2_CREATE_CHILD_SA;
|
|
|
1b7fd5 |
+ r_hdr.isa_np = ISAKMP_NEXT_v2E;
|
|
|
1b7fd5 |
+ r_hdr.isa_flags |= ISAKMP_FLAGS_R;
|
|
|
1b7fd5 |
+ r_hdr.isa_msgid = htonl(pst->st_msgid_nextuse);
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ /* encryption role based on original state not md state */
|
|
|
1b7fd5 |
+ if (IS_V2_INITIATOR(pst->st_state))
|
|
|
1b7fd5 |
+ md->role = INITIATOR;
|
|
|
1b7fd5 |
+ else
|
|
|
1b7fd5 |
+ md->role = RESPONDER;
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ if (!out_struct(&r_hdr, &isakmp_hdr_desc,
|
|
|
1b7fd5 |
+ &request, &md->rbody)) {
|
|
|
1b7fd5 |
+ libreswan_log("error initializing hdr for "
|
|
|
1b7fd5 |
+ "CREATE_CHILD_SA message");
|
|
|
1b7fd5 |
+ return STF_FATAL;
|
|
|
1b7fd5 |
+ }
|
|
|
1b7fd5 |
+ } /* HDR done*/
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ /* insert an Encryption payload header */
|
|
|
1b7fd5 |
+ e.isag_np = ISAKMP_NEXT_v2N;
|
|
|
1b7fd5 |
+ e.isag_critical = ISAKMP_PAYLOAD_NONCRITICAL;
|
|
|
1b7fd5 |
+ if (!out_struct(&e, &ikev2_e_desc, &md->rbody, &e_pbs))
|
|
|
1b7fd5 |
+ return STF_FATAL;
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ /* IV */
|
|
|
1b7fd5 |
+ iv = e_pbs.cur;
|
|
|
1b7fd5 |
+ ivsize = pst->st_oakley.encrypter->iv_size;
|
|
|
1b7fd5 |
+ if (!out_zero(ivsize, &e_pbs, "iv"))
|
|
|
1b7fd5 |
+ return STF_FATAL;
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ get_rnd_bytes(iv, ivsize);
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ /* note where cleartext starts */
|
|
|
1b7fd5 |
+ init_pbs(&e_pbs_cipher, e_pbs.cur, e_pbs.roof - e_pbs.cur,
|
|
|
1b7fd5 |
+ "cleartext");
|
|
|
1b7fd5 |
+ e_pbs_cipher.container = &e_pbs;
|
|
|
1b7fd5 |
+ e_pbs_cipher.desc = NULL;
|
|
|
1b7fd5 |
+ e_pbs_cipher.cur = e_pbs.cur;
|
|
|
1b7fd5 |
+ encstart = e_pbs_cipher.cur;
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ chunk_t child_spi;
|
|
|
1b7fd5 |
+ memset(&child_spi, 0, sizeof(child_spi));
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ ship_v2N(ISAKMP_NEXT_v2NONE,
|
|
|
1b7fd5 |
+ ISAKMP_PAYLOAD_NONCRITICAL,
|
|
|
1b7fd5 |
+ PROTO_ISAKMP,
|
|
|
1b7fd5 |
+ &child_spi,
|
|
|
1b7fd5 |
+ v2N_NO_ADDITIONAL_SAS, NULL,
|
|
|
1b7fd5 |
+ &e_pbs_cipher);
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ ikev2_padup_pre_encrypt(md, &e_pbs_cipher);
|
|
|
1b7fd5 |
+ close_output_pbs(&e_pbs_cipher);
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ {
|
|
|
1b7fd5 |
+ stf_status ret;
|
|
|
1b7fd5 |
+ unsigned char *authloc = ikev2_authloc(md, &e_pbs);
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ if (!authloc)
|
|
|
1b7fd5 |
+ return STF_FATAL;
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ close_output_pbs(&e_pbs);
|
|
|
1b7fd5 |
+ close_output_pbs(&md->rbody);
|
|
|
1b7fd5 |
+ close_output_pbs(&request);
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ ret = ikev2_encrypt_msg(md, md->role,
|
|
|
1b7fd5 |
+ authstart,
|
|
|
1b7fd5 |
+ iv, encstart, authloc,
|
|
|
1b7fd5 |
+ &e_pbs, &e_pbs_cipher);
|
|
|
1b7fd5 |
+ if (ret != STF_OK)
|
|
|
1b7fd5 |
+ return ret;
|
|
|
1b7fd5 |
+ }
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ /* keep it for a retransmit if necessary */
|
|
|
1b7fd5 |
+ freeanychunk(pst->st_tpacket);
|
|
|
1b7fd5 |
+ clonetochunk(pst->st_tpacket, request.start,
|
|
|
1b7fd5 |
+ pbs_offset(&request),
|
|
|
1b7fd5 |
+ "reply packet for CREATE_CHILD_SA exchange");
|
|
|
1b7fd5 |
+ send_ike_msg(pst, __FUNCTION__);
|
|
|
1b7fd5 |
+ }
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+ return STF_OK;
|
|
|
1b7fd5 |
+}
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
+stf_status ikev2_in_create_child_sa(struct msg_digest *md)
|
|
|
1b7fd5 |
+{
|
|
|
1b7fd5 |
+ return ikev2_in_create_child_sa_refuse(md);
|
|
|
1b7fd5 |
+}
|
|
|
1b7fd5 |
+
|
|
|
1b7fd5 |
stf_status process_informational_ikev2(struct msg_digest *md)
|
|
|
1b7fd5 |
{
|
|
|
dbd905 |
+ enum phase1_role prole;
|
|
|
1b7fd5 |
/* verify that there is in fact an encrypted payload */
|
|
|
dbd905 |
if (md->chain[ISAKMP_NEXT_v2E] == NULL) {
|
|
|
dbd905 |
libreswan_log(
|
|
|
dbd905 |
@@ -2734,15 +2851,23 @@
|
|
|
dbd905 |
/* decrypt things. */
|
|
|
dbd905 |
{
|
|
|
dbd905 |
stf_status ret;
|
|
|
dbd905 |
+ struct state *ost = md->st;
|
|
|
dbd905 |
|
|
|
dbd905 |
- if (md->hdr.isa_flags & ISAKMP_FLAGS_I) {
|
|
|
dbd905 |
+ /*
|
|
|
dbd905 |
+ * Since an informational exchange can be started by the original responder,
|
|
|
dbd905 |
+ * things such as encryption, decryption should be done based on the original
|
|
|
dbd905 |
+ * role and not the md->role
|
|
|
dbd905 |
+ */
|
|
|
dbd905 |
+ if (IS_V2_INITIATOR(ost->st_state)) {
|
|
|
dbd905 |
+ prole = INITIATOR;
|
|
|
dbd905 |
DBG(DBG_CONTROLMORE,
|
|
|
dbd905 |
- DBG_log("received informational exchange request from INITIATOR"));
|
|
|
dbd905 |
- ret = ikev2_decrypt_msg(md, RESPONDER);
|
|
|
dbd905 |
+ DBG_log("received informational exchange request from the original responder"));
|
|
|
dbd905 |
+ ret = ikev2_decrypt_msg(md, INITIATOR);
|
|
|
dbd905 |
} else {
|
|
|
dbd905 |
+ prole = RESPONDER;
|
|
|
dbd905 |
DBG(DBG_CONTROLMORE,
|
|
|
dbd905 |
- DBG_log("received informational exchange request from RESPONDER"));
|
|
|
dbd905 |
- ret = ikev2_decrypt_msg(md, INITIATOR);
|
|
|
dbd905 |
+ DBG_log("received informational exchange request from the original initiator"));
|
|
|
dbd905 |
+ ret = ikev2_decrypt_msg(md, RESPONDER);
|
|
|
dbd905 |
}
|
|
|
dbd905 |
|
|
|
dbd905 |
if (ret != STF_OK)
|
|
|
dbd905 |
@@ -2791,10 +2916,6 @@
|
|
|
dbd905 |
r_hdr.isa_np = ISAKMP_NEXT_v2E;
|
|
|
dbd905 |
r_hdr.isa_msgid = htonl(md->msgid_received);
|
|
|
dbd905 |
|
|
|
dbd905 |
- /*set initiator bit if we are initiator*/
|
|
|
dbd905 |
- if (md->role == INITIATOR)
|
|
|
dbd905 |
- r_hdr.isa_flags |= ISAKMP_FLAGS_I;
|
|
|
dbd905 |
-
|
|
|
dbd905 |
r_hdr.isa_flags |= ISAKMP_FLAGS_R;
|
|
|
dbd905 |
|
|
|
dbd905 |
if (!out_struct(&r_hdr, &isakmp_hdr_desc,
|
|
|
dbd905 |
@@ -3016,7 +3137,7 @@
|
|
|
dbd905 |
close_output_pbs(&md->rbody);
|
|
|
dbd905 |
close_output_pbs(&reply_stream);
|
|
|
dbd905 |
|
|
|
dbd905 |
- ret = ikev2_encrypt_msg(md, md->role,
|
|
|
dbd905 |
+ ret = ikev2_encrypt_msg(md, prole,
|
|
|
dbd905 |
authstart,
|
|
|
dbd905 |
iv, encstart, authloc,
|
|
|
dbd905 |
&e_pbs, &e_pbs_cipher);
|
|
|
dbd905 |
@@ -3158,7 +3279,7 @@
|
|
|
dbd905 |
|
|
|
dbd905 |
stf_status ikev2_send_informational(struct state *st)
|
|
|
dbd905 |
{
|
|
|
dbd905 |
- struct state *pst = NULL;
|
|
|
dbd905 |
+ struct state *pst = st;
|
|
|
dbd905 |
|
|
|
dbd905 |
if (IS_CHILD_SA(st)) {
|
|
|
dbd905 |
pst = state_with_serialno(st->st_clonedfrom);
|
|
|
dbd905 |
@@ -3169,8 +3290,6 @@
|
|
|
dbd905 |
DBG_log("INFORMATIONAL exchange can not be sent"));
|
|
|
dbd905 |
return STF_IGNORE;
|
|
|
dbd905 |
}
|
|
|
dbd905 |
- } else {
|
|
|
dbd905 |
- pst = st;
|
|
|
dbd905 |
}
|
|
|
dbd905 |
|
|
|
dbd905 |
{
|
|
|
dbd905 |
@@ -3180,7 +3299,6 @@
|
|
|
dbd905 |
int ivsize;
|
|
|
dbd905 |
struct msg_digest md;
|
|
|
dbd905 |
struct ikev2_generic e;
|
|
|
dbd905 |
- enum phase1_role role;
|
|
|
dbd905 |
pb_stream e_pbs, e_pbs_cipher;
|
|
|
dbd905 |
pb_stream rbody;
|
|
|
dbd905 |
pb_stream request;
|
|
|
dbd905 |
@@ -3204,18 +3322,14 @@
|
|
|
dbd905 |
COOKIE_SIZE);
|
|
|
dbd905 |
r_hdr.isa_xchg = ISAKMP_v2_INFORMATIONAL;
|
|
|
dbd905 |
r_hdr.isa_np = ISAKMP_NEXT_v2E;
|
|
|
dbd905 |
+ r_hdr.isa_flags |= ISAKMP_FLAGS_I;
|
|
|
dbd905 |
+ r_hdr.isa_msgid = htonl(pst->st_msgid_nextuse);
|
|
|
dbd905 |
|
|
|
dbd905 |
- if (pst->st_state == STATE_PARENT_I2 ||
|
|
|
dbd905 |
- pst->st_state == STATE_PARENT_I3) {
|
|
|
dbd905 |
- r_hdr.isa_flags |= ISAKMP_FLAGS_I;
|
|
|
dbd905 |
- role = INITIATOR;
|
|
|
dbd905 |
- r_hdr.isa_msgid = htonl(pst->st_msgid_nextuse);
|
|
|
dbd905 |
- } else {
|
|
|
dbd905 |
- role = RESPONDER;
|
|
|
dbd905 |
- r_hdr.isa_msgid = htonl(
|
|
|
dbd905 |
- pst->st_msgid_lastrecv + 1);
|
|
|
dbd905 |
- }
|
|
|
dbd905 |
-
|
|
|
dbd905 |
+ /* encryption role based on original state not md state */
|
|
|
dbd905 |
+ if (IS_V2_INITIATOR(pst->st_state))
|
|
|
dbd905 |
+ md.role = INITIATOR;
|
|
|
dbd905 |
+ else
|
|
|
dbd905 |
+ md.role = RESPONDER;
|
|
|
dbd905 |
if (!out_struct(&r_hdr, &isakmp_hdr_desc,
|
|
|
dbd905 |
&request, &rbody)) {
|
|
|
dbd905 |
libreswan_log(
|
|
|
dbd905 |
@@ -3261,7 +3375,7 @@
|
|
|
dbd905 |
close_output_pbs(&rbody);
|
|
|
dbd905 |
close_output_pbs(&request);
|
|
|
dbd905 |
|
|
|
dbd905 |
- ret = ikev2_encrypt_msg(&md, role,
|
|
|
dbd905 |
+ ret = ikev2_encrypt_msg(&md, md.role,
|
|
|
dbd905 |
authstart,
|
|
|
dbd905 |
iv, encstart, authloc,
|
|
|
dbd905 |
&e_pbs, &e_pbs_cipher);
|
|
|
dbd905 |
@@ -3276,7 +3390,6 @@
|
|
|
dbd905 |
"reply packet for informational exchange");
|
|
|
dbd905 |
pst->st_pend_liveness = TRUE; /* we should only do this when dpd/liveness is active? */
|
|
|
dbd905 |
send_ike_msg(pst, __FUNCTION__);
|
|
|
dbd905 |
- ikev2_update_counters(&md);
|
|
|
dbd905 |
}
|
|
|
dbd905 |
|
|
|
dbd905 |
return STF_OK;
|