blob: d2afd720ddcb1999e7157e8344acfab5f195843f [file] [log] [blame]
// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package wifi
import (
"context"
"fmt"
"strings"
"chromiumos/tast/common/crypto/certificate"
"chromiumos/tast/common/network/ping"
"chromiumos/tast/common/perf"
"chromiumos/tast/common/wifi/security"
"chromiumos/tast/common/wifi/security/dynamicwep"
"chromiumos/tast/common/wifi/security/tunneled1x"
"chromiumos/tast/common/wifi/security/wep"
"chromiumos/tast/common/wifi/security/wpa"
"chromiumos/tast/common/wifi/security/wpaeap"
"chromiumos/tast/remote/wificell"
ap "chromiumos/tast/remote/wificell/hostapd"
"chromiumos/tast/remote/wificell/wifiutil"
"chromiumos/tast/services/cros/wifi"
"chromiumos/tast/testing"
"chromiumos/tast/testing/hwdep"
)
type simpleConnectTestcase struct {
apOpts []ap.Option
// If unassigned, use default security config: open network.
secConfFac security.ConfigFactory
pingOps []ping.Option
expectedFailure bool
}
// EAP certs/keys for EAP tests.
var (
eapCert1 = certificate.TestCert1()
eapCert2 = certificate.TestCert2()
eapCert3 = certificate.TestCert3()
eapCert3AltSub = certificate.TestCert3AltSubjectMatch()
eapCert3DomainSuffix = certificate.TestCert3DomainSuffixMatch()
)
func init() {
testing.AddTest(&testing.Test{
Func: SimpleConnect,
Desc: "Verifies that DUT can connect to the host via AP in different WiFi configuration",
Contacts: []string{
"chromeos-wifi-champs@google.com", // WiFi oncall rotation; or http://b/new?component=893827
},
Attr: []string{"group:wificell", "wificell_func"},
ServiceDeps: []string{wificell.TFServiceName},
Fixture: "wificellFixtWithCapture",
Params: []testing.Param{
// Parameters generated by simple_connect_test.go. DO NOT EDIT.
{
// Verifies that DUT can connect to an open 802.11a network on channels 48, 64.
Name: "80211a",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211a), ap.Channel(48)},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211a), ap.Channel(64), ap.SpectrumManagement()},
}},
}, {
// Verifies that DUT can connect to an open 802.11b network on channels 1, 6, 11.
Name: "80211b",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211b), ap.Channel(1)},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211b), ap.Channel(6)},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211b), ap.Channel(11)},
}},
}, {
// Verifies that DUT can connect to an open 802.11g network on channels 1, 6, 11.
Name: "80211g",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(6)},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(11)},
}},
}, {
// Verifies that DUT can connect to an open 802.11n network on 2.4GHz channels 1, 6, 11 with a channel width of 20MHz.
Name: "80211n24ht20",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(1), ap.HTCaps(ap.HTCapHT20)},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(6), ap.HTCaps(ap.HTCapHT20)},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(11), ap.HTCaps(ap.HTCapHT20)},
}},
}, {
// Verifies that DUT can connect to an open 802.11n network on 2.4GHz channel 6 with a channel width of 40MHz.
Name: "80211n24ht40",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(6), ap.HTCaps(ap.HTCapHT40)},
}},
}, {
// Verifies that DUT can connect to an open 802.11n network on 5GHz channel 48 with a channel width of 20MHz.
Name: "80211n5ht20",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(48), ap.HTCaps(ap.HTCapHT20)},
}},
}, {
// Verifies that DUT can connect to an open 802.11n network on 5GHz channel 48
// (40MHz channel with the second 20MHz chunk of the 40MHz channel on the channel below the center channel).
Name: "80211n5ht40",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(48), ap.HTCaps(ap.HTCapHT40Minus)},
}},
}, {
// Verifies that DUT can connect to an open 802.11n network on 5 GHz channel with short guard intervals enabled (both 20/40 Mhz).
Name: "80211nsgi",
ExtraAttr: []string{"wificell_cq"},
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(48), ap.HTCaps(ap.HTCapHT20, ap.HTCapSGI20)},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(48), ap.HTCaps(ap.HTCapHT40Minus, ap.HTCapSGI40)},
}},
}, {
// Verifies that DUT can connect to an open 802.11ac network on channel 60 with a channel width of 20MHz.
Name: "80211acvht20",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{
ap.Mode(ap.Mode80211acPure), ap.Channel(60), ap.HTCaps(ap.HTCapHT20), ap.SpectrumManagement(),
ap.VHTChWidth(ap.VHTChWidth20Or40),
},
}},
ExtraHardwareDeps: hwdep.D(hwdep.Wifi80211ac()),
}, {
// Verifies that DUT can connect to an open 802.11ac network on channel 48 with a channel width of 40MHz.
Name: "80211acvht40",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{
ap.Mode(ap.Mode80211acPure), ap.Channel(48), ap.HTCaps(ap.HTCapHT40),
ap.VHTChWidth(ap.VHTChWidth20Or40),
},
}},
ExtraHardwareDeps: hwdep.D(hwdep.Wifi80211ac()),
}, {
// Verifies that DUT can connect to an open 802.11ac network on 5GHz channel 36 with center channel of 42 and channel width of 80MHz.
Name: "80211acvht80mixed",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{
ap.Mode(ap.Mode80211acMixed), ap.Channel(36), ap.HTCaps(ap.HTCapHT40Plus),
ap.VHTCaps(ap.VHTCapSGI80), ap.VHTCenterChannel(42), ap.VHTChWidth(ap.VHTChWidth80),
},
}},
}, {
// Verifies that DUT can connect to an open 802.11ac network on channel 157 with center channel of 155 and channel width of 80MHz.
// The router is forced to use 80 MHz wide rates only.
Name: "80211acvht80pure",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{
ap.Mode(ap.Mode80211acPure), ap.Channel(157), ap.HTCaps(ap.HTCapHT40Plus),
ap.VHTCaps(ap.VHTCapSGI80), ap.VHTCenterChannel(155), ap.VHTChWidth(ap.VHTChWidth80),
},
}},
ExtraHardwareDeps: hwdep.D(hwdep.Wifi80211ac()),
}, {
// Verifies that DUT can connect to a hidden network on 2.4GHz and 5GHz channels.
Name: "hidden",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(6), ap.Hidden()},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(36), ap.HTCaps(ap.HTCapHT20), ap.Hidden()},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211nPure), ap.Channel(48), ap.HTCaps(ap.HTCapHT20), ap.Hidden()},
}},
// TODO(b/189972561) Enable this test on Trogdor once active scanning on 5 GHz channel is enabled.
ExtraHardwareDeps: hwdep.D(hwdep.SkipOnPlatform("strongbad", "trogdor", "trogdor-kernelnext")),
}, {
// Verifies that DUT can connect to a WEP network with both open and shared system authentication and 40-bit pre-shared keys.
Name: "wep40",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep40Keys(), wep.DefaultKey(0), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep40Keys(), wep.DefaultKey(1), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep40Keys(), wep.DefaultKey(2), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep40Keys(), wep.DefaultKey(3), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep40Keys(), wep.DefaultKey(0), wep.AuthAlgs(wep.AuthAlgoShared)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep40Keys(), wep.DefaultKey(1), wep.AuthAlgs(wep.AuthAlgoShared)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep40Keys(), wep.DefaultKey(2), wep.AuthAlgs(wep.AuthAlgoShared)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep40Keys(), wep.DefaultKey(3), wep.AuthAlgs(wep.AuthAlgoShared)),
}},
ExtraHardwareDeps: hwdep.D(hwdep.WifiWEP()),
}, {
// Verifies that DUT can connect to a WEP network with both open and shared system authentication and 104-bit pre-shared keys.
Name: "wep104",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep104Keys(), wep.DefaultKey(0), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep104Keys(), wep.DefaultKey(1), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep104Keys(), wep.DefaultKey(2), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep104Keys(), wep.DefaultKey(3), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep104Keys(), wep.DefaultKey(0), wep.AuthAlgs(wep.AuthAlgoShared)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep104Keys(), wep.DefaultKey(1), wep.AuthAlgs(wep.AuthAlgoShared)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep104Keys(), wep.DefaultKey(2), wep.AuthAlgs(wep.AuthAlgoShared)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wep.NewConfigFactory(wep104Keys(), wep.DefaultKey(3), wep.AuthAlgs(wep.AuthAlgoShared)),
}},
ExtraHardwareDeps: hwdep.D(hwdep.WifiWEP()),
}, {
// Verifies that DUT can connect to a hidden WEP network with open/shared system authentication and 40/104-bit pre-shared keys.
Name: "wephidden",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.Hidden()},
secConfFac: wep.NewConfigFactory(wep40KeysHidden(), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.Hidden()},
secConfFac: wep.NewConfigFactory(wep40KeysHidden(), wep.AuthAlgs(wep.AuthAlgoShared)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.Hidden()},
secConfFac: wep.NewConfigFactory(wep104KeysHidden(), wep.AuthAlgs(wep.AuthAlgoOpen)),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.Hidden()},
secConfFac: wep.NewConfigFactory(wep104KeysHidden(), wep.AuthAlgs(wep.AuthAlgoShared)),
}},
ExtraHardwareDeps: hwdep.D(hwdep.WifiWEP()),
}, {
// Verifies that DUT can connect to a protected network supporting for pure WPA with TKIP.
Name: "wpatkip",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for pure WPA with AES based CCMP.
Name: "wpaccmp",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for pure WPA with both AES based CCMP and TKIP.
Name: "wpamulti",
ExtraAttr: []string{"wificell_cq"},
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP, wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for WPA2 (aka RSN) with TKIP. Some AP still uses TKIP in WPA2.
Name: "wpa2tkip",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA2),
wpa.Ciphers2(wpa.CipherTKIP),
),
}},
}, {
// Verifies that DUT can connect to an AP broadcasting a WPA2 network using AES based CCMP.
// In addition, the client must also support 802.11w protected management frames.
Name: "wpa2pmf",
ExtraAttr: []string{"wificell_cq"},
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.PMF(ap.PMFRequired)},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA2),
wpa.Ciphers2(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to an AP broadcasting a WPA2 network using AES based CCMP.
// In addition, the client may also negotiate use of 802.11w protected management frames.
Name: "wpa2pmfoptional",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.PMF(ap.PMFOptional)},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA2),
wpa.Ciphers2(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for WPA2 (aka RSN) and encrypted under AES.
Name: "wpa2",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA2),
wpa.Ciphers2(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for both WPA and WPA2 with TKIP/AES supported for WPA and AES supported for WPA2.
Name: "wpamixed",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModeMixed),
wpa.Ciphers(wpa.CipherTKIP, wpa.CipherCCMP), wpa.Ciphers2(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to an AP in WPA2/WPA3 mixed mode. WiFi alliance suggests PMF in this mode.
Name: "wpa3mixed",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{
ap.Mode(ap.Mode80211acMixed), ap.Channel(36), ap.HTCaps(ap.HTCapHT40Plus),
ap.VHTCenterChannel(42), ap.VHTChWidth(ap.VHTChWidth80),
ap.PMF(ap.PMFOptional),
},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModeMixedWPA3),
wpa.Ciphers2(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to an AP in WPA3-SAE ("pure") mode. WiFi alliance requires PMF in this mode.
Name: "wpa3",
// Not all WiFi chips support SAE. We enable the feature as a Software dependency for now, but eventually
// this will require a hardware dependency (crbug.com/1070299).
ExtraSoftwareDeps: []string{"wpa3_sae"},
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{
ap.Mode(ap.Mode80211acMixed), ap.Channel(36), ap.HTCaps(ap.HTCapHT40Plus),
ap.VHTCenterChannel(42), ap.VHTChWidth(ap.VHTChWidth80),
ap.PMF(ap.PMFRequired),
},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA3),
wpa.Ciphers2(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to a protected 802.11ac network supporting for WPA.
Name: "wpavht80",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{
ap.Mode(ap.Mode80211acPure), ap.Channel(36), ap.HTCaps(ap.HTCapHT40Plus),
ap.VHTCenterChannel(42), ap.VHTChWidth(ap.VHTChWidth80),
},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP, wpa.CipherCCMP),
),
}},
ExtraHardwareDeps: hwdep.D(hwdep.Wifi80211ac()),
}, {
// Verifies that DUT can connect to a protected network whose WPA passphrase can be pure unicode, mixed unicode and ASCII, and all the punctuations.
Name: "wpaoddpassphrase",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89", wpa.Mode(wpa.ModePureWPA2),
wpa.Ciphers2(wpa.CipherCCMP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"abcdef\xc2\xa2", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
"abcdef\xc2\xa2", wpa.Mode(wpa.ModePureWPA2),
wpa.Ciphers2(wpa.CipherCCMP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
" !\"#$%&'()>*+,-./:;<=>?@[\\]^_{|}~", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
" !\"#$%&'()>*+,-./:;<=>?@[\\]^_{|}~", wpa.Mode(wpa.ModePureWPA2),
wpa.Ciphers2(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to a hidden network supporting for WPA with TKIP, WPA with TKIP/AES, WPA2 with AES, and mixed WPA with TKIP/AES and WPA2 with AES.
Name: "wpahidden",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.Hidden()},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.Hidden()},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP, wpa.CipherCCMP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.Hidden()},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModePureWPA2),
wpa.Ciphers2(wpa.CipherCCMP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.Hidden()},
secConfFac: wpa.NewConfigFactory(
"chromeos", wpa.Mode(wpa.ModeMixed),
wpa.Ciphers(wpa.CipherTKIP, wpa.CipherCCMP), wpa.Ciphers2(wpa.CipherCCMP),
),
}},
}, {
// Verifies that DUT can connect to a WPA network using a raw PMK value instead of an ASCII passphrase.
Name: "raw_pmk",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpa.NewConfigFactory(
strings.Repeat("0123456789abcdef", 4), // length = 64.
wpa.Mode(wpa.ModePureWPA),
wpa.Ciphers(wpa.CipherTKIP),
),
}},
}, {
// Verifies that DUT can connect to an open network on a DFS channel.
// DFS (dynamic frequency selection) channels are channels that may be unavailable if radar interference is detected.
// See: https://en.wikipedia.org/wiki/Dynamic_frequency_selection, https://en.wikipedia.org/wiki/List_of_WLAN_channels
Name: "dfs",
ExtraAttr: []string{"wificell_cq"},
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211nMixed), ap.Channel(120), ap.HTCaps(ap.HTCapHT40), ap.SpectrumManagement()},
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211nMixed), ap.Channel(136), ap.HTCaps(ap.HTCapHT40), ap.SpectrumManagement()},
}},
}, {
// Verifies that DUT can connect to a networks with the longest and shortest SSID.
Name: "ssid_limits",
ExtraAttr: []string{"wificell_cq"},
Val: []simpleConnectTestcase{{
apOpts: wifiutil.CommonAPOptions(ap.SSID("a")),
}, {
apOpts: wifiutil.CommonAPOptions(ap.SSID(strings.Repeat("MaxLengthSSID", 4)[:32])),
}},
}, {
// This test case verifies that the DUT accepts ascii and non-ascii type characters as the SSID.
Name: "non_ascii_ssid",
Val: []simpleConnectTestcase{{
// TODO(crbug.com/1082582): shill don't allow leading 0x00 now, so let's append it in the
// end to keep the coverage.
apOpts: wifiutil.CommonAPOptions(ap.SSID(byteSequenceStr(1, 31) + "\x00")),
}, {
apOpts: wifiutil.CommonAPOptions(ap.SSID(byteSequenceStr(32, 63))),
}, {
apOpts: wifiutil.CommonAPOptions(ap.SSID(byteSequenceStr(64, 95))),
}, {
apOpts: wifiutil.CommonAPOptions(ap.SSID(byteSequenceStr(96, 127))),
}, {
apOpts: wifiutil.CommonAPOptions(ap.SSID(byteSequenceStr(128, 159))),
}, {
apOpts: wifiutil.CommonAPOptions(ap.SSID(byteSequenceStr(160, 191))),
}, {
apOpts: wifiutil.CommonAPOptions(ap.SSID(byteSequenceStr(192, 223))),
}, {
apOpts: wifiutil.CommonAPOptions(ap.SSID(byteSequenceStr(224, 255))),
}, {
// Valid Unicode characters.
apOpts: wifiutil.CommonAPOptions(ap.SSID("\xe4\xb8\xad\xe5\x9b\xbd")),
}, {
// Single extended ASCII character (a-grave).
apOpts: wifiutil.CommonAPOptions(ap.SSID("\xe0")),
}, {
// Mix of ASCII and Unicode characters as SSID.
apOpts: wifiutil.CommonAPOptions(ap.SSID("Chrome\xe7\xac\x94\xe8\xae\xb0\xe6\x9c\xac")),
}},
// TODO(b/158150763): Skip Marvell WiFi as there's a known issue to make the test always fail.
ExtraHardwareDeps: hwdep.D(hwdep.WifiNotMarvell()),
}, {
// Verifies that DUT can connect to a protected network supporting for dynamic WEP encryption.
Name: "8021xwep",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: dynamicwep.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred,
dynamicwep.ClientCACert(eapCert1.CACred.Cert),
dynamicwep.ClientCred(eapCert1.ClientCred),
dynamicwep.RekeyPeriod(10),
),
pingOps: []ping.Option{ping.Count(15), ping.Interval(1)},
}},
// Skip on Marvell because of 8021xwep test failure post security fixes b/187853331, no plans to fix.
// Skip on trogdor and strongbad board because of 8021xwep test regression post Qualcomm FW746 b/194644867,
// Qualcomm looks at the security fixes in the FW.
// TODO(b/194644867): revisit after FW fix and verification.
ExtraHardwareDeps: hwdep.D(hwdep.WifiNotMarvell(), hwdep.SkipOnPlatform("trogdor", "strongbad", "trogdor-kernelnext"), hwdep.WifiWEP()),
}, {
// Verifies that DUT can connect to a protected network supporting for WPA-EAP encryption.
Name: "8021xwpa",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpaeap.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred,
wpaeap.ClientCACert(eapCert1.CACred.Cert),
wpaeap.ClientCred(eapCert1.ClientCred),
),
}, {
// Failure due to lack of CACert on client.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpaeap.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred,
wpaeap.ClientCred(eapCert1.ClientCred),
),
expectedFailure: true,
}, {
// Failure due to unmatched CACert.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpaeap.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred,
wpaeap.ClientCACert(eapCert2.CACred.Cert),
wpaeap.ClientCred(eapCert1.ClientCred),
),
expectedFailure: true,
}, {
// Should succeed if we specify that we have no CACert.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpaeap.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred,
wpaeap.ClientCred(eapCert1.ClientCred),
wpaeap.NotUseSystemCAs(),
),
}, {
// Failure due to wrong certificate chain on client.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpaeap.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred,
wpaeap.ClientCACert(eapCert1.CACred.Cert),
wpaeap.ClientCred(eapCert2.ClientCred),
),
expectedFailure: true,
}, {
// Failure due to expired cert on server.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: wpaeap.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ExpiredServerCred,
wpaeap.ClientCACert(eapCert1.CACred.Cert),
wpaeap.ClientCred(eapCert1.ClientCred),
),
expectedFailure: true,
}},
// TODO(b/189986748): Remove the skiplist once those flaky boards have reached AUE.
ExtraHardwareDeps: hwdep.D(hwdep.SkipOnPlatform("banjo", "candy", "gnawty", "kip", "ninja", "sumo", "swanky", "winky")),
}, {
// Verifies that DUT can connect to an WPA3-Enterprise-transition AP
Name: "8021xwpa3mixed",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.PMF(ap.PMFOptional)},
secConfFac: wpaeap.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred,
wpaeap.ClientCACert(eapCert1.CACred.Cert),
wpaeap.ClientCred(eapCert1.ClientCred),
wpaeap.Mode(wpa.ModeMixedWPA3),
),
}},
}, {
// Verifies that DUT can connect to an WPA3-Enterprise-only AP
Name: "8021xwpa3",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1), ap.PMF(ap.PMFRequired)},
secConfFac: wpaeap.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred,
wpaeap.ClientCACert(eapCert1.CACred.Cert),
wpaeap.ClientCred(eapCert1.ClientCred),
wpaeap.Mode(wpa.ModePureWPA3),
),
}},
}, {
// Verifies that DUT CANNOT connect to a PEAP network with wrong settings.
// We do these tests for only one inner authentication protocol because we
// presume that supplicant reuses this code between inner authentication types.
Name: "8021xpeap_fail",
Val: []simpleConnectTestcase{{
// Failure due to bad password.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.ClientPassword("wrongpassword"),
),
expectedFailure: true,
}, {
// Failure due to wrong client CA.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert2.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
),
expectedFailure: true,
}, {
// Failure due to expired server cred.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ExpiredServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
),
expectedFailure: true,
}, {
// Failure due to that a subject alternative name (SAN) is set but does not match any of the server certificate SANs.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`}),
),
expectedFailure: true,
}, {
// Failure due the set domain suffix match that does not match any of the dNSName in the server certificate SANs.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain.com"}),
),
expectedFailure: true,
}},
}, {
// Verifies that DUT can connect to a protected network supporting for PEAP authentication with tunneled MSCHAPV2.
Name: "8021xpeap_mschapv2",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for PEAP authentication with tunneled MD5.
Name: "8021xpeap_md5",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for PEAP authentication with tunneled GTC.
Name: "8021xpeap_gtc",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypePEAP),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
}, {
// Verifies that DUT CANNOT connect to a TTLS network with wrong settings.
// We do these tests for only one inner authentication protocol because we
// presume that supplicant reuses this code between inner authentication types.
Name: "8021xttls_fail",
Val: []simpleConnectTestcase{{
// Failure due to bad password.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.ClientPassword("wrongpassword"),
),
expectedFailure: true,
}, {
// Failure due to wrong client CA.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert2.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
),
expectedFailure: true,
}, {
// Failure due to expired server cred.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ExpiredServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
),
expectedFailure: true,
}, {
// Failure due to that a subject alternative name (SAN) is set but does not match any of the server certificate SANs.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`}),
),
expectedFailure: true,
}, {
// Failure due the set domain suffix match that does not match any of the dNSName in the server certificate SANs.
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain.com"}),
),
expectedFailure: true,
}},
}, {
// Verifies that DUT can connect to a protected network supporting for TTLS authentication with tunneled MSCHAPV2.
Name: "8021xttls_mschapv2",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMSCHAPV2),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for TTLS authentication with tunneled MD5.
Name: "8021xttls_md5",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeMD5),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for TTLS authentication with tunneled GTC.
Name: "8021xttls_gtc",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeGTC),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for TTLS authentication with tunneled TTLSMSCHAPV2.
Name: "8021xttls_ttlsmschapv2",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAPV2),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAPV2),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAPV2),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAPV2),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for TTLS authentication with tunneled TTLSMSCHAP.
Name: "8021xttls_ttlsmschap",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAP),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAP),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAP),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAP),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAP),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSMSCHAP),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
}, {
// Verifies that DUT can connect to a protected network supporting for TTLS authentication with tunneled TTLSPAP.
Name: "8021xttls_ttlspap",
Val: []simpleConnectTestcase{{
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert1.CACred.Cert, eapCert1.ServerCred, eapCert1.CACred.Cert, "testuser", "password",
tunneled1x.Mode(wpa.ModePureWPA2),
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSPAP),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSPAP),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSPAP),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[1]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSPAP),
tunneled1x.AltSubjectMatch([]string{eapCert3AltSub[2]}),
),
}, {
// Should success since having multiple entries in 'altsubject_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses altsubject_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSPAP),
tunneled1x.AltSubjectMatch([]string{`{"Type":"DNS","Value":"wrong_dns.com"}`, eapCert3AltSub[0]}),
),
}, {
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSPAP),
tunneled1x.DomainSuffixMatch(eapCert3DomainSuffix),
),
}, {
// Should succeed since having multiple entries in 'domain_suffix_match' is treated as OR, not AND.
// For more information about how wpa_supplicant uses domain_suffix_match field:
// https://w1.fi/cgit/hostap/plain/wpa_supplicant/wpa_supplicant.conf
apOpts: []ap.Option{ap.Mode(ap.Mode80211g), ap.Channel(1)},
secConfFac: tunneled1x.NewConfigFactory(
eapCert3.CACred.Cert, eapCert3.ServerCred, eapCert3.CACred.Cert, "testuser", "password",
tunneled1x.OuterProtocol(tunneled1x.Layer1TypeTTLS),
tunneled1x.InnerProtocol(tunneled1x.Layer2TypeTTLSPAP),
tunneled1x.DomainSuffixMatch([]string{"wrongdomain1.com", eapCert3DomainSuffix[0], "wrongdomain1.com"}),
),
}},
},
},
})
}
func SimpleConnect(ctx context.Context, s *testing.State) {
tf := s.FixtValue().(*wificell.TestFixture)
pv := perf.NewValues()
defer func() {
if err := pv.Save(s.OutDir()); err != nil {
s.Log("Failed to save perf data, err: ", err)
}
}()
testOnce := func(ctx context.Context, s *testing.State, options []ap.Option, fac security.ConfigFactory, pingOps []ping.Option, expectedFailure bool) {
apIface, err := tf.ConfigureAP(ctx, options, fac)
if err != nil {
s.Fatal("Failed to configure ap, err: ", err)
}
defer func(ctx context.Context) {
if err := tf.DeconfigAP(ctx, apIface); err != nil {
s.Error("Failed to deconfig ap, err: ", err)
}
}(ctx)
ctx, cancel := tf.ReserveForDeconfigAP(ctx, apIface)
defer cancel()
s.Log("AP setup done")
// Some tests may fail as expected at following ConnectWifiAP(). In that case entries should still be deleted properly.
defer func(ctx context.Context) {
req := &wifi.DeleteEntriesForSSIDRequest{Ssid: []byte(apIface.Config().SSID)}
if _, err := tf.WifiClient().DeleteEntriesForSSID(ctx, req); err != nil {
s.Errorf("Failed to remove entries for ssid=%s, err: %v", apIface.Config().SSID, err)
}
}(ctx)
resp, err := tf.ConnectWifiAP(ctx, apIface)
if err != nil {
if expectedFailure {
s.Log("Failed to connect to WiFi as expected")
// If we expect to fail, then this test is already done.
return
}
s.Fatal("Failed to connect to WiFi, err: ", err)
}
defer func(ctx context.Context) {
if err := tf.CleanDisconnectWifi(ctx); err != nil {
s.Error("Failed to disconnect WiFi, err: ", err)
}
}(ctx)
ctx, cancel = tf.ReserveForDisconnect(ctx)
defer cancel()
if expectedFailure {
s.Fatal("Expected to fail to connect to WiFi, but it was successful")
}
s.Log("Connected")
desc := apIface.Config().PerfDesc()
pv.Set(perf.Metric{
Name: desc,
Variant: "Discovery",
Unit: "seconds",
Direction: perf.SmallerIsBetter,
}, float64(resp.DiscoveryTime)/1e9)
pv.Set(perf.Metric{
Name: desc,
Variant: "Association",
Unit: "seconds",
Direction: perf.SmallerIsBetter,
}, float64(resp.AssociationTime)/1e9)
pv.Set(perf.Metric{
Name: desc,
Variant: "Configuration",
Unit: "seconds",
Direction: perf.SmallerIsBetter,
}, float64(resp.ConfigurationTime)/1e9)
ping := func(ctx context.Context) error {
return tf.PingFromDUT(ctx, apIface.ServerIP().String(), pingOps...)
}
if err := tf.AssertNoDisconnect(ctx, ping); err != nil {
s.Fatal("Failed to ping from DUT, err: ", err)
}
s.Log("Checking the status of the SSID in the DUT")
serInfo, err := tf.WifiClient().QueryService(ctx)
if err != nil {
s.Fatal("Failed to get the WiFi service information from DUT, err: ", err)
}
if serInfo.Wifi.HiddenSsid != apIface.Config().Hidden {
s.Fatalf("Unexpected hidden SSID status: got %t, want %t ", serInfo.Wifi.HiddenSsid, apIface.Config().Hidden)
}
// TODO(crbug.com/1034875): Assert no deauth detected from the server side.
// TODO(crbug.com/1034875): Maybe some more check on the WiFi capabilities to
// verify we really have the settings as expected. (ref: crrev.com/c/1995105)
s.Log("Deconfiguring")
}
testcases := s.Param().([]simpleConnectTestcase)
for i, tc := range testcases {
subtest := func(ctx context.Context, s *testing.State) {
testOnce(ctx, s, tc.apOpts, tc.secConfFac, tc.pingOps, tc.expectedFailure)
}
if !s.Run(ctx, fmt.Sprintf("Testcase #%d", i), subtest) {
// Stop if any sub-test failed.
return
}
}
s.Log("Tearing down")
}
// WEP keys for WEP tests.
func wep40Keys() []string {
return []string{"abcde", "fedcba9876", "ab\xe4\xb8\x89", "\xe4\xb8\x89\xc2\xa2"}
}
func wep104Keys() []string {
return []string{
"0123456789abcdef0123456789", "mlk:ihgfedcba",
"d\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xe5\x9b\x9b",
"\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xc2\xa2\xc2\xa3",
}
}
func wep40KeysHidden() []string {
return []string{"0123456789", "89abcdef01", "9876543210", "fedcba9876"}
}
func wep104KeysHidden() []string {
return []string{
"0123456789abcdef0123456789", "89abcdef0123456789abcdef01",
"fedcba9876543210fedcba9876", "109fedcba987654321fedcba98",
}
}
// byteSequenceStr generates a string from the slice of bytes in [start, end].
// Both start and end are included in the result string.
// If start > end, empty string will be returned.
func byteSequenceStr(start, end byte) string {
var ret []byte
if start > end {
return ""
}
for i := start; i < end; i++ {
ret = append(ret, i)
}
ret = append(ret, end)
return string(ret)
}