root/openpgpsdk/trunk/examples/packet-dump.c

Revision 342 (checked in by ben, 7 years ago)

Give callbacks a preview of secret keys.

  • Property svn:keywords set to Id
Line 
1 #include <openpgpsdk/packet.h>
2 #include <openpgpsdk/packet-parse.h>
3 #include <openpgpsdk/packet-show.h>
4 #include <openpgpsdk/configure.h>
5 #include <openpgpsdk/util.h>
6 #include <openpgpsdk/errors.h>
7 #include <openpgpsdk/armour.h>
8 #include <openpgpsdk/crypto.h>
9 #include <openpgpsdk/keyring.h>
10
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <assert.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <fcntl.h>
17
18 static int indent=0;
19 static const char *pname;
20 static ops_keyring_t keyring;
21 static ops_boolean_t passphrase_prompt;
22
23 static void print_indent()
24     {
25     int i=0;
26
27     for(i=0 ; i < indent ; i++)
28         printf("  ");
29     }
30
31 static void showtime(const char *name,time_t t)
32     {
33     printf("%s=" TIME_T_FMT " (%.24s)",name,t,ctime(&t));
34     }
35
36 static void print_bn( const char *name, const BIGNUM *bn)
37     {
38     print_indent();
39     printf("%s=",name);
40     if(bn)
41         {
42         BN_print_fp(stdout,bn);
43         putchar('\n');
44         }
45     else
46         puts("(unset)");
47     }
48
49 static void print_time( char *name, time_t time)
50     {
51     print_indent();
52     printf("%s: ",name);
53     showtime("time",time);
54     printf("\n");
55     }
56
57 static void print_duration(char *name, time_t time)
58     {
59     int mins, hours, days, years;
60
61     print_indent();
62     printf("%s: ",name);
63     printf("duration " TIME_T_FMT " seconds",time);
64
65     mins=time/60;
66     hours=mins/60;
67     days=hours/24;
68     years=days/365;
69
70     printf(" (approx. ");
71     if (years)
72         printf("%d %s",years,years==1?"year":"years");
73     else if (days)
74         printf("%d %s",days,days==1?"day":"days");
75     else if (hours)
76         printf("%d %s", hours, hours==1?"hour":"hours");
77
78     printf(")");
79     printf("\n");
80     }
81
82 static void print_name(const char *name)
83     {
84     print_indent();
85     if(name)
86         printf("%s: ",name);
87     }
88
89 static void print_text_breakdown( ops_text_t *text)
90     {
91     unsigned i;
92     char *prefix=".. ";
93
94     /* these were recognised */
95
96     for(i=0 ; i<text->known.used ; i++)
97         {
98         print_indent();
99         printf(prefix);
100         printf("%s\n",text->known.strings[i]);
101         }
102
103     /* these were not recognised. the strings will contain the hex value
104        of the unrecognised value in string format - see process_octet_str()
105     */
106
107     if(text->unknown.used)
108         {
109         printf("\n");
110         print_indent();
111         printf("Not Recognised: ");
112         }
113     for( i=0; i < text->unknown.used; i++)
114         {
115         print_indent();
116         printf(prefix);
117         printf("%s\n",text->unknown.strings[i]);
118         }
119        
120     }
121
122 static void printhex(const unsigned char *src,size_t length)
123     {
124     while(length--)
125         printf("%02X",*src++);
126     }
127
128 static void print_hexdump(const char *name,
129                           const unsigned char *data,
130                           unsigned int len)
131     {
132     print_name(name);
133
134     printf("len=%d, data=0x", len);
135     printhex(data,len);
136     printf("\n");
137     }
138
139 static void print_hexdump_data(const char *name,
140                                const unsigned char *data,
141                                unsigned int len)
142     {
143     print_name(name);
144
145     printf("0x");
146     printhex(data,len);
147     printf("\n");
148     }
149
150 static void print_data(const char *name,const ops_data_t *data)
151     {
152     print_hexdump(name,data->contents,data->len);
153     }
154
155
156 static void print_boolean(const char *name, unsigned char bool)
157     {
158     print_name(name);
159
160     if(bool)
161         printf("Yes");
162     else
163         printf("No");
164     printf("\n");
165     }
166
167 static void print_tagname(const char *str)
168     {
169     print_indent();
170     printf("%s packet\n", str);
171     }
172
173 static void print_escaped(const unsigned char *data,size_t length)
174     {
175     while(length-- > 0)
176         {
177         if((*data >= 0x20 && *data < 0x7f && *data != '%') || *data == '\n')
178             putchar(*data);
179         else
180             printf("%%%02x",*data);
181         ++data;
182         }
183     }
184
185 static void print_string(const char *name,const char *str)
186     {
187     print_name(name);
188     print_escaped(str,strlen(str));
189     putchar('\n');
190     }
191
192 static void print_utf8_string(const char *name,const unsigned char *str)
193     {
194     // \todo Do this better for non-English character sets
195     print_string(name,(const char *)str);
196     }
197
198 static void print_block(const char *name,const unsigned char *str,
199                         size_t length)
200     {
201     int o=length;
202
203     print_indent();
204     printf(">>>>> %s >>>>>\n",name);
205
206     print_indent();
207     for( ; length > 0 ; --length)
208         {
209         if(*str >= 0x20 && *str < 0x7f && *str != '%')
210             putchar(*str);
211         else if(*str == '\n')
212             {
213             putchar(*str);
214             print_indent();
215             }
216         else
217             printf("%%%02x",*str);
218         ++str;
219         }
220     if(o && str[-1] != '\n')
221         {
222         putchar('\n');
223         print_indent();
224         fputs("[no newline]",stdout);
225         }
226     else
227         print_indent();
228     printf("<<<<< %s <<<<<\n",name);
229     }
230
231 static void print_headers(const ops_headers_t *headers)
232     {
233     unsigned n;
234
235     for(n=0 ; n < headers->nheaders ; ++n)
236         printf("%s=%s\n",headers->headers[n].key,headers->headers[n].value);
237     }
238
239 static void print_unsigned_int(char *name, unsigned int val)
240     {
241     print_name(name);
242     printf("%d\n", val);
243     }
244
245 static void print_string_and_value( char *name, char *str, unsigned char value)
246     {
247     print_name(name);
248
249     printf("%s", str);
250     printf(" (0x%x)", value);
251     printf("\n");
252     }
253
254 static void start_subpacket(unsigned type)
255     {
256     indent++;
257     print_indent();
258     printf("-- %s (type 0x%02x)\n",
259            ops_show_ss_type(type),
260            type-OPS_PTAG_SIGNATURE_SUBPACKET_BASE);
261     }
262  
263 static void end_subpacket()
264     {
265     indent--;
266     }
267
268 static void print_packet(const ops_packet_t *packet)
269     {
270     unsigned char *cur;
271     int i;
272     int rem;
273     int blksz=4;
274
275     printf("\nhexdump of packet contents follows:\n");
276
277
278     for (i=1,cur=packet->raw; cur<(packet->raw+packet->length); cur+=blksz,i++)
279         {
280         rem = packet->raw+packet->length-cur;
281         hexdump(cur,rem<=blksz ? rem : blksz);
282         printf(" ");
283         if (!(i%8))
284             printf("\n");
285        
286         }
287    
288     printf("\n");
289     }
290
291 static void print_public_key(const ops_public_key_t *key)
292     {
293     print_unsigned_int("Version",key->version);
294     print_time("Creation Time", key->creation_time);
295     if(key->version == OPS_V3)
296         print_unsigned_int("Days Valid",key->days_valid);
297
298     print_string_and_value("Algorithm",ops_show_pka(key->algorithm),
299                            key->algorithm);
300
301     switch(key->algorithm)
302         {
303     case OPS_PKA_DSA:
304         print_bn("p",key->key.dsa.p);
305         print_bn("q",key->key.dsa.q);
306         print_bn("g",key->key.dsa.g);
307         print_bn("y",key->key.dsa.y);
308         break;
309
310     case OPS_PKA_RSA:
311     case OPS_PKA_RSA_ENCRYPT_ONLY:
312     case OPS_PKA_RSA_SIGN_ONLY:
313         print_bn("n",key->key.rsa.n);
314         print_bn("e",key->key.rsa.e);
315         break;
316
317     case OPS_PKA_ELGAMAL:
318     case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
319         print_bn("p",key->key.elgamal.p);
320         print_bn("g",key->key.elgamal.g);
321         print_bn("y",key->key.elgamal.y);
322         break;
323
324     default:
325         assert(0);
326         }
327     }
328
329 static ops_parse_cb_return_t callback(const ops_parser_content_t *content_,
330                                       ops_parse_cb_info_t *cbinfo)
331     {
332     const ops_parser_content_union_t *content=&content_->content;
333     ops_text_t *text;
334     char *str;
335     ops_key_data_t *decrypter;
336     const ops_secret_key_t *secret;
337     static ops_boolean_t unarmoured;
338
339     OPS_USED(cbinfo);
340
341     if(unarmoured && content_->tag != OPS_PTAG_CT_UNARMOURED_TEXT)
342         {
343         unarmoured=ops_false;
344         puts("UNARMOURED TEXT ends");
345         }
346
347     switch(content_->tag)
348         {
349     case OPS_PARSER_ERROR:
350         printf("parse error: %s\n",content->error.error);
351         break;
352
353     case OPS_PARSER_ERRCODE:
354         printf("parse error: %s\n",
355                ops_errcode(content->errcode.errcode));
356         break;
357
358     case OPS_PARSER_PACKET_END:
359         print_packet(&content->packet);
360         break;
361
362     case OPS_PARSER_PTAG:
363         if(content->ptag.content_tag == OPS_PTAG_CT_PUBLIC_KEY)
364             {
365             indent=0;
366             printf("\n*** NEXT KEY ***\n");
367             }
368
369         printf("\n");
370         print_indent();
371         printf("==== ptag new_format=%d content_tag=%d length_type=%d"
372                " length=0x%x (%d) position=0x%x (%d)\n",content->ptag.new_format,
373                content->ptag.content_tag,content->ptag.length_type,
374                content->ptag.length,content->ptag.length,
375                content->ptag.position,content->ptag.position);
376         /*
377         print_tagname(ops_str_from_single_packet_tag(content->ptag.content_tag));
378         */
379         break;
380
381     case OPS_PTAG_CT_SE_DATA:
382         print_tagname("SYMMETRIC ENCRYPTED DATA");
383         break;
384
385     case OPS_PTAG_CT_PUBLIC_KEY:
386     case OPS_PTAG_CT_PUBLIC_SUBKEY:
387         if (content_->tag == OPS_PTAG_CT_PUBLIC_KEY)
388             print_tagname("PUBLIC KEY");
389         else
390             print_tagname("PUBLIC SUBKEY");
391
392         print_public_key(&content->public_key);
393         break;
394
395     case OPS_PTAG_CT_TRUST:
396         print_tagname("TRUST");
397         print_data("Trust",&content->trust.data);
398         break;
399        
400     case OPS_PTAG_CT_USER_ID:
401         /* XXX: how do we print UTF-8? */
402         print_tagname("USER ID");
403         print_utf8_string("user_id",content->user_id.user_id);
404         break;
405
406     case OPS_PTAG_CT_SIGNATURE:
407         print_tagname("SIGNATURE");
408         print_indent(indent);
409         print_unsigned_int("Signature Version",
410                content->signature.version);
411         if (content->signature.version == 3)
412             print_time("Signature Creation Time", content->signature.creation_time);
413
414         print_string_and_value("Signature Type",
415                                ops_show_sig_type(content->signature.type),
416                                content->signature.type);
417
418         print_hexdump_data("Signer ID",
419                       content->signature.signer_id,
420                       sizeof content->signature.signer_id);
421
422         print_string_and_value("Public Key Algorithm",
423                                ops_show_pka(content->signature.key_algorithm),
424                                content->signature.key_algorithm);
425         print_string_and_value("Hash Algorithm",
426                                ops_show_hash_algorithm(content->signature.hash_algorithm),
427                                content->signature.hash_algorithm);
428
429         print_indent();
430         print_hexdump_data("hash2",&content->signature.hash2[0],2);
431
432         switch(content->signature.key_algorithm)
433             {
434         case OPS_PKA_RSA:
435         case OPS_PKA_RSA_SIGN_ONLY:
436             print_bn("sig",content->signature.signature.rsa.sig);
437             break;
438
439         case OPS_PKA_DSA:
440             print_bn("r",content->signature.signature.dsa.r);
441             print_bn("s",content->signature.signature.dsa.s);
442             break;
443
444         case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
445             print_bn("r",content->signature.signature.elgamal.r);
446             print_bn("s",content->signature.signature.elgamal.s);
447             break;
448
449         default:
450             assert(0);
451             }   
452         break;
453
454     case OPS_PTAG_CT_COMPRESSED:
455         print_tagname("COMPRESSED");
456         print_unsigned_int("Compressed Data Type", content->compressed.type);
457         break;
458
459     case OPS_PTAG_CT_ONE_PASS_SIGNATURE:
460         print_tagname("ONE PASS SIGNATURE");
461
462         print_unsigned_int("Version",content->one_pass_signature.version);
463         print_string_and_value("Signature Type",
464                                ops_show_sig_type(content->one_pass_signature.sig_type),
465                                content->one_pass_signature.sig_type);
466         print_string_and_value("Hash Algorithm",
467                                ops_show_hash_algorithm(content->one_pass_signature.hash_algorithm),
468                                content->one_pass_signature.hash_algorithm);
469         print_string_and_value("Public Key Algorithm",
470                                ops_show_pka(content->one_pass_signature.key_algorithm),
471                                content->one_pass_signature.key_algorithm);
472         print_hexdump("Signer ID",
473                       content->one_pass_signature.keyid,
474                       sizeof content->one_pass_signature.keyid);
475
476         print_unsigned_int("Nested",
477                            content->one_pass_signature.nested);
478         break;
479
480     case OPS_PTAG_CT_USER_ATTRIBUTE:
481         print_tagname("USER ATTRIBUTE");
482         print_hexdump("User Attribute",
483                       content->user_attribute.data.contents,
484                       content->user_attribute.data.len);
485         break;
486
487     case OPS_PTAG_RAW_SS:
488         assert(!content_->critical);
489         start_subpacket(content_->tag);
490         print_unsigned_int("Raw Signature Subpacket: tag",
491                            content->ss_raw.tag-OPS_PTAG_SIGNATURE_SUBPACKET_BASE);
492         print_hexdump("Raw Data",
493                       content->ss_raw.raw,
494                       content->ss_raw.length);
495         break;
496
497     case OPS_PTAG_SS_CREATION_TIME:
498         start_subpacket(content_->tag);
499         print_time("Signature Creation Time",content->ss_time.time);
500         end_subpacket();
501         break;
502
503     case OPS_PTAG_SS_EXPIRATION_TIME:
504         start_subpacket(content_->tag);
505         print_duration("Signature Expiration Time",content->ss_time.time);
506         end_subpacket();
507         break;
508
509     case OPS_PTAG_SS_KEY_EXPIRATION_TIME:
510         start_subpacket(content_->tag);
511         print_duration("Key Expiration Time", content->ss_time.time);
512         end_subpacket();
513         break;
514
515     case OPS_PTAG_SS_TRUST:
516         start_subpacket(content_->tag);
517         print_string("Trust Signature","");
518         print_unsigned_int("Level",
519                            content->ss_trust.level);
520         print_unsigned_int("Amount",
521                            content->ss_trust.amount);
522         end_subpacket();
523         break;
524                
525     case OPS_PTAG_SS_REVOCABLE:
526         start_subpacket(content_->tag);
527         print_boolean("Revocable",content->ss_revocable.revocable);
528         end_subpacket();
529         break;     
530
531     case OPS_PTAG_SS_REVOCATION_KEY:
532         start_subpacket(content_->tag);
533         /* not yet tested */
534         printf ("  revocation key: class=0x%x",
535                 content->ss_revocation_key.class);
536         if (content->ss_revocation_key.class&0x40)
537             printf (" (sensitive)");
538         printf (", algid=0x%x",
539                 content->ss_revocation_key.algid);
540         printf(", fingerprint=");
541         hexdump(content->ss_revocation_key.fingerprint,20);
542         printf("\n");
543         end_subpacket();
544         break;
545    
546     case OPS_PTAG_SS_ISSUER_KEY_ID:
547         start_subpacket(content_->tag);
548         print_hexdump("Issuer Key Id",
549                       &content->ss_issuer_key_id.key_id[0],
550                       sizeof content->ss_issuer_key_id.key_id);
551         end_subpacket();
552         break;
553
554     case OPS_PTAG_SS_PREFERRED_SKA:
555         start_subpacket(content_->tag);
556         print_data( "Preferred Symmetric Algorithms",
557                    &content->ss_preferred_ska.data);
558
559         text = ops_showall_ss_preferred_ska(content->ss_preferred_ska);
560         print_text_breakdown(text);
561         ops_text_free(text);
562
563         end_subpacket();
564         break;
565
566     case OPS_PTAG_SS_PRIMARY_USER_ID:
567         start_subpacket(content_->tag);
568         print_boolean("Primary User ID",
569                       content->ss_primary_user_id.primary_user_id);
570         end_subpacket();
571         break;     
572
573     case OPS_PTAG_SS_PREFERRED_HASH:
574         start_subpacket(content_->tag);
575         print_data( "Preferred Hash Algorithms",
576                    &content->ss_preferred_hash.data);
577
578         text = ops_showall_ss_preferred_hash(content->ss_preferred_hash);
579         print_text_breakdown(text);
580         ops_text_free(text);
581         end_subpacket();
582         break;
583
584     case OPS_PTAG_SS_PREFERRED_COMPRESSION:
585         start_subpacket(content_->tag);
586         print_data( "Preferred Compression Algorithms",
587                    &content->ss_preferred_compression.data);
588
589         text = ops_showall_ss_preferred_compression(content->ss_preferred_compression);
590         print_text_breakdown(text);
591         ops_text_free(text);
592         end_subpacket();
593         break;
594        
595     case OPS_PTAG_SS_KEY_FLAGS:
596         start_subpacket(content_->tag);
597         print_data( "Key Flags", &content->ss_key_flags.data);
598
599         text = ops_showall_ss_key_flags(content->ss_key_flags);
600         print_text_breakdown( text);
601         ops_text_free(text);
602
603         end_subpacket();
604         break;
605        
606     case OPS_PTAG_SS_KEY_SERVER_PREFS:
607         start_subpacket(content_->tag);
608         print_data( "Key Server Preferences",
609                    &content->ss_key_server_prefs.data);
610
611         text = ops_showall_ss_key_server_prefs(content->ss_key_server_prefs);
612         print_text_breakdown( text);
613         ops_text_free(text);
614
615         end_subpacket();
616         break;
617        
618     case OPS_PTAG_SS_FEATURES:
619         start_subpacket(content_->tag);
620         print_data( "Features",
621                    &content->ss_features.data);
622
623         text = ops_showall_ss_features(content->ss_features);
624         print_text_breakdown( text);
625         ops_text_free(text);
626
627         end_subpacket();
628         break;
629
630     case OPS_PTAG_SS_NOTATION_DATA:
631         start_subpacket(content_->tag);
632         print_indent();
633         printf("Notation Data:\n");
634
635         indent++;
636         print_data( "Flags",
637                    &content->ss_notation_data.flags);
638         text = ops_showall_ss_notation_data_flags(content->ss_notation_data);
639         print_text_breakdown( text);
640         ops_text_free(text);
641
642         /* xxx - TODO: print out UTF - rachel */
643
644         print_data( "Name",
645                    &content->ss_notation_data.name);
646
647         print_data( "Value",
648                    &content->ss_notation_data.value);
649
650         indent--;
651         end_subpacket();
652         break;
653
654     case OPS_PTAG_SS_REGEXP:
655         start_subpacket(content_->tag);
656         print_hexdump("Regular Expression",
657                       (unsigned char *)content->ss_regexp.text,
658                       strlen(content->ss_regexp.text));
659         print_string(NULL,
660                      content->ss_regexp.text);
661         end_subpacket();
662         break;
663
664     case OPS_PTAG_SS_POLICY_URL:
665         start_subpacket(content_->tag);
666         print_string("Policy URL",
667                      content->ss_policy_url.text);
668         end_subpacket();
669         break;
670
671     case OPS_PTAG_SS_SIGNERS_USER_ID:
672         start_subpacket(content_->tag);
673         print_utf8_string("Signer's User ID",content->ss_signers_user_id.user_id);
674         end_subpacket();
675         break;
676
677     case OPS_PTAG_SS_PREFERRED_KEY_SERVER:
678         start_subpacket(content_->tag);
679         print_string("Preferred Key Server",
680                      content->ss_preferred_key_server.text);
681         end_subpacket();
682         break;
683
684     case OPS_PTAG_SS_USERDEFINED00:
685     case OPS_PTAG_SS_USERDEFINED01:
686     case OPS_PTAG_SS_USERDEFINED02:
687     case OPS_PTAG_SS_USERDEFINED03:
688     case OPS_PTAG_SS_USERDEFINED04:
689     case OPS_PTAG_SS_USERDEFINED05:
690     case OPS_PTAG_SS_USERDEFINED06:
691     case OPS_PTAG_SS_USERDEFINED07:
692     case OPS_PTAG_SS_USERDEFINED08:
693     case OPS_PTAG_SS_USERDEFINED09:
694     case OPS_PTAG_SS_USERDEFINED10:
695         start_subpacket(content_->tag);
696         print_hexdump("Internal or user-defined",
697                       content->ss_userdefined.data.contents,
698                       content->ss_userdefined.data.len);
699         end_subpacket();
700         break;
701
702     case OPS_PTAG_SS_RESERVED:
703         start_subpacket(content_->tag);
704         print_hexdump("Reserved",
705                       content->ss_userdefined.data.contents,
706                       content->ss_userdefined.data.len);
707         end_subpacket();
708         break;
709
710     case OPS_PTAG_SS_REVOCATION_REASON:
711         start_subpacket(content_->tag);
712         print_hexdump("Revocation Reason",
713                       &content->ss_revocation_reason.code,
714                       1);
715         str = ops_show_ss_rr_code(content->ss_revocation_reason.code);
716         print_string(NULL,str);
717         /* xxx - todo : output text as UTF-8 string */
718         end_subpacket();
719         break;
720
721     case OPS_PTAG_CT_LITERAL_DATA_HEADER:
722         print_tagname("LITERAL DATA HEADER");
723         printf("  literal data header format=%c filename='%s'\n",
724                content->literal_data_header.format,
725                content->literal_data_header.filename);
726         showtime("    modification time",
727                  content->literal_data_header.modification_time);
728         printf("\n");
729         break;
730
731     case OPS_PTAG_CT_LITERAL_DATA_BODY:
732         print_tagname("LITERAL DATA BODY");
733         printf("  literal data body length=%d\n",
734                content->literal_data_body.length);
735         printf("    data=");
736         hexdump(content->literal_data_body.data,
737                 content->literal_data_body.length);
738         printf("\n");
739         break;
740
741     case OPS_PTAG_CT_SIGNATURE_HEADER:
742         print_tagname("SIGNATURE");
743         print_indent(indent);
744         print_unsigned_int("Signature Version",
745                content->signature.version);
746         if(content->signature.creation_time_set)
747             print_time("Signature Creation Time", content->signature.creation_time);
748
749         print_string_and_value("Signature Type",
750                                ops_show_sig_type(content->signature.type),
751                                content->signature.type);
752
753         if(content->signature.signer_id_set)
754             print_hexdump_data("Signer ID",
755                                content->signature.signer_id,
756                                sizeof content->signature.signer_id);
757
758         print_string_and_value("Public Key Algorithm",
759                                ops_show_pka(content->signature.key_algorithm),
760                                content->signature.key_algorithm);
761         print_string_and_value("Hash Algorithm",
762                                ops_show_hash_algorithm(content->signature.hash_algorithm),
763                                content->signature.hash_algorithm);
764
765         break;
766
767     case OPS_PTAG_CT_SIGNATURE_FOOTER:
768         print_indent();
769         print_hexdump_data("hash2",&content->signature.hash2[0],2);
770
771         switch(content->signature.key_algorithm)
772             {
773         case OPS_PKA_RSA:
774             print_bn("sig",content->signature.signature.rsa.sig);
775             break;
776
777         case OPS_PKA_DSA:
778             print_bn("r",content->signature.signature.dsa.r);
779             print_bn("s",content->signature.signature.dsa.s);
780             break;
781
782         case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
783             print_bn("r",content->signature.signature.elgamal.r);
784             print_bn("s",content->signature.signature.elgamal.s);
785             break;
786
787         case OPS_PKA_PRIVATE00:
788         case OPS_PKA_PRIVATE01:
789         case OPS_PKA_PRIVATE02:
790         case OPS_PKA_PRIVATE03:
791         case OPS_PKA_PRIVATE04:
792         case OPS_PKA_PRIVATE05:
793         case OPS_PKA_PRIVATE06:
794         case OPS_PKA_PRIVATE07:
795         case OPS_PKA_PRIVATE08:
796         case OPS_PKA_PRIVATE09:
797         case OPS_PKA_PRIVATE10:
798             print_data("Private/Experimental",
799                        &content->signature.signature.unknown.data);
800             break;
801
802         default:
803             assert(0);
804             }
805         break;
806
807     case OPS_PARSER_CMD_GET_PASSPHRASE:
808         if(passphrase_prompt)
809             {
810             *content->passphrase=ops_get_passphrase();
811             if(!**content->passphrase)
812                 break;
813             return OPS_KEEP_MEMORY;
814             }
815         else
816             printf(">>> ASKED FOR PASSPHRASE <<<\n");
817         break;
818
819     case OPS_PTAG_CT_SECRET_KEY:
820     case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY:
821         // XXX: fix me
822         if(content_->tag == OPS_PTAG_CT_SECRET_KEY)
823             print_tagname("SECRET_KEY");
824         else
825             print_tagname("ENCRYPTED_SECRET_KEY");
826         print_public_key(&content->secret_key.public_key);
827         printf("S2K Usage: %d\n",content->secret_key.s2k_usage);
828         printf("S2K Specifier: %d\n",content->secret_key.s2k_specifier);
829         printf("Symmetric algorithm: %d\n",content->secret_key.algorithm);
830         printf("Hash algorithm: %d\n",content->secret_key.hash_algorithm);
831         print_hexdump("Salt",content->secret_key.salt,
832                       sizeof content->secret_key.salt);
833         printf("Iterations: %d\n",content->secret_key.iterations);
834         print_hexdump("IV",content->secret_key.iv,
835                       ops_block_size(content->secret_key.algorithm));
836
837         /* no more set if encrypted */
838         if(content_->tag == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY)
839             break;
840
841         printf("Checksum: %04x\n",content->secret_key.checksum);
842
843         switch(content->secret_key.public_key.algorithm)
844             {
845         case OPS_PKA_RSA:
846             print_bn("d",content->secret_key.key.rsa.d);
847             print_bn("p",content->secret_key.key.rsa.p);
848             print_bn("q",content->secret_key.key.rsa.q);
849             print_bn("u",content->secret_key.key.rsa.u);
850             break;
851
852         case OPS_PKA_DSA:
853             print_bn("x",content->secret_key.key.dsa.x);
854             break;
855
856         default:
857             assert(0);
858             }
859         break;
860
861     case OPS_PTAG_CT_ARMOUR_HEADER:
862         print_tagname("ARMOUR HEADER");
863         print_string("type",content->armour_header.type);
864         break;
865
866     case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
867         print_tagname("SIGNED CLEARTEXT HEADER");
868         print_headers(&content->signed_cleartext_header.headers);
869         break;
870
871     case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY:
872         print_tagname("SIGNED CLEARTEXT BODY");
873         print_block("signed cleartext",content->signed_cleartext_body.data,
874                     content->signed_cleartext_body.length);
875         break;
876
877     case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
878         print_tagname("SIGNED CLEARTEXT TRAILER");
879         printf("hash algorithm: %d\n",
880                content->signed_cleartext_trailer.hash->algorithm);
881         printf("\n");
882         break;
883
884     case OPS_PTAG_CT_UNARMOURED_TEXT:
885         if(!unarmoured)
886             {
887             print_tagname("UNARMOURED TEXT");
888             unarmoured=ops_true;
889             }
890         putchar('[');
891         print_escaped(content->unarmoured_text.data,
892                       content->unarmoured_text.length);
893         putchar(']');
894         break;
895
896     case OPS_PTAG_CT_ARMOUR_TRAILER:
897         print_tagname("ARMOUR TRAILER");
898         print_string("type",content->armour_header.type);
899         break;
900
901     case OPS_PTAG_CT_PK_SESSION_KEY:
902         print_tagname("PUBLIC KEY SESSION KEY");
903         printf("Version: %d\n",content->pk_session_key.version);
904         print_hexdump("key ID",content->pk_session_key.key_id,
905                       sizeof content->pk_session_key.key_id);
906         printf("Algorithm: %d\n",content->pk_session_key.algorithm);
907         switch(content->pk_session_key.algorithm)
908             {
909         case OPS_PKA_RSA:
910             print_bn("encrypted_m",
911                      content->pk_session_key.parameters.rsa.encrypted_m);
912             break;
913
914         case OPS_PKA_ELGAMAL:
915             print_bn("g_to_k",
916                      content->pk_session_key.parameters.elgamal.g_to_k);
917             print_bn("encrypted_m",
918                      content->pk_session_key.parameters.elgamal.encrypted_m);
919             break;
920
921         default:
922             assert(0);
923             }
924
925         /* Now get hold of session key for later on */
926
927         decrypter=ops_keyring_find_key_by_id(&keyring,
928                                              content->pk_session_key.key_id);
929         if(!decrypter || !ops_key_is_secret(decrypter))
930             break;
931
932         puts("[Decryption key found in keyring]");
933
934         secret=ops_get_secret_key_from_data(decrypter);
935         while(!secret)
936             {
937             /* then it must be encrypted */
938             char *phrase=ops_get_passphrase();
939             secret=ops_decrypt_secret_key_from_data(decrypter,phrase);
940             free(phrase);
941             }
942        
943         break;
944
945     default:
946         print_tagname("UNKNOWN PACKET TYPE");
947         fprintf(stderr,"packet-dump: unknown tag=%d (0x%x)\n",content_->tag,
948                 content_->tag);
949         exit(1);
950         }
951     return OPS_RELEASE_MEMORY;
952     }
953
954 static void usage()
955     {
956     fprintf(stderr,"%s [-a] [-b] <file name>\n\n",pname);
957     fprintf(stderr,"-a\tRead armoured data\n"
958             "-b\tDon't buffer stdout/stderr\n"
959             "-B\tRead via a memory buffer\n"
960             "-k <file>\tRead in a keyring\n"
961             "-p\tPrompt for passphrases\n");
962    
963     exit(1);
964     }
965
966 int main(int argc,char **argv)
967     {
968     ops_parse_info_t *pinfo;
969     ops_boolean_t armour=ops_false;
970     int ret;
971     int ch;
972     int fd;
973     ops_boolean_t buffer_read=ops_false;
974     unsigned char buffer[10240];
975     const char *keyring_file=NULL;
976
977     pname=argv[0];
978
979     while((ch=getopt(argc,argv,"abBk:p")) != -1)
980         switch(ch)
981             {
982         case 'a':
983             armour=ops_true;
984             break;
985
986         case 'b':
987             setvbuf(stdout,NULL,_IONBF,0);
988             setvbuf(stderr,NULL,_IONBF,0);
989             break;
990
991         case 'B':
992             buffer_read=ops_true;
993             break;
994
995         case 'k':
996             keyring_file=optarg;
997             break;
998
999         case 'p':
1000             passphrase_prompt=ops_true;
1001             break;
1002
1003         default:
1004             usage();
1005             }
1006     argc-=optind;
1007     argv+=optind;
1008
1009     if(argc != 1)
1010         usage();
1011
1012     if(keyring_file)
1013         ops_keyring_read(&keyring,keyring_file);
1014
1015     fd=open(argv[0],O_RDONLY);
1016     if(fd < 0)
1017         {
1018         perror(argv[0]);
1019         exit(2);
1020         }
1021
1022     pinfo=ops_parse_info_new();
1023     //    ops_parse_packet_options(&opt,OPS_PTAG_SS_ALL,OPS_PARSE_RAW);
1024     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
1025
1026     ops_parse_cb_set(pinfo,callback,NULL);
1027
1028     if(buffer_read)
1029         {
1030         int n;
1031
1032         n=read(fd,buffer,sizeof buffer);
1033         if(n < 0)
1034             {
1035             perror(argv[0]);
1036             exit(3);
1037             }
1038         ops_reader_set_memory(pinfo,buffer,n);
1039         }
1040     else
1041         ops_reader_set_fd(pinfo,fd);
1042
1043     if(armour)
1044         ops_reader_push_dearmour(pinfo,ops_true,ops_true,ops_true);
1045
1046     ret=ops_parse(pinfo);
1047     if (!ret)
1048         ops_print_errors(ops_parse_info_get_errors(pinfo));
1049
1050     ops_parse_info_delete(pinfo);
1051
1052     return 0;
1053     }
Note: See TracBrowser for help on using the browser.