diff options
| author | Tobias Brunner <tobias@strongswan.org> | 2011-11-23 13:17:46 +0100 |
|---|---|---|
| committer | Tobias Brunner <tobias@strongswan.org> | 2012-03-20 17:30:50 +0100 |
| commit | cd200cb821df307aec441308b74dbd8d94c73589 (patch) | |
| tree | 23f59454943c970c8b14aeb653aae94f06b4c9d6 /src/libcharon/encoding | |
| parent | 1e5dd62bb28ca177e813723327703ff93ba3d3b4 (diff) | |
| download | strongswan-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.c | 46 |
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 */ |
