summaryrefslogtreecommitdiff
path: root/libnm-core
diff options
context:
space:
mode:
authorDan Winship <danw@redhat.com>2014-12-01 14:13:06 -0500
committerDan Winship <danw@redhat.com>2014-12-04 08:39:54 -0500
commitbddc0de51e519e7b4622beb1db8d0a3af2da166e (patch)
treea05a7bd07577ecda78f8c7f4608a37bf5d7af12f /libnm-core
parent48ff21b5bc42daa8b6f72db8d82fd9b21fde842e (diff)
downloadNetworkManager-bddc0de51e519e7b4622beb1db8d0a3af2da166e.tar.gz
libnm-core: call crypto_init() on the fly
Rather than requiring crypto_init() to have been called beforehand, just have every method that depends on it call it itself. This required adding a GError argument to crypto_is_pkcs12_data(), which in turn required a few other changes elsewhere.
Diffstat (limited to 'libnm-core')
-rw-r--r--libnm-core/crypto.c44
-rw-r--r--libnm-core/crypto.h2
-rw-r--r--libnm-core/crypto_gnutls.c18
-rw-r--r--libnm-core/crypto_nss.c18
-rw-r--r--libnm-core/nm-setting-8021x.c26
-rw-r--r--libnm-core/nm-utils.c3
-rw-r--r--libnm-core/tests/test-crypto.c11
7 files changed, 86 insertions, 36 deletions
diff --git a/libnm-core/crypto.c b/libnm-core/crypto.c
index 086f1d6714..e769bb4ab3 100644
--- a/libnm-core/crypto.c
+++ b/libnm-core/crypto.c
@@ -482,6 +482,9 @@ crypto_decrypt_openssl_private_key_data (const guint8 *data,
if (out_key_type)
g_return_val_if_fail (*out_key_type == NM_CRYPTO_KEY_TYPE_UNKNOWN, NULL);
+ if (!crypto_init (error))
+ return NULL;
+
parsed = parse_old_openssl_key_file (data, data_len, &key_type, &cipher, &iv, NULL);
/* return the key type even if decryption failed */
if (out_key_type)
@@ -527,6 +530,9 @@ crypto_decrypt_openssl_private_key (const char *file,
GByteArray *contents;
GByteArray *key = NULL;
+ if (!crypto_init (error))
+ return NULL;
+
contents = file_to_g_byte_array (file, error);
if (contents) {
key = crypto_decrypt_openssl_private_key_data (contents->data, contents->len,
@@ -594,12 +600,15 @@ crypto_load_and_verify_certificate (const char *file,
g_return_val_if_fail (out_file_format != NULL, NULL);
g_return_val_if_fail (*out_file_format == NM_CRYPTO_FILE_FORMAT_UNKNOWN, NULL);
+ if (!crypto_init (error))
+ return NULL;
+
contents = file_to_g_byte_array (file, error);
if (!contents)
return NULL;
/* Check for PKCS#12 */
- if (crypto_is_pkcs12_data (contents->data, contents->len)) {
+ if (crypto_is_pkcs12_data (contents->data, contents->len, NULL)) {
*out_file_format = NM_CRYPTO_FILE_FORMAT_PKCS12;
return contents;
}
@@ -628,20 +637,26 @@ crypto_load_and_verify_certificate (const char *file,
gboolean
crypto_is_pkcs12_data (const guint8 *data,
- gsize data_len)
+ gsize data_len,
+ GError **error)
{
- GError *error = NULL;
+ GError *local = NULL;
gboolean success;
g_return_val_if_fail (data != NULL, FALSE);
- success = crypto_verify_pkcs12 (data, data_len, NULL, &error);
+ if (!crypto_init (error))
+ return FALSE;
+
+ success = 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 (error) {
- if (g_error_matches (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_DECRYPTION_FAILED))
+ if (local) {
+ if (g_error_matches (local, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_DECRYPTION_FAILED)) {
success = TRUE;
- g_error_free (error);
+ g_error_free (local);
+ } else
+ g_propagate_error (error, local);
}
}
return success;
@@ -655,9 +670,12 @@ crypto_is_pkcs12_file (const char *file, GError **error)
g_return_val_if_fail (file != NULL, FALSE);
+ if (!crypto_init (error))
+ return FALSE;
+
contents = file_to_g_byte_array (file, error);
if (contents) {
- success = crypto_is_pkcs12_data (contents->data, contents->len);
+ success = crypto_is_pkcs12_data (contents->data, contents->len, error);
g_byte_array_free (contents, TRUE);
}
return success;
@@ -681,8 +699,11 @@ crypto_verify_private_key_data (const guint8 *data,
g_return_val_if_fail (data != NULL, NM_CRYPTO_FILE_FORMAT_UNKNOWN);
g_return_val_if_fail (out_is_encrypted == NULL || *out_is_encrypted == FALSE, NM_CRYPTO_FILE_FORMAT_UNKNOWN);
+ if (!crypto_init (error))
+ return NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+
/* Check for PKCS#12 first */
- if (crypto_is_pkcs12_data (data, data_len)) {
+ if (crypto_is_pkcs12_data (data, data_len, NULL)) {
is_encrypted = TRUE;
if (!password || crypto_verify_pkcs12 (data, data_len, password, error))
format = NM_CRYPTO_FILE_FORMAT_PKCS12;
@@ -727,7 +748,10 @@ crypto_verify_private_key (const char *filename,
GByteArray *contents;
NMCryptoFileFormat format = NM_CRYPTO_FILE_FORMAT_UNKNOWN;
- g_return_val_if_fail (filename != NULL, FALSE);
+ g_return_val_if_fail (filename != NULL, NM_CRYPTO_FILE_FORMAT_UNKNOWN);
+
+ if (!crypto_init (error))
+ return NM_CRYPTO_FILE_FORMAT_UNKNOWN;
contents = file_to_g_byte_array (filename, error);
if (contents) {
diff --git a/libnm-core/crypto.h b/libnm-core/crypto.h
index 392ec57481..1a712dd7d0 100644
--- a/libnm-core/crypto.h
+++ b/libnm-core/crypto.h
@@ -63,7 +63,7 @@ GByteArray *crypto_load_and_verify_certificate (const char *file,
gboolean crypto_is_pkcs12_file (const char *file, GError **error);
-gboolean crypto_is_pkcs12_data (const guint8 *data, gsize len);
+gboolean crypto_is_pkcs12_data (const guint8 *data, gsize len, GError **error);
NMCryptoFileFormat crypto_verify_private_key_data (const guint8 *data,
gsize data_len,
diff --git a/libnm-core/crypto_gnutls.c b/libnm-core/crypto_gnutls.c
index 03923f6307..96dddb9029 100644
--- a/libnm-core/crypto_gnutls.c
+++ b/libnm-core/crypto_gnutls.c
@@ -75,6 +75,9 @@ crypto_decrypt (const char *cipher,
gboolean success = FALSE;
gsize pad_len, real_iv_len;
+ if (!crypto_init (error))
+ return NULL;
+
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
cipher_mech = GCRY_CIPHER_3DES;
real_iv_len = SALT_LEN;
@@ -196,6 +199,9 @@ crypto_encrypt (const char *cipher,
guint32 i;
gsize salt_len;
+ if (!crypto_init (error))
+ return NULL;
+
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
cipher_mech = GCRY_CIPHER_3DES;
salt_len = SALT_LEN;
@@ -291,6 +297,9 @@ crypto_verify_cert (const unsigned char *data,
gnutls_datum_t dt;
int err;
+ if (!crypto_init (error))
+ return NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+
err = gnutls_x509_crt_init (&der);
if (err < 0) {
g_set_error (error, NM_CRYPTO_ERROR,
@@ -335,6 +344,9 @@ crypto_verify_pkcs12 (const guint8 *data,
g_return_val_if_fail (data != NULL, FALSE);
+ if (!crypto_init (error))
+ return FALSE;
+
dt.data = (unsigned char *) data;
dt.size = data_len;
@@ -389,6 +401,9 @@ crypto_verify_pkcs8 (const guint8 *data,
g_return_val_if_fail (data != NULL, FALSE);
+ if (!crypto_init (error))
+ return FALSE;
+
dt.data = (unsigned char *) data;
dt.size = data_len;
@@ -431,6 +446,9 @@ crypto_verify_pkcs8 (const guint8 *data,
gboolean
crypto_randomize (void *buffer, gsize buffer_len, GError **error)
{
+ if (!crypto_init (error))
+ return FALSE;
+
gcry_randomize (buffer, buffer_len, GCRY_STRONG_RANDOM);
return TRUE;
}
diff --git a/libnm-core/crypto_nss.c b/libnm-core/crypto_nss.c
index 4dd85f3bdc..d0c3506b88 100644
--- a/libnm-core/crypto_nss.c
+++ b/libnm-core/crypto_nss.c
@@ -97,6 +97,9 @@ crypto_decrypt (const char *cipher,
unsigned int pad_len = 0, extra = 0;
guint32 i, real_iv_len = 0;
+ if (!crypto_init (error))
+ return NULL;
+
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC)) {
cipher_mech = CKM_DES3_CBC_PAD;
real_iv_len = 8;
@@ -264,6 +267,9 @@ crypto_encrypt (const char *cipher,
gboolean success = FALSE;
gsize padded_buf_len, pad_len;
+ if (!crypto_init (error))
+ return NULL;
+
if (!strcmp (cipher, CIPHER_DES_EDE3_CBC))
cipher_mech = CKM_DES3_CBC_PAD;
else if (!strcmp (cipher, CIPHER_AES_CBC))
@@ -368,6 +374,9 @@ crypto_verify_cert (const unsigned char *data,
{
CERTCertificate *cert;
+ if (!crypto_init (error))
+ return NM_CRYPTO_FILE_FORMAT_UNKNOWN;
+
/* Try DER/PEM first */
cert = CERT_DecodeCertFromPackage ((char *) data, len);
if (!cert) {
@@ -401,6 +410,9 @@ crypto_verify_pkcs12 (const guint8 *data,
if (error)
g_return_val_if_fail (*error == NULL, FALSE);
+ if (!crypto_init (error))
+ return FALSE;
+
/* PKCS#12 passwords are apparently UCS2 BIG ENDIAN, and NSS doesn't do
* any conversions for us.
*/
@@ -485,6 +497,9 @@ crypto_verify_pkcs8 (const guint8 *data,
{
g_return_val_if_fail (data != NULL, FALSE);
+ if (!crypto_init (error))
+ return FALSE;
+
/* NSS apparently doesn't do PKCS#8 natively, but you have to put the
* PKCS#8 key into a PKCS#12 file and import that?? So until we figure
* all that out, we can only assume the password is valid.
@@ -497,6 +512,9 @@ crypto_randomize (void *buffer, gsize buffer_len, GError **error)
{
SECStatus s;
+ if (!crypto_init (error))
+ return FALSE;
+
s = PK11_GenerateRandom (buffer, buffer_len);
if (s != SECSuccess) {
g_set_error_literal (error, NM_CRYPTO_ERROR,
diff --git a/libnm-core/nm-setting-8021x.c b/libnm-core/nm-setting-8021x.c
index d5e17b97a4..369359f47a 100644
--- a/libnm-core/nm-setting-8021x.c
+++ b/libnm-core/nm-setting-8021x.c
@@ -1871,15 +1871,15 @@ nm_setting_802_1x_get_private_key_format (NMSetting8021x *setting)
switch (nm_setting_802_1x_get_private_key_scheme (setting)) {
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
if (crypto_is_pkcs12_data (g_bytes_get_data (priv->private_key, NULL),
- g_bytes_get_size (priv->private_key)))
+ g_bytes_get_size (priv->private_key),
+ NULL))
return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
case NM_SETTING_802_1X_CK_SCHEME_PATH:
path = nm_setting_802_1x_get_private_key_path (setting);
if (crypto_is_pkcs12_file (path, &error))
return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
- if (error) {
- /* Couldn't read the file or something */
+ if (error && error->domain == G_FILE_ERROR) {
g_error_free (error);
return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
}
@@ -2151,15 +2151,15 @@ nm_setting_802_1x_get_phase2_private_key_format (NMSetting8021x *setting)
switch (nm_setting_802_1x_get_phase2_private_key_scheme (setting)) {
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
if (crypto_is_pkcs12_data (g_bytes_get_data (priv->phase2_private_key, NULL),
- g_bytes_get_size (priv->phase2_private_key)))
+ g_bytes_get_size (priv->phase2_private_key),
+ NULL))
return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
return NM_SETTING_802_1X_CK_FORMAT_RAW_KEY;
case NM_SETTING_802_1X_CK_SCHEME_PATH:
path = nm_setting_802_1x_get_phase2_private_key_path (setting);
if (crypto_is_pkcs12_file (path, &error))
return NM_SETTING_802_1X_CK_FORMAT_PKCS12;
- if (error) {
- /* Couldn't read the file or something */
+ if (error && error->domain == G_FILE_ERROR) {
g_error_free (error);
return NM_SETTING_802_1X_CK_FORMAT_UNKNOWN;
}
@@ -2300,7 +2300,8 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error)
/* If the private key is PKCS#12, check that it matches the client cert */
if (crypto_is_pkcs12_data (g_bytes_get_data (priv->phase2_private_key, NULL),
- g_bytes_get_size (priv->phase2_private_key))) {
+ g_bytes_get_size (priv->phase2_private_key),
+ NULL)) {
if (!g_bytes_equal (priv->phase2_private_key, priv->phase2_client_cert)) {
g_set_error (error,
NM_CONNECTION_ERROR,
@@ -2347,7 +2348,8 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error)
/* If the private key is PKCS#12, check that it matches the client cert */
if (crypto_is_pkcs12_data (g_bytes_get_data (priv->private_key, NULL),
- g_bytes_get_size (priv->private_key))) {
+ g_bytes_get_size (priv->private_key),
+ NULL)) {
if (!g_bytes_equal (priv->private_key, priv->client_cert)) {
g_set_error (error,
NM_CONNECTION_ERROR,
@@ -3078,7 +3080,6 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (setting_class);
NMSettingClass *parent_class = NM_SETTING_CLASS (setting_class);
- GError *error = NULL;
g_type_class_add_private (setting_class, sizeof (NMSetting8021xPrivate));
@@ -3859,11 +3860,4 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *setting_class)
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS));
-
- /* Initialize crypto lbrary. */
- if (!nm_utils_init (&error)) {
- g_warning ("Couldn't initilize nm-utils/crypto system: %d %s",
- error->code, error->message);
- g_error_free (error);
- }
}
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index 8f63a51988..c7c8421963 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -244,9 +244,6 @@ nm_utils_init (GError **error)
bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
- if (!crypto_init (error))
- return FALSE;
-
_nm_dbus_errors_init ();
}
return TRUE;
diff --git a/libnm-core/tests/test-crypto.c b/libnm-core/tests/test-crypto.c
index a5513122b5..287abfbe3b 100644
--- a/libnm-core/tests/test-crypto.c
+++ b/libnm-core/tests/test-crypto.c
@@ -221,15 +221,14 @@ test_is_pkcs12 (const char *path, gboolean expect_fail)
GError *error = NULL;
is_pkcs12 = crypto_is_pkcs12_file (path, &error);
- /* crypto_is_pkcs12_file() only returns an error if it couldn't read the
- * file, which we don't expect to happen here.
- */
- g_assert_no_error (error);
- if (expect_fail)
+ if (expect_fail) {
+ g_assert_error (error, NM_CRYPTO_ERROR, NM_CRYPTO_ERROR_INVALID_DATA);
g_assert (!is_pkcs12);
- else
+ } else {
+ g_assert_no_error (error);
g_assert (is_pkcs12);
+ }
}
static void