From: Tobias Brunner Date: Mon, 23 Feb 2015 14:53:23 +0000 (+0100) Subject: ikev2: Enable signature authentication by transmitting supported hash algorithms X-Git-Tag: 5.3.0dr1~39^2~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6329cae9c1cadbd6d7b3a82ba5db73c18158fb6;p=thirdparty%2Fstrongswan.git ikev2: Enable signature authentication by transmitting supported hash algorithms --- diff --git a/src/libcharon/sa/ike_sa.h b/src/libcharon/sa/ike_sa.h index f65efd81f6..9dbc805c9a 100644 --- a/src/libcharon/sa/ike_sa.h +++ b/src/libcharon/sa/ike_sa.h @@ -131,6 +131,11 @@ enum ike_extension_t { * peer supports proprietary IKEv1 or standardized IKEv2 fragmentation */ EXT_IKE_FRAGMENTATION = (1<<11), + + /** + * Signature Authentication, RFC 7427 + */ + EXT_SIGNATURE_AUTH = (1<<12), }; /** diff --git a/src/libcharon/sa/ikev2/tasks/ike_init.c b/src/libcharon/sa/ikev2/tasks/ike_init.c index b3e92d8ca0..c386877bbc 100644 --- a/src/libcharon/sa/ikev2/tasks/ike_init.c +++ b/src/libcharon/sa/ikev2/tasks/ike_init.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2009 Tobias Brunner + * Copyright (C) 2008-2015 Tobias Brunner * Copyright (C) 2005-2008 Martin Willi * Copyright (C) 2005 Jan Hutter * Hochschule fuer Technik Rapperswil @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include #include @@ -102,6 +104,64 @@ struct private_ike_init_t { u_int retry; }; +/** + * Notify the peer about the hash algorithms we support, as per RFC 7427 + */ +static void send_supported_hash_algorithms(message_t *message) +{ + enumerator_t *enumerator; + bio_writer_t *writer; + hash_algorithm_t hash; + char *plugin_name; + + /* TODO-SIG: As initiator we could send only the algorithms we expect based + * on e.g. rightauth config */ + writer = bio_writer_create(0); + enumerator = lib->crypto->create_hasher_enumerator(lib->crypto); + while (enumerator->enumerate(enumerator, &hash, &plugin_name)) + { + if (hasher_algorithm_for_ikev2(hash)) + { + writer->write_uint16(writer, hash); + } + } + enumerator->destroy(enumerator); + + if (writer->get_buf(writer).len) + { + message->add_notify(message, FALSE, SIGNATURE_HASH_ALGORITHMS, + writer->get_buf(writer)); + } + writer->destroy(writer); +} + +/** + * Store algorithms supported by other peer + */ +static void handle_supported_hash_algorithms(private_ike_init_t *this, + notify_payload_t *notify) +{ + bio_reader_t *reader; + u_int16_t algo; + bool added = FALSE; + + reader = bio_reader_create(notify->get_notification_data(notify)); + while (reader->remaining(reader) >= 2 && reader->read_uint16(reader, &algo)) + { + if (hasher_algorithm_for_ikev2(algo)) + { + this->keymat->add_hash_algorithm(this->keymat, algo); + added = TRUE; + } + } + reader->destroy(reader); + + if (added) + { + this->ike_sa->enable_extension(this->ike_sa, EXT_SIGNATURE_AUTH); + } +} + /** * build the payloads for the message */ @@ -174,6 +234,16 @@ static void build_payloads(private_ike_init_t *this, message_t *message) chunk_empty); } } + /* submit supported hash algorithms for signature authentication */ + if (!this->old_sa) + { + if (this->initiator || + this->ike_sa->supports_extension(this->ike_sa, + EXT_SIGNATURE_AUTH)) + { + send_supported_hash_algorithms(message); + } + } } /** @@ -228,11 +298,20 @@ static void process_payloads(private_ike_init_t *this, message_t *message) { notify_payload_t *notify = (notify_payload_t*)payload; - if (notify->get_notify_type(notify) == FRAGMENTATION_SUPPORTED) + switch (notify->get_notify_type(notify)) { - this->ike_sa->enable_extension(this->ike_sa, - EXT_IKE_FRAGMENTATION); + case FRAGMENTATION_SUPPORTED: + this->ike_sa->enable_extension(this->ike_sa, + EXT_IKE_FRAGMENTATION); + break; + case SIGNATURE_HASH_ALGORITHMS: + handle_supported_hash_algorithms(this, notify); + break; + default: + /* other notifies are handled elsewhere */ + break; } + } default: break;