diff options
author | Martin Willi <martin@revosec.ch> | 2011-12-07 14:52:02 +0100 |
---|---|---|
committer | Martin Willi <martin@revosec.ch> | 2012-03-20 17:31:14 +0100 |
commit | 279258787542652739e282e8dd2dec346c04fc99 (patch) | |
tree | 466755202f495af5d3840580b3e59967edf962e2 /src/libcharon/sa/authenticators | |
parent | 5d1eeec297de5009056d71e65c336987ee0fe10f (diff) | |
download | strongswan-279258787542652739e282e8dd2dec346c04fc99.tar.bz2 strongswan-279258787542652739e282e8dd2dec346c04fc99.tar.xz |
Implemented IKEv1 PSK HASH payload processing in separated authenticator
Diffstat (limited to 'src/libcharon/sa/authenticators')
-rw-r--r-- | src/libcharon/sa/authenticators/psk_v1_authenticator.c | 145 | ||||
-rw-r--r-- | src/libcharon/sa/authenticators/psk_v1_authenticator.h | 53 |
2 files changed, 198 insertions, 0 deletions
diff --git a/src/libcharon/sa/authenticators/psk_v1_authenticator.c b/src/libcharon/sa/authenticators/psk_v1_authenticator.c new file mode 100644 index 000000000..ecce92268 --- /dev/null +++ b/src/libcharon/sa/authenticators/psk_v1_authenticator.c @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "psk_v1_authenticator.h" + +#include <daemon.h> +#include <sa/keymat_v1.h> +#include <encoding/payloads/hash_payload.h> + +typedef struct private_psk_v1_authenticator_t private_psk_v1_authenticator_t; + +/** + * Private data of an psk_v1_authenticator_t object. + */ +struct private_psk_v1_authenticator_t { + + /** + * Public authenticator_t interface. + */ + psk_v1_authenticator_t public; + + /** + * Assigned IKE_SA + */ + ike_sa_t *ike_sa; + + /** + * TRUE if we are initiator + */ + bool initiator; + + /** + * DH key exchange + */ + diffie_hellman_t *dh; + + /** + * Others DH public value + */ + chunk_t dh_value; + + /** + * Encoded SA payload, without fixed header + */ + chunk_t sa_payload; +}; + +METHOD(authenticator_t, build, status_t, + private_psk_v1_authenticator_t *this, message_t *message) +{ + hash_payload_t *hash_payload; + keymat_v1_t *keymat; + chunk_t hash, dh; + + this->dh->get_my_public_value(this->dh, &dh); + keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa); + hash = keymat->get_hash(keymat, this->initiator, dh, this->dh_value, + this->ike_sa->get_id(this->ike_sa), this->sa_payload, + this->ike_sa->get_my_id(this->ike_sa)); + free(dh.ptr); + + hash_payload = hash_payload_create(HASH_V1); + hash_payload->set_hash(hash_payload, hash); + message->add_payload(message, &hash_payload->payload_interface); + free(hash.ptr); + + return SUCCESS; +} + +METHOD(authenticator_t, process, status_t, + private_psk_v1_authenticator_t *this, message_t *message) +{ + hash_payload_t *hash_payload; + keymat_v1_t *keymat; + chunk_t hash, dh; + + hash_payload = (hash_payload_t*)message->get_payload(message, HASH_V1); + if (!hash_payload) + { + DBG1(DBG_IKE, "HASH payload missing in message"); + return FAILED; + } + + this->dh->get_my_public_value(this->dh, &dh); + keymat = (keymat_v1_t*)this->ike_sa->get_keymat(this->ike_sa); + hash = keymat->get_hash(keymat, !this->initiator, this->dh_value, dh, + this->ike_sa->get_id(this->ike_sa), this->sa_payload, + this->ike_sa->get_other_id(this->ike_sa)); + free(dh.ptr); + + if (chunk_equals(hash, hash_payload->get_hash(hash_payload))) + { + free(hash.ptr); + return SUCCESS; + } + free(hash.ptr); + DBG1(DBG_IKE, "calculated HASH does not match HASH payload"); + return FAILED; +} + +METHOD(authenticator_t, destroy, void, + private_psk_v1_authenticator_t *this) +{ + free(this); +} + +/* + * Described in header. + */ +psk_v1_authenticator_t *psk_v1_authenticator_create(ike_sa_t *ike_sa, + bool initiator, diffie_hellman_t *dh, + chunk_t dh_value, chunk_t sa_payload) +{ + private_psk_v1_authenticator_t *this; + + INIT(this, + .public = { + .authenticator = { + .build = _build, + .process = _process, + .is_mutual = (void*)return_false, + .destroy = _destroy, + }, + }, + .ike_sa = ike_sa, + .initiator = initiator, + .dh = dh, + .dh_value = dh_value, + .sa_payload = sa_payload, + ); + + return &this->public; +} diff --git a/src/libcharon/sa/authenticators/psk_v1_authenticator.h b/src/libcharon/sa/authenticators/psk_v1_authenticator.h new file mode 100644 index 000000000..1103ee62f --- /dev/null +++ b/src/libcharon/sa/authenticators/psk_v1_authenticator.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 Martin Willi + * Copyright (C) 2011 revosec AG + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup psk_v1_authenticator psk_v1_authenticator + * @{ @ingroup authenticators + */ + +#ifndef PSK_V1_AUTHENTICATOR_H_ +#define PSK_V1_AUTHENTICATOR_H_ + +typedef struct psk_v1_authenticator_t psk_v1_authenticator_t; + +#include <sa/authenticators/authenticator.h> + +/** + * Implementation of authenticator_t using pre-shared keys for IKEv1. + */ +struct psk_v1_authenticator_t { + + /** + * Implemented authenticator_t interface. + */ + authenticator_t authenticator; +}; + +/** + * Create an authenticator to build PSK signatures. + * + * @param ike_sa associated IKE_SA + * @param initiator TRUE if we are the IKE_SA initiator + * @param dh diffie hellman key exchange + * @param dh_value others public diffie hellman value + * @param sa_payload generated SA payload data, without payload header + * @return PSK authenticator + */ +psk_v1_authenticator_t *psk_v1_authenticator_create(ike_sa_t *ike_sa, + bool initiator, diffie_hellman_t *dh, + chunk_t dh_value, chunk_t sa_payload); + +#endif /** PSK_V1_AUTHENTICATOR_H_ @}*/ |