aboutsummaryrefslogtreecommitdiffstats
path: root/src/libcharon/encoding
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2011-11-23 13:17:46 +0100
committerTobias Brunner <tobias@strongswan.org>2012-03-20 17:30:50 +0100
commitcd200cb821df307aec441308b74dbd8d94c73589 (patch)
tree23f59454943c970c8b14aeb653aae94f06b4c9d6 /src/libcharon/encoding
parent1e5dd62bb28ca177e813723327703ff93ba3d3b4 (diff)
downloadstrongswan-cd200cb821df307aec441308b74dbd8d94c73589.tar.bz2
strongswan-cd200cb821df307aec441308b74dbd8d94c73589.tar.xz
Authenticate and verify Phase 2 IKEv1 messages with appropriate hashes.
Diffstat (limited to 'src/libcharon/encoding')
-rw-r--r--src/libcharon/encoding/message.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/src/libcharon/encoding/message.c b/src/libcharon/encoding/message.c
index 032fc1b1c..f53be0036 100644
--- a/src/libcharon/encoding/message.c
+++ b/src/libcharon/encoding/message.c
@@ -29,6 +29,7 @@
#include <encoding/parser.h>
#include <encoding/payloads/encodings.h>
#include <encoding/payloads/payload.h>
+#include <encoding/payloads/hash_payload.h>
#include <encoding/payloads/encryption_payload.h>
#include <encoding/payloads/unknown_payload.h>
#include <encoding/payloads/cp_payload.h>
@@ -1408,7 +1409,19 @@ METHOD(message_t, generate, status_t,
encrypted = this->rule->encrypted;
}
else
- { /* if at least one payload requires encryption, encrypt the message */
+ {
+ /* get a hash for this message, if any is required */
+ chunk_t hash = keymat_v1->get_hash_phase2(keymat_v1, &this->public);
+ if (hash.ptr)
+ { /* insert a HASH payload as first payload */
+ hash_payload_t *hash_payload = hash_payload_create();
+ hash_payload->set_hash(hash_payload, hash);
+ this->payloads->insert_first(this->payloads,
+ (payload_t*)hash_payload);
+ chunk_free(&hash);
+ }
+
+ /* if at least one payload requires encryption, encrypt the message */
/* TODO-IKEV1: set is_encrypted externally instead of this check? */
enumerator = this->payloads->create_enumerator(this->payloads);
while (enumerator->enumerate(enumerator, (void**)&payload))
@@ -1821,7 +1834,7 @@ static status_t verify(private_message_t *this)
DBG2(DBG_ENC, "verifying message structure");
- /* check for payloads with wrong count*/
+ /* check for payloads with wrong count */
for (i = 0; i < this->rule->rule_count; i++)
{
enumerator_t *enumerator;
@@ -1906,6 +1919,35 @@ METHOD(message_t, parse_body, status_t,
DBG1(DBG_ENC, "parsed %s", get_string(this, str, sizeof(str)));
+ if (this->major_version == IKEV1_MAJOR_VERSION)
+ {
+ keymat_v1_t *keymat_v1 = (keymat_v1_t*)keymat;
+ chunk_t hash;
+ hash = keymat_v1->get_hash_phase2(keymat_v1, &this->public);
+ if (hash.ptr)
+ {
+ hash_payload_t *hash_payload;
+ chunk_t other_hash;
+ if (this->first_payload != HASH_V1)
+ {
+ DBG1(DBG_ENC, "expected HASH payload as first payload");
+ chunk_free(&hash);
+ return VERIFY_ERROR;
+ }
+ hash_payload = (hash_payload_t*)get_payload(this, HASH_V1);
+ other_hash = hash_payload->get_hash(hash_payload);
+ if (!chunk_equals(hash, other_hash))
+ {
+ DBG1(DBG_ENC, "our hash does not match received %B",
+ &other_hash);
+ chunk_free(&hash);
+ return VERIFY_ERROR;
+ }
+ DBG2(DBG_ENC, "verified IKEv1 message with hash %B", &hash);
+ chunk_free(&hash);
+ }
+ }
+
if (this->is_encrypted)
{ /* TODO-IKEv1: this should be done later when we know this is no
* retransmit */