Armor works now
[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         iobuf_set_block_mode(inp, 1);
131     }
132     else {
133         for( ; lenbytes; lenbytes-- ) {
134             pktlen <<= 8;
135             pktlen |= hdr[hdrlen++] = iobuf_get_noeof(inp);
136         }
137     }
138
139     if( DBG_PACKET )
140         log_debug("parse_packet(iob=%d): type=%d length=%lu\n",
141                                             iobuf_id(inp), pkttype, pktlen );
142     pkt->pkttype = pkttype;
143     rc = G10ERR_UNKNOWN_PACKET; /* default to no error */
144     switch( pkttype ) {
145       case PKT_PUBKEY_CERT:
146         pkt->pkt.pubkey_cert = m_alloc_clear(sizeof *pkt->pkt.pubkey_cert );
147         rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt );
148         break;
149       case PKT_SECKEY_CERT:
150         pkt->pkt.seckey_cert = m_alloc_clear(sizeof *pkt->pkt.seckey_cert );
151         rc = parse_certificate(inp, pkttype, pktlen, hdr, hdrlen, pkt );
152         break;
153       case PKT_PUBKEY_ENC:
154         rc = parse_publickey(inp, pkttype, pktlen, pkt );
155         break;
156       case PKT_SIGNATURE:
157         pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
158         rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
159         m_check(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     m_check(sig);
269     md5_len = iobuf_get_noeof(inp); pktlen--;
270     sig->sig_class = iobuf_get_noeof(inp); pktlen--;
271     sig->timestamp = read_32(inp); pktlen -= 4;
272     sig->keyid[0] = read_32(inp); pktlen -= 4;
273     sig->keyid[1] = read_32(inp); pktlen -= 4;
274     sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
275     m_check(sig);
276     if( list_mode )
277         printf(":signature packet: keyid %08lX%08lX\n"
278                "\tversion %d, created %lu, md5len %d, sigclass %02x\n",
279                 sig->keyid[0], sig->keyid[1],
280                 version, sig->timestamp, md5_len, sig->sig_class );
281     if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
282         if( pktlen < 5 ) {
283             log_error("packet(%d) too short\n", pkttype);
284             goto leave;
285         }
286     m_check(sig);
287         sig->d.rsa.digest_algo = iobuf_get_noeof(inp); pktlen--;
288         sig->d.rsa.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
289         sig->d.rsa.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
290     m_check(sig);
291         n = pktlen;
292         sig->d.rsa.rsa_integer = mpi_decode(inp, &n ); pktlen -=n;
293         if( list_mode ) {
294             printf("\tdigest algo %d, begin of digest %02x %02x\n",
295                     sig->d.rsa.digest_algo,
296                     sig->d.rsa.digest_start[0], sig->d.rsa.digest_start[1] );
297             printf("\trsa integer: ");
298             mpi_print(stdout, sig->d.rsa.rsa_integer, mpi_print_mode );
299             putchar('\n');
300         }
301     }
302     else if( list_mode )
303         printf("\tunknown algorithm %d\n", sig->pubkey_algo );
304     m_check(sig);
305
306
307   leave:
308     skip_rest(inp, pktlen);
309     return 0;
310 }
311
312
313
314
315 static int
316 parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
317                               byte *hdr, int hdrlen, PACKET *pkt )
318 {
319     int i, version, algorithm;
320     unsigned n;
321     unsigned long timestamp;
322     unsigned short valid_period;
323     MPI rsa_pub_mod, rsa_pub_exp;
324
325     if( pkttype == PKT_PUBKEY_CERT ) {
326         pkt->pkt.pubkey_cert->mfx.md5 = md5_open(0);
327         pkt->pkt.pubkey_cert->mfx.rmd160 = rmd160_open(0);
328         pkt->pkt.pubkey_cert->mfx.maxbuf_size = 1;
329         md5_write(pkt->pkt.pubkey_cert->mfx.md5, hdr, hdrlen);
330         rmd160_write(pkt->pkt.pubkey_cert->mfx.rmd160, hdr, hdrlen);
331         iobuf_push_filter( inp, md_filter, &pkt->pkt.pubkey_cert->mfx );
332     }
333
334     if( pktlen < 12 ) {
335         log_error("packet(%d) too short\n", pkttype);
336         goto leave;
337     }
338     version = iobuf_get_noeof(inp); pktlen--;
339     if( version != 2 && version != 3 ) {
340         log_error("packet(%d) with unknown version %d\n", pkttype, version);
341         goto leave;
342     }
343
344     timestamp = read_32(inp); pktlen -= 4;
345     valid_period = read_16(inp); pktlen -= 2;
346     algorithm = iobuf_get_noeof(inp); pktlen--;
347     if( list_mode )
348         printf(":%s key certification packet:\n"
349                "\tversion %d, created %lu, valid for %hu days\n",
350                 pkttype == PKT_PUBKEY_CERT? "public": "secret",
351                 version, timestamp, valid_period );
352     if( pkttype == PKT_SECKEY_CERT )  {
353         pkt->pkt.seckey_cert->timestamp = timestamp;
354         pkt->pkt.seckey_cert->valid_days = valid_period;
355         pkt->pkt.seckey_cert->pubkey_algo = algorithm;
356     }
357     else {
358         pkt->pkt.pubkey_cert->timestamp = timestamp;
359         pkt->pkt.pubkey_cert->valid_days = valid_period;
360         pkt->pkt.pubkey_cert->pubkey_algo = algorithm;
361     }
362
363     if( algorithm == PUBKEY_ALGO_RSA ) {
364         n = pktlen; rsa_pub_mod = mpi_decode(inp, &n ); pktlen -=n;
365         n = pktlen; rsa_pub_exp = mpi_decode(inp, &n ); pktlen -=n;
366         if( list_mode ) {
367             printf(  "\tpublic modulus  n:  ");
368             mpi_print(stdout, rsa_pub_mod, mpi_print_mode  );
369             printf("\n\tpublic exponent e: ");
370             mpi_print(stdout, rsa_pub_exp, mpi_print_mode  );
371             putchar('\n');
372         }
373         if( pkttype == PKT_PUBKEY_CERT ) {
374             pkt->pkt.pubkey_cert->d.rsa.rsa_n = rsa_pub_mod;
375             pkt->pkt.pubkey_cert->d.rsa.rsa_e = rsa_pub_exp;
376         }
377         else {
378             PKT_seckey_cert *cert = pkt->pkt.seckey_cert;
379             byte temp[8];
380             byte *mpibuf;
381
382             pkt->pkt.seckey_cert->d.rsa.rsa_n = rsa_pub_mod;
383             pkt->pkt.seckey_cert->d.rsa.rsa_e = rsa_pub_exp;
384             cert->d.rsa.protect_algo = iobuf_get_noeof(inp); pktlen--;
385             if( list_mode )
386                 printf(  "\tprotect algo: %d\n", cert->d.rsa.protect_algo);
387             if( cert->d.rsa.protect_algo ) {
388                 cert->d.rsa.is_protected = 1;
389                 for(i=0; i < 8 && pktlen; i++, pktlen-- )
390                     temp[i] = iobuf_get_noeof(inp);
391                 if( list_mode ) {
392                     printf(  "\tprotect IV: ");
393                     for(i=0; i < 8; i++ )
394                         printf(" %02x", temp[i] );
395                     putchar('\n');
396                 }
397                 if( cert->d.rsa.protect_algo == CIPHER_ALGO_IDEA )
398                     memcpy(cert->d.rsa.protect.idea.iv, temp, 8 );
399                 else if( cert->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH )
400                     memcpy(cert->d.rsa.protect.blowfish.iv, temp, 8 );
401             }
402             else
403                 cert->d.rsa.is_protected = 0;
404
405             n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
406             cert->d.rsa.rsa_d = (MPI)mpibuf;
407
408             n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
409             cert->d.rsa.rsa_p = (MPI)mpibuf;
410
411             n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
412             cert->d.rsa.rsa_q = (MPI)mpibuf;
413
414             n = pktlen; mpibuf = mpi_read(inp, &n ); pktlen -=n; assert(n>=2);
415             cert->d.rsa.rsa_u = (MPI)mpibuf;
416
417             cert->d.rsa.csum = read_16(inp); pktlen -= 2;
418             cert->d.rsa.calc_csum = 0;
419             if( list_mode ) {
420                 printf("\t[secret values d,p,q,u are not shown]\n"
421                        "\tchecksum: %04hx\n", cert->d.rsa.csum);
422             }
423             if( !cert->d.rsa.is_protected ) { /* convert buffer to MPIs */
424               #define X(a) do {                                         \
425                     mpibuf = (byte*)cert->d.rsa.rsa_##a;                \
426                     cert->d.rsa.calc_csum += checksum( mpibuf );        \
427                     cert->d.rsa.rsa_##a = mpi_decode_buffer( mpibuf );  \
428                     m_free( mpibuf );                                   \
429                 } while(0)
430                 X(d);
431                 X(p);
432                 X(q);
433                 X(u);
434               #undef X
435              /* log_mpidump("rsa n=", cert->d.rsa.rsa_n );
436                 log_mpidump("rsa e=", cert->d.rsa.rsa_e );
437                 log_mpidump("rsa d=", cert->d.rsa.rsa_d );
438                 log_mpidump("rsa p=", cert->d.rsa.rsa_p );
439                 log_mpidump("rsa q=", cert->d.rsa.rsa_q );
440                 log_mpidump("rsa u=", cert->d.rsa.rsa_u ); */
441             }
442         }
443     }
444     else if( list_mode )
445         printf("\tunknown algorithm %d\n", algorithm );
446
447
448   leave:
449     if( pkttype == PKT_PUBKEY_CERT )
450         iobuf_pop_filter( inp, md_filter, &pkt->pkt.pubkey_cert->mfx );
451     skip_rest(inp, pktlen);
452     return 0;
453 }
454
455
456 static int
457 parse_user_id( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *packet )
458 {
459     byte *p;
460
461     packet->pkt.user_id = m_alloc(sizeof *packet->pkt.user_id  + pktlen - 1);
462     packet->pkt.user_id->len = pktlen;
463     p = packet->pkt.user_id->name;
464     for( ; pktlen; pktlen--, p++ )
465         *p = iobuf_get_noeof(inp);
466
467     if( list_mode ) {
468         int n = packet->pkt.user_id->len;
469         printf(":user id packet: \"");
470         for(p=packet->pkt.user_id->name; n; p++, n-- ) {
471             if( *p >= ' ' && *p <= 'z' )
472                 putchar(*p);
473             else
474                 printf("\\x%02x", *p );
475         }
476         printf("\"\n");
477     }
478     return 0;
479 }
480
481 static void
482 parse_comment( IOBUF inp, int pkttype, unsigned long pktlen )
483 {
484     if( list_mode ) {
485         printf(":comment packet: \"" );
486         for( ; pktlen; pktlen-- ) {
487             int c;
488             c = iobuf_get_noeof(inp);
489             if( c >= ' ' && c <= 'z' )
490                 putchar(c);
491             else
492                 printf("\\x%02x", c );
493         }
494         printf("\"\n");
495     }
496     skip_rest(inp, pktlen);
497 }
498
499
500 static void
501 parse_trust( IOBUF inp, int pkttype, unsigned long pktlen )
502 {
503     int c;
504
505     c = iobuf_get_noeof(inp);
506     if( list_mode )
507         printf(":trust packet: flag=%02x\n", c );
508   #if 0 /* fixme: depending on the context we have different interpretations*/
509     if( prev_packet_is_a_key_packet ) {
510         int ot = c & 7;   /* ownertrust bits (for the key owner) */
511
512             !ot ? "undefined" :
513         ot == 1 ? "unknown"   : /* we don't know the owner of this key */
514         ot == 2 ? "no"        : /* usually we do not trust this key owner */
515                                 /* to sign other keys */
516         ot == 5 ? "usually"   : /* usually we trust this key owner to sign */
517         ot == 6 ? "always"    : /* always trust this key owner to sign */
518         ot == 7 ? "ultimate"  : /* also present in the secret keyring */
519               ""                /* reserved value */
520         if( c & (1<<5) )
521             "key is disabled"
522         if( c & (1<<7) )
523             "buckstop"
524     else if( prev_packet_is_user_is_packet ) {
525             int kl = c & 3; /* keylegit bits */
526         0 = "unknown, undefined, or uninitialized trust"
527         1 = "we do not trust this key's ownership"
528         2 = "we have marginal confidence of this key's ownership"
529         3 = "we completely trust this key's ownership."
530          /* This one (3) requires either:
531           * - 1 ultimately trusted signature (SIGTRUST=7)
532           * - COMPLETES_NEEDED completely trusted signatures (SIGTRUST=6)
533           * - MARGINALS_NEEDED marginally trusted signatures (SIGTRUST=5)
534           */
535         if( c & 0x80 )
536             "warnonly"
537     else if( prev_packet_is_a_signature ) {
538          Bits 0-2 - SIGTRUST bits - Trust bits for this signature.  Value is
539                     copied directly from OWNERTRUST bits of signer:
540               000 - undefined, or uninitialized trust.
541               001 - unknown
542               010 - We do not trust this signature.
543               011 - reserved
544               100 - reserved
545               101 - We reasonably trust this signature.
546               110 - We completely trust this signature.
547               111 - ultimately trusted signature (from the owner of the ring)
548           Bit 6 - CHECKED bit - This means that the key checking pass (pgp -kc,
549                   also invoked automatically whenever keys are added to the
550                   keyring) has tested this signature and found it good.  If
551                   this bit is not set, the maintenance pass considers this
552                   signature untrustworthy.
553           Bit 7 - CONTIG bit - Means this signature leads up a contiguous trusted
554                   certification path all the way back to the ultimately-
555                   trusted keyring owner, where the buck stops.  This bit is derived
556                   from other trust packets.  It is currently not used for anything
557                   in PGP.
558     }
559   #endif
560 }
561
562
563 static int
564 parse_plaintext( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
565 {
566     int mode, namelen;
567     PKT_plaintext *pt;
568     byte *p;
569     int c, i;
570
571     if( pktlen && pktlen < 6 ) {
572         log_error("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
573         goto leave;
574     }
575     mode = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
576     namelen = iobuf_get_noeof(inp); if( pktlen ) pktlen--;
577     pt = pkt->pkt.plaintext = m_alloc(sizeof *pkt->pkt.plaintext + namelen -1);
578     pt->mode = mode;
579     pt->namelen = namelen;
580     if( pktlen ) {
581         for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
582             pt->name[i] = iobuf_get_noeof(inp);
583     }
584     else {
585         for( i=0; i < namelen; i++ )
586             if( (c=iobuf_get(inp)) == -1 )
587                 break;
588             else
589                 pt->name[i] = c;
590     }
591     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
592     pt->len = pktlen;
593     pt->buf = inp;
594     pktlen = 0;
595
596     if( list_mode ) {
597         printf(":literal data packet:\n"
598                "\tmode %c, created %lu, name=\"",
599                     mode >= ' ' && mode <'z'? mode : '?',
600                     pt->timestamp );
601         for(p=pt->name,i=0; i < namelen; p++, i++ ) {
602             if( *p >= ' ' && *p <= 'z' )
603                 putchar(*p);
604             else
605                 printf("\\x%02x", *p );
606         }
607         printf("\",\n\traw data: %lu bytes\n", pt->len );
608     }
609
610   leave:
611     return 0;
612 }
613
614
615 static int
616 parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
617 {
618     PKT_compressed *zd;
619     int algorithm;
620
621     /* pktlen is here 0, but data follows
622      * (this should be the last object in a file or
623      *  the compress algorithm should know the length)
624      */
625     zd = pkt->pkt.compressed =  m_alloc(sizeof *pkt->pkt.compressed );
626     zd->len = 0; /* not yet used */
627     zd->algorithm = iobuf_get_noeof(inp);
628     zd->buf = inp;
629     algorithm = iobuf_get_noeof(inp);
630     if( list_mode )
631         printf(":compressed packet: algo=%d\n", zd->algorithm);
632     return 0;
633 }
634
635
636 static int
637 parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen, PACKET *pkt )
638 {
639     PKT_encr_data *ed;
640
641     ed = pkt->pkt.encr_data =  m_alloc(sizeof *pkt->pkt.encr_data );
642     ed->len = pktlen;
643     ed->buf = NULL;
644     if( pktlen && pktlen < 10 ) {
645         log_error("packet(%d) too short\n", pkttype);
646         skip_rest(inp, pktlen);
647         goto leave;
648     }
649     if( list_mode )
650         if( pktlen )
651             printf(":encrypted data packet:\n\tlength: %lu\n", pktlen-10);
652         else
653             printf(":encrypted data packet:\n\tlength: unknown\n");
654
655     ed->buf = inp;
656     pktlen = 0;
657
658   leave:
659     return 0;
660 }
661
662