Nuked almost all trailing white space.
[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     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         es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
420         log_printf ("\n");
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         es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
431         log_printf ("\n");
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         es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
457         log_printf ("\n");
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                         es_write_sanitized (log_get_stream (), p, n,
645                                             NULL, NULL);
646                         log_printf ("\n");
647                       }
648
649                     lastline = 1;
650                     rc = -1;
651                   }
652               }
653             else if(!afx->not_dash_escaped)
654               {
655                 /* Bad dash-escaping. */
656                 log_info (_("invalid dash escaped line: "));
657                 es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
658                 log_printf ("\n");
659               }
660           }
661
662         /* Now handle the end-of-line canonicalization */
663         if( !afx->not_dash_escaped )
664           {
665             int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
666
667             /* PGP2 does not treat a tab as white space character */
668             afx->buffer_len=
669               trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
670                                    afx->pgp2mode ? " \r\n" : " \t\r\n");
671             afx->buffer_len+=afx->buffer_pos;
672             /* the buffer is always allocated with enough space to append
673              * the removed [CR], LF and a Nul
674              * The reason for this complicated procedure is to keep at least
675              * the original type of lineending - handling of the removed
676              * trailing spaces seems to be impossible in our method
677              * of faking a packet; either we have to use a temporary file
678              * or calculate the hash here in this module and somehow find
679              * a way to send the hash down the processing line (well, a special
680              * faked packet could do the job).
681              */
682             if( crlf )
683               afx->buffer[afx->buffer_len++] = '\r';
684             afx->buffer[afx->buffer_len++] = '\n';
685             afx->buffer[afx->buffer_len] = '\0';
686           }
687     }
688
689     if( lastline ) { /* write last (ending) length header */
690         if(tempbuf_len<192)
691           buf[len++]=tempbuf_len;
692         else
693           {
694             buf[len++]=((tempbuf_len-192)/256) + 192;
695             buf[len++]=(tempbuf_len-192) % 256;
696           }
697         memcpy(&buf[len],tempbuf,tempbuf_len);
698         len+=tempbuf_len;
699
700         rc = 0;
701         afx->faked = 0;
702         afx->in_cleartext = 0;
703         /* and now read the header lines */
704         afx->buffer_pos = 0;
705         for(;;) {
706             int i;
707
708             /* read the next line (skip all truncated lines) */
709             do {
710                 maxlen = MAX_LINELEN;
711                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
712                                                  &afx->buffer_size, &maxlen );
713             } while( !maxlen );
714             p = afx->buffer;
715             n = afx->buffer_len;
716             if( !n ) {
717                 rc = -1;
718                 break; /* eof */
719             }
720             i = parse_header_line( afx, p , n );
721             if( i <= 0 ) {
722                 if( i )
723                     invalid_armor();
724                 break;
725             }
726         }
727         afx->inp_checked = 1;
728         afx->crc = CRCINIT;
729         afx->idx = 0;
730         afx->radbuf[0] = 0;
731     }
732
733     *retn = len;
734     return rc;
735 }
736
737
738 static int
739 invalid_crc(void)
740 {
741   if ( opt.ignore_crc_error )
742     return 0;
743   log_inc_errorcount();
744   return gpg_error (GPG_ERR_INV_ARMOR);
745 }
746
747
748 static int
749 radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
750               byte *buf, size_t size )
751 {
752     byte val;
753     int c=0, c2; /*init c because gcc is not clever enough for the continue*/
754     int checkcrc=0;
755     int rc = 0;
756     size_t n = 0;
757     int  idx, i, onlypad=0;
758     u32 crc;
759
760     crc = afx->crc;
761     idx = afx->idx;
762     val = afx->radbuf[0];
763     for( n=0; n < size; ) {
764
765         if( afx->buffer_pos < afx->buffer_len )
766             c = afx->buffer[afx->buffer_pos++];
767         else { /* read the next line */
768             unsigned maxlen = MAX_LINELEN;
769             afx->buffer_pos = 0;
770             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
771                                                &afx->buffer_size, &maxlen );
772             if( !maxlen )
773                 afx->truncated++;
774             if( !afx->buffer_len )
775                 break; /* eof */
776             continue;
777         }
778
779       again:
780         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
781             continue;
782         else if( c == '=' ) { /* pad character: stop */
783             /* some mailers leave quoted-printable encoded characters
784              * so we try to workaround this */
785             if( afx->buffer_pos+2 < afx->buffer_len ) {
786                 int cc1, cc2, cc3;
787                 cc1 = afx->buffer[afx->buffer_pos];
788                 cc2 = afx->buffer[afx->buffer_pos+1];
789                 cc3 = afx->buffer[afx->buffer_pos+2];
790                 if( isxdigit(cc1) && isxdigit(cc2)
791                                   && strchr( "=\n\r\t ", cc3 )) {
792                     /* well it seems to be the case - adjust */
793                     c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
794                     c <<= 4;
795                     c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
796                     afx->buffer_pos += 2;
797                     afx->qp_detected = 1;
798                     goto again;
799                 }
800             }
801
802             if (!n)
803               onlypad = 1;
804
805             if( idx == 1 )
806                 buf[n++] = val;
807             checkcrc++;
808             break;
809         }
810         else if( (c = asctobin[(c2=c)]) == 255 ) {
811             log_error(_("invalid radix64 character %02X skipped\n"), c2);
812             continue;
813         }
814         switch(idx) {
815           case 0: val =  c << 2; break;
816           case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break;
817           case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break;
818           case 3: val |= c&0x3f; buf[n++] = val; break;
819         }
820         idx = (idx+1) % 4;
821     }
822
823     for(i=0; i < n; i++ )
824         crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
825     crc &= 0x00ffffff;
826     afx->crc = crc;
827     afx->idx = idx;
828     afx->radbuf[0] = val;
829
830     if( checkcrc ) {
831         afx->any_data = 1;
832         afx->inp_checked=0;
833         afx->faked = 0;
834         for(;;) { /* skip lf and pad characters */
835             if( afx->buffer_pos < afx->buffer_len )
836                 c = afx->buffer[afx->buffer_pos++];
837             else { /* read the next line */
838                 unsigned maxlen = MAX_LINELEN;
839                 afx->buffer_pos = 0;
840                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
841                                                    &afx->buffer_size, &maxlen );
842                 if( !maxlen )
843                     afx->truncated++;
844                 if( !afx->buffer_len )
845                     break; /* eof */
846                 continue;
847             }
848             if( c == '\n' || c == ' ' || c == '\r'
849                 || c == '\t' || c == '=' )
850                 continue;
851             break;
852         }
853         if( c == -1 )
854             log_error(_("premature eof (no CRC)\n"));
855         else {
856             u32 mycrc = 0;
857             idx = 0;
858             do {
859                 if( (c = asctobin[c]) == 255 )
860                     break;
861                 switch(idx) {
862                   case 0: val =  c << 2; break;
863                   case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break;
864                   case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break;
865                   case 3: val |= c&0x3f; mycrc |= val; break;
866                 }
867                 for(;;) {
868                     if( afx->buffer_pos < afx->buffer_len )
869                         c = afx->buffer[afx->buffer_pos++];
870                     else { /* read the next line */
871                         unsigned maxlen = MAX_LINELEN;
872                         afx->buffer_pos = 0;
873                         afx->buffer_len = iobuf_read_line( a, &afx->buffer,
874                                                            &afx->buffer_size,
875                                                                 &maxlen );
876                         if( !maxlen )
877                             afx->truncated++;
878                         if( !afx->buffer_len )
879                             break; /* eof */
880                         continue;
881                     }
882                     break;
883                 }
884                 if( !afx->buffer_len )
885                     break; /* eof */
886             } while( ++idx < 4 );
887             if( c == -1 ) {
888                 log_info(_("premature eof (in CRC)\n"));
889                 rc = invalid_crc();
890             }
891             else if( idx == 0 ) {
892                 /* No CRC at all is legal ("MAY") */
893                 rc=0;
894             }
895             else if( idx != 4 ) {
896                 log_info(_("malformed CRC\n"));
897                 rc = invalid_crc();
898             }
899             else if( mycrc != afx->crc ) {
900                 log_info (_("CRC error; %06lX - %06lX\n"),
901                                     (ulong)afx->crc, (ulong)mycrc);
902                 rc = invalid_crc();
903             }
904             else {
905                 rc = 0;
906                 /* FIXME: Here we should emit another control packet,
907                  * so that we know in mainproc that we are processing
908                  * a clearsign message */
909 #if 0
910                 for(rc=0;!rc;) {
911                     rc = 0 /*check_trailer( &fhdr, c )*/;
912                     if( !rc ) {
913                         if( (c=iobuf_get(a)) == -1 )
914                             rc = 2;
915                     }
916                 }
917                 if( rc == -1 )
918                     rc = 0;
919                 else if( rc == 2 ) {
920                     log_error(_("premature eof (in trailer)\n"));
921                     rc = G10ERR_INVALID_ARMOR;
922                 }
923                 else {
924                     log_error(_("error in trailer line\n"));
925                     rc = G10ERR_INVALID_ARMOR;
926                 }
927 #endif
928             }
929         }
930     }
931
932     if( !n && !onlypad )
933         rc = -1;
934
935     *retn = n;
936     return rc;
937 }
938
939 /****************
940  * This filter is used to handle the armor stuff
941  */
942 static int
943 armor_filter( void *opaque, int control,
944              IOBUF a, byte *buf, size_t *ret_len)
945 {
946     size_t size = *ret_len;
947     armor_filter_context_t *afx = opaque;
948     int rc=0, i, c;
949     byte radbuf[3];
950     int  idx, idx2;
951     size_t n=0;
952     u32 crc;
953 #if 0
954     static FILE *fp ;
955
956     if( !fp ) {
957         fp = fopen("armor.out", "w");
958         assert(fp);
959     }
960 #endif
961
962     if( DBG_FILTER )
963         log_debug("armor-filter: control: %d\n", control );
964     if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
965         n = 0;
966         if( afx->buffer_len ) {
967             for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
968                 buf[n++] = afx->buffer[afx->buffer_pos++];
969             if( afx->buffer_pos >= afx->buffer_len )
970                 afx->buffer_len = 0;
971         }
972         for(; n < size; n++ ) {
973             if( (c=iobuf_get(a)) == -1 )
974                 break;
975             buf[n] = c & 0xff;
976         }
977         if( !n )
978             rc = -1;
979         *ret_len = n;
980     }
981     else if( control == IOBUFCTRL_UNDERFLOW ) {
982         /* We need some space for the faked packet.  The minmum
983          * required size is the PARTIAL_CHUNK size plus a byte for the
984          * length itself */
985         if( size < PARTIAL_CHUNK+1 )
986             BUG(); /* supplied buffer too short */
987
988         if( afx->faked )
989             rc = fake_packet( afx, a, &n, buf, size );
990         else if( !afx->inp_checked ) {
991             rc = check_input( afx, a );
992             if( afx->inp_bypass ) {
993                 for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
994                     buf[n++] = afx->buffer[afx->buffer_pos++];
995                 if( afx->buffer_pos >= afx->buffer_len )
996                     afx->buffer_len = 0;
997                 if( !n )
998                     rc = -1;
999             }
1000             else if( afx->faked ) {
1001                 unsigned int hashes = afx->hashes;
1002                 const byte *sesmark;
1003                 size_t sesmarklen;
1004
1005                 sesmark = get_session_marker( &sesmarklen );
1006                 if ( sesmarklen > 20 )
1007                     BUG();
1008
1009                 /* the buffer is at least 15+n*15 bytes long, so it
1010                  * is easy to construct the packets */
1011
1012                 hashes &= 1|2|4|8|16|32|64;
1013                 if( !hashes ) {
1014                     hashes |= 4;  /* default to MD 5 */
1015                     /* This is non-ideal since PGP 5-8 have the same
1016                        end-of-line bugs as PGP 2. However, we only
1017                        enable pgp2mode if there is no Hash: header. */
1018                     if( opt.pgp2_workarounds )
1019                         afx->pgp2mode = 1;
1020                 }
1021                 n=0;
1022                 /* First a gpg control packet... */
1023                 buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1024                 n++;   /* see below */
1025                 memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1026                 buf[n++] = CTRLPKT_CLEARSIGN_START;
1027                 buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1028                 if( hashes & 1 )
1029                     buf[n++] = DIGEST_ALGO_RMD160;
1030                 if( hashes & 2 )
1031                     buf[n++] = DIGEST_ALGO_SHA1;
1032                 if( hashes & 4 )
1033                     buf[n++] = DIGEST_ALGO_MD5;
1034                 if( hashes & 8 )
1035                     buf[n++] = DIGEST_ALGO_SHA224;
1036                 if( hashes & 16 )
1037                     buf[n++] = DIGEST_ALGO_SHA256;
1038                 if( hashes & 32 )
1039                     buf[n++] = DIGEST_ALGO_SHA384;
1040                 if( hashes & 64 )
1041                     buf[n++] = DIGEST_ALGO_SHA512;
1042                 buf[1] = n - 2;
1043
1044                 /* ...followed by an invented plaintext packet.
1045                    Amusingly enough, this packet is not compliant with
1046                    2440 as the initial partial length is less than 512
1047                    bytes.  Of course, we'll accept it anyway ;) */
1048
1049                 buf[n++] = 0xCB; /* new packet format, type 11 */
1050                 buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1051                 buf[n++] = 't';  /* canonical text mode */
1052                 buf[n++] = 0;    /* namelength */
1053                 buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1054                 memset(buf+n, 0, 4); /* timestamp */
1055                 n += 4;
1056             }
1057             else if( !rc )
1058                 rc = radix64_read( afx, a, &n, buf, size );
1059         }
1060         else
1061             rc = radix64_read( afx, a, &n, buf, size );
1062 #if 0
1063         if( n )
1064             if( fwrite(buf, n, 1, fp ) != 1 )
1065                 BUG();
1066 #endif
1067         *ret_len = n;
1068     }
1069     else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
1070         if( !afx->status ) { /* write the header line */
1071             const char *s;
1072             strlist_t comment=opt.comments;
1073
1074             if( afx->what >= DIM(head_strings) )
1075                 log_bug("afx->what=%d", afx->what);
1076             iobuf_writestr(a, "-----");
1077             iobuf_writestr(a, head_strings[afx->what] );
1078             iobuf_writestr(a, "-----" );
1079             iobuf_writestr(a,afx->eol);
1080             if( !opt.no_version )
1081               {
1082                 iobuf_writestr(a, "Version: GnuPG v"  VERSION " ("
1083                                PRINTABLE_OS_NAME ")" );
1084                 iobuf_writestr(a,afx->eol);
1085               }
1086
1087             /* write the comment strings */
1088             for(s=comment->d;comment;comment=comment->next,s=comment->d)
1089               {
1090                 iobuf_writestr(a, "Comment: " );
1091                 for( ; *s; s++ )
1092                   {
1093                     if( *s == '\n' )
1094                       iobuf_writestr(a, "\\n" );
1095                     else if( *s == '\r' )
1096                       iobuf_writestr(a, "\\r" );
1097                     else if( *s == '\v' )
1098                       iobuf_writestr(a, "\\v" );
1099                     else
1100                       iobuf_put(a, *s );
1101                   }
1102
1103                 iobuf_writestr(a,afx->eol);
1104               }
1105
1106             if ( afx->hdrlines ) {
1107                 for ( s = afx->hdrlines; *s; s++ ) {
1108 #ifdef HAVE_DOSISH_SYSTEM
1109                     if ( *s == '\n' )
1110                         iobuf_put( a, '\r');
1111 #endif
1112                     iobuf_put(a, *s );
1113                 }
1114             }
1115
1116             iobuf_writestr(a,afx->eol);
1117             afx->status++;
1118             afx->idx = 0;
1119             afx->idx2 = 0;
1120             afx->crc = CRCINIT;
1121
1122         }
1123         crc = afx->crc;
1124         idx = afx->idx;
1125         idx2 = afx->idx2;
1126         for(i=0; i < idx; i++ )
1127             radbuf[i] = afx->radbuf[i];
1128
1129         for(i=0; i < size; i++ )
1130             crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
1131         crc &= 0x00ffffff;
1132
1133         for( ; size; buf++, size-- ) {
1134             radbuf[idx++] = *buf;
1135             if( idx > 2 ) {
1136                 idx = 0;
1137                 c = bintoasc[(*radbuf >> 2) & 077];
1138                 iobuf_put(a, c);
1139                 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1140                 iobuf_put(a, c);
1141                 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1142                 iobuf_put(a, c);
1143                 c = bintoasc[radbuf[2]&077];
1144                 iobuf_put(a, c);
1145                 if( ++idx2 >= (64/4) )
1146                   { /* pgp doesn't like 72 here */
1147                     iobuf_writestr(a,afx->eol);
1148                     idx2=0;
1149                   }
1150             }
1151         }
1152         for(i=0; i < idx; i++ )
1153             afx->radbuf[i] = radbuf[i];
1154         afx->idx = idx;
1155         afx->idx2 = idx2;
1156         afx->crc  = crc;
1157     }
1158     else if( control == IOBUFCTRL_INIT )
1159       {
1160         if( !is_initialized )
1161           initialize();
1162
1163         /* Figure out what we're using for line endings if the caller
1164            didn't specify. */
1165         if(afx->eol[0]==0)
1166           {
1167 #ifdef HAVE_DOSISH_SYSTEM
1168             afx->eol[0]='\r';
1169             afx->eol[1]='\n';
1170 #else
1171             afx->eol[0]='\n';
1172 #endif
1173           }
1174       }
1175     else if( control == IOBUFCTRL_CANCEL ) {
1176         afx->cancel = 1;
1177     }
1178     else if( control == IOBUFCTRL_FREE ) {
1179         if( afx->cancel )
1180             ;
1181         else if( afx->status ) { /* pad, write cecksum, and bottom line */
1182             crc = afx->crc;
1183             idx = afx->idx;
1184             idx2 = afx->idx2;
1185             for(i=0; i < idx; i++ )
1186                 radbuf[i] = afx->radbuf[i];
1187             if( idx ) {
1188                 c = bintoasc[(*radbuf>>2)&077];
1189                 iobuf_put(a, c);
1190                 if( idx == 1 ) {
1191                     c = bintoasc[((*radbuf << 4) & 060) & 077];
1192                     iobuf_put(a, c);
1193                     iobuf_put(a, '=');
1194                     iobuf_put(a, '=');
1195                 }
1196                 else { /* 2 */
1197                     c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077];
1198                     iobuf_put(a, c);
1199                     c = bintoasc[((radbuf[1] << 2) & 074) & 077];
1200                     iobuf_put(a, c);
1201                     iobuf_put(a, '=');
1202                 }
1203                 if( ++idx2 >= (64/4) )
1204                   { /* pgp doesn't like 72 here */
1205                     iobuf_writestr(a,afx->eol);
1206                     idx2=0;
1207                   }
1208             }
1209             /* may need a linefeed */
1210             if( idx2 )
1211               iobuf_writestr(a,afx->eol);
1212             /* write the CRC */
1213             iobuf_put(a, '=');
1214             radbuf[0] = crc >>16;
1215             radbuf[1] = crc >> 8;
1216             radbuf[2] = crc;
1217             c = bintoasc[(*radbuf >> 2) & 077];
1218             iobuf_put(a, c);
1219             c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1220             iobuf_put(a, c);
1221             c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1222             iobuf_put(a, c);
1223             c = bintoasc[radbuf[2]&077];
1224             iobuf_put(a, c);
1225             iobuf_writestr(a,afx->eol);
1226             /* and the the trailer */
1227             if( afx->what >= DIM(tail_strings) )
1228                 log_bug("afx->what=%d", afx->what);
1229             iobuf_writestr(a, "-----");
1230             iobuf_writestr(a, tail_strings[afx->what] );
1231             iobuf_writestr(a, "-----" );
1232             iobuf_writestr(a,afx->eol);
1233         }
1234         else if( !afx->any_data && !afx->inp_bypass ) {
1235             log_error(_("no valid OpenPGP data found.\n"));
1236             afx->no_openpgp_data = 1;
1237             write_status_text( STATUS_NODATA, "1" );
1238         }
1239         if( afx->truncated )
1240             log_info(_("invalid armor: line longer than %d characters\n"),
1241                       MAX_LINELEN );
1242         /* issue an error to enforce dissemination of correct software */
1243         if( afx->qp_detected )
1244             log_error(_("quoted printable character in armor - "
1245                         "probably a buggy MTA has been used\n") );
1246         xfree( afx->buffer );
1247         afx->buffer = NULL;
1248         release_armor_context (afx);
1249     }
1250     else if( control == IOBUFCTRL_DESC )
1251         *(char**)buf = "armor_filter";
1252     return rc;
1253 }
1254
1255
1256 /****************
1257  * create a radix64 encoded string.
1258  */
1259 char *
1260 make_radix64_string( const byte *data, size_t len )
1261 {
1262     char *buffer, *p;
1263
1264     buffer = p = xmalloc( (len+2)/3*4 + 1 );
1265     for( ; len >= 3 ; len -= 3, data += 3 ) {
1266         *p++ = bintoasc[(data[0] >> 2) & 077];
1267         *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1268         *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
1269         *p++ = bintoasc[data[2]&077];
1270     }
1271     if( len == 2 ) {
1272         *p++ = bintoasc[(data[0] >> 2) & 077];
1273         *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1274         *p++ = bintoasc[((data[1]<<2)&074)];
1275     }
1276     else if( len == 1 ) {
1277         *p++ = bintoasc[(data[0] >> 2) & 077];
1278         *p++ = bintoasc[(data[0] <<4)&060];
1279     }
1280     *p = 0;
1281     return buffer;
1282 }
1283
1284
1285 /***********************************************
1286  *  For the pipemode command we can't use the armor filter for various
1287  *  reasons, so we use this new unarmor_pump stuff to remove the armor
1288  */
1289
1290 enum unarmor_state_e {
1291     STA_init = 0,
1292     STA_bypass,
1293     STA_wait_newline,
1294     STA_wait_dash,
1295     STA_first_dash,
1296     STA_compare_header,
1297     STA_found_header_wait_newline,
1298     STA_skip_header_lines,
1299     STA_skip_header_lines_non_ws,
1300     STA_read_data,
1301     STA_wait_crc,
1302     STA_read_crc,
1303     STA_ready
1304 };
1305
1306 struct unarmor_pump_s {
1307     enum unarmor_state_e state;
1308     byte val;
1309     int checkcrc;
1310     int pos;   /* counts from 0..3 */
1311     u32 crc;
1312     u32 mycrc; /* the one store in the data */
1313 };
1314
1315
1316
1317 UnarmorPump
1318 unarmor_pump_new (void)
1319 {
1320     UnarmorPump x;
1321
1322     if( !is_initialized )
1323         initialize();
1324     x = xmalloc_clear (sizeof *x);
1325     return x;
1326 }
1327
1328 void
1329 unarmor_pump_release (UnarmorPump x)
1330 {
1331     xfree (x);
1332 }
1333
1334 /*
1335  * Get the next character from the ascii armor taken from the IOBUF
1336  * created earlier by unarmor_pump_new().
1337  * Return:  c = Character
1338  *        256 = ignore this value
1339  *         -1 = End of current armor
1340  *         -2 = Premature EOF (not used)
1341  *         -3 = Invalid armor
1342  */
1343 int
1344 unarmor_pump (UnarmorPump x, int c)
1345 {
1346     int rval = 256; /* default is to ignore the return value */
1347
1348     switch (x->state) {
1349       case STA_init:
1350         {
1351             byte tmp[1];
1352             tmp[0] = c;
1353             if ( is_armored (tmp) )
1354                 x->state = c == '-'? STA_first_dash : STA_wait_newline;
1355             else {
1356                 x->state = STA_bypass;
1357                 return c;
1358             }
1359         }
1360         break;
1361       case STA_bypass:
1362         return c; /* return here to avoid crc calculation */
1363       case STA_wait_newline:
1364         if (c == '\n')
1365             x->state = STA_wait_dash;
1366         break;
1367       case STA_wait_dash:
1368         x->state = c == '-'? STA_first_dash : STA_wait_newline;
1369         break;
1370       case STA_first_dash: /* just need for initalization */
1371         x->pos = 0;
1372         x->state = STA_compare_header;
1373       case STA_compare_header:
1374         if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) {
1375             if ( x->pos == 28 )
1376                 x->state = STA_found_header_wait_newline;
1377         }
1378         else
1379             x->state = c == '\n'? STA_wait_dash : STA_wait_newline;
1380         break;
1381       case STA_found_header_wait_newline:
1382         /* to make CR,LF issues easier we simply allow for white space
1383            behind the 5 dashes */
1384         if ( c == '\n' )
1385             x->state = STA_skip_header_lines;
1386         else if ( c != '\r' && c != ' ' && c != '\t' )
1387             x->state = STA_wait_dash; /* garbage after the header line */
1388         break;
1389       case STA_skip_header_lines:
1390         /* i.e. wait for one empty line */
1391         if ( c == '\n' ) {
1392             x->state = STA_read_data;
1393             x->crc = CRCINIT;
1394             x->val = 0;
1395             x->pos = 0;
1396         }
1397         else if ( c != '\r' && c != ' ' && c != '\t' )
1398             x->state = STA_skip_header_lines_non_ws;
1399         break;
1400       case STA_skip_header_lines_non_ws:
1401         /* like above but we already encountered non white space */
1402         if ( c == '\n' )
1403             x->state = STA_skip_header_lines;
1404         break;
1405       case STA_read_data:
1406         /* fixme: we don't check for the trailing dash lines but rely
1407          * on the armor stop characters */
1408         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
1409             break; /* skip all kind of white space */
1410
1411         if( c == '=' ) { /* pad character: stop */
1412             if( x->pos == 1 ) /* in this case val has some value */
1413                 rval = x->val;
1414             x->state = STA_wait_crc;
1415             break;
1416         }
1417
1418         {
1419             int c2;
1420             if( (c = asctobin[(c2=c)]) == 255 ) {
1421                 log_error(_("invalid radix64 character %02X skipped\n"), c2);
1422                 break;
1423             }
1424         }
1425
1426         switch(x->pos) {
1427           case 0:
1428             x->val = c << 2;
1429             break;
1430           case 1:
1431             x->val |= (c>>4)&3;
1432             rval = x->val;
1433             x->val = (c<<4)&0xf0;
1434             break;
1435           case 2:
1436             x->val |= (c>>2)&15;
1437             rval = x->val;
1438             x->val = (c<<6)&0xc0;
1439             break;
1440           case 3:
1441             x->val |= c&0x3f;
1442             rval = x->val;
1443             break;
1444         }
1445         x->pos = (x->pos+1) % 4;
1446         break;
1447       case STA_wait_crc:
1448         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' || c == '=' )
1449             break; /* skip ws and pad characters */
1450         /* assume that we are at the next line */
1451         x->state = STA_read_crc;
1452         x->pos = 0;
1453         x->mycrc = 0;
1454       case STA_read_crc:
1455         if( (c = asctobin[c]) == 255 ) {
1456             rval = -1; /* ready */
1457             if( x->crc != x->mycrc ) {
1458                 log_info (_("CRC error; %06lX - %06lX\n"),
1459                           (ulong)x->crc, (ulong)x->mycrc);
1460                 if ( invalid_crc() )
1461                     rval = -3;
1462             }
1463             x->state = STA_ready; /* not sure whether this is correct */
1464             break;
1465         }
1466
1467         switch(x->pos) {
1468           case 0:
1469             x->val = c << 2;
1470             break;
1471           case 1:
1472             x->val |= (c>>4)&3;
1473             x->mycrc |= x->val << 16;
1474             x->val = (c<<4)&0xf0;
1475             break;
1476           case 2:
1477             x->val |= (c>>2)&15;
1478             x->mycrc |= x->val << 8;
1479             x->val = (c<<6)&0xc0;
1480             break;
1481           case 3:
1482             x->val |= c&0x3f;
1483             x->mycrc |= x->val;
1484             break;
1485         }
1486         x->pos = (x->pos+1) % 4;
1487         break;
1488       case STA_ready:
1489         rval = -1;
1490         break;
1491     }
1492
1493     if ( !(rval & ~255) ) { /* compute the CRC */
1494         x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval];
1495         x->crc &= 0x00ffffff;
1496     }
1497
1498     return rval;
1499 }