Annotation of embedaddon/strongswan/src/libcharon/sa/ikev2/authenticators/psk_authenticator.c, revision 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>