Generating an OpenPGP key cia gpg-agent basically works.
authorWerner Koch <wk@gnupg.org>
Tue, 20 Apr 2010 17:57:50 +0000 (17:57 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 20 Apr 2010 17:57:50 +0000 (17:57 +0000)
23 files changed:
g10/ChangeLog
g10/call-agent.c
g10/call-agent.h
g10/card-util.c
g10/export.c
g10/getkey.c
g10/gpg.h
g10/gpgv.c
g10/keydb.h
g10/keyedit.c
g10/keygen.c
g10/keyid.c
g10/keylist.c
g10/main.h
g10/packet.h
g10/pkglue.c
g10/pkglue.h
g10/pubkey-enc.c
g10/revoke.c
g10/seckey-cert.c
g10/seskey.c
g10/sig-check.c
g10/sign.c

index 8e2d655..d82afa1 100644 (file)
@@ -1,3 +1,38 @@
+2010-04-20  Werner Koch  <wk@g10code.com>
+
+       * keylist.c (list_keyblock_colon): Print the keygrip.
+
+       * sign.c (do_sign): Call the agent to create the signature.
+       (mpi_from_sexp): New.
+       * keyid.c (keygrip_from_pk, hexkeygrip_from_pk): New.
+       * call-agent.c (agent_pksign): New.
+       * pkglue.c (pk_sign): Remove.
+
+       * keygen.c (generate_keypair): Do not ask for a passphrase.
+
+2010-04-15  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (gen_dsa, gen_elg, gen_rsa): Remove args SEC_ROOT, DEK,
+       S2K and RET_SK.  Change to use the gpg-agent based key generation.
+       Factor common code out to ...
+       (common_gen): New.
+       (do_create): Remove args SEC_ROOT, DEK, S2K and RET_SK.
+       (do_generate_keypair, write_selfsigs, write_direct_sig)
+       (write_keybinding, make_backsig): Adjust for above changes.
+       (generate_subkeypair): Remove arg SEC_KEYBLOCK.
+       (genhelp_protect, genhelp_factors): Remove.
+       (get_parameter_dek, get_parameter_s2k): Remove.
+
+       * call-agent.c (start_agent): Add dummy arg CTRL.
+       (agent_havekey, keyinfo_status_cb, agent_get_keyinfo)
+       (agent_genkey): New.
+
+       * seckey-cert.c (check_secret_key): Remove
+       (is_secret_key_protected): Take a public key as arg.
+       (protect_secret_key): Remove.
+
+       * seskey.c (encode_md_value): Remove SK arg.
+
 2010-04-14  Werner Koch  <wk@g10code.com>
 
        * cpr.c (myread) [W32CE]: Do not use raise.
 2010-04-14  Werner Koch  <wk@g10code.com>
 
        * cpr.c (myread) [W32CE]: Do not use raise.
index 260cd48..9379fcb 100644 (file)
@@ -1,6 +1,6 @@
 /* call-agent.c - Divert GPG operations to the agent.
 /* call-agent.c - Divert GPG operations to the agent.
- * Copyright (C) 2001, 2002, 2003, 2006, 2007, 
- *               2008, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2006, 2007, 2008, 2009,
+ *               2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  *
  * This file is part of GnuPG.
  *
@@ -69,14 +69,15 @@ struct writekey_parm_s
   size_t keydatalen;
 };
 
   size_t keydatalen;
 };
 
-struct genkey_parm_s 
+struct genkey_parm_s
 {
 {
+  ctrl_t ctrl;
   assuan_context_t ctx;
   assuan_context_t ctx;
-  const char *sexp;
-  size_t sexplen;
+  const char *keyparms;
 };
 
 
 };
 
 
+
 static gpg_error_t learn_status_cb (void *opaque, const char *line);
 
 
 static gpg_error_t learn_status_cb (void *opaque, const char *line);
 
 
@@ -107,10 +108,12 @@ status_sc_op_failure (int rc)
 /* Try to connect to the agent via socket or fork it off and work by
    pipes.  Handle the server's initial greeting */
 static int
 /* Try to connect to the agent via socket or fork it off and work by
    pipes.  Handle the server's initial greeting */
 static int
-start_agent (int for_card)
+start_agent (ctrl_t ctrl, int for_card)
 {
   int rc;
 
 {
   int rc;
 
+  (void)ctrl;  /* Not yet used.  */
+
   /* Fixme: We need a context for each thread or serialize the access
      to the agent. */
   if (agent_ctx)
   /* Fixme: We need a context for each thread or serialize the access
      to the agent. */
   if (agent_ctx)
@@ -486,7 +489,7 @@ agent_learn (struct agent_card_info_s *info)
 {
   int rc;
 
 {
   int rc;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -531,7 +534,7 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
     return gpg_error (GPG_ERR_TOO_LARGE);
   stpcpy (stpcpy (line, "SCD GETATTR "), name); 
 
     return gpg_error (GPG_ERR_TOO_LARGE);
   stpcpy (stpcpy (line, "SCD GETATTR "), name); 
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -581,7 +584,7 @@ agent_scd_setattr (const char *name,
     }
   *p = 0;
 
     }
   *p = 0;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (!rc)
     {
       rc = assuan_transact (agent_ctx, line, NULL, NULL, 
   if (!rc)
     {
       rc = assuan_transact (agent_ctx, line, NULL, NULL, 
@@ -623,7 +626,7 @@ agent_scd_writecert (const char *certidstr,
   char line[ASSUAN_LINELENGTH];
   struct writecert_parm_s parms;
 
   char line[ASSUAN_LINELENGTH];
   struct writecert_parm_s parms;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -673,7 +676,7 @@ agent_scd_writekey (int keyno, const char *serialno,
 
   (void)serialno;
 
 
   (void)serialno;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -762,7 +765,7 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
 
   (void)serialno;
 
 
   (void)serialno;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -909,7 +912,7 @@ agent_scd_pksign (const char *serialno, int hashalgo,
   *r_buf = NULL;
   *r_buflen = 0;
 
   *r_buf = NULL;
   *r_buflen = 0;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
     rc = 0; /* We check later.  */
   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
     rc = 0; /* We check later.  */
@@ -972,7 +975,7 @@ agent_scd_pkdecrypt (const char *serialno,
   size_t len;
 
   *r_buf = NULL;
   size_t len;
 
   *r_buf = NULL;
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
     rc = 0; /* We check later.  */
   if (gpg_err_code (rc) == GPG_ERR_CARD_NOT_PRESENT
       || gpg_err_code (rc) == GPG_ERR_NOT_SUPPORTED)
     rc = 0; /* We check later.  */
@@ -1029,7 +1032,7 @@ agent_scd_readcert (const char *certidstr,
   size_t len;
 
   *r_buf = NULL;
   size_t len;
 
   *r_buf = NULL;
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -1077,7 +1080,7 @@ agent_scd_change_pin (int chvno, const char *serialno)
     reset = "--reset";
   chvno %= 100;
 
     reset = "--reset";
   chvno %= 100;
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -1099,7 +1102,7 @@ agent_scd_checkpin  (const char *serialno)
   int rc;
   char line[ASSUAN_LINELENGTH];
 
   int rc;
   char line[ASSUAN_LINELENGTH];
 
-  rc = start_agent (1);
+  rc = start_agent (NULL, 1);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -1146,7 +1149,7 @@ agent_get_passphrase (const char *cache_id,
 
   *r_passphrase = NULL;
 
 
   *r_passphrase = NULL;
 
-  rc = start_agent (0);
+  rc = start_agent (NULL, 0);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -1217,7 +1220,7 @@ agent_clear_passphrase (const char *cache_id)
   if (!cache_id || !*cache_id)
     return 0;
 
   if (!cache_id || !*cache_id)
     return 0;
 
-  rc = start_agent (0);
+  rc = start_agent (NULL, 0);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -1237,7 +1240,7 @@ gpg_agent_get_confirmation (const char *desc)
   char *tmp;
   char line[ASSUAN_LINELENGTH];
 
   char *tmp;
   char line[ASSUAN_LINELENGTH];
 
-  rc = start_agent (0);
+  rc = start_agent (NULL, 0);
   if (rc)
     return rc;
 
   if (rc)
     return rc;
 
@@ -1264,7 +1267,7 @@ agent_get_s2k_count (unsigned long *r_count)
 
   *r_count = 0;
 
 
   *r_count = 0;
 
-  err = start_agent (0);
+  err = start_agent (NULL, 0);
   if (err)
     return err;
 
   if (err)
     return err;
 
@@ -1289,3 +1292,291 @@ agent_get_s2k_count (unsigned long *r_count)
   return err;
 }
 
   return err;
 }
 
+
+\f
+/* Ask the agent whether a secret key with the given keygrip is
+   known.  */
+gpg_error_t
+agent_havekey (ctrl_t ctrl, const char *hexkeygrip)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  if (!hexkeygrip || strlen (hexkeygrip) != 40)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  snprintf (line, DIM(line)-1, "HAVEKEY %s", hexkeygrip);
+  line[DIM(line)-1] = 0;
+
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+  return err;
+}
+
+
+\f
+static gpg_error_t
+keyinfo_status_cb (void *opaque, const char *line)
+{
+  char **serialno = opaque;
+  const char *s, *s2;
+
+  if (!strncmp (line, "KEYINFO ", 8) && !*serialno)
+    {
+      s = strchr (line+8, ' ');
+      if (s && s[1] == 'T' && s[2] == ' ' && s[3])
+        {
+          s += 3;
+          s2 = strchr (s, ' ');
+          if ( s2 > s )
+            {
+              *serialno = xtrymalloc ((s2 - s)+1);
+              if (*serialno)
+                {
+                  memcpy (*serialno, s, s2 - s);
+                  (*serialno)[s2 - s] = 0;
+                }
+            }
+        }
+    }
+  return 0;
+}
+
+
+/* Return the serial number for a secret key.  If the returned serial
+   number is NULL, the key is not stored on a smartcard.  Caller needs
+   to free R_SERIALNO.  */
+gpg_error_t
+agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip, char **r_serialno)
+{
+  gpg_error_t err;
+  char line[ASSUAN_LINELENGTH];
+  char *serialno = NULL;
+
+  *r_serialno = NULL;
+
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  if (!hexkeygrip || strlen (hexkeygrip) != 40)
+    return gpg_error (GPG_ERR_INV_VALUE);
+
+  snprintf (line, DIM(line)-1, "KEYINFO %s", hexkeygrip);
+  line[DIM(line)-1] = 0;
+
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL,
+                         keyinfo_status_cb, &serialno);
+  if (!err && serialno)
+    {
+      /* Sanity check for bad characters.  */
+      if (strpbrk (serialno, ":\n\r"))
+        err = GPG_ERR_INV_VALUE;
+    }
+  if (err)
+    xfree (serialno);
+  else
+    *r_serialno = serialno;
+  return err;
+}
+
+
+\f
+/* Handle a KEYPARMS inquiry.  Note, we only send the data,
+   assuan_transact takes care of flushing and writing the end */
+static gpg_error_t
+inq_genkey_parms (void *opaque, const char *line)
+{
+  struct genkey_parm_s *parm = opaque; 
+  gpg_error_t err;
+
+  if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
+    {
+      err = assuan_send_data (parm->ctx,
+                              parm->keyparms, strlen (parm->keyparms));
+    }
+  else
+    err = default_inq_cb (parm->ctrl, line);
+
+  return err; 
+}
+
+
+/* Call the agent to generate a new key.  KEYPARMS is the usual
+   S-expression giving the parameters of the key.  gpg-agent passes it
+   gcry_pk_genkey.  */
+gpg_error_t
+agent_genkey (ctrl_t ctrl, const char *keyparms, gcry_sexp_t *r_pubkey)
+{
+  gpg_error_t err;
+  struct genkey_parm_s gk_parm;
+  membuf_t data;
+  size_t len;
+  unsigned char *buf;
+
+  *r_pubkey = NULL;
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  err = assuan_transact (agent_ctx, "RESET", 
+                         NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  init_membuf (&data, 1024);
+  gk_parm.ctrl     = ctrl;
+  gk_parm.ctx      = agent_ctx;
+  gk_parm.keyparms = keyparms;
+  err = assuan_transact (agent_ctx, "GENKEY",
+                         membuf_data_cb, &data, 
+                         inq_genkey_parms, &gk_parm, NULL, NULL);
+  if (err)
+    {
+      xfree (get_membuf (&data, &len));
+      return err;
+    }
+  
+  buf = get_membuf (&data, &len);
+  if (!buf)
+    err = gpg_error_from_syserror ();
+  else
+    {
+      err = gcry_sexp_sscan (r_pubkey, NULL, buf, len);
+      xfree (buf);
+    }
+  return err;
+}
+
+
+
+\f
+/* FIXME: Call the agent to read the public key part for a given keygrip.  If
+   FROMCARD is true, the key is directly read from the current
+   smartcard. In this case HEXKEYGRIP should be the keyID
+   (e.g. OPENPGP.3). */
+/* int */
+/* agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, */
+/*                ksba_sexp_t *r_pubkey) */
+/* { */
+/*   int rc; */
+/*   membuf_t data; */
+/*   size_t len; */
+/*   unsigned char *buf; */
+/*   char line[ASSUAN_LINELENGTH]; */
+
+/*   *r_pubkey = NULL; */
+/*   rc = start_agent (ctrl); */
+/*   if (rc) */
+/*     return rc; */
+
+/*   rc = assuan_transact (agent_ctx, "RESET",NULL, NULL, NULL, NULL, NULL, NULL); */
+/*   if (rc) */
+/*     return rc; */
+
+/*   snprintf (line, DIM(line)-1, "%sREADKEY %s", */
+/*             fromcard? "SCD ":"", hexkeygrip); */
+/*   line[DIM(line)-1] = 0; */
+
+/*   init_membuf (&data, 1024); */
+/*   rc = assuan_transact (agent_ctx, line, */
+/*                         membuf_data_cb, &data,  */
+/*                         default_inq_cb, ctrl, NULL, NULL); */
+/*   if (rc) */
+/*     { */
+/*       xfree (get_membuf (&data, &len)); */
+/*       return rc; */
+/*     } */
+/*   buf = get_membuf (&data, &len); */
+/*   if (!buf) */
+/*     return gpg_error (GPG_ERR_ENOMEM); */
+/*   if (!gcry_sexp_canon_len (buf, len, NULL, NULL)) */
+/*     { */
+/*       xfree (buf); */
+/*       return gpg_error (GPG_ERR_INV_SEXP); */
+/*     } */
+/*   *r_pubkey = buf; */
+/*   return 0; */
+/* } */
+
+
+\f
+/* Call the agent to do a sign operation using the key identified by
+   the hex string KEYGRIP.  DESC is a description of the key to be
+   displayed if the agent needs to ask for the PIN.  DIGEST and
+   DIGESTLEN is the hash value to sign and DIGESTALGO the algorithm id
+   used to compute the digest.  */
+gpg_error_t
+agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
+              unsigned char *digest, size_t digestlen, int digestalgo,
+              gcry_sexp_t *r_sigval)
+{
+  gpg_error_t err;
+  int i;
+  char *p, line[ASSUAN_LINELENGTH];
+  membuf_t data;
+
+  *r_sigval = NULL;
+  err = start_agent (ctrl, 0);
+  if (err)
+    return err;
+
+  if (digestlen*2 + 50 > DIM(line))
+    return gpg_error (GPG_ERR_GENERAL);
+
+  err = assuan_transact (agent_ctx, "RESET",
+                         NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  snprintf (line, DIM(line)-1, "SIGKEY %s", keygrip);
+  line[DIM(line)-1] = 0;
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  if (desc)
+    {
+      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
+      line[DIM(line)-1] = 0;
+      err = assuan_transact (agent_ctx, line,
+                            NULL, NULL, NULL, NULL, NULL, NULL);
+      if (err)
+        return err;
+    }
+
+  snprintf (line, sizeof line, "SETHASH %d ", digestalgo);
+  p = line + strlen (line);
+  for (i=0; i < digestlen ; i++, p += 2 )
+    sprintf (p, "%02X", digest[i]);
+  err = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+  if (err)
+    return err;
+
+  init_membuf (&data, 1024);
+  err = assuan_transact (agent_ctx, "PKSIGN",
+                        membuf_data_cb, &data, default_inq_cb, ctrl,
+                        NULL, NULL);
+  if (err)
+    xfree (get_membuf (&data, NULL));
+  else
+    {
+      unsigned char *buf;
+      size_t len;
+
+      buf = get_membuf (&data, &len);
+      if (!buf)
+        err = gpg_error_from_syserror ();
+      else
+        {
+          err = gcry_sexp_sscan (r_sigval, NULL, buf, len);
+          xfree (buf);
+        }
+    }
+  return err;
+}
+
+
index 9088e4a..d42131f 100644 (file)
@@ -140,6 +140,24 @@ gpg_error_t gpg_agent_get_confirmation (const char *desc);
 /* Return the S2K iteration count as computed by gpg-agent.  */
 gpg_error_t agent_get_s2k_count (unsigned long *r_count);
 
 /* Return the S2K iteration count as computed by gpg-agent.  */
 gpg_error_t agent_get_s2k_count (unsigned long *r_count);
 
+/* Check whether a secret key with HEXKEYGRIP is available.  */
+gpg_error_t agent_havekey (ctrl_t ctrl, const char *hexkeygrip);
+
+/* Return infos about the secret key with HEXKEYGRIP.  */
+gpg_error_t agent_get_keyinfo (ctrl_t ctrl, const char *hexkeygrip,
+                               char **r_serialno);
+
+/* Generate a new key.  */
+gpg_error_t agent_genkey (ctrl_t ctrl, const char *keyparms,
+                          gcry_sexp_t *r_pubkey);
+
+/* Create a sigtnature.  */
+gpg_error_t agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
+                          unsigned char *digest, size_t digestlen,
+                          int digestalgo,
+                          gcry_sexp_t *r_sigval);
+
+
 
 #endif /*GNUPG_G10_CALL_AGENT_H*/
 
 
 #endif /*GNUPG_G10_CALL_AGENT_H*/
 
index 0723a1c..dd255a0 100644 (file)
@@ -1495,8 +1495,8 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
          the serialnumber and thus it won't harm.  */
     }
 
          the serialnumber and thus it won't harm.  */
     }
 
-  okay = generate_card_subkeypair (pub_keyblock, sec_keyblock,
-                                   keyno, info.serialno);
+  /* xxx = generate_card_subkeypair (pub_keyblock, sec_keyblock, */
+  /*                                  keyno, info.serialno); */
 
  leave:
   agent_release_card_info (&info);
 
  leave:
   agent_release_card_info (&info);
@@ -1612,17 +1612,18 @@ card_store_subkey (KBNODE node, int use)
        }
       /* We better copy the key before we unprotect it.  */
       copied_sk = sk = copy_secret_key (NULL, sk);
        }
       /* We better copy the key before we unprotect it.  */
       copied_sk = sk = copy_secret_key (NULL, sk);
-      rc = check_secret_key (sk, 0);
+      rc = 0/*check_secret_key (sk, 0)*/;
       if (rc)
         goto leave;
     }
 
       if (rc)
         goto leave;
     }
 
-  rc = save_unprotected_key_to_card (sk, keyno);
-  if (rc)
-    {
-      log_error (_("error writing key to card: %s\n"), gpg_strerror (rc));
-      goto leave;
-    }
+#warning code save_unprotected_key_to_card
+  /* rc = save_unprotected_key_to_card (sk, keyno); */
+  /* if (rc) */
+  /*   { */
+  /*     log_error (_("error writing key to card: %s\n"), gpg_strerror (rc)); */
+  /*     goto leave; */
+  /*   } */
 
   /* Get back to the maybe protected original secret key.  */
   if (copied_sk)
 
   /* Get back to the maybe protected original secret key.  */
   if (copied_sk)
index 3a4c665..34ab907 100644 (file)
@@ -550,7 +550,7 @@ do_export_stream( IOBUF out, strlist_t users, int secret,
                       ; /* Card key stub. */
                     else 
                       {
                       ; /* Card key stub. */
                     else 
                       {
-                        rc = check_secret_key( sk, 0 );
+                        /* rc = check_secret_key( sk, 0 ); */
                       }
                     break;
                   }
                       }
                     break;
                   }
index b5db65d..78d5a1e 100644 (file)
@@ -526,7 +526,7 @@ get_seckey (PKT_secret_key * sk, u32 * keyid)
     {
       /* Check the secret key (this may prompt for a passprase to
        * unlock the secret key.  */
     {
       /* Check the secret key (this may prompt for a passprase to
        * unlock the secret key.  */
-      rc = check_secret_key (sk, 0);
+      /* rc = check_secret_key (sk, 0); */
     }
 
   return rc;
     }
 
   return rc;
@@ -1111,8 +1111,8 @@ get_seckey_byname2 (GETKEY_CTX * retctx,
 
   free_strlist (namelist);
 
 
   free_strlist (namelist);
 
-  if (!rc && unprotect)
-    rc = check_secret_key (sk, 0);
+  /* if (!rc && unprotect) */
+  /*   rc = check_secret_key (sk, 0); */
 
   return rc;
 }
 
   return rc;
 }
index 013b135..1d645ea 100644 (file)
--- a/g10/gpg.h
+++ b/g10/gpg.h
@@ -108,7 +108,7 @@ struct server_control_s
 #define G10ERR_RENAME_FILE     GPG_ERR_RENAME_FILE      
 #define G10ERR_RESOURCE_LIMIT  GPG_ERR_RESOURCE_LIMIT   
 #define G10ERR_SIG_CLASS       GPG_ERR_SIG_CLASS        
 #define G10ERR_RENAME_FILE     GPG_ERR_RENAME_FILE      
 #define G10ERR_RESOURCE_LIMIT  GPG_ERR_RESOURCE_LIMIT   
 #define G10ERR_SIG_CLASS       GPG_ERR_SIG_CLASS        
-#define G10ERR_TIME_CONFLICT   GPG_ERR_TIME_CONFLICT    
+#define G10ERR_TIME_CONFLICT   GPG_ERR_TIME_CONFLICT 
 #define G10ERR_TRUSTDB         GPG_ERR_TRUSTDB          
 #define G10ERR_UNEXPECTED      GPG_ERR_UNEXPECTED       
 #define G10ERR_UNKNOWN_PACKET  GPG_ERR_UNKNOWN_PACKET   
 #define G10ERR_TRUSTDB         GPG_ERR_TRUSTDB          
 #define G10ERR_UNEXPECTED      GPG_ERR_UNEXPECTED       
 #define G10ERR_UNKNOWN_PACKET  GPG_ERR_UNKNOWN_PACKET   
index d6e49e3..ed3752f 100644 (file)
@@ -399,9 +399,9 @@ display_online_help (const char *keyword)
  * We don't use secret keys, but getkey.c links to this
  */
 int
  * We don't use secret keys, but getkey.c links to this
  */
 int
-check_secret_key (PKT_secret_key *sk, int n)
+check_secret_key (PKT_public_key *pk, int n)
 {
 {
-  (void)sk;
+  (void)pk;
   (void)n;
   return G10ERR_GENERAL;
 }
   (void)n;
   return G10ERR_GENERAL;
 }
index cb0e040..508226e 100644 (file)
@@ -286,6 +286,9 @@ byte *fingerprint_from_sk( PKT_secret_key *sk, byte *buf, size_t *ret_len );
 byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
 char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
                                 PKT_secret_key *sk);
 byte *fingerprint_from_pk( PKT_public_key *pk, byte *buf, size_t *ret_len );
 char *serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
                                 PKT_secret_key *sk);
+gpg_error_t keygrip_from_pk (PKT_public_key *pk, unsigned char *array);
+gpg_error_t hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip);
+
 
 /*-- kbnode.c --*/
 KBNODE new_kbnode( PACKET *pkt );
 
 /*-- kbnode.c --*/
 KBNODE new_kbnode( PACKET *pkt );
index a5a3be0..3ea926f 100644 (file)
@@ -1164,9 +1164,9 @@ change_passphrase (KBNODE keyblock, int *r_err)
             keyid_from_sk (sk, keyid);
             passphrase_clear_cache (keyid, NULL, 0);
 
             keyid_from_sk (sk, keyid);
             passphrase_clear_cache (keyid, NULL, 0);
 
-           rc = check_secret_key( sk, 0 );
-           if( !rc )
-               passphrase = get_last_passphrase();
+           /* rc = check_secret_key( sk, 0 ); */
+           /* if( !rc ) */
+           /*     passphrase = get_last_passphrase(); */
        }
        break;
     }
        }
        break;
     }
@@ -1179,9 +1179,9 @@ change_passphrase (KBNODE keyblock, int *r_err)
                    && (subsk->protect.s2k.mode == 1001 
                        || subsk->protect.s2k.mode == 1002))) {
                 set_next_passphrase( passphrase );
                    && (subsk->protect.s2k.mode == 1001 
                        || subsk->protect.s2k.mode == 1002))) {
                 set_next_passphrase( passphrase );
-                rc = check_secret_key( subsk, 0 );
-                if( !rc && !passphrase )
-                    passphrase = get_last_passphrase();
+                /* rc = check_secret_key( subsk, 0 ); */
+                /* if( !rc && !passphrase ) */
+                /*     passphrase = get_last_passphrase(); */
             }
        }
     }
             }
        }
     }
@@ -1227,7 +1227,9 @@ change_passphrase (KBNODE keyblock, int *r_err)
                if( !no_primary_secrets ) {
                    sk->protect.algo = dek->algo;
                    sk->protect.s2k = *s2k;
                if( !no_primary_secrets ) {
                    sk->protect.algo = dek->algo;
                    sk->protect.s2k = *s2k;
-                   rc = protect_secret_key( sk, dek );
+#warning fixme
+                    rc = 0;
+                   /* rc = protect_secret_key( sk, dek ); */
                }
                for(node=keyblock; !rc && node; node = node->next ) {
                    if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
                }
                for(node=keyblock; !rc && node; node = node->next ) {
                    if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
@@ -1237,7 +1239,9 @@ change_passphrase (KBNODE keyblock, int *r_err)
                                    || subsk->protect.s2k.mode == 1002))) {
                             subsk->protect.algo = dek->algo;
                             subsk->protect.s2k = *s2k;
                                    || subsk->protect.s2k.mode == 1002))) {
                             subsk->protect.algo = dek->algo;
                             subsk->protect.s2k = *s2k;
-                            rc = protect_secret_key( subsk, dek );
+#warning fixme
+                            rc = 0;
+                            /* rc = protect_secret_key( subsk, dek ); */
                         }
                    }
                }
                         }
                    }
                }
@@ -1892,12 +1896,13 @@ keyedit_menu( const char *username, strlist_t locusr,
            break;
 
          case cmdADDKEY:
            break;
 
          case cmdADDKEY:
-           if( generate_subkeypair( keyblock, sec_keyblock ) ) {
+           if (!generate_subkeypair (keyblock))
+              {
                redisplay = 1;
                sec_modified = modified = 1;
                merge_keys_and_selfsig( sec_keyblock );
                merge_keys_and_selfsig( keyblock );
                redisplay = 1;
                sec_modified = modified = 1;
                merge_keys_and_selfsig( sec_keyblock );
                merge_keys_and_selfsig( keyblock );
-           }
+              }
            break;
 
 #ifdef ENABLE_CARD_SUPPORT
            break;
 
 #ifdef ENABLE_CARD_SUPPORT
@@ -2018,8 +2023,8 @@ keyedit_menu( const char *username, strlist_t locusr,
                     if (sk->protect.s2k.mode == 1002)
                       tty_printf (_("Secret parts of key"
                                     " are stored on-card.\n"));
                     if (sk->protect.s2k.mode == 1002)
                       tty_printf (_("Secret parts of key"
                                     " are stored on-card.\n"));
-                    else
-                      check_secret_key (sk, 0);
+                    /* else */
+                    /*   check_secret_key (sk, 0); */
                   }
               }
             else /* Store it.  */
                   }
               }
             else /* Store it.  */
index 836b559..89f5e03 100644 (file)
@@ -132,15 +132,12 @@ static int mdc_available,ks_modify;
 
 static void do_generate_keypair( struct para_data_s *para,
                                 struct output_control_s *outctrl, int card );
 
 static void do_generate_keypair( struct para_data_s *para,
                                 struct output_control_s *outctrl, int card );
-static int  write_keyblock( IOBUF out, KBNODE node );
-static int gen_card_key (int algo, int keyno, int is_primary,
-                         KBNODE pub_root, KBNODE sec_root,
-                        PKT_secret_key **ret_sk,
-                         u32 *timestamp,
-                         u32 expireval, struct para_data_s *para);
+static int write_keyblock (iobuf_t out, kbnode_t node);
+static int gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
+                         u32 *timestamp, u32 expireval,
+                         struct para_data_s *para);
 static int gen_card_key_with_backup (int algo, int keyno, int is_primary,
 static int gen_card_key_with_backup (int algo, int keyno, int is_primary,
-                                     KBNODE pub_root, KBNODE sec_root,
-                                     u32 timestamp,
+                                     kbnode_t pub_root, u32 timestamp,
                                      u32 expireval, struct para_data_s *para,
                                      const char *backup_dir);
 
                                      u32 expireval, struct para_data_s *para,
                                      const char *backup_dir);
 
@@ -227,43 +224,46 @@ do_add_key_flags (PKT_signature *sig, unsigned int use)
 
 
 int
 
 
 int
-keygen_add_key_expire( PKT_signature *sig, void *opaque )
+keygen_add_key_expire (PKT_signature *sig, void *opaque)
 {
 {
-    PKT_public_key *pk = opaque;
-    byte buf[8];
-    u32  u;
-
-    if( pk->expiredate ) {
-        if(pk->expiredate > pk->timestamp)
-         u= pk->expiredate - pk->timestamp;
-       else
-         u= 1;
-
-       buf[0] = (u >> 24) & 0xff;
-       buf[1] = (u >> 16) & 0xff;
-       buf[2] = (u >>  8) & 0xff;
-       buf[3] = u & 0xff;
-       build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 );
+  PKT_public_key *pk = opaque;
+  byte buf[8];
+  u32  u;
+  
+  if (pk->expiredate)
+    {
+      if (pk->expiredate > pk->timestamp)
+        u = pk->expiredate - pk->timestamp;
+      else
+        u = 1;
+      
+      buf[0] = (u >> 24) & 0xff;
+      buf[1] = (u >> 16) & 0xff;
+      buf[2] = (u >>   8) & 0xff;
+      buf[3] = u & 0xff;
+      build_sig_subpkt (sig, SIGSUBPKT_KEY_EXPIRE, buf, 4);
+    }
+  else
+    {
+      /* Make sure we don't leave a key expiration subpacket lying
+         around */
+      delete_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE);
     }
     }
-    else
-      {
-       /* Make sure we don't leave a key expiration subpacket lying
-          around */
-       delete_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE);
-      }
 
 
-    return 0;
+  return 0;
 }
 
 }
 
+
 static int
 keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque)
 {
 static int
 keygen_add_key_flags_and_expire (PKT_signature *sig, void *opaque)
 {
-    struct opaque_data_usage_and_pk *oduap = opaque;
-
-    do_add_key_flags (sig, oduap->usage);
-    return keygen_add_key_expire (sig, oduap->pk);
+  struct opaque_data_usage_and_pk *oduap = opaque;
+  
+  do_add_key_flags (sig, oduap->usage);
+  return keygen_add_key_expire (sig, oduap->pk);
 }
 
 }
 
+
 static int
 set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf)
 {
 static int
 set_one_pref (int val, int type, const char *item, byte *buf, int *nbuf)
 {
@@ -697,19 +697,18 @@ keygen_upd_std_prefs (PKT_signature *sig, void *opaque)
 /****************
  * Add preference to the self signature packet.
  * This is only called for packets with version > 3.
 /****************
  * Add preference to the self signature packet.
  * This is only called for packets with version > 3.
-
  */
 int
  */
 int
-keygen_add_std_prefs( PKT_signature *sig, void *opaque )
+keygen_add_std_prefs (PKT_signature *sig, void *opaque)
 {
 {
-    PKT_public_key *pk = opaque;
-
-    do_add_key_flags (sig, pk->pubkey_usage);
-    keygen_add_key_expire( sig, opaque );
-    keygen_upd_std_prefs (sig, opaque);
-    keygen_add_keyserver_url(sig,NULL);
-
-    return 0;
+  PKT_public_key *pk = opaque;
+  
+  do_add_key_flags (sig, pk->pubkey_usage);
+  keygen_add_key_expire (sig, opaque );
+  keygen_upd_std_prefs (sig, opaque);
+  keygen_add_keyserver_url (sig,NULL);
+  
+  return 0;
 }
 
 int
 }
 
 int
@@ -778,23 +777,23 @@ keygen_add_notations(PKT_signature *sig,void *opaque)
 }
 
 int
 }
 
 int
-keygen_add_revkey(PKT_signature *sig, void *opaque)
+keygen_add_revkey (PKT_signature *sig, void *opaque)
 {
 {
-  struct revocation_key *revkey=opaque;
+  struct revocation_key *revkey = opaque;
   byte buf[2+MAX_FINGERPRINT_LEN];
 
   byte buf[2+MAX_FINGERPRINT_LEN];
 
-  buf[0]=revkey->class;
-  buf[1]=revkey->algid;
-  memcpy(&buf[2],revkey->fpr,MAX_FINGERPRINT_LEN);
+  buf[0] = revkey->class;
+  buf[1] = revkey->algid;
+  memcpy (&buf[2], revkey->fpr, MAX_FINGERPRINT_LEN);
 
 
-  build_sig_subpkt(sig,SIGSUBPKT_REV_KEY,buf,2+MAX_FINGERPRINT_LEN);
+  build_sig_subpkt (sig, SIGSUBPKT_REV_KEY, buf, 2+MAX_FINGERPRINT_LEN);
 
 
-  /* All sigs with revocation keys set are nonrevocable */
-  sig->flags.revocable=0;
+  /* All sigs with revocation keys set are nonrevocable */
+  sig->flags.revocable = 0;
   buf[0] = 0;
   buf[0] = 0;
-  build_sig_subpkt( sig, SIGSUBPKT_REVOCABLE, buf, 1 );
+  build_sig_subpkt (sig, SIGSUBPKT_REVOCABLE, buf, 1);
 
 
-  parse_revkeys(sig);
+  parse_revkeys (sig);
 
   return 0;
 }
 
   return 0;
 }
@@ -803,115 +802,118 @@ keygen_add_revkey(PKT_signature *sig, void *opaque)
 
 /* Create a back-signature.  If TIMESTAMP is not NULL, use it for the
    signature creation time.  */
 
 /* Create a back-signature.  If TIMESTAMP is not NULL, use it for the
    signature creation time.  */
-int
-make_backsig (PKT_signature *sig,PKT_public_key *pk,
-              PKT_public_key *sub_pk,PKT_secret_key *sub_sk,
+gpg_error_t
+make_backsig (PKT_signature *sig, PKT_public_key *pk,
+              PKT_public_key *sub_pk, PKT_public_key *sub_psk,
               u32 timestamp)
 {
               u32 timestamp)
 {
+  gpg_error_t err;
   PKT_signature *backsig;
   PKT_signature *backsig;
-  int rc;
 
 
-  cache_public_key(sub_pk);
+  cache_public_key (sub_pk);
 
 
-  rc = make_keysig_packet (&backsig, pk, NULL, sub_pk, sub_sk, 0x19,
-                           0, 0, timestamp, 0, NULL, NULL);
-  if(rc)
-    log_error("make_keysig_packet failed for backsig: %s\n",g10_errstr(rc));
+  err = make_keysig_packet (&backsig, pk, NULL, sub_pk, sub_psk, 0x19,
+                            0, 0, timestamp, 0, NULL, NULL);
+  if (err)
+    log_error ("make_keysig_packet failed for backsig: %s\n", g10_errstr(err));
   else
     {
       /* Get it into a binary packed form. */
   else
     {
       /* Get it into a binary packed form. */
-      IOBUF backsig_out=iobuf_temp();
+      IOBUF backsig_out = iobuf_temp();
       PACKET backsig_pkt;
  
       PACKET backsig_pkt;
  
-      init_packet(&backsig_pkt);
-      backsig_pkt.pkttype=PKT_SIGNATURE;
-      backsig_pkt.pkt.signature=backsig;
-      rc=build_packet(backsig_out,&backsig_pkt);
-      free_packet(&backsig_pkt);
-      if(rc)
-       log_error("build_packet failed for backsig: %s\n",g10_errstr(rc));
+      init_packet (&backsig_pkt);
+      backsig_pkt.pkttype = PKT_SIGNATURE;
+      backsig_pkt.pkt.signature = backsig;
+      err = build_packet (backsig_out, &backsig_pkt);
+      free_packet (&backsig_pkt);
+      if (err)
+       log_error ("build_packet failed for backsig: %s\n", g10_errstr(err));
       else
        {
       else
        {
-         size_t pktlen=0;
-         byte *buf=iobuf_get_temp_buffer(backsig_out);
+         size_t pktlen = 0;
+         byte *buf = iobuf_get_temp_buffer (backsig_out);
  
  
-         /* Remove the packet header */
+         /* Remove the packet header. */
          if(buf[0]&0x40)
            {
          if(buf[0]&0x40)
            {
-             if(buf[1]<192)
+             if (buf[1] < 192)
                {
                {
-                 pktlen=buf[1];
-                 buf+=2;
-               }
-             else if(buf[1]<224)
+                 pktlen = buf[1];
+                 buf += 2; 
+               } 
+             else if(buf[1] < 224)
                {
                {
-                 pktlen=(buf[1]-192)*256;
-                 pktlen+=buf[2]+192;
-                 buf+=3;
+                 pktlen = (buf[1]-192)*256;
+                 pktlen += buf[2]+192;
+                 buf += 3;
                }
                }
-             else if(buf[1]==255)
+             else if (buf[1] == 255)
                {
                {
-                 pktlen =buf[2] << 24;
-                 pktlen|=buf[3] << 16;
-                 pktlen|=buf[4] << 8;
-                 pktlen|=buf[5];
-                 buf+=6;
+                 pktlen  = buf[2] << 24;
+                 pktlen |= buf[3] << 16;
+                 pktlen |= buf[4] << 8;
+                 pktlen |= buf[5];
+                 buf += 6;
                }
              else
                }
              else
-               BUG();
+               BUG ();
            }
          else
            {
            }
          else
            {
-             int mark=1;
+             int mark = 1;
  
  
-             switch(buf[0]&3)
+             switch (buf[0]&3)
                {
                case 3:
                {
                case 3:
-                 BUG();
+                 BUG ();
                  break;
  
                case 2:
                  break;
  
                case 2:
-                 pktlen =buf[mark++] << 24;
-                 pktlen|=buf[mark++] << 16;
+                 pktlen  = buf[mark++] << 24;
+                 pktlen |= buf[mark++] << 16;
  
                case 1:
  
                case 1:
-                 pktlen|=buf[mark++] << 8;
+                 pktlen |= buf[mark++] << 8;
  
                case 0:
  
                case 0:
-                 pktlen|=buf[mark++];
+                 pktlen |= buf[mark++];
                }
  
                }
  
-             buf+=mark;
+             buf += mark;
            }
  
          /* Now make the binary blob into a subpacket.  */
            }
  
          /* Now make the binary blob into a subpacket.  */
-         build_sig_subpkt(sig,SIGSUBPKT_SIGNATURE,buf,pktlen);
+         build_sig_subpkt (sig, SIGSUBPKT_SIGNATURE, buf, pktlen);
 
 
-         iobuf_close(backsig_out);
+         iobuf_close (backsig_out);
        }
     }
        }
     }
-  return rc;
+  
+  return err;
 }
 
 
 }
 
 
-static int
-write_direct_sig (KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
-                 struct revocation_key *revkey, u32 timestamp)
+/* Write a direct key signature to the first key in ROOT using the key
+   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,
+                  struct revocation_key *revkey, u32 timestamp)
 {
 {
+  gpg_error_t err;
   PACKET *pkt;
   PKT_signature *sig;
   PACKET *pkt;
   PKT_signature *sig;
-  int rc=0;
   KBNODE node;
   PKT_public_key *pk;
 
   KBNODE node;
   PKT_public_key *pk;
 
-  if( opt.verbose )
-    log_info(_("writing direct signature\n"));
+  if (opt.verbose)
+    log_info (_("writing direct signature\n"));
 
   /* Get the pk packet from the pub_tree. */
 
   /* Get the pk packet from the pub_tree. */
-  node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
-  if( !node )
-    BUG();
+  node = find_kbnode (root, PKT_PUBLIC_KEY);
+  if (!node)
+    BUG ();
   pk = node->pkt->pkt.public_key;
 
   /* We have to cache the key, so that the verification of the
   pk = node->pkt->pkt.public_key;
 
   /* We have to cache the key, so that the verification of the
@@ -919,48 +921,54 @@ write_direct_sig (KBNODE root, KBNODE pub_root, PKT_secret_key *sk,
   cache_public_key (pk);
 
   /* Make the signature.  */
   cache_public_key (pk);
 
   /* Make the signature.  */
-  rc = make_keysig_packet (&sig,pk,NULL,NULL,sk,0x1F,
-                           0, 0, timestamp, 0,
-                           keygen_add_revkey, revkey);
-  if( rc )
+  err = make_keysig_packet (&sig, pk, NULL,NULL, psk, 0x1F,
+                            0, 0, timestamp, 0,
+                            keygen_add_revkey, revkey);
+  if (err)
     {
     {
-      log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
-      return rc;
+      log_error ("make_keysig_packet failed: %s\n", g10_errstr (err) );
+      return err;
     }
   
     }
   
-  pkt = xmalloc_clear( sizeof *pkt );
+  pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
-  add_kbnode( root, new_kbnode( pkt ) );
-  return rc;
+  add_kbnode (root, new_kbnode (pkt));
+  return err;
 }
 
 
 }
 
 
-static int
-write_selfsigs( KBNODE sec_root, KBNODE pub_root, PKT_secret_key *sk,
-               unsigned int use, u32 timestamp )
+
+/* Write a self-signature to the first user id in ROOT using the key
+   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,
+               unsigned int use, u32 timestamp)
 {
 {
+  gpg_error_t err;
   PACKET *pkt;
   PKT_signature *sig;
   PKT_user_id *uid;
   PACKET *pkt;
   PKT_signature *sig;
   PKT_user_id *uid;
-  int rc=0;
   KBNODE node;
   PKT_public_key *pk;
 
   KBNODE node;
   PKT_public_key *pk;
 
-  if( opt.verbose )
-    log_info(_("writing self signature\n"));
+  if (opt.verbose)
+    log_info (_("writing self signature\n"));
 
   /* Get the uid packet from the list. */
 
   /* Get the uid packet from the list. */
-  node = find_kbnode( pub_root, PKT_USER_ID );
-  if( !node )
+  node = find_kbnode (root, PKT_USER_ID);
+  if (!node)
     BUG(); /* No user id packet in tree.  */
   uid = node->pkt->pkt.user_id;
 
   /* Get the pk packet from the pub_tree. */
     BUG(); /* No user id packet in tree.  */
   uid = node->pkt->pkt.user_id;
 
   /* Get the pk packet from the pub_tree. */
-  node = find_kbnode( pub_root, PKT_PUBLIC_KEY );
-  if( !node )
+  node = find_kbnode (root, PKT_PUBLIC_KEY);
+  if (!node)
     BUG();
   pk = node->pkt->pkt.public_key;
     BUG();
   pk = node->pkt->pkt.public_key;
+
+  /* The usage has not yet been set - do it now. */
   pk->pubkey_usage = use;
  
   /* We have to cache the key, so that the verification of the
   pk->pubkey_usage = use;
  
   /* We have to cache the key, so that the verification of the
@@ -968,48 +976,45 @@ write_selfsigs( KBNODE sec_root, KBNODE pub_root, PKT_secret_key *sk,
   cache_public_key (pk);
 
   /* Make the signature.  */
   cache_public_key (pk);
 
   /* Make the signature.  */
-  rc = make_keysig_packet (&sig, pk, uid, NULL, sk, 0x13,
-                           0, 0, timestamp, 0,
-                           keygen_add_std_prefs, pk);
-  if( rc 
+  err = make_keysig_packet (&sig, pk, uid, NULL, psk, 0x13,
+                            0, 0, timestamp, 0,
+                            keygen_add_std_prefs, pk);
+  if (err
     {
     {
-      log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
-      return rc;
+      log_error ("make_keysig_packet failed: %s\n", g10_errstr (err));
+      return err;
     }
 
     }
 
-  pkt = xmalloc_clear( sizeof *pkt );
+  pkt = xmalloc_clear (sizeof *pkt);
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
-  add_kbnode( sec_root, new_kbnode( pkt ) );
+  add_kbnode (root, new_kbnode (pkt));
 
 
-  pkt = xmalloc_clear( sizeof *pkt );
-  pkt->pkttype = PKT_SIGNATURE;
-  pkt->pkt.signature = copy_signature(NULL,sig);
-  add_kbnode( pub_root, new_kbnode( pkt ) );
-  return rc;
+  return err;
 }
 
 
 /* Write the key binding signature.  If TIMESTAMP is not NULL use the
 }
 
 
 /* Write the key binding signature.  If TIMESTAMP is not NULL use the
-   signature creation times.  */
+   signature creation time.  PRI_PSK is the key use for signing.
+   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
 static int
-write_keybinding (KBNODE root, KBNODE pub_root,
-                 PKT_secret_key *pri_sk, PKT_secret_key *sub_sk,
+write_keybinding (KBNODE root, PKT_public_key *pri_psk, PKT_public_key *sub_psk,
                   unsigned int use, u32 timestamp)
 {
                   unsigned int use, u32 timestamp)
 {
+  gpg_error_t err;
   PACKET *pkt;
   PKT_signature *sig;
   PACKET *pkt;
   PKT_signature *sig;
-  int rc=0;
   KBNODE node;
   PKT_public_key *pri_pk, *sub_pk;
   struct opaque_data_usage_and_pk oduap;
 
   KBNODE node;
   PKT_public_key *pri_pk, *sub_pk;
   struct opaque_data_usage_and_pk oduap;
 
-  if ( opt.verbose )
+  if (opt.verbose)
     log_info(_("writing key binding signature\n"));
 
     log_info(_("writing key binding signature\n"));
 
-  /* Get the pk packet from the pub_tree.  */
-  node = find_kbnode ( pub_root, PKT_PUBLIC_KEY );
-  if ( !node )
+  /* Get the primary pk packet from the tree.  */
+  node = find_kbnode (root, PKT_PUBLIC_KEY);
+  if (!node)
     BUG();
   pri_pk = node->pkt->pkt.public_key;
 
     BUG();
   pri_pk = node->pkt->pkt.public_key;
 
@@ -1019,9 +1024,9 @@ write_keybinding (KBNODE root, KBNODE pub_root,
  
   /* Find the last subkey. */
   sub_pk = NULL;
  
   /* Find the last subkey. */
   sub_pk = NULL;
-  for (node=pub_root; node; node = node->next ) 
+  for (node = root; node; node = node->next ) 
     {
     {
-      if ( node->pkt->pkttype == PKT_PUBLIC_SUBKEY )
+      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
         sub_pk = node->pkt->pkt.public_key;
     }
   if (!sub_pk)
         sub_pk = node->pkt->pkt.public_key;
     }
   if (!sub_pk)
@@ -1030,28 +1035,28 @@ write_keybinding (KBNODE root, KBNODE pub_root,
   /* Make the signature.  */
   oduap.usage = use;
   oduap.pk = sub_pk;
   /* Make the signature.  */
   oduap.usage = use;
   oduap.pk = sub_pk;
-  rc = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_sk, 0x18, 
-                           0, 0, timestamp, 0,
-                           keygen_add_key_flags_and_expire, &oduap );
-  if (rc
+  err = make_keysig_packet (&sig, pri_pk, NULL, sub_pk, pri_psk, 0x18, 
+                            0, 0, timestamp, 0,
+                            keygen_add_key_flags_and_expire, &oduap);
+  if (err
     {
     {
-      log_error ("make_keysig_packet failed: %s\n", g10_errstr(rc) );
-      return rc;
+      log_error ("make_keysig_packet failed: %s\n", g10_errstr (err));
+      return err;
     }
 
   /* Make a backsig.  */
     }
 
   /* Make a backsig.  */
-  if (use&PUBKEY_USAGE_SIG)
+  if (use & PUBKEY_USAGE_SIG)
     {
     {
-      rc = make_backsig (sig, pri_pk, sub_pk, sub_sk, timestamp);
-      if (rc)
-        return rc;
+      err = make_backsig (sig, pri_pk, sub_pk, sub_psk, timestamp);
+      if (err)
+        return err;
     }
   
   pkt = xmalloc_clear ( sizeof *pkt );
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
   add_kbnode (root, new_kbnode (pkt) );
     }
   
   pkt = xmalloc_clear ( sizeof *pkt );
   pkt->pkttype = PKT_SIGNATURE;
   pkt->pkt.signature = sig;
   add_kbnode (root, new_kbnode (pkt) );
-  return rc;
+  return err;
 }
 
 
 }
 
 
@@ -1106,71 +1111,76 @@ key_from_sexp (gcry_mpi_t *array, gcry_sexp_t sexp,
 }
 
 
 }
 
 
+
+/* Common code for the key generation fucntion gen_xxx.  */
 static int
 static int
-genhelp_protect (DEK *dek, STRING2KEY *s2k, PKT_secret_key *sk)
+common_gen (const char *keyparms, int algo, const char *algoelem,
+            kbnode_t pub_root, u32 timestamp, u32 expireval, int is_subkey)
 {
 {
-  int rc = 0;
-
-  if (dek)
+  int err;
+  PACKET *pkt;
+  PKT_public_key *pk;
+  gcry_sexp_t s_key;
+  
+  err = agent_genkey (NULL, keyparms, &s_key);
+  if (err)
+    {
+      log_error ("agent_genkey failed: %s\n", gpg_strerror (err) );
+      return err;
+    }
+  
+  pk = xtrycalloc (1, sizeof *pk);
+  if (!pk)
     {
     {
-      sk->protect.algo = dek->algo;
-      sk->protect.s2k = *s2k;
-      rc = protect_secret_key (sk, dek);
-      if (rc)
-        log_error ("protect_secret_key failed: %s\n", gpg_strerror (rc) );
+      err = gpg_error_from_syserror ();
+      gcry_sexp_release (s_key);
+      return err;
     }
 
     }
 
-  return rc;
-}
+  pk->timestamp = timestamp;
+  pk->version = 4;
+  if (expireval) 
+    pk->expiredate = pk->timestamp + expireval;
+  pk->pubkey_algo = algo;
 
 
-static void
-genhelp_factors (gcry_sexp_t misc_key_info, KBNODE sec_root)
-{
-  (void)misc_key_info;
-  (void)sec_root;
-#if 0 /* Not used anymore */
-  size_t n;
-  char *buf;
+  err = key_from_sexp (pk->pkey, s_key, "public-key", algoelem);
+  if (err) 
+    {
+      log_error ("key_from_sexp failed: %s\n", gpg_strerror (err) );
+      gcry_sexp_release (s_key);
+      free_public_key (pk);
+      return err;
+    }
+  gcry_sexp_release (s_key);
   
   
-  if (misc_key_info)
+  pkt = xtrycalloc (1, sizeof *pkt);
+  if (!pkt)
     {
     {
-      /* DSA: don't know whether it makes sense to have the factors, so for now
-         we store them in the secret keyring (but they are not secret)
-         p = 2 * q * f1 * f2 * ... * fn
-         We store only f1 to f_n-1;  fn can be calculated because p and q
-         are known. */
-      n = gcry_sexp_sprint (misc_key_info, 0, NULL, 0);
-      buf = xmalloc (n+4);
-      strcpy (buf, "#::");
-      n = gcry_sexp_sprint (misc_key_info, 0, buf+3, n);
-      if (n)
-        {
-          n += 3;
-          add_kbnode (sec_root, make_comment_node_from_buffer (buf, n));
-        }
-      xfree (buf);
-      gcry_sexp_release (misc_key_info);
+      err = gpg_error_from_syserror ();
+      free_public_key (pk);
+      return err;
     }
     }
-#endif
+
+  pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
+  pkt->pkt.public_key = pk;
+  add_kbnode (pub_root, new_kbnode (pkt));
+
+  return 0;
 }
 
 
 }
 
 
-/* Generate an Elgamal encryption key pair. TIMESTAMP is the creatuion
-   time to be put into the key structure.  */
+/*
+ * Generate an Elgamal key.
+ */
 static int
 static int
-gen_elg (int algo, unsigned int nbits,
-         KBNODE pub_root, KBNODE sec_root, DEK *dek,
-         STRING2KEY *s2k, PKT_secret_key **ret_sk, 
+gen_elg (int algo, unsigned int nbits, KBNODE pub_root,
          u32 timestamp, u32 expireval, int is_subkey)
 {
          u32 timestamp, u32 expireval, int is_subkey)
 {
-  int rc;
-  PACKET *pkt;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
-  gcry_sexp_t s_parms, s_key;
-  gcry_sexp_t misc_key_info;
+  int err;
+  char *keyparms;
+  char nbitsstr[35];
   
   
-  assert( is_ELGAMAL(algo) );
+  assert (is_ELGAMAL (algo));
 
   if (nbits < 512)
     {
 
   if (nbits < 512)
     {
@@ -1184,104 +1194,36 @@ gen_elg (int algo, unsigned int nbits,
       log_info (_("keysize rounded up to %u bits\n"), nbits );
     }
 
       log_info (_("keysize rounded up to %u bits\n"), nbits );
     }
 
-
-  rc = gcry_sexp_build ( &s_parms, NULL,
-                         "(genkey(%s(nbits %d)))",
-                         algo == GCRY_PK_ELG_E ? "openpgp-elg" :
-                         algo == GCRY_PK_ELG    ? "elg" : "x-oops" ,
-                         (int)nbits);
-  if (rc)
-    log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
-  
-  rc = gcry_pk_genkey (&s_key, s_parms);
-  gcry_sexp_release (s_parms);
-  if (rc)
-    {
-      log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
-      return rc;
-    }
-  
-  sk = xmalloc_clear( sizeof *sk );
-  pk = xmalloc_clear( sizeof *pk );
-  sk->timestamp = pk->timestamp = timestamp;
-  sk->version = pk->version = 4;
-  if (expireval) 
-    {
-      sk->expiredate = pk->expiredate = sk->timestamp + expireval;
-    }
-  sk->pubkey_algo = pk->pubkey_algo = algo;
-
-  rc = key_from_sexp (pk->pkey, s_key, "public-key", "pgy");
-  if (rc) 
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
-      gcry_sexp_release (s_key);
-      free_secret_key (sk);
-      free_public_key (pk);
-      return rc;
-    }
-  rc = key_from_sexp (sk->skey, s_key, "private-key", "pgyx");
-  if (rc)
-    {
-      log_error("key_from_sexp failed: %s\n", gpg_strerror (rc) );
-      gcry_sexp_release (s_key);
-      free_secret_key (sk);
-      free_public_key (pk);
-      return rc;
-    }
-  misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0);
-  gcry_sexp_release (s_key);
-  
-  sk->is_protected = 0;
-  sk->protect.algo = 0;
-
-  sk->csum = checksum_mpi (sk->skey[3]);
-  if (ret_sk) /* Return an unprotected version of the sk.  */
-    *ret_sk = copy_secret_key ( NULL, sk );
-
-  rc = genhelp_protect (dek, s2k, sk);
-  if (rc)
+  snprintf (nbitsstr, sizeof nbitsstr, "%u", nbits);
+  keyparms = xtryasprintf ("(genkey(%s(nbits %zu:%s)))",
+                           algo == GCRY_PK_ELG_E ? "openpgp-elg" :
+                           algo == GCRY_PK_ELG  ? "elg" : "x-oops" ,
+                           strlen (nbitsstr), nbitsstr);
+  if (!keyparms)
+    err = gpg_error_from_syserror ();
+  else
     {
     {
-      free_public_key (pk);
-      free_secret_key (sk);
-      gcry_sexp_release (misc_key_info);
-      return rc;
+      err = common_gen (keyparms, algo, "pgy", 
+                        pub_root, timestamp, expireval, is_subkey);
+      xfree (keyparms);
     }
     }
-  
-  pkt = xmalloc_clear (sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
-  pkt->pkt.public_key = pk;
-  add_kbnode (pub_root, new_kbnode( pkt ));
 
 
-  /* Don't know whether it makes sense to have access to the factors,
-     so for now we store them in the secret keyring (but they are not
-     secret).  */
-  pkt = xmalloc_clear (sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
-  pkt->pkt.secret_key = sk;
-  add_kbnode (sec_root, new_kbnode( pkt ));
-  
-  genhelp_factors (misc_key_info, sec_root);
-  
-  return 0;
+  return err;
 }
 
 
 }
 
 
-/****************
- * Generate a DSA key
+/*
+ * Generate an DSA key
  */
  */
-static int
-gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
-         STRING2KEY *s2k, PKT_secret_key **ret_sk, 
+static gpg_error_t
+gen_dsa (unsigned int nbits, KBNODE pub_root, 
          u32 timestamp, u32 expireval, int is_subkey)
 {
          u32 timestamp, u32 expireval, int is_subkey)
 {
-  int rc;
-  PACKET *pkt;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
-  gcry_sexp_t s_parms, s_key;
-  gcry_sexp_t misc_key_info;
+  int err;
   unsigned int qbits;
   unsigned int qbits;
+  char *keyparms;
+  char nbitsstr[35];
+  char qbitsstr[35];
 
   if ( nbits < 512) 
     {
 
   if ( nbits < 512) 
     {
@@ -1334,84 +1276,21 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
     log_info (_("WARNING: some OpenPGP programs can't"
                 " handle a DSA key with this digest size\n"));
 
     log_info (_("WARNING: some OpenPGP programs can't"
                 " handle a DSA key with this digest size\n"));
 
-  rc = gcry_sexp_build (&s_parms, NULL,
-                        "(genkey(dsa(nbits %d)(qbits %d)))",
-                        (int)nbits, (int)qbits);
-  if (rc)
-    log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
-  
-  rc = gcry_pk_genkey (&s_key, s_parms);
-  gcry_sexp_release (s_parms);
-  if (rc)
-    {
-      log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
-      return rc;
-    }
-
-  sk = xmalloc_clear( sizeof *sk );
-  pk = xmalloc_clear( sizeof *pk );
-  sk->timestamp = pk->timestamp = timestamp;
-  sk->version = pk->version = 4;
-  if (expireval) 
-    sk->expiredate = pk->expiredate = sk->timestamp + expireval;
-  sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA;
-
-  rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy");
-  if (rc) 
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc));
-      gcry_sexp_release (s_key);
-      free_public_key(pk);
-      free_secret_key(sk);
-      return rc;
-    }
-  rc = key_from_sexp (sk->skey, s_key, "private-key", "pqgyx");
-  if (rc) 
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
-      gcry_sexp_release (s_key);
-      free_public_key(pk);
-      free_secret_key(sk);
-      return rc;
-    }
-  misc_key_info = gcry_sexp_find_token (s_key, "misc-key-info", 0);
-  gcry_sexp_release (s_key);
-  
-  sk->is_protected = 0;
-  sk->protect.algo = 0;
-
-  sk->csum = checksum_mpi ( sk->skey[4] );
-  if( ret_sk ) /* return an unprotected version of the sk */
-    *ret_sk = copy_secret_key( NULL, sk );
-
-  rc = genhelp_protect (dek, s2k, sk);
-  if (rc)
+  snprintf (nbitsstr, sizeof nbitsstr, "%u", nbits);
+  snprintf (qbitsstr, sizeof qbitsstr, "%u", qbits);
+  keyparms = xtryasprintf ("(genkey(dsa(nbits %zu:%s)(qbits %zu:%s)))",
+                           strlen (nbitsstr), nbitsstr,
+                           strlen (qbitsstr), qbitsstr);
+  if (!keyparms)
+    err = gpg_error_from_syserror ();
+  else
     {
     {
-      free_public_key (pk);
-      free_secret_key (sk);
-      gcry_sexp_release (misc_key_info);
-      return rc;
+      err = common_gen (keyparms, PUBKEY_ALGO_DSA, "pqgy", 
+                        pub_root, timestamp, expireval, is_subkey);
+      xfree (keyparms);
     }
 
     }
 
-  pkt = xmalloc_clear(sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
-  pkt->pkt.public_key = pk;
-  add_kbnode(pub_root, new_kbnode( pkt ));
-
-  /* Don't know whether it makes sense to have the factors, so for now
-   * we store them in the secret keyring (but they are not secret)
-   * p = 2 * q * f1 * f2 * ... * fn
-   * We store only f1 to f_n-1;  fn can be calculated because p and q
-   * are known.
-   */
-  pkt = xmalloc_clear(sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
-  pkt->pkt.secret_key = sk;
-  add_kbnode(sec_root, new_kbnode( pkt ));
-
-  genhelp_factors (misc_key_info, sec_root);
-
-  return 0;
+  return err;
 }
 
 
 }
 
 
@@ -1419,15 +1298,12 @@ gen_dsa (unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
  * Generate an RSA key.
  */
 static int
  * Generate an RSA key.
  */
 static int
-gen_rsa (int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
-         STRING2KEY *s2k, PKT_secret_key **ret_sk,
+gen_rsa (int algo, unsigned int nbits, KBNODE pub_root,
          u32 timestamp, u32 expireval, int is_subkey)
 {
          u32 timestamp, u32 expireval, int is_subkey)
 {
-  int rc;
-  PACKET *pkt;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
-  gcry_sexp_t s_parms, s_key;
+  int err;
+  char *keyparms;
+  char nbitsstr[35];
 
   assert (is_RSA(algo));
 
 
   assert (is_RSA(algo));
 
@@ -1446,79 +1322,19 @@ gen_rsa (int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
       log_info (_("keysize rounded up to %u bits\n"), nbits );
     }
 
       log_info (_("keysize rounded up to %u bits\n"), nbits );
     }
 
-  rc = gcry_sexp_build (&s_parms, NULL,
-                        "(genkey(rsa(nbits %d)))",
-                        (int)nbits);
-  if (rc)
-    log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
-  
-  rc = gcry_pk_genkey (&s_key, s_parms);
-  gcry_sexp_release (s_parms);
-  if (rc)
-    {
-      log_error ("gcry_pk_genkey failed: %s\n", gpg_strerror (rc) );
-      return rc;
-    }
-
-  sk = xmalloc_clear( sizeof *sk );
-  pk = xmalloc_clear( sizeof *pk );
-  sk->timestamp = pk->timestamp = timestamp;
-  sk->version = pk->version = 4;
-  if (expireval)
-    {
-      sk->expiredate = pk->expiredate = sk->timestamp + expireval;
-    }
-  sk->pubkey_algo = pk->pubkey_algo = algo;
-
-  rc = key_from_sexp (pk->pkey, s_key, "public-key", "ne");
-  if (rc) 
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc));
-      gcry_sexp_release (s_key);
-      free_public_key(pk);
-      free_secret_key(sk);
-      return rc;
-    }
-  rc = key_from_sexp (sk->skey, s_key, "private-key", "nedpqu");
-  if (rc) 
-    {
-      log_error ("key_from_sexp failed: %s\n", gpg_strerror (rc) );
-      gcry_sexp_release (s_key);
-      free_public_key(pk);
-      free_secret_key(sk);
-      return rc;
-    }
-  gcry_sexp_release (s_key);
-
-  sk->is_protected = 0;
-  sk->protect.algo = 0;
-
-  sk->csum  = checksum_mpi (sk->skey[2] );
-  sk->csum += checksum_mpi (sk->skey[3] );
-  sk->csum += checksum_mpi (sk->skey[4] );
-  sk->csum += checksum_mpi (sk->skey[5] );
-  if( ret_sk ) /* return an unprotected version of the sk */
-    *ret_sk = copy_secret_key( NULL, sk );
-
-  rc = genhelp_protect (dek, s2k, sk);
-  if (rc)
+  snprintf (nbitsstr, sizeof nbitsstr, "%u", nbits);
+  keyparms = xtryasprintf ("(genkey(rsa(nbits %zu:%s)))", 
+                           strlen (nbitsstr), nbitsstr);
+  if (!keyparms)
+    err = gpg_error_from_syserror ();
+  else
     {
     {
-      free_public_key (pk);
-      free_secret_key (sk);
-      return rc;
+      err = common_gen (keyparms, algo, "ne", 
+                        pub_root, timestamp, expireval, is_subkey);
+      xfree (keyparms);
     }
 
     }
 
-  pkt = xmalloc_clear(sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_PUBLIC_SUBKEY : PKT_PUBLIC_KEY;
-  pkt->pkt.public_key = pk;
-  add_kbnode(pub_root, new_kbnode( pkt ));
-
-  pkt = xmalloc_clear(sizeof *pkt);
-  pkt->pkttype = is_subkey ? PKT_SECRET_SUBKEY : PKT_SECRET_KEY;
-  pkt->pkt.secret_key = sk;
-  add_kbnode(sec_root, new_kbnode( pkt ));
-
-  return 0;
+  return err;
 }
 
 
 }
 
 
@@ -2310,32 +2126,30 @@ do_ask_passphrase (STRING2KEY **ret_s2k, int mode, int *r_canceled)
 /* Basic key generation.  Here we divert to the actual generation
    routines based on the requested algorithm.  */
 static int
 /* Basic key generation.  Here we divert to the actual generation
    routines based on the requested algorithm.  */
 static int
-do_create (int algo, unsigned int nbits, KBNODE pub_root, KBNODE sec_root,
-          DEK *dek, STRING2KEY *s2k, PKT_secret_key **sk, 
+do_create (int algo, unsigned int nbits, KBNODE pub_root,
            u32 timestamp, u32 expiredate, int is_subkey )
 {
            u32 timestamp, u32 expiredate, int is_subkey )
 {
-  int rc=0;
+  gpg_error_t err;
 
 
-  if( !opt.batch )
-    tty_printf(_(
+  /* Fixme: The entropy collecting message should be moved to a
+     libgcrypt progress handler.  */
+  if (!opt.batch)
+    tty_printf (_(
 "We need to generate a lot of random bytes. It is a good idea to perform\n"
 "some other action (type on the keyboard, move the mouse, utilize the\n"
 "disks) during the prime generation; this gives the random number\n"
 "generator a better chance to gain enough entropy.\n") );
 
 "We need to generate a lot of random bytes. It is a good idea to perform\n"
 "some other action (type on the keyboard, move the mouse, utilize the\n"
 "disks) during the prime generation; this gives the random number\n"
 "generator a better chance to gain enough entropy.\n") );
 
-  if( algo == PUBKEY_ALGO_ELGAMAL_E )
-    rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk,
-                 timestamp, expiredate, is_subkey);
-  else if( algo == PUBKEY_ALGO_DSA )
-    rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk,
-                 timestamp, expiredate, is_subkey);
-  else if( algo == PUBKEY_ALGO_RSA )
-    rc = gen_rsa(algo, nbits, pub_root, sec_root, dek, s2k, sk,
-                 timestamp, expiredate, is_subkey);
+  if (algo == PUBKEY_ALGO_ELGAMAL_E)
+    err = gen_elg (algo, nbits, pub_root, timestamp, expiredate, is_subkey);
+  else if (algo == PUBKEY_ALGO_DSA)
+    err = gen_dsa (nbits, pub_root, timestamp, expiredate, is_subkey);
+  else if (algo == PUBKEY_ALGO_RSA)
+    err = gen_rsa (algo, nbits, pub_root, timestamp, expiredate, is_subkey);
   else
     BUG();
 
   else
     BUG();
 
-  return rc;
+  return err;
 }
 
 
 }
 
 
@@ -2533,20 +2347,6 @@ get_parameter_uint( struct para_data_s *para, enum para_name key )
     return get_parameter_u32( para, key );
 }
 
     return get_parameter_u32( para, key );
 }
 
-static DEK *
-get_parameter_dek( struct para_data_s *para, enum para_name key )
-{
-    struct para_data_s *r = get_parameter( para, key );
-    return r? r->u.dek : NULL;
-}
-
-static STRING2KEY *
-get_parameter_s2k( struct para_data_s *para, enum para_name key )
-{
-    struct para_data_s *r = get_parameter( para, key );
-    return r? r->u.s2k : NULL;
-}
-
 static struct revocation_key *
 get_parameter_revkey( struct para_data_s *para, enum para_name key )
 {
 static struct revocation_key *
 get_parameter_revkey( struct para_data_s *para, enum para_name key )
 {
@@ -3050,8 +2850,6 @@ generate_keypair (const char *fname, const char *card_serialno,
 {
   unsigned int nbits;
   char *uid = NULL;
 {
   unsigned int nbits;
   char *uid = NULL;
-  DEK *dek;
-  STRING2KEY *s2k;
   int algo;
   unsigned int use;
   int both = 0;
   int algo;
   unsigned int use;
   int both = 0;
@@ -3059,7 +2857,6 @@ generate_keypair (const char *fname, const char *card_serialno,
   struct para_data_s *para = NULL;
   struct para_data_s *r;
   struct output_control_s outctrl;
   struct para_data_s *para = NULL;
   struct para_data_s *r;
   struct output_control_s outctrl;
-  int canceled;
   
   memset( &outctrl, 0, sizeof( outctrl ) );
   
   
   memset( &outctrl, 0, sizeof( outctrl ) );
   
@@ -3217,26 +3014,7 @@ generate_keypair (const char *fname, const char *card_serialno,
   r->next = para;
   para = r;
     
   r->next = para;
   para = r;
     
-  canceled = 0;
-  dek = card_serialno? NULL : do_ask_passphrase (&s2k, 0, &canceled);
-  if( dek )
-    {
-      r = xmalloc_clear( sizeof *r );
-      r->key = pPASSPHRASE_DEK;
-      r->u.dek = dek;
-      r->next = para;
-      para = r;
-      r = xmalloc_clear( sizeof *r );
-      r->key = pPASSPHRASE_S2K;
-      r->u.s2k = s2k;
-      r->next = para;
-      para = r;
-    }
-
-  if (canceled) 
-    log_error (_("Key generation canceled.\n"));
-  else
-    proc_parameter_file( para, "[internal]", &outctrl, !!card_serialno);
+  proc_parameter_file( para, "[internal]", &outctrl, !!card_serialno);
   release_parameter_list( para );
 }
 
   release_parameter_list( para );
 }
 
@@ -3356,16 +3134,16 @@ static void
 do_generate_keypair (struct para_data_s *para,
                     struct output_control_s *outctrl, int card)
 {
 do_generate_keypair (struct para_data_s *para,
                     struct output_control_s *outctrl, int card)
 {
+  gpg_error_t err;
   KBNODE pub_root = NULL;
   KBNODE pub_root = NULL;
-  KBNODE sec_root = NULL;
-  PKT_secret_key *pri_sk = NULL, *sub_sk = NULL;
   const char *s;
   const char *s;
+  PKT_public_key *pri_psk = NULL;
+  PKT_public_key *sub_psk = NULL;
   struct revocation_key *revkey;
   struct revocation_key *revkey;
-  int rc;
   int did_sub = 0;
   u32 timestamp;
 
   int did_sub = 0;
   u32 timestamp;
 
-  if( outctrl->dryrun )
+  if (outctrl->dryrun)
     {
       log_info("dry-run mode - key generation skipped\n");
       return;
     {
       log_info("dry-run mode - key generation skipped\n");
       return;
@@ -3403,51 +3181,9 @@ do_generate_keypair (struct para_data_s *para,
               push_armor_filter (outctrl->pub.afx, outctrl->pub.stream);
             }
         }
               push_armor_filter (outctrl->pub.afx, outctrl->pub.stream);
             }
         }
-      if (outctrl->sec.newfname)
-        {
-          mode_t oldmask;
-          
-          iobuf_close(outctrl->sec.stream);
-          outctrl->sec.stream = NULL;
-          if (outctrl->sec.fname)
-            iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE,
-                         0, (char*)outctrl->sec.fname);
-          xfree( outctrl->sec.fname );
-          outctrl->sec.fname =  outctrl->sec.newfname;
-          outctrl->sec.newfname = NULL;
-
-          oldmask = umask (077);
-          if (is_secured_filename (outctrl->sec.fname) )
-            {
-              outctrl->sec.stream = NULL;
-              gpg_err_set_errno (EPERM);
-            }
-          else
-            outctrl->sec.stream = iobuf_create( outctrl->sec.fname );
-          umask (oldmask);
-          if (!outctrl->sec.stream)
-            {
-              log_error(_("can't create `%s': %s\n"), outctrl->sec.newfname,
-                        strerror(errno) );
-              return;
-            }
-          if (opt.armor)
-            {
-              outctrl->sec.afx->what = 5;
-              push_armor_filter (outctrl->sec.afx, outctrl->sec.stream);
-            }
-        }
       assert( outctrl->pub.stream );
       assert( outctrl->pub.stream );
-      assert( outctrl->sec.stream );
       if (opt.verbose)
       if (opt.verbose)
-        {
-          log_info (_("writing public key to `%s'\n"), outctrl->pub.fname );
-          if (card)
-            log_info (_("writing secret key stub to `%s'\n"),
-                      outctrl->sec.fname);
-          else
-            log_info(_("writing secret key to `%s'\n"), outctrl->sec.fname );
-        }
+        log_info (_("writing public key to `%s'\n"), outctrl->pub.fname );
     }
 
 
     }
 
 
@@ -3457,7 +3193,6 @@ do_generate_keypair (struct para_data_s *para,
      deleted.  The very first packet must always be a KEY packet.  */
     
   start_tree (&pub_root);
      deleted.  The very first packet must always be a KEY packet.  */
     
   start_tree (&pub_root);
-  start_tree (&sec_root);
 
   timestamp = get_parameter_u32 (para, pKEYCREATIONDATE);
   if (!timestamp)
 
   timestamp = get_parameter_u32 (para, pKEYCREATIONDATE);
   if (!timestamp)
@@ -3473,42 +3208,31 @@ do_generate_keypair (struct para_data_s *para,
      current timestamp.  */
 
   if (!card)
      current timestamp.  */
 
   if (!card)
-    {
-      rc = do_create (get_parameter_algo( para, pKEYTYPE, NULL ),
-                      get_parameter_uint( para, pKEYLENGTH ),
-                      pub_root, sec_root,
-                      get_parameter_dek( para, pPASSPHRASE_DEK ),
-                      get_parameter_s2k( para, pPASSPHRASE_S2K ),
-                      &pri_sk,
-                      timestamp,
-                      get_parameter_u32( para, pKEYEXPIRE ), 0 );
-    }
+    err = do_create (get_parameter_algo( para, pKEYTYPE, NULL ),
+                     get_parameter_uint( para, pKEYLENGTH ),
+                     pub_root,
+                     timestamp,
+                     get_parameter_u32( para, pKEYEXPIRE ), 0 );
   else
   else
-    {
-      rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root, NULL,
-                         &timestamp,
-                         get_parameter_u32 (para, pKEYEXPIRE), para);
-      if (!rc)
-        {
-          pri_sk = sec_root->next->pkt->pkt.secret_key;
-          assert (pri_sk);
-        }
-    }
+    err = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root,
+                        &timestamp,
+                        get_parameter_u32 (para, pKEYEXPIRE), para);
 
 
-  if(!rc && (revkey=get_parameter_revkey(para,pREVOKER)))
+  /* Get the pointer to the generated public key packet.  */
+  if (!err)
     {
     {
-      rc = write_direct_sig (pub_root, pub_root, pri_sk, revkey, timestamp);
-      if (!rc)
-        rc = write_direct_sig (sec_root, pub_root, pri_sk, revkey, timestamp);
+      pri_psk = pub_root->next->pkt->pkt.public_key;
+      assert (pri_psk);
     }
 
     }
 
-  if( !rc && (s=get_parameter_value(para, pUSERID)) )
+  if (!err && (revkey = get_parameter_revkey (para, pREVOKER)))
+    err = write_direct_sig (pub_root, pri_psk, revkey, timestamp);
+
+  if (!err && (s = get_parameter_value (para, pUSERID)))
     {
       write_uid (pub_root, s );
     {
       write_uid (pub_root, s );
-      write_uid (sec_root, s );
-
-      rc = write_selfsigs (sec_root, pub_root, pri_sk,
-                           get_parameter_uint (para, pKEYUSAGE), timestamp);
+      err = write_selfsigs (pub_root, pri_psk,
+                            get_parameter_uint (para, pKEYUSAGE), timestamp);
     }
 
   /* Write the auth key to the card before the encryption key.  This
     }
 
   /* Write the auth key to the card before the encryption key.  This
@@ -3518,32 +3242,36 @@ do_generate_keypair (struct para_data_s *para,
      actually an encryption type.  In this case, the auth key is an
      RSA key so it succeeds. */
 
      actually an encryption type.  In this case, the auth key is an
      RSA key so it succeeds. */
 
-  if (!rc && card && get_parameter (para, pAUTHKEYTYPE))
+  if (!err && card && get_parameter (para, pAUTHKEYTYPE))
     {
     {
-      rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, NULL,
-                         &timestamp,
-                         get_parameter_u32 (para, pKEYEXPIRE), para);
-        
-      if (!rc)
-        rc = write_keybinding (pub_root, pub_root, pri_sk, sub_sk,
-                               PUBKEY_USAGE_AUTH, timestamp);
-      if (!rc)
-        rc = write_keybinding (sec_root, pub_root, pri_sk, sub_sk,
-                               PUBKEY_USAGE_AUTH, timestamp);
+      err = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root,
+                          &timestamp,
+                          get_parameter_u32 (para, pKEYEXPIRE), para);
+      if (!err)
+        err = write_keybinding (pub_root, pri_psk, NULL,
+                                PUBKEY_USAGE_AUTH, timestamp);
     }
 
     }
 
-  if( !rc && get_parameter( para, pSUBKEYTYPE ) )
+  if (!err && get_parameter (para, pSUBKEYTYPE))
     {
     {
+      sub_psk = NULL;
       if (!card)
         {
       if (!card)
         {
-          rc = do_create( get_parameter_algo( para, pSUBKEYTYPE, NULL ),
-                          get_parameter_uint( para, pSUBKEYLENGTH ),
-                          pub_root, sec_root,
-                          get_parameter_dek( para, pPASSPHRASE_DEK ),
-                          get_parameter_s2k( para, pPASSPHRASE_S2K ),
-                          &sub_sk,
-                          timestamp,
-                          get_parameter_u32( para, pSUBKEYEXPIRE ), 1 );
+          err = do_create (get_parameter_algo (para, pSUBKEYTYPE, NULL),
+                           get_parameter_uint (para, pSUBKEYLENGTH),
+                           pub_root, 
+                           timestamp,
+                           get_parameter_u32 (para, pSUBKEYEXPIRE), 1 );
+          /* Get the pointer to the generated public subkey packet.  */
+          if (!err)
+            {
+              kbnode_t node;
+              
+              for (node = pub_root; node; node = node->next)
+                if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+                  sub_psk = node->pkt->pkt.public_key;
+              assert (sub_psk);
+            }
         }
       else
         {
         }
       else
         {
@@ -3552,95 +3280,60 @@ do_generate_keypair (struct para_data_s *para,
               /* A backup of the encryption key has been requested.
                  Generate the key in software and import it then to
                  the card.  Write a backup file. */
               /* A backup of the encryption key has been requested.
                  Generate the key in software and import it then to
                  the card.  Write a backup file. */
-              rc = gen_card_key_with_backup (PUBKEY_ALGO_RSA, 2, 0,
-                                             pub_root, sec_root,
-                                             timestamp,
-                                             get_parameter_u32 (para,
-                                                                pKEYEXPIRE),
-                                             para, s);
+              err = gen_card_key_with_backup (PUBKEY_ALGO_RSA, 2, 0,
+                                              pub_root,
+                                              timestamp,
+                                              get_parameter_u32 (para,
+                                                                 pKEYEXPIRE),
+                                              para, s);
             }
           else
             {
             }
           else
             {
-              rc = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root, sec_root,
-                                 NULL,
-                                 &timestamp,
-                                 get_parameter_u32 (para, pKEYEXPIRE), para);
+              err = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root,
+                                  &timestamp,
+                                  get_parameter_u32 (para, pKEYEXPIRE), para);
             }
         }
 
             }
         }
 
-      if( !rc )
-        rc = write_keybinding(pub_root, pub_root, pri_sk, sub_sk,
-                              get_parameter_uint (para, pSUBKEYUSAGE),
-                              timestamp);
-      if( !rc )
-        rc = write_keybinding(sec_root, pub_root, pri_sk, sub_sk,
-                              get_parameter_uint (para, pSUBKEYUSAGE),
-                              timestamp);
+      if (!err)
+        err = write_keybinding (pub_root, pri_psk, sub_psk,
+                                get_parameter_uint (para, pSUBKEYUSAGE),
+                                timestamp);
       did_sub = 1;
     }
 
       did_sub = 1;
     }
 
-  if (!rc && outctrl->use_files)  /* Direct write to specified files.  */
+  if (!err && outctrl->use_files)  /* Direct write to specified files.  */
     {
     {
-      rc = write_keyblock( outctrl->pub.stream, pub_root );
-      if (rc)
-        log_error ("can't write public key: %s\n", g10_errstr(rc) );
-      if (!rc) 
-        {
-          rc = write_keyblock( outctrl->sec.stream, sec_root );
-          if(rc)
-            log_error ("can't write secret key: %s\n", g10_errstr(rc) );
-        }
+      err = write_keyblock (outctrl->pub.stream, pub_root);
+      if (err)
+        log_error ("can't write public key: %s\n", g10_errstr (err));
     }
     }
-  else if (!rc) /* Write to the standard keyrings.  */
+  else if (!err) /* Write to the standard keyrings.  */
     {
       KEYDB_HANDLE pub_hd = keydb_new (0);
     {
       KEYDB_HANDLE pub_hd = keydb_new (0);
-      KEYDB_HANDLE sec_hd = keydb_new (1);
 
 
-      rc = keydb_locate_writable (pub_hd, NULL);
-      if (rc
+      err = keydb_locate_writable (pub_hd, NULL);
+      if (err
         log_error (_("no writable public keyring found: %s\n"),
         log_error (_("no writable public keyring found: %s\n"),
-                   g10_errstr (rc));
-
-      if (!rc) 
-        {  
-          rc = keydb_locate_writable (sec_hd, NULL);
-          if (rc) 
-            log_error (_("no writable secret keyring found: %s\n"),
-                       g10_errstr (rc));
-        }
+                   g10_errstr (err));
       
       
-      if (!rc && opt.verbose)
+      if (!err && opt.verbose)
         {
           log_info (_("writing public key to `%s'\n"),
                     keydb_get_resource_name (pub_hd));
         {
           log_info (_("writing public key to `%s'\n"),
                     keydb_get_resource_name (pub_hd));
-          if (card)
-            log_info (_("writing secret key stub to `%s'\n"),
-                      keydb_get_resource_name (sec_hd));
-          else
-            log_info (_("writing secret key to `%s'\n"),
-                      keydb_get_resource_name (sec_hd));
         }
       
         }
       
-      if (!rc
+      if (!err
         {
         {
-          rc = keydb_insert_keyblock (pub_hd, pub_root);
-          if (rc)
+          err = keydb_insert_keyblock (pub_hd, pub_root);
+          if (err)
             log_error (_("error writing public keyring `%s': %s\n"),
             log_error (_("error writing public keyring `%s': %s\n"),
-                       keydb_get_resource_name (pub_hd), g10_errstr(rc));
+                       keydb_get_resource_name (pub_hd), g10_errstr(err));
         }
       
         }
       
-      if (!rc)
-        {
-          rc = keydb_insert_keyblock (sec_hd, sec_root);
-          if (rc)
-            log_error (_("error writing secret keyring `%s': %s\n"),
-                       keydb_get_resource_name (pub_hd), g10_errstr(rc));
-        }
-
       keydb_release (pub_hd);
       keydb_release (pub_hd);
-      keydb_release (sec_hd);
       
       
-      if (!rc)
+      if (!err)
         {
           int no_enc_rsa;
           PKT_public_key *pk;
         {
           int no_enc_rsa;
           PKT_public_key *pk;
@@ -3653,8 +3346,8 @@ do_generate_keypair (struct para_data_s *para,
 
           pk = find_kbnode (pub_root, PKT_PUBLIC_KEY)->pkt->pkt.public_key;
 
 
           pk = find_kbnode (pub_root, PKT_PUBLIC_KEY)->pkt->pkt.public_key;
 
-          keyid_from_pk(pk,pk->main_keyid);
-          register_trusted_keyid(pk->main_keyid);
+          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 (pk, ((get_ownertrust (pk) & ~TRUST_MASK)
                                   | TRUST_ULTIMATE ));
@@ -3663,7 +3356,7 @@ do_generate_keypair (struct para_data_s *para,
             {
               tty_printf (_("public and secret key created and signed.\n") );
               tty_printf ("\n");
             {
               tty_printf (_("public and secret key created and signed.\n") );
               tty_printf ("\n");
-              list_keyblock(pub_root,0,1,NULL);
+              list_keyblock (pub_root, 0, 1, NULL);
             }
             
           
             }
             
           
@@ -3680,13 +3373,13 @@ do_generate_keypair (struct para_data_s *para,
         }
     }
 
         }
     }
 
-  if (rc)
+  if (err)
     {
       if (opt.batch)
     {
       if (opt.batch)
-        log_error ("key generation failed: %s\n", g10_errstr(rc) );
+        log_error ("key generation failed: %s\n", g10_errstr(err) );
       else
       else
-        tty_printf (_("Key generation failed: %s\n"), g10_errstr(rc) );
-      write_status_errcode (card? "card_key_generate":"key_generate", rc);
+        tty_printf (_("Key generation failed: %s\n"), g10_errstr(err) );
+      write_status_error (card? "card_key_generate":"key_generate", err);
       print_status_key_not_created ( get_parameter_value (para, pHANDLE) );
     }
   else
       print_status_key_not_created ( get_parameter_value (para, pHANDLE) );
     }
   else
@@ -3696,99 +3389,91 @@ do_generate_keypair (struct para_data_s *para,
       print_status_key_created (did_sub? 'B':'P', pk,
                                 get_parameter_value (para, pHANDLE));
     }
       print_status_key_created (did_sub? 'B':'P', pk,
                                 get_parameter_value (para, pHANDLE));
     }
-  release_kbnode( pub_root );
-  release_kbnode( sec_root );
   
   
-  if (pri_sk && !card)        /* The unprotected secret key unless we */
-    free_secret_key (pri_sk); /* have a shallow copy in card mode. */
-  if (sub_sk)
-    free_secret_key(sub_sk);
+  release_kbnode (pub_root);
 }
 
 
 }
 
 
-/* Add a new subkey to an existing key.  Returns true if a new key has
+/* Add a new subkey to an existing key.  Returns 0 if a new key has
    been generated and put into the keyblocks.  */
    been generated and put into the keyblocks.  */
-int
-generate_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock)
+gpg_error_t
+generate_subkeypair (KBNODE keyblock)
 {
 {
-  int okay=0, rc=0;
-  KBNODE node;
-  PKT_secret_key *pri_sk = NULL, *sub_sk = NULL;
+  gpg_error_t err = 0;
+  kbnode_t node;
+  PKT_public_key *pri_psk = NULL;
+  PKT_public_key *sub_psk = NULL;
   int algo;
   unsigned int use;
   u32 expire;
   int algo;
   unsigned int use;
   u32 expire;
-  unsigned nbits;
-  char *passphrase = NULL;
-  DEK *dek = NULL;
-  STRING2KEY *s2k = NULL;
+  unsigned int nbits;
   u32 cur_time;
   u32 cur_time;
-  int ask_pass = 0;
-  int canceled;
 
 
-  /* Break out the primary secret key.  */
-  node = find_kbnode( sec_keyblock, PKT_SECRET_KEY );
-  if( !node 
+  /* Break out the primary key.  */
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+  if (!node
     {
     {
-      log_error ("Oops; secret key not found anymore!\n");
+      log_error ("Oops; primary key missing in keyblock!\n");
+      err = gpg_error (GPG_ERR_BUG);
       goto leave;
     }
       goto leave;
     }
-  
-  /* Make a copy of the sk to keep the protected one in the keyblock. */
-  pri_sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
+  pri_psk = node->pkt->pkt.public_key;
 
 
-  cur_time = make_timestamp();
+  cur_time = make_timestamp ();
 
 
-  if (pri_sk->timestamp > cur_time)
+  if (pri_psk->timestamp > cur_time)
     {
     {
-      ulong d = pri_sk->timestamp - cur_time;
+      ulong d = pri_psk->timestamp - cur_time;
       log_info ( d==1 ? _("key has been created %lu second "
                           "in future (time warp or clock problem)\n")
                  : _("key has been created %lu seconds "
                      "in future (time warp or clock problem)\n"), d );
       if (!opt.ignore_time_conflict)
         {
       log_info ( d==1 ? _("key has been created %lu second "
                           "in future (time warp or clock problem)\n")
                  : _("key has been created %lu seconds "
                      "in future (time warp or clock problem)\n"), d );
       if (!opt.ignore_time_conflict)
         {
-          rc = G10ERR_TIME_CONFLICT;
+          err = gpg_error (GPG_ERR_TIME_CONFLICT);
           goto leave;
         }
     }
 
           goto leave;
         }
     }
 
-  if (pri_sk->version < 4) 
+  if (pri_psk->version < 4) 
     {
       log_info (_("NOTE: creating subkeys for v3 keys "
                   "is not OpenPGP compliant\n"));
     {
       log_info (_("NOTE: creating subkeys for v3 keys "
                   "is not OpenPGP compliant\n"));
+      err = gpg_error (GPG_ERR_CONFLICT);
       goto leave;
     }
 
       goto leave;
     }
 
-  if (pri_sk->is_protected && pri_sk->protect.s2k.mode == 1001)
-    {
-      tty_printf (_("Secret parts of primary key are not available.\n"));
-      rc = G10ERR_NO_SECKEY;
-      goto leave;
-    }
-
-
-  /* Unprotect to get the passphrase.  */
-  switch (is_secret_key_protected (pri_sk) )
-    {
-    case -1:
-      rc = G10ERR_PUBKEY_ALGO;
-      break;
-    case 0:
-      tty_printf (_("This key is not protected.\n"));
-      break;
-    case -2:
-      tty_printf (_("Secret parts of primary key are stored on-card.\n"));
-      ask_pass = 1;
-      break;
-    default:
-      tty_printf (_("Key is protected.\n"));
-      rc = check_secret_key ( pri_sk, 0 );
-      if (!rc)
-        passphrase = get_last_passphrase();
-      break;
-    }
-  if (rc)
-    goto leave;
+#warning ask gpg-agent on the availibility of the secret key
+  /* if (pri_sk->is_protected && pri_sk->protect.s2k.mode == 1001) */
+  /*   { */
+  /*     tty_printf (_("Secret parts of primary key are not available.\n")); */
+  /*     err = G10ERR_NO_SECKEY; */
+  /*     goto leave; */
+  /*   } */
+
+
+  /* /\* Unprotect to get the passphrase.  *\/ */
+  /* switch (is_secret_key_protected (pri_sk) ) */
+  /*   { */
+  /*   case -1: */
+  /*     err = G10ERR_PUBKEY_ALGO; */
+  /*     break; */
+  /*   case 0: */
+  /*     tty_printf (_("This key is not protected.\n")); */
+  /*     break; */
+  /*   case -2: */
+  /*     tty_printf (_("Secret parts of primary key are stored on-card.\n")); */
+  /*     ask_pass = 1; */
+  /*     break; */
+  /*   default: */
+  /*     tty_printf (_("Key is protected.\n")); */
+  /*     err = check_secret_key ( pri_sk, 0 ); */
+  /*     if (!err) */
+  /*       passphrase = get_last_passphrase(); */
+  /*     break; */
+  /*   } */
+  /* if (err) */
+  /*   goto leave; */
 
   algo = ask_algo (1, NULL, &use);
   assert (algo);
 
   algo = ask_algo (1, NULL, &use);
   assert (algo);
@@ -3796,52 +3481,31 @@ generate_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock)
   expire = ask_expire_interval (0, NULL);
   if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay",
                                                _("Really create? (y/N) ")))
   expire = ask_expire_interval (0, NULL);
   if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay",
                                                _("Really create? (y/N) ")))
-    goto leave;
-  
-  canceled = 0;
-  if (ask_pass)
-    dek = do_ask_passphrase (&s2k, 0, &canceled);
-  else if (passphrase)
     {
     {
-      s2k = xmalloc_secure ( sizeof *s2k );
-      s2k->mode = opt.s2k_mode;
-      s2k->hash_algo = S2K_DIGEST_ALGO;
-      set_next_passphrase ( passphrase );
-      dek = passphrase_to_dek (NULL, 0, opt.s2k_cipher_algo, s2k, 2,
-                               NULL, NULL );
-    }
-  
-  if (canceled)
-    rc = GPG_ERR_CANCELED;
-  
-  if (!rc)
-    rc = do_create (algo, nbits, pub_keyblock, sec_keyblock,
-                    dek, s2k, &sub_sk, cur_time, expire, 1 );
-  if (!rc)
-    rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, 
-                          use, cur_time);
-  if (!rc)
-    rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk, 
-                           use, cur_time);
-  if (!rc) 
-    {
-      okay = 1;
-      write_status_text (STATUS_KEY_CREATED, "S");
-    }
+      err = gpg_error (GPG_ERR_CANCELED);
+      goto leave;
+    }  
+
+  err = do_create (algo, nbits, keyblock, cur_time, expire, 1);
+  if (err)
+    goto leave;
+
+  /* Get the pointer to the generated public subkey packet.  */
+  for (node = keyblock; node; node = node->next)
+    if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+      sub_psk = node->pkt->pkt.public_key;
+
+  /* Write the binding signature.  */
+  err = write_keybinding (keyblock, pri_psk, sub_psk, use, cur_time);
+  if (err)
+    goto leave;
+
+  write_status_text (STATUS_KEY_CREATED, "S");
 
  leave:
 
  leave:
-  if (rc)
-    log_error (_("Key generation failed: %s\n"), g10_errstr(rc) );
-  xfree (passphrase);
-  xfree (dek);
-  xfree (s2k);
-  /* Release the copy of the (now unprotected) secret keys.  */
-  if (pri_sk)
-    free_secret_key (pri_sk);
-  if (sub_sk)
-    free_secret_key (sub_sk);
-  set_next_passphrase (NULL);
-  return okay;
+  if (err)
+    log_error (_("Key generation failed: %s\n"), g10_errstr (err) );
+  return err;
 }
 
 
 }
 
 
@@ -3851,8 +3515,9 @@ int
 generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
                           int keyno, const char *serialno)
 {
 generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
                           int keyno, const char *serialno)
 {
-  int okay=0, rc=0;
-  KBNODE node;
+  gpg_error_t err = 0;
+  int okay = 0;
+  kbnode_t node;
   PKT_secret_key *pri_sk = NULL, *sub_sk;
   int algo;
   unsigned int use;
   PKT_secret_key *pri_sk = NULL, *sub_sk;
   int algo;
   unsigned int use;
@@ -3888,7 +3553,7 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
                          "in future (time warp or clock problem)\n"), d );
        if (!opt.ignore_time_conflict)
           {
                          "in future (time warp or clock problem)\n"), d );
        if (!opt.ignore_time_conflict)
           {
-           rc = G10ERR_TIME_CONFLICT;
+           err = G10ERR_TIME_CONFLICT;
            goto leave;
           }
     }
            goto leave;
           }
     }
@@ -3904,19 +3569,19 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
   switch( is_secret_key_protected (pri_sk) )
     {
     case -1:
   switch( is_secret_key_protected (pri_sk) )
     {
     case -1:
-      rc = G10ERR_PUBKEY_ALGO;
+      err = G10ERR_PUBKEY_ALGO;
       break;
     case 0:
       tty_printf("This key is not protected.\n");
       break;
     default:
       tty_printf("Key is protected.\n");
       break;
     case 0:
       tty_printf("This key is not protected.\n");
       break;
     default:
       tty_printf("Key is protected.\n");
-      rc = check_secret_key( pri_sk, 0 );
-      if (!rc)
+      err = check_secret_key( pri_sk, 0 );
+      if (!err)
         passphrase = get_last_passphrase();
       break;
     }
         passphrase = get_last_passphrase();
       break;
     }
-  if (rc)
+  if (err)
     goto leave;
 
   algo = PUBKEY_ALGO_RSA;
     goto leave;
 
   algo = PUBKEY_ALGO_RSA;
@@ -3936,23 +3601,22 @@ generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
 
   /* Note, that depending on the backend, the card key generation may
      update CUR_TIME.  */
 
   /* Note, that depending on the backend, the card key generation may
      update CUR_TIME.  */
-  rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock,
-                    &sub_sk, &cur_time, expire, para);
-  if (!rc)
-    rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, 
-                           use, cur_time);
-  if (!rc)
-    rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk, 
+  err = gen_card_key (algo, keyno, 0, pub_keyblock, &cur_time, expire, para);
+  if (!err)
+    err = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, 
+                            use, cur_time);
+  if (!err)
+    err = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk, 
                            use, cur_time);
                            use, cur_time);
-  if (!rc)
+  if (!err)
     {
       okay = 1;
       write_status_text (STATUS_KEY_CREATED, "S");
     }
 
  leave:
     {
       okay = 1;
       write_status_text (STATUS_KEY_CREATED, "S");
     }
 
  leave:
-  if (rc)
-    log_error (_("Key generation failed: %s\n"), g10_errstr(rc) );
+  if (err)
+    log_error (_("Key generation failed: %s\n"), g10_errstr(err) );
   xfree (passphrase);
   /* Release the copy of the (now unprotected) secret keys. */
   if (pri_sk)
   xfree (passphrase);
   /* Release the copy of the (now unprotected) secret keys. */
   if (pri_sk)
@@ -3990,8 +3654,7 @@ write_keyblock( IOBUF out, KBNODE node )
 
 /* Note that timestamp is an in/out arg. */
 static int
 
 /* Note that timestamp is an in/out arg. */
 static int
-gen_card_key (int algo, int keyno, int is_primary,
-              KBNODE pub_root, KBNODE sec_root, PKT_secret_key **ret_sk,
+gen_card_key (int algo, int keyno, int is_primary, KBNODE pub_root, 
               u32 *timestamp, u32 expireval, struct para_data_s *para)
 {
 #ifdef ENABLE_CARD_SUPPORT
               u32 *timestamp, u32 expireval, struct para_data_s *para)
 {
 #ifdef ENABLE_CARD_SUPPORT
@@ -4070,7 +3733,7 @@ gen_card_key (int algo, int keyno, int is_primary,
 
   return 0;
 #else
 
   return 0;
 #else
-  return -1;
+  return gpg_error (GPG_ERR_NOT_SUPPORTED);
 #endif /*!ENABLE_CARD_SUPPORT*/
 }
 
 #endif /*!ENABLE_CARD_SUPPORT*/
 }
 
@@ -4078,8 +3741,7 @@ gen_card_key (int algo, int keyno, int is_primary,
 
 static int
 gen_card_key_with_backup (int algo, int keyno, int is_primary,
 
 static int
 gen_card_key_with_backup (int algo, int keyno, int is_primary,
-                          KBNODE pub_root, KBNODE sec_root,
-                          u32 timestamp,
+                          KBNODE pub_root, u32 timestamp,
                           u32 expireval, struct para_data_s *para,
                           const char *backup_dir)
 {
                           u32 expireval, struct para_data_s *para,
                           const char *backup_dir)
 {
@@ -4240,7 +3902,7 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
 
   return 0;
 #else
 
   return 0;
 #else
-  return -1;
+  return gpg_error (GPG_ERR_NOT_SUPPORTED);
 #endif /*!ENABLE_CARD_SUPPORT*/
 }
 
 #endif /*!ENABLE_CARD_SUPPORT*/
 }
 
index 3ba7d42..8f2d8f7 100644 (file)
@@ -1,6 +1,6 @@
 /* keyid.c - key ID and fingerprint handling
  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
 /* keyid.c - key ID and fingerprint handling
  * Copyright (C) 1998, 1999, 2000, 2001, 2003,
- *               2004, 2006 Free Software Foundation, Inc.
+ *               2004, 2006, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
  *
  * This file is part of GnuPG.
  *
@@ -828,3 +828,90 @@ serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
   return buffer;
 }
 
   return buffer;
 }
 
+
+\f
+/* Return the so called KEYGRIP which is the SHA-1 hash of the public
+   key parameters expressed as an canoncial encoded S-Exp.  ARRAY must
+   be 20 bytes long.  Returns 0 on sucess or an error code.  */
+gpg_error_t
+keygrip_from_pk (PKT_public_key *pk, unsigned char *array)
+{
+  gpg_error_t err;
+  gcry_sexp_t s_pkey;
+  
+  if (DBG_PACKET)
+    log_debug ("get_keygrip for public key\n");
+
+  switch (pk->pubkey_algo)
+    {
+    case GCRY_PK_DSA:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
+                             pk->pkey[0], pk->pkey[1],
+                             pk->pkey[2], pk->pkey[3]);
+      break;
+
+    case GCRY_PK_ELG:
+    case GCRY_PK_ELG_E:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(elg(p%m)(g%m)(y%m)))",
+                             pk->pkey[0], pk->pkey[1], pk->pkey[2]);
+      break;
+
+    case GCRY_PK_RSA:
+    case GCRY_PK_RSA_S:
+    case GCRY_PK_RSA_E:
+      err = gcry_sexp_build (&s_pkey, NULL,
+                             "(public-key(rsa(n%m)(e%m)))",
+                             pk->pkey[0], pk->pkey[1]);
+      break;
+
+    default:
+      err = gpg_error (GPG_ERR_PUBKEY_ALGO);
+      break;
+    }
+  
+  if (err)
+    return err;
+
+  if (!gcry_pk_get_keygrip (s_pkey, array))
+    {
+      log_error ("error computing keygrip\n");
+      err = gpg_error (GPG_ERR_GENERAL);
+    }
+  else
+    {
+      if (DBG_PACKET)
+        log_printhex ("keygrip=", array, 20);
+      /* FIXME: Save the keygrip in PK.  */
+    }
+  gcry_sexp_release (s_pkey);
+  
+  return 0;
+}
+
+
+/* Store an allocated buffer with the keygrip of PK encoded as a
+   hexstring at r_GRIP.  Returns 0 on success.  */
+gpg_error_t
+hexkeygrip_from_pk (PKT_public_key *pk, char **r_grip)
+{
+  gpg_error_t err;
+  unsigned char grip[20];
+
+  *r_grip = NULL;
+  err = keygrip_from_pk (pk, grip);
+  if (!err)
+    {
+      char * buf = xtrymalloc (20*2+1);
+      if (!buf)
+        err = gpg_error_from_syserror ();
+      else
+        {
+          bin2hex (grip, 20, buf);
+          *r_grip = buf;
+        }
+    }
+  return err;
+}
+
index 6d70b2b..5d08c0d 100644 (file)
@@ -1063,6 +1063,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
   int trustletter = 0;
   int ulti_hack = 0;
   int i;
   int trustletter = 0;
   int ulti_hack = 0;
   int i;
+  char *p;
 
   /* Get the keyid from the keyblock.  */
   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
 
   /* Get the keyid from the keyblock.  */
   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
@@ -1128,8 +1129,15 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
   if (fpr)
     print_fingerprint (pk, NULL, 0);
   if (opt.with_key_data)
   if (fpr)
     print_fingerprint (pk, NULL, 0);
   if (opt.with_key_data)
-    print_key_data (pk);
-  
+    {
+      if (!hexkeygrip_from_pk (pk, &p))
+        {
+          es_fprintf (es_stdout, "grp:::::::::%s:\n", p);
+          xfree (p);
+        }
+      print_key_data (pk);
+    }
+
   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
     {
       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
   for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
     {
       if (node->pkt->pkttype == PKT_USER_ID && !opt.fast_list_mode)
@@ -1226,7 +1234,14 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
          if (fpr > 1)
            print_fingerprint (pk2, NULL, 0);
          if (opt.with_key_data)
          if (fpr > 1)
            print_fingerprint (pk2, NULL, 0);
          if (opt.with_key_data)
-           print_key_data (pk2);
+            {
+              if (!hexkeygrip_from_pk (pk2, &p))
+                {
+                  es_fprintf (es_stdout, "grp:::::::::%s:\n", p);
+                  xfree (p);
+                }
+              print_key_data (pk2);
+            }
        }
       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
        {
        }
       else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
        {
@@ -1319,7 +1334,7 @@ list_keyblock_colon (KBNODE keyblock, int secret, int fpr)
          else if (!opt.fast_list_mode)
            {
              size_t n;
          else if (!opt.fast_list_mode)
            {
              size_t n;
-             char *p = get_user_id (sig->keyid, &n);
+             p = get_user_id (sig->keyid, &n);
              es_write_sanitized (es_stdout, p, n, ":", NULL);
              xfree (p);
            }
              es_write_sanitized (es_stdout, p, n, ":", NULL);
              xfree (p);
            }
index 540d9b1..c687ee2 100644 (file)
@@ -237,10 +237,10 @@ int keygen_upd_std_prefs( PKT_signature *sig, void *opaque );
 int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
 int keygen_add_notations(PKT_signature *sig,void *opaque);
 int keygen_add_revkey(PKT_signature *sig, void *opaque);
 int keygen_add_keyserver_url(PKT_signature *sig, void *opaque);
 int keygen_add_notations(PKT_signature *sig,void *opaque);
 int keygen_add_revkey(PKT_signature *sig, void *opaque);
-int make_backsig(PKT_signature *sig,PKT_public_key *pk,
-                PKT_public_key *sub_pk,PKT_secret_key *sub_sk,
-                 u32 timestamp);
-int generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock );
+gpg_error_t make_backsig (PKT_signature *sig, PKT_public_key *pk,
+                          PKT_public_key *sub_pk, PKT_public_key *sub_psk,
+                          u32 timestamp);
+gpg_error_t generate_subkeypair (kbnode_t pub_keyblock);
 #ifdef ENABLE_CARD_SUPPORT
 int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
                               int keyno, const char *serialno);
 #ifdef ENABLE_CARD_SUPPORT
 int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
                               int keyno, const char *serialno);
@@ -258,7 +258,7 @@ void try_make_homedir( const char *fname );
 /*-- seskey.c --*/
 void make_session_key( DEK *dek );
 gcry_mpi_t encode_session_key( DEK *dek, unsigned nbits );
 /*-- seskey.c --*/
 void make_session_key( DEK *dek );
 gcry_mpi_t encode_session_key( DEK *dek, unsigned nbits );
-gcry_mpi_t encode_md_value( PKT_public_key *pk, PKT_secret_key *sk,
+gcry_mpi_t encode_md_value (PKT_public_key *pk, 
                             gcry_md_hd_t md, int hash_algo );
 
 /*-- import.c --*/
                             gcry_md_hd_t md, int hash_algo );
 
 /*-- import.c --*/
index 54f8295..2a6aea2 100644 (file)
@@ -206,7 +206,7 @@ struct revoke_info
 
 /****************
  * Note about the pkey/skey elements:  We assume that the secret keys
 
 /****************
  * Note about the pkey/skey elements:  We assume that the secret keys
- * has the same elemts as the public key at the begin of the array, so
+ * has the same elements as the public key at the begin of the array, so
  * that npkey < nskey and it is possible to compare the secret and
  * public keys by comparing the first npkey elements of pkey againts skey.
  */
  * that npkey < nskey and it is possible to compare the secret and
  * public keys by comparing the first npkey elements of pkey againts skey.
  */
@@ -477,9 +477,7 @@ int signature_check2( PKT_signature *sig, gcry_md_hd_t digest, u32 *r_expiredate
                      int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
 
 /*-- seckey-cert.c --*/
                      int *r_expired, int *r_revoked, PKT_public_key *ret_pk );
 
 /*-- seckey-cert.c --*/
-int is_secret_key_protected( PKT_secret_key *sk );
-int check_secret_key( PKT_secret_key *sk, int retries );
-int protect_secret_key( PKT_secret_key *sk, DEK *dek );
+int is_secret_key_protected (PKT_public_key *pk);
 
 /*-- pubkey-enc.c --*/
 int get_session_key( PKT_pubkey_enc *k, DEK *dek );
 
 /*-- pubkey-enc.c --*/
 int get_session_key( PKT_pubkey_enc *k, DEK *dek );
index cbfe21e..f3001f5 100644 (file)
@@ -44,63 +44,6 @@ mpi_from_sexp (gcry_sexp_t sexp, const char * item)
 }
 
 
 }
 
 
-/****************
- * Emulate our old PK interface here - sometime in the future we might
- * change the internal design to directly fit to libgcrypt.
- */
-int
-pk_sign (int algo, gcry_mpi_t * data, gcry_mpi_t hash, gcry_mpi_t * skey)
-{
-  gcry_sexp_t s_sig, s_hash, s_skey;
-  int rc;
-
-  /* make a sexp from skey */
-  if (algo == GCRY_PK_DSA)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))",
-                           skey[0], skey[1], skey[2], skey[3], skey[4]);
-    }
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))",
-                           skey[0], skey[1], skey[2], skey[3], skey[4],
-                           skey[5]);
-    }
-  else if (algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E)
-    {
-      rc = gcry_sexp_build (&s_skey, NULL,
-                           "(private-key(elg(p%m)(g%m)(y%m)(x%m)))",
-                           skey[0], skey[1], skey[2], skey[3]);
-    }
-  else
-    return GPG_ERR_PUBKEY_ALGO;
-
-  if (rc)
-    BUG ();
-
-  /* put hash into a S-Exp s_hash */
-  if (gcry_sexp_build (&s_hash, NULL, "%m", hash))
-    BUG ();
-
-  rc = gcry_pk_sign (&s_sig, s_hash, s_skey);
-  gcry_sexp_release (s_hash);
-  gcry_sexp_release (s_skey);
-
-  if (rc)
-    ;
-  else if (algo == GCRY_PK_RSA || algo == GCRY_PK_RSA_S)
-    data[0] = mpi_from_sexp (s_sig, "s");
-  else
-    {
-      data[0] = mpi_from_sexp (s_sig, "r");
-      data[1] = mpi_from_sexp (s_sig, "s");
-    }
-
-  gcry_sexp_release (s_sig);
-  return rc;
-}
 
 /****************
  * Emulate our old PK interface here - sometime in the future we might
 
 /****************
  * Emulate our old PK interface here - sometime in the future we might
@@ -304,7 +247,7 @@ pk_decrypt (int algo, gcry_mpi_t * result, gcry_mpi_t * data,
 
 /* Check whether SKEY is a suitable secret key. */
 int
 
 /* Check whether SKEY is a suitable secret key. */
 int
-pk_check_secret_key (int algo, gcry_mpi_t *skey)
+REMOVE_ME_pk_check_secret_key (int algo, gcry_mpi_t *skey)
 {
   gcry_sexp_t s_skey;
   int rc;
 {
   gcry_sexp_t s_skey;
   int rc;
index 89d2216..f97def1 100644 (file)
@@ -20,8 +20,6 @@
 #ifndef GNUPG_G10_PKGLUE_H
 #define GNUPG_G10_PKGLUE_H
 
 #ifndef GNUPG_G10_PKGLUE_H
 #define GNUPG_G10_PKGLUE_H
 
-int pk_sign (int algo, gcry_mpi_t *data, gcry_mpi_t hash,
-             gcry_mpi_t *skey);
 int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
                gcry_mpi_t *pkey);
 int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
 int pk_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
                gcry_mpi_t *pkey);
 int pk_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
index fedf4d9..b904c79 100644 (file)
@@ -114,10 +114,10 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
                xfree(p);
              }
 
                xfree(p);
              }
 
-           rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /* ask
-                                                                     only
-                                                                     once */
-           if( !rc )
+           /* rc = check_secret_key( sk, opt.try_all_secrets?1:-1 ); /\* ask */
+           /*                                                        only */
+           /*                                                        once *\/ */
+           /* if( !rc ) */
              {
                rc = get_it( k, dek, sk, keyid );
                /* Successfully checked the secret key (either it was
              {
                rc = get_it( k, dek, sk, keyid );
                /* Successfully checked the secret key (either it was
index 5e22a70..216c603 100644 (file)
@@ -436,181 +436,144 @@ gen_desig_revoke( const char *uname, strlist_t locusr )
  * Generate a revocation certificate for UNAME
  */
 int
  * Generate a revocation certificate for UNAME
  */
 int
-gen_revoke( const char *uname )
+gen_revoke (const char *uname)
 {
 {
-    int rc = 0;
-    armor_filter_context_t *afx;
-    PACKET pkt;
-    PKT_secret_key *sk; /* used as pointer into a kbnode */
-    PKT_public_key *pk = NULL;
-    PKT_signature *sig = NULL;
-    u32 sk_keyid[2];
-    IOBUF out = NULL;
-    KBNODE keyblock = NULL, pub_keyblock = NULL;
-    KBNODE node;
-    KEYDB_HANDLE kdbhd;
-    struct revocation_reason_info *reason = NULL;
-    KEYDB_SEARCH_DESC desc;
-
-    if( opt.batch )
-      {
-       log_error(_("can't do this in batch mode\n"));
-       return G10ERR_GENERAL;
-      }
-
-    afx = new_armor_context ();
-    init_packet( &pkt );
-
-    /* search the userid: 
-     * We don't want the whole getkey stuff here but the entire keyblock
-     */
-    kdbhd = keydb_new (1);
-    rc = classify_user_id (uname, &desc);
-    if (!rc)
-      rc = keydb_search (kdbhd, &desc, 1);
-    if (rc)
-      {
-       log_error (_("secret key \"%s\" not found: %s\n"),
-                   uname, g10_errstr (rc));
-       goto leave;
-      }
-
-    rc = keydb_get_keyblock (kdbhd, &keyblock );
-    if( rc ) {
-       log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
-       goto leave;
+  int rc = 0;
+  armor_filter_context_t *afx;
+  PACKET pkt;
+  PKT_public_key *psk;
+  PKT_signature *sig = NULL;
+  u32 keyid[2];
+  iobuf_t out = NULL;
+  kbnode_t keyblock = NULL;
+  kbnode_t node;
+  KEYDB_HANDLE kdbhd;
+  struct revocation_reason_info *reason = NULL;
+  KEYDB_SEARCH_DESC desc;
+
+  if( opt.batch )
+    {
+      log_error(_("can't do this in batch mode\n"));
+      return G10ERR_GENERAL;
     }
 
     }
 
-    /* get the keyid from the keyblock */
-    node = find_kbnode( keyblock, PKT_SECRET_KEY );
-    if( !node ) 
-       BUG ();
+  afx = new_armor_context ();
+  init_packet( &pkt );
 
 
-    /* fixme: should make a function out of this stuff,
-     * it's used all over the source */
-    sk = node->pkt->pkt.secret_key;
-    keyid_from_sk( sk, sk_keyid );
-    print_seckey_info (sk);
+  /* Search the userid; we don't want the whole getkey stuff here.  */
+  kdbhd = keydb_new (1);
+  rc = classify_user_id (uname, &desc);
+  if (!rc)
+    rc = keydb_search (kdbhd, &desc, 1);
+  if (rc)
+    {
+      log_error (_("secret key \"%s\" not found: %s\n"),
+                 uname, g10_errstr (rc));
+      goto leave;
+    }
 
 
-    /* FIXME: We should get the public key direct from the secret one */
+  rc = keydb_get_keyblock (kdbhd, &keyblock );
+  if( rc ) {
+    log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
+    goto leave;
+  }
 
 
-    pub_keyblock=get_pubkeyblock(sk_keyid);
-    if(!pub_keyblock)
-      {
-       log_error(_("no corresponding public key: %s\n"), g10_errstr(rc) );
-       goto leave;
-      }
+  /* Get the keyid from the keyblock.  */
+  node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
+  if (!node) 
+    BUG ();
 
 
-    node=find_kbnode(pub_keyblock,PKT_PUBLIC_KEY);
-    if(!node)
-      BUG();
+  /* fixme: should make a function out of this stuff,
+   * it's used all over the source */
+  psk = node->pkt->pkt.public_key;
+  keyid_from_pk (psk, keyid );
+  print_seckey_info (psk);
 
 
-    pk=node->pkt->pkt.public_key;
+#warning add code to check that the secret key is available
 
 
-    if( cmp_public_secret_key( pk, sk ) ) {
-       log_error(_("public key does not match secret key!\n") );
-       rc = G10ERR_GENERAL;
-       goto leave;
+  tty_printf("\n");
+  if (!cpr_get_answer_is_yes ("gen_revoke.okay",
+                _("Create a revocation certificate for this key? (y/N) ")))
+    {
+      rc = 0;
+      goto leave;
     }
     }
-
-    tty_printf("\n");
-    if( !cpr_get_answer_is_yes("gen_revoke.okay",
-                 _("Create a revocation certificate for this key? (y/N) ")) )
-      {
-       rc = 0;
-       goto leave;
-      }
-
-    if(sk->version>=4 || opt.force_v4_certs) {
-      /* get the reason for the revocation */
-      reason = ask_revocation_reason( 1, 0, 1 );
-      if( !reason ) { /* user decided to cancel */
-       rc = 0;
-       goto leave;
-      }
+  
+  if (psk->version >= 4 || opt.force_v4_certs)
+    {
+      /* Get the reason for the revocation.  */
+      reason = ask_revocation_reason (1, 0, 1);
+      if (!reason)
+        { 
+          /* user decided to cancel */
+          rc = 0;
+          goto leave;
+        }
     }
     }
-
-    switch( is_secret_key_protected( sk ) ) {
-      case -1:
-       log_error(_("unknown protection algorithm\n"));
-       rc = G10ERR_PUBKEY_ALGO;
-       break;
-      case -3:
-       tty_printf (_("Secret parts of primary key are not available.\n"));
-        rc = G10ERR_NO_SECKEY;
-        break;
-      case 0:
-       tty_printf(_("NOTE: This key is not protected!\n"));
-       break;
-      default:
-        rc = check_secret_key( sk, 0 );
-       break;
+  
+  if (!opt.armor)
+    tty_printf (_("ASCII armored output forced.\n"));
+
+  if ((rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out )))
+    goto leave;
+
+  afx->what = 1;
+  afx->hdrlines = "Comment: A revocation certificate should follow\n";
+  push_armor_filter (afx, out);
+
+  /* create it */
+  rc = make_keysig_packet (&sig, psk, NULL, NULL, psk, 0x20, 0,
+                           opt.force_v4_certs?4:0, 0, 0,
+                           revocation_reason_build_cb, reason );
+  if (rc)
+    {
+      log_error (_("make_keysig_packet failed: %s\n"), g10_errstr (rc));
+      goto leave;
     }
     }
-    if( rc )
-       goto leave;
-
-
-    if( !opt.armor )
-       tty_printf(_("ASCII armored output forced.\n"));
-
-    if( (rc = open_outfile (GNUPG_INVALID_FD, NULL, 0, &out )) )
-       goto leave;
-
-    afx->what = 1;
-    afx->hdrlines = "Comment: A revocation certificate should follow\n";
-    push_armor_filter (afx, out);
-
-    /* create it */
-    rc = make_keysig_packet( &sig, pk, NULL, NULL, sk, 0x20, 0,
-                            opt.force_v4_certs?4:0, 0, 0,
-                            revocation_reason_build_cb, reason );
-    if( rc ) {
-       log_error(_("make_keysig_packet failed: %s\n"), g10_errstr(rc));
-       goto leave;
+    
+  if (PGP2 || PGP6 || PGP7 || PGP8)
+    {
+      /* Use a minimal pk for PGPx mode, since PGP can't import bare
+         revocation certificates. */
+      rc = export_minimal_pk (out, keyblock, sig, NULL);
+      if(rc)
+        goto leave;
     }
     }
-
-    if(PGP2 || PGP6 || PGP7 || PGP8)
-      {
-       /* Use a minimal pk for PGPx mode, since PGP can't import bare
-          revocation certificates. */
-       rc=export_minimal_pk(out,pub_keyblock,sig,NULL);
-       if(rc)
-         goto leave;
-      }
-    else
-      {
-       init_packet( &pkt );
-       pkt.pkttype = PKT_SIGNATURE;
-       pkt.pkt.signature = sig;
-
-       rc = build_packet( out, &pkt );
-       if( rc ) {
-         log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
-         goto leave;
-       }
-      }
-
-    /* and issue a usage notice */
-    tty_printf(_("Revocation certificate created.\n\n"
+  else
+    {
+      init_packet( &pkt );
+      pkt.pkttype = PKT_SIGNATURE;
+      pkt.pkt.signature = sig;
+        
+      rc = build_packet (out, &pkt);
+      if (rc) 
+        {
+          log_error(_("build_packet failed: %s\n"), g10_errstr(rc) );
+          goto leave;
+        }
+    }
+    
+  /* and issue a usage notice */
+  tty_printf (_(
+"Revocation certificate created.\n\n"
 "Please move it to a medium which you can hide away; if Mallory gets\n"
 "access to this certificate he can use it to make your key unusable.\n"
 "It is smart to print this certificate and store it away, just in case\n"
 "your media become unreadable.  But have some caution:  The print system of\n"
 "your machine might store the data and make it available to others!\n"));
 
 "Please move it to a medium which you can hide away; if Mallory gets\n"
 "access to this certificate he can use it to make your key unusable.\n"
 "It is smart to print this certificate and store it away, just in case\n"
 "your media become unreadable.  But have some caution:  The print system of\n"
 "your machine might store the data and make it available to others!\n"));
 
-  leave:
-    if( sig )
-       free_seckey_enc( sig );
-    release_kbnode( keyblock );
-    release_kbnode( pub_keyblock );
-    keydb_release (kdbhd);
-    if( rc )
-       iobuf_cancel(out);
-    else
-       iobuf_close(out);
-    release_revocation_reason_info( reason );
-    release_armor_context (afx);
-    return rc;
+ leave:
+  if (sig)
+    free_seckey_enc (sig);
+  release_kbnode (keyblock);
+  keydb_release (kdbhd);
+  if (rc)
+    iobuf_cancel(out);
+  else
+    iobuf_close(out);
+  release_revocation_reason_info( reason );
+  release_armor_context (afx);
+  return rc;
 }
 
 
 }
 
 
index 9995aa4..fed9213 100644 (file)
@@ -260,214 +260,16 @@ do_check( PKT_secret_key *sk, const char *tryagain_text, int mode,
 
 
 /****************
 
 
 /****************
- * Check the secret key
- * Ask up to 3 (or n) times for a correct passphrase
- * If n is negative, disable the key info prompt and make n=abs(n)
- */
-int
-check_secret_key( PKT_secret_key *sk, int n )
-{
-    int rc = gpg_error (GPG_ERR_BAD_PASSPHRASE);
-    int i,mode;
-
-    if (sk && sk->is_protected && sk->protect.s2k.mode == 1002)
-      return 0; /* Let the scdaemon handle this. */
-
-    if(n<0)
-      {
-       n=abs(n);
-       mode=1;
-      }
-    else
-      mode=0;
-
-    if( n < 1 )
-       n = 3; /* Use the default value */
-
-    for(i=0; i < n && gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE; i++ ) {
-        int canceled = 0;
-        const char *tryagain = NULL;
-       if (i) {
-            tryagain = N_("Invalid passphrase; please try again");
-            log_info (_("%s ...\n"), _(tryagain));
-        }
-       rc = do_check( sk, tryagain, mode, &canceled );
-       if ( gpg_err_code (rc) == GPG_ERR_BAD_PASSPHRASE
-             && is_status_enabled () ) {
-           u32 kid[2];
-           char buf[50];
-
-           keyid_from_sk( sk, kid );
-           sprintf(buf, "%08lX%08lX", (ulong)kid[0], (ulong)kid[1]);
-           write_status_text( STATUS_BAD_PASSPHRASE, buf );
-       }
-       if( have_static_passphrase() || canceled)
-           break;
-    }
-
-    if( !rc )
-       write_status( STATUS_GOOD_PASSPHRASE );
-
-    return rc;
-}
-
-/****************
  * check whether the secret key is protected.
  * Returns: 0 not protected, -1 on error or the protection algorithm
  *                           -2 indicates a card stub.
  *                           -3 indicates a not-online stub.
  */
 int
  * check whether the secret key is protected.
  * Returns: 0 not protected, -1 on error or the protection algorithm
  *                           -2 indicates a card stub.
  *                           -3 indicates a not-online stub.
  */
 int
-is_secret_key_protected( PKT_secret_key *sk )
+is_secret_key_protected (PKT_public_key *pk)
 {
 {
-    return sk->is_protected?
-               sk->protect.s2k.mode == 1002? -2 :
-               sk->protect.s2k.mode == 1001? -3 : sk->protect.algo : 0;
-}
-
-
-
-/****************
- * Protect the secret key with the passphrase from DEK
- */
-int
-protect_secret_key( PKT_secret_key *sk, DEK *dek )
-{
-    int i,j, rc = 0;
-    byte *buffer;
-    size_t nbytes;
-    u16 csum;
-
-    if( !dek )
-       return 0;
-
-    if( !sk->is_protected ) { /* okay, apply the protection */
-       gcry_cipher_hd_t cipher_hd=NULL;
-
-       if ( openpgp_cipher_test_algo ( sk->protect.algo ) ) {
-            /* Unsupport protection algorithm. */
-            rc = gpg_error (GPG_ERR_CIPHER_ALGO); 
-        }
-       else {
-           print_cipher_algo_note( sk->protect.algo );
-           
-           if ( openpgp_cipher_open (&cipher_hd, sk->protect.algo,
-                                     GCRY_CIPHER_MODE_CFB,
-                                     (GCRY_CIPHER_SECURE
-                                      | (sk->protect.algo >= 100 ?
-                                         0 : GCRY_CIPHER_ENABLE_SYNC))) )
-              BUG();
-           if ( gcry_cipher_setkey ( cipher_hd, dek->key, dek->keylen ) )
-               log_info(_("WARNING: Weak key detected"
-                          " - please change passphrase again.\n"));
-           sk->protect.ivlen = openpgp_cipher_get_algo_blklen (sk->protect.algo);
-           assert( sk->protect.ivlen <= DIM(sk->protect.iv) );
-           if( sk->protect.ivlen != 8 && sk->protect.ivlen != 16 )
-               BUG(); /* yes, we are very careful */
-           gcry_create_nonce (sk->protect.iv, sk->protect.ivlen);
-           gcry_cipher_setiv (cipher_hd, sk->protect.iv, sk->protect.ivlen);
-           if( sk->version >= 4 ) {
-                byte *bufarr[PUBKEY_MAX_NSKEY];
-               size_t narr[PUBKEY_MAX_NSKEY];
-               unsigned int nbits[PUBKEY_MAX_NSKEY];
-               int ndata=0;
-               byte *p, *data;
-
-               for (j=0, i = pubkey_get_npkey(sk->pubkey_algo);
-                       i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ )
-                  {
-                   assert (!gcry_mpi_get_flag (sk->skey[i],
-                                                GCRYMPI_FLAG_OPAQUE));
-                   if (gcry_mpi_aprint (GCRYMPI_FMT_USG, bufarr+j,
-                                         narr+j, sk->skey[i]))
-                      BUG();
-                   nbits[j] = gcry_mpi_get_nbits (sk->skey[i]);
-                   ndata += narr[j] + 2;
-                  }
-               for ( ; j < PUBKEY_MAX_NSKEY; j++ )
-                  bufarr[j] = NULL;
-
-               ndata += opt.simple_sk_checksum? 2 : 20; /* for checksum */
-
-               data = xmalloc_secure( ndata );
-               p = data;
-               for(j=0; j < PUBKEY_MAX_NSKEY && bufarr[j]; j++ ) {
-                   p[0] = nbits[j] >> 8 ;
-                   p[1] = nbits[j];
-                   p += 2;
-                   memcpy(p, bufarr[j], narr[j] );
-                   p += narr[j];
-                   xfree(bufarr[j]);
-               }
-                
-                if (opt.simple_sk_checksum) {
-                    log_info (_("generating the deprecated 16-bit checksum"
-                              " for secret key protection\n")); 
-                    csum = checksum( data, ndata-2);
-                    sk->csum = csum;
-                    *p++ =     csum >> 8;
-                    *p++ =     csum;
-                    sk->protect.sha1chk = 0;
-                }
-                else {
-                    gcry_md_hd_t h;
-
-                    if (gcry_md_open (&h, GCRY_MD_SHA1, 1))
-                      BUG(); /* Algo not available. */
-                    gcry_md_write (h, data, ndata - 20);
-                    gcry_md_final (h);
-                    memcpy (p, gcry_md_read (h, DIGEST_ALGO_SHA1), 20);
-                    p += 20;
-                    gcry_md_close (h);
-                    sk->csum = csum = 0;
-                    sk->protect.sha1chk = 1;
-                }
-                assert( p == data+ndata );
-
-               gcry_cipher_encrypt (cipher_hd, data, ndata, NULL, 0);
-               for (i = pubkey_get_npkey(sk->pubkey_algo);
-                     i < pubkey_get_nskey(sk->pubkey_algo); i++ )
-                  {
-                   gcry_mpi_release (sk->skey[i]);
-                   sk->skey[i] = NULL;
-                  }
-               i = pubkey_get_npkey(sk->pubkey_algo);
-               sk->skey[i] = gcry_mpi_set_opaque (NULL, data, ndata*8 );
-           }
-           else {
-               csum = 0;
-               for(i=pubkey_get_npkey(sk->pubkey_algo);
-                       i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
-                    byte *data;
-                   unsigned int nbits;
-
-                   csum += checksum_mpi (sk->skey[i]);
-
-                   if (gcry_mpi_aprint (GCRYMPI_FMT_USG, &buffer,
-                                         &nbytes, sk->skey[i] ))
-                      BUG();
-                   gcry_cipher_sync (cipher_hd);
-                   assert (!gcry_mpi_get_flag (sk->skey[i],
-                                                GCRYMPI_FLAG_OPAQUE));
-
-                    data = xmalloc (nbytes+2);  /* fixme: need xtrymalloc. */
-                    nbits = gcry_mpi_get_nbits (sk->skey[i]);
-                    assert (nbytes == (nbits + 7)/8);
-                    data[0] = nbits >> 8;
-                    data[1] = nbits;
-                   gcry_cipher_encrypt (cipher_hd, data+2, nbytes,
-                                         buffer, nbytes);
-                   xfree( buffer );
-                    
-                    gcry_mpi_release (sk->skey[i]);
-                    sk->skey[i] = gcry_mpi_set_opaque (NULL,
-                                                       data, (nbytes+2)*8 );
-               }
-               sk->csum = csum;
-           }
-           sk->is_protected = 1;
-           gcry_cipher_close (cipher_hd);
-       }
-    }
-    return rc;
+  return 0; /* FIXME:  use agent_get_keyinfo?*/
+    /* return sk->is_protected? */
+    /*            sk->protect.s2k.mode == 1002? -2 : */
+    /*            sk->protect.s2k.mode == 1001? -3 : sk->protect.algo : 0; */
 }
 }
index ccbfe30..ee5584c 100644 (file)
@@ -206,19 +206,18 @@ do_encode_md( gcry_md_hd_t md, int algo, size_t len, unsigned nbits,
  * bits.
  */
 gcry_mpi_t
  * bits.
  */
 gcry_mpi_t
-encode_md_value (PKT_public_key *pk, PKT_secret_key *sk,
-                gcry_md_hd_t md, int hash_algo)
+encode_md_value (PKT_public_key *pk, gcry_md_hd_t md, int hash_algo)
 {
   gcry_mpi_t frame;
 
 {
   gcry_mpi_t frame;
 
-  assert(hash_algo);
-  assert(pk || sk);
+  assert (hash_algo);
+  assert (pk);
 
 
-  if((pk?pk->pubkey_algo:sk->pubkey_algo) == GCRY_PK_DSA)
+  if (pk->pubkey_algo == GCRY_PK_DSA)
     {
       /* It's a DSA signature, so find out the size of q. */
 
     {
       /* It's a DSA signature, so find out the size of q. */
 
-      size_t qbytes = gcry_mpi_get_nbits (pk?pk->pkey[1]:sk->skey[1]);
+      size_t qbytes = gcry_mpi_get_nbits (pk->pkey[1]);
 
       /* Make sure it is a multiple of 8 bits. */
 
 
       /* Make sure it is a multiple of 8 bits. */
 
@@ -237,21 +236,19 @@ encode_md_value (PKT_public_key *pk, PKT_secret_key *sk,
         DSA. ;) */
       if (qbytes < 160)
        {
         DSA. ;) */
       if (qbytes < 160)
        {
-         log_error (_("DSA key %s uses an unsafe (%u bit) hash\n"),
-                     pk?keystr_from_pk(pk):keystr_from_sk(sk),
-                     (unsigned int)qbytes);
+         log_error (_("DSA key %s uses an unsafe (%zu bit) hash\n"),
+                     keystr_from_pk (pk), qbytes);
          return NULL;
        }
 
          return NULL;
        }
 
-      qbytes/=8;
+      qbytes /= 8;
 
       /* Check if we're too short.  Too long is safe as we'll
         automatically left-truncate. */
       if (gcry_md_get_algo_dlen (hash_algo) < qbytes)
        {
 
       /* Check if we're too short.  Too long is safe as we'll
         automatically left-truncate. */
       if (gcry_md_get_algo_dlen (hash_algo) < qbytes)
        {
-         log_error (_("DSA key %s requires a %u bit or larger hash\n"),
-                     pk?keystr_from_pk(pk):keystr_from_sk(sk),
-                     (unsigned int)(qbytes*8));
+         log_error (_("DSA key %s requires a %zu bit or larger hash\n"),
+                     keystr_from_pk(pk), qbytes*8);
          return NULL;
        }
 
          return NULL;
        }
 
@@ -269,12 +266,13 @@ encode_md_value (PKT_public_key *pk, PKT_secret_key *sk,
       if (rc)
         log_fatal ("can't get OID of digest algorithm %d: %s\n",
                    hash_algo, gpg_strerror (rc));
       if (rc)
         log_fatal ("can't get OID of digest algorithm %d: %s\n",
                    hash_algo, gpg_strerror (rc));
-      asn = xmalloc (asnlen);
+      asn = xtrymalloc (asnlen);
+      if (!asn)
+        return NULL;
       if ( gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, asn, &asnlen) )
         BUG();
       frame = do_encode_md (md, hash_algo, gcry_md_get_algo_dlen (hash_algo),
       if ( gcry_md_algo_info (hash_algo, GCRYCTL_GET_ASNOID, asn, &asnlen) )
         BUG();
       frame = do_encode_md (md, hash_algo, gcry_md_get_algo_dlen (hash_algo),
-                            gcry_mpi_get_nbits (pk?pk->pkey[0]:sk->skey[0]),
-                            asn, asnlen);
+                            gcry_mpi_get_nbits (pk->pkey[0]), asn, asnlen);
       xfree (asn);
     }
 
       xfree (asn);
     }
 
index 1feac38..a24890f 100644 (file)
@@ -315,7 +315,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, gcry_md_hd_t digest,
     }
     gcry_md_final( digest );
 
     }
     gcry_md_final( digest );
 
-    result = encode_md_value( pk, NULL, digest, sig->digest_algo );
+    result = encode_md_value (pk, digest, sig->digest_algo );
     if (!result)
         return G10ERR_GENERAL;
     ctx.sig = sig;
     if (!result)
         return G10ERR_GENERAL;
     ctx.sig = sig;
index d06a9cc..eb3ec1f 100644 (file)
@@ -228,37 +228,55 @@ hash_sigversion_to_magic (gcry_md_hd_t md, const PKT_signature *sig)
 }
 
 
 }
 
 
+static gcry_mpi_t
+mpi_from_sexp (gcry_sexp_t sexp, const char * item)
+{
+  gcry_sexp_t list;
+  gcry_mpi_t data;
+  
+  list = gcry_sexp_find_token (sexp, item, 0);
+  assert (list);
+  data = gcry_sexp_nth_mpi (list, 1, 0);
+  assert (data);
+  gcry_sexp_release (list);
+  return data;
+}
+
+
 static int
 do_sign (PKT_public_key *pksk, PKT_signature *sig,
 static int
 do_sign (PKT_public_key *pksk, PKT_signature *sig,
-        gcry_md_hd_t md, int digest_algo)
+        gcry_md_hd_t md, int mdalgo)
 {
 {
-    gcry_mpi_t frame;
-    byte *dp;
-    int rc;
-
-    if (pksk->timestamp > sig->timestamp ) {
-       ulong d = pksk->timestamp - sig->timestamp;
-       log_info( d==1 ? _("key has been created %lu second "
-                          "in future (time warp or clock problem)\n")
-                      : _("key has been created %lu seconds "
-                          "in future (time warp or clock problem)\n"), d );
-       if( !opt.ignore_time_conflict )
-           return G10ERR_TIME_CONFLICT;
+  gpg_error_t err;
+  gcry_mpi_t frame;
+  byte *dp;
+
+  if (pksk->timestamp > sig->timestamp )
+    {
+      ulong d = pksk->timestamp - sig->timestamp;
+      log_info (d==1 ? _("key has been created %lu second "
+                         "in future (time warp or clock problem)\n")
+                : _("key has been created %lu seconds "
+                    "in future (time warp or clock problem)\n"), d );
+      if (!opt.ignore_time_conflict)
+        return gpg_error (GPG_ERR_TIME_CONFLICT);
     }
 
     }
 
+  
+  print_pubkey_algo_note (pksk->pubkey_algo);
 
 
-    print_pubkey_algo_note (pksk->pubkey_algo);
+  if (!mdalgo)
+    mdalgo = gcry_md_get_algo (md);
 
 
-    if( !digest_algo )
-       digest_algo = gcry_md_get_algo (md);
+  print_digest_algo_note (mdalgo);
+  dp = gcry_md_read  (md, mdalgo);
+  sig->digest_algo = mdalgo;
+  sig->digest_start[0] = dp[0];
+  sig->digest_start[1] = dp[1];
+  sig->data[0] = NULL;
+  sig->data[1] = NULL;
 
 
-    print_digest_algo_note( digest_algo );
-    dp = gcry_md_read ( md, digest_algo );
-    sig->digest_algo = digest_algo;
-    sig->digest_start[0] = dp[0];
-    sig->digest_start[1] = dp[1];
-
-    /* FIXME: Use agent.  */
+#warning fixme: Use the agent for the card
 /*     if (pksk->is_protected && pksk->protect.s2k.mode == 1002)  */
 /*       {  */
 /* #ifdef ENABLE_CARD_SUPPORT */
 /*     if (pksk->is_protected && pksk->protect.s2k.mode == 1002)  */
 /*       {  */
 /* #ifdef ENABLE_CARD_SUPPORT */
@@ -285,57 +303,89 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
 /* #endif /\* ENABLE_CARD_SUPPORT *\/ */
 /*       } */
 /*     else  */
 /* #endif /\* ENABLE_CARD_SUPPORT *\/ */
 /*       } */
 /*     else  */
-      {
-        frame = encode_md_value (NULL, pksk, md, digest_algo );
-        if (!frame)
-          return G10ERR_GENERAL;
-        rc = pk_sign (pksk->pubkey_algo, sig->data, frame, pksk->pkey );
-        gcry_mpi_release (frame);
-      }
+  if (1)
+    {
+      char *hexgrip;
+      
+      err = hexkeygrip_from_pk (pksk, &hexgrip);
+      if (!err)
+        {
+          char *desc;
+          gcry_sexp_t s_sigval;
+          
+          /* FIXME: desc = gpgsm_format_keydesc (cert); */
+          desc = xtrystrdup ("FIXME: Format a decription");
+          
+          err = agent_pksign (NULL/*ctrl*/, hexgrip, desc, 
+                              dp, gcry_md_get_algo_dlen (mdalgo), mdalgo,
+                              &s_sigval);
+          
+          xfree (desc);
+     
+          if (err)
+            ;
+          else if (pksk->pubkey_algo == GCRY_PK_RSA
+                   || pksk->pubkey_algo == GCRY_PK_RSA_S)
+            sig->data[0] = mpi_from_sexp (s_sigval, "s");
+          else
+            {
+              sig->data[0] = mpi_from_sexp (s_sigval, "r");
+              sig->data[1] = mpi_from_sexp (s_sigval, "s");
+            }
+      
+          gcry_sexp_release (s_sigval);
+        }
+      xfree (hexgrip);
+    }
 
 
-    if (!rc && !opt.no_sig_create_check) {
-        /* Check that the signature verification worked and nothing is
-         * fooling us e.g. by a bug in the signature create
-         * code or by deliberately introduced faults. */
-        PKT_public_key *pk = xmalloc_clear (sizeof *pk);
+  /* Check that the signature verification worked and nothing is
+   * fooling us e.g. by a bug in the signature create code or by
+   * deliberately introduced faults.  */
+  if (!err && !opt.no_sig_create_check)
+    {
+      PKT_public_key *pk = xmalloc_clear (sizeof *pk);
 
 
-        if( get_pubkey( pk, sig->keyid ) )
-            rc = G10ERR_NO_PUBKEY;
-        else {
-           frame = encode_md_value (pk, NULL, md, sig->digest_algo );
-            if (!frame)
-              rc = G10ERR_GENERAL;
-            else
-              rc = pk_verify (pk->pubkey_algo, frame, sig->data, pk->pkey );
-            gcry_mpi_release (frame);
+      if (get_pubkey (pk, sig->keyid ))
+        err = gpg_error (GPG_ERR_NO_PUBKEY);
+      else 
+        {
+          frame = encode_md_value (pk, md, sig->digest_algo );
+          if (!frame)
+            err = gpg_error (GPG_ERR_GENERAL);
+          else
+            err = pk_verify (pk->pubkey_algo, frame, sig->data, pk->pkey);
+          gcry_mpi_release (frame);
         }
         }
-        if (rc)
-            log_error (_("checking created signature failed: %s\n"),
-                         g10_errstr (rc));
-        free_public_key (pk);
+      if (err)
+        log_error (_("checking created signature failed: %s\n"),
+                   g10_errstr (err));
+      free_public_key (pk);
     }
     }
-    if( rc )
-       log_error(_("signing failed: %s\n"), g10_errstr(rc) );
-    else {
-       if( opt.verbose ) {
-           char *ustr = get_user_id_string_native (sig->keyid);
-           log_info(_("%s/%s signature from: \"%s\"\n"),
-                    gcry_pk_algo_name (pksk->pubkey_algo),
-                    gcry_md_algo_name (sig->digest_algo),
-                    ustr );
-           xfree(ustr);
+
+  if (err)
+    log_error (_("signing failed: %s\n"), g10_errstr (err));
+  else 
+    {
+      if (opt.verbose)
+        {
+          char *ustr = get_user_id_string_native (sig->keyid);
+          log_info (_("%s/%s signature from: \"%s\"\n"),
+                    gcry_pk_algo_name (pksk->pubkey_algo),
+                    gcry_md_algo_name (sig->digest_algo),
+                    ustr);
+          xfree (ustr);
        }
     }
        }
     }
-    return rc;
+  return err;
 }
 
 
 int
 }
 
 
 int
-complete_sig( PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md )
+complete_sig (PKT_signature *sig, PKT_public_key *pksk, gcry_md_hd_t md)
 {
   int rc;
 
 {
   int rc;
 
-  if (!(rc = check_secret_key (pksk, 0)))
+  /* if (!(rc = check_secret_key (pksk, 0))) */
     rc = do_sign (pksk, sig, md, 0);
   return rc;
 }
     rc = do_sign (pksk, sig, md, 0);
   return rc;
 }