added support for EAP methods not establishing an MSK

This commit is contained in:
Martin Willi
2007-04-19 12:37:48 +00:00
parent 04a7b6d868
commit 0706c39cda
5 changed files with 84 additions and 68 deletions
@@ -61,21 +61,31 @@ struct private_eap_authenticator_t {
chunk_t msk; chunk_t msk;
}; };
/**
* reuse shared key signature function from PSK authenticator
*/
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_skp, prf_t *prf); chunk_t skp, prf_t *prf);
/** /**
* Implementation of authenticator_t.verify. * Implementation of authenticator_t.verify.
*/ */
static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init, static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init,
chunk_t my_nonce, auth_payload_t *auth_payload) chunk_t my_nonce, auth_payload_t *auth_payload)
{ {
chunk_t auth_data, recv_auth_data; chunk_t auth_data, recv_auth_data, secret;
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);
auth_data = build_shared_key_signature(ike_sa_init, my_nonce, this->msk, if (this->msk.len)
other_id, this->ike_sa->get_auth_verify(this->ike_sa), { /* use MSK if EAP method established one... */
secret = this->msk;
}
else
{ /* ... or use SKp if not */
secret = this->ike_sa->get_skp_verify(this->ike_sa);
}
auth_data = build_shared_key_signature(ike_sa_init, my_nonce, secret,
other_id, this->ike_sa->get_skp_verify(this->ike_sa),
this->ike_sa->get_prf(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);
@@ -98,14 +108,22 @@ static status_t verify(private_eap_authenticator_t *this, chunk_t ike_sa_init,
static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init, static status_t build(private_eap_authenticator_t *this, chunk_t ike_sa_init,
chunk_t other_nonce, auth_payload_t **auth_payload) chunk_t other_nonce, auth_payload_t **auth_payload)
{ {
chunk_t auth_data; chunk_t auth_data, secret;
identification_t *my_id = this->ike_sa->get_my_id(this->ike_sa); identification_t *my_id = this->ike_sa->get_my_id(this->ike_sa);
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, this->msk, if (this->msk.len)
my_id, this->ike_sa->get_auth_build(this->ike_sa), { /* use MSK if EAP method established one... */
secret = this->msk;
}
else
{ /* ... or use SKp if not */
secret = this->ike_sa->get_skp_build(this->ike_sa);
}
auth_data = build_shared_key_signature(ike_sa_init, other_nonce, secret,
my_id, this->ike_sa->get_skp_build(this->ike_sa),
this->ike_sa->get_prf(this->ike_sa)); this->ike_sa->get_prf(this->ike_sa));
*auth_payload = auth_payload_create(); *auth_payload = auth_payload_create();
@@ -233,13 +251,14 @@ static status_t process_server(private_eap_authenticator_t *this,
DBG1(DBG_IKE, "EAP method %N succeded, MSK established", DBG1(DBG_IKE, "EAP method %N succeded, MSK established",
eap_type_names, this->method->get_type(this->method)); eap_type_names, this->method->get_type(this->method));
this->msk = chunk_clone(this->msk); this->msk = chunk_clone(this->msk);
*out = eap_payload_create_code(EAP_SUCCESS);
return SUCCESS;
} }
DBG1(DBG_IKE, "EAP method %N succeded, but no MSK established", else
eap_type_names, this->method->get_type(this->method)); {
*out = eap_payload_create_code(EAP_FAILURE); DBG1(DBG_IKE, "EAP method %N succeded, no MSK established",
return FAILED; eap_type_names, this->method->get_type(this->method));
}
*out = eap_payload_create_code(EAP_SUCCESS);
return SUCCESS;
case FAILED: case FAILED:
default: default:
DBG1(DBG_IKE, "EAP method %N failed for peer %D", DBG1(DBG_IKE, "EAP method %N failed for peer %D",
@@ -290,11 +309,8 @@ static status_t process(private_eap_authenticator_t *this, eap_payload_t *in,
if (this->method->get_msk(this->method, &this->msk) == SUCCESS) if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
{ {
this->msk = chunk_clone(this->msk); this->msk = chunk_clone(this->msk);
return SUCCESS;
} }
DBG1(DBG_IKE, "EAP method %N has no MSK established", return SUCCESS;
eap_type_names, this->method->get_type(this->method));
return FAILED;
} }
case EAP_FAILURE: case EAP_FAILURE:
default: default:
@@ -77,11 +77,12 @@ 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_skp, prf_t *prf) chunk_t 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_skp); prf->set_key(prf, skp);
octets = build_tbs_octets(ike_sa_init, nonce, id, prf);
/* 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,7 +122,7 @@ static status_t verify(private_psk_authenticator_t *this, chunk_t ike_sa_init,
} }
auth_data = build_shared_key_signature(ike_sa_init, my_nonce, shared_key, auth_data = build_shared_key_signature(ike_sa_init, my_nonce, shared_key,
other_id, this->ike_sa->get_auth_verify(this->ike_sa), other_id, this->ike_sa->get_skp_verify(this->ike_sa),
this->ike_sa->get_prf(this->ike_sa)); this->ike_sa->get_prf(this->ike_sa));
chunk_free(&shared_key); chunk_free(&shared_key);
@@ -164,7 +165,7 @@ static status_t build(private_psk_authenticator_t *this, chunk_t ike_sa_init,
} }
auth_data = build_shared_key_signature(ike_sa_init, other_nonce, shared_key, auth_data = build_shared_key_signature(ike_sa_init, other_nonce, shared_key,
my_id, this->ike_sa->get_auth_build(this->ike_sa), my_id, this->ike_sa->get_skp_build(this->ike_sa),
this->ike_sa->get_prf(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);
@@ -62,6 +62,7 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
chunk_t auth_data, octets; chunk_t auth_data, octets;
rsa_public_key_t *public_key; rsa_public_key_t *public_key;
identification_t *other_id; identification_t *other_id;
prf_t *prf;
other_id = this->ike_sa->get_other_id(this->ike_sa); other_id = this->ike_sa->get_other_id(this->ike_sa);
@@ -77,8 +78,9 @@ static status_t verify(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
DBG1(DBG_IKE, "no RSA public key found for '%D'", other_id); DBG1(DBG_IKE, "no RSA public key found for '%D'", other_id);
return NOT_FOUND; return NOT_FOUND;
} }
octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, prf = this->ike_sa->get_prf(this->ike_sa);
this->ike_sa->get_auth_verify(this->ike_sa)); prf->set_key(prf, this->ike_sa->get_skp_verify(this->ike_sa));
octets = build_tbs_octets(ike_sa_init, my_nonce, other_id, prf);
status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data); status = public_key->verify_emsa_pkcs1_signature(public_key, octets, auth_data);
chunk_free(&octets); chunk_free(&octets);
@@ -106,6 +108,7 @@ static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
rsa_public_key_t *my_pubkey; rsa_public_key_t *my_pubkey;
rsa_private_key_t *my_key; rsa_private_key_t *my_key;
identification_t *my_id; identification_t *my_id;
prf_t *prf;
my_id = this->ike_sa->get_my_id(this->ike_sa); my_id = this->ike_sa->get_my_id(this->ike_sa);
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N", DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
@@ -130,8 +133,9 @@ static status_t build(private_rsa_authenticator_t *this, chunk_t ike_sa_init,
} }
DBG2(DBG_IKE, "matching RSA private key found"); DBG2(DBG_IKE, "matching RSA private key found");
octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, prf = this->ike_sa->get_prf(this->ike_sa);
this->ike_sa->get_auth_build(this->ike_sa)); prf->set_key(prf, this->ike_sa->get_skp_build(this->ike_sa));
octets = build_tbs_octets(ike_sa_init, other_nonce, my_id, prf);
status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1, octets, &auth_data); status = my_key->build_emsa_pkcs1_signature(my_key, HASH_SHA1, octets, &auth_data);
chunk_free(&octets); chunk_free(&octets);
+30 -35
View File
@@ -176,14 +176,14 @@ struct private_ike_sa_t {
prf_t *child_prf; prf_t *child_prf;
/** /**
* PRF to build outging authentication data * Key to build outging authentication data (SKp)
*/ */
prf_t *auth_build; chunk_t skp_build;
/** /**
* PRF to verify incoming authentication data * Key to verify incoming authentication data (SKp)
*/ */
prf_t *auth_verify; chunk_t skp_verify;
/** /**
* NAT status of local host. * NAT status of local host.
@@ -1112,19 +1112,19 @@ static prf_t *get_child_prf(private_ike_sa_t *this)
} }
/** /**
* Implementation of ike_sa_t.get_auth_bild * Implementation of ike_sa_t.get_skp_bild
*/ */
static prf_t *get_auth_build(private_ike_sa_t *this) static chunk_t get_skp_build(private_ike_sa_t *this)
{ {
return this->auth_build; return this->skp_build;
} }
/** /**
* Implementation of ike_sa_t.get_auth_verify * Implementation of ike_sa_t.get_skp_verify
*/ */
static prf_t *get_auth_verify(private_ike_sa_t *this) static chunk_t get_skp_verify(private_ike_sa_t *this)
{ {
return this->auth_verify; return this->skp_verify;
} }
/** /**
@@ -1232,7 +1232,6 @@ static status_t derive_keys(private_ike_sa_t *this,
size_t key_size; size_t key_size;
crypter_t *crypter_i, *crypter_r; crypter_t *crypter_i, *crypter_r;
signer_t *signer_i, *signer_r; signer_t *signer_i, *signer_r;
prf_t *prf_i, *prf_r;
u_int8_t spi_i_buf[sizeof(u_int64_t)], spi_r_buf[sizeof(u_int64_t)]; u_int8_t spi_i_buf[sizeof(u_int64_t)], spi_r_buf[sizeof(u_int64_t)];
chunk_t spi_i = chunk_from_buf(spi_i_buf); chunk_t spi_i = chunk_from_buf(spi_i_buf);
chunk_t spi_r = chunk_from_buf(spi_r_buf); chunk_t spi_r = chunk_from_buf(spi_r_buf);
@@ -1373,31 +1372,27 @@ static status_t derive_keys(private_ike_sa_t *this,
this->crypter_out = crypter_r; this->crypter_out = crypter_r;
} }
/* SK_pi/SK_pr used for authentication => prf_auth_i, prf_auth_r */ /* SK_pi/SK_pr used for authentication => stored for later */
proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo); key_size = this->prf->get_key_size(this->prf);
prf_i = prf_create(algo->algorithm);
prf_r = prf_create(algo->algorithm);
key_size = prf_i->get_key_size(prf_i);
prf_plus->allocate_bytes(prf_plus, key_size, &key); prf_plus->allocate_bytes(prf_plus, key_size, &key);
DBG4(DBG_IKE, "Sk_pi secret %B", &key); DBG4(DBG_IKE, "Sk_pi secret %B", &key);
prf_i->set_key(prf_i, key);
chunk_free(&key);
prf_plus->allocate_bytes(prf_plus, key_size, &key);
DBG4(DBG_IKE, "Sk_pr secret %B", &key);
prf_r->set_key(prf_r, key);
chunk_free(&key);
if (initiator) if (initiator)
{ {
this->auth_verify = prf_r; this->skp_build = key;
this->auth_build = prf_i;
} }
else else
{ {
this->auth_verify = prf_i; this->skp_verify = key;
this->auth_build = prf_r; }
prf_plus->allocate_bytes(prf_plus, key_size, &key);
DBG4(DBG_IKE, "Sk_pr secret %B", &key);
if (initiator)
{
this->skp_verify = key;
}
else
{
this->skp_build = key;
} }
/* all done, prf_plus not needed anymore */ /* all done, prf_plus not needed anymore */
@@ -1837,8 +1832,8 @@ static void destroy(private_ike_sa_t *this)
DESTROY_IF(this->signer_out); DESTROY_IF(this->signer_out);
DESTROY_IF(this->prf); DESTROY_IF(this->prf);
DESTROY_IF(this->child_prf); DESTROY_IF(this->child_prf);
DESTROY_IF(this->auth_verify); chunk_free(&this->skp_verify);
DESTROY_IF(this->auth_build); chunk_free(&this->skp_build);
if (this->my_virtual_ip) if (this->my_virtual_ip)
{ {
@@ -1902,8 +1897,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->public.send_keepalive = (void (*)(ike_sa_t*)) send_keepalive; this->public.send_keepalive = (void (*)(ike_sa_t*)) send_keepalive;
this->public.get_prf = (prf_t *(*) (ike_sa_t *)) get_prf; this->public.get_prf = (prf_t *(*) (ike_sa_t *)) get_prf;
this->public.get_child_prf = (prf_t *(*) (ike_sa_t *)) get_child_prf; this->public.get_child_prf = (prf_t *(*) (ike_sa_t *)) get_child_prf;
this->public.get_auth_verify = (prf_t *(*) (ike_sa_t *)) get_auth_verify; this->public.get_skp_verify = (chunk_t(*) (ike_sa_t *)) get_skp_verify;
this->public.get_auth_build = (prf_t *(*) (ike_sa_t *)) get_auth_build; this->public.get_skp_build = (chunk_t(*) (ike_sa_t *)) get_skp_build;
this->public.derive_keys = (status_t (*) (ike_sa_t *,proposal_t*,chunk_t,chunk_t,chunk_t,bool,prf_t*,prf_t*)) derive_keys; this->public.derive_keys = (status_t (*) (ike_sa_t *,proposal_t*,chunk_t,chunk_t,chunk_t,bool,prf_t*,prf_t*)) derive_keys;
this->public.add_child_sa = (void (*) (ike_sa_t*,child_sa_t*)) add_child_sa; this->public.add_child_sa = (void (*) (ike_sa_t*,child_sa_t*)) add_child_sa;
this->public.get_child_sa = (child_sa_t* (*)(ike_sa_t*,protocol_id_t,u_int32_t,bool)) get_child_sa; this->public.get_child_sa = (child_sa_t* (*)(ike_sa_t*,protocol_id_t,u_int32_t,bool)) get_child_sa;
@@ -1935,8 +1930,8 @@ ike_sa_t * ike_sa_create(ike_sa_id_t *ike_sa_id)
this->signer_in = NULL; this->signer_in = NULL;
this->signer_out = NULL; this->signer_out = NULL;
this->prf = NULL; this->prf = NULL;
this->auth_verify = NULL; this->skp_verify = chunk_empty;
this->auth_build = NULL; this->skp_build = chunk_empty;
this->child_prf = NULL; this->child_prf = NULL;
this->nat_here = FALSE; this->nat_here = FALSE;
this->nat_there = FALSE; this->nat_there = FALSE;
+5 -5
View File
@@ -486,7 +486,7 @@ struct ike_sa_t {
bool initiator, prf_t *child_prf, prf_t *old_prf); bool initiator, prf_t *child_prf, prf_t *old_prf);
/** /**
* @brief Get the multi purpose prf. * @brief Get a multi purpose prf for the negotiated PRF function.
* *
* @param this calling object * @param this calling object
* @return pointer to prf_t object * @return pointer to prf_t object
@@ -502,20 +502,20 @@ struct ike_sa_t {
prf_t *(*get_child_prf) (ike_sa_t *this); prf_t *(*get_child_prf) (ike_sa_t *this);
/** /**
* @brief Get the prf to build outgoing authentication data. * @brief Get the key to build outgoing authentication data.
* *
* @param this calling object * @param this calling object
* @return pointer to prf_t object * @return pointer to prf_t object
*/ */
prf_t *(*get_auth_build) (ike_sa_t *this); chunk_t (*get_skp_build) (ike_sa_t *this);
/** /**
* @brief Get the prf to verify incoming authentication data. * @brief Get the key to verify incoming authentication data.
* *
* @param this calling object * @param this calling object
* @return pointer to prf_t object * @return pointer to prf_t object
*/ */
prf_t *(*get_auth_verify) (ike_sa_t *this); chunk_t (*get_skp_verify) (ike_sa_t *this);
/** /**
* @brief Associates a child SA to this IKE SA * @brief Associates a child SA to this IKE SA