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