libnm/crypto: move and mark nm_utils_rsa_key_encrypt() as test code

nm_utils_rsa_key_encrypt() is internal API which is only uesd for testing.
Move it to nm-crypto.h (where it fits better) and rename it to make the
testing-aspect obvious.
This commit is contained in:
Thomas Haller 2018-08-30 12:42:10 +02:00
parent 9153d9e2ea
commit f961dcb806
5 changed files with 117 additions and 115 deletions

View file

@ -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,

View file

@ -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;
}

View file

@ -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__ */

View file

@ -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[])
{

View file

@ -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 */