See ChangeLog: Thu Apr 8 09:35:53 CEST 1999 Werner Koch
[gnupg.git] / g10 / mainproc.c
1 /* mainproc.c - handle packets
2  *      Copyright (C) 1998 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 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <assert.h>
26 #include <time.h>
27
28 #include "packet.h"
29 #include "iobuf.h"
30 #include "memory.h"
31 #include "options.h"
32 #include "util.h"
33 #include "cipher.h"
34 #include "keydb.h"
35 #include "filter.h"
36 #include "main.h"
37 #include "status.h"
38 #include "i18n.h"
39 #include "trustdb.h"
40 #include "hkp.h"
41
42 /****************
43  * Structure to hold the context
44  */
45
46 typedef struct {
47     PKT_public_key *last_pubkey;
48     PKT_secret_key *last_seckey;
49     PKT_user_id     *last_user_id;
50     md_filter_context_t mfx;
51     int sigs_only;   /* process only signatures and reject all other stuff */
52     int encrypt_only; /* process only encrytion messages */
53     STRLIST signed_data;
54     const char *sigfilename;
55     DEK *dek;
56     int last_was_session_key;
57     KBNODE list;   /* the current list of packets */
58     int have_data;
59     IOBUF iobuf;    /* used to get the filename etc. */
60     int trustletter; /* temp usage in list_node */
61     ulong local_id;    /* ditto */
62 } *CTX;
63
64
65 static int do_proc_packets( CTX c, IOBUF a );
66
67 static void list_node( CTX c, KBNODE node );
68 static void proc_tree( CTX c, KBNODE node );
69
70
71 static void
72 release_list( CTX c )
73 {
74     if( !c->list )
75         return;
76     proc_tree(c, c->list );
77     release_kbnode( c->list );
78     c->list = NULL;
79 }
80
81
82 static int
83 add_onepass_sig( CTX c, PACKET *pkt )
84 {
85     KBNODE node;
86
87     if( c->list ) { /* add another packet */
88         if( c->list->pkt->pkttype != PKT_ONEPASS_SIG ) {
89            log_error("add_onepass_sig: another packet is in the way\n");
90            release_list( c );
91            c->list = new_kbnode( pkt );
92         }
93         else
94            add_kbnode( c->list, new_kbnode( pkt ));
95     }
96     else /* insert the first one */
97         c->list = node = new_kbnode( pkt );
98
99     return 1;
100 }
101
102
103
104 static int
105 add_user_id( CTX c, PACKET *pkt )
106 {
107     if( !c->list ) {
108         log_error("orphaned user id\n" );
109         return 0;
110     }
111     add_kbnode( c->list, new_kbnode( pkt ) );
112     return 1;
113 }
114
115 static int
116 add_subkey( CTX c, PACKET *pkt )
117 {
118     if( !c->list ) {
119         log_error("subkey w/o mainkey\n" );
120         return 0;
121     }
122     add_kbnode( c->list, new_kbnode( pkt ) );
123     return 1;
124 }
125
126
127 static int
128 add_signature( CTX c, PACKET *pkt )
129 {
130     KBNODE node;
131
132     if( pkt->pkttype == PKT_SIGNATURE && !c->list ) {
133         /* This is the first signature for the following datafile.
134          * G10 does not write such packets; instead it always uses
135          * onepass-sig packets.  The drawback of PGP's method
136          * of prepending the signature to the data is
137          * that it is not possible to make a signature from data read
138          * from stdin.  (G10 is able to read PGP stuff anyway.) */
139         node = new_kbnode( pkt );
140         c->list = node;
141         return 1;
142     }
143     else if( !c->list )
144         return 0; /* oops (invalid packet sequence)*/
145     else if( !c->list->pkt )
146         BUG();  /* so nicht */
147
148     /* add a new signature node id at the end */
149     node = new_kbnode( pkt );
150     add_kbnode( c->list, node );
151     return 1;
152 }
153
154
155 static void
156 proc_symkey_enc( CTX c, PACKET *pkt )
157 {
158     PKT_symkey_enc *enc;
159
160     enc = pkt->pkt.symkey_enc;
161     if( enc->seskeylen )
162         log_error( "symkey_enc packet with session keys are not supported!\n");
163     else {
164         c->last_was_session_key = 2;
165         c->dek = passphrase_to_dek( NULL, enc->cipher_algo, &enc->s2k, 0 );
166     }
167     free_packet(pkt);
168 }
169
170 static void
171 proc_pubkey_enc( CTX c, PACKET *pkt )
172 {
173     PKT_pubkey_enc *enc;
174     int result = 0;
175
176     /* check whether the secret key is available and store in this case */
177     c->last_was_session_key = 1;
178     enc = pkt->pkt.pubkey_enc;
179     /*printf("enc: encrypted by a pubkey with keyid %08lX\n", enc->keyid[1] );*/
180     /* Hmmm: why do I have this algo check here - anyway there is
181      * function to check it. */
182     if( opt.verbose )
183         log_info(_("public key is %08lX\n"), (ulong)enc->keyid[1] );
184
185     if( is_status_enabled() ) {
186         char buf[50];
187         sprintf(buf, "%08lX%08lX", (ulong)enc->keyid[0], (ulong)enc->keyid[1]);
188         write_status_text( STATUS_ENC_TO, buf );
189     }
190
191
192     if( is_ELGAMAL(enc->pubkey_algo)
193         || enc->pubkey_algo == PUBKEY_ALGO_DSA
194         || is_RSA(enc->pubkey_algo)  ) {
195         if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1])
196                           || !seckey_available( enc->keyid )) ) {
197             c->dek = m_alloc_secure( sizeof *c->dek );
198             if( (result = get_session_key( enc, c->dek )) ) {
199                 /* error: delete the DEK */
200                 m_free(c->dek); c->dek = NULL;
201             }
202         }
203     }
204     else
205         result = G10ERR_PUBKEY_ALGO;
206
207     if( result == -1 )
208         ;
209     else if( !result ) {
210         if( opt.verbose > 1 )
211             log_info( _("public key encrypted data: good DEK\n") );
212     }
213     else {
214         /* fixme: defer this message until we have parsed all packets of
215          * this type - do this by building a list of keys with their stati
216          * and store it with the conetxt.  do_proc_packets can then use
217          * this list to display some information */
218         log_error(_("public key decryption failed: %s\n"), g10_errstr(result));
219     }
220     free_packet(pkt);
221 }
222
223
224 static void
225 proc_encrypted( CTX c, PACKET *pkt )
226 {
227     int result = 0;
228
229     /*printf("dat: %sencrypted data\n", c->dek?"":"conventional ");*/
230     if( !c->dek && !c->last_was_session_key ) {
231         /* assume this is old conventional encrypted data */
232         c->dek = passphrase_to_dek( NULL,
233                     opt.def_cipher_algo ? opt.def_cipher_algo
234                                         : DEFAULT_CIPHER_ALGO, NULL, 0 );
235     }
236     else if( !c->dek )
237         result = G10ERR_NO_SECKEY;
238     if( !result )
239         result = decrypt_data( pkt->pkt.encrypted, c->dek );
240     m_free(c->dek); c->dek = NULL;
241     if( result == -1 )
242         ;
243     else if( !result ) {
244         if( opt.verbose > 1 )
245             log_info(_("decryption okay\n"));
246     }
247     else {
248         write_status( STATUS_DECRYPTION_FAILED );
249         log_error(_("decryption failed: %s\n"), g10_errstr(result));
250         /* FIXME: if this is secret key not available, try with
251          * other keys */
252     }
253     free_packet(pkt);
254     c->last_was_session_key = 0;
255 }
256
257
258 static void
259 proc_plaintext( CTX c, PACKET *pkt )
260 {
261     PKT_plaintext *pt = pkt->pkt.plaintext;
262     int any, clearsig, rc;
263     KBNODE n;
264
265     if( pt->namelen == 8 && !memcmp( pt->name, "_CONSOLE", 8 ) )
266         log_info(_("NOTE: sender requested \"for-your-eyes-only\"\n"));
267     else if( opt.verbose )
268         log_info(_("original file name='%.*s'\n"), pt->namelen, pt->name);
269     free_md_filter_context( &c->mfx );
270     c->mfx.md = md_open( 0, 0);
271     /* fixme: we may need to push the textfilter if we have sigclass 1
272      * and no armoring - Not yet tested
273      * Hmmm, why don't we need it at all if we have sigclass 1
274      * Should we assume that plaintext in mode 't' has always sigclass 1??
275      * See: Russ Allbery's mail 1999-02-09
276      */
277     any = clearsig = 0;
278     for(n=c->list; n; n = n->next ) {
279         if( n->pkt->pkttype == PKT_ONEPASS_SIG ) {
280             if( n->pkt->pkt.onepass_sig->digest_algo ) {
281                 md_enable( c->mfx.md, n->pkt->pkt.onepass_sig->digest_algo );
282                 any = 1;
283             }
284             /* Check whether this is a cleartext signature.  We assume that
285              * we have one if the sig_class is 1 and the keyid is 0, that
286              * are the faked packets produced by armor.c.  There is a
287              * possibility that this fails, but there is no other easy way
288              * to do it. (We could use a special packet type to indicate
289              * this, but this may also be faked - it simply can't be verified
290              * and is _no_ security issue)
291              */
292             if( n->pkt->pkt.onepass_sig->sig_class == 0x01
293                 && !n->pkt->pkt.onepass_sig->keyid[0]
294                 && !n->pkt->pkt.onepass_sig->keyid[1]  )
295                 clearsig = 1;
296         }
297     }
298     if( !any ) { /* no onepass sig packet: enable all standard algos */
299         md_enable( c->mfx.md, DIGEST_ALGO_RMD160 );
300         md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
301         md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
302     }
303   #if 0
304     #warning md_start_debug is enabled
305     md_start_debug( c->mfx.md, "verify" );
306   #endif
307     rc = handle_plaintext( pt, &c->mfx, c->sigs_only, clearsig );
308     if( rc == G10ERR_CREATE_FILE && !c->sigs_only) {
309         /* can't write output but we hash it anyway to
310          * check the signature */
311         rc = handle_plaintext( pt, &c->mfx, 1, clearsig );
312     }
313     if( rc )
314         log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
315     free_packet(pkt);
316     c->last_was_session_key = 0;
317 }
318
319
320 static int
321 proc_compressed_cb( IOBUF a, void *info )
322 {
323     return proc_signature_packets( a, ((CTX)info)->signed_data,
324                                       ((CTX)info)->sigfilename );
325 }
326
327 static int
328 proc_encrypt_cb( IOBUF a, void *info )
329 {
330     return proc_encryption_packets( a );
331 }
332
333 static void
334 proc_compressed( CTX c, PACKET *pkt )
335 {
336     PKT_compressed *zd = pkt->pkt.compressed;
337     int rc;
338
339     /*printf("zip: compressed data packet\n");*/
340     if( c->sigs_only )
341         rc = handle_compressed( zd, proc_compressed_cb, c );
342     else if( c->encrypt_only )
343         rc = handle_compressed( zd, proc_encrypt_cb, c );
344     else
345         rc = handle_compressed( zd, NULL, NULL );
346     if( rc )
347         log_error("uncompressing failed: %s\n", g10_errstr(rc));
348     free_packet(pkt);
349     c->last_was_session_key = 0;
350 }
351
352
353
354
355 /****************
356  * check the signature
357  * Returns: 0 = valid signature or an error code
358  */
359 static int
360 do_check_sig( CTX c, KBNODE node, int *is_selfsig )
361 {
362     PKT_signature *sig;
363     MD_HANDLE md;
364     int algo, rc;
365
366     assert( node->pkt->pkttype == PKT_SIGNATURE );
367     if( is_selfsig )
368         *is_selfsig = 0;
369     sig = node->pkt->pkt.signature;
370
371     algo = sig->digest_algo;
372     if( !algo )
373         return G10ERR_PUBKEY_ALGO;
374     if( (rc=check_digest_algo(algo)) )
375         return rc;
376
377     if( c->mfx.md ) {
378         m_check(c->mfx.md);
379         if( c->mfx.md->list )
380             m_check( c->mfx.md->list );
381     }
382
383     if( sig->sig_class == 0x00 ) {
384         if( c->mfx.md )
385             md = md_copy( c->mfx.md );
386         else /* detached signature */
387             md = md_open( 0, 0 ); /* signature_check() will enable the md*/
388     }
389     else if( sig->sig_class == 0x01 ) {
390         /* how do we know that we have to hash the (already hashed) text
391          * in canonical mode ??? (calculating both modes???) */
392         if( c->mfx.md )
393             md = md_copy( c->mfx.md );
394         else /* detached signature */
395             md = md_open( 0, 0 ); /* signature_check() will enable the md*/
396     }
397     else if( (sig->sig_class&~3) == 0x10
398              || sig->sig_class == 0x18
399              || sig->sig_class == 0x20
400              || sig->sig_class == 0x30  ) { /* classes 0x10..0x17,0x20,0x30 */
401         if( c->list->pkt->pkttype == PKT_PUBLIC_KEY
402             || c->list->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
403             return check_key_signature( c->list, node, is_selfsig );
404         }
405         else {
406             log_error("invalid root packet for sigclass %02x\n",
407                                                         sig->sig_class);
408             return G10ERR_SIG_CLASS;
409         }
410     }
411     else
412         return G10ERR_SIG_CLASS;
413     rc = signature_check( sig, md );
414     md_close(md);
415
416     return rc;
417 }
418
419
420
421 static void
422 print_userid( PACKET *pkt )
423 {
424     if( !pkt )
425         BUG();
426     if( pkt->pkttype != PKT_USER_ID ) {
427         printf("ERROR: unexpected packet type %d", pkt->pkttype );
428         return;
429     }
430     print_string( stdout,  pkt->pkt.user_id->name, pkt->pkt.user_id->len,
431                                                         opt.with_colons );
432 }
433
434
435 static void
436 print_fingerprint( PKT_public_key *pk, PKT_secret_key *sk )
437 {
438     byte array[MAX_FINGERPRINT_LEN], *p;
439     size_t i, n;
440
441     if( sk )
442         fingerprint_from_sk( sk, array, &n );
443     else
444         fingerprint_from_pk( pk, array, &n );
445     p = array;
446     if( opt.with_colons ) {
447         printf("fpr:::::::::");
448         for(i=0; i < n ; i++, p++ )
449             printf("%02X", *p );
450         putchar(':');
451     }
452     else {
453         printf("     Key fingerprint =");
454         if( n == 20 ) {
455             for(i=0; i < n ; i++, i++, p += 2 ) {
456                 if( i == 10 )
457                     putchar(' ');
458                 printf(" %02X%02X", *p, p[1] );
459             }
460         }
461         else {
462             for(i=0; i < n ; i++, p++ ) {
463                 if( i && !(i%8) )
464                     putchar(' ');
465                 printf(" %02X", *p );
466             }
467         }
468     }
469     putchar('\n');
470 }
471
472
473 /****************
474  * List the certificate in a user friendly way
475  */
476
477 static void
478 list_node( CTX c, KBNODE node )
479 {
480     int any=0;
481     int mainkey;
482
483     if( !node )
484         ;
485     else if( (mainkey = (node->pkt->pkttype == PKT_PUBLIC_KEY) )
486              || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
487         PKT_public_key *pk = node->pkt->pkt.public_key;
488
489         if( opt.with_colons ) {
490             u32 keyid[2];
491             keyid_from_pk( pk, keyid );
492             if( mainkey ) {
493                 c->local_id = pk->local_id;
494                 c->trustletter = query_trust_info( pk, NULL );
495             }
496             printf("%s:%c:%u:%d:%08lX%08lX:%s:%s:",
497                     mainkey? "pub":"sub",
498                     c->trustletter,
499                     nbits_from_pk( pk ),
500                     pk->pubkey_algo,
501                     (ulong)keyid[0],(ulong)keyid[1],
502                     datestr_from_pk( pk ),
503                     pk->expiredate? strtimestamp(pk->expiredate):"" );
504             if( c->local_id )
505                 printf("%lu", c->local_id );
506             putchar(':');
507             if( c->local_id )
508                 putchar( get_ownertrust_info( c->local_id ) );
509             putchar(':');
510         }
511         else
512             printf("%s  %4u%c/%08lX %s ",
513                                       mainkey? "pub":"sub",
514                                       nbits_from_pk( pk ),
515                                       pubkey_letter( pk->pubkey_algo ),
516                                       (ulong)keyid_from_pk( pk, NULL ),
517                                       datestr_from_pk( pk )     );
518         if( mainkey ) {
519             /* and now list all userids with their signatures */
520             for( node = node->next; node; node = node->next ) {
521                 if( node->pkt->pkttype == PKT_SIGNATURE ) {
522                     if( !any ) {
523                         if( node->pkt->pkt.signature->sig_class == 0x20 )
524                             puts("[revoked]");
525                         else
526                             putchar('\n');
527                         any = 1;
528                     }
529                     list_node(c,  node );
530                 }
531                 else if( node->pkt->pkttype == PKT_USER_ID ) {
532                     if( any ) {
533                         if( opt.with_colons )
534                             printf("uid:::::::::");
535                         else
536                             printf( "uid%*s", 28, "" );
537                     }
538                     print_userid( node->pkt );
539                     if( opt.with_colons )
540                         putchar(':');
541                     putchar('\n');
542                     if( opt.fingerprint && !any )
543                         print_fingerprint( pk, NULL );
544                     any=1;
545                 }
546                 else if( node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
547                     if( !any ) {
548                         putchar('\n');
549                         any = 1;
550                     }
551                     list_node(c,  node );
552                 }
553             }
554         }
555         if( !any )
556             putchar('\n');
557         if( !mainkey && opt.fingerprint > 1 )
558             print_fingerprint( pk, NULL );
559     }
560     else if( (mainkey = (node->pkt->pkttype == PKT_SECRET_KEY) )
561              || node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
562         PKT_secret_key *sk = node->pkt->pkt.secret_key;
563
564         if( opt.with_colons ) {
565             u32 keyid[2];
566             keyid_from_sk( sk, keyid );
567             printf("%s::%u:%d:%08lX%08lX:%s:%s:::",
568                     mainkey? "sec":"ssb",
569                     nbits_from_sk( sk ),
570                     sk->pubkey_algo,
571                     (ulong)keyid[0],(ulong)keyid[1],
572                     datestr_from_sk( sk ),
573                     sk->expiredate? strtimestamp(sk->expiredate):""
574                     /* fixme: add LID */ );
575         }
576         else
577             printf("%s  %4u%c/%08lX %s ",
578                                       mainkey? "sec":"ssb",
579                                       nbits_from_sk( sk ),
580                                       pubkey_letter( sk->pubkey_algo ),
581                                       (ulong)keyid_from_sk( sk, NULL ),
582                                       datestr_from_sk( sk )   );
583         if( mainkey ) {
584             /* and now list all userids with their signatures */
585             for( node = node->next; node; node = node->next ) {
586                 if( node->pkt->pkttype == PKT_SIGNATURE ) {
587                     if( !any ) {
588                         if( node->pkt->pkt.signature->sig_class == 0x20 )
589                             puts("[revoked]");
590                         else
591                             putchar('\n');
592                         any = 1;
593                     }
594                     list_node(c,  node );
595                 }
596                 else if( node->pkt->pkttype == PKT_USER_ID ) {
597                     if( any ) {
598                         if( opt.with_colons )
599                             printf("uid:::::::::");
600                         else
601                             printf( "uid%*s", 28, "" );
602                     }
603                     print_userid( node->pkt );
604                     if( opt.with_colons )
605                         putchar(':');
606                     putchar('\n');
607                     if( opt.fingerprint && !any )
608                         print_fingerprint( NULL, sk );
609                     any=1;
610                 }
611                 else if( node->pkt->pkttype == PKT_SECRET_SUBKEY ) {
612                     if( !any ) {
613                         putchar('\n');
614                         any = 1;
615                     }
616                     list_node(c,  node );
617                 }
618             }
619         }
620         if( !any )
621             putchar('\n');
622         if( !mainkey && opt.fingerprint > 1 )
623             print_fingerprint( NULL, sk );
624     }
625     else if( node->pkt->pkttype == PKT_SIGNATURE  ) {
626         PKT_signature *sig = node->pkt->pkt.signature;
627         int is_selfsig = 0;
628         int rc2=0;
629         size_t n;
630         char *p;
631         int sigrc = ' ';
632
633         if( !opt.list_sigs )
634             return;
635
636         if( sig->sig_class == 0x20 || sig->sig_class == 0x30 )
637             fputs("rev", stdout);
638         else
639             fputs("sig", stdout);
640         if( opt.check_sigs ) {
641             fflush(stdout);
642             switch( (rc2=do_check_sig( c, node, &is_selfsig )) ) {
643               case 0:                  sigrc = '!'; break;
644               case G10ERR_BAD_SIGN:    sigrc = '-'; break;
645               case G10ERR_NO_PUBKEY:   sigrc = '?'; break;
646               default:                 sigrc = '%'; break;
647             }
648         }
649         else {  /* check whether this is a self signature */
650             u32 keyid[2];
651
652             if( c->list->pkt->pkttype == PKT_PUBLIC_KEY
653                 || c->list->pkt->pkttype == PKT_SECRET_KEY ) {
654                 if( c->list->pkt->pkttype == PKT_PUBLIC_KEY )
655                     keyid_from_pk( c->list->pkt->pkt.public_key, keyid );
656                 else
657                     keyid_from_sk( c->list->pkt->pkt.secret_key, keyid );
658
659                 if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] )
660                     is_selfsig = 1;
661             }
662         }
663         if( opt.with_colons ) {
664             putchar(':');
665             if( sigrc != ' ' )
666                 putchar(sigrc);
667             printf(":::%08lX%08lX:%s::::", (ulong)sig->keyid[0],
668                        (ulong)sig->keyid[1], datestr_from_sig(sig));
669         }
670         else
671             printf("%c       %08lX %s   ",
672                     sigrc, (ulong)sig->keyid[1], datestr_from_sig(sig));
673         if( sigrc == '%' )
674             printf("[%s] ", g10_errstr(rc2) );
675         else if( sigrc == '?' )
676             ;
677         else if( is_selfsig ) {
678             if( opt.with_colons )
679                 putchar(':');
680             fputs( sig->sig_class == 0x18? "[keybind]":"[selfsig]", stdout);
681             if( opt.with_colons )
682                 putchar(':');
683         }
684         else {
685             p = get_user_id( sig->keyid, &n );
686             print_string( stdout, p, n, opt.with_colons );
687             m_free(p);
688         }
689         if( opt.with_colons )
690             printf(":%02x:", sig->sig_class );
691         putchar('\n');
692     }
693     else
694         log_error("invalid node with packet of type %d\n", node->pkt->pkttype);
695 }
696
697
698 int
699 proc_packets( IOBUF a )
700 {
701     CTX c = m_alloc_clear( sizeof *c );
702     int rc = do_proc_packets( c, a );
703     m_free( c );
704     return rc;
705 }
706
707 int
708 proc_signature_packets( IOBUF a, STRLIST signedfiles, const char *sigfilename )
709 {
710     CTX c = m_alloc_clear( sizeof *c );
711     int rc;
712     c->sigs_only = 1;
713     c->signed_data = signedfiles;
714     c->sigfilename = sigfilename;
715     rc = do_proc_packets( c, a );
716     m_free( c );
717     return rc;
718 }
719
720 int
721 proc_encryption_packets( IOBUF a )
722 {
723     CTX c = m_alloc_clear( sizeof *c );
724     int rc;
725     c->encrypt_only = 1;
726     rc = do_proc_packets( c, a );
727     m_free( c );
728     return rc;
729 }
730
731
732 int
733 do_proc_packets( CTX c, IOBUF a )
734 {
735     PACKET *pkt = m_alloc( sizeof *pkt );
736     int rc=0;
737     int newpkt;
738
739     c->iobuf = a;
740     init_packet(pkt);
741     while( (rc=parse_packet(a, pkt)) != -1 ) {
742
743         if( rc ) {
744             free_packet(pkt);
745             if( rc == G10ERR_INVALID_PACKET )
746                 break;
747             continue;
748         }
749         newpkt = -1;
750         if( opt.list_packets ) {
751             switch( pkt->pkttype ) {
752               case PKT_PUBKEY_ENC:  proc_pubkey_enc( c, pkt ); break;
753               case PKT_SYMKEY_ENC:  proc_symkey_enc( c, pkt ); break;
754               case PKT_ENCRYPTED:   proc_encrypted( c, pkt ); break;
755               case PKT_COMPRESSED:  proc_compressed( c, pkt ); break;
756               default: newpkt = 0; break;
757             }
758         }
759         else if( c->sigs_only ) {
760             switch( pkt->pkttype ) {
761               case PKT_PUBLIC_KEY:
762               case PKT_SECRET_KEY:
763               case PKT_USER_ID:
764               case PKT_SYMKEY_ENC:
765               case PKT_PUBKEY_ENC:
766               case PKT_ENCRYPTED:
767                 rc = G10ERR_UNEXPECTED;
768                 goto leave;
769               case PKT_SIGNATURE:   newpkt = add_signature( c, pkt ); break;
770               case PKT_PLAINTEXT:   proc_plaintext( c, pkt ); break;
771               case PKT_COMPRESSED:  proc_compressed( c, pkt ); break;
772               case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
773               default: newpkt = 0; break;
774             }
775         }
776         else if( c->encrypt_only ) {
777             switch( pkt->pkttype ) {
778               case PKT_PUBLIC_KEY:
779               case PKT_SECRET_KEY:
780               case PKT_USER_ID:
781                 rc = G10ERR_UNEXPECTED;
782                 goto leave;
783               case PKT_SIGNATURE:   newpkt = add_signature( c, pkt ); break;
784               case PKT_SYMKEY_ENC:  proc_symkey_enc( c, pkt ); break;
785               case PKT_PUBKEY_ENC:  proc_pubkey_enc( c, pkt ); break;
786               case PKT_ENCRYPTED:   proc_encrypted( c, pkt ); break;
787               case PKT_PLAINTEXT:   proc_plaintext( c, pkt ); break;
788               case PKT_COMPRESSED:  proc_compressed( c, pkt ); break;
789               case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
790               default: newpkt = 0; break;
791             }
792         }
793         else {
794             switch( pkt->pkttype ) {
795               case PKT_PUBLIC_KEY:
796               case PKT_SECRET_KEY:
797                 release_list( c );
798                 c->list = new_kbnode( pkt );
799                 newpkt = 1;
800                 break;
801               case PKT_PUBLIC_SUBKEY:
802               case PKT_SECRET_SUBKEY:
803                 newpkt = add_subkey( c, pkt );
804                 break;
805               case PKT_USER_ID:     newpkt = add_user_id( c, pkt ); break;
806               case PKT_SIGNATURE:   newpkt = add_signature( c, pkt ); break;
807               case PKT_PUBKEY_ENC:  proc_pubkey_enc( c, pkt ); break;
808               case PKT_SYMKEY_ENC:  proc_symkey_enc( c, pkt ); break;
809               case PKT_ENCRYPTED:   proc_encrypted( c, pkt ); break;
810               case PKT_PLAINTEXT:   proc_plaintext( c, pkt ); break;
811               case PKT_COMPRESSED:  proc_compressed( c, pkt ); break;
812               case PKT_ONEPASS_SIG: newpkt = add_onepass_sig( c, pkt ); break;
813               default: newpkt = 0; break;
814             }
815         }
816         if( pkt->pkttype != PKT_SIGNATURE )
817             c->have_data = pkt->pkttype == PKT_PLAINTEXT;
818
819         if( newpkt == -1 )
820             ;
821         else if( newpkt ) {
822             pkt = m_alloc( sizeof *pkt );
823             init_packet(pkt);
824         }
825         else
826             free_packet(pkt);
827     }
828     rc = 0;
829
830   leave:
831     release_list( c );
832     m_free(c->dek);
833     free_packet( pkt );
834     m_free( pkt );
835     free_md_filter_context( &c->mfx );
836     return rc;
837 }
838
839
840
841 static int
842 check_sig_and_print( CTX c, KBNODE node )
843 {
844     PKT_signature *sig = node->pkt->pkt.signature;
845     const char *astr, *tstr;
846     int rc;
847
848     if( opt.skip_verify ) {
849         log_info(_("signature verification suppressed\n"));
850         return 0;
851     }
852
853     tstr = asctimestamp(sig->timestamp);
854     astr = pubkey_algo_to_string( sig->pubkey_algo );
855     log_info(_("Signature made %.*s using %s key ID %08lX\n"),
856             (int)strlen(tstr), tstr, astr? astr: "?", (ulong)sig->keyid[1] );
857
858     rc = do_check_sig(c, node, NULL );
859     if( rc == G10ERR_NO_PUBKEY && opt.keyserver_name ) {
860         if( !hkp_ask_import( sig->keyid ) )
861             rc = do_check_sig(c, node, NULL );
862     }
863     if( !rc || rc == G10ERR_BAD_SIGN ) {
864         KBNODE un, keyblock;
865         char *us;
866         int count=0;
867
868         keyblock = get_pubkeyblock( sig->keyid );
869
870         us = get_long_user_id_string( sig->keyid );
871         write_status_text( rc? STATUS_BADSIG : STATUS_GOODSIG, us );
872         m_free(us);
873
874         /* fixme: list only user ids which are valid and add information
875          *        about the trustworthiness of each user id, sort them.
876          *        Integrate this with check_signatures_trust(). */
877         for( un=keyblock; un; un = un->next ) {
878             if( un->pkt->pkttype != PKT_USER_ID )
879                 continue;
880             if( !count++ )
881                 log_info(rc? _("BAD signature from \"")
882                            : _("Good signature from \""));
883             else
884                 log_info(    _("                aka \""));
885             print_string( stderr, un->pkt->pkt.user_id->name,
886                                   un->pkt->pkt.user_id->len, '\"' );
887             fputs("\"\n", stderr);
888             if( rc )
889                 break; /* print only one id in this case */
890         }
891         if( !count ) {  /* just in case that we have no userid */
892             log_info(rc? _("BAD signature from \"")
893                        : _("Good signature from \""));
894             fputs("[?]\"\n", stderr );
895         }
896         release_kbnode( keyblock );
897
898
899         if( !rc && is_status_enabled() ) {
900             /* print a status response with the fingerprint */
901             PKT_public_key *pk = m_alloc_clear( sizeof *pk );
902
903             if( !get_pubkey( pk, sig->keyid ) ) {
904                 byte array[MAX_FINGERPRINT_LEN], *p;
905                 char buf[MAX_FINGERPRINT_LEN*2+1];
906                 size_t i, n;
907
908                 fingerprint_from_pk( pk, array, &n );
909                 p = array;
910                 for(i=0; i < n ; i++, p++ )
911                     sprintf(buf+2*i, "%02X", *p );
912                 write_status_text( STATUS_VALIDSIG, buf );
913             }
914             free_public_key( pk );
915         }
916
917         if( !rc )
918             rc = check_signatures_trust( sig );
919         if( rc )
920             g10_errors_seen = 1;
921         if( opt.batch && rc )
922             g10_exit(1);
923     }
924     else {
925         char buf[50];
926         sprintf(buf, "%08lX%08lX %d",
927                      (ulong)sig->keyid[0], (ulong)sig->keyid[1],
928                      sig->pubkey_algo );
929         write_status_text( STATUS_ERRSIG, buf );
930         log_error(_("Can't check signature: %s\n"), g10_errstr(rc) );
931     }
932     return rc;
933 }
934
935
936 /****************
937  * Process the tree which starts at node
938  */
939 static void
940 proc_tree( CTX c, KBNODE node )
941 {
942     KBNODE n1;
943     int rc;
944
945     if( opt.list_packets )
946         return;
947
948     c->local_id = 0;
949     c->trustletter = ' ';
950     if( node->pkt->pkttype == PKT_PUBLIC_KEY
951         || node->pkt->pkttype == PKT_PUBLIC_SUBKEY ) {
952         merge_keys_and_selfsig( node );
953         list_node( c, node );
954     }
955     else if( node->pkt->pkttype == PKT_SECRET_KEY ) {
956         merge_keys_and_selfsig( node );
957         list_node( c, node );
958     }
959     else if( node->pkt->pkttype == PKT_ONEPASS_SIG ) {
960         /* check all signatures */
961         if( !c->have_data ) {
962             free_md_filter_context( &c->mfx );
963             /* prepare to create all requested message digests */
964             c->mfx.md = md_open(0, 0);
965             /* fixme: why looking for the signature packet and not 1passpacket*/
966             for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); ) {
967                 md_enable( c->mfx.md, n1->pkt->pkt.signature->digest_algo);
968             }
969             /* ask for file and hash it */
970             if( c->sigs_only )
971                 rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
972                         n1? (n1->pkt->pkt.onepass_sig->sig_class == 0x01):0 );
973             else
974                 rc = ask_for_detached_datafile( &c->mfx,
975                                             iobuf_get_fname(c->iobuf));
976             if( rc ) {
977                 log_error("can't hash datafile: %s\n", g10_errstr(rc));
978                 return;
979             }
980         }
981
982         for( n1 = node; (n1 = find_next_kbnode(n1, PKT_SIGNATURE )); )
983             check_sig_and_print( c, n1 );
984     }
985     else if( node->pkt->pkttype == PKT_SIGNATURE ) {
986         PKT_signature *sig = node->pkt->pkt.signature;
987
988         if( !c->have_data ) {
989             free_md_filter_context( &c->mfx );
990             c->mfx.md = md_open(sig->digest_algo, 0);
991             if( c->sigs_only )
992                 rc = hash_datafiles( c->mfx.md, c->signed_data, c->sigfilename,
993                                      sig->sig_class == 0x01 );
994             else
995                 rc = ask_for_detached_datafile( &c->mfx,
996                                             iobuf_get_fname(c->iobuf));
997             if( rc ) {
998                 log_error("can't hash datafile: %s\n", g10_errstr(rc));
999                 return;
1000             }
1001         }
1002         else
1003             log_info(_("old style (PGP 2.x) signature\n"));
1004
1005         check_sig_and_print( c, node );
1006     }
1007     else
1008         log_error(_("invalid root packet detected in proc_tree()\n"));
1009
1010 }
1011
1012
1013