summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2015-02-26 01:48:50 +0100
committerThomas Haller <thaller@redhat.com>2015-03-12 18:12:25 +0100
commitcda7b158e2b87fc4a397334c50448ecb9d2457c2 (patch)
treeb944f91ab527630f660734c4be3456cb5a5121fb
parente59e68c5286c59b8583d23651f2aea4440cfb147 (diff)
downloadNetworkManager-cda7b158e2b87fc4a397334c50448ecb9d2457c2.tar.gz
libnm: ensure valid blob for nm_setting_802_1x_set_*_cert()
A valid blob cannot start with "file://", otherwise it would break the implementation of the certificate properties in NMSetting8021x. Simply reject every blob in nm_setting_802_1x_set_ca_cert() et al. that is not valid according to get_cert_scheme().
-rw-r--r--libnm-core/nm-setting-8021x.c41
-rw-r--r--libnm-util/nm-setting-8021x.c36
2 files changed, 69 insertions, 8 deletions
diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c
index c07dbb38fb..ab22b2f98d 100644
--- a/libnm-core/nm-setting-8021x.c
+++ b/libnm-core/nm-setting-8021x.c
@@ -32,6 +32,7 @@
#include "nm-setting-private.h"
#include "nm-core-enum-types.h"
#include "nm-utils-internal.h"
+#include "gsystem-local-alloc.h"
/**
* SECTION:nm-setting-8021x
@@ -463,6 +464,38 @@ get_cert_scheme (GBytes *bytes, GError **error)
return NM_SETTING_802_1X_CK_SCHEME_BLOB;
}
+static GByteArray *
+load_and_verify_certificate (const char *cert_path,
+ NMSetting8021xCKScheme scheme,
+ NMCryptoFileFormat *out_file_format,
+ GError **error)
+{
+ NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+ GByteArray *array;
+
+ array = crypto_load_and_verify_certificate (cert_path, &format, error);
+
+ if (!array || !array->len || format == NM_CRYPTO_FILE_FORMAT_UNKNOWN) {
+ /* the array is empty or the format is already unknown. */
+ format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+ } else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
+ /* If we load the file as blob, we must ensure that the binary data does not
+ * start with file://. NMSetting8021x cannot represent blobs that start with
+ * file://.
+ * If that's the case, coerce the format to UNKNOWN. The callers will take care
+ * of that and not set the blob. */
+ GBytes *bytes = g_bytes_new_static (array->data, array->len);
+
+ if (get_cert_scheme (bytes, NULL) != NM_SETTING_802_1X_CK_SCHEME_BLOB)
+ format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+ g_bytes_unref (bytes);
+ }
+
+ if (out_file_format)
+ *out_file_format = format;
+ return array;
+}
+
/**
* nm_setting_802_1x_get_ca_cert_scheme:
* @setting: the #NMSetting8021x
@@ -602,7 +635,7 @@ nm_setting_802_1x_set_ca_cert (NMSetting8021x *setting,
return TRUE;
}
- data = crypto_load_and_verify_certificate (cert_path, &format, error);
+ data = load_and_verify_certificate (cert_path, scheme, &format, error);
if (data) {
/* wpa_supplicant can only use raw x509 CA certs */
if (format == NM_CRYPTO_FILE_FORMAT_X509) {
@@ -916,7 +949,7 @@ nm_setting_802_1x_set_client_cert (NMSetting8021x *setting,
return TRUE;
}
- data = crypto_load_and_verify_certificate (cert_path, &format, error);
+ data = load_and_verify_certificate (cert_path, scheme, &format, error);
if (data) {
gboolean valid = FALSE;
@@ -1181,7 +1214,7 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting,
return TRUE;
}
- data = crypto_load_and_verify_certificate (cert_path, &format, error);
+ data = load_and_verify_certificate (cert_path, scheme, &format, error);
if (data) {
/* wpa_supplicant can only use raw x509 CA certs */
if (format == NM_CRYPTO_FILE_FORMAT_X509) {
@@ -1499,7 +1532,7 @@ nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting,
return TRUE;
}
- data = crypto_load_and_verify_certificate (cert_path, &format, error);
+ data = load_and_verify_certificate (cert_path, scheme, &format, error);
if (data) {
gboolean valid = FALSE;
diff --git a/libnm-util/nm-setting-8021x.c b/libnm-util/nm-setting-8021x.c
index ffbac56fe4..456d5eee68 100644
--- a/libnm-util/nm-setting-8021x.c
+++ b/libnm-util/nm-setting-8021x.c
@@ -449,6 +449,34 @@ get_cert_scheme (GByteArray *array)
return NM_SETTING_802_1X_CK_SCHEME_BLOB;
}
+static GByteArray *
+load_and_verify_certificate (const char *cert_path,
+ NMSetting8021xCKScheme scheme,
+ NMCryptoFileFormat *out_file_format,
+ GError **error)
+{
+ NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+ GByteArray *array;
+
+ array = crypto_load_and_verify_certificate (cert_path, &format, error);
+
+ if (!array || !array->len || format == NM_CRYPTO_FILE_FORMAT_UNKNOWN)
+ format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+ else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB) {
+ /* If we load the file as blob, we must ensure that the binary data does not
+ * start with file://. NMSetting8021x cannot represent blobs that start with
+ * file://.
+ * If that's the case, coerce the format to UNKNOWN. The callers will take care
+ * of that and not set the blob. */
+ if (get_cert_scheme (array) != NM_SETTING_802_1X_CK_SCHEME_BLOB)
+ format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+ }
+
+ if (out_file_format)
+ *out_file_format = format;
+ return array;
+}
+
/**
* nm_setting_802_1x_get_ca_cert_scheme:
* @setting: the #NMSetting8021x
@@ -590,7 +618,7 @@ nm_setting_802_1x_set_ca_cert (NMSetting8021x *setting,
return TRUE;
}
- data = crypto_load_and_verify_certificate (cert_path, &format, error);
+ data = load_and_verify_certificate (cert_path, scheme, &format, error);
if (data) {
/* wpa_supplicant can only use raw x509 CA certs */
if (format == NM_CRYPTO_FILE_FORMAT_X509) {
@@ -906,7 +934,7 @@ nm_setting_802_1x_set_client_cert (NMSetting8021x *setting,
return TRUE;
}
- data = crypto_load_and_verify_certificate (cert_path, &format, error);
+ data = load_and_verify_certificate (cert_path, scheme, &format, error);
if (data) {
gboolean valid = FALSE;
@@ -1171,7 +1199,7 @@ nm_setting_802_1x_set_phase2_ca_cert (NMSetting8021x *setting,
return TRUE;
}
- data = crypto_load_and_verify_certificate (cert_path, &format, error);
+ data = load_and_verify_certificate (cert_path, scheme, &format, error);
if (data) {
/* wpa_supplicant can only use raw x509 CA certs */
if (format == NM_CRYPTO_FILE_FORMAT_X509) {
@@ -1491,7 +1519,7 @@ nm_setting_802_1x_set_phase2_client_cert (NMSetting8021x *setting,
return TRUE;
}
- data = crypto_load_and_verify_certificate (cert_path, &format, error);
+ data = load_and_verify_certificate (cert_path, scheme, &format, error);
if (data) {
gboolean valid = FALSE;