/[winpt]/trunk/Gnupg/parse-packet.c
ViewVC logotype

Annotation of /trunk/Gnupg/parse-packet.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 133 - (hide annotations)
Mon Jan 9 09:15:29 2006 UTC (19 years, 1 month ago) by twoaday
File MIME type: text/plain
File size: 74351 byte(s)
A lot of minor bug fixes.
New icons.

For a complete history, see the ChangeLog entries.


1 werner 46 /* parse-packet.c - read packets
2     * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3     *
4     * This file is part of GnuPG.
5     *
6     * GnuPG 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     * GnuPG 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     #ifdef HAVE_CONFIG_H
22     #include <config.h>
23     #endif
24    
25     #include <stdio.h>
26     #include <stdio.h>
27     #include <stdlib.h>
28     #include <string.h>
29     #include <time.h>
30     #include <assert.h>
31     #include <process.h>
32     #include <sys/types.h>
33    
34     #include "openpgp.h"
35     #include "packet.h"
36     #include "md.h"
37    
38     static int mpi_print_mode = 0;
39     static int list_mode = 0;
40    
41     static int parse( gpg_iobuf_t inp, PACKET *pkt, int onlykeypkts,
42     _off_t *retpos, int *skip, gpg_iobuf_t out, int do_skip );
43     static int copy_packet( gpg_iobuf_t inp, gpg_iobuf_t out, int pkttype,
44     unsigned long pktlen );
45     static void skip_packet( gpg_iobuf_t inp, int pkttype, unsigned long pktlen );
46     static void skip_rest( gpg_iobuf_t inp, unsigned long pktlen );
47     static void *read_rest( gpg_iobuf_t inp, size_t pktlen );
48     static int parse_symkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
49     PACKET *packet );
50     static int parse_pubkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
51     PACKET *packet );
52     static int parse_signature( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
53     PKT_signature *sig );
54     static int parse_onepass_sig( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
55     PKT_onepass_sig *ops );
56     static int parse_key( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
57     byte *hdr, int hdrlen, PACKET *packet );
58     static int parse_user_id( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
59     PACKET *packet );
60     static int parse_attribute( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
61     PACKET *packet );
62     static int parse_comment( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
63     PACKET *packet );
64     static void parse_trust( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
65     PACKET *packet );
66     static int parse_plaintext( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
67     PACKET *packet, int new_ctb);
68     static int parse_compressed( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
69     PACKET *packet, int new_ctb );
70     static int parse_encrypted( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
71     PACKET *packet, int new_ctb);
72     static int parse_mdc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
73     PACKET *packet, int new_ctb);
74     static int parse_gpg_control( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
75     PACKET *packet );
76    
77     static unsigned short
78     read_16(gpg_iobuf_t inp)
79     {
80     unsigned short a;
81     a = gpg_iobuf_get_noeof(inp) << 8;
82     a |= gpg_iobuf_get_noeof(inp);
83     return a;
84     }
85    
86     static unsigned long
87     read_32(gpg_iobuf_t inp)
88     {
89     unsigned long a;
90     a = gpg_iobuf_get_noeof(inp) << 24;
91     a |= gpg_iobuf_get_noeof(inp) << 16;
92     a |= gpg_iobuf_get_noeof(inp) << 8;
93     a |= gpg_iobuf_get_noeof(inp);
94     return a;
95     }
96    
97     static unsigned long
98     buffer_to_u32( const unsigned char *buffer )
99     {
100     unsigned long a;
101     a = *buffer << 24;
102     a |= buffer[1] << 16;
103     a |= buffer[2] << 8;
104     a |= buffer[3];
105     return a;
106     }
107    
108     int
109     set_packet_list_mode( int mode )
110     {
111     int old = list_mode;
112     list_mode = mode;
113     mpi_print_mode = 0;
114     return old;
115     }
116    
117 twoaday 2 static void
118 werner 46 unknown_pubkey_warning( int algo )
119     {
120     static byte unknown_pubkey_algos[256];
121    
122     algo &= 0xff;
123     if( !unknown_pubkey_algos[algo] ) {
124     unknown_pubkey_algos[algo] = 1;
125     }
126     }
127    
128     static const char *
129     strtimestamp( unsigned long stamp )
130     {
131     static char buffer[11+5];
132     struct tm *tp;
133     time_t atime = stamp;
134    
135     if (atime < 0) {
136     strcpy (buffer, "????" "-??" "-??");
137     }
138     else {
139     tp = gmtime( &atime );
140     sprintf(buffer,"%04d-%02d-%02d",
141     1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
142     }
143     return buffer;
144     }
145    
146     static const char *
147     strtimevalue( unsigned long value )
148     {
149     static char buffer[30];
150     unsigned int years, days, hours, minutes;
151    
152     value /= 60;
153     minutes = value % 60;
154     value /= 60;
155     hours = value % 24;
156     value /= 24;
157     days = value % 365;
158     value /= 365;
159     years = value;
160    
161     sprintf(buffer,"%uy%ud%uh%um", years, days, hours, minutes );
162     if( years )
163     return buffer;
164     if( days )
165     return strchr( buffer, 'y' ) + 1;
166     return strchr( buffer, 'd' ) + 1;
167     }
168    
169    
170     static gpg_mpi_t
171     mpi_read( gpg_iobuf_t inp, size_t *ret_n, int flags )
172     {
173     gpg_mpi_t a;
174     int i = 0, j = 0;
175     u32 t;
176     size_t n;
177    
178     a = calloc( 1, sizeof *a );
179     a->nbits = read_16( inp );
180     n = (a->nbits + 7) / 8;
181     a->alloced = n;
182     a->d = calloc( n, 4 );
183     i = 4 - n % 4;
184     i %= 4;
185     j = (n+4-1) / 4;
186     for( ; j > 0; j-- ) {
187     t = 0;
188     for( ; i < 4; i++ ) {
189     t <<= 8;
190     t |= gpg_iobuf_get( inp ) & 0xff;
191     }
192     i = 0;
193     a->d[j-1] = t;
194     }
195     if( *ret_n )
196     *ret_n = n + 2;
197    
198     return a;
199     }
200    
201     void
202     mpi_print( FILE *fp, gpg_mpi_t a, int mode )
203     {
204     int i;
205     for( i = 0; i < a->alloced / 4; i++ )
206     printf( "%08lx", a->d[i] );
207     }
208    
209     static void
210     mpi_set_protect_flag( gpg_mpi_t a )
211     {
212     a->flags = 1;
213     }
214    
215     static gpg_mpi_t
216     mpi_set_opaque( gpg_mpi_t a, void *p, int len )
217     {
218     if( !a ) {
219     a = calloc( 1, sizeof *a );
220     }
221    
222     if( a->flags & 4 )
223     safe_free( a->d );
224     else {
225     safe_free( a->d );
226     }
227    
228     a->d = p;
229     a->alloced = 0;
230     a->nlimbs = 0;
231     a->nbits = len;
232     a->flags = 4;
233     return a;
234     }
235    
236     void
237     free_symkey_enc( PKT_symkey_enc *enc )
238     {
239     safe_free(enc);
240     }
241    
242     void
243     free_pubkey_enc( PKT_pubkey_enc *enc )
244     {
245     int n, i;
246     n = pubkey_get_nenc( enc->pubkey_algo );
247     if( !n )
248     safe_free(enc->data[0]);
249     for(i=0; i < n; i++ )
250     safe_free( enc->data[i] );
251     safe_free(enc);
252     }
253    
254     void
255     free_seckey_enc( PKT_signature *sig )
256     {
257     int n, i;
258    
259     n = pubkey_get_nsig( sig->pubkey_algo );
260     if( !n )
261     safe_free(sig->data[0]);
262     for(i=0; i < n; i++ )
263     safe_free( sig->data[i] );
264    
265     safe_free(sig->revkey);
266     safe_free(sig->hashed);
267     safe_free(sig->unhashed);
268     safe_free(sig);
269     }
270    
271    
272    
273     void
274     release_public_key_parts( PKT_public_key *pk )
275     {
276     int n, i;
277     n = pubkey_get_npkey( pk->pubkey_algo );
278     if( !n )
279     safe_free(pk->pkey[0]);
280     for(i=0; i < n; i++ ) {
281     safe_free( pk->pkey[i] );
282     pk->pkey[i] = NULL;
283     }
284     if (pk->prefs) {
285     safe_free (pk->prefs);
286     pk->prefs = NULL;
287     }
288     if( pk->namehash ) {
289     safe_free(pk->namehash);
290     pk->namehash = NULL;
291     }
292     if (pk->user_id) {
293     free_user_id (pk->user_id);
294     pk->user_id = NULL;
295     }
296     if (pk->revkey) {
297     safe_free(pk->revkey);
298     pk->revkey=NULL;
299     pk->numrevkeys=0;
300     }
301     }
302    
303    
304     void
305     free_public_key( PKT_public_key *pk )
306     {
307     release_public_key_parts( pk );
308     safe_free(pk);
309     }
310    
311    
312     int
313     pubkey_get_nenc( int algo )
314     {
315     switch( algo ) {
316     case 1:
317     case 2:
318     case 3: return 1;
319     case 16:
320     case 20: return 2;
321     }
322     return 0;
323     }
324    
325     int
326     pubkey_get_nsig( algo )
327     {
328     switch( algo ) {
329     case 1:
330     case 2:
331     case 3: return 1;
332     case 17:
333     case 16:
334     case 20: return 2;
335     }
336     return 0;
337     }
338    
339     int
340     pubkey_get_npkey( int algo )
341     {
342     if( is_ELGAMAL( algo ) ) return 3;
343     else if ( algo == 17 ) return 4;
344     else if ( is_RSA( algo ) ) return 2;
345     return 0;
346     } /* cdk_pk_get_npkey */
347    
348     int
349     pubkey_get_nskey( int algo )
350     {
351     if ( is_ELGAMAL( algo ) ) return 4;
352     else if ( algo == 17 ) return 5;
353     else if ( is_RSA( algo ) )return 6;
354     return 0;
355 twoaday 133 }
356 werner 46
357    
358    
359     /*
360     * Return a copy of the preferences
361     */
362     prefitem_t *
363     copy_prefs (const prefitem_t *prefs)
364     {
365     size_t n;
366     prefitem_t *new;
367    
368     if (!prefs)
369     return NULL;
370    
371     for (n=0; prefs[n].type; n++)
372     ;
373     new = malloc ( sizeof (*new) * (n+1));
374     for (n=0; prefs[n].type; n++) {
375     new[n].type = prefs[n].type;
376     new[n].value = prefs[n].value;
377     }
378     new[n].type = PREFTYPE_NONE;
379     new[n].value = 0;
380    
381     return new;
382     }
383    
384     /****************
385     * Replace all common parts of a sk by the one from the public key.
386     * This is a hack and a better solution will be to just store the real secret
387     * parts somewhere and don't duplicate all the other stuff.
388     */
389     void
390     copy_public_parts_to_secret_key( PKT_public_key *pk, PKT_secret_key *sk )
391     {
392     sk->expiredate = pk->expiredate;
393     sk->pubkey_algo = pk->pubkey_algo;
394     sk->pubkey_usage= pk->pubkey_usage;
395     sk->req_usage = pk->req_usage;
396     sk->req_algo = pk->req_algo;
397     sk->has_expired = pk->has_expired;
398     sk->is_revoked = pk->is_revoked;
399     sk->is_valid = pk->is_valid;
400     sk->main_keyid[0]= pk->main_keyid[0];
401     sk->main_keyid[1]= pk->main_keyid[1];
402     sk->keyid[0] = pk->keyid[0];
403     sk->keyid[1] = pk->keyid[1];
404     }
405    
406     void
407     release_secret_key_parts( PKT_secret_key *sk )
408     {
409     int n, i;
410    
411     n = pubkey_get_nskey( sk->pubkey_algo );
412     if( !n )
413     safe_free(sk->skey[0]);
414     for(i=0; i < n; i++ ) {
415     safe_free( sk->skey[i] );
416     sk->skey[i] = NULL;
417     }
418     }
419    
420     void
421     free_secret_key( PKT_secret_key *sk )
422     {
423     release_secret_key_parts( sk );
424     safe_free(sk);
425     }
426    
427     void
428     free_comment( PKT_comment *rem )
429     {
430     safe_free(rem);
431     }
432    
433     void
434     free_attributes(PKT_user_id *uid)
435     {
436     safe_free(uid->attribs);
437     safe_free(uid->attrib_data);
438    
439     uid->attribs=NULL;
440     uid->attrib_data=NULL;
441     uid->attrib_len=0;
442     }
443    
444     void
445     free_user_id (PKT_user_id *uid)
446     {
447     assert (uid->ref > 0);
448     if (--uid->ref)
449     return;
450    
451     free_attributes(uid);
452    
453     if (uid->prefs)
454     safe_free (uid->prefs);
455     safe_free (uid);
456     }
457    
458     void
459     free_compressed( PKT_compressed *zd )
460     {
461     if( zd->buf ) { /* have to skip some bytes */
462     /* don't have any information about the length, so
463     * we assume this is the last packet */
464     while( gpg_iobuf_read( zd->buf, NULL, 1<<30 ) != -1 )
465     ;
466     }
467     safe_free(zd);
468     }
469    
470     void
471     free_encrypted( PKT_encrypted *ed )
472     {
473     if( ed->buf ) { /* have to skip some bytes */
474     if( gpg_iobuf_in_block_mode(ed->buf) ) {
475     while( gpg_iobuf_read( ed->buf, NULL, 1<<30 ) != -1 )
476     ;
477     }
478     else {
479     while( ed->len ) { /* skip the packet */
480     int n = gpg_iobuf_read( ed->buf, NULL, ed->len );
481     if( n == -1 )
482     ed->len = 0;
483     else
484     ed->len -= n;
485     }
486     }
487     }
488     safe_free(ed);
489     }
490    
491    
492     void
493     free_plaintext( PKT_plaintext *pt )
494     {
495     if( pt->buf ) { /* have to skip some bytes */
496     if( gpg_iobuf_in_block_mode(pt->buf) ) {
497     while( gpg_iobuf_read( pt->buf, NULL, 1<<30 ) != -1 )
498     ;
499     }
500     else {
501     while( pt->len ) { /* skip the packet */
502     int n = gpg_iobuf_read( pt->buf, NULL, pt->len );
503     if( n == -1 )
504     pt->len = 0;
505     else
506     pt->len -= n;
507     }
508     }
509     }
510     safe_free(pt);
511     }
512    
513     /****************
514     * Free the packet in pkt.
515     */
516     void
517     gpg_free_packet( PACKET *pkt )
518     {
519     if( !pkt || !pkt->pkt.generic )
520     return;
521    
522     switch( pkt->pkttype ) {
523     case PKT_SIGNATURE:
524     free_seckey_enc( pkt->pkt.signature );
525     break;
526     case PKT_PUBKEY_ENC:
527     free_pubkey_enc( pkt->pkt.pubkey_enc );
528     break;
529     case PKT_SYMKEY_ENC:
530     free_symkey_enc( pkt->pkt.symkey_enc );
531     break;
532     case PKT_PUBLIC_KEY:
533     case PKT_PUBLIC_SUBKEY:
534     free_public_key( pkt->pkt.public_key );
535     break;
536     case PKT_SECRET_KEY:
537     case PKT_SECRET_SUBKEY:
538     free_secret_key( pkt->pkt.secret_key );
539     break;
540     case PKT_COMMENT:
541     free_comment( pkt->pkt.comment );
542     break;
543     case PKT_USER_ID:
544     free_user_id( pkt->pkt.user_id );
545     break;
546     case PKT_COMPRESSED:
547     free_compressed( pkt->pkt.compressed);
548     break;
549     case PKT_ENCRYPTED:
550     case PKT_ENCRYPTED_MDC:
551     free_encrypted( pkt->pkt.encrypted );
552     break;
553     case PKT_PLAINTEXT:
554     free_plaintext( pkt->pkt.plaintext );
555     break;
556     default:
557     safe_free( pkt->pkt.generic );
558     break;
559     }
560     pkt->pkt.generic = NULL;
561     }
562    
563    
564    
565     /****************
566     * Parse a Packet and return it in packet
567     * Returns: 0 := valid packet in pkt
568     * -1 := no more packets
569     * >0 := error
570     * Note: The function may return an error and a partly valid packet;
571     * caller must free this packet.
572     */
573     int
574     gpg_parse_packet( gpg_iobuf_t inp, PACKET *pkt )
575     {
576     int skip, rc;
577    
578     do {
579     rc = parse( inp, pkt, 0, NULL, &skip, NULL, 0 );
580     } while( skip );
581     return rc;
582     }
583    
584     /****************
585     * Like parse packet, but only return secret or public (sub)key packets.
586     */
587     int
588     search_packet( gpg_iobuf_t inp, PACKET *pkt, _off_t *retpos, int with_uid )
589     {
590     int skip, rc;
591    
592     do {
593     rc = parse( inp, pkt, with_uid?2:1, retpos, &skip, NULL, 0 );
594     } while( skip );
595     return rc;
596     }
597    
598     /****************
599     * Copy all packets from INP to OUT, thereby removing unused spaces.
600     */
601     int
602     copy_all_packets( gpg_iobuf_t inp, gpg_iobuf_t out )
603     {
604     PACKET pkt;
605     int skip, rc=0;
606     do {
607     gpg_init_packet(&pkt);
608     } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )));
609     return rc;
610     }
611    
612     /****************
613     * Copy some packets from INP to OUT, thereby removing unused spaces.
614     * Stop at offset STOPoff (i.e. don't copy packets at this or later offsets)
615     */
616     int
617     copy_some_packets( gpg_iobuf_t inp, gpg_iobuf_t out, _off_t stopoff )
618     {
619     PACKET pkt;
620     int skip, rc=0;
621     do {
622     if( gpg_iobuf_tell(inp) >= stopoff )
623     return 0;
624     gpg_init_packet(&pkt);
625     } while( !(rc = parse( inp, &pkt, 0, NULL, &skip, out, 0 )) );
626     return rc;
627     }
628    
629     /****************
630     * Skip over N packets
631     */
632     int
633     skip_some_packets( gpg_iobuf_t inp, unsigned n )
634     {
635     int skip, rc=0;
636     PACKET pkt;
637    
638     for( ;n && !rc; n--) {
639     gpg_init_packet(&pkt);
640     rc = parse( inp, &pkt, 0, NULL, &skip, NULL, 1 );
641     }
642     return rc;
643     }
644    
645     /****************
646     * Parse packet. Set the variable skip points to 1 if the packet
647     * should be skipped; this is the case if either ONLYKEYPKTS is set
648     * and the parsed packet isn't one or the
649     * packet-type is 0, indicating deleted stuff.
650     * if OUT is not NULL, a special copymode is used.
651     */
652     static int
653     parse( gpg_iobuf_t inp, PACKET *pkt, int onlykeypkts, _off_t *retpos,
654     int *skip, gpg_iobuf_t out, int do_skip
655     )
656     {
657     int rc=0, c, ctb, pkttype, lenbytes;
658     unsigned long pktlen;
659     byte hdr[8];
660     int hdrlen;
661     int new_ctb = 0;
662     int with_uid = (onlykeypkts == 2);
663    
664     *skip = 0;
665     /*assert( !pkt->pkt.generic );*/
666     if( retpos )
667     *retpos = gpg_iobuf_tell(inp);
668    
669     if( (ctb = gpg_iobuf_get(inp)) == -1 ) {
670     rc = -1;
671     goto leave;
672     }
673     hdrlen=0;
674     hdr[hdrlen++] = ctb;
675     if( !(ctb & 0x80) ) {
676     printf("%s: invalid packet (ctb=%02x)\n", gpg_iobuf_where(inp), ctb );
677     rc = G10ERR_INVALID_PACKET;
678     goto leave;
679     }
680     pktlen = 0;
681     new_ctb = !!(ctb & 0x40);
682     if( new_ctb ) {
683     pkttype = ctb & 0x3f;
684     if( (c = gpg_iobuf_get(inp)) == -1 ) {
685     printf("%s: 1st length byte missing\n", gpg_iobuf_where(inp) );
686     rc = G10ERR_INVALID_PACKET;
687     goto leave;
688     }
689     if (pkttype == PKT_COMPRESSED) {
690     gpg_iobuf_set_partial_block_mode(inp, c & 0xff);
691     pktlen = 0;/* to indicate partial length */
692     }
693     else {
694     hdr[hdrlen++] = c;
695     if( c < 192 )
696     pktlen = c;
697     else if( c < 224 ) {
698     pktlen = (c - 192) * 256;
699     if( (c = gpg_iobuf_get(inp)) == -1 ) {
700     printf("%s: 2nd length byte missing\n",
701     gpg_iobuf_where(inp) );
702     rc = G10ERR_INVALID_PACKET;
703     goto leave;
704     }
705     hdr[hdrlen++] = c;
706     pktlen += c + 192;
707     }
708     else if( c == 255 ) {
709     pktlen = (hdr[hdrlen++] = gpg_iobuf_get_noeof(inp)) << 24;
710     pktlen |= (hdr[hdrlen++] = gpg_iobuf_get_noeof(inp)) << 16;
711     pktlen |= (hdr[hdrlen++] = gpg_iobuf_get_noeof(inp)) << 8;
712     if( (c = gpg_iobuf_get(inp)) == -1 ) {
713     printf("%s: 4 byte length invalid\n",
714     gpg_iobuf_where(inp) );
715     rc = G10ERR_INVALID_PACKET;
716     goto leave;
717     }
718     pktlen |= (hdr[hdrlen++] = c );
719     }
720     else { /* partial body length */
721     gpg_iobuf_set_partial_block_mode(inp, c & 0xff);
722     pktlen = 0;/* to indicate partial length */
723     }
724     }
725     }
726     else {
727     pkttype = (ctb>>2)&0xf;
728     lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3));
729     if( !lenbytes ) {
730     pktlen = 0; /* don't know the value */
731     if( pkttype != PKT_COMPRESSED )
732     gpg_iobuf_set_block_mode(inp, 1);
733     }
734     else {
735     for( ; lenbytes; lenbytes-- ) {
736     pktlen <<= 8;
737     pktlen |= hdr[hdrlen++] = gpg_iobuf_get_noeof(inp);
738     }
739     }
740     }
741    
742     if (pktlen == 0xffffffff) {
743     /* with a some probability this is caused by a problem in the
744     * the uncompressing layer - in some error cases it just loops
745     * and spits out 0xff bytes. */
746     printf ("%s: garbled packet detected\n", gpg_iobuf_where(inp) );
747     exit (2);
748     }
749    
750     if( out && pkttype ) {
751     if( gpg_iobuf_write( out, hdr, hdrlen ) == -1 )
752     rc = G10ERR_WRITE_FILE;
753     else
754     rc = copy_packet(inp, out, pkttype, pktlen );
755     goto leave;
756     }
757    
758     if (with_uid && pkttype == PKT_USER_ID)
759     ;
760     else if( do_skip
761     || !pkttype
762     || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
763     && pkttype != PKT_PUBLIC_KEY
764     && pkttype != PKT_SECRET_SUBKEY
765     && pkttype != PKT_SECRET_KEY ) ) {
766     skip_rest(inp, pktlen);
767     *skip = 1;
768     rc = 0;
769     goto leave;
770     }
771    
772     pkt->pkttype = pkttype;
773     rc = G10ERR_UNKNOWN_PACKET; /* default error */
774     switch( pkttype ) {
775     case PKT_PUBLIC_KEY:
776     case PKT_PUBLIC_SUBKEY:
777     pkt->pkt.public_key = calloc(1, sizeof *pkt->pkt.public_key );
778     rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
779     break;
780     case PKT_SECRET_KEY:
781     case PKT_SECRET_SUBKEY:
782     pkt->pkt.secret_key = calloc(1,sizeof *pkt->pkt.secret_key );
783     rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
784     break;
785     case PKT_SYMKEY_ENC:
786     rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
787     break;
788     case PKT_PUBKEY_ENC:
789     rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
790     break;
791     case PKT_SIGNATURE:
792     pkt->pkt.signature = calloc(1,sizeof *pkt->pkt.signature );
793     rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
794     break;
795     case PKT_ONEPASS_SIG:
796     pkt->pkt.onepass_sig = calloc(1,sizeof *pkt->pkt.onepass_sig );
797     rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
798     break;
799     case PKT_USER_ID:
800     rc = parse_user_id(inp, pkttype, pktlen, pkt );
801     break;
802     case PKT_ATTRIBUTE:
803     pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */
804     rc = parse_attribute(inp, pkttype, pktlen, pkt);
805     break;
806     case PKT_OLD_COMMENT:
807     case PKT_COMMENT:
808     rc = parse_comment(inp, pkttype, pktlen, pkt);
809     break;
810     case PKT_RING_TRUST:
811     parse_trust(inp, pkttype, pktlen, pkt);
812     rc = 0;
813     break;
814     case PKT_PLAINTEXT:
815     rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb );
816     break;
817     case PKT_COMPRESSED:
818     rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb );
819     break;
820     case PKT_ENCRYPTED:
821     case PKT_ENCRYPTED_MDC:
822     rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb );
823     break;
824     case PKT_MDC:
825     rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb );
826     break;
827     case PKT_GPG_CONTROL:
828     rc = parse_gpg_control(inp, pkttype, pktlen, pkt );
829     break;
830     default:
831     skip_packet(inp, pkttype, pktlen);
832     break;
833     }
834    
835     leave:
836     if( !rc && gpg_iobuf_error(inp) )
837     rc = G10ERR_INV_KEYRING;
838     return rc;
839     }
840    
841     static void
842     dump_hex_line( int c, int *i )
843     {
844     if( *i && !(*i%8) ) {
845     if( *i && !(*i%24) )
846     printf("\n%4d:", *i );
847     else
848     putchar(' ');
849     }
850     if( c == -1 )
851     printf(" EOF" );
852     else
853     printf(" %02x", c );
854     ++*i;
855     }
856    
857    
858     static int
859     copy_packet( gpg_iobuf_t inp, gpg_iobuf_t out, int pkttype, unsigned long pktlen )
860     {
861     int n;
862     char buf[100];
863    
864     if( gpg_iobuf_in_block_mode(inp) ) {
865     while( (n = gpg_iobuf_read( inp, buf, 100 )) != -1 )
866     if( gpg_iobuf_write(out, buf, n ) )
867     return G10ERR_WRITE_FILE; /* write error */
868     }
869     else if( !pktlen && pkttype == PKT_COMPRESSED ) {
870     printf("copy_packet: compressed!\n");
871     /* compressed packet, copy till EOF */
872     while( (n = gpg_iobuf_read( inp, buf, 100 )) != -1 )
873     if( gpg_iobuf_write(out, buf, n ) )
874     return G10ERR_WRITE_FILE; /* write error */
875     }
876     else {
877     for( ; pktlen; pktlen -= n ) {
878     n = pktlen > 100 ? 100 : pktlen;
879     n = gpg_iobuf_read( inp, buf, n );
880     if( n == -1 )
881     return G10ERR_READ_FILE;
882     if( gpg_iobuf_write(out, buf, n ) )
883     return G10ERR_WRITE_FILE; /* write error */
884     }
885     }
886     return 0;
887     }
888    
889    
890     static void
891     skip_packet( gpg_iobuf_t inp, int pkttype, unsigned long pktlen )
892     {
893     if( list_mode ) {
894     if( pkttype == PKT_MARKER )
895     fputs(":marker packet:\n", stdout );
896     else
897     printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen);
898     if( pkttype ) {
899     int c, i=0 ;
900     if( pkttype != PKT_MARKER )
901     fputs("dump:", stdout );
902     if( gpg_iobuf_in_block_mode(inp) ) {
903     while( (c=gpg_iobuf_get(inp)) != -1 )
904     dump_hex_line(c, &i);
905     }
906     else {
907     for( ; pktlen; pktlen-- )
908     dump_hex_line(gpg_iobuf_get(inp), &i);
909     }
910     putchar('\n');
911     return;
912     }
913     }
914     skip_rest(inp,pktlen);
915     }
916    
917     static void
918     skip_rest( gpg_iobuf_t inp, unsigned long pktlen )
919     {
920     if( gpg_iobuf_in_block_mode(inp) ) {
921     while( gpg_iobuf_get(inp) != -1 )
922     ;
923     }
924     else {
925     for( ; pktlen; pktlen-- )
926     if( gpg_iobuf_get(inp) == -1 )
927     break;
928     }
929     }
930    
931    
932     static void *
933     read_rest( gpg_iobuf_t inp, size_t pktlen )
934     {
935     byte *p;
936     int i;
937    
938     if( gpg_iobuf_in_block_mode(inp) ) {
939     printf("read_rest: can't store stream data\n");
940     p = NULL;
941     }
942     else {
943     p = malloc( pktlen );
944     for(i=0; pktlen; pktlen--, i++ )
945     p[i] = gpg_iobuf_get(inp);
946     }
947     return p;
948     }
949    
950    
951    
952     static int
953     parse_symkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
954     {
955     PKT_symkey_enc *k;
956     int rc = 0;
957     int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
958    
959     if( pktlen < 4 ) {
960     printf("packet(%d) too short\n", pkttype);
961     rc = G10ERR_INVALID_PACKET;
962     goto leave;
963     }
964     version = gpg_iobuf_get_noeof(inp); pktlen--;
965     if( version != 4 ) {
966     printf("packet(%d) with unknown version %d\n", pkttype, version);
967     rc = G10ERR_INVALID_PACKET;
968     goto leave;
969     }
970     if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */
971     printf("packet(%d) too large\n", pkttype);
972     rc = G10ERR_INVALID_PACKET;
973     goto leave;
974     }
975     cipher_algo = gpg_iobuf_get_noeof(inp); pktlen--;
976     s2kmode = gpg_iobuf_get_noeof(inp); pktlen--;
977     hash_algo = gpg_iobuf_get_noeof(inp); pktlen--;
978     switch( s2kmode ) {
979     case 0: /* simple s2k */
980     minlen = 0;
981     break;
982     case 1: /* salted s2k */
983     minlen = 8;
984     break;
985     case 3: /* iterated+salted s2k */
986     minlen = 9;
987     break;
988     default:
989     printf("unknown S2K %d\n", s2kmode );
990     goto leave;
991     }
992     if( minlen > pktlen ) {
993     printf("packet with S2K %d too short\n", s2kmode );
994     rc = G10ERR_INVALID_PACKET;
995     goto leave;
996     }
997     seskeylen = pktlen - minlen;
998     k = packet->pkt.symkey_enc = calloc(1, sizeof *packet->pkt.symkey_enc
999     + seskeylen - 1 );
1000     k->version = version;
1001     k->cipher_algo = cipher_algo;
1002     k->s2k.mode = s2kmode;
1003     k->s2k.hash_algo = hash_algo;
1004     if( s2kmode == 1 || s2kmode == 3 ) {
1005     for(i=0; i < 8 && pktlen; i++, pktlen-- )
1006     k->s2k.salt[i] = gpg_iobuf_get_noeof(inp);
1007     }
1008     if( s2kmode == 3 ) {
1009     k->s2k.count = gpg_iobuf_get(inp); pktlen--;
1010     }
1011     k->seskeylen = seskeylen;
1012     for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
1013     k->seskey[i] = gpg_iobuf_get_noeof(inp);
1014     assert( !pktlen );
1015    
1016     if( list_mode ) {
1017     printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n",
1018     version, cipher_algo, s2kmode, hash_algo);
1019     if( s2kmode == 1 || s2kmode == 3 ) {
1020     printf("\tsalt ");
1021     for(i=0; i < 8; i++ )
1022     printf("%02x", k->s2k.salt[i]);
1023     if( s2kmode == 3 )
1024     printf(", count %lu\n", (ulong)k->s2k.count );
1025     printf("\n");
1026     }
1027     }
1028    
1029     leave:
1030     skip_rest(inp, pktlen);
1031     return rc;
1032     }
1033    
1034     static int
1035     parse_pubkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
1036     {
1037     unsigned int n;
1038     int rc = 0;
1039     int i, ndata;
1040     PKT_pubkey_enc *k;
1041    
1042     k = packet->pkt.pubkey_enc = calloc(1, sizeof *packet->pkt.pubkey_enc);
1043     if( pktlen < 12 ) {
1044     printf("packet(%d) too short\n", pkttype);
1045     rc = G10ERR_INVALID_PACKET;
1046     goto leave;
1047     }
1048     k->version = gpg_iobuf_get_noeof(inp); pktlen--;
1049     if( k->version != 2 && k->version != 3 ) {
1050     printf("packet(%d) with unknown version %d\n", pkttype, k->version);
1051     rc = G10ERR_INVALID_PACKET;
1052     goto leave;
1053     }
1054     k->keyid[0] = read_32(inp); pktlen -= 4;
1055     k->keyid[1] = read_32(inp); pktlen -= 4;
1056     k->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1057     k->throw_keyid = 0; /* only used as flag for build_packet */
1058     if( list_mode )
1059     printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
1060     k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
1061    
1062     ndata = pubkey_get_nenc(k->pubkey_algo);
1063     if( !ndata ) {
1064     if( list_mode )
1065     printf("\tunsupported algorithm %d\n", k->pubkey_algo );
1066     unknown_pubkey_warning( k->pubkey_algo );
1067     k->data[0] = NULL; /* no need to store the encrypted data */
1068     }
1069     else {
1070     for( i=0; i < ndata; i++ ) {
1071     n = pktlen;
1072     k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
1073     if( list_mode ) {
1074     printf("\tdata: ");
1075     mpi_print(stdout, k->data[i], mpi_print_mode );
1076     putchar('\n');
1077     }
1078     if (!k->data[i])
1079     rc = G10ERR_INVALID_PACKET;
1080     }
1081     }
1082    
1083     leave:
1084     skip_rest(inp, pktlen);
1085     return rc;
1086     }
1087    
1088     static void
1089     dump_sig_subpkt( int hashed, int type, int critical,
1090     const byte *buffer, size_t buflen, size_t length )
1091     {
1092     const char *p=NULL;
1093     int i;
1094    
1095     /* The CERT has warning out with explains how to use GNUPG to
1096     * detect the ARRs - we print our old message here when it is a faked
1097     * ARR and add an additional notice */
1098     if ( type == SIGSUBPKT_ARR && !hashed ) {
1099     printf("\tsubpkt %d len %u (additional recipient request)\n"
1100     "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically "
1101     "encrypt to this key and thereby reveal the plaintext to "
1102     "the owner of this ARR key. Detailed info follows:\n",
1103     type, (unsigned)length );
1104     }
1105    
1106    
1107     printf("\t%s%ssubpkt %d len %u (", /*)*/
1108     critical ? "critical ":"",
1109     hashed ? "hashed ":"", type, (unsigned)length );
1110     buffer++;
1111     length--;
1112     if( length > buflen ) {
1113     printf("too short: buffer is only %u)\n", (unsigned)buflen );
1114     return;
1115     }
1116     switch( type ) {
1117     case SIGSUBPKT_SIG_CREATED:
1118     if( length >= 4 )
1119     printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) );
1120     break;
1121     case SIGSUBPKT_SIG_EXPIRE:
1122     if( length >= 4 )
1123     printf("sig expires after %s",
1124     strtimevalue( buffer_to_u32(buffer) ) );
1125     break;
1126     case SIGSUBPKT_EXPORTABLE:
1127     if( length )
1128     printf("%sexportable", *buffer? "":"not ");
1129     break;
1130     case SIGSUBPKT_TRUST:
1131     if(length!=2)
1132     p="[invalid trust signature]";
1133     else
1134     printf("trust signature of level %d, amount %d",buffer[0],buffer[1]);
1135     break;
1136     case SIGSUBPKT_REGEXP:
1137     if(!length)
1138     p="[invalid regexp]";
1139     else
1140     printf("regular expression: \"%s\"",buffer);
1141     break;
1142     case SIGSUBPKT_REVOCABLE:
1143     if( length )
1144     printf("%srevocable", *buffer? "":"not ");
1145     break;
1146     case SIGSUBPKT_KEY_EXPIRE:
1147     if( length >= 4 )
1148     printf("key expires after %s",
1149     strtimevalue( buffer_to_u32(buffer) ) );
1150     break;
1151     case SIGSUBPKT_PREF_SYM:
1152     fputs("pref-sym-algos:", stdout );
1153     for( i=0; i < length; i++ )
1154     printf(" %d", buffer[i] );
1155     break;
1156     case SIGSUBPKT_REV_KEY:
1157     fputs("revocation key: ", stdout );
1158     if( length < 22 )
1159     p = "[too short]";
1160     else {
1161     printf("c=%02x a=%d f=", buffer[0], buffer[1] );
1162     for( i=2; i < length; i++ )
1163     printf("%02X", buffer[i] );
1164     }
1165     break;
1166     case SIGSUBPKT_ISSUER:
1167     if( length >= 8 )
1168     printf("issuer key ID %08lX%08lX",
1169     (ulong)buffer_to_u32(buffer),
1170     (ulong)buffer_to_u32(buffer+4) );
1171     break;
1172     case SIGSUBPKT_NOTATION:
1173     {
1174     fputs("notation: ", stdout );
1175     if( length < 8 )
1176     p = "[too short]";
1177     else if( !(*buffer & 0x80) )
1178     p = "[not human readable]";
1179     else {
1180     const byte *s = buffer;
1181     size_t n1, n2;
1182    
1183     n1 = (s[4] << 8) | s[5];
1184     n2 = (s[6] << 8) | s[7];
1185     s += 8;
1186     if( 8+n1+n2 != length )
1187     p = "[error]";
1188     else {
1189     print_string( stdout, s, n1, ')' );
1190     putc( '=', stdout );
1191     print_string( stdout, s+n1, n2, ')' );
1192     }
1193     }
1194     }
1195     break;
1196     case SIGSUBPKT_PREF_HASH:
1197     fputs("pref-hash-algos:", stdout );
1198     for( i=0; i < length; i++ )
1199     printf(" %d", buffer[i] );
1200     break;
1201     case SIGSUBPKT_PREF_COMPR:
1202     fputs("pref-zip-algos:", stdout );
1203     for( i=0; i < length; i++ )
1204     printf(" %d", buffer[i] );
1205     break;
1206     case SIGSUBPKT_KS_FLAGS:
1207     fputs("key server preferences:",stdout);
1208     for(i=0;i<length;i++)
1209     printf(" %02X", buffer[i]);
1210     break;
1211     case SIGSUBPKT_PREF_KS:
1212     p = "preferred key server";
1213     break;
1214     case SIGSUBPKT_PRIMARY_UID:
1215     p = "primary user ID";
1216     break;
1217     case SIGSUBPKT_POLICY:
1218     fputs("policy: ", stdout );
1219     print_string( stdout, buffer, length, ')' );
1220     break;
1221     case SIGSUBPKT_KEY_FLAGS:
1222     fputs ( "key flags:", stdout );
1223     for( i=0; i < length; i++ )
1224     printf(" %02X", buffer[i] );
1225     break;
1226     case SIGSUBPKT_SIGNERS_UID:
1227     p = "signer's user ID";
1228     break;
1229     case SIGSUBPKT_REVOC_REASON:
1230     if( length ) {
1231     printf("revocation reason 0x%02x (", *buffer );
1232     print_string( stdout, buffer+1, length-1, ')' );
1233     p = ")";
1234     }
1235     break;
1236     case SIGSUBPKT_ARR:
1237     fputs("Big Brother's key (ignored): ", stdout );
1238     if( length < 22 )
1239     p = "[too short]";
1240     else {
1241     printf("c=%02x a=%d f=", buffer[0], buffer[1] );
1242     for( i=2; i < length; i++ )
1243     printf("%02X", buffer[i] );
1244     }
1245     break;
1246     case SIGSUBPKT_FEATURES:
1247     fputs ( "features:", stdout );
1248     for( i=0; i < length; i++ )
1249     printf(" %02x", buffer[i] );
1250     break;
1251     case SIGSUBPKT_PRIV_VERIFY_CACHE:
1252     p = "obsolete verification cache";
1253     break;
1254     default: p = "?"; break;
1255     }
1256    
1257     printf("%s)\n", p? p: "");
1258     }
1259    
1260     /****************
1261     * Returns: >= 0 offset into buffer
1262     * -1 unknown type
1263     * -2 unsupported type
1264     * -3 subpacket too short
1265     */
1266     int
1267     parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
1268     {
1269     switch( type ) {
1270     case SIGSUBPKT_REV_KEY:
1271     if(n < 22)
1272     break;
1273     return 0;
1274     case SIGSUBPKT_SIG_CREATED:
1275     case SIGSUBPKT_SIG_EXPIRE:
1276     case SIGSUBPKT_KEY_EXPIRE:
1277     if( n < 4 )
1278     break;
1279     return 0;
1280     case SIGSUBPKT_KEY_FLAGS:
1281     case SIGSUBPKT_KS_FLAGS:
1282     case SIGSUBPKT_PREF_SYM:
1283     case SIGSUBPKT_PREF_HASH:
1284     case SIGSUBPKT_PREF_COMPR:
1285     case SIGSUBPKT_POLICY:
1286     case SIGSUBPKT_FEATURES:
1287     return 0;
1288     case SIGSUBPKT_EXPORTABLE:
1289     case SIGSUBPKT_REVOCABLE:
1290     if( !n )
1291     break;
1292     return 0;
1293     case SIGSUBPKT_ISSUER: /* issuer key ID */
1294     if( n < 8 )
1295     break;
1296     return 0;
1297     case SIGSUBPKT_NOTATION:
1298     if( n < 8 ) /* minimum length needed */
1299     break;
1300     return 0;
1301     case SIGSUBPKT_REVOC_REASON:
1302     if( !n )
1303     break;
1304     return 0;
1305     case SIGSUBPKT_PRIMARY_UID:
1306     if ( n != 1 )
1307     break;
1308     return 0;
1309     case SIGSUBPKT_PRIV_VERIFY_CACHE:
1310     /* We used this in gpg 1.0.5 and 1.0.6 to cache signature
1311     * verification results - it is no longer used.
1312     * "GPG" 0x00 <mode> <stat>
1313     * where mode == 1: valid data, stat == 0: invalid signature
1314     * stat == 1: valid signature
1315     * (because we use private data, we check our marker) */
1316     if( n < 6 )
1317     break;
1318     if( buffer[0] != 'G' || buffer[1] != 'P'
1319     || buffer[2] != 'G' || buffer[3] )
1320     return -2;
1321     return 4;
1322     default: return -1;
1323     }
1324     return -3;
1325     }
1326    
1327    
1328     static int
1329     can_handle_critical( const byte *buffer, size_t n, int type )
1330     {
1331     switch( type ) {
1332     case SIGSUBPKT_NOTATION:
1333     if( n >= 8 && (*buffer & 0x80) )
1334     return 1; /* human readable is handled */
1335     return 0;
1336    
1337     case SIGSUBPKT_SIG_CREATED:
1338     case SIGSUBPKT_SIG_EXPIRE:
1339     case SIGSUBPKT_KEY_EXPIRE:
1340     case SIGSUBPKT_EXPORTABLE:
1341     case SIGSUBPKT_REVOCABLE:
1342     case SIGSUBPKT_REV_KEY:
1343     case SIGSUBPKT_ISSUER:/* issuer key ID */
1344     case SIGSUBPKT_PREF_SYM:
1345     case SIGSUBPKT_PREF_HASH:
1346     case SIGSUBPKT_PREF_COMPR:
1347     case SIGSUBPKT_KEY_FLAGS:
1348     case SIGSUBPKT_PRIMARY_UID:
1349     case SIGSUBPKT_FEATURES:
1350     case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
1351     return 1;
1352    
1353     default:
1354     return 0;
1355     }
1356     }
1357    
1358    
1359     const byte *
1360     enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype,
1361     size_t *ret_n, int *start, int *critical )
1362     {
1363     const byte *buffer;
1364     int buflen;
1365     int type;
1366     int critical_dummy;
1367     int offset;
1368     size_t n;
1369     int seq = 0;
1370     int reqseq = start? *start: 0;
1371    
1372     if(!critical)
1373     critical=&critical_dummy;
1374    
1375     if( !pktbuf || reqseq == -1 ) {
1376     /* return some value different from NULL to indicate that
1377     * there is no critical bit we do not understand. The caller
1378     * will never use the value. Yes I know, it is an ugly hack */
1379     return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&pktbuf : NULL;
1380     }
1381     buffer = pktbuf->data;
1382     buflen = pktbuf->len;
1383     while( buflen ) {
1384     n = *buffer++; buflen--;
1385     if( n == 255 ) { /* 4 byte length header */
1386     if( buflen < 4 )
1387     goto too_short;
1388     n = (buffer[0] << 24) | (buffer[1] << 16)
1389     | (buffer[2] << 8) | buffer[3];
1390     buffer += 4;
1391     buflen -= 4;
1392     }
1393     else if( n >= 192 ) { /* 2 byte special encoded length header */
1394     if( buflen < 2 )
1395     goto too_short;
1396     n = (( n - 192 ) << 8) + *buffer + 192;
1397     buffer++;
1398     buflen--;
1399     }
1400     if( buflen < n )
1401     goto too_short;
1402     type = *buffer;
1403     if( type & 0x80 ) {
1404     type &= 0x7f;
1405     *critical = 1;
1406     }
1407     else
1408     *critical = 0;
1409     if( !(++seq > reqseq) )
1410     ;
1411     else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
1412     if( *critical ) {
1413     if( n-1 > buflen+1 )
1414     goto too_short;
1415     if( !can_handle_critical(buffer+1, n-1, type ) ) {
1416     printf("subpacket of type %d has critical bit set\n",
1417     type);
1418     if( start )
1419     *start = seq;
1420     return NULL; /* this is an error */
1421     }
1422     }
1423     }
1424     else if( reqtype < 0 ) /* list packets */
1425     dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED,
1426     type, *critical, buffer, buflen, n );
1427     else if( type == reqtype ) { /* found */
1428     buffer++;
1429     n--;
1430     if( n > buflen )
1431     goto too_short;
1432     if( ret_n )
1433     *ret_n = n;
1434     offset = parse_one_sig_subpkt(buffer, n, type );
1435     switch( offset ) {
1436     case -3:
1437     printf("subpacket of type %d too short\n", type);
1438     return NULL;
1439     case -2:
1440     return NULL;
1441     case -1:
1442     printf( "This is a BUG.\n%s:%d\n", __FILE__, __LINE__ );
1443     exit( -1 );
1444     default:
1445     break;
1446     }
1447     if( start )
1448     *start = seq;
1449     return buffer+offset;
1450     }
1451     buffer += n; buflen -=n;
1452     }
1453     if( reqtype == SIGSUBPKT_TEST_CRITICAL )
1454     return buffer; /* as value true to indicate that there is no */
1455     /* critical bit we don't understand */
1456     if( start )
1457     *start = -1;
1458     return NULL; /* end of packets; not found */
1459    
1460     too_short:
1461     printf("buffer shorter than subpacket\n");
1462     if( start )
1463     *start = -1;
1464     return NULL;
1465     }
1466    
1467    
1468     const byte *
1469     gpg_parse_sig_subpkt (const subpktarea_t *buffer, sigsubpkttype_t reqtype,
1470     size_t *ret_n)
1471     {
1472     return enum_sig_subpkt( buffer, reqtype, ret_n, NULL, NULL );
1473     }
1474    
1475     const byte *
1476     gpg_parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype,
1477     size_t *ret_n )
1478     {
1479     const byte *p;
1480    
1481     p = gpg_parse_sig_subpkt (sig->hashed, reqtype, ret_n );
1482     if( !p )
1483     p = gpg_parse_sig_subpkt (sig->unhashed, reqtype, ret_n );
1484     return p;
1485     }
1486    
1487     /* Find all revocation keys. Look in hashed area only. */
1488     void parse_revkeys(PKT_signature *sig)
1489     {
1490     struct revocation_key *revkey;
1491     int seq=0;
1492     size_t len;
1493    
1494     if( sig->sig_class != 0x1F )
1495     return;
1496    
1497     while((revkey=
1498     (struct revocation_key *)enum_sig_subpkt(sig->hashed,
1499     SIGSUBPKT_REV_KEY,
1500     &len,&seq,NULL))) {
1501     if( len==sizeof(struct revocation_key) &&
1502     (revkey->rclass&0x80)) /* 0x80 bit must be set */ {
1503     sig->revkey=realloc(sig->revkey,
1504     sizeof(struct revocation_key *)*(sig->numrevkeys+1));
1505     sig->revkey[sig->numrevkeys]=revkey;
1506     sig->numrevkeys++;
1507     }
1508     }
1509     }
1510    
1511     static int
1512     parse_signature( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1513     PKT_signature *sig )
1514     {
1515     int md5_len=0;
1516     unsigned n;
1517     int is_v4=0;
1518     int rc=0;
1519     int i, ndata;
1520    
1521     if( pktlen < 16 ) {
1522     printf("packet(%d) too short\n", pkttype);
1523     goto leave;
1524     }
1525     sig->version = gpg_iobuf_get_noeof(inp); pktlen--;
1526     if( sig->version == 4 )
1527     is_v4=1;
1528     else if( sig->version != 2 && sig->version != 3 ) {
1529     printf("packet(%d) with unknown version %d\n", pkttype, sig->version);
1530     rc = G10ERR_INVALID_PACKET;
1531     goto leave;
1532     }
1533    
1534     if( !is_v4 ) {
1535     md5_len = gpg_iobuf_get_noeof(inp); pktlen--;
1536     }
1537     sig->sig_class = gpg_iobuf_get_noeof(inp); pktlen--;
1538     if( !is_v4 ) {
1539     sig->timestamp = read_32(inp); pktlen -= 4;
1540     sig->keyid[0] = read_32(inp); pktlen -= 4;
1541     sig->keyid[1] = read_32(inp); pktlen -= 4;
1542     }
1543     sig->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1544     sig->digest_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1545     sig->flags.exportable=1;
1546     sig->flags.revocable=1;
1547     if( is_v4 ) { /* read subpackets */
1548     n = read_16(inp); pktlen -= 2; /* length of hashed data */
1549     if( n > 10000 ) {
1550     printf("signature packet: hashed data too long\n");
1551     rc = G10ERR_INVALID_PACKET;
1552     goto leave;
1553     }
1554     if( n ) {
1555     sig->hashed = malloc (sizeof (*sig->hashed) + n - 1 );
1556     sig->hashed->size = n;
1557     sig->hashed->len = n;
1558     if( gpg_iobuf_read (inp, sig->hashed->data, n ) != n ) {
1559     printf ("premature eof while reading "
1560     "hashed signature data\n");
1561     rc = -1;
1562     goto leave;
1563     }
1564     pktlen -= n;
1565     }
1566     n = read_16(inp); pktlen -= 2; /* length of unhashed data */
1567     if( n > 10000 ) {
1568     printf("signature packet: unhashed data too long\n");
1569     rc = G10ERR_INVALID_PACKET;
1570     goto leave;
1571     }
1572     if( n ) {
1573     /* we add 8 extra bytes so that we have space for the signature
1574     * status cache. Well we are wastin this if there is a cache
1575     * packet already, but in the other case it avoids an realloc */
1576     sig->unhashed = malloc (sizeof(*sig->unhashed) + n + 8 - 1 );
1577     sig->unhashed->size = n + 8;
1578     sig->unhashed->len = n;
1579     if( gpg_iobuf_read(inp, sig->unhashed->data, n ) != n ) {
1580     printf("premature eof while reading "
1581     "unhashed signature data\n");
1582     rc = -1;
1583     goto leave;
1584     }
1585     pktlen -= n;
1586     }
1587     }
1588    
1589     if( pktlen < 5 ) { /* sanity check */
1590     printf("packet(%d) too short\n", pkttype);
1591     rc = G10ERR_INVALID_PACKET;
1592     goto leave;
1593     }
1594    
1595     sig->digest_start[0] = gpg_iobuf_get_noeof(inp); pktlen--;
1596     sig->digest_start[1] = gpg_iobuf_get_noeof(inp); pktlen--;
1597    
1598     if( is_v4 && sig->pubkey_algo ) { /*extract required information */
1599     const byte *p;
1600    
1601     /* set sig->flags.unknown_critical if there is a
1602     * critical bit set for packets which we do not understand */
1603     if( !gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL)
1604     || !gpg_parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL,
1605     NULL) )
1606     {
1607     sig->flags.unknown_critical = 1;
1608     }
1609    
1610     p = gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
1611     if( !p )
1612     printf("signature packet without timestamp\n");
1613     else
1614     sig->timestamp = buffer_to_u32(p);
1615     p = gpg_parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
1616     if( !p )
1617     printf("signature packet without keyid\n");
1618     else {
1619     sig->keyid[0] = buffer_to_u32(p);
1620     sig->keyid[1] = buffer_to_u32(p+4);
1621     }
1622    
1623     p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
1624     if(p)
1625     sig->expiredate=sig->timestamp+buffer_to_u32(p);
1626     if(sig->expiredate && sig->expiredate<=time(NULL))
1627     sig->flags.expired=1;
1628    
1629     p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL);
1630     if(p)
1631     sig->flags.policy_url=1;
1632    
1633     p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
1634     if(p)
1635     sig->flags.notation=1;
1636    
1637     p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL);
1638     if(p && *p==0)
1639     sig->flags.revocable=0;
1640    
1641     /* We accept the exportable subpacket from either the hashed
1642     or unhashed areas as older versions of gpg put it in the
1643     unhashed area. In theory, anyway, we should never see this
1644     packet off of a local keyring. */
1645    
1646     p=gpg_parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL);
1647     if(p && *p==0)
1648     sig->flags.exportable=0;
1649    
1650     /* Find all revocation keys. */
1651     if(sig->sig_class==0x1F)
1652     parse_revkeys(sig);
1653     }
1654    
1655     if( list_mode ) {
1656     printf(":signature packet: algo %d, keyid %08lX%08lX\n"
1657     "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
1658     "\tdigest algo %d, begin of digest %02x %02x\n",
1659     sig->pubkey_algo,
1660     (ulong)sig->keyid[0], (ulong)sig->keyid[1],
1661     sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
1662     sig->digest_algo,
1663     sig->digest_start[0], sig->digest_start[1] );
1664     if( is_v4 ) {
1665     gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL );
1666     gpg_parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
1667     }
1668     }
1669    
1670     ndata = pubkey_get_nsig(sig->pubkey_algo);
1671     if( !ndata ) {
1672     if( list_mode )
1673     printf("\tunknown algorithm %d\n", sig->pubkey_algo );
1674     unknown_pubkey_warning( sig->pubkey_algo );
1675     /* we store the plain material in data[0], so that we are able
1676     * to write it back with build_packet() */
1677     sig->data[0] = mpi_set_opaque(NULL, read_rest(inp, pktlen), pktlen );
1678     pktlen = 0;
1679     }
1680     else {
1681     for( i=0; i < ndata; i++ ) {
1682     n = pktlen;
1683     sig->data[i] = mpi_read(inp, &n, 0 );
1684     pktlen -=n;
1685     if( list_mode ) {
1686     printf("\tdata: ");
1687     mpi_print(stdout, sig->data[i], mpi_print_mode );
1688     putchar('\n');
1689     }
1690     if (!sig->data[i])
1691     rc = G10ERR_INVALID_PACKET;
1692     }
1693     }
1694    
1695     leave:
1696     skip_rest(inp, pktlen);
1697     return rc;
1698     }
1699    
1700    
1701     static int
1702     parse_onepass_sig( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1703     PKT_onepass_sig *ops )
1704     {
1705     int version;
1706     int rc = 0;
1707    
1708     if( pktlen < 13 ) {
1709     printf("packet(%d) too short\n", pkttype);
1710     rc = G10ERR_INVALID_PACKET;
1711     goto leave;
1712     }
1713     version = gpg_iobuf_get_noeof(inp); pktlen--;
1714     if( version != 3 ) {
1715     printf("onepass_sig with unknown version %d\n", version);
1716     rc = G10ERR_INVALID_PACKET;
1717     goto leave;
1718     }
1719     ops->sig_class = gpg_iobuf_get_noeof(inp); pktlen--;
1720     ops->digest_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1721     ops->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1722     ops->keyid[0] = read_32(inp); pktlen -= 4;
1723     ops->keyid[1] = read_32(inp); pktlen -= 4;
1724     ops->last = gpg_iobuf_get_noeof(inp); pktlen--;
1725     if( list_mode )
1726     printf(":onepass_sig packet: keyid %08lX%08lX\n"
1727     "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
1728     (ulong)ops->keyid[0], (ulong)ops->keyid[1],
1729     version, ops->sig_class,
1730     ops->digest_algo, ops->pubkey_algo, ops->last );
1731    
1732    
1733     leave:
1734     skip_rest(inp, pktlen);
1735     return rc;
1736     }
1737    
1738    
1739     static int
1740     parse_key( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1741     byte *hdr, int hdrlen, PACKET *pkt )
1742     {
1743     int i, version, algorithm;
1744     unsigned n;
1745     unsigned long timestamp, expiredate, max_expiredate;
1746     int npkey, nskey;
1747     int is_v4=0;
1748     int rc=0;
1749    
1750     version = gpg_iobuf_get_noeof(inp); pktlen--;
1751     if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
1752     /* early versions of G10 use old PGP comments packets;
1753     * luckily all those comments are started by a hash */
1754     if( list_mode ) {
1755     printf(":rfc1991 comment packet: \"" );
1756     for( ; pktlen; pktlen-- ) {
1757     int c;
1758     c = gpg_iobuf_get_noeof(inp);
1759     if( c >= ' ' && c <= 'z' )
1760     putchar(c);
1761     else
1762     printf("\\x%02x", c );
1763     }
1764     printf("\"\n");
1765     }
1766     skip_rest(inp, pktlen);
1767     return 0;
1768     }
1769     else if( version == 4 )
1770     is_v4=1;
1771     else if( version != 2 && version != 3 ) {
1772     printf("packet(%d) with unknown version %d\n", pkttype, version);
1773     rc = G10ERR_INVALID_PACKET;
1774     goto leave;
1775     }
1776    
1777     if( pktlen < 11 ) {
1778     printf("packet(%d) too short\n", pkttype);
1779     rc = G10ERR_INVALID_PACKET;
1780     goto leave;
1781     }
1782    
1783     timestamp = read_32(inp); pktlen -= 4;
1784     if( is_v4 ) {
1785     expiredate = 0; /* have to get it from the selfsignature */
1786     max_expiredate = 0;
1787     }
1788     else {
1789     unsigned short ndays;
1790     ndays = read_16(inp); pktlen -= 2;
1791     if( ndays )
1792     expiredate = timestamp + ndays * 86400L;
1793     else
1794     expiredate = 0;
1795    
1796     max_expiredate=expiredate;
1797     }
1798     algorithm = gpg_iobuf_get_noeof(inp); pktlen--;
1799     if( list_mode )
1800     printf(":%s key packet:\n"
1801     "\tversion %d, algo %d, created %lu, expires %lu\n",
1802     pkttype == PKT_PUBLIC_KEY? "public" :
1803     pkttype == PKT_SECRET_KEY? "secret" :
1804     pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
1805     pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
1806     version, algorithm, timestamp, expiredate );
1807    
1808     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1809     PKT_secret_key *sk = pkt->pkt.secret_key;
1810    
1811     sk->timestamp = timestamp;
1812     sk->expiredate = expiredate;
1813     sk->max_expiredate = max_expiredate;
1814     sk->hdrbytes = hdrlen;
1815     sk->version = version;
1816     sk->is_primary = pkttype == PKT_SECRET_KEY;
1817     sk->pubkey_algo = algorithm;
1818     sk->req_usage = 0;
1819     sk->pubkey_usage = 0; /* not yet used */
1820     }
1821     else {
1822     PKT_public_key *pk = pkt->pkt.public_key;
1823    
1824     pk->timestamp = timestamp;
1825     pk->expiredate = expiredate;
1826     pk->max_expiredate = max_expiredate;
1827     pk->hdrbytes = hdrlen;
1828     pk->version = version;
1829     pk->is_primary = pkttype == PKT_PUBLIC_KEY;
1830     pk->pubkey_algo = algorithm;
1831     pk->req_usage = 0;
1832     pk->pubkey_usage = 0; /* not yet used */
1833     pk->is_revoked = 0;
1834     pk->keyid[0] = 0;
1835     pk->keyid[1] = 0;
1836     }
1837     nskey = pubkey_get_nskey( algorithm );
1838     npkey = pubkey_get_npkey( algorithm );
1839     if( !npkey ) {
1840     if( list_mode )
1841     printf("\tunknown algorithm %d\n", algorithm );
1842     unknown_pubkey_warning( algorithm );
1843     }
1844    
1845    
1846     if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1847     PKT_secret_key *sk = pkt->pkt.secret_key;
1848     byte temp[16];
1849     size_t snlen = 0;
1850    
1851     if( !npkey ) {
1852     sk->skey[0] = mpi_set_opaque( NULL,
1853     read_rest(inp, pktlen), pktlen );
1854     pktlen = 0;
1855     goto leave;
1856     }
1857    
1858     for(i=0; i < npkey; i++ ) {
1859     n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1860     if( list_mode ) {
1861     printf( "\tskey[%d]: ", i);
1862     mpi_print(stdout, sk->skey[i], mpi_print_mode );
1863     putchar('\n');
1864     }
1865     if (!sk->skey[i])
1866     rc = G10ERR_INVALID_PACKET;
1867     }
1868     if (rc) /* one of the MPIs were bad */
1869     goto leave;
1870     sk->protect.algo = gpg_iobuf_get_noeof(inp); pktlen--;
1871     sk->protect.sha1chk = 0;
1872     if( sk->protect.algo ) {
1873     sk->is_protected = 1;
1874     sk->protect.s2k.count = 0;
1875     if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
1876     if( pktlen < 3 ) {
1877     rc = G10ERR_INVALID_PACKET;
1878     goto leave;
1879     }
1880     sk->protect.sha1chk = (sk->protect.algo == 254);
1881     sk->protect.algo = gpg_iobuf_get_noeof(inp); pktlen--;
1882     /* Note that a sk->protect.algo > 110 is illegal, but
1883     I'm not erroring on it here as otherwise there
1884     would be no way to delete such a key. */
1885     sk->protect.s2k.mode = gpg_iobuf_get_noeof(inp); pktlen--;
1886     sk->protect.s2k.hash_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1887     /* check for the special GNU extension */
1888     if( is_v4 && sk->protect.s2k.mode == 101 ) {
1889     for(i=0; i < 4 && pktlen; i++, pktlen-- )
1890     temp[i] = gpg_iobuf_get_noeof(inp);
1891     if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
1892     if( list_mode )
1893     printf( "\tunknown S2K %d\n",
1894     sk->protect.s2k.mode );
1895     rc = G10ERR_INVALID_PACKET;
1896     goto leave;
1897     }
1898     /* here we know that it is a gnu extension
1899     * What follows is the GNU protection mode:
1900     * All values have special meanings
1901     * and they are mapped in the mode with a base of 1000.
1902     */
1903     sk->protect.s2k.mode = 1000 + temp[3];
1904     }
1905     switch( sk->protect.s2k.mode ) {
1906     case 1:
1907     case 3:
1908     for(i=0; i < 8 && pktlen; i++, pktlen-- )
1909     temp[i] = gpg_iobuf_get_noeof(inp);
1910     memcpy(sk->protect.s2k.salt, temp, 8 );
1911     break;
1912     }
1913     switch( sk->protect.s2k.mode ) {
1914     case 0: if( list_mode ) printf( "\tsimple S2K" );
1915     break;
1916     case 1: if( list_mode ) printf( "\tsalted S2K" );
1917     break;
1918     case 3: if( list_mode ) printf( "\titer+salt S2K" );
1919     break;
1920     case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" );
1921     break;
1922     case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K");
1923     break;
1924     default:
1925     if( list_mode )
1926     printf( "\tunknown %sS2K %d\n",
1927     sk->protect.s2k.mode < 1000? "":"GNU ",
1928     sk->protect.s2k.mode );
1929     rc = G10ERR_INVALID_PACKET;
1930     goto leave;
1931     }
1932    
1933     if( list_mode ) {
1934     printf(", algo: %d,%s hash: %d",
1935     sk->protect.algo,
1936     sk->protect.sha1chk?" SHA1 protection,"
1937     :" simple checksum,",
1938     sk->protect.s2k.hash_algo );
1939     if( sk->protect.s2k.mode == 1
1940     || sk->protect.s2k.mode == 3 ) {
1941     printf(", salt: ");
1942     for(i=0; i < 8; i++ )
1943     printf("%02x", sk->protect.s2k.salt[i]);
1944     }
1945     putchar('\n');
1946     }
1947    
1948     if( sk->protect.s2k.mode == 3 ) {
1949     if( pktlen < 1 ) {
1950     rc = G10ERR_INVALID_PACKET;
1951     goto leave;
1952     }
1953     sk->protect.s2k.count = gpg_iobuf_get(inp);
1954     pktlen--;
1955     if( list_mode )
1956     printf("\tprotect count: %lu\n",
1957     (ulong)sk->protect.s2k.count);
1958     }
1959     else if( sk->protect.s2k.mode == 1002 ) {
1960     /* Read the serial number. */
1961     if (pktlen < 1) {
1962     rc = G10ERR_INVALID_PACKET;
1963     goto leave;
1964     }
1965     snlen = gpg_iobuf_get (inp);
1966     pktlen--;
1967     if (pktlen < snlen || snlen == -1) {
1968     rc = G10ERR_INVALID_PACKET;
1969     goto leave;
1970     }
1971     }
1972     }
1973     /* Note that a sk->protect.algo > 110 is illegal, but I'm
1974     not erroring on it here as otherwise there would be no
1975     way to delete such a key. */
1976     else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1977     sk->protect.s2k.mode = 0;
1978     sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1979     if( list_mode )
1980     printf( "\tprotect algo: %d (hash algo: %d)\n",
1981     sk->protect.algo, sk->protect.s2k.hash_algo );
1982     }
1983     /* It is really ugly that we don't know the size
1984     * of the IV here in cases we are not aware of the algorithm.
1985     * so a
1986     * sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1987     * won't work. The only solution I see is to hardwire it here.
1988     * NOTE: if you change the ivlen above 16, don't forget to
1989     * enlarge temp.
1990     */
1991     switch( sk->protect.algo ) {
1992     case 7: case 8: case 9: /* reserved for AES */
1993     case 10: /* Twofish */
1994     sk->protect.ivlen = 16;
1995     break;
1996     default:
1997     sk->protect.ivlen = 8;
1998     }
1999     if( sk->protect.s2k.mode == 1001 )
2000     sk->protect.ivlen = 0;
2001     else if( sk->protect.s2k.mode == 1002 )
2002     sk->protect.ivlen = snlen < 16? snlen : 16;
2003    
2004     if( pktlen < sk->protect.ivlen ) {
2005     rc = G10ERR_INVALID_PACKET;
2006     goto leave;
2007     }
2008     for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
2009     temp[i] = gpg_iobuf_get_noeof(inp);
2010     if( list_mode ) {
2011     printf( sk->protect.s2k.mode == 1002? "\tserial-number: "
2012     : "\tprotect IV: ");
2013     for(i=0; i < sk->protect.ivlen; i++ )
2014     printf(" %02x", temp[i] );
2015     putchar('\n');
2016     }
2017     memcpy( sk->protect.iv, temp, sk->protect.ivlen );
2018     }
2019     else
2020     sk->is_protected = 0;
2021     /* It does not make sense to read it into secure memory.
2022     * If the user is so careless, not to protect his secret key,
2023     * we can assume, that he operates an open system :=(.
2024     * So we put the key into secure memory when we unprotect it. */
2025     if( sk->protect.s2k.mode == 1001
2026     || sk->protect.s2k.mode == 1002 ) {
2027     /* better set some dummy stuff here */
2028     sk->skey[npkey] = mpi_set_opaque(NULL, strdup("dummydata"), 10);
2029     pktlen = 0;
2030     }
2031     else if( is_v4 && sk->is_protected ) {
2032     /* ugly; the length is encrypted too, so we read all
2033     * stuff up to the end of the packet into the first
2034     * skey element */
2035     sk->skey[npkey] = mpi_set_opaque(NULL,
2036     read_rest(inp, pktlen), pktlen );
2037     pktlen = 0;
2038     if( list_mode ) {
2039     printf("\tencrypted stuff follows\n");
2040     }
2041     }
2042     else { /* v3 method: the mpi length is not encrypted */
2043     for(i=npkey; i < nskey; i++ ) {
2044     n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
2045     if( sk->is_protected && sk->skey[i] )
2046     mpi_set_protect_flag(sk->skey[i]);
2047     if( list_mode ) {
2048     printf( "\tskey[%d]: ", i);
2049     if( sk->is_protected )
2050     printf( "[encrypted]\n");
2051     else {
2052     mpi_print(stdout, sk->skey[i], mpi_print_mode );
2053     putchar('\n');
2054     }
2055     }
2056     if (!sk->skey[i])
2057     rc = G10ERR_INVALID_PACKET;
2058     }
2059     if (rc)
2060     goto leave;
2061    
2062     sk->csum = read_16(inp); pktlen -= 2;
2063     if( list_mode ) {
2064     printf("\tchecksum: %04hx\n", sk->csum);
2065     }
2066     }
2067     }
2068     else {
2069     PKT_public_key *pk = pkt->pkt.public_key;
2070    
2071     if( !npkey ) {
2072     pk->pkey[0] = mpi_set_opaque( NULL,
2073     read_rest(inp, pktlen), pktlen );
2074     pktlen = 0;
2075     goto leave;
2076     }
2077    
2078     for(i=0; i < npkey; i++ ) {
2079     n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
2080     if( list_mode ) {
2081     printf( "\tpkey[%d]: ", i);
2082     mpi_print(stdout, pk->pkey[i], mpi_print_mode );
2083     putchar('\n');
2084     }
2085     if (!pk->pkey[i])
2086     rc = G10ERR_INVALID_PACKET;
2087     }
2088     if (rc)
2089     goto leave;
2090     }
2091    
2092     leave:
2093     skip_rest(inp, pktlen);
2094     return rc;
2095     }
2096    
2097     /* Attribute subpackets have the same format as v4 signature
2098     subpackets. This is not part of OpenPGP, but is done in several
2099     versions of PGP nevertheless. */
2100     int
2101     parse_attribute_subpkts(PKT_user_id *uid)
2102     {
2103     size_t n;
2104     int count=0;
2105     struct user_attribute *attribs=NULL;
2106     const byte *buffer=uid->attrib_data;
2107     int buflen=uid->attrib_len;
2108     byte type;
2109    
2110     safe_free(uid->attribs);
2111    
2112     while(buflen) {
2113     n = *buffer++; buflen--;
2114     if( n == 255 ) { /* 4 byte length header */
2115     if( buflen < 4 )
2116     goto too_short;
2117     n = (buffer[0] << 24) | (buffer[1] << 16)
2118     | (buffer[2] << 8) | buffer[3];
2119     buffer += 4;
2120     buflen -= 4;
2121     }
2122     else if( n >= 192 ) { /* 2 byte special encoded length header */
2123     if( buflen < 2 )
2124     goto too_short;
2125     n = (( n - 192 ) << 8) + *buffer + 192;
2126     buffer++;
2127     buflen--;
2128     }
2129     if( buflen < n )
2130     goto too_short;
2131    
2132     attribs=realloc(attribs,(count+1)*sizeof(struct user_attribute));
2133     memset(&attribs[count],0,sizeof(struct user_attribute));
2134    
2135     type=*buffer;
2136     buffer++;
2137     buflen--;
2138     n--;
2139    
2140     attribs[count].type=type;
2141     attribs[count].data=buffer;
2142     attribs[count].len=n;
2143     buffer+=n;
2144     buflen-=n;
2145     count++;
2146     }
2147    
2148     uid->attribs=attribs;
2149     uid->numattribs=count;
2150     return count;
2151    
2152     too_short:
2153     printf("buffer shorter than attribute subpacket\n");
2154     uid->attribs=attribs;
2155     uid->numattribs=count;
2156     return count;
2157     }
2158    
2159     static void
2160     setup_user_id(PACKET *packet)
2161     {
2162     packet->pkt.user_id->ref = 1;
2163     packet->pkt.user_id->attribs = NULL;
2164     packet->pkt.user_id->attrib_data = NULL;
2165     packet->pkt.user_id->attrib_len = 0;
2166     packet->pkt.user_id->is_primary = 0;
2167     packet->pkt.user_id->is_revoked = 0;
2168     packet->pkt.user_id->is_expired = 0;
2169     packet->pkt.user_id->expiredate = 0;
2170     packet->pkt.user_id->created = 0;
2171     packet->pkt.user_id->help_key_usage = 0;
2172     packet->pkt.user_id->help_key_expire = 0;
2173     packet->pkt.user_id->prefs = NULL;
2174     }
2175    
2176     static int
2177     parse_user_id( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2178     {
2179     byte *p;
2180    
2181     packet->pkt.user_id = malloc(sizeof *packet->pkt.user_id + pktlen);
2182     packet->pkt.user_id->len = pktlen;
2183    
2184     setup_user_id(packet);
2185    
2186     p = packet->pkt.user_id->name;
2187     for( ; pktlen; pktlen--, p++ )
2188     *p = gpg_iobuf_get_noeof(inp);
2189     *p = 0;
2190    
2191     if( list_mode ) {
2192     int n = packet->pkt.user_id->len;
2193     printf(":user ID packet: \"");
2194     /* fixme: Hey why don't we replace this with print_string?? */
2195     for(p=packet->pkt.user_id->name; n; p++, n-- ) {
2196     if( *p >= ' ' && *p <= 'z' )
2197     putchar(*p);
2198     else
2199     printf("\\x%02x", *p );
2200     }
2201     printf("\"\n");
2202     }
2203     return 0;
2204     }
2205    
2206     /* Returns 0 for error, 1 for valid */
2207     int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len)
2208     {
2209     u16 headerlen;
2210    
2211     if(attr->len<3)
2212     return 0;
2213    
2214     /* For historical reasons (i.e. "oops!"), the header length is
2215     little endian. */
2216     headerlen=(attr->data[1]<<8) | attr->data[0];
2217    
2218     if(headerlen>attr->len)
2219     return 0;
2220    
2221     if(type && attr->len>=4)
2222     {
2223     if(attr->data[2]==1) /* header version 1 */
2224     *type=attr->data[3];
2225     else
2226     *type=0;
2227     }
2228    
2229     *len=attr->len-headerlen;
2230    
2231     if(*len==0)
2232     return 0;
2233    
2234     return 1;
2235     }
2236    
2237     /* style==0 for extension, 1 for name, 2 for MIME type. Remember that
2238     the "name" style string could be used in a user ID name field, so
2239     make sure it is not too big (see
2240     parse-packet.c:parse_attribute). */
2241     char *image_type_to_string(byte type,int style)
2242     {
2243     char *string;
2244    
2245     switch(type) {
2246     case 1: /* jpeg */
2247     if(style==0)
2248     string="jpg";
2249     else if(style==1)
2250     string="jpeg";
2251     else
2252     string="image/jpeg";
2253     break;
2254    
2255     default:
2256     if(style==0)
2257     string="bin";
2258     else if(style==1)
2259     string="unknown";
2260     else
2261     string="image/x-unknown";
2262     break;
2263     }
2264    
2265     return string;
2266     }
2267    
2268     void
2269     make_attribute_uidname(PKT_user_id *uid)
2270     {
2271     if(uid->numattribs<=0)
2272     sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
2273     else if(uid->numattribs>1)
2274     sprintf(uid->name,"[%d attributes of size %lu]",
2275     uid->numattribs,uid->attrib_len);
2276     else {
2277     /* Only one attribute, so list it as the "user id" */
2278    
2279     if(uid->attribs->type==ATTRIB_IMAGE) {
2280     u32 len;
2281     byte type;
2282    
2283     if(parse_image_header(uid->attribs,&type,&len))
2284     sprintf(uid->name,"[%s image of size %lu]",
2285     image_type_to_string(type,1),(ulong)len);
2286     else
2287     sprintf(uid->name,"[invalid image]");
2288     }
2289     else
2290     sprintf(uid->name,"[unknown attribute of size %lu]",
2291     (ulong)uid->attribs->len);
2292     }
2293    
2294     uid->len = strlen(uid->name);
2295     }
2296    
2297     static int
2298     parse_attribute( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2299     {
2300     byte *p;
2301    
2302     packet->pkt.user_id = malloc(sizeof *packet->pkt.user_id + 70);
2303    
2304     setup_user_id(packet);
2305    
2306     packet->pkt.user_id->attrib_data = malloc(pktlen);
2307     packet->pkt.user_id->attrib_len = pktlen;
2308     p = packet->pkt.user_id->attrib_data;
2309     for( ; pktlen; pktlen--, p++ )
2310     *p = gpg_iobuf_get_noeof(inp);
2311    
2312     /* Now parse out the individual attribute subpackets. This is
2313     somewhat pointless since there is only one currently defined
2314     attribute type (jpeg), but it is correct by the spec. */
2315     parse_attribute_subpkts(packet->pkt.user_id);
2316    
2317     make_attribute_uidname(packet->pkt.user_id);
2318    
2319     if( list_mode ) {
2320     printf(":attribute packet: %s\n", packet->pkt.user_id->name );
2321     }
2322     return 0;
2323     }
2324    
2325    
2326     static int
2327     parse_comment( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2328     {
2329     byte *p;
2330    
2331     packet->pkt.comment = malloc(sizeof *packet->pkt.comment + pktlen - 1);
2332     packet->pkt.comment->len = pktlen;
2333     p = packet->pkt.comment->data;
2334     for( ; pktlen; pktlen--, p++ )
2335     *p = gpg_iobuf_get_noeof(inp);
2336    
2337     if( list_mode ) {
2338     int n = packet->pkt.comment->len;
2339     printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
2340     "OpenPGP draft " : "" );
2341     for(p=packet->pkt.comment->data; n; p++, n-- ) {
2342     if( *p >= ' ' && *p <= 'z' )
2343     putchar(*p);
2344     else
2345     printf("\\x%02x", *p );
2346     }
2347     printf("\"\n");
2348     }
2349     return 0;
2350     }
2351    
2352    
2353     static void
2354     parse_trust( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *pkt )
2355     {
2356     int c;
2357    
2358     if (pktlen) {
2359     c = gpg_iobuf_get_noeof(inp);
2360     pktlen--;
2361     pkt->pkt.ring_trust = malloc( sizeof *pkt->pkt.ring_trust );
2362     pkt->pkt.ring_trust->trustval = c;
2363     pkt->pkt.ring_trust->sigcache = 0;
2364     if (!c && pktlen==1) {
2365     c = gpg_iobuf_get_noeof (inp);
2366     pktlen--;
2367     /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2368     if ( !(c & 0x80) )
2369     pkt->pkt.ring_trust->sigcache = c;
2370     }
2371     if( list_mode )
2372     printf(":trust packet: flag=%02x sigcache=%02x\n",
2373     pkt->pkt.ring_trust->trustval,
2374     pkt->pkt.ring_trust->sigcache);
2375     }
2376     else {
2377     if( list_mode )
2378     printf(":trust packet: empty\n");
2379     }
2380     skip_rest (inp, pktlen);
2381     }
2382    
2383    
2384     static int
2385     parse_plaintext( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2386     PACKET *pkt, int new_ctb )
2387     {
2388     int rc = 0;
2389     int mode, namelen, partial=0;
2390     PKT_plaintext *pt;
2391     byte *p;
2392     int c, i;
2393    
2394     if( pktlen && pktlen < 6 ) {
2395     printf("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2396     rc = G10ERR_INVALID_PACKET;
2397     goto leave;
2398     }
2399     /* A packet length of zero indicates partial body length. A zero
2400     data length isn't a zero length packet due to the header (mode,
2401     name, etc), so this is accurate. */
2402     if(pktlen==0)
2403     partial=1;
2404     mode = gpg_iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2405     namelen = gpg_iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2406     pt = pkt->pkt.plaintext = malloc(sizeof *pkt->pkt.plaintext + namelen -1);
2407     pt->new_ctb = new_ctb;
2408     pt->mode = mode;
2409     pt->namelen = namelen;
2410     pt->is_partial = partial;
2411     if( pktlen ) {
2412     for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2413     pt->name[i] = gpg_iobuf_get_noeof(inp);
2414     }
2415     else {
2416     for( i=0; i < namelen; i++ )
2417     if( (c=gpg_iobuf_get(inp)) == -1 )
2418     break;
2419     else
2420     pt->name[i] = c;
2421     }
2422     pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2423     pt->len = pktlen;
2424     pt->buf = inp;
2425     pktlen = 0;
2426    
2427     if( list_mode ) {
2428     printf(":literal data packet:\n"
2429     "\tmode %c, created %lu, name=\"",
2430     mode >= ' ' && mode <'z'? mode : '?',
2431     (ulong)pt->timestamp );
2432     for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2433     if( *p >= ' ' && *p <= 'z' )
2434     putchar(*p);
2435     else
2436     printf("\\x%02x", *p );
2437     }
2438     printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
2439     }
2440    
2441     leave:
2442     return rc;
2443     }
2444    
2445    
2446     static int
2447     parse_compressed( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2448     PACKET *pkt, int new_ctb )
2449     {
2450     PKT_compressed *zd;
2451    
2452     /* pktlen is here 0, but data follows
2453     * (this should be the last object in a file or
2454     * the compress algorithm should know the length)
2455     */
2456     zd = pkt->pkt.compressed = malloc(sizeof *pkt->pkt.compressed );
2457     zd->algorithm = gpg_iobuf_get_noeof(inp);
2458     zd->len = 0; /* not used */
2459     zd->new_ctb = new_ctb;
2460     zd->buf = inp;
2461     if( list_mode )
2462     printf(":compressed packet: algo=%d\n", zd->algorithm);
2463     return 0;
2464     }
2465    
2466    
2467     static int
2468     parse_encrypted( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2469     PACKET *pkt, int new_ctb )
2470     {
2471     int rc = 0;
2472     PKT_encrypted *ed;
2473     unsigned long orig_pktlen = pktlen;
2474    
2475     ed = pkt->pkt.encrypted = malloc(sizeof *pkt->pkt.encrypted );
2476     ed->len = pktlen;
2477     /* we don't know the extralen which is (cipher_blocksize+2)
2478     because the algorithm ist not specified in this packet.
2479     However, it is only important to know this for some sanity
2480     checks on the packet length - it doesn't matter that we can't
2481     do it */
2482     ed->extralen = 0;
2483     ed->buf = NULL;
2484     ed->new_ctb = new_ctb;
2485     ed->mdc_method = 0;
2486     if( pkttype == PKT_ENCRYPTED_MDC ) {
2487     /* fixme: add some pktlen sanity checks */
2488     int version;
2489    
2490     version = gpg_iobuf_get_noeof(inp);
2491     if (orig_pktlen)
2492     pktlen--;
2493     if( version != 1 ) {
2494     printf("encrypted_mdc packet with unknown version %d\n",
2495     version);
2496     /*skip_rest(inp, pktlen); should we really do this? */
2497     rc = G10ERR_INVALID_PACKET;
2498     goto leave;
2499     }
2500     ed->mdc_method = DIGEST_ALGO_SHA1;
2501     }
2502     if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2503     printf("packet(%d) too short\n", pkttype);
2504     rc = G10ERR_INVALID_PACKET;
2505     skip_rest(inp, pktlen);
2506     goto leave;
2507     }
2508     if( list_mode ) {
2509     if( orig_pktlen )
2510     printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
2511     else
2512     printf(":encrypted data packet:\n\tlength: unknown\n");
2513     if( ed->mdc_method )
2514     printf("\tmdc_method: %d\n", ed->mdc_method );
2515     }
2516    
2517     ed->buf = inp;
2518     pktlen = 0;
2519    
2520     leave:
2521     return rc;
2522     }
2523    
2524    
2525     static int
2526     parse_mdc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2527     PACKET *pkt, int new_ctb )
2528     {
2529     int rc = 0;
2530     PKT_mdc *mdc;
2531     byte *p;
2532    
2533     mdc = pkt->pkt.mdc= malloc(sizeof *pkt->pkt.mdc );
2534     if( list_mode )
2535     printf(":mdc packet: length=%lu\n", pktlen);
2536     if( !new_ctb || pktlen != 20 ) {
2537     printf("mdc_packet with invalid encoding\n");
2538     rc = G10ERR_INVALID_PACKET;
2539     goto leave;
2540     }
2541     p = mdc->hash;
2542     for( ; pktlen; pktlen--, p++ )
2543     *p = gpg_iobuf_get_noeof(inp);
2544    
2545     leave:
2546     return rc;
2547     }
2548    
2549    
2550     /*
2551     * This packet is internally generated by PGG (by armor.c) to
2552     * transfer some information to the lower layer. To make sure that
2553     * this packet is really a GPG faked one and not one comming from outside,
2554     * we first check that tehre is a unique tag in it.
2555     * The format of such a control packet is:
2556     * n byte session marker
2557     * 1 byte control type CTRLPKT_xxxxx
2558     * m byte control data
2559     */
2560    
2561     /* Return a string which is used as a kind of process ID */
2562     const byte *
2563     get_session_marker( size_t *rlen )
2564     {
2565     static byte marker[SIZEOF_UNSIGNED_LONG*2];
2566     static int initialized;
2567    
2568     if ( !initialized ) {
2569     volatile ulong aa, bb; /* we really want the uninitialized value */
2570     ulong a, b;
2571    
2572     initialized = 1;
2573     /* also this marker is guessable it is not easy to use this
2574     * for a faked control packet because an attacker does not
2575     * have enough control about the time the verification does
2576     * take place. Of course, we can add just more random but
2577     * than we need the random generator even for verification
2578     * tasks - which does not make sense. */
2579     a = aa ^ (ulong)getpid();
2580     b = bb ^ (ulong)time(NULL);
2581     memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
2582     memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
2583     }
2584     *rlen = sizeof(marker);
2585     return marker;
2586     }
2587    
2588     static int
2589     parse_gpg_control( gpg_iobuf_t inp,
2590     int pkttype, unsigned long pktlen, PACKET *packet )
2591     {
2592     byte *p;
2593     const byte *sesmark;
2594     size_t sesmarklen;
2595     int i;
2596    
2597     if ( list_mode )
2598     printf(":packet 63: length %lu ", pktlen);
2599    
2600     sesmark = get_session_marker ( &sesmarklen );
2601     if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2602     goto skipit;
2603     for( i=0; i < sesmarklen; i++, pktlen-- ) {
2604     if ( sesmark[i] != gpg_iobuf_get_noeof(inp) )
2605     goto skipit;
2606     }
2607     if ( list_mode )
2608     puts ("- gpg control packet");
2609    
2610     packet->pkt.gpg_control = malloc(sizeof *packet->pkt.gpg_control
2611     + pktlen - 1);
2612     packet->pkt.gpg_control->control = gpg_iobuf_get_noeof(inp); pktlen--;
2613     packet->pkt.gpg_control->datalen = pktlen;
2614     p = packet->pkt.gpg_control->data;
2615     for( ; pktlen; pktlen--, p++ )
2616     *p = gpg_iobuf_get_noeof(inp);
2617    
2618     return 0;
2619    
2620     skipit:
2621     if ( list_mode ) {
2622     int c;
2623    
2624     i=0;
2625     printf("- private (rest length %lu)\n", pktlen);
2626     if( gpg_iobuf_in_block_mode(inp) ) {
2627     while( (c=gpg_iobuf_get(inp)) != -1 )
2628     dump_hex_line(c, &i);
2629     }
2630     else {
2631     for( ; pktlen; pktlen-- )
2632     dump_hex_line(gpg_iobuf_get(inp), &i);
2633     }
2634     putchar('\n');
2635     }
2636     skip_rest(inp,pktlen);
2637     return G10ERR_INVALID_PACKET;
2638     }
2639    
2640    
2641     u32
2642     gpg_keyid_from_pk( PKT_public_key * pk, byte *fprint )
2643     {
2644     gpg_md_t md;
2645     int npkey, pktlen, i;
2646     const byte *mdbuf;
2647    
2648     if( pk->version == 3 && pk->pubkey_algo == PUBKEY_ALGO_RSA )
2649     return pk->pkey[0]->d[0];
2650     else {
2651     md = gpg_md_open( DIGEST_ALGO_SHA1 );
2652     gpg_md_putc( md, 0x99 );
2653     npkey = pubkey_get_npkey( pk->pubkey_algo );
2654     pktlen = 6;
2655     for( i = 0 ; i <npkey; i++ )
2656     pktlen = pktlen + 2 + pk->pkey[i]->alloced;
2657     gpg_md_putc( md, pktlen>>8 );
2658     gpg_md_putc( md, pktlen );
2659     gpg_md_putc( md, 4 );
2660     gpg_md_putc( md, pk->timestamp >> 24 );
2661     gpg_md_putc( md, pk->timestamp >> 16 );
2662     gpg_md_putc( md, pk->timestamp >> 8 );
2663     gpg_md_putc( md, pk->timestamp );
2664     gpg_md_putc( md, pk->pubkey_algo );
2665     for( i=0; i <npkey; i++ ) {
2666     const u32 * d = pk->pkey[i]->d;
2667     int nbits = pk->pkey[i]->nbits,
2668     n = pk->pkey[i]->alloced;
2669     gpg_md_putc( md, nbits >> 8 );
2670     gpg_md_putc( md, nbits );
2671     n = n>4? n/4 : n;
2672     while( n-- ) {
2673     if( pk->pkey[i]->alloced > 3 )
2674     gpg_md_putc( md, d[n] >> 24 );
2675     if( pk->pkey[i]->alloced > 2 )
2676     gpg_md_putc( md, d[n] >> 16 );
2677     if( pk->pkey[i]->alloced > 1 )
2678     gpg_md_putc( md, d[n] >> 8 );
2679     if( pk->pkey[i]->alloced > 0 )
2680     gpg_md_putc( md, d[n] );
2681     }
2682     }
2683     gpg_md_final( md );
2684     mdbuf = gpg_md_read( md );
2685     }
2686     if( mdbuf && fprint )
2687     memcpy( fprint, mdbuf, 20 );
2688     return mdbuf? mdbuf[16] << 24 | mdbuf[17] << 16 | mdbuf[18] << 8 | mdbuf[19] : 0;
2689     }
2690    
2691    
2692     u32
2693     gpg_keyid_from_sk( PKT_secret_key * sk, byte *fprint )
2694     {
2695     PKT_public_key pk;
2696     int npkey = pubkey_get_npkey( sk->pubkey_algo );
2697     int i;
2698    
2699     pk.pubkey_algo = sk->pubkey_algo;
2700     pk.version = sk->version;
2701     pk.timestamp = sk->timestamp;
2702     pk.expiredate = sk->expiredate;
2703     pk.pubkey_algo = sk->pubkey_algo;
2704     for( i=0; i < npkey; i++ )
2705     pk.pkey[i] = sk->skey[i];
2706     return gpg_keyid_from_pk( &pk, fprint );
2707     }
2708    
2709    
2710     /****************
2711     * Read the next keyblock from stream A.
2712     * PENDING_PKT should be initialzed to NULL
2713     * and not chnaged form the caller.
2714     * Retunr: 0 = okay, -1 no more blocks or another errorcode.
2715     */
2716     int
2717     gpg_read_keyblock( gpg_iobuf_t a, PACKET **pending_pkt, gpg_kbnode_t *ret_root )
2718     {
2719     int rc;
2720     PACKET *pkt;
2721     gpg_kbnode_t root = NULL;
2722     int in_cert;
2723    
2724     if( *pending_pkt ) {
2725     root = gpg_new_kbnode( *pending_pkt );
2726     *pending_pkt = NULL;
2727     in_cert = 1;
2728     }
2729     else
2730     in_cert = 0;
2731     pkt = malloc( sizeof *pkt );
2732     gpg_init_packet(pkt);
2733     while( (rc=gpg_parse_packet(a, pkt)) != -1 ) {
2734     if( rc ) { /* ignore errors */
2735     if( rc != G10ERR_UNKNOWN_PACKET ) {
2736     printf("read_block: read error: %d\n", rc );
2737     rc = G10ERR_INV_KEYRING;
2738     goto ready;
2739     }
2740     gpg_free_packet( pkt );
2741     gpg_init_packet(pkt);
2742     continue;
2743     }
2744    
2745     if( !root && pkt->pkttype == PKT_SIGNATURE
2746     && pkt->pkt.signature->sig_class == 0x20 ) {
2747     /* this is a revocation certificate which is handled
2748     * in a special way */
2749     root = gpg_new_kbnode( pkt );
2750     pkt = NULL;
2751     goto ready;
2752     }
2753    
2754     /* make a linked list of all packets */
2755     switch( pkt->pkttype ) {
2756     case PKT_RING_TRUST:
2757     /* skip those packets */
2758     gpg_free_packet( pkt );
2759     gpg_init_packet(pkt);
2760     break;
2761    
2762     case PKT_PUBLIC_KEY:
2763     case PKT_SECRET_KEY:
2764     if( in_cert ) { /* store this packet */
2765     *pending_pkt = pkt;
2766     pkt = NULL;
2767     goto ready;
2768     }
2769     in_cert = 1;
2770     default:
2771     if( in_cert ) {
2772     if( !root )
2773     root = gpg_new_kbnode( pkt );
2774     else
2775     gpg_add_kbnode( root, gpg_new_kbnode( pkt ) );
2776     pkt = malloc( sizeof *pkt );
2777     }
2778     gpg_init_packet(pkt);
2779     break;
2780     }
2781     }
2782     ready:
2783     if( rc == -1 && root )
2784     rc = 0;
2785    
2786     if( rc )
2787     gpg_release_kbnode( root );
2788     else
2789     *ret_root = root;
2790     gpg_free_packet( pkt );
2791     free( pkt );
2792     return rc;
2793     }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26