doc/
authorMarcus Brinkmann <mb@g10code.com>
Fri, 3 Jun 2005 00:42:08 +0000 (00:42 +0000)
committerMarcus Brinkmann <mb@g10code.com>
Fri, 3 Jun 2005 00:42:08 +0000 (00:42 +0000)
2005-06-03  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.texi (Decrypt): Add gpgme_recipient_t.

gpgme/
2005-06-03  Marcus Brinkmann  <marcus@g10code.de>

* gpgme.h (struct _gpgme_recipient): New structure.
(gpgme_recipient_t): New type.
(struct _gpgme_op_decrypt_result): Add member recipients.
* decrypt.c (op_data_t): New member last_recipient_p.
(_gpgme_op_decrypt_init_result): Initialize last_recipient_p.
(parse_enc_to): New function.
(_gpgme_decrypt_status_handler): Handle status ENC_TO and
NO_SECKEY.

NEWS
doc/ChangeLog
doc/gpgme.texi
gpgme/ChangeLog
gpgme/decrypt.c
gpgme/gpgme.h

diff --git a/NEWS b/NEWS
index 42d181472e6e4d092c58f82058706d24c3509b54..28316001ea0ada3c05560247fab3510b8a1d7de7 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -13,12 +13,17 @@ Noteworthy changes in version 1.1.0 (unreleased)
    Because the default changes, this is a slight change of the API
    semantics.  We consider it to be a bug fix.
 
+ * Information about the recipients of an encrypted text is now
+   available at decryption time.
+
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 gpgme_set_engine_info          NEW
 gpgme_ctx_get_engine_info      NEW
 gpgme_ctx_set_engine_info      NEW
 gpgme_set_include_certs                CHANGED DEFAULT
 GPGME_INCLUDE_CERTS_DEFAULT    NEW
+gpgme_recipient_t              NEW
+gpgme_decrypt_result_t         EXTENDED: New field recipients.
 GPGME_STATUS_SIG_SUBPACKET     NEW
 GPGME_STATUS_NEED_PASSPHRASE_PIN NEW
 GPGME_STATUS_SC_OP_FAILURE     NEW
index 67519fa7e735a025269f9df1e38105f8e8bcf3ab..e4071285506f5be4b9c4de51e20b3b4c4409cea0 100644 (file)
@@ -1,3 +1,7 @@
+2005-06-03  Marcus Brinkmann  <marcus@g10code.de>
+
+       * gpgme.texi (Decrypt): Add gpgme_recipient_t.
+
 2005-05-28  Marcus Brinkmann  <marcus@g10code.de>
 
        * gpgme.texi (Key Listing Mode): Fix return type of
index cae9b70cadd40005d06b8c9f4222e7e8965c2a21..92289c2e2c139efe5a60175a9df040866fb0ac7b 100644 (file)
@@ -3622,9 +3622,38 @@ operation could be started successfully, and @code{GPG_ERR_INV_VALUE}
 if @var{cipher} or @var{plain} is not a valid pointer.
 @end deftypefun
 
+@deftp {Data type} {gpgme_recipient_t}
+This is a pointer to a structure used to store information about the
+recipient of an encrypted text which is decrypted in a
+@code{gpgme_op_decrypt} operation.  This information (except for the
+status field) is even available before the operation finished
+successfully, for example in a passphrase callback.  The structure
+contains the following members:
+
+@table @code
+@item gpgme_recipient_t next
+This is a pointer to the next recipient structure in the linked list,
+or @code{NULL} if this is the last element.
+
+@item gpgme_pubkey_algo_t
+The public key algorithm used in the encryption.
+
+@item unsigned int wrong_key_usage : 1
+This is true if the key was not used according to its policy.
+
+@item char *keyid
+This is the key ID of the key (in hexadecimal digits) used as
+recipient.
+
+@item gpgme_error_t status
+This is an error number with the error code GPG_ERR_NO_SECKEY if the
+secret key for this recipient is not available, and 0 otherwise.
+@end table
+@end deftp
+
 @deftp {Data type} {gpgme_decrypt_result_t}
 This is a pointer to a structure used to store the result of a
-@code{gpgme_op_decrypt} operation.  After successfully encrypting
+@code{gpgme_op_decrypt} operation.  After successfully decrypting
 data, you can retrieve the pointer to the result with
 @code{gpgme_op_decrypt_result}.  The structure contains the following
 members:
@@ -3636,6 +3665,9 @@ algorithm that is not supported.
 
 @item unsigned int wrong_key_usage : 1
 This is true if the key was not used according to its policy.
+
+@item gpgme_recipient_t recipient
+This is a linked list of recipients to which this message was encrypted.
 @end table
 @end deftp
 
index a28ece04eab2ceab998597e5f7f58230f4058d8d..52a77d052e3614937124aae1f7061a188d289308 100644 (file)
@@ -1,5 +1,14 @@
 2005-06-03  Marcus Brinkmann  <marcus@g10code.de>
 
+       * gpgme.h (struct _gpgme_recipient): New structure.
+       (gpgme_recipient_t): New type.
+       (struct _gpgme_op_decrypt_result): Add member recipients.
+       * decrypt.c (op_data_t): New member last_recipient_p.
+       (_gpgme_op_decrypt_init_result): Initialize last_recipient_p.
+       (parse_enc_to): New function.
+       (_gpgme_decrypt_status_handler): Handle status ENC_TO and
+       NO_SECKEY.
+
        * wait-global.c (gpgme_wait): Break out of the fd processing loop
        after an error.
        Reported by Igor Belyi <gpgme@katehok.ac93.org>.
index c235be4adbac371a06636ada6cd83fb376418766..bbbe29573950d14a0f732a80e9faa7120e6886c4 100644 (file)
@@ -38,6 +38,11 @@ typedef struct
 
   int okay;
   int failed;
+  
+  /* A pointer to the next pointer of the last recipient in the list.
+     This makes appending new invalid signers painless while
+     preserving the order.  */
+  gpgme_recipient_t *last_recipient_p;
 } *op_data_t;
 
 
@@ -67,6 +72,60 @@ gpgme_op_decrypt_result (gpgme_ctx_t ctx)
 }
 
 \f
+static gpgme_error_t
+parse_enc_to (char *args, gpgme_recipient_t *recp)
+{
+  gpgme_recipient_t rec;
+  char *tail;
+  int i;
+
+  rec = malloc (sizeof (*rec));
+  if (!rec)
+    return gpg_error_from_errno (errno);
+
+  rec->next = NULL;
+  rec->keyid = rec->_keyid;
+  rec->status = 0;
+
+  for (i = 0; i < sizeof (rec->_keyid) - 1; i++)
+    {
+      if (args[i] == '\0' || args[i] == ' ')
+       break;
+
+      rec->_keyid[i] = args[i];
+    }
+  rec->_keyid[i] = '\0';
+
+  args = &args[i];
+  if (*args != '\0' && *args != ' ')
+    {
+      free (rec);
+      return gpg_error (GPG_ERR_INV_ENGINE);
+    }
+
+  while (*args == ' ')
+    args++;
+
+  if (*args)
+    {
+      errno = 0;
+      rec->pubkey_algo = strtol (args, &tail, 0);
+      if (errno || args == tail || *tail != ' ')
+       {
+         /* The crypto backend does not behave.  */
+         free (rec);
+         return gpg_error (GPG_ERR_INV_ENGINE);
+       }
+    }
+
+  /* FIXME: The key length is always 0 right now, so no need to parse
+     it.  */
+
+  *recp = rec;
+  return 0;
+}
+
+
 gpgme_error_t
 _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
                               char *args)
@@ -151,7 +210,33 @@ _gpgme_decrypt_status_handler (void *priv, gpgme_status_code_t code,
          }
       }
       break;
-        
+
+    case GPGME_STATUS_ENC_TO:
+      err = parse_enc_to (args, opd->last_recipient_p);
+      if (err)
+       return err;
+
+      opd->last_recipient_p = &(*opd->last_recipient_p)->next;
+      break;
+
+    case GPGME_STATUS_NO_SECKEY:
+      {
+       gpgme_recipient_t rec = opd->result.recipients;
+
+       while (rec)
+         {
+           if (!strcmp (rec->keyid, args))
+             {
+               rec->status = gpg_error (GPG_ERR_NO_SECKEY);
+               break;
+             }
+         }
+       /* FIXME: Is this ok?  */
+       if (!rec)
+         return gpg_error (GPG_ERR_INV_ENGINE);
+      }
+      break;
+
     default:
       break;
     }
@@ -175,11 +260,18 @@ decrypt_status_handler (void *priv, gpgme_status_code_t code, char *args)
 gpgme_error_t
 _gpgme_op_decrypt_init_result (gpgme_ctx_t ctx)
 {
+  gpgme_error_t err;
   void *hook;
   op_data_t opd;
 
-  return _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
-                               sizeof (*opd), release_op_data);
+  err = _gpgme_op_data_lookup (ctx, OPDATA_DECRYPT, &hook,
+                              sizeof (*opd), release_op_data);
+  opd = hook;
+  if (err)
+    return err;
+
+  opd->last_recipient_p = &opd->result.recipients;
+  return 0;
 }
 
 
index 0708d378f79d48776afeb3d726f324b9796b12d2..31fffe19c25a0043b2b76609bf4c2d7f2bc6935c 100644 (file)
@@ -1080,6 +1080,25 @@ gpgme_error_t gpgme_op_encrypt_sign (gpgme_ctx_t ctx, gpgme_key_t recp[],
 
 \f
 /* Decryption.  */
+
+struct _gpgme_recipient
+{
+  struct _gpgme_recipient *next;
+
+  /* The key ID of key for which the text was encrypted.  */
+  char *keyid;
+
+  /* Internal to GPGME, do not use.  */
+  char _keyid[16 + 1];
+
+  /* The public key algorithm of the recipient key.  */
+  gpgme_pubkey_algo_t pubkey_algo;
+
+  /* The status of the recipient.  */
+  gpgme_error_t status;
+};
+typedef struct _gpgme_recipient *gpgme_recipient_t;
+
 struct _gpgme_op_decrypt_result
 {
   char *unsupported_algorithm;
@@ -1089,6 +1108,8 @@ struct _gpgme_op_decrypt_result
 
   /* Internal to GPGME, do not use.  */
   int _unused : 31;
+
+  gpgme_recipient_t recipients;
 };
 typedef struct _gpgme_op_decrypt_result *gpgme_decrypt_result_t;