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

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

More hash support, print the right thing.

  • 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         printf("Checksum: %04x\n",content->secret_key.checksum);
837
838         switch(content->secret_key.public_key.algorithm)
839             {
840         case OPS_PKA_RSA:
841             print_bn("d",content->secret_key.key.rsa.d);
842             print_bn("p",content->secret_key.key.rsa.p);
843             print_bn("q",content->secret_key.key.rsa.q);
844             print_bn("u",content->secret_key.key.rsa.u);
845             break;
846
847         case OPS_PKA_DSA:
848             print_bn("x",content->secret_key.key.dsa.x);
849             break;
850
851         default:
852             assert(0);
853             }
854         break;
855
856     case OPS_PTAG_CT_ARMOUR_HEADER:
857         print_tagname("ARMOUR HEADER");
858         print_string("type",content->armour_header.type);
859         break;
860
861     case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
862         print_tagname("SIGNED CLEARTEXT HEADER");
863         print_headers(&content->signed_cleartext_header.headers);
864         break;
865
866     case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY:
867         print_tagname("SIGNED CLEARTEXT BODY");
868         print_block("signed cleartext",content->signed_cleartext_body.data,
869                     content->signed_cleartext_body.length);
870         break;
871
872     case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
873         print_tagname("SIGNED CLEARTEXT TRAILER");
874         printf("hash algorithm: %d\n",
875                content->signed_cleartext_trailer.hash->algorithm);
876         printf("\n");
877         break;
878
879     case OPS_PTAG_CT_UNARMOURED_TEXT:
880         if(!unarmoured)
881             {
882             print_tagname("UNARMOURED TEXT");
883             unarmoured=ops_true;
884             }
885         putchar('[');
886         print_escaped(content->unarmoured_text.data,
887                       content->unarmoured_text.length);
888         putchar(']');
889         break;
890
891     case OPS_PTAG_CT_ARMOUR_TRAILER:
892         print_tagname("ARMOUR TRAILER");
893         print_string("type",content->armour_header.type);
894         break;
895
896     case OPS_PTAG_CT_PK_SESSION_KEY:
897         print_tagname("PUBLIC KEY SESSION KEY");
898         printf("Version: %d\n",content->pk_session_key.version);
899         print_hexdump("key ID",content->pk_session_key.key_id,
900                       sizeof content->pk_session_key.key_id);
901         printf("Algorithm: %d\n",content->pk_session_key.algorithm);
902         switch(content->pk_session_key.algorithm)
903             {
904         case OPS_PKA_RSA:
905             print_bn("encrypted_m",
906                      content->pk_session_key.parameters.rsa.encrypted_m);
907             break;
908
909         case OPS_PKA_ELGAMAL:
910             print_bn("g_to_k",
911                      content->pk_session_key.parameters.elgamal.g_to_k);
912             print_bn("encrypted_m",
913                      content->pk_session_key.parameters.elgamal.encrypted_m);
914             break;
915
916         default:
917             assert(0);
918             }
919
920         /* Now get hold of session key for later on */
921
922         decrypter=ops_keyring_find_key_by_id(&keyring,
923                                              content->pk_session_key.key_id);
924         if(!decrypter || !ops_key_is_secret(decrypter))
925             break;
926
927         puts("[Decryption key found in keyring]");
928
929         secret=ops_get_secret_key_from_data(decrypter);
930         while(!secret)
931             {
932             /* then it must be encrypted */
933             char *phrase=ops_get_passphrase();
934             secret=ops_decrypt_secret_key_from_data(decrypter,phrase);
935             free(phrase);
936             }
937        
938         break;
939
940     default:
941         print_tagname("UNKNOWN PACKET TYPE");
942         fprintf(stderr,"packet-dump: unknown tag=%d (0x%x)\n",content_->tag,
943                 content_->tag);
944         exit(1);
945         }
946     return OPS_RELEASE_MEMORY;
947     }
948
949 static void usage()
950     {
951     fprintf(stderr,"%s [-a] [-b] <file name>\n\n",pname);
952     fprintf(stderr,"-a\tRead armoured data\n"
953             "-b\tDon't buffer stdout/stderr\n"
954             "-B\tRead via a memory buffer\n"
955             "-k <file>\tRead in a keyring\n"
956             "-p\tPrompt for passphrases\n");
957    
958     exit(1);
959     }
960
961 int main(int argc,char **argv)
962     {
963     ops_parse_info_t *pinfo;
964     ops_boolean_t armour=ops_false;
965     int ret;
966     int ch;
967     int fd;
968     ops_boolean_t buffer_read=ops_false;
969     unsigned char buffer[10240];
970     const char *keyring_file=NULL;
971
972     pname=argv[0];
973
974     while((ch=getopt(argc,argv,"abBk:p")) != -1)
975         switch(ch)
976             {
977         case 'a':
978             armour=ops_true;
979             break;
980
981         case 'b':
982             setvbuf(stdout,NULL,_IONBF,0);
983             setvbuf(stderr,NULL,_IONBF,0);
984             break;
985
986         case 'B':
987             buffer_read=ops_true;
988             break;
989
990         case 'k':
991             keyring_file=optarg;
992             break;
993
994         case 'p':
995             passphrase_prompt=ops_true;
996             break;
997
998         default:
999             usage();
1000             }
1001     argc-=optind;
1002     argv+=optind;
1003
1004     if(argc != 1)
1005         usage();
1006
1007     if(keyring_file)
1008         ops_keyring_read(&keyring,keyring_file);
1009
1010     fd=open(argv[0],O_RDONLY);
1011     if(fd < 0)
1012         {
1013         perror(argv[0]);
1014         exit(2);
1015         }
1016
1017     pinfo=ops_parse_info_new();
1018     //    ops_parse_packet_options(&opt,OPS_PTAG_SS_ALL,OPS_PARSE_RAW);
1019     ops_parse_options(pinfo,OPS_PTAG_SS_ALL,OPS_PARSE_PARSED);
1020
1021     ops_parse_cb_set(pinfo,callback,NULL);
1022
1023     if(buffer_read)
1024         {
1025         int n;
1026
1027         n=read(fd,buffer,sizeof buffer);
1028         if(n < 0)
1029             {
1030             perror(argv[0]);
1031             exit(3);
1032             }
1033         ops_reader_set_memory(pinfo,buffer,n);
1034         }
1035     else
1036         ops_reader_set_fd(pinfo,fd);
1037
1038     if(armour)
1039         ops_reader_push_dearmour(pinfo,ops_true,ops_true,ops_true);
1040
1041     ret=ops_parse(pinfo);
1042     if (!ret)
1043         ops_print_errors(ops_parse_info_get_errors(pinfo));
1044
1045     ops_parse_info_delete(pinfo);
1046
1047     return 0;
1048     }
Note: See TracBrowser for help on using the browser.