IDEA removed, signing works
[gnupg.git] / g10 / parse-packet.c
1 /* parse-packet.c  - read packets
2  *      Copyright (c) 1997 by Werner Koch (dd9jn)
3  *
4  * This file is part of G10.
5  *
6  * G10 is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * G10 is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26
27 #include "packet.h"
28 #include "iobuf.h"
29 #include "mpi.h"
30 #include "util.h"
31 #include "cipher.h"
32 #include "memory.h"
33 #include "filter.h"
34 #include "options.h"
35
36 static mpi_print_mode = 0;
37 static list_mode = 0;
38
39 static void skip_packet( IOBUF inp, int pkttype, unsigned long pktlen );
40 static void skip_rest( IOBUF inp, unsigned long pktlen );
41 static int  parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen,
42                                                              PACKET *packet );
43 static int  parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
44                                                          PKT_signature *sig );
45 static int  parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
46                                       byte *hdr, int hdrlen, PACKET *packet );
47 static int  parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen,
48                                                            PACKET *packet );
49 static void parse_comment( IOBUF inp, int pkttype, unsigned long pktlen );
50 static void parse_trust( IOBUF inp, int pkttype, unsigned long pktlen );
51 static int  parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen,
52                                                                 PACKET *pkt );
53 static int  parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
54                                                            PACKET *packet );
55 static int  parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
56                                                            PACKET *packet );
57
58 static u16
59 checksum( byte *p )
60 {
61     u16 n, a;
62
63     n = *p++ << 8;
64     n |= *p++;
65     for(a=0; n; n-- )
66         a += *p++;
67     return a;
68 }
69
70 static unsigned short
71 read_16(IOBUF inp)
72 {
73     unsigned short a;
74     a = iobuf_get_noeof(inp) << 8;
75     a |= iobuf_get_noeof(inp);
76     return a;
77 }
78
79 static unsigned long
80 read_32(IOBUF inp)
81 {
82     unsigned long a;
83     a =  iobuf_get_noeof(inp) << 24;
84     a |= iobuf_get_noeof(inp) << 16;
85     a |= iobuf_get_noeof(inp) << 8;
86     a |= iobuf_get_noeof(inp);
87     return a;
88 }
89
90 int
91 set_packet_list_mode( int mode )
92 {
93     int old = list_mode;
94     list_mode = mode;
95     mpi_print_mode = DBG_MPI;
96     return old;
97 }
98
99 /****************
100  * Parse a Packet and return it in packet
101  * Returns: 0 := valid packet in pkt
102  *         -1 := no more packets
103  *         >0 := error
104  * Note: The function may return an error and a partly valid packet;
105  * caller must free this packet.
106  */
107 int
108 parse_packet( IOBUF inp, PACKET *pkt )
109 {
110     int rc, ctb, pkttype, lenbytes;
111     unsigned long pktlen;
112     byte hdr[5];
113     int hdrlen;
114
115     assert( !pkt->pkt.generic );
116     if( (ctb = iobuf_get(inp)) == -1 )
117         return -1;
118     hdrlen=0;
119     hdr[hdrlen++] = ctb;
120     if( !(ctb & 0x80) ) {
121         log_error("invalid packet at '%s'\n", iobuf_where(inp) );
122         return G10ERR_INVALID_PACKET;
123     }
124     /* we handle the pgp 3 extensions here, so that we can skip such packets*/
125     pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
126     lenbytes = (ctb & 0x40) || ((ctb&3)==3)? 0 : (1<<(ctb & 3));
127     pktlen = 0;
128     if( !lenbytes ) {
129         pktlen = 0; /* don't know the value */
130         if( pkttype != PKT_COMPR_DATA )
131             iobuf_set_block_mode(inp, 1);
132     }
133     else {
134         for( ; lenbytes; lenbytes-- ) {
135             pktlen <<= 8;
136             pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp);
137         }
138     }
139
140     if( DBG_PACKET )
141         log_debug("parse_packet(iob=%d): type=%d length=%lu\n",
142                                             iobuf_id(inp), pkttype, pktlen );
143     pkt->pkttype = pkttype;
144     rc = G10ERR_UNKNOWN_PACKET; /* default to no error */
145     switch( pkttype ) {
146       case PKT_PUBKEY_CERT:
147         pkt->pkt.pubkey_cert = m_alloc_clear(sizeof *pkt->pkt.pubkey_cert );
148         rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt );
149         break;
150       case PKT_SECKEY_CERT:
151         pkt->pkt.seckey_cert = m_alloc_clear(sizeof *pkt->pkt.seckey_cert );
152         rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt );
153         break;
154       case PKT_PUBKEY_ENC:
155         rc = parse_publickey(inp, pkttype, pktlen, pkt );
156         break;
157       case PKT_SIGNATURE:
158         pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
159         rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
160         break;
161       case PKT_USER_ID:
162         rc = parse_user_id(inp, pkttype, pktlen, pkt );
163         break;
164       case PKT_COMMENT:
165         parse_comment(inp, pkttype, pktlen);
166         break;
167       case PKT_RING_TRUST:
168         parse_trust(inp, pkttype, pktlen);
169         break;
170       case PKT_PLAINTEXT:
171         rc = parse_plaintext(inp, pkttype, pktlen, pkt );
172         break;
173       case PKT_COMPR_DATA:
174         rc = parse_compressed(inp, pkttype, pktlen, pkt );
175         break;
176       case PKT_ENCR_DATA:
177         rc = parse_encrypted(inp, pkttype, pktlen, pkt );
178         break;
179       default:
180         skip_packet(inp, pkttype, pktlen);
181         break;
182     }
183
184     return rc;
185 }
186
187
188 static void
189 skip_packet( IOBUF inp, int pkttype, unsigned long pktlen )
190 {
191     if( list_mode )
192         printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen );
193     skip_rest(inp,pktlen);
194 }
195
196 static void
197 skip_rest( IOBUF inp, unsigned long pktlen )
198 {
199     if( iobuf_in_block_mode(inp) ) {
200         while( iobuf_get(inp) != -1 )
201                 ;
202     }
203     else {
204         for( ; pktlen; pktlen-- )
205             iobuf_get(inp);
206     }
207 }
208
209
210 static int
211 parse_publickey( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
212 {
213     int version;
214     unsigned n;
215     PKT_pubkey_enc *k;
216
217     k = packet->pkt.pubkey_enc = m_alloc(sizeof *packet->pkt.pubkey_enc );
218     if( pktlen < 12 ) {
219         log_error("packet(%d) too short\n", pkttype);
220         goto leave;
221     }
222     version = iobuf_get_noeof(inp); pktlen--;
223     if( version != 2 && version != 3 ) {
224         log_error("packet(%d) with unknown version %d\n", pkttype, version);
225         goto leave;
226     }
227     k->keyid[0] = read_32(inp); pktlen -= 4;
228     k->keyid[1] = read_32(inp); pktlen -= 4;
229     k->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
230     if( list_mode )
231         printf(":public key packet: keyid %08lX%08lX\n",
232                                         k->keyid[0], k->keyid[1]);
233     if( k->pubkey_algo == PUBKEY_ALGO_RSA ) {
234         n = pktlen;
235         k->d.rsa.rsa_integer = mpi_decode(inp, &n ); pktlen -=n;
236         if( list_mode ) {
237             printf("\trsa integer: ");
238             mpi_print(stdout, k->d.rsa.rsa_integer, mpi_print_mode );
239             putchar('\n');
240         }
241     }
242     else if( list_mode )
243         printf("\tunknown algorithm %d\n", k->pubkey_algo );
244
245
246   leave:
247     skip_rest(inp, pktlen);
248     return 0;
249 }
250
251
252 static int
253 parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
254                                           PKT_signature *sig )
255 {
256     int version, md5_len;
257     unsigned n;
258
259     if( pktlen < 16 ) {
260         log_error("packet(%d) too short\n", pkttype);
261         goto leave;
262     }
263     version = iobuf_get_noeof(inp); pktlen--;
264     if( version != 2 && version != 3 ) {
265         log_error("packet(%d) with unknown version %d\n", pkttype, version);
266         goto leave;
267     }
268     md5_len = iobuf_get_noeof(inp); pktlen--;
269     sig->sig_class = iobuf_get_noeof(inp); pktlen--;
270     sig->timestamp = read_32(inp); pktlen -= 4;
271     sig->keyid[0] = read_32(inp); pktlen -= 4;
272     sig->keyid[1] = read_32(inp); pktlen -= 4;
273     sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
274     if( list_mode )
275         printf(":signature packet: keyid %08lX%08lX\n"
276                "\tversion %d, created %lu, md5len %d, sigclass %02x\n",
277                 sig->keyid[0], sig->keyid[1],
278                 version, sig->timestamp, md5_len, sig->sig_class );
279     if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
280         if( pktlen < 5 ) {
281             log_error("packet(%d) too short\n", pkttype);
282             goto leave;
283         }
284         sig->d.rsa.digest_algo = iobuf_get_noeof(inp); pktlen--;
285         sig->d.rsa.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
286         sig->d.rsa.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
287         n = pktlen;
288         sig->d.rsa.rsa_integer = mpi_decode(inp, &n ); pktlen -=n;
289         if( list_mode ) {
290             printf("\tdigest algo %d, begin of digest %02x %02x\n",
291                     sig->d.rsa.digest_algo,
292                     sig->d.rsa.digest_start[0], sig->d.rsa.digest_start[1] );
293             printf("\trsa integer: ");
294             mpi_print(stdout, sig->d.rsa.rsa_integer, mpi_print_mode );
295             putchar('\n');
296         }
297     }
298     else if( list_mode )
299         printf("\tunknown algorithm %d\n", sig->pubkey_algo );
300
301
302   leave:
303     skip_rest(inp, pktlen);
304     return 0;
305 }
306
307
308
309
310 static int
311 parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
312                               byte *hdr, int hdrlen, PACKET *pkt )
313 {
314     int i, version, algorithm;
315     unsigned n;
316     unsigned long timestamp;
317     unsigned short valid_period;
318     MPI rsa_pub_mod, rsa_pub_exp;
319
320     if( pkttype == PKT_PUBKEY_CERT ) {
321         pkt->pkt.pubkey_cert->mfx.md5 = md5_open(0);
322         pkt->pkt.pubkey_cert->mfx.rmd160 = rmd160_open(0);
323         pkt->pkt.pubkey_cert->mfx.maxbuf_size = 1;
324         md5_write(pkt->pkt.pubkey_cert->mfx.md5, hdr, hdrlen);
325         rmd160_write(pkt->pkt.pubkey_cert->mfx.rmd160, hdr, hdrlen);
326         iobuf_push_filter( inp, md_filter, &pkt->pkt.pubkey_cert->mfx );
327     }
328
329     if( pktlen < 12 ) {
330         log_error("packet(%d) too short\n", pkttype);
331         goto leave;
332     }
333     version = iobuf_get_noeof(inp); pktlen--;
334     if( version != 2 && version != 3 ) {
335         log_error("packet(%d) with unknown version %d\n", pkttype, version);
336         goto leave;
337     }
338
339     timestamp = read_32(inp); pktlen -= 4;
340     valid_period = read_16(inp); pktlen -= 2;
341     algorithm = iobuf_get_noeof(inp); pktlen--;
342     if( list_mode )
343         printf(":%s key certification packet:\n"
344                "\tversion %d, created %lu, valid for %hu days\n",
345                 pkttype == PKT_PUBKEY_CERT? "public": "secret",
346                 version, timestamp, valid_period );
347     if( pkttype == PKT_SECKEY_CERT )  {
348         pkt->pkt.seckey_cert->timestamp = timestamp;
349         pkt->pkt.seckey_cert->valid_days = valid_period;
350         pkt->pkt.seckey_cert->pubkey_algo = algorithm;
351     }
352     else {
353         pkt->pkt.pubkey_cert->timestamp = timestamp;
354         pkt->pkt.pubkey_cert->valid_days = valid_period;
355         pkt->pkt.pubkey_cert->pubkey_algo = algorithm;
356     }
357
358     if( algorithm == PUBKEY_ALGO_RSA ) {
359         n = pktlen; rsa_pub_mod = mpi_decode(inp, &n ); pktlen -=n;
360         n = pktlen; rsa_pub_exp = mpi_decode(inp, &n ); pktlen -=n;
361         if( list_mode ) {
362             printf(  "\tpublic modulus  n:  ");
363             mpi_print(stdout, rsa_pub_mod, mpi_print_mode  );
364             printf("\n\tpublic exponent e: ");
365             mpi_print(stdout, rsa_pub_exp, mpi_print_mode  );
366             putchar('\n');
367         }
368         if( pkttype == PKT_PUBKEY_CERT ) {
369             pkt->pkt.pubkey_cert->d.rsa.rsa_n = rsa_pub_mod;
370             pkt->pkt.pubkey_cert->d.rsa.rsa_e = rsa_pub_exp;
371         }
372         else {
373             PKT_seckey_cert *cert = pkt->pkt.seckey_cert;
374             byte temp[8];
375             byte *mpibuf;
376
377             pkt->pkt.seckey_cert->d.rsa.rsa_n = rsa_pub_mod;
378             pkt->pkt.seckey_cert->d.rsa.rsa_e = rsa_pub_exp;
379             cert->d.rsa.protect_algo = iobuf_get_noeof(inp); pktlen--;
380             if( list_mode )
381                 printf(  "\tprotect algo: %d\n", cert->d.rsa.protect_algo);
382             if( cert->d.rsa.protect_algo ) {
383                 cert->d.rsa.is_protected = 1;
384                 for(i=0; i < 8 && pktlen; i++, pktlen-- )
385                     temp[i] = iobuf_get_noeof(inp);
386                 if( list_mode ) {
387                     printf(  "\tprotect IV: ");
388                     for(i=0; i < 8; i++ )
389                         printf(" %02x", temp[i] );
390                     putchar('\n');
391                 }
392                 if( cert->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH )
393                     memcpy(cert->d.rsa.protect.blowfish.iv, temp, 8 );
394             }
395             else
396                 cert->d.rsa.is_protected = 0;
397
398             n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
399             cert->d.rsa.rsa_d = (MPI)mpibuf;
400
401             n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
402             cert->d.rsa.rsa_p = (MPI)mpibuf;
403
404             n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
405             cert->d.rsa.rsa_q = (MPI)mpibuf;
406
407             n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
408             cert->d.rsa.rsa_u = (MPI)mpibuf;
409
410             cert->d.rsa.csum = read_16(inp); pktlen -= 2;
411             cert->d.rsa.calc_csum = 0;
412             if( list_mode ) {
413                 printf("\t[secret values d,p,q,u are not shown]\n"
414                        "\tchecksum: %04hx\n", cert->d.rsa.csum);
415             }
416             if( !cert->d.rsa.is_protected ) { /* convert buffer to MPIs */
417               #define X(a) do {                                         \
418                     mpibuf = (byte*)cert->d.rsa.rsa_##a;                \
419                     cert->d.rsa.calc_csum += checksum( mpibuf );        \
420                     cert->d.rsa.rsa_##a = mpi_decode_buffer( mpibuf );  \
421                     m_free( mpibuf );                                   \
422                 } while(0)
423                 X(d);
424                 X(p);
425                 X(q);
426                 X(u);
427               #undef X
428              /* log_mpidump("rsa n=", cert->d.rsa.rsa_n );
429                 log_mpidump("rsa e=", cert->d.rsa.rsa_e );
430                 log_mpidump("rsa d=", cert->d.rsa.rsa_d );
431                 log_mpidump("rsa p=", cert->d.rsa.rsa_p );
432                 log_mpidump("rsa q=", cert->d.rsa.rsa_q );
433                 log_mpidump("rsa u=", cert->d.rsa.rsa_u ); */
434             }
435         }
436     }
437     else if( list_mode )
438         printf("\tunknown algorithm %d\n", algorithm );
439
440
441   leave:
442     if( pkttype == PKT_PUBKEY_CERT )
443         iobuf_pop_filter( inp, md_filter, &pkt->pkt.pubkey_cert->mfx );
444     skip_rest(inp, pktlen);
445     return 0;
446 }
447
448
449 static int
450 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
451 {
452     byte *p;
453
454     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id  + pktlen - 1);
455     packet->pkt.user_id->len = pktlen;
456     p = packet->pkt.user_id->name;
457     for( ; pktlen; pktlen--, p++ )
458         *p = iobuf_get_noeof(inp);
459
460     if( list_mode ) {
461         int n = packet->pkt.user_id->len;
462         printf(":user id packet: \"");
463         for(p=packet->pkt.user_id->name; n; p++, n-- ) {
464             if( *p >= ' ' && *p <= 'z' )
465                 putchar(*p);
466             else
467                 printf("\\x%02x", *p );
468         }
469         printf("\"\n");
470     }
471     return 0;
472 }
473
474 static void
475 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen )
476 {
477     if( list_mode ) {
478         printf(":comment packet: \"" );
479         for( ; pktlen; pktlen-- ) {
480             int c;
481             c = iobuf_get_noeof(inp);
482             if( c >= ' ' && c <= 'z' )
483                 putchar(c);
484             else
485                 printf("\\x%02x", c );
486         }
487         printf("\"\n");
488     }
489     skip_rest(inp, pktlen);
490 }
491
492
493 static void
494 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen )
495 {
496     int c;
497
498     c = iobuf_get_noeof(inp);
499     if( list_mode )
500         printf(":trust packet: flag=%02x\n", c );
501   #if 0 /* fixme: depending on the context we have different interpretations*/
502     if( prev_packet_is_a_key_packet ) {
503         int ot = c & 7;   /* ownertrust bits (for the key owner) */
504
505             !ot ? "undefined" :
506         ot == 1 ? "unknown"   : /* we don't know the owner of this key */
507         ot == 2 ? "no"        : /* usually we do not trust this key owner */
508                                 /* to sign other keys */
509         ot == 5 ? "usually"   : /* usually we trust this key owner to sign */
510         ot == 6 ? "always"    : /* always trust this key owner to sign */
511         ot == 7 ? "ultimate"  : /* also present in the secret keyring */
512               ""                /* reserved value */
513         if( c & (1<<5) )
514             "key is disabled"
515         if( c & (1<<7) )
516             "buckstop"
517     else if( prev_packet_is_user_is_packet ) {
518             int kl = c & 3; /* keylegit bits */
519         0 = "unknown, undefined, or uninitialized trust"
520         1 = "we do not trust this key's ownership"
521         2 = "we have marginal confidence of this key's ownership"
522         3 = "we completely trust this key's ownership."
523          /* This one (3) requires either:
524           * - 1 ultimately trusted signature (SIGTRUST=7)
525           * - COMPLETES_NEEDED completely trusted signatures (SIGTRUST=6)
526           * - MARGINALS_NEEDED marginally trusted signatures (SIGTRUST=5)
527           */
528         if( c & 0x80 )
529             "warnonly"
530     else if( prev_packet_is_a_signature ) {
531          Bits 0-2 - SIGTRUST bits - Trust bits for this signature.  Value is
532                     copied directly from OWNERTRUST bits of signer:
533               000 - undefined, or uninitialized trust.
534               001 - unknown
535               010 - We do not trust this signature.
536               011 - reserved
537               100 - reserved
538               101 - We reasonably trust this signature.
539               110 - We completely trust this signature.
540               111 - ultimately trusted signature (from the owner of the ring)
541           Bit 6 - CHECKED bit - This means that the key checking pass (pgp -kc,
542                   also invoked automatically whenever keys are added to the
543                   keyring) has tested this signature and found it good.  If
544                   this bit is not set, the maintenance pass considers this
545                   signature untrustworthy.
546           Bit 7 - CONTIG bit - Means this signature leads up a contiguous trusted
547                   certification path all the way back to the ultimately-
548                   trusted keyring owner, where the buck stops.  This bit is derived
549                   from other trust packets.  It is currently not used for anything
550                   in PGP.
551     }
552   #endif
553 }
554
555
556 static int
557 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
558 {
559     int mode, namelen;
560     PKT_plaintext *pt;
561     byte *p;
562     int c, i;
563
564     if( pktlen && pktlen < 6 ) {
565         log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
566         goto leave;
567     }
568     mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
569     namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
570     pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1);
571     pt->mode = mode;
572     pt->namelen = namelen;
573     if( pktlen ) {
574         for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
575             pt->name[i] = iobuf_get_noeof(inp);
576     }
577     else {
578         for( i=0; i < namelen; i++ )
579             if( (c=iobuf_get(inp)) == -1 )
580                 break;
581             else
582                 pt->name[i] = c;
583     }
584     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
585     pt->len = pktlen;
586     pt->buf = inp;
587     pktlen = 0;
588
589     if( list_mode ) {
590         printf(":literal data packet:\n"
591                "\tmode %c, created %lu, name=\"",
592                     mode >= ' ' && mode <'z'? mode : '?',
593                     pt->timestamp );
594         for(p=pt->name,i=0; i < namelen; p++, i++ ) {
595             if( *p >= ' ' && *p <= 'z' )
596                 putchar(*p);
597             else
598                 printf("\\x%02x", *p );
599         }
600         printf("\",\n\traw data: %lu bytes\n", pt->len );
601     }
602
603   leave:
604     return 0;
605 }
606
607
608 static int
609 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
610 {
611     PKT_compressed *zd;
612     int algorithm;
613
614     /* pktlen is here 0, but data follows
615      * (this should be the last object in a file or
616      *  the compress algorithm should know the length)
617      */
618     zd = pkt->pkt.compressed =  m_alloc(sizeof *pkt->pkt.compressed );
619     zd->len = 0; /* not yet used */
620     zd->algorithm = iobuf_get_noeof(inp);
621     zd->buf = inp;
622     if( list_mode )
623         printf(":compressed packet: algo=%d\n", zd->algorithm);
624     return 0;
625 }
626
627
628 static int
629 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
630 {
631     PKT_encr_data *ed;
632
633     ed = pkt->pkt.encr_data =  m_alloc(sizeof *pkt->pkt.encr_data );
634     ed->len = pktlen;
635     ed->buf = NULL;
636     if( pktlen && pktlen < 10 ) {
637         log_error("packet(%d) too short\n", pkttype);
638         skip_rest(inp, pktlen);
639         goto leave;
640     }
641     if( list_mode )
642         if( pktlen )
643             printf(":encrypted data packet:\n\tlength: %lu\n", pktlen-10);
644         else
645             printf(":encrypted data packet:\n\tlength: unknown\n");
646
647     ed->buf = inp;
648     pktlen = 0;
649
650   leave:
651     return 0;
652 }
653
654