Annotation of embedaddon/strongswan/src/libcharon/plugins/eap_aka/eap_aka_server.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2006-2009 Martin Willi
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * This program is free software; you can redistribute it and/or modify it
                      6:  * under the terms of the GNU General Public License as published by the
                      7:  * Free Software Foundation; either version 2 of the License, or (at your
                      8:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                      9:  *
                     10:  * This program is distributed in the hope that it will be useful, but
                     11:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     12:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     13:  * for more details.
                     14:  */
                     15: 
                     16: #include "eap_aka_server.h"
                     17: 
                     18: #include <daemon.h>
                     19: #include <library.h>
                     20: 
                     21: #include <simaka_message.h>
                     22: #include <simaka_crypto.h>
                     23: #include <simaka_manager.h>
                     24: 
                     25: /** length of the AT_NONCE_S value */
                     26: #define NONCE_LEN 16
                     27: 
                     28: typedef struct private_eap_aka_server_t private_eap_aka_server_t;
                     29: 
                     30: /**
                     31:  * Private data of an eap_aka_server_t object.
                     32:  */
                     33: struct private_eap_aka_server_t {
                     34: 
                     35:        /**
                     36:         * Public authenticator_t interface.
                     37:         */
                     38:        eap_aka_server_t public;
                     39: 
                     40:        /**
                     41:         * AKA backend manager
                     42:         */
                     43:        simaka_manager_t *mgr;
                     44: 
                     45:        /**
                     46:         * EAP-AKA crypto helper
                     47:         */
                     48:        simaka_crypto_t *crypto;
                     49: 
                     50:        /**
                     51:         * permanent ID of the peer
                     52:         */
                     53:        identification_t *permanent;
                     54: 
                     55:        /**
                     56:         * pseudonym ID of peer
                     57:         */
                     58:        identification_t *pseudonym;
                     59: 
                     60:        /**
                     61:         * reauthentication ID of peer
                     62:         */
                     63:        identification_t *reauth;
                     64: 
                     65:        /**
                     66:         * EAP message identifier
                     67:         */
                     68:        uint8_t identifier;
                     69: 
                     70:        /**
                     71:         * Expected Result XRES
                     72:         */
                     73:        chunk_t xres;
                     74: 
                     75:        /**
                     76:         * Random value RAND
                     77:         */
                     78:        chunk_t rand;
                     79: 
                     80:        /**
                     81:         * MSK
                     82:         */
                     83:        chunk_t msk;
                     84: 
                     85:        /**
                     86:         * Nonce value used in AT_NONCE_S
                     87:         */
                     88:        chunk_t nonce;
                     89: 
                     90:        /**
                     91:         * Counter value negotiated, network order
                     92:         */
                     93:        chunk_t counter;
                     94: 
                     95:        /**
                     96:         * Do we request fast reauthentication?
                     97:         */
                     98:        bool use_reauth;
                     99: 
                    100:        /**
                    101:         * Do we request pseudonym identities?
                    102:         */
                    103:        bool use_pseudonym;
                    104: 
                    105:        /**
                    106:         * Do we request permanent identities?
                    107:         */
                    108:        bool use_permanent;
                    109: 
                    110:        /**
                    111:         * EAP-AKA message we have initiated
                    112:         */
                    113:        simaka_subtype_t pending;
                    114: 
                    115:        /**
                    116:         * Did the client send a synchronize request?
                    117:         */
                    118:        bool synchronized;
                    119: };
                    120: 
                    121: /**
                    122:  * Generate a payload from a message, destroy message
                    123:  */
                    124: static bool generate_payload(simaka_message_t *message, chunk_t data,
                    125:                                                         eap_payload_t **out)
                    126: {
                    127:        chunk_t chunk;
                    128:        bool ok;
                    129: 
                    130:        ok = message->generate(message, data, &chunk);
                    131:        if (ok)
                    132:        {
                    133:                *out = eap_payload_create_data_own(chunk);
                    134:        }
                    135:        message->destroy(message);
                    136:        return ok;
                    137: }
                    138: 
                    139: /**
                    140:  * Create EAP-AKA/Request/Identity message
                    141:  */
                    142: static status_t identity(private_eap_aka_server_t *this, eap_payload_t **out)
                    143: {
                    144:        simaka_message_t *message;
                    145: 
                    146:        message = simaka_message_create(TRUE, this->identifier++, EAP_AKA,
                    147:                                                                        AKA_IDENTITY, this->crypto);
                    148:        if (this->use_reauth)
                    149:        {
                    150:                message->add_attribute(message, AT_ANY_ID_REQ, chunk_empty);
                    151:        }
                    152:        else if (this->use_pseudonym)
                    153:        {
                    154:                message->add_attribute(message, AT_FULLAUTH_ID_REQ, chunk_empty);
                    155:        }
                    156:        else if (this->use_permanent)
                    157:        {
                    158:                message->add_attribute(message, AT_PERMANENT_ID_REQ, chunk_empty);
                    159:        }
                    160:        if (!generate_payload(message, chunk_empty, out))
                    161:        {
                    162:                return FAILED;
                    163:        }
                    164:        this->pending = AKA_IDENTITY;
                    165:        return NEED_MORE;
                    166: }
                    167: 
                    168: /**
                    169:  * Create EAP-AKA/Request/Challenge message
                    170:  */
                    171: static status_t challenge(private_eap_aka_server_t *this, eap_payload_t **out)
                    172: {
                    173:        simaka_message_t *message;
                    174:        char rand[AKA_RAND_LEN], xres[AKA_RES_MAX];
                    175:        char ck[AKA_CK_LEN], ik[AKA_IK_LEN], autn[AKA_AUTN_LEN];
                    176:        int xres_len;
                    177:        chunk_t data, mk;
                    178:        identification_t *id;
                    179: 
                    180:        if (!this->mgr->provider_get_quintuplet(this->mgr, this->permanent,
                    181:                                                                                rand, xres, &xres_len, ck, ik, autn))
                    182:        {
                    183:                if (this->use_pseudonym)
                    184:                {
                    185:                        /* probably received a pseudonym/reauth id we couldn't map */
                    186:                        DBG1(DBG_IKE, "failed to map pseudonym/reauth identity '%Y', "
                    187:                                 "fallback to permanent identity request", this->permanent);
                    188:                        this->use_pseudonym = FALSE;
                    189:                        DESTROY_IF(this->pseudonym);
                    190:                        this->pseudonym = NULL;
                    191:                        return identity(this, out);
                    192:                }
                    193:                return FAILED;
                    194:        }
                    195:        id = this->permanent;
                    196:        if (this->pseudonym)
                    197:        {
                    198:                id = this->pseudonym;
                    199:        }
                    200:        data = chunk_cata("cc", chunk_create(ik, AKA_IK_LEN),
                    201:                                          chunk_create(ck, AKA_CK_LEN));
                    202:        chunk_clear(&this->msk);
                    203:        if (!this->crypto->derive_keys_full(this->crypto, id, data, &mk, &this->msk))
                    204:        {
                    205:                return FAILED;
                    206:        }
                    207:        this->rand = chunk_clone(chunk_create(rand, AKA_RAND_LEN));
                    208:        this->xres = chunk_clone(chunk_create(xres, xres_len));
                    209: 
                    210:        message = simaka_message_create(TRUE, this->identifier++, EAP_AKA,
                    211:                                                                        AKA_CHALLENGE, this->crypto);
                    212:        message->add_attribute(message, AT_RAND, this->rand);
                    213:        message->add_attribute(message, AT_AUTN, chunk_create(autn, AKA_AUTN_LEN));
                    214:        id = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk.ptr);
                    215:        free(mk.ptr);
                    216:        if (id)
                    217:        {
                    218:                message->add_attribute(message, AT_NEXT_REAUTH_ID,
                    219:                                                           id->get_encoding(id));
                    220:                id->destroy(id);
                    221:        }
                    222:        id = this->mgr->provider_gen_pseudonym(this->mgr, this->permanent);
                    223:        if (id)
                    224:        {
                    225:                message->add_attribute(message, AT_NEXT_PSEUDONYM,
                    226:                                                           id->get_encoding(id));
                    227:                id->destroy(id);
                    228:        }
                    229:        if (!generate_payload(message, chunk_empty, out))
                    230:        {
                    231:                return FAILED;
                    232:        }
                    233:        this->pending = AKA_CHALLENGE;
                    234:        return NEED_MORE;
                    235: }
                    236: 
                    237: /**
                    238:  * Initiate  EAP-AKA/Request/Re-authentication message
                    239:  */
                    240: static status_t reauthenticate(private_eap_aka_server_t *this,
                    241:                                                           char mk[HASH_SIZE_SHA1], uint16_t counter,
                    242:                                                           eap_payload_t **out)
                    243: {
                    244:        simaka_message_t *message;
                    245:        identification_t *next;
                    246:        chunk_t mkc;
                    247:        rng_t *rng;
                    248: 
                    249:        DBG1(DBG_IKE, "initiating EAP-AKA reauthentication");
                    250: 
                    251:        rng = this->crypto->get_rng(this->crypto);
                    252:        if (!rng->allocate_bytes(rng, NONCE_LEN, &this->nonce))
                    253:        {
                    254:                return FAILED;
                    255:        }
                    256: 
                    257:        mkc = chunk_create(mk, HASH_SIZE_SHA1);
                    258:        counter = htons(counter);
                    259:        this->counter = chunk_clone(chunk_create((char*)&counter, sizeof(counter)));
                    260: 
                    261:        if (!this->crypto->derive_keys_reauth(this->crypto, mkc) ||
                    262:                !this->crypto->derive_keys_reauth_msk(this->crypto,
                    263:                                        this->reauth, this->counter, this->nonce, mkc, &this->msk))
                    264:        {
                    265:                return FAILED;
                    266:        }
                    267: 
                    268:        message = simaka_message_create(TRUE, this->identifier++, EAP_AKA,
                    269:                                                                        AKA_REAUTHENTICATION, this->crypto);
                    270:        message->add_attribute(message, AT_COUNTER, this->counter);
                    271:        message->add_attribute(message, AT_NONCE_S, this->nonce);
                    272:        next = this->mgr->provider_gen_reauth(this->mgr, this->permanent, mk);
                    273:        if (next)
                    274:        {
                    275:                message->add_attribute(message, AT_NEXT_REAUTH_ID,
                    276:                                                           next->get_encoding(next));
                    277:                next->destroy(next);
                    278:        }
                    279:        if (!generate_payload(message, chunk_empty, out))
                    280:        {
                    281:                return FAILED;
                    282:        }
                    283:        this->pending = SIM_REAUTHENTICATION;
                    284:        return NEED_MORE;
                    285: }
                    286: 
                    287: METHOD(eap_method_t, initiate, status_t,
                    288:        private_eap_aka_server_t *this, eap_payload_t **out)
                    289: {
                    290:        if (this->use_permanent || this->use_pseudonym || this->use_reauth)
                    291:        {
                    292:                return identity(this, out);
                    293:        }
                    294:        return challenge(this, out);
                    295: }
                    296: 
                    297: /**
                    298:  * Process EAP-AKA/Response/Identity message
                    299:  */
                    300: static status_t process_identity(private_eap_aka_server_t *this,
                    301:                                                                 simaka_message_t *in, eap_payload_t **out)
                    302: {
                    303:        identification_t *permanent, *id;
                    304:        enumerator_t *enumerator;
                    305:        simaka_attribute_t type;
                    306:        chunk_t data, identity = chunk_empty;
                    307: 
                    308:        if (this->pending != AKA_IDENTITY)
                    309:        {
                    310:                DBG1(DBG_IKE, "received %N, but not expected",
                    311:                         simaka_subtype_names, AKA_IDENTITY);
                    312:                return FAILED;
                    313:        }
                    314: 
                    315:        enumerator = in->create_attribute_enumerator(in);
                    316:        while (enumerator->enumerate(enumerator, &type, &data))
                    317:        {
                    318:                switch (type)
                    319:                {
                    320:                        case AT_IDENTITY:
                    321:                                identity = data;
                    322:                                break;
                    323:                        default:
                    324:                                if (!simaka_attribute_skippable(type))
                    325:                                {
                    326:                                        enumerator->destroy(enumerator);
                    327:                                        return FAILED;
                    328:                                }
                    329:                                break;
                    330:                }
                    331:        }
                    332:        enumerator->destroy(enumerator);
                    333: 
                    334:        if (!identity.len)
                    335:        {
                    336:                DBG1(DBG_IKE, "received incomplete Identity response");
                    337:                return FAILED;
                    338:        }
                    339: 
                    340:        id = identification_create_from_data(identity);
                    341:        if (this->use_reauth)
                    342:        {
                    343:                char mk[HASH_SIZE_SHA1];
                    344:                uint16_t counter;
                    345: 
                    346:                permanent = this->mgr->provider_is_reauth(this->mgr, id, mk, &counter);
                    347:                if (permanent)
                    348:                {
                    349:                        this->permanent->destroy(this->permanent);
                    350:                        this->permanent = permanent;
                    351:                        this->reauth = id;
                    352:                        return reauthenticate(this, mk, counter, out);
                    353:                }
                    354:                /* unable to map, maybe a pseudonym? */
                    355:                DBG1(DBG_IKE, "'%Y' is not a reauth identity", id);
                    356:                this->use_reauth = FALSE;
                    357:        }
                    358:        if (this->use_pseudonym)
                    359:        {
                    360:                permanent = this->mgr->provider_is_pseudonym(this->mgr, id);
                    361:                if (permanent)
                    362:                {
                    363:                        this->permanent->destroy(this->permanent);
                    364:                        this->permanent = permanent;
                    365:                        this->pseudonym = id->clone(id);
                    366:                        /* we already have a new permanent identity now */
                    367:                        this->use_permanent = FALSE;
                    368:                }
                    369:                else
                    370:                {
                    371:                        DBG1(DBG_IKE, "'%Y' is not a pseudonym", id);
                    372:                }
                    373:        }
                    374:        if (!this->pseudonym && this->use_permanent)
                    375:        {
                    376:                /* got a permanent identity or a pseudonym reauth id wou couldn't map,
                    377:                 * try to get quintuplets */
                    378:                DBG1(DBG_IKE, "received identity '%Y'", id);
                    379:                this->permanent->destroy(this->permanent);
                    380:                this->permanent = id->clone(id);
                    381:        }
                    382:        id->destroy(id);
                    383: 
                    384:        return challenge(this, out);
                    385: }
                    386: 
                    387: /**
                    388:  * Process EAP-AKA/Response/Challenge message
                    389:  */
                    390: static status_t process_challenge(private_eap_aka_server_t *this,
                    391:                                                                  simaka_message_t *in)
                    392: {
                    393:        enumerator_t *enumerator;
                    394:        simaka_attribute_t type;
                    395:        chunk_t data, res = chunk_empty;
                    396: 
                    397:        if (this->pending != AKA_CHALLENGE)
                    398:        {
                    399:                DBG1(DBG_IKE, "received %N, but not expected",
                    400:                         simaka_subtype_names, AKA_CHALLENGE);
                    401:                return FAILED;
                    402:        }
                    403:        /* verify MAC of EAP message, AT_MAC */
                    404:        if (!in->verify(in, chunk_empty))
                    405:        {
                    406:                return FAILED;
                    407:        }
                    408:        enumerator = in->create_attribute_enumerator(in);
                    409:        while (enumerator->enumerate(enumerator, &type, &data))
                    410:        {
                    411:                switch (type)
                    412:                {
                    413:                        case AT_RES:
                    414:                                res = data;
                    415:                                break;
                    416:                        default:
                    417:                                if (!simaka_attribute_skippable(type))
                    418:                                {
                    419:                                        enumerator->destroy(enumerator);
                    420:                                        return FAILED;
                    421:                                }
                    422:                                break;
                    423:                }
                    424:        }
                    425:        enumerator->destroy(enumerator);
                    426: 
                    427:        /* compare received RES against stored XRES */
                    428:        if (!chunk_equals_const(res, this->xres))
                    429:        {
                    430:                DBG1(DBG_IKE, "received RES does not match XRES");
                    431:                return FAILED;
                    432:        }
                    433:        return SUCCESS;
                    434: }
                    435: 
                    436: /**
                    437:  * process an EAP-AKA/Response/Reauthentication message
                    438:  */
                    439: static status_t process_reauthentication(private_eap_aka_server_t *this,
                    440:                                                                        simaka_message_t *in, eap_payload_t **out)
                    441: {
                    442:        enumerator_t *enumerator;
                    443:        simaka_attribute_t type;
                    444:        chunk_t data, counter = chunk_empty;
                    445:        bool too_small = FALSE;
                    446: 
                    447:        if (this->pending != AKA_REAUTHENTICATION)
                    448:        {
                    449:                DBG1(DBG_IKE, "received %N, but not expected",
                    450:                         simaka_subtype_names, AKA_REAUTHENTICATION);
                    451:                return FAILED;
                    452:        }
                    453:        /* verify AT_MAC attribute, signature is over "EAP packet | NONCE_S"  */
                    454:        if (!in->verify(in, this->nonce))
                    455:        {
                    456:                return FAILED;
                    457:        }
                    458: 
                    459:        enumerator = in->create_attribute_enumerator(in);
                    460:        while (enumerator->enumerate(enumerator, &type, &data))
                    461:        {
                    462:                switch (type)
                    463:                {
                    464:                        case AT_COUNTER:
                    465:                                counter = data;
                    466:                                break;
                    467:                        case AT_COUNTER_TOO_SMALL:
                    468:                                too_small = TRUE;
                    469:                                break;
                    470:                        default:
                    471:                                if (!simaka_attribute_skippable(type))
                    472:                                {
                    473:                                        enumerator->destroy(enumerator);
                    474:                                        return FAILED;
                    475:                                }
                    476:                                break;
                    477:                }
                    478:        }
                    479:        enumerator->destroy(enumerator);
                    480: 
                    481:        if (too_small)
                    482:        {
                    483:                DBG1(DBG_IKE, "received %N, initiating full authentication",
                    484:                         simaka_attribute_names, AT_COUNTER_TOO_SMALL);
                    485:                this->use_reauth = FALSE;
                    486:                this->crypto->clear_keys(this->crypto);
                    487:                return challenge(this, out);
                    488:        }
                    489:        if (!chunk_equals_const(counter, this->counter))
                    490:        {
                    491:                DBG1(DBG_IKE, "received counter does not match");
                    492:                return FAILED;
                    493:        }
                    494:        return SUCCESS;
                    495: }
                    496: 
                    497: /**
                    498:  * Process EAP-AKA/Response/SynchronizationFailure message
                    499:  */
                    500: static status_t process_synchronize(private_eap_aka_server_t *this,
                    501:                                                                        simaka_message_t *in, eap_payload_t **out)
                    502: {
                    503:        enumerator_t *enumerator;
                    504:        simaka_attribute_t type;
                    505:        chunk_t data, auts = chunk_empty;
                    506: 
                    507:        if (this->synchronized)
                    508:        {
                    509:                DBG1(DBG_IKE, "received %N, but peer did already resynchronize",
                    510:                         simaka_subtype_names, AKA_SYNCHRONIZATION_FAILURE);
                    511:                return FAILED;
                    512:        }
                    513: 
                    514:        DBG1(DBG_IKE, "received synchronization request, retrying...");
                    515: 
                    516:        enumerator = in->create_attribute_enumerator(in);
                    517:        while (enumerator->enumerate(enumerator, &type, &data))
                    518:        {
                    519:                switch (type)
                    520:                {
                    521:                        case AT_AUTS:
                    522:                                auts = data;
                    523:                                break;
                    524:                        default:
                    525:                                if (!simaka_attribute_skippable(type))
                    526:                                {
                    527:                                        enumerator->destroy(enumerator);
                    528:                                        return FAILED;
                    529:                                }
                    530:                                break;
                    531:                }
                    532:        }
                    533:        enumerator->destroy(enumerator);
                    534: 
                    535:        if (!auts.len)
                    536:        {
                    537:                DBG1(DBG_IKE, "synchronization request didn't contain usable AUTS");
                    538:                return FAILED;
                    539:        }
                    540: 
                    541:        if (!this->mgr->provider_resync(this->mgr, this->permanent,
                    542:                                                                        this->rand.ptr, auts.ptr))
                    543:        {
                    544:                DBG1(DBG_IKE, "no AKA provider found supporting "
                    545:                         "resynchronization for '%Y'", this->permanent);
                    546:                return FAILED;
                    547:        }
                    548:        this->synchronized = TRUE;
                    549:        return challenge(this, out);
                    550: }
                    551: 
                    552: /**
                    553:  * Process EAP-AKA/Response/ClientErrorCode message
                    554:  */
                    555: static status_t process_client_error(private_eap_aka_server_t *this,
                    556:                                                                         simaka_message_t *in)
                    557: {
                    558:        enumerator_t *enumerator;
                    559:        simaka_attribute_t type;
                    560:        chunk_t data;
                    561: 
                    562:        enumerator = in->create_attribute_enumerator(in);
                    563:        while (enumerator->enumerate(enumerator, &type, &data))
                    564:        {
                    565:                if (type == AT_CLIENT_ERROR_CODE)
                    566:                {
                    567:                        uint16_t code;
                    568: 
                    569:                        memcpy(&code, data.ptr, sizeof(code));
                    570:                        DBG1(DBG_IKE, "received EAP-AKA client error '%N'",
                    571:                                 simaka_client_error_names, ntohs(code));
                    572:                }
                    573:                else if (!simaka_attribute_skippable(type))
                    574:                {
                    575:                        break;
                    576:                }
                    577:        }
                    578:        enumerator->destroy(enumerator);
                    579:        return FAILED;
                    580: }
                    581: 
                    582: /**
                    583:  * Process EAP-AKA/Response/AuthenticationReject message
                    584:  */
                    585: static status_t process_authentication_reject(private_eap_aka_server_t *this,
                    586:                                                                                          simaka_message_t *in)
                    587: {
                    588:        DBG1(DBG_IKE, "received %N, authentication failed",
                    589:                 simaka_subtype_names, in->get_subtype(in));
                    590:        return FAILED;
                    591: }
                    592: 
                    593: METHOD(eap_method_t, process, status_t,
                    594:        private_eap_aka_server_t *this, eap_payload_t *in, eap_payload_t **out)
                    595: {
                    596:        simaka_message_t *message;
                    597:        status_t status;
                    598: 
                    599:        message = simaka_message_create_from_payload(in->get_data(in), this->crypto);
                    600:        if (!message)
                    601:        {
                    602:                return FAILED;
                    603:        }
                    604:        if (!message->parse(message))
                    605:        {
                    606:                message->destroy(message);
                    607:                return FAILED;
                    608:        }
                    609:        switch (message->get_subtype(message))
                    610:        {
                    611:                case AKA_IDENTITY:
                    612:                        status = process_identity(this, message, out);
                    613:                        break;
                    614:                case AKA_CHALLENGE:
                    615:                        status = process_challenge(this, message);
                    616:                        break;
                    617:                case AKA_REAUTHENTICATION:
                    618:                        status = process_reauthentication(this, message, out);
                    619:                        break;
                    620:                case AKA_SYNCHRONIZATION_FAILURE:
                    621:                        status = process_synchronize(this, message, out);
                    622:                        break;
                    623:                case AKA_CLIENT_ERROR:
                    624:                        status = process_client_error(this, message);
                    625:                        break;
                    626:                case AKA_AUTHENTICATION_REJECT:
                    627:                        status = process_authentication_reject(this, message);
                    628:                        break;
                    629:                default:
                    630:                        DBG1(DBG_IKE, "unable to process EAP-AKA subtype %N",
                    631:                                 simaka_subtype_names, message->get_subtype(message));
                    632:                        status = FAILED;
                    633:                        break;
                    634:        }
                    635:        message->destroy(message);
                    636:        return status;
                    637: }
                    638: 
                    639: METHOD(eap_method_t, get_type, eap_type_t,
                    640:        private_eap_aka_server_t *this, uint32_t *vendor)
                    641: {
                    642:        *vendor = 0;
                    643:        return EAP_AKA;
                    644: }
                    645: 
                    646: METHOD(eap_method_t, get_msk, status_t,
                    647:        private_eap_aka_server_t *this, chunk_t *msk)
                    648: {
                    649:        if (this->msk.ptr)
                    650:        {
                    651:                *msk = this->msk;
                    652:                return SUCCESS;
                    653:        }
                    654:        return FAILED;
                    655: }
                    656: 
                    657: METHOD(eap_method_t, get_identifier, uint8_t,
                    658:        private_eap_aka_server_t *this)
                    659: {
                    660:        return this->identifier;
                    661: }
                    662: 
                    663: METHOD(eap_method_t, set_identifier, void,
                    664:        private_eap_aka_server_t *this, uint8_t identifier)
                    665: {
                    666:        this->identifier = identifier;
                    667: }
                    668: 
                    669: METHOD(eap_method_t, is_mutual, bool,
                    670:        private_eap_aka_server_t *this)
                    671: {
                    672:        return TRUE;
                    673: }
                    674: 
                    675: METHOD(eap_method_t, destroy, void,
                    676:        private_eap_aka_server_t *this)
                    677: {
                    678:        this->crypto->destroy(this->crypto);
                    679:        this->permanent->destroy(this->permanent);
                    680:        DESTROY_IF(this->pseudonym);
                    681:        DESTROY_IF(this->reauth);
                    682:        free(this->xres.ptr);
                    683:        free(this->rand.ptr);
                    684:        free(this->nonce.ptr);
                    685:        free(this->msk.ptr);
                    686:        free(this->counter.ptr);
                    687:        free(this);
                    688: }
                    689: 
                    690: /*
                    691:  * Described in header.
                    692:  */
                    693: eap_aka_server_t *eap_aka_server_create(identification_t *server,
                    694:                                                                                identification_t *peer)
                    695: {
                    696:        private_eap_aka_server_t *this;
                    697: 
                    698:        INIT(this,
                    699:                .public = {
                    700:                        .interface = {
                    701:                                .initiate = _initiate,
                    702:                                .process = _process,
                    703:                                .get_type = _get_type,
                    704:                                .is_mutual = _is_mutual,
                    705:                                .get_msk = _get_msk,
                    706:                                .get_identifier = _get_identifier,
                    707:                                .set_identifier = _set_identifier,
                    708:                                .destroy = _destroy,
                    709:                        },
                    710:                },
                    711:                .crypto = simaka_crypto_create(EAP_AKA),
                    712:                .mgr = lib->get(lib, "aka-manager"),
                    713:        );
                    714: 
                    715:        if (!this->crypto)
                    716:        {
                    717:                free(this);
                    718:                return NULL;
                    719:        }
                    720: 
                    721:        this->permanent = peer->clone(peer);
                    722:        this->use_reauth = this->use_pseudonym = this->use_permanent =
                    723:                lib->settings->get_bool(lib->settings,
                    724:                                                "%s.plugins.eap-aka.request_identity", TRUE, lib->ns);
                    725: 
                    726:        /* generate a non-zero identifier */
                    727:        do {
                    728:                this->identifier = random();
                    729:        } while (!this->identifier);
                    730: 
                    731:        return &this->public;
                    732: }

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