+ * 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.
+
* New interfaces gpgme_set_include_certs and gpgme_get_include_certs
to set and get the number of certifications to include in S/MIME
signed messages.
* 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.
+ * New interface gpgme_op_keylist_ext_start to search for multiple patterns.
* Interface changes relative to the 0.3.3 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_get_include_certs NEW
gpgme_op_encrypt_sign NEW
gpgme_op_encrypt_sign_start NEW
+gpgme_op_keylist_ext_start NEW
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Noteworthy changes in version 0.3.3 (2002-02-12)
get GPGME_No_Passphrase." Bug reported by Stephane Corthesy.
* Tests
- Write a fake gpg-agent so that we can supply known passphrases to
- gpgsm and setup the configuration files to use the agent. Without
- this we are testing a currently running gpg-agent which is not a
- clever idea.
+** Write a fake gpg-agent so that we can supply known passphrases to
+ gpgsm and setup the configuration files to use the agent. Without
+ this we are testing a currently running gpg-agent which is not a
+ clever idea.
** t-data
*** Test gpgme_data_release_and_get_mem.
*** Test gpgme_data_rewind for invalid types.
* Build suite
** Make sure everything is cleaned correctly (esp. test area).
-** There is a spurious 4/10 tests failed in some conditions.
- Rebuilding from scratch works around that.
* Architecture support
** Implement posix-sema.c
+2002-02-27 Marcus Brinkmann <marcus@g10code.de>
+
+ * gpgme.texi (Listing Keys): Document gpgme_op_keylist_ext_start.
+
2002-02-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.texi (Encrypting a Plaintext): Document
crypto engine support routines.
@end deftypefun
+@deftypefun GpgmeError gpgme_op_keylist_ext_start (@w{GpgmeCtx @var{ctx}}, @w{const char *@var{pattern}[]}, @w{int @var{secret_only}}, @w{int @var{reserved}})
+The function @code{gpgme_op_keylist_ext_start} initiates an extended
+key listing operation inside the context @var{ctx}. It sets
+everything up so that subsequent invocations of
+@code{gpgme_op_keylist_next} return the keys in the list.
+
+If @var{pattern} or @var{*pattern} is @code{NULL}, all available keys
+are returned. Otherwise, @var{pattern} is a @code{NULL} terminated
+array of strings that are used to limit the list to all keys matching
+at least one of the patterns verbatim.
+
+If @var{secret_only} is not @code{0}, the list is restricted to secret
+keys only.
+
+The value of @var{reserved} must be @code{0}.
+
+The context will be busy until either all keys are received (and
+@code{gpgme_op_keylist_next} returns @code{GPGME_EOF}), or
+@code{gpgme_op_keylist_end} is called to finish the operation.
+
+The function returns @code{GPGME_Invalid_Value} if @var{ctx} is not a
+valid pointer, and passes through any errors that are reported by the
+crypto engine support routines.
+@end deftypefun
+
@deftypefun GpgmeError gpgme_op_keylist_next (@w{GpgmeCtx @var{ctx}}, @w{GpgmeKey *@var{r_key}})
The function @code{gpgme_op_keylist_next} returns the next key in the
list created by a previous @code{gpgme_op_keylist_start} operation in
+2002-02-27 Marcus Brinkmann <marcus@g10code.de>
+
+ * rungpg.h (_gpgme_gpg_op_keylist_ext): New prototype.
+ * rungpg.c (_gpgme_gpg_op_keylist_ext): New function.
+ * engine-gpgsm.h (_gpgme_gpgsm_op_keylist_ext): New prototype.
+ * engine-gpgsm.c (_gpgme_gpgsm_op_keylist_ext): New function.
+ * engine.h (_gpgme_engine_op_keylist_ext): New prototype.
+ * engine.c (_gpgme_engine_op_keylist_ext): New function.
+ * keylist.c (gpgme_op_keylist_ext_start): New function.
+
2002-02-27 Marcus Brinkmann <marcus@g10code.de>
* gpgme.h: Add new error code GPGME_Invalid_Recipient.
}
+GpgmeError
+_gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, const char *pattern[],
+ int secret_only, int reserved, int keylist_mode)
+{
+ char *line;
+ /* Length is "LISTSECRETKEYS " + p + '\0'. */
+ int length = 15 + 1;
+ char *linep;
+
+ if (reserved)
+ return mk_error (Invalid_Value);
+
+ if (pattern && *pattern)
+ {
+ const char **pat = pattern;
+
+ while (*pat)
+ {
+ const char *patlet = *pat;
+
+ while (*patlet)
+ {
+ length++;
+ if (*patlet == '%' || *patlet == ' ' || *patlet == '+')
+ length += 2;
+ patlet++;
+ }
+ pat++;
+ /* This will allocate one byte more than necessary. */
+ length++;
+ }
+ }
+ line = xtrymalloc (length);
+ if (!line)
+ return mk_error (Out_Of_Core);
+ if (secret_only)
+ {
+ strcpy (line, "LISTSECRETKEYS ");
+ linep = &line[15];
+ }
+ else
+ {
+ strcpy (line, "LISTKEYS ");
+ linep = &line[9];
+ }
+
+ if (pattern && *pattern)
+ {
+ while (*pattern)
+ {
+ const char *patlet = *pattern;
+
+ while (*patlet)
+ {
+ switch (*patlet)
+ {
+ case '%':
+ *(linep++) = '%';
+ *(linep++) = '2';
+ *(linep++) = '5';
+ break;
+ case ' ':
+ *(linep++) = '%';
+ *(linep++) = '2';
+ *(linep++) = '0';
+ break;
+ case '+':
+ *(linep++) = '%';
+ *(linep++) = '2';
+ *(linep++) = 'B';
+ break;
+ default:
+ *(linep++) = *patlet;
+ break;
+ }
+ patlet++;
+ }
+ pattern++;
+ }
+ }
+ *linep = '\0';
+
+ _gpgme_io_close (gpgsm->input_fd);
+ _gpgme_io_close (gpgsm->output_fd);
+ _gpgme_io_close (gpgsm->message_fd);
+
+ gpgsm->command = line;
+ return 0;
+}
+
+
GpgmeError
_gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor,
GpgmeError _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata);
GpgmeError _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
int secret_only, int keylist_mode);
+GpgmeError _gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm,
+ const char *pattern[],
+ int secret_only, int reserved,
+ int keylist_mode);
GpgmeError _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in,
GpgmeData out,
GpgmeSigMode mode, int use_armor,
return 0;
}
+
GpgmeError
-_gpgme_engine_op_keylist (EngineObject engine, const char *pattern, int secret_only,
- int keylist_mode)
+_gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
+ int secret_only, int keylist_mode)
{
if (!engine)
return mk_error (Invalid_Value);
return 0;
}
+
+GpgmeError
+_gpgme_engine_op_keylist_ext (EngineObject engine, const char *pattern[],
+ int secret_only, int reserved, int keylist_mode)
+{
+ if (!engine)
+ return mk_error (Invalid_Value);
+
+ switch (engine->protocol)
+ {
+ case GPGME_PROTOCOL_OpenPGP:
+ return _gpgme_gpg_op_keylist_ext (engine->engine.gpg, pattern,
+ secret_only, reserved, keylist_mode);
+ case GPGME_PROTOCOL_CMS:
+ return _gpgme_gpgsm_op_keylist_ext (engine->engine.gpgsm, pattern,
+ secret_only, reserved, keylist_mode);
+ default:
+ break;
+ }
+ return 0;
+}
+
+
GpgmeError
_gpgme_engine_op_sign (EngineObject engine, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor,
GpgmeError _gpgme_engine_op_keylist (EngineObject engine, const char *pattern,
int secret_only,
int keylist_mode);
+GpgmeError _gpgme_engine_op_keylist_ext (EngineObject engine,
+ const char *pattern[],
+ int secret_only,
+ int reserved,
+ int keylist_mode);
GpgmeError _gpgme_engine_op_sign (EngineObject engine, GpgmeData in,
GpgmeData out, GpgmeSigMode mode,
int use_armor, int use_textmode,
}
+/**
+ * gpgme_op_keylist_ext_start:
+ * @c: context
+ * @pattern: a NULL terminated array of search patterns
+ * @secret_only: List only keys where the secret part is available
+ * @reserved: Should be 0.
+ *
+ * Note that this function also cancels a pending key listing
+ * operaton. To actually retrieve the key, use
+ * gpgme_op_keylist_next().
+ *
+ * Return value: 0 on success or an errorcode.
+ **/
+GpgmeError
+gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],
+ int secret_only, int reserved)
+{
+ GpgmeError err = 0;
+
+ if (!ctx)
+ return mk_error (Invalid_Value);
+ ctx->pending = 1;
+
+ _gpgme_release_result (ctx);
+
+ if (ctx->engine)
+ {
+ _gpgme_engine_release (ctx->engine);
+ ctx->engine = NULL;
+ }
+ gpgme_key_release (ctx->tmp_key);
+ ctx->tmp_key = NULL;
+ /* Fixme: Release key_queue. */
+
+ err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
+ : GPGME_PROTOCOL_OpenPGP, &ctx->engine);
+ if (err)
+ goto leave;
+
+ _gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
+ err = _gpgme_engine_set_colon_line_handler (ctx->engine,
+ keylist_colon_handler, ctx);
+ if (err)
+ goto leave;
+
+ /* We don't want to use the verbose mode as this will also print
+ the key signatures which is in most cases not needed and furthermore we
+ just ignore those lines - This should speed up things */
+ _gpgme_engine_set_verbosity (ctx->engine, 0);
+
+ err = _gpgme_engine_op_keylist_ext (ctx->engine, pattern, secret_only,
+ reserved, ctx->keylist_mode);
+
+ if (!err) /* And kick off the process. */
+ err = _gpgme_engine_start (ctx->engine, ctx);
+
+ leave:
+ if (err)
+ {
+ ctx->pending = 0;
+ _gpgme_engine_release (ctx->engine);
+ ctx->engine = NULL;
+ }
+ return err;
+}
+
+
/**
* gpgme_op_keylist_next:
* @c: Context
return err;
}
+
GpgmeError
_gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern, int secret_only,
int keylist_mode)
return err;
}
+
+GpgmeError
+_gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[],
+ int secret_only, int reserved, int keylist_mode)
+{
+ GpgmeError err;
+
+ if (reserved)
+ return mk_error (Invalid_Value);
+
+ err = _gpgme_gpg_add_arg (gpg, "--with-colons");
+ if (!err)
+ err = _gpgme_gpg_add_arg (gpg, "--fixed-list-mode");
+ if (!err)
+ err = _gpgme_gpg_add_arg (gpg, "--with-fingerprint");
+ if (!err)
+ err = _gpgme_gpg_add_arg (gpg, secret_only ? "--list-secret-keys"
+ : "--list-keys");
+
+ /* Tell the gpg object about the data */
+ if (!err)
+ err = _gpgme_gpg_add_arg (gpg, "--");
+ if (!err && pattern && *pattern)
+ {
+ while (*pattern)
+ err = _gpgme_gpg_add_arg (gpg, *(pattern++));
+ }
+
+ return err;
+}
+
+
GpgmeError
_gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor,
GpgmeError _gpgme_gpg_op_import (GpgObject gpg, GpgmeData keydata);
GpgmeError _gpgme_gpg_op_keylist (GpgObject gpg, const char *pattern,
int secret_only, int keylist_mode);
+GpgmeError _gpgme_gpg_op_keylist_ext (GpgObject gpg, const char *pattern[],
+ int secret_only, int reserved,
+ int keylist_mode);
GpgmeError _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
GpgmeSigMode mode, int use_armor,
int use_textmode, GpgmeCtx ctx /* FIXME */);