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