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