test_ieee8021x.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259
  1. # IEEE 802.1X tests
  2. # Copyright (c) 2013-2015, Jouni Malinen <j@w1.fi>
  3. #
  4. # This software may be distributed under the terms of the BSD license.
  5. # See README for more details.
  6. import binascii
  7. import hmac
  8. import logging
  9. import time
  10. import hostapd
  11. import hwsim_utils
  12. logger = logging.getLogger()
  13. def test_ieee8021x_wep104(dev, apdev):
  14. """IEEE 802.1X connection using dynamic WEP104"""
  15. params = hostapd.radius_params()
  16. params["ssid"] = "ieee8021x-wep"
  17. params["ieee8021x"] = "1"
  18. params["wep_key_len_broadcast"] = "13"
  19. params["wep_key_len_unicast"] = "13"
  20. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  21. dev[0].connect("ieee8021x-wep", key_mgmt="IEEE8021X", eap="PSK",
  22. identity="psk.user@example.com",
  23. password_hex="0123456789abcdef0123456789abcdef",
  24. scan_freq="2412")
  25. hwsim_utils.test_connectivity(dev[0], hapd)
  26. def test_ieee8021x_wep40(dev, apdev):
  27. """IEEE 802.1X connection using dynamic WEP40"""
  28. params = hostapd.radius_params()
  29. params["ssid"] = "ieee8021x-wep"
  30. params["ieee8021x"] = "1"
  31. params["wep_key_len_broadcast"] = "5"
  32. params["wep_key_len_unicast"] = "5"
  33. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  34. dev[0].connect("ieee8021x-wep", key_mgmt="IEEE8021X", eap="PSK",
  35. identity="psk.user@example.com",
  36. password_hex="0123456789abcdef0123456789abcdef",
  37. scan_freq="2412")
  38. hwsim_utils.test_connectivity(dev[0], hapd)
  39. def test_ieee8021x_open(dev, apdev):
  40. """IEEE 802.1X connection using open network"""
  41. params = hostapd.radius_params()
  42. params["ssid"] = "ieee8021x-open"
  43. params["ieee8021x"] = "1"
  44. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  45. id = dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  46. eap="PSK", identity="psk.user@example.com",
  47. password_hex="0123456789abcdef0123456789abcdef",
  48. scan_freq="2412")
  49. hwsim_utils.test_connectivity(dev[0], hapd)
  50. logger.info("Test EAPOL-Logoff")
  51. dev[0].request("LOGOFF")
  52. ev = dev[0].wait_event(["CTRL-EVENT-DISCONNECTED"])
  53. if ev is None:
  54. raise Exception("Did not get disconnected")
  55. if "reason=23" not in ev:
  56. raise Exception("Unexpected disconnection reason")
  57. dev[0].request("LOGON")
  58. dev[0].connect_network(id)
  59. hwsim_utils.test_connectivity(dev[0], hapd)
  60. def test_ieee8021x_static_wep40(dev, apdev):
  61. """IEEE 802.1X connection using static WEP40"""
  62. params = hostapd.radius_params()
  63. params["ssid"] = "ieee8021x-wep"
  64. params["ieee8021x"] = "1"
  65. params["wep_key0"] = '"hello"'
  66. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  67. dev[0].connect("ieee8021x-wep", key_mgmt="IEEE8021X", eap="PSK",
  68. identity="psk.user@example.com",
  69. password_hex="0123456789abcdef0123456789abcdef",
  70. wep_key0='"hello"', eapol_flags="0",
  71. scan_freq="2412")
  72. hwsim_utils.test_connectivity(dev[0], hapd)
  73. def test_ieee8021x_proto(dev, apdev):
  74. """IEEE 802.1X and EAPOL supplicant protocol testing"""
  75. params = hostapd.radius_params()
  76. params["ssid"] = "ieee8021x-open"
  77. params["ieee8021x"] = "1"
  78. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  79. bssid = apdev[0]['bssid']
  80. dev[1].request("SET ext_eapol_frame_io 1")
  81. dev[1].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  82. eap="PSK", identity="psk.user@example.com",
  83. password_hex="0123456789abcdef0123456789abcdef",
  84. scan_freq="2412", wait_connect=False)
  85. id = dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  86. eap="PSK", identity="psk.user@example.com",
  87. password_hex="0123456789abcdef0123456789abcdef",
  88. scan_freq="2412")
  89. ev = dev[1].wait_event(["CTRL-EVENT-EAP-STARTED"], timeout=5)
  90. start = dev[0].get_mib()
  91. tests = [ "11",
  92. "11223344",
  93. "020000050a93000501",
  94. "020300050a93000501",
  95. "0203002c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  96. "0203002c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  97. "0203002c0100050000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  98. "02aa00050a93000501" ]
  99. for frame in tests:
  100. res = dev[0].request("EAPOL_RX " + bssid + " " + frame)
  101. if "OK" not in res:
  102. raise Exception("EAPOL_RX to wpa_supplicant failed")
  103. dev[1].request("EAPOL_RX " + bssid + " " + frame)
  104. stop = dev[0].get_mib()
  105. logger.info("MIB before test frames: " + str(start))
  106. logger.info("MIB after test frames: " + str(stop))
  107. vals = [ 'dot1xSuppInvalidEapolFramesRx',
  108. 'dot1xSuppEapLengthErrorFramesRx' ]
  109. for val in vals:
  110. if int(stop[val]) <= int(start[val]):
  111. raise Exception(val + " did not increase")
  112. def test_ieee8021x_eapol_start(dev, apdev):
  113. """IEEE 802.1X and EAPOL-Start retransmissions"""
  114. params = hostapd.radius_params()
  115. params["ssid"] = "ieee8021x-open"
  116. params["ieee8021x"] = "1"
  117. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  118. bssid = apdev[0]['bssid']
  119. hapd.set("ext_eapol_frame_io", "1")
  120. try:
  121. dev[0].request("SET EAPOL::startPeriod 1")
  122. dev[0].request("SET EAPOL::maxStart 1")
  123. dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  124. eap="PSK", identity="psk.user@example.com",
  125. password_hex="0123456789abcdef0123456789abcdef",
  126. scan_freq="2412", wait_connect=False)
  127. held = False
  128. for i in range(30):
  129. pae = dev[0].get_status_field('Supplicant PAE state')
  130. if pae == "HELD":
  131. held = True
  132. break
  133. time.sleep(0.25)
  134. if not held:
  135. raise Exception("PAE state HELD not reached")
  136. dev[0].wait_disconnected()
  137. finally:
  138. dev[0].request("SET EAPOL::startPeriod 30")
  139. dev[0].request("SET EAPOL::maxStart 3")
  140. def test_ieee8021x_held(dev, apdev):
  141. """IEEE 802.1X and HELD state"""
  142. params = hostapd.radius_params()
  143. params["ssid"] = "ieee8021x-open"
  144. params["ieee8021x"] = "1"
  145. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  146. bssid = apdev[0]['bssid']
  147. hapd.set("ext_eapol_frame_io", "1")
  148. try:
  149. dev[0].request("SET EAPOL::startPeriod 1")
  150. dev[0].request("SET EAPOL::maxStart 0")
  151. dev[0].request("SET EAPOL::heldPeriod 1")
  152. dev[0].connect("ieee8021x-open", key_mgmt="IEEE8021X", eapol_flags="0",
  153. eap="PSK", identity="psk.user@example.com",
  154. password_hex="0123456789abcdef0123456789abcdef",
  155. scan_freq="2412", wait_connect=False)
  156. held = False
  157. for i in range(30):
  158. pae = dev[0].get_status_field('Supplicant PAE state')
  159. if pae == "HELD":
  160. held = True
  161. break
  162. time.sleep(0.25)
  163. if not held:
  164. raise Exception("PAE state HELD not reached")
  165. hapd.set("ext_eapol_frame_io", "0")
  166. for i in range(30):
  167. pae = dev[0].get_status_field('Supplicant PAE state')
  168. if pae != "HELD":
  169. held = False
  170. break
  171. time.sleep(0.25)
  172. if held:
  173. raise Exception("PAE state HELD not left")
  174. ev = dev[0].wait_event([ "CTRL-EVENT-CONNECTED",
  175. "CTRL-EVENT-DISCONNECTED" ], timeout=10)
  176. if ev is None:
  177. raise Exception("Connection timed out")
  178. if "CTRL-EVENT-DISCONNECTED" in ev:
  179. raise Exception("Unexpected disconnection")
  180. finally:
  181. dev[0].request("SET EAPOL::startPeriod 30")
  182. dev[0].request("SET EAPOL::maxStart 3")
  183. dev[0].request("SET EAPOL::heldPeriod 60")
  184. def send_eapol_key(dev, bssid, signkey, frame_start, frame_end):
  185. zero_sign = "00000000000000000000000000000000"
  186. frame = frame_start + zero_sign + frame_end
  187. hmac_obj = hmac.new(binascii.unhexlify(signkey))
  188. hmac_obj.update(binascii.unhexlify(frame))
  189. sign = hmac_obj.digest()
  190. frame = frame_start + binascii.hexlify(sign) + frame_end
  191. dev.request("EAPOL_RX " + bssid + " " + frame)
  192. def test_ieee8021x_eapol_key(dev, apdev):
  193. """IEEE 802.1X connection and EAPOL-Key protocol tests"""
  194. params = hostapd.radius_params()
  195. params["ssid"] = "ieee8021x-wep"
  196. params["ieee8021x"] = "1"
  197. params["wep_key_len_broadcast"] = "5"
  198. params["wep_key_len_unicast"] = "5"
  199. hapd = hostapd.add_ap(apdev[0]['ifname'], params)
  200. bssid = apdev[0]['bssid']
  201. dev[0].connect("ieee8021x-wep", key_mgmt="IEEE8021X", eap="VENDOR-TEST",
  202. identity="vendor-test", scan_freq="2412")
  203. # Hardcoded MSK from VENDOR-TEST
  204. encrkey = "1111111111111111111111111111111111111111111111111111111111111111"
  205. signkey = "2222222222222222222222222222222222222222222222222222222222222222"
  206. # EAPOL-Key replay counter does not increase
  207. send_eapol_key(dev[0], bssid, signkey,
  208. "02030031" + "010005" + "0000000000000000" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  209. "1c636a30a4")
  210. # EAPOL-Key too large Key Length field value
  211. send_eapol_key(dev[0], bssid, signkey,
  212. "02030031" + "010021" + "ffffffffffffffff" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  213. "1c636a30a4")
  214. # EAPOL-Key too much key data
  215. send_eapol_key(dev[0], bssid, signkey,
  216. "0203004d" + "010005" + "ffffffffffffffff" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  217. 33*"ff")
  218. # EAPOL-Key too little key data
  219. send_eapol_key(dev[0], bssid, signkey,
  220. "02030030" + "010005" + "ffffffffffffffff" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  221. "1c636a30")
  222. # EAPOL-Key with no key data and too long WEP key length
  223. send_eapol_key(dev[0], bssid, signkey,
  224. "0203002c" + "010020" + "ffffffffffffffff" + "056c22d109f29d4d9fb9b9ccbad33283" + "02",
  225. "")