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