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