diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 3dbbb7aa64..614e017490 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -287,12 +287,6 @@ void _nm_dbus_errors_init (void); extern gboolean _nm_utils_is_manager_process; -GByteArray *nm_utils_rsa_key_encrypt (const guint8 *data, - gsize len, - const char *in_password, - char **out_password, - GError **error); - gulong _nm_dbus_signal_connect_data (GDBusProxy *proxy, const char *signal_name, const GVariantType *signature, diff --git a/libnm-core/nm-crypto.c b/libnm-core/nm-crypto.c index c529cf458d..b626b07654 100644 --- a/libnm-core/nm-crypto.c +++ b/libnm-core/nm-crypto.c @@ -33,6 +33,7 @@ #include "nm-utils/nm-secret-utils.h" #include "nm-crypto-impl.h" +#include "nm-utils.h" #include "nm-errors.h" #define PEM_RSA_KEY_BEGIN "-----BEGIN RSA PRIVATE KEY-----" @@ -878,3 +879,108 @@ nm_crypto_randomize (void *buffer, gsize buffer_len, GError **error) { return _nm_crypto_randomize (buffer, buffer_len, error); } + + +/** + * nmtst_crypto_rsa_key_encrypt: + * @data: (array length=len): RSA private key data to be encrypted + * @len: length of @data + * @in_password: (allow-none): existing password to use, if any + * @out_password: (out) (allow-none): if @in_password was %NULL, a random + * password will be generated and returned in this argument + * @error: detailed error information on return, if an error occurred + * + * Encrypts the given RSA private key data with the given password (or generates + * a password if no password was given) and converts the data to PEM format + * suitable for writing to a file. It uses Triple DES cipher for the encryption. + * + * Returns: (transfer full): on success, PEM-formatted data suitable for writing + * to a PEM-formatted certificate/private key file. + **/ +GByteArray * +nmtst_crypto_rsa_key_encrypt (const guint8 *data, + gsize len, + const char *in_password, + char **out_password, + GError **error) +{ + char salt[16]; + int salt_len; + char *key = NULL, *enc = NULL, *pw_buf[32]; + gsize key_len = 0, enc_len = 0; + GString *pem = NULL; + char *tmp, *tmp_password = NULL; + int left; + const char *p; + GByteArray *ret = NULL; + + g_return_val_if_fail (data != NULL, NULL); + g_return_val_if_fail (len > 0, NULL); + if (out_password) + g_return_val_if_fail (*out_password == NULL, NULL); + + /* Make the password if needed */ + if (!in_password) { + if (!nm_crypto_randomize (pw_buf, sizeof (pw_buf), error)) + return NULL; + in_password = tmp_password = nm_utils_bin2hexstr (pw_buf, sizeof (pw_buf), -1); + } + + salt_len = 8; + if (!nm_crypto_randomize (salt, salt_len, error)) + goto out; + + key = nm_crypto_make_des_aes_key (CIPHER_DES_EDE3_CBC, &salt[0], salt_len, in_password, &key_len, NULL); + if (!key) + g_return_val_if_reached (NULL); + + enc = nm_crypto_encrypt (CIPHER_DES_EDE3_CBC, data, len, salt, salt_len, key, key_len, &enc_len, error); + if (!enc) + goto out; + + pem = g_string_sized_new (enc_len * 2 + 100); + g_string_append (pem, "-----BEGIN RSA PRIVATE KEY-----\n"); + g_string_append (pem, "Proc-Type: 4,ENCRYPTED\n"); + + /* Convert the salt to a hex string */ + tmp = nm_utils_bin2hexstr (salt, salt_len, salt_len * 2); + g_string_append_printf (pem, "DEK-Info: %s,%s\n\n", CIPHER_DES_EDE3_CBC, tmp); + g_free (tmp); + + /* Convert the encrypted key to a base64 string */ + p = tmp = g_base64_encode ((const guchar *) enc, enc_len); + left = strlen (tmp); + while (left > 0) { + g_string_append_len (pem, p, (left < 64) ? left : 64); + g_string_append_c (pem, '\n'); + left -= 64; + p += 64; + } + g_free (tmp); + + g_string_append (pem, "-----END RSA PRIVATE KEY-----\n"); + + ret = g_byte_array_sized_new (pem->len); + g_byte_array_append (ret, (const unsigned char *) pem->str, pem->len); + if (tmp_password && out_password) + *out_password = g_strdup (tmp_password); + +out: + if (key) { + memset (key, 0, key_len); + g_free (key); + } + if (enc) { + memset (enc, 0, enc_len); + g_free (enc); + } + if (pem) + g_string_free (pem, TRUE); + + if (tmp_password) { + memset (tmp_password, 0, strlen (tmp_password)); + g_free (tmp_password); + } + + return ret; +} diff --git a/libnm-core/nm-crypto.h b/libnm-core/nm-crypto.h index 2b56f4371b..d8b69a7411 100644 --- a/libnm-core/nm-crypto.h +++ b/libnm-core/nm-crypto.h @@ -110,6 +110,12 @@ GBytes *nmtst_crypto_decrypt_openssl_private_key (const char *file, NMCryptoKeyType *out_key_type, GError **error); +GByteArray *nmtst_crypto_rsa_key_encrypt (const guint8 *data, + gsize len, + const char *in_password, + char **out_password, + GError **error); + /*****************************************************************************/ #endif /* __NM_CRYPTO_H__ */ diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 1542625c01..1ca78421c3 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -2924,110 +2924,6 @@ _nm_utils_uuid_generate_from_strings (const char *string1, ...) /*****************************************************************************/ -/** - * nm_utils_rsa_key_encrypt: - * @data: (array length=len): RSA private key data to be encrypted - * @len: length of @data - * @in_password: (allow-none): existing password to use, if any - * @out_password: (out) (allow-none): if @in_password was %NULL, a random - * password will be generated and returned in this argument - * @error: detailed error information on return, if an error occurred - * - * Encrypts the given RSA private key data with the given password (or generates - * a password if no password was given) and converts the data to PEM format - * suitable for writing to a file. It uses Triple DES cipher for the encryption. - * - * Returns: (transfer full): on success, PEM-formatted data suitable for writing - * to a PEM-formatted certificate/private key file. - **/ -GByteArray * -nm_utils_rsa_key_encrypt (const guint8 *data, - gsize len, - const char *in_password, - char **out_password, - GError **error) -{ - char salt[16]; - int salt_len; - char *key = NULL, *enc = NULL, *pw_buf[32]; - gsize key_len = 0, enc_len = 0; - GString *pem = NULL; - char *tmp, *tmp_password = NULL; - int left; - const char *p; - GByteArray *ret = NULL; - - g_return_val_if_fail (data != NULL, NULL); - g_return_val_if_fail (len > 0, NULL); - if (out_password) - g_return_val_if_fail (*out_password == NULL, NULL); - - /* Make the password if needed */ - if (!in_password) { - if (!nm_crypto_randomize (pw_buf, sizeof (pw_buf), error)) - return NULL; - in_password = tmp_password = nm_utils_bin2hexstr (pw_buf, sizeof (pw_buf), -1); - } - - salt_len = 8; - if (!nm_crypto_randomize (salt, salt_len, error)) - goto out; - - key = nm_crypto_make_des_aes_key (CIPHER_DES_EDE3_CBC, &salt[0], salt_len, in_password, &key_len, NULL); - if (!key) - g_return_val_if_reached (NULL); - - enc = nm_crypto_encrypt (CIPHER_DES_EDE3_CBC, data, len, salt, salt_len, key, key_len, &enc_len, error); - if (!enc) - goto out; - - pem = g_string_sized_new (enc_len * 2 + 100); - g_string_append (pem, "-----BEGIN RSA PRIVATE KEY-----\n"); - g_string_append (pem, "Proc-Type: 4,ENCRYPTED\n"); - - /* Convert the salt to a hex string */ - tmp = nm_utils_bin2hexstr (salt, salt_len, salt_len * 2); - g_string_append_printf (pem, "DEK-Info: %s,%s\n\n", CIPHER_DES_EDE3_CBC, tmp); - g_free (tmp); - - /* Convert the encrypted key to a base64 string */ - p = tmp = g_base64_encode ((const guchar *) enc, enc_len); - left = strlen (tmp); - while (left > 0) { - g_string_append_len (pem, p, (left < 64) ? left : 64); - g_string_append_c (pem, '\n'); - left -= 64; - p += 64; - } - g_free (tmp); - - g_string_append (pem, "-----END RSA PRIVATE KEY-----\n"); - - ret = g_byte_array_sized_new (pem->len); - g_byte_array_append (ret, (const unsigned char *) pem->str, pem->len); - if (tmp_password && out_password) - *out_password = g_strdup (tmp_password); - -out: - if (key) { - memset (key, 0, key_len); - g_free (key); - } - if (enc) { - memset (enc, 0, enc_len); - g_free (enc); - } - if (pem) - g_string_free (pem, TRUE); - - if (tmp_password) { - memset (tmp_password, 0, strlen (tmp_password)); - g_free (tmp_password); - } - - return ret; -} - static gboolean file_has_extension (const char *filename, const char *extensions[]) { diff --git a/libnm-core/tests/test-crypto.c b/libnm-core/tests/test-crypto.c index 93970f3adc..b2474f88e7 100644 --- a/libnm-core/tests/test-crypto.c +++ b/libnm-core/tests/test-crypto.c @@ -252,11 +252,11 @@ test_encrypt_private_key (const char *path, g_assert_cmpint (key_type, ==, NM_CRYPTO_KEY_TYPE_RSA); /* Now re-encrypt the private key */ - encrypted = nm_utils_rsa_key_encrypt (g_bytes_get_data (array, NULL), - g_bytes_get_size (array), - password, - NULL, - &error); + encrypted = nmtst_crypto_rsa_key_encrypt (g_bytes_get_data (array, NULL), + g_bytes_get_size (array), + password, + NULL, + &error); nmtst_assert_success (encrypted, error); /* Then re-decrypt the private key */