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