json: Delete primary key if subkey gen fails
authorAndre Heinecke <aheinecke@intevation.de>
Tue, 28 Aug 2018 06:35:06 +0000 (08:35 +0200)
committerAndre Heinecke <aheinecke@intevation.de>
Tue, 28 Aug 2018 06:35:06 +0000 (08:35 +0200)
* src/gpgme-json.c (op_delete): Delete primary key on
subkey gen error.

--
This can happen for example if the user cancels the
pinentry to unlock the primary key when adding the
subkey.  To avoid an artifact of a pimary key without
an encryption capable subkey we delete the created
key and treat the whole operation as failed.

src/gpgme-json.c

index 0d1ec50..5c670eb 100644 (file)
@@ -3084,7 +3084,7 @@ op_createkey (cjson_t request, cjson_t result)
 
       err = gpgme_get_key (keylistctx, new_fpr, &new_key, 1);
       release_onetime_context (keylistctx);
-      if (err)
+      if (err || !new_key)
         {
           gpg_error_object (result, err, "Error finding created key: %s",
                             gpg_strerror (err));
@@ -3096,7 +3096,27 @@ op_createkey (cjson_t request, cjson_t result)
                                    0, expires, flags |= GPGME_CREATE_ENCR);
       xfree (subkey_algo);
       if (err)
-        goto leave;
+        {
+          /* This can happen for example if the user cancels the
+           * pinentry to unlock the primary key when adding the
+           * subkey.  To avoid an artifact of a pimary key without
+           * an encryption capable subkey we delete the created
+           * key and treat the whole operation as failed. */
+          gpgme_error_t err2;
+          gpg_error_object (result, err, "Error creating subkey: %s",
+                            gpg_strerror (err));
+          log_info ("Deleting primary key after keygen failure.\n");
+          err2 = gpgme_op_delete_ext (ctx, new_key, GPGME_DELETE_FORCE |
+                                      GPGME_DELETE_ALLOW_SECRET);
+          if (err2)
+            {
+              log_error ("Error deleting primary key: %s",
+                         gpg_strerror (err));
+            }
+          gpgme_key_unref (new_key);
+          goto leave;
+        }
+      gpgme_key_unref (new_key);
     }
 
   xjson_AddStringToObject0 (result, "fingerprint", new_fpr);