Skip to content

Commit

Permalink
Fix: Handle more fields in encrypt_all_credentials
Browse files Browse the repository at this point in the history
The function for encrypting or decrypting all credentials now also
handles the fields "community" and "privacy_password".
  • Loading branch information
timopollmeier committed Jul 17, 2023
1 parent c9bca00 commit 8b7e6d1
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 15 deletions.
66 changes: 66 additions & 0 deletions src/lsc_crypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,72 @@ lsc_crypt_create_enckey (lsc_crypt_ctx_t ctx)



/**
* @brief Encrypt a list of name/value pairs
*
* @param[in] ctx The context
* @param[in] data The GHashTable containing the plain text data
* using the name as key, value as value.
*
* @return A pointer to a freshly allocated string in base64 encoding.
* Caller must free. On error NULL is returned.
*/
char *
lsc_crypt_encrypt_hashtable (lsc_crypt_ctx_t ctx, GHashTable *data)
{
GString *stringbuf;
char *plaintext;
size_t plaintextlen;
char *ciphertext;
char *name, *value;
size_t len;

if (!ctx || !data)
return NULL;

/* Assuming a 2048 bit RSA ssh private key in PEM encoding, a buffer
with an initial size of 2k should be large enough. */
stringbuf = g_string_sized_new (2048);
GHashTableIter iter;
g_hash_table_iter_init (&iter, data);

while (g_hash_table_iter_next (&iter,
(gpointer*)(&name),
(gpointer*)(&value)))
{
if (!value)
value = "";
len = strlen (name);
if (len) /* We skip pairs with an empty name. */
{
put32 (stringbuf, len);
g_string_append (stringbuf, name);
len = strlen (value);
if (len > MAX_VALUE_LENGTH)
{
g_warning ("%s: value for '%s' larger than our limit (%d)",
G_STRFUNC, name, MAX_VALUE_LENGTH);
g_string_free (stringbuf, TRUE);
return NULL;
}
put32 (stringbuf, len);
g_string_append (stringbuf, value);
}
}

plaintext = stringbuf->str;
plaintextlen = stringbuf->len;
g_string_free (stringbuf, FALSE);
g_assert (plaintextlen);

ciphertext = do_encrypt (ctx, plaintext, plaintextlen);
g_free (plaintext);

return ciphertext;
}



/**
* @brief Encrypt a list of name/value pairs
*
Expand Down
2 changes: 2 additions & 0 deletions src/lsc_crypt.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ gboolean lsc_crypt_enckey_exists (lsc_crypt_ctx_t);

int lsc_crypt_create_enckey (lsc_crypt_ctx_t ctx);

char *lsc_crypt_encrypt_hashtable (lsc_crypt_ctx_t, GHashTable*);

char *lsc_crypt_encrypt (lsc_crypt_ctx_t,
const char *, ...) G_GNUC_NULL_TERMINATED;

Expand Down
60 changes: 45 additions & 15 deletions src/manage_sql.c
Original file line number Diff line number Diff line change
Expand Up @@ -6041,7 +6041,13 @@ encrypt_all_credentials (gboolean decrypt_flag)
" AND type = 'password'),"
" (SELECT value FROM credentials_data"
" WHERE credential = credentials.id"
" AND type = 'private_key')"
" AND type = 'private_key'),"
" (SELECT value FROM credentials_data"
" WHERE credential = credentials.id"
" AND type = 'community'),"
" (SELECT value FROM credentials_data"
" WHERE credential = credentials.id"
" AND type = 'privacy_password')"
" FROM credentials");

char *encryption_key_uid = current_encryption_key_uid (TRUE);
Expand All @@ -6054,7 +6060,7 @@ encrypt_all_credentials (gboolean decrypt_flag)
while (next (&iterator))
{
long long int rowid;
const char *secret, *password, *privkey;
const char *secret, *password, *privkey, *community, *privacy_password;

ntotal++;
if (!(ntotal % 10))
Expand All @@ -6064,19 +6070,25 @@ encrypt_all_credentials (gboolean decrypt_flag)
secret = iterator_string (&iterator, 1);
password = iterator_string (&iterator, 2);
privkey = iterator_string (&iterator, 3);
community = iterator_string (&iterator, 4);
privacy_password = iterator_string (&iterator, 5);

/* If there is no secret, password or private key, skip the row. */
if (!secret && !password && !privkey)
if (!secret && !password && !privkey && !privacy_password)
continue;

if (secret)
{
lsc_crypt_flush (iterator.crypt_ctx);
password = lsc_crypt_get_password (iterator.crypt_ctx, secret);
privkey = lsc_crypt_get_private_key (iterator.crypt_ctx, secret);
community = lsc_crypt_decrypt (iterator.crypt_ctx,
secret, "community");
privacy_password = lsc_crypt_decrypt (iterator.crypt_ctx,
secret, "privacy_password");

/* If there is no password or private key, skip the row. */
if (!password && !privkey)
/* If there is none of the expected secrets, skip the row. */
if (!password && !privkey && !community && !privacy_password)
continue;

nreencrypted++;
Expand All @@ -6093,6 +6105,8 @@ encrypt_all_credentials (gboolean decrypt_flag)
{
set_credential_data (rowid, "password", password);
set_credential_data (rowid, "private_key", privkey);
set_credential_data (rowid, "community", community);
set_credential_data (rowid, "privacy_password", privacy_password);
set_credential_data (rowid, "secret", NULL);
sql ("UPDATE credentials SET"
" modification_time = m_now ()"
Expand All @@ -6101,18 +6115,32 @@ encrypt_all_credentials (gboolean decrypt_flag)
}
else
{
GHashTable *plaintext_hashtable;
char *encblob;

plaintext_hashtable
= g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);

if (password && privkey)
encblob = lsc_crypt_encrypt (iterator.crypt_ctx,
"password", password,
"private_key", privkey, NULL);
else if (password)
encblob = lsc_crypt_encrypt (iterator.crypt_ctx,
"password", password, NULL);
else
encblob = lsc_crypt_encrypt (iterator.crypt_ctx,
"private_key", privkey, NULL);
if (password)
g_hash_table_insert (plaintext_hashtable,
"password",
g_strdup (password));
if (privkey)
g_hash_table_insert (plaintext_hashtable,
"private_key",
g_strdup (privkey));
if (community)
g_hash_table_insert (plaintext_hashtable,
"community",
g_strdup (community));
if (privacy_password)
g_hash_table_insert (plaintext_hashtable,
"privacy_password",
g_strdup (privacy_password));

encblob = lsc_crypt_encrypt_hashtable (iterator.crypt_ctx,
plaintext_hashtable);
g_hash_table_destroy (plaintext_hashtable);

if (!encblob)
{
Expand All @@ -6122,6 +6150,8 @@ encrypt_all_credentials (gboolean decrypt_flag)
}
set_credential_data (rowid, "password", NULL);
set_credential_data (rowid, "private_key", NULL);
set_credential_data (rowid, "community", NULL);
set_credential_data (rowid, "privacy_password", NULL);
set_credential_data (rowid, "secret", encblob);
sql ("UPDATE credentials SET"
" modification_time = m_now ()"
Expand Down

0 comments on commit 8b7e6d1

Please sign in to comment.