1 /* armor.c - Armor flter
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 * 2007 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 3 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, see <https://www.gnu.org/licenses/>.
39 #define MAX_LINELEN 20000
41 #define CRCINIT 0xB704CE
42 #define CRCPOLY 0X864CFB
43 #define CRCUPDATE(a,c) do { \
44 a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \
47 static u32 crc_table[256];
48 static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
49 "abcdefghijklmnopqrstuvwxyz"
51 static byte asctobin[256]; /* runtime initialized */
52 static int is_initialized;
72 fhdrCHECKDashEscaped2,
73 fhdrCHECKDashEscaped3,
79 fhdrCLEARSIGSimpleNext,
88 /* if we encounter this armor string with this index, go
89 * into a mode which fakes packets and wait for the next armor */
90 #define BEGIN_SIGNATURE 2
91 #define BEGIN_SIGNED_MSG_IDX 3
92 static char *head_strings[] = {
94 "BEGIN PGP PUBLIC KEY BLOCK",
95 "BEGIN PGP SIGNATURE",
96 "BEGIN PGP SIGNED MESSAGE",
97 "BEGIN PGP ARMORED FILE", /* gnupg extension */
98 "BEGIN PGP PRIVATE KEY BLOCK",
99 "BEGIN PGP SECRET KEY BLOCK", /* only used by pgp2 */
102 static char *tail_strings[] = {
104 "END PGP PUBLIC KEY BLOCK",
107 "END PGP ARMORED FILE",
108 "END PGP PRIVATE KEY BLOCK",
109 "END PGP SECRET KEY BLOCK",
114 static int armor_filter ( void *opaque, int control,
115 iobuf_t chain, byte *buf, size_t *ret_len);
120 /* Create a new context for armor filters. */
121 armor_filter_context_t *
122 new_armor_context (void)
124 armor_filter_context_t *afx;
126 afx = xcalloc (1, sizeof *afx);
132 /* Release an armor filter context. Passing NULL is explicitly
133 allowed and a no-op. */
135 release_armor_context (armor_filter_context_t *afx)
139 log_assert (afx->refcount);
140 if ( --afx->refcount )
145 /* Push the armor filter onto the iobuf stream IOBUF. */
147 push_armor_filter (armor_filter_context_t *afx, iobuf_t iobuf)
152 rc = iobuf_push_filter (iobuf, armor_filter, afx);
169 /* init the crc lookup table */
171 for(i=j=0; j < 128; j++ ) {
173 if( t & 0x00800000 ) {
175 crc_table[i++] = t ^ CRCPOLY;
181 crc_table[i++] = t ^ CRCPOLY;
184 /* build the helptable for radix64 to bin conversion */
185 for(i=0; i < 256; i++ )
186 asctobin[i] = 255; /* used to detect invalid characters */
187 for(s=bintoasc,i=0; *s; s++,i++ )
195 * Check whether this is an armored file. See also
196 * parse-packet.c for details on this code.
198 * Note that the buffer BUF needs to be at least 2 bytes long. If in
199 * doubt that the second byte to 0.
201 * Returns: True if it seems to be armored
204 is_armored (const byte *buf)
207 int indeterminate_length_allowed;
211 /* The most significant bit of the CTB must be set. Since it is
212 cleared, this is not a binary OpenPGP message. Assume it is
216 pkttype = ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
221 case PKT_ONEPASS_SIG:
224 case PKT_SECRET_SUBKEY:
228 case PKT_PUBLIC_SUBKEY:
231 indeterminate_length_allowed = 0;
236 case PKT_ENCRYPTED_MDC:
238 case PKT_OLD_COMMENT:
240 case PKT_GPG_CONTROL:
241 indeterminate_length_allowed = 1;
245 /* Invalid packet type. */
249 if (! indeterminate_length_allowed)
250 /* It is only legal to use an indeterminate length with a few
251 packet types. If a packet uses an indeterminate length, but
252 that is not allowed, then the data is not valid binary
256 int indeterminate_length;
258 new_format = !! (ctb & (1 << 6));
260 indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
262 indeterminate_length = (ctb & 3) == 3;
264 if (indeterminate_length)
268 /* The first CTB seems legit. It is probably not armored
275 * Try to check whether the iobuf is armored
276 * Returns true if this may be the case; the caller should use the
277 * filter to do further processing.
280 use_armor_filter( IOBUF a )
285 /* fixme: there might be a problem with iobuf_peek */
286 n = iobuf_peek (a, buf, 2);
288 return 0; /* EOF, doesn't matter whether armored or not */
290 return 1; /* can't check it: try armored */
292 return 0; /* short buffer */
293 return is_armored(buf);
302 write_status(STATUS_BADARMOR);
303 g10_exit(1); /* stop here */
308 * check whether the armor header is valid on a signed message.
309 * this is for security reasons: the header lines are not included in the
310 * hash and by using some creative formatting rules, Mallory could fake
311 * any text at the beginning of a document; assuming it is read with
312 * a simple viewer. We only allow the Hash Header.
315 parse_hash_header( const char *line )
320 if( strlen(line) < 6 || strlen(line) > 60 )
321 return 0; /* too short or too long */
322 if( memcmp( line, "Hash:", 5 ) )
323 return 0; /* invalid header */
325 for(s=line+5;;s=s2) {
326 for(; *s && (*s==' ' || *s == '\t'); s++ )
330 for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
332 if( !strncmp( s, "RIPEMD160", s2-s ) )
334 else if( !strncmp( s, "SHA1", s2-s ) )
336 else if( !strncmp( s, "SHA224", s2-s ) )
338 else if( !strncmp( s, "SHA256", s2-s ) )
340 else if( !strncmp( s, "SHA384", s2-s ) )
342 else if( !strncmp( s, "SHA512", s2-s ) )
346 for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
348 if( *s2 && *s2 != ',' )
356 /* Returns true if this is a valid armor tag as per RFC-2440bis-21. */
358 is_armor_tag(const char *line)
360 if(strncmp(line,"Version",7)==0
361 || strncmp(line,"Comment",7)==0
362 || strncmp(line,"MessageID",9)==0
363 || strncmp(line,"Hash",4)==0
364 || strncmp(line,"Charset",7)==0)
371 * Check whether this is a armor line.
372 * returns: -1 if it is not a armor header or the index number of the
376 is_armor_header( byte *line, unsigned len )
384 return -1; /* too short */
385 if( memcmp( line, "-----", 5 ) )
387 p = strstr( line+5, "-----");
393 /* Some Windows environments seem to add whitespace to the end of
394 the line, so we strip it here. This becomes strict if
395 --rfc2440 is set since 2440 reads "The header lines, therefore,
396 MUST start at the beginning of a line, and MUST NOT have text
397 following them on the same line." It is unclear whether "text"
398 refers to all text or just non-whitespace text. 4880 clarified
399 this was only non-whitespace text. */
409 while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
413 return -1; /* garbage after dashes */
414 save_c = *save_p; *save_p = 0;
416 for(i=0; (s=head_strings[i]); i++ )
421 return -1; /* unknown armor line */
423 if( opt.verbose > 1 )
424 log_info(_("armor: %s\n"), head_strings[i]);
431 * Parse a header lines
432 * Return 0: Empty line (end of header lines)
433 * -1: invalid header line
434 * >0: Good header line
437 parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
443 len2 = length_sans_trailing_ws ( line, len );
445 afx->buffer_pos = len2; /* (it is not the fine way to do it here) */
446 return 0; /* WS only: same as empty line */
450 This is fussy. The spec says that a header line is delimited
451 with a colon-space pair. This means that a line such as
452 "Comment: " (with nothing else) is actually legal as an empty
453 string comment. However, email and cut-and-paste being what it
454 is, that trailing space may go away. Therefore, we accept empty
455 headers delimited with only a colon. --rfc2440, as always,
456 makes this strict and enforces the colon-space pair. -dms
459 p = strchr( line, ':');
460 if( !p || (RFC2440 && p[1]!=' ')
461 || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
463 log_error (_("invalid armor header: "));
464 es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
469 /* Chop off the whitespace we detected before */
474 log_info(_("armor header: "));
475 es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
479 if( afx->in_cleartext )
481 if( (hashes=parse_hash_header( line )) )
482 afx->hashes |= hashes;
483 else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
484 afx->not_dash_escaped = 1;
487 log_error(_("invalid clearsig header\n"));
491 else if(!is_armor_tag(line))
493 /* Section 6.2: "Unknown keys should be reported to the user,
494 but OpenPGP should continue to process the message." Note
495 that in a clearsigned message this applies to the signature
496 part (i.e. "BEGIN PGP SIGNATURE") and not the signed data
497 ("BEGIN PGP SIGNED MESSAGE"). The only key allowed in the
498 signed data section is "Hash". */
500 log_info(_("unknown armor header: "));
501 es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
510 /* figure out whether the data is armored or not */
512 check_input( armor_filter_context_t *afx, IOBUF a )
521 /* read the first line to see whether this is armored data */
522 maxlen = MAX_LINELEN;
523 len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
524 &afx->buffer_size, &maxlen );
527 /* line has been truncated: assume not armored */
528 afx->inp_checked = 1;
537 /* (the line is always a C string but maybe longer) */
538 if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
540 else if (len >= 2 && !is_armored (line)) {
541 afx->inp_checked = 1;
546 /* find the armor header */
548 i = is_armor_header( line, len );
549 if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
551 if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
552 if( afx->in_cleartext ) {
553 log_error(_("nested clear text signatures\n"));
554 rc = gpg_error (GPG_ERR_INV_ARMOR);
556 afx->in_cleartext = 1;
560 /* read the next line (skip all truncated lines) */
562 maxlen = MAX_LINELEN;
563 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
564 &afx->buffer_size, &maxlen );
566 len = afx->buffer_len;
570 /* Parse the header lines. */
572 /* Read the next line (skip all truncated lines). */
574 maxlen = MAX_LINELEN;
575 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
576 &afx->buffer_size, &maxlen );
578 len = afx->buffer_len;
581 i = parse_header_line( afx, line, len );
584 rc = GPG_ERR_INV_ARMOR;
592 else if( afx->in_cleartext )
595 afx->inp_checked = 1;
604 #define PARTIAL_CHUNK 512
605 #define PARTIAL_POW 9
608 * Fake a literal data packet and wait for the next armor line
609 * fixme: empty line handling and null length clear text signature are
610 * not implemented/checked.
613 fake_packet( armor_filter_context_t *afx, IOBUF a,
614 size_t *retn, byte *buf, size_t size )
621 byte tempbuf[PARTIAL_CHUNK];
622 size_t tempbuf_len=0;
624 while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
625 /* copy what we have in the line buffer */
626 if( afx->faked == 1 )
627 afx->faked++; /* skip the first (empty) line */
630 /* It's full, so write this partial chunk */
631 if(tempbuf_len==PARTIAL_CHUNK)
633 buf[len++]=0xE0+PARTIAL_POW;
634 memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
640 while( tempbuf_len < PARTIAL_CHUNK
641 && afx->buffer_pos < afx->buffer_len )
642 tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
643 if( tempbuf_len==PARTIAL_CHUNK )
647 /* read the next line */
648 maxlen = MAX_LINELEN;
650 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
651 &afx->buffer_size, &maxlen );
652 if( !afx->buffer_len ) {
653 rc = -1; /* eof (should not happen) */
662 /* Armor header or dash-escaped line? */
665 /* 2440bis-10: When reversing dash-escaping, an
666 implementation MUST strip the string "- " if it occurs
667 at the beginning of a line, and SHOULD warn on "-" and
668 any character other than a space at the beginning of a
671 if(p[1]==' ' && !afx->not_dash_escaped)
673 /* It's a dash-escaped line, so skip over the
677 else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
679 /* Five dashes in a row mean it's probably armor
681 int type = is_armor_header( p, n );
682 if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
686 if( type != BEGIN_SIGNATURE )
688 log_info(_("unexpected armor: "));
689 es_write_sanitized (log_get_stream (), p, n,
698 else if(!afx->not_dash_escaped)
700 /* Bad dash-escaping. */
701 log_info (_("invalid dash escaped line: "));
702 es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
707 /* Now handle the end-of-line canonicalization */
708 if( !afx->not_dash_escaped )
710 int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
713 trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
715 afx->buffer_len+=afx->buffer_pos;
716 /* the buffer is always allocated with enough space to append
717 * the removed [CR], LF and a Nul
718 * The reason for this complicated procedure is to keep at least
719 * the original type of lineending - handling of the removed
720 * trailing spaces seems to be impossible in our method
721 * of faking a packet; either we have to use a temporary file
722 * or calculate the hash here in this module and somehow find
723 * a way to send the hash down the processing line (well, a special
724 * faked packet could do the job).
727 afx->buffer[afx->buffer_len++] = '\r';
728 afx->buffer[afx->buffer_len++] = '\n';
729 afx->buffer[afx->buffer_len] = '\0';
733 if( lastline ) { /* write last (ending) length header */
735 buf[len++]=tempbuf_len;
738 buf[len++]=((tempbuf_len-192)/256) + 192;
739 buf[len++]=(tempbuf_len-192) % 256;
741 memcpy(&buf[len],tempbuf,tempbuf_len);
746 afx->in_cleartext = 0;
747 /* and now read the header lines */
752 /* read the next line (skip all truncated lines) */
754 maxlen = MAX_LINELEN;
755 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
756 &afx->buffer_size, &maxlen );
764 i = parse_header_line( afx, p , n );
771 afx->inp_checked = 1;
785 if ( opt.ignore_crc_error )
787 log_inc_errorcount();
788 return gpg_error (GPG_ERR_INV_ARMOR);
793 radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
794 byte *buf, size_t size )
797 int c=0, c2; /*init c because gcc is not clever enough for the continue*/
801 int idx, i, onlypad=0;
806 val = afx->radbuf[0];
807 for( n=0; n < size; ) {
809 if( afx->buffer_pos < afx->buffer_len )
810 c = afx->buffer[afx->buffer_pos++];
811 else { /* read the next line */
812 unsigned maxlen = MAX_LINELEN;
814 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
815 &afx->buffer_size, &maxlen );
818 if( !afx->buffer_len )
824 if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
826 else if( c == '=' ) { /* pad character: stop */
827 /* some mailers leave quoted-printable encoded characters
828 * so we try to workaround this */
829 if( afx->buffer_pos+2 < afx->buffer_len ) {
831 cc1 = afx->buffer[afx->buffer_pos];
832 cc2 = afx->buffer[afx->buffer_pos+1];
833 cc3 = afx->buffer[afx->buffer_pos+2];
834 if( isxdigit(cc1) && isxdigit(cc2)
835 && strchr( "=\n\r\t ", cc3 )) {
836 /* well it seems to be the case - adjust */
837 c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
839 c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
840 afx->buffer_pos += 2;
841 afx->qp_detected = 1;
846 /* Occasionally a bug MTA will leave the = escaped as
847 =3D. If the 4 characters following that are valid
848 Radix64 characters and they are following by a new
849 line, assume that this is the case and skip the
851 if (afx->buffer_pos + 6 < afx->buffer_len
852 && afx->buffer[afx->buffer_pos + 0] == '3'
853 && afx->buffer[afx->buffer_pos + 1] == 'D'
854 && asctobin[afx->buffer[afx->buffer_pos + 2]] != 255
855 && asctobin[afx->buffer[afx->buffer_pos + 3]] != 255
856 && asctobin[afx->buffer[afx->buffer_pos + 4]] != 255
857 && asctobin[afx->buffer[afx->buffer_pos + 5]] != 255
858 && afx->buffer[afx->buffer_pos + 6] == '\n')
860 afx->buffer_pos += 2;
861 afx->qp_detected = 1;
872 else if( (c = asctobin[(c2=c)]) == 255 ) {
873 log_error(_("invalid radix64 character %02X skipped\n"), c2);
877 case 0: val = c << 2; break;
878 case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break;
879 case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break;
880 case 3: val |= c&0x3f; buf[n++] = val; break;
885 for(i=0; i < n; i++ )
886 crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
890 afx->radbuf[0] = val;
896 for(;;) { /* skip lf and pad characters */
897 if( afx->buffer_pos < afx->buffer_len )
898 c = afx->buffer[afx->buffer_pos++];
899 else { /* read the next line */
900 unsigned maxlen = MAX_LINELEN;
902 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
903 &afx->buffer_size, &maxlen );
906 if( !afx->buffer_len )
910 if( c == '\n' || c == ' ' || c == '\r'
911 || c == '\t' || c == '=' )
916 log_error(_("premature eof (no CRC)\n"));
921 if( (c = asctobin[c]) == 255 )
924 case 0: val = c << 2; break;
925 case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break;
926 case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break;
927 case 3: val |= c&0x3f; mycrc |= val; break;
930 if( afx->buffer_pos < afx->buffer_len )
931 c = afx->buffer[afx->buffer_pos++];
932 else { /* read the next line */
933 unsigned maxlen = MAX_LINELEN;
935 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
940 if( !afx->buffer_len )
946 if( !afx->buffer_len )
948 } while( ++idx < 4 );
950 log_info(_("premature eof (in CRC)\n"));
953 else if( idx == 0 ) {
954 /* No CRC at all is legal ("MAY") */
957 else if( idx != 4 ) {
958 log_info(_("malformed CRC\n"));
961 else if( mycrc != afx->crc ) {
962 log_info (_("CRC error; %06lX - %06lX\n"),
963 (ulong)afx->crc, (ulong)mycrc);
968 /* FIXME: Here we should emit another control packet,
969 * so that we know in mainproc that we are processing
970 * a clearsign message */
973 rc = 0 /*check_trailer( &fhdr, c )*/;
975 if( (c=iobuf_get(a)) == -1 )
982 log_error(_("premature eof (in trailer)\n"));
983 rc = GPG_ERR_INVALID_ARMOR;
986 log_error(_("error in trailer line\n"));
987 rc = GPG_ERR_INVALID_ARMOR;
1002 * This filter is used to handle the armor stuff
1005 armor_filter( void *opaque, int control,
1006 IOBUF a, byte *buf, size_t *ret_len)
1008 size_t size = *ret_len;
1009 armor_filter_context_t *afx = opaque;
1019 fp = fopen("armor.out", "w");
1025 log_debug("armor-filter: control: %d\n", control );
1026 if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
1028 if( afx->buffer_len ) {
1029 for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
1030 buf[n++] = afx->buffer[afx->buffer_pos++];
1031 if( afx->buffer_pos >= afx->buffer_len )
1032 afx->buffer_len = 0;
1034 for(; n < size; n++ ) {
1035 if( (c=iobuf_get(a)) == -1 )
1043 else if( control == IOBUFCTRL_UNDERFLOW ) {
1044 /* We need some space for the faked packet. The minmum
1045 * required size is the PARTIAL_CHUNK size plus a byte for the
1047 if( size < PARTIAL_CHUNK+1 )
1048 BUG(); /* supplied buffer too short */
1051 rc = fake_packet( afx, a, &n, buf, size );
1052 else if( !afx->inp_checked ) {
1053 rc = check_input( afx, a );
1054 if( afx->inp_bypass ) {
1055 for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
1056 buf[n++] = afx->buffer[afx->buffer_pos++];
1057 if( afx->buffer_pos >= afx->buffer_len )
1058 afx->buffer_len = 0;
1062 else if( afx->faked ) {
1063 unsigned int hashes = afx->hashes;
1064 const byte *sesmark;
1067 sesmark = get_session_marker( &sesmarklen );
1068 if ( sesmarklen > 20 )
1071 /* the buffer is at least 15+n*15 bytes long, so it
1072 * is easy to construct the packets */
1074 hashes &= 1|2|8|16|32|64;
1076 hashes |= 2; /* Default to SHA-1. */
1079 /* First a gpg control packet... */
1080 buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1081 n++; /* see below */
1082 memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1083 buf[n++] = CTRLPKT_CLEARSIGN_START;
1084 buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1086 buf[n++] = DIGEST_ALGO_RMD160;
1088 buf[n++] = DIGEST_ALGO_SHA1;
1090 buf[n++] = DIGEST_ALGO_SHA224;
1092 buf[n++] = DIGEST_ALGO_SHA256;
1094 buf[n++] = DIGEST_ALGO_SHA384;
1096 buf[n++] = DIGEST_ALGO_SHA512;
1099 /* ...followed by an invented plaintext packet.
1100 Amusingly enough, this packet is not compliant with
1101 2440 as the initial partial length is less than 512
1102 bytes. Of course, we'll accept it anyway ;) */
1104 buf[n++] = 0xCB; /* new packet format, type 11 */
1105 buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1106 buf[n++] = 't'; /* canonical text mode */
1107 buf[n++] = 0; /* namelength */
1108 buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1109 memset(buf+n, 0, 4); /* timestamp */
1113 rc = radix64_read( afx, a, &n, buf, size );
1116 rc = radix64_read( afx, a, &n, buf, size );
1119 if( fwrite(buf, n, 1, fp ) != 1 )
1124 else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
1125 if( !afx->status ) { /* write the header line */
1127 strlist_t comment=opt.comments;
1129 if( afx->what >= DIM(head_strings) )
1130 log_bug("afx->what=%d", afx->what);
1131 iobuf_writestr(a, "-----");
1132 iobuf_writestr(a, head_strings[afx->what] );
1133 iobuf_writestr(a, "-----" );
1134 iobuf_writestr(a,afx->eol);
1135 if (opt.emit_version)
1137 iobuf_writestr (a, "Version: "GNUPG_NAME" v");
1138 for (s=VERSION; *s && *s != '.'; s++)
1139 iobuf_writebyte (a, *s);
1140 if (opt.emit_version > 1 && *s)
1142 iobuf_writebyte (a, *s++);
1143 for (; *s && *s != '.'; s++)
1144 iobuf_writebyte (a, *s);
1145 if (opt.emit_version > 2)
1147 for (; *s && *s != '-' && !spacep (s); s++)
1148 iobuf_writebyte (a, *s);
1149 if (opt.emit_version > 3)
1150 iobuf_writestr (a, " (" PRINTABLE_OS_NAME ")");
1153 iobuf_writestr(a,afx->eol);
1156 /* write the comment strings */
1157 for(s=comment->d;comment;comment=comment->next,s=comment->d)
1159 iobuf_writestr(a, "Comment: " );
1163 iobuf_writestr(a, "\\n" );
1164 else if( *s == '\r' )
1165 iobuf_writestr(a, "\\r" );
1166 else if( *s == '\v' )
1167 iobuf_writestr(a, "\\v" );
1172 iobuf_writestr(a,afx->eol);
1175 if ( afx->hdrlines ) {
1176 for ( s = afx->hdrlines; *s; s++ ) {
1177 #ifdef HAVE_DOSISH_SYSTEM
1179 iobuf_put( a, '\r');
1185 iobuf_writestr(a,afx->eol);
1195 for(i=0; i < idx; i++ )
1196 radbuf[i] = afx->radbuf[i];
1198 for(i=0; i < size; i++ )
1199 crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
1202 for( ; size; buf++, size-- ) {
1203 radbuf[idx++] = *buf;
1206 c = bintoasc[(*radbuf >> 2) & 077];
1208 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1210 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1212 c = bintoasc[radbuf[2]&077];
1214 if( ++idx2 >= (64/4) )
1215 { /* pgp doesn't like 72 here */
1216 iobuf_writestr(a,afx->eol);
1221 for(i=0; i < idx; i++ )
1222 afx->radbuf[i] = radbuf[i];
1227 else if( control == IOBUFCTRL_INIT )
1229 if( !is_initialized )
1232 /* Figure out what we're using for line endings if the caller
1236 #ifdef HAVE_DOSISH_SYSTEM
1244 else if( control == IOBUFCTRL_CANCEL ) {
1247 else if( control == IOBUFCTRL_FREE ) {
1250 else if( afx->status ) { /* pad, write cecksum, and bottom line */
1255 c = bintoasc[(afx->radbuf[0]>>2)&077];
1258 c = bintoasc[((afx->radbuf[0] << 4) & 060) & 077];
1264 c = bintoasc[(((afx->radbuf[0]<<4)&060)
1265 |((afx->radbuf[1]>>4)&017))&077];
1267 c = bintoasc[((afx->radbuf[1] << 2) & 074) & 077];
1271 if( ++idx2 >= (64/4) )
1272 { /* pgp doesn't like 72 here */
1273 iobuf_writestr(a,afx->eol);
1277 /* may need a linefeed */
1279 iobuf_writestr(a,afx->eol);
1282 radbuf[0] = crc >>16;
1283 radbuf[1] = crc >> 8;
1285 c = bintoasc[(*radbuf >> 2) & 077];
1287 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1289 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1291 c = bintoasc[radbuf[2]&077];
1293 iobuf_writestr(a,afx->eol);
1294 /* and the the trailer */
1295 if( afx->what >= DIM(tail_strings) )
1296 log_bug("afx->what=%d", afx->what);
1297 iobuf_writestr(a, "-----");
1298 iobuf_writestr(a, tail_strings[afx->what] );
1299 iobuf_writestr(a, "-----" );
1300 iobuf_writestr(a,afx->eol);
1302 else if( !afx->any_data && !afx->inp_bypass ) {
1303 log_error(_("no valid OpenPGP data found.\n"));
1304 afx->no_openpgp_data = 1;
1305 write_status_text( STATUS_NODATA, "1" );
1307 if( afx->truncated )
1308 log_info(_("invalid armor: line longer than %d characters\n"),
1310 /* issue an error to enforce dissemination of correct software */
1311 if( afx->qp_detected )
1312 log_error(_("quoted printable character in armor - "
1313 "probably a buggy MTA has been used\n") );
1314 xfree( afx->buffer );
1316 release_armor_context (afx);
1318 else if( control == IOBUFCTRL_DESC )
1319 mem2str (buf, "armor_filter", *ret_len);
1325 * create a radix64 encoded string.
1328 make_radix64_string( const byte *data, size_t len )
1332 buffer = p = xmalloc( (len+2)/3*4 + 1 );
1333 for( ; len >= 3 ; len -= 3, data += 3 ) {
1334 *p++ = bintoasc[(data[0] >> 2) & 077];
1335 *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1336 *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
1337 *p++ = bintoasc[data[2]&077];
1340 *p++ = bintoasc[(data[0] >> 2) & 077];
1341 *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1342 *p++ = bintoasc[((data[1]<<2)&074)];
1344 else if( len == 1 ) {
1345 *p++ = bintoasc[(data[0] >> 2) & 077];
1346 *p++ = bintoasc[(data[0] <<4)&060];
1353 /***********************************************
1354 * For the pipemode command we can't use the armor filter for various
1355 * reasons, so we use this new unarmor_pump stuff to remove the armor
1358 enum unarmor_state_e {
1365 STA_found_header_wait_newline,
1366 STA_skip_header_lines,
1367 STA_skip_header_lines_non_ws,
1374 struct unarmor_pump_s {
1375 enum unarmor_state_e state;
1378 int pos; /* counts from 0..3 */
1380 u32 mycrc; /* the one store in the data */
1386 unarmor_pump_new (void)
1390 if( !is_initialized )
1392 x = xmalloc_clear (sizeof *x);
1397 unarmor_pump_release (UnarmorPump x)
1403 * Get the next character from the ascii armor taken from the IOBUF
1404 * created earlier by unarmor_pump_new().
1405 * Return: c = Character
1406 * 256 = ignore this value
1407 * -1 = End of current armor
1408 * -2 = Premature EOF (not used)
1409 * -3 = Invalid armor
1412 unarmor_pump (UnarmorPump x, int c)
1414 int rval = 256; /* default is to ignore the return value */
1422 if ( is_armored (tmp) )
1423 x->state = c == '-'? STA_first_dash : STA_wait_newline;
1425 x->state = STA_bypass;
1431 return c; /* return here to avoid crc calculation */
1432 case STA_wait_newline:
1434 x->state = STA_wait_dash;
1437 x->state = c == '-'? STA_first_dash : STA_wait_newline;
1439 case STA_first_dash: /* just need for initialization */
1441 x->state = STA_compare_header;
1442 case STA_compare_header:
1443 if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) {
1445 x->state = STA_found_header_wait_newline;
1448 x->state = c == '\n'? STA_wait_dash : STA_wait_newline;
1450 case STA_found_header_wait_newline:
1451 /* to make CR,LF issues easier we simply allow for white space
1452 behind the 5 dashes */
1454 x->state = STA_skip_header_lines;
1455 else if ( c != '\r' && c != ' ' && c != '\t' )
1456 x->state = STA_wait_dash; /* garbage after the header line */
1458 case STA_skip_header_lines:
1459 /* i.e. wait for one empty line */
1461 x->state = STA_read_data;
1466 else if ( c != '\r' && c != ' ' && c != '\t' )
1467 x->state = STA_skip_header_lines_non_ws;
1469 case STA_skip_header_lines_non_ws:
1470 /* like above but we already encountered non white space */
1472 x->state = STA_skip_header_lines;
1475 /* fixme: we don't check for the trailing dash lines but rely
1476 * on the armor stop characters */
1477 if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
1478 break; /* skip all kind of white space */
1480 if( c == '=' ) { /* pad character: stop */
1481 if( x->pos == 1 ) /* in this case val has some value */
1483 x->state = STA_wait_crc;
1489 if( (c = asctobin[(c2=c)]) == 255 ) {
1490 log_error(_("invalid radix64 character %02X skipped\n"), c2);
1502 x->val = (c<<4)&0xf0;
1505 x->val |= (c>>2)&15;
1507 x->val = (c<<6)&0xc0;
1514 x->pos = (x->pos+1) % 4;
1517 if( c == '\n' || c == ' ' || c == '\r' || c == '\t' || c == '=' )
1518 break; /* skip ws and pad characters */
1519 /* assume that we are at the next line */
1520 x->state = STA_read_crc;
1524 if( (c = asctobin[c]) == 255 ) {
1525 rval = -1; /* ready */
1526 if( x->crc != x->mycrc ) {
1527 log_info (_("CRC error; %06lX - %06lX\n"),
1528 (ulong)x->crc, (ulong)x->mycrc);
1529 if ( invalid_crc() )
1532 x->state = STA_ready; /* not sure whether this is correct */
1542 x->mycrc |= x->val << 16;
1543 x->val = (c<<4)&0xf0;
1546 x->val |= (c>>2)&15;
1547 x->mycrc |= x->val << 8;
1548 x->val = (c<<6)&0xc0;
1555 x->pos = (x->pos+1) % 4;
1562 if ( !(rval & ~255) ) { /* compute the CRC */
1563 x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval];
1564 x->crc &= 0x00ffffff;