diff options
-rw-r--r-- | libnm-core/crypto.c | 44 | ||||
-rw-r--r-- | libnm-core/crypto.h | 2 | ||||
-rw-r--r-- | libnm-core/crypto_gnutls.c | 18 | ||||
-rw-r--r-- | libnm-core/crypto_nss.c | 18 | ||||
-rw-r--r-- | libnm-core/nm-setting-8021x.c | 26 | ||||
-rw-r--r-- | libnm-core/nm-utils.c | 3 | ||||
-rw-r--r-- | libnm-core/tests/test-crypto.c | 11 |
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 |