core: Allow specifiying a key origin when importing keys

* src/context.h (struct gpgme_context): New field key_origin.
* src/engine-backend.h (struct engine_ops): Add arg key_origin to
field 'import'.
* src/engine-gpg.c (gpg_import): Add arg key_origin and pass option
--key-origin with argument value to gpg. Adjust all callers.
* src/engine-gpgsm.c (gpgsm_import): Add dummy arg key_origin.
* src/gpgme.c (gpgme_release): Free 'key_origin'.
(gpgme_set_ctx_flag, gpgme_get_ctx_flag): New flag "key-origin".

* tests/run-import.c (main): Add option --key-origin.
* tests/gpg/t-import.c (main): Set and verify key origin.
--

This makes the --key-origin option available in the GPGME API for
key imports.

GnuPG-bug-id: 5733
This commit is contained in:
Ingo Klöcker 2021-12-13 16:52:23 +01:00
parent c89226d47f
commit 60880adafa
12 changed files with 81 additions and 8 deletions

3
NEWS
View File

@ -1,11 +1,14 @@
Noteworthy changes in version 1.16.1 (unreleased) Noteworthy changes in version 1.16.1 (unreleased)
------------------------------------------------- -------------------------------------------------
* New context flag "key-origin". [#5733]
* qt: Extend ChangeExpiryJob to change expiration of primary key * qt: Extend ChangeExpiryJob to change expiration of primary key
and of subkeys at the same time. [#4717] and of subkeys at the same time. [#4717]
* Interface changes relative to the 1.16.0 release: * Interface changes relative to the 1.16.0 release:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
gpgme_set_ctx_flag EXTENDED: New flag 'key-origin'.
qt: ChangeExpiryJob::Option NEW. qt: ChangeExpiryJob::Option NEW.
qt: ChangeExpiryJob::Options NEW. qt: ChangeExpiryJob::Options NEW.
qt: ChangeExpiryJob::setOptions NEW. qt: ChangeExpiryJob::setOptions NEW.

View File

@ -3201,6 +3201,11 @@ the expiration time to use for key signature expiration. Valid values
are documented in the GnuPG manual and the gpg man page under are documented in the GnuPG manual and the gpg man page under
the option @option{--default-cert-expire}. the option @option{--default-cert-expire}.
@item "key-origin"
@since{1.16.1}
The string given in @var{value} is passed to the GnuPG engine to set
the origin of imported keys. Valid values are documented in the GnuPG
manual and the gpg man page under the option @option{--key-origin}.
@end table @end table

View File

@ -177,6 +177,9 @@ struct gpgme_context
/* The optional expiration date of a certification. */ /* The optional expiration date of a certification. */
char *cert_expire; char *cert_expire;
/* The optional key origin. */
char *key_origin;
/* The operation data hooked into the context. */ /* The operation data hooked into the context. */
ctx_op_data_t op_data; ctx_op_data_t op_data;

View File

@ -95,7 +95,8 @@ struct engine_ops
unsigned int extraflags, unsigned int extraflags,
gpgme_data_t pubkey, gpgme_data_t seckey); gpgme_data_t pubkey, gpgme_data_t seckey);
gpgme_error_t (*import) (void *engine, gpgme_data_t keydata, gpgme_error_t (*import) (void *engine, gpgme_data_t keydata,
gpgme_key_t *keyarray); gpgme_key_t *keyarray,
const char *key_origin);
gpgme_error_t (*keylist) (void *engine, const char *pattern, gpgme_error_t (*keylist) (void *engine, const char *pattern,
int secret_only, gpgme_keylist_mode_t mode, int secret_only, gpgme_keylist_mode_t mode,
int engine_flags); int engine_flags);

View File

@ -2766,7 +2766,8 @@ string_from_data (gpgme_data_t data, int delim,
static gpgme_error_t static gpgme_error_t
gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray) gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray,
const char *key_origin)
{ {
engine_gpg_t gpg = engine; engine_gpg_t gpg = engine;
gpgme_error_t err; gpgme_error_t err;
@ -2830,6 +2831,12 @@ gpg_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray)
else else
{ {
err = add_arg (gpg, "--import"); err = add_arg (gpg, "--import");
if (!err && key_origin)
{
err = add_arg (gpg, "--key-origin");
if (!err)
err = add_arg (gpg, key_origin);
}
if (!err) if (!err)
err = add_arg (gpg, "--"); err = add_arg (gpg, "--");
if (!err) if (!err)

View File

@ -1696,13 +1696,15 @@ gpgsm_genkey (void *engine,
static gpgme_error_t static gpgme_error_t
gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray) gpgsm_import (void *engine, gpgme_data_t keydata, gpgme_key_t *keyarray, const char *key_origin)
{ {
engine_gpgsm_t gpgsm = engine; engine_gpgsm_t gpgsm = engine;
gpgme_error_t err; gpgme_error_t err;
gpgme_data_encoding_t dataenc; gpgme_data_encoding_t dataenc;
int idx; int idx;
(void)key_origin;
if (!gpgsm) if (!gpgsm)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);

View File

@ -850,7 +850,7 @@ _gpgme_engine_op_tofu_policy (engine_t engine,
gpgme_error_t gpgme_error_t
_gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata, _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
gpgme_key_t *keyarray) gpgme_key_t *keyarray, const char *key_origin)
{ {
if (!engine) if (!engine)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
@ -858,7 +858,7 @@ _gpgme_engine_op_import (engine_t engine, gpgme_data_t keydata,
if (!engine->ops->import) if (!engine->ops->import)
return gpg_error (GPG_ERR_NOT_IMPLEMENTED); return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
return (*engine->ops->import) (engine->engine, keydata, keyarray); return (*engine->ops->import) (engine->engine, keydata, keyarray, key_origin);
} }

View File

@ -141,7 +141,8 @@ gpgme_error_t _gpgme_engine_op_tofu_policy (engine_t engine,
gpgme_tofu_policy_t policy); gpgme_tofu_policy_t policy);
gpgme_error_t _gpgme_engine_op_import (engine_t engine, gpgme_error_t _gpgme_engine_op_import (engine_t engine,
gpgme_data_t keydata, gpgme_data_t keydata,
gpgme_key_t *keyarray); gpgme_key_t *keyarray,
const char *key_origin);
gpgme_error_t _gpgme_engine_op_keylist (engine_t engine, gpgme_error_t _gpgme_engine_op_keylist (engine_t engine,
const char *pattern, const char *pattern,
int secret_only, int secret_only,

View File

@ -254,6 +254,7 @@ gpgme_release (gpgme_ctx_t ctx)
free (ctx->auto_key_locate); free (ctx->auto_key_locate);
free (ctx->trust_model); free (ctx->trust_model);
free (ctx->cert_expire); free (ctx->cert_expire);
free (ctx->key_origin);
_gpgme_engine_info_release (ctx->engine_info); _gpgme_engine_info_release (ctx->engine_info);
ctx->engine_info = NULL; ctx->engine_info = NULL;
DESTROY_LOCK (ctx->lock); DESTROY_LOCK (ctx->lock);
@ -586,6 +587,13 @@ gpgme_set_ctx_flag (gpgme_ctx_t ctx, const char *name, const char *value)
if (!ctx->cert_expire) if (!ctx->cert_expire)
err = gpg_error_from_syserror (); err = gpg_error_from_syserror ();
} }
else if (!strcmp (name, "key-origin"))
{
free (ctx->key_origin);
ctx->key_origin = strdup (value);
if (!ctx->key_origin)
err = gpg_error_from_syserror ();
}
else else
err = gpg_error (GPG_ERR_UNKNOWN_NAME); err = gpg_error (GPG_ERR_UNKNOWN_NAME);
@ -659,6 +667,10 @@ gpgme_get_ctx_flag (gpgme_ctx_t ctx, const char *name)
{ {
return ctx->cert_expire? ctx->cert_expire : ""; return ctx->cert_expire? ctx->cert_expire : "";
} }
else if (!strcmp (name, "key-origin"))
{
return ctx->key_origin? ctx->key_origin : "";
}
else else
return NULL; return NULL;
} }

View File

@ -282,7 +282,7 @@ _gpgme_op_import_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t keydata)
_gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx); _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx);
return _gpgme_engine_op_import (ctx->engine, keydata, NULL); return _gpgme_engine_op_import (ctx->engine, keydata, NULL, ctx->key_origin);
} }
@ -365,7 +365,7 @@ _gpgme_op_import_keys_start (gpgme_ctx_t ctx, int synchronous,
_gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx); _gpgme_engine_set_status_handler (ctx->engine, import_status_handler, ctx);
return _gpgme_engine_op_import (ctx->engine, NULL, keys); return _gpgme_engine_op_import (ctx->engine, NULL, keys, ctx->key_origin);
} }

View File

@ -214,6 +214,7 @@ main (int argc, char *argv[])
gpgme_error_t err; gpgme_error_t err;
gpgme_data_t in; gpgme_data_t in;
gpgme_import_result_t result; gpgme_import_result_t result;
gpgme_key_t key;
char *pubkey_1_asc = make_filename ("pubkey-1.asc"); char *pubkey_1_asc = make_filename ("pubkey-1.asc");
char *seckey_1_asc = make_filename ("seckey-1.asc"); char *seckey_1_asc = make_filename ("seckey-1.asc");
@ -225,6 +226,9 @@ main (int argc, char *argv[])
err = gpgme_new (&ctx); err = gpgme_new (&ctx);
fail_if_err (err); fail_if_err (err);
err = gpgme_set_ctx_flag (ctx, "key-origin", "wkd,https://openpgpkey.gnupg.org");
fail_if_err (err);
err = gpgme_data_new_from_file (&in, pubkey_1_asc, 1); err = gpgme_data_new_from_file (&in, pubkey_1_asc, 1);
free (pubkey_1_asc); free (pubkey_1_asc);
fail_if_err (err); fail_if_err (err);
@ -246,5 +250,24 @@ main (int argc, char *argv[])
gpgme_data_release (in); gpgme_data_release (in);
gpgme_release (ctx); gpgme_release (ctx);
err = gpgme_new (&ctx);
fail_if_err (err);
err = gpgme_get_key (ctx, "0xADAB7FCC1F4DE2616ECFA402AF82244F9CD9FD55", &key, 0);
fail_if_err (err);
if (!key)
{
fprintf (stderr, "Imported key not found\n");
exit (1);
}
if (key->origin != GPGME_KEYORG_WKD)
{
fprintf (stderr, "Key has unexpected origin: %d\n", key->origin);
exit (1);
}
return 0; return 0;
} }

View File

@ -46,6 +46,7 @@ show_usage (int ex)
" --verbose run in verbose mode\n" " --verbose run in verbose mode\n"
" --openpgp use the OpenPGP protocol (default)\n" " --openpgp use the OpenPGP protocol (default)\n"
" --cms use the CMS protocol\n" " --cms use the CMS protocol\n"
" --key-origin use the specified key origin\n"
" --url import from given URLs\n" " --url import from given URLs\n"
" -0 URLs are delimited by a nul\n" " -0 URLs are delimited by a nul\n"
, stderr); , stderr);
@ -63,6 +64,7 @@ main (int argc, char **argv)
gpgme_import_result_t impres; gpgme_import_result_t impres;
gpgme_data_t data; gpgme_data_t data;
gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP;
char *key_origin = NULL;
if (argc) if (argc)
{ argc--; argv++; } { argc--; argv++; }
@ -101,6 +103,14 @@ main (int argc, char **argv)
protocol = GPGME_PROTOCOL_CMS; protocol = GPGME_PROTOCOL_CMS;
argc--; argv++; argc--; argv++;
} }
else if (!strcmp (*argv, "--key-origin"))
{
argc--; argv++;
if (!argc)
show_usage (1);
key_origin = strdup (*argv);
argc--; argv++;
}
else if (!strncmp (*argv, "--", 2)) else if (!strncmp (*argv, "--", 2))
show_usage (1); show_usage (1);
@ -115,6 +125,12 @@ main (int argc, char **argv)
fail_if_err (err); fail_if_err (err);
gpgme_set_protocol (ctx, protocol); gpgme_set_protocol (ctx, protocol);
if (key_origin)
{
err = gpgme_set_ctx_flag (ctx, "key-origin", key_origin);
fail_if_err (err);
}
for (; argc; argc--, argv++) for (; argc; argc--, argv++)
{ {
printf ("reading file `%s'\n", *argv); printf ("reading file `%s'\n", *argv);