* call-agent.c (start_agent): Make copies of old locales and check
[gnupg.git] / g10 / armor.c
1 /* armor.c - Armor flter
2  *      Copyright (C) 1998, 1999, 2000 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 #include <ctype.h>
28
29 #include "errors.h"
30 #include "iobuf.h"
31 #include <gcrypt.h>
32 #include "util.h"
33 #include "filter.h"
34 #include "packet.h"
35 #include "options.h"
36 #include "main.h"
37 #include "status.h"
38 #include "i18n.h"
39
40 #ifdef HAVE_DOSISH_SYSTEM
41   #define LF "\r\n"
42 #else
43   #define LF "\n"
44 #endif
45
46 #define MAX_LINELEN 20000
47
48 #define CRCINIT 0xB704CE
49 #define CRCPOLY 0X864CFB
50 #define CRCUPDATE(a,c) do {                                                 \
51                         a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \
52                         a &= 0x00ffffff;                                    \
53                     } while(0)
54 static u32 crc_table[256];
55 static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
56                          "abcdefghijklmnopqrstuvwxyz"
57                          "0123456789+/";
58 static byte asctobin[256]; /* runtime initialized */
59 static int is_initialized;
60
61
62 typedef enum {
63     fhdrHASArmor = 0,
64     fhdrNOArmor,
65     fhdrINIT,
66     fhdrINITCont,
67     fhdrINITSkip,
68     fhdrCHECKBegin,
69     fhdrWAITHeader,
70     fhdrWAITClearsig,
71     fhdrSKIPHeader,
72     fhdrCLEARSIG,
73     fhdrREADClearsig,
74     fhdrNullClearsig,
75     fhdrEMPTYClearsig,
76     fhdrCHECKClearsig,
77     fhdrCHECKClearsig2,
78     fhdrCHECKDashEscaped,
79     fhdrCHECKDashEscaped2,
80     fhdrCHECKDashEscaped3,
81     fhdrREADClearsigNext,
82     fhdrENDClearsig,
83     fhdrENDClearsigHelp,
84     fhdrTESTSpaces,
85     fhdrCLEARSIGSimple,
86     fhdrCLEARSIGSimpleNext,
87     fhdrTEXT,
88     fhdrTEXTSimple,
89     fhdrERROR,
90     fhdrERRORShow,
91     fhdrEOF
92 } fhdr_state_t;
93
94
95 /* if we encounter this armor string with this index, go
96  * into a mode which fakes packets and wait for the next armor */
97 #define BEGIN_SIGNATURE 2
98 #define BEGIN_SIGNED_MSG_IDX 3
99 static char *head_strings[] = {
100     "BEGIN PGP MESSAGE",
101     "BEGIN PGP PUBLIC KEY BLOCK",
102     "BEGIN PGP SIGNATURE",
103     "BEGIN PGP SIGNED MESSAGE",
104     "BEGIN PGP ARMORED FILE",       /* gnupg extension */
105     "BEGIN PGP PRIVATE KEY BLOCK",
106     "BEGIN PGP SECRET KEY BLOCK",   /* only used by pgp2 */
107     NULL
108 };
109 static char *tail_strings[] = {
110     "END PGP MESSAGE",
111     "END PGP PUBLIC KEY BLOCK",
112     "END PGP SIGNATURE",
113     "END dummy",
114     "END PGP ARMORED FILE",
115     "END PGP PRIVATE KEY BLOCK",
116     "END PGP SECRET KEY BLOCK",
117     NULL
118 };
119
120
121
122 static void
123 initialize(void)
124 {
125     int i, j;
126     u32 t;
127     byte *s;
128
129     /* init the crc lookup table */
130     crc_table[0] = 0;
131     for(i=j=0; j < 128; j++ ) {
132         t = crc_table[j];
133         if( t & 0x00800000 ) {
134             t <<= 1;
135             crc_table[i++] = t ^ CRCPOLY;
136             crc_table[i++] = t;
137         }
138         else {
139             t <<= 1;
140             crc_table[i++] = t;
141             crc_table[i++] = t ^ CRCPOLY;
142         }
143     }
144     /* build the helptable for radix64 to bin conversion */
145     for(i=0; i < 256; i++ )
146         asctobin[i] = 255; /* used to detect invalid characters */
147     for(s=bintoasc,i=0; *s; s++,i++ )
148         asctobin[*s] = i;
149
150     is_initialized=1;
151 }
152
153 /****************
154  * Check whether this is an armored file or not
155  * See also parse-packet.c for details on this code
156  * Returns: True if it seems to be armored
157  */
158 static int
159 is_armored( const byte *buf )
160 {
161     int ctb, pkttype;
162
163     ctb = *buf;
164     if( !(ctb & 0x80) )
165         return 1; /* invalid packet: assume it is armored */
166     pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
167     switch( pkttype ) {
168       case PKT_MARKER:
169       case PKT_SYMKEY_ENC:
170       case PKT_ONEPASS_SIG:
171       case PKT_PUBLIC_KEY:
172       case PKT_SECRET_KEY:
173       case PKT_PUBKEY_ENC:
174       case PKT_SIGNATURE:
175       case PKT_COMMENT:
176       case PKT_OLD_COMMENT:
177       case PKT_PLAINTEXT:
178       case PKT_COMPRESSED:
179       case PKT_ENCRYPTED:
180         return 0; /* seems to be a regular packet: not armored */
181     }
182
183     return 1;
184 }
185
186
187 /****************
188  * Try to check whether the iobuf is armored
189  * Returns true if this may be the case; the caller should use the
190  *         filter to do further processing.
191  */
192 int
193 use_armor_filter( IOBUF a )
194 {
195     byte buf[1];
196     int n;
197
198     n = iobuf_peek(a, buf, 1 );
199     if( n == -1 )
200         return 0; /* EOF, doesn't matter whether armored or not */
201     if( !n )
202         return 1; /* can't check it: try armored */
203     return is_armored(buf);
204 }
205
206
207
208
209 static void
210 invalid_armor(void)
211 {
212     write_status(STATUS_BADARMOR);
213     gpg_exit(1); /* stop here */
214 }
215
216
217 /****************
218  * check whether the armor header is valid on a signed message.
219  * this is for security reasons: the header lines are not included in the
220  * hash and by using some creative formatting rules, Mallory could fake
221  * any text at the beginning of a document; assuming it is read with
222  * a simple viewer. We only allow the Hash Header.
223  */
224 static int
225 parse_hash_header( const char *line )
226 {
227     const char *s, *s2;
228     unsigned found = 0;
229
230     if( strlen(line) < 6  || strlen(line) > 60 )
231         return 0; /* too short or too long */
232     if( memcmp( line, "Hash:", 5 ) )
233         return 0; /* invalid header */
234     s = line+5;
235     for(s=line+5;;s=s2) {
236         for(; *s && (*s==' ' || *s == '\t'); s++ )
237             ;
238         if( !*s )
239             break;
240         for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
241             ;
242         if( !strncmp( s, "RIPEMD160", s2-s ) )
243             found |= 1;
244         else if( !strncmp( s, "SHA1", s2-s ) )
245             found |= 2;
246         else if( !strncmp( s, "MD5", s2-s ) )
247             found |= 4;
248         else if( !strncmp( s, "TIGER", s2-s ) )
249             found |= 8;
250         else
251             return 0;
252         for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
253             ;
254         if( *s2 && *s2 != ',' )
255             return 0;
256         if( *s2 )
257             s2++;
258     }
259     return found;
260 }
261
262
263
264 /****************
265  * Check whether this is a armor line.
266  * returns: -1 if it is not a armor header or the index number of the
267  * armor header.
268  */
269 static int
270 is_armor_header( byte *line, unsigned len )
271 {
272     const char *s;
273     byte *save_p, *p;
274     int save_c;
275     int i;
276
277     if( len < 15 )
278         return -1; /* too short */
279     if( memcmp( line, "-----", 5 ) )
280         return -1; /* no */
281     p = strstr( line+5, "-----");
282     if( !p )
283         return -1;
284     save_p = p;
285     p += 5;
286     if( *p == '\r' )
287         p++;
288     if( *p == '\n' )
289         p++;
290     if( *p )
291         return -1; /* garbage after dashes */
292     save_c = *save_p; *save_p = 0;
293     p = line+5;
294     for(i=0; (s=head_strings[i]); i++ )
295         if( !strcmp(s, p) )
296             break;
297     *save_p = save_c;
298     if( !s )
299         return -1; /* unknown armor line */
300
301     if( opt.verbose > 1 )
302         log_info(_("armor: %s\n"), head_strings[i]);
303     return i;
304 }
305
306
307
308 /****************
309  * Parse a header lines
310  * Return 0: Empty line (end of header lines)
311  *       -1: invalid header line
312  *       >0: Good header line
313  */
314 static int
315 parse_header_line( armor_filter_context_t *afx, byte *line, unsigned len )
316 {
317     byte *p;
318     int hashes=0;
319
320     /* fixme: why this double check?  I think the original code w/o the
321      * second check for an empty line was done from an early draft of
322      * of OpenPGP - or simply very stupid code */
323     if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
324         return 0; /* empty line */
325     len = trim_trailing_ws( line, len );
326     if( !len )
327         return 0; /* WS only same as empty line */
328
329     p = strchr( line, ':');
330     if( !p || !p[1] ) {
331         log_error(_("invalid armor header: "));
332         print_string( stderr, line, len, 0 );
333         putc('\n', stderr);
334         return -1;
335     }
336
337     if( opt.verbose ) {
338         log_info(_("armor header: "));
339         print_string( stderr, line, len, 0 );
340         putc('\n', stderr);
341     }
342
343     if( afx->in_cleartext ) {
344         if( (hashes=parse_hash_header( line )) )
345             afx->hashes |= hashes;
346         else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
347             afx->not_dash_escaped = 1;
348         else {
349             log_error(_("invalid clearsig header\n"));
350             return -1;
351         }
352     }
353     return 1;
354 }
355
356
357
358 /* figure out whether the data is armored or not */
359 static int
360 check_input( armor_filter_context_t *afx, IOBUF a )
361 {
362     int rc = 0;
363     int i;
364     byte *line;
365     unsigned len;
366     unsigned maxlen;
367     int hdr_line = -1;
368
369     /* read the first line to see whether this is armored data */
370     maxlen = MAX_LINELEN;
371     len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
372                                              &afx->buffer_size, &maxlen );
373     line = afx->buffer;
374     if( !maxlen ) {
375         /* line has been truncated: assume not armored */
376         afx->inp_checked = 1;
377         afx->inp_bypass = 1;
378         return 0;
379     }
380
381     if( !len ) {
382         return -1; /* eof */
383     }
384
385     /* (the line is always a C string but maybe longer) */
386     if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
387         ;
388     else if( !is_armored( line ) ) {
389         afx->inp_checked = 1;
390         afx->inp_bypass = 1;
391         return 0;
392     }
393
394     /* find the armor header */
395     while(len) {
396         i = is_armor_header( line, len );
397         if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
398             hdr_line = i;
399             if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
400                 if( afx->in_cleartext ) {
401                     log_error(_("nested clear text signatures\n"));
402                     rc = GPGERR_INVALID_ARMOR;
403                 }
404                 afx->in_cleartext = 1;
405             }
406             break;
407         }
408         /* read the next line (skip all truncated lines) */
409         do {
410             maxlen = MAX_LINELEN;
411             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
412                                                &afx->buffer_size, &maxlen );
413             line = afx->buffer;
414             len = afx->buffer_len;
415         } while( !maxlen );
416     }
417
418     /* parse the header lines */
419     while(len) {
420         /* read the next line (skip all truncated lines) */
421         do {
422             maxlen = MAX_LINELEN;
423             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
424                                                &afx->buffer_size, &maxlen );
425             line = afx->buffer;
426             len = afx->buffer_len;
427         } while( !maxlen );
428
429         i = parse_header_line( afx, line, len );
430         if( i <= 0 ) {
431             if( i )
432                 rc = GPGERR_INVALID_ARMOR;
433             break;
434         }
435     }
436
437
438     if( rc )
439         invalid_armor();
440     else if( afx->in_cleartext )
441         afx->faked = 1;
442     else {
443         afx->inp_checked = 1;
444         afx->crc = CRCINIT;
445         afx->idx = 0;
446         afx->radbuf[0] = 0;
447     }
448
449     return rc;
450 }
451
452
453
454 /****************
455  * Fake a literal data packet and wait for the next armor line
456  * fixme: empty line handling and null length clear text signature are
457  *        not implemented/checked.
458  */
459 static int
460 fake_packet( armor_filter_context_t *afx, IOBUF a,
461              size_t *retn, byte *buf, size_t size  )
462 {
463     int rc = 0;
464     size_t len = 0;
465     int lastline = 0;
466     unsigned maxlen, n;
467     byte *p;
468
469     len = 2;    /* reserve 2 bytes for the length header */
470     size -= 2;  /* and 2 for the terminating header */
471     while( !rc && len < size ) {
472         /* copy what we have in the line buffer */
473         if( afx->faked == 1 )
474             afx->faked++; /* skip the first (empty) line */
475         else {
476             while( len < size && afx->buffer_pos < afx->buffer_len )
477                 buf[len++] = afx->buffer[afx->buffer_pos++];
478             if( len >= size )
479                 continue;
480         }
481
482         /* read the next line */
483         maxlen = MAX_LINELEN;
484         afx->buffer_pos = 0;
485         afx->buffer_len = iobuf_read_line( a, &afx->buffer,
486                                            &afx->buffer_size, &maxlen );
487         if( !afx->buffer_len ) {
488             rc = -1; /* eof (should not happen) */
489             continue;
490         }
491         if( !maxlen )
492             afx->truncated++;
493         if( !afx->not_dash_escaped ) {
494             int crlf;
495             p = afx->buffer;
496             n = afx->buffer_len;
497             crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
498
499             /* PGP2 does not treat a tab as white space character */
500             afx->buffer_len = trim_trailing_chars( p, n,
501                                          afx->pgp2mode ? " \r\n" : " \t\r\n");
502             /* the buffer is always allocated with enough space to append
503              * the removed [CR], LF and a Nul
504              * The reason for this complicated procedure is to keep at least
505              * the original tupe of lineending - handling of the removed
506              * trailing spaces seems to be impossible in our method
507              * of faking a packet; either we have to use a temporary file
508              * or calculate the hash here in this module and somehow find
509              * a way to send the hash down the processing line (well, a special
510              * faked packet could do the job).
511              */
512             if( crlf )
513                 afx->buffer[afx->buffer_len++] = '\r';
514             afx->buffer[afx->buffer_len++] = '\n';
515             afx->buffer[afx->buffer_len] = 0;
516         }
517         p = afx->buffer;
518         n = afx->buffer_len;
519
520         if( n > 2 && *p == '-' ) {
521             /* check for dash escaped or armor header */
522             if( p[1] == ' ' && !afx->not_dash_escaped ) {
523                 /* issue a warning if it is not regular encoded */
524                 if( p[2] != '-' && !( n > 6 && !memcmp(p+2, "From ", 5))) {
525                     log_info(_("invalid dash escaped line: "));
526                     print_string( stderr, p, n, 0 );
527                     putc('\n', stderr);
528                 }
529                 afx->buffer_pos = 2; /* skip */
530             }
531             else if( n >= 15 &&  p[1] == '-' && p[2] == '-' && p[3] == '-' ) {
532                 int type = is_armor_header( p, n );
533                 if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
534                     ; /* this is okay */
535                 else {
536                     if( type != BEGIN_SIGNATURE ) {
537                         log_info(_("unexpected armor:"));
538                         print_string( stderr, p, n, 0 );
539                         putc('\n', stderr);
540                     }
541                     lastline = 1;
542                     rc = -1;
543                 }
544             }
545         }
546     }
547
548     buf[0] = (len-2) >> 8;
549     buf[1] = (len-2);
550     if( lastline ) { /* write last (ending) length header */
551         if( buf[0] || buf[1] ) { /* only if we have some text */
552             buf[len++] = 0;
553             buf[len++] = 0;
554         }
555         rc = 0;
556         afx->faked = 0;
557         afx->in_cleartext = 0;
558         /* and now read the header lines */
559         afx->buffer_pos = 0;
560         for(;;) {
561             int i;
562
563             /* read the next line (skip all truncated lines) */
564             do {
565                 maxlen = MAX_LINELEN;
566                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
567                                                  &afx->buffer_size, &maxlen );
568             } while( !maxlen );
569             p = afx->buffer;
570             n = afx->buffer_len;
571             if( !n ) {
572                 rc = -1;
573                 break; /* eof */
574             }
575             i = parse_header_line( afx, p , n );
576             if( i <= 0 ) {
577                 if( i )
578                     invalid_armor();
579                 break;
580             }
581         }
582         afx->inp_checked = 1;
583         afx->crc = CRCINIT;
584         afx->idx = 0;
585         afx->radbuf[0] = 0;
586     }
587
588     *retn = len;
589     return rc;
590 }
591
592
593
594 static int
595 radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
596               byte *buf, size_t size )
597 {
598     byte val;
599     int c=0, c2; /*init c because gcc is not clever enough for the continue*/
600     int checkcrc=0;
601     int rc = 0;
602     size_t n = 0;
603     int  idx, i;
604     u32 crc;
605
606     crc = afx->crc;
607     idx = afx->idx;
608     val = afx->radbuf[0];
609     for( n=0; n < size; ) {
610
611         if( afx->buffer_pos < afx->buffer_len )
612             c = afx->buffer[afx->buffer_pos++];
613         else { /* read the next line */
614             unsigned maxlen = MAX_LINELEN;
615             afx->buffer_pos = 0;
616             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
617                                                &afx->buffer_size, &maxlen );
618             if( !maxlen )
619                 afx->truncated++;
620             if( !afx->buffer_len )
621                 break; /* eof */
622             continue;
623         }
624
625       again:
626         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
627             continue;
628         else if( c == '=' ) { /* pad character: stop */
629             /* some mailers leave quoted-printable encoded characters
630              * so we try to workaround this */
631             if( afx->buffer_pos+2 < afx->buffer_len ) {
632                 int cc1, cc2, cc3;
633                 cc1 = afx->buffer[afx->buffer_pos];
634                 cc2 = afx->buffer[afx->buffer_pos+1];
635                 cc3 = afx->buffer[afx->buffer_pos+2];
636                 if( isxdigit(cc1) && isxdigit(cc2)
637                                   && strchr( "=\n\r\t ", cc3 )) {
638                     /* well it seems to be the case - adjust */
639                     c = isdigit(cc1)? (cc1 - '0'): (toupper(cc1)-'A'+10);
640                     c <<= 4;
641                     c |= isdigit(cc2)? (cc2 - '0'): (toupper(cc2)-'A'+10);
642                     afx->buffer_pos += 2;
643                     afx->qp_detected = 1;
644                     goto again;
645                 }
646             }
647
648             if( idx == 1 )
649                 buf[n++] = val;
650             checkcrc++;
651             break;
652         }
653         else if( (c = asctobin[(c2=c)]) == 255 ) {
654             log_error(_("invalid radix64 character %02x skipped\n"), c2);
655             continue;
656         }
657         switch(idx) {
658           case 0: val =  c << 2; break;
659           case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break;
660           case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break;
661           case 3: val |= c&0x3f; buf[n++] = val; break;
662         }
663         idx = (idx+1) % 4;
664     }
665
666     for(i=0; i < n; i++ )
667         crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
668     crc &= 0x00ffffff;
669     afx->crc = crc;
670     afx->idx = idx;
671     afx->radbuf[0] = val;
672
673     if( checkcrc ) {
674         afx->any_data = 1;
675         afx->inp_checked=0;
676         afx->faked = 0;
677         for(;;) { /* skip lf and pad characters */
678             if( afx->buffer_pos < afx->buffer_len )
679                 c = afx->buffer[afx->buffer_pos++];
680             else { /* read the next line */
681                 unsigned maxlen = MAX_LINELEN;
682                 afx->buffer_pos = 0;
683                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
684                                                    &afx->buffer_size, &maxlen );
685                 if( !maxlen )
686                     afx->truncated++;
687                 if( !afx->buffer_len )
688                     break; /* eof */
689                 continue;
690             }
691             if( c == '\n' || c == ' ' || c == '\r'
692                 || c == '\t' || c == '=' )
693                 continue;
694             break;
695         }
696         if( c == -1 )
697             log_error(_("premature eof (no CRC)\n"));
698         else {
699             u32 mycrc = 0;
700             idx = 0;
701             do {
702                 if( (c = asctobin[c]) == 255 )
703                     break;
704                 switch(idx) {
705                   case 0: val =  c << 2; break;
706                   case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break;
707                   case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break;
708                   case 3: val |= c&0x3f; mycrc |= val; break;
709                 }
710                 for(;;) {
711                     if( afx->buffer_pos < afx->buffer_len )
712                         c = afx->buffer[afx->buffer_pos++];
713                     else { /* read the next line */
714                         unsigned maxlen = MAX_LINELEN;
715                         afx->buffer_pos = 0;
716                         afx->buffer_len = iobuf_read_line( a, &afx->buffer,
717                                                            &afx->buffer_size,
718                                                                 &maxlen );
719                         if( !maxlen )
720                             afx->truncated++;
721                         if( !afx->buffer_len )
722                             break; /* eof */
723                         continue;
724                     }
725                     break;
726                 }
727                 if( !afx->buffer_len )
728                     break; /* eof */
729             } while( ++idx < 4 );
730             if( c == -1 ) {
731                 log_error(_("premature eof (in CRC)\n"));
732                 rc = GPGERR_INVALID_ARMOR;
733             }
734             else if( idx != 4 ) {
735                 log_error(_("malformed CRC\n"));
736                 rc = GPGERR_INVALID_ARMOR;
737             }
738             else if( mycrc != afx->crc ) {
739                 log_error(_("CRC error; %06lx - %06lx\n"),
740                                     (ulong)afx->crc, (ulong)mycrc);
741                 rc = GPGERR_INVALID_ARMOR;
742             }
743             else {
744                 rc = 0;
745               #if 0
746                 for(rc=0;!rc;) {
747                     rc = 0 /*check_trailer( &fhdr, c )*/;
748                     if( !rc ) {
749                         if( (c=iobuf_get(a)) == -1 )
750                             rc = 2;
751                     }
752                 }
753                 if( rc == -1 )
754                     rc = 0;
755                 else if( rc == 2 ) {
756                     log_error(_("premature eof (in Trailer)\n"));
757                     rc = GPGERR_INVALID_ARMOR;
758                 }
759                 else {
760                     log_error(_("error in trailer line\n"));
761                     rc = GPGERR_INVALID_ARMOR;
762                 }
763               #endif
764             }
765         }
766     }
767
768     if( !n )
769         rc = -1;
770
771     *retn = n;
772     return rc;
773 }
774
775 /****************
776  * This filter is used to handle the armor stuff
777  */
778 int
779 armor_filter( void *opaque, int control,
780              IOBUF a, byte *buf, size_t *ret_len)
781 {
782     size_t size = *ret_len;
783     armor_filter_context_t *afx = opaque;
784     int rc=0, i, c;
785     byte radbuf[3];
786     int  idx, idx2;
787     size_t n=0;
788     u32 crc;
789   #if 0
790     static FILE *fp ;
791
792     if( !fp ) {
793         fp = fopen("armor.out", "w");
794         assert(fp);
795     }
796   #endif
797
798     if( DBG_FILTER )
799         log_debug("armor-filter: control: %d\n", control );
800     if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
801         n = 0;
802         if( afx->buffer_len ) {
803             for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
804                 buf[n++] = afx->buffer[afx->buffer_pos++];
805             if( afx->buffer_pos >= afx->buffer_len )
806                 afx->buffer_len = 0;
807         }
808         for(; n < size; n++ ) {
809             if( (c=iobuf_get(a)) == -1 )
810                 break;
811             buf[n] = c & 0xff;
812         }
813         if( !n )
814             rc = -1;
815         *ret_len = n;
816     }
817     else if( control == IOBUFCTRL_UNDERFLOW ) {
818         if( size < 15+(4*15) )  /* need space for up to 4 onepass_sigs */
819             BUG(); /* supplied buffer too short */
820
821         if( afx->faked )
822             rc = fake_packet( afx, a, &n, buf, size );
823         else if( !afx->inp_checked ) {
824             rc = check_input( afx, a );
825             if( afx->inp_bypass ) {
826                 for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
827                     buf[n++] = afx->buffer[afx->buffer_pos++];
828                 if( afx->buffer_pos >= afx->buffer_len )
829                     afx->buffer_len = 0;
830                 if( !n )
831                     rc = -1;
832             }
833             else if( afx->faked ) {
834                 unsigned hashes = afx->hashes;
835                 /* the buffer is at least 15+n*15 bytes long, so it
836                  * is easy to construct the packets */
837
838                 hashes &= 1|2|4|8;
839                 if( !hashes ) {
840                     hashes |= 4;  /* default to MD 5 */
841                     if( opt.pgp2_workarounds )
842                         afx->pgp2mode = 1;
843                 }
844                 n=0;
845                 do {
846                     /* first some onepass signature packets */
847                     buf[n++] = 0x90; /* old format, type 4, 1 length byte */
848                     buf[n++] = 13;   /* length */
849                     buf[n++] = 3;    /* version */
850                     buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
851                     if( hashes & 1 ) {
852                         hashes &= ~1;
853                         buf[n++] = GCRY_MD_RMD160;
854                     }
855                     else if( hashes & 2 ) {
856                         hashes &= ~2;
857                         buf[n++] = GCRY_MD_SHA1;
858                     }
859                     else if( hashes & 4 ) {
860                         hashes &= ~4;
861                         buf[n++] = GCRY_MD_MD5;
862                     }
863                     else if( hashes & 8 ) {
864                         hashes &= ~8;
865                         buf[n++] = GCRY_MD_TIGER;
866                     }
867                     else
868                         buf[n++] = 0;    /* (don't know) */
869
870                     buf[n++] = 0;    /* public key algo (don't know) */
871                     memset(buf+n, 0, 8); /* don't know the keyid */
872                     n += 8;
873                     buf[n++] = !hashes;   /* last one */
874                 } while( hashes );
875
876                 /* followed by a plaintext packet */
877                 buf[n++] = 0xaf; /* old packet format, type 11, var length */
878                 buf[n++] = 0;    /* set the length header */
879                 buf[n++] = 6;
880                 buf[n++] = 't';  /* canonical text mode */
881                 buf[n++] = 0;    /* namelength */
882                 memset(buf+n, 0, 4); /* timestamp */
883                 n += 4;
884             }
885             else if( !rc )
886                 rc = radix64_read( afx, a, &n, buf, size );
887         }
888         else
889             rc = radix64_read( afx, a, &n, buf, size );
890       #if 0
891         if( n )
892             if( fwrite(buf, n, 1, fp ) != 1 )
893                 BUG();
894       #endif
895         *ret_len = n;
896     }
897     else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
898         if( !afx->status ) { /* write the header line */
899             const char *s;
900
901             if( afx->what >= DIM(head_strings) )
902                 log_bug("afx->what=%d", afx->what);
903             iobuf_writestr(a, "-----");
904             iobuf_writestr(a, head_strings[afx->what] );
905             iobuf_writestr(a, "-----" LF );
906             if( !opt.no_version )
907                 iobuf_writestr(a, "Version: GnuPG v"  VERSION " ("
908                                               PRINTABLE_OS_NAME ")" LF );
909
910             /* write the comment string or a default one */
911             s = opt.comment_string ? opt.comment_string
912                                    : _("For info see http://www.gnupg.org");
913             if( *s ) {
914                 iobuf_writestr(a, "Comment: " );
915                 for( ; *s; s++ ) {
916                     if( *s == '\n' )
917                         iobuf_writestr(a, "\\n" );
918                     else if( *s == '\r' )
919                         iobuf_writestr(a, "\\r" );
920                     else if( *s == '\v' )
921                         iobuf_writestr(a, "\\v" );
922                     else
923                         iobuf_put(a, *s );
924                 }
925                 iobuf_writestr(a, LF );
926             }
927
928             if( afx->hdrlines )
929                 iobuf_writestr(a, afx->hdrlines);
930             iobuf_writestr(a, LF );
931             afx->status++;
932             afx->idx = 0;
933             afx->idx2 = 0;
934             afx->crc = CRCINIT;
935
936         }
937         crc = afx->crc;
938         idx = afx->idx;
939         idx2 = afx->idx2;
940         for(i=0; i < idx; i++ )
941             radbuf[i] = afx->radbuf[i];
942
943         for(i=0; i < size; i++ )
944             crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
945         crc &= 0x00ffffff;
946
947         for( ; size; buf++, size-- ) {
948             radbuf[idx++] = *buf;
949             if( idx > 2 ) {
950                 idx = 0;
951                 c = bintoasc[(*radbuf >> 2) & 077];
952                 iobuf_put(a, c);
953                 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
954                 iobuf_put(a, c);
955                 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
956                 iobuf_put(a, c);
957                 c = bintoasc[radbuf[2]&077];
958                 iobuf_put(a, c);
959                 if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
960                     iobuf_writestr(a, LF );
961                     idx2=0;
962                 }
963             }
964         }
965         for(i=0; i < idx; i++ )
966             afx->radbuf[i] = radbuf[i];
967         afx->idx = idx;
968         afx->idx2 = idx2;
969         afx->crc  = crc;
970     }
971     else if( control == IOBUFCTRL_INIT ) {
972         if( !is_initialized )
973             initialize();
974     }
975     else if( control == IOBUFCTRL_CANCEL ) {
976         afx->cancel = 1;
977     }
978     else if( control == IOBUFCTRL_FREE ) {
979         if( afx->cancel )
980             ;
981         else if( afx->status ) { /* pad, write cecksum, and bottom line */
982             crc = afx->crc;
983             idx = afx->idx;
984             idx2 = afx->idx2;
985             for(i=0; i < idx; i++ )
986                 radbuf[i] = afx->radbuf[i];
987             if( idx ) {
988                 c = bintoasc[(*radbuf>>2)&077];
989                 iobuf_put(a, c);
990                 if( idx == 1 ) {
991                     c = bintoasc[((*radbuf << 4) & 060) & 077];
992                     iobuf_put(a, c);
993                     iobuf_put(a, '=');
994                     iobuf_put(a, '=');
995                 }
996                 else { /* 2 */
997                     c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
998                     iobuf_put(a, c);
999                     c = bintoasc[((radbuf[1] << 2) & 074) & 077];
1000                     iobuf_put(a, c);
1001                     iobuf_put(a, '=');
1002                 }
1003                 if( ++idx2 >= (64/4) ) { /* pgp doesn't like 72 here */
1004                     iobuf_writestr(a, LF );
1005                     idx2=0;
1006                 }
1007             }
1008             /* may need a linefeed */
1009             if( idx2 )
1010                 iobuf_writestr(a, LF );
1011             /* write the CRC */
1012             iobuf_put(a, '=');
1013             radbuf[0] = crc >>16;
1014             radbuf[1] = crc >> 8;
1015             radbuf[2] = crc;
1016             c = bintoasc[(*radbuf >> 2) & 077];
1017             iobuf_put(a, c);
1018             c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1019             iobuf_put(a, c);
1020             c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1021             iobuf_put(a, c);
1022             c = bintoasc[radbuf[2]&077];
1023             iobuf_put(a, c);
1024             iobuf_writestr(a, LF );
1025             /* and the the trailer */
1026             if( afx->what >= DIM(tail_strings) )
1027                 log_bug("afx->what=%d", afx->what);
1028             iobuf_writestr(a, "-----");
1029             iobuf_writestr(a, tail_strings[afx->what] );
1030             iobuf_writestr(a, "-----" LF );
1031         }
1032         else if( !afx->any_data && !afx->inp_bypass ) {
1033             log_error(_("no valid OpenPGP data found.\n"));
1034             afx->no_openpgp_data = 1;
1035             write_status_text( STATUS_NODATA, "1" );
1036         }
1037         if( afx->truncated )
1038             log_info(_("invalid armor: line longer than %d characters\n"),
1039                       MAX_LINELEN );
1040         /* issue an error to enforce dissemination of correct software */
1041         if( afx->qp_detected )
1042             log_error(_("quoted printable character in armor - "
1043                         "probably a buggy MTA has been used\n") );
1044         gcry_free( afx->buffer );
1045         afx->buffer = NULL;
1046     }
1047     else if( control == IOBUFCTRL_DESC )
1048         *(char**)buf = "armor_filter";
1049     return rc;
1050 }
1051
1052
1053 /****************
1054  * create a radix64 encoded string.
1055  */
1056 char *
1057 make_radix64_string( const byte *data, size_t len )
1058 {
1059     char *buffer, *p;
1060
1061     buffer = p = gcry_xmalloc( (len+2)/3*4 + 1 );
1062     for( ; len >= 3 ; len -= 3, data += 3 ) {
1063         *p++ = bintoasc[(data[0] >> 2) & 077];
1064         *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1065         *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
1066         *p++ = bintoasc[data[2]&077];
1067     }
1068     if( len == 2 ) {
1069         *p++ = bintoasc[(data[0] >> 2) & 077];
1070         *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1071         *p++ = bintoasc[((data[1]<<2)&074)];
1072     }
1073     else if( len == 1 ) {
1074         *p++ = bintoasc[(data[0] >> 2) & 077];
1075         *p++ = bintoasc[(data[0] <<4)&060];
1076     }
1077     *p = 0;
1078     return buffer;
1079 }
1080