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 <wk@gnupg.org>
This commit is contained in:
parent
cc353701b0
commit
3210f3e472
2
NEWS
2
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.
|
||||
|
@ -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);
|
||||
|
||||
|
110
src/genkey.c
110
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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -107,6 +107,8 @@ GPGME_1.1 {
|
||||
gpgme_op_createkey;
|
||||
gpgme_op_createsubkey_start;
|
||||
gpgme_op_createsubkey;
|
||||
gpgme_op_adduid_start;
|
||||
gpgme_op_adduid;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user