[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