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