[svn] GnuPG - r4176 - branches/GNUPG-1-9-BRANCH/g10

svn author wk cvs at cvs.gnupg.org
Tue Jun 27 16:31:02 CEST 2006


Author: wk
Date: 2006-06-27 16:30:59 +0200 (Tue, 27 Jun 2006)
New Revision: 4176

Modified:
   branches/GNUPG-1-9-BRANCH/g10/ChangeLog
   branches/GNUPG-1-9-BRANCH/g10/build-packet.c
   branches/GNUPG-1-9-BRANCH/g10/exec.c
   branches/GNUPG-1-9-BRANCH/g10/getkey.c
   branches/GNUPG-1-9-BRANCH/g10/gpg.c
   branches/GNUPG-1-9-BRANCH/g10/import.c
   branches/GNUPG-1-9-BRANCH/g10/keygen.c
   branches/GNUPG-1-9-BRANCH/g10/options.h
   branches/GNUPG-1-9-BRANCH/g10/parse-packet.c
   branches/GNUPG-1-9-BRANCH/g10/sign.c
Log:
Ported patches from 1.4.x 


Modified: branches/GNUPG-1-9-BRANCH/g10/ChangeLog
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/ChangeLog	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/ChangeLog	2006-06-27 14:30:59 UTC (rev 4176)
@@ -1,3 +1,63 @@
+2006-06-27  Werner Koch  <wk at g10code.com>
+
+	Applied patches from 1.4.x (2006-05-22 to 2006-06-23) from David:
+
+	* keygen.c (keygen_upd_std_prefs, keygen_add_std_prefs)
+	(proc_parameter_file): Add --default-keyserver-url to specify a
+	keyserver URL at key generation time, and "Keyserver:" keyword for
+	doing the same through a batch file.
+	* options.h, gpg.c (main): Ditto.
+
+	* sign.c (do_sign): For now don't accept a truncated hash even
+	for DSA1 keys (be liberal in what you accept, etc).
+
+	* import.c (import_one): Add a flag (from_sk) so we don't check
+	prefs on an autoconverted public key.  The check should only
+	happen on the sk side.  Noted by Dirk Traulsen.
+
+	* keygen.c (gen_card_key): Add optional argument to return a
+	pointer (not a copy) of the stub secret key for the secret key we
+	just generated on the card.
+	(generate_card_subkeypair): Use it here so that the signing key on
+	the card can use the card to generate the 0x19 backsig on the
+	primary key.  Noted by Janko Heilgeist and Jonas Oberg.
+
+	* parse-packet.c (parse_user_id): Cap the user ID size at 2048
+	bytes.  This prevents a memory allocation attack with a very large
+	user ID.  A very large packet length could even cause the
+	allocation (a u32) to wrap around to a small number.  Noted by
+	Evgeny Legerov on full-disclosure.
+
+	* keygen.c (gen_dsa): Allow generating DSA2 keys.  Allow
+	specifying sizes > 1024 when --enable-dsa2 is set.  The size of q
+	is set automatically based on the key size.
+	(ask_keysize, generate_keypair): Ask for DSA size when
+	--enable-dsa2 is set.
+
+	* exec.c (make_tempdir) [W32]: Fix bug with a temporary directory
+	on W32 that is over 256 bytes long.  Noted by Israel G. Lugo.
+
+	* gpg.c (reopen_std): New function to reopen fd 0, 1, or 2 if we
+	are called with them closed.  This is to protect our
+	keyring/trustdb files from corruption if they get attached to one
+	of the standard fds.  Print a warning if possible that this has
+	happened, and fail completely if we cannot reopen (should never
+	happen).
+	(main): Call it here.
+	
+	* parse-packet.c (dump_sig_subpkt, parse_signature): Fix meaning
+	of key expiration and sig expiration subpackets - zero means
+	"never expire" according to 2440, not "expire instantly".
+	* build-packet.c (build_sig_subpkt_from_sig): Ditto.
+	* getkey.c (fixup_uidnode, merge_selfsigs_main)
+	(merge_selfsigs_subkey): Ditto.
+	* keygen.c (keygen_add_key_expire): Ditto.
+
+	* getkey.c (get_pubkey_byname)
+	* import.c (import_one): Fix key selection problem when
+	auto-key-locate returns a list of keys, not all of which are
+	usable (revoked, expired, etc).  Noted by Simon Josefsson.
+
 2006-05-24  Werner Koch  <wk at g10code.com>
 
 	* keyid.c (hash_public_key): Do not double hash the length bytes,

Modified: branches/GNUPG-1-9-BRANCH/g10/build-packet.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/build-packet.c	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/build-packet.c	2006-06-27 14:30:59 UTC (rev 4176)
@@ -841,7 +841,8 @@
 	if(sig->expiredate>sig->timestamp)
 	  u=sig->expiredate-sig->timestamp;
 	else
-	  u=0;
+	  u=1; /* A 1-second expiration time is the shortest one
+		  OpenPGP has */
 
 	buf[0] = (u >> 24) & 0xff;
 	buf[1] = (u >> 16) & 0xff;

Modified: branches/GNUPG-1-9-BRANCH/g10/exec.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/exec.c	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/exec.c	2006-06-27 14:30:59 UTC (rev 4176)
@@ -127,8 +127,11 @@
   if(tmp==NULL)
     {
 #if defined (_WIN32)
-      tmp=xmalloc(256);
-      if(GetTempPath(256,tmp)==0)
+      int err;
+
+      tmp=xmalloc(MAX_PATH+2);
+      err=GetTempPath(MAX_PATH+1,tmp);
+      if(err==0 || err>MAX_PATH+1)
 	strcpy(tmp,"c:\\windows\\temp");
       else
 	{

Modified: branches/GNUPG-1-9-BRANCH/g10/getkey.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/getkey.c	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/getkey.c	2006-06-27 14:30:59 UTC (rev 4176)
@@ -935,7 +935,7 @@
 
       for(akl=opt.auto_key_locate;akl;akl=akl->next)
 	{
-	  unsigned char *fpr;
+	  unsigned char *fpr=NULL;
 	  size_t fpr_len;
 
 	  switch(akl->type)
@@ -1507,12 +1507,12 @@
     /* store the key flags in the helper variable for later processing */
     uid->help_key_usage=parse_key_usage(sig);
 
-    /* ditto or the key expiration */
-    uid->help_key_expire = 0;
+    /* ditto for the key expiration */
     p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
-    if ( p ) { 
-        uid->help_key_expire = keycreated + buffer_to_u32(p);
-    }
+    if( p && buffer_to_u32(p) )
+      uid->help_key_expire = keycreated + buffer_to_u32(p);
+    else
+      uid->help_key_expire = 0;
 
     /* Set the primary user ID flag - we will later wipe out some
      * of them to only have one in our keyblock */
@@ -1724,7 +1724,7 @@
 	key_usage=parse_key_usage(sig);
 
 	p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
-	if ( p )
+	if( p && buffer_to_u32(p) )
 	  {
 	    key_expire = keytimestamp + buffer_to_u32(p);
 	    key_expire_seen = 1;
@@ -2128,7 +2128,7 @@
     subpk->pubkey_usage = key_usage;
     
     p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
-    if ( p ) 
+    if ( p && buffer_to_u32(p) )
         key_expire = keytimestamp + buffer_to_u32(p);
     else
         key_expire = 0;

Modified: branches/GNUPG-1-9-BRANCH/g10/gpg.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/gpg.c	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/gpg.c	2006-06-27 14:30:59 UTC (rev 4176)
@@ -328,6 +328,7 @@
     oNoAutoCheckTrustDB,
     oPreservePermissions,
     oDefaultPreferenceList,
+    oDefaultKeyserverURL,
     oPersonalCipherPreferences,
     oPersonalDigestPreferences,
     oPersonalCompressPreferences,
@@ -659,6 +660,7 @@
     { aRebuildKeydbCaches, "rebuild-keydb-caches", 256, "@"},
     { oPreservePermissions, "preserve-permissions", 0, "@"},
     { oDefaultPreferenceList,  "default-preference-list", 2, "@"},
+    { oDefaultKeyserverURL,  "default-keyserver-url", 2, "@"},
     { oPersonalCipherPreferences,  "personal-cipher-preferences", 2, "@"},
     { oPersonalDigestPreferences,  "personal-digest-preferences", 2, "@"},
     { oPersonalCompressPreferences,  "personal-compress-preferences", 2, "@"},
@@ -1643,6 +1645,78 @@
     log_error("unknown trust model `%s'\n",model);
 }
 
+
+
+/* Make sure that the standard file descriptors are opened. Obviously
+   some folks close them before an exec and the next file we open will
+   get one of them assigned and thus any output (i.e. diagnostics) end
+   up in that file (e.g. the trustdb).  Not actually a gpg problem as
+   this will hapenn with almost all utilities when called in a wrong
+   way.  However we try to minimize the damage here and raise
+   awareness of the problem.
+
+   Must be called before we open any files! */
+static void
+reopen_std(void)
+{  
+#if defined(HAVE_STAT) && !defined(HAVE_W32_SYSTEM)
+  struct stat statbuf;
+  int did_stdin=0,did_stdout=0,did_stderr=0;
+  FILE *complain;
+
+  if(fstat(STDIN_FILENO,&statbuf)==-1 && errno==EBADF)
+    {
+      if(open("/dev/null",O_RDONLY)==STDIN_FILENO)
+	did_stdin=1;
+      else
+	did_stdin=2;
+    }
+
+  if(fstat(STDOUT_FILENO,&statbuf)==-1 && errno==EBADF)
+    {
+      if(open("/dev/null",O_WRONLY)==STDOUT_FILENO)
+	did_stdout=1;
+      else
+	did_stdout=2;
+    }
+
+  if(fstat(STDERR_FILENO,&statbuf)==-1 && errno==EBADF)
+    {
+      if(open("/dev/null",O_WRONLY)==STDERR_FILENO)
+	did_stderr=1;
+      else
+	did_stderr=2;
+    }
+
+  /* It's hard to log this sort of thing since the filehandle we would
+     complain to may be closed... */
+  if(did_stderr==0)
+    complain=stderr;
+  else if(did_stdout==0)
+    complain=stdout;
+  else
+    complain=NULL;
+
+  if(complain)
+    {
+      if(did_stdin==1)
+	fprintf(complain,"gpg: WARNING: standard input reopened\n");
+      if(did_stdout==1)
+	fprintf(complain,"gpg: WARNING: standard output reopened\n");
+      if(did_stderr==1)
+	fprintf(complain,"gpg: WARNING: standard error reopened\n");
+
+      if(did_stdin==2 || did_stdout==2 || did_stderr==2)
+	fprintf(complain,"gpg: fatal: unable to reopen standard input,"
+		" output, or error\n");
+    }
+
+  if(did_stdin==2 || did_stdout==2 || did_stderr==2)
+    exit(3);
+#endif /* HAVE_STAT && !HAVE_W32_SYSTEM */
+}
+
+
 int
 main (int argc, char **argv )
 {
@@ -1697,7 +1771,7 @@
     /* Please note that we may running SUID(ROOT), so be very CAREFUL
        when adding any stuff between here and the call to
        secmem_init() somewhere after the option parsing. */
-
+    reopen_std ();
     trap_unaligned();
     set_strusage (my_strusage);
     gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);
@@ -2586,6 +2660,19 @@
           case oDefaultPreferenceList:
 	    opt.def_preference_list = pargs.r.ret_str;
 	    break;
+	  case oDefaultKeyserverURL:
+	    {
+	      struct keyserver_spec *keyserver;
+	      keyserver=parse_keyserver_uri(pargs.r.ret_str,1,
+					    configname,configlineno);
+	      if(!keyserver)
+		log_error(_("could not parse keyserver URL\n"));
+	      else
+		free_keyserver_spec(keyserver);
+
+	      opt.def_keyserver_url = pargs.r.ret_str;
+	    }
+	    break;
           case oPersonalCipherPreferences:
 	    pers_cipher_list=pargs.r.ret_str;
 	    break;

Modified: branches/GNUPG-1-9-BRANCH/g10/import.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/import.c	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/import.c	2006-06-27 14:30:59 UTC (rev 4176)
@@ -66,7 +66,7 @@
 static void revocation_present(KBNODE keyblock);
 static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats,
 		      unsigned char **fpr,size_t *fpr_len,
-		      unsigned int options);
+		      unsigned int options,int from_sk);
 static int import_secret_one( const char *fname, KBNODE keyblock,
                               struct stats_s *stats, unsigned int options);
 static int import_revoke_cert( const char *fname, KBNODE node,
@@ -258,7 +258,7 @@
 
     while( !(rc = read_block( inp, &pending_pkt, &keyblock) )) {
 	if( keyblock->pkt->pkttype == PKT_PUBLIC_KEY )
-	    rc = import_one( fname, keyblock, stats, fpr, fpr_len, options );
+	    rc = import_one( fname, keyblock, stats, fpr, fpr_len, options, 0);
 	else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) 
                 rc = import_secret_one( fname, keyblock, stats, options );
 	else if( keyblock->pkt->pkttype == PKT_SIGNATURE
@@ -679,7 +679,8 @@
  */
 static int
 import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
-	    unsigned char **fpr,size_t *fpr_len,unsigned int options )
+	    unsigned char **fpr,size_t *fpr_len,unsigned int options,
+	    int from_sk )
 {
     PKT_public_key *pk;
     PKT_public_key *pk_orig;
@@ -698,9 +699,6 @@
 
     pk = node->pkt->pkt.public_key;
 
-    if(fpr)
-      *fpr=fingerprint_from_pk(pk,NULL,fpr_len);
-
     keyid_from_pk( pk, keyid );
     uidnode = find_next_kbnode( keyblock, PKT_USER_ID );
 
@@ -978,13 +976,31 @@
     if(mod_key)
       {
 	revocation_present(keyblock_orig);
-	if(seckey_available(keyid)==0)
+	if(!from_sk && seckey_available(keyid)==0)
 	  check_prefs(keyblock_orig);
       }
     else if(new_key)
       {
+	/* A little explanation for this: we fill in the fingerprint
+	   when importing keys as it can be useful to know the
+	   fingerprint in certain keyserver-related cases (a keyserver
+	   asked for a particular name, but the key doesn't have that
+	   name).  However, in cases where we're importing more than
+	   one key at a time, we cannot know which key to fingerprint.
+	   In these cases, rather than guessing, we do not fingerpring
+	   at all, and we must hope the user ID on the keys are
+	   useful. */
+	if(fpr)
+	  {
+	    xfree(*fpr);
+	    if(stats->imported==1)
+	      *fpr=fingerprint_from_pk(pk,NULL,fpr_len);
+	    else
+	      *fpr=NULL;
+	  }
+
 	revocation_present(keyblock);
-	if(seckey_available(keyid)==0)
+	if(!from_sk && seckey_available(keyid)==0)
 	  check_prefs(keyblock);
       }
 
@@ -1156,7 +1172,7 @@
 	    if(pub_keyblock)
 	      {
 		import_one(fname,pub_keyblock,stats,
-			   NULL,NULL,opt.import_options);
+			   NULL,NULL,opt.import_options,1);
 		release_kbnode(pub_keyblock);
 	      }
 	  }

Modified: branches/GNUPG-1-9-BRANCH/g10/keygen.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/keygen.c	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/keygen.c	2006-06-27 14:30:59 UTC (rev 4176)
@@ -42,6 +42,7 @@
 #include "trustdb.h"
 #include "status.h"
 #include "i18n.h"
+#include "keyserver-internal.h"
 #include "call-agent.h"
 
 
@@ -69,7 +70,8 @@
   pPASSPHRASE_S2K,
   pSERIALNO,
   pBACKUPENCDIR,
-  pHANDLE
+  pHANDLE,
+  pKEYSERVER
 };
 
 struct para_data_s {
@@ -125,6 +127,7 @@
 static int  write_keyblock( IOBUF out, KBNODE node );
 static int gen_card_key (int algo, int keyno, int is_primary,
                          KBNODE pub_root, KBNODE sec_root,
+			 PKT_secret_key **ret_sk,
                          u32 expireval, struct para_data_s *para);
 static int gen_card_key_with_backup (int algo, int keyno, int is_primary,
                                      KBNODE pub_root, KBNODE sec_root,
@@ -224,7 +227,7 @@
         if(pk->expiredate > pk->timestamp)
 	  u= pk->expiredate - pk->timestamp;
 	else
-	  u= 0;
+	  u= 1;
 
 	buf[0] = (u >> 24) & 0xff;
 	buf[1] = (u >> 16) & 0xff;
@@ -657,6 +660,7 @@
     /* Make sure that the MDC feature flag is set if needed */
     add_feature_mdc (sig,mdc_available);
     add_keyserver_modify (sig,ks_modify);
+    keygen_add_keyserver_url(sig,NULL);
 
     return 0;
 }
@@ -675,6 +679,7 @@
     do_add_key_flags (sig, pk->pubkey_usage);
     keygen_add_key_expire( sig, opaque );
     keygen_upd_std_prefs (sig, opaque);
+    keygen_add_keyserver_url(sig,NULL);
 
     return 0;
 }
@@ -684,6 +689,9 @@
 {
   const char *url=opaque;
 
+  if(!url)
+    url=opt.def_keyserver_url;
+
   if(url)
     build_sig_subpkt(sig,SIGSUBPKT_PREF_KS,url,strlen(url));
   else
@@ -940,7 +948,6 @@
     return rc;
 }
 
-/* sub_sk is currently unused (reserved for backsigs) */
 static int
 write_keybinding( KBNODE root, KBNODE pub_root,
 		  PKT_secret_key *pri_sk, PKT_secret_key *sub_sk,
@@ -1224,20 +1231,54 @@
     PKT_public_key *pk;
     gcry_sexp_t s_parms, s_key;
     gcry_sexp_t misc_key_info;
+    unsigned int qbits;
 
-    if( nbits > 1024 || nbits < 512 ) {
+    if ( nbits < 512 || (!opt.flags.dsa2 && nbits > 1024)) 
+      {
 	nbits = 1024;
 	log_info(_("keysize invalid; using %u bits\n"), nbits );
-    }
+      }
+    else if ( nbits > 3072 )
+      {
+ 	nbits = 3072;
+        log_info(_("keysize invalid; using %u bits\n"), nbits );
+      }
 
-    if( (nbits % 64) ) {
+    if( (nbits % 64) )
+      {
 	nbits = ((nbits + 63) / 64) * 64;
 	log_info(_("keysize rounded up to %u bits\n"), nbits );
-    }
+      }
 
+    /*
+      Figure out a q size based on the key size.  FIPS 180-3 says:
+ 
+      L = 1024, N = 160
+      L = 2048, N = 224
+      L = 2048, N = 256
+      L = 3072, N = 256
+ 
+      2048/256 is an odd pair since there is also a 2048/224 and
+      3072/256.  Matching sizes is not a very exact science.
+      
+      We'll do 256 qbits for nbits over 2048, 224 for nbits over 1024
+      but less than 2048, and 160 for 1024 (DSA1).
+    */
+ 
+    if (nbits > 2048)
+      qbits = 256;
+    else if ( nbits > 1024)
+      qbits = 224;
+    else
+      qbits = 160;
+ 
+    if (qbits != 160 )
+      log_info (_("WARNING: some OpenPGP programs can't"
+                  " handle a DSA key with this digest size\n"));
+
     rc = gcry_sexp_build (&s_parms, NULL,
-                          "(genkey(dsa(nbits %d)))",
-                          (int)nbits);
+                            "(genkey(dsa(nbits %d)(qbits %d)))",
+                            (int)nbits, (int)qbits);
     if (rc)
       log_bug ("gcry_sexp_build failed: %s\n", gpg_strerror (rc));
   
@@ -1253,9 +1294,8 @@
     pk = xmalloc_clear( sizeof *pk );
     sk->timestamp = pk->timestamp = make_timestamp();
     sk->version = pk->version = 4;
-    if( expireval ) {
-	sk->expiredate = pk->expiredate = sk->timestamp + expireval;
-    }
+    if (expireval) 
+      sk->expiredate = pk->expiredate = sk->timestamp + expireval;
     sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA;
 
     rc = key_from_sexp (pk->pkey, s_key, "public-key", "pqgy");
@@ -1633,10 +1673,10 @@
   switch(algo)
     {
     case PUBKEY_ALGO_DSA:
-      if(opt.expert)
+      if(opt.flags.dsa2)
 	{
 	  def=1024;
-	  max=1024;
+	  max=3072;
 	}
       else
 	{
@@ -2375,6 +2415,25 @@
   /* Set preferences, if any. */
   keygen_set_std_prefs(get_parameter_value( para, pPREFERENCES ), 0);
 
+  /* Set keyserver, if any. */
+  s1=get_parameter_value( para, pKEYSERVER );
+  if(s1)
+    {
+      struct keyserver_spec *spec;
+
+      spec=parse_keyserver_uri(s1,1,NULL,0);
+      if(spec)
+	{
+	  free_keyserver_spec(spec);
+	  opt.def_keyserver_url=s1;
+	}
+      else
+	{
+	  log_error("%s:%d: invalid keyserver url\n", fname, r->lnr );
+	  return -1;
+	}
+    }
+
   /* Set revoker, if any. */
   if (parse_revocation_key (fname, para, pREVOKER))
     return -1;
@@ -2467,6 +2526,7 @@
 	{ "Preferences",    pPREFERENCES },
 	{ "Revoker",        pREVOKER },
         { "Handle",         pHANDLE },
+	{ "Keyserver",      pKEYSERVER },
 	{ NULL, 0 }
     };
     IOBUF fp;
@@ -2746,13 +2806,13 @@
           sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA );
           r->next = para;
           para = r;
-          tty_printf(_("DSA keypair will have %u bits.\n"),1024);
+	  nbits = ask_keysize( PUBKEY_ALGO_DSA );
+	  r = xmalloc_clear( sizeof *r + 20 );
+	  r->key = pKEYLENGTH;
+	  sprintf( r->u.value, "%u", nbits);
+	  r->next = para;
+	  para = r;
           r = xmalloc_clear( sizeof *r + 20 );
-          r->key = pKEYLENGTH;
-          strcpy( r->u.value, "1024" );
-          r->next = para;
-          para = r;
-          r = xmalloc_clear( sizeof *r + 20 );
           r->key = pKEYUSAGE;
           strcpy( r->u.value, "sign" );
           r->next = para;
@@ -2791,7 +2851,7 @@
             }
            
         }
-       
+
       nbits = ask_keysize( algo );
       r = xmalloc_clear( sizeof *r + 20 );
       r->key = both? pSUBKEYLENGTH : pKEYLENGTH;
@@ -3057,7 +3117,7 @@
       }
     else
       {
-        rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root,
+        rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root, NULL,
                            get_parameter_u32 (para, pKEYEXPIRE), para);
         if (!rc)
           {
@@ -3093,7 +3153,7 @@
 
     if (!rc && card && get_parameter (para, pAUTHKEYTYPE))
       {
-        rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root,
+        rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, NULL,
                            get_parameter_u32 (para, pKEYEXPIRE), para);
         
         if (!rc)
@@ -3129,6 +3189,7 @@
               }
             else
               rc = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root, sec_root,
+				 NULL,
                                  get_parameter_u32 (para, pKEYEXPIRE), para);
           }
 
@@ -3353,7 +3414,7 @@
     }
 
     rc = do_create( algo, nbits, pub_keyblock, sec_keyblock,
-				      dek, s2k, &sub_sk, expire, 1 );
+		    dek, s2k, &sub_sk, expire, 1 );
     if( !rc )
 	rc = write_keybinding(pub_keyblock, pub_keyblock, pri_sk, sub_sk, use);
     if( !rc )
@@ -3387,7 +3448,7 @@
 {
   int okay=0, rc=0;
   KBNODE node;
-  PKT_secret_key *pri_sk = NULL;
+  PKT_secret_key *pri_sk = NULL, *sub_sk;
   int algo;
   unsigned int use;
   u32 expire;
@@ -3467,11 +3528,12 @@
 
   if (passphrase)
     set_next_passphrase (passphrase);
-  rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock, expire, para);
+  rc = gen_card_key (algo, keyno, 0, pub_keyblock, sec_keyblock,
+		     &sub_sk, expire, para);
   if (!rc)
-    rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, NULL, use);
+    rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, use);
   if (!rc)
-    rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, NULL, use);
+    rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk, use);
   if (!rc)
     {
       okay = 1;
@@ -3518,7 +3580,7 @@
 
 static int
 gen_card_key (int algo, int keyno, int is_primary,
-              KBNODE pub_root, KBNODE sec_root,
+              KBNODE pub_root, KBNODE sec_root, PKT_secret_key **ret_sk,
               u32 expireval, struct para_data_s *para)
 {
 #ifdef ENABLE_CARD_SUPPORT
@@ -3579,6 +3641,9 @@
         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;

Modified: branches/GNUPG-1-9-BRANCH/g10/options.h
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/options.h	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/options.h	2006-06-27 14:30:59 UTC (rev 4176)
@@ -154,7 +154,8 @@
   unsigned int export_options;
   unsigned int list_options;
   unsigned int verify_options;
-  char *def_preference_list;
+  const char *def_preference_list;
+  const char *def_keyserver_url;
   prefitem_t *personal_cipher_prefs;
   prefitem_t *personal_digest_prefs;
   prefitem_t *personal_compress_prefs;

Modified: branches/GNUPG-1-9-BRANCH/g10/parse-packet.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/parse-packet.c	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/parse-packet.c	2006-06-27 14:30:59 UTC (rev 4176)
@@ -1,6 +1,6 @@
 /* parse-packet.c  - read packets
- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- *               2005 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+ *               2006 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -876,8 +876,13 @@
 	break;
       case SIGSUBPKT_SIG_EXPIRE:
 	if( length >= 4 )
-	    fprintf (listfp, "sig expires after %s",
-				     strtimevalue( buffer_to_u32(buffer) ) );
+	  {
+	    if(buffer_to_u32(buffer))
+	      fprintf (listfp, "sig expires after %s",
+		       strtimevalue( buffer_to_u32(buffer) ) );
+	    else
+	      fprintf (listfp, "sig does not expire");
+	  }
 	break;
       case SIGSUBPKT_EXPORTABLE:
 	if( length )
@@ -901,8 +906,13 @@
 	break;
       case SIGSUBPKT_KEY_EXPIRE:
 	if( length >= 4 )
-	    fprintf (listfp, "key expires after %s",
-				    strtimevalue( buffer_to_u32(buffer) ) );
+	  {
+	    if(buffer_to_u32(buffer))
+	      fprintf (listfp, "key expires after %s",
+		       strtimevalue( buffer_to_u32(buffer) ) );
+	    else
+	      fprintf (listfp, "key does not expire");
+	  }
 	break;
       case SIGSUBPKT_PREF_SYM:
 	fputs("pref-sym-algos:", listfp );
@@ -1408,7 +1418,7 @@
 	  log_info ("signature packet without keyid\n");
 
 	p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
-	if(p)
+	if(p && buffer_to_u32(p))
 	  sig->expiredate=sig->timestamp+buffer_to_u32(p);
 	if(sig->expiredate && sig->expiredate<=make_timestamp())
 	  sig->flags.expired=1;
@@ -2027,6 +2037,20 @@
 {
     byte *p;
 
+    /* Cap the size of a user ID at 2k: a value absurdly large enough
+       that there is no sane user ID string (which is printable text
+       as of RFC2440bis) that won't fit in it, but yet small enough to
+       avoid allocation problems.  A large pktlen may not be
+       allocatable, and a very large pktlen could actually cause our
+       allocation to wrap around in xmalloc to a small number. */
+
+    if (pktlen > 2048)
+      {
+	log_error ("packet(%d) too large\n", pkttype);
+	iobuf_skip_rest(inp, pktlen, 0);
+	return G10ERR_INVALID_PACKET;
+      }
+    
     packet->pkt.user_id = xmalloc_clear(sizeof *packet->pkt.user_id + pktlen);
     packet->pkt.user_id->len = pktlen;
     packet->pkt.user_id->ref=1;

Modified: branches/GNUPG-1-9-BRANCH/g10/sign.c
===================================================================
--- branches/GNUPG-1-9-BRANCH/g10/sign.c	2006-06-27 08:40:23 UTC (rev 4175)
+++ branches/GNUPG-1-9-BRANCH/g10/sign.c	2006-06-27 14:30:59 UTC (rev 4176)
@@ -320,6 +320,12 @@
       }
     else 
       {
+#if 0 /* disabled *.
+	/* Disabled for now.  It seems reasonable to accept a
+	   truncated hash for a DSA1 key, even though we don't
+	   generate it without --enable-dsa2.  Be liberal in what you
+	   accept, etc. */
+
 	/* If it's a DSA key, and q is 160 bits, it might be an
 	   old-style DSA key.  If the hash doesn't match the q, fail
 	   unless --enable-dsa2 is set.  If the q isn't 160 bits, then
@@ -333,6 +339,7 @@
 	    log_error(_("DSA requires the use of a 160 bit hash algorithm\n"));
 	    return G10ERR_GENERAL;
 	  }
+#endif /* disabled */
 
         frame = encode_md_value( NULL, sk, md, digest_algo );
         if (!frame)
@@ -1539,7 +1546,7 @@
       }
 
     /* Note that already expired sigs will remain expired (with a
-       duration of 0) since build-packet.c:build_sig_subpkt_from_sig
+       duration of 1) since build-packet.c:build_sig_subpkt_from_sig
        detects this case. */
 
     if( sig->version >= 4 )




More information about the Gnupg-commits mailing list