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,
- chunk_t secret, identification_t *id,
- prf_t *prf_skp, prf_t *prf);
-
+ chunk_t secret, identification_t *id,
+ chunk_t skp, prf_t *prf);
/**
* Implementation of authenticator_t.verify.
*/
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 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);
- auth_data = build_shared_key_signature(ike_sa_init, my_nonce, this->msk,
- other_id, this->ike_sa->get_auth_verify(this->ike_sa),
+ if (this->msk.len)
+ { /* 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));
recv_auth_data = auth_payload->get_data(auth_payload);
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 auth_data;
+ chunk_t auth_data, secret;
identification_t *my_id = this->ike_sa->get_my_id(this->ike_sa);
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
my_id, auth_method_names, AUTH_EAP);
-
- auth_data = build_shared_key_signature(ike_sa_init, other_nonce, this->msk,
- my_id, this->ike_sa->get_auth_build(this->ike_sa),
+
+ if (this->msk.len)
+ { /* 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));
*auth_payload = auth_payload_create();
DBG1(DBG_IKE, "EAP method %N succeded, MSK established",
eap_type_names, this->method->get_type(this->method));
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",
- eap_type_names, this->method->get_type(this->method));
- *out = eap_payload_create_code(EAP_FAILURE);
- return FAILED;
+ else
+ {
+ DBG1(DBG_IKE, "EAP method %N succeded, no MSK established",
+ eap_type_names, this->method->get_type(this->method));
+ }
+ *out = eap_payload_create_code(EAP_SUCCESS);
+ return SUCCESS;
case FAILED:
default:
DBG1(DBG_IKE, "EAP method %N failed for peer %D",
if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
{
this->msk = chunk_clone(this->msk);
- return SUCCESS;
}
- DBG1(DBG_IKE, "EAP method %N has no MSK established",
- eap_type_names, this->method->get_type(this->method));
- return FAILED;
+ return SUCCESS;
}
case EAP_FAILURE:
default:
*/
chunk_t build_shared_key_signature(chunk_t ike_sa_init, chunk_t nonce,
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;
- 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>) */
key_pad.ptr = IKEV2_KEY_PAD;
key_pad.len = IKEV2_KEY_PAD_LENGTH;
}
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));
chunk_free(&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));
DBG2(DBG_IKE, "successfully created shared key MAC");
chunk_free(&shared_key);
chunk_t auth_data, octets;
rsa_public_key_t *public_key;
identification_t *other_id;
+ prf_t *prf;
other_id = this->ike_sa->get_other_id(this->ike_sa);
DBG1(DBG_IKE, "no RSA public key found for '%D'", other_id);
return NOT_FOUND;
}
- octets = build_tbs_octets(ike_sa_init, my_nonce, other_id,
- this->ike_sa->get_auth_verify(this->ike_sa));
+ prf = this->ike_sa->get_prf(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);
chunk_free(&octets);
rsa_public_key_t *my_pubkey;
rsa_private_key_t *my_key;
identification_t *my_id;
+ prf_t *prf;
my_id = this->ike_sa->get_my_id(this->ike_sa);
DBG1(DBG_IKE, "authentication of '%D' (myself) with %N",
}
DBG2(DBG_IKE, "matching RSA private key found");
- octets = build_tbs_octets(ike_sa_init, other_nonce, my_id,
- this->ike_sa->get_auth_build(this->ike_sa));
+ prf = this->ike_sa->get_prf(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);
chunk_free(&octets);
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.
}
/**
- * 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;
}
/**
size_t key_size;
crypter_t *crypter_i, *crypter_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)];
chunk_t spi_i = chunk_from_buf(spi_i_buf);
chunk_t spi_r = chunk_from_buf(spi_r_buf);
this->crypter_out = crypter_r;
}
- /* SK_pi/SK_pr used for authentication => prf_auth_i, prf_auth_r */
- proposal->get_algorithm(proposal, PSEUDO_RANDOM_FUNCTION, &algo);
- prf_i = prf_create(algo->algorithm);
- prf_r = prf_create(algo->algorithm);
-
- key_size = prf_i->get_key_size(prf_i);
+ /* SK_pi/SK_pr used for authentication => stored for later */
+ key_size = this->prf->get_key_size(this->prf);
prf_plus->allocate_bytes(prf_plus, key_size, &key);
DBG4(DBG_IKE, "Sk_pi secret %B", &key);
- prf_i->set_key(prf_i, key);
- chunk_free(&key);
-
+ if (initiator)
+ {
+ this->skp_build = key;
+ }
+ else
+ {
+ this->skp_verify = 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)
{
- this->auth_verify = prf_r;
- this->auth_build = prf_i;
+ this->skp_verify = key;
}
else
{
- this->auth_verify = prf_i;
- this->auth_build = prf_r;
+ this->skp_build = key;
}
/* all done, prf_plus not needed anymore */
DESTROY_IF(this->signer_out);
DESTROY_IF(this->prf);
DESTROY_IF(this->child_prf);
- DESTROY_IF(this->auth_verify);
- DESTROY_IF(this->auth_build);
+ chunk_free(&this->skp_verify);
+ chunk_free(&this->skp_build);
if (this->my_virtual_ip)
{
this->public.send_keepalive = (void (*)(ike_sa_t*)) send_keepalive;
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_auth_verify = (prf_t *(*) (ike_sa_t *)) get_auth_verify;
- this->public.get_auth_build = (prf_t *(*) (ike_sa_t *)) get_auth_build;
+ this->public.get_skp_verify = (chunk_t(*) (ike_sa_t *)) get_skp_verify;
+ 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.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->signer_in = NULL;
this->signer_out = NULL;
this->prf = NULL;
- this->auth_verify = NULL;
- this->auth_build = NULL;
+ this->skp_verify = chunk_empty;
+ this->skp_build = chunk_empty;
this->child_prf = NULL;
this->nat_here = FALSE;
this->nat_there = FALSE;
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
* @return pointer to prf_t object
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
* @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
* @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