libnm: rename and expose nm_utils_base64secret_decode() in libnm

A NetworkManager client requires an API to validate and decode
a base64 secret -- like it is used by WireGuard. If we don't have
this as part of the API, it's inconvenient. Expose it.

Rename it from _nm_utils_wireguard_decode_key(), to give it a more
general name.

Also, rename _nm_utils_wireguard_normalize_key() to
nm_utils_base64secret_normalize(). But this one we keep as internal
API. The user will care more about validating and decoding the base64
key. To convert the key back to base64, we don't need a public API in
libnm.

This is another ABI change since 1.16-rc1.
This commit is contained in:
Thomas Haller
2019-03-02 17:10:25 +01:00
parent f3ac8c6fe8
commit e46ba01867
7 changed files with 41 additions and 38 deletions

View File

@@ -765,13 +765,9 @@ gboolean _nm_connection_find_secret (NMConnection *self,
#define nm_auto_unref_wgpeer nm_auto(_nm_auto_unref_wgpeer) #define nm_auto_unref_wgpeer nm_auto(_nm_auto_unref_wgpeer)
NM_AUTO_DEFINE_FCN_VOID0 (NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref) NM_AUTO_DEFINE_FCN_VOID0 (NMWireGuardPeer *, _nm_auto_unref_wgpeer, nm_wireguard_peer_unref)
gboolean _nm_utils_wireguard_decode_key (const char *base64_key, gboolean nm_utils_base64secret_normalize (const char *base64_key,
gsize required_key_len, gsize required_key_len,
guint8 *out_key); char **out_base64_key_norm);
gboolean _nm_utils_wireguard_normalize_key (const char *base64_key,
gsize required_key_len,
char **out_base64_key_norm);
/*****************************************************************************/ /*****************************************************************************/

View File

@@ -2920,7 +2920,7 @@ _read_setting_wireguard_peer (KeyfileReaderInfo *info)
nm_assert (g_str_has_prefix (info->group, NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER)); nm_assert (g_str_has_prefix (info->group, NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER));
cstr = &info->group[NM_STRLEN (NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER)]; cstr = &info->group[NM_STRLEN (NM_KEYFILE_GROUPPREFIX_WIREGUARD_PEER)];
if ( !_nm_utils_wireguard_normalize_key (cstr, NM_WIREGUARD_PUBLIC_KEY_LEN, &str) if ( !nm_utils_base64secret_normalize (cstr, NM_WIREGUARD_PUBLIC_KEY_LEN, &str)
|| !nm_streq0 (str, cstr)) { || !nm_streq0 (str, cstr)) {
/* the group name must be identical to the normalized(!) key, so that it /* the group name must be identical to the normalized(!) key, so that it
* is uniquely identified. */ * is uniquely identified. */

View File

@@ -309,9 +309,9 @@ nm_wireguard_peer_set_public_key (NMWireGuardPeer *self,
return TRUE; return TRUE;
} }
is_valid = _nm_utils_wireguard_normalize_key (public_key, is_valid = nm_utils_base64secret_normalize (public_key,
NM_WIREGUARD_PUBLIC_KEY_LEN, NM_WIREGUARD_PUBLIC_KEY_LEN,
&public_key_normalized); &public_key_normalized);
nm_assert (is_valid == (public_key_normalized != NULL)); nm_assert (is_valid == (public_key_normalized != NULL));
if ( !is_valid if ( !is_valid
@@ -397,9 +397,9 @@ nm_wireguard_peer_set_preshared_key (NMWireGuardPeer *self,
return TRUE; return TRUE;
} }
is_valid = _nm_utils_wireguard_normalize_key (preshared_key, is_valid = nm_utils_base64secret_normalize (preshared_key,
NM_WIREGUARD_SYMMETRIC_KEY_LEN, NM_WIREGUARD_SYMMETRIC_KEY_LEN,
&preshared_key_normalized); &preshared_key_normalized);
nm_assert (is_valid == (preshared_key_normalized != NULL)); nm_assert (is_valid == (preshared_key_normalized != NULL));
if ( !is_valid if ( !is_valid
@@ -1128,9 +1128,9 @@ again:
return pd; return pd;
} }
if ( try_with_normalized_key if ( try_with_normalized_key
&& _nm_utils_wireguard_normalize_key (public_key, && nm_utils_base64secret_normalize (public_key,
NM_WIREGUARD_PUBLIC_KEY_LEN, NM_WIREGUARD_PUBLIC_KEY_LEN,
&public_key_normalized)) { &public_key_normalized)) {
public_key = public_key_normalized; public_key = public_key_normalized;
try_with_normalized_key = FALSE; try_with_normalized_key = FALSE;
goto again; goto again;
@@ -2299,9 +2299,9 @@ set_property (GObject *object, guint prop_id,
nm_clear_pointer (&priv->private_key, nm_free_secret); nm_clear_pointer (&priv->private_key, nm_free_secret);
str = g_value_get_string (value); str = g_value_get_string (value);
if (str) { if (str) {
if (_nm_utils_wireguard_normalize_key (str, if (nm_utils_base64secret_normalize (str,
NM_WIREGUARD_PUBLIC_KEY_LEN, NM_WIREGUARD_PUBLIC_KEY_LEN,
&priv->private_key)) &priv->private_key))
priv->private_key_valid = TRUE; priv->private_key_valid = TRUE;
else { else {
priv->private_key = g_strdup (str); priv->private_key = g_strdup (str);

View File

@@ -6673,21 +6673,23 @@ nm_utils_version (void)
/*****************************************************************************/ /*****************************************************************************/
/** /**
* _nm_utils_wireguard_decode_key: * nm_utils_base64secret_decode:
* @base64_key: the (possibly invalid) base64 encode key. * @base64_key: the (possibly invalid) base64 encode key.
* @required_key_len: the expected (binary) length of the key after * @required_key_len: the expected (binary) length of the key after
* decoding. If the length does not match, the validation fails. * decoding. If the length does not match, the validation fails.
* @out_key: (allow-none): an optional output buffer for the binary * @out_key: (allow-none): (out): an optional output buffer for the binary
* key. If given, it will be filled with exactly @required_key_len * key. If given, it will be filled with exactly @required_key_len
* bytes. * bytes.
* *
* Returns: %TRUE if the input key is a valid base64 encoded key * Returns: %TRUE if the input key is a valid base64 encoded key
* with @required_key_len bytes. * with @required_key_len bytes.
*
* Since: 1.16
*/ */
gboolean gboolean
_nm_utils_wireguard_decode_key (const char *base64_key, nm_utils_base64secret_decode (const char *base64_key,
gsize required_key_len, gsize required_key_len,
guint8 *out_key) guint8 *out_key)
{ {
gs_free guint8 *bin_arr = NULL; gs_free guint8 *bin_arr = NULL;
gsize base64_key_len; gsize base64_key_len;
@@ -6715,9 +6717,9 @@ _nm_utils_wireguard_decode_key (const char *base64_key,
} }
gboolean gboolean
_nm_utils_wireguard_normalize_key (const char *base64_key, nm_utils_base64secret_normalize (const char *base64_key,
gsize required_key_len, gsize required_key_len,
char **out_base64_key_norm) char **out_base64_key_norm)
{ {
gs_free guint8 *buf_free = NULL; gs_free guint8 *buf_free = NULL;
guint8 buf_static[200]; guint8 buf_static[200];
@@ -6729,7 +6731,7 @@ _nm_utils_wireguard_normalize_key (const char *base64_key,
} else } else
buf = buf_static; buf = buf_static;
if (!_nm_utils_wireguard_decode_key (base64_key, required_key_len, buf)) { if (!nm_utils_base64secret_decode (base64_key, required_key_len, buf)) {
NM_SET_OUT (out_base64_key_norm, NULL); NM_SET_OUT (out_base64_key_norm, NULL);
return FALSE; return FALSE;
} }

View File

@@ -263,6 +263,10 @@ NMSriovVF *nm_utils_sriov_vf_from_str (const char *str, GError **error);
NM_AVAILABLE_IN_1_12 NM_AVAILABLE_IN_1_12
gint64 nm_utils_get_timestamp_msec (void); gint64 nm_utils_get_timestamp_msec (void);
NM_AVAILABLE_IN_1_16
gboolean nm_utils_base64secret_decode (const char *base64_key,
gsize required_key_len,
guint8 *out_key);
G_END_DECLS G_END_DECLS

View File

@@ -1479,6 +1479,7 @@ global:
nm_setting_wireguard_set_peer; nm_setting_wireguard_set_peer;
nm_team_link_watcher_get_vlanid; nm_team_link_watcher_get_vlanid;
nm_team_link_watcher_new_arp_ping2; nm_team_link_watcher_new_arp_ping2;
nm_utils_base64secret_decode;
nm_wifi_p2p_peer_connection_valid; nm_wifi_p2p_peer_connection_valid;
nm_wifi_p2p_peer_filter_connections; nm_wifi_p2p_peer_filter_connections;
nm_wifi_p2p_peer_get_flags; nm_wifi_p2p_peer_get_flags;

View File

@@ -729,9 +729,9 @@ _peers_get_platform_list (NMDeviceWireGuardPrivate *priv,
NMPWireGuardPeer *plp = &plpeers[i_good]; NMPWireGuardPeer *plp = &plpeers[i_good];
NMSettingSecretFlags psk_secret_flags; NMSettingSecretFlags psk_secret_flags;
if (!_nm_utils_wireguard_decode_key (nm_wireguard_peer_get_public_key (peer_data->peer), if (!nm_utils_base64secret_decode (nm_wireguard_peer_get_public_key (peer_data->peer),
sizeof (plp->public_key), sizeof (plp->public_key),
plp->public_key)) plp->public_key))
continue; continue;
*plf = NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE; *plf = NM_PLATFORM_WIREGUARD_CHANGE_PEER_FLAG_NONE;
@@ -754,9 +754,9 @@ _peers_get_platform_list (NMDeviceWireGuardPrivate *priv,
LINK_CONFIG_MODE_REAPPLY)) { LINK_CONFIG_MODE_REAPPLY)) {
psk_secret_flags = nm_wireguard_peer_get_preshared_key_flags (peer_data->peer); psk_secret_flags = nm_wireguard_peer_get_preshared_key_flags (peer_data->peer);
if (!NM_FLAGS_HAS (psk_secret_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) { if (!NM_FLAGS_HAS (psk_secret_flags, NM_SETTING_SECRET_FLAG_NOT_REQUIRED)) {
if ( !_nm_utils_wireguard_decode_key (nm_wireguard_peer_get_preshared_key (peer_data->peer), if ( !nm_utils_base64secret_decode (nm_wireguard_peer_get_preshared_key (peer_data->peer),
sizeof (plp->preshared_key), sizeof (plp->preshared_key),
plp->preshared_key) plp->preshared_key)
&& config_mode == LINK_CONFIG_MODE_FULL) && config_mode == LINK_CONFIG_MODE_FULL)
goto skip; goto skip;
} }
@@ -1128,9 +1128,9 @@ link_config (NMDeviceWireGuard *self,
wg_lnk.fwmark = nm_setting_wireguard_get_fwmark (s_wg), wg_lnk.fwmark = nm_setting_wireguard_get_fwmark (s_wg),
wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK; wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_FWMARK;
if (_nm_utils_wireguard_decode_key (nm_setting_wireguard_get_private_key (s_wg), if (nm_utils_base64secret_decode (nm_setting_wireguard_get_private_key (s_wg),
sizeof (wg_lnk.private_key), sizeof (wg_lnk.private_key),
wg_lnk.private_key)) { wg_lnk.private_key)) {
wg_lnk_clear_private_key = NM_SECRET_PTR_ARRAY (wg_lnk.private_key); wg_lnk_clear_private_key = NM_SECRET_PTR_ARRAY (wg_lnk.private_key);
wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY; wg_change_flags |= NM_PLATFORM_WIREGUARD_CHANGE_FLAG_HAS_PRIVATE_KEY;
} else { } else {