binder: Implement Set/Get network params (Part 2)

Implement the following Set/Get methods:
1. PskPassphrase
2. WepKeys
3. WepTxKeyIdx

BUG: 1252274
TEST: Ran 'wpa_supplicant_binder_test'
Change-Id: Icfc318352e85778f5a16b92dee58ff7c0f2f9f23
Signed-off-by: Roshan Pius <rpius@google.com>
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
index 01c765a..a04fc7b 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/INetwork.aidl
@@ -42,8 +42,10 @@
 	/** Max number of WEP keys param. */
 	const int WEP_KEYS_MAX_NUM = 4;
 
-	/** Max length of each WEP keys param. */
-	const int WEP_KEY_MAX_LEN = 16;
+	/** Length of each WEP40 keys param. */
+	const int WEP40_KEY_LEN = 5;
+	/** Length of each WEP104 keys param. */
+	const int WEP104_KEY_LEN = 13;
 
 	/** Possble mask of values for KeyMgmt param. */
 	const int KEY_MGMT_MASK_NONE = 0x01;
@@ -141,7 +143,8 @@
 
 	/**
 	 * Set WEP key for WEP network.
-	 * Max length of each key is |WEP_KEY_MAX_LEN|.
+	 * Length of each key should be either |WEP40_KEY_LEN| or
+	 * |WEP104_KEY_LEN|.
 	 *
 	 * @param key_idx Index of wep key to be set.
 	 *                Max of |WEP_KEYS_MAX_NUM| keys.
diff --git a/wpa_supplicant/binder/network.cpp b/wpa_supplicant/binder/network.cpp
index 24bed4c..12cfec0 100644
--- a/wpa_supplicant/binder/network.cpp
+++ b/wpa_supplicant/binder/network.cpp
@@ -164,6 +164,32 @@
 {
 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
 	RETURN_IF_NETWORK_INVALID(wpa_ssid);
+
+	if (isPskPassphraseValid(psk)) {
+		return android::binder::Status::fromExceptionCode(
+		    android::binder::Status::EX_ILLEGAL_ARGUMENT,
+		    "Invalid Psk passphrase value.");
+	}
+	if (wpa_ssid->passphrase &&
+	    os_strlen(wpa_ssid->passphrase) == psk.size() &&
+	    os_memcmp(wpa_ssid->passphrase, psk.c_str(), psk.size()) == 0) {
+		return android::binder::Status::ok();
+	}
+	// Flag to indicate if raw psk is calculated or not using
+	// |wpa_config_update_psk|. Deferred if ssid not already set.
+	wpa_ssid->psk_set = 0;
+	str_clear_free(wpa_ssid->passphrase);
+	wpa_ssid->passphrase = dup_binstr(psk.c_str(), psk.size());
+	if (!wpa_ssid->passphrase) {
+		return android::binder::Status::fromExceptionCode(
+		    ERROR_GENERIC, "Memory allocation failed.");
+	}
+	if (wpa_ssid->ssid_len) {
+		wpa_config_update_psk(wpa_ssid);
+	}
+	wpa_hexdump_ascii_key(
+	    MSG_MSGDUMP, "PSK (ASCII passphrase)", (u8 *)wpa_ssid->passphrase,
+	    psk.size());
 	return android::binder::Status::ok();
 }
 
@@ -172,6 +198,29 @@
 {
 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
 	RETURN_IF_NETWORK_INVALID(wpa_ssid);
+
+	if (key_idx < 0 || key_idx >= WEP_KEYS_MAX_NUM) {
+		const std::string error_msg =
+		    "Invalid Wep Key index: " + std::to_string(key_idx) + ".";
+		return android::binder::Status::fromExceptionCode(
+		    android::binder::Status::EX_ILLEGAL_ARGUMENT,
+		    error_msg.c_str());
+	}
+	if (wep_key.size() != WEP40_KEY_LEN &&
+	    wep_key.size() != WEP104_KEY_LEN) {
+		const std::string error_msg = "Invalid Wep Key value length: " +
+					      std::to_string(wep_key.size()) +
+					      ".";
+		return android::binder::Status::fromExceptionCode(
+		    android::binder::Status::EX_ILLEGAL_ARGUMENT,
+		    error_msg.c_str());
+	}
+	os_memcpy(wpa_ssid->wep_key[key_idx], wep_key.data(), wep_key.size());
+	wpa_ssid->wep_key_len[key_idx] = wep_key.size();
+	std::string msg_dump_title("wep_key" + std::to_string(key_idx));
+	wpa_hexdump_key(
+	    MSG_MSGDUMP, msg_dump_title.c_str(), wpa_ssid->wep_key[key_idx],
+	    wpa_ssid->wep_key_len[key_idx]);
 	return android::binder::Status::ok();
 }
 
@@ -179,6 +228,16 @@
 {
 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
 	RETURN_IF_NETWORK_INVALID(wpa_ssid);
+
+	if (wep_tx_key_idx < 0 || wep_tx_key_idx >= WEP_KEYS_MAX_NUM) {
+		const std::string error_msg = "Invalid Wep Key index: " +
+					      std::to_string(wep_tx_key_idx) +
+					      ".";
+		return android::binder::Status::fromExceptionCode(
+		    android::binder::Status::EX_ILLEGAL_ARGUMENT,
+		    error_msg.c_str());
+	}
+	wpa_ssid->wep_tx_keyidx = wep_tx_key_idx;
 	return android::binder::Status::ok();
 }
 
@@ -260,6 +319,12 @@
 {
 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
 	RETURN_IF_NETWORK_INVALID(wpa_ssid);
+
+	if (wpa_ssid->passphrase) {
+		*psk = wpa_ssid->passphrase;
+	} else {
+		*psk = std::string();
+	}
 	return android::binder::Status::ok();
 }
 
@@ -268,6 +333,18 @@
 {
 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
 	RETURN_IF_NETWORK_INVALID(wpa_ssid);
+
+	if (key_idx < 0 || key_idx >= WEP_KEYS_MAX_NUM) {
+		const std::string error_msg =
+		    "Invalid Wep Key index: " + std::to_string(key_idx) + ".";
+		return android::binder::Status::fromExceptionCode(
+		    android::binder::Status::EX_ILLEGAL_ARGUMENT,
+		    error_msg.c_str());
+	}
+
+	wep_key->assign(
+	    wpa_ssid->wep_key[key_idx],
+	    wpa_ssid->wep_key[key_idx] + wpa_ssid->wep_key_len[key_idx]);
 	return android::binder::Status::ok();
 }
 
@@ -275,6 +352,7 @@
 {
 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
 	RETURN_IF_NETWORK_INVALID(wpa_ssid);
+	*wep_tx_key_idx = wpa_ssid->wep_tx_keyidx;
 	return android::binder::Status::ok();
 }
 
@@ -364,4 +442,21 @@
 	return wpa_supplicant_get_iface(
 	    (struct wpa_global *)wpa_global_, ifname_.c_str());
 }
+
+/**
+ * Check if the provided psk passhrase is valid or not.
+ *
+ * Returns 0 if valid, 1 otherwise.
+ */
+int Network::isPskPassphraseValid(const std::string &psk)
+{
+	if (psk.size() < PSK_PASSPHRASE_MIN_LEN ||
+	    psk.size() > PSK_PASSPHRASE_MAX_LEN) {
+		return 1;
+	}
+	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
+		return 1;
+	}
+	return 0;
+}
 } // namespace wpa_supplicant_binder
diff --git a/wpa_supplicant/binder/network.h b/wpa_supplicant/binder/network.h
index 1717597..4758198 100644
--- a/wpa_supplicant/binder/network.h
+++ b/wpa_supplicant/binder/network.h
@@ -83,6 +83,7 @@
 private:
 	struct wpa_ssid *retrieveNetworkPtr();
 	struct wpa_supplicant *retrieveIfacePtr();
+	int isPskPassphraseValid(const std::string &psk);
 
 	// Reference to the global wpa_struct. This is assumed to be valid for
 	// the lifetime of the process.