libnm: move dependency to libnm-crypto out of libnm-core's "nm-utils.c"
libnm-core is also used by the daemon, thus currently dragging in libnm-crypto there. But could we ever drop that dependency? One use of the libnm-crypto is in functions like nm_utils_file_is_certificate() in "nm-utils.h". These are part of the public API of libnm. But this is not used by the daemon. Move it to "libnm-client-core" to be closer to where it's actually used. As we have unit tests in "libnm-core-impl/tests" that test this function, those unit tests also would need to move to "libnm-client-impl". Instead, add the actual implementation of these function to "libnm-crypto" and test it there. This patch moves forward declarations from public header "nm-utils.h" to "nm-client.h". Arguably, "nm-client.h" is not a great name, but we don't have a general purpose header in "libnm-client-public", so use this. Note that libnm users can only include <NetworkManager.h> and including individual files is not supported (and even prevented). Thus moving the declarations won't break any users.
This commit is contained in:
@@ -10,7 +10,9 @@
|
|||||||
|
|
||||||
#include "libnm-glib-aux/nm-time-utils.h"
|
#include "libnm-glib-aux/nm-time-utils.h"
|
||||||
#include "libnm-core-aux-intern/nm-common-macros.h"
|
#include "libnm-core-aux-intern/nm-common-macros.h"
|
||||||
|
#include "libnm-crypto/nm-crypto.h"
|
||||||
#include "nm-object.h"
|
#include "nm-object.h"
|
||||||
|
#include "nm-utils.h"
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
@@ -914,3 +916,58 @@ nm_utils_print(int output_mode, const char *msg)
|
|||||||
else
|
else
|
||||||
g_return_if_reached();
|
g_return_if_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_utils_file_is_certificate:
|
||||||
|
* @filename: name of the file to test
|
||||||
|
*
|
||||||
|
* Tests if @filename has a valid extension for an X.509 certificate file
|
||||||
|
* (".cer", ".crt", ".der", or ".pem"), and contains a certificate in a format
|
||||||
|
* recognized by NetworkManager.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the file is a certificate, %FALSE if it is not
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
nm_utils_file_is_certificate(const char *filename)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(filename != NULL, FALSE);
|
||||||
|
|
||||||
|
return nm_crypto_utils_file_is_certificate(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_utils_file_is_private_key:
|
||||||
|
* @filename: name of the file to test
|
||||||
|
* @out_encrypted: (out): on return, whether the file is encrypted
|
||||||
|
*
|
||||||
|
* Tests if @filename has a valid extension for an X.509 private key file
|
||||||
|
* (".der", ".key", ".pem", or ".p12"), and contains a private key in a format
|
||||||
|
* recognized by NetworkManager.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the file is a private key, %FALSE if it is not
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
nm_utils_file_is_private_key(const char *filename, gboolean *out_encrypted)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(filename != NULL, FALSE);
|
||||||
|
|
||||||
|
return nm_crypto_utils_file_is_private_key(filename, out_encrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* nm_utils_file_is_pkcs12:
|
||||||
|
* @filename: name of the file to test
|
||||||
|
*
|
||||||
|
* Tests if @filename is a PKCS#<!-- -->12 file.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE if the file is PKCS#<!-- -->12, %FALSE if it is not
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
nm_utils_file_is_pkcs12(const char *filename)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(filename != NULL, FALSE);
|
||||||
|
|
||||||
|
return nm_crypto_is_pkcs12_file(filename, NULL);
|
||||||
|
}
|
||||||
|
@@ -496,6 +496,10 @@ gboolean nm_client_dbus_set_property_finish(NMClient *client, GAsyncResult *resu
|
|||||||
NM_AVAILABLE_IN_1_30
|
NM_AVAILABLE_IN_1_30
|
||||||
void nm_utils_print(int output_mode, const char *msg);
|
void nm_utils_print(int output_mode, const char *msg);
|
||||||
|
|
||||||
|
gboolean nm_utils_file_is_certificate(const char *filename);
|
||||||
|
gboolean nm_utils_file_is_private_key(const char *filename, gboolean *out_encrypted);
|
||||||
|
gboolean nm_utils_file_is_pkcs12(const char *filename);
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __NM_CLIENT_H__ */
|
#endif /* __NM_CLIENT_H__ */
|
||||||
|
@@ -17,7 +17,6 @@
|
|||||||
#include <linux/pkt_sched.h>
|
#include <linux/pkt_sched.h>
|
||||||
#include <linux/if_infiniband.h>
|
#include <linux/if_infiniband.h>
|
||||||
|
|
||||||
#include "libnm-crypto/nm-crypto.h"
|
|
||||||
#include "libnm-glib-aux/nm-uuid.h"
|
#include "libnm-glib-aux/nm-uuid.h"
|
||||||
#include "libnm-glib-aux/nm-json-aux.h"
|
#include "libnm-glib-aux/nm-json-aux.h"
|
||||||
#include "libnm-glib-aux/nm-str-buf.h"
|
#include "libnm-glib-aux/nm-str-buf.h"
|
||||||
@@ -3083,94 +3082,6 @@ nm_utils_uuid_generate(void)
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static gboolean
|
|
||||||
file_has_extension(const char *filename, const char *extensions[])
|
|
||||||
{
|
|
||||||
const char *ext;
|
|
||||||
gsize i;
|
|
||||||
|
|
||||||
ext = strrchr(filename, '.');
|
|
||||||
if (!ext)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
for (i = 0; extensions[i]; i++) {
|
|
||||||
if (!g_ascii_strcasecmp(ext, extensions[i]))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nm_utils_file_is_certificate:
|
|
||||||
* @filename: name of the file to test
|
|
||||||
*
|
|
||||||
* Tests if @filename has a valid extension for an X.509 certificate file
|
|
||||||
* (".cer", ".crt", ".der", or ".pem"), and contains a certificate in a format
|
|
||||||
* recognized by NetworkManager.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if the file is a certificate, %FALSE if it is not
|
|
||||||
**/
|
|
||||||
gboolean
|
|
||||||
nm_utils_file_is_certificate(const char *filename)
|
|
||||||
{
|
|
||||||
const char *extensions[] = {".der", ".pem", ".crt", ".cer", NULL};
|
|
||||||
NMCryptoFileFormat file_format;
|
|
||||||
|
|
||||||
g_return_val_if_fail(filename != NULL, FALSE);
|
|
||||||
|
|
||||||
if (!file_has_extension(filename, extensions))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (!nm_crypto_load_and_verify_certificate(filename, &file_format, NULL, NULL))
|
|
||||||
return FALSE;
|
|
||||||
return file_format = NM_CRYPTO_FILE_FORMAT_X509;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nm_utils_file_is_private_key:
|
|
||||||
* @filename: name of the file to test
|
|
||||||
* @out_encrypted: (out): on return, whether the file is encrypted
|
|
||||||
*
|
|
||||||
* Tests if @filename has a valid extension for an X.509 private key file
|
|
||||||
* (".der", ".key", ".pem", or ".p12"), and contains a private key in a format
|
|
||||||
* recognized by NetworkManager.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if the file is a private key, %FALSE if it is not
|
|
||||||
**/
|
|
||||||
gboolean
|
|
||||||
nm_utils_file_is_private_key(const char *filename, gboolean *out_encrypted)
|
|
||||||
{
|
|
||||||
const char *extensions[] = {".der", ".pem", ".p12", ".key", NULL};
|
|
||||||
|
|
||||||
g_return_val_if_fail(filename != NULL, FALSE);
|
|
||||||
|
|
||||||
NM_SET_OUT(out_encrypted, FALSE);
|
|
||||||
if (!file_has_extension(filename, extensions))
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
return nm_crypto_verify_private_key(filename, NULL, out_encrypted, NULL)
|
|
||||||
!= NM_CRYPTO_FILE_FORMAT_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* nm_utils_file_is_pkcs12:
|
|
||||||
* @filename: name of the file to test
|
|
||||||
*
|
|
||||||
* Tests if @filename is a PKCS#<!-- -->12 file.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if the file is PKCS#<!-- -->12, %FALSE if it is not
|
|
||||||
**/
|
|
||||||
gboolean
|
|
||||||
nm_utils_file_is_pkcs12(const char *filename)
|
|
||||||
{
|
|
||||||
g_return_val_if_fail(filename != NULL, FALSE);
|
|
||||||
|
|
||||||
return nm_crypto_is_pkcs12_file(filename, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
gboolean
|
gboolean
|
||||||
_nm_utils_check_file(const char *filename,
|
_nm_utils_check_file(const char *filename,
|
||||||
gint64 check_owner,
|
gint64 check_owner,
|
||||||
|
@@ -92,7 +92,7 @@ test_cert(gconstpointer test_data)
|
|||||||
nmtst_assert_success(success, error);
|
nmtst_assert_success(success, error);
|
||||||
g_assert_cmpint(format, ==, NM_CRYPTO_FILE_FORMAT_X509);
|
g_assert_cmpint(format, ==, NM_CRYPTO_FILE_FORMAT_X509);
|
||||||
|
|
||||||
g_assert(nm_utils_file_is_certificate(path));
|
g_assert(nm_crypto_utils_file_is_certificate(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -106,7 +106,7 @@ test_load_private_key(const char *path,
|
|||||||
gs_unref_bytes GBytes *array = NULL;
|
gs_unref_bytes GBytes *array = NULL;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_assert(nm_utils_file_is_private_key(path, &is_encrypted));
|
g_assert(nm_crypto_utils_file_is_private_key(path, &is_encrypted));
|
||||||
g_assert(is_encrypted);
|
g_assert(is_encrypted);
|
||||||
|
|
||||||
array = nmtst_crypto_decrypt_openssl_private_key(path, password, &key_type, &error);
|
array = nmtst_crypto_decrypt_openssl_private_key(path, password, &key_type, &error);
|
||||||
@@ -146,7 +146,7 @@ test_load_pkcs12(const char *path, const char *password, int expected_error)
|
|||||||
gboolean is_encrypted = FALSE;
|
gboolean is_encrypted = FALSE;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_assert(nm_utils_file_is_private_key(path, NULL));
|
g_assert(nm_crypto_utils_file_is_private_key(path, NULL));
|
||||||
|
|
||||||
format = nm_crypto_verify_private_key(path, password, &is_encrypted, &error);
|
format = nm_crypto_verify_private_key(path, password, &is_encrypted, &error);
|
||||||
if (expected_error != -1) {
|
if (expected_error != -1) {
|
||||||
@@ -167,7 +167,7 @@ test_load_pkcs12_no_password(const char *path)
|
|||||||
gboolean is_encrypted = FALSE;
|
gboolean is_encrypted = FALSE;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_assert(nm_utils_file_is_private_key(path, NULL));
|
g_assert(nm_crypto_utils_file_is_private_key(path, NULL));
|
||||||
|
|
||||||
/* We should still get a valid returned crypto file format */
|
/* We should still get a valid returned crypto file format */
|
||||||
format = nm_crypto_verify_private_key(path, NULL, &is_encrypted, &error);
|
format = nm_crypto_verify_private_key(path, NULL, &is_encrypted, &error);
|
||||||
@@ -201,7 +201,7 @@ test_load_pkcs8(const char *path, const char *password, int expected_error)
|
|||||||
gboolean is_encrypted = FALSE;
|
gboolean is_encrypted = FALSE;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
|
|
||||||
g_assert(nm_utils_file_is_private_key(path, NULL));
|
g_assert(nm_crypto_utils_file_is_private_key(path, NULL));
|
||||||
|
|
||||||
format = nm_crypto_verify_private_key(path, password, &is_encrypted, &error);
|
format = nm_crypto_verify_private_key(path, password, &is_encrypted, &error);
|
||||||
if (expected_error != -1) {
|
if (expected_error != -1) {
|
||||||
@@ -285,7 +285,7 @@ test_key_decrypted(gconstpointer test_data)
|
|||||||
|
|
||||||
path = g_build_filename(TEST_CERT_DIR, file, NULL);
|
path = g_build_filename(TEST_CERT_DIR, file, NULL);
|
||||||
|
|
||||||
g_assert(nm_utils_file_is_private_key(path, &is_encrypted));
|
g_assert(nm_crypto_utils_file_is_private_key(path, &is_encrypted));
|
||||||
g_assert(!is_encrypted);
|
g_assert(!is_encrypted);
|
||||||
|
|
||||||
g_free(path);
|
g_free(path);
|
||||||
|
@@ -111,10 +111,6 @@ GPtrArray *nm_utils_ip_routes_from_variant(GVariant *value, int family);
|
|||||||
|
|
||||||
char *nm_utils_uuid_generate(void);
|
char *nm_utils_uuid_generate(void);
|
||||||
|
|
||||||
gboolean nm_utils_file_is_certificate(const char *filename);
|
|
||||||
gboolean nm_utils_file_is_private_key(const char *filename, gboolean *out_encrypted);
|
|
||||||
gboolean nm_utils_file_is_pkcs12(const char *filename);
|
|
||||||
|
|
||||||
typedef gboolean (*NMUtilsFileSearchInPathsPredicate)(const char *filename, gpointer user_data);
|
typedef gboolean (*NMUtilsFileSearchInPathsPredicate)(const char *filename, gpointer user_data);
|
||||||
|
|
||||||
struct stat;
|
struct stat;
|
||||||
|
@@ -1042,3 +1042,54 @@ nmtst_crypto_rsa_key_encrypt(const guint8 *data,
|
|||||||
NM_SET_OUT(out_password, g_strdup(tmp_password));
|
NM_SET_OUT(out_password, g_strdup(tmp_password));
|
||||||
return nm_secret_buf_to_gbytes_take(ret, ret_len);
|
return nm_secret_buf_to_gbytes_take(ret, ret_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
file_has_extension(const char *filename, const char *extensions[])
|
||||||
|
{
|
||||||
|
const char *ext;
|
||||||
|
gsize i;
|
||||||
|
|
||||||
|
ext = strrchr(filename, '.');
|
||||||
|
if (!ext)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; extensions[i]; i++) {
|
||||||
|
if (!g_ascii_strcasecmp(ext, extensions[i]))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_crypto_utils_file_is_certificate(const char *filename)
|
||||||
|
{
|
||||||
|
const char *extensions[] = {".der", ".pem", ".crt", ".cer", NULL};
|
||||||
|
NMCryptoFileFormat file_format;
|
||||||
|
|
||||||
|
nm_assert(filename);
|
||||||
|
|
||||||
|
if (!file_has_extension(filename, extensions))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (!nm_crypto_load_and_verify_certificate(filename, &file_format, NULL, NULL))
|
||||||
|
return FALSE;
|
||||||
|
return file_format = NM_CRYPTO_FILE_FORMAT_X509;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
nm_crypto_utils_file_is_private_key(const char *filename, gboolean *out_encrypted)
|
||||||
|
{
|
||||||
|
const char *extensions[] = {".der", ".pem", ".p12", ".key", NULL};
|
||||||
|
|
||||||
|
nm_assert(filename);
|
||||||
|
|
||||||
|
NM_SET_OUT(out_encrypted, FALSE);
|
||||||
|
if (!file_has_extension(filename, extensions))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return nm_crypto_verify_private_key(filename, NULL, out_encrypted, NULL)
|
||||||
|
!= NM_CRYPTO_FILE_FORMAT_UNKNOWN;
|
||||||
|
}
|
||||||
|
@@ -93,4 +93,7 @@ guint8 *nmtst_crypto_make_des_aes_key(NMCryptoCipherType cipher,
|
|||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
gboolean nm_crypto_utils_file_is_certificate(const char *filename);
|
||||||
|
gboolean nm_crypto_utils_file_is_private_key(const char *filename, gboolean *out_encrypted);
|
||||||
|
|
||||||
#endif /* __NM_CRYPTO_H__ */
|
#endif /* __NM_CRYPTO_H__ */
|
||||||
|
Reference in New Issue
Block a user