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