[svn] GnuPG - r5484 - in trunk: . doc g10 scd

svn author wk cvs at cvs.gnupg.org
Wed Nov 17 14:21:26 CET 2010


Author: wk
Date: 2010-11-17 14:21:24 +0100 (Wed, 17 Nov 2010)
New Revision: 5484

Modified:
   trunk/ChangeLog
   trunk/configure.ac
   trunk/doc/DETAILS
   trunk/g10/ChangeLog
   trunk/g10/call-agent.c
   trunk/g10/card-util.c
   trunk/g10/gpg.c
   trunk/g10/keyedit.c
   trunk/g10/keygen.c
   trunk/g10/keylist.c
   trunk/g10/main.h
   trunk/g10/misc.c
   trunk/scd/ChangeLog
   trunk/scd/apdu.c
Log:
Smartcard related updates


Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/ChangeLog	2010-11-17 13:21:24 UTC (rev 5484)
@@ -1,3 +1,7 @@
+2010-11-17  Werner Koch  <wk at g10code.com>
+
+	* configure.ac (ENABLE_CARD_SUPPORT): Define. 
+
 2010-10-27  Werner Koch  <wk at g10code.com>
 
 	* acinclude.m4 (GNUPG_TIME_T_UNSIGNED): New.

Modified: trunk/g10/ChangeLog
===================================================================
--- trunk/g10/ChangeLog	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/ChangeLog	2010-11-17 13:21:24 UTC (rev 5484)
@@ -1,3 +1,24 @@
+2010-11-17  Werner Koch  <wk at g10code.com>
+
+	* keyedit.c (find_pk_from_sknode): Remove.
+	* misc.c (get_signature_count): Call agent.
+	* keygen.c (gen_card_key): Rework.  Remove arg PARA.
+	(generate_keypair): Change arg BACKUP_ENCRYPTION_DIR to the flag
+	CARD_BACKUP_KEY.
+	(pBACKUPENCDIR): Change to pCARDBACKUPKEY.
+	(struct output_control_s): Remove struct SEC.  Remove all usages
+	of it.
+	(gen_card_key_with_backup): Remove arg BACKUP_DIR.
+
+	* call-agent.c (agent_scd_genkey): Remove extra memset.
+
+2010-11-16  Werner Koch  <wk at g10code.com>
+
+	* keygen.c (generate_card_subkeypair): Remove arg SEC_KEYBLOCK and
+	change to return an error code.  Rework for removed secring code.
+	* card-util.c (card_generate_subkey): Remove arg SEC_KEYBLOCK.
+	Return an error code instead of a success flag. Change caller.
+
 2010-10-29  David Shaw  <dshaw at jabberwocky.com>
 
 	* pkclist.c (select_algo_from_prefs): Make sure the scores can't

Modified: trunk/scd/ChangeLog
===================================================================
--- trunk/scd/ChangeLog	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/scd/ChangeLog	2010-11-17 13:21:24 UTC (rev 5484)
@@ -1,3 +1,8 @@
+2010-11-16  Werner Koch  <wk at g10code.com>
+
+	* apdu.c (PCSC_UNKNOWN) [W32]: Fix all these values which don't
+	match those of libpcsc.  Reported by Michael Petig.
+
 2010-10-27  Werner Koch  <wk at g10code.com>
 
 	* scdaemon.c (create_socket_name): Use TMPDIR.  Change callers.

Modified: trunk/configure.ac
===================================================================
--- trunk/configure.ac	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/configure.ac	2010-11-17 13:21:24 UTC (rev 5484)
@@ -485,7 +485,7 @@
 #define HTTP_NO_WSASTARTUP
 
 /* We always include support for the OpenPGP card.  */
-/* Disabled for now ENABLE_CARD_SUPPORT 1 */
+#define ENABLE_CARD_SUPPORT 1
 
 /* We explicitly need to disable PTH's soft mapping as Debian
    currently enables it by default for no reason. */

Modified: trunk/doc/DETAILS
===================================================================
--- trunk/doc/DETAILS	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/doc/DETAILS	2010-11-17 13:21:24 UTC (rev 5484)
@@ -817,7 +817,8 @@
 	The filename is used until a new filename is used (at commit points)
 	and all keys are written to that file.	If a new filename is given,
 	this file is created (and overwrites an existing one).
-	Both control statements must be given.
+        GnuPG < 2.1:  Both control statements must be given.
+        GnuPG >= 2.1: "%secring" is now a no-op.
     %ask-passphrase
         Enable a mode where the command "passphrase" is ignored and
         instead the usual passphrase dialog is used.  This does not

Modified: trunk/g10/call-agent.c
===================================================================
--- trunk/g10/call-agent.c	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/call-agent.c	2010-11-17 13:21:24 UTC (rev 5484)
@@ -771,10 +771,9 @@
 }
 
 /* Send a GENKEY command to the SCdaemon.  SERIALNO is not used in
-   this implementation.  If CREATEDATE has been given, it will be
-   passed to SCDAEMON so that the key can be created with this
-   timestamp; note the user needs to use the returned timestamp as old
-   versions of scddaemon don't support this option.  */
+   this implementation.  If CREATEDATE is not 0, it will be passed to
+   SCDAEMON so that the key is created with this timestamp.  INFO will
+   receive information about the generated key.  */
 int
 agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
                   const char *serialno, u32 createtime)
@@ -794,7 +793,6 @@
   else
     *tbuf = 0;
 
-  memset (info, 0, sizeof *info);
   snprintf (line, DIM(line)-1, "SCD GENKEY %s%s %s %d",
             *tbuf? "--timestamp=":"", tbuf,
             force? "--force":"", 

Modified: trunk/g10/card-util.c
===================================================================
--- trunk/g10/card-util.c	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/card-util.c	2010-11-17 13:21:24 UTC (rev 5484)
@@ -581,29 +581,31 @@
       if ( thefpr && !fpr_is_ff (thefpr) 
            && !get_pubkey_byfprint (pk, thefpr, 20))
         {
-          KBNODE keyblock = NULL;
-
           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) )
-            {
-              release_kbnode (keyblock);
-              keyblock = NULL;
-              
-              if (!auto_create_card_key_stub (info.serialno,
-                                              info.fpr1valid? info.fpr1:NULL,
-                                              info.fpr2valid? info.fpr2:NULL,
-                                              info.fpr3valid? info.fpr3:NULL))
-                {
-                  if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
-                    print_card_key_info (fp, keyblock);
-                }
-            }
-
-          release_kbnode (keyblock);
+          {
+            kbnode_t keyblock = NULL;
+            
+            if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
+              print_card_key_info (fp, keyblock);
+            else if ( !get_keyblock_byfprint (&keyblock, thefpr, 20) )
+              {
+                release_kbnode (keyblock);
+                keyblock = NULL;
+                
+                if (!auto_create_card_key_stub (info.serialno,
+                                                info.fpr1valid? info.fpr1:NULL,
+                                                info.fpr2valid? info.fpr2:NULL,
+                                                info.fpr3valid? info.fpr3:NULL))
+                  {
+                    if ( !get_seckeyblock_byfprint (&keyblock, thefpr, 20) )
+                      print_card_key_info (fp, keyblock);
+                  }
+              }
+            
+            release_kbnode (keyblock);
+          }
 #endif /* GNUPG_MAJOR_VERSION == 1 */
         }
       else
@@ -1431,7 +1433,7 @@
          the serialnumber and thus it won't harm.  */
     }
      
-  generate_keypair (NULL, info.serialno, want_backup? opt.homedir:NULL);
+  generate_keypair (NULL, info.serialno, want_backup);
 
  leave:
   agent_release_card_info (&info);
@@ -1441,17 +1443,18 @@
 
 /* This function is used by the key edit menu to generate an arbitrary
    subkey. */
-int
-card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock)
+gpg_error_t
+card_generate_subkey (KBNODE pub_keyblock)
 {
+  gpg_error_t err;
   struct agent_card_info_s info;
-  int okay = 0;
   int forced_chv1 = 0;
   int keyno;
-
-  if (get_info_for_key_operation (&info))
-    return 0;
-
+  
+  err = get_info_for_key_operation (&info);
+  if (err)
+    return err;
+  
   show_card_key_info (&info);
 
   tty_printf (_("Please select the type of key to generate:\n"));
@@ -1468,6 +1471,7 @@
       if (*answer == CONTROL_D)
         {
           xfree (answer);
+          err = gpg_error (GPG_ERR_CANCELED);
           goto leave;
         }
       keyno = *answer? atoi(answer): 0;
@@ -1476,40 +1480,44 @@
         break; /* Okay. */
       tty_printf(_("Invalid selection.\n"));
     }
-
+  
   if (replace_existing_key_p (&info, keyno))
+    {
+      err = gpg_error (GPG_ERR_CANCELED);
+      goto leave;
+    }
+  
+  err = check_pin_for_key_operation (&info, &forced_chv1);
+  if (err)
     goto leave;
-
-  if (check_pin_for_key_operation (&info, &forced_chv1))
-    goto leave;
-
+  
   /* If the cards features changeable key attributes, we ask for the
      key size.  */
   if (info.is_v2 && info.extcap.aac)
     {
       unsigned int nbits;
-
+      
     ask_again:
       nbits = ask_card_keysize (keyno-1, info.key_attr[keyno-1].nbits);
       if (nbits && do_change_keysize (keyno-1, nbits))
         {
           /* Error: Better read the default key size again.  */
           agent_release_card_info (&info);
-          if (get_info_for_key_operation (&info))
+          err = get_info_for_key_operation (&info);
+          if (err)
             goto leave;
           goto ask_again;
         }
       /* Note that INFO has not be synced.  However we will only use
          the serialnumber and thus it won't harm.  */
     }
-
-  /* xxx = generate_card_subkeypair (pub_keyblock, sec_keyblock, */
-  /*                                  keyno, info.serialno); */
-
+  
+  err = generate_card_subkeypair (pub_keyblock, keyno, info.serialno);
+  
  leave:
   agent_release_card_info (&info);
   restore_forced_chv1 (&forced_chv1);
-  return okay;
+  return err;
 }
 
 
@@ -1520,6 +1528,7 @@
 int 
 card_store_subkey (KBNODE node, int use)
 {
+  log_info ("FIXME: card_store_subkey has not yet been implemented\n");
 /*   struct agent_card_info_s info; */
 /*   int okay = 0; */
 /*   int rc; */

Modified: trunk/g10/gpg.c
===================================================================
--- trunk/g10/gpg.c	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/gpg.c	2010-11-17 13:21:24 UTC (rev 5484)
@@ -3705,12 +3705,12 @@
 	if( opt.batch ) {
 	    if( argc > 1 )
 		wrong_args("--gen-key [parameterfile]");
-	    generate_keypair( argc? *argv : NULL, NULL, NULL );
+	    generate_keypair (argc? *argv : NULL, NULL, 0);
 	}
 	else {
 	    if( argc )
 		wrong_args("--gen-key");
-	    generate_keypair(NULL, NULL, NULL);
+	    generate_keypair (NULL, NULL, 0);
 	}
 	break;
 

Modified: trunk/g10/keyedit.c
===================================================================
--- trunk/g10/keyedit.c	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/keyedit.c	2010-11-17 13:21:24 UTC (rev 5484)
@@ -108,36 +108,7 @@
 };
 
 
-#ifdef ENABLE_CARD_SUPPORT
-/* Given a node SEC_NODE with a secret key or subkey, locate the
-   corresponding public key from pub_keyblock. */
-static PKT_public_key *
-find_pk_from_sknode (KBNODE pub_keyblock, KBNODE sec_node)
-{
-  KBNODE node = pub_keyblock;
-  PKT_secret_key *sk;
-  PKT_public_key *pk;
 
-#warning:  This is not anymore needed.
-  if (sec_node->pkt->pkttype == PKT_SECRET_KEY
-      && node->pkt->pkttype == PKT_PUBLIC_KEY)
-    return node->pkt->pkt.public_key;
-  if (sec_node->pkt->pkttype != PKT_SECRET_SUBKEY)
-    return NULL;
-  sk = sec_node->pkt->pkt.secret_key;
-  for (; node; node = node->next)
-    if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
-      {
-	pk = node->pkt->pkt.public_key;
-	if (pk->keyid[0] == sk->keyid[0] && pk->keyid[1] == sk->keyid[1])
-	  return pk;
-      }
-
-  return NULL;
-}
-#endif /* ENABLE_CARD_SUPPORT */
-
-
 /* TODO: Fix duplicated code between here and the check-sigs/list-sigs
    code in keylist.c. */
 static int
@@ -1833,7 +1804,7 @@
 
 #ifdef ENABLE_CARD_SUPPORT
 	case cmdADDCARDKEY:
-	  if (card_generate_subkey (keyblock))
+	  if (!card_generate_subkey (keyblock))
 	    {
 	      redisplay = 1;
 	      modified = 1;
@@ -1868,7 +1839,7 @@
 	      }
 	    if (node)
 	      {
-		PKT_public_key *xxpk = find_pk_from_sknode (keyblock, node);
+		PKT_public_key *xxpk = node->pkt->pkt.public_key;
 		if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
 		  {
 		    redisplay = 1;
@@ -1934,25 +1905,25 @@
 
 	    if (cmd == cmdCHECKBKUPKEY)
 	      {
-		PKT_secret_key *sk = node->pkt->pkt.secret_key;
-		switch (is_secret_key_protected (sk))
-		  {
-		  case 0:	/* Not protected. */
-		    tty_printf (_("This key is not protected.\n"));
-		    break;
-		  case -1:
-		    log_error (_("unknown key protection algorithm\n"));
-		    break;
-		  default:
-		    if (sk->protect.s2k.mode == 1001)
-		      tty_printf (_("Secret parts of key"
-				    " are not available.\n"));
-		    if (sk->protect.s2k.mode == 1002)
-		      tty_printf (_("Secret parts of key"
-				    " are stored on-card.\n"));
+		/* PKT_public_key *sk = node->pkt->pkt.secret_key; */
+		/* switch (is_secret_key_protected (sk)) */
+		/*   { */
+		/*   case 0:	/\* Not protected. *\/ */
+		/*     tty_printf (_("This key is not protected.\n")); */
+		/*     break; */
+		/*   case -1: */
+		/*     log_error (_("unknown key protection algorithm\n")); */
+		/*     break; */
+		/*   default: */
+		/*     if (sk->protect.s2k.mode == 1001) */
+		/*       tty_printf (_("Secret parts of key" */
+		/* 		    " are not available.\n")); */
+		/*     if (sk->protect.s2k.mode == 1002) */
+		/*       tty_printf (_("Secret parts of key" */
+		/* 		    " are stored on-card.\n")); */
 		    /* else */
 		    /*   check_secret_key (sk, 0); */
-		  }
+		  /* } */
 	      }
 	    else		/* Store it.  */
 	      {

Modified: trunk/g10/keygen.c
===================================================================
--- trunk/g10/keygen.c	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/keygen.c	2010-11-17 13:21:24 UTC (rev 5484)
@@ -78,7 +78,7 @@
   pPASSPHRASE_DEK,
   pPASSPHRASE_S2K,
   pSERIALNO,
-  pBACKUPENCDIR,
+  pCARDBACKUPKEY,
   pHANDLE,
   pKEYSERVER
 };
@@ -98,24 +98,19 @@
     } u;
 };
 
-struct output_control_s {
-    int lnr;
-    int dryrun;
-    int ask_passphrase;
-    unsigned int keygen_flags;
-    int use_files;
-    struct {
-	char  *fname;
-	char  *newfname;
-	IOBUF stream;
-	armor_filter_context_t *afx;
-    } pub;
-    struct {
-	char  *fname;
-	char  *newfname;
-	IOBUF stream;
-	armor_filter_context_t *afx;
-    } sec;
+struct output_control_s
+{
+  int lnr;
+  int dryrun;
+  int ask_passphrase;
+  unsigned int keygen_flags;
+  int use_files;
+  struct {
+    char  *fname;
+    char  *newfname;
+    IOBUF stream;
+    armor_filter_context_t *afx;
+  } pub;
 };
 
 
@@ -137,13 +132,12 @@
 static void do_generate_keypair( struct para_data_s *para,
 				 struct output_control_s *outctrl, int card );
 static int write_keyblock (iobuf_t out, kbnode_t node);
-static int gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root,
-                         u32 *timestamp, u32 expireval,
-                         struct para_data_s *para);
+static gpg_error_t gen_card_key (int algo, int keyno, int is_primary,
+                                 kbnode_t pub_root,
+                                 u32 *timestamp, u32 expireval);
 static int gen_card_key_with_backup (int algo, int keyno, int is_primary,
                                      kbnode_t pub_root, u32 timestamp,
-                                     u32 expireval, struct para_data_s *para,
-                                     const char *backup_dir);
+                                     u32 expireval, struct para_data_s *para);
 
 
 static void
@@ -2217,18 +2211,19 @@
 
 
 static void
-release_parameter_list( struct para_data_s *r )
+release_parameter_list (struct para_data_s *r)
 {
-    struct para_data_s *r2;
-
-    for( ; r ; r = r2 ) {
-	r2 = r->next;
-	if( r->key == pPASSPHRASE_DEK )
-	    xfree( r->u.dek );
-	else if( r->key == pPASSPHRASE_S2K )
-	    xfree( r->u.s2k );
-
-	xfree(r);
+  struct para_data_s *r2;
+  
+  for (; r ; r = r2)
+    {
+      r2 = r->next;
+      if (r->key == pPASSPHRASE_DEK)
+        xfree (r->u.dek);
+      else if (r->key == pPASSPHRASE_S2K )
+        xfree (r->u.s2k);
+      
+      xfree (r);
     }
 }
 
@@ -2657,11 +2652,6 @@
       para = r;
     }
 
-  if( !!outctrl->pub.newfname ^ !!outctrl->sec.newfname ) {
-    log_error("%s:%d: only one ring name is set\n", fname, outctrl->lnr );
-    return -1;
-  }
-
   do_generate_keypair( para, outctrl, card );
   return 0;
 }
@@ -2708,7 +2698,6 @@
 
     memset( &outctrl, 0, sizeof( outctrl ) );
     outctrl.pub.afx = new_armor_context ();
-    outctrl.sec.afx = new_armor_context ();
 
     if( !fname || !*fname)
       fname = "-";
@@ -2783,13 +2772,7 @@
 		}
 	    }
 	    else if( !ascii_strcasecmp( keyword, "%secring" ) ) {
-		if( outctrl.sec.fname && !strcmp( outctrl.sec.fname, value ) )
-		    ; /* still the same file - ignore it */
-		else {
-		   xfree( outctrl.sec.newfname );
-		   outctrl.sec.newfname = xstrdup( value );
-		   outctrl.use_files = 1;
-		}
+              /* Ignore this command.  */
 	    }
 	    else
 		log_info("skipping control `%s' (%s)\n", keyword, value );
@@ -2865,40 +2848,32 @@
 
     if( outctrl.use_files ) { /* close open streams */
 	iobuf_close( outctrl.pub.stream );
-	iobuf_close( outctrl.sec.stream );
 
         /* Must invalidate that ugly cache to actually close it.  */
         if (outctrl.pub.fname)
           iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 
                        0, (char*)outctrl.pub.fname);
-        if (outctrl.sec.fname)
-          iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE,
-                       0, (char*)outctrl.sec.fname);
 
 	xfree( outctrl.pub.fname );
 	xfree( outctrl.pub.newfname );
-	xfree( outctrl.sec.fname );
-	xfree( outctrl.sec.newfname );
     }
 
     release_parameter_list( para );
     iobuf_close (fp);
     release_armor_context (outctrl.pub.afx);
-    release_armor_context (outctrl.sec.afx);
 }
 
 
 /*
  * Generate a keypair (fname is only used in batch mode) If
  * CARD_SERIALNO is not NULL the function will create the keys on an
- * OpenPGP Card.  If BACKUP_ENCRYPTION_DIR has been set and
- * CARD_SERIALNO is NOT NULL, the encryption key for the card gets
- * generate in software, imported to the card and a backup file
- * written to directory given by this argument .
+ * OpenPGP Card.  If CARD_BACKUP_KEY has been set and CARD_SERIALNO is
+ * NOT NULL, the encryption key for the card is generated on the host,
+ * imported to the card and a backup file created by gpg-agent.
  */
 void
 generate_keypair (const char *fname, const char *card_serialno, 
-                  const char *backup_encryption_dir)
+                  int card_backup_key)
 {
   unsigned int nbits;
   char *uid = NULL;
@@ -2964,11 +2939,11 @@
       r->next = para;
       para = r;
 
-      if (backup_encryption_dir)
+      if (card_backup_key)
         {
-          r = xcalloc (1, sizeof *r + strlen (backup_encryption_dir) );
-          r->key = pBACKUPENCDIR;
-          strcpy (r->u.value, backup_encryption_dir);
+          r = xcalloc (1, sizeof *r + 1);
+          r->key = pCARDBACKUPKEY;
+          strcpy (r->u.value, "1");
           r->next = para;
           para = r;
         }
@@ -3071,7 +3046,7 @@
 }
 
 
-#ifdef ENABLE_CARD_SUPPORT
+#if 0 /* not required */
 /* Generate a raw key and return it as a secret key packet.  The
    function will ask for the passphrase and return a protected as well
    as an unprotected copy of a new secret key packet.  0 is returned
@@ -3270,7 +3245,7 @@
   else
     err = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root,
                         &timestamp,
-                        get_parameter_u32 (para, pKEYEXPIRE), para);
+                        get_parameter_u32 (para, pKEYEXPIRE));
 
   /* Get the pointer to the generated public key packet.  */
   if (!err)
@@ -3301,7 +3276,7 @@
     {
       err = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root,
                           &timestamp,
-                          get_parameter_u32 (para, pKEYEXPIRE), para);
+                          get_parameter_u32 (para, pKEYEXPIRE));
       if (!err)
         err = write_keybinding (pub_root, pri_psk, NULL,
                                 PUBKEY_USAGE_AUTH, timestamp, cache_nonce);
@@ -3331,23 +3306,20 @@
         }
       else
         {
-          if ((s = get_parameter_value (para, pBACKUPENCDIR)))
+          if ((s = get_parameter_value (para, pCARDBACKUPKEY)))
             {
               /* A backup of the encryption key has been requested.
                  Generate the key in software and import it then to
                  the card.  Write a backup file. */
-              err = gen_card_key_with_backup (PUBKEY_ALGO_RSA, 2, 0,
-                                              pub_root,
-                                              timestamp,
-                                              get_parameter_u32 (para,
-                                                                 pKEYEXPIRE),
-                                              para, s);
+              err = gen_card_key_with_backup
+                (PUBKEY_ALGO_RSA, 2, 0, pub_root, timestamp,
+                 get_parameter_u32 (para, pKEYEXPIRE), para);
             }
           else
             {
               err = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root,
                                   &timestamp,
-                                  get_parameter_u32 (para, pKEYEXPIRE), para);
+                                  get_parameter_u32 (para, pKEYEXPIRE));
             }
         }
 
@@ -3551,81 +3523,65 @@
 
 #ifdef ENABLE_CARD_SUPPORT
 /* Generate a subkey on a card. */
-int
-generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
+gpg_error_t
+generate_card_subkeypair (kbnode_t pub_keyblock,
                           int keyno, const char *serialno)
 {
   gpg_error_t err = 0;
-  int okay = 0;
   kbnode_t node;
-  PKT_secret_key *pri_sk = NULL, *sub_sk;
+  PKT_public_key *pri_pk = NULL;
   int algo;
   unsigned int use;
   u32 expire;
-  char *passphrase = NULL;
   u32 cur_time;
   struct para_data_s *para = NULL;
 
   assert (keyno >= 1 && keyno <= 3);
 
-  para = xcalloc (1, sizeof *para + strlen (serialno) );
+  para = xtrycalloc (1, sizeof *para + strlen (serialno) );
+  if (!para)
+    {
+      err = gpg_error_from_syserror ();
+      goto leave;
+    }
   para->key = pSERIALNO;
   strcpy (para->u.value, serialno);
 
   /* Break out the primary secret key */
-  node = find_kbnode (sec_keyblock, PKT_SECRET_KEY);
+  node = find_kbnode (pub_keyblock, PKT_PUBLIC_KEY);
   if (!node)
     {
-      log_error("Oops; secret key not found anymore!\n");
+      log_error ("Oops; publkic key lost!\n");
+      err = gpg_error (GPG_ERR_INTERNAL);
       goto leave;
     }
+  pri_pk = node->pkt->pkt.public_key;
 
-  /* Make a copy of the sk to keep the protected one in the keyblock */
-  pri_sk = copy_secret_key (NULL, node->pkt->pkt.secret_key);
-
   cur_time = make_timestamp();
-  if (pri_sk->timestamp > cur_time)
+  if (pri_pk->timestamp > cur_time)
     {
-      ulong d = pri_sk->timestamp - cur_time;
+      ulong d = pri_pk->timestamp - cur_time;
       log_info (d==1 ? _("key has been created %lu second "
                          "in future (time warp or clock problem)\n")
                      : _("key has been created %lu seconds "
                          "in future (time warp or clock problem)\n"), d );
 	if (!opt.ignore_time_conflict)
           {
-	    err = G10ERR_TIME_CONFLICT;
+	    err = gpg_error (GPG_ERR_TIME_CONFLICT);
 	    goto leave;
           }
     }
 
-  if (pri_sk->version < 4)
+  if (pri_pk->version < 4)
     {
       log_info (_("NOTE: creating subkeys for v3 keys "
                   "is not OpenPGP compliant\n"));
+      err = gpg_error (GPG_ERR_NOT_SUPPORTED);
       goto leave;
     }
 
-  /* Unprotect to get the passphrase. */
-  switch( is_secret_key_protected (pri_sk) )
-    {
-    case -1:
-      err = G10ERR_PUBKEY_ALGO;
-      break;
-    case 0:
-      tty_printf("This key is not protected.\n");
-      break;
-    default:
-      tty_printf("Key is protected.\n");
-      err = check_secret_key( pri_sk, 0 );
-      if (!err)
-        passphrase = get_last_passphrase();
-      break;
-    }
-  if (err)
-    goto leave;
-
   algo = PUBKEY_ALGO_RSA;
-  expire = ask_expire_interval (0,NULL);
+  expire = ask_expire_interval (0, NULL);
   if (keyno == 1)
     use = PUBKEY_USAGE_SIG;
   else if (keyno == 2)
@@ -3634,40 +3590,37 @@
     use = PUBKEY_USAGE_AUTH;
   if (!cpr_enabled() && !cpr_get_answer_is_yes("keygen.cardsub.okay",
                                                _("Really create? (y/N) ")))
-    goto leave;
+    {
+      err = gpg_error (GPG_ERR_CANCELED);
+      goto leave;
+    }
 
-  if (passphrase)
-    set_next_passphrase (passphrase);
-
   /* Note, that depending on the backend, the card key generation may
      update CUR_TIME.  */
-  err = gen_card_key (algo, keyno, 0, pub_keyblock, &cur_time, expire, para);
+  err = gen_card_key (algo, keyno, 0, pub_keyblock, &cur_time, expire);
+  /* Get the pointer to the generated public subkey packet.  */
   if (!err)
-    err = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, 
-                            use, cur_time);
-  if (!err)
-    err = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk, 
-                           use, cur_time);
-  if (!err)
     {
-      okay = 1;
-      write_status_text (STATUS_KEY_CREATED, "S");
+      PKT_public_key *sub_pk = NULL;
+      
+      for (node = pub_keyblock; node; node = node->next)
+        if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
+          sub_pk = node->pkt->pkt.public_key;
+      assert (sub_pk);
+      err = write_keybinding (pub_keyblock, pri_pk, sub_pk,
+                              use, cur_time, NULL);
     }
 
  leave:
   if (err)
     log_error (_("Key generation failed: %s\n"), g10_errstr(err) );
-  xfree (passphrase);
-  /* Release the copy of the (now unprotected) secret keys. */
-  if (pri_sk)
-    free_secret_key (pri_sk);
-  set_next_passphrase( NULL );
+  else
+    write_status_text (STATUS_KEY_CREATED, "S");
   release_parameter_list (para);
-  return okay;
+  return err;
 }
 #endif /* !ENABLE_CARD_SUPPORT */
 
-
 /*
  * Write a keyblock to an output stream
  */
@@ -3693,84 +3646,74 @@
 
 
 /* Note that timestamp is an in/out arg. */
-static int
-gen_card_key (int algo, int keyno, int is_primary, KBNODE pub_root, 
-              u32 *timestamp, u32 expireval, struct para_data_s *para)
+static gpg_error_t
+gen_card_key (int algo, int keyno, int is_primary, kbnode_t pub_root, 
+              u32 *timestamp, u32 expireval)
 {
 #ifdef ENABLE_CARD_SUPPORT
-  int rc;
-  const char *s;
+  gpg_error_t err;
   struct agent_card_genkey_s info;
   PACKET *pkt;
-  PKT_secret_key *sk;
   PKT_public_key *pk;
 
-  assert (algo == PUBKEY_ALGO_RSA);
-  
-  /* Fixme: We don't have the serialnumber available, thus passing NULL. */
-  rc = agent_scd_genkey (&info, keyno, 1, NULL, *timestamp);
-/*    if (gpg_err_code (rc) == GPG_ERR_EEXIST) */
-/*      { */
-/*        tty_printf ("\n"); */
-/*        log_error ("WARNING: key does already exists!\n"); */
-/*        tty_printf ("\n"); */
-/*        if ( cpr_get_answer_is_yes( "keygen.card.replace_key", */
-/*                                    _("Replace existing key? "))) */
-/*          rc = agent_scd_genkey (&info, keyno, 1); */
-/*      } */
+  if (algo != PUBKEY_ALGO_RSA)
+    return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
-  if (rc)
+  pk = xtrycalloc (1, sizeof *pk );
+  if (!pk)
+    return gpg_error_from_syserror ();
+  pkt = xtrycalloc (1, sizeof *pkt);
+  if (!pkt)
     {
-      log_error ("key generation failed: %s\n", gpg_strerror (rc));
-      return rc;
+      xfree (pk);
+      return gpg_error_from_syserror ();
     }
-  if ( !info.n || !info.e )
+  
+  /* Note: SCD knows the serialnumber, thus there is no point in passing it.  */
+  err = agent_scd_genkey (&info, keyno, 1, NULL, *timestamp);
+  /*  The code below is not used because we force creation of 
+   *  the a card key (3rd arg). 
+   * if (gpg_err_code (rc) == GPG_ERR_EEXIST)
+   *   {
+   *     tty_printf ("\n");
+   *     log_error ("WARNING: key does already exists!\n");
+   *     tty_printf ("\n");
+   *     if ( cpr_get_answer_is_yes( "keygen.card.replace_key",
+   *                                 _("Replace existing key? ")))
+   *       rc = agent_scd_genkey (&info, keyno, 1);
+   *   }
+  */
+  if (!err && (!info.n || !info.e))
     {
       log_error ("communication error with SCD\n");
       gcry_mpi_release (info.n);
       gcry_mpi_release (info.e);
-      return gpg_error (GPG_ERR_GENERAL);
+      err =  gpg_error (GPG_ERR_GENERAL);
     }
+  if (err)
+    {
+      log_error ("key generation failed: %s\n", gpg_strerror (err));
+      xfree (pkt);
+      xfree (pk);
+      return err;
+    }
   
   if (*timestamp != info.created_at)
-    log_info ("Note that the key does not use the suggested creation date\n");
+    log_info ("NOTE: the key does not use the suggested creation date\n");
   *timestamp = info.created_at;
 
-  pk = xcalloc (1, sizeof *pk );
-  sk = xcalloc (1, sizeof *sk );
-  sk->timestamp = pk->timestamp = info.created_at;
-  sk->version = pk->version = 4;
+  pk->timestamp = info.created_at;
+  pk->version = 4;
   if (expireval)
-      sk->expiredate = pk->expiredate = pk->timestamp + expireval;
-  sk->pubkey_algo = pk->pubkey_algo = algo;
+    pk->expiredate = pk->timestamp + expireval;
+  pk->pubkey_algo = algo;
   pk->pkey[0] = info.n;
   pk->pkey[1] = info.e; 
-  sk->skey[0] = gcry_mpi_copy (pk->pkey[0]);
-  sk->skey[1] = gcry_mpi_copy (pk->pkey[1]);
-  sk->skey[2] = gcry_mpi_set_opaque (NULL, xstrdup ("dummydata"), 10*8);
-  sk->is_protected = 1;
-  sk->protect.s2k.mode = 1002;
-  s = get_parameter_value (para, pSERIALNO);
-  if (s)
-    {
-      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);
-    }
 
-  if( ret_sk )
-    *ret_sk = sk;
-
-  pkt = xcalloc (1,sizeof *pkt);
   pkt->pkttype = is_primary ? PKT_PUBLIC_KEY : PKT_PUBLIC_SUBKEY;
   pkt->pkt.public_key = pk;
-  add_kbnode(pub_root, new_kbnode( pkt ));
+  add_kbnode (pub_root, new_kbnode (pkt));
 
-  pkt = xcalloc (1,sizeof *pkt);
-  pkt->pkttype = is_primary ? PKT_SECRET_KEY : PKT_SECRET_SUBKEY;
-  pkt->pkt.secret_key = sk;
-  add_kbnode(sec_root, new_kbnode( pkt ));
-
   return 0;
 #else
   return gpg_error (GPG_ERR_NOT_SUPPORTED);
@@ -3782,10 +3725,9 @@
 static int
 gen_card_key_with_backup (int algo, int keyno, int is_primary,
                           KBNODE pub_root, u32 timestamp,
-                          u32 expireval, struct para_data_s *para,
-                          const char *backup_dir)
+                          u32 expireval, struct para_data_s *para)
 {
-#ifdef ENABLE_CARD_SUPPORT
+#if 0 /* FIXME: Move this to gpg-agent.  */
   int rc;
   const char *s;
   PACKET *pkt;
@@ -3947,9 +3889,9 @@
 }
 
 
-#ifdef ENABLE_CARD_SUPPORT
+#if 0
 int
-save_unprotected_key_to_card (PKT_secret_key *sk, int keyno)
+save_unprotected_key_to_card (PKT_public_key *sk, int keyno)
 {
   int rc;
   unsigned char *rsa_n = NULL;

Modified: trunk/g10/keylist.c
===================================================================
--- trunk/g10/keylist.c	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/keylist.c	2010-11-17 13:21:24 UTC (rev 5484)
@@ -182,8 +182,7 @@
 {
   /* KBNODE node; */
   /* int i; */
-
-  log_debug ("Fixme: Needs to be adjusted to gpg-agent\n");
+#warning Fixme: Needs to be adjusted to gpg-agent
   /* for (node = keyblock; node; node = node->next) */
   /*   { */
   /*     if (node->pkt->pkttype == PKT_SECRET_KEY */

Modified: trunk/g10/main.h
===================================================================
--- trunk/g10/main.h	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/main.h	2010-11-17 13:21:24 UTC (rev 5484)
@@ -231,8 +231,8 @@
 u32 parse_expire_string(const char *string);
 u32 ask_expire_interval(int object,const char *def_expire);
 u32 ask_expiredate(void);
-void generate_keypair( const char *fname, const char *card_serialno,
-                       const char *backup_encryption_dir );
+void generate_keypair (const char *fname, const char *card_serialno,
+                       int card_backup_key);
 int keygen_set_std_prefs (const char *string,int personal);
 PKT_user_id *keygen_get_std_prefs (void);
 int keygen_add_key_expire( PKT_signature *sig, void *opaque );
@@ -246,9 +246,9 @@
                           u32 timestamp, const char *cache_nonce);
 gpg_error_t generate_subkeypair (kbnode_t pub_keyblock);
 #ifdef ENABLE_CARD_SUPPORT
-int generate_card_subkeypair (KBNODE pub_keyblock, KBNODE sec_keyblock,
-                              int keyno, const char *serialno);
-int save_unprotected_key_to_card (PKT_secret_key *sk, int keyno);
+gpg_error_t generate_card_subkeypair (kbnode_t pub_keyblock,
+                                      int keyno, const char *serialno);
+int save_unprotected_key_to_card (PKT_public_key *sk, int keyno);
 #endif
 
 /*-- openfile.c --*/
@@ -348,7 +348,7 @@
 void change_pin (int no, int allow_admin);
 void card_status (estream_t fp, char *serialno, size_t serialnobuflen);
 void card_edit (ctrl_t ctrl, strlist_t commands);
-int  card_generate_subkey (KBNODE pub_keyblock, KBNODE sec_keyblock);
+gpg_error_t  card_generate_subkey (KBNODE pub_keyblock);
 int  card_store_subkey (KBNODE node, int use);
 #endif
 

Modified: trunk/g10/misc.c
===================================================================
--- trunk/g10/misc.c	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/g10/misc.c	2010-11-17 13:21:24 UTC (rev 5484)
@@ -548,13 +548,12 @@
 get_signature_count (PKT_public_key *pk)
 {
 #ifdef ENABLE_CARD_SUPPORT
-  /* FIXME: Need to call the agent.  */
-  /* if(sk && sk->is_protected && sk->protect.s2k.mode==1002) */
-  /*   { */
-  /*     struct agent_card_info_s info; */
-  /*     if(agent_scd_getattr("SIG-COUNTER",&info)==0) */
-  /*       return info.sig_counter; */
-  /*   }   */
+  struct agent_card_info_s info;
+#warning fixme: We should check that the correct card has been inserted
+  if (!agent_scd_getattr ("SIG-COUNTER",&info))
+    return info.sig_counter;
+  else
+    return 0;
 #else
   (void)pk;
   return 0;

Modified: trunk/scd/apdu.c
===================================================================
--- trunk/scd/apdu.c	2010-11-16 10:38:13 UTC (rev 5483)
+++ trunk/scd/apdu.c	2010-11-17 13:21:24 UTC (rev 5484)
@@ -1,5 +1,5 @@
 /* apdu.c - ISO 7816 APDU functions and low level I/O
- * Copyright (C) 2003, 2004, 2008, 2009 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2004, 2008, 2009, 2010 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -165,7 +165,11 @@
 
 #define PCSC_PROTOCOL_T0     1
 #define PCSC_PROTOCOL_T1     2
-#define PCSC_PROTOCOL_RAW    4
+#ifdef HAVE_W32_SYSTEM
+# define PCSC_PROTOCOL_RAW   0x00010000  /* The active protocol.  */
+#else
+# define PCSC_PROTOCOL_RAW   4
+#endif
 
 #define PCSC_SHARE_EXCLUSIVE 1
 #define PCSC_SHARE_SHARED    2
@@ -176,13 +180,23 @@
 #define PCSC_UNPOWER_CARD    2
 #define PCSC_EJECT_CARD      3
 
-#define PCSC_UNKNOWN    0x0001
-#define PCSC_ABSENT     0x0002  /* Card is absent.  */
-#define PCSC_PRESENT    0x0004  /* Card is present.  */
-#define PCSC_SWALLOWED  0x0008  /* Card is present and electrical connected. */
-#define PCSC_POWERED    0x0010  /* Card is powered.  */
-#define PCSC_NEGOTIABLE 0x0020  /* Card is awaiting PTS.  */
-#define PCSC_SPECIFIC   0x0040  /* Card is ready for use.  */
+#ifdef HAVE_W32_SYSTEM
+# define PCSC_UNKNOWN    0x0000  /* The driver is not aware of the status.  */
+# define PCSC_ABSENT     0x0001  /* Card is absent.  */
+# define PCSC_PRESENT    0x0002  /* Card is present.  */
+# define PCSC_SWALLOWED  0x0003  /* Card is present and electrical connected. */
+# define PCSC_POWERED    0x0004  /* Card is powered.  */
+# define PCSC_NEGOTIABLE 0x0005  /* Card is awaiting PTS.  */
+# define PCSC_SPECIFIC   0x0006  /* Card is ready for use.  */
+#else
+# define PCSC_UNKNOWN    0x0001
+# define PCSC_ABSENT     0x0002  /* Card is absent.  */
+# define PCSC_PRESENT    0x0004  /* Card is present.  */
+# define PCSC_SWALLOWED  0x0008  /* Card is present and electrical connected. */
+# define PCSC_POWERED    0x0010  /* Card is powered.  */
+# define PCSC_NEGOTIABLE 0x0020  /* Card is awaiting PTS.  */
+# define PCSC_SPECIFIC   0x0040  /* Card is ready for use.  */
+#endif
 
 #define PCSC_STATE_UNAWARE     0x0000  /* Want status.  */
 #define PCSC_STATE_IGNORE      0x0001  /* Ignore this reader.  */
@@ -195,6 +209,9 @@
 #define PCSC_STATE_EXCLUSIVE   0x0080  /* Exclusive Mode.  */
 #define PCSC_STATE_INUSE       0x0100  /* Shared mode.  */
 #define PCSC_STATE_MUTE	       0x0200  /* Unresponsive card.  */
+#ifdef HAVE_W32_SYSTEM
+# define PCSC_STATE_UNPOWERED  0x0400  /* Card not powerred up.  */
+#endif
 
 /* Some PC/SC error codes.  */
 #define PCSC_E_CANCELLED               0x80100002





More information about the Gnupg-commits mailing list