diff options
author | Thomas Haller <thaller@redhat.com> | 2018-08-30 15:38:47 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2018-09-03 18:07:59 +0200 |
commit | 50de8501425701745ba6765a439accad8c9f1ec2 (patch) | |
tree | d6fc9a0befd1985bd1f867d73cd316eff9589385 | |
parent | b5932892d57413ec2c496c981b70b7ccf5272491 (diff) | |
download | NetworkManager-50de8501425701745ba6765a439accad8c9f1ec2.tar.gz |
libnm/crypto: fix loading certificates from file securely
file_to_secure_bytes() tried to load the file from disk and ensure that
the data will be cleared. It did so poorely, because g_file_get_contents()
cannot be used for that.
Add a helper function nm_crypto_read_file() to get this right.
-rw-r--r-- | libnm-core/nm-crypto.c | 13 | ||||
-rw-r--r-- | libnm-core/nm-crypto.h | 3 | ||||
-rw-r--r-- | libnm-core/nm-setting-8021x.c | 30 |
3 files changed, 18 insertions, 28 deletions
diff --git a/libnm-core/nm-crypto.c b/libnm-core/nm-crypto.c index e1235ccbbe..776a6d6858 100644 --- a/libnm-core/nm-crypto.c +++ b/libnm-core/nm-crypto.c @@ -359,6 +359,19 @@ file_read_contents (const char *filename, error) >= 0; } +GBytes * +nm_crypto_read_file (const char *filename, + GError **error) +{ + nm_auto_clear_secret_ptr NMSecretPtr contents = { 0 }; + + g_return_val_if_fail (filename, NULL); + + if (!file_read_contents (filename, &contents, error)) + return NULL; + return nm_secret_copy_to_gbytes (contents.bin, contents.len); +} + /* * Convert a hex string into bytes. */ diff --git a/libnm-core/nm-crypto.h b/libnm-core/nm-crypto.h index 1b9e039484..59c2f7c3e1 100644 --- a/libnm-core/nm-crypto.h +++ b/libnm-core/nm-crypto.h @@ -51,6 +51,9 @@ typedef enum { /*****************************************************************************/ +GBytes *nm_crypto_read_file (const char *filename, + GError **error); + gboolean nm_crypto_load_and_verify_certificate (const char *file, NMCryptoFileFormat *out_file_format, GBytes **out_certificat, diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c index 4fae2c64e6..7218e7e536 100644 --- a/libnm-core/nm-setting-8021x.c +++ b/libnm-core/nm-setting-8021x.c @@ -2165,32 +2165,6 @@ nm_setting_802_1x_get_private_key_uri (NMSetting8021x *setting) return (const char *)data; } -static void -free_secure_bytes (gpointer data) -{ - GByteArray *array = data; - - memset (array->data, 0, array->len); - g_byte_array_unref (array); -} - -static GBytes * -file_to_secure_bytes (const char *filename) -{ - char *contents; - GByteArray *array = NULL; - gsize length = 0; - - if (g_file_get_contents (filename, &contents, &length, NULL)) { - array = g_byte_array_sized_new (length); - g_byte_array_append (array, (guint8 *) contents, length); - memset (contents, 0, length); - g_free (contents); - return g_bytes_new_with_free_func (array->data, array->len, free_secure_bytes, array); - } - return NULL; -} - /** * nm_setting_802_1x_set_private_key: * @setting: the #NMSetting8021x @@ -2295,7 +2269,7 @@ nm_setting_802_1x_set_private_key (NMSetting8021x *setting, if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { /* FIXME: potential race after verifying the private key above */ /* FIXME: ensure blob doesn't start with file:// */ - priv->private_key = file_to_secure_bytes (value); + priv->private_key = nm_crypto_read_file (value, NULL); nm_assert (priv->private_key); } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) priv->private_key = path_to_scheme_value (value); @@ -2637,7 +2611,7 @@ nm_setting_802_1x_set_phase2_private_key (NMSetting8021x *setting, if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) { /* FIXME: potential race after verifying the private key above */ /* FIXME: ensure blob doesn't start with file:// */ - priv->phase2_private_key = file_to_secure_bytes (value); + priv->phase2_private_key = nm_crypto_read_file (value, NULL); nm_assert (priv->phase2_private_key); } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH) priv->phase2_private_key = path_to_scheme_value (value); |