ha: Add support to sync IKE and Child SAs with multiple key exchanges
Synchronization for the additional transforms in the IKE and Child SA proposals is added. Details of the IKE_SA synchronization are changed to support IKE_INTERMEDIATE exchanges that cause multiple HA_IKE_ADD messages and key derivations. The cache has been extended to handle multiple such messages. Co-authored-by: Thomas Egerer <[email protected]>
This commit is contained in:
co-authored by
Thomas Egerer
parent
f717bb5249
commit
e7848e36fa
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2015-2024 Tobias Brunner
|
||||||
* Copyright (C) 2010 Martin Willi
|
* Copyright (C) 2010 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@@ -70,9 +71,9 @@ struct private_ha_cache_t {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
/* segment this entry is associate to */
|
/* segment this entry is associate to */
|
||||||
u_int segment;
|
u_int segment;
|
||||||
/* ADD message */
|
/* list of ADD messages */
|
||||||
ha_message_t *add;
|
linked_list_t *add;
|
||||||
/* list of updates UPDATE message */
|
/* list of UPDATE messages */
|
||||||
linked_list_t *updates;
|
linked_list_t *updates;
|
||||||
/* last initiator mid */
|
/* last initiator mid */
|
||||||
ha_message_t *midi;
|
ha_message_t *midi;
|
||||||
@@ -83,27 +84,27 @@ typedef struct {
|
|||||||
} entry_t;
|
} entry_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a entry with an add message
|
* Create a entry
|
||||||
*/
|
*/
|
||||||
static entry_t *entry_create(ha_message_t *add)
|
static entry_t *entry_create()
|
||||||
{
|
{
|
||||||
entry_t *entry;
|
entry_t *entry;
|
||||||
|
|
||||||
INIT(entry,
|
INIT(entry,
|
||||||
.add = add,
|
.add = linked_list_create(),
|
||||||
.updates = linked_list_create(),
|
.updates = linked_list_create(),
|
||||||
);
|
);
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clean up a entry
|
* Clean up a entry
|
||||||
*/
|
*/
|
||||||
static void entry_destroy(entry_t *entry)
|
static void entry_destroy(entry_t *entry)
|
||||||
{
|
{
|
||||||
entry->updates->destroy_offset(entry->updates,
|
entry->updates->destroy_offset(entry->updates,
|
||||||
offsetof(ha_message_t, destroy));
|
offsetof(ha_message_t, destroy));
|
||||||
entry->add->destroy(entry->add);
|
entry->add->destroy_offset(entry->add, offsetof(ha_message_t, destroy));
|
||||||
DESTROY_IF(entry->midi);
|
DESTROY_IF(entry->midi);
|
||||||
DESTROY_IF(entry->midr);
|
DESTROY_IF(entry->midr);
|
||||||
DESTROY_IF(entry->iv);
|
DESTROY_IF(entry->iv);
|
||||||
@@ -119,12 +120,13 @@ METHOD(ha_cache_t, cache, void,
|
|||||||
switch (message->get_type(message))
|
switch (message->get_type(message))
|
||||||
{
|
{
|
||||||
case HA_IKE_ADD:
|
case HA_IKE_ADD:
|
||||||
entry = entry_create(message);
|
entry = this->cache->get(this->cache, ike_sa);
|
||||||
entry = this->cache->put(this->cache, ike_sa, entry);
|
if (!entry)
|
||||||
if (entry)
|
|
||||||
{
|
{
|
||||||
entry_destroy(entry);
|
entry = entry_create();
|
||||||
|
this->cache->put(this->cache, ike_sa, entry);
|
||||||
}
|
}
|
||||||
|
entry->add->insert_last(entry->add, message);
|
||||||
break;
|
break;
|
||||||
case HA_IKE_UPDATE:
|
case HA_IKE_UPDATE:
|
||||||
entry = this->cache->get(this->cache, ike_sa);
|
entry = this->cache->get(this->cache, ike_sa);
|
||||||
@@ -305,7 +307,7 @@ static void rekey_segment(private_ha_cache_t *this, u_int segment)
|
|||||||
METHOD(ha_cache_t, resync, void,
|
METHOD(ha_cache_t, resync, void,
|
||||||
private_ha_cache_t *this, u_int segment)
|
private_ha_cache_t *this, u_int segment)
|
||||||
{
|
{
|
||||||
enumerator_t *enumerator, *updates;
|
enumerator_t *enumerator, *messages;
|
||||||
ike_sa_t *ike_sa;
|
ike_sa_t *ike_sa;
|
||||||
entry_t *entry;
|
entry_t *entry;
|
||||||
ha_message_t *message;
|
ha_message_t *message;
|
||||||
@@ -318,13 +320,18 @@ METHOD(ha_cache_t, resync, void,
|
|||||||
{
|
{
|
||||||
if (entry->segment == segment)
|
if (entry->segment == segment)
|
||||||
{
|
{
|
||||||
this->socket->push(this->socket, entry->add);
|
messages = entry->add->create_enumerator(entry->add);
|
||||||
updates = entry->updates->create_enumerator(entry->updates);
|
while (messages->enumerate(messages, &message))
|
||||||
while (updates->enumerate(updates, &message))
|
|
||||||
{
|
{
|
||||||
this->socket->push(this->socket, message);
|
this->socket->push(this->socket, message);
|
||||||
}
|
}
|
||||||
updates->destroy(updates);
|
messages->destroy(messages);
|
||||||
|
messages = entry->updates->create_enumerator(entry->updates);
|
||||||
|
while (messages->enumerate(messages, &message))
|
||||||
|
{
|
||||||
|
this->socket->push(this->socket, message);
|
||||||
|
}
|
||||||
|
messages->destroy(messages);
|
||||||
if (entry->midi)
|
if (entry->midi)
|
||||||
{
|
{
|
||||||
this->socket->push(this->socket, entry->midi);
|
this->socket->push(this->socket, entry->midi);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2024 Tobias Brunner
|
||||||
* Copyright (C) 2008 Martin Willi
|
* Copyright (C) 2008 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@@ -91,21 +92,23 @@ METHOD(listener_t, child_keys, bool,
|
|||||||
{
|
{
|
||||||
m->add_attribute(m, HA_ALG_INTEG, alg);
|
m->add_attribute(m, HA_ALG_INTEG, alg);
|
||||||
}
|
}
|
||||||
if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &alg, NULL))
|
m->add_key_exchange_methods(m, proposal);
|
||||||
{
|
|
||||||
m->add_attribute(m, HA_ALG_DH, alg);
|
|
||||||
}
|
|
||||||
if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, &alg, NULL))
|
if (proposal->get_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, &alg, NULL))
|
||||||
{
|
{
|
||||||
m->add_attribute(m, HA_ESN, alg);
|
m->add_attribute(m, HA_ESN, alg);
|
||||||
}
|
}
|
||||||
|
|
||||||
m->add_attribute(m, HA_NONCE_I, nonce_i);
|
m->add_attribute(m, HA_NONCE_I, nonce_i);
|
||||||
m->add_attribute(m, HA_NONCE_R, nonce_r);
|
m->add_attribute(m, HA_NONCE_R, nonce_r);
|
||||||
if (kes && key_exchange_concat_secrets(kes, &secret, &add_secret))
|
if (kes && key_exchange_concat_secrets(kes, &secret, &add_secret))
|
||||||
{
|
{
|
||||||
m->add_attribute(m, HA_SECRET, secret);
|
m->add_attribute(m, HA_SECRET, secret);
|
||||||
chunk_clear(&secret);
|
chunk_clear(&secret);
|
||||||
chunk_clear(&add_secret);
|
if (add_secret.len)
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_ADD_SECRET, add_secret);
|
||||||
|
chunk_clear(&add_secret);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
local_ts = linked_list_create();
|
local_ts = linked_list_create();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2016-2024 Tobias Brunner
|
||||||
* Copyright (C) 2008 Martin Willi
|
* Copyright (C) 2008 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@@ -23,7 +24,7 @@
|
|||||||
#include <processing/jobs/adopt_children_job.h>
|
#include <processing/jobs/adopt_children_job.h>
|
||||||
|
|
||||||
typedef struct private_ha_dispatcher_t private_ha_dispatcher_t;
|
typedef struct private_ha_dispatcher_t private_ha_dispatcher_t;
|
||||||
typedef struct ha_diffie_hellman_t ha_diffie_hellman_t;
|
typedef struct ha_key_exchange_t ha_key_exchange_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private data of an ha_dispatcher_t object.
|
* Private data of an ha_dispatcher_t object.
|
||||||
@@ -62,14 +63,14 @@ struct private_ha_dispatcher_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DH implementation for HA synced DH values
|
* KE implementation for HA synced KE shared secrets
|
||||||
*/
|
*/
|
||||||
struct ha_diffie_hellman_t {
|
struct ha_key_exchange_t {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements key_exchange_t
|
* Public interface
|
||||||
*/
|
*/
|
||||||
key_exchange_t dh;
|
key_exchange_t ke;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared secret
|
* Shared secret
|
||||||
@@ -77,49 +78,73 @@ struct ha_diffie_hellman_t {
|
|||||||
chunk_t secret;
|
chunk_t secret;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Own public value
|
* Own public value (IKEv1 only)
|
||||||
*/
|
*/
|
||||||
chunk_t pub;
|
chunk_t pub;
|
||||||
};
|
};
|
||||||
|
|
||||||
METHOD(key_exchange_t, dh_get_shared_secret, bool,
|
METHOD(key_exchange_t, ke_get_shared_secret, bool,
|
||||||
ha_diffie_hellman_t *this, chunk_t *secret)
|
ha_key_exchange_t *this, chunk_t *secret)
|
||||||
{
|
{
|
||||||
*secret = chunk_clone(this->secret);
|
*secret = chunk_clone(this->secret);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(key_exchange_t, dh_get_public_key, bool,
|
METHOD(key_exchange_t, ke_get_public_key, bool,
|
||||||
ha_diffie_hellman_t *this, chunk_t *value)
|
ha_key_exchange_t *this, chunk_t *value)
|
||||||
{
|
{
|
||||||
*value = chunk_clone(this->pub);
|
*value = chunk_clone(this->pub);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
METHOD(key_exchange_t, dh_destroy, void,
|
METHOD(key_exchange_t, ke_destroy, void,
|
||||||
ha_diffie_hellman_t *this)
|
ha_key_exchange_t *this)
|
||||||
{
|
{
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a HA synced DH implementation
|
* Create a HA synced KE implementation
|
||||||
*/
|
*/
|
||||||
static key_exchange_t *ha_diffie_hellman_create(chunk_t secret, chunk_t pub)
|
static key_exchange_t *ha_key_exchange_create(chunk_t secret, chunk_t pub)
|
||||||
{
|
{
|
||||||
ha_diffie_hellman_t *this;
|
ha_key_exchange_t *this;
|
||||||
|
|
||||||
INIT(this,
|
INIT(this,
|
||||||
.dh = {
|
.ke = {
|
||||||
.get_shared_secret = _dh_get_shared_secret,
|
.get_shared_secret = _ke_get_shared_secret,
|
||||||
.get_public_key = _dh_get_public_key,
|
.get_public_key = _ke_get_public_key,
|
||||||
.destroy = _dh_destroy,
|
.destroy = _ke_destroy,
|
||||||
},
|
},
|
||||||
.secret = secret,
|
.secret = secret,
|
||||||
.pub = pub,
|
.pub = pub,
|
||||||
);
|
);
|
||||||
|
|
||||||
return &this->dh;
|
return &this->ke;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given KE methods to a proposal
|
||||||
|
*/
|
||||||
|
static void add_ke_methods_to_proposal(proposal_t *proposal, uint16_t ke_alg,
|
||||||
|
chunk_t add_kes)
|
||||||
|
{
|
||||||
|
int i, count;
|
||||||
|
|
||||||
|
if (ke_alg)
|
||||||
|
{
|
||||||
|
proposal->add_algorithm(proposal, KEY_EXCHANGE_METHOD, ke_alg, 0);
|
||||||
|
}
|
||||||
|
count = min(add_kes.len / sizeof(uint16_t), MAX_ADDITIONAL_KEY_EXCHANGES);
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
ke_alg = ntohs(((uint16_t*)add_kes.ptr)[i]);
|
||||||
|
if (ke_alg)
|
||||||
|
{
|
||||||
|
proposal->add_algorithm(proposal, i + ADDITIONAL_KEY_EXCHANGE_1,
|
||||||
|
ke_alg, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,9 +158,10 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||||||
ike_sa_t *ike_sa = NULL, *old_sa = NULL;
|
ike_sa_t *ike_sa = NULL, *old_sa = NULL;
|
||||||
ike_version_t version = IKEV2;
|
ike_version_t version = IKEV2;
|
||||||
uint16_t encr = 0, len = 0, integ = 0, prf = 0, old_prf = PRF_UNDEFINED;
|
uint16_t encr = 0, len = 0, integ = 0, prf = 0, old_prf = PRF_UNDEFINED;
|
||||||
uint16_t dh_grp = 0;
|
uint16_t ke_alg = 0;
|
||||||
chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty;
|
chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty;
|
||||||
chunk_t secret = chunk_empty, old_skd = chunk_empty;
|
chunk_t secret = chunk_empty, old_skd = chunk_empty;
|
||||||
|
chunk_t add_secret = chunk_empty, add_kes = chunk_empty;
|
||||||
chunk_t dh_local = chunk_empty, dh_remote = chunk_empty, psk = chunk_empty;
|
chunk_t dh_local = chunk_empty, dh_remote = chunk_empty, psk = chunk_empty;
|
||||||
host_t *other = NULL;
|
host_t *other = NULL;
|
||||||
bool ok = FALSE;
|
bool ok = FALSE;
|
||||||
@@ -147,8 +173,13 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||||||
switch (attribute)
|
switch (attribute)
|
||||||
{
|
{
|
||||||
case HA_IKE_ID:
|
case HA_IKE_ID:
|
||||||
ike_sa = ike_sa_create(value.ike_sa_id,
|
ike_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
|
||||||
|
value.ike_sa_id);
|
||||||
|
if (!ike_sa)
|
||||||
|
{
|
||||||
|
ike_sa = ike_sa_create(value.ike_sa_id,
|
||||||
value.ike_sa_id->is_initiator(value.ike_sa_id), version);
|
value.ike_sa_id->is_initiator(value.ike_sa_id), version);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case HA_IKE_REKEY_ID:
|
case HA_IKE_REKEY_ID:
|
||||||
old_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
|
old_sa = charon->ike_sa_manager->checkout(charon->ike_sa_manager,
|
||||||
@@ -169,6 +200,9 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||||||
case HA_SECRET:
|
case HA_SECRET:
|
||||||
secret = value.chunk;
|
secret = value.chunk;
|
||||||
break;
|
break;
|
||||||
|
case HA_ADD_SECRET:
|
||||||
|
add_secret = value.chunk;
|
||||||
|
break;
|
||||||
case HA_LOCAL_DH:
|
case HA_LOCAL_DH:
|
||||||
dh_local = value.chunk;
|
dh_local = value.chunk;
|
||||||
break;
|
break;
|
||||||
@@ -196,11 +230,15 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||||||
case HA_ALG_OLD_PRF:
|
case HA_ALG_OLD_PRF:
|
||||||
old_prf = value.u16;
|
old_prf = value.u16;
|
||||||
break;
|
break;
|
||||||
case HA_ALG_DH:
|
case HA_ALG_KE:
|
||||||
dh_grp = value.u16;
|
ke_alg = value.u16;
|
||||||
|
break;
|
||||||
|
case HA_ALG_ADD_KES:
|
||||||
|
add_kes = value.chunk;
|
||||||
break;
|
break;
|
||||||
case HA_AUTH_METHOD:
|
case HA_AUTH_METHOD:
|
||||||
method = value.u16;
|
method = value.u16;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -210,38 +248,52 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||||||
if (ike_sa)
|
if (ike_sa)
|
||||||
{
|
{
|
||||||
proposal_t *proposal;
|
proposal_t *proposal;
|
||||||
key_exchange_t *dh;
|
key_exchange_t *ke;
|
||||||
|
array_t *kes = NULL;
|
||||||
|
bool key_update = FALSE;
|
||||||
|
|
||||||
proposal = proposal_create(PROTO_IKE, 0);
|
proposal = ike_sa->get_proposal(ike_sa);
|
||||||
if (integ)
|
if (!proposal)
|
||||||
{
|
{
|
||||||
proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, integ, 0);
|
proposal = proposal_create(PROTO_IKE, 0);
|
||||||
|
if (integ)
|
||||||
|
{
|
||||||
|
proposal->add_algorithm(proposal, INTEGRITY_ALGORITHM, integ, 0);
|
||||||
|
}
|
||||||
|
if (encr)
|
||||||
|
{
|
||||||
|
proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, len);
|
||||||
|
}
|
||||||
|
if (prf)
|
||||||
|
{
|
||||||
|
proposal->add_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, prf, 0);
|
||||||
|
}
|
||||||
|
add_ke_methods_to_proposal(proposal, ke_alg, add_kes);
|
||||||
}
|
}
|
||||||
if (encr)
|
else
|
||||||
{
|
{
|
||||||
proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, len);
|
key_update = TRUE;
|
||||||
}
|
|
||||||
if (prf)
|
|
||||||
{
|
|
||||||
proposal->add_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, prf, 0);
|
|
||||||
}
|
|
||||||
if (dh_grp)
|
|
||||||
{
|
|
||||||
proposal->add_algorithm(proposal, KEY_EXCHANGE_METHOD, dh_grp, 0);
|
|
||||||
}
|
}
|
||||||
charon->bus->set_sa(charon->bus, ike_sa);
|
charon->bus->set_sa(charon->bus, ike_sa);
|
||||||
dh = ha_diffie_hellman_create(secret, dh_local);
|
ke = ha_key_exchange_create(secret, dh_local);
|
||||||
|
array_insert_create(&kes, ARRAY_HEAD, ke);
|
||||||
if (ike_sa->get_version(ike_sa) == IKEV2)
|
if (ike_sa->get_version(ike_sa) == IKEV2)
|
||||||
{
|
{
|
||||||
keymat_v2_t *keymat_v2 = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
|
keymat_v2_t *keymat_v2 = (keymat_v2_t*)ike_sa->get_keymat(ike_sa);
|
||||||
array_t *kes = NULL;
|
|
||||||
|
|
||||||
array_insert_create(&kes, ARRAY_HEAD, dh);
|
if (add_secret.len)
|
||||||
|
{
|
||||||
|
ke = ha_key_exchange_create(add_secret, chunk_empty);
|
||||||
|
array_insert_create(&kes, ARRAY_TAIL, ke);
|
||||||
|
}
|
||||||
|
if (key_update)
|
||||||
|
{
|
||||||
|
old_prf = keymat_v2->get_skd(keymat_v2, &old_skd);
|
||||||
|
}
|
||||||
ok = keymat_v2->derive_ike_keys(keymat_v2, proposal, kes, nonce_i,
|
ok = keymat_v2->derive_ike_keys(keymat_v2, proposal, kes, nonce_i,
|
||||||
nonce_r, ike_sa->get_id(ike_sa), old_prf, old_skd);
|
nonce_r, ike_sa->get_id(ike_sa), old_prf, old_skd);
|
||||||
array_destroy(kes);
|
|
||||||
}
|
}
|
||||||
if (ike_sa->get_version(ike_sa) == IKEV1)
|
else if (ike_sa->get_version(ike_sa) == IKEV1)
|
||||||
{
|
{
|
||||||
keymat_v1_t *keymat_v1 = (keymat_v1_t*)ike_sa->get_keymat(ike_sa);
|
keymat_v1_t *keymat_v1 = (keymat_v1_t*)ike_sa->get_keymat(ike_sa);
|
||||||
shared_key_t *shared = NULL;
|
shared_key_t *shared = NULL;
|
||||||
@@ -254,12 +306,12 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||||||
if (keymat_v1->create_hasher(keymat_v1, proposal))
|
if (keymat_v1->create_hasher(keymat_v1, proposal))
|
||||||
{
|
{
|
||||||
ok = keymat_v1->derive_ike_keys(keymat_v1, proposal,
|
ok = keymat_v1->derive_ike_keys(keymat_v1, proposal,
|
||||||
dh, dh_remote, nonce_i, nonce_r,
|
ke, dh_remote, nonce_i, nonce_r,
|
||||||
ike_sa->get_id(ike_sa), method, shared);
|
ike_sa->get_id(ike_sa), method, shared);
|
||||||
}
|
}
|
||||||
DESTROY_IF(shared);
|
DESTROY_IF(shared);
|
||||||
}
|
}
|
||||||
dh->destroy(dh);
|
array_destroy_offset(kes, offsetof(key_exchange_t, destroy));
|
||||||
if (ok)
|
if (ok)
|
||||||
{
|
{
|
||||||
if (old_sa)
|
if (old_sa)
|
||||||
@@ -278,8 +330,11 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||||||
ike_sa->set_other_host(ike_sa, other);
|
ike_sa->set_other_host(ike_sa, other);
|
||||||
other = NULL;
|
other = NULL;
|
||||||
}
|
}
|
||||||
ike_sa->set_state(ike_sa, IKE_CONNECTING);
|
if (!key_update)
|
||||||
ike_sa->set_proposal(ike_sa, proposal);
|
{
|
||||||
|
ike_sa->set_state(ike_sa, IKE_CONNECTING);
|
||||||
|
ike_sa->set_proposal(ike_sa, proposal);
|
||||||
|
}
|
||||||
this->cache->cache(this->cache, ike_sa, message);
|
this->cache->cache(this->cache, ike_sa, message);
|
||||||
message = NULL;
|
message = NULL;
|
||||||
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
charon->ike_sa_manager->checkin(charon->ike_sa_manager, ike_sa);
|
||||||
@@ -287,10 +342,21 @@ static void process_ike_add(private_ha_dispatcher_t *this, ha_message_t *message
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG1(DBG_IKE, "HA keymat derivation failed");
|
DBG1(DBG_IKE, "HA keymat derivation failed");
|
||||||
ike_sa->destroy(ike_sa);
|
if (key_update)
|
||||||
|
{
|
||||||
|
charon->ike_sa_manager->checkin_and_destroy(charon->ike_sa_manager,
|
||||||
|
ike_sa);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ike_sa->destroy(ike_sa);
|
||||||
|
charon->bus->set_sa(charon->bus, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!key_update)
|
||||||
|
{
|
||||||
|
proposal->destroy(proposal);
|
||||||
}
|
}
|
||||||
charon->bus->set_sa(charon->bus, NULL);
|
|
||||||
proposal->destroy(proposal);
|
|
||||||
}
|
}
|
||||||
if (old_sa)
|
if (old_sa)
|
||||||
{
|
{
|
||||||
@@ -659,12 +725,13 @@ static void process_child_add(private_ha_dispatcher_t *this,
|
|||||||
uint32_t inbound_spi = 0, outbound_spi = 0;
|
uint32_t inbound_spi = 0, outbound_spi = 0;
|
||||||
uint16_t inbound_cpi = 0, outbound_cpi = 0;
|
uint16_t inbound_cpi = 0, outbound_cpi = 0;
|
||||||
uint8_t mode = MODE_TUNNEL, ipcomp = 0;
|
uint8_t mode = MODE_TUNNEL, ipcomp = 0;
|
||||||
uint16_t encr = 0, integ = 0, len = 0, dh_grp = 0;
|
uint16_t encr = 0, integ = 0, len = 0, ke_alg = 0;
|
||||||
uint16_t esn = NO_EXT_SEQ_NUMBERS;
|
uint16_t esn = NO_EXT_SEQ_NUMBERS;
|
||||||
chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty, secret = chunk_empty;
|
chunk_t nonce_i = chunk_empty, nonce_r = chunk_empty, secret = chunk_empty;
|
||||||
|
chunk_t add_secret = chunk_empty, add_kes = chunk_empty;
|
||||||
chunk_t encr_i, integ_i, encr_r, integ_r;
|
chunk_t encr_i, integ_i, encr_r, integ_r;
|
||||||
linked_list_t *local_ts, *remote_ts;
|
linked_list_t *local_ts, *remote_ts;
|
||||||
key_exchange_t *dh = NULL;
|
key_exchange_t *ke = NULL;
|
||||||
array_t *kes = NULL;
|
array_t *kes = NULL;
|
||||||
|
|
||||||
enumerator = message->create_attribute_enumerator(message);
|
enumerator = message->create_attribute_enumerator(message);
|
||||||
@@ -709,8 +776,11 @@ static void process_child_add(private_ha_dispatcher_t *this,
|
|||||||
case HA_ALG_INTEG:
|
case HA_ALG_INTEG:
|
||||||
integ = value.u16;
|
integ = value.u16;
|
||||||
break;
|
break;
|
||||||
case HA_ALG_DH:
|
case HA_ALG_KE:
|
||||||
dh_grp = value.u16;
|
ke_alg = value.u16;
|
||||||
|
break;
|
||||||
|
case HA_ALG_ADD_KES:
|
||||||
|
add_kes = value.chunk;
|
||||||
break;
|
break;
|
||||||
case HA_ESN:
|
case HA_ESN:
|
||||||
esn = value.u16;
|
esn = value.u16;
|
||||||
@@ -724,6 +794,9 @@ static void process_child_add(private_ha_dispatcher_t *this,
|
|||||||
case HA_SECRET:
|
case HA_SECRET:
|
||||||
secret = value.chunk;
|
secret = value.chunk;
|
||||||
break;
|
break;
|
||||||
|
case HA_ADD_SECRET:
|
||||||
|
add_secret = value.chunk;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -763,15 +836,18 @@ static void process_child_add(private_ha_dispatcher_t *this,
|
|||||||
{
|
{
|
||||||
proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, len);
|
proposal->add_algorithm(proposal, ENCRYPTION_ALGORITHM, encr, len);
|
||||||
}
|
}
|
||||||
if (dh_grp)
|
add_ke_methods_to_proposal(proposal, ke_alg, add_kes);
|
||||||
{
|
|
||||||
proposal->add_algorithm(proposal, KEY_EXCHANGE_METHOD, dh_grp, 0);
|
|
||||||
}
|
|
||||||
proposal->add_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, esn, 0);
|
proposal->add_algorithm(proposal, EXTENDED_SEQUENCE_NUMBERS, esn, 0);
|
||||||
|
|
||||||
if (secret.len)
|
if (secret.len)
|
||||||
{
|
{
|
||||||
dh = ha_diffie_hellman_create(secret, chunk_empty);
|
ke = ha_key_exchange_create(secret, chunk_empty);
|
||||||
array_insert_create(&kes, ARRAY_HEAD, dh);
|
array_insert_create(&kes, ARRAY_HEAD, ke);
|
||||||
|
}
|
||||||
|
if (add_secret.len)
|
||||||
|
{
|
||||||
|
ke = ha_key_exchange_create(add_secret, chunk_empty);
|
||||||
|
array_insert_create(&kes, ARRAY_TAIL, ke);
|
||||||
}
|
}
|
||||||
if (ike_sa->get_version(ike_sa) == IKEV2)
|
if (ike_sa->get_version(ike_sa) == IKEV2)
|
||||||
{
|
{
|
||||||
@@ -780,7 +856,7 @@ static void process_child_add(private_ha_dispatcher_t *this,
|
|||||||
ok = keymat_v2->derive_child_keys(keymat_v2, proposal, kes,
|
ok = keymat_v2->derive_child_keys(keymat_v2, proposal, kes,
|
||||||
nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r);
|
nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r);
|
||||||
}
|
}
|
||||||
if (ike_sa->get_version(ike_sa) == IKEV1)
|
else if (ike_sa->get_version(ike_sa) == IKEV1)
|
||||||
{
|
{
|
||||||
keymat_v1_t *keymat_v1 = (keymat_v1_t*)ike_sa->get_keymat(ike_sa);
|
keymat_v1_t *keymat_v1 = (keymat_v1_t*)ike_sa->get_keymat(ike_sa);
|
||||||
uint32_t spi_i, spi_r;
|
uint32_t spi_i, spi_r;
|
||||||
@@ -788,11 +864,10 @@ static void process_child_add(private_ha_dispatcher_t *this,
|
|||||||
spi_i = initiator ? inbound_spi : outbound_spi;
|
spi_i = initiator ? inbound_spi : outbound_spi;
|
||||||
spi_r = initiator ? outbound_spi : inbound_spi;
|
spi_r = initiator ? outbound_spi : inbound_spi;
|
||||||
|
|
||||||
ok = keymat_v1->derive_child_keys(keymat_v1, proposal, dh, spi_i, spi_r,
|
ok = keymat_v1->derive_child_keys(keymat_v1, proposal, ke, spi_i, spi_r,
|
||||||
nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r);
|
nonce_i, nonce_r, &encr_i, &integ_i, &encr_r, &integ_r);
|
||||||
}
|
}
|
||||||
array_destroy(kes);
|
array_destroy_offset(kes, offsetof(key_exchange_t, destroy));
|
||||||
DESTROY_IF(dh);
|
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
DBG1(DBG_CHD, "HA CHILD_SA key derivation failed");
|
DBG1(DBG_CHD, "HA CHILD_SA key derivation failed");
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2024 Tobias Brunner
|
||||||
* Copyright (C) 2008 Martin Willi
|
* Copyright (C) 2008 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@@ -97,8 +98,7 @@ METHOD(listener_t, ike_keys, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (!key_exchange_concat_secrets(kes, &secret, &add_secret) ||
|
if (!key_exchange_concat_secrets(kes, &secret, &add_secret) ||
|
||||||
!array_get(kes, ARRAY_HEAD, &ke) ||
|
!array_get(kes, ARRAY_HEAD, &ke))
|
||||||
add_secret.len > 0)
|
|
||||||
{
|
{
|
||||||
chunk_clear(&secret);
|
chunk_clear(&secret);
|
||||||
chunk_clear(&add_secret);
|
chunk_clear(&add_secret);
|
||||||
@@ -109,7 +109,7 @@ METHOD(listener_t, ike_keys, bool,
|
|||||||
m->add_attribute(m, HA_IKE_VERSION, ike_sa->get_version(ike_sa));
|
m->add_attribute(m, HA_IKE_VERSION, ike_sa->get_version(ike_sa));
|
||||||
m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
|
m->add_attribute(m, HA_IKE_ID, ike_sa->get_id(ike_sa));
|
||||||
|
|
||||||
if (rekey && rekey->get_version(rekey) == IKEV2)
|
if (rekey && rekey != ike_sa && rekey->get_version(rekey) == IKEV2)
|
||||||
{
|
{
|
||||||
chunk_t skd;
|
chunk_t skd;
|
||||||
keymat_v2_t *keymat;
|
keymat_v2_t *keymat;
|
||||||
@@ -119,32 +119,37 @@ METHOD(listener_t, ike_keys, bool,
|
|||||||
m->add_attribute(m, HA_ALG_OLD_PRF, keymat->get_skd(keymat, &skd));
|
m->add_attribute(m, HA_ALG_OLD_PRF, keymat->get_skd(keymat, &skd));
|
||||||
m->add_attribute(m, HA_OLD_SKD, skd);
|
m->add_attribute(m, HA_OLD_SKD, skd);
|
||||||
}
|
}
|
||||||
|
if (rekey != ike_sa)
|
||||||
proposal = ike_sa->get_proposal(ike_sa);
|
|
||||||
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &len))
|
|
||||||
{
|
{
|
||||||
m->add_attribute(m, HA_ALG_ENCR, alg);
|
/* only sync the proposal for initial key derivation and rekeyings */
|
||||||
if (len)
|
proposal = ike_sa->get_proposal(ike_sa);
|
||||||
|
if (proposal->get_algorithm(proposal, ENCRYPTION_ALGORITHM, &alg, &len))
|
||||||
{
|
{
|
||||||
m->add_attribute(m, HA_ALG_ENCR_LEN, len);
|
m->add_attribute(m, HA_ALG_ENCR, alg);
|
||||||
|
if (len)
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_ALG_ENCR_LEN, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
|
||||||
if (proposal->get_algorithm(proposal, INTEGRITY_ALGORITHM, &alg, NULL))
|
{
|
||||||
{
|
m->add_attribute(m, HA_ALG_INTEG, alg);
|
||||||
m->add_attribute(m, HA_ALG_INTEG, alg);
|
}
|
||||||
}
|
if (proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
|
||||||
if (proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &alg, NULL))
|
{
|
||||||
{
|
m->add_attribute(m, HA_ALG_PRF, alg);
|
||||||
m->add_attribute(m, HA_ALG_PRF, alg);
|
}
|
||||||
}
|
m->add_key_exchange_methods(m, proposal);
|
||||||
if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &alg, NULL))
|
|
||||||
{
|
|
||||||
m->add_attribute(m, HA_ALG_DH, alg);
|
|
||||||
}
|
}
|
||||||
m->add_attribute(m, HA_NONCE_I, nonce_i);
|
m->add_attribute(m, HA_NONCE_I, nonce_i);
|
||||||
m->add_attribute(m, HA_NONCE_R, nonce_r);
|
m->add_attribute(m, HA_NONCE_R, nonce_r);
|
||||||
m->add_attribute(m, HA_SECRET, secret);
|
m->add_attribute(m, HA_SECRET, secret);
|
||||||
chunk_clear(&secret);
|
chunk_clear(&secret);
|
||||||
|
if (add_secret.len)
|
||||||
|
{
|
||||||
|
m->add_attribute(m, HA_ADD_SECRET, add_secret);
|
||||||
|
chunk_clear(&add_secret);
|
||||||
|
}
|
||||||
if (ike_sa->get_version(ike_sa) == IKEV1)
|
if (ike_sa->get_version(ike_sa) == IKEV1)
|
||||||
{
|
{
|
||||||
if (ke->get_public_key(ke, &secret))
|
if (ke->get_public_key(ke, &secret))
|
||||||
@@ -421,4 +426,3 @@ ha_ike_t *ha_ike_create(ha_socket_t *socket, ha_tunnel_t *tunnel,
|
|||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2024 Tobias Brunner
|
||||||
* Copyright (C) 2008 Martin Willi
|
* Copyright (C) 2008 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@@ -231,7 +232,7 @@ METHOD(ha_message_t, add_attribute, void,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* uint16_t */
|
/* uint16_t */
|
||||||
case HA_ALG_DH:
|
case HA_ALG_KE:
|
||||||
case HA_ALG_PRF:
|
case HA_ALG_PRF:
|
||||||
case HA_ALG_OLD_PRF:
|
case HA_ALG_OLD_PRF:
|
||||||
case HA_ALG_ENCR:
|
case HA_ALG_ENCR:
|
||||||
@@ -270,11 +271,13 @@ METHOD(ha_message_t, add_attribute, void,
|
|||||||
case HA_NONCE_I:
|
case HA_NONCE_I:
|
||||||
case HA_NONCE_R:
|
case HA_NONCE_R:
|
||||||
case HA_SECRET:
|
case HA_SECRET:
|
||||||
|
case HA_ADD_SECRET:
|
||||||
case HA_LOCAL_DH:
|
case HA_LOCAL_DH:
|
||||||
case HA_REMOTE_DH:
|
case HA_REMOTE_DH:
|
||||||
case HA_PSK:
|
case HA_PSK:
|
||||||
case HA_IV:
|
case HA_IV:
|
||||||
case HA_OLD_SKD:
|
case HA_OLD_SKD:
|
||||||
|
case HA_ALG_ADD_KES:
|
||||||
{
|
{
|
||||||
chunk_t chunk;
|
chunk_t chunk;
|
||||||
|
|
||||||
@@ -318,6 +321,36 @@ METHOD(ha_message_t, add_attribute, void,
|
|||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
METHOD(ha_message_t, add_key_exchange_methods, void,
|
||||||
|
private_ha_message_t *this, proposal_t *proposal)
|
||||||
|
{
|
||||||
|
uint16_t algs[MAX_ADDITIONAL_KEY_EXCHANGES] = {};
|
||||||
|
int i, count = 0;
|
||||||
|
|
||||||
|
if (proposal->get_algorithm(proposal, KEY_EXCHANGE_METHOD, &algs[0], NULL))
|
||||||
|
{
|
||||||
|
add_attribute(this, HA_ALG_KE, algs[0]);
|
||||||
|
algs[0] = 0;
|
||||||
|
}
|
||||||
|
for (i = 0; i < countof(algs); i++)
|
||||||
|
{
|
||||||
|
if (proposal->get_algorithm(proposal, i + ADDITIONAL_KEY_EXCHANGE_1,
|
||||||
|
&algs[i], NULL))
|
||||||
|
{
|
||||||
|
count = i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count)
|
||||||
|
{
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
algs[i] = htons(algs[i]);
|
||||||
|
}
|
||||||
|
add_attribute(this, HA_ALG_ADD_KES,
|
||||||
|
chunk_create((u_char*)algs, count * sizeof(uint16_t)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attribute enumerator implementation
|
* Attribute enumerator implementation
|
||||||
*/
|
*/
|
||||||
@@ -455,7 +488,7 @@ METHOD(enumerator_t, attribute_enumerate, bool,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
/** uint16_t */
|
/** uint16_t */
|
||||||
case HA_ALG_DH:
|
case HA_ALG_KE:
|
||||||
case HA_ALG_PRF:
|
case HA_ALG_PRF:
|
||||||
case HA_ALG_OLD_PRF:
|
case HA_ALG_OLD_PRF:
|
||||||
case HA_ALG_ENCR:
|
case HA_ALG_ENCR:
|
||||||
@@ -496,11 +529,13 @@ METHOD(enumerator_t, attribute_enumerate, bool,
|
|||||||
case HA_NONCE_I:
|
case HA_NONCE_I:
|
||||||
case HA_NONCE_R:
|
case HA_NONCE_R:
|
||||||
case HA_SECRET:
|
case HA_SECRET:
|
||||||
|
case HA_ADD_SECRET:
|
||||||
case HA_LOCAL_DH:
|
case HA_LOCAL_DH:
|
||||||
case HA_REMOTE_DH:
|
case HA_REMOTE_DH:
|
||||||
case HA_PSK:
|
case HA_PSK:
|
||||||
case HA_IV:
|
case HA_IV:
|
||||||
case HA_OLD_SKD:
|
case HA_OLD_SKD:
|
||||||
|
case HA_ALG_ADD_KES:
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
@@ -626,7 +661,7 @@ METHOD(ha_message_t, get_encoding, chunk_t,
|
|||||||
METHOD(ha_message_t, destroy, void,
|
METHOD(ha_message_t, destroy, void,
|
||||||
private_ha_message_t *this)
|
private_ha_message_t *this)
|
||||||
{
|
{
|
||||||
free(this->buf.ptr);
|
chunk_clear(&this->buf);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -639,6 +674,7 @@ static private_ha_message_t *ha_message_create_generic()
|
|||||||
.public = {
|
.public = {
|
||||||
.get_type = _get_type,
|
.get_type = _get_type,
|
||||||
.add_attribute = _add_attribute,
|
.add_attribute = _add_attribute,
|
||||||
|
.add_key_exchange_methods = _add_key_exchange_methods,
|
||||||
.create_attribute_enumerator = _create_attribute_enumerator,
|
.create_attribute_enumerator = _create_attribute_enumerator,
|
||||||
.get_encoding = _get_encoding,
|
.get_encoding = _get_encoding,
|
||||||
.destroy = _destroy,
|
.destroy = _destroy,
|
||||||
@@ -688,4 +724,3 @@ ha_message_t *ha_message_parse(chunk_t data)
|
|||||||
|
|
||||||
return &this->public;
|
return &this->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
|
* Copyright (C) 2024 Tobias Brunner
|
||||||
* Copyright (C) 2008 Martin Willi
|
* Copyright (C) 2008 Martin Willi
|
||||||
*
|
*
|
||||||
* Copyright (C) secunet Security Networks AG
|
* Copyright (C) secunet Security Networks AG
|
||||||
@@ -26,12 +27,13 @@
|
|||||||
#include <networking/host.h>
|
#include <networking/host.h>
|
||||||
#include <utils/identification.h>
|
#include <utils/identification.h>
|
||||||
#include <sa/ike_sa_id.h>
|
#include <sa/ike_sa_id.h>
|
||||||
|
#include <crypto/proposal/proposal.h>
|
||||||
#include <selectors/traffic_selector.h>
|
#include <selectors/traffic_selector.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Protocol version of this implementation
|
* Protocol version of this implementation
|
||||||
*/
|
*/
|
||||||
#define HA_MESSAGE_VERSION 3
|
#define HA_MESSAGE_VERSION 4
|
||||||
|
|
||||||
typedef struct ha_message_t ha_message_t;
|
typedef struct ha_message_t ha_message_t;
|
||||||
typedef enum ha_message_type_t ha_message_type_t;
|
typedef enum ha_message_type_t ha_message_type_t;
|
||||||
@@ -109,8 +111,10 @@ enum ha_message_attribute_t {
|
|||||||
HA_NONCE_I,
|
HA_NONCE_I,
|
||||||
/** chunk_t, responders nonce */
|
/** chunk_t, responders nonce */
|
||||||
HA_NONCE_R,
|
HA_NONCE_R,
|
||||||
/** chunk_t, diffie hellman shared secret */
|
/** chunk_t, KE shared secret */
|
||||||
HA_SECRET,
|
HA_SECRET,
|
||||||
|
/** chunk_t, optional additional KE shared secret(s) */
|
||||||
|
HA_ADD_SECRET,
|
||||||
/** chunk_t, SKd of old SA if rekeying */
|
/** chunk_t, SKd of old SA if rekeying */
|
||||||
HA_OLD_SKD,
|
HA_OLD_SKD,
|
||||||
/** uint16_t, pseudo random function */
|
/** uint16_t, pseudo random function */
|
||||||
@@ -123,8 +127,10 @@ enum ha_message_attribute_t {
|
|||||||
HA_ALG_ENCR_LEN,
|
HA_ALG_ENCR_LEN,
|
||||||
/** uint16_t, integrity protection algorithm */
|
/** uint16_t, integrity protection algorithm */
|
||||||
HA_ALG_INTEG,
|
HA_ALG_INTEG,
|
||||||
/** uint16_t, DH group */
|
/** uint16_t, KE method */
|
||||||
HA_ALG_DH,
|
HA_ALG_KE,
|
||||||
|
/** chunk_t of uint16_t[], optional additional KE methods (IKEv2 only) */
|
||||||
|
HA_ALG_ADD_KES,
|
||||||
/** uint8_t, IPsec mode, TUNNEL|TRANSPORT|... */
|
/** uint8_t, IPsec mode, TUNNEL|TRANSPORT|... */
|
||||||
HA_IPSEC_MODE,
|
HA_IPSEC_MODE,
|
||||||
/** uint8_t, IPComp protocol */
|
/** uint8_t, IPComp protocol */
|
||||||
@@ -149,9 +155,9 @@ enum ha_message_attribute_t {
|
|||||||
HA_ESN,
|
HA_ESN,
|
||||||
/** uint8_t, IKE version */
|
/** uint8_t, IKE version */
|
||||||
HA_IKE_VERSION,
|
HA_IKE_VERSION,
|
||||||
/** chunk_t, own DH public value */
|
/** chunk_t, own DH public value (IKEv1 only) */
|
||||||
HA_LOCAL_DH,
|
HA_LOCAL_DH,
|
||||||
/** chunk_t, remote DH public value */
|
/** chunk_t, remote DH public value (IKEv1 only) */
|
||||||
HA_REMOTE_DH,
|
HA_REMOTE_DH,
|
||||||
/** chunk_t, shared secret for IKEv1 key derivation */
|
/** chunk_t, shared secret for IKEv1 key derivation */
|
||||||
HA_PSK,
|
HA_PSK,
|
||||||
@@ -197,6 +203,13 @@ struct ha_message_t {
|
|||||||
void (*add_attribute)(ha_message_t *this,
|
void (*add_attribute)(ha_message_t *this,
|
||||||
ha_message_attribute_t attribute, ...);
|
ha_message_attribute_t attribute, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add attributes for key exchange methods in the given proposal.
|
||||||
|
*
|
||||||
|
* @param proposal proposal from which to get key exchange methods
|
||||||
|
*/
|
||||||
|
void (*add_key_exchange_methods)(ha_message_t *this, proposal_t *proposal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an enumerator over all attributes in a message.
|
* Create an enumerator over all attributes in a message.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -33,8 +33,7 @@
|
|||||||
#include <processing/jobs/initiate_tasks_job.h>
|
#include <processing/jobs/initiate_tasks_job.h>
|
||||||
|
|
||||||
/** Maximum number of key exchanges (including the initial one, if any) */
|
/** Maximum number of key exchanges (including the initial one, if any) */
|
||||||
#define MAX_KEY_EXCHANGES (ADDITIONAL_KEY_EXCHANGE_7 - \
|
#define MAX_KEY_EXCHANGES (MAX_ADDITIONAL_KEY_EXCHANGES + 1)
|
||||||
ADDITIONAL_KEY_EXCHANGE_1 + 2)
|
|
||||||
|
|
||||||
typedef struct private_child_create_t private_child_create_t;
|
typedef struct private_child_create_t private_child_create_t;
|
||||||
|
|
||||||
|
|||||||
@@ -52,6 +52,12 @@ enum transform_type_t {
|
|||||||
KEY_DERIVATION_FUNCTION = 262,
|
KEY_DERIVATION_FUNCTION = 262,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of additional key exchanges.
|
||||||
|
*/
|
||||||
|
#define MAX_ADDITIONAL_KEY_EXCHANGES (ADDITIONAL_KEY_EXCHANGE_7 - \
|
||||||
|
ADDITIONAL_KEY_EXCHANGE_1 + 1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* enum names for transform_type_t.
|
* enum names for transform_type_t.
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user