Index: b/src/engine-assuan.c =================================================================== --- b/src/engine-assuan.c +++ b/src/engine-assuan.c @@ -787,6 +787,7 @@ NULL, /* import */ NULL, /* keylist */ NULL, /* keylist_ext */ + NULL, /* keylist_data */ NULL, /* keysign */ NULL, /* tofu_policy */ NULL, /* sign */ Index: b/src/engine-backend.h =================================================================== --- b/src/engine-backend.h +++ b/src/engine-backend.h @@ -98,6 +98,7 @@ int secret_only, int reserved, gpgme_keylist_mode_t mode, int engine_flags); + gpgme_error_t (*keylist_data) (void *engine, gpgme_data_t data); gpgme_error_t (*keysign) (void *engine, gpgme_key_t key, const char *userid, unsigned long expires, unsigned int flags, Index: b/src/engine-g13.c =================================================================== --- b/src/engine-g13.c +++ b/src/engine-g13.c @@ -802,6 +802,7 @@ NULL, /* import */ NULL, /* keylist */ NULL, /* keylist_ext */ + NULL, /* keylist_data */ NULL, /* keysign */ NULL, /* tofu_policy */ NULL, /* sign */ Index: b/src/engine-gpg.c =================================================================== --- b/src/engine-gpg.c +++ b/src/engine-gpg.c @@ -2658,6 +2658,38 @@ static gpgme_error_t +gpg_keylist_data (void *engine, gpgme_data_t data) +{ + engine_gpg_t gpg = engine; + gpgme_error_t err; + + if (!have_gpg_version (gpg, "2.1.14")) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + err = add_arg (gpg, "--with-colons"); + if (!err) + err = add_arg (gpg, "--with-fingerprint"); + if (!err) + err = add_arg (gpg, "--import-options"); + if (!err) + err = add_arg (gpg, "import-show"); + if (!err) + err = add_arg (gpg, "--dry-run"); + if (!err) + err = add_arg (gpg, "--import"); + if (!err) + err = add_arg (gpg, "--"); + if (!err) + err = add_data (gpg, data, -1, 0); + + if (!err) + err = start (gpg); + + return err; +} + + +static gpgme_error_t gpg_keysign (void *engine, gpgme_key_t key, const char *userid, unsigned long expire, unsigned int flags, gpgme_ctx_t ctx) @@ -2935,6 +2967,7 @@ gpg_import, gpg_keylist, gpg_keylist_ext, + gpg_keylist_data, gpg_keysign, gpg_tofu_policy, /* tofu_policy */ gpg_sign, Index: b/src/engine-gpgconf.c =================================================================== --- b/src/engine-gpgconf.c +++ b/src/engine-gpgconf.c @@ -957,6 +957,7 @@ NULL, /* import */ NULL, /* keylist */ NULL, /* keylist_ext */ + NULL, /* keylist_data */ NULL, /* keysign */ NULL, /* tofu_policy */ NULL, /* sign */ Index: b/src/engine-gpgsm.c =================================================================== --- b/src/engine-gpgsm.c +++ b/src/engine-gpgsm.c @@ -2090,6 +2090,7 @@ gpgsm_import, gpgsm_keylist, gpgsm_keylist_ext, + NULL, /* keylist_data */ NULL, /* keysign */ NULL, /* tofu_policy */ gpgsm_sign, Index: b/src/engine-spawn.c =================================================================== --- b/src/engine-spawn.c +++ b/src/engine-spawn.c @@ -460,6 +460,7 @@ NULL, /* import */ NULL, /* keylist */ NULL, /* keylist_ext */ + NULL, /* keylist_data */ NULL, /* keysign */ NULL, /* tofu_policy */ NULL, /* sign */ Index: b/src/engine-uiserver.c =================================================================== --- b/src/engine-uiserver.c +++ b/src/engine-uiserver.c @@ -1381,6 +1381,7 @@ NULL, /* import */ NULL, /* keylist */ NULL, /* keylist_ext */ + NULL, /* keylist_data */ NULL, /* keysign */ NULL, /* tofu_policy */ uiserver_sign, Index: b/src/engine.h =================================================================== --- b/src/engine.h +++ b/src/engine.h @@ -143,6 +143,8 @@ int reserved, gpgme_keylist_mode_t mode, int engine_flags); +gpgme_error_t _gpgme_engine_op_keylist_data (engine_t engine, + gpgme_data_t data); gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out, gpgme_sig_mode_t mode, int use_armor, int use_textmode, Index: b/src/engine.c =================================================================== --- b/src/engine.c +++ b/src/engine.c @@ -871,6 +871,19 @@ gpgme_error_t +_gpgme_engine_op_keylist_data (engine_t engine, gpgme_data_t data) +{ + if (!engine) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!engine->ops->keylist_data) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + return (*engine->ops->keylist_data) (engine->engine, data); +} + + +gpgme_error_t _gpgme_engine_op_sign (engine_t engine, gpgme_data_t in, gpgme_data_t out, gpgme_sig_mode_t mode, int use_armor, int use_textmode, int include_certs, Index: b/src/gpgme.h.in =================================================================== --- b/src/gpgme.h.in +++ b/src/gpgme.h.in @@ -2028,6 +2028,11 @@ const char *pattern[], int secret_only, int reserved); +/* List the keys contained in the data DATA. + The keylist mode is ignored. */ +gpgme_error_t gpgme_op_keylist_from_data_start (gpgme_ctx_t ctx, + gpgme_data_t data); + /* Return the next key from the keylist in R_KEY. */ gpgme_error_t gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key); Index: b/src/gpgme.def =================================================================== --- b/src/gpgme.def +++ b/src/gpgme.def @@ -246,5 +246,7 @@ gpgme_addrspec_from_uid @186 + gpgme_op_keylist_from_data_start @187 + ; END Index: b/src/keylist.c =================================================================== --- b/src/keylist.c +++ b/src/keylist.c @@ -1107,6 +1107,41 @@ } +/* Start a keylist operation within CTX to show keys contained + in the data DATA. */ +gpgme_error_t +gpgme_op_keylist_from_data_start (gpgme_ctx_t ctx, gpgme_data_t data) +{ + gpgme_error_t err; + void *hook; + op_data_t opd; + + TRACE_BEG (DEBUG_CTX, "gpgme_op_keylist_from_data_start", ctx); + + if (!ctx || !data) + return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); + + err = _gpgme_op_reset (ctx, 2); + if (err) + return TRACE_ERR (err); + + err = _gpgme_op_data_lookup (ctx, OPDATA_KEYLIST, &hook, + sizeof (*opd), release_op_data); + opd = hook; + if (err) + return TRACE_ERR (err); + + _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) + return TRACE_ERR (err); + + err = _gpgme_engine_op_keylist_data (ctx->engine, data); + return TRACE_ERR (err); +} + + /* Return the next key from the keylist in R_KEY. */ gpgme_error_t gpgme_op_keylist_next (gpgme_ctx_t ctx, gpgme_key_t *r_key) Index: b/src/libgpgme.vers =================================================================== --- b/src/libgpgme.vers +++ b/src/libgpgme.vers @@ -216,6 +216,7 @@ gpgme_op_import_start; gpgme_op_keylist_end; gpgme_op_keylist_ext_start; + gpgme_op_keylist_from_data_start; gpgme_op_keylist_next; gpgme_op_keylist_result; gpgme_op_keylist_start;