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