diff options
author | Stef Walter <stefw@gnome.org> | 2012-03-10 07:57:41 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2012-04-07 16:44:27 +0200 |
commit | 5c4a86255897206875d72fee0c41e657dce3e39f (patch) | |
tree | be8ff4a2950aec3006a6c8310932503b549556a0 /egg/egg-openssl.c | |
parent | 46748de8fc812dbc384e47b5910d522f57bbc79c (diff) | |
download | gnome-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.c | 147 |
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; } |