aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2017-03-21 18:02:20 +0000
committerWerner Koch <[email protected]>2017-03-21 18:03:58 +0000
commit421ddd1e6706046c5062417fd69a87e10c9fc0a9 (patch)
treea48e37f5fd1c22c2f295c5f63537a8726ab5c9fd
parentpython: Wrap 'gpgme_op_keylist_from_data_start'. (diff)
downloadgpgme-421ddd1e6706046c5062417fd69a87e10c9fc0a9.tar.gz
gpgme-421ddd1e6706046c5062417fd69a87e10c9fc0a9.zip
core: New API gpgme_op_set_uid_flag.
* src/gpgme.h.in (gpgme_op_set_uid_flag_start): New. (gpgme_op_set_uid_flag_start): New. * src/gpgme.def, src/libgpgme.vers: Add them. * src/genkey.c (addrevuid_start): Change arg revoke to a flag. (gpgme_op_revuid_start): Pass GENKEY_EXTRAFLAG_REVOKE for the fomer revoke parameter. (gpgme_op_revuid): Ditto. (set_uid_flag): New. (gpgme_op_set_uid_flag_start): New. (gpgme_op_set_uid_flag): New. * src/engine.h (GENKEY_EXTRAFLAG_SETPRIMARY): new. * src/engine-gpg.c (gpg_adduid): Implement that flag. * tests/run-genkey.c (main): New command --set-primary. -- GnuPG-bug-id: 2931 Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--NEWS6
-rw-r--r--doc/gpgme.texi55
-rw-r--r--src/engine-gpg.c11
-rw-r--r--src/engine.h5
-rw-r--r--src/genkey.c62
-rw-r--r--src/gpgme.def3
-rw-r--r--src/gpgme.h.in7
-rw-r--r--src/libgpgme.vers3
-rw-r--r--tests/run-genkey.c69
9 files changed, 189 insertions, 32 deletions
diff --git a/NEWS b/NEWS
index 16e1550c..367b718f 100644
--- a/NEWS
+++ b/NEWS
@@ -10,10 +10,12 @@ Noteworthy changes in version 1.8.1 (unreleased)
gpgme_op_createkey CHANGED: Meaning of 'expire' parameter.
gpgme_op_createsubkey CHANGED: Meaning of 'expire' parameter.
GPGME_CREATE_NOEXPIRE NEW.
- gpgme_subkey_t EXTENDED: New field is_de_vs.
+ gpgme_subkey_t EXTENDED: New field 'is_de_vs'.
gpgme_op_keylist_from_data_start NEW.
+ gpgme_op_set_uid_flag_start NEW.
+ gpgme_op_set_uid_flag NEW.
GPGME_ENCRYPT_THROW_KEYIDS NEW.
- gpgme_data_rewind UN-DEPRECATE
+ gpgme_data_rewind UN-DEPRECATE.
cpp: Context::revUid(const Key&, const char*) NEW.
cpp: Context::startRevUid(const Key&, const char*) NEW.
cpp: Context::addUid(const Key&, const char*) NEW.
diff --git a/doc/gpgme.texi b/doc/gpgme.texi
index 98462990..fd1f9bc7 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -3897,6 +3897,61 @@ be completed by calling @code{gpgme_wait} on the context.
@c
+@c gpgme_op_set_uid_flag
+@c
+@deftypefun gpgme_error_t gpgme_op_set_ui_flag @
+ (@w{gpgme_ctx_t @var{ctx}}, @
+ @w{gpgme_key_t @var{key}}, @
+ @w{const char *@var{userid}}, @
+ @w{cons char * @var{name}}, @
+ @w{cons char * @var{value}});
+
+The function @code{gpgme_op_set_uid_flag} is used to set flags on a
+user ID from the OpenPGP key given by @var{KEY}. Setting flags on
+user IDs after key creation is a feature of the OpenPGP protocol and
+thus the protocol for the context @var{ctx} must be set to OpenPGP.
+
+@var{key} specifies the key to operate on. This parameters is required.
+
+@var{userid} is the user ID of the key to be manipulated. This user ID
+must be given verbatim because the engine does an exact and case
+sensitive match. Thus the @code{uid} field from the user ID object
+(@code{gpgme_user_id_t}) is to be used. This is a required parameter.
+
+@var{name} names the flag which is to be changed. The only currently
+supported flag is:
+
+@table @code
+@item primary
+This sets the primary key flag on the given user ID. All other
+primary key flag on other user IDs are removed. @var{value} must be
+given as NULL. For technical reasons this functions bumps the
+creation timestamp of all affected self-signatures up by one second.
+At least GnuPG version 2.1.20 is required.
+
+@end table
+
+The function returns zero on success, @code{GPG_ERR_NOT_SUPPORTED} if
+the engine does not support the command, or a bunch of other error
+codes.
+
+@end deftypefun
+
+@deftypefun gpgme_error_t gpgme_op_set_uid_flag_start @
+ (@w{gpgme_ctx_t @var{ctx}}, @
+ @w{gpgme_key_t @var{key}}, @
+ @w{const char *@var{userid}}, @
+ @w{cons char * @var{name}}, @
+ @w{cons char * @var{value}});
+
+The function @code{gpgme_op_set_uid_flag_start} initiates a
+@code{gpgme_op_set_uid_flag} operation; see there for details. It must
+be completed by calling @code{gpgme_wait} on the context.
+@xref{Waiting For Completion}.
+
+@end deftypefun
+
+@c
@c gpgme_op_genkey
@c
@deftypefun gpgme_error_t gpgme_op_genkey @
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 6024529b..6e4b8339 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -2222,7 +2222,14 @@ gpg_adduid (engine_gpg_t gpg,
if (!key || !key->fpr || !userid)
return gpg_error (GPG_ERR_INV_ARG);
- if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
+ if ((extraflags & GENKEY_EXTRAFLAG_SETPRIMARY))
+ {
+ if (!have_gpg_version (gpg, "2.1.20"))
+ err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+ else
+ err = add_arg (gpg, "--quick-set-primary-uid");
+ }
+ else if ((extraflags & GENKEY_EXTRAFLAG_REVOKE))
err = add_arg (gpg, "--quick-revuid");
else
err = add_arg (gpg, "--quick-adduid");
@@ -2262,7 +2269,7 @@ gpg_genkey (void *engine,
* USERID && !KEY - Create a new keyblock.
* !USERID && KEY - Add a new subkey to KEY (gpg >= 2.1.14)
* USERID && KEY && !ALGO - Add a new user id to KEY (gpg >= 2.1.14).
- *
+ * or set a flag on a user id.
*/
if (help_data)
{
diff --git a/src/engine.h b/src/engine.h
index f456812e..1064f5ed 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -25,8 +25,9 @@
#include "gpgme.h"
/* Flags used by the EXTRAFLAGS arg of _gpgme_engine_op_genkey. */
-#define GENKEY_EXTRAFLAG_ARMOR 1
-#define GENKEY_EXTRAFLAG_REVOKE 2
+#define GENKEY_EXTRAFLAG_ARMOR 1
+#define GENKEY_EXTRAFLAG_REVOKE 2
+#define GENKEY_EXTRAFLAG_SETPRIMARY 4
struct engine;
diff --git a/src/genkey.c b/src/genkey.c
index ea3f1ea4..710b58ff 100644
--- a/src/genkey.c
+++ b/src/genkey.c
@@ -489,7 +489,7 @@ gpgme_op_createsubkey (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,
static gpgme_error_t
-addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
+addrevuid_start (gpgme_ctx_t ctx, int synchronous, int extraflags,
gpgme_key_t key, const char *userid, unsigned int flags)
{
gpgme_error_t err;
@@ -512,7 +512,7 @@ addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
if (err)
return err;
- opd->uidmode = revoke? 2 : 1;
+ opd->uidmode = extraflags? 2 : 1;
_gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
@@ -528,7 +528,7 @@ addrevuid_start (gpgme_ctx_t ctx, int synchronous, int revoke,
userid, NULL, 0, 0,
key, flags,
NULL,
- revoke? GENKEY_EXTRAFLAG_REVOKE : 0,
+ extraflags,
NULL, NULL);
}
@@ -584,7 +584,7 @@ gpgme_op_revuid_start (gpgme_ctx_t ctx,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
- err = addrevuid_start (ctx, 0, 1, key, userid, flags);
+ err = addrevuid_start (ctx, 0, GENKEY_EXTRAFLAG_REVOKE, key, userid, flags);
return TRACE_ERR (err);
}
@@ -601,8 +601,60 @@ gpgme_op_revuid (gpgme_ctx_t ctx,
if (!ctx)
return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
- err = addrevuid_start (ctx, 1, 1, key, userid, flags);
+ err = addrevuid_start (ctx, 1, GENKEY_EXTRAFLAG_REVOKE, key, userid, flags);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
}
+
+
+/* Set a flag on the USERID of KEY. The only supported flag right now
+ * is "primary" to mark the primary key. */
+static gpg_error_t
+set_uid_flag (gpgme_ctx_t ctx, int synchronous,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG4 (DEBUG_CTX, "gpgme_op_set_uid_flag", ctx,
+ "%d uid='%s' '%s'='%s'", synchronous, userid, name, value);
+
+ if (!ctx || !name || !key || !userid)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
+
+ if (!strcmp (name, "primary"))
+ {
+ if (value)
+ err = gpg_error (GPG_ERR_INV_ARG);
+ else
+ err = addrevuid_start (ctx, synchronous,
+ GENKEY_EXTRAFLAG_SETPRIMARY, key, userid, 0);
+ }
+ else
+ return err = gpg_error (GPG_ERR_UNKNOWN_NAME);
+
+ if (synchronous && !err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
+
+
+/* See set_uid_flag. */
+gpgme_error_t
+gpgme_op_set_uid_flag_start (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ return set_uid_flag (ctx, 0, key, userid, name, value);
+}
+
+
+/* See set_uid_flag. Thsi is the synchronous variant. */
+gpgme_error_t
+gpgme_op_set_uid_flag (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value)
+{
+ return set_uid_flag (ctx, 1, key, userid, name, value);
+}
diff --git a/src/gpgme.def b/src/gpgme.def
index ddd57d35..9faffb85 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -256,5 +256,8 @@ EXPORTS
gpgme_op_keylist_from_data_start @192
+ gpgme_op_set_uid_flag_start @193
+ gpgme_op_set_uid_flag @194
+
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 16191ebc..e9ee6e2f 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1726,6 +1726,13 @@ gpgme_error_t gpgme_op_revuid (gpgme_ctx_t ctx,
gpgme_key_t key, const char *userid,
unsigned int reserved);
+/* Set a flag on the USERID of KEY. See the manual for supported flags. */
+gpgme_error_t gpgme_op_set_uid_flag_start (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value);
+gpgme_error_t gpgme_op_set_uid_flag (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ const char *name, const char *value);
/* Retrieve a pointer to the result of a genkey, createkey, or
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index 9344a752..037a6ae2 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -126,6 +126,9 @@ GPGME_1.1 {
gpgme_op_query_swdb;
gpgme_op_query_swdb_result;
+
+ gpgme_op_set_uid_flag_start;
+ gpgme_op_set_uid_flag;
};
diff --git a/tests/run-genkey.c b/tests/run-genkey.c
index c5abc423..91edb222 100644
--- a/tests/run-genkey.c
+++ b/tests/run-genkey.c
@@ -204,10 +204,12 @@ show_usage (int ex)
" for addkey: FPR [ALGO [USAGE [EXPIRESECONDS]]]\n"
" for adduid: FPR USERID\n"
" for revuid: FPR USERID\n"
+ " for set-primary: FPR USERID\n"
"Options:\n"
" --addkey add a subkey to the key with FPR\n"
" --adduid add a user id to the key with FPR\n"
- " --revuid Revoke a user id from the key with FPR\n"
+ " --revuid revoke a user id from the key with FPR\n"
+ " --set-primary set the primary key flag on USERID\n"
" --verbose run in verbose mode\n"
" --status print status lines from the backend\n"
" --progress print progress info\n"
@@ -234,6 +236,7 @@ main (int argc, char **argv)
int addkey = 0;
int adduid = 0;
int revuid = 0;
+ int setpri = 0;
const char *userid;
const char *algo = NULL;
const char *newuserid = NULL;
@@ -259,6 +262,7 @@ main (int argc, char **argv)
addkey = 1;
adduid = 0;
revuid = 0;
+ setpri = 0;
argc--; argv++;
}
else if (!strcmp (*argv, "--adduid"))
@@ -266,6 +270,7 @@ main (int argc, char **argv)
addkey = 0;
adduid = 1;
revuid = 0;
+ setpri = 0;
argc--; argv++;
}
else if (!strcmp (*argv, "--revuid"))
@@ -273,6 +278,15 @@ main (int argc, char **argv)
addkey = 0;
adduid = 0;
revuid = 1;
+ setpri = 0;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--set-primary"))
+ {
+ addkey = 0;
+ adduid = 0;
+ revuid = 0;
+ setpri = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--verbose"))
@@ -319,7 +333,7 @@ main (int argc, char **argv)
show_usage (1);
}
- if (adduid || revuid)
+ if (adduid || revuid || setpri)
{
if (argc != 2)
show_usage (1);
@@ -358,7 +372,7 @@ main (int argc, char **argv)
gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
}
- if (addkey || adduid || revuid)
+ if (addkey || adduid || revuid || setpri)
{
gpgme_key_t akey;
@@ -400,6 +414,16 @@ main (int argc, char **argv)
exit (1);
}
}
+ else if (setpri)
+ {
+ err = gpgme_op_set_uid_flag (ctx, akey, newuserid, "primary", NULL);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gpgme_op_set_uid_flag failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
gpgme_key_unref (akey);
}
else
@@ -413,26 +437,29 @@ main (int argc, char **argv)
}
}
- result = gpgme_op_genkey_result (ctx);
- if (!result)
+ if (!setpri)
{
- fprintf (stderr, PGM": gpgme_op_genkey_result returned NULL\n");
- exit (1);
- }
+ result = gpgme_op_genkey_result (ctx);
+ if (!result)
+ {
+ fprintf (stderr, PGM": gpgme_op_genkey_result returned NULL\n");
+ exit (1);
+ }
- printf ("Generated key: %s (%s)\n",
- result->fpr ? result->fpr : "none",
- result->primary ? (result->sub ? "primary, sub" : "primary")
- /**/ : (result->sub ? "sub" : "none"));
-
- if (result->fpr && strlen (result->fpr) < 40)
- fprintf (stderr, PGM": generated key has unexpected fingerprint\n");
- if (!result->primary)
- fprintf (stderr, PGM": primary key was not generated\n");
- if (!result->sub)
- fprintf (stderr, PGM": sub key was not generated\n");
- if (!result->uid)
- fprintf (stderr, PGM": uid was not generated\n");
+ printf ("Generated key: %s (%s)\n",
+ result->fpr ? result->fpr : "none",
+ result->primary ? (result->sub ? "primary, sub" : "primary")
+ /**/ : (result->sub ? "sub" : "none"));
+
+ if (result->fpr && strlen (result->fpr) < 40)
+ fprintf (stderr, PGM": generated key has unexpected fingerprint\n");
+ if (!result->primary)
+ fprintf (stderr, PGM": primary key was not generated\n");
+ if (!result->sub)
+ fprintf (stderr, PGM": sub key was not generated\n");
+ if (!result->uid)
+ fprintf (stderr, PGM": uid was not generated\n");
+ }
gpgme_release (ctx);
return 0;