2003-09-28 Timo Schulz <twoaday@freakmail.de>
[gnupg.git] / g10 / parse-packet.c
index b9afb75..0831d26 100644 (file)
@@ -1,5 +1,6 @@
 /* parse-packet.c  - read packets
- * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002,
+ *               2003 Free Software Foundation, Inc.
  *
  * This file is part of GnuPG.
  *
@@ -41,9 +42,9 @@ static int list_mode = 0;
 
 static int  parse( IOBUF inp, PACKET *pkt, int onlykeypkts,
                   off_t *retpos, int *skip, IOBUF out, int do_skip
-           #ifdef DEBUG_PARSE_PACKET
+#ifdef DEBUG_PARSE_PACKET
                   ,const char *dbg_w, const char *dbg_f, int dbg_l
-           #endif
+#endif
                 );
 static int  copy_packet( IOBUF inp, IOBUF out, int pkttype,
                                               unsigned long pktlen );
@@ -366,8 +367,28 @@ parse( IOBUF inp, PACKET *pkt, int onlykeypkts, off_t *retpos,
        lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
        if( !lenbytes ) {
            pktlen = 0; /* don't know the value */
-           if( pkttype != PKT_COMPRESSED )
-               iobuf_set_block_mode(inp, 1);
+            switch (pkttype) {
+              case PKT_ENCRYPTED:
+              case PKT_PLAINTEXT:
+                /* These partial length encodings are from an very
+                  early GnuPG release and deprecated.  However we
+                  still support them read-wise.  Note, that we should
+                  not allow them for any key related packets, because
+                  this might render a keyring unusable if an errenous
+                  packet indicated this mode but not complying to it
+                  gets imported. */
+                iobuf_set_block_mode(inp, 1);
+               break;
+
+              case PKT_COMPRESSED:
+                break; /* the orginal pgp 2 way. */
+
+              default:
+                log_error ("%s: old style partial length "
+                           "for invalid packet type\n", iobuf_where(inp) );
+                rc = G10ERR_INVALID_PACKET;
+                goto leave;
+            }
        }
        else {
            for( ; lenbytes; lenbytes-- ) {
@@ -860,7 +881,8 @@ dump_sig_subpkt( int hashed, int type, int critical,
          printf(" %02X", buffer[i]);
        break;
       case SIGSUBPKT_PREF_KS:
-       p = "preferred key server";
+       fputs("preferred key server: ", stdout );
+       print_string( stdout, buffer, length, ')' );
        break;
       case SIGSUBPKT_PRIMARY_UID:
        p = "primary user ID";
@@ -936,6 +958,7 @@ parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
       case SIGSUBPKT_PREF_HASH:
       case SIGSUBPKT_PREF_COMPR:
       case SIGSUBPKT_POLICY:
+      case SIGSUBPKT_PREF_KS:
       case SIGSUBPKT_FEATURES:
       case SIGSUBPKT_REGEXP:
        return 0;
@@ -992,9 +1015,11 @@ can_handle_critical( const byte *buffer, size_t n, int type )
       case SIGSUBPKT_KEY_FLAGS:
       case SIGSUBPKT_PRIMARY_UID:
       case SIGSUBPKT_FEATURES:
-      case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
       case SIGSUBPKT_TRUST:
       case SIGSUBPKT_REGEXP:
+       /* Is it enough to show the policy or keyserver? */
+      case SIGSUBPKT_POLICY:
+      case SIGSUBPKT_PREF_KS:
        return 1;
 
       default:
@@ -1220,11 +1245,8 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
            goto leave;
        }
        if( n ) {
-            /* we add 8 extra bytes so that we have space for the signature
-             * status cache.  Well we are wasting this if there is a cache
-             * packet already, but in the other case it avoids an realloc */
-           sig->unhashed = m_alloc (sizeof(*sig->unhashed) + n + 8 - 1 );
-            sig->unhashed->size = n + 8;
+           sig->unhashed = m_alloc (sizeof(*sig->unhashed) + n - 1 );
+            sig->unhashed->size = n;
            sig->unhashed->len = n;
            if( iobuf_read(inp, sig->unhashed->data, n ) != n ) {
                log_error("premature eof while reading "
@@ -1259,17 +1281,19 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
        }
 
        p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
-       if( !p )
-           log_error("signature packet without timestamp\n");
-       else
-           sig->timestamp = buffer_to_u32(p);
+       if(p)
+         sig->timestamp = buffer_to_u32(p);
+       else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
+         log_error("signature packet without timestamp\n");
+
        p = parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
-       if( !p )
-           log_error("signature packet without keyid\n");
-       else {
+       if(p)
+         {
            sig->keyid[0] = buffer_to_u32(p);
            sig->keyid[1] = buffer_to_u32(p+4);
-       }
+         }
+       else if(!(sig->pubkey_algo>=100 && sig->pubkey_algo<=110))
+         log_error("signature packet without keyid\n");
 
        p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
        if(p)
@@ -1281,6 +1305,10 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
        if(p)
          sig->flags.policy_url=1;
 
+       p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_PREF_KS,NULL);
+       if(p)
+         sig->flags.pref_ks=1;
+
        p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
        if(p)
          sig->flags.notation=1;
@@ -1546,6 +1574,7 @@ parse_key( IOBUF inp, int pkttype, unsigned long pktlen,
        pk->req_usage = 0; 
        pk->pubkey_usage = 0; /* not yet used */
         pk->is_revoked = 0;
+       pk->is_disabled = 0;
        pk->keyid[0] = 0;
        pk->keyid[1] = 0;
     }