Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/authenticators/psk_authenticator.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2018 Tobias Brunner
                      3:  * Copyright (C) 2005-2009 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 "psk_authenticator.h"
                     19: 
                     20: #include <daemon.h>
                     21: #include <encoding/payloads/auth_payload.h>
                     22: #include <sa/ikev2/keymat_v2.h>
                     23: 
                     24: typedef struct private_psk_authenticator_t private_psk_authenticator_t;
                     25: 
                     26: /**
                     27:  * Private data of an psk_authenticator_t object.
                     28:  */
                     29: struct private_psk_authenticator_t {
                     30: 
                     31:        /**
                     32:         * Public authenticator_t interface.
                     33:         */
                     34:        psk_authenticator_t public;
                     35: 
                     36:        /**
                     37:         * Assigned IKE_SA
                     38:         */
                     39:        ike_sa_t *ike_sa;
                     40: 
                     41:        /**
                     42:         * nonce to include in AUTH calculation
                     43:         */
                     44:        chunk_t nonce;
                     45: 
                     46:        /**
                     47:         * IKE_SA_INIT message data to include in AUTH calculation
                     48:         */
                     49:        chunk_t ike_sa_init;
                     50: 
                     51:        /**
                     52:         * Reserved bytes of ID payload
                     53:         */
                     54:        char reserved[3];
                     55: 
                     56:        /**
                     57:         * PPK to use
                     58:         */
                     59:        chunk_t ppk;
                     60: 
                     61:        /**
                     62:         * Add a NO_PPK_AUTH notify
                     63:         */
                     64:        bool no_ppk_auth;
                     65: };
                     66: 
                     67: METHOD(authenticator_t, build, status_t,
                     68:        private_psk_authenticator_t *this, message_t *message)
                     69: {
                     70:        identification_t *my_id, *other_id;
                     71:        auth_payload_t *auth_payload;
                     72:        shared_key_t *key;
                     73:        chunk_t auth_data;
                     74:        keymat_v2_t *keymat;
                     75: 
                     76:        keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
                     77:        my_id = this->ike_sa->get_my_id(this->ike_sa);
                     78:        other_id = this->ike_sa->get_other_id(this->ike_sa);
                     79:        DBG1(DBG_IKE, "authentication of '%Y' (myself) with %N",
                     80:                 my_id, auth_method_names, AUTH_PSK);
                     81:        key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE, my_id, other_id);
                     82:        if (!key)
                     83:        {
                     84:                DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id);
                     85:                return NOT_FOUND;
                     86:        }
                     87:        if (!keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init, this->nonce,
                     88:                                                         key->get_key(key), this->ppk, my_id,
                     89:                                                         this->reserved, &auth_data))
                     90:        {
                     91:                key->destroy(key);
                     92:                return FAILED;
                     93:        }
                     94: 
                     95:        DBG2(DBG_IKE, "successfully created shared key MAC");
                     96:        auth_payload = auth_payload_create();
                     97:        auth_payload->set_auth_method(auth_payload, AUTH_PSK);
                     98:        auth_payload->set_data(auth_payload, auth_data);
                     99:        chunk_free(&auth_data);
                    100:        message->add_payload(message, (payload_t*)auth_payload);
                    101: 
                    102:        if (this->no_ppk_auth)
                    103:        {
                    104:                if (!keymat->get_psk_sig(keymat, FALSE, this->ike_sa_init, this->nonce,
                    105:                                                         key->get_key(key), chunk_empty, my_id,
                    106:                                                         this->reserved, &auth_data))
                    107:                {
                    108:                        DBG1(DBG_IKE, "failed adding NO_PPK_AUTH notify");
                    109:                        key->destroy(key);
                    110:                        return SUCCESS;
                    111:                }
                    112:                DBG2(DBG_IKE, "successfully created shared key MAC without PPK");
                    113:                message->add_notify(message, FALSE, NO_PPK_AUTH, auth_data);
                    114:                chunk_free(&auth_data);
                    115:        }
                    116:        key->destroy(key);
                    117:        return SUCCESS;
                    118: }
                    119: 
                    120: METHOD(authenticator_t, process, status_t,
                    121:        private_psk_authenticator_t *this, message_t *message)
                    122: {
                    123:        chunk_t auth_data, recv_auth_data;
                    124:        identification_t *my_id, *other_id;
                    125:        auth_payload_t *auth_payload;
                    126:        notify_payload_t *notify;
                    127:        auth_cfg_t *auth;
                    128:        shared_key_t *key;
                    129:        enumerator_t *enumerator;
                    130:        bool authenticated = FALSE;
                    131:        int keys_found = 0;
                    132:        keymat_v2_t *keymat;
                    133: 
                    134:        auth_payload = (auth_payload_t*)message->get_payload(message, PLV2_AUTH);
                    135:        if (!auth_payload)
                    136:        {
                    137:                return FAILED;
                    138:        }
                    139:        recv_auth_data = auth_payload->get_data(auth_payload);
                    140: 
                    141:        if (this->ike_sa->supports_extension(this->ike_sa, EXT_PPK) &&
                    142:                !this->ppk.ptr)
                    143:        {       /* look for a NO_PPK_AUTH notify if we have no PPK */
                    144:                notify = message->get_notify(message, NO_PPK_AUTH);
                    145:                if (notify)
                    146:                {
                    147:                        DBG1(DBG_IKE, "no PPK available, using NO_PPK_AUTH notify");
                    148:                        recv_auth_data = notify->get_notification_data(notify);
                    149:                }
                    150:        }
                    151: 
                    152:        keymat = (keymat_v2_t*)this->ike_sa->get_keymat(this->ike_sa);
                    153:        my_id = this->ike_sa->get_my_id(this->ike_sa);
                    154:        other_id = this->ike_sa->get_other_id(this->ike_sa);
                    155:        enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
                    156:                                                                                                SHARED_IKE, my_id, other_id);
                    157:        while (!authenticated && enumerator->enumerate(enumerator, &key, NULL, NULL))
                    158:        {
                    159:                keys_found++;
                    160: 
                    161:                if (!keymat->get_psk_sig(keymat, TRUE, this->ike_sa_init, this->nonce,
                    162:                                                                 key->get_key(key), this->ppk, other_id,
                    163:                                                                 this->reserved, &auth_data))
                    164:                {
                    165:                        continue;
                    166:                }
                    167:                if (auth_data.len && chunk_equals_const(auth_data, recv_auth_data))
                    168:                {
                    169:                        DBG1(DBG_IKE, "authentication of '%Y' with %N successful",
                    170:                                 other_id, auth_method_names, AUTH_PSK);
                    171:                        authenticated = TRUE;
                    172:                }
                    173:                chunk_free(&auth_data);
                    174:        }
                    175:        enumerator->destroy(enumerator);
                    176: 
                    177:        if (!authenticated)
                    178:        {
                    179:                if (keys_found == 0)
                    180:                {
                    181:                        DBG1(DBG_IKE, "no shared key found for '%Y' - '%Y'", my_id, other_id);
                    182:                        return NOT_FOUND;
                    183:                }
                    184:                DBG1(DBG_IKE, "tried %d shared key%s for '%Y' - '%Y', but MAC mismatched",
                    185:                         keys_found, keys_found == 1 ? "" : "s", my_id, other_id);
                    186:                return FAILED;
                    187:        }
                    188: 
                    189:        auth = this->ike_sa->get_auth_cfg(this->ike_sa, FALSE);
                    190:        auth->add(auth, AUTH_RULE_AUTH_CLASS, AUTH_CLASS_PSK);
                    191:        return SUCCESS;
                    192: }
                    193: 
                    194: METHOD(authenticator_t, use_ppk, void,
                    195:        private_psk_authenticator_t *this, chunk_t ppk, bool no_ppk_auth)
                    196: {
                    197:        this->ppk = ppk;
                    198:        this->no_ppk_auth = no_ppk_auth;
                    199: }
                    200: 
                    201: METHOD(authenticator_t, destroy, void,
                    202:        private_psk_authenticator_t *this)
                    203: {
                    204:        free(this);
                    205: }
                    206: 
                    207: /*
                    208:  * Described in header.
                    209:  */
                    210: psk_authenticator_t *psk_authenticator_create_builder(ike_sa_t *ike_sa,
                    211:                                                                        chunk_t received_nonce, chunk_t sent_init,
                    212:                                                                        char reserved[3])
                    213: {
                    214:        private_psk_authenticator_t *this;
                    215: 
                    216:        INIT(this,
                    217:                .public = {
                    218:                        .authenticator = {
                    219:                                .build = _build,
                    220:                                .process = (void*)return_failed,
                    221:                                .use_ppk = _use_ppk,
                    222:                                .is_mutual = (void*)return_false,
                    223:                                .destroy = _destroy,
                    224:                        },
                    225:                },
                    226:                .ike_sa = ike_sa,
                    227:                .ike_sa_init = sent_init,
                    228:                .nonce = received_nonce,
                    229:        );
                    230:        memcpy(this->reserved, reserved, sizeof(this->reserved));
                    231: 
                    232:        return &this->public;
                    233: }
                    234: 
                    235: /*
                    236:  * Described in header.
                    237:  */
                    238: psk_authenticator_t *psk_authenticator_create_verifier(ike_sa_t *ike_sa,
                    239:                                                                        chunk_t sent_nonce, chunk_t received_init,
                    240:                                                                        char reserved[3])
                    241: {
                    242:        private_psk_authenticator_t *this;
                    243: 
                    244:        INIT(this,
                    245:                .public = {
                    246:                        .authenticator = {
                    247:                                .build = (void*)return_failed,
                    248:                                .process = _process,
                    249:                                .use_ppk = _use_ppk,
                    250:                                .is_mutual = (void*)return_false,
                    251:                                .destroy = _destroy,
                    252:                        },
                    253:                },
                    254:                .ike_sa = ike_sa,
                    255:                .ike_sa_init = received_init,
                    256:                .nonce = sent_nonce,
                    257:        );
                    258:        memcpy(this->reserved, reserved, sizeof(this->reserved));
                    259: 
                    260:        return &this->public;
                    261: }

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