merged changes from eap-aka trunk
This commit is contained in:
@@ -145,6 +145,11 @@ struct private_local_credential_store_t {
|
|||||||
*/
|
*/
|
||||||
linked_list_t *shared_keys;
|
linked_list_t *shared_keys;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* list of EAP keys
|
||||||
|
*/
|
||||||
|
linked_list_t *eap_keys;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* list of key_entry_t's with private keys
|
* list of key_entry_t's with private keys
|
||||||
*/
|
*/
|
||||||
@@ -173,9 +178,9 @@ struct private_local_credential_store_t {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of local_credential_store_t.get_shared_key.
|
* Get a key from a list with shared_key_t's
|
||||||
*/
|
*/
|
||||||
static status_t get_shared_key(private_local_credential_store_t *this,
|
static status_t get_key(linked_list_t *keys,
|
||||||
identification_t *my_id,
|
identification_t *my_id,
|
||||||
identification_t *other_id, chunk_t *secret)
|
identification_t *other_id, chunk_t *secret)
|
||||||
{
|
{
|
||||||
@@ -190,7 +195,7 @@ static status_t get_shared_key(private_local_credential_store_t *this,
|
|||||||
chunk_t found = chunk_empty;
|
chunk_t found = chunk_empty;
|
||||||
shared_key_t *shared_key;
|
shared_key_t *shared_key;
|
||||||
|
|
||||||
iterator_t *iterator = this->shared_keys->create_iterator(this->shared_keys, TRUE);
|
iterator_t *iterator = keys->create_iterator(keys, TRUE);
|
||||||
|
|
||||||
while (iterator->iterate(iterator, (void**)&shared_key))
|
while (iterator->iterate(iterator, (void**)&shared_key))
|
||||||
{
|
{
|
||||||
@@ -240,6 +245,27 @@ static status_t get_shared_key(private_local_credential_store_t *this,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of local_credential_store_t.get_shared_key.
|
||||||
|
*/
|
||||||
|
static status_t get_shared_key(private_local_credential_store_t *this,
|
||||||
|
identification_t *my_id,
|
||||||
|
identification_t *other_id, chunk_t *secret)
|
||||||
|
{
|
||||||
|
return get_key(this->shared_keys, my_id, other_id, secret);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of local_credential_store_t.get_eap_key.
|
||||||
|
*/
|
||||||
|
static status_t get_eap_key(private_local_credential_store_t *this,
|
||||||
|
identification_t *my_id,
|
||||||
|
identification_t *other_id, chunk_t *secret)
|
||||||
|
{
|
||||||
|
return get_key(this->eap_keys, my_id, other_id, secret);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of credential_store_t.get_certificate.
|
* Implementation of credential_store_t.get_certificate.
|
||||||
*/
|
*/
|
||||||
@@ -1167,6 +1193,7 @@ static void load_secrets(private_local_credential_store_t *this)
|
|||||||
while (fetchline(&src, &line))
|
while (fetchline(&src, &line))
|
||||||
{
|
{
|
||||||
chunk_t ids, token;
|
chunk_t ids, token;
|
||||||
|
bool is_eap = FALSE;
|
||||||
|
|
||||||
line_nr++;
|
line_nr++;
|
||||||
|
|
||||||
@@ -1240,7 +1267,8 @@ static void load_secrets(private_local_credential_store_t *this)
|
|||||||
this->private_keys->insert_last(this->private_keys, (void*)key);
|
this->private_keys->insert_last(this->private_keys, (void*)key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (match("PSK", &token))
|
else if ((match("PSK", &token)) ||
|
||||||
|
(match("EAP", &token) && (is_eap = TRUE)))
|
||||||
{
|
{
|
||||||
shared_key_t *shared_key;
|
shared_key_t *shared_key;
|
||||||
|
|
||||||
@@ -1253,22 +1281,24 @@ static void load_secrets(private_local_credential_store_t *this)
|
|||||||
DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
|
DBG1(DBG_CFG, "line %d: malformed secret: %s", line_nr, ugh);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ids.len > 0)
|
DBG1(DBG_CFG, " loading %s key for %s",
|
||||||
{
|
is_eap ? "EAP" : "shared",
|
||||||
DBG1(DBG_CFG, " loading shared key for %s", ids.ptr);
|
ids.len > 0 ? (char*)ids.ptr : "%any");
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
DBG1(DBG_CFG, " loading shared key for %%any");
|
|
||||||
}
|
|
||||||
|
|
||||||
DBG4(DBG_CFG, " secret:", secret);
|
DBG4(DBG_CFG, " secret:", secret);
|
||||||
|
|
||||||
shared_key = shared_key_create(secret);
|
shared_key = shared_key_create(secret);
|
||||||
if (shared_key)
|
if (shared_key)
|
||||||
{
|
{
|
||||||
this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
|
if (is_eap)
|
||||||
|
{
|
||||||
|
this->eap_keys->insert_last(this->eap_keys, (void*)shared_key);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this->shared_keys->insert_last(this->shared_keys, (void*)shared_key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (ids.len > 0)
|
while (ids.len > 0)
|
||||||
{
|
{
|
||||||
@@ -1311,7 +1341,7 @@ static void load_secrets(private_local_credential_store_t *this)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DBG1(DBG_CFG, "line %d: token must be either "
|
DBG1(DBG_CFG, "line %d: token must be either "
|
||||||
"RSA, PSK, or PIN", line_nr, token.len);
|
"RSA, PSK, EAP, or PIN", line_nr, token.len);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1334,6 +1364,7 @@ static void destroy(private_local_credential_store_t *this)
|
|||||||
this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
|
this->ca_infos->destroy_offset(this->ca_infos, offsetof(ca_info_t, destroy));
|
||||||
this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
|
this->private_keys->destroy_offset(this->private_keys, offsetof(rsa_private_key_t, destroy));
|
||||||
this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
|
this->shared_keys->destroy_function(this->shared_keys, (void*)shared_key_destroy);
|
||||||
|
this->eap_keys->destroy_function(this->eap_keys, (void*)shared_key_destroy);
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1345,6 +1376,7 @@ local_credential_store_t * local_credential_store_create(bool strict)
|
|||||||
private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
|
private_local_credential_store_t *this = malloc_thing(private_local_credential_store_t);
|
||||||
|
|
||||||
this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
|
this->public.credential_store.get_shared_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_shared_key;
|
||||||
|
this->public.credential_store.get_eap_key = (status_t (*) (credential_store_t*,identification_t*,identification_t*,chunk_t*))get_eap_key;
|
||||||
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
|
this->public.credential_store.get_rsa_public_key = (rsa_public_key_t*(*)(credential_store_t*,identification_t*))get_rsa_public_key;
|
||||||
this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
|
this->public.credential_store.get_rsa_private_key = (rsa_private_key_t* (*) (credential_store_t*,rsa_public_key_t*))get_rsa_private_key;
|
||||||
this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
|
this->public.credential_store.has_rsa_private_key = (bool (*) (credential_store_t*,rsa_public_key_t*))has_rsa_private_key;
|
||||||
@@ -1372,6 +1404,7 @@ local_credential_store_t * local_credential_store_create(bool strict)
|
|||||||
|
|
||||||
/* private variables */
|
/* private variables */
|
||||||
this->shared_keys = linked_list_create();
|
this->shared_keys = linked_list_create();
|
||||||
|
this->eap_keys = linked_list_create();
|
||||||
this->private_keys = linked_list_create();
|
this->private_keys = linked_list_create();
|
||||||
this->certs = linked_list_create();
|
this->certs = linked_list_create();
|
||||||
this->auth_certs = linked_list_create();
|
this->auth_certs = linked_list_create();
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ struct private_eap_authenticator_t {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce,
|
extern chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce,
|
||||||
chunk_t secret, identification_t *id,
|
chunk_t secret, identification_t *id,
|
||||||
prf_t *prf);
|
prf_t *prf_skp, prf_t *prf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of authenticator_t.verify.
|
* Implementation of authenticator_t.verify.
|
||||||
@@ -73,10 +73,10 @@ static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init,
|
|||||||
{
|
{
|
||||||
chunk_t auth_data, recv_auth_data;
|
chunk_t auth_data, recv_auth_data;
|
||||||
identification_t *other_id = this->ike_sa->get_other_id(this->ike_sa);
|
identification_t *other_id = this->ike_sa->get_other_id(this->ike_sa);
|
||||||
prf_t *prf = this->ike_sa->get_auth_verify(this->ike_sa);
|
|
||||||
|
|
||||||
auth_data = build_shared_key_signature(ike_sa_init, my_nonce, this->msk,
|
auth_data = build_shared_key_signature(ike_sa_init, my_nonce, this->msk,
|
||||||
other_id, prf);
|
other_id, this->ike_sa->get_auth_verify(this->ike_sa),
|
||||||
|
this->ike_sa->get_prf(this->ike_sa));
|
||||||
|
|
||||||
recv_auth_data = auth_payload->get_data(auth_payload);
|
recv_auth_data = auth_payload->get_data(auth_payload);
|
||||||
if (!chunk_equals(auth_data, recv_auth_data))
|
if (!chunk_equals(auth_data, recv_auth_data))
|
||||||
@@ -105,8 +105,9 @@ static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init,
|
|||||||
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
|
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
|
||||||
my_id, auth_method_names, AUTH_EAP);
|
my_id, auth_method_names, AUTH_EAP);
|
||||||
|
|
||||||
auth_data = build_shared_key_signature(ike_sa_init, other_nonce,
|
auth_data = build_shared_key_signature(ike_sa_init, other_nonce, this->msk,
|
||||||
this->msk, my_id, prf);
|
my_id, this->ike_sa->get_auth_build(this->ike_sa),
|
||||||
|
this->ike_sa->get_prf(this->ike_sa));
|
||||||
|
|
||||||
*auth_payload = auth_payload_create();
|
*auth_payload = auth_payload_create();
|
||||||
(*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
|
(*auth_payload)->set_auth_method(*auth_payload, AUTH_PSK);
|
||||||
|
|||||||
@@ -78,11 +78,11 @@ chunk_t build_tbs_octets(chunk_t ike_sa_init, chunk_t nonce,
|
|||||||
*/
|
*/
|
||||||
chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce,
|
chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce,
|
||||||
chunk_t secret, identification_t *id,
|
chunk_t secret, identification_t *id,
|
||||||
prf_t *prf)
|
prf_t *prf_skp, prf_t *prf)
|
||||||
{
|
{
|
||||||
chunk_t key_pad, key, auth_data, octets;
|
chunk_t key_pad, key, auth_data, octets;
|
||||||
|
|
||||||
octets = build_tbs_octets(ike_sa_init, nonce, id, prf);
|
octets = build_tbs_octets(ike_sa_init, nonce, id, prf_skp);
|
||||||
/* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */
|
/* AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>) */
|
||||||
key_pad.ptr = IKEV2_KEY_PAD;
|
key_pad.ptr = IKEV2_KEY_PAD;
|
||||||
key_pad.len = IKEV2_KEY_PAD_LENGTH;
|
key_pad.len = IKEV2_KEY_PAD_LENGTH;
|
||||||
@@ -121,9 +121,9 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
auth_data = build_shared_key_signature(ike_sa_init, my_nonce,
|
auth_data = build_shared_key_signature(ike_sa_init, my_nonce, shared_key,
|
||||||
shared_key, other_id,
|
other_id, this->ike_sa->get_auth_verify(this->ike_sa),
|
||||||
this->ike_sa->get_auth_verify(this->ike_sa));
|
this->ike_sa->get_prf(this->ike_sa));
|
||||||
chunk_free(&shared_key);
|
chunk_free(&shared_key);
|
||||||
|
|
||||||
recv_auth_data = auth_payload->get_data(auth_payload);
|
recv_auth_data = auth_payload->get_data(auth_payload);
|
||||||
@@ -164,9 +164,9 @@ static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init,
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
auth_data = build_shared_key_signature(ike_sa_init,
|
auth_data = build_shared_key_signature(ike_sa_init, other_nonce, shared_key,
|
||||||
other_nonce, shared_key, my_id,
|
my_id, this->ike_sa->get_auth_build(this->ike_sa),
|
||||||
this->ike_sa->get_auth_build(this->ike_sa));
|
this->ike_sa->get_prf(this->ike_sa));
|
||||||
DBG2(DBG_IKE, "successfully created shared key MAC");
|
DBG2(DBG_IKE, "successfully created shared key MAC");
|
||||||
chunk_free(&shared_key);
|
chunk_free(&shared_key);
|
||||||
*auth_payload = auth_payload_create();
|
*auth_payload = auth_payload_create();
|
||||||
|
|||||||
@@ -58,7 +58,25 @@ struct credential_store_t {
|
|||||||
* - SUCCESS
|
* - SUCCESS
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
status_t (*get_shared_key) (credential_store_t *this, identification_t *my_id, identification_t *other_id, chunk_t *shared_key);
|
status_t (*get_shared_key) (credential_store_t *this, identification_t *my_id,
|
||||||
|
identification_t *other_id, chunk_t *shared_key);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the EAP secret for two specified IDs.
|
||||||
|
*
|
||||||
|
* The returned chunk must be destroyed by the caller after usage.
|
||||||
|
*
|
||||||
|
* @param this calling object
|
||||||
|
* @param my_id my ID identifiying the secret.
|
||||||
|
* @param other_id peer ID identifying the secret.
|
||||||
|
* @param[out] eap_key the EAP secret will be written here
|
||||||
|
* @return
|
||||||
|
* - NOT_FOUND if no preshared secrets for specific ID could be found
|
||||||
|
* - SUCCESS
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
status_t (*get_eap_key) (credential_store_t *this, identification_t *my_id,
|
||||||
|
identification_t *other_id, chunk_t *eap_key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the RSA public key of a specific ID.
|
* @brief Returns the RSA public key of a specific ID.
|
||||||
|
|||||||
Reference in New Issue
Block a user