summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-03-29 12:00:28 +0200
committerThomas Haller <thaller@redhat.com>2022-03-29 12:00:28 +0200
commit318776c56ddc2e83594d4c298b04d5215ae6ae29 (patch)
treeac36ebac56998f7d630a3b9a49b6d111499585a9
parentf6ee923ff568543dbb645da85b4923e5369446c8 (diff)
parent9aa02f6543f525740bb9e5594fcde835905ba6fd (diff)
libnm: merge branch 'th/libnm-crypto'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1155
-rw-r--r--Makefile.am98
-rw-r--r--meson.build4
-rw-r--r--po/POTFILES.in8
-rw-r--r--src/libnm-base/meson.build1
-rw-r--r--src/libnm-base/nm-base.c11
-rw-r--r--src/libnm-base/nm-base.h16
-rw-r--r--src/libnm-client-impl/nm-libnm-utils.c57
-rw-r--r--src/libnm-client-public/NetworkManager.h4
-rw-r--r--src/libnm-client-public/nm-client.h4
-rw-r--r--src/libnm-core-impl/meson.build40
-rw-r--r--src/libnm-core-impl/nm-errors.c14
-rw-r--r--src/libnm-core-impl/nm-setting-8021x.c4
-rw-r--r--src/libnm-core-impl/nm-utils.c100
-rw-r--r--src/libnm-core-impl/tests/test-crypto.c32
-rw-r--r--src/libnm-core-public/nm-utils.h4
-rw-r--r--src/libnm-crypto/README.md7
-rw-r--r--src/libnm-crypto/meson.build69
-rw-r--r--src/libnm-crypto/nm-crypto-gnutls.c (renamed from src/libnm-core-impl/nm-crypto-gnutls.c)75
-rw-r--r--src/libnm-crypto/nm-crypto-impl.h (renamed from src/libnm-core-impl/nm-crypto-impl.h)1
-rw-r--r--src/libnm-crypto/nm-crypto-nss.c (renamed from src/libnm-core-impl/nm-crypto-nss.c)108
-rw-r--r--src/libnm-crypto/nm-crypto-null.c (renamed from src/libnm-core-impl/nm-crypto-null.c)29
-rw-r--r--src/libnm-crypto/nm-crypto.c (renamed from src/libnm-core-impl/nm-crypto.c)227
-rw-r--r--src/libnm-crypto/nm-crypto.h (renamed from src/libnm-core-impl/nm-crypto.h)3
-rw-r--r--src/libnm-glib-aux/nm-secret-utils.c33
-rw-r--r--src/libnm-glib-aux/nm-secret-utils.h4
-rw-r--r--src/libnm-glib-aux/nm-shared-utils.c21
-rw-r--r--src/libnm-glib-aux/nm-shared-utils.h2
-rw-r--r--src/meson.build1
28 files changed, 575 insertions, 402 deletions
diff --git a/Makefile.am b/Makefile.am
index 760b46b97a..c7d5c934e3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -110,11 +110,15 @@ include config-extra.h.mk
DISTCLEANFILES += config-extra.h
-$(src_libnm_core_public_mkenums_h): config-extra.h
$(src_libnm_core_public_mkenums_c): config-extra.h
+$(src_libnm_core_public_mkenums_h): config-extra.h
+src/core/dhcp/.dirstamp: config-extra.h
+src/libnm-base/.dirstamp: config-extra.h
+src/libnm-client-public/.dirstamp: config-extra.h
+src/libnm-client-public/.dirstamp: config-extra.h
src/libnm-core-impl/.dirstamp: config-extra.h
src/libnm-core-impl/.dirstamp: config-extra.h
-src/libnm-base/.dirstamp: config-extra.h
+src/libnm-crypto/.dirstamp: config-extra.h
src/libnm-glib-aux/.dirstamp: config-extra.h
src/libnm-glib-aux/tests/.dirstamp: config-extra.h
src/libnm-log-core/.dirstamp: config-extra.h
@@ -124,14 +128,11 @@ src/libnm-platform/tests/.dirstamp: config-extra.h
src/libnm-platform/wifi/.dirstamp: config-extra.h
src/libnm-platform/wpan/.dirstamp: config-extra.h
src/libnm-std-aux/.dirstamp: config-extra.h
-src/libnm-udev-aux/.dirstamp: config-extra.h
src/libnm-systemd-shared/.dirstamp: config-extra.h
src/libnm-systemd-shared/src/basic/.dirstamp: config-extra.h
src/libnm-systemd-shared/src/fundamental/.dirstamp: config-extra.h
src/libnm-systemd-shared/src/shared/.dirstamp: config-extra.h
-src/libnm-client-public/.dirstamp: config-extra.h
-src/libnm-client-public/.dirstamp: config-extra.h
-src/core/dhcp/.dirstamp: config-extra.h
+src/libnm-udev-aux/.dirstamp: config-extra.h
###############################################################################
@@ -499,6 +500,7 @@ src_libnm_base_libnm_base_la_CPPFLAGS = \
$(NULL)
src_libnm_base_libnm_base_la_SOURCES = \
+ src/libnm-base/nm-base.c \
src/libnm-base/nm-base.h \
src/libnm-base/nm-config-base.h \
src/libnm-base/nm-ethtool-base.c \
@@ -1241,8 +1243,6 @@ src_libnm_core_public_mkenums_h = \
$(NULL)
src_libnm_core_impl_lib_h_priv = \
src/libnm-core-impl/nm-connection-private.h \
- src/libnm-core-impl/nm-crypto-impl.h \
- src/libnm-core-impl/nm-crypto.h \
src/libnm-core-impl/nm-default-libnm-core.h \
src/libnm-core-impl/nm-property-compare.h \
src/libnm-core-impl/nm-setting-private.h \
@@ -1312,7 +1312,6 @@ src_libnm_core_impl_lib_c_settings_real = \
src_libnm_core_impl_lib_c_real = \
$(src_libnm_core_impl_lib_c_settings_real) \
src/libnm-core-impl/nm-connection.c \
- src/libnm-core-impl/nm-crypto.c \
src/libnm-core-impl/nm-dbus-utils.c \
src/libnm-core-impl/nm-errors.c \
src/libnm-core-impl/nm-keyfile-utils.c \
@@ -1413,8 +1412,6 @@ src_libnm_core_impl_libnm_core_impl_la_LDFLAGS = \
$(NULL)
EXTRA_DIST += \
- src/libnm-core-impl/nm-crypto-gnutls.c \
- src/libnm-core-impl/nm-crypto-nss.c \
src/libnm-core-impl/meson.build \
$(NULL)
@@ -1436,62 +1433,93 @@ dist_dependencies += \
###############################################################################
+noinst_LTLIBRARIES += src/libnm-crypto/libnm-crypto.la
+
+src_libnm_crypto_libnm_crypto_la_SOURCES = \
+ src/libnm-crypto/nm-crypto-impl.h \
+ src/libnm-crypto/nm-crypto.c \
+ src/libnm-crypto/nm-crypto.h \
+ $(NULL)
+
+src_libnm_crypto_libnm_crypto_la_CPPFLAGS = \
+ $(dflt_cppflags_libnm_core) \
+ $(NULL)
+
+src_libnm_crypto_libnm_crypto_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(NULL)
+
+src_libnm_crypto_libnm_crypto_la_LDFLAGS = \
+ $(CODE_COVERAGE_LDFLAGS) \
+ $(SANITIZER_LIB_LDFLAGS) \
+ $(NULL)
+
if HAVE_CRYPTO_GNUTLS
if WITH_GNUTLS
-libnm_crypto_lib = src/libnm-core-impl/libnm-crypto-gnutls.la
+libnm_crypto_lib = src/libnm-crypto/libnm-crypto-gnutls.la
else
-check_ltlibraries += src/libnm-core-impl/libnm-crypto-gnutls.la
+check_ltlibraries += src/libnm-crypto/libnm-crypto-gnutls.la
endif
-src_libnm_core_impl_libnm_crypto_gnutls_la_SOURCES = src/libnm-core-impl/nm-crypto-gnutls.c
-src_libnm_core_impl_libnm_crypto_gnutls_la_CPPFLAGS = \
+src_libnm_crypto_libnm_crypto_gnutls_la_SOURCES = src/libnm-crypto/nm-crypto-gnutls.c
+src_libnm_crypto_libnm_crypto_gnutls_la_CPPFLAGS = \
$(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) \
$(GNUTLS_CFLAGS)
-src_libnm_core_impl_libnm_crypto_gnutls_la_LDFLAGS = \
+src_libnm_crypto_libnm_crypto_gnutls_la_LDFLAGS = \
$(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS)
-src_libnm_core_impl_libnm_crypto_gnutls_la_LIBADD = \
+src_libnm_crypto_libnm_crypto_gnutls_la_LIBADD = \
$(GLIB_LIBS) \
$(GNUTLS_LIBS)
endif
if HAVE_CRYPTO_NSS
if WITH_NSS
-libnm_crypto_lib = src/libnm-core-impl/libnm-crypto-nss.la
+libnm_crypto_lib = src/libnm-crypto/libnm-crypto-nss.la
else
-check_ltlibraries += src/libnm-core-impl/libnm-crypto-nss.la
+check_ltlibraries += src/libnm-crypto/libnm-crypto-nss.la
endif
-src_libnm_core_impl_libnm_crypto_nss_la_SOURCES = src/libnm-core-impl/nm-crypto-nss.c
-src_libnm_core_impl_libnm_crypto_nss_la_CPPFLAGS = \
+src_libnm_crypto_libnm_crypto_nss_la_SOURCES = src/libnm-crypto/nm-crypto-nss.c
+src_libnm_crypto_libnm_crypto_nss_la_CPPFLAGS = \
$(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) \
$(NSS_CFLAGS)
-src_libnm_core_impl_libnm_crypto_nss_la_LDFLAGS = \
+src_libnm_crypto_libnm_crypto_nss_la_LDFLAGS = \
$(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS)
-src_libnm_core_impl_libnm_crypto_nss_la_LIBADD = \
+src_libnm_crypto_libnm_crypto_nss_la_LIBADD = \
$(GLIB_LIBS) \
$(NSS_LIBS)
endif
if !WITH_GNUTLS
if !WITH_NSS
-libnm_crypto_lib = src/libnm-core-impl/libnm-crypto-null.la
+libnm_crypto_lib = src/libnm-crypto/libnm-crypto-null.la
else
-check_ltlibraries += src/libnm-core-impl/libnm-crypto-null.la
+check_ltlibraries += src/libnm-crypto/libnm-crypto-null.la
endif
else
-check_ltlibraries += src/libnm-core-impl/libnm-crypto-null.la
+check_ltlibraries += src/libnm-crypto/libnm-crypto-null.la
endif
-src_libnm_core_impl_libnm_crypto_null_la_SOURCES = src/libnm-core-impl/nm-crypto-null.c
-src_libnm_core_impl_libnm_crypto_null_la_CPPFLAGS = \
- $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS)
-src_libnm_core_impl_libnm_crypto_null_la_LDFLAGS = \
- $(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS)
-src_libnm_core_impl_libnm_crypto_null_la_LIBADD = \
- $(GLIB_LIBS)
+src_libnm_crypto_libnm_crypto_null_la_SOURCES = src/libnm-crypto/nm-crypto-null.c
+src_libnm_crypto_libnm_crypto_null_la_CPPFLAGS = \
+ $(src_libnm_core_impl_libnm_core_impl_la_CPPFLAGS) \
+ $(NULL)
+src_libnm_crypto_libnm_crypto_null_la_LDFLAGS = \
+ $(src_libnm_core_impl_libnm_core_impl_la_LDFLAGS) \
+ $(NULL)
+src_libnm_crypto_libnm_crypto_null_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(NULL)
noinst_LTLIBRARIES += $(libnm_crypto_lib)
+EXTRA_DIST += \
+ src/libnm-crypto/README.md \
+ src/libnm-crypto/meson.build \
+ src/libnm-crypto/nm-crypto-gnutls.c \
+ src/libnm-crypto/nm-crypto-nss.c \
+ $(NULL)
+
###############################################################################
check_programs += \
@@ -1545,6 +1573,7 @@ nodist_src_libnm_core_impl_tests_test_general_SOURCES = \
src_libnm_core_impl_tests_ldadd = \
src/libnm-core-aux-extern/libnm-core-aux-extern.la \
src/libnm-core-impl/libnm-core-impl.la \
+ src/libnm-crypto/libnm-crypto.la \
$(libnm_crypto_lib) \
src/libnm-core-aux-intern/libnm-core-aux-intern.la \
src/libnm-base/libnm-base.la \
@@ -1778,6 +1807,7 @@ nodist_src_libnm_client_impl_libnm_client_impl_la_SOURCES = \
src_libnm_client_impl_libnm_client_impl_la_LIBADD = \
src/libnm-core-aux-extern/libnm-core-aux-extern.la \
src/libnm-core-impl/libnm-core-impl.la \
+ src/libnm-crypto/libnm-crypto.la \
$(libnm_crypto_lib) \
src/libnm-core-aux-intern/libnm-core-aux-intern.la \
src/libnm-base/libnm-base.la \
@@ -2626,6 +2656,7 @@ src_core_libNetworkManager_la_LIBADD = \
src/core/libNetworkManagerBase.la \
src/libnm-core-aux-extern/libnm-core-aux-extern.la \
src/libnm-core-impl/libnm-core-impl.la \
+ src/libnm-crypto/libnm-crypto.la \
$(libnm_crypto_lib) \
src/libnm-core-aux-intern/libnm-core-aux-intern.la \
src/libnm-platform/libnm-platform.la \
@@ -2771,6 +2802,7 @@ src_nm_initrd_generator_nm_initrd_generator_CPPFLAGS = \
src_nm_initrd_generator_nm_initrd_generator_LDADD = \
src/nm-initrd-generator/libnmi-core.la \
src/libnm-core-impl/libnm-core-impl.la \
+ src/libnm-crypto/libnm-crypto.la \
$(libnm_crypto_lib) \
src/libnm-core-aux-intern/libnm-core-aux-intern.la \
src/libnm-platform/libnm-platform.la \
diff --git a/meson.build b/meson.build
index aa782febba..f63cb22986 100644
--- a/meson.build
+++ b/meson.build
@@ -1094,7 +1094,9 @@ output += '\n'
output += ' code coverage: ' + get_option('b_coverage').to_string() + '\n'
output += ' LTO: ' + enable_lto.to_string() + '\n'
output += ' Linker garbage collection: ' + enable_ld_gc.to_string() + '\n'
-output += ' crypto: ' + crypto + '\n'
+output += ' crypto: ' + crypto + ' ('
+output += 'have-gnutls: ' + crypto_gnutls_dep.found().to_string() + ', '
+output += 'have-nss: ' + crypto_nss_dep.found().to_string() + ')\n'
output += ' sanitizers: ' + get_option('b_sanitize') + '\n'
output += ' Mozilla Public Suffix List: ' + enable_libpsl.to_string() + '\n'
output += ' vapi: ' + enable_vapi.to_string() + '\n'
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 548ae5a1e7..151f58fca9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -72,10 +72,6 @@ src/libnm-client-impl/nm-vpn-service-plugin.c
src/libnm-core-aux-extern/nm-libnm-core-aux.c
src/libnm-core-aux-intern/nm-libnm-core-utils.c
src/libnm-core-impl/nm-connection.c
-src/libnm-core-impl/nm-crypto-gnutls.c
-src/libnm-core-impl/nm-crypto-nss.c
-src/libnm-core-impl/nm-crypto-null.c
-src/libnm-core-impl/nm-crypto.c
src/libnm-core-impl/nm-dbus-utils.c
src/libnm-core-impl/nm-keyfile-utils.c
src/libnm-core-impl/nm-keyfile.c
@@ -132,6 +128,10 @@ src/libnm-core-impl/nm-team-utils.c
src/libnm-core-impl/nm-utils.c
src/libnm-core-impl/nm-vpn-editor-plugin.c
src/libnm-core-impl/nm-vpn-plugin-info.c
+src/libnm-crypto/nm-crypto-gnutls.c
+src/libnm-crypto/nm-crypto-nss.c
+src/libnm-crypto/nm-crypto-null.c
+src/libnm-crypto/nm-crypto.c
src/libnm-glib-aux/nm-shared-utils.c
src/libnm-log-core/nm-logging.c
src/libnmc-base/nm-client-utils.c
diff --git a/src/libnm-base/meson.build b/src/libnm-base/meson.build
index 1bb61020da..f4d977e986 100644
--- a/src/libnm-base/meson.build
+++ b/src/libnm-base/meson.build
@@ -3,6 +3,7 @@
libnm_base = static_library(
'nm-base',
sources: files(
+ 'nm-base.c',
'nm-ethtool-base.c',
'nm-net-aux.c',
'nm-priv-helper-utils.c',
diff --git a/src/libnm-base/nm-base.c b/src/libnm-base/nm-base.c
new file mode 100644
index 0000000000..f81b285c4e
--- /dev/null
+++ b/src/libnm-base/nm-base.c
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "libnm-glib-aux/nm-default-glib-i18n-lib.h"
+
+#include "nm-base.h"
+
+/*****************************************************************************/
+
+NM_CACHED_QUARK_FCN("nm-crypto-error-quark", _nm_crypto_error_quark);
+
+/*****************************************************************************/
diff --git a/src/libnm-base/nm-base.h b/src/libnm-base/nm-base.h
index 0363e3b64b..ff062a18b8 100644
--- a/src/libnm-base/nm-base.h
+++ b/src/libnm-base/nm-base.h
@@ -393,4 +393,20 @@ typedef struct {
#define NM_BOND_PORT_QUEUE_ID_DEF 0
+/*****************************************************************************/
+
+/* NM_CRYPTO_ERROR is part of public API in libnm (implemented in libnm-core).
+ * We also want to use it without libnm-core. So this "_" variant is the internal
+ * version, with numerically same values -- to be used without libnm-base. */
+
+#define _NM_CRYPTO_ERROR_FAILED 0
+#define _NM_CRYPTO_ERROR_INVALID_DATA 1
+#define _NM_CRYPTO_ERROR_INVALID_PASSWORD 2
+#define _NM_CRYPTO_ERROR_UNKNOWN_CIPHER 3
+#define _NM_CRYPTO_ERROR_DECRYPTION_FAILED 4
+#define _NM_CRYPTO_ERROR_ENCRYPTION_FAILED 5
+
+#define _NM_CRYPTO_ERROR _nm_crypto_error_quark()
+GQuark _nm_crypto_error_quark(void);
+
#endif /* __NM_LIBNM_BASE_H__ */
diff --git a/src/libnm-client-impl/nm-libnm-utils.c b/src/libnm-client-impl/nm-libnm-utils.c
index d3d429eba2..951db1bc12 100644
--- a/src/libnm-client-impl/nm-libnm-utils.c
+++ b/src/libnm-client-impl/nm-libnm-utils.c
@@ -10,7 +10,9 @@
#include "libnm-glib-aux/nm-time-utils.h"
#include "libnm-core-aux-intern/nm-common-macros.h"
+#include "libnm-crypto/nm-crypto.h"
#include "nm-object.h"
+#include "nm-utils.h"
/*****************************************************************************/
@@ -914,3 +916,58 @@ nm_utils_print(int output_mode, const char *msg)
else
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);
+}
diff --git a/src/libnm-client-public/NetworkManager.h b/src/libnm-client-public/NetworkManager.h
index 3134562e61..66f676a111 100644
--- a/src/libnm-client-public/NetworkManager.h
+++ b/src/libnm-client-public/NetworkManager.h
@@ -120,8 +120,8 @@
#if !defined(NETWORKMANAGER_COMPILATION) \
&& (!defined(NM_NO_INCLUDE_EXTRA_HEADERS) || !NM_NO_INCLUDE_EXTRA_HEADERS)
/* historically, NetworkManager.h drags in the following system headers.
- * These are not strictly necessary and the user may wish to opt out from
- * including them. */
+ * These are not strictly necessary and the user may wish to opt out from
+ * including them. */
#include <linux/if_ether.h>
#include <linux/if_infiniband.h>
#include <linux/if_vlan.h>
diff --git a/src/libnm-client-public/nm-client.h b/src/libnm-client-public/nm-client.h
index 8b00eab095..2e3e77c43c 100644
--- a/src/libnm-client-public/nm-client.h
+++ b/src/libnm-client-public/nm-client.h
@@ -496,6 +496,10 @@ gboolean nm_client_dbus_set_property_finish(NMClient *client, GAsyncResult *resu
NM_AVAILABLE_IN_1_30
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
#endif /* __NM_CLIENT_H__ */
diff --git a/src/libnm-core-impl/meson.build b/src/libnm-core-impl/meson.build
index 3ee044fe10..83c290857c 100644
--- a/src/libnm-core-impl/meson.build
+++ b/src/libnm-core-impl/meson.build
@@ -2,45 +2,6 @@
libnm_core_impl_inc = include_directories('.')
-if crypto_nss_dep.found()
- libnm_crypto_nss = static_library(
- 'nm-crypto-nss',
- sources: 'nm-crypto-nss.c',
- dependencies: [
- libnm_core_public_dep,
- crypto_nss_dep,
- ],
- )
-endif
-
-if crypto_gnutls_dep.found()
- libnm_crypto_gnutls = static_library(
- 'nm-crypto-gnutls',
- sources: 'nm-crypto-gnutls.c',
- dependencies: [
- libnm_core_public_dep,
- crypto_gnutls_dep,
- ],
- )
-endif
-
-libnm_crypto_null = static_library(
- 'nm-crypto-null',
- sources: 'nm-crypto-null.c',
- dependencies: [
- libnm_core_public_dep,
- ],
-)
-
-if crypto == 'nss'
- libnm_crypto = libnm_crypto_nss
-elif crypto == 'gnutls'
- libnm_crypto = libnm_crypto_gnutls
-else
- assert(crypto == 'null', 'Unexpected setting "crypto=' + crypto + '"')
- libnm_crypto = libnm_crypto_null
-endif
-
libnm_core_settings_sources = files(
'nm-setting-6lowpan.c',
'nm-setting-8021x.c',
@@ -99,7 +60,6 @@ libnm_core_settings_sources = files(
libnm_core_impl_sources = files(
'nm-connection.c',
- 'nm-crypto.c',
'nm-dbus-utils.c',
'nm-errors.c',
'nm-keyfile-utils.c',
diff --git a/src/libnm-core-impl/nm-errors.c b/src/libnm-core-impl/nm-errors.c
index ea4ca5e9e6..fad854bc2d 100644
--- a/src/libnm-core-impl/nm-errors.c
+++ b/src/libnm-core-impl/nm-errors.c
@@ -12,12 +12,24 @@
NM_CACHED_QUARK_FCN("nm-agent-manager-error-quark", nm_agent_manager_error_quark);
NM_CACHED_QUARK_FCN("nm-connection-error-quark", nm_connection_error_quark);
-NM_CACHED_QUARK_FCN("nm-crypto-error-quark", nm_crypto_error_quark);
NM_CACHED_QUARK_FCN("nm-device-error-quark", nm_device_error_quark);
NM_CACHED_QUARK_FCN("nm-secret-agent-error-quark", nm_secret_agent_error_quark);
NM_CACHED_QUARK_FCN("nm-settings-error-quark", nm_settings_error_quark);
NM_CACHED_QUARK_FCN("nm-vpn-plugin-error-quark", nm_vpn_plugin_error_quark);
+GQuark
+nm_crypto_error_quark(void)
+{
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_FAILED == _NM_CRYPTO_ERROR_FAILED);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_INVALID_DATA == _NM_CRYPTO_ERROR_INVALID_DATA);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_INVALID_PASSWORD == _NM_CRYPTO_ERROR_INVALID_PASSWORD);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_UNKNOWN_CIPHER == _NM_CRYPTO_ERROR_UNKNOWN_CIPHER);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_DECRYPTION_FAILED == _NM_CRYPTO_ERROR_DECRYPTION_FAILED);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_ENCRYPTION_FAILED == _NM_CRYPTO_ERROR_ENCRYPTION_FAILED);
+
+ return _nm_crypto_error_quark();
+}
+
static void
register_error_domain(GQuark domain, const char *interface, GType enum_type)
{
diff --git a/src/libnm-core-impl/nm-setting-8021x.c b/src/libnm-core-impl/nm-setting-8021x.c
index fa0a3057fe..dce35cf016 100644
--- a/src/libnm-core-impl/nm-setting-8021x.c
+++ b/src/libnm-core-impl/nm-setting-8021x.c
@@ -9,8 +9,8 @@
#include "nm-setting-8021x.h"
#include "libnm-glib-aux/nm-secret-utils.h"
+#include "libnm-crypto/nm-crypto.h"
#include "nm-utils.h"
-#include "nm-crypto.h"
#include "nm-utils-private.h"
#include "nm-setting-private.h"
#include "nm-core-enum-types.h"
@@ -516,7 +516,7 @@ _cert_impl_set(NMSetting8021x *setting,
gs_unref_bytes GBytes *file = NULL;
if (NM_IN_SET(property, PROP_PRIVATE_KEY, PROP_PHASE2_PRIVATE_KEY)) {
- file = nm_crypto_read_file(value, error);
+ file = nm_utils_read_crypto_file_to_bytes(value, error);
if (!file)
goto err;
format = nm_crypto_verify_private_key_data(g_bytes_get_data(file, NULL),
diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c
index 55b01c159b..d5d884f2e4 100644
--- a/src/libnm-core-impl/nm-utils.c
+++ b/src/libnm-core-impl/nm-utils.c
@@ -27,7 +27,6 @@
#include "libnm-core-aux-intern/nm-common-macros.h"
#include "nm-utils-private.h"
#include "nm-setting-private.h"
-#include "nm-crypto.h"
#include "nm-setting-bond.h"
#include "nm-setting-bond-port.h"
#include "nm-setting-bridge.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
_nm_utils_check_file(const char *filename,
gint64 check_owner,
@@ -3795,22 +3706,13 @@ nm_utils_hwaddr_aton(const char *asc, gpointer buffer, gsize length)
char *
nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len)
{
- char *result;
gsize buflen = (len * 2) + 1;
g_return_val_if_fail(src != NULL, NULL);
g_return_val_if_fail(len > 0 && (buflen - 1) / 2 == len, NULL);
g_return_val_if_fail(final_len < 0 || (gsize) final_len < buflen, NULL);
- result = g_malloc(buflen);
-
- nm_utils_bin2hexstr_full(src, len, '\0', FALSE, result);
-
- /* Cut converted key off at the correct length for this cipher type */
- if (final_len >= 0 && (gsize) final_len < buflen)
- result[final_len] = '\0';
-
- return result;
+ return _nm_utils_bin2hexstr(src, len, final_len);
}
/**
diff --git a/src/libnm-core-impl/tests/test-crypto.c b/src/libnm-core-impl/tests/test-crypto.c
index 6a6e7fbc80..896c3c2e69 100644
--- a/src/libnm-core-impl/tests/test-crypto.c
+++ b/src/libnm-core-impl/tests/test-crypto.c
@@ -10,7 +10,7 @@
#include <stdlib.h>
#include <stdio.h>
-#include "nm-crypto-impl.h"
+#include "libnm-crypto/nm-crypto-impl.h"
#include "nm-utils.h"
#include "nm-errors.h"
#include "libnm-core-intern/nm-core-internal.h"
@@ -92,7 +92,7 @@ test_cert(gconstpointer test_data)
nmtst_assert_success(success, error);
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
@@ -106,7 +106,7 @@ test_load_private_key(const char *path,
gs_unref_bytes GBytes *array = 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);
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;
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);
if (expected_error != -1) {
@@ -167,7 +167,7 @@ test_load_pkcs12_no_password(const char *path)
gboolean is_encrypted = FALSE;
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 */
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;
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);
if (expected_error != -1) {
@@ -285,7 +285,7 @@ test_key_decrypted(gconstpointer test_data)
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_free(path);
@@ -399,6 +399,23 @@ test_md5(void)
}
}
+/*****************************************************************************/
+
+static void
+test_crypto_error(void)
+{
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_FAILED == _NM_CRYPTO_ERROR_FAILED);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_INVALID_DATA == _NM_CRYPTO_ERROR_INVALID_DATA);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_INVALID_PASSWORD == _NM_CRYPTO_ERROR_INVALID_PASSWORD);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_UNKNOWN_CIPHER == _NM_CRYPTO_ERROR_UNKNOWN_CIPHER);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_DECRYPTION_FAILED == _NM_CRYPTO_ERROR_DECRYPTION_FAILED);
+ G_STATIC_ASSERT(NM_CRYPTO_ERROR_ENCRYPTION_FAILED == _NM_CRYPTO_ERROR_ENCRYPTION_FAILED);
+
+ g_assert_cmpint(NM_CRYPTO_ERROR, ==, _NM_CRYPTO_ERROR);
+}
+
+/*****************************************************************************/
+
NMTST_DEFINE();
int
@@ -448,6 +465,7 @@ main(int argc, char **argv)
g_test_add_data_func("/libnm/crypto/PKCS#8", "pkcs8-enc-key.pem, 1234567890", test_pkcs8);
g_test_add_func("/libnm/crypto/md5", test_md5);
+ g_test_add_func("/libnm/crypto/error", test_crypto_error);
ret = g_test_run();
diff --git a/src/libnm-core-public/nm-utils.h b/src/libnm-core-public/nm-utils.h
index 0a7c7a8136..5faed75a36 100644
--- a/src/libnm-core-public/nm-utils.h
+++ b/src/libnm-core-public/nm-utils.h
@@ -111,10 +111,6 @@ GPtrArray *nm_utils_ip_routes_from_variant(GVariant *value, int family);
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);
struct stat;
diff --git a/src/libnm-crypto/README.md b/src/libnm-crypto/README.md
new file mode 100644
index 0000000000..5e83eb0188
--- /dev/null
+++ b/src/libnm-crypto/README.md
@@ -0,0 +1,7 @@
+libnm-crypto
+============
+
+libnm-core has a dependency on crypto code (either backed by
+"gnutls", "nss" or the "null" dummy implementation).
+
+libnm-core gets then statically linked into the daemon and into libnm.so.
diff --git a/src/libnm-crypto/meson.build b/src/libnm-crypto/meson.build
new file mode 100644
index 0000000000..9134c929f1
--- /dev/null
+++ b/src/libnm-crypto/meson.build
@@ -0,0 +1,69 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+if crypto_nss_dep.found()
+ libnm_crypto_nss = static_library(
+ 'nm-crypto-nss',
+ sources: 'nm-crypto-nss.c',
+ include_directories: [
+ top_inc,
+ src_inc,
+ ],
+ dependencies: [
+ glib_dep,
+ crypto_nss_dep,
+ ],
+ )
+endif
+
+if crypto_gnutls_dep.found()
+ libnm_crypto_gnutls = static_library(
+ 'nm-crypto-gnutls',
+ sources: 'nm-crypto-gnutls.c',
+ include_directories: [
+ top_inc,
+ src_inc,
+ ],
+ dependencies: [
+ glib_dep,
+ crypto_gnutls_dep,
+ ],
+ )
+endif
+
+libnm_crypto_null = static_library(
+ 'nm-crypto-null',
+ sources: 'nm-crypto-null.c',
+ include_directories: [
+ top_inc,
+ src_inc,
+ ],
+ dependencies: [
+ glib_dep,
+ ],
+)
+
+if crypto == 'nss'
+ libnm_crypto_impl = libnm_crypto_nss
+elif crypto == 'gnutls'
+ libnm_crypto_impl = libnm_crypto_gnutls
+else
+ assert(crypto == 'null', 'Unexpected setting "crypto=' + crypto + '"')
+ libnm_crypto_impl = libnm_crypto_null
+endif
+
+libnm_crypto = static_library(
+ 'nm-crypto',
+ sources: [
+ 'nm-crypto.c',
+ ],
+ include_directories: [
+ top_inc,
+ src_inc,
+ ],
+ link_with: [
+ libnm_crypto_impl,
+ ],
+ dependencies: [
+ glib_dep,
+ ],
+)
diff --git a/src/libnm-core-impl/nm-crypto-gnutls.c b/src/libnm-crypto/nm-crypto-gnutls.c
index d9e5913645..60adf4d3f0 100644
--- a/src/libnm-core-impl/nm-crypto-gnutls.c
+++ b/src/libnm-crypto/nm-crypto-gnutls.c
@@ -14,7 +14,6 @@
#include <gnutls/pkcs12.h>
#include "libnm-glib-aux/nm-secret-utils.h"
-#include "nm-errors.h"
/*****************************************************************************/
@@ -54,8 +53,8 @@ _nm_crypto_init(GError **error)
if (gnutls_global_init() != 0) {
gnutls_global_deinit();
g_set_error_literal(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Failed to initialize the crypto engine."));
return FALSE;
}
@@ -87,8 +86,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
if (!_get_cipher_info(cipher, &cipher_mech, &real_iv_len)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Unsupported key cipher for decryption"));
return NULL;
}
@@ -98,8 +97,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
if (iv_len < real_iv_len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Invalid IV length (must be at least %u)."),
(guint) real_iv_len);
return NULL;
@@ -116,8 +115,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
err = gnutls_cipher_init(&ctx, cipher_mech, &key_dt, &iv_dt);
if (err < 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to initialize the decryption cipher context: %s (%s)"),
gnutls_strerror_name(err),
gnutls_strerror(err));
@@ -130,8 +129,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
if (err < 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to decrypt the private key: %s (%s)"),
gnutls_strerror_name(err),
gnutls_strerror(err));
@@ -143,8 +142,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
/* Check if the padding at the end of the decrypted data is valid */
if (pad_len == 0 || pad_len > real_iv_len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to decrypt the private key: unexpected padding length."));
return NULL;
}
@@ -155,8 +154,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
for (pad_i = 1; pad_i <= pad_len; ++pad_i) {
if (output.bin[data_len - pad_i] != pad_len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to decrypt the private key."));
return NULL;
}
@@ -189,8 +188,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
if (cipher == NM_CRYPTO_CIPHER_DES_CBC || !_get_cipher_info(cipher, &cipher_mech, NULL)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Unsupported key cipher for encryption"));
return NULL;
}
@@ -206,8 +205,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
err = gnutls_cipher_init(&ctx, cipher_mech, &key_dt, &iv_dt);
if (err < 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
_("Failed to initialize the encryption cipher context: %s (%s)"),
gnutls_strerror_name(err),
gnutls_strerror(err));
@@ -234,8 +233,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
if (err < 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
_("Failed to encrypt the data: %s (%s)"),
gnutls_strerror_name(err),
gnutls_strerror(err));
@@ -259,8 +258,8 @@ _nm_crypto_verify_x509(const guint8 *data, gsize len, GError **error)
err = gnutls_x509_crt_init(&der);
if (err < 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Error initializing certificate data: %s"),
gnutls_strerror(err));
return FALSE;
@@ -282,8 +281,8 @@ _nm_crypto_verify_x509(const guint8 *data, gsize len, GError **error)
return TRUE;
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Couldn't decode certificate: %s"),
gnutls_strerror(err));
return FALSE;
@@ -307,8 +306,8 @@ _nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *passwor
err = gnutls_pkcs12_init(&p12);
if (err < 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Couldn't initialize PKCS#12 decoder: %s"),
gnutls_strerror(err));
return FALSE;
@@ -321,8 +320,8 @@ _nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *passwor
err = gnutls_pkcs12_import(p12, &dt, GNUTLS_X509_FMT_PEM, 0);
if (err < 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Couldn't decode PKCS#12 file: %s"),
gnutls_strerror(err));
gnutls_pkcs12_deinit(p12);
@@ -331,18 +330,18 @@ _nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *passwor
}
err = gnutls_pkcs12_verify_mac(p12, password);
-
- gnutls_pkcs12_deinit(p12);
-
if (err != GNUTLS_E_SUCCESS) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Couldn't verify PKCS#12 file: %s"),
gnutls_strerror(err));
+ gnutls_pkcs12_deinit(p12);
return FALSE;
}
+ gnutls_pkcs12_deinit(p12);
+
return TRUE;
}
@@ -365,8 +364,8 @@ _nm_crypto_verify_pkcs8(const guint8 *data,
err = gnutls_x509_privkey_init(&p8);
if (err < 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Couldn't initialize PKCS#8 decoder: %s"),
gnutls_strerror(err));
return FALSE;
@@ -393,8 +392,8 @@ _nm_crypto_verify_pkcs8(const guint8 *data,
*/
} else {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Couldn't decode PKCS#8 file: %s"),
gnutls_strerror(err));
return FALSE;
diff --git a/src/libnm-core-impl/nm-crypto-impl.h b/src/libnm-crypto/nm-crypto-impl.h
index 61c3f7f8e2..0b7c14dc08 100644
--- a/src/libnm-core-impl/nm-crypto-impl.h
+++ b/src/libnm-crypto/nm-crypto-impl.h
@@ -8,6 +8,7 @@
#define __NM_CRYPTO_IMPL_H__
#include "nm-crypto.h"
+#include "libnm-base/nm-base.h"
gboolean _nm_crypto_init(GError **error);
diff --git a/src/libnm-core-impl/nm-crypto-nss.c b/src/libnm-crypto/nm-crypto-nss.c
index c27bf09e35..b31ca55ee0 100644
--- a/src/libnm-core-impl/nm-crypto-nss.c
+++ b/src/libnm-crypto/nm-crypto-nss.c
@@ -21,7 +21,7 @@ NM_PRAGMA_WARNING_DISABLE("-Wstrict-prototypes")
NM_PRAGMA_WARNING_REENABLE
#include "libnm-glib-aux/nm-secret-utils.h"
-#include "nm-errors.h"
+#include "libnm-base/nm-base.h"
/*****************************************************************************/
@@ -65,8 +65,8 @@ _nm_crypto_init(GError **error)
ret = NSS_NoDB_Init(NULL);
if (ret != SECSuccess) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Failed to initialize the crypto engine: %d."),
PR_GetError());
PR_Cleanup();
@@ -113,16 +113,16 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
if (!_get_cipher_info(cipher, &cipher_mech, &real_iv_len)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Unsupported key cipher for decryption"));
return NULL;
}
if (iv_len < real_iv_len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Invalid IV length (must be at least %u)."),
(guint) real_iv_len);
return NULL;
@@ -134,8 +134,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
slot = PK11_GetBestSlot(cipher_mech, NULL);
if (!slot) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Failed to initialize the decryption cipher slot."));
goto out;
}
@@ -145,8 +145,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
sym_key = PK11_ImportSymKey(slot, cipher_mech, PK11_OriginUnwrap, CKA_DECRYPT, &key_item, NULL);
if (!sym_key) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to set symmetric key for decryption."));
goto out;
}
@@ -156,8 +156,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
sec_param = PK11_ParamFromIV(cipher_mech, &key_item);
if (!sec_param) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to set IV for decryption."));
goto out;
}
@@ -165,8 +165,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
ctx = PK11_CreateContextBySymKey(cipher_mech, CKA_DECRYPT, sym_key, sec_param);
if (!ctx) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to initialize the decryption context."));
goto out;
}
@@ -182,8 +182,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
data_len);
if (s != SECSuccess) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to decrypt the private key: %d."),
PORT_GetError());
goto out;
@@ -191,8 +191,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
if (decrypted_len > data_len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to decrypt the private key: decrypted data too large."));
goto out;
}
@@ -203,8 +203,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
data_len - decrypted_len);
if (s != SECSuccess) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to finalize decryption of the private key: %d."),
PORT_GetError());
goto out;
@@ -216,8 +216,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
/* Check if the padding at the end of the decrypted data is valid */
if (pad_len == 0 || pad_len > real_iv_len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to decrypt the private key: unexpected padding length."));
goto out;
}
@@ -228,8 +228,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
for (i = pad_len; i > 0; i--) {
if (output.bin[data_len - i] != pad_len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Failed to decrypt the private key."));
goto out;
}
@@ -283,8 +283,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
if (cipher == NM_CRYPTO_CIPHER_DES_CBC || !_get_cipher_info(cipher, &cipher_mech, NULL)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_UNKNOWN_CIPHER,
_("Unsupported key cipher for encryption"));
return NULL;
}
@@ -295,8 +295,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
slot = PK11_GetBestSlot(cipher_mech, NULL);
if (!slot) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Failed to initialize the encryption cipher slot."));
return NULL;
}
@@ -304,8 +304,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
sym_key = PK11_ImportSymKey(slot, cipher_mech, PK11_OriginUnwrap, CKA_ENCRYPT, &key_item, NULL);
if (!sym_key) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
_("Failed to set symmetric key for encryption."));
goto out;
}
@@ -313,8 +313,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
sec_param = PK11_ParamFromIV(cipher_mech, &iv_item);
if (!sec_param) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
_("Failed to set IV for encryption."));
goto out;
}
@@ -322,8 +322,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
ctx = PK11_CreateContextBySymKey(cipher_mech, CKA_ENCRYPT, sym_key, sec_param);
if (!ctx) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
_("Failed to initialize the encryption context."));
goto out;
}
@@ -347,8 +347,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
PK11_CipherOp(ctx, output.bin, &encrypted_len, output.len, padded_buf.bin, padded_buf.len);
if (ret != SECSuccess) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
_("Failed to encrypt: %d."),
PORT_GetError());
goto out;
@@ -356,8 +356,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
if (encrypted_len != output.len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_ENCRYPTION_FAILED,
_("Unexpected amount of data after encrypting."));
goto out;
}
@@ -393,8 +393,8 @@ _nm_crypto_verify_x509(const guint8 *data, gsize len, GError **error)
cert = CERT_DecodeCertFromPackage((char *) data, len);
if (!cert) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Couldn't decode certificate: %d"),
PORT_GetError());
return FALSE;
@@ -438,8 +438,8 @@ _nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *passwor
if (!ucs2_password.bin || ucs2_password.len == 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_PASSWORD,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_PASSWORD,
_("Password must be UTF-8"));
return FALSE;
}
@@ -461,15 +461,18 @@ _nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *passwor
slot = PK11_GetInternalKeySlot();
if (!slot) {
- g_set_error(error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_FAILED, _("Couldn't initialize slot"));
+ g_set_error(error,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
+ _("Couldn't initialize slot"));
goto out;
}
p12ctx = SEC_PKCS12DecoderStart(&pw, slot, NULL, NULL, NULL, NULL, NULL, NULL);
if (!p12ctx) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Couldn't initialize PKCS#12 decoder: %d"),
PORT_GetError());
goto out;
@@ -478,8 +481,8 @@ _nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *passwor
s = SEC_PKCS12DecoderUpdate(p12ctx, (guint8 *) data, data_len);
if (s != SECSuccess) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Couldn't decode PKCS#12 file: %d"),
PORT_GetError());
goto out;
@@ -488,8 +491,8 @@ _nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *passwor
s = SEC_PKCS12DecoderVerify(p12ctx);
if (s != SECSuccess) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_DECRYPTION_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_DECRYPTION_FAILED,
_("Couldn't verify PKCS#12 file: %d"),
PORT_GetError());
goto out;
@@ -506,6 +509,7 @@ out:
if (pw.data)
SECITEM_ZfreeItem(&pw, PR_FALSE);
+ nm_assert(!error || (success == (!*error)));
return success;
}
@@ -539,8 +543,8 @@ _nm_crypto_randomize(void *buffer, gsize buffer_len, GError **error)
s = PK11_GenerateRandom(buffer, buffer_len);
if (s != SECSuccess) {
g_set_error_literal(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Could not generate random data."));
return FALSE;
}
diff --git a/src/libnm-core-impl/nm-crypto-null.c b/src/libnm-crypto/nm-crypto-null.c
index 2f072257ec..6f6c7f2897 100644
--- a/src/libnm-core-impl/nm-crypto-null.c
+++ b/src/libnm-crypto/nm-crypto-null.c
@@ -9,7 +9,6 @@
#include "nm-crypto-impl.h"
#include "libnm-glib-aux/nm-secret-utils.h"
-#include "nm-errors.h"
/*****************************************************************************/
@@ -17,8 +16,8 @@ gboolean
_nm_crypto_init(GError **error)
{
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Compiled without crypto support."));
return FALSE;
}
@@ -35,8 +34,8 @@ _nmtst_crypto_decrypt(NMCryptoCipherType cipher,
GError **error)
{
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Compiled without crypto support."));
return NULL;
}
@@ -53,8 +52,8 @@ _nmtst_crypto_encrypt(NMCryptoCipherType cipher,
GError **error)
{
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Compiled without crypto support."));
return NULL;
}
@@ -63,8 +62,8 @@ gboolean
_nm_crypto_verify_x509(const guint8 *data, gsize len, GError **error)
{
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Compiled without crypto support."));
return FALSE;
}
@@ -73,8 +72,8 @@ gboolean
_nm_crypto_verify_pkcs12(const guint8 *data, gsize data_len, const char *password, GError **error)
{
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Compiled without crypto support."));
return FALSE;
}
@@ -87,8 +86,8 @@ _nm_crypto_verify_pkcs8(const guint8 *data,
GError **error)
{
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Compiled without crypto support."));
return FALSE;
}
@@ -97,8 +96,8 @@ gboolean
_nm_crypto_randomize(void *buffer, gsize buffer_len, GError **error)
{
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_FAILED,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_FAILED,
_("Compiled without crypto support."));
return FALSE;
}
diff --git a/src/libnm-core-impl/nm-crypto.c b/src/libnm-crypto/nm-crypto.c
index 78f793bd0b..69d2b53f9e 100644
--- a/src/libnm-core-impl/nm-crypto.c
+++ b/src/libnm-crypto/nm-crypto.c
@@ -4,7 +4,7 @@
* Copyright (C) 2007 - 2018 Red Hat, Inc.
*/
-#include "libnm-core-impl/nm-default-libnm-core.h"
+#include "libnm-glib-aux/nm-default-glib-i18n-lib.h"
#include "nm-crypto.h"
@@ -16,8 +16,8 @@
#include "libnm-glib-aux/nm-io-utils.h"
#include "nm-crypto-impl.h"
-#include "nm-utils.h"
-#include "nm-errors.h"
+
+/*****************************************************************************/
#define PEM_RSA_KEY_BEGIN "-----BEGIN RSA PRIVATE KEY-----"
#define PEM_RSA_KEY_END "-----END RSA PRIVATE KEY-----"
@@ -203,8 +203,8 @@ parse_old_openssl_key_file(const guint8 *data,
end_tag = PEM_DSA_KEY_END;
} else {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("PEM key file had no start tag"));
return FALSE;
}
@@ -212,8 +212,8 @@ parse_old_openssl_key_file(const guint8 *data,
start += strlen(start_tag);
if (!find_tag(end_tag, data, data_len, start, &end)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("PEM key file had no end tag '%s'."),
end_tag);
return FALSE;
@@ -240,8 +240,8 @@ parse_old_openssl_key_file(const guint8 *data,
if (!strncmp(p, PROC_TYPE_TAG, strlen(PROC_TYPE_TAG))) {
if (enc_tags++ != 0 || str_p != str) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Malformed PEM file: Proc-Type was not first tag."));
return FALSE;
}
@@ -249,8 +249,8 @@ parse_old_openssl_key_file(const guint8 *data,
p += strlen(PROC_TYPE_TAG);
if (strcmp(p, "4,ENCRYPTED")) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Malformed PEM file: unknown Proc-Type tag '%s'."),
p);
return FALSE;
@@ -262,8 +262,8 @@ parse_old_openssl_key_file(const guint8 *data,
if (enc_tags++ != 1 || str_p != str) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Malformed PEM file: DEK-Info was not the second tag."));
return FALSE;
}
@@ -274,8 +274,8 @@ parse_old_openssl_key_file(const guint8 *data,
comma = strchr(p, ',');
if (!comma || (*(comma + 1) == '\0')) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Malformed PEM file: no IV found in DEK-Info tag."));
return FALSE;
}
@@ -283,8 +283,8 @@ parse_old_openssl_key_file(const guint8 *data,
comma++;
if (!g_ascii_isxdigit(*comma)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Malformed PEM file: invalid format of IV in DEK-Info tag."));
return FALSE;
}
@@ -295,8 +295,8 @@ parse_old_openssl_key_file(const guint8 *data,
cipher_info = nm_crypto_cipher_get_info_by_name(p, p_len);
if (!cipher_info) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Malformed PEM file: unknown private key cipher '%s'."),
p);
return FALSE;
@@ -305,8 +305,8 @@ parse_old_openssl_key_file(const guint8 *data,
} else {
if (enc_tags == 1) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
"Malformed PEM file: both Proc-Type and DEK-Info tags are required.");
return FALSE;
}
@@ -318,8 +318,8 @@ parse_old_openssl_key_file(const guint8 *data,
parsed.bin = (guint8 *) g_base64_decode(str, &parsed.len);
if (!parsed.bin || parsed.len == 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Could not decode private key."));
nm_secret_ptr_clear(&parsed);
return FALSE;
@@ -360,8 +360,8 @@ parse_pkcs8_key_file(const guint8 *data,
encrypted = FALSE;
} else {
g_set_error_literal(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Failed to find expected PKCS#8 start tag."));
return FALSE;
}
@@ -369,8 +369,8 @@ parse_pkcs8_key_file(const guint8 *data,
start += strlen(start_tag);
if (!find_tag(end_tag, data, data_len, start, &end)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Failed to find expected PKCS#8 end tag '%s'."),
end_tag);
return FALSE;
@@ -382,8 +382,8 @@ parse_pkcs8_key_file(const guint8 *data,
parsed->bin = (guint8 *) g_base64_decode(der_base64, &parsed->len);
if (!parsed->bin || parsed->len == 0) {
g_set_error_literal(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Failed to decode PKCS#8 private key."));
nm_secret_ptr_clear(parsed);
return FALSE;
@@ -412,8 +412,8 @@ parse_tpm2_wrapped_key_file(const guint8 *data,
end_tag = PEM_TPM2_OLD_WRAPPED_KEY_END;
} else {
g_set_error_literal(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Failed to find expected TSS start tag."));
return FALSE;
}
@@ -421,8 +421,8 @@ parse_tpm2_wrapped_key_file(const guint8 *data,
start += strlen(start_tag);
if (!find_tag(end_tag, data, data_len, start, &end)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Failed to find expected TSS end tag '%s'."),
end_tag);
return FALSE;
@@ -432,35 +432,6 @@ parse_tpm2_wrapped_key_file(const guint8 *data,
return TRUE;
}
-static gboolean
-file_read_contents(const char *filename, NMSecretPtr *out_contents, GError **error)
-{
- nm_assert(out_contents);
- nm_assert(out_contents->len == 0);
- nm_assert(!out_contents->str);
-
- return nm_utils_file_get_contents(-1,
- filename,
- 100 * 1024 * 1024,
- NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET,
- &out_contents->str,
- &out_contents->len,
- NULL,
- error);
-}
-
-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.
*/
@@ -476,8 +447,8 @@ _nmtst_convert_iv(const char *src, gsize *out_len, GError **error)
num = strlen(src);
if (num == 0 || (num % 2) != 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("IV must be an even number of bytes in length."));
return NULL;
}
@@ -493,8 +464,8 @@ _nmtst_convert_iv(const char *src, gsize *out_len, GError **error)
if (((c0 = nm_utils_hexchar_to_int(*(src++))) < 0)
|| ((c1 = nm_utils_hexchar_to_int(*(src++))) < 0)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("IV contains non-hexadecimal digits."));
nm_explicit_bzero(c, i);
return FALSE;
@@ -569,8 +540,8 @@ _nmtst_decrypt_key(NMCryptoCipherType cipher,
if (bin_iv.len < 8) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("IV must contain at least 8 characters"));
return FALSE;
}
@@ -619,8 +590,8 @@ nmtst_crypto_decrypt_openssl_private_key_data(const guint8 *data,
if (!parse_old_openssl_key_file(data, data_len, &parsed, &key_type, &cipher, &iv, NULL)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Unable to determine private key type."));
return NULL;
}
@@ -632,8 +603,8 @@ nmtst_crypto_decrypt_openssl_private_key_data(const guint8 *data,
if (cipher == NM_CRYPTO_CIPHER_UNKNOWN || !iv) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_PASSWORD,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_PASSWORD,
_("Password provided, but key was not encrypted."));
return NULL;
}
@@ -661,7 +632,7 @@ nmtst_crypto_decrypt_openssl_private_key(const char *file,
if (!_nm_crypto_init(error))
return NULL;
- if (!file_read_contents(file, &contents, error))
+ if (!nm_utils_read_crypto_file(file, &contents, error))
return NULL;
return nmtst_crypto_decrypt_openssl_private_key_data(contents.bin,
@@ -688,8 +659,8 @@ extract_pem_cert_data(const guint8 *contents,
if (!find_tag(PEM_CERT_BEGIN, contents, contents_len, 0, &start)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("PEM certificate had no start tag '%s'."),
PEM_CERT_BEGIN);
return FALSE;
@@ -698,8 +669,8 @@ extract_pem_cert_data(const guint8 *contents,
start += strlen(PEM_CERT_BEGIN);
if (!find_tag(PEM_CERT_END, contents, contents_len, start, &end)) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("PEM certificate had no end tag '%s'."),
PEM_CERT_END);
return FALSE;
@@ -711,8 +682,8 @@ extract_pem_cert_data(const guint8 *contents,
out_cert->bin = (guint8 *) g_base64_decode(der_base64, &out_cert->len);
if (!out_cert->bin || !out_cert->len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Failed to decode certificate."));
nm_secret_ptr_clear(out_cert);
return FALSE;
@@ -735,13 +706,13 @@ nm_crypto_load_and_verify_certificate(const char *file,
if (!_nm_crypto_init(error))
goto out;
- if (!file_read_contents(file, &contents, error))
+ if (!nm_utils_read_crypto_file(file, &contents, error))
goto out;
if (contents.len == 0) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Certificate file is empty"));
goto out;
}
@@ -773,8 +744,8 @@ nm_crypto_load_and_verify_certificate(const char *file,
}
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Failed to recognize certificate"));
out:
@@ -786,13 +757,13 @@ out:
gboolean
nm_crypto_is_pkcs12_data(const guint8 *data, gsize data_len, GError **error)
{
- GError *local = NULL;
- gboolean success;
+ gs_free_error GError *local = NULL;
+ gboolean success;
if (!data_len) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("Certificate file is empty"));
return FALSE;
}
@@ -803,17 +774,14 @@ nm_crypto_is_pkcs12_data(const guint8 *data, gsize data_len, GError **error)
return FALSE;
success = _nm_crypto_verify_pkcs12(data, data_len, NULL, &local);
- if (success == FALSE) {
- /* If the error was just a decryption error, then it's pkcs#12 */
- if (local) {
- if (g_error_matches(local, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_DECRYPTION_FAILED)) {
- success = TRUE;
- g_error_free(local);
- } else
- g_propagate_error(error, local);
- }
+
+ /* If the error was just a decryption error, then it's pkcs#12 */
+ if (!success && !g_error_matches(local, _NM_CRYPTO_ERROR, _NM_CRYPTO_ERROR_DECRYPTION_FAILED)) {
+ g_propagate_error(error, g_steal_pointer(&local));
+ return FALSE;
}
- return success;
+
+ return TRUE;
}
gboolean
@@ -826,7 +794,7 @@ nm_crypto_is_pkcs12_file(const char *file, GError **error)
if (!_nm_crypto_init(error))
return FALSE;
- if (!file_read_contents(file, &contents, error))
+ if (!nm_utils_read_crypto_file(file, &contents, error))
return FALSE;
return nm_crypto_is_pkcs12_data(contents.bin, contents.len, error);
@@ -881,8 +849,8 @@ nm_crypto_verify_private_key_data(const guint8 *data,
if (format == NM_CRYPTO_FILE_FORMAT_UNKNOWN && error && !*error) {
g_set_error(error,
- NM_CRYPTO_ERROR,
- NM_CRYPTO_ERROR_INVALID_DATA,
+ _NM_CRYPTO_ERROR,
+ _NM_CRYPTO_ERROR_INVALID_DATA,
_("not a valid private key"));
}
@@ -904,7 +872,7 @@ nm_crypto_verify_private_key(const char *filename,
if (!_nm_crypto_init(error))
return NM_CRYPTO_FILE_FORMAT_UNKNOWN;
- if (!file_read_contents(filename, &contents, error))
+ if (!nm_utils_read_crypto_file(filename, &contents, error))
return NM_CRYPTO_FILE_FORMAT_UNKNOWN;
return nm_crypto_verify_private_key_data(contents.bin,
@@ -965,7 +933,7 @@ nmtst_crypto_rsa_key_encrypt(const guint8 *data,
if (!nm_crypto_randomize(pw_buf.bin, pw_buf.len, error))
return NULL;
- tmp_password = nm_utils_bin2hexstr(pw_buf.bin, pw_buf.len, -1);
+ tmp_password = _nm_utils_bin2hexstr(pw_buf.bin, pw_buf.len, -1);
in_password = tmp_password;
}
@@ -1009,7 +977,7 @@ nmtst_crypto_rsa_key_encrypt(const guint8 *data,
pem,
g_strdup_printf("DEK-Info: %s,",
nm_crypto_cipher_get_info(NM_CRYPTO_CIPHER_DES_EDE3_CBC)->name));
- g_ptr_array_add(pem, nm_utils_bin2hexstr(salt, sizeof(salt), sizeof(salt) * 2));
+ g_ptr_array_add(pem, _nm_utils_bin2hexstr(salt, sizeof(salt), sizeof(salt) * 2));
g_ptr_array_add(pem, g_strdup("\n\n"));
/* Convert the encrypted key to a base64 string */
@@ -1042,3 +1010,54 @@ nmtst_crypto_rsa_key_encrypt(const guint8 *data,
NM_SET_OUT(out_password, g_strdup(tmp_password));
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;
+}
diff --git a/src/libnm-core-impl/nm-crypto.h b/src/libnm-crypto/nm-crypto.h
index a740c43c5b..48c7c6b7ab 100644
--- a/src/libnm-core-impl/nm-crypto.h
+++ b/src/libnm-crypto/nm-crypto.h
@@ -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__ */
diff --git a/src/libnm-glib-aux/nm-secret-utils.c b/src/libnm-glib-aux/nm-secret-utils.c
index c764b6e575..983b04cac8 100644
--- a/src/libnm-glib-aux/nm-secret-utils.c
+++ b/src/libnm-glib-aux/nm-secret-utils.c
@@ -10,6 +10,8 @@
#include <malloc.h>
+#include "nm-io-utils.h"
+
/*****************************************************************************/
void
@@ -176,3 +178,34 @@ nm_utils_memeqzero_secret(gconstpointer data, gsize length)
}
return 1 & ((acc - 1) >> 8);
}
+
+/*****************************************************************************/
+
+gboolean
+nm_utils_read_crypto_file(const char *filename, NMSecretPtr *out_contents, GError **error)
+{
+ nm_assert(out_contents);
+ nm_assert(out_contents->len == 0);
+ nm_assert(!out_contents->str);
+
+ return nm_utils_file_get_contents(-1,
+ filename,
+ 100 * 1024 * 1024,
+ NM_UTILS_FILE_GET_CONTENTS_FLAG_SECRET,
+ &out_contents->str,
+ &out_contents->len,
+ NULL,
+ error);
+}
+
+GBytes *
+nm_utils_read_crypto_file_to_bytes(const char *filename, GError **error)
+{
+ nm_auto_clear_secret_ptr NMSecretPtr contents = {0};
+
+ g_return_val_if_fail(filename, NULL);
+
+ if (!nm_utils_read_crypto_file(filename, &contents, error))
+ return NULL;
+ return nm_secret_copy_to_gbytes(contents.bin, contents.len);
+}
diff --git a/src/libnm-glib-aux/nm-secret-utils.h b/src/libnm-glib-aux/nm-secret-utils.h
index 513dbca5bc..c175bc8f3e 100644
--- a/src/libnm-glib-aux/nm-secret-utils.h
+++ b/src/libnm-glib-aux/nm-secret-utils.h
@@ -286,4 +286,8 @@ nm_secret_mem_try_realloc_take(gpointer m_old, gboolean do_bzero_mem, gsize cur_
/*****************************************************************************/
+gboolean nm_utils_read_crypto_file(const char *filename, NMSecretPtr *out_contents, GError **error);
+
+GBytes *nm_utils_read_crypto_file_to_bytes(const char *filename, GError **error);
+
#endif /* __NM_SECRET_UTILS_H__ */
diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c
index 3b5bc6f92b..7c93615ed8 100644
--- a/src/libnm-glib-aux/nm-shared-utils.c
+++ b/src/libnm-glib-aux/nm-shared-utils.c
@@ -4851,6 +4851,27 @@ nm_utils_bin2hexstr_full(gconstpointer addr,
return out0;
}
+char *
+_nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len)
+{
+ char *result;
+ gsize buflen = (len * 2) + 1;
+
+ nm_assert(src);
+ nm_assert(len > 0 && (buflen - 1) / 2 == len);
+ nm_assert(final_len < 0 || (gsize) final_len < buflen);
+
+ result = g_malloc(buflen);
+
+ nm_utils_bin2hexstr_full(src, len, '\0', FALSE, result);
+
+ /* Cut converted key off at the correct length for this cipher type */
+ if (final_len >= 0 && (gsize) final_len < buflen)
+ result[final_len] = '\0';
+
+ return result;
+}
+
guint8 *
nm_utils_hexstr2bin_full(const char *hexstr,
gboolean allow_0x_prefix,
diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h
index 6070bb0e0c..d0c7434b3c 100644
--- a/src/libnm-glib-aux/nm-shared-utils.h
+++ b/src/libnm-glib-aux/nm-shared-utils.h
@@ -2710,6 +2710,8 @@ char *nm_utils_bin2hexstr_full(gconstpointer addr,
gboolean upper_case,
char *out);
+char *_nm_utils_bin2hexstr(gconstpointer src, gsize len, int final_len);
+
#define nm_utils_bin2hexstr_a(addr, length, delimiter, upper_case, str_to_free) \
({ \
gconstpointer _addr = (addr); \
diff --git a/src/meson.build b/src/meson.build
index ab69691566..f3c87f1af3 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -78,6 +78,7 @@ subdir('libnm-systemd-core')
subdir('libnm-udev-aux')
subdir('libnm-base')
subdir('libnm-platform')
+subdir('libnm-crypto')
subdir('libnm-core-public')
subdir('libnm-core-intern')
subdir('libnm-core-aux-intern')