ike-init: Send USE_PPK notify as appropriate
[strongswan.git] / src / libcharon / sa / ikev2 / tasks / ike_init.c
index b5a58df..28e28e4 100644 (file)
@@ -1,8 +1,8 @@
 /*
- * Copyright (C) 2008-2015 Tobias Brunner
+ * Copyright (C) 2008-2018 Tobias Brunner
  * Copyright (C) 2005-2008 Martin Willi
  * Copyright (C) 2005 Jan Hutter
- * Hochschule fuer Technik Rapperswil
+ * HSR Hochschule fuer Technik Rapperswil
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
@@ -55,11 +55,6 @@ struct private_ike_init_t {
        bool initiator;
 
        /**
-        * IKE config to establish
-        */
-       ike_cfg_t *config;
-
-       /**
         * diffie hellman group to use
         */
        diffie_hellman_group_t dh_group;
@@ -158,7 +153,11 @@ static void send_supported_hash_algorithms(private_ike_init_t *this,
        peer_cfg_t *peer;
        auth_cfg_t *auth;
        auth_rule_t rule;
-       uintptr_t config;
+       signature_params_t *config;
+       int written;
+       size_t len = BUF_LEN;
+       char buf[len];
+       char *pos = buf;
        char *plugin_name;
 
        algos = hash_algorithm_set_create();
@@ -171,9 +170,10 @@ static void send_supported_hash_algorithms(private_ike_init_t *this,
                        enumerator = auth->create_enumerator(auth);
                        while (enumerator->enumerate(enumerator, &rule, &config))
                        {
-                               if (rule == AUTH_RULE_SIGNATURE_SCHEME)
+                               if (rule == AUTH_RULE_IKE_SIGNATURE_SCHEME)
                                {
-                                       hash = hasher_from_signature_scheme(config);
+                                       hash = hasher_from_signature_scheme(config->scheme,
+                                                                                                               config->params);
                                        if (hasher_algorithm_for_ikev2(hash))
                                        {
                                                algos->add(algos, hash);
@@ -205,11 +205,23 @@ static void send_supported_hash_algorithms(private_ike_init_t *this,
                while (enumerator->enumerate(enumerator, &hash))
                {
                        writer->write_uint16(writer, hash);
+
+                       /* generate debug output */
+                       written = snprintf(pos, len, " %N", hash_algorithm_short_names,
+                                                          hash);
+                       if (written > 0 && written < len)
+                       {
+                               pos += written;
+                               len -= written;
+                       }
                }
                enumerator->destroy(enumerator);
                message->add_notify(message, FALSE, SIGNATURE_HASH_ALGORITHMS,
                                                        writer->get_buf(writer));
                writer->destroy(writer);
+
+               *pos = '\0';
+               DBG2(DBG_CFG, "sending supported signature hash algorithms:%s", buf);
        }
        algos->destroy(algos);
 }
@@ -221,7 +233,11 @@ static void handle_supported_hash_algorithms(private_ike_init_t *this,
                                                                                         notify_payload_t *notify)
 {
        bio_reader_t *reader;
-       u_int16_t algo;
+       uint16_t algo;
+       int written;
+       size_t len = BUF_LEN;
+       char buf[len];
+       char *pos = buf;
        bool added = FALSE;
 
        reader = bio_reader_create(notify->get_notification_data(notify));
@@ -231,10 +247,22 @@ static void handle_supported_hash_algorithms(private_ike_init_t *this,
                {
                        this->keymat->add_hash_algorithm(this->keymat, algo);
                        added = TRUE;
+
+                       /* generate debug output */
+                       written = snprintf(pos, len, " %N", hash_algorithm_short_names,
+                                                          algo);
+                       if (written > 0 && written < len)
+                       {
+                               pos += written;
+                               len -= written;
+                       }
                }
        }
        reader->destroy(reader);
 
+       *pos = '\0';
+       DBG2(DBG_CFG, "received supported signature hash algorithms:%s", buf);
+
        if (added)
        {
                this->ike_sa->enable_extension(this->ike_sa, EXT_SIGNATURE_AUTH);
@@ -242,6 +270,38 @@ static void handle_supported_hash_algorithms(private_ike_init_t *this,
 }
 
 /**
+ * Check whether to send a USE_PPK notify
+ */
+static bool send_use_ppk(private_ike_init_t *this)
+{
+       peer_cfg_t *peer;
+       enumerator_t *keys;
+       shared_key_t *key;
+       bool use_ppk = FALSE;
+
+       if (this->initiator)
+       {
+               peer = this->ike_sa->get_peer_cfg(this->ike_sa);
+               if (peer->get_ppk_id(peer))
+               {
+                       use_ppk = TRUE;
+               }
+       }
+       else if (this->ike_sa->supports_extension(this->ike_sa, EXT_PPK))
+       {
+               /* check if we have at least one PPK available */
+               keys = lib->credmgr->create_shared_enumerator(lib->credmgr, SHARED_PPK,
+                                                                                                         NULL, NULL);
+               if (keys->enumerate(keys, &key, NULL, NULL))
+               {
+                       use_ppk = TRUE;
+               }
+               keys->destroy(keys);
+       }
+       return use_ppk;
+}
+
+/**
  * build the payloads for the message
  */
 static bool build_payloads(private_ike_init_t *this, message_t *message)
@@ -249,28 +309,44 @@ static bool build_payloads(private_ike_init_t *this, message_t *message)
        sa_payload_t *sa_payload;
        ke_payload_t *ke_payload;
        nonce_payload_t *nonce_payload;
-       linked_list_t *proposal_list;
+       linked_list_t *proposal_list, *other_dh_groups;
        ike_sa_id_t *id;
        proposal_t *proposal;
        enumerator_t *enumerator;
+       ike_cfg_t *ike_cfg;
 
        id = this->ike_sa->get_id(this->ike_sa);
 
-       this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
+       ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
 
        if (this->initiator)
        {
-               proposal_list = this->config->get_proposals(this->config);
-               if (this->old_sa)
+               proposal_list = ike_cfg->get_proposals(ike_cfg);
+               other_dh_groups = linked_list_create();
+               enumerator = proposal_list->create_enumerator(proposal_list);
+               while (enumerator->enumerate(enumerator, (void**)&proposal))
                {
                        /* include SPI of new IKE_SA when we are rekeying */
-                       enumerator = proposal_list->create_enumerator(proposal_list);
-                       while (enumerator->enumerate(enumerator, (void**)&proposal))
+                       if (this->old_sa)
                        {
                                proposal->set_spi(proposal, id->get_initiator_spi(id));
                        }
-                       enumerator->destroy(enumerator);
+                       /* move the selected DH group to the front of the proposal */
+                       if (!proposal->promote_dh_group(proposal, this->dh_group))
+                       {       /* the proposal does not include the group, move to the back */
+                               proposal_list->remove_at(proposal_list, enumerator);
+                               other_dh_groups->insert_last(other_dh_groups, proposal);
+                       }
                }
+               enumerator->destroy(enumerator);
+               /* add proposals that don't contain the selected group */
+               enumerator = other_dh_groups->create_enumerator(other_dh_groups);
+               while (enumerator->enumerate(enumerator, (void**)&proposal))
+               {       /* no need to remove from the list as we destroy it anyway*/
+                       proposal_list->insert_last(proposal_list, proposal);
+               }
+               enumerator->destroy(enumerator);
+               other_dh_groups->destroy(other_dh_groups);
 
                sa_payload = sa_payload_create_from_proposals_v2(proposal_list);
                proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy));
@@ -309,7 +385,7 @@ static bool build_payloads(private_ike_init_t *this, message_t *message)
 
        /* negotiate fragmentation if we are not rekeying */
        if (!this->old_sa &&
-                this->config->fragmentation(this->config) != FRAGMENTATION_NO)
+                ike_cfg->fragmentation(ike_cfg) != FRAGMENTATION_NO)
        {
                if (this->initiator ||
                        this->ike_sa->supports_extension(this->ike_sa,
@@ -352,10 +428,77 @@ static bool build_payloads(private_ike_init_t *this, message_t *message)
                                                                chunk_empty);
                }
        }
+       /* notify the peer if we want to use/support PPK */
+       if (!this->old_sa && send_use_ppk(this))
+       {
+               message->add_notify(message, FALSE, USE_PPK, chunk_empty);
+       }
        return TRUE;
 }
 
 /**
+ * Process the SA payload and select a proposal
+ */
+static void process_sa_payload(private_ike_init_t *this, message_t *message,
+                                                          sa_payload_t *sa_payload)
+{
+       ike_cfg_t *ike_cfg, *cfg, *alt_cfg = NULL;
+       enumerator_t *enumerator;
+       linked_list_t *proposal_list;
+       host_t *me, *other;
+       bool private, prefer_configured;
+
+       ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
+
+       proposal_list = sa_payload->get_proposals(sa_payload);
+       private = this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN);
+       prefer_configured = lib->settings->get_bool(lib->settings,
+                                                       "%s.prefer_configured_proposals", TRUE, lib->ns);
+
+       this->proposal = ike_cfg->select_proposal(ike_cfg, proposal_list, private,
+                                                                                         prefer_configured);
+       if (!this->proposal)
+       {
+               if (!this->initiator && !this->old_sa)
+               {
+                       me = message->get_destination(message);
+                       other = message->get_source(message);
+                       enumerator = charon->backends->create_ike_cfg_enumerator(
+                                                                                       charon->backends, me, other, IKEV2);
+                       while (enumerator->enumerate(enumerator, &cfg))
+                       {
+                               if (ike_cfg == cfg)
+                               {       /* already tried and failed */
+                                       continue;
+                               }
+                               DBG1(DBG_IKE, "no matching proposal found, trying alternative "
+                                        "config");
+                               this->proposal = cfg->select_proposal(cfg, proposal_list,
+                                                                                                       private, prefer_configured);
+                               if (this->proposal)
+                               {
+                                       alt_cfg = cfg->get_ref(cfg);
+                                       break;
+                               }
+                       }
+                       enumerator->destroy(enumerator);
+               }
+               if (alt_cfg)
+               {
+                       this->ike_sa->set_ike_cfg(this->ike_sa, alt_cfg);
+                       alt_cfg->destroy(alt_cfg);
+               }
+               else
+               {
+                       charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_IKE,
+                                                          proposal_list);
+               }
+       }
+       proposal_list->destroy_offset(proposal_list,
+                                                                 offsetof(proposal_t, destroy));
+}
+
+/**
  * Read payloads from message
  */
 static void process_payloads(private_ike_init_t *this, message_t *message)
@@ -371,22 +514,7 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
                {
                        case PLV2_SECURITY_ASSOCIATION:
                        {
-                               sa_payload_t *sa_payload = (sa_payload_t*)payload;
-                               linked_list_t *proposal_list;
-                               bool private;
-
-                               proposal_list = sa_payload->get_proposals(sa_payload);
-                               private = this->ike_sa->supports_extension(this->ike_sa,
-                                                                                                                  EXT_STRONGSWAN);
-                               this->proposal = this->config->select_proposal(this->config,
-                                                                                                               proposal_list, private);
-                               if (!this->proposal)
-                               {
-                                       charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_IKE,
-                                                                          proposal_list);
-                               }
-                               proposal_list->destroy_offset(proposal_list,
-                                                                                         offsetof(proposal_t, destroy));
+                               process_sa_payload(this, message, (sa_payload_t*)payload);
                                break;
                        }
                        case PLV2_KEY_EXCHANGE:
@@ -419,6 +547,13 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
                                                        handle_supported_hash_algorithms(this, notify);
                                                }
                                                break;
+                                       case USE_PPK:
+                                               if (!this->old_sa)
+                                               {
+                                                       this->ike_sa->enable_extension(this->ike_sa,
+                                                                                                                  EXT_PPK);
+                                               }
+                                               break;
                                        case REDIRECTED_FROM:
                                        {
                                                identification_t *gateway;
@@ -437,8 +572,11 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
                                                /* fall-through */
                                        }
                                        case REDIRECT_SUPPORTED:
-                                               this->ike_sa->enable_extension(this->ike_sa,
-                                                                                                          EXT_IKE_REDIRECTION);
+                                               if (!this->old_sa)
+                                               {
+                                                       this->ike_sa->enable_extension(this->ike_sa,
+                                                                                                                  EXT_IKE_REDIRECTION);
+                                               }
                                                break;
                                        default:
                                                /* other notifies are handled elsewhere */
@@ -452,6 +590,11 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
        }
        enumerator->destroy(enumerator);
 
+       if (this->proposal)
+       {
+               this->ike_sa->set_proposal(this->ike_sa, this->proposal);
+       }
+
        if (ke_payload && this->proposal &&
                this->proposal->has_dh_group(this->proposal, this->dh_group))
        {
@@ -460,7 +603,11 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
                        this->dh = this->keymat->keymat.create_dh(
                                                                &this->keymat->keymat, this->dh_group);
                }
-               if (this->dh)
+               else if (this->dh)
+               {
+                       this->dh_failed = this->dh->get_dh_group(this->dh) != this->dh_group;
+               }
+               if (this->dh && !this->dh_failed)
                {
                        this->dh_failed = !this->dh->set_other_public_value(this->dh,
                                                                ke_payload->get_key_exchange_data(ke_payload));
@@ -471,7 +618,10 @@ static void process_payloads(private_ike_init_t *this, message_t *message)
 METHOD(task_t, build_i, status_t,
        private_ike_init_t *this, message_t *message)
 {
-       this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
+       ike_cfg_t *ike_cfg;
+
+       ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
+
        DBG0(DBG_IKE, "initiating IKE_SA %s[%d] to %H",
                 this->ike_sa->get_name(this->ike_sa),
                 this->ike_sa->get_unique_id(this->ike_sa),
@@ -484,10 +634,30 @@ METHOD(task_t, build_i, status_t,
                return FAILED;
        }
 
-       /* if the DH group is set via use_dh_group(), we already have a DH object */
+       /* if we are retrying after an INVALID_KE_PAYLOAD we already have one */
        if (!this->dh)
        {
-               this->dh_group = this->config->get_dh_group(this->config);
+               if (this->old_sa && lib->settings->get_bool(lib->settings,
+                                                               "%s.prefer_previous_dh_group", TRUE, lib->ns))
+               {       /* reuse the DH group we used for the old IKE_SA when rekeying */
+                       proposal_t *proposal;
+                       uint16_t dh_group;
+
+                       proposal = this->old_sa->get_proposal(this->old_sa);
+                       if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
+                                                                               &dh_group, NULL))
+                       {
+                               this->dh_group = dh_group;
+                       }
+                       else
+                       {       /* this shouldn't happen, but let's be safe */
+                               this->dh_group = ike_cfg->get_dh_group(ike_cfg);
+                       }
+               }
+               else
+               {
+                       this->dh_group = ike_cfg->get_dh_group(ike_cfg);
+               }
                this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
                                                                                                  this->dh_group);
                if (!this->dh)
@@ -497,6 +667,18 @@ METHOD(task_t, build_i, status_t,
                        return FAILED;
                }
        }
+       else if (this->dh->get_dh_group(this->dh) != this->dh_group)
+       {       /* reset DH instance if group changed (INVALID_KE_PAYLOAD) */
+               this->dh->destroy(this->dh);
+               this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
+                                                                                                 this->dh_group);
+               if (!this->dh)
+               {
+                       DBG1(DBG_IKE, "requested DH group %N not supported",
+                                diffie_hellman_group_names, this->dh_group);
+                       return FAILED;
+               }
+       }
 
        /* generate nonce only when we are trying the first time */
        if (this->my_nonce.ptr == NULL)
@@ -533,7 +715,6 @@ METHOD(task_t, build_i, status_t,
 METHOD(task_t, process_r,  status_t,
        private_ike_init_t *this, message_t *message)
 {
-       this->config = this->ike_sa->get_ike_cfg(this->ike_sa);
        DBG0(DBG_IKE, "%H is initiating an IKE_SA", message->get_source(message));
        this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
 
@@ -605,14 +786,14 @@ METHOD(task_t, build_r, status_t,
        if (this->proposal == NULL ||
                this->other_nonce.len == 0 || this->my_nonce.len == 0)
        {
-               DBG1(DBG_IKE, "received proposals inacceptable");
+               DBG1(DBG_IKE, "received proposals unacceptable");
                message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
                return FAILED;
        }
-       this->ike_sa->set_proposal(this->ike_sa, this->proposal);
 
        /* check if we'd have to redirect the client */
-       if (this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
+       if (!this->old_sa &&
+               this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
                charon->redirect->redirect_on_init(charon->redirect, this->ike_sa,
                                                                                   &gateway))
        {
@@ -629,12 +810,12 @@ METHOD(task_t, build_r, status_t,
        if (this->dh == NULL ||
                !this->proposal->has_dh_group(this->proposal, this->dh_group))
        {
-               u_int16_t group;
+               uint16_t group;
 
                if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
                                                                                  &group, NULL))
                {
-                       DBG1(DBG_IKE, "DH group %N inacceptable, requesting %N",
+                       DBG1(DBG_IKE, "DH group %N unacceptable, requesting %N",
                                 diffie_hellman_group_names, this->dh_group,
                                 diffie_hellman_group_names, group);
                        this->dh_group = group;
@@ -645,6 +826,7 @@ METHOD(task_t, build_r, status_t,
                else
                {
                        DBG1(DBG_IKE, "no acceptable proposal found");
+                       message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
                }
                return FAILED;
        }
@@ -675,12 +857,14 @@ METHOD(task_t, build_r, status_t,
  */
 static void raise_alerts(private_ike_init_t *this, notify_type_t type)
 {
+       ike_cfg_t *ike_cfg;
        linked_list_t *list;
 
        switch (type)
        {
                case NO_PROPOSAL_CHOSEN:
-                       list = this->config->get_proposals(this->config);
+                       ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
+                       list = ike_cfg->get_proposals(ike_cfg);
                        charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_IKE, list);
                        list->destroy_offset(list, offsetof(proposal_t, destroy));
                        break;
@@ -689,6 +873,54 @@ static void raise_alerts(private_ike_init_t *this, notify_type_t type)
        }
 }
 
+METHOD(task_t, pre_process_i, status_t,
+       private_ike_init_t *this, message_t *message)
+{
+       enumerator_t *enumerator;
+       payload_t *payload;
+
+       /* check for erroneous notifies */
+       enumerator = message->create_payload_enumerator(message);
+       while (enumerator->enumerate(enumerator, &payload))
+       {
+               if (payload->get_type(payload) == PLV2_NOTIFY)
+               {
+                       notify_payload_t *notify = (notify_payload_t*)payload;
+                       notify_type_t type = notify->get_notify_type(notify);
+
+                       switch (type)
+                       {
+                               case REDIRECT:
+                               {
+                                       identification_t *gateway;
+                                       chunk_t data, nonce = chunk_empty;
+                                       status_t status = SUCCESS;
+
+                                       if (this->old_sa)
+                                       {
+                                               break;
+                                       }
+                                       data = notify->get_notification_data(notify);
+                                       gateway = redirect_data_parse(data, &nonce);
+                                       if (!gateway || !chunk_equals(nonce, this->my_nonce))
+                                       {
+                                               DBG1(DBG_IKE, "received invalid REDIRECT notify");
+                                               status = FAILED;
+                                       }
+                                       DESTROY_IF(gateway);
+                                       chunk_free(&nonce);
+                                       enumerator->destroy(enumerator);
+                                       return status;
+                               }
+                               default:
+                                       break;
+                       }
+               }
+       }
+       enumerator->destroy(enumerator);
+       return SUCCESS;
+}
+
 METHOD(task_t, process_i, status_t,
        private_ike_init_t *this, message_t *message)
 {
@@ -713,14 +945,14 @@ METHOD(task_t, process_i, status_t,
 
                                        bad_group = this->dh_group;
                                        data = notify->get_notification_data(notify);
-                                       this->dh_group = ntohs(*((u_int16_t*)data.ptr));
+                                       this->dh_group = ntohs(*((uint16_t*)data.ptr));
                                        DBG1(DBG_IKE, "peer didn't accept DH group %N, "
                                                 "it requested %N", diffie_hellman_group_names,
                                                 bad_group, diffie_hellman_group_names, this->dh_group);
 
                                        if (this->old_sa == NULL)
                                        {       /* reset the IKE_SA if we are not rekeying */
-                                               this->ike_sa->reset(this->ike_sa);
+                                               this->ike_sa->reset(this->ike_sa, FALSE);
                                        }
 
                                        enumerator->destroy(enumerator);
@@ -738,7 +970,7 @@ METHOD(task_t, process_i, status_t,
                                {
                                        chunk_free(&this->cookie);
                                        this->cookie = chunk_clone(notify->get_notification_data(notify));
-                                       this->ike_sa->reset(this->ike_sa);
+                                       this->ike_sa->reset(this->ike_sa, FALSE);
                                        enumerator->destroy(enumerator);
                                        DBG2(DBG_IKE, "received %N notify", notify_type_names, type);
                                        this->retry++;
@@ -750,20 +982,21 @@ METHOD(task_t, process_i, status_t,
                                        chunk_t data, nonce = chunk_empty;
                                        status_t status = FAILED;
 
-                                       data = notify->get_notification_data(notify);
-                                       gateway = redirect_data_parse(data, &nonce);
-                                       enumerator->destroy(enumerator);
-                                       if (!gateway || !chunk_equals(nonce, this->my_nonce))
+                                       if (this->old_sa)
                                        {
-                                               DBG1(DBG_IKE, "received invalid REDIRECT notify");
+                                               DBG1(DBG_IKE, "received REDIRECT notify during rekeying"
+                                                    ", ignored");
+                                               break;
                                        }
-                                       else if (this->ike_sa->handle_redirect(this->ike_sa,
-                                                                                                                       gateway))
+                                       data = notify->get_notification_data(notify);
+                                       gateway = redirect_data_parse(data, &nonce);
+                                       if (this->ike_sa->handle_redirect(this->ike_sa, gateway))
                                        {
                                                status = NEED_MORE;
                                        }
                                        DESTROY_IF(gateway);
                                        chunk_free(&nonce);
+                                       enumerator->destroy(enumerator);
                                        return status;
                                }
                                default:
@@ -794,7 +1027,6 @@ METHOD(task_t, process_i, status_t,
                DBG1(DBG_IKE, "peers proposal selection invalid");
                return FAILED;
        }
-       this->ike_sa->set_proposal(this->ike_sa, this->proposal);
 
        if (this->dh == NULL ||
                !this->proposal->has_dh_group(this->proposal, this->dh_group))
@@ -833,12 +1065,6 @@ METHOD(task_t, migrate, void,
        this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
        this->proposal = NULL;
        this->dh_failed = FALSE;
-       if (this->dh && this->dh->get_dh_group(this->dh) != this->dh_group)
-       {       /* reset DH value only if group changed (INVALID_KE_PAYLOAD) */
-               this->dh->destroy(this->dh);
-               this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
-                                                                                                 this->dh_group);
-       }
 }
 
 METHOD(task_t, destroy, void,
@@ -899,6 +1125,7 @@ ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa)
        {
                this->public.task.build = _build_i;
                this->public.task.process = _process_i;
+               this->public.task.pre_process = _pre_process_i;
        }
        else
        {