mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 04:10:14 +01:00
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.
This commit is contained in:
parent
48ff21b5bc
commit
bddc0de51e
7 changed files with 86 additions and 36 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue