Imported Upstream version 2.0.26
[platform/upstream/gpg2.git] / g10 / armor.c
1 /* armor.c - Armor filter
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3  *               2007 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 3 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, see <http://www.gnu.org/licenses/>.
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 "gpg.h"
30 #include "status.h"
31 #include "iobuf.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 #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 static int armor_filter ( void *opaque, int control,
116                           iobuf_t chain, byte *buf, size_t *ret_len);
117
118
119
120 \f
121 /* Create a new context for armor filters.  */
122 armor_filter_context_t *
123 new_armor_context (void)
124 {
125   armor_filter_context_t *afx;
126
127   afx = xcalloc (1, sizeof *afx);
128   afx->refcount = 1;
129
130   return afx;
131 }
132
133 /* Release an armor filter context.  Passing NULL is explicitly
134    allowed and a no-op.  */
135 void
136 release_armor_context (armor_filter_context_t *afx)
137 {
138   if (!afx)
139     return;
140   assert (afx->refcount);
141   if ( --afx->refcount )
142     return;
143   xfree (afx);
144 }
145
146 /* Push the armor filter onto the iobuf stream IOBUF.  */
147 int
148 push_armor_filter (armor_filter_context_t *afx, iobuf_t iobuf)
149 {
150   int rc;
151
152   afx->refcount++;
153   rc = iobuf_push_filter (iobuf, armor_filter, afx);
154   if (rc)
155     afx->refcount--;
156   return rc;
157 }
158
159
160
161
162
163 static void
164 initialize(void)
165 {
166     int i, j;
167     u32 t;
168     byte *s;
169
170     /* init the crc lookup table */
171     crc_table[0] = 0;
172     for(i=j=0; j < 128; j++ ) {
173         t = crc_table[j];
174         if( t & 0x00800000 ) {
175             t <<= 1;
176             crc_table[i++] = t ^ CRCPOLY;
177             crc_table[i++] = t;
178         }
179         else {
180             t <<= 1;
181             crc_table[i++] = t;
182             crc_table[i++] = t ^ CRCPOLY;
183         }
184     }
185     /* build the helptable for radix64 to bin conversion */
186     for(i=0; i < 256; i++ )
187         asctobin[i] = 255; /* used to detect invalid characters */
188     for(s=bintoasc,i=0; *s; s++,i++ )
189         asctobin[*s] = i;
190
191     is_initialized=1;
192 }
193
194 /****************
195  * Check whether this is an armored file or not See also
196  * parse-packet.c for details on this code For unknown historic
197  * reasons we use a string here but only the first byte will be used.
198  * Returns: True if it seems to be armored
199  */
200 static int
201 is_armored( const byte *buf )
202 {
203     int ctb, pkttype;
204
205     ctb = *buf;
206     if( !(ctb & 0x80) )
207         return 1; /* invalid packet: assume it is armored */
208     pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
209     switch( pkttype ) {
210       case PKT_MARKER:
211       case PKT_SYMKEY_ENC:
212       case PKT_ONEPASS_SIG:
213       case PKT_PUBLIC_KEY:
214       case PKT_SECRET_KEY:
215       case PKT_PUBKEY_ENC:
216       case PKT_SIGNATURE:
217       case PKT_COMMENT:
218       case PKT_OLD_COMMENT:
219       case PKT_PLAINTEXT:
220       case PKT_COMPRESSED:
221       case PKT_ENCRYPTED:
222         return 0; /* seems to be a regular packet: not armored */
223     }
224
225     return 1;
226 }
227
228
229 /****************
230  * Try to check whether the iobuf is armored
231  * Returns true if this may be the case; the caller should use the
232  *         filter to do further processing.
233  */
234 int
235 use_armor_filter( IOBUF a )
236 {
237     byte buf[1];
238     int n;
239
240     /* fixme: there might be a problem with iobuf_peek */
241     n = iobuf_peek(a, buf, 1 );
242     if( n == -1 )
243         return 0; /* EOF, doesn't matter whether armored or not */
244     if( !n )
245         return 1; /* can't check it: try armored */
246     return is_armored(buf);
247 }
248
249
250
251
252 static void
253 invalid_armor(void)
254 {
255     write_status(STATUS_BADARMOR);
256     g10_exit(1); /* stop here */
257 }
258
259
260 /****************
261  * check whether the armor header is valid on a signed message.
262  * this is for security reasons: the header lines are not included in the
263  * hash and by using some creative formatting rules, Mallory could fake
264  * any text at the beginning of a document; assuming it is read with
265  * a simple viewer. We only allow the Hash Header.
266  */
267 static int
268 parse_hash_header( const char *line )
269 {
270     const char *s, *s2;
271     unsigned found = 0;
272
273     if( strlen(line) < 6  || strlen(line) > 60 )
274         return 0; /* too short or too long */
275     if( memcmp( line, "Hash:", 5 ) )
276         return 0; /* invalid header */
277     s = line+5;
278     for(s=line+5;;s=s2) {
279         for(; *s && (*s==' ' || *s == '\t'); s++ )
280             ;
281         if( !*s )
282             break;
283         for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
284             ;
285         if( !strncmp( s, "RIPEMD160", s2-s ) )
286             found |= 1;
287         else if( !strncmp( s, "SHA1", s2-s ) )
288             found |= 2;
289         else if( !strncmp( s, "MD5", s2-s ) )
290             found |= 4;
291         else if( !strncmp( s, "SHA224", s2-s ) )
292             found |= 8;
293         else if( !strncmp( s, "SHA256", s2-s ) )
294             found |= 16;
295         else if( !strncmp( s, "SHA384", s2-s ) )
296             found |= 32;
297         else if( !strncmp( s, "SHA512", s2-s ) )
298             found |= 64;
299         else
300             return 0;
301         for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
302             ;
303         if( *s2 && *s2 != ',' )
304             return 0;
305         if( *s2 )
306             s2++;
307     }
308     return found;
309 }
310
311 /* Returns true if this is a valid armor tag as per RFC-2440bis-21. */
312 static int
313 is_armor_tag(const char *line)
314 {
315   if(strncmp(line,"Version",7)==0
316      || strncmp(line,"Comment",7)==0
317      || strncmp(line,"MessageID",9)==0
318      || strncmp(line,"Hash",4)==0
319      || strncmp(line,"Charset",7)==0)
320     return 1;
321
322   return 0;
323 }
324
325 /****************
326  * Check whether this is a armor line.
327  * returns: -1 if it is not a armor header or the index number of the
328  * armor header.
329  */
330 static int
331 is_armor_header( byte *line, unsigned len )
332 {
333     const char *s;
334     byte *save_p, *p;
335     int save_c;
336     int i;
337
338     if( len < 15 )
339         return -1; /* too short */
340     if( memcmp( line, "-----", 5 ) )
341         return -1; /* no */
342     p = strstr( line+5, "-----");
343     if( !p )
344         return -1;
345     save_p = p;
346     p += 5;
347
348     /* Some Windows environments seem to add whitespace to the end of
349        the line, so we strip it here.  This becomes strict if
350        --rfc2440 is set since 2440 reads "The header lines, therefore,
351        MUST start at the beginning of a line, and MUST NOT have text
352        following them on the same line."  It is unclear whether "text"
353        refers to all text or just non-whitespace text.  4880 clarified
354        this was only non-whitespace text. */
355
356     if(RFC2440)
357       {
358         if( *p == '\r' )
359           p++;
360         if( *p == '\n' )
361           p++;
362       }
363     else
364       while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
365         p++;
366
367     if( *p )
368         return -1; /* garbage after dashes */
369     save_c = *save_p; *save_p = 0;
370     p = line+5;
371     for(i=0; (s=head_strings[i]); i++ )
372         if( !strcmp(s, p) )
373             break;
374     *save_p = save_c;
375     if( !s )
376         return -1; /* unknown armor line */
377
378     if( opt.verbose > 1 )
379         log_info(_("armor: %s\n"), head_strings[i]);
380     return i;
381 }
382
383
384
385 /****************
386  * Parse a header lines
387  * Return 0: Empty line (end of header lines)
388  *       -1: invalid header line
389  *       >0: Good header line
390  */
391 static int
392 parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
393 {
394     byte *p;
395     int hashes=0;
396     unsigned int len2;
397
398     len2 = length_sans_trailing_ws ( line, len );
399     if( !len2 ) {
400         afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
401         return 0; /* WS only: same as empty line */
402     }
403
404     /*
405       This is fussy.  The spec says that a header line is delimited
406       with a colon-space pair.  This means that a line such as
407       "Comment: " (with nothing else) is actually legal as an empty
408       string comment.  However, email and cut-and-paste being what it
409       is, that trailing space may go away.  Therefore, we accept empty
410       headers delimited with only a colon.  --rfc2440, as always,
411       makes this strict and enforces the colon-space pair. -dms
412     */
413
414     p = strchr( line, ':');
415     if( !p || (RFC2440 && p[1]!=' ')
416         || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
417       {
418         log_error(_("invalid armor header: "));
419         print_string( stderr, line, len, 0 );
420         putc('\n', stderr);
421         return -1;
422       }
423
424     /* Chop off the whitespace we detected before */
425     len=len2;
426     line[len2]='\0';
427
428     if( opt.verbose ) {
429         log_info(_("armor header: "));
430         print_string( stderr, line, len, 0 );
431         putc('\n', stderr);
432     }
433
434     if( afx->in_cleartext )
435       {
436         if( (hashes=parse_hash_header( line )) )
437           afx->hashes |= hashes;
438         else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
439           afx->not_dash_escaped = 1;
440         else
441           {
442             log_error(_("invalid clearsig header\n"));
443             return -1;
444           }
445       }
446     else if(!is_armor_tag(line))
447       {
448         /* Section 6.2: "Unknown keys should be reported to the user,
449            but OpenPGP should continue to process the message."  Note
450            that in a clearsigned message this applies to the signature
451            part (i.e. "BEGIN PGP SIGNATURE") and not the signed data
452            ("BEGIN PGP SIGNED MESSAGE").  The only key allowed in the
453            signed data section is "Hash". */
454
455         log_info(_("unknown armor header: "));
456         print_string( stderr, line, len, 0 );
457         putc('\n', stderr);
458       }
459
460     return 1;
461 }
462
463
464
465 /* figure out whether the data is armored or not */
466 static int
467 check_input( armor_filter_context_t *afx, IOBUF a )
468 {
469     int rc = 0;
470     int i;
471     byte *line;
472     unsigned len;
473     unsigned maxlen;
474     int hdr_line = -1;
475
476     /* read the first line to see whether this is armored data */
477     maxlen = MAX_LINELEN;
478     len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
479                                              &afx->buffer_size, &maxlen );
480     line = afx->buffer;
481     if( !maxlen ) {
482         /* line has been truncated: assume not armored */
483         afx->inp_checked = 1;
484         afx->inp_bypass = 1;
485         return 0;
486     }
487
488     if( !len ) {
489         return -1; /* eof */
490     }
491
492     /* (the line is always a C string but maybe longer) */
493     if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
494         ;
495     else if( !is_armored( line ) ) {
496         afx->inp_checked = 1;
497         afx->inp_bypass = 1;
498         return 0;
499     }
500
501     /* find the armor header */
502     while(len) {
503         i = is_armor_header( line, len );
504         if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
505             hdr_line = i;
506             if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
507                 if( afx->in_cleartext ) {
508                     log_error(_("nested clear text signatures\n"));
509                     rc = gpg_error (GPG_ERR_INV_ARMOR);
510                 }
511                 afx->in_cleartext = 1;
512             }
513             break;
514         }
515         /* read the next line (skip all truncated lines) */
516         do {
517             maxlen = MAX_LINELEN;
518             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
519                                                &afx->buffer_size, &maxlen );
520             line = afx->buffer;
521             len = afx->buffer_len;
522         } while( !maxlen );
523     }
524
525     /* Parse the header lines.  */
526     while(len) {
527         /* Read the next line (skip all truncated lines). */
528         do {
529             maxlen = MAX_LINELEN;
530             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
531                                                &afx->buffer_size, &maxlen );
532             line = afx->buffer;
533             len = afx->buffer_len;
534         } while( !maxlen );
535
536         i = parse_header_line( afx, line, len );
537         if( i <= 0 ) {
538             if (i && RFC2440)
539                 rc = G10ERR_INVALID_ARMOR;
540             break;
541         }
542     }
543
544
545     if( rc )
546         invalid_armor();
547     else if( afx->in_cleartext )
548         afx->faked = 1;
549     else {
550         afx->inp_checked = 1;
551         afx->crc = CRCINIT;
552         afx->idx = 0;
553         afx->radbuf[0] = 0;
554     }
555
556     return rc;
557 }
558
559 #define PARTIAL_CHUNK 512
560 #define PARTIAL_POW   9
561
562 /****************
563  * Fake a literal data packet and wait for the next armor line
564  * fixme: empty line handling and null length clear text signature are
565  *        not implemented/checked.
566  */
567 static int
568 fake_packet( armor_filter_context_t *afx, IOBUF a,
569              size_t *retn, byte *buf, size_t size  )
570 {
571     int rc = 0;
572     size_t len = 0;
573     int lastline = 0;
574     unsigned maxlen, n;
575     byte *p;
576     byte tempbuf[PARTIAL_CHUNK];
577     size_t tempbuf_len=0;
578
579     while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
580         /* copy what we have in the line buffer */
581         if( afx->faked == 1 )
582             afx->faked++; /* skip the first (empty) line */
583         else
584           {
585             /* It's full, so write this partial chunk */
586             if(tempbuf_len==PARTIAL_CHUNK)
587               {
588                 buf[len++]=0xE0+PARTIAL_POW;
589                 memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
590                 len+=PARTIAL_CHUNK;
591                 tempbuf_len=0;
592                 continue;
593               }
594
595             while( tempbuf_len < PARTIAL_CHUNK
596                    && afx->buffer_pos < afx->buffer_len )
597               tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
598             if( tempbuf_len==PARTIAL_CHUNK )
599               continue;
600           }
601
602         /* read the next line */
603         maxlen = MAX_LINELEN;
604         afx->buffer_pos = 0;
605         afx->buffer_len = iobuf_read_line( a, &afx->buffer,
606                                            &afx->buffer_size, &maxlen );
607         if( !afx->buffer_len ) {
608             rc = -1; /* eof (should not happen) */
609             continue;
610         }
611         if( !maxlen )
612             afx->truncated++;
613
614         p = afx->buffer;
615         n = afx->buffer_len;
616
617         /* Armor header or dash-escaped line? */
618         if(p[0]=='-')
619           {
620             /* 2440bis-10: When reversing dash-escaping, an
621                implementation MUST strip the string "- " if it occurs
622                at the beginning of a line, and SHOULD warn on "-" and
623                any character other than a space at the beginning of a
624                line.  */
625
626             if(p[1]==' ' && !afx->not_dash_escaped)
627               {
628                 /* It's a dash-escaped line, so skip over the
629                    escape. */
630                 afx->buffer_pos = 2;
631               }
632             else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
633               {
634                 /* Five dashes in a row mean it's probably armor
635                    header. */
636                 int type = is_armor_header( p, n );
637                 if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
638                   ; /* this is okay */
639                 else
640                   {
641                     if( type != BEGIN_SIGNATURE )
642                       {
643                         log_info(_("unexpected armor: "));
644                         print_string( stderr, p, n, 0 );
645                         putc('\n', stderr);
646                       }
647
648                     lastline = 1;
649                     rc = -1;
650                   }
651               }
652             else if(!afx->not_dash_escaped)
653               {
654                 /* Bad dash-escaping. */
655                 log_info(_("invalid dash escaped line: "));
656                 print_string( stderr, p, n, 0 );
657                 putc('\n', stderr);
658               }
659           }
660
661         /* Now handle the end-of-line canonicalization */
662         if( !afx->not_dash_escaped )
663           {
664             int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
665
666             /* PGP2 does not treat a tab as white space character */
667             afx->buffer_len=
668               trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
669                                    afx->pgp2mode ? " \r\n" : " \t\r\n");
670             afx->buffer_len+=afx->buffer_pos;
671             /* the buffer is always allocated with enough space to append
672              * the removed [CR], LF and a Nul
673              * The reason for this complicated procedure is to keep at least
674              * the original type of lineending - handling of the removed
675              * trailing spaces seems to be impossible in our method
676              * of faking a packet; either we have to use a temporary file
677              * or calculate the hash here in this module and somehow find
678              * a way to send the hash down the processing line (well, a special
679              * faked packet could do the job).
680              */
681             if( crlf )
682               afx->buffer[afx->buffer_len++] = '\r';
683             afx->buffer[afx->buffer_len++] = '\n';
684             afx->buffer[afx->buffer_len] = '\0';
685           }
686     }
687
688     if( lastline ) { /* write last (ending) length header */
689         if(tempbuf_len<192)
690           buf[len++]=tempbuf_len;
691         else
692           {
693             buf[len++]=((tempbuf_len-192)/256) + 192;
694             buf[len++]=(tempbuf_len-192) % 256;
695           }
696         memcpy(&buf[len],tempbuf,tempbuf_len);
697         len+=tempbuf_len;
698
699         rc = 0;
700         afx->faked = 0;
701         afx->in_cleartext = 0;
702         /* and now read the header lines */
703         afx->buffer_pos = 0;
704         for(;;) {
705             int i;
706
707             /* read the next line (skip all truncated lines) */
708             do {
709                 maxlen = MAX_LINELEN;
710                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
711                                                  &afx->buffer_size, &maxlen );
712             } while( !maxlen );
713             p = afx->buffer;
714             n = afx->buffer_len;
715             if( !n ) {
716                 rc = -1;
717                 break; /* eof */
718             }
719             i = parse_header_line( afx, p , n );
720             if( i <= 0 ) {
721                 if( i )
722                     invalid_armor();
723                 break;
724             }
725         }
726         afx->inp_checked = 1;
727         afx->crc = CRCINIT;
728         afx->idx = 0;
729         afx->radbuf[0] = 0;
730     }
731
732     *retn = len;
733     return rc;
734 }
735
736
737 static int
738 invalid_crc(void)
739 {
740   if ( opt.ignore_crc_error )
741     return 0;
742   log_inc_errorcount();
743   return gpg_error (GPG_ERR_INV_ARMOR);
744 }
745
746
747 static int
748 radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
749               byte *buf, size_t size )
750 {
751     byte val;
752     int c=0, c2; /*init c because gcc is not clever enough for the continue*/
753     int checkcrc=0;
754     int rc = 0;
755     size_t n = 0;
756     int  idx, i, onlypad=0;
757     u32 crc;
758
759     crc = afx->crc;
760     idx = afx->idx;
761     val = afx->radbuf[0];
762     for( n=0; n < size; ) {
763
764         if( afx->buffer_pos < afx->buffer_len )
765             c = afx->buffer[afx->buffer_pos++];
766         else { /* read the next line */
767             unsigned maxlen = MAX_LINELEN;
768             afx->buffer_pos = 0;
769             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
770                                                &afx->buffer_size, &maxlen );
771             if( !maxlen )
772                 afx->truncated++;
773             if( !afx->buffer_len )
774                 break; /* eof */
775             continue;
776         }
777
778       again:
779         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
780             continue;
781         else if( c == '=' ) { /* pad character: stop */
782             /* some mailers leave quoted-printable encoded characters
783              * so we try to workaround this */
784             if( afx->buffer_pos+2 < afx->buffer_len ) {
785                 int cc1, cc2, cc3;
786                 cc1 = afx->buffer[afx->buffer_pos];
787                 cc2 = afx->buffer[afx->buffer_pos+1];
788                 cc3 = afx->buffer[afx->buffer_pos+2];
789                 if( isxdigit(cc1) && isxdigit(cc2)
790                                   && strchr( "=\n\r\t ", cc3 )) {
791                     /* well it seems to be the case - adjust */
792                     c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
793                     c <<= 4;
794                     c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
795                     afx->buffer_pos += 2;
796                     afx->qp_detected = 1;
797                     goto again;
798                 }
799             }
800
801             if (!n)
802               onlypad = 1;
803
804             if( idx == 1 )
805                 buf[n++] = val;
806             checkcrc++;
807             break;
808         }
809         else if( (c = asctobin[(c2=c)]) == 255 ) {
810             log_error(_("invalid radix64 character %02X skipped\n"), c2);
811             continue;
812         }
813         switch(idx) {
814           case 0: val =  c << 2; break;
815           case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break;
816           case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break;
817           case 3: val |= c&0x3f; buf[n++] = val; break;
818         }
819         idx = (idx+1) % 4;
820     }
821
822     for(i=0; i < n; i++ )
823         crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
824     crc &= 0x00ffffff;
825     afx->crc = crc;
826     afx->idx = idx;
827     afx->radbuf[0] = val;
828
829     if( checkcrc ) {
830         afx->any_data = 1;
831         afx->inp_checked=0;
832         afx->faked = 0;
833         for(;;) { /* skip lf and pad characters */
834             if( afx->buffer_pos < afx->buffer_len )
835                 c = afx->buffer[afx->buffer_pos++];
836             else { /* read the next line */
837                 unsigned maxlen = MAX_LINELEN;
838                 afx->buffer_pos = 0;
839                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
840                                                    &afx->buffer_size, &maxlen );
841                 if( !maxlen )
842                     afx->truncated++;
843                 if( !afx->buffer_len )
844                     break; /* eof */
845                 continue;
846             }
847             if( c == '\n' || c == ' ' || c == '\r'
848                 || c == '\t' || c == '=' )
849                 continue;
850             break;
851         }
852         if( c == -1 )
853             log_error(_("premature eof (no CRC)\n"));
854         else {
855             u32 mycrc = 0;
856             idx = 0;
857             do {
858                 if( (c = asctobin[c]) == 255 )
859                     break;
860                 switch(idx) {
861                   case 0: val =  c << 2; break;
862                   case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break;
863                   case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break;
864                   case 3: val |= c&0x3f; mycrc |= val; break;
865                 }
866                 for(;;) {
867                     if( afx->buffer_pos < afx->buffer_len )
868                         c = afx->buffer[afx->buffer_pos++];
869                     else { /* read the next line */
870                         unsigned maxlen = MAX_LINELEN;
871                         afx->buffer_pos = 0;
872                         afx->buffer_len = iobuf_read_line( a, &afx->buffer,
873                                                            &afx->buffer_size,
874                                                                 &maxlen );
875                         if( !maxlen )
876                             afx->truncated++;
877                         if( !afx->buffer_len )
878                             break; /* eof */
879                         continue;
880                     }
881                     break;
882                 }
883                 if( !afx->buffer_len )
884                     break; /* eof */
885             } while( ++idx < 4 );
886             if( c == -1 ) {
887                 log_info(_("premature eof (in CRC)\n"));
888                 rc = invalid_crc();
889             }
890             else if( idx == 0 ) {
891                 /* No CRC at all is legal ("MAY") */
892                 rc=0;
893             }
894             else if( idx != 4 ) {
895                 log_info(_("malformed CRC\n"));
896                 rc = invalid_crc();
897             }
898             else if( mycrc != afx->crc ) {
899                 log_info (_("CRC error; %06lX - %06lX\n"),
900                                     (ulong)afx->crc, (ulong)mycrc);
901                 rc = invalid_crc();
902             }
903             else {
904                 rc = 0;
905                 /* FIXME: Here we should emit another control packet,
906                  * so that we know in mainproc that we are processing
907                  * a clearsign message */
908 #if 0
909                 for(rc=0;!rc;) {
910                     rc = 0 /*check_trailer( &fhdr, c )*/;
911                     if( !rc ) {
912                         if( (c=iobuf_get(a)) == -1 )
913                             rc = 2;
914                     }
915                 }
916                 if( rc == -1 )
917                     rc = 0;
918                 else if( rc == 2 ) {
919                     log_error(_("premature eof (in trailer)\n"));
920                     rc = G10ERR_INVALID_ARMOR;
921                 }
922                 else {
923                     log_error(_("error in trailer line\n"));
924                     rc = G10ERR_INVALID_ARMOR;
925                 }
926 #endif
927             }
928         }
929     }
930
931     if( !n && !onlypad )
932         rc = -1;
933
934     *retn = n;
935     return rc;
936 }
937
938 /****************
939  * This filter is used to handle the armor stuff
940  */
941 static int
942 armor_filter( void *opaque, int control,
943              IOBUF a, byte *buf, size_t *ret_len)
944 {
945     size_t size = *ret_len;
946     armor_filter_context_t *afx = opaque;
947     int rc=0, i, c;
948     byte radbuf[3];
949     int  idx, idx2;
950     size_t n=0;
951     u32 crc;
952 #if 0
953     static FILE *fp ;
954
955     if( !fp ) {
956         fp = fopen("armor.out", "w");
957         assert(fp);
958     }
959 #endif
960
961     if( DBG_FILTER )
962         log_debug("armor-filter: control: %d\n", control );
963     if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
964         n = 0;
965         if( afx->buffer_len ) {
966             for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
967                 buf[n++] = afx->buffer[afx->buffer_pos++];
968             if( afx->buffer_pos >= afx->buffer_len )
969                 afx->buffer_len = 0;
970         }
971         for(; n < size; n++ ) {
972             if( (c=iobuf_get(a)) == -1 )
973                 break;
974             buf[n] = c & 0xff;
975         }
976         if( !n )
977             rc = -1;
978         *ret_len = n;
979     }
980     else if( control == IOBUFCTRL_UNDERFLOW ) {
981         /* We need some space for the faked packet.  The minmum
982          * required size is the PARTIAL_CHUNK size plus a byte for the
983          * length itself */
984         if( size < PARTIAL_CHUNK+1 )
985             BUG(); /* supplied buffer too short */
986
987         if( afx->faked )
988             rc = fake_packet( afx, a, &n, buf, size );
989         else if( !afx->inp_checked ) {
990             rc = check_input( afx, a );
991             if( afx->inp_bypass ) {
992                 for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
993                     buf[n++] = afx->buffer[afx->buffer_pos++];
994                 if( afx->buffer_pos >= afx->buffer_len )
995                     afx->buffer_len = 0;
996                 if( !n )
997                     rc = -1;
998             }
999             else if( afx->faked ) {
1000                 unsigned int hashes = afx->hashes;
1001                 const byte *sesmark;
1002                 size_t sesmarklen;
1003
1004                 sesmark = get_session_marker( &sesmarklen );
1005                 if ( sesmarklen > 20 )
1006                     BUG();
1007
1008                 /* the buffer is at least 15+n*15 bytes long, so it
1009                  * is easy to construct the packets */
1010
1011                 hashes &= 1|2|4|8|16|32|64;
1012                 if( !hashes ) {
1013                     hashes |= 4;  /* default to MD 5 */
1014                     /* This is non-ideal since PGP 5-8 have the same
1015                        end-of-line bugs as PGP 2. However, we only
1016                        enable pgp2mode if there is no Hash: header. */
1017                     if( opt.pgp2_workarounds )
1018                         afx->pgp2mode = 1;
1019                 }
1020                 n=0;
1021                 /* First a gpg control packet... */
1022                 buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1023                 n++;   /* see below */
1024                 memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1025                 buf[n++] = CTRLPKT_CLEARSIGN_START;
1026                 buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1027                 if( hashes & 1 )
1028                     buf[n++] = DIGEST_ALGO_RMD160;
1029                 if( hashes & 2 )
1030                     buf[n++] = DIGEST_ALGO_SHA1;
1031                 if( hashes & 4 )
1032                     buf[n++] = DIGEST_ALGO_MD5;
1033                 if( hashes & 8 )
1034                     buf[n++] = DIGEST_ALGO_SHA224;
1035                 if( hashes & 16 )
1036                     buf[n++] = DIGEST_ALGO_SHA256;
1037                 if( hashes & 32 )
1038                     buf[n++] = DIGEST_ALGO_SHA384;
1039                 if( hashes & 64 )
1040                     buf[n++] = DIGEST_ALGO_SHA512;
1041                 buf[1] = n - 2;
1042
1043                 /* ...followed by an invented plaintext packet.
1044                    Amusingly enough, this packet is not compliant with
1045                    2440 as the initial partial length is less than 512
1046                    bytes.  Of course, we'll accept it anyway ;) */
1047
1048                 buf[n++] = 0xCB; /* new packet format, type 11 */
1049                 buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1050                 buf[n++] = 't';  /* canonical text mode */
1051                 buf[n++] = 0;    /* namelength */
1052                 buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1053                 memset(buf+n, 0, 4); /* timestamp */
1054                 n += 4;
1055             }
1056             else if( !rc )
1057                 rc = radix64_read( afx, a, &n, buf, size );
1058         }
1059         else
1060             rc = radix64_read( afx, a, &n, buf, size );
1061 #if 0
1062         if( n )
1063             if( fwrite(buf, n, 1, fp ) != 1 )
1064                 BUG();
1065 #endif
1066         *ret_len = n;
1067     }
1068     else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
1069         if( !afx->status ) { /* write the header line */
1070             const char *s;
1071             strlist_t comment=opt.comments;
1072
1073             if( afx->what >= DIM(head_strings) )
1074                 log_bug("afx->what=%d", afx->what);
1075             iobuf_writestr(a, "-----");
1076             iobuf_writestr(a, head_strings[afx->what] );
1077             iobuf_writestr(a, "-----" );
1078             iobuf_writestr(a,afx->eol);
1079             if (opt.emit_version)
1080               {
1081                 iobuf_writestr (a, "Version: GnuPG v");
1082                 for (s=VERSION; *s && *s != '.'; s++)
1083                   iobuf_writebyte (a, *s);
1084                 if (opt.emit_version > 1 && *s)
1085                   {
1086                     iobuf_writebyte (a, *s++);
1087                     for (; *s && *s != '.'; s++)
1088                       iobuf_writebyte (a, *s);
1089                     if (opt.emit_version > 2)
1090                       {
1091                         for (; *s && *s != '-' && !spacep (s); s++)
1092                           iobuf_writebyte (a, *s);
1093                         if (opt.emit_version > 3)
1094                           iobuf_writestr (a, " (" PRINTABLE_OS_NAME ")");
1095                       }
1096                   }
1097                 iobuf_writestr(a,afx->eol);
1098               }
1099
1100             /* write the comment strings */
1101             for(s=comment->d;comment;comment=comment->next,s=comment->d)
1102               {
1103                 iobuf_writestr(a, "Comment: " );
1104                 for( ; *s; s++ )
1105                   {
1106                     if( *s == '\n' )
1107                       iobuf_writestr(a, "\\n" );
1108                     else if( *s == '\r' )
1109                       iobuf_writestr(a, "\\r" );
1110                     else if( *s == '\v' )
1111                       iobuf_writestr(a, "\\v" );
1112                     else
1113                       iobuf_put(a, *s );
1114                   }
1115
1116                 iobuf_writestr(a,afx->eol);
1117               }
1118
1119             if ( afx->hdrlines ) {
1120                 for ( s = afx->hdrlines; *s; s++ ) {
1121 #ifdef HAVE_DOSISH_SYSTEM
1122                     if ( *s == '\n' )
1123                         iobuf_put( a, '\r');
1124 #endif
1125                     iobuf_put(a, *s );
1126                 }
1127             }
1128
1129             iobuf_writestr(a,afx->eol);
1130             afx->status++;
1131             afx->idx = 0;
1132             afx->idx2 = 0;
1133             afx->crc = CRCINIT;
1134
1135         }
1136         crc = afx->crc;
1137         idx = afx->idx;
1138         idx2 = afx->idx2;
1139         for(i=0; i < idx; i++ )
1140             radbuf[i] = afx->radbuf[i];
1141
1142         for(i=0; i < size; i++ )
1143             crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
1144         crc &= 0x00ffffff;
1145
1146         for( ; size; buf++, size-- ) {
1147             radbuf[idx++] = *buf;
1148             if( idx > 2 ) {
1149                 idx = 0;
1150                 c = bintoasc[(*radbuf >> 2) & 077];
1151                 iobuf_put(a, c);
1152                 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1153                 iobuf_put(a, c);
1154                 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1155                 iobuf_put(a, c);
1156                 c = bintoasc[radbuf[2]&077];
1157                 iobuf_put(a, c);
1158                 if( ++idx2 >= (64/4) )
1159                   { /* pgp doesn't like 72 here */
1160                     iobuf_writestr(a,afx->eol);
1161                     idx2=0;
1162                   }
1163             }
1164         }
1165         for(i=0; i < idx; i++ )
1166             afx->radbuf[i] = radbuf[i];
1167         afx->idx = idx;
1168         afx->idx2 = idx2;
1169         afx->crc  = crc;
1170     }
1171     else if( control == IOBUFCTRL_INIT )
1172       {
1173         if( !is_initialized )
1174           initialize();
1175
1176         /* Figure out what we're using for line endings if the caller
1177            didn't specify. */
1178         if(afx->eol[0]==0)
1179           {
1180 #ifdef HAVE_DOSISH_SYSTEM
1181             afx->eol[0]='\r';
1182             afx->eol[1]='\n';
1183 #else
1184             afx->eol[0]='\n';
1185 #endif
1186           }
1187       }
1188     else if( control == IOBUFCTRL_CANCEL ) {
1189         afx->cancel = 1;
1190     }
1191     else if( control == IOBUFCTRL_FREE ) {
1192         if( afx->cancel )
1193             ;
1194         else if( afx->status ) { /* pad, write cecksum, and bottom line */
1195             crc = afx->crc;
1196             idx = afx->idx;
1197             idx2 = afx->idx2;
1198             for(i=0; i < idx; i++ )
1199                 radbuf[i] = afx->radbuf[i];
1200             if( idx ) {
1201                 c = bintoasc[(*radbuf>>2)&077];
1202                 iobuf_put(a, c);
1203                 if( idx == 1 ) {
1204                     c = bintoasc[((*radbuf << 4) & 060) & 077];
1205                     iobuf_put(a, c);
1206                     iobuf_put(a, '=');
1207                     iobuf_put(a, '=');
1208                 }
1209                 else { /* 2 */
1210                     c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
1211                     iobuf_put(a, c);
1212                     c = bintoasc[((radbuf[1] << 2) & 074) & 077];
1213                     iobuf_put(a, c);
1214                     iobuf_put(a, '=');
1215                 }
1216                 if( ++idx2 >= (64/4) )
1217                   { /* pgp doesn't like 72 here */
1218                     iobuf_writestr(a,afx->eol);
1219                     idx2=0;
1220                   }
1221             }
1222             /* may need a linefeed */
1223             if( idx2 )
1224               iobuf_writestr(a,afx->eol);
1225             /* write the CRC */
1226             iobuf_put(a, '=');
1227             radbuf[0] = crc >>16;
1228             radbuf[1] = crc >> 8;
1229             radbuf[2] = crc;
1230             c = bintoasc[(*radbuf >> 2) & 077];
1231             iobuf_put(a, c);
1232             c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1233             iobuf_put(a, c);
1234             c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1235             iobuf_put(a, c);
1236             c = bintoasc[radbuf[2]&077];
1237             iobuf_put(a, c);
1238             iobuf_writestr(a,afx->eol);
1239             /* and the the trailer */
1240             if( afx->what >= DIM(tail_strings) )
1241                 log_bug("afx->what=%d", afx->what);
1242             iobuf_writestr(a, "-----");
1243             iobuf_writestr(a, tail_strings[afx->what] );
1244             iobuf_writestr(a, "-----" );
1245             iobuf_writestr(a,afx->eol);
1246         }
1247         else if( !afx->any_data && !afx->inp_bypass ) {
1248             log_error(_("no valid OpenPGP data found.\n"));
1249             afx->no_openpgp_data = 1;
1250             write_status_text( STATUS_NODATA, "1" );
1251         }
1252         if( afx->truncated )
1253             log_info(_("invalid armor: line longer than %d characters\n"),
1254                       MAX_LINELEN );
1255         /* issue an error to enforce dissemination of correct software */
1256         if( afx->qp_detected )
1257             log_error(_("quoted printable character in armor - "
1258                         "probably a buggy MTA has been used\n") );
1259         xfree( afx->buffer );
1260         afx->buffer = NULL;
1261         release_armor_context (afx);
1262     }
1263     else if( control == IOBUFCTRL_DESC )
1264         *(char**)buf = "armor_filter";
1265     return rc;
1266 }
1267
1268
1269 /****************
1270  * create a radix64 encoded string.
1271  */
1272 char *
1273 make_radix64_string( const byte *data, size_t len )
1274 {
1275     char *buffer, *p;
1276
1277     buffer = p = xmalloc( (len+2)/3*4 + 1 );
1278     for( ; len >= 3 ; len -= 3, data += 3 ) {
1279         *p++ = bintoasc[(data[0] >> 2) & 077];
1280         *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1281         *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
1282         *p++ = bintoasc[data[2]&077];
1283     }
1284     if( len == 2 ) {
1285         *p++ = bintoasc[(data[0] >> 2) & 077];
1286         *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1287         *p++ = bintoasc[((data[1]<<2)&074)];
1288     }
1289     else if( len == 1 ) {
1290         *p++ = bintoasc[(data[0] >> 2) & 077];
1291         *p++ = bintoasc[(data[0] <<4)&060];
1292     }
1293     *p = 0;
1294     return buffer;
1295 }
1296
1297
1298 /***********************************************
1299  *  For the pipemode command we can't use the armor filter for various
1300  *  reasons, so we use this new unarmor_pump stuff to remove the armor
1301  */
1302
1303 enum unarmor_state_e {
1304     STA_init = 0,
1305     STA_bypass,
1306     STA_wait_newline,
1307     STA_wait_dash,
1308     STA_first_dash,
1309     STA_compare_header,
1310     STA_found_header_wait_newline,
1311     STA_skip_header_lines,
1312     STA_skip_header_lines_non_ws,
1313     STA_read_data,
1314     STA_wait_crc,
1315     STA_read_crc,
1316     STA_ready
1317 };
1318
1319 struct unarmor_pump_s {
1320     enum unarmor_state_e state;
1321     byte val;
1322     int checkcrc;
1323     int pos;   /* counts from 0..3 */
1324     u32 crc;
1325     u32 mycrc; /* the one store in the data */
1326 };
1327
1328
1329
1330 UnarmorPump
1331 unarmor_pump_new (void)
1332 {
1333     UnarmorPump x;
1334
1335     if( !is_initialized )
1336         initialize();
1337     x = xmalloc_clear (sizeof *x);
1338     return x;
1339 }
1340
1341 void
1342 unarmor_pump_release (UnarmorPump x)
1343 {
1344     xfree (x);
1345 }
1346
1347 /*
1348  * Get the next character from the ascii armor taken from the IOBUF
1349  * created earlier by unarmor_pump_new().
1350  * Return:  c = Character
1351  *        256 = ignore this value
1352  *         -1 = End of current armor
1353  *         -2 = Premature EOF (not used)
1354  *         -3 = Invalid armor
1355  */
1356 int
1357 unarmor_pump (UnarmorPump x, int c)
1358 {
1359     int rval = 256; /* default is to ignore the return value */
1360
1361     switch (x->state) {
1362       case STA_init:
1363         {
1364             byte tmp[1];
1365             tmp[0] = c;
1366             if ( is_armored (tmp) )
1367                 x->state = c == '-'? STA_first_dash : STA_wait_newline;
1368             else {
1369                 x->state = STA_bypass;
1370                 return c;
1371             }
1372         }
1373         break;
1374       case STA_bypass:
1375         return c; /* return here to avoid crc calculation */
1376       case STA_wait_newline:
1377         if (c == '\n')
1378             x->state = STA_wait_dash;
1379         break;
1380       case STA_wait_dash:
1381         x->state = c == '-'? STA_first_dash : STA_wait_newline;
1382         break;
1383       case STA_first_dash: /* just need for initalization */
1384         x->pos = 0;
1385         x->state = STA_compare_header;
1386       case STA_compare_header:
1387         if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) {
1388             if ( x->pos == 28 )
1389                 x->state = STA_found_header_wait_newline;
1390         }
1391         else
1392             x->state = c == '\n'? STA_wait_dash : STA_wait_newline;
1393         break;
1394       case STA_found_header_wait_newline:
1395         /* to make CR,LF issues easier we simply allow for white space
1396            behind the 5 dashes */
1397         if ( c == '\n' )
1398             x->state = STA_skip_header_lines;
1399         else if ( c != '\r' && c != ' ' && c != '\t' )
1400             x->state = STA_wait_dash; /* garbage after the header line */
1401         break;
1402       case STA_skip_header_lines:
1403         /* i.e. wait for one empty line */
1404         if ( c == '\n' ) {
1405             x->state = STA_read_data;
1406             x->crc = CRCINIT;
1407             x->val = 0;
1408             x->pos = 0;
1409         }
1410         else if ( c != '\r' && c != ' ' && c != '\t' )
1411             x->state = STA_skip_header_lines_non_ws;
1412         break;
1413       case STA_skip_header_lines_non_ws:
1414         /* like above but we already encountered non white space */
1415         if ( c == '\n' )
1416             x->state = STA_skip_header_lines;
1417         break;
1418       case STA_read_data:
1419         /* fixme: we don't check for the trailing dash lines but rely
1420          * on the armor stop characters */
1421         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
1422             break; /* skip all kind of white space */
1423
1424         if( c == '=' ) { /* pad character: stop */
1425             if( x->pos == 1 ) /* in this case val has some value */
1426                 rval = x->val;
1427             x->state = STA_wait_crc;
1428             break;
1429         }
1430
1431         {
1432             int c2;
1433             if( (c = asctobin[(c2=c)]) == 255 ) {
1434                 log_error(_("invalid radix64 character %02X skipped\n"), c2);
1435                 break;
1436             }
1437         }
1438
1439         switch(x->pos) {
1440           case 0:
1441             x->val = c << 2;
1442             break;
1443           case 1:
1444             x->val |= (c>>4)&3;
1445             rval = x->val;
1446             x->val = (c<<4)&0xf0;
1447             break;
1448           case 2:
1449             x->val |= (c>>2)&15;
1450             rval = x->val;
1451             x->val = (c<<6)&0xc0;
1452             break;
1453           case 3:
1454             x->val |= c&0x3f;
1455             rval = x->val;
1456             break;
1457         }
1458         x->pos = (x->pos+1) % 4;
1459         break;
1460       case STA_wait_crc:
1461         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' || c == '=' )
1462             break; /* skip ws and pad characters */
1463         /* assume that we are at the next line */
1464         x->state = STA_read_crc;
1465         x->pos = 0;
1466         x->mycrc = 0;
1467       case STA_read_crc:
1468         if( (c = asctobin[c]) == 255 ) {
1469             rval = -1; /* ready */
1470             if( x->crc != x->mycrc ) {
1471                 log_info (_("CRC error; %06lX - %06lX\n"),
1472                           (ulong)x->crc, (ulong)x->mycrc);
1473                 if ( invalid_crc() )
1474                     rval = -3;
1475             }
1476             x->state = STA_ready; /* not sure whether this is correct */
1477             break;
1478         }
1479
1480         switch(x->pos) {
1481           case 0:
1482             x->val = c << 2;
1483             break;
1484           case 1:
1485             x->val |= (c>>4)&3;
1486             x->mycrc |= x->val << 16;
1487             x->val = (c<<4)&0xf0;
1488             break;
1489           case 2:
1490             x->val |= (c>>2)&15;
1491             x->mycrc |= x->val << 8;
1492             x->val = (c<<6)&0xc0;
1493             break;
1494           case 3:
1495             x->val |= c&0x3f;
1496             x->mycrc |= x->val;
1497             break;
1498         }
1499         x->pos = (x->pos+1) % 4;
1500         break;
1501       case STA_ready:
1502         rval = -1;
1503         break;
1504     }
1505
1506     if ( !(rval & ~255) ) { /* compute the CRC */
1507         x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval];
1508         x->crc &= 0x00ffffff;
1509     }
1510
1511     return rval;
1512 }