This commit has all the changes to extend and generalise the current
eap-wsc.c code to handle both the Enrollee and Registrar side of the
protocol, reusing existing functions and structures.
Alongside the current EAP-WSC enrollee side support, add the initial
part of registrar side. In the same file, register a new method with
the name string of "WSC-R". In this patch only the load_settings
method is added. validate_identity and handle_response are added in
later patches.
Replace the usage of eap_send_response() in the method implementations
with a new eap_method_respond that skips the redundant "type" parameter.
The new eap_send_packet is used inside eap_method_respond and will be
reused for sending request packets in authenticator side EAP methods.
Valgrind does not like uninitialized bytes used in a syscall. In this
case the buffer is an out buffer but since valgrind doesn't know that
it complains. Initializing to zero fixes the warning:
Syscall param socketcall.sendto(msg) points to uninitialised byte(s)
at 0x5162C4D: send (send.c:28)
by 0x457AF4: l_checksum_update (checksum.c:319)
by 0x43C03C: eap_wsc_handle_m2 (eap-wsc.c:842)
by 0x43CD33: eap_wsc_handle_request (eap-wsc.c:1048)
by 0x43A3A7: __eap_handle_request.part.0 (eap.c:266)
by 0x41A426: eapol_rx_packet.part.12 (eapol.c:2262)
by 0x41B536: __eapol_rx_packet (eapol.c:2650)
by 0x407C80: netdev_control_port_frame_event (netdev.c:3542)
by 0x407C80: netdev_unicast_notify (netdev.c:3684)
by 0x4598C5: dispatch_unicast_watches (genl.c:899)
by 0x4598C5: process_unicast (genl.c:918)
by 0x4598C5: received_data (genl.c:1039)
by 0x456452: io_callback (io.c:126)
by 0x45569D: l_main_iterate (main.c:473)
by 0x45576B: l_main_run (main.c:520)
Address 0x1ffeffe290 is on thread 1's stack
in frame #2, created by eap_wsc_handle_m2 (eap-wsc.c:797)
Also printing keys with l_debug conditional on an environment variable
as someone wanting debug logs, or leaving debug on accidentally, does
not necessarily want the keys in the logs and in memory.
Start using l_key_generate_dh_private and l_key_validate_dh_payload to
check for the disallowed corner case values in the DH private/public
values generated/received.
device password was read from settings using l_settings_get_string which
returns a newly-allocated string due to un-escape semantics. However,
when assigning wsc->device_password, we strdup-ed the password again
unnecessarily.
==1069== 14 bytes in 2 blocks are definitely lost in loss record 1 of 1
==1069== at 0x4C2AF0F: malloc (vg_replace_malloc.c:299)
==1069== by 0x16696A: l_malloc (util.c:62)
==1069== by 0x16B14B: unescape_value (settings.c:108)
==1069== by 0x16D12C: l_settings_get_string (settings.c:971)
==1069== by 0x149680: eap_wsc_load_settings (eap-wsc.c:1270)
==1069== by 0x146113: eap_load_settings (eap.c:556)
==1069== by 0x12E079: eapol_start (eapol.c:2022)
==1069== by 0x1143A5: netdev_connect_event (netdev.c:1728)
==1069== by 0x118751: netdev_mlme_notify (netdev.c:3406)
==1069== by 0x1734F1: notify_handler (genl.c:454)
==1069== by 0x168987: l_queue_foreach (queue.c:441)
==1069== by 0x173561: process_multicast (genl.c:469)
EAP-WSC handles 4 digit, 8 digit and out-of-band Device passwords. The
latter in particular can be anything, so drop the mandatory minimum
password length check here.
This also has the effect of enabling 4-digit PINs to actually work as
they are intended.
The EAP-method's .probe methods only checked the method name so do that
in eap.c instead and allocate method state in .load_settings. Rename
method's .remove method to .free to improve the naming.
When we send M5 & M7, we need to generate a random IV. For testing
purposes, the IV can be provided in settings, otherwise it will be
generated randomly.
We need quite a bit of attributes of M2 for the duration of the WSC
handshake. Most importantly, we need to use the peer's public key when
processing M4 and M6. RegistrarNonce is also needed for generating any
ACK/NACK messages as needed.
Also, peer's device attributes such as Model, Manufacturer, etc might be
useful to report upon successful handshake.
AuthKey is already uploaded into auth_key_hmac. KeyWrapKey is now
uploaded into the AES-CBC(128) cipher. We currently have no use for
EMSK.
So we no longer need to keep the wsc_session_key structure around.
DevicePassword is the PIN, either static, dynamically generated or
entered by the user. For PushButton mode, DevicePassword is set to
'00000000'. It can also be provided via external means, such as NFC.
This patch allows DevicePassword to be externally configured into the
EAP-WSC layer. Optionally, the secret nonce values can also be
provided for testing purposes. If omitted, they will be generated using
l_getrandom.
We use the load_settings method to bootstrap the internal state of the
EAP WSC state machine. We require certain information to be provided by
the higher layers, namely:
Global Device parameters
- Manufacturer
- Model Name
- Model Number
- Serial Number
- Device Name
- Primary Device Type
- OS Version
Session specific parameters
- MAC Address
- Configuration Methods
- RF Bands
The following parameters are auto-generated for each new session, but
can be over-ridden if desired
- Private Key
- Enrollee Nonce