Fix bug#1307
authorWerner Koch <wk@gnupg.org>
Tue, 9 Aug 2011 08:12:36 +0000 (10:12 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 9 Aug 2011 08:12:36 +0000 (10:12 +0200)
This is a backport of the fixes for 2.0.  There is only one real bug,
the other changes are for clarity and for more picky compilers.

g10/ChangeLog
g10/import.c
g10/keygen.c
util/ChangeLog
util/pka.c

index fda3b85..5787b80 100644 (file)
@@ -1,3 +1,10 @@
+2011-08-09  Werner Koch  <wk@g10code.com>
+
+       * keygen.c (ask_user_id): Fix loop break condition. See bug#1307.
+
+       * import.c (import_keys_internal): Make breaking the loop more
+       explicit.  See bug#1307.
+
 2011-07-22  Werner Koch  <wk@g10code.com>
 
        * parse-packet.c (parse_key): Print the decoded iteration count.
index 934101c..21ada41 100644 (file)
@@ -175,10 +175,9 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
         rc = import( inp, "[stream]", stats, fpr, fpr_len, options);
     }
     else {
-        if( !fnames && !nnames )
-           nnames = 1;  /* Ohh what a ugly hack to jump into the loop */
+        int once = (!fnames && !nnames);
 
-       for(i=0; i < nnames; i++ ) {
+       for(i=0; once || i < nnames; once=0, i++ ) {
            const char *fname = fnames? fnames[i] : NULL;
            IOBUF inp2 = iobuf_open(fname);
            if( !fname )
@@ -201,8 +200,6 @@ import_keys_internal( IOBUF inp, char **fnames, int nnames,
                  log_error("import from `%s' failed: %s\n", fname,
                            g10_errstr(rc) );
              }
-           if( !fname )
-               break;
        }
     }
     if (!stats_handle) {
@@ -256,7 +253,7 @@ import( IOBUF inp, const char* fname,struct stats_s *stats,
     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, 0);
-       else if( keyblock->pkt->pkttype == PKT_SECRET_KEY ) 
+       else if( keyblock->pkt->pkttype == PKT_SECRET_KEY )
                 rc = import_secret_one( fname, keyblock, stats, options );
        else if( keyblock->pkt->pkttype == PKT_SIGNATURE
                 && keyblock->pkt->pkt.signature->sig_class == 0x20 )
@@ -615,7 +612,7 @@ check_prefs(KBNODE keyblock)
   KBNODE node;
   PKT_public_key *pk;
   int problem=0;
-  
+
   merge_keys_and_selfsig(keyblock);
   pk=keyblock->pkt->pkt.public_key;
 
@@ -759,7 +756,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
        log_error( _("key %s: no user ID\n"), keystr_from_pk(pk));
        return 0;
       }
-    
+
     if (opt.interactive) {
         if(is_status_enabled())
          print_import_check (pk, uidnode->pkt->pkt.user_id);
@@ -896,7 +893,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
             size_t an;
 
             fingerprint_from_pk (pk_orig, afp, &an);
-            while (an < MAX_FINGERPRINT_LEN) 
+            while (an < MAX_FINGERPRINT_LEN)
                 afp[an++] = 0;
             rc = keydb_search_fpr (hd, afp);
         }
@@ -920,7 +917,7 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
         n_sigs_cleaned = fix_bad_direct_key_sigs (keyblock_orig, keyid);
         if (n_sigs_cleaned)
           commit_kbnode (&keyblock_orig);
-            
+
        /* and try to merge the block */
        clear_kbnode_flags( keyblock_orig );
        clear_kbnode_flags( keyblock );
@@ -990,13 +987,13 @@ import_one( const char *fname, KBNODE keyblock, struct stats_s *stats,
            stats->n_sigs_cleaned +=n_sigs_cleaned;
            stats->n_uids_cleaned +=n_uids_cleaned;
 
-            if (is_status_enabled ()) 
+            if (is_status_enabled ())
                  print_import_ok (pk, NULL,
                                   ((n_uids?2:0)|(n_sigs?4:0)|(n_subk?8:0)));
        }
        else
          {
-           if (is_status_enabled ()) 
+           if (is_status_enabled ())
              print_import_ok (pk, NULL, 0);
 
            if( !opt.quiet )
@@ -1127,7 +1124,7 @@ sec_to_pub_keyblock(KBNODE sec_keyblock)
  * with the trust calculation.
  */
 static int
-import_secret_one( const char *fname, KBNODE keyblock, 
+import_secret_one( const char *fname, KBNODE keyblock,
                    struct stats_s *stats, unsigned int options)
 {
     PKT_secret_key *sk;
@@ -1179,8 +1176,8 @@ import_secret_one( const char *fname, KBNODE keyblock,
         log_error (_("importing secret keys not allowed\n"));
         return 0;
       }
-#endif 
-    
+#endif
+
     clear_kbnode_flags( keyblock );
 
     /* do we have this key already in one of our secrings ? */
@@ -1206,7 +1203,7 @@ import_secret_one( const char *fname, KBNODE keyblock,
        if( !opt.quiet )
          log_info( _("key %s: secret key imported\n"), keystr_from_sk(sk));
        stats->secret_imported++;
-        if (is_status_enabled ()) 
+        if (is_status_enabled ())
          print_import_ok (NULL, sk, 1|16);
 
        if(options&IMPORT_SK2PK)
@@ -1237,7 +1234,7 @@ import_secret_one( const char *fname, KBNODE keyblock,
        log_error( _("key %s: already in secret keyring\n"),
                   keystr_from_sk(sk));
        stats->secret_dups++;
-        if (is_status_enabled ()) 
+        if (is_status_enabled ())
          print_import_ok (NULL, sk, 16);
 
        /* TODO: if we ever do merge secret keys, make sure to handle
@@ -1291,9 +1288,9 @@ import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats )
     {
         byte afp[MAX_FINGERPRINT_LEN];
         size_t an;
-        
+
         fingerprint_from_pk (pk, afp, &an);
-        while (an < MAX_FINGERPRINT_LEN) 
+        while (an < MAX_FINGERPRINT_LEN)
             afp[an++] = 0;
         rc = keydb_search_fpr (hd, afp);
     }
@@ -2274,35 +2271,35 @@ pub_to_sec_keyblock (KBNODE pub_keyblock)
          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
@@ -2316,12 +2313,12 @@ pub_to_sec_keyblock (KBNODE pub_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). 
-   
+   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, 
+update_sec_keyblock_with_cardinfo (KBNODE sec_keyblock,
                                    const unsigned char *fpr1,
                                    const unsigned char *fpr2,
                                    const unsigned char *fpr3,
@@ -2341,7 +2338,7 @@ update_sec_keyblock_with_cardinfo (KBNODE sec_keyblock,
           && 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.  */
@@ -2391,7 +2388,7 @@ update_sec_keyblock_with_cardinfo (KBNODE sec_keyblock,
    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, 
+auto_create_card_key_stub ( const char *serialnostr,
                             const unsigned char *fpr1,
                             const unsigned char *fpr2,
                             const unsigned char *fpr3)
@@ -2402,7 +2399,7 @@ auto_create_card_key_stub ( const char *serialnostr,
   int rc;
 
   /* We only want to do this for an OpenPGP card.  */
-  if (!serialnostr || strncmp (serialnostr, "D27600012401", 12) 
+  if (!serialnostr || strncmp (serialnostr, "D27600012401", 12)
       || strlen (serialnostr) != 32 )
     return G10ERR_GENERAL;
 
@@ -2413,7 +2410,7 @@ auto_create_card_key_stub ( const char *serialnostr,
     ;
   else
     return G10ERR_GENERAL;
+
   hd = keydb_new (1);
 
   /* Now check whether there is a secret keyring.  */
@@ -2439,7 +2436,7 @@ auto_create_card_key_stub ( const char *serialnostr,
       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,
@@ -2473,7 +2470,7 @@ auto_create_card_key_stub ( const char *serialnostr,
                        keydb_get_resource_name (hd), g10_errstr(rc) );
         }
     }
-    
+
   release_kbnode (sec_keyblock);
   release_kbnode (pub_keyblock);
   keydb_release (hd);
index 8e396ce..90bddae 100644 (file)
@@ -41,7 +41,7 @@
 #include "cardglue.h"
 #include "keyserver-internal.h"
 
-#define MAX_PREFS 30 
+#define MAX_PREFS 30
 
 enum para_name {
   pKEYTYPE,
@@ -142,7 +142,7 @@ print_status_key_created (int letter, PKT_public_key *pk, const char *handle)
   byte array[MAX_FINGERPRINT_LEN], *s;
   char *buf, *p;
   size_t i, n;
-  
+
   if (!handle)
     handle = "";
 
@@ -210,7 +210,7 @@ do_add_key_flags (PKT_signature *sig, unsigned int use)
     if (use & PUBKEY_USAGE_AUTH)
         buf[0] |= 0x20;
 
-    if (!buf[0]) 
+    if (!buf[0])
         return;
 
     build_sig_subpkt (sig, SIGSUBPKT_KEY_FLAGS, buf, 1);
@@ -315,7 +315,7 @@ keygen_set_std_prefs (const char *string,int personal)
 
                  gpg -r pgpkey -r gpgkey  ---gives--> AES256
                  gpg -r gpgkey -r pgpkey  ---gives--> AES
-                 
+
                Note that by using --personal-cipher-preferences it is
                possible to prefer AES128.
             */
@@ -652,7 +652,7 @@ keygen_upd_std_prefs( PKT_signature *sig, void *opaque )
     if (!prefs_initialized)
         keygen_set_std_prefs (NULL, 0);
 
-    if (nsym_prefs) 
+    if (nsym_prefs)
         build_sig_subpkt (sig, SIGSUBPKT_PREF_SYM, sym_prefs, nsym_prefs);
     else
       {
@@ -811,7 +811,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
       /* get it into a binary packed form. */
       IOBUF backsig_out=iobuf_temp();
       PACKET backsig_pkt;
+
       init_packet(&backsig_pkt);
       backsig_pkt.pkttype=PKT_SIGNATURE;
       backsig_pkt.pkt.signature=backsig;
@@ -823,7 +823,7 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
        {
          size_t pktlen=0;
          byte *buf=iobuf_get_temp_buffer(backsig_out);
+
          /* Remove the packet header */
          if(buf[0]&0x40)
            {
@@ -852,34 +852,34 @@ make_backsig (PKT_signature *sig, PKT_public_key *pk,
          else
            {
              int mark=1;
+
              switch(buf[0]&3)
                {
                case 3:
                  BUG();
                  break;
+
                case 2:
                  pktlen =buf[mark++] << 24;
                  pktlen|=buf[mark++] << 16;
+
                case 1:
                  pktlen|=buf[mark++] << 8;
+
                case 0:
                  pktlen|=buf[mark++];
                }
+
              buf+=mark;
            }
+
          /* now make the binary blob into a subpacket */
          build_sig_subpkt(sig,SIGSUBPKT_SIGNATURE,buf,pktlen);
 
          iobuf_close(backsig_out);
        }
     }
+
   return rc;
 }
 
@@ -996,7 +996,7 @@ write_keybinding (KBNODE root, KBNODE pub_root,
     /* we have to cache the key, so that the verification of the signature
      * creation is able to retrieve the public key */
     cache_public_key (pri_pk);
+
     /* find the last subkey */
     sub_pk = NULL;
     for(node=pub_root; node; node = node->next ) {
@@ -1164,7 +1164,7 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
 
       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 2047, 224 for nbits over 1024
       but less than 2048, and 160 for 1024 (DSA1).
     */
@@ -1243,7 +1243,7 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
 }
 
 
-/* 
+/*
  * Generate an RSA key.
  */
 static int
@@ -1483,10 +1483,10 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage)
   char *answer;
   int algo;
   int dummy_algo;
-  
+
   if (!r_subkey_algo)
     r_subkey_algo = &dummy_algo;
-  
+
   tty_printf(_("Please select what kind of key you want:\n"));
   if (!addmode)
     tty_printf (_("   (%d) RSA and RSA (default)\n"), 1 );
@@ -1507,7 +1507,7 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage)
       tty_printf (_("   (%d) RSA (set your own capabilities)\n"), 8 );
     }
 
-  for (;;) 
+  for (;;)
     {
       *r_usage = 0;
       *r_subkey_algo = 0;
@@ -1566,7 +1566,7 @@ ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage)
       else
         tty_printf (_("Invalid selection.\n"));
     }
-  
+
   return algo;
 }
 
@@ -1630,7 +1630,7 @@ ask_keysize (int algo, unsigned int primary_keysize)
       nbits = *answer? atoi(answer): def;
       xfree(prompt);
       xfree(answer);
-      
+
       if(nbits<min || nbits>max)
        tty_printf(_("%s keysizes must be in the range %u-%u\n"),
                   pubkey_algo_to_string(algo),min,max);
@@ -1685,7 +1685,7 @@ parse_expire_string (u32 timestamp, const char *string)
     seconds = atoi(string) * 86400L * mult;
   else
     seconds=(u32)-1;
-  
+
   return seconds;
 }
 
@@ -1695,7 +1695,7 @@ static u32
 parse_creation_string (const char *string)
 {
   u32 seconds;
-  
+
   if (!*string)
     seconds = 0;
   else if ( !strncmp (string, "seconds=", 8) )
@@ -1915,7 +1915,7 @@ ask_user_id( int mode )
                lower and uppercase.  Below you will find the matching
                string which should be translated accordingly and the
                letter changed to match the one in the answer string.
-               
+
                  n = Change name
                  c = Change comment
                  e = Change email
@@ -1971,7 +1971,7 @@ ask_user_id( int mode )
            xfree(answer);
        }
        xfree(answer);
-       if( !amail && !acomment && !amail )
+       if( !aname && !acomment && !amail )
            break;
        xfree(uid); uid = NULL;
     }
@@ -2122,7 +2122,7 @@ get_parameter_algo( struct para_data_s *para, enum para_name key )
     return i;
 }
 
-/* 
+/*
  * parse the usage parameter and set the keyflags.  Return true on error.
  */
 static int
@@ -2135,7 +2135,7 @@ parse_parameter_usage (const char *fname,
 
     if( !r )
        return 0; /* none (this is an optional parameter)*/
-    
+
     use = 0;
     pn = r->u.value;
     while ( (p = strsep (&pn, " \t,")) ) {
@@ -2228,14 +2228,14 @@ get_parameter_u32( struct para_data_s *para, enum para_name key )
       if (r && *r->u.value)
         {
           u32 seconds;
-          
+
           seconds = parse_creation_string (r->u.value);
           if (!seconds)
             log_error ("invalid creation date in line %d\n", r->lnr );
           else /* Okay: Change this parameter. */
             {
               r->u.creation = seconds;
-              r->key = pKEYCREATIONDATE;  
+              r->key = pKEYCREATIONDATE;
             }
         }
 
@@ -2608,7 +2608,7 @@ read_parameter_file( const char *fname )
            else if( !ascii_strcasecmp( keyword, "%commit" ) ) {
                outctrl.lnr = lnr;
                if (proc_parameter_file( para, fname, &outctrl, 0 ))
-                  print_status_key_not_created 
+                  print_status_key_not_created
                     (get_parameter_value (para, pHANDLE));
                release_parameter_list( para );
                para = NULL;
@@ -2733,7 +2733,7 @@ read_parameter_file( const char *fname )
  * written to directory given by this argument .
  */
 void
-generate_keypair (const char *fname, const char *card_serialno, 
+generate_keypair (const char *fname, const char *card_serialno,
                   const char *backup_encryption_dir)
 {
   unsigned int nbits;
@@ -2747,16 +2747,16 @@ generate_keypair (const char *fname, const char *card_serialno,
   struct para_data_s *para = NULL;
   struct para_data_s *r;
   struct output_control_s outctrl;
-  
+
   memset( &outctrl, 0, sizeof( outctrl ) );
-  
+
   if (opt.batch && card_serialno)
     {
       /* We don't yet support unattended key generation. */
       log_error (_("can't do this in batch mode\n"));
       return;
     }
-  
+
   if (opt.batch)
     {
       read_parameter_file( fname );
@@ -2771,9 +2771,9 @@ generate_keypair (const char *fname, const char *card_serialno,
       strcpy( r->u.value, card_serialno);
       r->next = para;
       para = r;
-       
+
       algo = PUBKEY_ALGO_RSA;
-       
+
       r = xcalloc (1, sizeof *r + 20 );
       r->key = pKEYTYPE;
       sprintf( r->u.value, "%d", algo );
@@ -2784,7 +2784,7 @@ generate_keypair (const char *fname, const char *card_serialno,
       strcpy (r->u.value, "sign");
       r->next = para;
       para = r;
-       
+
       r = xcalloc (1, sizeof *r + 20 );
       r->key = pSUBKEYTYPE;
       sprintf( r->u.value, "%d", algo );
@@ -2795,7 +2795,7 @@ generate_keypair (const char *fname, const char *card_serialno,
       strcpy (r->u.value, "encrypt");
       r->next = para;
       para = r;
-       
+
       r = xcalloc (1, sizeof *r + 20 );
       r->key = pAUTHKEYTYPE;
       sprintf( r->u.value, "%d", algo );
@@ -2818,7 +2818,7 @@ generate_keypair (const char *fname, const char *card_serialno,
 
       algo = ask_algo (0, &subkey_algo, &use );
       if (subkey_algo)
-        { 
+        {
           /* Create primary and subkey at once.  */
           both = 1;
           r = xmalloc_clear( sizeof *r + 20 );
@@ -2837,7 +2837,7 @@ generate_keypair (const char *fname, const char *card_serialno,
           strcpy( r->u.value, "sign" );
           r->next = para;
           para = r;
-           
+
           r = xmalloc_clear( sizeof *r + 20 );
           r->key = pSUBKEYTYPE;
           sprintf( r->u.value, "%d", subkey_algo );
@@ -2849,14 +2849,14 @@ generate_keypair (const char *fname, const char *card_serialno,
           r->next = para;
           para = r;
         }
-      else 
+      else
         {
           r = xmalloc_clear( sizeof *r + 20 );
           r->key = pKEYTYPE;
           sprintf( r->u.value, "%d", algo );
           r->next = para;
           para = r;
-           
+
           if (use)
             {
               r = xmalloc_clear( sizeof *r + 25 );
@@ -2878,7 +2878,7 @@ generate_keypair (const char *fname, const char *card_serialno,
       r->next = para;
       para = r;
     }
-   
+
   expire = ask_expire_interval (get_parameter_u32 (para, pKEYCREATIONDATE),
                                 0, NULL);
   r = xmalloc_clear( sizeof *r + 20 );
@@ -2893,7 +2893,7 @@ generate_keypair (const char *fname, const char *card_serialno,
   para = r;
 
   uid = ask_user_id(0);
-  if( !uid ) 
+  if( !uid )
     {
       log_error(_("Key generation canceled.\n"));
       release_parameter_list( para );
@@ -2904,7 +2904,7 @@ generate_keypair (const char *fname, const char *card_serialno,
   strcpy( r->u.value, uid );
   r->next = para;
   para = r;
-    
+
   dek = card_serialno? NULL : do_ask_passphrase( &s2k );
   if( dek )
     {
@@ -2919,7 +2919,7 @@ generate_keypair (const char *fname, const char *card_serialno,
       r->next = para;
       para = r;
     }
-    
+
   proc_parameter_file( para, "[internal]", &outctrl, !!card_serialno);
   release_parameter_list( para );
 }
@@ -2952,7 +2952,7 @@ generate_raw_key (int algo, unsigned int nbits, u32 created_at,
       log_info (_("keysize invalid; using %u bits\n"), nbits );
     }
 
-  if ((nbits % 32)) 
+  if ((nbits % 32))
     {
       nbits = ((nbits + 31) / 32) * 32;
       log_info(_("keysize rounded up to %u bits\n"), nbits );
@@ -2975,7 +2975,7 @@ generate_raw_key (int algo, unsigned int nbits, u32 created_at,
   for (i=npkey; i < nskey; i++)
     sk->csum += checksum_mpi (sk->skey[i]);
 
-  if (r_sk_unprotected) 
+  if (r_sk_unprotected)
     *r_sk_unprotected = copy_secret_key (NULL, sk);
 
   if (dek)
@@ -3110,7 +3110,7 @@ do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl,
      * linked list.  The first packet is a dummy packet which we flag
      * as deleted.  The very first packet must always be a KEY packet.
      */
-    
+
     start_tree(&pub_root);
     start_tree(&sec_root);
 
@@ -3179,7 +3179,7 @@ do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl,
         rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, NULL,
                            &timestamp,
                            get_parameter_u32 (para, pKEYEXPIRE), para);
-        
+
         if (!rc)
           rc = write_keybinding (pub_root, pub_root, pri_sk, sub_sk,
                                  PUBKEY_USAGE_AUTH, timestamp);
@@ -3250,13 +3250,13 @@ do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl,
 
         /* FIXME: we may have to create the keyring first */
         rc = keydb_locate_writable (pub_hd, NULL);
-        if (rc) 
+        if (rc)
            log_error (_("no writable public keyring found: %s\n"),
                        g10_errstr (rc));
 
-        if (!rc) {  
+        if (!rc) {
             rc = keydb_locate_writable (sec_hd, NULL);
-            if (rc) 
+            if (rc)
                 log_error (_("no writable secret keyring found: %s\n"),
                            g10_errstr (rc));
         }
@@ -3294,7 +3294,7 @@ do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl,
                 get_parameter_algo(para, pKEYTYPE) == PUBKEY_ALGO_RSA
                 && get_parameter_uint( para, pKEYUSAGE )
                 && !(get_parameter_uint( para,pKEYUSAGE) & PUBKEY_USAGE_ENC);
-            PKT_public_key *pk = find_kbnode (pub_root, 
+            PKT_public_key *pk = find_kbnode (pub_root,
                                     PKT_PUBLIC_KEY)->pkt->pkt.public_key;
 
            keyid_from_pk(pk,pk->main_keyid);
@@ -3309,7 +3309,7 @@ do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl,
                tty_printf("\n");
                list_keyblock(pub_root,0,1,NULL);
             }
-            
+
 
            if( !opt.batch
                && ( get_parameter_algo( para, pKEYTYPE ) == PUBKEY_ALGO_DSA
@@ -3332,7 +3332,7 @@ do_generate_keypair (struct para_data_s *para,struct output_control_s *outctrl,
         print_status_key_not_created ( get_parameter_value (para, pHANDLE) );
     }
     else {
-        PKT_public_key *pk = find_kbnode (pub_root, 
+        PKT_public_key *pk = find_kbnode (pub_root,
                                     PKT_PUBLIC_KEY)->pkt->pkt.public_key;
         print_status_key_created (did_sub? 'B':'P', pk,
                                   get_parameter_value (para, pHANDLE));
@@ -3447,7 +3447,7 @@ generate_subkeypair( KBNODE pub_keyblock, KBNODE sec_keyblock )
     rc = do_create (algo, nbits, pub_keyblock, sec_keyblock,
                    dek, s2k, &sub_sk, timestamp, expire, 1 );
     if (!rc)
-       rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk, 
+       rc = write_keybinding (pub_keyblock, pub_keyblock, pri_sk, sub_sk,
                                use, timestamp);
     if (!rc)
        rc = write_keybinding (sec_keyblock, pub_keyblock, pri_sk, sub_sk,
@@ -3628,7 +3628,7 @@ gen_card_key (int algo, int keyno, int is_primary,
   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) */
@@ -3653,7 +3653,7 @@ gen_card_key (int algo, int keyno, int is_primary,
       mpi_free (info.e);
       return gpg_error (GPG_ERR_GENERAL);
     }
-  
+
   if (*timestamp != info.created_at)
     log_info ("Note that the key does not use the suggested creation date\n");
   *timestamp = info.created_at;
@@ -3666,7 +3666,7 @@ gen_card_key (int algo, int keyno, int is_primary,
       sk->expiredate = pk->expiredate = pk->timestamp + expireval;
   sk->pubkey_algo = pk->pubkey_algo = algo;
   pk->pkey[0] = info.n;
-  pk->pkey[1] = info.e; 
+  pk->pkey[1] = info.e;
   sk->skey[0] = mpi_copy (pk->pkey[0]);
   sk->skey[1] = mpi_copy (pk->pkey[1]);
   sk->skey[2] = mpi_set_opaque (NULL, xstrdup ("dummydata"), 10);
@@ -3773,7 +3773,7 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
     else
       fp = iobuf_create (fname);
     umask (oldmask);
-    if (!fp) 
+    if (!fp)
       {
        log_error (_("can't create backup file `%s': %s\n"),
                    fname, strerror(errno) );
@@ -3798,7 +3798,7 @@ gen_card_key_with_backup (int algo, int keyno, int is_primary,
       {
         byte array[MAX_FINGERPRINT_LEN];
         char *fprbuf, *p;
-       
+
         iobuf_close (fp);
         iobuf_ioctl (NULL, 2, 0, (char*)fname);
         log_info (_("NOTE: backup of card key saved to `%s'\n"), fname);
@@ -3915,7 +3915,7 @@ save_unprotected_key_to_card (PKT_secret_key *sk, int keyno)
   p = stpcpy (stpcpy (stpcpy (p, numbuf), numbuf2), "))");
 
   /* Fixme: Unfortunately we don't have the serialnumber available -
-     thus we can't pass it down to the agent. */ 
+     thus we can't pass it down to the agent. */
   rc = agent_scd_writekey (keyno, NULL, sexp, p - sexp);
 
  leave:
index 767d0be..fabedee 100644 (file)
@@ -1,3 +1,9 @@
+2011-08-09  Werner Koch  <wk@g10code.com>
+
+       * pka.c (get_pka_info): Turn ANSWER into a union to avoid aliasing
+       problems with modern compilers.  See bug#1307.  Reported by Steve
+       Grubb.
+
 2010-10-27  Werner Koch  <wk@g10code.com>
 
        * miscutil.c (INVALID_TIME_CHECK): New.
 
        * simple-gettext.c (set_gettext_file): Use MO files depending on
        the installation directory.  Add new arg REGKEY.
-       
+
 2005-01-18  Werner Koch  <wk@g10code.com>
 
        * argparse.c (default_strusage): Changed default copyright year to
 2005-01-11  Werner Koch  <wk@g10code.com>
 
        * strgutil.c (set_native_charset) [W32]: Use the alias table from
-       libiconv 1.9.2. 
+       libiconv 1.9.2.
 
 2005-01-13  David Shaw  <dshaw@jabberwocky.com>
 
        header.  Noted by Jason Harris.
 
 2004-11-03  Timo Schulz  <twoaday@g10code.com>
-       
+
        * strgutil.c (w32_strerror): New.
        * ttyio.c (init_ttyfp, tty_printf, do_get): Use it here.
        * iobuf.c (fd_cache_open, file_filter): Likewise.
        (iobuf_seek, translate_file_handle): Likewise.
-       
+
 2004-11-02  Werner Koch  <wk@g10code.com>
 
        * strgutil.c (load_libiconv): Use log_info to avoid failures when
 2004-10-21  Werner Koch  <wk@g10code.com>
 
        * vasprintf.c: Removed. It was used only at one place and I don't
-       want to get into build problems in 1.4. 
+       want to get into build problems in 1.4.
 
 2004-10-18  David Shaw  <dshaw@jabberwocky.com>
 
 2003-09-28  Timo Schulz  <twoaday@freakmail.de>
 
        * strgutil.c [WIN32] (asprintf): New.
-       
+
 2003-09-28  Werner Koch  <wk@gnupg.org>
 
        * ttyio.c (tty_fprintf): New.
 
        * http.c [WIN32]: Define MB_CUR_MAX.
        (connect_server): use unsigned long since W32 does not have in_addr_t.
-       
+
 2003-08-28  David Shaw  <dshaw@jabberwocky.com>
 
        * dotlock.c, http.c, iobuf.c, simple-gettext.c, srv.c, srv.h,
        strgutil.c, ttyio.c, w32reg.c: s/__MINGW32__/_WIN32/ to help
        building on native Windows compilers.  Requested by Brian Gladman.
        From Werner on stable branch.
-       
+
        * http.c (connect_server): Oops - forgot to freeaddrinfo().
 
 2003-08-24  David Shaw  <dshaw@jabberwocky.com>
 
        * fileutil.c (is_file_compressed): Corrected the magic values
        for bzip2 and gzip. Noted by David.
-       
+
 2002-05-22  Werner Koch  <wk@gnupg.org>
 
        * fileutil.c (compare_filenames): Replaced stricmp by strcasecmp.
        enclose the string, and do not occur within the string.  This
        makes specifying a program under Win32 easier when you need quotes
        around part of a string, but not around the whole string.
-       
+
 2002-05-02  Werner Koch  <wk@gnupg.org>
 
-       * memory.c (alloc): Malloc at least 1 byte.  Noted by Winona Brown. 
+       * memory.c (alloc): Malloc at least 1 byte.  Noted by Winona Brown.
 
 2002-04-23  David Shaw  <dshaw@jabberwocky.com>
 
 2002-02-28  Timo Schulz  <ts@winpt.org>
 
        * http.c (write_server): Convert integer to a HANDLE for W32.
-       
+
 2002-01-27  David Shaw  <dshaw@jabberwocky.com>
 
        * iobuf.c (iobuf_fdopen, iobuf_sockopen): Do not cache fdopened
 
 2001-09-17  Werner Koch  <wk@gnupg.org>
 
-       * miscutil.c (print_string): Use explicit ranges and not iscntrl().  
+       * miscutil.c (print_string): Use explicit ranges and not iscntrl().
        (make_printable_string): Ditto.
 
 2001-09-07  Werner Koch  <wk@gnupg.org>
        * secmem.c [__riscos__]: Disabled secure memory stuff.
        * dotlock.c, ttyio.c [__riscos__]: Adapted for RISC OS
        * fileutil.c, iobuf.c: Adapted for RISC OS;  mainly replaced
-       hardcoded path separators with EXTSEP_S like macros. 
+       hardcoded path separators with EXTSEP_S like macros.
        * http.c (send_request): Use macros for the env-var name.
        * logger.c [__riscos__]: Do an fflush at the end of each log
-       function. 
+       function.
        * memory.c [__riscos__]: Minor patches
        * riscos.c (set_filetype): New.
 
        * secmem.c (lock_pool): Under HPUX mlock is broken but we might
        have plock, so we use this to lock the entire process.  By Albert
        Chin.
-       
+
 2001-07-03  Werner Koch  <wk@gnupg.org>
 
        * strgutil.c (utf8_to_native): Fixed printing of invalid utf-8
 
        * strgutil.c (vasprintf) [__MINGW32__]: New. Taken from libiberty.
        * ttyio.c (tty_printf) [__MINGW32__]:  Replaced the sprintf with
-       the new vasprintf. 
+       the new vasprintf.
 
 2001-06-05  Werner Koch  <wk@gnupg.org>
 
-       * dotlock.c (make_dotlock): Typo fixes. 
+       * dotlock.c (make_dotlock): Typo fixes.
 
 2001-05-25  Werner Koch  <wk@gnupg.org>
 
        everywhere in this file.
        (iobuf_translate_file_handle): Always use the osfhandle stuff here
        because callers don't know the implementation details of iobuf and
-       they expect that the handles are translated. 
+       they expect that the handles are translated.
 
 2001-03-29  Werner Koch  <wk@gnupg.org>
 
        * argparse.c (default_strusage): Changed year of printed copyright
        to 2001.
 
-       * iobuf.c (fd_cache_invalidate, fd_cache_close, fd_cache_open): New. 
+       * iobuf.c (fd_cache_invalidate, fd_cache_close, fd_cache_open): New.
        (direct_open): Invalidate the fd_cache for read access.
        (file_filter): Cache the close here.
        (iobuf_open): Use new my_fopen_ro macro to try the cache first.
         the right thing in an implementation-independent way.
         (fopen, fstat): Remove macros.
 
-        * iobuf.c (iobuf_set_limit, iobuf_tell, iobuf_seek): 
+        * iobuf.c (iobuf_set_limit, iobuf_tell, iobuf_seek):
         Use off_t, not ulong, for file offsets.
         (<limits.h>): Include if needed.
         (LONG_MAX, LONG_MIN): Define a substitute if needed.
index 40f4dd1..a8e4f9a 100644 (file)
@@ -51,7 +51,7 @@
 /* Parse the TXT resource record. Format is:
 
    v=pka1;fpr=a4d94e92b0986ab5ee9dcd755de249965b0358a2;uri=string
-   
+
    For simplicity white spaces are not allowed.  Because we expect to
    use a new RRTYPE for this in the future we define the TXT really
    strict for simplicity: No white spaces, case sensitivity of the
@@ -74,7 +74,7 @@ parse_txt_record (char *buffer, unsigned char *fpr)
   *pend++ = 0;
   if (strcmp (p, "v=pka1"))
     return -1; /* Wrong or missing version. */
-  
+
   p = pend;
   pend = strchr (p, ';');
   if (pend)
@@ -86,11 +86,11 @@ parse_txt_record (char *buffer, unsigned char *fpr)
     fpr[i] = xtoi_2 (p);
   if (i != 20)
     return -1; /* Fingerprint consists not of exactly 40 hexbytes. */
-    
+
   p = pend;
   if (!p || !*p)
     {
-      *buffer = 0;  
+      *buffer = 0;
       return 0; /* Success (no URI given). */
     }
   if (strncmp (p, "uri=", 4))
@@ -116,7 +116,11 @@ parse_txt_record (char *buffer, unsigned char *fpr)
 char *
 get_pka_info (const char *address, unsigned char *fpr)
 {
-  unsigned char answer[PACKETSZ];
+  union
+    {
+      signed char p[PACKETSZ];
+      HEADER h;
+    } answer;
   int anslen;
   int qdcount, ancount, nscount, arcount;
   int rc;
@@ -133,11 +137,11 @@ get_pka_info (const char *address, unsigned char *fpr)
   memcpy (name, address, domain - address);
   strcpy (stpcpy (name + (domain-address), "._pka."), domain+1);
 
-  anslen = res_query (name, C_IN, T_TXT, answer, PACKETSZ);
+  anslen = res_query (name, C_IN, T_TXT, answer.p, PACKETSZ);
   xfree (name);
   if (anslen < sizeof(HEADER))
     return NULL; /* DNS resolver returned a too short answer. */
-  if ( (rc=((HEADER*)answer)->rcode) != NOERROR )
+  if ( (rc=answer.h.rcode) != NOERROR )
     return NULL; /* DNS resolver returned an error. */
 
   /* We assume that PACKETSZ is large enough and don't do dynmically
@@ -145,23 +149,23 @@ get_pka_info (const char *address, unsigned char *fpr)
   if (anslen > PACKETSZ)
     return NULL; /* DNS resolver returned a too long answer */
 
-  qdcount = ntohs (((HEADER*)answer)->qdcount);
-  ancount = ntohs (((HEADER*)answer)->ancount);
-  nscount = ntohs (((HEADER*)answer)->nscount);
-  arcount = ntohs (((HEADER*)answer)->arcount);
+  qdcount = ntohs (answer.h.qdcount);
+  ancount = ntohs (answer.h.ancount);
+  nscount = ntohs (answer.h.nscount);
+  arcount = ntohs (answer.h.arcount);
 
   if (!ancount)
     return NULL; /* Got no answer. */
 
-  p = answer + sizeof (HEADER);
-  pend = answer + anslen; /* Actually points directly behind the buffer. */
+  p = answer.p + sizeof (HEADER);
+  pend = answer.p + anslen; /* Actually points directly behind the buffer. */
 
   while (qdcount-- && p < pend)
     {
       rc = dn_skipname (p, pend);
       if (rc == -1)
         return NULL;
-      p += rc + QFIXEDSZ; 
+      p += rc + QFIXEDSZ;
     }
 
   if (ancount > 1)