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