g10: Always save standard revocation certificate in file.
[gnupg.git] / g10 / keygen.c
index 9fa4a07..6a3d323 100644 (file)
 #include <unistd.h>
 
 #include "gpg.h"
-#include "util.h"
+#include "../common/util.h"
 #include "main.h"
 #include "packet.h"
-#include "ttyio.h"
+#include "../common/ttyio.h"
 #include "options.h"
 #include "keydb.h"
 #include "trustdb.h"
-#include "status.h"
-#include "i18n.h"
+#include "../common/status.h"
+#include "../common/i18n.h"
 #include "keyserver-internal.h"
 #include "call-agent.h"
 #include "pkglue.h"
 #include "../common/shareddefs.h"
-#include "host2net.h"
-#include "mbox-util.h"
+#include "../common/host2net.h"
+#include "../common/mbox-util.h"
 
 
 /* The default algorithms.  If you change them remember to change them
@@ -89,7 +89,8 @@ enum para_name {
   pSERIALNO,
   pCARDBACKUPKEY,
   pHANDLE,
-  pKEYSERVER
+  pKEYSERVER,
+  pKEYGRIP
 };
 
 struct para_data_s {
@@ -434,9 +435,11 @@ keygen_set_std_prefs (const char *string,int personal)
 
     if(strlen(string))
       {
-       char *dup, *tok, *prefstring;
+       char *prefstringbuf;
+        char *tok, *prefstring;
 
-       dup = prefstring = xstrdup (string); /* need a writable string! */
+        /* We need a writable string. */
+       prefstring = prefstringbuf = xstrdup (string);
 
        while((tok=strsep(&prefstring," ,")))
          {
@@ -470,7 +473,7 @@ keygen_set_std_prefs (const char *string,int personal)
              }
          }
 
-       xfree (dup);
+       xfree (prefstringbuf);
       }
 
     if(!rc)
@@ -840,7 +843,7 @@ keygen_add_revkey (PKT_signature *sig, void *opaque)
 /* Create a back-signature.  If TIMESTAMP is not NULL, use it for the
    signature creation time.  */
 gpg_error_t
-make_backsig (PKT_signature *sig, PKT_public_key *pk,
+make_backsig (ctrl_t ctrl, PKT_signature *sig, PKT_public_key *pk,
               PKT_public_key *sub_pk, PKT_public_key *sub_psk,
               u32 timestamp, const char *cache_nonce)
 {
@@ -849,7 +852,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
 
   cache_public_key (sub_pk);
 
-  err = make_keysig_packet (&backsig, pk, NULL, sub_pk, sub_psk, 0x19,
+  err = make_keysig_packet (ctrl, &backsig, pk, NULL, sub_pk, sub_psk, 0x19,
                             0, timestamp, 0, NULL, NULL, cache_nonce);
   if (err)
     log_error ("make_keysig_packet failed for backsig: %s\n",
@@ -864,7 +867,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
       backsig_pkt.pkttype = PKT_SIGNATURE;
       backsig_pkt.pkt.signature = backsig;
       err = build_packet (backsig_out, &backsig_pkt);
-      free_packet (&backsig_pkt);
+      free_packet (&backsig_pkt, NULL);
       if (err)
        log_error ("build_packet failed for backsig: %s\n", gpg_strerror (err));
       else
@@ -907,10 +910,10 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
                case 2:
                  pktlen  = (size_t)buf[mark++] << 24;
                  pktlen |= buf[mark++] << 16;
-
+                 /* fall through */
                case 1:
                  pktlen |= buf[mark++] << 8;
-
+                 /* fall through */
                case 0:
                  pktlen |= buf[mark++];
                }
@@ -933,7 +936,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
    PSK.  REVKEY is describes the direct key signature and TIMESTAMP is
    the timestamp to set on the signature.  */
 static gpg_error_t
-write_direct_sig (KBNODE root, PKT_public_key *psk,
+write_direct_sig (ctrl_t ctrl, kbnode_t root, PKT_public_key *psk,
                   struct revocation_key *revkey, u32 timestamp,
                   const char *cache_nonce)
 {
@@ -957,7 +960,7 @@ write_direct_sig (KBNODE root, PKT_public_key *psk,
   cache_public_key (pk);
 
   /* Make the signature.  */
-  err = make_keysig_packet (&sig, pk, NULL,NULL, psk, 0x1F,
+  err = make_keysig_packet (ctrl, &sig, pk, NULL,NULL, psk, 0x1F,
                             0, timestamp, 0,
                             keygen_add_revkey, revkey, cache_nonce);
   if (err)
@@ -979,7 +982,7 @@ write_direct_sig (KBNODE root, PKT_public_key *psk,
    PSK.  USE and TIMESTAMP give the extra data we need for the
    signature.  */
 static gpg_error_t
-write_selfsigs (KBNODE root, PKT_public_key *psk,
+write_selfsigs (ctrl_t ctrl, kbnode_t root, PKT_public_key *psk,
                unsigned int use, u32 timestamp, const char *cache_nonce)
 {
   gpg_error_t err;
@@ -1012,7 +1015,7 @@ write_selfsigs (KBNODE root, PKT_public_key *psk,
   cache_public_key (pk);
 
   /* Make the signature.  */
-  err = make_keysig_packet (&sig, pk, uid, NULL, psk, 0x13,
+  err = make_keysig_packet (ctrl, &sig, pk, uid, NULL, psk, 0x13,
                             0, timestamp, 0,
                             keygen_add_std_prefs, pk, cache_nonce);
   if (err)
@@ -1035,7 +1038,8 @@ write_selfsigs (KBNODE root, PKT_public_key *psk,
    SUB_PSK is a key used to create a back-signature; that one is only
    used if USE has the PUBKEY_USAGE_SIG capability.  */
 static int
-write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
+write_keybinding (ctrl_t ctrl, kbnode_t root,
+                  PKT_public_key *pri_psk, PKT_public_key *sub_psk,
                   unsigned int use, u32 timestamp, const char *cache_nonce)
 {
   gpg_error_t err;
@@ -1071,7 +1075,7 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
   /* Make the signature.  */
   oduap.usage = use;
   oduap.pk = sub_pk;
-  err = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_psk, 0x18,
+  err = make_keysig_packet (ctrl, &sig, pri_pk, NULL, sub_pk, pri_psk, 0x18,
                             0, timestamp, 0,
                             keygen_add_key_flags_and_expire, &oduap,
                             cache_nonce);
@@ -1084,7 +1088,8 @@ write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
   /* Make a backsig.  */
   if (use & PUBKEY_USAGE_SIG)
     {
-      err = make_backsig (sig, pri_pk, sub_pk, sub_psk, timestamp, cache_nonce);
+      err = make_backsig (ctrl,
+                          sig, pri_pk, sub_pk, sub_psk, timestamp, cache_nonce);
       if (err)
         return err;
     }
@@ -1783,7 +1788,7 @@ ask_key_flags (int algo, int subkey, unsigned int current)
               else if (!subkey && *s == 'c')
                 {
                   /* Accept 'c' for the primary key because USAGE_CERT
-                     will will be set anyway.  This is for folks who
+                     will be set anyway.  This is for folks who
                      want to experiment with a cert-only primary key.  */
                   current |= PUBKEY_USAGE_CERT;
                 }
@@ -1836,7 +1841,7 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
   gpg_error_t err;
   unsigned char *public;
   size_t publiclen;
-  const char *algostr;
+  int algo;
 
   if (hexgrip[0] == '&')
     hexgrip++;
@@ -1846,26 +1851,10 @@ check_keygrip (ctrl_t ctrl, const char *hexgrip)
     return 0;
   publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL);
 
-  get_pk_algo_from_canon_sexp (public, publiclen, &algostr);
+  algo = get_pk_algo_from_canon_sexp (public, publiclen);
   xfree (public);
 
-  /* FIXME: Mapping of ECC algorithms is probably not correct. */
-  if (!algostr)
-    return 0;
-  else if (!strcmp (algostr, "rsa"))
-    return PUBKEY_ALGO_RSA;
-  else if (!strcmp (algostr, "dsa"))
-    return PUBKEY_ALGO_DSA;
-  else if (!strcmp (algostr, "elg"))
-    return PUBKEY_ALGO_ELGAMAL_E;
-  else if (!strcmp (algostr, "ecc"))
-    return PUBKEY_ALGO_ECDH;
-  else if (!strcmp (algostr, "ecdsa"))
-    return PUBKEY_ALGO_ECDSA;
-  else if (!strcmp (algostr, "eddsa"))
-    return PUBKEY_ALGO_EDDSA;
-  else
-    return 0;
+  return map_pk_gcry_to_openpgp (algo);
 }
 
 
@@ -3651,8 +3640,9 @@ read_parameter_file (ctrl_t ctrl, const char *fname )
        { "Preferences",    pPREFERENCES },
        { "Revoker",        pREVOKER },
         { "Handle",         pHANDLE },
-       { "Keyserver",      pKEYSERVER },
-       { NULL, 0 }
+        { "Keyserver",      pKEYSERVER },
+        { "Keygrip",        pKEYGRIP },
+        { NULL, 0 }
     };
     IOBUF fp;
     byte *line;
@@ -4173,137 +4163,166 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
   else if (full)  /* Full featured key generation.  */
     {
       int subkey_algo;
-      char *curve = NULL;
-
-      /* Fixme: To support creating a primary key by keygrip we better
-         also define the keyword for the parameter file.  Note that
-         the subkey case will never be asserted if a keygrip has been
-         given.  */
-      algo = ask_algo (ctrl, 0, &subkey_algo, &use, NULL);
-      if (subkey_algo)
+      char *key_from_hexgrip = NULL;
+
+      algo = ask_algo (ctrl, 0, &subkey_algo, &use, &key_from_hexgrip);
+      if (key_from_hexgrip)
         {
-          /* Create primary and subkey at once.  */
-          both = 1;
-          if (algo == PUBKEY_ALGO_ECDSA
-              || algo == PUBKEY_ALGO_EDDSA
-              || algo == PUBKEY_ALGO_ECDH)
+          r = xmalloc_clear( sizeof *r + 20 );
+          r->key = pKEYTYPE;
+          sprintf( r->u.value, "%d", algo);
+          r->next = para;
+          para = r;
+
+          if (use)
             {
-              curve = ask_curve (&algo, &subkey_algo);
-              r = xmalloc_clear( sizeof *r + 20 );
-              r->key = pKEYTYPE;
-              sprintf( r->u.value, "%d", algo);
-              r->next = para;
-              para = r;
-              nbits = 0;
-              r = xmalloc_clear (sizeof *r + strlen (curve));
-              r->key = pKEYCURVE;
-              strcpy (r->u.value, curve);
+              r = xmalloc_clear( sizeof *r + 25 );
+              r->key = pKEYUSAGE;
+              sprintf( r->u.value, "%s%s%s",
+                       (use & PUBKEY_USAGE_SIG)? "sign ":"",
+                       (use & PUBKEY_USAGE_ENC)? "encrypt ":"",
+                       (use & PUBKEY_USAGE_AUTH)? "auth":"" );
               r->next = para;
               para = r;
             }
-          else
+
+          r = xmalloc_clear( sizeof *r + 40 );
+          r->key = pKEYGRIP;
+          strcpy (r->u.value, key_from_hexgrip);
+          r->next = para;
+          para = r;
+
+          xfree (key_from_hexgrip);
+        }
+      else
+        {
+          char *curve = NULL;
+
+          if (subkey_algo)
             {
+              /* Create primary and subkey at once.  */
+              both = 1;
+              if (algo == PUBKEY_ALGO_ECDSA
+                  || algo == PUBKEY_ALGO_EDDSA
+                  || algo == PUBKEY_ALGO_ECDH)
+                {
+                  curve = ask_curve (&algo, &subkey_algo);
+                  r = xmalloc_clear( sizeof *r + 20 );
+                  r->key = pKEYTYPE;
+                  sprintf( r->u.value, "%d", algo);
+                  r->next = para;
+                  para = r;
+                  nbits = 0;
+                  r = xmalloc_clear (sizeof *r + strlen (curve));
+                  r->key = pKEYCURVE;
+                  strcpy (r->u.value, curve);
+                  r->next = para;
+                  para = r;
+                }
+              else
+                {
+                  r = xmalloc_clear( sizeof *r + 20 );
+                  r->key = pKEYTYPE;
+                  sprintf( r->u.value, "%d", algo);
+                  r->next = para;
+                  para = r;
+                  nbits = ask_keysize (algo, 0);
+                  r = xmalloc_clear( sizeof *r + 20 );
+                  r->key = pKEYLENGTH;
+                  sprintf( r->u.value, "%u", nbits);
+                  r->next = para;
+                  para = r;
+                }
               r = xmalloc_clear( sizeof *r + 20 );
-              r->key = pKEYTYPE;
-              sprintf( r->u.value, "%d", algo);
+              r->key = pKEYUSAGE;
+              strcpy( r->u.value, "sign" );
               r->next = para;
               para = r;
-              nbits = ask_keysize (algo, 0);
+
               r = xmalloc_clear( sizeof *r + 20 );
-              r->key = pKEYLENGTH;
-              sprintf( r->u.value, "%u", nbits);
+              r->key = pSUBKEYTYPE;
+              sprintf( r->u.value, "%d", subkey_algo);
+              r->next = para;
+              para = r;
+              r = xmalloc_clear( sizeof *r + 20 );
+              r->key = pSUBKEYUSAGE;
+              strcpy( r->u.value, "encrypt" );
               r->next = para;
               para = r;
-            }
-          r = xmalloc_clear( sizeof *r + 20 );
-          r->key = pKEYUSAGE;
-          strcpy( r->u.value, "sign" );
-          r->next = para;
-          para = r;
-
-          r = xmalloc_clear( sizeof *r + 20 );
-          r->key = pSUBKEYTYPE;
-          sprintf( r->u.value, "%d", subkey_algo);
-          r->next = para;
-          para = r;
-          r = xmalloc_clear( sizeof *r + 20 );
-          r->key = pSUBKEYUSAGE;
-          strcpy( r->u.value, "encrypt" );
-          r->next = para;
-          para = r;
 
-          if (algo == PUBKEY_ALGO_ECDSA
-              || algo == PUBKEY_ALGO_EDDSA
-              || algo == PUBKEY_ALGO_ECDH)
+              if (algo == PUBKEY_ALGO_ECDSA
+                  || algo == PUBKEY_ALGO_EDDSA
+                  || algo == PUBKEY_ALGO_ECDH)
+                {
+                  if (algo == PUBKEY_ALGO_EDDSA
+                      && subkey_algo == PUBKEY_ALGO_ECDH)
+                    {
+                      /* Need to switch to a different curve for the
+                         encryption key.  */
+                      xfree (curve);
+                      curve = xstrdup ("Curve25519");
+                    }
+                  r = xmalloc_clear (sizeof *r + strlen (curve));
+                  r->key = pSUBKEYCURVE;
+                  strcpy (r->u.value, curve);
+                  r->next = para;
+                  para = r;
+                }
+            }
+          else /* Create only a single key.  */
             {
-              if (algo == PUBKEY_ALGO_EDDSA
-                  && subkey_algo == PUBKEY_ALGO_ECDH)
+              /* For ECC we need to ask for the curve before storing the
+                 algo because ask_curve may change the algo.  */
+              if (algo == PUBKEY_ALGO_ECDSA
+                  || algo == PUBKEY_ALGO_EDDSA
+                  || algo == PUBKEY_ALGO_ECDH)
                 {
-                  /* Need to switch to a different curve for the
-                     encryption key.  */
-                  xfree (curve);
-                  curve = xstrdup ("Curve25519");
+                  curve = ask_curve (&algo, NULL);
+                  r = xmalloc_clear (sizeof *r + strlen (curve));
+                  r->key = pKEYCURVE;
+                  strcpy (r->u.value, curve);
+                  r->next = para;
+                  para = r;
                 }
-              r = xmalloc_clear (sizeof *r + strlen (curve));
-              r->key = pSUBKEYCURVE;
-              strcpy (r->u.value, curve);
+
+              r = xmalloc_clear( sizeof *r + 20 );
+              r->key = pKEYTYPE;
+              sprintf( r->u.value, "%d", algo );
               r->next = para;
               para = r;
+
+              if (use)
+                {
+                  r = xmalloc_clear( sizeof *r + 25 );
+                  r->key = pKEYUSAGE;
+                  sprintf( r->u.value, "%s%s%s",
+                           (use & PUBKEY_USAGE_SIG)? "sign ":"",
+                           (use & PUBKEY_USAGE_ENC)? "encrypt ":"",
+                           (use & PUBKEY_USAGE_AUTH)? "auth":"" );
+                  r->next = para;
+                  para = r;
+                }
+              nbits = 0;
             }
-        }
-      else /* Create only a single key.  */
-        {
-          /* For ECC we need to ask for the curve before storing the
-             algo because ask_curve may change the algo.  */
+
           if (algo == PUBKEY_ALGO_ECDSA
               || algo == PUBKEY_ALGO_EDDSA
               || algo == PUBKEY_ALGO_ECDH)
             {
-              curve = ask_curve (&algo, NULL);
-              r = xmalloc_clear (sizeof *r + strlen (curve));
-              r->key = pKEYCURVE;
-              strcpy (r->u.value, curve);
-              r->next = para;
-              para = r;
+              /* The curve has already been set.  */
             }
-
-          r = xmalloc_clear( sizeof *r + 20 );
-          r->key = pKEYTYPE;
-          sprintf( r->u.value, "%d", algo );
-          r->next = para;
-          para = r;
-
-          if (use)
+          else
             {
-              r = xmalloc_clear( sizeof *r + 25 );
-              r->key = pKEYUSAGE;
-              sprintf( r->u.value, "%s%s%s",
-                       (use & PUBKEY_USAGE_SIG)? "sign ":"",
-                       (use & PUBKEY_USAGE_ENC)? "encrypt ":"",
-                       (use & PUBKEY_USAGE_AUTH)? "auth":"" );
+              nbits = ask_keysize (both? subkey_algo : algo, nbits);
+              r = xmalloc_clear( sizeof *r + 20 );
+              r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
+              sprintf( r->u.value, "%u", nbits);
               r->next = para;
               para = r;
             }
-          nbits = 0;
-        }
 
-      if (algo == PUBKEY_ALGO_ECDSA
-          || algo == PUBKEY_ALGO_EDDSA
-          || algo == PUBKEY_ALGO_ECDH)
-        {
-          /* The curve has already been set.  */
+          xfree (curve);
         }
-      else
-        {
-          nbits = ask_keysize (both? subkey_algo : algo, nbits);
-          r = xmalloc_clear( sizeof *r + 20 );
-          r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
-          sprintf( r->u.value, "%u", nbits);
-          r->next = para;
-          para = r;
-        }
-
-      xfree (curve);
     }
   else /* Default key generation.  */
     {
@@ -4319,7 +4338,7 @@ generate_keypair (ctrl_t ctrl, int full, const char *fname,
 #else
                    GPG_NAME
 #endif
-                   , "--full-gen-key" );
+                   , "--full-generate-key" );
 
       err = parse_key_parameter_string (NULL, -1,
                                         &algo, &size, &keyuse, &curve,
@@ -4545,6 +4564,9 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
   int did_sub = 0;
   u32 timestamp;
   char *cache_nonce = NULL;
+  int algo;
+  u32 expire;
+  const char *key_from_hexgrip = NULL;
 
   if (outctrl->dryrun)
     {
@@ -4610,20 +4632,26 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
      node of the subkey but that is more work than just to pass the
      current timestamp.  */
 
-  if (!card)
-    err = do_create (get_parameter_algo( para, pKEYTYPE, NULL ),
+  algo = get_parameter_algo( para, pKEYTYPE, NULL );
+  expire = get_parameter_u32( para, pKEYEXPIRE );
+  key_from_hexgrip = get_parameter_value (para, pKEYGRIP);
+  if (key_from_hexgrip)
+    err = do_create_from_keygrip (ctrl, algo, key_from_hexgrip,
+                                  pub_root, timestamp, expire, 0);
+  else if (!card)
+    err = do_create (algo,
                      get_parameter_uint( para, pKEYLENGTH ),
                      get_parameter_value (para, pKEYCURVE),
                      pub_root,
                      timestamp,
-                     get_parameter_u32( para, pKEYEXPIRE ), 0,
+                     expire, 0,
                      outctrl->keygen_flags,
                      get_parameter_passphrase (para),
                      &cache_nonce, NULL);
   else
-    err = gen_card_key (1, get_parameter_algo( para, pKEYTYPE, NULL ),
+    err = gen_card_key (1, algo,
                         1, pub_root, &timestamp,
-                        get_parameter_u32 (para, pKEYEXPIRE));
+                        expire);
 
   /* Get the pointer to the generated public key packet.  */
   if (!err)
@@ -4641,12 +4669,13 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
     }
 
   if (!err && (revkey = get_parameter_revkey (para, pREVOKER)))
-    err = write_direct_sig (pub_root, pri_psk, revkey, timestamp, cache_nonce);
+    err = write_direct_sig (ctrl, pub_root, pri_psk,
+                            revkey, timestamp, cache_nonce);
 
   if (!err && (s = get_parameter_value (para, pUSERID)))
     {
       write_uid (pub_root, s );
-      err = write_selfsigs (pub_root, pri_psk,
+      err = write_selfsigs (ctrl, pub_root, pri_psk,
                             get_parameter_uint (para, pKEYUSAGE), timestamp,
                             cache_nonce);
     }
@@ -4664,7 +4693,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
                           0, pub_root, &timestamp,
                           get_parameter_u32 (para, pKEYEXPIRE));
       if (!err)
-        err = write_keybinding (pub_root, pri_psk, NULL,
+        err = write_keybinding (ctrl, pub_root, pri_psk, NULL,
                                 PUBKEY_USAGE_AUTH, timestamp, cache_nonce);
     }
 
@@ -4706,7 +4735,7 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
         }
 
       if (!err)
-        err = write_keybinding (pub_root, pri_psk, sub_psk,
+        err = write_keybinding (ctrl, pub_root, pri_psk, sub_psk,
                                 get_parameter_uint (para, pSUBKEYUSAGE),
                                 timestamp, cache_nonce);
       did_sub = 1;
@@ -4765,10 +4794,11 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
           keyid_from_pk (pk, pk->main_keyid);
           register_trusted_keyid (pk->main_keyid);
 
-          update_ownertrust (pk, ((get_ownertrust (pk) & ~TRUST_MASK)
-                                  | TRUST_ULTIMATE ));
+         update_ownertrust (ctrl, pk,
+                             ((get_ownertrust (ctrl, pk) & ~TRUST_MASK)
+                              | TRUST_ULTIMATE ));
 
-          gen_standard_revoke (pk, cache_nonce);
+          gen_standard_revoke (ctrl, pk, cache_nonce);
 
           /* Get rid of the first empty packet.  */
           commit_kbnode (&pub_root);
@@ -4777,8 +4807,11 @@ do_generate_keypair (ctrl_t ctrl, struct para_data_s *para,
             {
               tty_printf (_("public and secret key created and signed.\n") );
               tty_printf ("\n");
-              merge_keys_and_selfsig (pub_root);
-              list_keyblock_direct (ctrl, pub_root, 0, 1, 1, 1);
+              merge_keys_and_selfsig (ctrl, pub_root);
+
+              list_keyblock_direct (ctrl, pub_root, 0, 1,
+                                    opt.fingerprint || opt.with_fingerprint,
+                                    1);
             }
 
 
@@ -5007,10 +5040,12 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
    * nonce, which we can use to set the passphrase for the subkey to
    * that of the primary key.  */
   {
-    char *desc = gpg_format_keydesc (pri_psk, FORMAT_KEYDESC_NORMAL, 1);
+    char *desc = gpg_format_keydesc (ctrl, pri_psk, FORMAT_KEYDESC_NORMAL, 1);
     err = agent_passwd (ctrl, hexgrip, desc, 1 /*=verify*/,
                         &cache_nonce, &passwd_nonce);
     xfree (desc);
+    if (err)
+      goto leave;
   }
 
   /* Start creation.  */
@@ -5045,7 +5080,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
       sub_psk = node->pkt->pkt.public_key;
 
   /* Write the binding signature.  */
-  err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time,
+  err = write_keybinding (ctrl, keyblock, pri_psk, sub_psk, use, cur_time,
                           cache_nonce);
   if (err)
     goto leave;
@@ -5069,7 +5104,7 @@ generate_subkeypair (ctrl_t ctrl, kbnode_t keyblock, const char *algostr,
 #ifdef ENABLE_CARD_SUPPORT
 /* Generate a subkey on a card. */
 gpg_error_t
-generate_card_subkeypair (kbnode_t pub_keyblock,
+generate_card_subkeypair (ctrl_t ctrl, kbnode_t pub_keyblock,
                           int keyno, const char *serialno)
 {
   gpg_error_t err = 0;
@@ -5107,7 +5142,7 @@ generate_card_subkeypair (kbnode_t pub_keyblock,
   node = find_kbnode (pub_keyblock, PKT_PUBLIC_KEY);
   if (!node)
     {
-      log_error ("Oops; publkic key lost!\n");
+      log_error ("Oops; public key lost!\n");
       err = gpg_error (GPG_ERR_INTERNAL);
       goto leave;
     }
@@ -5160,7 +5195,7 @@ generate_card_subkeypair (kbnode_t pub_keyblock,
         if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
           sub_pk = node->pkt->pkt.public_key;
       log_assert (sub_pk);
-      err = write_keybinding (pub_keyblock, pri_pk, sub_pk,
+      err = write_keybinding (ctrl, pub_keyblock, pri_pk, sub_pk,
                               use, cur_time, NULL);
     }