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.
This commit is contained in:
@@ -359,6 +359,19 @@ file_read_contents (const char *filename,
|
|||||||
error) >= 0;
|
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.
|
* Convert a hex string into bytes.
|
||||||
*/
|
*/
|
||||||
|
@@ -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,
|
gboolean nm_crypto_load_and_verify_certificate (const char *file,
|
||||||
NMCryptoFileFormat *out_file_format,
|
NMCryptoFileFormat *out_file_format,
|
||||||
GBytes **out_certificat,
|
GBytes **out_certificat,
|
||||||
|
@@ -2165,32 +2165,6 @@ nm_setting_802_1x_get_private_key_uri (NMSetting8021x *setting)
|
|||||||
return (const char *)data;
|
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:
|
* nm_setting_802_1x_set_private_key:
|
||||||
* @setting: the #NMSetting8021x
|
* @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) {
|
if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
|
||||||
/* FIXME: potential race after verifying the private key above */
|
/* FIXME: potential race after verifying the private key above */
|
||||||
/* FIXME: ensure blob doesn't start with file:// */
|
/* 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);
|
nm_assert (priv->private_key);
|
||||||
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
|
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
|
||||||
priv->private_key = path_to_scheme_value (value);
|
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) {
|
if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
|
||||||
/* FIXME: potential race after verifying the private key above */
|
/* FIXME: potential race after verifying the private key above */
|
||||||
/* FIXME: ensure blob doesn't start with file:// */
|
/* 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);
|
nm_assert (priv->phase2_private_key);
|
||||||
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
|
} else if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
|
||||||
priv->phase2_private_key = path_to_scheme_value (value);
|
priv->phase2_private_key = path_to_scheme_value (value);
|
||||||
|
Reference in New Issue
Block a user