See ChangeLog: Thu Jan 7 18:00:58 CET 1999 Werner Koch
[gnupg.git] / g10 / armor.c
1 /* armor.c - Armor flter
2  *      Copyright (C) 1998,1999 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 <errno.h>
26 #include <assert.h>
27
28 #include "errors.h"
29 #include "iobuf.h"
30 #include "memory.h"
31 #include "util.h"
32 #include "filter.h"
33 #include "packet.h"
34 #include "options.h"
35 #include "main.h"
36 #include "status.h"
37 #include "i18n.h"
38
39
40 #define MAX_LINELEN 20000
41
42 #define CRCINIT 0xB704CE
43 #define CRCPOLY 0X864CFB
44 #define CRCUPDATE(a,c) do {                                                 \
45                         a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \
46                         a &= 0x00ffffff;                                    \
47                     } while(0)
48 static u32 crc_table[256];
49 static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
50                          "abcdefghijklmnopqrstuvwxyz"
51                          "0123456789+/";
52 static byte asctobin[256]; /* runtime initialized */
53 static int is_initialized;
54
55
56 typedef enum {
57     fhdrHASArmor = 0,
58     fhdrNOArmor,
59     fhdrINIT,
60     fhdrINITCont,
61     fhdrINITSkip,
62     fhdrCHECKBegin,
63     fhdrWAITHeader,
64     fhdrWAITClearsig,
65     fhdrSKIPHeader,
66     fhdrCLEARSIG,
67     fhdrREADClearsig,
68     fhdrNullClearsig,
69     fhdrEMPTYClearsig,
70     fhdrCHECKClearsig,
71     fhdrCHECKClearsig2,
72     fhdrCHECKDashEscaped,
73     fhdrCHECKDashEscaped2,
74     fhdrCHECKDashEscaped3,
75     fhdrREADClearsigNext,
76     fhdrENDClearsig,
77     fhdrENDClearsigHelp,
78     fhdrTESTSpaces,
79     fhdrCLEARSIGSimple,
80     fhdrCLEARSIGSimpleNext,
81     fhdrTEXT,
82     fhdrTEXTSimple,
83     fhdrERROR,
84     fhdrERRORShow,
85     fhdrEOF
86 } fhdr_state_t;
87
88
89 /* if we encounter this armor string with this index, go
90  * into a mode which fakes packets and wait for the next armor */
91 #define BEGIN_SIGNATURE 2
92 #define BEGIN_SIGNED_MSG_IDX 3
93 static char *head_strings[] = {
94     "BEGIN PGP MESSAGE",
95     "BEGIN PGP PUBLIC KEY BLOCK",
96     "BEGIN PGP SIGNATURE",
97     "BEGIN PGP SIGNED MESSAGE",
98     "BEGIN PGP ARMORED FILE",       /* gnupg extension */
99     "BEGIN PGP PRIVATE KEY BLOCK",
100     "BEGIN PGP SECRET KEY BLOCK",   /* only used by pgp2 */
101     NULL
102 };
103 static char *tail_strings[] = {
104     "END PGP MESSAGE",
105     "END PGP PUBLIC KEY BLOCK",
106     "END PGP SIGNATURE",
107     "END dummy",
108     "END PGP ARMORED FILE",
109     "END PGP PRIVATE KEY BLOCK",
110     "END PGP SECRET KEY BLOCK",
111     NULL
112 };
113
114
115
116 static void
117 initialize(void)
118 {
119     int i, j;
120     u32 t;
121     byte *s;
122
123     /* init the crc lookup table */
124     crc_table[0] = 0;
125     for(i=j=0; j < 128; j++ ) {
126         t = crc_table[j];
127         if( t & 0x00800000 ) {
128             t <<= 1;
129             crc_table[i++] = t ^ CRCPOLY;
130             crc_table[i++] = t;
131         }
132         else {
133             t <<= 1;
134             crc_table[i++] = t;
135             crc_table[i++] = t ^ CRCPOLY;
136         }
137     }
138     /* build the helptable for radix64 to bin conversion */
139     for(i=0; i < 256; i++ )
140         asctobin[i] = 255; /* used to detect invalid characters */
141     for(s=bintoasc,i=0; *s; s++,i++ )
142         asctobin[*s] = i;
143
144     is_initialized=1;
145 }
146
147 /****************
148  * Check whether this is an armored file or not
149  * See also parse-packet.c for details on this code
150  * Returns: True if it seems to be armored
151  */
152 static int
153 is_armored( const byte *buf )
154 {
155     int ctb, pkttype;
156
157     ctb = *buf;
158     if( !(ctb & 0x80) )
159         return 1; /* invalid packet: assume it is armored */
160     pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
161     switch( pkttype ) {
162       case PKT_MARKER:
163       case PKT_SYMKEY_ENC:
164       case PKT_PUBLIC_KEY:
165       case PKT_SECRET_KEY:
166       case PKT_PUBKEY_ENC:
167       case PKT_SIGNATURE:
168       case PKT_COMMENT:
169       case PKT_OLD_COMMENT:
170       case PKT_PLAINTEXT:
171       case PKT_COMPRESSED:
172       case PKT_ENCRYPTED:
173         return 0; /* seems to be a regular packet: not armored */
174     }
175
176     return 1;
177 }
178
179
180 /****************
181  * Try to check whether the iobuf is armored
182  * Returns true if this may be the case; the caller should use the
183  *         filter to do further processing.
184  */
185 int
186 use_armor_filter( IOBUF a )
187 {
188     byte buf[1];
189     int n;
190
191     n = iobuf_peek(a, buf, 1 );
192     if( n == -1 )
193         return 0; /* EOF, doesn't matter whether armored or not */
194     if( !n )
195         return 1; /* can't check it: try armored */
196     return is_armored(buf);
197 }
198
199
200
201
202 static void
203 invalid_armor(void)
204 {
205     write_status(STATUS_BADARMOR);
206     g10_exit(1); /* stop here */
207 }
208
209
210 /****************
211  * check whether the armor header is valid on a signed message.
212  * this is for security reasons: the header lines are not included in the
213  * hash and by using some creative formatting rules, Mallory could fake
214  * any text at the beginning of a document; assuming it is read with
215  * a simple viewer. We only allow the Hash Header.
216  */
217 static int
218 parse_hash_header( const char *line )
219 {
220     const char *s, *s2;
221     unsigned found = 0;
222
223     if( strlen(line) < 6  || strlen(line) > 60 )
224         return 0; /* too short or too long */
225     if( memcmp( line, "Hash:", 5 ) )
226         return 0; /* invalid header */
227     s = line+5;
228     for(s=line+5;;s=s2) {
229         for(; *s && (*s==' ' || *s == '\t'); s++ )
230             ;
231         if( !*s )
232             break;
233         for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
234             ;
235         if( !strncmp( s, "RIPEMD160", s2-s ) )
236             found |= 1;
237         else if( !strncmp( s, "SHA1", s2-s ) )
238             found |= 2;
239         else if( !strncmp( s, "MD5", s2-s ) )
240             found |= 4;
241         else if( !strncmp( s, "TIGER", s2-s ) )
242             found |= 8;
243         else
244             return 0;
245         for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
246             ;
247         if( *s2 && *s2 != ',' )
248             return 0;
249         if( *s2 )
250             s2++;
251     }
252     return found;
253 }
254
255
256
257 #if 0 /* old code */
258 /****************
259  * parse an ascii armor.
260  * Returns: the state,
261  *          the remaining bytes in BUF are returned in RBUFLEN.
262  *          r_empty return the # of empty lines before the buffer
263  */
264 static fhdr_state_t
265 find_header( fhdr_state_t state, byte *buf, size_t *r_buflen,
266              IOBUF a, size_t n, unsigned *r_empty, int *r_hashes,
267              int only_keyblocks, int *not_dashed )
268 {
269     int c=0, i;
270     const char *s;
271     byte *p;
272     size_t buflen;
273     int cont;
274     int clearsig=0;
275     int hdr_line=0;
276     unsigned empty = 0;
277
278     buflen = *r_buflen;
279     assert(buflen >= 100 );
280     buflen -= 4; /* reserved room for CR,LF, and two extra */
281     do {
282         switch( state ) {
283           case fhdrHASArmor:
284             /* read at least the first byte to check whether it is armored
285              * or not */
286             c = 0;
287             for(n=0; n < 28 && (c=iobuf_get(a)) != -1 && c != '\n'; )
288                 buf[n++] = c;
289             if( !n && c == '\n' )
290                 state = fhdrCHECKBegin;
291             else if( !n  || c == -1 )
292                 state = fhdrNOArmor; /* too short */
293             else if( !is_armored( buf ) ) {
294                 state = fhdrNOArmor;
295                 if( c == '\n' )
296                     buf[n++] = c;
297             }
298             else if( c == '\n' )
299                 state = fhdrCHECKBegin;
300             else
301                 state = fhdrINITCont;
302             break;
303
304           case fhdrINIT: /* read some stuff into buffer */
305             n = 0;
306           case fhdrINITCont: /* read more stuff into buffer */
307             c = 0;
308             for(; n < buflen && (c=iobuf_get(a)) != -1 && c != '\n'; )
309                 buf[n++] = c;
310             state = c == '\n' ? fhdrCHECKBegin :
311                      c == -1  ? fhdrEOF : fhdrINITSkip;
312             break;
313
314           case fhdrINITSkip:
315             if( c == '\n' )
316                 n = 0;
317             else {
318                 while( (c=iobuf_get(a)) != -1 && c != '\n' )
319                     ;
320             }
321             state =  c == -1? fhdrEOF : fhdrINIT;
322             break;
323
324           case fhdrSKIPHeader:
325             while( (c=iobuf_get(a)) != -1 && c != '\n' )
326                 ;
327             state =  c == -1? fhdrEOF : fhdrWAITHeader;
328             break;
329
330           case fhdrWAITHeader: /* wait for Header lines */
331             c = 0;
332             for(n=0; n < buflen && (c=iobuf_get(a)) != -1 && c != '\n'; )
333                 buf[n++] = c;
334             buf[n] = 0;
335             if( n < buflen || c == '\n' ) {
336                 if( n && buf[0] != '\r') { /* maybe a header */
337                     if( strchr( buf, ':') ) { /* yes */
338                         int hashes=0;
339                         if( buf[n-1] == '\r' )
340                             buf[--n] = 0;
341                         if( opt.verbose ) {
342                             log_info(_("armor header: "));
343                             print_string( stderr, buf, n, 0 );
344                             putc('\n', stderr);
345                         }
346                         if( clearsig && !(hashes=parse_hash_header( buf )) ) {
347                             if( strlen(buf) > 15
348                                 && !memcmp( buf, "NotDashEscaped:", 15 ) ) {
349                                 *not_dashed = 1;
350                                 state = fhdrWAITHeader;
351                             }
352                             else {
353                                 log_error(_("invalid clearsig header\n"));
354                                 state = fhdrERROR;
355                             }
356                         }
357                         else {
358                             state = fhdrWAITHeader;
359                             if( r_hashes )
360                                 *r_hashes |= hashes;
361                         }
362                     }
363                     else if( clearsig && n > 15 && !memcmp(buf, "-----", 5 ) )
364                         state = fhdrNullClearsig;
365                     else
366                         state = fhdrCHECKDashEscaped3;
367                 }
368                 else if( !n || (buf[0] == '\r' && !buf[1]) ) { /* empty line */
369                     if( clearsig )
370                         state = fhdrWAITClearsig;
371                     else {
372                         /* this is not really correct: if we do not have
373                          * a clearsig and no armor lines we are not allowed
374                          * to have an empty line */
375                         n = 0;
376                         state = fhdrTEXT;
377                     }
378                 }
379                 else {
380                     log_error(_("invalid armor header: "));
381                     print_string( stderr, buf, n, 0 );
382                     putc('\n', stderr);
383                     state = fhdrERROR;
384                 }
385             }
386             else if( c != -1 ) {
387                 if( strchr( buf, ':') ) { /* buffer to short, but this is okay*/
388                     if( opt.verbose ) {
389                         log_info(_("armor header: "));
390                         print_string( stderr, buf, n, 0 );
391                         fputs("[...]\n", stderr);  /* indicate it is truncated */
392                     }
393                     state = fhdrSKIPHeader;  /* skip rest of line */
394                 }
395                 else /* line too long */
396                     state = fhdrERROR;
397             }
398             else
399                 state = fhdrEOF;
400             break;
401
402           case fhdrWAITClearsig: /* skip the empty line (for clearsig) */
403             c = 0;
404             for(n=0; n < buflen && (c=iobuf_get(a)) != -1 && c != '\n'; )
405                 buf[n++] = c;
406             if( c != -1 ) {
407                 if( n > 15 && !memcmp(buf, "-----", 5 ) )
408                     state = fhdrNullClearsig;
409                 else if( c != '\n' )
410                     state = fhdrREADClearsigNext;
411                 else
412                     state = fhdrCHECKDashEscaped3;
413             }
414             else {
415                 /* fixme: we should check whether this line continues
416                  *   it is possible that we have only read ws until here
417                  *   and more stuff is to come */
418                 state = fhdrEOF;
419             }
420             break;
421
422           case fhdrNullClearsig: /* zero length cleartext */
423             state = fhdrENDClearsig;
424             break;
425
426           case fhdrENDClearsig:
427           case fhdrCHECKBegin:
428             state = state == fhdrCHECKBegin ? fhdrINITSkip : fhdrERRORShow;
429             if( n < 15 )
430                 break;  /* too short */
431             if( memcmp( buf, "-----", 5 ) )
432                 break;
433             buf[n] = 0;
434             p = strstr(buf+5, "-----");
435             if( !p )
436                 break;
437             *p = 0;
438             p += 5;
439             if( *p == '\r' )
440                 p++;
441             if( *p )
442                 break; /* garbage after dashes */
443             p = buf+5;
444             for(i=0; (s=head_strings[i]); i++ )
445                 if( !strcmp(s, p) )
446                     break;
447             if( !s )
448                 break; /* unknown begin line */
449             if( only_keyblocks && i != 1 && i != 5 && i != 6 )
450                 break; /* not a keyblock armor */
451
452             /* found the begin line */
453             hdr_line = i;
454             state = fhdrWAITHeader;
455             *not_dashed = 0;
456             if( hdr_line == BEGIN_SIGNED_MSG_IDX )
457                 clearsig = 1;
458             if( opt.verbose > 1 )
459                 log_info(_("armor: %s\n"), head_strings[hdr_line]);
460             break;
461
462           case fhdrCLEARSIGSimple:
463             /* we are at the begin of a new line */
464           case fhdrCLEARSIGSimpleNext:
465             n = 0;
466             c = 0;
467             while( n < buflen && (c=iobuf_get(a)) != -1 ) {
468                 buf[n++] = c;
469                 if( c == '\n' )
470                     break;
471             }
472             buf[n] = 0;
473             if( c == -1 )
474                 state = fhdrEOF;
475             else if( state == fhdrCLEARSIGSimple
476                      && n > 15 && !memcmp(buf, "-----", 5 ) ) {
477                 if( c == '\n' )
478                     buf[n-1] = 0;
479                 state = fhdrENDClearsig;
480             }
481             else if( c == '\n' )
482                 state = fhdrCLEARSIGSimple;
483             else
484                 state = fhdrCLEARSIGSimpleNext;
485             break;
486
487           case fhdrCLEARSIG:
488           case fhdrEMPTYClearsig:
489           case fhdrREADClearsig:
490             /* we are at the start of a line: read a clearsig into the buffer
491              * we have to look for a header line or dashed escaped text*/
492             n = 0;
493             c = 0;
494             while( n < buflen && (c=iobuf_get(a)) != -1 && c != '\n' )
495                 buf[n++] = c;
496             buf[n] = 0;
497             if( c == -1 )
498                 state = fhdrEOF;
499             else if( !n || ( buf[0]=='\r' && !buf[1] ) ) {
500                 state = fhdrEMPTYClearsig;
501                 empty++;
502             }
503             else if( c == '\n' )
504                 state = fhdrCHECKClearsig2;
505             else
506                 state = fhdrCHECKClearsig;
507             break;
508
509           case fhdrCHECKDashEscaped3:
510             if( *not_dashed ) {
511                 state = fhdrTEXTSimple;
512                 break;
513             }
514             if( !(n > 1 && buf[0] == '-' && buf[1] == ' ' ) ) {
515                 state = fhdrTEXT;
516                 break;
517             }
518             /* fall through */
519           case fhdrCHECKDashEscaped2:
520           case fhdrCHECKDashEscaped:
521             /* check dash escaped line */
522             if( buf[2] == '-' || ( n > 6 && !memcmp(buf+2, "From ", 5))) {
523                 for(i=2; i < n; i++ )
524                     buf[i-2] = buf[i];
525                 n -= 2;
526                 buf[n] = 0; /* not really needed */
527                 state = state == fhdrCHECKDashEscaped3 ? fhdrTEXT :
528                         state == fhdrCHECKDashEscaped2 ?
529                                  fhdrREADClearsig : fhdrTESTSpaces;
530             }
531             else {
532                 log_error(_("invalid dash escaped line: "));
533                 print_string( stderr, buf, n, 0 );
534                 putc('\n', stderr);
535                 state = fhdrERROR;
536             }
537             break;
538
539           case fhdrCHECKClearsig:
540             /* check the clearsig line */
541             if( n > 15 && !memcmp(buf, "-----", 5 ) )
542                 state = fhdrENDClearsig;
543             else if( buf[0] == '-' && buf[1] == ' ' && !*not_dashed )
544                 state = fhdrCHECKDashEscaped;
545             else {
546                 state = fhdrTESTSpaces;
547             }
548             break;
549
550           case fhdrCHECKClearsig2:
551             /* check the clearsig line */
552             if( n > 15 && !memcmp(buf, "-----", 5 ) )
553                 state = fhdrENDClearsig;
554             else if( buf[0] == '-' && buf[1] == ' ' && !*not_dashed )
555                 state = fhdrCHECKDashEscaped2;
556             else {
557                 state = fhdrREADClearsig;
558             }
559             break;
560
561           case fhdrREADClearsigNext:
562             /* Read to the end of the line, do not care about checking
563              * for dashed escaped text of headers */
564             c = 0;
565             n = 0;
566             while( n < buflen && (c=iobuf_get(a)) != -1 && c != '\n' )
567                 buf[n++] = c;
568             buf[n] = 0;
569             if( c == -1 )
570                 state = fhdrEOF;
571             else if( c == '\n' )
572                 state = fhdrREADClearsig;
573             else
574                 state = fhdrTESTSpaces;
575             break;
576
577           case fhdrTESTSpaces: {
578             /* but must check whether the rest of the line
579              * only contains white spaces; this is problematic
580              * since we may have to restore the stuff.  simply
581              * counting spaces is not enough, because it may be a
582              * mix of different white space characters */
583             IOBUF b = iobuf_temp();
584             while( (c=iobuf_get(a)) != -1 && c != '\n' ) {
585                 iobuf_put(b,c);
586                 if( c != ' ' && c != '\t' && c != '\r' )
587                     break;
588             }
589             if( c == '\n' ) {
590                 /* okay we can skip the rest of the line */
591                 iobuf_close(b);
592                 state = fhdrREADClearsig;
593             }
594             else {
595                 iobuf_unget_and_close_temp(a,b);
596                 state = fhdrREADClearsigNext;
597             }
598           } break;
599
600           case fhdrERRORShow:
601             log_error(_("invalid clear text header: "));
602             print_string( stderr, buf, n, 0 );
603             putc('\n', stderr);
604             state = fhdrERROR;
605             break;
606
607           default: BUG();
608         }
609         switch( state ) {
610           case fhdrINIT:
611           case fhdrINITCont:
612           case fhdrINITSkip:
613           case fhdrCHECKBegin:
614           case fhdrWAITHeader:
615           case fhdrWAITClearsig:
616           case fhdrSKIPHeader:
617           case fhdrEMPTYClearsig:
618           case fhdrCHECKClearsig:
619           case fhdrCHECKClearsig2:
620           case fhdrCHECKDashEscaped:
621           case fhdrCHECKDashEscaped2:
622           case fhdrCHECKDashEscaped3:
623           case fhdrTESTSpaces:
624           case fhdrERRORShow:
625             cont = 1;
626             break;
627           default: cont = 0;
628         }
629     } while( cont );
630
631     if( clearsig && state == fhdrTEXT ) {
632         state = fhdrCLEARSIG;
633     }
634     else if( clearsig && state == fhdrTEXTSimple ) {
635         state = fhdrCLEARSIGSimple;
636         buf[n] = '\n';
637         n++;
638     }
639
640     if( state == fhdrCLEARSIG || state == fhdrREADClearsig ) {
641         /* append CR,LF after removing trailing wspaces */
642         for(p=buf+n-1; n; n--, p-- ) {
643             assert( *p != '\n' );
644             if( *p != ' ' && *p != '\t' && *p != '\r' ) {
645                 p[1] = '\r';
646                 p[2] = '\n';
647                 n += 2;
648                 break;
649             }
650         }
651         if( !n ) {
652             buf[0] = '\r';
653             buf[1] = '\n';
654             n = 2;
655         }
656     }
657
658   fprintf(stderr,"ARMOR READ (state=%d): %.*s", state, n, buf );
659
660     *r_buflen = n;
661     *r_empty = empty;
662     return state;
663 }
664 #endif
665
666
667 static unsigned
668 trim_trailing_spaces( byte *line, unsigned len )
669 {
670     byte *p, *mark;
671     unsigned n;
672
673     for(mark=NULL, p=line, n=0; n < len; n++, p++ ) {
674         if( strchr(" \t\r\n", *p ) ) {
675             if( !mark )
676                 mark = p;
677         }
678         else
679             mark = NULL;
680     }
681
682     if( mark ) {
683         *mark = 0;
684         return mark - line;
685     }
686     return len;
687 }
688
689
690
691 /****************
692  * Check whether this is a armor line.
693  * returns: -1 if it is not a armor header or the index number of the
694  * armor header.
695  */
696 static int
697 is_armor_header( byte *line, unsigned len )
698 {
699     const char *s;
700     byte *save_p, *p;
701     int save_c;
702     int i;
703
704     if( len < 15 )
705         return -1; /* too short */
706     if( memcmp( line, "-----", 5 ) )
707         return -1; /* no */
708     p = strstr( line+5, "-----");
709     if( !p )
710         return -1;
711     save_p = p;
712     p += 5;
713     if( *p == '\r' )
714         p++;
715     if( *p == '\n' )
716         p++;
717     if( *p )
718         return -1; /* garbage after dashes */
719     save_c = *save_p; *save_p = 0;
720     p = line+5;
721     for(i=0; (s=head_strings[i]); i++ )
722         if( !strcmp(s, p) )
723             break;
724     *save_p = save_c;
725     if( !s )
726         return -1; /* unknown armor line */
727
728     if( opt.verbose > 1 )
729         log_info(_("armor: %s\n"), head_strings[i]);
730     return i;
731 }
732
733
734
735 /****************
736  * Parse a header lines
737  * Return 0: Empty line (end of header lines)
738  *       -1: invalid header line
739  *       >0: Good header line
740  */
741 static int
742 parse_header_line( armor_filter_context_t *afx, byte *line, unsigned len )
743 {
744     byte *p;
745     int hashes=0;
746
747     if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
748         return 0; /* empty line */
749     len = trim_trailing_spaces( line, len );
750     p = strchr( line, ':');
751     if( !p || !p[1] ) {
752         log_error(_("invalid armor header: "));
753         print_string( stderr, line, len, 0 );
754         putc('\n', stderr);
755         return -1;
756     }
757
758     if( opt.verbose ) {
759         log_info(_("armor header: "));
760         print_string( stderr, line, len, 0 );
761         putc('\n', stderr);
762     }
763
764     if( afx->in_cleartext ) {
765         if( (hashes=parse_hash_header( line )) )
766             afx->hashes |= hashes;
767         else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
768             afx->not_dash_escaped = 1;
769         else {
770             log_error(_("invalid clearsig header\n"));
771             return -1;
772         }
773     }
774     return 1;
775 }
776
777
778
779 /* figure out whether the data is armored or not */
780 static int
781 check_input( armor_filter_context_t *afx, IOBUF a )
782 {
783     int rc = 0;
784     int i;
785     size_t n;
786     unsigned emplines;
787     byte *line;
788     unsigned len;
789     unsigned maxlen;
790     int hdr_line = -1;
791
792     /* read the first line to see whether this is armored data */
793     maxlen = MAX_LINELEN;
794     len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
795                                              &afx->buffer_size, &maxlen );
796     line = afx->buffer;
797     if( !maxlen ) {
798         /* line has been truncated: assume not armored */
799         afx->inp_checked = 1;
800         afx->inp_bypass = 1;
801         return 0;
802     }
803
804     if( !len ) {
805         return -1; /* eof */
806     }
807
808     /* (the line is always a C string but maybe longer) */
809     if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
810         ;
811     else if( !is_armored( line ) ) {
812         afx->inp_checked = 1;
813         afx->inp_bypass = 1;
814         return 0;
815     }
816
817     /* find the armor header */
818     while(len) {
819         i = is_armor_header( line, len );
820         if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
821             hdr_line = i;
822             if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
823                 if( afx->in_cleartext ) {
824                     log_error(_("nested clear text signatures\n"));
825                     rc = G10ERR_INVALID_ARMOR;
826                 }
827                 afx->in_cleartext = 1;
828             }
829             break;
830         }
831         /* read the next line (skip all truncated lines) */
832         do {
833             maxlen = MAX_LINELEN;
834             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
835                                                &afx->buffer_size, &maxlen );
836             line = afx->buffer;
837             len = afx->buffer_len;
838         } while( !maxlen );
839     }
840
841     /* parse the header lines */
842     while(len) {
843         /* read the next line (skip all truncated lines) */
844         do {
845             maxlen = MAX_LINELEN;
846             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
847                                                &afx->buffer_size, &maxlen );
848             line = afx->buffer;
849             len = afx->buffer_len;
850         } while( !maxlen );
851
852         i = parse_header_line( afx, line, len );
853         if( i <= 0 ) {
854             if( i )
855                 rc = G10ERR_INVALID_ARMOR;
856             break;
857         }
858     }
859
860
861     if( rc )
862         invalid_armor();
863     else if( afx->in_cleartext ) {
864         afx->faked = 1;
865     }
866     else {
867         afx->inp_checked = 1;
868         afx->crc = CRCINIT;
869         afx->idx = 0;
870         afx->radbuf[0] = 0;
871     }
872
873     return rc;
874 }
875
876
877
878 /****************
879  * Fake a literal data packet and wait for the next armor line
880  * fixme: empty line handling and null length clear text signature are
881  *        not implemented/checked.
882  */
883 static int
884 fake_packet( armor_filter_context_t *afx, IOBUF a,
885              size_t *retn, byte *buf, size_t size  )
886 {
887     int rc = 0;
888     size_t len = 0;
889     unsigned emplines = afx->empty;
890     int lastline = 0;
891     unsigned maxlen, n;
892     byte *p;
893
894     len = 2;    /* reserve 2 bytes for the length header */
895     size -= 3;  /* and 1 for empline handling and 2 for the term header */
896                 /* or the appended CR,LF */
897     while( !rc && len < size ) {
898         if( emplines ) {
899             while( emplines && len < size ) {
900                 buf[len++] = '\r';
901                 buf[len++] = '\n';
902                 emplines--;
903             }
904             continue;
905         }
906
907         if( afx->faked == 1 )
908             afx->faked++;  /* skip the first (empty) line */
909         else {
910             while( len < size && afx->buffer_pos < afx->buffer_len )
911                 buf[len++] = afx->buffer[afx->buffer_pos++];
912             buf[len++] = '\r';
913             buf[len++] = '\n';
914             if( len >= size )
915                 continue;
916         }
917
918         /* read the next line */
919         maxlen = MAX_LINELEN;
920         afx->buffer_pos = 0;
921         afx->buffer_len = iobuf_read_line( a, &afx->buffer,
922                                            &afx->buffer_size, &maxlen );
923         if( !afx->buffer_len ) {
924             rc = -1; /* eof */
925             continue;
926         }
927         if( !maxlen )
928             afx->truncated++;
929         afx->buffer_len = trim_trailing_spaces( afx->buffer, afx->buffer_len );
930         p = afx->buffer;
931         n = afx->buffer_len;
932
933         if( n > 2 && *p == '-' ) {
934             /* check for dash escaped or armor header */
935             if( p[1] == ' ' && !afx->not_dash_escaped ) {
936                 /* issue a warning if it is not regular encoded */
937                 if( p[2] != '-' && !( n > 6 && !memcmp(p+2, "From ", 5))) {
938                     log_info(_("invalid dash escaped line: "));
939                     print_string( stderr, p, n, 0 );
940                     putc('\n', stderr);
941                 }
942                 afx->buffer_pos = 2; /* skip */
943             }
944             else if( n >= 15 &&  p[1] == '-' && p[2] == '-' && p[3] == '-' ) {
945                 if( is_armor_header( p, n ) != BEGIN_SIGNATURE ) {
946                     log_info(_("unexpected armor:"));
947                     print_string( stderr, p, n, 0 );
948                     putc('\n', stderr);
949                 }
950                 lastline = 1;
951                 assert( len >= 4 );
952                 len -= 2; /* remove the last CR,LF */
953                 rc = -1;
954             }
955         }
956     }
957
958     buf[0] = (len-2) >> 8;
959     buf[1] = (len-2);
960     if( lastline ) { /* write last (ending) length header */
961         if( buf[0] && buf[1] ) { /* only if we have some text */
962             buf[len++] = 0;
963             buf[len++] = 0;
964         }
965         rc = 0;
966         afx->faked = 0;
967         afx->in_cleartext = 0;
968         /* and now read the header lines */
969         afx->buffer_pos = 0;
970         for(;;) {
971             int i;
972
973             /* read the next line (skip all truncated lines) */
974             do {
975                 maxlen = MAX_LINELEN;
976                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
977                                                  &afx->buffer_size, &maxlen );
978             } while( !maxlen );
979             p = afx->buffer;
980             n = afx->buffer_len;
981             if( !n ) {
982                 rc = -1;
983                 break; /* eof */
984             }
985             i = parse_header_line( afx, p , n );
986             if( i <= 0 ) {
987                 if( i )
988                     invalid_armor();
989                 break;
990             }
991         }
992         afx->inp_checked = 1;
993         afx->crc = CRCINIT;
994         afx->idx = 0;
995         afx->radbuf[0] = 0;
996     }
997
998     afx->empty = emplines;
999     *retn = len;
1000     return rc;
1001 }
1002
1003
1004
1005 static int
1006 radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
1007               byte *buf, size_t size )
1008 {
1009     byte val;
1010     int c, c2;
1011     int checkcrc=0;
1012     int rc = 0;
1013     size_t n = 0;
1014     int  idx, i;
1015     u32 crc;
1016
1017     crc = afx->crc;
1018     idx = afx->idx;
1019     val = afx->radbuf[0];
1020     for( n=0; n < size; ) {
1021         if( (c=iobuf_get(a)) == -1 )
1022             break;
1023         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
1024             continue;
1025         else if( c == '=' ) { /* pad character: stop */
1026             if( idx == 1 )
1027                 buf[n++] = val;
1028             checkcrc++;
1029             break;
1030         }
1031         else if( (c = asctobin[(c2=c)]) == 255 ) {
1032             log_error(_("invalid radix64 character %02x skipped\n"), c2);
1033             continue;
1034         }
1035         switch(idx) {
1036           case 0: val =  c << 2; break;
1037           case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break;
1038           case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break;
1039           case 3: val |= c&0x3f; buf[n++] = val; break;
1040         }
1041         idx = (idx+1) % 4;
1042     }
1043     for(i=0; i < n; i++ )
1044         crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
1045     crc &= 0x00ffffff;
1046     afx->crc = crc;
1047     afx->idx = idx;
1048     afx->radbuf[0] = val;
1049     if( checkcrc ) {
1050         afx->any_data = 1;
1051         afx->inp_checked=0;
1052         afx->faked = 0;
1053         for(;;) { /* skip lf and pad characters */
1054             if( (c=iobuf_get(a)) == -1 )
1055                 break;
1056             if( c == '\n' || c == ' ' || c == '\r'
1057                 || c == '\t' || c == '=' )
1058                 continue;
1059             break;
1060         }
1061         if( c == -1 )
1062             log_error(_("premature eof (no CRC)\n"));
1063         else {
1064             u32 mycrc = 0;
1065             idx = 0;
1066             do {
1067                 if( (c = asctobin[c]) == 255 )
1068                     break;
1069                 switch(idx) {
1070                   case 0: val =  c << 2; break;
1071                   case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break;
1072                   case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break;
1073                   case 3: val |= c&0x3f; mycrc |= val; break;
1074                 }
1075                 if( (c=iobuf_get(a)) == -1 )
1076                     break;
1077             } while( ++idx < 4 );
1078             if( c == -1 ) {
1079                 log_error(_("premature eof (in CRC)\n"));
1080                 rc = G10ERR_INVALID_ARMOR;
1081             }
1082             else if( idx != 4 ) {
1083                 log_error(_("malformed CRC\n"));
1084                 rc = G10ERR_INVALID_ARMOR;
1085             }
1086             else if( mycrc != afx->crc ) {
1087                 log_error(_("CRC error; %06lx - %06lx\n"),
1088                                     (ulong)afx->crc, (ulong)mycrc);
1089                 rc = G10ERR_INVALID_ARMOR;
1090             }
1091             else {
1092                 rc = 0;
1093               #if 0
1094                 for(rc=0;!rc;) {
1095                     rc = 0 /*check_trailer( &fhdr, c )*/;
1096                     if( !rc ) {
1097                         if( (c=iobuf_get(a)) == -1 )
1098                             rc = 2;
1099                     }
1100                 }
1101                 if( rc == -1 )
1102                     rc = 0;
1103                 else if( rc == 2 ) {
1104                     log_error(_("premature eof (in Trailer)\n"));
1105                     rc = G10ERR_INVALID_ARMOR;
1106                 }
1107                 else {
1108                     log_error(_("error in trailer line\n"));
1109                     rc = G10ERR_INVALID_ARMOR;
1110                 }
1111               #endif
1112             }
1113         }
1114     }
1115
1116     if( !n )
1117         rc = -1;
1118
1119     *retn = n;
1120     return rc;
1121 }
1122
1123 /****************
1124  * This filter is used to handle the armor stuff
1125  */
1126 int
1127 armor_filter( void *opaque, int control,
1128              IOBUF a, byte *buf, size_t *ret_len)
1129 {
1130     size_t size = *ret_len;
1131     armor_filter_context_t *afx = opaque;
1132     int rc=0, i, c;
1133     byte radbuf[3];
1134     int  idx, idx2;
1135     size_t n=0;
1136     u32 crc;
1137   #if 1
1138     static FILE *fp ;
1139
1140     if( !fp ) {
1141         fp = fopen("armor.out", "w");
1142         assert(fp);
1143     }
1144   #endif
1145
1146     if( DBG_FILTER )
1147         log_debug("armor-filter: control: %d\n", control );
1148     if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
1149         n = 0;
1150         if( afx->buffer_len ) {
1151             for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
1152                 buf[n++] = afx->buffer[afx->buffer_pos++];
1153             if( afx->buffer_pos >= afx->buffer_len )
1154                 afx->buffer_len = 0;
1155         }
1156         for(; n < size; n++ ) {
1157             if( (c=iobuf_get(a)) == -1 )
1158                 break;
1159             buf[n] = c & 0xff;
1160         }
1161         if( !n )
1162             rc = -1;
1163         *ret_len = n;
1164     }
1165     else if( control == IOBUFCTRL_UNDERFLOW ) {
1166         if( size < 15+(4*15) )  /* need space for up to 4 onepass_sigs */
1167             BUG(); /* supplied buffer too short */
1168
1169         if( afx->faked )
1170             rc = fake_packet( afx, a, &n, buf, size );
1171         else if( !afx->inp_checked ) {
1172             rc = check_input( afx, a );
1173             if( afx->inp_bypass ) {
1174                 for(n=0; n < size && afx->buffer_pos < afx->buffer_len; n++ )
1175                     buf[n++] = afx->buffer[afx->buffer_pos++];
1176                 if( afx->buffer_pos >= afx->buffer_len )
1177                     afx->buffer_len = 0;
1178                 if( !n )
1179                     rc = -1;
1180             }
1181             else if( afx->faked ) {
1182                 unsigned hashes = afx->hashes;
1183                 /* the buffer is at least 15+n*15 bytes long, so it
1184                  * is easy to construct the packets */
1185
1186                 hashes &= 1|2|4|8;
1187                 if( !hashes )
1188                     hashes |= 4;  /* default to MD 5 */
1189                 n=0;
1190                 do {
1191                     /* first some onepass signature packets */
1192                     buf[n++] = 0x90; /* old format, type 4, 1 length byte */
1193                     buf[n++] = 13;   /* length */
1194                     buf[n++] = 3;    /* version */
1195                     buf[n++] = 0x01; /* sigclass 0x01 (canonical text mode)*/
1196                     if( hashes & 1 ) {
1197                         hashes &= ~1;
1198                         buf[n++] = DIGEST_ALGO_RMD160;
1199                     }
1200                     else if( hashes & 2 ) {
1201                         hashes &= ~2;
1202                         buf[n++] = DIGEST_ALGO_SHA1;
1203                     }
1204                     else if( hashes & 4 ) {
1205                         hashes &= ~4;
1206                         buf[n++] = DIGEST_ALGO_MD5;
1207                     }
1208                     else if( hashes & 8 ) {
1209                         hashes &= ~8;
1210                         buf[n++] = DIGEST_ALGO_TIGER;
1211                     }
1212                     else
1213                         buf[n++] = 0;    /* (don't know) */
1214
1215                     buf[n++] = 0;    /* public key algo (don't know) */
1216                     memset(buf+n, 0, 8); /* don't know the keyid */
1217                     n += 8;
1218                     buf[n++] = !hashes;   /* last one */
1219                 } while( hashes );
1220
1221                 /* followed by a plaintext packet */
1222                 buf[n++] = 0xaf; /* old packet format, type 11, var length */
1223                 buf[n++] = 0;    /* set the length header */
1224                 buf[n++] = 6;
1225                 buf[n++] = 't';  /* canonical text mode */
1226                 buf[n++] = 0;    /* namelength */
1227                 memset(buf+n, 0, 4); /* timestamp */
1228                 n += 4;
1229             }
1230             else if( !rc )
1231                 rc = radix64_read( afx, a, &n, buf, size );
1232         }
1233         else
1234             rc = radix64_read( afx, a, &n, buf, size );
1235       #if 1
1236         if( n )
1237             if( fwrite(buf, n, 1, fp ) != 1 )
1238                 BUG();
1239       #endif
1240         *ret_len = n;
1241     }
1242     else if( control == IOBUFCTRL_FLUSH ) {
1243         if( !afx->status ) { /* write the header line */
1244             if( afx->what >= DIM(head_strings) )
1245                 log_bug("afx->what=%d", afx->what);
1246             iobuf_writestr(a, "-----");
1247             iobuf_writestr(a, head_strings[afx->what] );
1248             iobuf_writestr(a, "-----\n");
1249             iobuf_writestr(a, "Version: GnuPG v"  VERSION " ("
1250                                             PRINTABLE_OS_NAME ")\n");
1251
1252             if( opt.comment_string ) {
1253                 const char *s = opt.comment_string;
1254                 iobuf_writestr(a, "Comment: " );
1255                 for( ; *s; s++ ) {
1256                     if( *s == '\n' )
1257                         iobuf_writestr(a, "\\n" );
1258                     else if( *s == '\r' )
1259                         iobuf_writestr(a, "\\r" );
1260                     else if( *s == '\v' )
1261                         iobuf_writestr(a, "\\v" );
1262                     else
1263                         iobuf_put(a, *s );
1264                 }
1265                 iobuf_put(a, '\n' );
1266             }
1267             else
1268                 iobuf_writestr(a,
1269                     "Comment: For info see http://www.gnupg.org\n");
1270             if( afx->hdrlines )
1271                 iobuf_writestr(a, afx->hdrlines);
1272             iobuf_put(a, '\n');
1273             afx->status++;
1274             afx->idx = 0;
1275             afx->idx2 = 0;
1276             afx->crc = CRCINIT;
1277         }
1278         crc = afx->crc;
1279         idx = afx->idx;
1280         idx2 = afx->idx2;
1281         for(i=0; i < idx; i++ )
1282             radbuf[i] = afx->radbuf[i];
1283
1284         for(i=0; i < size; i++ )
1285             crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
1286         crc &= 0x00ffffff;
1287
1288         for( ; size; buf++, size-- ) {
1289             radbuf[idx++] = *buf;
1290             if( idx > 2 ) {
1291                 idx = 0;
1292                 c = bintoasc[(*radbuf >> 2) & 077];
1293                 iobuf_put(a, c);
1294                 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1295                 iobuf_put(a, c);
1296                 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1297                 iobuf_put(a, c);
1298                 c = bintoasc[radbuf[2]&077];
1299                 iobuf_put(a, c);
1300                 if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
1301                     iobuf_put(a, '\n');
1302                     idx2=0;
1303                 }
1304             }
1305         }
1306         for(i=0; i < idx; i++ )
1307             afx->radbuf[i] = radbuf[i];
1308         afx->idx = idx;
1309         afx->idx2 = idx2;
1310         afx->crc  = crc;
1311     }
1312     else if( control == IOBUFCTRL_INIT ) {
1313         if( !is_initialized )
1314             initialize();
1315     }
1316     else if( control == IOBUFCTRL_FREE ) {
1317         if( afx->status ) { /* pad, write cecksum, and bottom line */
1318             crc = afx->crc;
1319             idx = afx->idx;
1320             idx2 = afx->idx2;
1321             for(i=0; i < idx; i++ )
1322                 radbuf[i] = afx->radbuf[i];
1323             if( idx ) {
1324                 c = bintoasc[(*radbuf>>2)&077];
1325                 iobuf_put(a, c);
1326                 if( idx == 1 ) {
1327                     c = bintoasc[((*radbuf << 4) & 060) & 077];
1328                     iobuf_put(a, c);
1329                     iobuf_put(a, '=');
1330                     iobuf_put(a, '=');
1331                 }
1332                 else { /* 2 */
1333                     c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
1334                     iobuf_put(a, c);
1335                     c = bintoasc[((radbuf[1] << 2) & 074) & 077];
1336                     iobuf_put(a, c);
1337                     iobuf_put(a, '=');
1338                 }
1339                 if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
1340                     iobuf_put(a, '\n');
1341                     idx2=0;
1342                 }
1343             }
1344             /* may need a linefeed */
1345             if( idx2 )
1346                 iobuf_put(a, '\n');
1347             /* write the CRC */
1348             iobuf_put(a, '=');
1349             radbuf[0] = crc >>16;
1350             radbuf[1] = crc >> 8;
1351             radbuf[2] = crc;
1352             c = bintoasc[(*radbuf >> 2) & 077];
1353             iobuf_put(a, c);
1354             c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1355             iobuf_put(a, c);
1356             c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1357             iobuf_put(a, c);
1358             c = bintoasc[radbuf[2]&077];
1359             iobuf_put(a, c);
1360             iobuf_put(a, '\n');
1361             /* and the the trailer */
1362             if( afx->what >= DIM(tail_strings) )
1363                 log_bug("afx->what=%d", afx->what);
1364             iobuf_writestr(a, "-----");
1365             iobuf_writestr(a, tail_strings[afx->what] );
1366             iobuf_writestr(a, "-----\n");
1367         }
1368         else if( !afx->any_data && !afx->inp_bypass )
1369             log_error(_("no valid OpenPGP data found.\n"));
1370         m_free( afx->buffer );
1371         afx->buffer = NULL;
1372     }
1373     else if( control == IOBUFCTRL_DESC )
1374         *(char**)buf = "armor_filter";
1375     return rc;
1376 }
1377
1378
1379