3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-12-23 06:02:37 +01:00

network: ensure passphrase is valid when psk is set

If PreSharedKey is set, the current logic does not validate the
Passphrase beyond its existence.  This can lead to strange situations
where an invalid WPA3-PSK passphrase might get used.  This can of course
only happen if the user (as root) or NetworkManager-iwd-backend writes
such a file incorrectly.
This commit is contained in:
Denis Kenzior 2021-04-27 09:34:22 -05:00
parent 8d58f5b679
commit 654154e721

View File

@ -32,6 +32,8 @@
#include <ell/ell.h> #include <ell/ell.h>
#include "ell/useful.h"
#include "src/missing.h" #include "src/missing.h"
#include "src/module.h" #include "src/module.h"
#include "src/ie.h" #include "src/ie.h"
@ -377,56 +379,54 @@ static int network_load_psk(struct network *network, bool need_passphrase)
size_t psk_len; size_t psk_len;
uint8_t *psk = l_settings_get_bytes(network->settings, "Security", uint8_t *psk = l_settings_get_bytes(network->settings, "Security",
"PreSharedKey", &psk_len); "PreSharedKey", &psk_len);
char *passphrase = l_settings_get_string(network->settings, _auto_(l_free) char *passphrase =
l_settings_get_string(network->settings,
"Security", "Passphrase"); "Security", "Passphrase");
_auto_(l_free) char *path =
storage_get_network_file_path(security, ssid);
int r; int r;
/* PSK can be generated from the passphrase but not the other way */ if (psk && psk_len != 32) {
if ((!psk || need_passphrase) && !passphrase) { l_error("%s: invalid PreSharedKey format", path);
l_free(psk); l_free(psk);
return -ENOKEY; psk = NULL;
psk_len = 0;
}
/* PSK can be generated from the passphrase but not the other way */
if (!psk || need_passphrase) {
if (!passphrase)
return -ENOKEY;
if (!crypto_passphrase_is_valid(passphrase)) {
l_error("%s: invalid Passphrase format", path);
return -ENOKEY;
}
} }
network_reset_passphrase(network); network_reset_passphrase(network);
network_reset_psk(network); network_reset_psk(network);
network->passphrase = passphrase; network->passphrase = l_steal_ptr(passphrase);
if (psk) { if (psk) {
char *path; network->psk = psk;
return 0;
if (psk_len == 32) {
network->psk = psk;
return 0;
}
l_free(psk);
path = storage_get_network_file_path(security, ssid);
l_error("%s: invalid PreSharedKey format", path);
l_free(path);
if (!passphrase)
return -EINVAL;
} }
network->psk = l_malloc(32); network->psk = l_malloc(32);
r = crypto_psk_from_passphrase(passphrase, (uint8_t *) ssid, r = crypto_psk_from_passphrase(network->passphrase, (uint8_t *) ssid,
strlen(ssid), network->psk); strlen(ssid), network->psk);
if (!r) { if (!r) {
network->update_psk = true; network->update_psk = true;
return 0; return 0;
} }
if (r == -ERANGE || r == -EINVAL) l_error("PSK generation failed: %s", strerror(-r));
l_error("PSK generation failed: invalid passphrase format");
else
l_error("PSK generation failed: %s. "
"Ensure Crypto Engine is properly configured",
strerror(-r));
network_reset_passphrase(network); network_reset_passphrase(network);
network_reset_psk(network); network_reset_psk(network);
return -EINVAL;
return r;
} }
void network_sync_psk(struct network *network) void network_sync_psk(struct network *network)