* New interfaces gpgme_op_encrypt_sign and gpgme_op_encrypt_sign_start
to encrypt and sign a message in a combined operation.
+ * gpgme_op_encrypt does now fail with GPGME_Invalid_Recipients if
+ some recipients have been invalid, whereas earlier versions
+ succeeded in this case. The plaintext is still encrypted for all valid
+ recipients, so the application might take this error as a hint that
+ the ciphertext is not usable for all requested recipients.
+ Information about invalid recipients is available with gpgme_get_op_info.
+
* Interface changes relative to the 0.3.3 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+gpgme_op_encrypt CHANGED: Can fail with GPGME_Invalid_Recipients
gpgme_set_include_certs NEW
gpgme_get_include_certs NEW
gpgme_op_encrypt_sign NEW
+2002-02-27 Marcus Brinkmann <marcus@g10code.de>
+
+ * gpgme.texi (Encrypting a Plaintext): Document
+ GPGME_Invalid_Recipients.
+ (Error Values): Likewise.
+
2002-02-26 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Encrypting a Plaintext): Document
This value means that the creation of a pipe failed.
@item GPGME_No_Recipients
-This value means that no recipients for a message have been set.
+This value means that no valid recipients for a message have been set.
+
+@item GPGME_Invalid_Recipients
+This value means that some, but not all, recipients for a message have
+been invalid.
@item GPGME_No_Data
This value means that a @code{GpgmeData} object which was expected to
ciphertext created is determined by the @acronym{ASCII} armor and text
mode attributes set for the context @var{ctx}.
-More information about the encrypted text is available with
+If @code{GPGME_Invalid_Recipients} is returned, some recipients in
+@var{rset} are invalid, but not all. In this case the plaintext is
+encrypted for all valid recipients and returned in @var{cipher}. More
+information about the invalid recipients is available with
@code{gpgme_get_op_info}. @xref{Detailed Results}.
The function returns @code{GPGME_No_Error} if the ciphertext could be
created successfully, @code{GPGME_Invalid_Value} if @var{ctx},
@var{rset}, @var{plain} or @var{cipher} is not a valid pointer,
-@code{GPGME_No_Recipient} if @var{rset} does not contain any
-valid recipients, @code{GPGME_No_Passphrase} if the passphrase for the
-secret key could not be retrieved, and passes through any errors that
-are reported by the crypto engine support routines.
+@code{GPGME_No_Recipients} if @var{rset} does not contain any valid
+recipients, @code{GPGME_Invalid_Recipients} if @var{rset} contains
+some invalid recipients, @code{GPGME_No_Passphrase} if the passphrase
+for the secret key could not be retrieved, and passes through any
+errors that are reported by the crypto engine support routines.
@end deftypefun
@deftypefun GpgmeError gpgme_op_encrypt_start (@w{GpgmeCtx @var{ctx}}, @w{GpgmeRecipients @var{rset}}, @w{GpgmeData @var{plain}}, @w{GpgmeData @var{cipher}})
The function returns @code{GPGME_No_Error} if the operation could be
started successfully, @code{GPGME_Invalid_Value} if @var{ctx},
@var{rset}, @var{plain} or @var{cipher} is not a valid pointer, and
-@code{GPGME_No_Recipient} if @var{rset} does not contain any valid
+@code{GPGME_No_Recipients} if @var{rset} does not contain any valid
recipients.
@end deftypefun
The function returns @code{GPGME_No_Error} if the operation could be
started successfully, @code{GPGME_Invalid_Value} if @var{ctx},
@var{rset}, @var{plain} or @var{cipher} is not a valid pointer, and
-@code{GPGME_No_Recipient} if @var{rset} does not contain any valid
+@code{GPGME_No_Recipients} if @var{rset} does not contain any valid
recipients.
@end deftypefun
+2002-02-27 Marcus Brinkmann <marcus@g10code.de>
+
+ * gpgme.h: Add new error code GPGME_Invalid_Recipient.
+ * encrypt.c (struct encrypt_result_s): New member invalid_recipients,
+ rename no_recipients to no_valid_recipients.
+ (_gpgme_encrypt_status_handler): Include error for invalid
+ recipients.
+ * engine-gpgsm.c (gpgsm_set_recipients): Change type of first
+ argument to GpgsmObject. Use that to report back the status about
+ the recipients.
+
2002-02-26 Marcus Brinkmann <marcus@g10code.de>
* verify.c (_gpgme_verify_status_handler): Fix the last change.
struct encrypt_result_s
{
- int no_recipients;
+ int no_valid_recipients;
+ int invalid_recipients;
GpgmeData xmlinfo;
};
_gpgme_set_op_info (ctx, ctx->result.encrypt->xmlinfo);
ctx->result.encrypt->xmlinfo = NULL;
}
- if (ctx->result.encrypt->no_recipients)
+ if (ctx->result.encrypt->no_valid_recipients)
ctx->error = mk_error (No_Recipients);
+ else if (ctx->result.encrypt->invalid_recipients)
+ ctx->error = mk_error (Invalid_Recipients);
break;
case STATUS_INV_RECP:
+ ctx->result.encrypt->invalid_recipients++;
append_xml_encinfo (&ctx->result.encrypt->xmlinfo, args);
break;
case STATUS_NO_RECP:
- ctx->result.encrypt->no_recipients = 1; /* i.e. no usable ones */
+ ctx->result.encrypt->no_valid_recipients = 1;
break;
default:
static GpgmeError
-gpgsm_set_recipients (ASSUAN_CONTEXT ctx, GpgmeRecipients recp)
+gpgsm_set_recipients (GpgsmObject gpgsm, GpgmeRecipients recp)
{
GpgmeError err;
+ ASSUAN_CONTEXT ctx = gpgsm->assuan_ctx;
char *line;
int linelen;
struct user_id_s *r;
+ int valid_recipients = 0;
linelen = 10 + 40 + 1; /* "RECIPIENT " + guess + '\0'. */
line = xtrymalloc (10 + 40 + 1);
strcpy (&line[10], r->name);
err = gpgsm_assuan_simple_command (ctx, line);
- if (err)
+ if (!err)
+ valid_recipients = 1;
+ else if (err == GPGME_Invalid_Key && gpgsm->status.fnc)
+ {
+ /* FIXME: Include other reasons. */
+ line[8] = '0'; /* FIXME: Report detailed reason. */
+ gpgsm->status.fnc (gpgsm->status.fnc_value, STATUS_INV_RECP, &line[8]);
+ line[8] = 'T';
+ }
+ else if (err != GPGME_Invalid_Key)
{
xfree (line);
return err;
}
}
xfree (line);
+ if (!valid_recipients && gpgsm->status.fnc)
+ gpgsm->status.fnc (gpgsm->status.fnc_value, STATUS_NO_RECP, "");
return 0;
}
return err;
_gpgme_io_close (gpgsm->message_fd);
- err = gpgsm_set_recipients (gpgsm->assuan_ctx, recp);
+ err = gpgsm_set_recipients (gpgsm, recp);
if (err)
return err;
/* The error numbers used by GPGME. */
typedef enum
{
- GPGME_EOF = -1,
- GPGME_No_Error = 0,
- GPGME_General_Error = 1,
- GPGME_Out_Of_Core = 2,
- GPGME_Invalid_Value = 3,
- GPGME_Busy = 4,
- GPGME_No_Request = 5,
- GPGME_Exec_Error = 6,
- GPGME_Too_Many_Procs = 7,
- GPGME_Pipe_Error = 8,
- GPGME_No_Recipients = 9,
- GPGME_No_Data = 10,
- GPGME_Conflict = 11,
- GPGME_Not_Implemented = 12,
- GPGME_Read_Error = 13,
- GPGME_Write_Error = 14,
- GPGME_Invalid_Type = 15,
- GPGME_Invalid_Mode = 16,
- GPGME_File_Error = 17, /* errno is set in this case. */
- GPGME_Decryption_Failed = 18,
- GPGME_No_Passphrase = 19,
- GPGME_Canceled = 20,
- GPGME_Invalid_Key = 21,
- GPGME_Invalid_Engine = 22
+ GPGME_EOF = -1,
+ GPGME_No_Error = 0,
+ GPGME_General_Error = 1,
+ GPGME_Out_Of_Core = 2,
+ GPGME_Invalid_Value = 3,
+ GPGME_Busy = 4,
+ GPGME_No_Request = 5,
+ GPGME_Exec_Error = 6,
+ GPGME_Too_Many_Procs = 7,
+ GPGME_Pipe_Error = 8,
+ GPGME_No_Recipients = 9,
+ GPGME_No_Data = 10,
+ GPGME_Conflict = 11,
+ GPGME_Not_Implemented = 12,
+ GPGME_Read_Error = 13,
+ GPGME_Write_Error = 14,
+ GPGME_Invalid_Type = 15,
+ GPGME_Invalid_Mode = 16,
+ GPGME_File_Error = 17, /* errno is set in this case. */
+ GPGME_Decryption_Failed = 18,
+ GPGME_No_Passphrase = 19,
+ GPGME_Canceled = 20,
+ GPGME_Invalid_Key = 21,
+ GPGME_Invalid_Engine = 22,
+ GPGME_Invalid_Recipients = 23
}
GpgmeError;