Use key derivation in IKEv1 main mode (PSK authentication).
This commit is contained in:
@@ -1,4 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2011 Tobias Brunner
|
||||||
|
* Hochschule fuer Technik Rapperswil
|
||||||
|
*
|
||||||
* Copyright (C) 2011 Martin Willi
|
* Copyright (C) 2011 Martin Willi
|
||||||
* Copyright (C) 2011 revosec AG
|
* Copyright (C) 2011 revosec AG
|
||||||
*
|
*
|
||||||
@@ -18,6 +21,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
|
#include <sa/keymat_v1.h>
|
||||||
#include <crypto/diffie_hellman.h>
|
#include <crypto/diffie_hellman.h>
|
||||||
#include <encoding/payloads/sa_payload.h>
|
#include <encoding/payloads/sa_payload.h>
|
||||||
#include <encoding/payloads/ke_payload.h>
|
#include <encoding/payloads/ke_payload.h>
|
||||||
@@ -76,6 +80,11 @@ struct private_main_mode_t {
|
|||||||
*/
|
*/
|
||||||
diffie_hellman_t *dh;
|
diffie_hellman_t *dh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Keymat derivation (from SA)
|
||||||
|
*/
|
||||||
|
keymat_v1_t *keymat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Received public DH value from peer
|
* Received public DH value from peer
|
||||||
*/
|
*/
|
||||||
@@ -156,7 +165,8 @@ METHOD(task_t, build_i, status_t,
|
|||||||
DBG1(DBG_IKE, "DH group selection failed");
|
DBG1(DBG_IKE, "DH group selection failed");
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
this->dh = lib->crypto->create_dh(lib->crypto, group);
|
this->dh = this->keymat->keymat.create_dh(&this->keymat->keymat,
|
||||||
|
group);
|
||||||
if (!this->dh)
|
if (!this->dh)
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "negotiated DH group not supported");
|
DBG1(DBG_IKE, "negotiated DH group not supported");
|
||||||
@@ -355,6 +365,68 @@ METHOD(task_t, process_r, status_t,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Lookup a shared secret for this IKE_SA
|
||||||
|
*/
|
||||||
|
static shared_key_t *lookup_shared_key(private_main_mode_t *this)
|
||||||
|
{
|
||||||
|
host_t *me, *other;
|
||||||
|
identification_t *my_id, *other_id;
|
||||||
|
shared_key_t *shared_key;
|
||||||
|
|
||||||
|
me = this->ike_sa->get_my_host(this->ike_sa);
|
||||||
|
other = this->ike_sa->get_other_host(this->ike_sa);
|
||||||
|
my_id = identification_create_from_sockaddr(me->get_sockaddr(me));
|
||||||
|
other_id = identification_create_from_sockaddr(other->get_sockaddr(other));
|
||||||
|
if (!my_id || !other_id)
|
||||||
|
{
|
||||||
|
DESTROY_IF(my_id);
|
||||||
|
DESTROY_IF(other_id);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
shared_key = lib->credmgr->get_shared(lib->credmgr, SHARED_IKE, my_id,
|
||||||
|
other_id);
|
||||||
|
if (!shared_key)
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "no shared key found for %H - %H", me, other);
|
||||||
|
}
|
||||||
|
my_id->destroy(my_id);
|
||||||
|
other_id->destroy(other_id);
|
||||||
|
return shared_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Derive key material for this IKE_SA
|
||||||
|
*/
|
||||||
|
static bool derive_keys(private_main_mode_t *this, chunk_t nonce_i,
|
||||||
|
chunk_t nonce_r)
|
||||||
|
{
|
||||||
|
ike_sa_id_t *id = this->ike_sa->get_id(this->ike_sa);
|
||||||
|
shared_key_t *shared_key = NULL;
|
||||||
|
auth_class_t auth;
|
||||||
|
|
||||||
|
/* TODO-IKEv1: support other authentication classes */
|
||||||
|
auth = AUTH_CLASS_PSK;
|
||||||
|
switch (auth)
|
||||||
|
{
|
||||||
|
case AUTH_CLASS_PSK:
|
||||||
|
shared_key = lookup_shared_key(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!this->keymat->derive_ike_keys(this->keymat, this->proposal, this->dh,
|
||||||
|
this->dh_value, nonce_i, nonce_r, id, auth, shared_key))
|
||||||
|
{
|
||||||
|
DESTROY_IF(shared_key);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
DESTROY_IF(shared_key);
|
||||||
|
charon->bus->ike_keys(charon->bus, this->ike_sa, this->dh, nonce_i, nonce_r,
|
||||||
|
NULL);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
METHOD(task_t, build_r, status_t,
|
METHOD(task_t, build_r, status_t,
|
||||||
private_main_mode_t *this, message_t *message)
|
private_main_mode_t *this, message_t *message)
|
||||||
{
|
{
|
||||||
@@ -388,6 +460,12 @@ METHOD(task_t, build_r, status_t,
|
|||||||
rng->allocate_bytes(rng, NONCE_SIZE, &this->nonce_r);
|
rng->allocate_bytes(rng, NONCE_SIZE, &this->nonce_r);
|
||||||
rng->destroy(rng);
|
rng->destroy(rng);
|
||||||
|
|
||||||
|
if (!derive_keys(this, this->nonce_i, this->nonce_r))
|
||||||
|
{
|
||||||
|
DBG1(DBG_IKE, "key derivation failed");
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
nonce_payload = nonce_payload_create(NONCE_V1);
|
nonce_payload = nonce_payload_create(NONCE_V1);
|
||||||
nonce_payload->set_nonce(nonce_payload, this->nonce_r);
|
nonce_payload->set_nonce(nonce_payload, this->nonce_r);
|
||||||
message->add_payload(message, &nonce_payload->payload_interface);
|
message->add_payload(message, &nonce_payload->payload_interface);
|
||||||
@@ -564,6 +642,7 @@ main_mode_t *main_mode_create(ike_sa_t *ike_sa, bool initiator)
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
.ike_sa = ike_sa,
|
.ike_sa = ike_sa,
|
||||||
|
.keymat = (keymat_v1_t*)ike_sa->get_keymat(ike_sa),
|
||||||
.initiator = initiator,
|
.initiator = initiator,
|
||||||
.state = MM_INIT,
|
.state = MM_INIT,
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user