Starting EAP sequence
Michel Verhagen
mike at guruce.com
Tue Mar 30 05:53:40 BST 2021
Issue resolved; problem was missing call to eloop_init.
Regards,
Michel Verhagen
On 30/03/2021 17:04, Michel Verhagen wrote:.
> We are running into an issue where calling eapol_sm_init results in a
> write to a null pointer in dl_list_add:
>
> static inline void dl_list_add(struct dl_list *list, struct dl_list
> *item)
> {
> item->next = list->next;
> item->prev = list;
> list->next->prev = item;
> list->next = item;
> }
>
> item->next is null in the above when called from function
> eloop_register_timeout through macro dl_list_for_each in line 273:
>
> /* Maintain timeouts in order of increasing time */
> dl_list_for_each(tmp, &eloop.timeout, struct eloop_timeout,
> list) {
> if (os_reltime_before(&timeout->time, &tmp->time)) {
> dl_list_add(tmp->list.prev, &timeout->list);
> return 0;
> }
> }
>
> #define dl_list_for_each(item, list, type, member) \
> for (item = dl_list_entry((list)->next, type, member); \
> &item->member != (list); \
> item = dl_list_entry(item->member.next, type, member))
>
>
> So, the code is:
>
> for (tmp = dl_list_entry((&loop.timeout)->next, struct
> eloop_timeout, list); \
> &tmp->list != (&loop.timeout); \
> tmp = dl_list_entry(tmp->list.next, struct eloop_timeout,
> list))
>
>
> And eloop.timeout.next is NULL.
>
> We are implementing EAPOL authentication using the hostap eap library
> and eapol state machine code. We only need EAPOL over wired LAN, so no
> WPA or WPS needed. Our initialization looks like this:
>
> if (ERROR_SUCCESS != EAPRegisterMethods())
> break;
>
> os_memset(&_eap_ctx, 0, sizeof(_eap_ctx));
>
> _eap_ctx.eap_config.identity = (u8 *)os_strdup("Identity");
> _eap_ctx.eap_config.identity_len = strlen((const
> char*)_eap_ctx.eap_config.identity);
> _eap_ctx.eap_config.password = (u8 *)os_strdup("password");
> _eap_ctx.eap_config.password_len = strlen((const
> char*)_eap_ctx.eap_config.password);
> _eap_ctx.eap_config.ca_cert = os_strdup("\\Windows\\ca.pem");
> //_eap_ctx.eap_config.ca_path = os_strdup("\\Windows");
> _eap_ctx.eap_config.fragment_size = 1398;
>
> os_memset(&_eap_cb, 0, sizeof(_eap_cb));
> _eap_cb.get_config = peer_get_config;
> _eap_cb.get_bool = (Boolean(__cdecl *)(void *,
> eapol_bool_var))peer_get_bool;
> _eap_cb.set_bool = (void(__cdecl *)(void *, eapol_bool_var,
> Boolean))peer_set_bool;
> _eap_cb.get_int = peer_get_int;
> _eap_cb.set_int = peer_set_int;
> _eap_cb.get_eapReqData = peer_get_eapReqData;
> _eap_cb.set_config_blob = peer_set_config_blob;
> _eap_cb.get_config_blob = peer_get_config_blob;
> _eap_cb.notify_pending = peer_notify_pending;
>
> os_memset(&_eap_conf, 0, sizeof(_eap_conf));
> _eap_ctx.eap = eap_peer_sm_init(&_eap_ctx, &_eap_cb,
> &_eap_ctx, &_eap_conf);
> if (_eap_ctx.eap == NULL)
> break;
>
> /* Enable "port" to allow authentication */
> _eap_ctx.portEnabled = true;
>
> os_memset(&_eapol_ctx, 0, sizeof(_eapol_ctx));
> _eapol_ctx.ctx = this; // This can be
> pointing to any structure we define as context
> _eapol_ctx.preauth = 0; // Not using IEEE
> 802.11i/RSN pre-authentication
> _eapol_ctx.cb = NULL; // Not using IEEE
> 802.11i/RSN pre-authentication, so no need for this callback
> _eapol_ctx.cb_ctx = NULL; // Not using IEEE
> 802.11i/RSN pre-authentication, so no need for context
> _eapol_ctx.msg_ctx = this; // Callback context
> for wpa_msg() calls
> _eapol_ctx.scard_ctx = NULL; // Callback context
> for PC/SC scard_*() function calls
> _eapol_ctx.eapol_send_ctx = this; // Callback context
> for eapol_send() calls
> _eapol_ctx.eapol_done_cb = eapol_done_cb;
> _eapol_ctx.eapol_send = eapol_send;
> _eapol_ctx.set_wep_key = NULL; // Not using WEP
> _eapol_ctx.set_config_blob = NULL;
> _eapol_ctx.get_config_blob = NULL;
> _eapol_ctx.aborted_cached = NULL;
>
> _eapol_ctx.opensc_engine_path = NULL; // No idea what to
> set here
> _eapol_ctx.pkcs11_engine_path = NULL; // No idea what to
> set here
> _eapol_ctx.pkcs11_module_path = NULL; // No idea what to
> set here
> _eapol_ctx.openssl_ciphers = NULL; // No idea what to
> set here
>
> _eapol_ctx.wps = NULL; // Not using WPS
>
> _eapol_ctx.eap_param_needed = NULL; // Not using WEP
>
> _eapol_ctx.port_cb = port_cb;
> _eapol_ctx.cert_cb = cert_cb;
> _eapol_ctx.cert_in_cb = 1;
> _eapol_ctx.status_cb = status_cb;
> _eapol_ctx.eap_error_cb = eap_error_cb;
>
> _eapol_ctx.set_anon_id = NULL; // Not sure this is
> needed
> _eapol_ctx.confirm_auth_cb = NULL; // Not sure this is
> needed
>
> _peapol_sm = eapol_sm_init(&_eapol_ctx);
> if (!_peapol_sm)
> break;
>
> os_memset(&_eapol_conf, 0, sizeof(_eapol_conf));
> _eapol_conf.accept_802_1x_keys = 0;
> _eapol_conf.required_keys = 0; //
> EAPOL_REQUIRE_KEY_UNICAST | EAPOL_REQUIRE_KEY_BROADCAST
> _eapol_conf.fast_reauth = 1;
> _eapol_conf.workaround = 0;
> _eapol_conf.eap_disabled = 0;
> _eapol_conf.external_sim = 0;
> _eapol_conf.wps = 0;
> eapol_sm_notify_config(_peapol_sm, &_eap_ctx.eap_config,
> &_eapol_conf);
>
> eapol_sm_notify_portValid(_peapol_sm, false);
> eapol_sm_notify_portEnabled(_peapol_sm, true);
>
>
> As you can see, not everything is clear so I'm probably just missing
> something. In the above code we don't get past the call to
> eapol_sm_init. Hope somebody can shed some light or point me in the
> right direction...
>
> Many thanks in advance!
>
> Regards,
>
> Michel Verhagen
>
> On 12/03/2021 10:10, Michel Verhagen wrote:
>> Thanks Alan!
>>
>> That does make sense indeed. I'll try to use eapol_supp for better
>> handling of the EAPOL layer on top of EAP. I hope this code can be
>> used with just the code I ported for the EAP library to compile.
>>
>> Is there any documentation explaining what all the context parameters
>> do (see test_eapol function in eapol_test.c), which are required and
>> for which functionality etc? All I need is to implement an EAPOL
>> client with certificates, so no WPA/WEP or any of the wireless stuff.
>>
>> I'll come back with more questions probably, thanks for pointing me
>> in the right direction!
>>
>>
>> On 12/03/2021 01:23, Alan DeKok wrote:
>>> On Mar 10, 2021, at 11:56 PM, Michel Verhagen <mike at guruce.com> wrote:
>>>> I'm using the EAP library to implement EAPOL on an embedded device.
>>>> Got it to go, with EAP-MD5 and EAP-TTLS and certificates, so all
>>>> good. However, I'm trying to get the library to prepare me an EAPOL
>>>> START packet. I'd like to initiate the start of the EAP handshake,
>>>> because depending on the settings of the authenticator, it can take
>>>> a long time before the EAP handshake sequence is initiated.
>>> I haven't used the library myself, but the problem, here is
>>> likely layering.
>>>
>>> i.e. you're using an EAP library. EAP runs on EAPoL, PPP, PANA,
>>> RADIUS, Diameter, ..., where the library just does EAP.
>>>
>>> EAPoL is managed by the IEEE 802.1X state machine. Which uses
>>> EAP, but isn't part of the EAP library.
>>>
>>>> I thought setting _eap_ctx.eapRestart to 1 (true) or even
>>>> eapTriggerStart to 1 and calling eap_peer_step would get me the
>>>> packet data to send, but I can't see eapTriggerStart used anywhere
>>>> in the code.
>>> See src/eapol_supp/eapol_supp_sm.c, which runs the EAPoL
>>> supplicant state machine. It checks eapTriggerStart, and ends up
>>> calling eapol_sm_txStart().
>>>
>>>> Does anybody know how to get the EAP library to prepare an EAP
>>>> Start packet?
>>> You can't. EAP isn't the same as the Ethernet layer EAPoL state
>>> machine.
>>>
>>>> I can of course prepare and send that packet myself, but it looks
>>>> like the EAP library should be able to do this as well...
>>> No. The EAP library does EAP. The 802.1X / supplicant state
>>> machine does Ethernet, and EAPoL.
>>>
>>> Alan DeKok.
>>>
>>
>>
>> _______________________________________________
>> Hostap mailing list
>> Hostap at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/hostap
>
>
> _______________________________________________
> Hostap mailing list
> Hostap at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/hostap
More information about the Hostap
mailing list