Removed more secret key related code.
authorWerner Koch <wk@gnupg.org>
Mon, 6 Sep 2010 19:57:42 +0000 (19:57 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 6 Sep 2010 19:57:42 +0000 (19:57 +0000)
It builds fine and passes some of the tests but there are quite some
features which don't work yet.

20 files changed:
g10/ChangeLog
g10/build-packet.c
g10/card-util.c
g10/delkey.c
g10/export.c
g10/free-packet.c
g10/getkey.c
g10/import.c
g10/keydb.h
g10/keyedit.c
g10/keyid.c
g10/keylist.c
g10/keyring.c
g10/main.h
g10/mainproc.c
g10/packet.h
g10/parse-packet.c
g10/passphrase.c
g10/pubkey-enc.c
g10/sign.c

index eede336..70e471e 100644 (file)
@@ -1,3 +1,53 @@
+2010-09-06  Werner Koch  <wk@g10code.com>
+
+
+       * card-util.c (card_status): Remove stub creation fro GnuPG >= 2.
+       (card_store_subkey): Temporary disable this code.
+
+       * keyedit.c (show_key_with_all_names): Merge secret and public key
+       parts.
+       (show_basic_key_info): Ditto.
+       * delkey.c (do_delete_key): Ditto.
+       * export.c (subkey_in_list_p, exact_subkey_match_p): Ditto.
+       (new_subkey_list_item): Ditto.
+
+       * keyid.c (keystr_from_sk, keystr_from_sk_with_sub)
+       (keyid_from_sk, nbits_from_sk, datestr_from_sk)
+       (expirestr_from_sk, colon_datestr_from_sk, fingerprint_from_sk)
+       (serialno_and_fpr_from_sk, do_fingerprint_md_sk): Remove.
+
+       * import.c (print_import_ok): Remove arg SK.
+       (import_secret_one): Adjust for seckey_info format.
+       (transfer_secret_keys): Ditto.  Use gpg_format_keydesc.
+       (sec_to_pub_keyblock): Simplify.
+       (pub_to_sec_keyblock): Remove.
+       (auto_create_card_key_stub): Remove - not anymore needed.
+       (update_sec_keyblock_with_cardinfo): Remove.
+       (import_secret_one): Use arg option instead of the global option.
+
+       * free-packet.c (copy_public_key): Adjust for seckey_info format.
+       (copy_public_parts_to_secret_key, copy_secret_key)
+       (cmp_secret_keys, cmp_public_secret_key): Remove.
+
+       * passphrase.c (gpg_format_keydesc): Add arg MODE and change all
+       callers.
+       * keyring.c (keyring_search): Remove special case for secret keys.
+       * mainproc.c (struct mainproc_context): Remove unused field
+       LAST_SECKEY.
+       * parse-packet.c (parse_key): Rewrite to cope with new seckey_info
+       format.
+       * build-packet.c (do_public_key, do_secret_key): Merge code into ...
+       (do_key): .. new.  Cope with seckey_info format.
+
+2010-09-03  Werner Koch  <wk@g10code.com>
+
+       * packet.h (struct seckey_info): New.
+       (PKT_public_key): Increase size of PKEY to allow storing of secret
+       keys.  Add field SECKEY_INFO.
+       (PKT_secret_key): Remove.
+       * free-packet.c (release_public_key_parts): Take care of change.
+       (release_secret_key_parts, free_secret_key): Remove.
+
 2010-09-02  Werner Koch  <wk@g10code.com>
 
        * import.c (transfer_secret_keys, import_secret_one): Enable stats.
index 37922d9..354afec 100644 (file)
@@ -1,6 +1,6 @@
 /* build-packet.c - assemble packets and write them
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
- *               2006 Free Software Foundation, Inc.
+ *               2006, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -35,8 +35,7 @@
 #include "options.h"
 
 static int do_user_id( IOBUF out, int ctb, PKT_user_id *uid );
-static int do_public_key( IOBUF out, int ctb, PKT_public_key *pk );
-static int do_secret_key( IOBUF out, int ctb, PKT_secret_key *pk );
+static int do_key (iobuf_t out, int ctb, PKT_public_key *pk);
 static int do_symkey_enc( IOBUF out, int ctb, PKT_symkey_enc *enc );
 static int do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc );
 static u32 calc_plaintext( PKT_plaintext *pt );
@@ -107,11 +106,9 @@ build_packet( IOBUF out, PACKET *pkt )
        break;
       case PKT_PUBLIC_SUBKEY:
       case PKT_PUBLIC_KEY:
-       rc = do_public_key( out, ctb, pkt->pkt.public_key );
-       break;
       case PKT_SECRET_SUBKEY:
       case PKT_SECRET_KEY:
-       rc = do_secret_key( out, ctb, pkt->pkt.secret_key );
+       rc = do_key (out, ctb, pkt->pkt.public_key);
        break;
       case PKT_SYMKEY_ENC:
        rc = do_symkey_enc( out, ctb, pkt->pkt.symkey_enc );
@@ -242,198 +239,162 @@ do_user_id( IOBUF out, int ctb, PKT_user_id *uid )
     return 0;
 }
 
-static int
-do_public_key( IOBUF out, int ctb, PKT_public_key *pk )
-{
-  int rc = 0;
-  int n, i;
-  IOBUF a = iobuf_temp();
-  
-  if ( !pk->version )
-    iobuf_put( a, 3 );
-  else
-    iobuf_put( a, pk->version );
-  write_32(a, pk->timestamp );
-  if ( pk->version < 4 ) 
-    {
-      u16 ndays;
-      if ( pk->expiredate )
-        ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
-      else
-        ndays = 0;
-      write_16(a, ndays );
-    }
-  iobuf_put (a, pk->pubkey_algo );
-  n = pubkey_get_npkey ( pk->pubkey_algo );
-  if ( !n )
-    write_fake_data( a, pk->pkey[0] );
-  for (i=0; i < n && !rc ; i++ )
-    rc = mpi_write(a, pk->pkey[i] );
-
-  if (!rc)
-    {
-      write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
-      rc = iobuf_write_temp ( out, a );
-    }
-
-  iobuf_close(a);
-  return rc;
-}
-
 
 static int
-do_secret_key( IOBUF out, int ctb, PKT_secret_key *sk )
+do_key (iobuf_t out, int ctb, PKT_public_key *pk)
 {
-  int rc = 0;
+  gpg_error_t err = 0;
   int i, nskey, npkey;
-  IOBUF a = iobuf_temp(); /* Build in a self-enlarging buffer.  */
+  iobuf_t a = iobuf_temp(); /* Build in a self-enlarging buffer.  */
 
   /* Write the version number - if none is specified, use 3 */
-  if ( !sk->version )
+  if ( !pk->version )
     iobuf_put ( a, 3 );
   else
-    iobuf_put ( a, sk->version );
-  write_32 (a, sk->timestamp );
+    iobuf_put ( a, pk->version );
+  write_32 (a, pk->timestamp );
 
   /* v3 needs the expiration time. */
-  if ( sk->version < 4 )
+  if ( pk->version < 4 )
     {
       u16 ndays;
-      if ( sk->expiredate )
-        ndays = (u16)((sk->expiredate - sk->timestamp) / 86400L);
+      if ( pk->expiredate )
+        ndays = (u16)((pk->expiredate - pk->timestamp) / 86400L);
       else
         ndays = 0;
       write_16(a, ndays);
     }
   
-  iobuf_put (a, sk->pubkey_algo );
+  iobuf_put (a, pk->pubkey_algo );
   
   /* Get number of secret and public parameters.  They are held in one
      array first the public ones, then the secret ones.  */
-  nskey = pubkey_get_nskey ( sk->pubkey_algo );
-  npkey = pubkey_get_npkey ( sk->pubkey_algo );
+  nskey = pubkey_get_nskey (pk->pubkey_algo);
+  npkey = pubkey_get_npkey (pk->pubkey_algo);
   
   /* If we don't have any public parameters - which is the case if we
      don't know the algorithm used - the parameters are stored as one
      blob in a faked (opaque) MPI. */
-  if ( !npkey 
+  if (!npkey
     {
-      write_fake_data( a, sk->skey[0] );
+      write_fake_data (a, pk->pkey[0]);
       goto leave;
     }
-  assert ( npkey < nskey );
+  assert (npkey < nskey);
 
   /* Writing the public parameters is easy. */
   for (i=0; i < npkey; i++ )
-    if ((rc = mpi_write (a, sk->skey[i])))
+    if ((err = mpi_write (a, pk->pkey[i])))
       goto leave;
   
-  /* Build the header for protected (encrypted) secret parameters.  */
-  if ( sk->is_protected ) 
+  if (pk->seckey_info)
     {
-      if ( is_RSA(sk->pubkey_algo) 
-           && sk->version < 4
-           && !sk->protect.s2k.mode )
-        {
-          /* The simple rfc1991 (v3) way. */
-          iobuf_put (a, sk->protect.algo );
-          iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
-       }
-      else
+      /* This is a secret key packet.  */
+      struct seckey_info *ski = pk->seckey_info;
+
+      /* Build the header for protected (encrypted) secret parameters.  */
+      if (ski->is_protected) 
         {
-          /* OpenPGP protection according to rfc2440. */
-          iobuf_put(a, sk->protect.sha1chk? 0xfe : 0xff );
-          iobuf_put(a, sk->protect.algo );
-          if ( sk->protect.s2k.mode >= 1000 )
+          if ( is_RSA (pk->pubkey_algo) && pk->version < 4 && !ski->s2k.mode )
             {
-              /* These modes are not possible in OpenPGP, we use them
-                 to implement our extensions, 101 can be seen as a
-                 private/experimental extension (this is not specified
-                 in rfc2440 but the same scheme is used for all other
-                 algorithm identifiers) */
-              iobuf_put(a, 101 ); 
-              iobuf_put(a, sk->protect.s2k.hash_algo );
-              iobuf_write(a, "GNU", 3 );
-              iobuf_put(a, sk->protect.s2k.mode - 1000 );
-           }
-          else 
+              /* The simple rfc1991 (v3) way. */
+              iobuf_put (a, ski->algo );
+              iobuf_write (a, ski->iv, ski->ivlen);
+            }
+          else
             {
-              iobuf_put(a, sk->protect.s2k.mode );
-              iobuf_put(a, sk->protect.s2k.hash_algo );
-           }
-          if ( sk->protect.s2k.mode == 1
-               || sk->protect.s2k.mode == 3 )
-            iobuf_write (a, sk->protect.s2k.salt, 8 );
-
-          if ( sk->protect.s2k.mode == 3 )
-            iobuf_put (a, sk->protect.s2k.count ); 
-
-          /* For our special modes 1001, 1002 we do not need an IV. */
-          if ( sk->protect.s2k.mode != 1001 
-               && sk->protect.s2k.mode != 1002 )
-            iobuf_write (a, sk->protect.iv, sk->protect.ivlen );
-       }
-    }
-  else
-    iobuf_put (a, 0 );
-
-  if ( sk->protect.s2k.mode == 1001 )
-    ; /* GnuPG extension - don't write a secret key at all. */ 
-  else if ( sk->protect.s2k.mode == 1002 )
-    { 
-      /* GnuPG extension - divert to OpenPGP smartcard. */ 
-      iobuf_put(a, sk->protect.ivlen ); /* Length of the serial number
-                                           or 0 for no serial
-                                           number. */
-      /* The serial number gets stored in the IV field. */
-      iobuf_write(a, sk->protect.iv, sk->protect.ivlen);
-    }
-  else if ( sk->is_protected && sk->version >= 4 )
-    {
-      /* The secret key is protected - write it out as it is.  */
-      byte *p;
-      unsigned int ndatabits;
-      
-      assert (gcry_mpi_get_flag (sk->skey[npkey], GCRYMPI_FLAG_OPAQUE));
-      p = gcry_mpi_get_opaque (sk->skey[npkey], &ndatabits );
-      iobuf_write (a, p, (ndatabits+7)/8 );
-    }
-  else if ( sk->is_protected ) 
-    {
-      /* The secret key is protected the old v4 way. */
-      for ( ; i < nskey; i++ ) 
+              /* OpenPGP protection according to rfc2440. */
+              iobuf_put (a, ski->sha1chk? 0xfe : 0xff);
+              iobuf_put (a, ski->algo);
+              if (ski->s2k.mode >= 1000)
+                {
+                  /* These modes are not possible in OpenPGP, we use
+                     them to implement our extensions, 101 can be
+                     viewed as a private/experimental extension (this
+                     is not specified in rfc2440 but the same scheme
+                     is used for all other algorithm identifiers). */
+                  iobuf_put (a, 101); 
+                  iobuf_put (a, ski->s2k.hash_algo);
+                  iobuf_write (a, "GNU", 3 );
+                  iobuf_put (a, ski->s2k.mode - 1000);
+                }
+              else 
+                {
+                  iobuf_put (a, ski->s2k.mode);
+                  iobuf_put (a, ski->s2k.hash_algo);
+                }
+
+              if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
+                iobuf_write (a, ski->s2k.salt, 8);
+
+              if (ski->s2k.mode == 3)
+                iobuf_put (a, ski->s2k.count); 
+
+              /* For our special modes 1001, 1002 we do not need an IV. */
+              if (ski->s2k.mode != 1001 && ski->s2k.mode != 1002)
+                iobuf_write (a, ski->iv, ski->ivlen);
+            }
+        }
+      else /* Not protected. */
+        iobuf_put (a, 0 );
+
+      if (ski->s2k.mode == 1001)
+        ; /* GnuPG extension - don't write a secret key at all. */ 
+      else if (ski->s2k.mode == 1002)
+        { 
+          /* GnuPG extension - divert to OpenPGP smartcard. */ 
+          /* Length of the serial number or 0 for no serial number. */
+          iobuf_put (a, ski->ivlen );
+          /* The serial number gets stored in the IV field.  */
+          iobuf_write (a, ski->iv, ski->ivlen);
+        }
+      else if (ski->is_protected && pk->version >= 4)
         {
+          /* The secret key is protected - write it out as it is.  */
           byte *p;
           unsigned int ndatabits;
+      
+          assert (gcry_mpi_get_flag (pk->pkey[npkey], GCRYMPI_FLAG_OPAQUE));
+          p = gcry_mpi_get_opaque (pk->pkey[npkey], &ndatabits);
+          iobuf_write (a, p, (ndatabits+7)/8 );
+        }
+      else if (ski->is_protected) 
+        {
+          /* The secret key is protected the old v4 way. */
+          for ( ; i < nskey; i++ ) 
+            {
+              byte *p;
+              unsigned int ndatabits;
           
-          assert (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE));
-          p = gcry_mpi_get_opaque (sk->skey[i], &ndatabits);
-          iobuf_write (a, p, (ndatabits+7)/8);
+              assert (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE));
+              p = gcry_mpi_get_opaque (pk->pkey[i], &ndatabits);
+              iobuf_write (a, p, (ndatabits+7)/8);
+            }
+          write_16 (a, ski->csum );
+        }
+      else
+        {
+          /* Non-protected key. */
+          for ( ; i < nskey; i++ )
+            if ( (err = mpi_write (a, pk->pkey[i])))
+              goto leave;
+          write_16 (a, ski->csum );
         }
-      write_16(a, sk->csum );
-    }
-  else
-    {
-      /* Non-protected key. */
-      for ( ; i < nskey; i++ )
-        if ( (rc = mpi_write (a, sk->skey[i])))
-          goto leave;
-      write_16 (a, sk->csum );
     }
 
  leave:
-  if (!rc)
+  if (!err)
     {
       /* Build the header of the packet - which we must do after
          writing all the other stuff, so that we know the length of
          the packet */
-      write_header2(out, ctb, iobuf_get_temp_length(a), sk->hdrbytes);
-      /* And finally write it out the real stream */
-      rc = iobuf_write_temp( out, a );
+      write_header2 (out, ctb, iobuf_get_temp_length(a), pk->hdrbytes);
+      /* And finally write it out to the real stream. */
+      err = iobuf_write_temp (out, a);
     }
 
-  iobuf_close(a); /* Close the remporary buffer */
-  return rc;
+  iobuf_close (a); /* Close the temporary buffer */
+  return err;
 }
 
 static int
index 4b537bc..1dd7a92 100644 (file)
@@ -207,6 +207,9 @@ get_manufacturer (unsigned int no)
     case 0x0005: return "ZeitControl";
 
     case 0x002A: return "Magrathea";
+
+    case 0xF517: return "FSIJ";
+
       /* 0x00000 and 0xFFFF are defined as test cards per spec,
          0xFFF00 to 0xFFFE are assigned for use with randomly created
          serial numbers.  */
@@ -581,6 +584,7 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
 
           print_pubkey_info (fp, pk);
 
+#if GNUPG_MAJOR_VERSION == 1
           if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
             print_card_key_info (fp, keyblock);
           else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
@@ -599,6 +603,7 @@ card_status (estream_t fp, char *serialno, size_t serialnobuflen)
             }
 
           release_kbnode (keyblock);
+#endif /* GNUPG_MAJOR_VERSION == 1 */
         }
       else
         tty_fprintf (fp, "[none]\n");
@@ -1514,150 +1519,151 @@ card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
 int 
 card_store_subkey (KBNODE node, int use)
 {
-  struct agent_card_info_s info;
-  int okay = 0;
-  int rc;
-  int keyno, i;
-  PKT_secret_key *copied_sk = NULL;
-  PKT_secret_key *sk;
-  size_t n;
-  const char *s;
-  int allow_keyno[3];
-  unsigned int nbits;
-
-
-  assert (node->pkt->pkttype == PKT_SECRET_KEY
-          || node->pkt->pkttype == PKT_SECRET_SUBKEY);
-  sk = node->pkt->pkt.secret_key;
-
-  if (get_info_for_key_operation (&info))
-    return 0;
-
-  if (!info.extcap.ki)
-    {
-      tty_printf ("The card does not support the import of keys\n");
-      tty_printf ("\n");
-      goto leave;
-    }
-
-  show_card_key_info (&info);
-
-  nbits = nbits_from_sk (sk);
-
-  if (!is_RSA (sk->pubkey_algo) || (!info.is_v2 && nbits != 1024) )
-    {
-      tty_printf ("You may only store a 1024 bit RSA key on the card\n");
-      tty_printf ("\n");
-      goto leave;
-    }
-
-  allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG)));
-  allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC)));
-  allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)));
-
-  tty_printf (_("Please select where to store the key:\n"));
-
-  if (allow_keyno[0])
-    tty_printf (_("   (1) Signature key\n"));
-  if (allow_keyno[1])
-    tty_printf (_("   (2) Encryption key\n"));
-  if (allow_keyno[2])
-    tty_printf (_("   (3) Authentication key\n"));
-
-  for (;;) 
-    {
-      char *answer = cpr_get ("cardedit.genkeys.storekeytype",
-                              _("Your selection? "));
-      cpr_kill_prompt();
-      if (*answer == CONTROL_D || !*answer)
-        {
-          xfree (answer);
-          goto leave;
-        }
-      keyno = *answer? atoi(answer): 0;
-      xfree(answer);
-      if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1])
-        {
-          if (info.is_v2 && !info.extcap.aac 
-              && info.key_attr[keyno-1].nbits != nbits)
-            {
-              tty_printf ("Key does not match the card's capability.\n");
-            }
-          else
-            break; /* Okay. */
-        }
-      else
-        tty_printf(_("Invalid selection.\n"));
-    }
-
-  if (replace_existing_key_p (&info, keyno))
-    goto leave;
-
-  /* Unprotect key.  */
-  switch (is_secret_key_protected (sk) )
-    {
-    case 0: /* Not protected. */
-      break;
-    case -1:
-      log_error (_("unknown key protection algorithm\n"));
-      goto leave;
-    default:
-      if (sk->protect.s2k.mode == 1001)
-        {
-          log_error (_("secret parts of key are not available\n"));
-          goto leave;
-       }
-      if (sk->protect.s2k.mode == 1002)
-        {
-          log_error (_("secret key already stored on a card\n"));
-          goto leave;
-       }
-      /* We better copy the key before we unprotect it.  */
-      copied_sk = sk = copy_secret_key (NULL, sk);
-      rc = 0/*check_secret_key (sk, 0)*/;
-      if (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)
-    {
-      free_secret_key (copied_sk);
-      copied_sk = NULL; 
-    }
-  sk = node->pkt->pkt.secret_key;
-
-  /* Get rid of the secret key parameters and store the serial numer. */
-  n = pubkey_get_nskey (sk->pubkey_algo);
-  for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; 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, xstrdup ("dummydata"), 10*8);
-  sk->is_protected = 1;
-  sk->protect.s2k.mode = 1002;
-  s = info.serialno;
-  for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
-       sk->protect.ivlen++, s += 2)
-    sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
-
-  okay = 1;
-
- leave:
-  if (copied_sk)
-    free_secret_key (copied_sk);
-  agent_release_card_info (&info);
-  return okay;
+/*   struct agent_card_info_s info; */
+/*   int okay = 0; */
+/*   int rc; */
+/*   int keyno, i; */
+/*   PKT_secret_key *copied_sk = NULL; */
+/*   PKT_secret_key *sk; */
+/*   size_t n; */
+/*   const char *s; */
+/*   int allow_keyno[3]; */
+/*   unsigned int nbits; */
+
+
+/*   assert (node->pkt->pkttype == PKT_SECRET_KEY */
+/*           || node->pkt->pkttype == PKT_SECRET_SUBKEY); */
+/*   sk = node->pkt->pkt.secret_key; */
+
+/*   if (get_info_for_key_operation (&info)) */
+/*     return 0; */
+
+/*   if (!info.extcap.ki) */
+/*     { */
+/*       tty_printf ("The card does not support the import of keys\n"); */
+/*       tty_printf ("\n"); */
+/*       goto leave; */
+/*     } */
+
+/*   show_card_key_info (&info); */
+
+/*   nbits = nbits_from_sk (sk); */
+
+/*   if (!is_RSA (sk->pubkey_algo) || (!info.is_v2 && nbits != 1024) ) */
+/*     { */
+/*       tty_printf ("You may only store a 1024 bit RSA key on the card\n"); */
+/*       tty_printf ("\n"); */
+/*       goto leave; */
+/*     } */
+
+/*   allow_keyno[0] = (!use || (use & (PUBKEY_USAGE_SIG))); */
+/*   allow_keyno[1] = (!use || (use & (PUBKEY_USAGE_ENC))); */
+/*   allow_keyno[2] = (!use || (use & (PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH))); */
+
+/*   tty_printf (_("Please select where to store the key:\n")); */
+
+/*   if (allow_keyno[0]) */
+/*     tty_printf (_("   (1) Signature key\n")); */
+/*   if (allow_keyno[1]) */
+/*     tty_printf (_("   (2) Encryption key\n")); */
+/*   if (allow_keyno[2]) */
+/*     tty_printf (_("   (3) Authentication key\n")); */
+
+/*   for (;;)  */
+/*     { */
+/*       char *answer = cpr_get ("cardedit.genkeys.storekeytype", */
+/*                               _("Your selection? ")); */
+/*       cpr_kill_prompt(); */
+/*       if (*answer == CONTROL_D || !*answer) */
+/*         { */
+/*           xfree (answer); */
+/*           goto leave; */
+/*         } */
+/*       keyno = *answer? atoi(answer): 0; */
+/*       xfree(answer); */
+/*       if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1]) */
+/*         { */
+/*           if (info.is_v2 && !info.extcap.aac  */
+/*               && info.key_attr[keyno-1].nbits != nbits) */
+/*             { */
+/*               tty_printf ("Key does not match the card's capability.\n"); */
+/*             } */
+/*           else */
+/*             break; /\* Okay. *\/ */
+/*         } */
+/*       else */
+/*         tty_printf(_("Invalid selection.\n")); */
+/*     } */
+
+/*   if (replace_existing_key_p (&info, keyno)) */
+/*     goto leave; */
+
+/*   /\* Unprotect key.  *\/ */
+/*   switch (is_secret_key_protected (sk) ) */
+/*     { */
+/*     case 0: /\* Not protected. *\/ */
+/*       break; */
+/*     case -1: */
+/*       log_error (_("unknown key protection algorithm\n")); */
+/*       goto leave; */
+/*     default: */
+/*       if (sk->protect.s2k.mode == 1001) */
+/*         { */
+/*           log_error (_("secret parts of key are not available\n")); */
+/*           goto leave; */
+/*     } */
+/*       if (sk->protect.s2k.mode == 1002) */
+/*         { */
+/*           log_error (_("secret key already stored on a card\n")); */
+/*           goto leave; */
+/*     } */
+/*       /\* We better copy the key before we unprotect it.  *\/ */
+/*       copied_sk = sk = copy_secret_key (NULL, sk); */
+/*       rc = 0/\*check_secret_key (sk, 0)*\/; */
+/*       if (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) */
+/*     { */
+/*       free_secret_key (copied_sk); */
+/*       copied_sk = NULL;  */
+/*     } */
+/*   sk = node->pkt->pkt.secret_key; */
+
+/*   /\* Get rid of the secret key parameters and store the serial numer. *\/ */
+/*   n = pubkey_get_nskey (sk->pubkey_algo); */
+/*   for (i=pubkey_get_npkey (sk->pubkey_algo); i < n; 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, xstrdup ("dummydata"), 10*8); */
+/*   sk->is_protected = 1; */
+/*   sk->protect.s2k.mode = 1002; */
+/*   s = info.serialno; */
+/*   for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1]; */
+/*        sk->protect.ivlen++, s += 2) */
+/*     sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s); */
+
+/*   okay = 1; */
+
+/*  leave: */
+/*   if (copied_sk) */
+/*     free_secret_key (copied_sk); */
+/*   agent_release_card_info (&info); */
+/*   return okay; */
+  return -1;
 }
 
 
index 2361d83..62c7563 100644 (file)
@@ -54,7 +54,6 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
     KBNODE node;
     KEYDB_HANDLE hd = keydb_new ();
     PKT_public_key *pk = NULL;
-    PKT_secret_key *sk = NULL;
     u32 keyid[2];
     int okay=0;
     int yes;
@@ -91,28 +90,19 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
        goto leave;
     }
 
-    if( secret )
+    pk = node->pkt->pkt.public_key;
+    keyid_from_pk( pk, keyid );
+    
+    if (!force)
       {
-       sk = node->pkt->pkt.secret_key;
-       keyid_from_sk( sk, keyid );
-      }
-    else
-      {
-       /* public */
-       pk = node->pkt->pkt.public_key;
-       keyid_from_pk( pk, keyid );
-
-       if(!force)
-         {
-           if (have_secret_key_with_kid (keyid))
-             {
-               *r_sec_avail = 1;
-               rc = -1;
-               goto leave;
-             }
-           else
-             rc = 0;
-         }
+        if (have_secret_key_with_kid (keyid))
+          {
+            *r_sec_avail = 1;
+            rc = -1;
+            goto leave;
+          }
+        else
+          rc = 0;
       }
 
     if( rc )
@@ -133,9 +123,9 @@ do_delete_key( const char *username, int secret, int force, int *r_sec_avail )
       }
     else {
         if( secret )
-            print_seckey_info( sk );
+            print_seckey_info (pk);
         else
-            print_pubkey_info(NULL, pk );
+            print_pubkey_info (NULL, pk );
        tty_printf( "\n" );
 
        yes = cpr_get_answer_is_yes( secret? "delete_key.secret.okay"
index e5a0d9d..bea798e 100644 (file)
@@ -190,10 +190,7 @@ subkey_in_list_p (subkey_list_t list, KBNODE node)
     {
       u32 kid[2];
 
-      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-        keyid_from_pk (node->pkt->pkt.public_key, kid);
-      else
-        keyid_from_sk (node->pkt->pkt.secret_key, kid);
+      keyid_from_pk (node->pkt->pkt.public_key, kid);
       
       for (; list; list = list->next)
         if (list->kid[0] == kid[0] && list->kid[1] == kid[1])
@@ -208,10 +205,9 @@ new_subkey_list_item (KBNODE node)
 {
   subkey_list_t list = xcalloc (1, sizeof *list);
 
-  if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+  if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+      || node->pkt->pkttype == PKT_SECRET_SUBKEY)
     keyid_from_pk (node->pkt->pkt.public_key, list->kid);
-  else if (node->pkt->pkttype == PKT_SECRET_SUBKEY)
-    keyid_from_sk (node->pkt->pkt.secret_key, list->kid);
 
   return list;
 }
@@ -235,19 +231,13 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
     {
     case KEYDB_SEARCH_MODE_SHORT_KID:
     case KEYDB_SEARCH_MODE_LONG_KID:
-      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-        keyid_from_pk (node->pkt->pkt.public_key, kid);
-      else
-        keyid_from_sk (node->pkt->pkt.secret_key, kid);
+      keyid_from_pk (node->pkt->pkt.public_key, kid);
       break;
       
     case KEYDB_SEARCH_MODE_FPR16:
     case KEYDB_SEARCH_MODE_FPR20:
     case KEYDB_SEARCH_MODE_FPR:
-      if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-        fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
-      else
-        fingerprint_from_sk (node->pkt->pkt.secret_key, fpr,&fprlen);
+      fingerprint_from_pk (node->pkt->pkt.public_key, fpr,&fprlen);
       break;
       
     default:
@@ -287,451 +277,466 @@ exact_subkey_match_p (KEYDB_SEARCH_DESC *desc, KBNODE node)
 
 /* If keyblock_out is non-NULL, AND the exit code is zero, then it
    contains a pointer to the first keyblock found and exported.  No
-   other keyblocks are exported.  The caller must free it. */
+   other keyblocks are exported.  The caller must free it.  */
 static int
-do_export_stream( IOBUF out, strlist_t users, int secret,
-                 KBNODE *keyblock_out, unsigned int options, int *any )
+do_export_stream (iobuf_t out, strlist_t users, int secret,
+                 kbnode_t *keyblock_out, unsigned int options, int *any)
 {
-    int rc = 0;
-    gpg_error_t err;
-    PACKET pkt;
-    KBNODE keyblock = NULL;
-    KBNODE kbctx, node;
-    size_t ndesc, descindex;
-    KEYDB_SEARCH_DESC *desc = NULL;
-    subkey_list_t subkey_list = NULL;  /* Track alreay processed subkeys. */
-    KEYDB_HANDLE kdbhd;
-    strlist_t sl;
-    int indent = 0;
-
-    *any = 0;
-    init_packet( &pkt );
-    kdbhd = keydb_new ();
-
-    if (!users) {
-        ndesc = 1;
-        desc = xcalloc ( ndesc, sizeof *desc );
-        desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
+  gpg_error_t err = 0;
+  PACKET pkt;
+  KBNODE keyblock = NULL;
+  KBNODE kbctx, node;
+  size_t ndesc, descindex;
+  KEYDB_SEARCH_DESC *desc = NULL;
+  subkey_list_t subkey_list = NULL;  /* Track already processed subkeys. */
+  KEYDB_HANDLE kdbhd;
+  strlist_t sl;
+  int indent = 0;
+
+  *any = 0;
+  init_packet (&pkt);
+  kdbhd = keydb_new ();
+
+  if (!users) 
+    {
+      ndesc = 1;
+      desc = xcalloc (ndesc, sizeof *desc);
+      desc[0].mode = KEYDB_SEARCH_MODE_FIRST;
     }
-    else {
-        for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) 
-            ;
-        desc = xmalloc ( ndesc * sizeof *desc);
+  else
+    {
+      for (ndesc=0, sl=users; sl; sl = sl->next, ndesc++) 
+        ;
+      desc = xmalloc ( ndesc * sizeof *desc);
         
-        for (ndesc=0, sl=users; sl; sl = sl->next) {
-            if (!(err=classify_user_id (sl->d, desc+ndesc)))
-                ndesc++;
-            else
-                log_error (_("key \"%s\" not found: %s\n"),
-                           sl->d, gpg_strerror (err));
+      for (ndesc=0, sl=users; sl; sl = sl->next)
+        {
+          if (!(err=classify_user_id (sl->d, desc+ndesc)))
+            ndesc++;
+          else
+            log_error (_("key \"%s\" not found: %s\n"),
+                       sl->d, gpg_strerror (err));
         }
 
-        /* It would be nice to see which of the given users did
-           actually match one in the keyring.  To implement this we
-           need to have a found flag for each entry in desc and to set
-           this we must check all those entries after a match to mark
-           all matched one - currently we stop at the first match.  To
-           do this we need an extra flag to enable this feature so */
+      /* It would be nice to see which of the given users did actually
+         match one in the keyring.  To implement this we need to have
+         a found flag for each entry in desc.  To set this flag we
+         must check all those entries after a match to mark all
+         matched one - currently we stop at the first match.  To do
+         this we need an extra flag to enable this feature.  */
     }
 
 #ifdef ENABLE_SELINUX_HACKS
-    if (secret) {
-        log_error (_("exporting secret keys not allowed\n"));
-        rc = G10ERR_GENERAL;
-        goto leave;
+  if (secret)
+    {
+      log_error (_("exporting secret keys not allowed\n"));
+      err = G10ERR_GENERAL;
+      goto leave;
     }
 #endif
 
-    while (!(rc = keydb_search2 (kdbhd, desc, ndesc, &descindex))) {
-        int sha1_warned=0,skip_until_subkey=0;
-       u32 sk_keyid[2];
+  while (!(err = keydb_search2 (kdbhd, desc, ndesc, &descindex))) 
+    {
+      int sha1_warned = 0;
+      int skip_until_subkey = 0;
+      u32 keyid[2];
 
-       if (!users) 
-            desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
+      if (!users) 
+        desc[0].mode = KEYDB_SEARCH_MODE_NEXT;
 
-        /* Read the keyblock. */
-        rc = keydb_get_keyblock (kdbhd, &keyblock );
-       if( rc ) {
-            log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
-           goto leave;
+      /* Read the keyblock. */
+      err = keydb_get_keyblock (kdbhd, &keyblock);
+      if (err) 
+        {
+          log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
+          goto leave;
        }
 
-       if((node=find_kbnode(keyblock,PKT_SECRET_KEY)))
-         {
-           PKT_secret_key *sk=node->pkt->pkt.secret_key;
-
-           keyid_from_sk(sk,sk_keyid);
-
-           /* We can't apply GNU mode 1001 on an unprotected key. */
-           if( secret == 2 && !sk->is_protected )
-             {
-               log_info(_("key %s: not protected - skipped\n"),
-                        keystr(sk_keyid));
-               continue;
-             }
-
-           /* No v3 keys with GNU mode 1001. */
-           if( secret == 2 && sk->version == 3 )
-             {
-               log_info(_("key %s: PGP 2.x style key - skipped\n"),
-                        keystr(sk_keyid));
-               continue;
-             }
-
-            /* It does not make sense to export a key with a primary
-               key on card using a non-key stub.  We simply skip those
-               keys when used with --export-secret-subkeys. */
-            if (secret == 2 && sk->is_protected
-                && sk->protect.s2k.mode == 1002 ) 
-              {
-               log_info(_("key %s: key material on-card - skipped\n"),
-                        keystr(sk_keyid));
-               continue;
-              }
-         }
-       else
-         {
-           /* It's a public key export, so do the cleaning if
-              requested.  Note that both export-clean and
-              export-minimal only apply to UID sigs (0x10, 0x11,
-              0x12, and 0x13).  A designated revocation is never
-              stripped, even with export-minimal set. */
-
-           if(options&EXPORT_CLEAN)
-             clean_key(keyblock,opt.verbose,options&EXPORT_MINIMAL,NULL,NULL);
-         }
-
-       /* And write it. */
-       for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) {
-           if( skip_until_subkey )
-             {
-               if(node->pkt->pkttype==PKT_PUBLIC_SUBKEY
-                  || node->pkt->pkttype==PKT_SECRET_SUBKEY)
-                 skip_until_subkey=0;
-               else
-                 continue;
-             }
-
-           /* We used to use comment packets, but not any longer.  In
-              case we still have comments on a key, strip them here
-              before we call build_packet(). */
-           if( node->pkt->pkttype == PKT_COMMENT )
-             continue;
+      if ((node=find_kbnode(keyblock, PKT_SECRET_KEY)))
+        {
+          PKT_public_key *pk = node->pkt->pkt.public_key;
+
+          keyid_from_pk (pk, keyid);
+
+          /* We can't apply GNU mode 1001 on an unprotected key. */
+          if( secret == 2
+              && pk->seckey_info && !pk->seckey_info->is_protected )
+            {
+              log_info (_("key %s: not protected - skipped\n"),
+                        keystr (keyid));
+              continue;
+            }
 
-            /* Make sure that ring_trust packets never get exported. */
-            if (node->pkt->pkttype == PKT_RING_TRUST)
+          /* No v3 keys with GNU mode 1001. */
+          if( secret == 2 && pk->version == 3 )
+            {
+              log_info(_("key %s: PGP 2.x style key - skipped\n"),
+                       keystr (keyid));
+              continue;
+            }
+
+          /* It does not make sense to export a key with a primary
+             key on card using a non-key stub.  We simply skip those
+             keys when used with --export-secret-subkeys. */
+          if (secret == 2
+              && pk->seckey_info && pk->seckey_info->is_protected
+              && pk->seckey_info->s2k.mode == 1002 ) 
+            {
+              log_info(_("key %s: key material on-card - skipped\n"),
+                       keystr (keyid));
               continue;
+            }
+        }
+      else
+        {
+          /* It's a public key export, so do the cleaning if
+             requested.  Note that both export-clean and
+             export-minimal only apply to UID sigs (0x10, 0x11, 0x12,
+             and 0x13).  A designated revocation is never stripped,
+             even with export-minimal set.  */
+          if ( (options & EXPORT_CLEAN) )
+            clean_key (keyblock, opt.verbose, options&EXPORT_MINIMAL,
+                       NULL, NULL);
+        }
 
-           /* If exact is set, then we only export what was requested
-              (plus the primary key, if the user didn't specifically
-              request it). */
-           if(desc[descindex].exact
-              && (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
-                  || node->pkt->pkttype==PKT_SECRET_SUBKEY))
-             {
-                if (!exact_subkey_match_p (desc+descindex, node))
-                  {
-                    /* Before skipping this subkey, check whether any
-                       other description wants an exact match on a
-                       subkey and include that subkey into the output
-                       too.  Need to add this subkey to a list so that
-                       it won't get processed a second time.
+      /* And write it. */
+      for (kbctx=NULL; (node = walk_kbnode (keyblock, &kbctx, 0)); ) 
+        {
+          if (skip_until_subkey)
+            {
+              if (node->pkt->pkttype==PKT_PUBLIC_SUBKEY
+                  || node->pkt->pkttype==PKT_SECRET_SUBKEY)
+                skip_until_subkey = 0;
+              else
+                continue;
+            }
+
+          /* We used to use comment packets, but not any longer.  In
+             case we still have comments on a key, strip them here
+             before we call build_packet(). */
+          if (node->pkt->pkttype == PKT_COMMENT)
+            continue;
+
+          /* Make sure that ring_trust packets never get exported. */
+          if (node->pkt->pkttype == PKT_RING_TRUST)
+            continue;
+
+          /* If exact is set, then we only export what was requested
+             (plus the primary key, if the user didn't specifically
+             request it). */
+          if (desc[descindex].exact
+              && (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                  || node->pkt->pkttype == PKT_SECRET_SUBKEY))
+            {
+              if (!exact_subkey_match_p (desc+descindex, node))
+                {
+                  /* Before skipping this subkey, check whether any
+                     other description wants an exact match on a
+                     subkey and include that subkey into the output
+                     too.  Need to add this subkey to a list so that
+                     it won't get processed a second time.
                    
-                       So the first step here is to check that list and
-                       skip in any case if the key is in that list.
-
-                       We need this whole mess because the import
-                       function is not able to merge secret keys and
-                       thus it is useless to output them as two
-                       separate keys and have import merge them.  */
-                    if (subkey_in_list_p (subkey_list, node))  
-                      skip_until_subkey = 1; /* Already processed this one. */
-                    else
-                      {
-                        size_t j;
-
-                        for (j=0; j < ndesc; j++)
-                          if (j != descindex && desc[j].exact
-                              && exact_subkey_match_p (desc+j, node))
-                            break;
-                        if (!(j < ndesc))
-                          skip_until_subkey = 1; /* No other one matching. */ 
-                      }
-                  }
-
-               if(skip_until_subkey)
-                 continue;
-
-                /* Mark this one as processed. */
+                     So the first step here is to check that list and
+                     skip in any case if the key is in that list.
+
+                     We need this whole mess because the import
+                     function is not able to merge secret keys and
+                     thus it is useless to output them as two separate
+                     keys and have import merge them.  */
+                  if (subkey_in_list_p (subkey_list, node))  
+                    skip_until_subkey = 1; /* Already processed this one. */
+                  else
+                    {
+                      size_t j;
+
+                      for (j=0; j < ndesc; j++)
+                        if (j != descindex && desc[j].exact
+                            && exact_subkey_match_p (desc+j, node))
+                          break;
+                      if (!(j < ndesc))
+                        skip_until_subkey = 1; /* No other one matching. */ 
+                    }
+                }
+
+              if(skip_until_subkey)
+                continue;
+
+              /* Mark this one as processed. */
+              {
+                subkey_list_t tmp = new_subkey_list_item (node);
+                tmp->next = subkey_list;
+                subkey_list = tmp;
+              }
+            }
+
+          if (node->pkt->pkttype == PKT_SIGNATURE)
+            {
+              /* Do not export packets which are marked as not
+                 exportable.  */
+              if (!(options&EXPORT_LOCAL_SIGS)
+                  && !node->pkt->pkt.signature->flags.exportable)
+                continue; /* not exportable */
+
+              /* Do not export packets with a "sensitive" revocation
+                 key unless the user wants us to.  Note that we do
+                 export these when issuing the actual revocation
+                 (see revoke.c). */
+              if (!(options&EXPORT_SENSITIVE_REVKEYS)
+                  && node->pkt->pkt.signature->revkey)
                 {
-                  subkey_list_t tmp = new_subkey_list_item (node);
-                  tmp->next = subkey_list;
-                  subkey_list = tmp;
+                  int i;
+                  
+                  for (i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
+                    if ( (node->pkt->pkt.signature->revkey[i]->class & 0x40))
+                      break;
+
+                  if (i < node->pkt->pkt.signature->numrevkeys)
+                    continue;
                 }
-             }
-
-           if(node->pkt->pkttype==PKT_SIGNATURE)
-             {
-               /* do not export packets which are marked as not
-                  exportable */
-               if(!(options&EXPORT_LOCAL_SIGS)
-                  && !node->pkt->pkt.signature->flags.exportable)
-                 continue; /* not exportable */
-
-               /* Do not export packets with a "sensitive" revocation
-                  key unless the user wants us to.  Note that we do
-                  export these when issuing the actual revocation
-                  (see revoke.c). */
-               if(!(options&EXPORT_SENSITIVE_REVKEYS)
-                  && node->pkt->pkt.signature->revkey)
-                 {
-                   int i;
-
-                   for(i=0;i<node->pkt->pkt.signature->numrevkeys;i++)
-                     if(node->pkt->pkt.signature->revkey[i]->class & 0x40)
-                       break;
-
-                   if(i<node->pkt->pkt.signature->numrevkeys)
-                     continue;
-                 }
-             }
-
-           /* Don't export attribs? */
-           if( !(options&EXPORT_ATTRIBUTES) &&
-               node->pkt->pkttype == PKT_USER_ID &&
-               node->pkt->pkt.user_id->attrib_data ) {
+            }
+
+          /* Don't export attribs? */
+          if (!(options&EXPORT_ATTRIBUTES)
+              && node->pkt->pkttype == PKT_USER_ID
+              && node->pkt->pkt.user_id->attrib_data )
+            {
              /* Skip until we get to something that is not an attrib
                 or a signature on an attrib */
-             while(kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE) {
-               kbctx=kbctx->next;
-             }
+             while (kbctx->next && kbctx->next->pkt->pkttype==PKT_SIGNATURE)
+                kbctx = kbctx->next;
  
              continue;
            }
 
-           if( secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY )
-             {
-               /* We don't want to export the secret parts of the
-                * primary key, this is done by using GNU protection mode 1001
-                */
-               int save_mode = node->pkt->pkt.secret_key->protect.s2k.mode;
-               node->pkt->pkt.secret_key->protect.s2k.mode = 1001;
-                if ((options&EXPORT_SEXP_FORMAT))
-                  rc = build_sexp (out, node->pkt, &indent);
-                else
-                  rc = build_packet (out, node->pkt);
-               node->pkt->pkt.secret_key->protect.s2k.mode = save_mode;
-             }
-           else if (secret == 2 && node->pkt->pkttype == PKT_SECRET_SUBKEY
-                     && (opt.export_options&EXPORT_RESET_SUBKEY_PASSWD))
-              {
-                /* If the subkey is protected reset the passphrase to
-                   export an unprotected subkey.  This feature is
-                   useful in cases of a subkey copied to an unattended
-                   machine where a passphrase is not required. */
-                PKT_secret_key *sk_save, *sk;
-
-                sk_save = node->pkt->pkt.secret_key;
-                sk = copy_secret_key (NULL, sk_save);
-                node->pkt->pkt.secret_key = sk;
-
-                log_info (_("about to export an unprotected subkey\n"));
-                switch (is_secret_key_protected (sk))
-                  {
-                  case -1:
-                    rc = G10ERR_PUBKEY_ALGO;
-                    break;
-                  case 0:
-                    break;
-                  default:
-                    if (sk->protect.s2k.mode == 1001)
-                      ; /* No secret parts. */
-                    else if( sk->protect.s2k.mode == 1002 ) 
-                      ; /* Card key stub. */
-                    else 
-                      {
-                        /* rc = check_secret_key( sk, 0 ); */
-                      }
-                    break;
-                  }
-                if (rc)
-                  {
-                    node->pkt->pkt.secret_key = sk_save;
-                    free_secret_key (sk);
-                    log_error (_("failed to unprotect the subkey: %s\n"),
-                               g10_errstr (rc));
-                    goto leave;
-                  }
-
-                if ((options&EXPORT_SEXP_FORMAT))
-                  rc = build_sexp (out, node->pkt, &indent);
-                else
-                  rc = build_packet (out, node->pkt);
-
-                node->pkt->pkt.secret_key = sk_save;
-                free_secret_key (sk);
-              }
-           else
-             {
-               /* Warn the user if the secret key or any of the secret
-                  subkeys are protected with SHA1 and we have
-                  simple_sk_checksum set. */
-               if(!sha1_warned && opt.simple_sk_checksum &&
-                  (node->pkt->pkttype==PKT_SECRET_KEY ||
-                   node->pkt->pkttype==PKT_SECRET_SUBKEY) &&
-                  node->pkt->pkt.secret_key->protect.sha1chk)
-                 {
-                   /* I hope this warning doesn't confuse people. */
-                   log_info(_("WARNING: secret key %s does not have a "
-                              "simple SK checksum\n"),keystr(sk_keyid));
-
-                   sha1_warned=1;
-                 }
-
-                if ((options&EXPORT_SEXP_FORMAT))
-                  rc = build_sexp (out, node->pkt, &indent);
-                else
-                  rc = build_packet (out, node->pkt);
-             }
-
-           if( rc ) {
-               log_error("build_packet(%d) failed: %s\n",
-                           node->pkt->pkttype, g10_errstr(rc) );
-               goto leave;
+          if (secret == 2 && node->pkt->pkttype == PKT_SECRET_KEY)
+            {
+              /* We don't want to export the secret parts of the
+               * primary key, this is done by temporary switching to
+               * GNU protection mode 1001.  */
+              int save_mode = node->pkt->pkt.public_key->seckey_info->s2k.mode;
+              node->pkt->pkt.public_key->seckey_info->s2k.mode = 1001;
+              if ((options&EXPORT_SEXP_FORMAT))
+                err = build_sexp (out, node->pkt, &indent);
+              else
+                err = build_packet (out, node->pkt);
+              node->pkt->pkt.public_key->seckey_info->s2k.mode = save_mode;
+            }
+          else if (secret == 2 && node->pkt->pkttype == PKT_SECRET_SUBKEY
+                   && (opt.export_options&EXPORT_RESET_SUBKEY_PASSWD))
+            {
+              /* If the subkey is protected reset the passphrase to
+                 export an unprotected subkey.  This feature is useful
+                 in cases of a subkey copied to an unattended machine
+                 where a passphrase is not required. */
+              err = gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+              goto leave;
+#warning We need to implement this              
+              /* PKT_secret_key *sk_save, *sk; */
+
+              /* sk_save = node->pkt->pkt.secret_key; */
+              /* sk = copy_secret_key (NULL, sk_save); */
+              /* node->pkt->pkt.secret_key = sk; */
+
+              /* log_info (_("about to export an unprotected subkey\n")); */
+              /* switch (is_secret_key_protected (sk)) */
+              /*   { */
+              /*   case -1: */
+              /*     err = gpg_error (GPG_ERR_PUBKEY_ALGO); */
+              /*     break; */
+              /*   case 0: */
+              /*     break; */
+              /*   default: */
+              /*     if (sk->protect.s2k.mode == 1001) */
+              /*       ; /\* No secret parts. *\/ */
+              /*     else if( sk->protect.s2k.mode == 1002 )  */
+              /*       ; /\* Card key stub. *\/ */
+              /*     else  */
+              /*       { */
+              /*         /\* err = check_secret_key( sk, 0 ); *\/ */
+              /*       } */
+              /*     break; */
+              /*   } */
+              /* if (err) */
+              /*   { */
+              /*     node->pkt->pkt.secret_key = sk_save; */
+              /*     free_secret_key (sk); */
+              /*     log_error (_("failed to unprotect the subkey: %s\n"), */
+              /*                g10_errstr (rc)); */
+              /*     goto leave; */
+              /*   } */
+
+              /* if ((options&EXPORT_SEXP_FORMAT)) */
+              /*   err = build_sexp (out, node->pkt, &indent); */
+              /* else */
+              /*   err = build_packet (out, node->pkt); */
+
+              /* node->pkt->pkt.secret_key = sk_save; */
+              /* free_secret_key (sk); */
+            }
+          else
+            {
+              /* Warn the user if the secret key or any of the secret
+                 subkeys are protected with SHA1 and we have
+                 simple_sk_checksum set. */
+              if (!sha1_warned && opt.simple_sk_checksum &&
+                  (node->pkt->pkttype == PKT_SECRET_KEY
+                   || node->pkt->pkttype == PKT_SECRET_SUBKEY)
+                  && node->pkt->pkt.public_key->seckey_info->sha1chk)
+                {
+                  /* I hope this warning doesn't confuse people. */
+                  log_info(_("WARNING: secret key %s does not have a "
+                             "simple SK checksum\n"), keystr (keyid));
+
+                  sha1_warned = 1;
+                }
+
+              if ((options&EXPORT_SEXP_FORMAT))
+                err = build_sexp (out, node->pkt, &indent);
+              else
+                err = build_packet (out, node->pkt);
+            }
+
+          if (err)
+            {
+              log_error ("build_packet(%d) failed: %s\n",
+                         node->pkt->pkttype, gpg_strerror (err));
+              goto leave;
            }
        }
 
-        if ((options&EXPORT_SEXP_FORMAT) && indent)
-          {
-            for (; indent; indent--)
-              iobuf_put (out, ')');
-            iobuf_put (out, '\n');
-          }
-
-       ++*any;
-       if(keyblock_out)
-         {
-           *keyblock_out=keyblock;
-           break;
-         }
+      if ((options&EXPORT_SEXP_FORMAT) && indent)
+        {
+          for (; indent; indent--)
+            iobuf_put (out, ')');
+          iobuf_put (out, '\n');
+        }
+
+      ++*any;
+      if(keyblock_out)
+        {
+          *keyblock_out=keyblock;
+          break;
+        }
     }
-    if ((options&EXPORT_SEXP_FORMAT) && indent)
-      {
-        for (; indent; indent--)
-          iobuf_put (out, ')');
-        iobuf_put (out, '\n');
-      }
-    if( rc == -1 )
-       rc = 0;
-
 leave:
-    release_subkey_list (subkey_list);
-    xfree(desc);
-    keydb_release (kdbhd);
-    if(rc || keyblock_out==NULL)
-      release_kbnode( keyblock );
-    if( !*any )
-       log_info(_("WARNING: nothing exported\n"));
-    return rc;
+  if ((options&EXPORT_SEXP_FORMAT) && indent)
+    {
+      for (; indent; indent--)
+        iobuf_put (out, ')');
+      iobuf_put (out, '\n');
+    }
+  if( err == -1 )
+    err = 0;
+
+ leave:
+  release_subkey_list (subkey_list);
+  xfree(desc);
+  keydb_release (kdbhd);
+  if (err || !keyblock_out)
+    release_kbnode( keyblock );
+  if( !*any )
+    log_info(_("WARNING: nothing exported\n"));
+  return err;
 }
 
 
 
-static int
-write_sexp_line (iobuf_t out, int *indent, const char *text)
-{
-  int i;
+/* static int */
+/* write_sexp_line (iobuf_t out, int *indent, const char *text) */
+/* { */
+/*   int i; */
 
-  for (i=0; i < *indent; i++)
-    iobuf_put (out, ' ');
-  iobuf_writestr (out, text);
-  return 0;
-}
+/*   for (i=0; i < *indent; i++) */
+/*     iobuf_put (out, ' '); */
+/*   iobuf_writestr (out, text); */
+/*   return 0; */
+/* } */
 
-static int
-write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a)
-{
-  int rc;
-  unsigned char *buffer;
+/* static int */
+/* write_sexp_keyparm (iobuf_t out, int *indent, const char *name, gcry_mpi_t a) */
+/* { */
+/*   int rc; */
+/*   unsigned char *buffer; */
 
-  write_sexp_line (out, indent, "(");
-  iobuf_writestr (out, name);
-  iobuf_writestr (out, " #");
+/*   write_sexp_line (out, indent, "("); */
+/*   iobuf_writestr (out, name); */
+/*   iobuf_writestr (out, " #"); */
 
-  rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a);
-  assert (!rc);
-  iobuf_writestr (out, buffer);
-  iobuf_writestr (out, "#)");
-  gcry_free (buffer);
-  return 0;
-}
+/*   rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a); */
+/*   assert (!rc); */
+/*   iobuf_writestr (out, buffer); */
+/*   iobuf_writestr (out, "#)"); */
+/*   gcry_free (buffer); */
+/*   return 0; */
+/* } */
 
 static int
 build_sexp_seckey (iobuf_t out, PACKET *pkt, int *indent)
 {
-  PKT_secret_key *sk = pkt->pkt.secret_key;
-  char tmpbuf[100];
-
-  if (pkt->pkttype == PKT_SECRET_KEY)
-    {
-      iobuf_writestr (out, "(openpgp-key\n");
-      (*indent)++;
-    }
-  else
-    {
-      iobuf_writestr (out, " (subkey\n");
-      (*indent)++;
-    }
-  (*indent)++;
-  write_sexp_line (out, indent, "(private-key\n");
-  (*indent)++;
-  if (is_RSA (sk->pubkey_algo) && !sk->is_protected)
-    {
-      write_sexp_line (out, indent, "(rsa\n");
-      (*indent)++;
-      write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "u", sk->skey[5]); 
-      iobuf_put (out,')'); iobuf_put (out,'\n');
-      (*indent)--;
-    }
-  else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected)
-    {
-      write_sexp_line (out, indent, "(dsa\n");
-      (*indent)++;
-      write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "x", sk->skey[4]);
-      iobuf_put (out,')'); iobuf_put (out,'\n');
-      (*indent)--;
-    }
-  else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected)
-    {
-      write_sexp_line (out, indent, "(elg\n");
-      (*indent)++;
-      write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n');
-      write_sexp_keyparm (out, indent, "x", sk->skey[4]);
-      iobuf_put (out,')'); iobuf_put (out,'\n');
-      (*indent)--;
-    }
-  write_sexp_line (out, indent,  "(attrib\n"); (*indent)++;
-  sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp);
-  write_sexp_line (out, indent, tmpbuf);
-  iobuf_put (out,')'); (*indent)--; /* close created */
-  iobuf_put (out,')'); (*indent)--; /* close attrib */
-  iobuf_put (out,')'); (*indent)--; /* close private-key */
-  if (pkt->pkttype != PKT_SECRET_KEY)
-    iobuf_put (out,')'), (*indent)--; /* close subkey */
-  iobuf_put (out,'\n');
-
-  return 0;
+  /* FIXME: Not yet implemented.  */
+  return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
+  /* PKT_secret_key *sk = pkt->pkt.secret_key; */
+  /* char tmpbuf[100]; */
+
+  /* if (pkt->pkttype == PKT_SECRET_KEY) */
+  /*   { */
+  /*     iobuf_writestr (out, "(openpgp-key\n"); */
+  /*     (*indent)++; */
+  /*   } */
+  /* else */
+  /*   { */
+  /*     iobuf_writestr (out, " (subkey\n"); */
+  /*     (*indent)++; */
+  /*   } */
+  /* (*indent)++; */
+  /* write_sexp_line (out, indent, "(private-key\n"); */
+  /* (*indent)++; */
+  /* if (is_RSA (sk->pubkey_algo) && !sk->is_protected) */
+  /*   { */
+  /*     write_sexp_line (out, indent, "(rsa\n"); */
+  /*     (*indent)++; */
+  /*     write_sexp_keyparm (out, indent, "n", sk->skey[0]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "e", sk->skey[1]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "d", sk->skey[2]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "p", sk->skey[3]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "q", sk->skey[4]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "u", sk->skey[5]);  */
+  /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
+  /*     (*indent)--; */
+  /*   } */
+  /* else if (sk->pubkey_algo == PUBKEY_ALGO_DSA && !sk->is_protected) */
+  /*   { */
+  /*     write_sexp_line (out, indent, "(dsa\n"); */
+  /*     (*indent)++; */
+  /*     write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "q", sk->skey[1]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
+  /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
+  /*     (*indent)--; */
+  /*   } */
+  /* else if (is_ELGAMAL (sk->pubkey_algo) && !sk->is_protected) */
+  /*   { */
+  /*     write_sexp_line (out, indent, "(elg\n"); */
+  /*     (*indent)++; */
+  /*     write_sexp_keyparm (out, indent, "p", sk->skey[0]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "g", sk->skey[2]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "y", sk->skey[3]); iobuf_put (out,'\n'); */
+  /*     write_sexp_keyparm (out, indent, "x", sk->skey[4]); */
+  /*     iobuf_put (out,')'); iobuf_put (out,'\n'); */
+  /*     (*indent)--; */
+  /*   } */
+  /* write_sexp_line (out, indent,  "(attrib\n"); (*indent)++; */
+  /* sprintf (tmpbuf, "(created \"%lu\"", (unsigned long)sk->timestamp); */
+  /* write_sexp_line (out, indent, tmpbuf); */
+  /* iobuf_put (out,')'); (*indent)--; /\* close created *\/ */
+  /* iobuf_put (out,')'); (*indent)--; /\* close attrib *\/ */
+  /* iobuf_put (out,')'); (*indent)--; /\* close private-key *\/ */
+  /* if (pkt->pkttype != PKT_SECRET_KEY) */
+  /*   iobuf_put (out,')'), (*indent)--; /\* close subkey *\/ */
+  /* iobuf_put (out,'\n'); */
+
+  /* return 0; */
 }
 
 
index 5da7fc0..47d89ee 100644 (file)
@@ -1,6 +1,6 @@
 /* free-packet.c - cleanup stuff for packets
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
- *               2005  Free Software Foundation, Inc.
+ *               2005, 2010  Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -76,37 +76,51 @@ free_seckey_enc( PKT_signature *sig )
 
 
 void
-release_public_key_parts( PKT_public_key *pk )
+release_public_key_parts (PKT_public_key *pk)
 {
-    int n, i;
-    n = pubkey_get_npkey( pk->pubkey_algo );
-    if( !n )
-       mpi_release(pk->pkey[0]);
-    for(i=0; i < n; i++ ) {
-       mpi_release( pk->pkey[i] );
-       pk->pkey[i] = NULL;
+  int n, i;
+  
+  if (pk->seckey_info)
+    n = pubkey_get_nskey (pk->pubkey_algo);
+  else
+    n = pubkey_get_npkey (pk->pubkey_algo);
+  if (!n)
+    mpi_release (pk->pkey[0]);
+  for (i=0; i < n; i++ )
+    {
+      mpi_release (pk->pkey[i]);
+      pk->pkey[i] = NULL;
     }
-    if (pk->prefs) {
-        xfree (pk->prefs);
-        pk->prefs = NULL;
+  if (pk->seckey_info)
+    {
+      xfree (pk->seckey_info);
+      pk->seckey_info = NULL;
     }
-    if (pk->user_id) {
-        free_user_id (pk->user_id);
-        pk->user_id = NULL;
+  if (pk->prefs)
+    {
+      xfree (pk->prefs);
+      pk->prefs = NULL;
+    }
+  if (pk->user_id)
+    {
+      free_user_id (pk->user_id);
+      pk->user_id = NULL;
     }
-    if (pk->revkey) {
-        xfree(pk->revkey);
-       pk->revkey=NULL;
-       pk->numrevkeys=0;
+  if (pk->revkey)
+    {
+      xfree(pk->revkey);
+      pk->revkey=NULL;
+      pk->numrevkeys=0;
     }
+
 }
 
 
 void
-free_public_key( PKT_public_key *pk )
+free_public_key (PKT_public_key *pk)
 {
-    release_public_key_parts( pk );
-    xfree(pk);
+  release_public_key_parts (pk);
+  xfree(pk);
 }
 
 
@@ -150,55 +164,45 @@ copy_prefs (const prefitem_t *prefs)
 }
 
 
+/* Copy the public key S to D.  If D is NULL allocate a new public key
+   structure.  If S has seckret key infos, only the public stuff is
+   copied.  */
 PKT_public_key *
-copy_public_key ( PKT_public_key *d, PKT_public_key *s)
+copy_public_key (PKT_public_key *d, PKT_public_key *s)
 {
-    int n, i;
-
-    if( !d )
-       d = xmalloc(sizeof *d);
-    memcpy( d, s, sizeof *d );
-    d->user_id = scopy_user_id (s->user_id);
-    d->prefs = copy_prefs (s->prefs);
-    n = pubkey_get_npkey( s->pubkey_algo );
-    if( !n )
-       d->pkey[0] = mpi_copy(s->pkey[0]);
-    else {
-       for(i=0; i < n; i++ )
-           d->pkey[i] = mpi_copy( s->pkey[i] );
+  int n, i;
+  
+  if (!d)
+    d = xmalloc (sizeof *d);
+  memcpy (d, s, sizeof *d);
+  d->seckey_info = NULL; 
+  d->user_id = scopy_user_id (s->user_id);
+  d->prefs = copy_prefs (s->prefs);
+
+  n = pubkey_get_npkey (s->pubkey_algo);
+  i = 0;
+  if (!n)
+    d->pkey[i++] = mpi_copy (s->pkey[0]);
+  else 
+    {
+      for (; i < n; i++ )
+        d->pkey[i] = mpi_copy( s->pkey[i] );
     }
-    if( !s->revkey && s->numrevkeys )
-        BUG();
-    if( s->numrevkeys ) {
-        d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
-        memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
+  for (; i < PUBKEY_MAX_NSKEY; i++)
+    d->pkey[i] = NULL;
+
+  if (!s->revkey && s->numrevkeys)
+    BUG();
+  if (s->numrevkeys)
+    {
+      d->revkey = xmalloc(sizeof(struct revocation_key)*s->numrevkeys);
+      memcpy(d->revkey,s->revkey,sizeof(struct revocation_key)*s->numrevkeys);
     }
-    else
-        d->revkey = NULL;
-    return d;
+  else
+    d->revkey = NULL;
+  return d;
 }
 
-/****************
- * Replace all common parts of a sk by the one from the public key.
- * This is a hack and a better solution will be to just store the real secret
- * parts somewhere and don't duplicate all the other stuff.
- */
-void
-copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
-{
-    sk->expiredate  = pk->expiredate;     
-    sk->pubkey_algo = pk->pubkey_algo;    
-    sk->pubkey_usage= pk->pubkey_usage;
-    sk->req_usage   = pk->req_usage;
-    sk->req_algo    = pk->req_algo;
-    sk->has_expired = pk->has_expired;    
-    sk->is_revoked  = pk->is_revoked;     
-    sk->is_valid    = pk->is_valid;    
-    sk->main_keyid[0]= pk->main_keyid[0];
-    sk->main_keyid[1]= pk->main_keyid[1];
-    sk->keyid[0]    = pk->keyid[0];
-    sk->keyid[1]    = pk->keyid[1];
-}
 
 
 static pka_info_t *
@@ -257,48 +261,6 @@ scopy_user_id (PKT_user_id *s)
 
 
 void
-release_secret_key_parts( PKT_secret_key *sk )
-{
-    int n, i;
-
-    n = pubkey_get_nskey( sk->pubkey_algo );
-    if( !n )
-       mpi_release(sk->skey[0]);
-    for(i=0; i < n; i++ ) {
-       mpi_release( sk->skey[i] );
-       sk->skey[i] = NULL;
-    }
-}
-
-void
-free_secret_key( PKT_secret_key *sk )
-{
-    release_secret_key_parts( sk );
-    xfree(sk);
-}
-
-PKT_secret_key *
-copy_secret_key( PKT_secret_key *d, PKT_secret_key *s )
-{
-    int n, i;
-
-    if( !d )
-       d = xmalloc_secure(sizeof *d);
-    else
-        release_secret_key_parts (d);
-    memcpy( d, s, sizeof *d );
-    n = pubkey_get_nskey( s->pubkey_algo );
-    if( !n )
-       d->skey[0] = mpi_copy(s->skey[0]);
-    else {
-       for(i=0; i < n; i++ )
-           d->skey[i] = mpi_copy( s->skey[i] );
-    }
-
-    return d;
-}
-
-void
 free_comment( PKT_comment *rem )
 {
     xfree(rem);
@@ -407,11 +369,9 @@ free_packet( PACKET *pkt )
        break;
       case PKT_PUBLIC_KEY:
       case PKT_PUBLIC_SUBKEY:
-       free_public_key( pkt->pkt.public_key );
-       break;
       case PKT_SECRET_KEY:
       case PKT_SECRET_SUBKEY:
-       free_secret_key( pkt->pkt.secret_key );
+       free_public_key (pkt->pkt.public_key);
        break;
       case PKT_COMMENT:
        free_comment( pkt->pkt.comment );
@@ -462,59 +422,6 @@ cmp_public_keys( PKT_public_key *a, PKT_public_key *b )
     return 0;
 }
 
-/****************
- * Returns 0 if they match.
- * We only compare the public parts.
- */
-int
-cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b )
-{
-    int n, i;
-
-    log_debug ("FIXME: %s Should not be used\n", __func__);
-    if( a->timestamp != b->timestamp )
-       return -1;
-    if( a->version < 4 && a->expiredate != b->expiredate )
-       return -1;
-    if( a->pubkey_algo != b->pubkey_algo )
-       return -1;
-
-    n = pubkey_get_npkey( b->pubkey_algo );
-    if( !n )
-       return -1; /* can't compare due to unknown algorithm */
-    for(i=0; i < n; i++ ) {
-       if( mpi_cmp( a->skey[i], b->skey[i] ) )
-           return -1;
-    }
-
-    return 0;
-}
-
-/****************
- * Returns 0 if they match.
- */
-int
-cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
-{
-    int n, i;
-
-    if( pk->timestamp != sk->timestamp )
-       return -1;
-    if( pk->version < 4 && pk->expiredate != sk->expiredate )
-       return -1;
-    if( pk->pubkey_algo != sk->pubkey_algo )
-       return -1;
-
-    n = pubkey_get_npkey( pk->pubkey_algo );
-    if( !n )
-       return -1; /* can't compare due to unknown algorithm */
-    for(i=0; i < n; i++ ) {
-       if( mpi_cmp( pk->pkey[i] , sk->skey[i] ) )
-           return -1;
-    }
-    return 0;
-}
-
 
 
 int
index 4929974..401e668 100644 (file)
@@ -2522,7 +2522,7 @@ found:
  *     so that can free it's context.
  */
 int
-enum_secret_keys (void **context, PKT_secret_key * sk,
+enum_secret_keys (void **context, PKT_public_key * sk,
                  int with_subkeys, int with_spm)
 {
   log_debug ("FIXME: Anonymous recipient does not yet work\n");
index b183465..e3e7824 100644 (file)
@@ -567,19 +567,16 @@ fix_bad_direct_key_sigs (kbnode_t keyblock, u32 *keyid)
 
 
 static void
-print_import_ok (PKT_public_key *pk, PKT_secret_key *sk, unsigned int reason)
+print_import_ok (PKT_public_key *pk, unsigned int reason)
 {
   byte array[MAX_FINGERPRINT_LEN], *s;
   char buf[MAX_FINGERPRINT_LEN*2+30], *p;
   size_t i, n;
 
-  sprintf (buf, "%u ", reason);
+  snprintf (buf, sizeof buf, "%u ", reason);
   p = buf + strlen (buf);
 
-  if (pk)
-    fingerprint_from_pk (pk, array, &n);
-  else
-    fingerprint_from_sk (sk, array, &n);
+  fingerprint_from_pk (pk, array, &n);
   s = array;
   for (i=0; i < n ; i++, s++, p += 2)
     sprintf (p, "%02X", *s);
@@ -886,7 +883,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
            char *us = get_long_user_id_string( keyid );
            write_status_text( STATUS_IMPORTED, us );
            xfree(us);
-            print_import_ok (pk,NULL, 1);
+            print_import_ok (pk, 1);
          }
        stats->imported++;
        if( is_RSA( pk->pubkey_algo ) )
@@ -1007,14 +1004,13 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
            stats->n_uids_cleaned +=n_uids_cleaned;
 
             if (is_status_enabled ()) 
-                 print_import_ok (pk, NULL,
-                                  ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
+              print_import_ok (pk, ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
        }
        else
          {
             same_key = 1;
             if (is_status_enabled ()) 
-             print_import_ok (pk, NULL, 0);
+             print_import_ok (pk, 0);
 
            if( !opt.quiet )
              {
@@ -1092,7 +1088,8 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
   size_t keklen;
   kbnode_t ctx = NULL;
   kbnode_t node;
-  PKT_secret_key *main_sk, *sk;
+  PKT_public_key *main_pk, *pk;
+  struct seckey_info *ski;
   int nskey;
   membuf_t mbuf;
   int i, j;
@@ -1126,21 +1123,25 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
   xfree (kek);
   kek = NULL;
 
-  main_sk = NULL;
+  main_pk = NULL;
   while ((node = walk_kbnode (sec_keyblock, &ctx, 0)))
     {
       if (node->pkt->pkttype != PKT_SECRET_KEY
           && node->pkt->pkttype != PKT_SECRET_SUBKEY)
         continue;
-      sk = node->pkt->pkt.secret_key;
-      if (!main_sk)
-        main_sk = sk;
+      pk = node->pkt->pkt.public_key;
+      if (!main_pk)
+        main_pk = pk;
+
+      ski = pk->seckey_info;
+      if (!ski)
+        BUG ();
 
       stats->count++;
       stats->secret_read++;
 
       /* Convert our internal secret key object into an S-expression.  */
-      nskey = pubkey_get_nskey (sk->pubkey_algo);
+      nskey = pubkey_get_nskey (pk->pubkey_algo);
       if (!nskey || nskey > PUBKEY_MAX_NSKEY)
         {
           err = gpg_error (GPG_ERR_BAD_SECKEY);
@@ -1152,10 +1153,10 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
       put_membuf_str (&mbuf, "(skey");
       for (i=j=0; i < nskey; i++)
         {
-          if (gcry_mpi_get_flag (sk->skey[i], GCRYMPI_FLAG_OPAQUE))
+          if (gcry_mpi_get_flag (pk->pkey[i], GCRYMPI_FLAG_OPAQUE))
             {
               put_membuf_str (&mbuf, " e %b");
-              format_args_buf_ptr[i] = gcry_mpi_get_opaque (sk->skey[i], &n);
+              format_args_buf_ptr[i] = gcry_mpi_get_opaque (pk->pkey[i], &n);
               format_args_buf_int[i] = (n+7)/8;
               format_args[j++] = format_args_buf_int + i;
               format_args[j++] = format_args_buf_ptr + i;
@@ -1163,7 +1164,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
           else
             {
               put_membuf_str (&mbuf, " _ %m");
-              format_args[j++] = sk->skey + i;
+              format_args[j++] = pk->pkey + i;
             }
         }
       put_membuf_str (&mbuf, ")\n");
@@ -1182,21 +1183,21 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
           goto leave;
         }
 
-      if (sk->is_protected)
+      if (ski->is_protected)
         {
           char countbuf[35];
 
           snprintf (countbuf, sizeof countbuf, "%lu",
-                    (unsigned long)sk->protect.s2k.count);
+                    (unsigned long)ski->s2k.count);
           err = gcry_sexp_build
             (&prot, NULL,
              " (protection %s %s %b %d %s %b %s)\n",
-             sk->protect.sha1chk? "sha1":"sum",
-             openpgp_cipher_algo_name (sk->protect.algo),
-             (int)sk->protect.ivlen, sk->protect.iv,
-             sk->protect.s2k.mode,
-             openpgp_md_algo_name (sk->protect.s2k.hash_algo),
-             (int)sizeof (sk->protect.s2k.salt), sk->protect.s2k.salt,
+             ski->sha1chk? "sha1":"sum",
+             openpgp_cipher_algo_name (ski->algo),
+             (int)ski->ivlen, ski->iv,
+             ski->s2k.mode,
+             openpgp_md_algo_name (ski->s2k.hash_algo),
+             (int)sizeof (ski->s2k.salt), ski->s2k.salt,
              countbuf);
         }
       else
@@ -1213,9 +1214,9 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
                                " %S\n"
                                " (csum %d)\n"
                                " %S)\n",
-                               sk->version,
-                               openpgp_pk_algo_name (sk->pubkey_algo),
-                               skey, (int)(unsigned long)sk->csum, prot);
+                               pk->version,
+                               openpgp_pk_algo_name (pk->pubkey_algo),
+                               skey, (int)(unsigned long)ski->csum, prot);
       gcry_sexp_release (skey);
       gcry_sexp_release (prot);
       if (!err)
@@ -1243,37 +1244,7 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
 
       /* Send the wrapped key to the agent.  */
       { 
-        char *uid, *desc;
-        size_t uidlen;
-        u32 keyid[2];
-        char *orig_codeset;
-
-        /* FIXME: We should use gpg_format_keydesc, however that
-           requires a public key structure.  It might be useful to
-           merge the secret and public key structures. */
-        keyid_from_sk (sk, keyid);
-        uid = get_user_id (keyid, &uidlen); 
-        orig_codeset = i18n_switchto_utf8 ();
-        desc = xtryasprintf (_("Please enter the passphrase to import the"
-                             " secret key for the OpenPGP certificate:\n"
-                               "\"%.*s\"\n"             \
-                               "%u-bit %s key, ID %s,\n"       
-                               "created %s.\n"),
-                             (int)uidlen, uid,
-                             nbits_from_sk (sk),
-                             openpgp_pk_algo_name (sk->pubkey_algo),
-                             (main_sk == sk
-                              ? keystr_from_sk (sk)
-                              : keystr_from_sk_with_sub (main_sk, sk)),
-                             strtimestamp (sk->timestamp));
-        i18n_switchback (orig_codeset);
-        xfree (uid);
-        if (desc)
-          {
-            uid = percent_plus_escape (desc);
-            xfree (desc);
-            desc = uid;
-          }
+        char *desc = gpg_format_keydesc (pk, 1, 1);
         err = agent_import_key (ctrl, desc, &cache_nonce, 
                                 wrappedkey, wrappedkeylen);
         xfree (desc);
@@ -1282,23 +1253,23 @@ transfer_secret_keys (ctrl_t ctrl, struct stats_s *stats, kbnode_t sec_keyblock)
         {
           if (opt.verbose)
             log_info (_("key %s: secret key imported\n"),
-                      keystr_from_sk_with_sub (main_sk, sk));
+                      keystr_from_pk_with_sub (main_pk, pk));
           stats->secret_imported++;
         }
       else if ( gpg_err_code (err) == GPG_ERR_EEXIST )
         {
           if (opt.verbose)
             log_info (_("key %s: secret key already exists\n"),
-                      keystr_from_sk_with_sub (main_sk, sk));
+                      keystr_from_pk_with_sub (main_pk, pk));
           err = 0;
           stats->secret_dups++;
         }
       else
         {
           log_error (_("key %s: error sending to agent: %s\n"),
-                     keystr_from_sk_with_sub (main_sk, sk),
+                     keystr_from_pk_with_sub (main_pk, pk),
                      gpg_strerror (err));
-          if (sk->protect.algo == GCRY_CIPHER_IDEA
+          if (ski->algo == GCRY_CIPHER_IDEA
               && gpg_err_code (err) == GPG_ERR_CIPHER_ALGO)
             {
               write_status (STATUS_RSA_OR_IDEA);
@@ -1333,40 +1304,24 @@ sec_to_pub_keyblock (kbnode_t sec_keyblock)
       if (secnode->pkt->pkttype == PKT_SECRET_KEY
           || secnode->pkt->pkttype == PKT_SECRET_SUBKEY)
        {
-         /* Make a public key.  We only need to convert enough to
-            write the keyblock out. */
+         /* Make a public key.  */
          PACKET *pkt;
-         PKT_secret_key *sk;
-         PKT_public_key *pk;
-         int n, i;
-
-         pkt = xcalloc (1, sizeof *pkt);
-         sk = secnode->pkt->pkt.secret_key;
-         pk = xcalloc (1, sizeof *pk);
+          PKT_public_key *pk;
 
+         pkt = xtrycalloc (1, sizeof *pkt);
+          pk = pkt? copy_public_key (NULL, secnode->pkt->pkt.public_key): NULL;
+          if (!pk)
+            {
+              xfree (pkt);
+             release_kbnode (pub_keyblock);
+              return NULL;
+            }
          if (secnode->pkt->pkttype == PKT_SECRET_KEY)
            pkt->pkttype = PKT_PUBLIC_KEY;
          else
            pkt->pkttype = PKT_PUBLIC_SUBKEY;
-
          pkt->pkt.public_key = pk;
 
-         pk->version     = sk->version;
-         pk->timestamp   = sk->timestamp;
-         pk->expiredate  = sk->expiredate;
-         pk->pubkey_algo = sk->pubkey_algo;
-
-         n = pubkey_get_npkey (pk->pubkey_algo);
-         if (!n)
-           {
-             /* We can't properly extract the pubkey without knowing
-                the number of MPIs */
-             release_kbnode (pub_keyblock);
-             return NULL;
-           }
-
-          for (i=0; i < n; i++)
-            pk->pkey[i] = mpi_copy (sk->skey[i]);
          pubnode = new_kbnode (pkt);
        }
       else
@@ -1393,10 +1348,10 @@ static int
 import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, 
                    struct stats_s *stats, unsigned int options)
 {
-  PKT_secret_key *sk;
+  PKT_public_key *pk;
+  struct seckey_info *ski;
   KBNODE node, uidnode;
   u32 keyid[2];
-  int have_seckey;
   int rc = 0;
     
   /* Get the key and print some info about it */
@@ -1404,16 +1359,17 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
   if (!node)
     BUG ();
   
-  sk = node->pkt->pkt.secret_key;
-  keyid_from_sk (sk, keyid);
+  pk = node->pkt->pkt.public_key;
+
+  keyid_from_pk (pk, keyid);
   uidnode = find_next_kbnode (keyblock, PKT_USER_ID);
   
   if (opt.verbose)
     {
       log_info ("sec  %4u%c/%s %s   ",
-                nbits_from_sk (sk),
-                pubkey_letter (sk->pubkey_algo),
-                keystr_from_sk (sk), datestr_from_sk (sk));
+                nbits_from_pk (pk),
+                pubkey_letter (pk->pubkey_algo),
+                keystr_from_pk (pk), datestr_from_pk (pk));
       if (uidnode)
         print_utf8_buffer (log_get_stream (), uidnode->pkt->pkt.user_id->name,
                            uidnode->pkt->pkt.user_id->len);
@@ -1423,16 +1379,24 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
   
   if (!uidnode)
     {
-      log_error( _("key %s: no user ID\n"), keystr_from_sk(sk));
+      log_error( _("key %s: no user ID\n"), keystr_from_pk (pk));
       return 0;
     }
-    
+
+  ski = pk->seckey_info;
+  if (!ski)
+    {
+      /* Actually an internal error.  */
+      log_error ("key %s: secret key info missing\n", keystr_from_pk (pk));
+      return 0;
+    }
+
   /* A quick check to not import keys with an invalid protection
      cipher algorithm (only checks the primary key, though).  */
-  if (sk->protect.algo > 110)
+  if (ski->algo > 110)
     {
       log_error (_("key %s: secret key with invalid cipher %d"
-                   " - skipped\n"),keystr_from_sk(sk),sk->protect.algo);
+                   " - skipped\n"), keystr_from_pk (pk), ski->algo);
       return 0;
     }
 
@@ -1447,9 +1411,9 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
     }
 #endif 
     
-  clear_kbnode_flags( keyblock );
+  clear_kbnode_flags (keyblock);
   
-  if ( !(opt.import_options&IMPORT_MERGE_ONLY) )
+  if (!(options&IMPORT_MERGE_ONLY) || !have_secret_key_with_kid (keyid) )
     {
       /* We don't have this key, insert as a new key.  */
       kbnode_t pub_keyblock;
@@ -1458,7 +1422,7 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
       pub_keyblock = sec_to_pub_keyblock (keyblock);
       if (!pub_keyblock)
         log_error ("key %s: failed to create public key from secret key\n",
-                   keystr_from_sk (sk));
+                   keystr_from_pk (pk));
       else
         {
           import_one (fname, pub_keyblock, stats,
@@ -1474,29 +1438,29 @@ import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock,
           node = get_pubkeyblock (keyid);
           if (!node)
             log_error ("key %s: failed to re-lookup public key\n",
-                       keystr_from_sk (sk));
+                       keystr_from_pk (pk));
           else
             {
               if (!transfer_secret_keys (ctrl, stats, keyblock))
                 {
                   if (!opt.quiet)
                     log_info (_("key %s: secret key imported\n"),
-                              keystr_from_sk (sk));
+                              keystr_from_pk (pk));
                   if (is_status_enabled ()) 
-                    print_import_ok (NULL, sk, 1|16);
+                    print_import_ok (pk, 1|16);
                   check_prefs (node);
                 }
               release_kbnode (node);
             }
         }
     }
-  else if (have_secret_key_with_kid (keyid))
+  else
     { 
       /* We don't want to merge the secret keys. */
-      log_error_("key %s: secret key part already available\n"),
-                 keystr_from_sk(sk));
+      log_error (_("key %s: secret key part already available\n"),
+                 keystr_from_pk (pk));
       if (is_status_enabled ()) 
-        print_import_ok (NULL, sk, 16);
+        print_import_ok (pk, 16);
     }
 
   return rc;
@@ -2072,12 +2036,12 @@ collapse_uids( KBNODE *keyblock )
     {
       const char *key="???";
 
-      if( (uid1=find_kbnode( *keyblock, PKT_PUBLIC_KEY )) )
-       key=keystr_from_pk(uid1->pkt->pkt.public_key);
-      else if( (uid1 = find_kbnode( *keyblock, PKT_SECRET_KEY )) )
-       key=keystr_from_sk(uid1->pkt->pkt.secret_key);
+      if ((uid1 = find_kbnode (*keyblock, PKT_PUBLIC_KEY)) )
+       key = keystr_from_pk (uid1->pkt->pkt.public_key);
+      else if ((uid1 = find_kbnode( *keyblock, PKT_SECRET_KEY)) )
+       key = keystr_from_pk (uid1->pkt->pkt.public_key);
 
-      log_info(_("key %s: duplicated user ID detected - merged\n"),key);
+      log_info (_("key %s: duplicated user ID detected - merged\n"), key);
     }
 
   return any;
@@ -2308,8 +2272,8 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
            /* do we have this in the original keyblock? */
            for(onode=keyblock_orig->next; onode; onode=onode->next )
                if( onode->pkt->pkttype == PKT_SECRET_SUBKEY
-                   && !cmp_secret_keys( onode->pkt->pkt.secret_key,
-                                        node->pkt->pkt.secret_key ) )
+                   && !cmp_public_keys (onode->pkt->pkt.public_key,
+                                        node->pkt->pkt.public_key) )
                    break;
            if( !onode ) { /* this is a new subkey: append */
                rc = append_key( keyblock_orig, node, n_sigs, fname, keyid);
@@ -2327,14 +2291,11 @@ merge_blocks( const char *fname, KBNODE keyblock_orig, KBNODE keyblock,
                 || onode->pkt->pkttype == PKT_SECRET_SUBKEY) ) {
            /* find the subkey in the imported keyblock */
            for(node=keyblock->next; node; node=node->next ) {
-               if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY
+                     || node->pkt->pkttype == PKT_SECRET_SUBKEY)
                    && !cmp_public_keys( onode->pkt->pkt.public_key,
                                          node->pkt->pkt.public_key ) )
                    break;
-               else if( node->pkt->pkttype == PKT_SECRET_SUBKEY
-                   && !cmp_secret_keys( onode->pkt->pkt.secret_key,
-                                         node->pkt->pkt.secret_key ) )
-                   break;
            }
            if( node ) { /* found: merge */
                rc = merge_keysigs( onode, node, n_sigs, fname, keyid );
@@ -2497,8 +2458,9 @@ merge_keysigs (KBNODE dst, KBNODE src, int *n_sigs,
     return 0;
 }
 
-/****************
- * append the subkey starting with NODE and all signatures to KEYBLOCK.
+
+/*
+ * Append the subkey starting with NODE and all signatures to KEYBLOCK.
  * Mark all new and copied packets by setting flag bit 0.
  */
 static int
@@ -2530,233 +2492,3 @@ append_key (KBNODE keyblock, KBNODE node, int *n_sigs,
 
     return 0;
 }
-
-
-
-/* Walk a public keyblock and produce a secret keyblock out of it.
-   Instead of inserting the secret key parameters (which we don't
-   have), we insert a stub.  */
-static KBNODE
-pub_to_sec_keyblock (KBNODE pub_keyblock)
-{
-  KBNODE pubnode, secnode;
-  KBNODE sec_keyblock = NULL;
-  KBNODE walkctx = NULL;
-
-  while((pubnode = walk_kbnode (pub_keyblock,&walkctx,0)))
-    {
-      if (pubnode->pkt->pkttype == PKT_PUBLIC_KEY
-          || pubnode->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-       {
-         /* Make a secret key.  We only need to convert enough to
-            write the keyblock out. */
-         PKT_public_key *pk = pubnode->pkt->pkt.public_key;
-         PACKET *pkt = xmalloc_clear (sizeof *pkt);
-         PKT_secret_key *sk = xmalloc_clear (sizeof *sk);
-          int i, n;
-          
-          if (pubnode->pkt->pkttype == PKT_PUBLIC_KEY)
-           pkt->pkttype = PKT_SECRET_KEY;
-         else
-           pkt->pkttype = PKT_SECRET_SUBKEY;
-          
-         pkt->pkt.secret_key = sk;
-
-          copy_public_parts_to_secret_key ( pk, sk );
-         sk->version     = pk->version;
-         sk->timestamp   = pk->timestamp;
-        
-          n = pubkey_get_npkey (pk->pubkey_algo);
-          if (!n)
-            n = 1; /* Unknown number of parameters, however the data
-                      is stored in the first mpi. */
-          for (i=0; i < n; i++ )
-            sk->skey[i] = mpi_copy (pk->pkey[i]);
-  
-          sk->is_protected = 1;
-          sk->protect.s2k.mode = 1001;
-  
-         secnode = new_kbnode (pkt);
-        }
-      else
-       {
-         secnode = clone_kbnode (pubnode);
-       }
-      
-      if(!sec_keyblock)
-       sec_keyblock = secnode;
-      else
-       add_kbnode (sec_keyblock, secnode);
-    }
-
-  return sec_keyblock;
-}
-
-
-/* Walk over the secret keyring SEC_KEYBLOCK and update any simple
-   stub keys with the serial number SNNUM of the card if one of the
-   fingerprints FPR1, FPR2 or FPR3 match.  Print a note if the key is
-   a duplicate (may happen in case of backed uped keys). 
-   
-   Returns: True if anything changed.
-*/
-static int
-update_sec_keyblock_with_cardinfo (KBNODE sec_keyblock, 
-                                   const unsigned char *fpr1,
-                                   const unsigned char *fpr2,
-                                   const unsigned char *fpr3,
-                                   const char *serialnostr)
-{
-  KBNODE node;
-  KBNODE walkctx = NULL;
-  PKT_secret_key *sk;
-  byte array[MAX_FINGERPRINT_LEN];
-  size_t n;
-  int result = 0;
-  const char *s;
-
-  while((node = walk_kbnode (sec_keyblock, &walkctx, 0)))
-    {
-      if (node->pkt->pkttype != PKT_SECRET_KEY
-          && node->pkt->pkttype != PKT_SECRET_SUBKEY)
-        continue;
-      sk = node->pkt->pkt.secret_key;
-      
-      fingerprint_from_sk (sk, array, &n);
-      if (n != 20)
-        continue; /* Can't be a card key.  */
-      if ( !((fpr1 && !memcmp (array, fpr1, 20))
-             || (fpr2 && !memcmp (array, fpr2, 20))
-             || (fpr3 && !memcmp (array, fpr3, 20))) )
-        continue;  /* No match.  */
-
-      if (sk->is_protected == 1 && sk->protect.s2k.mode == 1001)
-        {
-          /* Standard case: migrate that stub to a key stub.  */
-          sk->protect.s2k.mode = 1002;
-          s = serialnostr;
-          for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
-               sk->protect.ivlen++, s += 2)
-            sk->protect.iv[sk->protect.ivlen] = xtoi_2 (s);
-          result = 1;
-        }
-      else if (sk->is_protected == 1 && sk->protect.s2k.mode == 1002)
-        {
-          s = serialnostr;
-          for (sk->protect.ivlen=0; sk->protect.ivlen < 16 && *s && s[1];
-               sk->protect.ivlen++, s += 2)
-            if (sk->protect.iv[sk->protect.ivlen] != xtoi_2 (s))
-              {
-                log_info (_("NOTE: a key's S/N does not "
-                            "match the card's one\n"));
-                break;
-              }
-        }
-      else
-        {
-          if (node->pkt->pkttype != PKT_SECRET_KEY)
-            log_info (_("NOTE: primary key is online and stored on card\n"));
-          else
-            log_info (_("NOTE: secondary key is online and stored on card\n"));
-        }
-    }
-
-  return result;
-}
-
-
-
-/* Check whether a secret key stub exists for the public key PK.  If
-   not create such a stub key and store it into the secring.  If it
-   exists, add appropriate subkey stubs and update the secring.
-   Return 0 if the key could be created. */
-int
-auto_create_card_key_stub ( const char *serialnostr, 
-                            const unsigned char *fpr1,
-                            const unsigned char *fpr2,
-                            const unsigned char *fpr3)
-{
-  KBNODE pub_keyblock;
-  KBNODE sec_keyblock;
-  KEYDB_HANDLE hd;
-  int rc;
-
-  /* We only want to do this for an OpenPGP card.  */
-  if (!serialnostr || strncmp (serialnostr, "D27600012401", 12) 
-      || strlen (serialnostr) != 32 )
-    return G10ERR_GENERAL;
-
-  /* First get the public keyring from any of the provided fingerprints. */
-  if ( (fpr1 && !get_keyblock_byfprint (&pub_keyblock, fpr1, 20))
-       || (fpr2 && !get_keyblock_byfprint (&pub_keyblock, fpr2, 20))
-       || (fpr3 && !get_keyblock_byfprint (&pub_keyblock, fpr3, 20)))
-    ;
-  else
-    return G10ERR_GENERAL;
-
-  log_debug ("FIXME: Do we need the stub at all?\n");
-  hd = keydb_new (); /* FIXME. */
-
-  /* Now check whether there is a secret keyring.  */
-  {
-    PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
-    byte afp[MAX_FINGERPRINT_LEN];
-    size_t an;
-
-    fingerprint_from_pk (pk, afp, &an);
-    if (an < MAX_FINGERPRINT_LEN)
-      memset (afp+an, 0, MAX_FINGERPRINT_LEN-an);
-    rc = keydb_search_fpr (hd, afp);
-  }
-
-  if (!rc)
-    {
-      rc = keydb_get_keyblock (hd, &sec_keyblock);
-      if (rc)
-        {
-          log_error (_("error reading keyblock: %s\n"), g10_errstr(rc) );
-          rc = G10ERR_GENERAL;
-        }
-      else
-        {
-          merge_keys_and_selfsig (sec_keyblock);
-          
-          /* FIXME: We need to add new subkeys first.  */
-          if (update_sec_keyblock_with_cardinfo (sec_keyblock,
-                                                 fpr1, fpr2, fpr3,
-                                                 serialnostr))
-            {
-              rc = keydb_update_keyblock (hd, sec_keyblock );
-              if (rc)
-                log_error (_("error writing keyring `%s': %s\n"),
-                           keydb_get_resource_name (hd), g10_errstr(rc) );
-            }
-        }
-    }
-  else  /* A secret key does not exists - create it.  */
-    {
-      sec_keyblock = pub_to_sec_keyblock (pub_keyblock);
-      update_sec_keyblock_with_cardinfo (sec_keyblock,
-                                         fpr1, fpr2, fpr3,
-                                         serialnostr);
-
-      rc = keydb_locate_writable (hd, NULL);
-      if (rc)
-        {
-          log_error (_("no default secret keyring: %s\n"), g10_errstr (rc));
-          rc = G10ERR_GENERAL;
-        }
-      else
-        {
-          rc = keydb_insert_keyblock (hd, sec_keyblock );
-          if (rc)
-            log_error (_("error writing keyring `%s': %s\n"),
-                       keydb_get_resource_name (hd), g10_errstr(rc) );
-        }
-    }
-    
-  release_kbnode (sec_keyblock);
-  release_kbnode (pub_keyblock);
-  keydb_release (hd);
-  return rc;
-}
index ca6b901..63f42a5 100644 (file)
@@ -195,7 +195,7 @@ void set_next_passphrase( const char *s );
 char *get_last_passphrase(void);
 void next_to_last_passphrase(void);
 
-char *gpg_format_keydesc (PKT_public_key *pk, int escaped);
+char *gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped);
 
 
 /*-- getkey.c --*/
@@ -241,8 +241,8 @@ void getkey_end (getkey_ctx_t ctx);
 int have_any_secret_key (ctrl_t ctrl, kbnode_t keyblock);
 
 
-int enum_secret_keys( void **context, PKT_secret_key *sk,
-                     int with_subkeys, int with_spm );
+//int enum_secret_keys( void **context, PKT_secret_key *sk,
+//                   int with_subkeys, int with_spm );
 void merge_keys_and_selfsig( KBNODE keyblock );
 char*get_user_id_string( u32 *keyid );
 char*get_user_id_string_native( u32 *keyid );
@@ -263,34 +263,23 @@ const char *keystr_with_sub (u32 *main_kid, u32 *sub_kid);
 const char *keystr_from_pk(PKT_public_key *pk);
 const char *keystr_from_pk_with_sub (PKT_public_key *main_pk,
                                      PKT_public_key *sub_pk);
-const char *keystr_from_sk(PKT_secret_key *sk);
-const char *keystr_from_sk_with_sub (PKT_secret_key *main_sk,
-                                     PKT_secret_key *sub_sk);
 const char *keystr_from_desc(KEYDB_SEARCH_DESC *desc);
-u32 keyid_from_sk( PKT_secret_key *sk, u32 *keyid );
 u32 keyid_from_pk( PKT_public_key *pk, u32 *keyid );
 u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
 u32 keyid_from_fingerprint(const byte *fprint, size_t fprint_len, u32 *keyid);
 byte *namehash_from_uid(PKT_user_id *uid);
 unsigned nbits_from_pk( PKT_public_key *pk );
-unsigned nbits_from_sk( PKT_secret_key *sk );
 const char *datestr_from_pk( PKT_public_key *pk );
-const char *datestr_from_sk( PKT_secret_key *sk );
 const char *datestr_from_sig( PKT_signature *sig );
 const char *expirestr_from_pk( PKT_public_key *pk );
-const char *expirestr_from_sk( PKT_secret_key *sk );
 const char *expirestr_from_sig( PKT_signature *sig );
 const char *revokestr_from_pk( PKT_public_key *pk );
 const char *usagestr_from_pk( PKT_public_key *pk );
 const char *colon_strtime (u32 t);
 const char *colon_datestr_from_pk (PKT_public_key *pk);
-const char *colon_datestr_from_sk (PKT_secret_key *sk);
 const char *colon_datestr_from_sig (PKT_signature *sig);
 const char *colon_expirestr_from_sig (PKT_signature *sig);
-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);
 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);
 
index a086457..86dacff 100644 (file)
@@ -2924,7 +2924,9 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
 
          keyid_from_pk (pk, NULL);
          tty_printf ("%s%c %4u%c/%s  ",
-                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" : "sub",
+                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
+                     node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
+                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
                      (node->flag & NODFLG_SELKEY) ? '*' : ' ',
                      nbits_from_pk (pk),
                      pubkey_letter (pk->pubkey_algo), keystr (pk->keyid));
@@ -2941,7 +2943,35 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
          tty_printf (_("usage: %s"), usagestr_from_pk (pk));
          tty_printf ("\n");
 
-         if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+         if (pk->seckey_info
+              && pk->seckey_info->is_protected
+              && pk->seckey_info->s2k.mode == 1002)
+           {
+             tty_printf ("                     ");
+             tty_printf (_("card-no: "));
+             if (pk->seckey_info->ivlen == 16
+                 && !memcmp (pk->seckey_info->iv,
+                              "\xD2\x76\x00\x01\x24\x01", 6))
+               {       
+                  /* This is an OpenPGP card. */
+                 for (i = 8; i < 14; i++)
+                   {
+                     if (i == 10)
+                       tty_printf (" ");
+                     tty_printf ("%02X", pk->seckey_info->iv[i]);
+                   }
+               }
+             else
+               { 
+                  /* Unknown card: Print all. */
+                 for (i = 0; i < pk->seckey_info->ivlen; i++)
+                   tty_printf ("%02X", pk->seckey_info->iv[i]);
+               }
+             tty_printf ("\n");
+           }
+
+         if (node->pkt->pkttype == PKT_PUBLIC_KEY
+              || node->pkt->pkttype == PKT_SECRET_KEY)
            {
              if (opt.trust_model != TM_ALWAYS)
                {
@@ -2970,47 +3000,13 @@ show_key_with_all_names (KBNODE keyblock, int only_marked, int with_revoker,
                }
            }
 
-         if (node->pkt->pkttype == PKT_PUBLIC_KEY && with_fpr)
+         if ((node->pkt->pkttype == PKT_PUBLIC_KEY
+               || node->pkt->pkttype == PKT_SECRET_KEY) && with_fpr)
            {
              print_fingerprint (pk, 2);
              tty_printf ("\n");
            }
        }
-      else if (node->pkt->pkttype == PKT_SECRET_KEY
-              || (with_subkeys && node->pkt->pkttype == PKT_SECRET_SUBKEY))
-       {
-         PKT_secret_key *sk = node->pkt->pkt.secret_key;
-         tty_printf ("%s%c %4u%c/%s  ",
-                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
-                     (node->flag & NODFLG_SELKEY) ? '*' : ' ',
-                     nbits_from_sk (sk),
-                     pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk));
-         tty_printf (_("created: %s"), datestr_from_sk (sk));
-         tty_printf ("  ");
-         tty_printf (_("expires: %s"), expirestr_from_sk (sk));
-         tty_printf ("\n");
-         if (sk->is_protected && sk->protect.s2k.mode == 1002)
-           {
-             tty_printf ("                     ");
-             tty_printf (_("card-no: "));
-             if (sk->protect.ivlen == 16
-                 && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
-               {               /* This is an OpenPGP card. */
-                 for (i = 8; i < 14; i++)
-                   {
-                     if (i == 10)
-                       tty_printf (" ");
-                     tty_printf ("%02X", sk->protect.iv[i]);
-                   }
-               }
-             else
-               {               /* Something is wrong: Print all. */
-                 for (i = 0; i < sk->protect.ivlen; i++)
-                   tty_printf ("%02X", sk->protect.iv[i]);
-               }
-             tty_printf ("\n");
-           }
-       }
     }
 
   show_names (keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
@@ -3035,14 +3031,17 @@ show_basic_key_info (KBNODE keyblock)
   /* The primary key */
   for (node = keyblock; node; node = node->next)
     {
-      if (node->pkt->pkttype == PKT_PUBLIC_KEY)
+      if (node->pkt->pkttype == PKT_PUBLIC_KEY
+          || node->pkt->pkttype == PKT_SECRET_KEY)
        {
          PKT_public_key *pk = node->pkt->pkt.public_key;
 
          /* Note, we use the same format string as in other show
             functions to make the translation job easier. */
          tty_printf ("%s  %4u%c/%s  ",
-                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" : "sub",
+                     node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
+                     node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
+                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" :"ssb",
                      nbits_from_pk (pk),
                      pubkey_letter (pk->pubkey_algo), keystr_from_pk (pk));
          tty_printf (_("created: %s"), datestr_from_pk (pk));
@@ -3052,21 +3051,6 @@ show_basic_key_info (KBNODE keyblock)
          print_fingerprint (pk, 3);
          tty_printf ("\n");
        }
-      else if (node->pkt->pkttype == PKT_SECRET_KEY)
-       {
-         PKT_secret_key *sk = node->pkt->pkt.secret_key;
-         tty_printf ("%s  %4u%c/%s",
-                     node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
-                     nbits_from_sk (sk),
-                     pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk));
-         tty_printf (_("created: %s"), datestr_from_sk (sk));
-         tty_printf ("  ");
-         tty_printf (_("expires: %s"), expirestr_from_sk (sk));
-         tty_printf ("\n");
-          log_debug ("FIXME\n");
-         /* print_fingerprint (NULL, sk, 3); */
-         tty_printf ("\n");
-       }
     }
 
   /* The user IDs. */
index a6e8b37..1d09726 100644 (file)
 #define KEYID_STR_SIZE 19
 
 
+/* Return a letter describing the public key algorithms.  */
 int
 pubkey_letter( int algo )
 {
-    switch( algo ) {
-      case PUBKEY_ALGO_RSA:    return 'R' ;
-      case PUBKEY_ALGO_RSA_E:  return 'r' ;
-      case PUBKEY_ALGO_RSA_S:  return 's' ;
-      case PUBKEY_ALGO_ELGAMAL_E: return 'g';
-      case PUBKEY_ALGO_ELGAMAL: return 'G' ;
-      case PUBKEY_ALGO_DSA:    return 'D' ;
-      default: return '?';
+  switch (algo)
+    {
+    case PUBKEY_ALGO_RSA:      return 'R' ;
+    case PUBKEY_ALGO_RSA_E:    return 'r' ;
+    case PUBKEY_ALGO_RSA_S:    return 's' ;
+    case PUBKEY_ALGO_ELGAMAL_E: return 'g';
+    case PUBKEY_ALGO_ELGAMAL:   return 'G' ;
+    case PUBKEY_ALGO_DSA:      return 'D' ;
+    default: return '?';
     }
 }
 
-/* This function is useful for v4 fingerprints and v3 or v4 key
-   signing. */
+
+/* Hash a public key.  This function is useful for v4 fingerprints and
+   for v3 or v4 key signing. */
 void
-hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
+hash_public_key (gcry_md_hd_t md, PKT_public_key *pk)
 {
   unsigned int n = 6;
   unsigned int nn[PUBKEY_MAX_NPKEY];
@@ -77,17 +80,19 @@ hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
       n+=nn[0];
     }
   else
-    for(i=0; i < npkey; i++ )
-      {
-       if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i]))
-          BUG ();
-       pp[i] = xmalloc (nbytes);
-       if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
-                            &nbytes, pk->pkey[i]))
-          BUG ();
-        nn[i] = nbytes;
-       n += nn[i];
-      }
+    {
+      for(i=0; i < npkey; i++ )
+        {
+          if (gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, pk->pkey[i]))
+            BUG ();
+          pp[i] = xmalloc (nbytes);
+          if (gcry_mpi_print (GCRYMPI_FMT_PGP, pp[i], nbytes,
+                              &nbytes, pk->pkey[i]))
+            BUG ();
+          nn[i] = nbytes;
+          n += nn[i];
+        }
+    }
 
   gcry_md_putc ( md, 0x99 );     /* ctb */
   /* What does it mean if n is greater than than 0xFFFF ? */
@@ -125,6 +130,7 @@ hash_public_key( gcry_md_hd_t md, PKT_public_key *pk )
       }
 }
 
+
 static gcry_md_hd_t
 do_fingerprint_md( PKT_public_key *pk )
 {
@@ -138,27 +144,9 @@ do_fingerprint_md( PKT_public_key *pk )
   return md;
 }
 
-static gcry_md_hd_t
-do_fingerprint_md_sk( PKT_secret_key *sk )
-{
-    PKT_public_key pk;
-    int npkey = pubkey_get_npkey( sk->pubkey_algo ); /* npkey is correct! */
-    int i;
-
-    if(npkey==0)
-      return NULL;
-
-    pk.pubkey_algo = sk->pubkey_algo;
-    pk.version    = sk->version;
-    pk.timestamp = sk->timestamp;
-    pk.expiredate = sk->expiredate;
-    pk.pubkey_algo = sk->pubkey_algo;
-    for( i=0; i < npkey; i++ )
-      pk.pkey[i] = sk->skey[i];
-    return do_fingerprint_md( &pk );
-}
-
 
+/* fixme: Check whether we can replace this function or if not
+   describe why we need it.  */
 u32
 v3_keyid (gcry_mpi_t a, u32 *ki)
 {
@@ -280,24 +268,6 @@ keystr_from_pk_with_sub (PKT_public_key *main_pk, PKT_public_key *sub_pk)
 }
 
 
-const char *
-keystr_from_sk(PKT_secret_key *sk)
-{
-  keyid_from_sk (sk,NULL);
-
-  return keystr(sk->keyid);
-}
-
-
-const char *
-keystr_from_sk_with_sub (PKT_secret_key *main_sk, PKT_secret_key *sub_sk)
-{
-  keyid_from_sk (main_sk, NULL);
-  keyid_from_sk (sub_sk, NULL);
-
-  return keystr_with_sub (main_sk->keyid, sub_sk->keyid);
-}
-
 
 const char *
 keystr_from_desc(KEYDB_SEARCH_DESC *desc)
@@ -332,72 +302,18 @@ keystr_from_desc(KEYDB_SEARCH_DESC *desc)
     }
 }
 
-/****************
- * Get the keyid from the secret key and put it into keyid
- * if this is not NULL. Return the 32 low bits of the keyid.
- */
-u32
-keyid_from_sk( PKT_secret_key *sk, u32 *keyid )
-{
-  u32 lowbits;
-  u32 dummy_keyid[2];
 
-  if( !keyid )
-    keyid = dummy_keyid;
-
-  if( sk->keyid[0] || sk->keyid[1] )
-    {
-      keyid[0] = sk->keyid[0];
-      keyid[1] = sk->keyid[1];
-      lowbits = keyid[1];
-    }
-  else if( sk->version < 4 )
-    {
-      if( is_RSA(sk->pubkey_algo) )
-       {
-         lowbits = (pubkey_get_npkey (sk->pubkey_algo) ?
-                     v3_keyid( sk->skey[0], keyid ) : 0); /* Take n. */
-         sk->keyid[0]=keyid[0];
-         sk->keyid[1]=keyid[1];
-       }
-      else
-       sk->keyid[0]=sk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
-    }
-  else
-    {
-      const byte *dp;
-      gcry_md_hd_t md;
-
-      md = do_fingerprint_md_sk(sk);
-      if(md)
-       {
-         dp = gcry_md_read (md, 0);
-         keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
-         keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
-         lowbits = keyid[1];
-         gcry_md_close (md);
-         sk->keyid[0] = keyid[0];
-         sk->keyid[1] = keyid[1];
-       }
-      else
-       sk->keyid[0]=sk->keyid[1]=keyid[0]=keyid[1]=lowbits=0xFFFFFFFF;
-    }
-
-  return lowbits;
-}
-
-
-/****************
+/*
  * Get the keyid from the public key and put it into keyid
  * if this is not NULL. Return the 32 low bits of the keyid.
  */
 u32
-keyid_from_pk( PKT_public_key *pk, u32 *keyid )
+keyid_from_pk (PKT_public_key *pk, u32 *keyid)
 {
   u32 lowbits;
   u32 dummy_keyid[2];
 
-  if( !keyid )
+  if (!keyid)
     keyid = dummy_keyid;
 
   if( pk->keyid[0] || pk->keyid[1] )
@@ -442,61 +358,66 @@ keyid_from_pk( PKT_public_key *pk, u32 *keyid )
 }
 
 
-/****************
+/*
  * Get the keyid from the fingerprint. This function is simple for most
  * keys, but has to do a keylookup for old stayle keys.
  */
 u32
 keyid_from_fingerprint( const byte *fprint, size_t fprint_len, u32 *keyid )
 {
-    u32 dummy_keyid[2];
-
-    if( !keyid )
-       keyid = dummy_keyid;
-
-    if( fprint_len != 20 ) {
-       /* This is special as we have to lookup the key first */
-       PKT_public_key pk;
-       int rc;
-
-       memset( &pk, 0, sizeof pk );
-       rc = get_pubkey_byfprint( &pk, fprint, fprint_len );
-       if( rc ) {
-           log_error("Oops: keyid_from_fingerprint: no pubkey\n");
-           keyid[0] = 0;
-           keyid[1] = 0;
-       }
-       else
-           keyid_from_pk( &pk, keyid );
+  u32 dummy_keyid[2];
+
+  if( !keyid )
+    keyid = dummy_keyid;
+
+  if (fprint_len != 20)
+    {
+      /* This is special as we have to lookup the key first.  */
+      PKT_public_key pk;
+      int rc;
+
+      memset (&pk, 0, sizeof pk);
+      rc = get_pubkey_byfprint (&pk, fprint, fprint_len);
+      if( rc )
+        {
+          log_error("Oops: keyid_from_fingerprint: no pubkey\n");
+          keyid[0] = 0;
+          keyid[1] = 0;
+        }
+      else
+        keyid_from_pk (&pk, keyid);
     }
-    else {
-       const byte *dp = fprint;
-       keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
-       keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
+  else 
+    {
+      const byte *dp = fprint;
+      keyid[0] = dp[12] << 24 | dp[13] << 16 | dp[14] << 8 | dp[15] ;
+      keyid[1] = dp[16] << 24 | dp[17] << 16 | dp[18] << 8 | dp[19] ;
     }
 
-    return keyid[1];
+  return keyid[1];
 }
 
 
 u32
-keyid_from_sig( PKT_signature *sig, u32 *keyid )
+keyid_from_sig (PKT_signature *sig, u32 *keyid)
 {
-    if( keyid ) {
-       keyid[0] = sig->keyid[0];
-       keyid[1] = sig->keyid[1];
+  if( keyid ) 
+    {
+      keyid[0] = sig->keyid[0];
+      keyid[1] = sig->keyid[1];
     }
-    return sig->keyid[1];
+  return sig->keyid[1];
 }
 
+
 byte *
-namehash_from_uid(PKT_user_id *uid)
+namehash_from_uid (PKT_user_id *uid)
 {
   if (!uid->namehash)
     {
       uid->namehash = xmalloc (20);
       
-      if(uid->attrib_data)
+      if (uid->attrib_data)
        rmd160_hash_buffer (uid->namehash, uid->attrib_data, uid->attrib_len);
       else
        rmd160_hash_buffer (uid->namehash, uid->name, uid->len);
@@ -505,117 +426,95 @@ namehash_from_uid(PKT_user_id *uid)
   return uid->namehash;
 }
 
-/****************
- * return the number of bits used in the pk
- */
-unsigned
-nbits_from_pk( PKT_public_key *pk )
-{
-    return pubkey_nbits( pk->pubkey_algo, pk->pkey );
-}
 
-/****************
- * return the number of bits used in the sk
+/*
+ * Return the number of bits used in PK.
  */
-unsigned
-nbits_from_sk( PKT_secret_key *sk )
+unsigned int
+nbits_from_pk (PKT_public_key *pk)
 {
-    return pubkey_nbits( sk->pubkey_algo, sk->skey );
+    return pubkey_nbits (pk->pubkey_algo, pk->pkey);
 }
 
+
 static const char *
 mk_datestr (char *buffer, time_t atime)
 {
-    struct tm *tp;
-
-    if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
-        strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
-    else {
-        tp = gmtime (&atime);
-        sprintf (buffer,"%04d-%02d-%02d",
-                 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
+  struct tm *tp;
+
+  if ( atime < 0 ) /* 32 bit time_t and after 2038-01-19 */
+    strcpy (buffer, "????" "-??" "-??"); /* mark this as invalid */
+  else 
+    {
+      tp = gmtime (&atime);
+      sprintf (buffer,"%04d-%02d-%02d",
+               1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
     }
-    return buffer;
+  return buffer;
 }
 
-/****************
+
+/*
  * return a string with the creation date of the pk
  * Note: this is alloced in a static buffer.
  *    Format is: yyyy-mm-dd
  */
 const char *
-datestr_from_pk( PKT_public_key *pk )
+datestr_from_pk (PKT_public_key *pk)
 {
-    static char buffer[11+5];
-    time_t atime = pk->timestamp;
-
-    return mk_datestr (buffer, atime);
+  static char buffer[11+5];
+  time_t atime = pk->timestamp;
+  
+  return mk_datestr (buffer, atime);
 }
 
-const char *
-datestr_from_sk( PKT_secret_key *sk )
-{
-    static char buffer[11+5];
-    time_t atime = sk->timestamp;
-
-    return mk_datestr (buffer, atime);
-}
 
 const char *
-datestr_from_sigPKT_signature *sig )
+datestr_from_sig (PKT_signature *sig )
 {
-    static char buffer[11+5];
-    time_t atime = sig->timestamp;
+  static char buffer[11+5];
+  time_t atime = sig->timestamp;
 
-    return mk_datestr (buffer, atime);
+  return mk_datestr (buffer, atime);
 }
 
-const char *
-expirestr_from_pk( PKT_public_key *pk )
-{
-    static char buffer[11+5];
-    time_t atime;
-
-    if( !pk->expiredate )
-       return _("never     ");
-    atime = pk->expiredate;
-    return mk_datestr (buffer, atime);
-}
 
 const char *
-expirestr_from_sk( PKT_secret_key *sk )
+expirestr_from_pk (PKT_public_key *pk)
 {
-    static char buffer[11+5];
-    time_t atime;
+  static char buffer[11+5];
+  time_t atime;
 
-    if( !sk->expiredate )
-       return _("never     ");
-    atime = sk->expiredate;
-    return mk_datestr (buffer, atime);
+  if (!pk->expiredate)
+    return _("never     ");
+  atime = pk->expiredate;
+  return mk_datestr (buffer, atime);
 }
 
+
 const char *
-expirestr_from_sig( PKT_signature *sig )
+expirestr_from_sig (PKT_signature *sig)
 {
-    static char buffer[11+5];
-    time_t atime;
-
-    if(!sig->expiredate)
-      return _("never     ");
-    atime=sig->expiredate;
-    return mk_datestr (buffer, atime);
+  static char buffer[11+5];
+  time_t atime;
+  
+  if (!sig->expiredate)
+    return _("never     ");
+  atime=sig->expiredate;
+  return mk_datestr (buffer, atime);
 }
 
+
 const char *
 revokestr_from_pk( PKT_public_key *pk )
 {
-    static char buffer[11+5];
-    time_t atime;
+  static char buffer[11+5];
+  time_t atime;
 
-    if(!pk->revoked.date)
-      return _("never     ");
-    atime=pk->revoked.date;
-    return mk_datestr (buffer, atime);
+  if(!pk->revoked.date)
+    return _("never     ");
+  atime=pk->revoked.date;
+  return mk_datestr (buffer, atime);
 }
 
 
@@ -666,14 +565,6 @@ colon_datestr_from_pk (PKT_public_key *pk)
   return buf;
 }
 
-const char *
-colon_datestr_from_sk (PKT_secret_key *sk)
-{
-  static char buf[20];
-
-  snprintf (buf, sizeof buf, "%lu", (ulong)sk->timestamp);
-  return buf;
-}
 
 const char *
 colon_datestr_from_sig (PKT_signature *sig)
@@ -697,14 +588,13 @@ colon_expirestr_from_sig (PKT_signature *sig)
 }
 
 
-/**************** .
+/*
  * Return a byte array with the fingerprint for the given PK/SK
  * The length of the array is returned in ret_len. Caller must free
  * the array or provide an array of length MAX_FINGERPRINT_LEN.
  */
-
 byte *
-fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
+fingerprint_from_pk (PKT_public_key *pk, byte *array, size_t *ret_len)
 {
   byte *buf;
   const byte *dp;
@@ -771,106 +661,8 @@ fingerprint_from_pk( PKT_public_key *pk, byte *array, size_t *ret_len )
   return array;
 }
 
-byte *
-fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
-{
-  byte *buf;
-  const char *dp;
-  size_t len, nbytes;
-  int i;
-  
-  if (sk->version < 4)
-    {
-      if ( is_RSA(sk->pubkey_algo) )
-        {
-          /* RSA in version 3 packets is special. */
-          gcry_md_hd_t md;
-          
-          if (gcry_md_open (&md, DIGEST_ALGO_MD5, 0))
-            BUG ();
-          if (pubkey_get_npkey( sk->pubkey_algo ) > 1)
-            {
-              for (i=0; i < 2; i++)
-                {
-                  if (gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, 
-                                      &nbytes, sk->skey[i]))
-                    BUG ();
-                  /* fixme: Better allocate BUF on the stack */
-                  buf = xmalloc (nbytes);
-                  if (gcry_mpi_print (GCRYMPI_FMT_USG, buf, nbytes,
-                                      NULL, sk->skey[i]))
-                    BUG ();
-                  gcry_md_write (md, buf, nbytes);
-                  xfree (buf);
-                }
-           }
-          gcry_md_final(md);
-          if (!array)
-            array = xmalloc (16);
-          len = 16;
-          memcpy (array, gcry_md_read (md, DIGEST_ALGO_MD5), 16);
-          gcry_md_close (md);
-        }
-      else
-        {
-          if (!array)
-            array = xmalloc (16);
-          len=16;
-          memset (array,0,16);
-        }
-    }
-  else
-    {
-      gcry_md_hd_t md;
-      
-      md = do_fingerprint_md_sk(sk);
-      if (md)
-        {
-          dp = gcry_md_read ( md, 0 );
-          len = gcry_md_get_algo_dlen ( gcry_md_get_algo (md) );
-          assert ( len <= MAX_FINGERPRINT_LEN );
-          if (!array)
-            array = xmalloc( len );
-          memcpy (array, dp, len);
-          gcry_md_close (md);
-        }
-      else
-        {
-          len = MAX_FINGERPRINT_LEN;
-          if (!array)
-            array = xmalloc (len);
-          memset (array, 0, len);
-        }
-    }
-  
-  *ret_len = len;
-  return array;
-}
 
 
-/* Create a serialno/fpr string from the serial number and the secret
-   key.  Caller must free the returned string.  There is no error
-   return.  */
-char *
-serialno_and_fpr_from_sk (const unsigned char *sn, size_t snlen,
-                          PKT_secret_key *sk)
-{
-  unsigned char fpr[MAX_FINGERPRINT_LEN];
-  size_t fprlen;
-  char *buffer, *p;
-  int i;
-  
-  fingerprint_from_sk (sk, fpr, &fprlen);
-  buffer = p = xmalloc (snlen*2 + 1 + fprlen*2 + 1);
-  for (i=0; i < snlen; i++, p+=2)
-    sprintf (p, "%02X", sn[i]);
-  *p++ = '/';
-  for (i=0; i < fprlen; i++, p+=2)
-    sprintf (p, "%02X", fpr[i]);
-  *p = 0;
-  return buffer;
-}
-
 
 \f
 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
index b99047b..2d3574a 100644 (file)
@@ -44,7 +44,7 @@
 static void list_all (int);
 static void list_one (strlist_t names, int secret);
 static void locate_one (strlist_t names);
-static void print_card_serialno (PKT_secret_key * sk);
+static void print_card_serialno (PKT_public_key *sk);
 
 struct sig_stats
 {
@@ -174,52 +174,53 @@ print_pubkey_info (estream_t fp, PKT_public_key * pk)
 /* Print basic information of a secret key including the card serial
    number information.  */
 void
-print_card_key_info (estream_t fp, KBNODE keyblock)
+print_card_key_info (estream_t fp, kbnode_t keyblock)
 {
-  KBNODE node;
-  int i;
-
-  for (node = keyblock; node; node = node->next)
-    {
-      if (node->pkt->pkttype == PKT_SECRET_KEY
-         || (node->pkt->pkttype == PKT_SECRET_SUBKEY))
-       {
-         PKT_secret_key *sk = node->pkt->pkt.secret_key;
-
-         tty_fprintf (fp, "%s%c  %4u%c/%s  ",
-                      node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb",
-                      (sk->protect.s2k.mode == 1001) ? '#' :
-                      (sk->protect.s2k.mode == 1002) ? '>' : ' ',
-                      nbits_from_sk (sk),
-                      pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk));
-         tty_fprintf (fp, _("created: %s"), datestr_from_sk (sk));
-         tty_fprintf (fp, "  ");
-         tty_fprintf (fp, _("expires: %s"), expirestr_from_sk (sk));
-         if (sk->is_protected && sk->protect.s2k.mode == 1002)
-           {
-             tty_fprintf (fp, "\n                      ");
-             tty_fprintf (fp, _("card-no: "));
-             if (sk->protect.ivlen == 16
-                 && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
-               {
-                 /* This is an OpenPGP card. */
-                 for (i = 8; i < 14; i++)
-                   {
-                     if (i == 10)
-                       tty_fprintf (fp, " ");
-                     tty_fprintf (fp, "%02X", sk->protect.iv[i]);
-                   }
-               }
-             else
-               {
-                  /* Something is wrong: Print all. */
-                 for (i = 0; i < sk->protect.ivlen; i++)
-                   tty_fprintf (fp, "%02X", sk->protect.iv[i]);
-               }
-           }
-         tty_fprintf (fp, "\n");
-       }
-    }
+  /* KBNODE node; */
+  /* int i; */
+
+  log_debug ("Fixme: Needs to be adjusted to gpg-agent\n");
+  /* for (node = keyblock; node; node = node->next) */
+  /*   { */
+  /*     if (node->pkt->pkttype == PKT_SECRET_KEY */
+  /*         || (node->pkt->pkttype == PKT_SECRET_SUBKEY)) */
+  /*       { */
+  /*         PKT_public_key *pk = node->pkt->pkt.public_key; */
+
+  /*         tty_fprintf (fp, "%s%c  %4u%c/%s  ", */
+  /*                  node->pkt->pkttype == PKT_SECRET_KEY ? "sec" : "ssb", */
+  /*                  (sk->protect.s2k.mode == 1001) ? '#' : */
+  /*                  (sk->protect.s2k.mode == 1002) ? '>' : ' ', */
+  /*                  nbits_from_sk (sk), */
+  /*                  pubkey_letter (sk->pubkey_algo), keystr_from_sk (sk)); */
+  /*         tty_fprintf (fp, _("created: %s"), datestr_from_sk (sk)); */
+  /*         tty_fprintf (fp, "  "); */
+  /*         tty_fprintf (fp, _("expires: %s"), expirestr_from_sk (sk)); */
+  /*         if (sk->is_protected && sk->protect.s2k.mode == 1002) */
+  /*           { */
+  /*             tty_fprintf (fp, "\n                      "); */
+  /*             tty_fprintf (fp, _("card-no: ")); */
+  /*             if (sk->protect.ivlen == 16 */
+  /*             && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6)) */
+  /*           { */
+  /*             /\* This is an OpenPGP card. *\/ */
+  /*             for (i = 8; i < 14; i++) */
+  /*               { */
+  /*                 if (i == 10) */
+  /*                   tty_fprintf (fp, " "); */
+  /*                 tty_fprintf (fp, "%02X", sk->protect.iv[i]); */
+  /*               } */
+  /*           } */
+  /*             else */
+  /*           { */
+  /*                 /\* Something is wrong: Print all. *\/ */
+  /*             for (i = 0; i < sk->protect.ivlen; i++) */
+  /*               tty_fprintf (fp, "%02X", sk->protect.iv[i]); */
+  /*           } */
+  /*           } */
+  /*         tty_fprintf (fp, "\n"); */
+  /*       } */
+  /*   } */
 }
 
 
@@ -1524,37 +1525,38 @@ print_fingerprint (PKT_public_key *pk, int mode)
 
 /* Print the serial number of an OpenPGP card if available.  */
 static void
-print_card_serialno (PKT_secret_key * sk)
+print_card_serialno (PKT_public_key *pk)
 {
-  int i;
-
-  if (!sk)
-    return;
-  if (!sk->is_protected || sk->protect.s2k.mode != 1002)
-    return; /* Not a card. */
-  if (opt.with_colons)
-    return; /* Handled elsewhere. */
-
-  es_fputs (_("      Card serial no. ="), es_stdout);
-  es_putc (' ', es_stdout);
-  if (sk->protect.ivlen == 16
-      && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6))
-    {          
-      /* This is an OpenPGP card. Just print the relevant part.  */
-      for (i = 8; i < 14; i++)
-       {
-         if (i == 10)
-           es_putc (' ', es_stdout);
-         es_fprintf (es_stdout, "%02X", sk->protect.iv[i]);
-       }
-    }
-  else
-    {
-      /* Something is wrong: Print all.  */
-      for (i = 0; i < sk->protect.ivlen; i++)
-       es_fprintf (es_stdout, "%02X", sk->protect.iv[i]);
-    }
-  es_putc ('\n', es_stdout);
+  log_debug ("Fixme: Needs to be adjusted to gpg-agent\n");
+  /* int i; */
+
+  /* if (!sk) */
+  /*   return; */
+  /* if (!sk->is_protected || sk->protect.s2k.mode != 1002) */
+  /*   return; /\* Not a card. *\/ */
+  /* if (opt.with_colons) */
+  /*   return; /\* Handled elsewhere. *\/ */
+
+  /* es_fputs (_("      Card serial no. ="), es_stdout); */
+  /* es_putc (' ', es_stdout); */
+  /* if (sk->protect.ivlen == 16 */
+  /*     && !memcmp (sk->protect.iv, "\xD2\x76\x00\x01\x24\x01", 6)) */
+  /*   {                */
+  /*     /\* This is an OpenPGP card. Just print the relevant part.  *\/ */
+  /*     for (i = 8; i < 14; i++) */
+  /*       { */
+  /*         if (i == 10) */
+  /*           es_putc (' ', es_stdout); */
+  /*         es_fprintf (es_stdout, "%02X", sk->protect.iv[i]); */
+  /*       } */
+  /*   } */
+  /* else */
+  /*   { */
+  /*     /\* Something is wrong: Print all.  *\/ */
+  /*     for (i = 0; i < sk->protect.ivlen; i++) */
+  /*       es_fprintf (es_stdout, "%02X", sk->protect.iv[i]); */
+  /*   } */
+  /* es_putc ('\n', es_stdout); */
 }
 
 
index 5277db9..d069b13 100644 (file)
@@ -899,7 +899,6 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
   int use_offtbl;
   PKT_user_id *uid = NULL;
   PKT_public_key *pk = NULL;
-  PKT_secret_key *sk = NULL;
   u32 aki[2];
 
   /* figure out what information we need */
@@ -1017,10 +1016,11 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
         }
        
       pk = NULL;
-      sk = NULL;
       uid = NULL;
       if (   pkt.pkttype == PKT_PUBLIC_KEY
-             || pkt.pkttype == PKT_PUBLIC_SUBKEY)
+             || pkt.pkttype == PKT_PUBLIC_SUBKEY
+             || pkt.pkttype == PKT_SECRET_KEY
+             || pkt.pkttype == PKT_SECRET_SUBKEY) 
         {
           pk = pkt.pkt.public_key;
           ++pk_no;
@@ -1041,21 +1041,6 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
           uid = pkt.pkt.user_id;
           ++uid_no;
         }
-      else if (    pkt.pkttype == PKT_SECRET_KEY
-                   || pkt.pkttype == PKT_SECRET_SUBKEY) 
-        {
-          sk = pkt.pkt.secret_key;
-          ++pk_no;
-
-          if (need_fpr) {
-            fingerprint_from_sk (sk, afp, &an);
-            while (an < 20) /* fill up to 20 bytes */
-              afp[an++] = 0;
-          }
-          if (need_keyid)
-            keyid_from_sk (sk, aki);
-            
-        }
 
       for (n=0; n < ndesc; n++) 
         {
@@ -1076,29 +1061,29 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
             break;
                 
           case KEYDB_SEARCH_MODE_SHORT_KID: 
-            if ((pk||sk) && desc[n].u.kid[1] == aki[1])
+            if (pk && desc[n].u.kid[1] == aki[1])
               goto found;
             break;
           case KEYDB_SEARCH_MODE_LONG_KID:
-            if ((pk||sk) && desc[n].u.kid[0] == aki[0]
+            if (pk && desc[n].u.kid[0] == aki[0]
                 && desc[n].u.kid[1] == aki[1])
               goto found;
             break;
           case KEYDB_SEARCH_MODE_FPR16:
-            if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 16))
+            if (pk && !memcmp (desc[n].u.fpr, afp, 16))
               goto found;
             break;
           case KEYDB_SEARCH_MODE_FPR20:
           case KEYDB_SEARCH_MODE_FPR: 
-            if ((pk||sk) && !memcmp (desc[n].u.fpr, afp, 20))
+            if (pk && !memcmp (desc[n].u.fpr, afp, 20))
               goto found;
             break;
           case KEYDB_SEARCH_MODE_FIRST: 
-            if (pk||sk)
+            if (pk)
               goto found;
             break;
           case KEYDB_SEARCH_MODE_NEXT: 
-            if (pk||sk)
+            if (pk)
               goto found;
             break;
           default: 
@@ -1128,7 +1113,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc,
     {
       hd->found.offset = main_offset;
       hd->found.kr = hd->current.kr;
-      hd->found.pk_no = (pk||sk)? pk_no : 0;
+      hd->found.pk_no = pk? pk_no : 0;
       hd->found.uid_no = uid? uid_no : 0;
     }
   else if (rc == -1)
index e84d5d0..ba8afba 100644 (file)
@@ -277,10 +277,6 @@ void import_print_stats (void *hd);
 
 int collapse_uids( KBNODE *keyblock );
 
-int auto_create_card_key_stub ( const char *serialnostr, 
-                                const unsigned char *fpr1,
-                                const unsigned char *fpr2,
-                                const unsigned char *fpr3);
 
 /*-- export.c --*/
 int parse_export_options(char *str,unsigned int *options,int noisy);
index 87e9912..02ffae9 100644 (file)
@@ -58,7 +58,6 @@ struct mainproc_context
 {
   struct mainproc_context *anchor;  /* May be useful in the future. */
   PKT_public_key *last_pubkey;
-  PKT_secret_key *last_seckey;
   PKT_user_id     *last_user_id;
   md_filter_context_t mfx;
   int sigs_only;    /* Process only signatures and reject all other stuff. */
@@ -1118,15 +1117,13 @@ list_node( CTX c, KBNODE node )
            u32 keyid[2];
 
            if( c->list->pkt->pkttype == PKT_PUBLIC_KEY
-               || c->list->pkt->pkttype == PKT_SECRET_KEY ) {
-               if( c->list->pkt->pkttype == PKT_PUBLIC_KEY )
-                   keyid_from_pk( c->list->pkt->pkt.public_key, keyid );
-               else
-                   keyid_from_sk( c->list->pkt->pkt.secret_key, keyid );
-
-               if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
-                   is_selfsig = 1;
-           }
+               || c->list->pkt->pkttype == PKT_SECRET_KEY )
+              {
+                keyid_from_pk (c->list->pkt->pkt.public_key, keyid);
+                
+                if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
+                  is_selfsig = 1;
+              }
        }
        if( opt.with_colons ) {
            putchar(':');
index d124f4c..02674a0 100644 (file)
@@ -53,11 +53,12 @@ typedef struct {
     byte value;
 } prefitem_t;
 
-typedef struct {
-    int  mode;
-    byte hash_algo;
-    byte salt[8];
-    u32  count;
+typedef struct 
+{
+  int  mode;      /* Must be an integer due to the GNU modes 1001 et al.  */
+  byte hash_algo;
+  byte salt[8];
+  u32  count;
 } STRING2KEY;
 
 typedef struct {
@@ -204,11 +205,35 @@ struct revoke_info
   byte algo;
 };
 
+
+/* Information pertaining to secret keys. */
+struct seckey_info
+{
+  int is_protected:1;  /* The secret info is protected and must */
+                       /* be decrypted before use, the protected */
+                       /* MPIs are simply (void*) pointers to memory */
+                       /* and should never be passed to a mpi_xxx() */
+  int sha1chk:1;        /* SHA1 is used instead of a 16 bit checksum */ 
+  u16 csum;            /* Checksum for old protection modes.  */
+  byte algo;            /* Cipher used to protect the secret information. */
+  STRING2KEY s2k;       /* S2K parameter.  */
+  byte ivlen;           /* Used length of the IV.  */
+  byte iv[16];          /* Initialization vector for CFB mode.  */
+};
+
+
 /****************
- * Note about the pkey/skey elements:  We assume that the secret keys
- * 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.
+ * We assume that secret keys have the same number of parameters as
+ * the public key and that the public parameters are the first items
+ * in the PKEY array.  Thus NPKEY is always less than NSKEY and it is
+ * possible to compare the secret and public keys by comparing the
+ * first NPKEY elements of the PKEY array.  Note that since GnuPG 2.1
+ * we don't use secret keys anymore directly because they are managed
+ * by gpg-agent.  However for parsing OpenPGP key files we need a way
+ * to temporary store those secret keys.  We do this by putting them
+ * into the public key structure and extending the PKEY field to NSKEY
+ * elements; the extra secret key information are stored in the
+ * SECKEY_INFO field.
  */
 typedef struct {
     u32     timestamp;     /* key made */
@@ -243,44 +268,16 @@ typedef struct {
     byte    trust_depth;
     byte    trust_value;
     const byte *trust_regexp;
-    gcry_mpi_t     pkey[PUBKEY_MAX_NPKEY];
+    struct seckey_info *seckey_info;  /* If not NULL this malloced
+                                         structure describes a secret
+                                         key.  */
+    gcry_mpi_t  pkey[PUBKEY_MAX_NSKEY]; /* Right, NSKEY elements.  */
 } PKT_public_key;
 
 /* Evaluates as true if the pk is disabled, and false if it isn't.  If
    there is no disable value cached, fill one in. */
 #define pk_is_disabled(a) (((a)->is_disabled)?((a)->is_disabled==2):(cache_disabled_value((a))))
 
-typedef struct {
-    u32     timestamp;     /* key made */
-    u32     expiredate;     /* expires at this date or 0 if not at all */
-    u32     max_expiredate; /* must not expire past this date */
-    byte    hdrbytes;      /* number of header bytes */
-    byte    version;
-    byte    pubkey_algo;    /* algorithm used for public key scheme */
-    byte    pubkey_usage;
-    byte    req_usage;
-    byte    req_algo;
-    u32     has_expired;    /* set to the expiration date if expired */ 
-    int     is_revoked;     /* key has been revoked */
-    int     is_valid;       /* key (especially subkey) is valid */
-    u32     main_keyid[2];  /* keyid of the primary key */
-    u32     keyid[2];   
-    byte is_primary;
-    byte is_protected; /* The secret info is protected and must */
-                       /* be decrypted before use, the protected */
-                       /* MPIs are simply (void*) pointers to memory */
-                       /* and should never be passed to a mpi_xxx() */
-    struct {
-       byte algo;  /* cipher used to protect the secret information*/
-        byte sha1chk;  /* SHA1 is used instead of a 16 bit checksum */ 
-       STRING2KEY s2k;
-       byte ivlen;  /* used length of the iv */
-       byte iv[16]; /* initialization vector for CFB mode */
-    } protect;
-    gcry_mpi_t skey[PUBKEY_MAX_NSKEY];
-    u16 csum;          /* checksum */
-} PKT_secret_key;
-
 
 typedef struct {
     int  len;            /* length of data */
@@ -339,7 +336,7 @@ struct packet_struct {
        PKT_onepass_sig *onepass_sig;   /* PKT_ONEPASS_SIG */
        PKT_signature   *signature;     /* PKT_SIGNATURE */
        PKT_public_key  *public_key;    /* PKT_PUBLIC_[SUB)KEY */
-       PKT_secret_key  *secret_key;    /* PKT_SECRET_[SUB]KEY */
+       PKT_public_key  *secret_key;    /* PKT_SECRET_[SUB]KEY */
        PKT_comment     *comment;       /* PKT_COMMENT */
        PKT_user_id     *user_id;       /* PKT_USER_ID */
        PKT_compressed  *compressed;    /* PKT_COMPRESSED */
@@ -452,22 +449,16 @@ void free_seckey_enc( PKT_signature *enc );
 int  digest_algo_from_sig( PKT_signature *sig );
 void release_public_key_parts( PKT_public_key *pk );
 void free_public_key( PKT_public_key *key );
-void release_secret_key_parts( PKT_secret_key *sk );
-void free_secret_key( PKT_secret_key *sk );
 void free_attributes(PKT_user_id *uid);
 void free_user_id( PKT_user_id *uid );
 void free_comment( PKT_comment *rem );
 void free_packet( PACKET *pkt );
 prefitem_t *copy_prefs (const prefitem_t *prefs);
 PKT_public_key *copy_public_key( PKT_public_key *d, PKT_public_key *s );
-void copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
-PKT_secret_key *copy_secret_key( PKT_secret_key *d, PKT_secret_key *s );
 PKT_signature *copy_signature( PKT_signature *d, PKT_signature *s );
 PKT_user_id *scopy_user_id (PKT_user_id *sd );
 int cmp_public_keys( PKT_public_key *a, PKT_public_key *b );
-int cmp_secret_keys( PKT_secret_key *a, PKT_secret_key *b );
 int cmp_signatures( PKT_signature *a, PKT_signature *b );
-int cmp_public_secret_key( PKT_public_key *pk, PKT_secret_key *sk );
 int cmp_user_ids( PKT_user_id *a, PKT_user_id *b );
 
 
index 2065c22..c835240 100644 (file)
@@ -565,12 +565,9 @@ parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos,
     {
     case PKT_PUBLIC_KEY:
     case PKT_PUBLIC_SUBKEY:
-      pkt->pkt.public_key = xmalloc_clear (sizeof *pkt->pkt.public_key);
-      rc = parse_key (inp, pkttype, pktlen, hdr, hdrlen, pkt);
-      break;
     case PKT_SECRET_KEY:
     case PKT_SECRET_SUBKEY:
-      pkt->pkt.secret_key = xmalloc_clear (sizeof *pkt->pkt.secret_key);
+      pkt->pkt.public_key = xmalloc_clear (sizeof *pkt->pkt.public_key);
       rc = parse_key (inp, pkttype, pktlen, hdr, hdrlen, pkt);
       break;
     case PKT_SYMKEY_ENC:
@@ -627,6 +624,7 @@ parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos,
     }
 
  leave:
+  /* FIXME: Do we leak in case of an error?  */
   if (!rc && iobuf_error (inp))
     rc = G10ERR_INV_KEYRING;
   return rc;
@@ -1815,6 +1813,7 @@ static int
 parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
           byte * hdr, int hdrlen, PACKET * pkt)
 {
+  gpg_error_t err = 0;
   int i, version, algorithm;
   unsigned n;
   unsigned long timestamp, expiredate, max_expiredate;
@@ -1822,9 +1821,12 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
   int is_v4 = 0;
   int rc = 0;
   u32 keyid[2];
+  PKT_public_key *pk;
 
   (void) hdr;
 
+  pk = pkt->pkt.public_key; /* PK has been cleared. */
+
   version = iobuf_get_noeof (inp);
   pktlen--;
   if (pkttype == PKT_PUBLIC_SUBKEY && version == '#')
@@ -1853,14 +1855,14 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
   else if (version != 2 && version != 3)
     {
       log_error ("packet(%d) with unknown version %d\n", pkttype, version);
-      rc = gpg_error (GPG_ERR_INV_PACKET);
+      err = gpg_error (GPG_ERR_INV_PACKET);
       goto leave;
     }
 
   if (pktlen < 11)
     {
       log_error ("packet(%d) too short\n", pkttype);
-      rc = gpg_error (GPG_ERR_INV_PACKET);
+      err = gpg_error (GPG_ERR_INV_PACKET);
       goto leave;
     }
 
@@ -1894,38 +1896,14 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
                 pkttype == PKT_SECRET_SUBKEY ? "secret sub" : "??",
                 version, algorithm, timestamp, expiredate);
 
-  if (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY)
-    {
-      PKT_secret_key *sk = pkt->pkt.secret_key;
+  pk->timestamp = timestamp;
+  pk->expiredate = expiredate;
+  pk->max_expiredate = max_expiredate;
+  pk->hdrbytes = hdrlen;
+  pk->version = version;
+  pk->is_primary = (pkttype == PKT_PUBLIC_KEY || pkttype == PKT_SECRET_KEY);
+  pk->pubkey_algo = algorithm;
 
-      sk->timestamp = timestamp;
-      sk->expiredate = expiredate;
-      sk->max_expiredate = max_expiredate;
-      sk->hdrbytes = hdrlen;
-      sk->version = version;
-      sk->is_primary = pkttype == PKT_SECRET_KEY;
-      sk->pubkey_algo = algorithm;
-      sk->req_usage = 0;
-      sk->pubkey_usage = 0;    /* not yet used */
-    }
-  else
-    {
-      PKT_public_key *pk = pkt->pkt.public_key;
-
-      pk->timestamp = timestamp;
-      pk->expiredate = expiredate;
-      pk->max_expiredate = max_expiredate;
-      pk->hdrbytes = hdrlen;
-      pk->version = version;
-      pk->is_primary = pkttype == PKT_PUBLIC_KEY;
-      pk->pubkey_algo = algorithm;
-      pk->req_usage = 0;
-      pk->pubkey_usage = 0;    /* not yet used */
-      pk->is_revoked = 0;
-      pk->is_disabled = 0;
-      pk->keyid[0] = 0;
-      pk->keyid[1] = 0;
-    }
   nskey = pubkey_get_nskey (algorithm);
   npkey = pubkey_get_npkey (algorithm);
   if (!npkey)
@@ -1936,62 +1914,77 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
     }
 
 
-  if (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY)
+  if (!npkey)
     {
-      PKT_secret_key *sk = pkt->pkt.secret_key;
-      byte temp[16];
-      size_t snlen = 0;
-
-      if (!npkey)
-       {
-         sk->skey[0] = gcry_mpi_set_opaque (NULL, read_rest (inp, pktlen, 0),
-                                            pktlen * 8);
-         pktlen = 0;
-         goto leave;
-       }
-
+      /* Unknown algorithm - put data into an opaque MPI.  */
+      pk->pkey[0] = gcry_mpi_set_opaque (NULL,
+                                         read_rest (inp, pktlen, 0),
+                                         pktlen * 8);
+      pktlen = 0;
+      goto leave;
+    }
+  else
+    {
+      /* Fill in public key parameters.  */
       for (i = 0; i < npkey; i++)
        {
          n = pktlen;
-         sk->skey[i] = mpi_read (inp, &n, 0);
+         pk->pkey[i] = mpi_read (inp, &n, 0);
          pktlen -= n;
          if (list_mode)
            {
-             es_fprintf (listfp, "\tskey[%d]: ", i);
-             mpi_print (listfp, sk->skey[i], mpi_print_mode);
+             es_fprintf (listfp, "\tpkey[%d]: ", i);
+             mpi_print (listfp, pk->pkey[i], mpi_print_mode);
              es_putc ('\n', listfp);
            }
-         if (!sk->skey[i])
-           rc = G10ERR_INVALID_PACKET;
+         if (!pk->pkey[i])
+           err = gpg_error (GPG_ERR_INV_PACKET);
        }
-      if (rc)  /* One of the MPIs were bad.  */
+      if (err)
        goto leave;
-      sk->protect.algo = iobuf_get_noeof (inp);
+    }
+
+  if (list_mode)
+    keyid_from_pk (pk, keyid);
+
+  if (pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY)
+    {
+      struct seckey_info *ski;
+      byte temp[16];
+      size_t snlen = 0;
+
+      pk->seckey_info = ski = xtrycalloc (1, sizeof *ski);
+      if (!pk->seckey_info)
+        {
+          err = gpg_error_from_syserror ();
+          goto leave;
+        }
+
+      ski->algo = iobuf_get_noeof (inp);
       pktlen--;
-      sk->protect.sha1chk = 0;
-      if (sk->protect.algo)
+      if (ski->algo)
        {
-         sk->is_protected = 1;
-         sk->protect.s2k.count = 0;
-         if (sk->protect.algo == 254 || sk->protect.algo == 255)
+         ski->is_protected = 1;
+         ski->s2k.count = 0;
+         if (ski->algo == 254 || ski->algo == 255)
            {
              if (pktlen < 3)
                {
-                 rc = G10ERR_INVALID_PACKET;
+                 err = gpg_error (GPG_ERR_INV_PACKET);
                  goto leave;
                }
-             sk->protect.sha1chk = (sk->protect.algo == 254);
-             sk->protect.algo = iobuf_get_noeof (inp);
+             ski->sha1chk = (ski->algo == 254);
+             ski->algo = iobuf_get_noeof (inp);
              pktlen--;
-             /* Note that a sk->protect.algo > 110 is illegal, but
-                I'm not erroring on it here as otherwise there would
-                be no way to delete such a key.  */
-             sk->protect.s2k.mode = iobuf_get_noeof (inp);
+             /* Note that a ski->algo > 110 is illegal, but I'm not
+                erroring on it here as otherwise there would be no
+                way to delete such a key.  */
+             ski->s2k.mode = iobuf_get_noeof (inp);
              pktlen--;
-             sk->protect.s2k.hash_algo = iobuf_get_noeof (inp);
+             ski->s2k.hash_algo = iobuf_get_noeof (inp);
              pktlen--;
-             /* check for the special GNU extension */
-             if (is_v4 && sk->protect.s2k.mode == 101)
+             /* Check for the special GNU extension.  */
+             if (is_v4 && ski->s2k.mode == 101)
                {
                  for (i = 0; i < 4 && pktlen; i++, pktlen--)
                    temp[i] = iobuf_get_noeof (inp);
@@ -1999,26 +1992,30 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
                    {
                      if (list_mode)
                        es_fprintf (listfp, "\tunknown S2K %d\n",
-                                    sk->protect.s2k.mode);
-                     rc = G10ERR_INVALID_PACKET;
+                                    ski->s2k.mode);
+                     err = gpg_error (GPG_ERR_INV_PACKET);
                      goto leave;
                    }
                  /* Here we know that it is a GNU extension.  What
                   * follows is the GNU protection mode: All values
                   * have special meanings and they are mapped to MODE
                   * with a base of 1000.  */
-                 sk->protect.s2k.mode = 1000 + temp[3];
+                 ski->s2k.mode = 1000 + temp[3];
                }
-             switch (sk->protect.s2k.mode)
+
+              /* Read the salt.  */
+             switch (ski->s2k.mode)
                {
                case 1:
                case 3:
                  for (i = 0; i < 8 && pktlen; i++, pktlen--)
                    temp[i] = iobuf_get_noeof (inp);
-                 memcpy (sk->protect.s2k.salt, temp, 8);
+                 memcpy (ski->s2k.salt, temp, 8);
                  break;
                }
-             switch (sk->protect.s2k.mode)
+
+              /* Check the mode.  */
+             switch (ski->s2k.mode)
                {
                case 0:
                  if (list_mode)
@@ -2043,202 +2040,163 @@ parse_key (IOBUF inp, int pkttype, unsigned long pktlen,
                default:
                  if (list_mode)
                    es_fprintf (listfp, "\tunknown %sS2K %d\n",
-                                sk->protect.s2k.mode < 1000 ? "" : "GNU ",
-                                sk->protect.s2k.mode);
-                 rc = G10ERR_INVALID_PACKET;
+                                ski->s2k.mode < 1000 ? "" : "GNU ",
+                                ski->s2k.mode);
+                 err = gpg_error (GPG_ERR_INV_PACKET);
                  goto leave;
                }
 
+              /* Print some info.  */
              if (list_mode)
                {
                  es_fprintf (listfp, ", algo: %d,%s hash: %d",
-                              sk->protect.algo,
-                              sk->protect.sha1chk ? " SHA1 protection,"
-                              : " simple checksum,", sk->protect.s2k.hash_algo);
-                 if (sk->protect.s2k.mode == 1 || sk->protect.s2k.mode == 3)
+                              ski->algo,
+                              ski->sha1chk ? " SHA1 protection,"
+                              : " simple checksum,", ski->s2k.hash_algo);
+                 if (ski->s2k.mode == 1 || ski->s2k.mode == 3)
                    {
                      es_fprintf (listfp, ", salt: ");
-                      es_write_hexstring (listfp, sk->protect.s2k.salt, 8,
-                                          0, NULL);
+                      es_write_hexstring (listfp, ski->s2k.salt, 8, 0, NULL);
                    }
                  es_putc ('\n', listfp);
                }
 
-             if (sk->protect.s2k.mode == 3)
+              /* Read remaining protection parameters.  */
+             if (ski->s2k.mode == 3)
                {
                  if (pktlen < 1)
                    {
-                     rc = G10ERR_INVALID_PACKET;
+                     err = gpg_error (GPG_ERR_INV_PACKET);
                      goto leave;
                    }
-                 sk->protect.s2k.count = iobuf_get (inp);
+                 ski->s2k.count = iobuf_get (inp);
                  pktlen--;
                  if (list_mode)
                    es_fprintf (listfp, "\tprotect count: %lu\n",
-                                (ulong) sk->protect.s2k.count);
+                                (ulong) ski->s2k.count);
                }
-             else if (sk->protect.s2k.mode == 1002)
+             else if (ski->s2k.mode == 1002)
                {
                  /* Read the serial number. */
                  if (pktlen < 1)
                    {
-                     rc = G10ERR_INVALID_PACKET;
+                     err = gpg_error (GPG_ERR_INV_PACKET);
                      goto leave;
                    }
                  snlen = iobuf_get (inp);
                  pktlen--;
                  if (pktlen < snlen || snlen == -1)
                    {
-                     rc = G10ERR_INVALID_PACKET;
+                     err = gpg_error (GPG_ERR_INV_PACKET);
                      goto leave;
                    }
                }
            }
          else /* Old version; no S2K, so we set mode to 0, hash MD5.  */
            { 
-              /* Note that a sk->protect.algo > 110 is illegal, but
-                 I'm not erroring on it here as otherwise there would
-                 be no way to delete such a key.  */
-             sk->protect.s2k.mode = 0;
-             sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
+              /* Note that a ski->algo > 110 is illegal, but I'm not
+                 erroring on it here as otherwise there would be no
+                 way to delete such a key.  */
+             ski->s2k.mode = 0;
+             ski->s2k.hash_algo = DIGEST_ALGO_MD5;
              if (list_mode)
                es_fprintf (listfp, "\tprotect algo: %d  (hash algo: %d)\n",
-                            sk->protect.algo, sk->protect.s2k.hash_algo);
+                            ski->algo, ski->s2k.hash_algo);
            }
           
          /* It is really ugly that we don't know the size
           * of the IV here in cases we are not aware of the algorithm.
           * so a
-          *   sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
+          *   ski->ivlen = cipher_get_blocksize (ski->algo);
           * won't work.  The only solution I see is to hardwire it.
           * NOTE: if you change the ivlen above 16, don't forget to
           * enlarge temp.  */
-         sk->protect.ivlen = openpgp_cipher_blocklen (sk->protect.algo);
-         assert (sk->protect.ivlen <= sizeof (temp));
+         ski->ivlen = openpgp_cipher_blocklen (ski->algo);
+         assert (ski->ivlen <= sizeof (temp));
 
-         if (sk->protect.s2k.mode == 1001)
-           sk->protect.ivlen = 0;
-         else if (sk->protect.s2k.mode == 1002)
-           sk->protect.ivlen = snlen < 16 ? snlen : 16;
+         if (ski->s2k.mode == 1001)
+           ski->ivlen = 0;
+         else if (ski->s2k.mode == 1002)
+           ski->ivlen = snlen < 16 ? snlen : 16;
 
-         if (pktlen < sk->protect.ivlen)
+         if (pktlen < ski->ivlen)
            {
-             rc = G10ERR_INVALID_PACKET;
+              err = gpg_error (GPG_ERR_INV_PACKET);
              goto leave;
            }
-         for (i = 0; i < sk->protect.ivlen && pktlen; i++, pktlen--)
+         for (i = 0; i < ski->ivlen && pktlen; i++, pktlen--)
            temp[i] = iobuf_get_noeof (inp);
          if (list_mode)
            {
              es_fprintf (listfp,
-                      sk->protect.s2k.mode == 1002 ? "\tserial-number: "
-                      : "\tprotect IV: ");
-             for (i = 0; i < sk->protect.ivlen; i++)
+                          ski->s2k.mode == 1002 ? "\tserial-number: "
+                          : "\tprotect IV: ");
+             for (i = 0; i < ski->ivlen; i++)
                es_fprintf (listfp, " %02x", temp[i]);
              es_putc ('\n', listfp);
            }
-         memcpy (sk->protect.iv, temp, sk->protect.ivlen);
+         memcpy (ski->iv, temp, ski->ivlen);
        }
-      else
-       sk->is_protected = 0;
 
       /* It does not make sense to read it into secure memory.
        * If the user is so careless, not to protect his secret key,
        * we can assume, that he operates an open system :=(.
        * So we put the key into secure memory when we unprotect it. */
-      if (sk->protect.s2k.mode == 1001 || sk->protect.s2k.mode == 1002)
+      if (ski->s2k.mode == 1001 || ski->s2k.mode == 1002)
        {
          /* Better set some dummy stuff here.  */
-         sk->skey[npkey] = gcry_mpi_set_opaque (NULL,
+         pk->pkey[npkey] = gcry_mpi_set_opaque (NULL,
                                                 xstrdup ("dummydata"),
                                                 10 * 8);
          pktlen = 0;
        }
-      else if (is_v4 && sk->is_protected)
+      else if (is_v4 && ski->is_protected)
        {
          /* Ugly: The length is encrypted too, so we read all stuff
           * up to the end of the packet into the first SKEY
           * element.  */
-         sk->skey[npkey] = gcry_mpi_set_opaque (NULL,
+         pk->pkey[npkey] = gcry_mpi_set_opaque (NULL,
                                                 read_rest (inp, pktlen, 0),
                                                 pktlen * 8);
          pktlen = 0;
          if (list_mode)
-           {
-             es_fprintf (listfp, "\tencrypted stuff follows\n");
-           }
+            es_fprintf (listfp, "\tskey[%d]: [v4 protected]\n", npkey);
        }
-      else /* The v3 method: The mpi length is not encrypted.  */
+      else 
        {       
+          /* The v3 method: The mpi length is not encrypted.  */
          for (i = npkey; i < nskey; i++)
            {
-             if (sk->is_protected)
+             if (ski->is_protected)
                {
-                 sk->skey[i] = read_protected_v3_mpi (inp, &pktlen);
+                 pk->pkey[i] = read_protected_v3_mpi (inp, &pktlen);
                  if (list_mode)
-                   es_fprintf (listfp, "\tskey[%d]: [encrypted]\n", i);
+                   es_fprintf (listfp, "\tskey[%d]: [v3 protected]\n", i);
                }
              else
                {
                  n = pktlen;
-                 sk->skey[i] = mpi_read (inp, &n, 0);
+                 pk->pkey[i] = mpi_read (inp, &n, 0);
                  pktlen -= n;
                  if (list_mode)
                    {
                      es_fprintf (listfp, "\tskey[%d]: ", i);
-                     mpi_print (listfp, sk->skey[i], mpi_print_mode);
+                     mpi_print (listfp, pk->pkey[i], mpi_print_mode);
                      es_putc ('\n', listfp);
                    }
                }
 
-             if (!sk->skey[i])
-               rc = G10ERR_INVALID_PACKET;
+             if (!pk->pkey[i])
+               err = gpg_error (GPG_ERR_INV_PACKET);
            }
-         if (rc)
+         if (err)
            goto leave;
 
-         sk->csum = read_16 (inp);
+         ski->csum = read_16 (inp);
          pktlen -= 2;
          if (list_mode)
-           {
-             es_fprintf (listfp, "\tchecksum: %04hx\n", sk->csum);
-           }
+            es_fprintf (listfp, "\tchecksum: %04hx\n", ski->csum);
        }
-
-      if (list_mode)
-       keyid_from_sk (sk, keyid);
-    }
-  else
-    {
-      PKT_public_key *pk = pkt->pkt.public_key;
-
-      if (!npkey)
-       {
-         pk->pkey[0] = gcry_mpi_set_opaque (NULL,
-                                            read_rest (inp, pktlen, 0),
-                                            pktlen * 8);
-         pktlen = 0;
-         goto leave;
-       }
-
-      for (i = 0; i < npkey; i++)
-       {
-         n = pktlen;
-         pk->pkey[i] = mpi_read (inp, &n, 0);
-         pktlen -= n;
-         if (list_mode)
-           {
-             es_fprintf (listfp, "\tpkey[%d]: ", i);
-             mpi_print (listfp, pk->pkey[i], mpi_print_mode);
-             es_putc ('\n', listfp);
-           }
-         if (!pk->pkey[i])
-           rc = G10ERR_INVALID_PACKET;
-       }
-      if (rc)
-       goto leave;
-      if (list_mode)
-       keyid_from_pk (pk, keyid);
     }
 
   if (list_mode)
index b934cb3..6056012 100644 (file)
@@ -686,10 +686,10 @@ passphrase_to_dek (u32 *keyid, int pubkey_algo,
 
 
 /* Return an allocated utf-8 string describing the key PK.  IF ESCAPED
-   is true spaces and control characters are percent or plus
-   escaped. */
+   is true spaces and control characters are percent or plus escaped.
+   MODE 0 is for the common prompt, MODE 1 for the import prompt. */
 char *
-gpg_format_keydesc (PKT_public_key *pk, int escaped)
+gpg_format_keydesc (PKT_public_key *pk, int mode, int escaped)
 {
   char *uid;
   size_t uidlen;
@@ -698,6 +698,7 @@ gpg_format_keydesc (PKT_public_key *pk, int escaped)
   char *orig_codeset;
   char *maink;
   char *desc;
+  const char *prompt;
       
   algo_name = gcry_pk_algo_name (pk->pubkey_algo);
   timestr = strtimestamp (pk->timestamp);
@@ -712,11 +713,26 @@ gpg_format_keydesc (PKT_public_key *pk, int escaped)
   else
     maink = NULL;
 
-  desc = xtryasprintf (_("Please enter the passphrase to unlock the"
-                         " secret key for the OpenPGP certificate:\n"
+  switch (mode)
+    {
+    case 0:
+      prompt = _("Please enter the passphrase to unlock the"
+                 " secret key for the OpenPGP certificate:");
+      break;
+    case 1:
+      prompt = _("Please enter the passphrase to import the"
+                 " secret key for the OpenPGP certificate:");
+      break;
+    default:
+      prompt = "?";
+      break;
+    }
+
+  desc = xtryasprintf (_("%s\n"
                          "\"%.*s\"\n"
                          "%u-bit %s key, ID %s,\n"
                          "created %s%s.\n"),
+                       prompt,
                        (int)uidlen, uid,
                        nbits_from_pk (pk), algo_name, 
                        keystr (pk->keyid), timestr,
index d90559d..74bdc76 100644 (file)
@@ -196,7 +196,7 @@ get_it (PKT_pubkey_enc *enc, DEK *dek, PKT_public_key *sk, u32 *keyid)
     goto leave;
 
   /* Decrypt. */
-  desc = gpg_format_keydesc (sk, 1);
+  desc = gpg_format_keydesc (sk, 0, 1);
   err = agent_pkdecrypt (NULL, keygrip, desc, s_data, &frame, &nframe);
   xfree (desc);
   gcry_sexp_release (s_data);
index d5b6a51..eeb4549 100644 (file)
@@ -314,7 +314,7 @@ do_sign (PKT_public_key *pksk, PKT_signature *sig,
           char *desc;
           gcry_sexp_t s_sigval;
           
-          desc = gpg_format_keydesc (pksk, 1);
+          desc = gpg_format_keydesc (pksk, 0, 1);
           err = agent_pksign (NULL/*ctrl*/, cache_nonce, hexgrip, desc, 
                               dp, gcry_md_get_algo_dlen (mdalgo), mdalgo,
                               &s_sigval);