[git] GPGME - branch, master, updated. gpgme-1.6.0-349-gcc35370
by Werner Koch
cvs at cvs.gnupg.org
Wed Sep 14 09:54:47 CEST 2016
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".
The branch, master has been updated
via cc353701b0fde4c811ddc1e9a91b852dfe9f4e06 (commit)
from 51f9acbca935c5287d9a28205037b0923e9a65f5 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit cc353701b0fde4c811ddc1e9a91b852dfe9f4e06
Author: Werner Koch <wk at gnupg.org>
Date: Wed Sep 14 09:51:16 2016 +0200
core: New function gpgme_op_createsubkey.
* src/genkey.c (createsubkey_start): New.
(gpgme_op_createsubkey_start, gpgme_op_createsubkey): New.
* src/gpgme.def, src/libgpgme.vers: Add them.
* src/engine-gpg.c (gpg_createkey): Factor some code out to ...
(gpg_add_algo_usage_expire): new.
(gpg_addkey): Implement.
* tests/run-genkey.c: Add option --addkey.
Signed-off-by: Werner Koch <wk at gnupg.org>
diff --git a/NEWS b/NEWS
index d3639c8..9445f7f 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,8 @@ Noteworthy changes in version 1.7.0 (unreleased) [C25/A14/R_]
gpgme_data_set_flag NEW.
gpgme_op_createkey NEW.
gpgme_op_createkey_start NEW.
+ gpgme_op_createsubkey NEW.
+ gpgme_op_createsubkey_start 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/doc/gpgme.texi b/doc/gpgme.texi
index dfc9548..ef39d81 100644
--- a/doc/gpgme.texi
+++ b/doc/gpgme.texi
@@ -3792,7 +3792,7 @@ The function @code{gpgme_op_genkey} generates a new key pair in the
context @var{ctx}. The meaning of @var{public} and @var{secret}
depends on the crypto backend.
-GnuPG does not support @var{public} and @var{secret}, they should be
+GPG does not support @var{public} and @var{secret}, they should be
@code{NULL}. GnuPG will generate a key pair and add it to the
standard key ring. The fingerprint of the generated key is available
with @code{gpgme_op_genkey_result}.
diff --git a/src/engine-gpg.c b/src/engine-gpg.c
index f22d8b4..5a16f80 100644
--- a/src/engine-gpg.c
+++ b/src/engine-gpg.c
@@ -1969,6 +1969,47 @@ gpg_export_ext (void *engine, const char *pattern[], gpgme_export_mode_t mode,
}
+
+/* Helper to add algo, usage, and expire to the list of args. */
+static gpgme_error_t
+gpg_add_algo_usage_expire (engine_gpg_t gpg,
+ const char *algo,
+ unsigned long expires,
+ unsigned int flags)
+{
+ gpg_error_t err;
+
+ /* This condition is only required to allow the use of gpg < 2.1.16 */
+ if (algo
+ || (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
+ | GPGME_CREATE_CERT | GPGME_CREATE_AUTH))
+ || expires)
+ {
+ err = add_arg (gpg, algo? algo : "default");
+ if (!err)
+ {
+ char tmpbuf[5*4+1];
+ snprintf (tmpbuf, sizeof tmpbuf, "%s%s%s%s",
+ (flags & GPGME_CREATE_SIGN)? " sign":"",
+ (flags & GPGME_CREATE_ENCR)? " encr":"",
+ (flags & GPGME_CREATE_CERT)? " cert":"",
+ (flags & GPGME_CREATE_AUTH)? " auth":"");
+ err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
+ }
+ if (!err && expires)
+ {
+ char tmpbuf[8+20];
+ snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
+ err = add_arg (gpg, tmpbuf);
+ }
+ }
+ else
+ err = 0;
+
+ return err;
+}
+
+
static gpgme_error_t
gpg_createkey_from_param (engine_gpg_t gpg,
gpgme_data_t help_data, int use_armor)
@@ -2026,32 +2067,8 @@ gpg_createkey (engine_gpg_t gpg,
if (!err)
err = add_arg (gpg, userid);
- /* This condition is only required to allow the use of gpg < 2.1.16 */
- if (algo
- || (flags & (GPGME_CREATE_SIGN | GPGME_CREATE_ENCR
- | GPGME_CREATE_CERT | GPGME_CREATE_AUTH))
- || expires)
- {
-
- if (!err)
- err = add_arg (gpg, algo? algo : "default");
- if (!err)
- {
- char tmpbuf[5*4+1];
- snprintf (tmpbuf, sizeof tmpbuf, "%s%s%s%s",
- (flags & GPGME_CREATE_SIGN)? " sign":"",
- (flags & GPGME_CREATE_ENCR)? " encr":"",
- (flags & GPGME_CREATE_CERT)? " cert":"",
- (flags & GPGME_CREATE_AUTH)? " auth":"");
- err = add_arg (gpg, *tmpbuf? tmpbuf : "default");
- }
- if (!err && expires)
- {
- char tmpbuf[8+20];
- snprintf (tmpbuf, sizeof tmpbuf, "seconds=%lu", expires);
- err = add_arg (gpg, tmpbuf);
- }
- }
+ if (!err)
+ err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
if (!err)
err = start (gpg);
@@ -2067,7 +2084,31 @@ gpg_addkey (engine_gpg_t gpg,
unsigned int flags,
int use_armor)
{
- return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+ gpgme_error_t err;
+
+ if (!key || !key->fpr)
+ return gpg_error (GPG_ERR_INV_ARG);
+
+ err = add_arg (gpg, "--quick-addkey");
+ if (!err && use_armor)
+ err = add_arg (gpg, "--armor");
+ if (!err && (flags & GPGME_CREATE_NOPASSWD))
+ {
+ err = add_arg (gpg, "--passphrase");
+ if (!err)
+ err = add_arg (gpg, "");
+ }
+ if (!err)
+ err = add_arg (gpg, "--");
+ if (!err)
+ err = add_arg (gpg, key->fpr);
+
+ if (!err)
+ err = gpg_add_algo_usage_expire (gpg, algo, expires, flags);
+
+ if (!err)
+ err = start (gpg);
+ return err;
}
diff --git a/src/genkey.c b/src/genkey.c
index 0b795f4..26bcca6 100644
--- a/src/genkey.c
+++ b/src/genkey.c
@@ -387,3 +387,88 @@ gpgme_op_createkey (gpgme_ctx_t ctx, const char *userid, const char *algo,
err = _gpgme_wait_one (ctx);
return TRACE_ERR (err);
}
+
+
+
+static gpgme_error_t
+createsubkey_start (gpgme_ctx_t ctx, int synchronous,
+ gpgme_key_t key,
+ const char *algo,
+ unsigned long reserved, unsigned long expires,
+ 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);
+
+ err = _gpgme_op_reset (ctx, synchronous);
+ if (err)
+ return err;
+
+ if (reserved || !key)
+ return gpg_error (GPG_ERR_INV_VALUE);
+
+ err = _gpgme_op_data_lookup (ctx, OPDATA_GENKEY, &hook,
+ sizeof (*opd), release_op_data);
+ opd = hook;
+ if (err)
+ return err;
+
+ _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,
+ NULL, algo, reserved, expires,
+ key, flags,
+ NULL, ctx->use_armor, NULL, NULL);
+
+}
+
+
+/* Add a subkey to an existing KEY. */
+gpgme_error_t
+gpgme_op_createsubkey_start (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,
+ unsigned long reserved, unsigned long expires,
+ unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG3 (DEBUG_CTX, "gpgme_op_createsubkey_start", ctx,
+ "key=%p, algo='%s' flags=0x%x", key, algo, flags);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ err = createsubkey_start (ctx, 0, key, algo, reserved, expires, flags);
+ return TRACE_ERR (err);
+}
+
+
+gpgme_error_t
+gpgme_op_createsubkey (gpgme_ctx_t ctx, gpgme_key_t key, const char *algo,
+ unsigned long reserved, unsigned long expires,
+ unsigned int flags)
+{
+ gpgme_error_t err;
+
+ TRACE_BEG3 (DEBUG_CTX, "gpgme_op_createsubkey", ctx,
+ "key=%p, algo='%s' flags=0x%x", key, algo, flags);
+
+ if (!ctx)
+ return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE));
+
+ err = createsubkey_start (ctx, 1, key, algo, reserved, expires, flags);
+ if (!err)
+ err = _gpgme_wait_one (ctx);
+ return TRACE_ERR (err);
+}
diff --git a/src/gpgme.def b/src/gpgme.def
index a56b9ef..7b7b1f2 100644
--- a/src/gpgme.def
+++ b/src/gpgme.def
@@ -231,6 +231,8 @@ EXPORTS
gpgme_op_createkey_start @172
gpgme_op_createkey @173
+ gpgme_op_createsubkey_start @174
+ gpgme_op_createsubkey @175
; END
diff --git a/src/libgpgme.vers b/src/libgpgme.vers
index b06c9c6..2a3e9fc 100644
--- a/src/libgpgme.vers
+++ b/src/libgpgme.vers
@@ -105,6 +105,8 @@ GPGME_1.1 {
gpgme_op_createkey_start;
gpgme_op_createkey;
+ gpgme_op_createsubkey_start;
+ gpgme_op_createsubkey;
};
diff --git a/tests/run-genkey.c b/tests/run-genkey.c
index 74d4038..3b64502 100644
--- a/tests/run-genkey.c
+++ b/tests/run-genkey.c
@@ -201,6 +201,7 @@ show_usage (int ex)
{
fputs ("usage: " PGM " [options] USERID [ALGO [USAGE [EXPIRESECONDS]]]\n\n"
"Options:\n"
+ " --addkey add a subkey to the key with USERID\n"
" --verbose run in verbose mode\n"
" --status print status lines from the backend\n"
" --progress print progress info\n"
@@ -224,6 +225,7 @@ main (int argc, char **argv)
int print_status = 0;
int print_progress = 0;
int use_loopback = 0;
+ int addkey = 0;
const char *userid;
const char *algo = NULL;
unsigned int flags = 0;
@@ -243,6 +245,11 @@ main (int argc, char **argv)
}
else if (!strcmp (*argv, "--help"))
show_usage (0);
+ else if (!strcmp (*argv, "--addkey"))
+ {
+ addkey = 1;
+ argc--; argv++;
+ }
else if (!strcmp (*argv, "--verbose"))
{
verbose = 1;
@@ -316,12 +323,36 @@ main (int argc, char **argv)
gpgme_set_passphrase_cb (ctx, passphrase_cb, NULL);
}
- err = gpgme_op_createkey (ctx, userid, algo, 0, expire, NULL, flags);
- if (err)
+ if (addkey)
{
- fprintf (stderr, PGM ": gpgme_op_createkey failed: %s\n",
- gpg_strerror (err));
- exit (1);
+ gpgme_key_t akey;
+
+ err = gpgme_get_key (ctx, userid, &akey, 1);
+ if (err)
+ {
+ fprintf (stderr, PGM ": error getting secret key for '%s': %s\n",
+ userid, 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);
+ }
+ gpgme_key_unref (akey);
+ }
+ else
+ {
+ err = gpgme_op_createkey (ctx, userid, algo, 0, expire, NULL, flags);
+ if (err)
+ {
+ fprintf (stderr, PGM ": gpgme_op_createkey failed: %s\n",
+ gpg_strerror (err));
+ exit (1);
+ }
}
result = gpgme_op_genkey_result (ctx);
-----------------------------------------------------------------------
Summary of changes:
NEWS | 2 ++
doc/gpgme.texi | 2 +-
src/engine-gpg.c | 95 ++++++++++++++++++++++++++++++++++++++----------------
src/genkey.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
src/gpgme.def | 2 ++
src/libgpgme.vers | 2 ++
tests/run-genkey.c | 41 ++++++++++++++++++++---
7 files changed, 196 insertions(+), 33 deletions(-)
hooks/post-receive
--
GnuPG Made Easy
http://git.gnupg.org
More information about the Gnupg-commits
mailing list