METHOD(eap_method_t, get_msk, status_t,
private_eap_gtc_t *this, chunk_t *msk)
{
- return FAILED;
+ return NOT_SUPPORTED;
}
METHOD(eap_method_t, get_identifier, uint8_t,
METHOD(eap_method_t, get_msk, status_t,
private_eap_md5_t *this, chunk_t *msk)
{
- return FAILED;
+ return NOT_SUPPORTED;
}
METHOD(eap_method_t, is_mutual, bool,
*out = msk;
return SUCCESS;
}
- return FAILED;
+ /* we assume the selected method did not establish an MSK, if it failed
+ * to establish one, process() would have failed */
+ return NOT_SUPPORTED;
}
METHOD(eap_method_t, get_identifier, uint8_t,
* Not all EAP methods establish a shared secret. For implementations of
* the EAP-Identity method, get_msk() returns the received identity.
*
+ * @note Returning NOT_SUPPORTED is important for implementations of EAP
+ * methods that don't establish an MSK. In particular as client because
+ * key-generating EAP methods MUST fail to process EAP-Success messages if
+ * no MSK is established.
+ *
* @param msk chunk receiving internal stored MSK
* @return
- * - SUCCESS, or
+ * - SUCCESS, if MSK is established
* - FAILED, if MSK not established (yet)
+ * - NOT_SUPPORTED, for non-MSK-establishing methods
*/
status_t (*get_msk) (eap_method_t *this, chunk_t *msk);
this->method->destroy(this->method);
return server_initiate_eap(this, FALSE);
}
- if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
+ switch (this->method->get_msk(this->method, &this->msk))
{
- this->msk = chunk_clone(this->msk);
+ case SUCCESS:
+ this->msk = chunk_clone(this->msk);
+ break;
+ case NOT_SUPPORTED:
+ break;
+ case FAILED:
+ default:
+ DBG1(DBG_IKE, "failed to establish MSK");
+ goto failure;
}
if (vendor)
{
return eap_payload_create_code(EAP_SUCCESS, in->get_identifier(in));
case FAILED:
default:
+failure:
/* type might have changed for virtual methods */
type = this->method->get_type(this->method, &vendor);
if (vendor)
uint32_t vendor;
auth_cfg_t *cfg;
- if (this->method->get_msk(this->method, &this->msk) == SUCCESS)
+ if (!this->method)
{
- this->msk = chunk_clone(this->msk);
+ DBG1(DBG_IKE, "received unexpected %N",
+ eap_code_names, eap_payload->get_code(eap_payload));
+ return FAILED;
+ }
+ switch (this->method->get_msk(this->method, &this->msk))
+ {
+ case SUCCESS:
+ this->msk = chunk_clone(this->msk);
+ break;
+ case NOT_SUPPORTED:
+ break;
+ case FAILED:
+ default:
+ DBG1(DBG_IKE, "received %N but failed to establish MSK",
+ eap_code_names, eap_payload->get_code(eap_payload));
+ return FAILED;
}
type = this->method->get_type(this->method, &vendor);
if (vendor)