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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 214 - (show annotations)
Sun May 14 18:40:36 2006 UTC (18 years, 9 months ago) by twoaday
File MIME type: text/plain
File size: 74385 byte(s)
2006-05-14  Timo Schulz  <ts@g10code.de>
                                                                                
        * wptKeyCache.cpp (gpg_keycache_update_attr): Parse
        preferred keyserver URL.
        * wptHTTP.cpp (extractHostInfo): Fix segv.
        * wptGPGUtil.cpp (gpg_find_key_subpacket): Ignore default
        gpg.conf.
        * wptKeyserverSearchDlg.cpp (search_hkp_keys): Do not
        assume an existing user id.
        * wptPassphraseCB.cpp (passphrase_cb): Automatic cancel
        if no passphrase is available.

(for complete list of changes, see Src/ChangeLog)

About to release 0.12.1


1 /* 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 static void
118 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 }
356
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 rc = G10ERR_INVALID_PACKET;
748 goto leave;
749 }
750
751 if( out && pkttype ) {
752 if( gpg_iobuf_write( out, hdr, hdrlen ) == -1 )
753 rc = G10ERR_WRITE_FILE;
754 else
755 rc = copy_packet(inp, out, pkttype, pktlen );
756 goto leave;
757 }
758
759 if (with_uid && pkttype == PKT_USER_ID)
760 ;
761 else if( do_skip
762 || !pkttype
763 || (onlykeypkts && pkttype != PKT_PUBLIC_SUBKEY
764 && pkttype != PKT_PUBLIC_KEY
765 && pkttype != PKT_SECRET_SUBKEY
766 && pkttype != PKT_SECRET_KEY ) ) {
767 skip_rest(inp, pktlen);
768 *skip = 1;
769 rc = 0;
770 goto leave;
771 }
772
773 pkt->pkttype = pkttype;
774 rc = G10ERR_UNKNOWN_PACKET; /* default error */
775 switch( pkttype ) {
776 case PKT_PUBLIC_KEY:
777 case PKT_PUBLIC_SUBKEY:
778 pkt->pkt.public_key = calloc(1, sizeof *pkt->pkt.public_key );
779 rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
780 break;
781 case PKT_SECRET_KEY:
782 case PKT_SECRET_SUBKEY:
783 pkt->pkt.secret_key = calloc(1,sizeof *pkt->pkt.secret_key );
784 rc = parse_key(inp, pkttype, pktlen, hdr, hdrlen, pkt );
785 break;
786 case PKT_SYMKEY_ENC:
787 rc = parse_symkeyenc( inp, pkttype, pktlen, pkt );
788 break;
789 case PKT_PUBKEY_ENC:
790 rc = parse_pubkeyenc(inp, pkttype, pktlen, pkt );
791 break;
792 case PKT_SIGNATURE:
793 pkt->pkt.signature = calloc(1,sizeof *pkt->pkt.signature );
794 rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
795 break;
796 case PKT_ONEPASS_SIG:
797 pkt->pkt.onepass_sig = calloc(1,sizeof *pkt->pkt.onepass_sig );
798 rc = parse_onepass_sig(inp, pkttype, pktlen, pkt->pkt.onepass_sig );
799 break;
800 case PKT_USER_ID:
801 rc = parse_user_id(inp, pkttype, pktlen, pkt );
802 break;
803 case PKT_ATTRIBUTE:
804 pkt->pkttype = pkttype = PKT_USER_ID; /* we store it in the userID */
805 rc = parse_attribute(inp, pkttype, pktlen, pkt);
806 break;
807 case PKT_OLD_COMMENT:
808 case PKT_COMMENT:
809 rc = parse_comment(inp, pkttype, pktlen, pkt);
810 break;
811 case PKT_RING_TRUST:
812 parse_trust(inp, pkttype, pktlen, pkt);
813 rc = 0;
814 break;
815 case PKT_PLAINTEXT:
816 rc = parse_plaintext(inp, pkttype, pktlen, pkt, new_ctb );
817 break;
818 case PKT_COMPRESSED:
819 rc = parse_compressed(inp, pkttype, pktlen, pkt, new_ctb );
820 break;
821 case PKT_ENCRYPTED:
822 case PKT_ENCRYPTED_MDC:
823 rc = parse_encrypted(inp, pkttype, pktlen, pkt, new_ctb );
824 break;
825 case PKT_MDC:
826 rc = parse_mdc(inp, pkttype, pktlen, pkt, new_ctb );
827 break;
828 case PKT_GPG_CONTROL:
829 rc = parse_gpg_control(inp, pkttype, pktlen, pkt );
830 break;
831 default:
832 skip_packet(inp, pkttype, pktlen);
833 break;
834 }
835
836 leave:
837 if( !rc && gpg_iobuf_error(inp) )
838 rc = G10ERR_INV_KEYRING;
839 return rc;
840 }
841
842 static void
843 dump_hex_line( int c, int *i )
844 {
845 if( *i && !(*i%8) ) {
846 if( *i && !(*i%24) )
847 printf("\n%4d:", *i );
848 else
849 putchar(' ');
850 }
851 if( c == -1 )
852 printf(" EOF" );
853 else
854 printf(" %02x", c );
855 ++*i;
856 }
857
858
859 static int
860 copy_packet( gpg_iobuf_t inp, gpg_iobuf_t out, int pkttype, unsigned long pktlen )
861 {
862 int n;
863 char buf[100];
864
865 if( gpg_iobuf_in_block_mode(inp) ) {
866 while( (n = gpg_iobuf_read( inp, buf, 100 )) != -1 )
867 if( gpg_iobuf_write(out, buf, n ) )
868 return G10ERR_WRITE_FILE; /* write error */
869 }
870 else if( !pktlen && pkttype == PKT_COMPRESSED ) {
871 printf("copy_packet: compressed!\n");
872 /* compressed packet, copy till EOF */
873 while( (n = gpg_iobuf_read( inp, buf, 100 )) != -1 )
874 if( gpg_iobuf_write(out, buf, n ) )
875 return G10ERR_WRITE_FILE; /* write error */
876 }
877 else {
878 for( ; pktlen; pktlen -= n ) {
879 n = pktlen > 100 ? 100 : pktlen;
880 n = gpg_iobuf_read( inp, buf, n );
881 if( n == -1 )
882 return G10ERR_READ_FILE;
883 if( gpg_iobuf_write(out, buf, n ) )
884 return G10ERR_WRITE_FILE; /* write error */
885 }
886 }
887 return 0;
888 }
889
890
891 static void
892 skip_packet( gpg_iobuf_t inp, int pkttype, unsigned long pktlen )
893 {
894 if( list_mode ) {
895 if( pkttype == PKT_MARKER )
896 fputs(":marker packet:\n", stdout );
897 else
898 printf(":unknown packet: type %2d, length %lu\n", pkttype, pktlen);
899 if( pkttype ) {
900 int c, i=0 ;
901 if( pkttype != PKT_MARKER )
902 fputs("dump:", stdout );
903 if( gpg_iobuf_in_block_mode(inp) ) {
904 while( (c=gpg_iobuf_get(inp)) != -1 )
905 dump_hex_line(c, &i);
906 }
907 else {
908 for( ; pktlen; pktlen-- )
909 dump_hex_line(gpg_iobuf_get(inp), &i);
910 }
911 putchar('\n');
912 return;
913 }
914 }
915 skip_rest(inp,pktlen);
916 }
917
918 static void
919 skip_rest( gpg_iobuf_t inp, unsigned long pktlen )
920 {
921 if( gpg_iobuf_in_block_mode(inp) ) {
922 while( gpg_iobuf_get(inp) != -1 )
923 ;
924 }
925 else {
926 for( ; pktlen; pktlen-- )
927 if( gpg_iobuf_get(inp) == -1 )
928 break;
929 }
930 }
931
932
933 static void *
934 read_rest( gpg_iobuf_t inp, size_t pktlen )
935 {
936 byte *p;
937 int i;
938
939 if( gpg_iobuf_in_block_mode(inp) ) {
940 printf("read_rest: can't store stream data\n");
941 p = NULL;
942 }
943 else {
944 p = malloc( pktlen );
945 for(i=0; pktlen; pktlen--, i++ )
946 p[i] = gpg_iobuf_get(inp);
947 }
948 return p;
949 }
950
951
952
953 static int
954 parse_symkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
955 {
956 PKT_symkey_enc *k;
957 int rc = 0;
958 int i, version, s2kmode, cipher_algo, hash_algo, seskeylen, minlen;
959
960 if( pktlen < 4 ) {
961 printf("packet(%d) too short\n", pkttype);
962 rc = G10ERR_INVALID_PACKET;
963 goto leave;
964 }
965 version = gpg_iobuf_get_noeof(inp); pktlen--;
966 if( version != 4 ) {
967 printf("packet(%d) with unknown version %d\n", pkttype, version);
968 rc = G10ERR_INVALID_PACKET;
969 goto leave;
970 }
971 if( pktlen > 200 ) { /* (we encode the seskeylen in a byte) */
972 printf("packet(%d) too large\n", pkttype);
973 rc = G10ERR_INVALID_PACKET;
974 goto leave;
975 }
976 cipher_algo = gpg_iobuf_get_noeof(inp); pktlen--;
977 s2kmode = gpg_iobuf_get_noeof(inp); pktlen--;
978 hash_algo = gpg_iobuf_get_noeof(inp); pktlen--;
979 switch( s2kmode ) {
980 case 0: /* simple s2k */
981 minlen = 0;
982 break;
983 case 1: /* salted s2k */
984 minlen = 8;
985 break;
986 case 3: /* iterated+salted s2k */
987 minlen = 9;
988 break;
989 default:
990 printf("unknown S2K %d\n", s2kmode );
991 goto leave;
992 }
993 if( minlen > pktlen ) {
994 printf("packet with S2K %d too short\n", s2kmode );
995 rc = G10ERR_INVALID_PACKET;
996 goto leave;
997 }
998 seskeylen = pktlen - minlen;
999 k = packet->pkt.symkey_enc = calloc(1, sizeof *packet->pkt.symkey_enc
1000 + seskeylen - 1 );
1001 k->version = version;
1002 k->cipher_algo = cipher_algo;
1003 k->s2k.mode = s2kmode;
1004 k->s2k.hash_algo = hash_algo;
1005 if( s2kmode == 1 || s2kmode == 3 ) {
1006 for(i=0; i < 8 && pktlen; i++, pktlen-- )
1007 k->s2k.salt[i] = gpg_iobuf_get_noeof(inp);
1008 }
1009 if( s2kmode == 3 ) {
1010 k->s2k.count = gpg_iobuf_get(inp); pktlen--;
1011 }
1012 k->seskeylen = seskeylen;
1013 for(i=0; i < seskeylen && pktlen; i++, pktlen-- )
1014 k->seskey[i] = gpg_iobuf_get_noeof(inp);
1015 assert( !pktlen );
1016
1017 if( list_mode ) {
1018 printf(":symkey enc packet: version %d, cipher %d, s2k %d, hash %d\n",
1019 version, cipher_algo, s2kmode, hash_algo);
1020 if( s2kmode == 1 || s2kmode == 3 ) {
1021 printf("\tsalt ");
1022 for(i=0; i < 8; i++ )
1023 printf("%02x", k->s2k.salt[i]);
1024 if( s2kmode == 3 )
1025 printf(", count %lu\n", (ulong)k->s2k.count );
1026 printf("\n");
1027 }
1028 }
1029
1030 leave:
1031 skip_rest(inp, pktlen);
1032 return rc;
1033 }
1034
1035 static int
1036 parse_pubkeyenc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
1037 {
1038 unsigned int n;
1039 int rc = 0;
1040 int i, ndata;
1041 PKT_pubkey_enc *k;
1042
1043 k = packet->pkt.pubkey_enc = calloc(1, sizeof *packet->pkt.pubkey_enc);
1044 if( pktlen < 12 ) {
1045 printf("packet(%d) too short\n", pkttype);
1046 rc = G10ERR_INVALID_PACKET;
1047 goto leave;
1048 }
1049 k->version = gpg_iobuf_get_noeof(inp); pktlen--;
1050 if( k->version != 2 && k->version != 3 ) {
1051 printf("packet(%d) with unknown version %d\n", pkttype, k->version);
1052 rc = G10ERR_INVALID_PACKET;
1053 goto leave;
1054 }
1055 k->keyid[0] = read_32(inp); pktlen -= 4;
1056 k->keyid[1] = read_32(inp); pktlen -= 4;
1057 k->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1058 k->throw_keyid = 0; /* only used as flag for build_packet */
1059 if( list_mode )
1060 printf(":pubkey enc packet: version %d, algo %d, keyid %08lX%08lX\n",
1061 k->version, k->pubkey_algo, (ulong)k->keyid[0], (ulong)k->keyid[1]);
1062
1063 ndata = pubkey_get_nenc(k->pubkey_algo);
1064 if( !ndata ) {
1065 if( list_mode )
1066 printf("\tunsupported algorithm %d\n", k->pubkey_algo );
1067 unknown_pubkey_warning( k->pubkey_algo );
1068 k->data[0] = NULL; /* no need to store the encrypted data */
1069 }
1070 else {
1071 for( i=0; i < ndata; i++ ) {
1072 n = pktlen;
1073 k->data[i] = mpi_read(inp, &n, 0); pktlen -=n;
1074 if( list_mode ) {
1075 printf("\tdata: ");
1076 mpi_print(stdout, k->data[i], mpi_print_mode );
1077 putchar('\n');
1078 }
1079 if (!k->data[i])
1080 rc = G10ERR_INVALID_PACKET;
1081 }
1082 }
1083
1084 leave:
1085 skip_rest(inp, pktlen);
1086 return rc;
1087 }
1088
1089 static void
1090 dump_sig_subpkt( int hashed, int type, int critical,
1091 const byte *buffer, size_t buflen, size_t length )
1092 {
1093 const char *p=NULL;
1094 int i;
1095
1096 /* The CERT has warning out with explains how to use GNUPG to
1097 * detect the ARRs - we print our old message here when it is a faked
1098 * ARR and add an additional notice */
1099 if ( type == SIGSUBPKT_ARR && !hashed ) {
1100 printf("\tsubpkt %d len %u (additional recipient request)\n"
1101 "WARNING: PGP versions > 5.0 and < 6.5.8 will automagically "
1102 "encrypt to this key and thereby reveal the plaintext to "
1103 "the owner of this ARR key. Detailed info follows:\n",
1104 type, (unsigned)length );
1105 }
1106
1107
1108 printf("\t%s%ssubpkt %d len %u (", /*)*/
1109 critical ? "critical ":"",
1110 hashed ? "hashed ":"", type, (unsigned)length );
1111 buffer++;
1112 length--;
1113 if( length > buflen ) {
1114 printf("too short: buffer is only %u)\n", (unsigned)buflen );
1115 return;
1116 }
1117 switch( type ) {
1118 case SIGSUBPKT_SIG_CREATED:
1119 if( length >= 4 )
1120 printf("sig created %s", strtimestamp( buffer_to_u32(buffer) ) );
1121 break;
1122 case SIGSUBPKT_SIG_EXPIRE:
1123 if( length >= 4 )
1124 printf("sig expires after %s",
1125 strtimevalue( buffer_to_u32(buffer) ) );
1126 break;
1127 case SIGSUBPKT_EXPORTABLE:
1128 if( length )
1129 printf("%sexportable", *buffer? "":"not ");
1130 break;
1131 case SIGSUBPKT_TRUST:
1132 if(length!=2)
1133 p="[invalid trust signature]";
1134 else
1135 printf("trust signature of level %d, amount %d",buffer[0],buffer[1]);
1136 break;
1137 case SIGSUBPKT_REGEXP:
1138 if(!length)
1139 p="[invalid regexp]";
1140 else
1141 printf("regular expression: \"%s\"",buffer);
1142 break;
1143 case SIGSUBPKT_REVOCABLE:
1144 if( length )
1145 printf("%srevocable", *buffer? "":"not ");
1146 break;
1147 case SIGSUBPKT_KEY_EXPIRE:
1148 if( length >= 4 )
1149 printf("key expires after %s",
1150 strtimevalue( buffer_to_u32(buffer) ) );
1151 break;
1152 case SIGSUBPKT_PREF_SYM:
1153 fputs("pref-sym-algos:", stdout );
1154 for( i=0; i < length; i++ )
1155 printf(" %d", buffer[i] );
1156 break;
1157 case SIGSUBPKT_REV_KEY:
1158 fputs("revocation key: ", stdout );
1159 if( length < 22 )
1160 p = "[too short]";
1161 else {
1162 printf("c=%02x a=%d f=", buffer[0], buffer[1] );
1163 for( i=2; i < length; i++ )
1164 printf("%02X", buffer[i] );
1165 }
1166 break;
1167 case SIGSUBPKT_ISSUER:
1168 if( length >= 8 )
1169 printf("issuer key ID %08lX%08lX",
1170 (ulong)buffer_to_u32(buffer),
1171 (ulong)buffer_to_u32(buffer+4) );
1172 break;
1173 case SIGSUBPKT_NOTATION:
1174 {
1175 fputs("notation: ", stdout );
1176 if( length < 8 )
1177 p = "[too short]";
1178 else if( !(*buffer & 0x80) )
1179 p = "[not human readable]";
1180 else {
1181 const byte *s = buffer;
1182 size_t n1, n2;
1183
1184 n1 = (s[4] << 8) | s[5];
1185 n2 = (s[6] << 8) | s[7];
1186 s += 8;
1187 if( 8+n1+n2 != length )
1188 p = "[error]";
1189 else {
1190 print_string( stdout, s, n1, ')' );
1191 putc( '=', stdout );
1192 print_string( stdout, s+n1, n2, ')' );
1193 }
1194 }
1195 }
1196 break;
1197 case SIGSUBPKT_PREF_HASH:
1198 fputs("pref-hash-algos:", stdout );
1199 for( i=0; i < length; i++ )
1200 printf(" %d", buffer[i] );
1201 break;
1202 case SIGSUBPKT_PREF_COMPR:
1203 fputs("pref-zip-algos:", stdout );
1204 for( i=0; i < length; i++ )
1205 printf(" %d", buffer[i] );
1206 break;
1207 case SIGSUBPKT_KS_FLAGS:
1208 fputs("key server preferences:",stdout);
1209 for(i=0;i<length;i++)
1210 printf(" %02X", buffer[i]);
1211 break;
1212 case SIGSUBPKT_PREF_KS:
1213 p = "preferred key server";
1214 break;
1215 case SIGSUBPKT_PRIMARY_UID:
1216 p = "primary user ID";
1217 break;
1218 case SIGSUBPKT_POLICY:
1219 fputs("policy: ", stdout );
1220 print_string( stdout, buffer, length, ')' );
1221 break;
1222 case SIGSUBPKT_KEY_FLAGS:
1223 fputs ( "key flags:", stdout );
1224 for( i=0; i < length; i++ )
1225 printf(" %02X", buffer[i] );
1226 break;
1227 case SIGSUBPKT_SIGNERS_UID:
1228 p = "signer's user ID";
1229 break;
1230 case SIGSUBPKT_REVOC_REASON:
1231 if( length ) {
1232 printf("revocation reason 0x%02x (", *buffer );
1233 print_string( stdout, buffer+1, length-1, ')' );
1234 p = ")";
1235 }
1236 break;
1237 case SIGSUBPKT_ARR:
1238 fputs("Big Brother's key (ignored): ", stdout );
1239 if( length < 22 )
1240 p = "[too short]";
1241 else {
1242 printf("c=%02x a=%d f=", buffer[0], buffer[1] );
1243 for( i=2; i < length; i++ )
1244 printf("%02X", buffer[i] );
1245 }
1246 break;
1247 case SIGSUBPKT_FEATURES:
1248 fputs ( "features:", stdout );
1249 for( i=0; i < length; i++ )
1250 printf(" %02x", buffer[i] );
1251 break;
1252 case SIGSUBPKT_PRIV_VERIFY_CACHE:
1253 p = "obsolete verification cache";
1254 break;
1255 default: p = "?"; break;
1256 }
1257
1258 printf("%s)\n", p? p: "");
1259 }
1260
1261 /****************
1262 * Returns: >= 0 offset into buffer
1263 * -1 unknown type
1264 * -2 unsupported type
1265 * -3 subpacket too short
1266 */
1267 int
1268 parse_one_sig_subpkt( const byte *buffer, size_t n, int type )
1269 {
1270 switch( type ) {
1271 case SIGSUBPKT_REV_KEY:
1272 if(n < 22)
1273 break;
1274 return 0;
1275 case SIGSUBPKT_SIG_CREATED:
1276 case SIGSUBPKT_SIG_EXPIRE:
1277 case SIGSUBPKT_KEY_EXPIRE:
1278 if( n < 4 )
1279 break;
1280 return 0;
1281 case SIGSUBPKT_KEY_FLAGS:
1282 case SIGSUBPKT_KS_FLAGS:
1283 case SIGSUBPKT_PREF_SYM:
1284 case SIGSUBPKT_PREF_HASH:
1285 case SIGSUBPKT_PREF_COMPR:
1286 case SIGSUBPKT_POLICY:
1287 case SIGSUBPKT_FEATURES:
1288 return 0;
1289 case SIGSUBPKT_EXPORTABLE:
1290 case SIGSUBPKT_REVOCABLE:
1291 if( !n )
1292 break;
1293 return 0;
1294 case SIGSUBPKT_ISSUER: /* issuer key ID */
1295 if( n < 8 )
1296 break;
1297 return 0;
1298 case SIGSUBPKT_NOTATION:
1299 if( n < 8 ) /* minimum length needed */
1300 break;
1301 return 0;
1302 case SIGSUBPKT_REVOC_REASON:
1303 if( !n )
1304 break;
1305 return 0;
1306 case SIGSUBPKT_PRIMARY_UID:
1307 if ( n != 1 )
1308 break;
1309 return 0;
1310 case SIGSUBPKT_PRIV_VERIFY_CACHE:
1311 /* We used this in gpg 1.0.5 and 1.0.6 to cache signature
1312 * verification results - it is no longer used.
1313 * "GPG" 0x00 <mode> <stat>
1314 * where mode == 1: valid data, stat == 0: invalid signature
1315 * stat == 1: valid signature
1316 * (because we use private data, we check our marker) */
1317 if( n < 6 )
1318 break;
1319 if( buffer[0] != 'G' || buffer[1] != 'P'
1320 || buffer[2] != 'G' || buffer[3] )
1321 return -2;
1322 return 4;
1323 default: return -1;
1324 }
1325 return -3;
1326 }
1327
1328
1329 static int
1330 can_handle_critical( const byte *buffer, size_t n, int type )
1331 {
1332 switch( type ) {
1333 case SIGSUBPKT_NOTATION:
1334 if( n >= 8 && (*buffer & 0x80) )
1335 return 1; /* human readable is handled */
1336 return 0;
1337
1338 case SIGSUBPKT_SIG_CREATED:
1339 case SIGSUBPKT_SIG_EXPIRE:
1340 case SIGSUBPKT_KEY_EXPIRE:
1341 case SIGSUBPKT_EXPORTABLE:
1342 case SIGSUBPKT_REVOCABLE:
1343 case SIGSUBPKT_REV_KEY:
1344 case SIGSUBPKT_ISSUER:/* issuer key ID */
1345 case SIGSUBPKT_PREF_SYM:
1346 case SIGSUBPKT_PREF_HASH:
1347 case SIGSUBPKT_PREF_COMPR:
1348 case SIGSUBPKT_KEY_FLAGS:
1349 case SIGSUBPKT_PRIMARY_UID:
1350 case SIGSUBPKT_FEATURES:
1351 case SIGSUBPKT_POLICY: /* Is it enough to show the policy? */
1352 return 1;
1353
1354 default:
1355 return 0;
1356 }
1357 }
1358
1359
1360 const byte *
1361 enum_sig_subpkt( const subpktarea_t *pktbuf, sigsubpkttype_t reqtype,
1362 size_t *ret_n, int *start, int *critical )
1363 {
1364 const byte *buffer;
1365 int buflen;
1366 int type;
1367 int critical_dummy;
1368 int offset;
1369 size_t n;
1370 int seq = 0;
1371 int reqseq = start? *start: 0;
1372
1373 if(!critical)
1374 critical=&critical_dummy;
1375
1376 if( !pktbuf || reqseq == -1 ) {
1377 /* return some value different from NULL to indicate that
1378 * there is no critical bit we do not understand. The caller
1379 * will never use the value. Yes I know, it is an ugly hack */
1380 return reqtype == SIGSUBPKT_TEST_CRITICAL? (const byte*)&pktbuf : NULL;
1381 }
1382 buffer = pktbuf->data;
1383 buflen = pktbuf->len;
1384 while( buflen ) {
1385 n = *buffer++; buflen--;
1386 if( n == 255 ) { /* 4 byte length header */
1387 if( buflen < 4 )
1388 goto too_short;
1389 n = (buffer[0] << 24) | (buffer[1] << 16)
1390 | (buffer[2] << 8) | buffer[3];
1391 buffer += 4;
1392 buflen -= 4;
1393 }
1394 else if( n >= 192 ) { /* 2 byte special encoded length header */
1395 if( buflen < 2 )
1396 goto too_short;
1397 n = (( n - 192 ) << 8) + *buffer + 192;
1398 buffer++;
1399 buflen--;
1400 }
1401 if( buflen < n )
1402 goto too_short;
1403 type = *buffer;
1404 if( type & 0x80 ) {
1405 type &= 0x7f;
1406 *critical = 1;
1407 }
1408 else
1409 *critical = 0;
1410 if( !(++seq > reqseq) )
1411 ;
1412 else if( reqtype == SIGSUBPKT_TEST_CRITICAL ) {
1413 if( *critical ) {
1414 if( n-1 > buflen+1 )
1415 goto too_short;
1416 if( !can_handle_critical(buffer+1, n-1, type ) ) {
1417 printf("subpacket of type %d has critical bit set\n",
1418 type);
1419 if( start )
1420 *start = seq;
1421 return NULL; /* this is an error */
1422 }
1423 }
1424 }
1425 else if( reqtype < 0 ) /* list packets */
1426 dump_sig_subpkt( reqtype == SIGSUBPKT_LIST_HASHED,
1427 type, *critical, buffer, buflen, n );
1428 else if( type == reqtype ) { /* found */
1429 buffer++;
1430 n--;
1431 if( n > buflen )
1432 goto too_short;
1433 if( ret_n )
1434 *ret_n = n;
1435 offset = parse_one_sig_subpkt(buffer, n, type );
1436 switch( offset ) {
1437 case -3:
1438 printf("subpacket of type %d too short\n", type);
1439 return NULL;
1440 case -2:
1441 return NULL;
1442 case -1:
1443 printf( "This is a BUG.\n%s:%d\n", __FILE__, __LINE__ );
1444 exit( -1 );
1445 default:
1446 break;
1447 }
1448 if( start )
1449 *start = seq;
1450 return buffer+offset;
1451 }
1452 buffer += n; buflen -=n;
1453 }
1454 if( reqtype == SIGSUBPKT_TEST_CRITICAL )
1455 return buffer; /* as value true to indicate that there is no */
1456 /* critical bit we don't understand */
1457 if( start )
1458 *start = -1;
1459 return NULL; /* end of packets; not found */
1460
1461 too_short:
1462 printf("buffer shorter than subpacket\n");
1463 if( start )
1464 *start = -1;
1465 return NULL;
1466 }
1467
1468
1469 const byte *
1470 gpg_parse_sig_subpkt (const subpktarea_t *buffer, sigsubpkttype_t reqtype,
1471 size_t *ret_n)
1472 {
1473 return enum_sig_subpkt( buffer, reqtype, ret_n, NULL, NULL );
1474 }
1475
1476 const byte *
1477 gpg_parse_sig_subpkt2 (PKT_signature *sig, sigsubpkttype_t reqtype,
1478 size_t *ret_n )
1479 {
1480 const byte *p;
1481
1482 p = gpg_parse_sig_subpkt (sig->hashed, reqtype, ret_n );
1483 if( !p )
1484 p = gpg_parse_sig_subpkt (sig->unhashed, reqtype, ret_n );
1485 return p;
1486 }
1487
1488 /* Find all revocation keys. Look in hashed area only. */
1489 void parse_revkeys(PKT_signature *sig)
1490 {
1491 struct revocation_key *revkey;
1492 int seq=0;
1493 size_t len;
1494
1495 if( sig->sig_class != 0x1F )
1496 return;
1497
1498 while((revkey=
1499 (struct revocation_key *)enum_sig_subpkt(sig->hashed,
1500 SIGSUBPKT_REV_KEY,
1501 &len,&seq,NULL))) {
1502 if( len==sizeof(struct revocation_key) &&
1503 (revkey->rclass&0x80)) /* 0x80 bit must be set */ {
1504 sig->revkey=realloc(sig->revkey,
1505 sizeof(struct revocation_key *)*(sig->numrevkeys+1));
1506 sig->revkey[sig->numrevkeys]=revkey;
1507 sig->numrevkeys++;
1508 }
1509 }
1510 }
1511
1512 static int
1513 parse_signature( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1514 PKT_signature *sig )
1515 {
1516 int md5_len=0;
1517 unsigned n;
1518 int is_v4=0;
1519 int rc=0;
1520 int i, ndata;
1521
1522 if( pktlen < 16 ) {
1523 printf("packet(%d) too short\n", pkttype);
1524 goto leave;
1525 }
1526 sig->version = gpg_iobuf_get_noeof(inp); pktlen--;
1527 if( sig->version == 4 )
1528 is_v4=1;
1529 else if( sig->version != 2 && sig->version != 3 ) {
1530 printf("packet(%d) with unknown version %d\n", pkttype, sig->version);
1531 rc = G10ERR_INVALID_PACKET;
1532 goto leave;
1533 }
1534
1535 if( !is_v4 ) {
1536 md5_len = gpg_iobuf_get_noeof(inp); pktlen--;
1537 }
1538 sig->sig_class = gpg_iobuf_get_noeof(inp); pktlen--;
1539 if( !is_v4 ) {
1540 sig->timestamp = read_32(inp); pktlen -= 4;
1541 sig->keyid[0] = read_32(inp); pktlen -= 4;
1542 sig->keyid[1] = read_32(inp); pktlen -= 4;
1543 }
1544 sig->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1545 sig->digest_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1546 sig->flags.exportable=1;
1547 sig->flags.revocable=1;
1548 if( is_v4 ) { /* read subpackets */
1549 n = read_16(inp); pktlen -= 2; /* length of hashed data */
1550 if( n > 10000 ) {
1551 printf("signature packet: hashed data too long\n");
1552 rc = G10ERR_INVALID_PACKET;
1553 goto leave;
1554 }
1555 if( n ) {
1556 sig->hashed = malloc (sizeof (*sig->hashed) + n - 1 );
1557 sig->hashed->size = n;
1558 sig->hashed->len = n;
1559 if( gpg_iobuf_read (inp, sig->hashed->data, n ) != n ) {
1560 printf ("premature eof while reading "
1561 "hashed signature data\n");
1562 rc = -1;
1563 goto leave;
1564 }
1565 pktlen -= n;
1566 }
1567 n = read_16(inp); pktlen -= 2; /* length of unhashed data */
1568 if( n > 10000 ) {
1569 printf("signature packet: unhashed data too long\n");
1570 rc = G10ERR_INVALID_PACKET;
1571 goto leave;
1572 }
1573 if( n ) {
1574 /* we add 8 extra bytes so that we have space for the signature
1575 * status cache. Well we are wastin this if there is a cache
1576 * packet already, but in the other case it avoids an realloc */
1577 sig->unhashed = malloc (sizeof(*sig->unhashed) + n + 8 - 1 );
1578 sig->unhashed->size = n + 8;
1579 sig->unhashed->len = n;
1580 if( gpg_iobuf_read(inp, sig->unhashed->data, n ) != n ) {
1581 printf("premature eof while reading "
1582 "unhashed signature data\n");
1583 rc = -1;
1584 goto leave;
1585 }
1586 pktlen -= n;
1587 }
1588 }
1589
1590 if( pktlen < 5 ) { /* sanity check */
1591 printf("packet(%d) too short\n", pkttype);
1592 rc = G10ERR_INVALID_PACKET;
1593 goto leave;
1594 }
1595
1596 sig->digest_start[0] = gpg_iobuf_get_noeof(inp); pktlen--;
1597 sig->digest_start[1] = gpg_iobuf_get_noeof(inp); pktlen--;
1598
1599 if( is_v4 && sig->pubkey_algo ) { /*extract required information */
1600 const byte *p;
1601
1602 /* set sig->flags.unknown_critical if there is a
1603 * critical bit set for packets which we do not understand */
1604 if( !gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_TEST_CRITICAL, NULL)
1605 || !gpg_parse_sig_subpkt (sig->unhashed, SIGSUBPKT_TEST_CRITICAL,
1606 NULL) )
1607 {
1608 sig->flags.unknown_critical = 1;
1609 }
1610
1611 p = gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_SIG_CREATED, NULL );
1612 if( !p )
1613 printf("signature packet without timestamp\n");
1614 else
1615 sig->timestamp = buffer_to_u32(p);
1616 p = gpg_parse_sig_subpkt2( sig, SIGSUBPKT_ISSUER, NULL );
1617 if( !p )
1618 printf("signature packet without keyid\n");
1619 else {
1620 sig->keyid[0] = buffer_to_u32(p);
1621 sig->keyid[1] = buffer_to_u32(p+4);
1622 }
1623
1624 p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_SIG_EXPIRE,NULL);
1625 if(p)
1626 sig->expiredate=sig->timestamp+buffer_to_u32(p);
1627 if(sig->expiredate && sig->expiredate<=time(NULL))
1628 sig->flags.expired=1;
1629
1630 p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_POLICY,NULL);
1631 if(p)
1632 sig->flags.policy_url=1;
1633
1634 p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_NOTATION,NULL);
1635 if(p)
1636 sig->flags.notation=1;
1637
1638 p=gpg_parse_sig_subpkt(sig->hashed,SIGSUBPKT_REVOCABLE,NULL);
1639 if(p && *p==0)
1640 sig->flags.revocable=0;
1641
1642 /* We accept the exportable subpacket from either the hashed
1643 or unhashed areas as older versions of gpg put it in the
1644 unhashed area. In theory, anyway, we should never see this
1645 packet off of a local keyring. */
1646
1647 p=gpg_parse_sig_subpkt2(sig,SIGSUBPKT_EXPORTABLE,NULL);
1648 if(p && *p==0)
1649 sig->flags.exportable=0;
1650
1651 /* Find all revocation keys. */
1652 if(sig->sig_class==0x1F)
1653 parse_revkeys(sig);
1654 }
1655
1656 if( list_mode ) {
1657 printf(":signature packet: algo %d, keyid %08lX%08lX\n"
1658 "\tversion %d, created %lu, md5len %d, sigclass %02x\n"
1659 "\tdigest algo %d, begin of digest %02x %02x\n",
1660 sig->pubkey_algo,
1661 (ulong)sig->keyid[0], (ulong)sig->keyid[1],
1662 sig->version, (ulong)sig->timestamp, md5_len, sig->sig_class,
1663 sig->digest_algo,
1664 sig->digest_start[0], sig->digest_start[1] );
1665 if( is_v4 ) {
1666 gpg_parse_sig_subpkt (sig->hashed, SIGSUBPKT_LIST_HASHED, NULL );
1667 gpg_parse_sig_subpkt (sig->unhashed, SIGSUBPKT_LIST_UNHASHED, NULL);
1668 }
1669 }
1670
1671 ndata = pubkey_get_nsig(sig->pubkey_algo);
1672 if( !ndata ) {
1673 if( list_mode )
1674 printf("\tunknown algorithm %d\n", sig->pubkey_algo );
1675 unknown_pubkey_warning( sig->pubkey_algo );
1676 /* we store the plain material in data[0], so that we are able
1677 * to write it back with build_packet() */
1678 sig->data[0] = mpi_set_opaque(NULL, read_rest(inp, pktlen), pktlen );
1679 pktlen = 0;
1680 }
1681 else {
1682 for( i=0; i < ndata; i++ ) {
1683 n = pktlen;
1684 sig->data[i] = mpi_read(inp, &n, 0 );
1685 pktlen -=n;
1686 if( list_mode ) {
1687 printf("\tdata: ");
1688 mpi_print(stdout, sig->data[i], mpi_print_mode );
1689 putchar('\n');
1690 }
1691 if (!sig->data[i])
1692 rc = G10ERR_INVALID_PACKET;
1693 }
1694 }
1695
1696 leave:
1697 skip_rest(inp, pktlen);
1698 return rc;
1699 }
1700
1701
1702 static int
1703 parse_onepass_sig( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1704 PKT_onepass_sig *ops )
1705 {
1706 int version;
1707 int rc = 0;
1708
1709 if( pktlen < 13 ) {
1710 printf("packet(%d) too short\n", pkttype);
1711 rc = G10ERR_INVALID_PACKET;
1712 goto leave;
1713 }
1714 version = gpg_iobuf_get_noeof(inp); pktlen--;
1715 if( version != 3 ) {
1716 printf("onepass_sig with unknown version %d\n", version);
1717 rc = G10ERR_INVALID_PACKET;
1718 goto leave;
1719 }
1720 ops->sig_class = gpg_iobuf_get_noeof(inp); pktlen--;
1721 ops->digest_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1722 ops->pubkey_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1723 ops->keyid[0] = read_32(inp); pktlen -= 4;
1724 ops->keyid[1] = read_32(inp); pktlen -= 4;
1725 ops->last = gpg_iobuf_get_noeof(inp); pktlen--;
1726 if( list_mode )
1727 printf(":onepass_sig packet: keyid %08lX%08lX\n"
1728 "\tversion %d, sigclass %02x, digest %d, pubkey %d, last=%d\n",
1729 (ulong)ops->keyid[0], (ulong)ops->keyid[1],
1730 version, ops->sig_class,
1731 ops->digest_algo, ops->pubkey_algo, ops->last );
1732
1733
1734 leave:
1735 skip_rest(inp, pktlen);
1736 return rc;
1737 }
1738
1739
1740 static int
1741 parse_key( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
1742 byte *hdr, int hdrlen, PACKET *pkt )
1743 {
1744 int i, version, algorithm;
1745 unsigned n;
1746 unsigned long timestamp, expiredate, max_expiredate;
1747 int npkey, nskey;
1748 int is_v4=0;
1749 int rc=0;
1750
1751 version = gpg_iobuf_get_noeof(inp); pktlen--;
1752 if( pkttype == PKT_PUBLIC_SUBKEY && version == '#' ) {
1753 /* early versions of G10 use old PGP comments packets;
1754 * luckily all those comments are started by a hash */
1755 if( list_mode ) {
1756 printf(":rfc1991 comment packet: \"" );
1757 for( ; pktlen; pktlen-- ) {
1758 int c;
1759 c = gpg_iobuf_get_noeof(inp);
1760 if( c >= ' ' && c <= 'z' )
1761 putchar(c);
1762 else
1763 printf("\\x%02x", c );
1764 }
1765 printf("\"\n");
1766 }
1767 skip_rest(inp, pktlen);
1768 return 0;
1769 }
1770 else if( version == 4 )
1771 is_v4=1;
1772 else if( version != 2 && version != 3 ) {
1773 printf("packet(%d) with unknown version %d\n", pkttype, version);
1774 rc = G10ERR_INVALID_PACKET;
1775 goto leave;
1776 }
1777
1778 if( pktlen < 11 ) {
1779 printf("packet(%d) too short\n", pkttype);
1780 rc = G10ERR_INVALID_PACKET;
1781 goto leave;
1782 }
1783
1784 timestamp = read_32(inp); pktlen -= 4;
1785 if( is_v4 ) {
1786 expiredate = 0; /* have to get it from the selfsignature */
1787 max_expiredate = 0;
1788 }
1789 else {
1790 unsigned short ndays;
1791 ndays = read_16(inp); pktlen -= 2;
1792 if( ndays )
1793 expiredate = timestamp + ndays * 86400L;
1794 else
1795 expiredate = 0;
1796
1797 max_expiredate=expiredate;
1798 }
1799 algorithm = gpg_iobuf_get_noeof(inp); pktlen--;
1800 if( list_mode )
1801 printf(":%s key packet:\n"
1802 "\tversion %d, algo %d, created %lu, expires %lu\n",
1803 pkttype == PKT_PUBLIC_KEY? "public" :
1804 pkttype == PKT_SECRET_KEY? "secret" :
1805 pkttype == PKT_PUBLIC_SUBKEY? "public sub" :
1806 pkttype == PKT_SECRET_SUBKEY? "secret sub" : "??",
1807 version, algorithm, timestamp, expiredate );
1808
1809 if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1810 PKT_secret_key *sk = pkt->pkt.secret_key;
1811
1812 sk->timestamp = timestamp;
1813 sk->expiredate = expiredate;
1814 sk->max_expiredate = max_expiredate;
1815 sk->hdrbytes = hdrlen;
1816 sk->version = version;
1817 sk->is_primary = pkttype == PKT_SECRET_KEY;
1818 sk->pubkey_algo = algorithm;
1819 sk->req_usage = 0;
1820 sk->pubkey_usage = 0; /* not yet used */
1821 }
1822 else {
1823 PKT_public_key *pk = pkt->pkt.public_key;
1824
1825 pk->timestamp = timestamp;
1826 pk->expiredate = expiredate;
1827 pk->max_expiredate = max_expiredate;
1828 pk->hdrbytes = hdrlen;
1829 pk->version = version;
1830 pk->is_primary = pkttype == PKT_PUBLIC_KEY;
1831 pk->pubkey_algo = algorithm;
1832 pk->req_usage = 0;
1833 pk->pubkey_usage = 0; /* not yet used */
1834 pk->is_revoked = 0;
1835 pk->keyid[0] = 0;
1836 pk->keyid[1] = 0;
1837 }
1838 nskey = pubkey_get_nskey( algorithm );
1839 npkey = pubkey_get_npkey( algorithm );
1840 if( !npkey ) {
1841 if( list_mode )
1842 printf("\tunknown algorithm %d\n", algorithm );
1843 unknown_pubkey_warning( algorithm );
1844 }
1845
1846
1847 if( pkttype == PKT_SECRET_KEY || pkttype == PKT_SECRET_SUBKEY ) {
1848 PKT_secret_key *sk = pkt->pkt.secret_key;
1849 byte temp[16];
1850 size_t snlen = 0;
1851
1852 if( !npkey ) {
1853 sk->skey[0] = mpi_set_opaque( NULL,
1854 read_rest(inp, pktlen), pktlen );
1855 pktlen = 0;
1856 goto leave;
1857 }
1858
1859 for(i=0; i < npkey; i++ ) {
1860 n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
1861 if( list_mode ) {
1862 printf( "\tskey[%d]: ", i);
1863 mpi_print(stdout, sk->skey[i], mpi_print_mode );
1864 putchar('\n');
1865 }
1866 if (!sk->skey[i])
1867 rc = G10ERR_INVALID_PACKET;
1868 }
1869 if (rc) /* one of the MPIs were bad */
1870 goto leave;
1871 sk->protect.algo = gpg_iobuf_get_noeof(inp); pktlen--;
1872 sk->protect.sha1chk = 0;
1873 if( sk->protect.algo ) {
1874 sk->is_protected = 1;
1875 sk->protect.s2k.count = 0;
1876 if( sk->protect.algo == 254 || sk->protect.algo == 255 ) {
1877 if( pktlen < 3 ) {
1878 rc = G10ERR_INVALID_PACKET;
1879 goto leave;
1880 }
1881 sk->protect.sha1chk = (sk->protect.algo == 254);
1882 sk->protect.algo = gpg_iobuf_get_noeof(inp); pktlen--;
1883 /* Note that a sk->protect.algo > 110 is illegal, but
1884 I'm not erroring on it here as otherwise there
1885 would be no way to delete such a key. */
1886 sk->protect.s2k.mode = gpg_iobuf_get_noeof(inp); pktlen--;
1887 sk->protect.s2k.hash_algo = gpg_iobuf_get_noeof(inp); pktlen--;
1888 /* check for the special GNU extension */
1889 if( is_v4 && sk->protect.s2k.mode == 101 ) {
1890 for(i=0; i < 4 && pktlen; i++, pktlen-- )
1891 temp[i] = gpg_iobuf_get_noeof(inp);
1892 if( i < 4 || memcmp( temp, "GNU", 3 ) ) {
1893 if( list_mode )
1894 printf( "\tunknown S2K %d\n",
1895 sk->protect.s2k.mode );
1896 rc = G10ERR_INVALID_PACKET;
1897 goto leave;
1898 }
1899 /* here we know that it is a gnu extension
1900 * What follows is the GNU protection mode:
1901 * All values have special meanings
1902 * and they are mapped in the mode with a base of 1000.
1903 */
1904 sk->protect.s2k.mode = 1000 + temp[3];
1905 }
1906 switch( sk->protect.s2k.mode ) {
1907 case 1:
1908 case 3:
1909 for(i=0; i < 8 && pktlen; i++, pktlen-- )
1910 temp[i] = gpg_iobuf_get_noeof(inp);
1911 memcpy(sk->protect.s2k.salt, temp, 8 );
1912 break;
1913 }
1914 switch( sk->protect.s2k.mode ) {
1915 case 0: if( list_mode ) printf( "\tsimple S2K" );
1916 break;
1917 case 1: if( list_mode ) printf( "\tsalted S2K" );
1918 break;
1919 case 3: if( list_mode ) printf( "\titer+salt S2K" );
1920 break;
1921 case 1001: if( list_mode ) printf( "\tgnu-dummy S2K" );
1922 break;
1923 case 1002: if (list_mode) printf("\tgnu-divert-to-card S2K");
1924 break;
1925 default:
1926 if( list_mode )
1927 printf( "\tunknown %sS2K %d\n",
1928 sk->protect.s2k.mode < 1000? "":"GNU ",
1929 sk->protect.s2k.mode );
1930 rc = G10ERR_INVALID_PACKET;
1931 goto leave;
1932 }
1933
1934 if( list_mode ) {
1935 printf(", algo: %d,%s hash: %d",
1936 sk->protect.algo,
1937 sk->protect.sha1chk?" SHA1 protection,"
1938 :" simple checksum,",
1939 sk->protect.s2k.hash_algo );
1940 if( sk->protect.s2k.mode == 1
1941 || sk->protect.s2k.mode == 3 ) {
1942 printf(", salt: ");
1943 for(i=0; i < 8; i++ )
1944 printf("%02x", sk->protect.s2k.salt[i]);
1945 }
1946 putchar('\n');
1947 }
1948
1949 if( sk->protect.s2k.mode == 3 ) {
1950 if( pktlen < 1 ) {
1951 rc = G10ERR_INVALID_PACKET;
1952 goto leave;
1953 }
1954 sk->protect.s2k.count = gpg_iobuf_get(inp);
1955 pktlen--;
1956 if( list_mode )
1957 printf("\tprotect count: %lu\n",
1958 (ulong)sk->protect.s2k.count);
1959 }
1960 else if( sk->protect.s2k.mode == 1002 ) {
1961 /* Read the serial number. */
1962 if (pktlen < 1) {
1963 rc = G10ERR_INVALID_PACKET;
1964 goto leave;
1965 }
1966 snlen = gpg_iobuf_get (inp);
1967 pktlen--;
1968 if (pktlen < snlen || snlen == -1) {
1969 rc = G10ERR_INVALID_PACKET;
1970 goto leave;
1971 }
1972 }
1973 }
1974 /* Note that a sk->protect.algo > 110 is illegal, but I'm
1975 not erroring on it here as otherwise there would be no
1976 way to delete such a key. */
1977 else { /* old version; no S2K, so we set mode to 0, hash MD5 */
1978 sk->protect.s2k.mode = 0;
1979 sk->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
1980 if( list_mode )
1981 printf( "\tprotect algo: %d (hash algo: %d)\n",
1982 sk->protect.algo, sk->protect.s2k.hash_algo );
1983 }
1984 /* It is really ugly that we don't know the size
1985 * of the IV here in cases we are not aware of the algorithm.
1986 * so a
1987 * sk->protect.ivlen = cipher_get_blocksize(sk->protect.algo);
1988 * won't work. The only solution I see is to hardwire it here.
1989 * NOTE: if you change the ivlen above 16, don't forget to
1990 * enlarge temp.
1991 */
1992 switch( sk->protect.algo ) {
1993 case 7: case 8: case 9: /* reserved for AES */
1994 case 10: /* Twofish */
1995 sk->protect.ivlen = 16;
1996 break;
1997 default:
1998 sk->protect.ivlen = 8;
1999 }
2000 if( sk->protect.s2k.mode == 1001 )
2001 sk->protect.ivlen = 0;
2002 else if( sk->protect.s2k.mode == 1002 )
2003 sk->protect.ivlen = snlen < 16? snlen : 16;
2004
2005 if( pktlen < sk->protect.ivlen ) {
2006 rc = G10ERR_INVALID_PACKET;
2007 goto leave;
2008 }
2009 for(i=0; i < sk->protect.ivlen && pktlen; i++, pktlen-- )
2010 temp[i] = gpg_iobuf_get_noeof(inp);
2011 if( list_mode ) {
2012 printf( sk->protect.s2k.mode == 1002? "\tserial-number: "
2013 : "\tprotect IV: ");
2014 for(i=0; i < sk->protect.ivlen; i++ )
2015 printf(" %02x", temp[i] );
2016 putchar('\n');
2017 }
2018 memcpy( sk->protect.iv, temp, sk->protect.ivlen );
2019 }
2020 else
2021 sk->is_protected = 0;
2022 /* It does not make sense to read it into secure memory.
2023 * If the user is so careless, not to protect his secret key,
2024 * we can assume, that he operates an open system :=(.
2025 * So we put the key into secure memory when we unprotect it. */
2026 if( sk->protect.s2k.mode == 1001
2027 || sk->protect.s2k.mode == 1002 ) {
2028 /* better set some dummy stuff here */
2029 sk->skey[npkey] = mpi_set_opaque(NULL, strdup("dummydata"), 10);
2030 pktlen = 0;
2031 }
2032 else if( is_v4 && sk->is_protected ) {
2033 /* ugly; the length is encrypted too, so we read all
2034 * stuff up to the end of the packet into the first
2035 * skey element */
2036 sk->skey[npkey] = mpi_set_opaque(NULL,
2037 read_rest(inp, pktlen), pktlen );
2038 pktlen = 0;
2039 if( list_mode ) {
2040 printf("\tencrypted stuff follows\n");
2041 }
2042 }
2043 else { /* v3 method: the mpi length is not encrypted */
2044 for(i=npkey; i < nskey; i++ ) {
2045 n = pktlen; sk->skey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
2046 if( sk->is_protected && sk->skey[i] )
2047 mpi_set_protect_flag(sk->skey[i]);
2048 if( list_mode ) {
2049 printf( "\tskey[%d]: ", i);
2050 if( sk->is_protected )
2051 printf( "[encrypted]\n");
2052 else {
2053 mpi_print(stdout, sk->skey[i], mpi_print_mode );
2054 putchar('\n');
2055 }
2056 }
2057 if (!sk->skey[i])
2058 rc = G10ERR_INVALID_PACKET;
2059 }
2060 if (rc)
2061 goto leave;
2062
2063 sk->csum = read_16(inp); pktlen -= 2;
2064 if( list_mode ) {
2065 printf("\tchecksum: %04hx\n", sk->csum);
2066 }
2067 }
2068 }
2069 else {
2070 PKT_public_key *pk = pkt->pkt.public_key;
2071
2072 if( !npkey ) {
2073 pk->pkey[0] = mpi_set_opaque( NULL,
2074 read_rest(inp, pktlen), pktlen );
2075 pktlen = 0;
2076 goto leave;
2077 }
2078
2079 for(i=0; i < npkey; i++ ) {
2080 n = pktlen; pk->pkey[i] = mpi_read(inp, &n, 0 ); pktlen -=n;
2081 if( list_mode ) {
2082 printf( "\tpkey[%d]: ", i);
2083 mpi_print(stdout, pk->pkey[i], mpi_print_mode );
2084 putchar('\n');
2085 }
2086 if (!pk->pkey[i])
2087 rc = G10ERR_INVALID_PACKET;
2088 }
2089 if (rc)
2090 goto leave;
2091 }
2092
2093 leave:
2094 skip_rest(inp, pktlen);
2095 return rc;
2096 }
2097
2098 /* Attribute subpackets have the same format as v4 signature
2099 subpackets. This is not part of OpenPGP, but is done in several
2100 versions of PGP nevertheless. */
2101 int
2102 parse_attribute_subpkts(PKT_user_id *uid)
2103 {
2104 size_t n;
2105 int count=0;
2106 struct user_attribute *attribs=NULL;
2107 const byte *buffer=uid->attrib_data;
2108 int buflen=uid->attrib_len;
2109 byte type;
2110
2111 safe_free(uid->attribs);
2112
2113 while(buflen) {
2114 n = *buffer++; buflen--;
2115 if( n == 255 ) { /* 4 byte length header */
2116 if( buflen < 4 )
2117 goto too_short;
2118 n = (buffer[0] << 24) | (buffer[1] << 16)
2119 | (buffer[2] << 8) | buffer[3];
2120 buffer += 4;
2121 buflen -= 4;
2122 }
2123 else if( n >= 192 ) { /* 2 byte special encoded length header */
2124 if( buflen < 2 )
2125 goto too_short;
2126 n = (( n - 192 ) << 8) + *buffer + 192;
2127 buffer++;
2128 buflen--;
2129 }
2130 if( buflen < n )
2131 goto too_short;
2132
2133 attribs=realloc(attribs,(count+1)*sizeof(struct user_attribute));
2134 memset(&attribs[count],0,sizeof(struct user_attribute));
2135
2136 type=*buffer;
2137 buffer++;
2138 buflen--;
2139 n--;
2140
2141 attribs[count].type=type;
2142 attribs[count].data=buffer;
2143 attribs[count].len=n;
2144 buffer+=n;
2145 buflen-=n;
2146 count++;
2147 }
2148
2149 uid->attribs=attribs;
2150 uid->numattribs=count;
2151 return count;
2152
2153 too_short:
2154 printf("buffer shorter than attribute subpacket\n");
2155 uid->attribs=attribs;
2156 uid->numattribs=count;
2157 return count;
2158 }
2159
2160 static void
2161 setup_user_id(PACKET *packet)
2162 {
2163 packet->pkt.user_id->ref = 1;
2164 packet->pkt.user_id->attribs = NULL;
2165 packet->pkt.user_id->attrib_data = NULL;
2166 packet->pkt.user_id->attrib_len = 0;
2167 packet->pkt.user_id->is_primary = 0;
2168 packet->pkt.user_id->is_revoked = 0;
2169 packet->pkt.user_id->is_expired = 0;
2170 packet->pkt.user_id->expiredate = 0;
2171 packet->pkt.user_id->created = 0;
2172 packet->pkt.user_id->help_key_usage = 0;
2173 packet->pkt.user_id->help_key_expire = 0;
2174 packet->pkt.user_id->prefs = NULL;
2175 }
2176
2177 static int
2178 parse_user_id( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2179 {
2180 byte *p;
2181
2182 packet->pkt.user_id = malloc(sizeof *packet->pkt.user_id + pktlen);
2183 packet->pkt.user_id->len = pktlen;
2184
2185 setup_user_id(packet);
2186
2187 p = packet->pkt.user_id->name;
2188 for( ; pktlen; pktlen--, p++ )
2189 *p = gpg_iobuf_get_noeof(inp);
2190 *p = 0;
2191
2192 if( list_mode ) {
2193 int n = packet->pkt.user_id->len;
2194 printf(":user ID packet: \"");
2195 /* fixme: Hey why don't we replace this with print_string?? */
2196 for(p=packet->pkt.user_id->name; n; p++, n-- ) {
2197 if( *p >= ' ' && *p <= 'z' )
2198 putchar(*p);
2199 else
2200 printf("\\x%02x", *p );
2201 }
2202 printf("\"\n");
2203 }
2204 return 0;
2205 }
2206
2207 /* Returns 0 for error, 1 for valid */
2208 int parse_image_header(const struct user_attribute *attr,byte *type,u32 *len)
2209 {
2210 u16 headerlen;
2211
2212 if(attr->len<3)
2213 return 0;
2214
2215 /* For historical reasons (i.e. "oops!"), the header length is
2216 little endian. */
2217 headerlen=(attr->data[1]<<8) | attr->data[0];
2218
2219 if(headerlen>attr->len)
2220 return 0;
2221
2222 if(type && attr->len>=4)
2223 {
2224 if(attr->data[2]==1) /* header version 1 */
2225 *type=attr->data[3];
2226 else
2227 *type=0;
2228 }
2229
2230 *len=attr->len-headerlen;
2231
2232 if(*len==0)
2233 return 0;
2234
2235 return 1;
2236 }
2237
2238 /* style==0 for extension, 1 for name, 2 for MIME type. Remember that
2239 the "name" style string could be used in a user ID name field, so
2240 make sure it is not too big (see
2241 parse-packet.c:parse_attribute). */
2242 char *image_type_to_string(byte type,int style)
2243 {
2244 char *string;
2245
2246 switch(type) {
2247 case 1: /* jpeg */
2248 if(style==0)
2249 string="jpg";
2250 else if(style==1)
2251 string="jpeg";
2252 else
2253 string="image/jpeg";
2254 break;
2255
2256 default:
2257 if(style==0)
2258 string="bin";
2259 else if(style==1)
2260 string="unknown";
2261 else
2262 string="image/x-unknown";
2263 break;
2264 }
2265
2266 return string;
2267 }
2268
2269 void
2270 make_attribute_uidname(PKT_user_id *uid)
2271 {
2272 if(uid->numattribs<=0)
2273 sprintf(uid->name,"[bad attribute packet of size %lu]",uid->attrib_len);
2274 else if(uid->numattribs>1)
2275 sprintf(uid->name,"[%d attributes of size %lu]",
2276 uid->numattribs,uid->attrib_len);
2277 else {
2278 /* Only one attribute, so list it as the "user id" */
2279
2280 if(uid->attribs->type==ATTRIB_IMAGE) {
2281 u32 len;
2282 byte type;
2283
2284 if(parse_image_header(uid->attribs,&type,&len))
2285 sprintf(uid->name,"[%s image of size %lu]",
2286 image_type_to_string(type,1),(ulong)len);
2287 else
2288 sprintf(uid->name,"[invalid image]");
2289 }
2290 else
2291 sprintf(uid->name,"[unknown attribute of size %lu]",
2292 (ulong)uid->attribs->len);
2293 }
2294
2295 uid->len = strlen(uid->name);
2296 }
2297
2298 static int
2299 parse_attribute( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2300 {
2301 byte *p;
2302
2303 packet->pkt.user_id = malloc(sizeof *packet->pkt.user_id + 70);
2304
2305 setup_user_id(packet);
2306
2307 packet->pkt.user_id->attrib_data = malloc(pktlen);
2308 packet->pkt.user_id->attrib_len = pktlen;
2309 p = packet->pkt.user_id->attrib_data;
2310 for( ; pktlen; pktlen--, p++ )
2311 *p = gpg_iobuf_get_noeof(inp);
2312
2313 /* Now parse out the individual attribute subpackets. This is
2314 somewhat pointless since there is only one currently defined
2315 attribute type (jpeg), but it is correct by the spec. */
2316 parse_attribute_subpkts(packet->pkt.user_id);
2317
2318 make_attribute_uidname(packet->pkt.user_id);
2319
2320 if( list_mode ) {
2321 printf(":attribute packet: %s\n", packet->pkt.user_id->name );
2322 }
2323 return 0;
2324 }
2325
2326
2327 static int
2328 parse_comment( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *packet )
2329 {
2330 byte *p;
2331
2332 packet->pkt.comment = malloc(sizeof *packet->pkt.comment + pktlen - 1);
2333 packet->pkt.comment->len = pktlen;
2334 p = packet->pkt.comment->data;
2335 for( ; pktlen; pktlen--, p++ )
2336 *p = gpg_iobuf_get_noeof(inp);
2337
2338 if( list_mode ) {
2339 int n = packet->pkt.comment->len;
2340 printf(":%scomment packet: \"", pkttype == PKT_OLD_COMMENT?
2341 "OpenPGP draft " : "" );
2342 for(p=packet->pkt.comment->data; n; p++, n-- ) {
2343 if( *p >= ' ' && *p <= 'z' )
2344 putchar(*p);
2345 else
2346 printf("\\x%02x", *p );
2347 }
2348 printf("\"\n");
2349 }
2350 return 0;
2351 }
2352
2353
2354 static void
2355 parse_trust( gpg_iobuf_t inp, int pkttype, unsigned long pktlen, PACKET *pkt )
2356 {
2357 int c;
2358
2359 if (pktlen) {
2360 c = gpg_iobuf_get_noeof(inp);
2361 pktlen--;
2362 pkt->pkt.ring_trust = malloc( sizeof *pkt->pkt.ring_trust );
2363 pkt->pkt.ring_trust->trustval = c;
2364 pkt->pkt.ring_trust->sigcache = 0;
2365 if (!c && pktlen==1) {
2366 c = gpg_iobuf_get_noeof (inp);
2367 pktlen--;
2368 /* we require that bit 7 of the sigcache is 0 (easier eof handling)*/
2369 if ( !(c & 0x80) )
2370 pkt->pkt.ring_trust->sigcache = c;
2371 }
2372 if( list_mode )
2373 printf(":trust packet: flag=%02x sigcache=%02x\n",
2374 pkt->pkt.ring_trust->trustval,
2375 pkt->pkt.ring_trust->sigcache);
2376 }
2377 else {
2378 if( list_mode )
2379 printf(":trust packet: empty\n");
2380 }
2381 skip_rest (inp, pktlen);
2382 }
2383
2384
2385 static int
2386 parse_plaintext( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2387 PACKET *pkt, int new_ctb )
2388 {
2389 int rc = 0;
2390 int mode, namelen, partial=0;
2391 PKT_plaintext *pt;
2392 byte *p;
2393 int c, i;
2394
2395 if( pktlen && pktlen < 6 ) {
2396 printf("packet(%d) too short (%lu)\n", pkttype, (ulong)pktlen);
2397 rc = G10ERR_INVALID_PACKET;
2398 goto leave;
2399 }
2400 /* A packet length of zero indicates partial body length. A zero
2401 data length isn't a zero length packet due to the header (mode,
2402 name, etc), so this is accurate. */
2403 if(pktlen==0)
2404 partial=1;
2405 mode = gpg_iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2406 namelen = gpg_iobuf_get_noeof(inp); if( pktlen ) pktlen--;
2407 pt = pkt->pkt.plaintext = malloc(sizeof *pkt->pkt.plaintext + namelen -1);
2408 pt->new_ctb = new_ctb;
2409 pt->mode = mode;
2410 pt->namelen = namelen;
2411 pt->is_partial = partial;
2412 if( pktlen ) {
2413 for( i=0; pktlen > 4 && i < namelen; pktlen--, i++ )
2414 pt->name[i] = gpg_iobuf_get_noeof(inp);
2415 }
2416 else {
2417 for( i=0; i < namelen; i++ )
2418 if( (c=gpg_iobuf_get(inp)) == -1 )
2419 break;
2420 else
2421 pt->name[i] = c;
2422 }
2423 pt->timestamp = read_32(inp); if( pktlen) pktlen -= 4;
2424 pt->len = pktlen;
2425 pt->buf = inp;
2426 pktlen = 0;
2427
2428 if( list_mode ) {
2429 printf(":literal data packet:\n"
2430 "\tmode %c, created %lu, name=\"",
2431 mode >= ' ' && mode <'z'? mode : '?',
2432 (ulong)pt->timestamp );
2433 for(p=pt->name,i=0; i < namelen; p++, i++ ) {
2434 if( *p >= ' ' && *p <= 'z' )
2435 putchar(*p);
2436 else
2437 printf("\\x%02x", *p );
2438 }
2439 printf("\",\n\traw data: %lu bytes\n", (ulong)pt->len );
2440 }
2441
2442 leave:
2443 return rc;
2444 }
2445
2446
2447 static int
2448 parse_compressed( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2449 PACKET *pkt, int new_ctb )
2450 {
2451 PKT_compressed *zd;
2452
2453 /* pktlen is here 0, but data follows
2454 * (this should be the last object in a file or
2455 * the compress algorithm should know the length)
2456 */
2457 zd = pkt->pkt.compressed = malloc(sizeof *pkt->pkt.compressed );
2458 zd->algorithm = gpg_iobuf_get_noeof(inp);
2459 zd->len = 0; /* not used */
2460 zd->new_ctb = new_ctb;
2461 zd->buf = inp;
2462 if( list_mode )
2463 printf(":compressed packet: algo=%d\n", zd->algorithm);
2464 return 0;
2465 }
2466
2467
2468 static int
2469 parse_encrypted( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2470 PACKET *pkt, int new_ctb )
2471 {
2472 int rc = 0;
2473 PKT_encrypted *ed;
2474 unsigned long orig_pktlen = pktlen;
2475
2476 ed = pkt->pkt.encrypted = malloc(sizeof *pkt->pkt.encrypted );
2477 ed->len = pktlen;
2478 /* we don't know the extralen which is (cipher_blocksize+2)
2479 because the algorithm ist not specified in this packet.
2480 However, it is only important to know this for some sanity
2481 checks on the packet length - it doesn't matter that we can't
2482 do it */
2483 ed->extralen = 0;
2484 ed->buf = NULL;
2485 ed->new_ctb = new_ctb;
2486 ed->mdc_method = 0;
2487 if( pkttype == PKT_ENCRYPTED_MDC ) {
2488 /* fixme: add some pktlen sanity checks */
2489 int version;
2490
2491 version = gpg_iobuf_get_noeof(inp);
2492 if (orig_pktlen)
2493 pktlen--;
2494 if( version != 1 ) {
2495 printf("encrypted_mdc packet with unknown version %d\n",
2496 version);
2497 /*skip_rest(inp, pktlen); should we really do this? */
2498 rc = G10ERR_INVALID_PACKET;
2499 goto leave;
2500 }
2501 ed->mdc_method = DIGEST_ALGO_SHA1;
2502 }
2503 if( orig_pktlen && pktlen < 10 ) { /* actually this is blocksize+2 */
2504 printf("packet(%d) too short\n", pkttype);
2505 rc = G10ERR_INVALID_PACKET;
2506 skip_rest(inp, pktlen);
2507 goto leave;
2508 }
2509 if( list_mode ) {
2510 if( orig_pktlen )
2511 printf(":encrypted data packet:\n\tlength: %lu\n", orig_pktlen);
2512 else
2513 printf(":encrypted data packet:\n\tlength: unknown\n");
2514 if( ed->mdc_method )
2515 printf("\tmdc_method: %d\n", ed->mdc_method );
2516 }
2517
2518 ed->buf = inp;
2519 pktlen = 0;
2520
2521 leave:
2522 return rc;
2523 }
2524
2525
2526 static int
2527 parse_mdc( gpg_iobuf_t inp, int pkttype, unsigned long pktlen,
2528 PACKET *pkt, int new_ctb )
2529 {
2530 int rc = 0;
2531 PKT_mdc *mdc;
2532 byte *p;
2533
2534 mdc = pkt->pkt.mdc= malloc(sizeof *pkt->pkt.mdc );
2535 if( list_mode )
2536 printf(":mdc packet: length=%lu\n", pktlen);
2537 if( !new_ctb || pktlen != 20 ) {
2538 printf("mdc_packet with invalid encoding\n");
2539 rc = G10ERR_INVALID_PACKET;
2540 goto leave;
2541 }
2542 p = mdc->hash;
2543 for( ; pktlen; pktlen--, p++ )
2544 *p = gpg_iobuf_get_noeof(inp);
2545
2546 leave:
2547 return rc;
2548 }
2549
2550
2551 /*
2552 * This packet is internally generated by PGG (by armor.c) to
2553 * transfer some information to the lower layer. To make sure that
2554 * this packet is really a GPG faked one and not one comming from outside,
2555 * we first check that tehre is a unique tag in it.
2556 * The format of such a control packet is:
2557 * n byte session marker
2558 * 1 byte control type CTRLPKT_xxxxx
2559 * m byte control data
2560 */
2561
2562 /* Return a string which is used as a kind of process ID */
2563 const byte *
2564 get_session_marker( size_t *rlen )
2565 {
2566 static byte marker[SIZEOF_UNSIGNED_LONG*2];
2567 static int initialized;
2568
2569 if ( !initialized ) {
2570 volatile ulong aa, bb; /* we really want the uninitialized value */
2571 ulong a, b;
2572
2573 initialized = 1;
2574 /* also this marker is guessable it is not easy to use this
2575 * for a faked control packet because an attacker does not
2576 * have enough control about the time the verification does
2577 * take place. Of course, we can add just more random but
2578 * than we need the random generator even for verification
2579 * tasks - which does not make sense. */
2580 a = aa ^ (ulong)getpid();
2581 b = bb ^ (ulong)time(NULL);
2582 memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
2583 memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
2584 }
2585 *rlen = sizeof(marker);
2586 return marker;
2587 }
2588
2589 static int
2590 parse_gpg_control( gpg_iobuf_t inp,
2591 int pkttype, unsigned long pktlen, PACKET *packet )
2592 {
2593 byte *p;
2594 const byte *sesmark;
2595 size_t sesmarklen;
2596 int i;
2597
2598 if ( list_mode )
2599 printf(":packet 63: length %lu ", pktlen);
2600
2601 sesmark = get_session_marker ( &sesmarklen );
2602 if ( pktlen < sesmarklen+1 ) /* 1 is for the control bytes */
2603 goto skipit;
2604 for( i=0; i < sesmarklen; i++, pktlen-- ) {
2605 if ( sesmark[i] != gpg_iobuf_get_noeof(inp) )
2606 goto skipit;
2607 }
2608 if ( list_mode )
2609 puts ("- gpg control packet");
2610
2611 packet->pkt.gpg_control = malloc(sizeof *packet->pkt.gpg_control
2612 + pktlen - 1);
2613 packet->pkt.gpg_control->control = gpg_iobuf_get_noeof(inp); pktlen--;
2614 packet->pkt.gpg_control->datalen = pktlen;
2615 p = packet->pkt.gpg_control->data;
2616 for( ; pktlen; pktlen--, p++ )
2617 *p = gpg_iobuf_get_noeof(inp);
2618
2619 return 0;
2620
2621 skipit:
2622 if ( list_mode ) {
2623 int c;
2624
2625 i=0;
2626 printf("- private (rest length %lu)\n", pktlen);
2627 if( gpg_iobuf_in_block_mode(inp) ) {
2628 while( (c=gpg_iobuf_get(inp)) != -1 )
2629 dump_hex_line(c, &i);
2630 }
2631 else {
2632 for( ; pktlen; pktlen-- )
2633 dump_hex_line(gpg_iobuf_get(inp), &i);
2634 }
2635 putchar('\n');
2636 }
2637 skip_rest(inp,pktlen);
2638 return G10ERR_INVALID_PACKET;
2639 }
2640
2641
2642 u32
2643 gpg_keyid_from_pk( PKT_public_key * pk, byte *fprint )
2644 {
2645 gpg_md_t md;
2646 int npkey, pktlen, i;
2647 const byte *mdbuf;
2648
2649 if( pk->version == 3 && pk->pubkey_algo == PUBKEY_ALGO_RSA )
2650 return pk->pkey[0]->d[0];
2651 else {
2652 md = gpg_md_open( DIGEST_ALGO_SHA1 );
2653 gpg_md_putc( md, 0x99 );
2654 npkey = pubkey_get_npkey( pk->pubkey_algo );
2655 pktlen = 6;
2656 for( i = 0 ; i <npkey; i++ )
2657 pktlen = pktlen + 2 + pk->pkey[i]->alloced;
2658 gpg_md_putc( md, pktlen>>8 );
2659 gpg_md_putc( md, pktlen );
2660 gpg_md_putc( md, 4 );
2661 gpg_md_putc( md, pk->timestamp >> 24 );
2662 gpg_md_putc( md, pk->timestamp >> 16 );
2663 gpg_md_putc( md, pk->timestamp >> 8 );
2664 gpg_md_putc( md, pk->timestamp );
2665 gpg_md_putc( md, pk->pubkey_algo );
2666 for( i=0; i <npkey; i++ ) {
2667 const u32 * d = pk->pkey[i]->d;
2668 int nbits = pk->pkey[i]->nbits,
2669 n = pk->pkey[i]->alloced;
2670 gpg_md_putc( md, nbits >> 8 );
2671 gpg_md_putc( md, nbits );
2672 n = n>4? n/4 : n;
2673 while( n-- ) {
2674 if( pk->pkey[i]->alloced > 3 )
2675 gpg_md_putc( md, d[n] >> 24 );
2676 if( pk->pkey[i]->alloced > 2 )
2677 gpg_md_putc( md, d[n] >> 16 );
2678 if( pk->pkey[i]->alloced > 1 )
2679 gpg_md_putc( md, d[n] >> 8 );
2680 if( pk->pkey[i]->alloced > 0 )
2681 gpg_md_putc( md, d[n] );
2682 }
2683 }
2684 gpg_md_final( md );
2685 mdbuf = gpg_md_read( md );
2686 }
2687 if( mdbuf && fprint )
2688 memcpy( fprint, mdbuf, 20 );
2689 return mdbuf? mdbuf[16] << 24 | mdbuf[17] << 16 | mdbuf[18] << 8 | mdbuf[19] : 0;
2690 }
2691
2692
2693 u32
2694 gpg_keyid_from_sk( PKT_secret_key * sk, byte *fprint )
2695 {
2696 PKT_public_key pk;
2697 int npkey = pubkey_get_npkey( sk->pubkey_algo );
2698 int i;
2699
2700 pk.pubkey_algo = sk->pubkey_algo;
2701 pk.version = sk->version;
2702 pk.timestamp = sk->timestamp;
2703 pk.expiredate = sk->expiredate;
2704 pk.pubkey_algo = sk->pubkey_algo;
2705 for( i=0; i < npkey; i++ )
2706 pk.pkey[i] = sk->skey[i];
2707 return gpg_keyid_from_pk( &pk, fprint );
2708 }
2709
2710
2711 /****************
2712 * Read the next keyblock from stream A.
2713 * PENDING_PKT should be initialzed to NULL
2714 * and not chnaged form the caller.
2715 * Retunr: 0 = okay, -1 no more blocks or another errorcode.
2716 */
2717 int
2718 gpg_read_keyblock( gpg_iobuf_t a, PACKET **pending_pkt, gpg_kbnode_t *ret_root )
2719 {
2720 int rc;
2721 PACKET *pkt;
2722 gpg_kbnode_t root = NULL;
2723 int in_cert;
2724
2725 if( *pending_pkt ) {
2726 root = gpg_new_kbnode( *pending_pkt );
2727 *pending_pkt = NULL;
2728 in_cert = 1;
2729 }
2730 else
2731 in_cert = 0;
2732 pkt = malloc( sizeof *pkt );
2733 gpg_init_packet(pkt);
2734 while( (rc=gpg_parse_packet(a, pkt)) != -1 ) {
2735 if( rc ) { /* ignore errors */
2736 if( rc != G10ERR_UNKNOWN_PACKET ) {
2737 printf("read_block: read error: %d\n", rc );
2738 rc = G10ERR_INV_KEYRING;
2739 goto ready;
2740 }
2741 gpg_free_packet( pkt );
2742 gpg_init_packet(pkt);
2743 continue;
2744 }
2745
2746 if( !root && pkt->pkttype == PKT_SIGNATURE
2747 && pkt->pkt.signature->sig_class == 0x20 ) {
2748 /* this is a revocation certificate which is handled
2749 * in a special way */
2750 root = gpg_new_kbnode( pkt );
2751 pkt = NULL;
2752 goto ready;
2753 }
2754
2755 /* make a linked list of all packets */
2756 switch( pkt->pkttype ) {
2757 case PKT_RING_TRUST:
2758 /* skip those packets */
2759 gpg_free_packet( pkt );
2760 gpg_init_packet(pkt);
2761 break;
2762
2763 case PKT_PUBLIC_KEY:
2764 case PKT_SECRET_KEY:
2765 if( in_cert ) { /* store this packet */
2766 *pending_pkt = pkt;
2767 pkt = NULL;
2768 goto ready;
2769 }
2770 in_cert = 1;
2771 default:
2772 if( in_cert ) {
2773 if( !root )
2774 root = gpg_new_kbnode( pkt );
2775 else
2776 gpg_add_kbnode( root, gpg_new_kbnode( pkt ) );
2777 pkt = malloc( sizeof *pkt );
2778 }
2779 gpg_init_packet(pkt);
2780 break;
2781 }
2782 }
2783 ready:
2784 if( rc == -1 && root )
2785 rc = 0;
2786
2787 if( rc )
2788 gpg_release_kbnode( root );
2789 else
2790 *ret_root = root;
2791 gpg_free_packet( pkt );
2792 free( pkt );
2793 return rc;
2794 }

Properties

Name Value
svn:eol-style native

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26