From 47bb5b5f729d074598a330d2ea4d52eb415c37e1 Mon Sep 17 00:00:00 2001 From: Andrew Zaborowski Date: Mon, 3 Dec 2018 15:40:44 +0100 Subject: [PATCH] network: Generate the PSK as soon as we have a passphrase In the name of failing earlier try to generate the PSK from the passphrase as soon as we receive the passphrase or read it from the file, mainly to validate it has the right number of characters. The passphrase length currently gets validates inside crypto_psk_from_passphrase which will be called when we receive a new passphrase from the agent or when the config file has no PSK in it. We do not do this when there's already both the PSK and the passphrase available in the settings -- we can add that separately if needed. --- src/network.c | 86 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/src/network.c b/src/network.c index e1facfd9..b741d994 100644 --- a/src/network.c +++ b/src/network.c @@ -314,28 +314,7 @@ enum security network_get_security(const struct network *network) const uint8_t *network_get_psk(struct network *network) { - int r; - - if (network->psk) - return network->psk; - - if (!network->passphrase) - return NULL; - - network->psk = l_malloc(32); - r = crypto_psk_from_passphrase(network->passphrase, - (uint8_t *) network->info->ssid, - strlen(network->info->ssid), - network->psk); - if (!r) - return network->psk; - - l_free(network->psk); - network->psk = NULL; - l_error("PMK generation failed: %s. " - "Ensure Crypto Engine is properly configured", - strerror(-r)); - return NULL; + return network->psk; } const char *network_get_passphrase(const struct network *network) @@ -427,19 +406,52 @@ static int network_load_psk(struct network *network, bool need_passphrase) "Security", "PreSharedKey"); char *passphrase = l_settings_get_string(network->settings, "Security", "Passphrase"); + struct network_info *info = network->info; + int r; + /* PSK can be generated from the passphrase but not the other way */ if ((!psk || need_passphrase) && !passphrase) return -ENOKEY; l_free(network->passphrase); network->passphrase = passphrase; l_free(network->psk); - network->psk = l_util_from_hexstring(psk, &len); - if (network->psk && len == 32) + + if (psk) { + char *path; + + network->psk = l_util_from_hexstring(psk, &len); + if (network->psk && len == 32) + return 0; + + path = storage_get_network_file_path(info->type, info->ssid); + l_error("%s: invalid PreSharedKey format", path); + l_free(path); + + if (!passphrase) + goto reset_psk; + + l_free(network->psk); + } + + network->psk = l_malloc(32); + r = crypto_psk_from_passphrase(passphrase, (uint8_t *) info->ssid, + strlen(info->ssid), network->psk); + if (!r) { + network->update_psk = true; return 0; + } + + if (r == -ERANGE || r == -EINVAL) + l_error("PSK generation failed: invalid passphrase format"); + else + l_error("PSK generation failed: %s. " + "Ensure Crypto Engine is properly configured", + strerror(-r)); l_free(network->passphrase); network->passphrase = NULL; +reset_psk: l_free(network->psk); network->psk = NULL; return -EINVAL; @@ -677,6 +689,7 @@ static void passphrase_callback(enum agent_result result, struct network *network = user_data; struct station *station = network->station; struct scan_bss *bss; + int r; l_debug("result %d", result); @@ -703,7 +716,30 @@ static void passphrase_callback(enum agent_result result, } l_free(network->psk); - network->psk = NULL; + network->psk = l_malloc(32); + r = crypto_psk_from_passphrase(passphrase, + (uint8_t *) network->info->ssid, + strlen(network->info->ssid), + network->psk); + if (r) { + struct l_dbus_message *error; + + l_free(network->psk); + network->psk = NULL; + + if (r == -ERANGE || r == -EINVAL) + error = dbus_error_invalid_format(message); + else { + l_error("PSK generation failed: %s. " + "Ensure Crypto Engine is properly configured", + strerror(-r)); + error = dbus_error_failed(message); + } + + dbus_pending_reply(&message, error); + goto err; + } + l_free(network->passphrase); network->passphrase = l_strdup(passphrase);