Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/tasks/ike_init.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2008-2019 Tobias Brunner
                      3:  * Copyright (C) 2005-2008 Martin Willi
                      4:  * Copyright (C) 2005 Jan Hutter
                      5:  * HSR Hochschule fuer Technik Rapperswil
                      6:  *
                      7:  * This program is free software; you can redistribute it and/or modify it
                      8:  * under the terms of the GNU General Public License as published by the
                      9:  * Free Software Foundation; either version 2 of the License, or (at your
                     10:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     11:  *
                     12:  * This program is distributed in the hope that it will be useful, but
                     13:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     14:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     15:  * for more details.
                     16:  */
                     17: 
                     18: #include "ike_init.h"
                     19: 
                     20: #include <string.h>
                     21: 
                     22: #include <daemon.h>
                     23: #include <bio/bio_reader.h>
                     24: #include <bio/bio_writer.h>
                     25: #include <sa/ikev2/keymat_v2.h>
                     26: #include <crypto/diffie_hellman.h>
                     27: #include <crypto/hashers/hash_algorithm_set.h>
                     28: #include <encoding/payloads/sa_payload.h>
                     29: #include <encoding/payloads/ke_payload.h>
                     30: #include <encoding/payloads/nonce_payload.h>
                     31: 
                     32: /** maximum retries to do with cookies/other dh groups */
                     33: #define MAX_RETRIES 5
                     34: 
                     35: typedef struct private_ike_init_t private_ike_init_t;
                     36: 
                     37: /**
                     38:  * Private members of a ike_init_t task.
                     39:  */
                     40: struct private_ike_init_t {
                     41: 
                     42:        /**
                     43:         * Public methods and task_t interface.
                     44:         */
                     45:        ike_init_t public;
                     46: 
                     47:        /**
                     48:         * Assigned IKE_SA.
                     49:         */
                     50:        ike_sa_t *ike_sa;
                     51: 
                     52:        /**
                     53:         * Are we the initiator?
                     54:         */
                     55:        bool initiator;
                     56: 
                     57:        /**
                     58:         * diffie hellman group to use
                     59:         */
                     60:        diffie_hellman_group_t dh_group;
                     61: 
                     62:        /**
                     63:         * diffie hellman key exchange
                     64:         */
                     65:        diffie_hellman_t *dh;
                     66: 
                     67:        /**
                     68:         * Applying DH public value failed?
                     69:         */
                     70:        bool dh_failed;
                     71: 
                     72:        /**
                     73:         * Keymat derivation (from IKE_SA)
                     74:         */
                     75:        keymat_v2_t *keymat;
                     76: 
                     77:        /**
                     78:         * nonce chosen by us
                     79:         */
                     80:        chunk_t my_nonce;
                     81: 
                     82:        /**
                     83:         * nonce chosen by peer
                     84:         */
                     85:        chunk_t other_nonce;
                     86: 
                     87:        /**
                     88:         * nonce generator
                     89:         */
                     90:        nonce_gen_t *nonceg;
                     91: 
                     92:        /**
                     93:         * Negotiated proposal used for IKE_SA
                     94:         */
                     95:        proposal_t *proposal;
                     96: 
                     97:        /**
                     98:         * Old IKE_SA which gets rekeyed
                     99:         */
                    100:        ike_sa_t *old_sa;
                    101: 
                    102:        /**
                    103:         * cookie received from responder
                    104:         */
                    105:        chunk_t cookie;
                    106: 
                    107:        /**
                    108:         * retries done so far after failure (cookie or bad dh group)
                    109:         */
                    110:        u_int retry;
                    111: 
                    112:        /**
                    113:         * Whether to use Signature Authentication as per RFC 7427
                    114:         */
                    115:        bool signature_authentication;
                    116: 
                    117:        /**
                    118:         * Whether to follow IKEv2 redirects as per RFC 5685
                    119:         */
                    120:        bool follow_redirects;
                    121: };
                    122: 
                    123: /**
                    124:  * Allocate our own nonce value
                    125:  */
                    126: static bool generate_nonce(private_ike_init_t *this)
                    127: {
                    128:        if (!this->nonceg)
                    129:        {
                    130:                DBG1(DBG_IKE, "no nonce generator found to create nonce");
                    131:                return FALSE;
                    132:        }
                    133:        if (!this->nonceg->allocate_nonce(this->nonceg, NONCE_SIZE,
                    134:                                                                          &this->my_nonce))
                    135:        {
                    136:                DBG1(DBG_IKE, "nonce allocation failed");
                    137:                return FALSE;
                    138:        }
                    139:        return TRUE;
                    140: }
                    141: 
                    142: /**
                    143:  * Notify the peer about the hash algorithms we support or expect,
                    144:  * as per RFC 7427
                    145:  */
                    146: static void send_supported_hash_algorithms(private_ike_init_t *this,
                    147:                                                                                   message_t *message)
                    148: {
                    149:        hash_algorithm_set_t *algos;
                    150:        enumerator_t *enumerator, *rounds;
                    151:        bio_writer_t *writer;
                    152:        hash_algorithm_t hash;
                    153:        peer_cfg_t *peer;
                    154:        auth_cfg_t *auth;
                    155:        auth_rule_t rule;
                    156:        signature_params_t *config;
                    157:        int written;
                    158:        size_t len = BUF_LEN;
                    159:        char buf[len];
                    160:        char *pos = buf;
                    161:        char *plugin_name;
                    162: 
                    163:        algos = hash_algorithm_set_create();
                    164:        peer = this->ike_sa->get_peer_cfg(this->ike_sa);
                    165:        if (peer)
                    166:        {
                    167:                rounds = peer->create_auth_cfg_enumerator(peer, FALSE);
                    168:                while (rounds->enumerate(rounds, &auth))
                    169:                {
                    170:                        enumerator = auth->create_enumerator(auth);
                    171:                        while (enumerator->enumerate(enumerator, &rule, &config))
                    172:                        {
                    173:                                if (rule == AUTH_RULE_IKE_SIGNATURE_SCHEME)
                    174:                                {
                    175:                                        hash = hasher_from_signature_scheme(config->scheme,
                    176:                                                                                                                config->params);
                    177:                                        if (hasher_algorithm_for_ikev2(hash))
                    178:                                        {
                    179:                                                algos->add(algos, hash);
                    180:                                        }
                    181:                                }
                    182:                        }
                    183:                        enumerator->destroy(enumerator);
                    184:                }
                    185:                rounds->destroy(rounds);
                    186:        }
                    187: 
                    188:        if (!algos->count(algos))
                    189:        {
                    190:                enumerator = lib->crypto->create_hasher_enumerator(lib->crypto);
                    191:                while (enumerator->enumerate(enumerator, &hash, &plugin_name))
                    192:                {
                    193:                        if (hasher_algorithm_for_ikev2(hash))
                    194:                        {
                    195:                                algos->add(algos, hash);
                    196:                        }
                    197:                }
                    198:                enumerator->destroy(enumerator);
                    199:        }
                    200: 
                    201:        if (algos->count(algos))
                    202:        {
                    203:                writer = bio_writer_create(0);
                    204:                enumerator = algos->create_enumerator(algos);
                    205:                while (enumerator->enumerate(enumerator, &hash))
                    206:                {
                    207:                        writer->write_uint16(writer, hash);
                    208: 
                    209:                        /* generate debug output */
                    210:                        written = snprintf(pos, len, " %N", hash_algorithm_short_names,
                    211:                                                           hash);
                    212:                        if (written > 0 && written < len)
                    213:                        {
                    214:                                pos += written;
                    215:                                len -= written;
                    216:                        }
                    217:                }
                    218:                enumerator->destroy(enumerator);
                    219:                message->add_notify(message, FALSE, SIGNATURE_HASH_ALGORITHMS,
                    220:                                                        writer->get_buf(writer));
                    221:                writer->destroy(writer);
                    222: 
                    223:                *pos = '\0';
                    224:                DBG2(DBG_CFG, "sending supported signature hash algorithms:%s", buf);
                    225:        }
                    226:        algos->destroy(algos);
                    227: }
                    228: 
                    229: /**
                    230:  * Store algorithms supported by other peer
                    231:  */
                    232: static void handle_supported_hash_algorithms(private_ike_init_t *this,
                    233:                                                                                         notify_payload_t *notify)
                    234: {
                    235:        bio_reader_t *reader;
                    236:        uint16_t algo;
                    237:        int written;
                    238:        size_t len = BUF_LEN;
                    239:        char buf[len];
                    240:        char *pos = buf;
                    241:        bool added = FALSE;
                    242: 
                    243:        reader = bio_reader_create(notify->get_notification_data(notify));
                    244:        while (reader->remaining(reader) >= 2 && reader->read_uint16(reader, &algo))
                    245:        {
                    246:                if (hasher_algorithm_for_ikev2(algo))
                    247:                {
                    248:                        this->keymat->add_hash_algorithm(this->keymat, algo);
                    249:                        added = TRUE;
                    250: 
                    251:                        /* generate debug output */
                    252:                        written = snprintf(pos, len, " %N", hash_algorithm_short_names,
                    253:                                                           algo);
                    254:                        if (written > 0 && written < len)
                    255:                        {
                    256:                                pos += written;
                    257:                                len -= written;
                    258:                        }
                    259:                }
                    260:        }
                    261:        reader->destroy(reader);
                    262: 
                    263:        *pos = '\0';
                    264:        DBG2(DBG_CFG, "received supported signature hash algorithms:%s", buf);
                    265: 
                    266:        if (added)
                    267:        {
                    268:                this->ike_sa->enable_extension(this->ike_sa, EXT_SIGNATURE_AUTH);
                    269:        }
                    270: }
                    271: 
                    272: /**
                    273:  * Check whether to send a USE_PPK notify
                    274:  */
                    275: static bool send_use_ppk(private_ike_init_t *this)
                    276: {
                    277:        peer_cfg_t *peer;
                    278:        enumerator_t *keys;
                    279:        shared_key_t *key;
                    280:        bool use_ppk = FALSE;
                    281: 
                    282:        if (this->initiator)
                    283:        {
                    284:                peer = this->ike_sa->get_peer_cfg(this->ike_sa);
                    285:                if (peer->get_ppk_id(peer))
                    286:                {
                    287:                        use_ppk = TRUE;
                    288:                }
                    289:        }
                    290:        else if (this->ike_sa->supports_extension(this->ike_sa, EXT_PPK))
                    291:        {
                    292:                /* check if we have at least one PPK available */
                    293:                keys = lib->credmgr->create_shared_enumerator(lib->credmgr, SHARED_PPK,
                    294:                                                                                                          NULL, NULL);
                    295:                if (keys->enumerate(keys, &key, NULL, NULL))
                    296:                {
                    297:                        use_ppk = TRUE;
                    298:                }
                    299:                keys->destroy(keys);
                    300:        }
                    301:        return use_ppk;
                    302: }
                    303: 
                    304: /**
                    305:  * build the payloads for the message
                    306:  */
                    307: static bool build_payloads(private_ike_init_t *this, message_t *message)
                    308: {
                    309:        sa_payload_t *sa_payload;
                    310:        ke_payload_t *ke_payload;
                    311:        nonce_payload_t *nonce_payload;
                    312:        linked_list_t *proposal_list, *other_dh_groups;
                    313:        ike_sa_id_t *id;
                    314:        proposal_t *proposal;
                    315:        enumerator_t *enumerator;
                    316:        ike_cfg_t *ike_cfg;
                    317: 
                    318:        id = this->ike_sa->get_id(this->ike_sa);
                    319: 
                    320:        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
                    321: 
                    322:        if (this->initiator)
                    323:        {
                    324:                proposal_list = ike_cfg->get_proposals(ike_cfg);
                    325:                other_dh_groups = linked_list_create();
                    326:                enumerator = proposal_list->create_enumerator(proposal_list);
                    327:                while (enumerator->enumerate(enumerator, (void**)&proposal))
                    328:                {
                    329:                        /* include SPI of new IKE_SA when we are rekeying */
                    330:                        if (this->old_sa)
                    331:                        {
                    332:                                proposal->set_spi(proposal, id->get_initiator_spi(id));
                    333:                        }
                    334:                        /* move the selected DH group to the front of the proposal */
                    335:                        if (!proposal->promote_dh_group(proposal, this->dh_group))
                    336:                        {       /* the proposal does not include the group, move to the back */
                    337:                                proposal_list->remove_at(proposal_list, enumerator);
                    338:                                other_dh_groups->insert_last(other_dh_groups, proposal);
                    339:                        }
                    340:                }
                    341:                enumerator->destroy(enumerator);
                    342:                /* add proposals that don't contain the selected group */
                    343:                enumerator = other_dh_groups->create_enumerator(other_dh_groups);
                    344:                while (enumerator->enumerate(enumerator, (void**)&proposal))
                    345:                {       /* no need to remove from the list as we destroy it anyway*/
                    346:                        proposal_list->insert_last(proposal_list, proposal);
                    347:                }
                    348:                enumerator->destroy(enumerator);
                    349:                other_dh_groups->destroy(other_dh_groups);
                    350: 
                    351:                sa_payload = sa_payload_create_from_proposals_v2(proposal_list);
                    352:                proposal_list->destroy_offset(proposal_list, offsetof(proposal_t, destroy));
                    353:        }
                    354:        else
                    355:        {
                    356:                if (this->old_sa)
                    357:                {
                    358:                        /* include SPI of new IKE_SA when we are rekeying */
                    359:                        this->proposal->set_spi(this->proposal, id->get_responder_spi(id));
                    360:                }
                    361:                sa_payload = sa_payload_create_from_proposal_v2(this->proposal);
                    362:        }
                    363:        message->add_payload(message, (payload_t*)sa_payload);
                    364: 
                    365:        ke_payload = ke_payload_create_from_diffie_hellman(PLV2_KEY_EXCHANGE,
                    366:                                                                                                           this->dh);
                    367:        if (!ke_payload)
                    368:        {
                    369:                DBG1(DBG_IKE, "creating KE payload failed");
                    370:                return FALSE;
                    371:        }
                    372:        nonce_payload = nonce_payload_create(PLV2_NONCE);
                    373:        nonce_payload->set_nonce(nonce_payload, this->my_nonce);
                    374: 
                    375:        if (this->old_sa)
                    376:        {       /* payload order differs if we are rekeying */
                    377:                message->add_payload(message, (payload_t*)nonce_payload);
                    378:                message->add_payload(message, (payload_t*)ke_payload);
                    379:        }
                    380:        else
                    381:        {
                    382:                message->add_payload(message, (payload_t*)ke_payload);
                    383:                message->add_payload(message, (payload_t*)nonce_payload);
                    384:        }
                    385: 
                    386:        /* negotiate fragmentation if we are not rekeying */
                    387:        if (!this->old_sa &&
                    388:                 ike_cfg->fragmentation(ike_cfg) != FRAGMENTATION_NO)
                    389:        {
                    390:                if (this->initiator ||
                    391:                        this->ike_sa->supports_extension(this->ike_sa,
                    392:                                                                                         EXT_IKE_FRAGMENTATION))
                    393:                {
                    394:                        message->add_notify(message, FALSE, FRAGMENTATION_SUPPORTED,
                    395:                                                                chunk_empty);
                    396:                }
                    397:        }
                    398:        /* submit supported hash algorithms for signature authentication */
                    399:        if (!this->old_sa && this->signature_authentication)
                    400:        {
                    401:                if (this->initiator ||
                    402:                        this->ike_sa->supports_extension(this->ike_sa,
                    403:                                                                                         EXT_SIGNATURE_AUTH))
                    404:                {
                    405:                        send_supported_hash_algorithms(this, message);
                    406:                }
                    407:        }
                    408:        /* notify other peer if we support redirection */
                    409:        if (!this->old_sa && this->initiator && this->follow_redirects)
                    410:        {
                    411:                identification_t *gateway;
                    412:                host_t *from;
                    413:                chunk_t data;
                    414: 
                    415:                from = this->ike_sa->get_redirected_from(this->ike_sa);
                    416:                if (from)
                    417:                {
                    418:                        gateway = identification_create_from_sockaddr(
                    419:                                                                                                        from->get_sockaddr(from));
                    420:                        data = redirect_data_create(gateway, chunk_empty);
                    421:                        message->add_notify(message, FALSE, REDIRECTED_FROM, data);
                    422:                        chunk_free(&data);
                    423:                        gateway->destroy(gateway);
                    424:                }
                    425:                else
                    426:                {
                    427:                        message->add_notify(message, FALSE, REDIRECT_SUPPORTED,
                    428:                                                                chunk_empty);
                    429:                }
                    430:        }
                    431:        /* notify the peer if we want to use/support PPK */
                    432:        if (!this->old_sa && send_use_ppk(this))
                    433:        {
                    434:                message->add_notify(message, FALSE, USE_PPK, chunk_empty);
                    435:        }
                    436:        /* notify the peer if we accept childless IKE_SAs */
                    437:        if (!this->old_sa && !this->initiator &&
                    438:                 ike_cfg->childless(ike_cfg) != CHILDLESS_NEVER)
                    439:        {
                    440:                message->add_notify(message, FALSE, CHILDLESS_IKEV2_SUPPORTED,
                    441:                                                        chunk_empty);
                    442:        }
                    443:        return TRUE;
                    444: }
                    445: 
                    446: /**
                    447:  * Process the SA payload and select a proposal
                    448:  */
                    449: static void process_sa_payload(private_ike_init_t *this, message_t *message,
                    450:                                                           sa_payload_t *sa_payload)
                    451: {
                    452:        ike_cfg_t *ike_cfg, *cfg, *alt_cfg = NULL;
                    453:        enumerator_t *enumerator;
                    454:        linked_list_t *proposal_list;
                    455:        host_t *me, *other;
                    456:        proposal_selection_flag_t flags = 0;
                    457: 
                    458:        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
                    459: 
                    460:        proposal_list = sa_payload->get_proposals(sa_payload);
                    461:        if (!this->ike_sa->supports_extension(this->ike_sa, EXT_STRONGSWAN) &&
                    462:                !lib->settings->get_bool(lib->settings, "%s.accept_private_algs",
                    463:                                                                 FALSE, lib->ns))
                    464:        {
                    465:                flags |= PROPOSAL_SKIP_PRIVATE;
                    466:        }
                    467:        if (!lib->settings->get_bool(lib->settings,
                    468:                                                        "%s.prefer_configured_proposals", TRUE, lib->ns))
                    469:        {
                    470:                flags |= PROPOSAL_PREFER_SUPPLIED;
                    471:        }
                    472:        this->proposal = ike_cfg->select_proposal(ike_cfg, proposal_list, flags);
                    473:        if (!this->proposal)
                    474:        {
                    475:                if (!this->initiator && !this->old_sa)
                    476:                {
                    477:                        me = message->get_destination(message);
                    478:                        other = message->get_source(message);
                    479:                        enumerator = charon->backends->create_ike_cfg_enumerator(
                    480:                                                                                        charon->backends, me, other, IKEV2);
                    481:                        while (enumerator->enumerate(enumerator, &cfg))
                    482:                        {
                    483:                                if (ike_cfg == cfg)
                    484:                                {       /* already tried and failed */
                    485:                                        continue;
                    486:                                }
                    487:                                DBG1(DBG_IKE, "no matching proposal found, trying alternative "
                    488:                                         "config");
                    489:                                this->proposal = cfg->select_proposal(cfg, proposal_list,
                    490:                                                                                                          flags);
                    491:                                if (this->proposal)
                    492:                                {
                    493:                                        alt_cfg = cfg->get_ref(cfg);
                    494:                                        break;
                    495:                                }
                    496:                        }
                    497:                        enumerator->destroy(enumerator);
                    498:                }
                    499:                if (alt_cfg)
                    500:                {
                    501:                        this->ike_sa->set_ike_cfg(this->ike_sa, alt_cfg);
                    502:                        alt_cfg->destroy(alt_cfg);
                    503:                }
                    504:                else
                    505:                {
                    506:                        charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_IKE,
                    507:                                                           proposal_list);
                    508:                }
                    509:        }
                    510:        proposal_list->destroy_offset(proposal_list,
                    511:                                                                  offsetof(proposal_t, destroy));
                    512: }
                    513: 
                    514: /**
                    515:  * Read payloads from message
                    516:  */
                    517: static void process_payloads(private_ike_init_t *this, message_t *message)
                    518: {
                    519:        enumerator_t *enumerator;
                    520:        payload_t *payload;
                    521:        ke_payload_t *ke_payload = NULL;
                    522: 
                    523:        enumerator = message->create_payload_enumerator(message);
                    524:        while (enumerator->enumerate(enumerator, &payload))
                    525:        {
                    526:                switch (payload->get_type(payload))
                    527:                {
                    528:                        case PLV2_SECURITY_ASSOCIATION:
                    529:                        {
                    530:                                process_sa_payload(this, message, (sa_payload_t*)payload);
                    531:                                break;
                    532:                        }
                    533:                        case PLV2_KEY_EXCHANGE:
                    534:                        {
                    535:                                ke_payload = (ke_payload_t*)payload;
                    536: 
                    537:                                this->dh_group = ke_payload->get_dh_group_number(ke_payload);
                    538:                                break;
                    539:                        }
                    540:                        case PLV2_NONCE:
                    541:                        {
                    542:                                nonce_payload_t *nonce_payload = (nonce_payload_t*)payload;
                    543: 
                    544:                                this->other_nonce = nonce_payload->get_nonce(nonce_payload);
                    545:                                break;
                    546:                        }
                    547:                        case PLV2_NOTIFY:
                    548:                        {
                    549:                                notify_payload_t *notify = (notify_payload_t*)payload;
                    550: 
                    551:                                switch (notify->get_notify_type(notify))
                    552:                                {
                    553:                                        case FRAGMENTATION_SUPPORTED:
                    554:                                                this->ike_sa->enable_extension(this->ike_sa,
                    555:                                                                                                           EXT_IKE_FRAGMENTATION);
                    556:                                                break;
                    557:                                        case SIGNATURE_HASH_ALGORITHMS:
                    558:                                                if (this->signature_authentication)
                    559:                                                {
                    560:                                                        handle_supported_hash_algorithms(this, notify);
                    561:                                                }
                    562:                                                break;
                    563:                                        case USE_PPK:
                    564:                                                if (!this->old_sa)
                    565:                                                {
                    566:                                                        this->ike_sa->enable_extension(this->ike_sa,
                    567:                                                                                                                   EXT_PPK);
                    568:                                                }
                    569:                                                break;
                    570:                                        case REDIRECTED_FROM:
                    571:                                        {
                    572:                                                identification_t *gateway;
                    573:                                                chunk_t data;
                    574: 
                    575:                                                data = notify->get_notification_data(notify);
                    576:                                                gateway = redirect_data_parse(data, NULL);
                    577:                                                if (!gateway)
                    578:                                                {
                    579:                                                        DBG1(DBG_IKE, "received invalid REDIRECTED_FROM "
                    580:                                                                 "notify, ignored");
                    581:                                                        break;
                    582:                                                }
                    583:                                                DBG1(DBG_IKE, "client got redirected from %Y", gateway);
                    584:                                                gateway->destroy(gateway);
                    585:                                                /* fall-through */
                    586:                                        }
                    587:                                        case REDIRECT_SUPPORTED:
                    588:                                                if (!this->old_sa)
                    589:                                                {
                    590:                                                        this->ike_sa->enable_extension(this->ike_sa,
                    591:                                                                                                                   EXT_IKE_REDIRECTION);
                    592:                                                }
                    593:                                                break;
                    594:                                        case CHILDLESS_IKEV2_SUPPORTED:
                    595:                                                if (this->initiator && !this->old_sa)
                    596:                                                {
                    597:                                                        this->ike_sa->enable_extension(this->ike_sa,
                    598:                                                                                                                   EXT_IKE_CHILDLESS);
                    599:                                                }
                    600:                                                break;
                    601:                                        default:
                    602:                                                /* other notifies are handled elsewhere */
                    603:                                                break;
                    604:                                }
                    605: 
                    606:                        }
                    607:                        default:
                    608:                                break;
                    609:                }
                    610:        }
                    611:        enumerator->destroy(enumerator);
                    612: 
                    613:        if (this->proposal)
                    614:        {
                    615:                this->ike_sa->set_proposal(this->ike_sa, this->proposal);
                    616:        }
                    617: 
                    618:        if (ke_payload && this->proposal &&
                    619:                this->proposal->has_dh_group(this->proposal, this->dh_group))
                    620:        {
                    621:                if (!this->initiator)
                    622:                {
                    623:                        this->dh = this->keymat->keymat.create_dh(
                    624:                                                                &this->keymat->keymat, this->dh_group);
                    625:                }
                    626:                else if (this->dh)
                    627:                {
                    628:                        this->dh_failed = this->dh->get_dh_group(this->dh) != this->dh_group;
                    629:                }
                    630:                if (this->dh && !this->dh_failed)
                    631:                {
                    632:                        this->dh_failed = !this->dh->set_other_public_value(this->dh,
                    633:                                                                ke_payload->get_key_exchange_data(ke_payload));
                    634:                }
                    635:        }
                    636: }
                    637: 
                    638: METHOD(task_t, build_i, status_t,
                    639:        private_ike_init_t *this, message_t *message)
                    640: {
                    641:        ike_cfg_t *ike_cfg;
                    642: 
                    643:        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
                    644: 
                    645:        DBG0(DBG_IKE, "initiating IKE_SA %s[%d] to %H",
                    646:                 this->ike_sa->get_name(this->ike_sa),
                    647:                 this->ike_sa->get_unique_id(this->ike_sa),
                    648:                 this->ike_sa->get_other_host(this->ike_sa));
                    649:        this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
                    650: 
                    651:        if (this->retry >= MAX_RETRIES)
                    652:        {
                    653:                DBG1(DBG_IKE, "giving up after %d retries", MAX_RETRIES);
                    654:                return FAILED;
                    655:        }
                    656: 
                    657:        /* if we are retrying after an INVALID_KE_PAYLOAD we already have one */
                    658:        if (!this->dh)
                    659:        {
                    660:                if (this->old_sa && lib->settings->get_bool(lib->settings,
                    661:                                                                "%s.prefer_previous_dh_group", TRUE, lib->ns))
                    662:                {       /* reuse the DH group we used for the old IKE_SA when rekeying */
                    663:                        proposal_t *proposal;
                    664:                        uint16_t dh_group;
                    665: 
                    666:                        proposal = this->old_sa->get_proposal(this->old_sa);
                    667:                        if (proposal->get_algorithm(proposal, DIFFIE_HELLMAN_GROUP,
                    668:                                                                                &dh_group, NULL))
                    669:                        {
                    670:                                this->dh_group = dh_group;
                    671:                        }
                    672:                        else
                    673:                        {       /* this shouldn't happen, but let's be safe */
                    674:                                this->dh_group = ike_cfg->get_dh_group(ike_cfg);
                    675:                        }
                    676:                }
                    677:                else
                    678:                {
                    679:                        this->dh_group = ike_cfg->get_dh_group(ike_cfg);
                    680:                }
                    681:                this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
                    682:                                                                                                  this->dh_group);
                    683:                if (!this->dh)
                    684:                {
                    685:                        DBG1(DBG_IKE, "configured DH group %N not supported",
                    686:                                diffie_hellman_group_names, this->dh_group);
                    687:                        return FAILED;
                    688:                }
                    689:        }
                    690:        else if (this->dh->get_dh_group(this->dh) != this->dh_group)
                    691:        {       /* reset DH instance if group changed (INVALID_KE_PAYLOAD) */
                    692:                this->dh->destroy(this->dh);
                    693:                this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
                    694:                                                                                                  this->dh_group);
                    695:                if (!this->dh)
                    696:                {
                    697:                        DBG1(DBG_IKE, "requested DH group %N not supported",
                    698:                                 diffie_hellman_group_names, this->dh_group);
                    699:                        return FAILED;
                    700:                }
                    701:        }
                    702: 
                    703:        /* generate nonce only when we are trying the first time */
                    704:        if (this->my_nonce.ptr == NULL)
                    705:        {
                    706:                if (!generate_nonce(this))
                    707:                {
                    708:                        return FAILED;
                    709:                }
                    710:        }
                    711: 
                    712:        if (this->cookie.ptr)
                    713:        {
                    714:                message->add_notify(message, FALSE, COOKIE, this->cookie);
                    715:        }
                    716: 
                    717:        if (!build_payloads(this, message))
                    718:        {
                    719:                return FAILED;
                    720:        }
                    721: 
                    722: #ifdef ME
                    723:        {
                    724:                chunk_t connect_id = this->ike_sa->get_connect_id(this->ike_sa);
                    725:                if (connect_id.ptr)
                    726:                {
                    727:                        message->add_notify(message, FALSE, ME_CONNECTID, connect_id);
                    728:                }
                    729:        }
                    730: #endif /* ME */
                    731: 
                    732:        return NEED_MORE;
                    733: }
                    734: 
                    735: METHOD(task_t, process_r,  status_t,
                    736:        private_ike_init_t *this, message_t *message)
                    737: {
                    738:        DBG0(DBG_IKE, "%H is initiating an IKE_SA", message->get_source(message));
                    739:        this->ike_sa->set_state(this->ike_sa, IKE_CONNECTING);
                    740: 
                    741:        if (!generate_nonce(this))
                    742:        {
                    743:                return FAILED;
                    744:        }
                    745: 
                    746: #ifdef ME
                    747:        {
                    748:                notify_payload_t *notify = message->get_notify(message, ME_CONNECTID);
                    749:                if (notify)
                    750:                {
                    751:                        chunk_t connect_id = notify->get_notification_data(notify);
                    752:                        DBG2(DBG_IKE, "received ME_CONNECTID %#B", &connect_id);
                    753:                        charon->connect_manager->stop_checks(charon->connect_manager,
                    754:                                                                                                 connect_id);
                    755:                }
                    756:        }
                    757: #endif /* ME */
                    758: 
                    759:        process_payloads(this, message);
                    760: 
                    761:        return NEED_MORE;
                    762: }
                    763: 
                    764: /**
                    765:  * Derive the keymat for the IKE_SA
                    766:  */
                    767: static bool derive_keys(private_ike_init_t *this,
                    768:                                                chunk_t nonce_i, chunk_t nonce_r)
                    769: {
                    770:        keymat_v2_t *old_keymat;
                    771:        pseudo_random_function_t prf_alg = PRF_UNDEFINED;
                    772:        chunk_t skd = chunk_empty;
                    773:        ike_sa_id_t *id;
                    774: 
                    775:        id = this->ike_sa->get_id(this->ike_sa);
                    776:        if (this->old_sa)
                    777:        {
                    778:                /* rekeying: Include old SKd, use old PRF, apply SPI */
                    779:                old_keymat = (keymat_v2_t*)this->old_sa->get_keymat(this->old_sa);
                    780:                prf_alg = old_keymat->get_skd(old_keymat, &skd);
                    781:                if (this->initiator)
                    782:                {
                    783:                        id->set_responder_spi(id, this->proposal->get_spi(this->proposal));
                    784:                }
                    785:                else
                    786:                {
                    787:                        id->set_initiator_spi(id, this->proposal->get_spi(this->proposal));
                    788:                }
                    789:        }
                    790:        if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh,
                    791:                                                                           nonce_i, nonce_r, id, prf_alg, skd))
                    792:        {
                    793:                return FALSE;
                    794:        }
                    795:        charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, chunk_empty,
                    796:                                                  nonce_i, nonce_r, this->old_sa, NULL, AUTH_NONE);
                    797:        return TRUE;
                    798: }
                    799: 
                    800: METHOD(task_t, build_r, status_t,
                    801:        private_ike_init_t *this, message_t *message)
                    802: {
                    803:        identification_t *gateway;
                    804: 
                    805:        /* check if we have everything we need */
                    806:        if (this->proposal == NULL ||
                    807:                this->other_nonce.len == 0 || this->my_nonce.len == 0)
                    808:        {
                    809:                DBG1(DBG_IKE, "received proposals unacceptable");
                    810:                message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
                    811:                return FAILED;
                    812:        }
                    813: 
                    814:        /* check if we'd have to redirect the client */
                    815:        if (!this->old_sa &&
                    816:                this->ike_sa->supports_extension(this->ike_sa, EXT_IKE_REDIRECTION) &&
                    817:                charon->redirect->redirect_on_init(charon->redirect, this->ike_sa,
                    818:                                                                                   &gateway))
                    819:        {
                    820:                chunk_t data;
                    821: 
                    822:                DBG1(DBG_IKE, "redirecting peer to %Y", gateway);
                    823:                data = redirect_data_create(gateway, this->other_nonce);
                    824:                message->add_notify(message, TRUE, REDIRECT, data);
                    825:                gateway->destroy(gateway);
                    826:                chunk_free(&data);
                    827:                return FAILED;
                    828:        }
                    829: 
                    830:        if (this->dh == NULL ||
                    831:                !this->proposal->has_dh_group(this->proposal, this->dh_group))
                    832:        {
                    833:                uint16_t group;
                    834: 
                    835:                if (this->proposal->get_algorithm(this->proposal, DIFFIE_HELLMAN_GROUP,
                    836:                                                                                  &group, NULL))
                    837:                {
                    838:                        DBG1(DBG_IKE, "DH group %N unacceptable, requesting %N",
                    839:                                 diffie_hellman_group_names, this->dh_group,
                    840:                                 diffie_hellman_group_names, group);
                    841:                        this->dh_group = group;
                    842:                        group = htons(group);
                    843:                        message->add_notify(message, FALSE, INVALID_KE_PAYLOAD,
                    844:                                                                chunk_from_thing(group));
                    845:                }
                    846:                else
                    847:                {
                    848:                        DBG1(DBG_IKE, "no acceptable proposal found");
                    849:                        message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
                    850:                }
                    851:                return FAILED;
                    852:        }
                    853: 
                    854:        if (this->dh_failed)
                    855:        {
                    856:                DBG1(DBG_IKE, "applying DH public value failed");
                    857:                message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
                    858:                return FAILED;
                    859:        }
                    860: 
                    861:        if (!derive_keys(this, this->other_nonce, this->my_nonce))
                    862:        {
                    863:                DBG1(DBG_IKE, "key derivation failed");
                    864:                message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
                    865:                return FAILED;
                    866:        }
                    867:        if (!build_payloads(this, message))
                    868:        {
                    869:                message->add_notify(message, TRUE, NO_PROPOSAL_CHOSEN, chunk_empty);
                    870:                return FAILED;
                    871:        }
                    872:        return SUCCESS;
                    873: }
                    874: 
                    875: /**
                    876:  * Raise alerts for received notify errors
                    877:  */
                    878: static void raise_alerts(private_ike_init_t *this, notify_type_t type)
                    879: {
                    880:        ike_cfg_t *ike_cfg;
                    881:        linked_list_t *list;
                    882: 
                    883:        switch (type)
                    884:        {
                    885:                case NO_PROPOSAL_CHOSEN:
                    886:                        ike_cfg = this->ike_sa->get_ike_cfg(this->ike_sa);
                    887:                        list = ike_cfg->get_proposals(ike_cfg);
                    888:                        charon->bus->alert(charon->bus, ALERT_PROPOSAL_MISMATCH_IKE, list);
                    889:                        list->destroy_offset(list, offsetof(proposal_t, destroy));
                    890:                        break;
                    891:                default:
                    892:                        break;
                    893:        }
                    894: }
                    895: 
                    896: METHOD(task_t, pre_process_i, status_t,
                    897:        private_ike_init_t *this, message_t *message)
                    898: {
                    899:        enumerator_t *enumerator;
                    900:        payload_t *payload;
                    901: 
                    902:        /* check for erroneous notifies */
                    903:        enumerator = message->create_payload_enumerator(message);
                    904:        while (enumerator->enumerate(enumerator, &payload))
                    905:        {
                    906:                if (payload->get_type(payload) == PLV2_NOTIFY)
                    907:                {
                    908:                        notify_payload_t *notify = (notify_payload_t*)payload;
                    909:                        notify_type_t type = notify->get_notify_type(notify);
                    910: 
                    911:                        switch (type)
                    912:                        {
                    913:                                case COOKIE:
                    914:                                {
                    915:                                        chunk_t cookie;
                    916: 
                    917:                                        cookie = notify->get_notification_data(notify);
                    918:                                        if (chunk_equals(cookie, this->cookie))
                    919:                                        {
                    920:                                                DBG1(DBG_IKE, "ignore response with duplicate COOKIE "
                    921:                                                         "notify");
                    922:                                                enumerator->destroy(enumerator);
                    923:                                                return FAILED;
                    924:                                        }
                    925:                                        break;
                    926:                                }
                    927:                                case REDIRECT:
                    928:                                {
                    929:                                        identification_t *gateway;
                    930:                                        chunk_t data, nonce = chunk_empty;
                    931:                                        status_t status = SUCCESS;
                    932: 
                    933:                                        if (this->old_sa)
                    934:                                        {
                    935:                                                break;
                    936:                                        }
                    937:                                        data = notify->get_notification_data(notify);
                    938:                                        gateway = redirect_data_parse(data, &nonce);
                    939:                                        if (!gateway || !chunk_equals(nonce, this->my_nonce))
                    940:                                        {
                    941:                                                DBG1(DBG_IKE, "received invalid REDIRECT notify");
                    942:                                                status = FAILED;
                    943:                                        }
                    944:                                        DESTROY_IF(gateway);
                    945:                                        chunk_free(&nonce);
                    946:                                        enumerator->destroy(enumerator);
                    947:                                        return status;
                    948:                                }
                    949:                                default:
                    950:                                        break;
                    951:                        }
                    952:                }
                    953:        }
                    954:        enumerator->destroy(enumerator);
                    955:        return SUCCESS;
                    956: }
                    957: 
                    958: METHOD(task_t, process_i, status_t,
                    959:        private_ike_init_t *this, message_t *message)
                    960: {
                    961:        enumerator_t *enumerator;
                    962:        payload_t *payload;
                    963: 
                    964:        /* check for erroneous notifies */
                    965:        enumerator = message->create_payload_enumerator(message);
                    966:        while (enumerator->enumerate(enumerator, &payload))
                    967:        {
                    968:                if (payload->get_type(payload) == PLV2_NOTIFY)
                    969:                {
                    970:                        notify_payload_t *notify = (notify_payload_t*)payload;
                    971:                        notify_type_t type = notify->get_notify_type(notify);
                    972: 
                    973:                        switch (type)
                    974:                        {
                    975:                                case INVALID_KE_PAYLOAD:
                    976:                                {
                    977:                                        chunk_t data;
                    978:                                        diffie_hellman_group_t bad_group;
                    979: 
                    980:                                        bad_group = this->dh_group;
                    981:                                        data = notify->get_notification_data(notify);
                    982:                                        this->dh_group = ntohs(*((uint16_t*)data.ptr));
                    983:                                        DBG1(DBG_IKE, "peer didn't accept DH group %N, "
                    984:                                                 "it requested %N", diffie_hellman_group_names,
                    985:                                                 bad_group, diffie_hellman_group_names, this->dh_group);
                    986: 
                    987:                                        if (this->old_sa == NULL)
                    988:                                        {       /* reset the IKE_SA if we are not rekeying */
                    989:                                                this->ike_sa->reset(this->ike_sa, FALSE);
                    990:                                        }
                    991: 
                    992:                                        enumerator->destroy(enumerator);
                    993:                                        this->retry++;
                    994:                                        return NEED_MORE;
                    995:                                }
                    996:                                case NAT_DETECTION_SOURCE_IP:
                    997:                                case NAT_DETECTION_DESTINATION_IP:
                    998:                                        /* skip, handled in ike_natd_t */
                    999:                                        break;
                   1000:                                case MULTIPLE_AUTH_SUPPORTED:
                   1001:                                        /* handled in ike_auth_t */
                   1002:                                        break;
                   1003:                                case COOKIE:
                   1004:                                {
                   1005:                                        chunk_free(&this->cookie);
                   1006:                                        this->cookie = chunk_clone(notify->get_notification_data(notify));
                   1007:                                        this->ike_sa->reset(this->ike_sa, FALSE);
                   1008:                                        enumerator->destroy(enumerator);
                   1009:                                        DBG2(DBG_IKE, "received %N notify", notify_type_names, type);
                   1010:                                        this->retry++;
                   1011:                                        return NEED_MORE;
                   1012:                                }
                   1013:                                case REDIRECT:
                   1014:                                {
                   1015:                                        identification_t *gateway;
                   1016:                                        chunk_t data, nonce = chunk_empty;
                   1017:                                        status_t status = FAILED;
                   1018: 
                   1019:                                        if (this->old_sa)
                   1020:                                        {
                   1021:                                                DBG1(DBG_IKE, "received REDIRECT notify during rekeying"
                   1022:                                                     ", ignored");
                   1023:                                                break;
                   1024:                                        }
                   1025:                                        data = notify->get_notification_data(notify);
                   1026:                                        gateway = redirect_data_parse(data, &nonce);
                   1027:                                        if (this->ike_sa->handle_redirect(this->ike_sa, gateway))
                   1028:                                        {
                   1029:                                                status = NEED_MORE;
                   1030:                                        }
                   1031:                                        DESTROY_IF(gateway);
                   1032:                                        chunk_free(&nonce);
                   1033:                                        enumerator->destroy(enumerator);
                   1034:                                        return status;
                   1035:                                }
                   1036:                                default:
                   1037:                                {
                   1038:                                        if (type <= 16383)
                   1039:                                        {
                   1040:                                                DBG1(DBG_IKE, "received %N notify error",
                   1041:                                                         notify_type_names, type);
                   1042:                                                enumerator->destroy(enumerator);
                   1043:                                                raise_alerts(this, type);
                   1044:                                                return FAILED;
                   1045:                                        }
                   1046:                                        DBG2(DBG_IKE, "received %N notify",
                   1047:                                                notify_type_names, type);
                   1048:                                        break;
                   1049:                                }
                   1050:                        }
                   1051:                }
                   1052:        }
                   1053:        enumerator->destroy(enumerator);
                   1054: 
                   1055:        process_payloads(this, message);
                   1056: 
                   1057:        /* check if we have everything */
                   1058:        if (this->proposal == NULL ||
                   1059:                this->other_nonce.len == 0 || this->my_nonce.len == 0)
                   1060:        {
                   1061:                DBG1(DBG_IKE, "peers proposal selection invalid");
                   1062:                return FAILED;
                   1063:        }
                   1064: 
                   1065:        if (this->dh == NULL ||
                   1066:                !this->proposal->has_dh_group(this->proposal, this->dh_group))
                   1067:        {
                   1068:                DBG1(DBG_IKE, "peer DH group selection invalid");
                   1069:                return FAILED;
                   1070:        }
                   1071: 
                   1072:        if (this->dh_failed)
                   1073:        {
                   1074:                DBG1(DBG_IKE, "applying DH public value failed");
                   1075:                return FAILED;
                   1076:        }
                   1077: 
                   1078:        if (!derive_keys(this, this->my_nonce, this->other_nonce))
                   1079:        {
                   1080:                DBG1(DBG_IKE, "key derivation failed");
                   1081:                return FAILED;
                   1082:        }
                   1083:        return SUCCESS;
                   1084: }
                   1085: 
                   1086: METHOD(task_t, get_type, task_type_t,
                   1087:        private_ike_init_t *this)
                   1088: {
                   1089:        return TASK_IKE_INIT;
                   1090: }
                   1091: 
                   1092: METHOD(task_t, migrate, void,
                   1093:        private_ike_init_t *this, ike_sa_t *ike_sa)
                   1094: {
                   1095:        DESTROY_IF(this->proposal);
                   1096:        chunk_free(&this->other_nonce);
                   1097: 
                   1098:        this->ike_sa = ike_sa;
                   1099:        this->keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
                   1100:        this->proposal = NULL;
                   1101:        this->dh_failed = FALSE;
                   1102: }
                   1103: 
                   1104: METHOD(task_t, destroy, void,
                   1105:        private_ike_init_t *this)
                   1106: {
                   1107:        DESTROY_IF(this->dh);
                   1108:        DESTROY_IF(this->proposal);
                   1109:        DESTROY_IF(this->nonceg);
                   1110:        chunk_free(&this->my_nonce);
                   1111:        chunk_free(&this->other_nonce);
                   1112:        chunk_free(&this->cookie);
                   1113:        free(this);
                   1114: }
                   1115: 
                   1116: METHOD(ike_init_t, get_lower_nonce, chunk_t,
                   1117:        private_ike_init_t *this)
                   1118: {
                   1119:        if (memcmp(this->my_nonce.ptr, this->other_nonce.ptr,
                   1120:                           min(this->my_nonce.len, this->other_nonce.len)) < 0)
                   1121:        {
                   1122:                return this->my_nonce;
                   1123:        }
                   1124:        else
                   1125:        {
                   1126:                return this->other_nonce;
                   1127:        }
                   1128: }
                   1129: 
                   1130: /*
                   1131:  * Described in header.
                   1132:  */
                   1133: ike_init_t *ike_init_create(ike_sa_t *ike_sa, bool initiator, ike_sa_t *old_sa)
                   1134: {
                   1135:        private_ike_init_t *this;
                   1136: 
                   1137:        INIT(this,
                   1138:                .public = {
                   1139:                        .task = {
                   1140:                                .get_type = _get_type,
                   1141:                                .migrate = _migrate,
                   1142:                                .destroy = _destroy,
                   1143:                        },
                   1144:                        .get_lower_nonce = _get_lower_nonce,
                   1145:                },
                   1146:                .ike_sa = ike_sa,
                   1147:                .initiator = initiator,
                   1148:                .dh_group = MODP_NONE,
                   1149:                .keymat = (keymat_v2_t*)ike_sa->get_keymat(ike_sa),
                   1150:                .old_sa = old_sa,
                   1151:                .signature_authentication = lib->settings->get_bool(lib->settings,
                   1152:                                                                "%s.signature_authentication", TRUE, lib->ns),
                   1153:                .follow_redirects = lib->settings->get_bool(lib->settings,
                   1154:                                                                "%s.follow_redirects", TRUE, lib->ns),
                   1155:        );
                   1156:        this->nonceg = this->keymat->keymat.create_nonce_gen(&this->keymat->keymat);
                   1157: 
                   1158:        if (initiator)
                   1159:        {
                   1160:                this->public.task.build = _build_i;
                   1161:                this->public.task.process = _process_i;
                   1162:                this->public.task.pre_process = _pre_process_i;
                   1163:        }
                   1164:        else
                   1165:        {
                   1166:                this->public.task.build = _build_r;
                   1167:                this->public.task.process = _process_r;
                   1168:        }
                   1169:        return &this->public;
                   1170: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>