summaryrefslogtreecommitdiff
path: root/egg/egg-openssl.c
diff options
context:
space:
mode:
authorStef Walter <stefw@gnome.org>2012-03-10 07:57:41 +0100
committerStef Walter <stefw@gnome.org>2012-04-07 16:44:27 +0200
commit5c4a86255897206875d72fee0c41e657dce3e39f (patch)
treebe8ff4a2950aec3006a6c8310932503b549556a0 /egg/egg-openssl.c
parent46748de8fc812dbc384e47b5910d522f57bbc79c (diff)
downloadgnome-keyring-5c4a86255897206875d72fee0c41e657dce3e39f.tar.gz
Bring over new egg'd components from gcr
* Updated ASN.1, armor, bytes, openssl, etc.
Diffstat (limited to 'egg/egg-openssl.c')
-rw-r--r--egg/egg-openssl.c147
1 files changed, 80 insertions, 67 deletions
diff --git a/egg/egg-openssl.c b/egg/egg-openssl.c
index 352451f7..2433f076 100644
--- a/egg/egg-openssl.c
+++ b/egg/egg-openssl.c
@@ -55,8 +55,8 @@ static const struct {
/* DES-EDE-CFB1 */
/* DES-EDE-CFB8 */
/* DES-EDE-OFB */
- /* DES-EDE3 */
- { "DES-EDE3-ECB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
+ /* DES-EDE3 */
+ { "DES-EDE3-ECB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB },
{ "DES-EDE3-CFB64", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
{ "DES-EDE3-CFB", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB },
/* DES-EDE3-CFB1 */
@@ -87,7 +87,7 @@ static const struct {
{ "CAST5-CFB64", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
{ "CAST5-CFB", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB },
{ "CAST5-OFB", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB },
- /* RC5-32-12-16-CBC */
+ /* RC5-32-12-16-CBC */
/* RC5-32-12-16-ECB */
/* RC5-32-12-16-CFB64 RC5-32-12-16-CFB */
/* RC5-32-12-16-OFB */
@@ -150,7 +150,7 @@ egg_openssl_parse_algo (const char *name, int *mode)
openssl_quarks[i] = g_quark_from_static_string (openssl_algos[i].desc);
g_once_init_leave (&openssl_quarks_inited, 1);
}
-
+
q = g_quark_try_string (name);
if (q) {
for (i = 0; i < G_N_ELEMENTS(openssl_algos); ++i) {
@@ -160,7 +160,7 @@ egg_openssl_parse_algo (const char *name, int *mode)
}
}
}
-
+
return 0;
}
@@ -171,16 +171,16 @@ parse_dekinfo (const gchar *dek, int *algo, int *mode, guchar **iv)
gchar **parts = NULL;
gcry_error_t gcry;
gsize ivlen, len;
-
+
parts = g_strsplit (dek, ",", 2);
- if (!parts || !parts[0] || !parts[1])
+ if (!parts || !parts[0] || !parts[1])
goto done;
-
+
/* Parse the algorithm name */
*algo = egg_openssl_parse_algo (parts[0], mode);
if (!*algo)
goto done;
-
+
/* Make sure this is usable */
gcry = gcry_cipher_test_algo (*algo);
if (gcry)
@@ -188,13 +188,13 @@ parse_dekinfo (const gchar *dek, int *algo, int *mode, guchar **iv)
/* Parse the IV */
ivlen = gcry_cipher_get_algo_blklen (*algo);
-
+
*iv = egg_hex_decode (parts[1], strlen(parts[1]), &len);
if (!*iv || ivlen != len) {
g_free (*iv);
goto done;
}
-
+
success = TRUE;
done:
@@ -202,10 +202,12 @@ done:
return success;
}
-gboolean
-egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **decrypted, gsize *n_decrypted)
+guchar *
+egg_openssl_decrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_decrypted)
{
gcry_cipher_hd_t ch;
guchar *key = NULL;
@@ -213,54 +215,58 @@ egg_openssl_decrypt_block (const gchar *dekinfo, const gchar *password,
int gcry, ivlen;
int algo = 0;
int mode = 0;
-
+ guchar *decrypted;
+
if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
return FALSE;
-
+
ivlen = gcry_cipher_get_algo_blklen (algo);
/* We assume the iv is at least as long as at 8 byte salt */
g_return_val_if_fail (ivlen >= 8, FALSE);
-
+
/* IV is already set from the DEK info */
- if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
- n_password, iv, 8, 1, &key, NULL)) {
+ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
+ n_password, iv, 8, 1, &key, NULL)) {
g_free (iv);
- return FALSE;
+ return NULL;
}
-
- /* TODO: Use secure memory */
+
gcry = gcry_cipher_open (&ch, algo, mode, 0);
- g_return_val_if_fail (!gcry, FALSE);
-
+ g_return_val_if_fail (!gcry, NULL);
+
gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
egg_secure_free (key);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (ch, iv, ivlen);
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
g_free (iv);
-
+
/* Allocate output area */
- *n_decrypted = n_data;
- *decrypted = egg_secure_alloc (n_data);
+ *n_decrypted = egg_bytes_get_size (data);
+ decrypted = egg_secure_alloc (*n_decrypted);
- gcry = gcry_cipher_decrypt (ch, *decrypted, *n_decrypted, (void*)data, n_data);
+ gcry = gcry_cipher_decrypt (ch, decrypted, *n_decrypted,
+ egg_bytes_get_data (data),
+ egg_bytes_get_size (data));
if (gcry) {
- egg_secure_free (*decrypted);
- g_return_val_if_reached (FALSE);
+ egg_secure_free (decrypted);
+ g_return_val_if_reached (NULL);
}
-
+
gcry_cipher_close (ch);
-
- return TRUE;
+
+ return decrypted;
}
-gboolean
-egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
- gssize n_password, const guchar *data, gsize n_data,
- guchar **encrypted, gsize *n_encrypted)
+guchar *
+egg_openssl_encrypt_block (const gchar *dekinfo,
+ const gchar *password,
+ gssize n_password,
+ EggBytes *data,
+ gsize *n_encrypted)
{
gsize n_overflow, n_batch, n_padding;
gcry_cipher_hd_t ch;
@@ -270,65 +276,71 @@ egg_openssl_encrypt_block (const gchar *dekinfo, const gchar *password,
int gcry, ivlen;
int algo = 0;
int mode = 0;
-
+ gsize n_data;
+ guchar *encrypted;
+ const guchar *dat;
+
if (!parse_dekinfo (dekinfo, &algo, &mode, &iv))
- g_return_val_if_reached (FALSE);
-
+ g_return_val_if_reached (NULL);
+
ivlen = gcry_cipher_get_algo_blklen (algo);
/* We assume the iv is at least as long as at 8 byte salt */
- g_return_val_if_fail (ivlen >= 8, FALSE);
-
+ g_return_val_if_fail (ivlen >= 8, NULL);
+
/* IV is already set from the DEK info */
- if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
+ if (!egg_symkey_generate_simple (algo, GCRY_MD_MD5, password,
n_password, iv, 8, 1, &key, NULL))
- g_return_val_if_reached (FALSE);
-
+ g_return_val_if_reached (NULL);
+
gcry = gcry_cipher_open (&ch, algo, mode, 0);
- g_return_val_if_fail (!gcry, FALSE);
-
+ g_return_val_if_fail (!gcry, NULL);
+
gcry = gcry_cipher_setkey (ch, key, gcry_cipher_get_algo_keylen (algo));
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
egg_secure_free (key);
/* 16 = 128 bits */
gcry = gcry_cipher_setiv (ch, iv, ivlen);
- g_return_val_if_fail (!gcry, FALSE);
+ g_return_val_if_fail (!gcry, NULL);
g_free (iv);
-
+
+ dat = egg_bytes_get_data (data);
+ n_data = egg_bytes_get_size (data);
+
/* Allocate output area */
n_overflow = (n_data % ivlen);
n_padding = n_overflow ? (ivlen - n_overflow) : 0;
n_batch = n_data - n_overflow;
*n_encrypted = n_data + n_padding;
- *encrypted = g_malloc0 (*n_encrypted);
-
+ encrypted = g_malloc0 (*n_encrypted);
+
g_assert (*n_encrypted % ivlen == 0);
g_assert (*n_encrypted >= n_data);
g_assert (*n_encrypted == n_batch + n_overflow + n_padding);
/* Encrypt everything but the last bit */
- gcry = gcry_cipher_encrypt (ch, *encrypted, n_batch, (void*)data, n_batch);
+ gcry = gcry_cipher_encrypt (ch, encrypted, n_batch, dat, n_batch);
if (gcry) {
- g_free (*encrypted);
- g_return_val_if_reached (FALSE);
+ g_free (encrypted);
+ g_return_val_if_reached (NULL);
}
-
+
/* Encrypt the padded block */
if (n_overflow) {
padded = egg_secure_alloc (ivlen);
memset (padded, 0, ivlen);
- memcpy (padded, data + n_batch, n_overflow);
- gcry = gcry_cipher_encrypt (ch, *encrypted + n_batch, ivlen, padded, ivlen);
+ memcpy (padded, dat + n_batch, n_overflow);
+ gcry = gcry_cipher_encrypt (ch, encrypted + n_batch, ivlen, padded, ivlen);
egg_secure_free (padded);
if (gcry) {
- g_free (*encrypted);
- g_return_val_if_reached (FALSE);
+ g_free (encrypted);
+ g_return_val_if_reached (NULL);
}
}
gcry_cipher_close (ch);
- return TRUE;
+ return encrypted;
}
const gchar*
@@ -351,21 +363,22 @@ egg_openssl_prep_dekinfo (GHashTable *headers)
gchar *dekinfo, *hex;
gsize ivlen;
guchar *iv;
-
+
/* Create the iv */
ivlen = gcry_cipher_get_algo_blklen (GCRY_CIPHER_3DES);
g_return_val_if_fail (ivlen, NULL);
iv = g_malloc (ivlen);
gcry_create_nonce (iv, ivlen);
-
+
/* And encode it into the string */
hex = egg_hex_encode (iv, ivlen);
g_return_val_if_fail (hex, NULL);
dekinfo = g_strdup_printf ("DES-EDE3-CBC,%s", hex);
g_free (hex);
+ g_free (iv);
g_hash_table_insert (headers, g_strdup ("DEK-Info"), (void*)dekinfo);
g_hash_table_insert (headers, g_strdup ("Proc-Type"), g_strdup ("4,ENCRYPTED"));
-
+
return dekinfo;
}