[libcryptui] Add support for symmetric encryption



commit 6012bfe8e9db61902d8db439be488b0fb118bf50
Author: Jérémy Bobbio <lunar debian org>
Date:   Wed Apr 10 13:36:57 2013 +0000

    Add support for symmetric encryption
    
    A new flag, FLAG_SYMMETRIC is added for the EncryptText and EncryptFile
    services. When specified, both will perform symmetric encryption instead of
    using public keys.
    
    To prevent programming mistakes, we error out if there is anything in the list
    of recipients as it will not be used when performing symmetric encryption.
    
    The default passphrase callback - seahorse-gpgme-source.c:passphrase_get() -
    will be used to prompt users to enter the passphrase used for symmetric
    encryption, like we already do for symmetric decryption.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=699161

 daemon/seahorse-service-crypto.c   |  221 +++++++++++++++++++----------------
 daemon/seahorse-service-crypto.xml |    1 +
 tests/dbus-crypto-test.py          |    8 ++
 tests/dbus-test.py                 |    4 +-
 4 files changed, 131 insertions(+), 103 deletions(-)
---
diff --git a/daemon/seahorse-service-crypto.c b/daemon/seahorse-service-crypto.c
index 346579d..f05d4f8 100644
--- a/daemon/seahorse-service-crypto.c
+++ b/daemon/seahorse-service-crypto.c
@@ -38,6 +38,7 @@
 
 /* flags from seahorse-service-cyrpto.xml */
 #define FLAG_QUIET 0x01
+#define FLAG_SYMMETRIC 0x02
 
 G_DEFINE_TYPE (SeahorseServiceCrypto, seahorse_service_crypto, G_TYPE_OBJECT);
 
@@ -274,8 +275,9 @@ notify_signatures (const gchar* data, gpgme_verify_result_t status)
 /**
 * crypto: the crypto service (#SeahorseServiceCrypto)
 * recipients: A list of recipients (keyids "openpgp:B8098FB063E2C811")
+*             Must be empty when symmetric encryption is used.
 * signer: optional, the keyid of the signer
-* flags: 0, not used
+* flags: FLAG_SYMMETRIC to perform symmetric encryption
 * cleartext: the text to encrypt
 * clearlength: Length of the cleartext
 * crypttext: the encrypted text (out)
@@ -295,110 +297,126 @@ crypto_encrypt_generic (SeahorseServiceCrypto *crypto,
                         char **crypttext, gsize *cryptlength, gboolean textmode,
                         gboolean ascii_armor, GError **error)
 {
-    GList *recipkeys = NULL;
-    SeahorseGpgmeOperation *pop; 
-    SeahorseObject *signkey = NULL;
-    SeahorseObject *skey;
-    gpgme_key_t *recips;
-    gpgme_data_t plain, cipher;
-    gpgme_error_t gerr;
-    gboolean ret = TRUE;
-    GSettings *settings;
-    gchar *keyid;
+       GList *recipkeys = NULL;
+       SeahorseGpgmeOperation *pop;
+       SeahorseObject *signkey = NULL;
+       SeahorseObject *skey;
+       gpgme_key_t *recips;
+       gboolean symmetric = FALSE;
+       gpgme_data_t plain, cipher;
+       gpgme_error_t gerr;
+       gboolean ret = TRUE;
+       GSettings *settings;
+       gchar *keyid;
+
+       if ((flags & FLAG_SYMMETRIC) == FLAG_SYMMETRIC)
+               symmetric = TRUE;
+
+       if (symmetric && recipients[0] != NULL) {
+               g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
+                            _("Recipients specified for symmetric encryption"));
+               return FALSE;
+       }
 
-    /* 
-     * TODO: Once we support different kinds of keys that support encryption
-     * then all this logic will need to change. 
-     */
-    /* The signer */
-    if (signer && signer[0]) {
-        signkey = seahorse_context_object_from_dbus (SCTX_APP (), signer);
-        if (!signkey) {
-            g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, 
-                         _("Invalid or unrecognized signer: %s"), signer);
-            return FALSE;
-        }
-        
-        if (!SEAHORSE_IS_GPGME_KEY (signkey) || 
-            !(seahorse_object_get_flags (signkey) & SEAHORSE_FLAG_CAN_SIGN)) {
-            g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
-                         _("Key is not valid for signing: %s"), signer);
-            return FALSE;
-        }
-    }
-    /* The recipients */
-    for( ; recipients[0]; recipients++)
-    {
-        skey = seahorse_context_object_from_dbus (SCTX_APP (), recipients[0]);
-        if (!skey) {
-            g_list_free (recipkeys);
-            g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID, 
-                         _("Invalid or unrecognized recipient: %s"), recipients[0]);
-            return FALSE;
-        }
-        
-        if (!SEAHORSE_IS_GPGME_KEY (skey) ||
-            !(seahorse_object_get_flags (skey) & SEAHORSE_FLAG_CAN_ENCRYPT)) {
-            g_list_free (recipkeys);
-            g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
-                         _("Key is not a valid recipient for encryption: %s"), recipients[0]);
-            return FALSE;
-        }
-        
-        recipkeys = g_list_prepend (recipkeys, SEAHORSE_PGP_KEY (skey));
-    }
-    
-    if (!recipkeys) {
-        g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
-                     _("No recipients specified"));
-        return FALSE;
-    }
-    pop = seahorse_gpgme_operation_new (NULL);
-    
-    /* new data form text */
-    gerr = gpgme_data_new_from_mem (&plain, cleartext, clearlength, FALSE);
-    g_return_val_if_fail (GPG_IS_OK (gerr), FALSE);
-    gerr = gpgme_data_new (&cipher);
-    g_return_val_if_fail (GPG_IS_OK (gerr), FALSE);
-   
-    /* encrypt with armor */
-    gpgme_set_textmode (pop->gctx, textmode);
-    gpgme_set_armor (pop->gctx, ascii_armor);
+       /* The signer */
+       if (signer && signer[0]) {
+               signkey = seahorse_context_object_from_dbus (SCTX_APP (), signer);
+               if (!signkey) {
+                       g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
+                                    _("Invalid or unrecognized signer: %s"), signer);
+                       return FALSE;
+               }
 
-       /* Add the default key if set and necessary */
-       settings = g_settings_new ("org.gnome.crypto.pgp");
-       if (g_settings_get_boolean (settings, "encrypt-to-self")) {
-               keyid = g_settings_get_string (settings, "default-key");
-               if (keyid && keyid[0]) {
-                       skey = seahorse_context_find_object (NULL, g_quark_from_string (keyid),
-                                                            SEAHORSE_LOCATION_LOCAL);
-                       if (SEAHORSE_IS_PGP_KEY (skey))
-                               recipkeys = g_list_append (recipkeys, skey);
+               if (!SEAHORSE_IS_GPGME_KEY (signkey) ||
+                       !(seahorse_object_get_flags (signkey) & SEAHORSE_FLAG_CAN_SIGN)) {
+                       g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
+                                    _("Key is not valid for signing: %s"), signer);
+                       return FALSE;
                }
-               g_free (keyid);
        }
-       g_object_unref (settings);
 
-    /* Make keys into the right format for GPGME */
-    recips = keylist_to_keys (recipkeys);
-    g_list_free (recipkeys);
-    
-    /* Do the encryption */
-    if (signkey) {
-        gpgme_signers_add (pop->gctx, seahorse_gpgme_key_get_private (SEAHORSE_GPGME_KEY (signkey)));
-        gerr = gpgme_op_encrypt_sign_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST, 
-                                            plain, cipher);
-    } else {
-        gerr = gpgme_op_encrypt_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST, 
-                                       plain, cipher);
-    }
-    free_keys (recips);
+       if (!symmetric) {
+               /* The recipients */
+               for( ; recipients[0]; recipients++)
+               {
+                       skey = seahorse_context_object_from_dbus (SCTX_APP (), recipients[0]);
+                       if (!skey) {
+                               g_list_free (recipkeys);
+                               g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
+                                            _("Invalid or unrecognized recipient: %s"), recipients[0]);
+                               return FALSE;
+                       }
+
+                       if (!SEAHORSE_IS_GPGME_KEY (skey) ||
+                               !(seahorse_object_get_flags (skey) & SEAHORSE_FLAG_CAN_ENCRYPT)) {
+                               g_list_free (recipkeys);
+                               g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
+                                            _("Key is not a valid recipient for encryption: %s"), 
recipients[0]);
+                               return FALSE;
+                       }
+
+                       recipkeys = g_list_prepend (recipkeys, SEAHORSE_PGP_KEY (skey));
+               }
 
-    /* Frees cipher */
-    ret = process_crypto_result (pop, gerr, cipher, crypttext, cryptlength, error);
-    g_object_unref (pop);
-    gpgme_data_release (plain);
-    return ret;
+               if (!recipkeys) {
+                       g_set_error (error, SEAHORSE_DBUS_ERROR, SEAHORSE_DBUS_ERROR_INVALID,
+                                    _("No recipients specified"));
+                       return FALSE;
+               }
+       }
+
+       pop = seahorse_gpgme_operation_new (NULL);
+
+       /* new data form text */
+       gerr = gpgme_data_new_from_mem (&plain, cleartext, clearlength, FALSE);
+       g_return_val_if_fail (GPG_IS_OK (gerr), FALSE);
+       gerr = gpgme_data_new (&cipher);
+       g_return_val_if_fail (GPG_IS_OK (gerr), FALSE);
+
+       /* encrypt with armor */
+       gpgme_set_textmode (pop->gctx, textmode);
+       gpgme_set_armor (pop->gctx, ascii_armor);
+
+       if (symmetric) {
+               /* gpgme_op_encrypt{_sign,}_start() will perform symmetric encryption
+                * when no recipients are specified. */
+               recips = NULL;
+       } else {
+               /* Add the default key if set and necessary */
+               settings = g_settings_new ("org.gnome.crypto.pgp");
+               if (g_settings_get_boolean (settings, "encrypt-to-self")) {
+                       keyid = g_settings_get_string (settings, "default-key");
+                       if (keyid && keyid[0]) {
+                               skey = seahorse_context_find_object (NULL, g_quark_from_string (keyid),
+                                                                    SEAHORSE_LOCATION_LOCAL);
+                               if (SEAHORSE_IS_PGP_KEY (skey))
+                                       recipkeys = g_list_append (recipkeys, skey);
+                       }
+                       g_free (keyid);
+               }
+               g_object_unref (settings);
+
+               /* Make keys into the right format for GPGME */
+               recips = keylist_to_keys (recipkeys);
+               g_list_free (recipkeys);
+       }
+
+       /* Do the encryption */
+       if (signkey) {
+               gpgme_signers_add (pop->gctx, seahorse_gpgme_key_get_private (SEAHORSE_GPGME_KEY (signkey)));
+               gerr = gpgme_op_encrypt_sign_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST,
+                                                   plain, cipher);
+       } else {
+               gerr = gpgme_op_encrypt_start (pop->gctx, recips, GPGME_ENCRYPT_ALWAYS_TRUST,
+                                              plain, cipher);
+       }
+       free_keys (recips);
+
+       /* Frees cipher */
+       ret = process_crypto_result (pop, gerr, cipher, crypttext, cryptlength, error);
+       g_object_unref (pop);
+       gpgme_data_release (plain);
+       return ret;
 }
 
 
@@ -494,9 +512,10 @@ crypto_decrypt_generic (SeahorseServiceCrypto *crypto,
 /**
  * seahorse_service_crypto_encrypt_text:
  * @crypto: the crypto service (#SeahorseServiceCrypto)
- * @recipients: A list of recipients (keyids "openpgp:B8098FB063E2C811")
+ * @recipients: A list of recipients (keyids "openpgp:B8098FB063E2C811").
+ *              Must be empty when symmetric encryption is used.
  * @signer: optional, the keyid of the signer
- * @flags: 0, not used
+ * @flags: FLAG_SYMMETRIC to perform symmetric encryption
  * @cleartext: the text to encrypt
  * @crypttext: the encrypted text (out)
  * @error: an error (out)
diff --git a/daemon/seahorse-service-crypto.xml b/daemon/seahorse-service-crypto.xml
index 604878f..21bedcb 100644
--- a/daemon/seahorse-service-crypto.xml
+++ b/daemon/seahorse-service-crypto.xml
@@ -6,6 +6,7 @@
      *
      * FLAGS for use in |flags| fields 
      *   FLAG_QUIET  =  0x01   (Don't display unnecessary UI)
+     *   FLAG_SYMMETRIC  =  0x02 (Perform symmetric encryption)
      *
     -->
 
diff --git a/tests/dbus-crypto-test.py b/tests/dbus-crypto-test.py
index dccea4a..b16b1a5 100644
--- a/tests/dbus-crypto-test.py
+++ b/tests/dbus-crypto-test.py
@@ -25,4 +25,12 @@ print "Signed: ", signed
 print "Verified: ", verified
 print "Signer: ", signer
 
+# Symmetric encryption
+FLAG_SYMMETRIC = 0x02
 
+encrypted = service.EncryptText([], "", FLAG_SYMMETRIC, "cleartext")
+print "Encrypted: ", encrypted
+
+(decrypted, signer) = service.DecryptText("openpgp", 0, encrypted)
+print "Decrypted: ", decrypted
+print "Signer: ", signer
diff --git a/tests/dbus-test.py b/tests/dbus-test.py
index 788d206..8fd7fc4 100644
--- a/tests/dbus-test.py
+++ b/tests/dbus-test.py
@@ -21,7 +21,7 @@ if not len(types):
     print "No key types found"
     sys.exit(0)
 
-path = service.GetKeyset(types[1])
+path = service.GetKeyset(types[0])
 print "GetKeySet(): ", path
 
 proxy_obj = bus.get_object('org.gnome.seahorse', path)
@@ -36,4 +36,4 @@ if not len(keys):
 print keys[0]
 print keyset.GetKeyField(keys[0], "display-name")
 print keyset.GetKeyFields(keys[0], [ "display-name", "raw-id", "fingerprint" ])
-print service.ExportKeys("openssh", [ keys[0] ])
+print service.ExportKeys("openpgp", [ keys[0] ])


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]