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