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 
112 /* Create a new context for armor filters.  */
113 armor_filter_context_t *
new_armor_context(void)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
release_armor_context(armor_filter_context_t * afx)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
push_armor_filter(armor_filter_context_t * afx,iobuf_t iobuf)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
initialize(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
get_afx_crc(armor_filter_context_t * afx)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
is_armored(const byte * buf)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
use_armor_filter(IOBUF a)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
invalid_armor(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
parse_hash_header(const char * line)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
is_armor_tag(const char * line)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
is_armor_header(byte * line,unsigned len)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
parse_header_line(armor_filter_context_t * afx,byte * line,unsigned int len)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
check_input(armor_filter_context_t * afx,IOBUF a)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
fake_packet(armor_filter_context_t * afx,IOBUF a,size_t * retn,byte * buf,size_t size)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
invalid_crc(void)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
radix64_read(armor_filter_context_t * afx,IOBUF a,size_t * retn,byte * buf,size_t size)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
armor_output_buf_as_radix64(armor_filter_context_t * afx,IOBUF a,byte * buf,size_t size)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
armor_filter(void * opaque,int control,IOBUF a,byte * buf,size_t * ret_len)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 *
make_radix64_string(const byte * data,size_t len)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 }
1562