aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2016-09-14 09:40:34 +0000
committerWerner Koch <[email protected]>2016-09-14 09:40:34 +0000
commit3210f3e4725afc5ee2810b9a1361918ec9c42ca4 (patch)
tree742cdfee9596708ce838d88ca47236162821817e
parentcore: New function gpgme_op_createsubkey. (diff)
downloadgpgme-3210f3e4725afc5ee2810b9a1361918ec9c42ca4.tar.gz
gpgme-3210f3e4725afc5ee2810b9a1361918ec9c42ca4.zip
core: New function gpgme_op_adduid.
* src/genkey.c: Replace most error codes GPG_ERR_INV_VALUE by GPG_ERR_INV_ARG. (struct op_data_t): Add field UIDMODE. (genkey_status_handler): Use UIDMODE. (adduid_start): New. (gpgme_op_adduid_start, gpgme_op_adduid): New. * src/gpgme.def, src/libgpgme.vers: Add them. * tests/run-genkey.c: Add option --adduid. Signed-off-by: Werner Koch <[email protected]>
-rw-r--r--NEWS2
-rw-r--r--src/engine-gpg.c24
-rw-r--r--src/genkey.c110
-rw-r--r--src/gpgme.def2
-rw-r--r--src/gpgme.h.in13
-rw-r--r--src/libgpgme.vers2
-rw-r--r--tests/run-genkey.c72
7 files changed, 192 insertions, 33 deletions
diff --git a/NEWS b/NEWS
index 9445f7f9..621ce3ff 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,8 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_]
gpgme_op_createkey_start NEW.
gpgme_op_createsubkey NEW.
gpgme_op_createsubkey_start NEW.
+ gpgme_op_adduid_start NEW.
+ gpgme_op_adduid NEW.
gpgme_genkey_result_t EXTENDED: New fields pubkey and seckey.
gpgme_signature_t EXTENDED: New field key.
gpgme_key_t EXTENDED: New field fpr.
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index 5a16f805..d2b6dd34 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -2114,11 +2114,25 @@ gpg_addkey (engine_gpg_t gpg,
static gpgme_error_t
gpg_adduid (engine_gpg_t gpg,
- const char *userid,
- unsigned int flags,
- int use_armor)
+ gpgme_key_t key,
+ const char *userid)
{
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ gpgme_error_t err;
+
+ if (!key || !key->fpr || !userid)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ err = add_arg (gpg, "--quick-adduid");
+ if (!err)
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_arg (gpg, key->fpr);
+ if (!err)
+ err = add_arg (gpg, userid);
+
+ if (!err)
+ err = start (gpg);
+ return err;
}
@@ -2170,7 +2184,7 @@ gpg_genkey (void *engine,
else if (!userid && key)
err = gpg_addkey (gpg, algo, expires, key, flags, use_armor);
else if (userid && key && !algo)
- err = gpg_adduid (gpg, userid, flags, use_armor);
+ err = gpg_adduid (gpg, key, userid);
else
err = gpg_error (GPG_ERR_INV_VALUE);
diff --git a/src/genkey.c b/src/genkey.c
index 26bcca6e..b93abb80 100644
--- a/src/genkey.c
+++ b/src/genkey.c
@@ -42,6 +42,9 @@ typedef struct
/* The error code from certain ERROR status lines or 0. */
gpg_error_t error_code;
+ /* Flag to indicate that a UID is to be added. */
+ gpg_error_t uidmode;
+
/* The key parameters passed to the crypto engine. */
gpgme_data_t key_parameter;
} *op_data_t;
@@ -142,7 +145,10 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
if (args && *args)
{
if (*args == 'B' || *args == 'P')
- opd->result.primary = 1;
+ {
+ opd->result.primary = 1;
+ opd->result.uid = 1;
+ }
if (*args == 'B' || *args == 'S')
opd->result.sub = 1;
if (args[1] == ' ')
@@ -171,10 +177,12 @@ genkey_status_handler (void *priv, gpgme_status_code_t code, char *args)
case GPGME_STATUS_EOF:
if (opd->error_code)
return opd->error_code;
- else if (!opd->result.primary && !opd->result.sub)
+ else if (!opd->uidmode && !opd->result.primary && !opd->result.sub)
return gpg_error (GPG_ERR_GENERAL);
else if (opd->failure_code)
return opd->failure_code;
+ else if (opd->uidmode)
+ opd->result.uid = 1; /* We have no status line, thus this hack. */
break;
case GPGME_STATUS_INQUIRE_MAXLEN:
@@ -277,7 +285,7 @@ gpgme_op_genkey_start (gpgme_ctx_t ctx, const char *parms,
TRACE_LOGBUF (parms, strlen (parms));
if (!ctx)
- return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
err = genkey_start (ctx, 0, parms, pubkey, seckey);
return TRACE_ERR (err);
@@ -298,7 +306,7 @@ gpgme_op_genkey (gpgme_ctx_t ctx, const char *parms, gpgme_data_t pubkey,
TRACE_LOGBUF (parms, strlen (parms));
if (!ctx)
- return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
err = genkey_start (ctx, 1, parms, pubkey, seckey);
if (!err)
@@ -323,7 +331,7 @@ createkey_start (gpgme_ctx_t ctx, int synchronous,
return err;
if (reserved || anchorkey || !userid)
- return gpg_error (GPG_ERR_INV_VALUE);
+ return gpg_error (GPG_ERR_INV_ARG);
err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,
sizeof (*opd), release_op_data);
@@ -360,7 +368,7 @@ gpgme_op_createkey_start (gpgme_ctx_t ctx, const char *userid, const char *algo,
"userid='%s', algo='%s' flags=0x%x", userid, algo, flags);
if (!ctx)
- return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
err = createkey_start (ctx, 0,
userid, algo, reserved, expires, anchorkey, flags);
@@ -379,7 +387,7 @@ gpgme_op_createkey (gpgme_ctx_t ctx, const char *userid, const char *algo,
"userid='%s', algo='%s' flags=0x%x", userid, algo, flags);
if (!ctx)
- return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
err = createkey_start (ctx, 1,
userid, algo, reserved, expires, anchorkey, flags);
@@ -409,7 +417,7 @@ createsubkey_start (gpgme_ctx_t ctx, int synchronous,
return err;
if (reserved || !key)
- return gpg_error (GPG_ERR_INV_VALUE);
+ return gpg_error (GPG_ERR_INV_ARG);
err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,
sizeof (*opd), release_op_data);
@@ -447,7 +455,7 @@ gpgme_op_createsubkey_start (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,
"key=%p, algo='%s' flags=0x%x", key, algo, flags);
if (!ctx)
- return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
err = createsubkey_start (ctx, 0, key, algo, reserved, expires, flags);
return TRACE_ERR (err);
@@ -465,10 +473,92 @@ gpgme_op_createsubkey (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,
"key=%p, algo='%s' flags=0x%x", key, algo, flags);
if (!ctx)
- return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
err = createsubkey_start (ctx, 1, key, algo, reserved, expires, flags);
if (!err)
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
}
+
+
+
+static gpgme_error_t
+adduid_start (gpgme_ctx_t ctx, int synchronous,
+ gpgme_key_t key, const char *userid, unsigned int flags)
+{
+ gpgme_error_t err;
+ void *hook;
+ op_data_t opd;
+
+ if (ctx->protocol != GPGME_PROTOCOL_OPENPGP)
+ return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL);
+
+ if (!key || !userid)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ err = _gpgme_op_reset (ctx, synchronous);
+ if (err)
+ return err;
+
+ err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,
+ sizeof (*opd), release_op_data);
+ opd = hook;
+ if (err)
+ return err;
+
+ opd->uidmode = 1;
+
+ _gpgme_engine_set_status_handler (ctx->engine, genkey_status_handler, ctx);
+
+ if (ctx->passphrase_cb)
+ {
+ err = _gpgme_engine_set_command_handler
+ (ctx->engine, _gpgme_passphrase_command_handler, ctx, NULL);
+ if (err)
+ return err;
+ }
+
+ return _gpgme_engine_op_genkey (ctx->engine,
+ userid, NULL, 0, 0,
+ key, flags,
+ NULL, ctx->use_armor, NULL, NULL);
+
+}
+
+
+/* Add USERID to an existing KEY. */
+gpgme_error_t
+gpgme_op_adduid_start (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid, unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_adduid_start", ctx,
+ "uid='%s' flags=0x%x", userid, flags);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
+
+ err = adduid_start (ctx, 0, key, userid, flags);
+ return TRACE_ERR (err);
+}
+
+
+gpgme_error_t
+gpgme_op_adduid (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid, unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG2 (DEBUG_CTX, "gpgme_op_adduid", ctx,
+ "uid='%s' flags=0x%x", userid, flags);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_ARG));
+
+ err = adduid_start (ctx, 1, key, userid, flags);
+ if (!err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
diff --git a/src/gpgme.def b/src/gpgme.def
index 7b7b1f20..54b04e04 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -233,6 +233,8 @@ EXPORTS
gpgme_op_createkey @173
gpgme_op_createsubkey_start @174
gpgme_op_createsubkey @175
+ gpgme_op_adduid_start @176
+ gpgme_op_adduid @177
; END
diff --git a/src/gpgme.h.in b/src/gpgme.h.in
index 0fdc9276..ec436c80 100644
--- a/src/gpgme.h.in
+++ b/src/gpgme.h.in
@@ -1835,8 +1835,11 @@ struct _gpgme_op_genkey_result
/* A sub key was generated. */
unsigned int sub : 1;
+ /* A user id was generated. */
+ unsigned int uid : 1;
+
/* Internal to GPGME, do not use. */
- unsigned int _unused : 30;
+ unsigned int _unused : 29;
/* The fingerprint of the generated key. */
char *fpr;
@@ -1888,6 +1891,14 @@ gpgme_error_t gpgme_op_createsubkey (gpgme_ctx_t ctx,
unsigned long expires,
unsigned int flags);
+/* Add USERID to an existing KEY. */
+gpgme_error_t gpgme_op_adduid_start (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ unsigned int flags);
+gpgme_error_t gpgme_op_adduid (gpgme_ctx_t ctx,
+ gpgme_key_t key, const char *userid,
+ unsigned int flags);
+
/* Retrieve a pointer to the result of a genkey, createkey, or
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index 2a3e9fc3..0cef9e0b 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -107,6 +107,8 @@ GPGME_1.1 {
gpgme_op_createkey;
gpgme_op_createsubkey_start;
gpgme_op_createsubkey;
+ gpgme_op_adduid_start;
+ gpgme_op_adduid;
};
diff --git a/tests/run-genkey.c b/tests/run-genkey.c
index 3b645025..959e2ea1 100644
--- a/tests/run-genkey.c
+++ b/tests/run-genkey.c
@@ -199,9 +199,13 @@ parse_usage_string (const char *string)
static int
show_usage (int ex)
{
- fputs ("usage: " PGM " [options] USERID [ALGO [USAGE [EXPIRESECONDS]]]\n\n"
+ fputs ("usage: " PGM " [options] ARGS\n"
+ " args: USERID [ALGO [USAGE [EXPIRESECONDS]]]\n"
+ " for addkey: FPR [ALGO [USAGE [EXPIRESECONDS]]]\n"
+ " for adduid: FPR USERID\n"
"Options:\n"
- " --addkey add a subkey to the key with USERID\n"
+ " --addkey add a subkey to the key with FPR\n"
+ " --adduid add a user id to the key with FPR\n"
" --verbose run in verbose mode\n"
" --status print status lines from the backend\n"
" --progress print progress info\n"
@@ -226,8 +230,10 @@ main (int argc, char **argv)
int print_progress = 0;
int use_loopback = 0;
int addkey = 0;
+ int adduid = 0;
const char *userid;
const char *algo = NULL;
+ const char *newuserid = NULL;
unsigned int flags = 0;
unsigned long expire = 0;
gpgme_genkey_result_t result;
@@ -248,6 +254,13 @@ main (int argc, char **argv)
else if (!strcmp (*argv, "--addkey"))
{
addkey = 1;
+ adduid = 0;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--adduid"))
+ {
+ addkey = 0;
+ adduid = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--verbose"))
@@ -294,15 +307,25 @@ main (int argc, char **argv)
show_usage (1);
}
- if (!argc || argc > 4)
- show_usage (1);
- userid = argv[0];
- if (argc > 1)
- algo = argv[1];
- if (argc > 2)
- flags |= parse_usage_string (argv[2]);
- if (argc > 3)
- expire = parse_expire_string (argv[3]);
+ if (adduid)
+ {
+ if (argc != 2)
+ show_usage (1);
+ userid = argv[0];
+ newuserid = argv[1];
+ }
+ else
+ {
+ if (!argc || argc > 4)
+ show_usage (1);
+ userid = argv[0];
+ if (argc > 1)
+ algo = argv[1];
+ if (argc > 2)
+ flags |= parse_usage_string (argv[2]);
+ if (argc > 3)
+ expire = parse_expire_string (argv[3]);
+ }
init_gpgme (protocol);
@@ -323,7 +346,7 @@ main (int argc, char **argv)
gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
}
- if (addkey)
+ if (addkey || adduid)
{
gpgme_key_t akey;
@@ -335,12 +358,25 @@ main (int argc, char **argv)
exit (1);
}
- err = gpgme_op_createsubkey (ctx, akey, algo, 0, expire, flags);
- if (err)
+ if (addkey)
{
- fprintf (stderr, PGM ": gpgme_op_createsubkey failed: %s\n",
- gpg_strerror (err));
- exit (1);
+ err = gpgme_op_createsubkey (ctx, akey, algo, 0, expire, flags);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gpgme_op_createsubkey failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
+ }
+ else if (adduid)
+ {
+ err = gpgme_op_adduid (ctx, akey, newuserid, flags);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gpgme_op_adduid failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
}
gpgme_key_unref (akey);
}
@@ -373,6 +409,8 @@ main (int argc, char **argv)
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;