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 /* Copy the data from AFX->BUFFER to BUF. */
1030 for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
1031 buf[n++] = afx->buffer[afx->buffer_pos++];
1032 if( afx->buffer_pos >= afx->buffer_len )
1033 afx->buffer_len = 0;
1035 /* If there is still space in BUF, read directly into it. */
1036 for(; n < size; n++ ) {
1037 if( (c=iobuf_get(a)) == -1 )
1042 /* We didn't get any data. EOF. */
1046 else if( control == IOBUFCTRL_UNDERFLOW ) {
1047 /* We need some space for the faked packet. The minmum
1048 * required size is the PARTIAL_CHUNK size plus a byte for the
1050 if( size < PARTIAL_CHUNK+1 )
1051 BUG(); /* supplied buffer too short */
1054 rc = fake_packet( afx, a, &n, buf, size );
1055 else if( !afx->inp_checked ) {
1056 rc = check_input( afx, a );
1057 if( afx->inp_bypass ) {
1058 for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
1059 buf[n++] = afx->buffer[afx->buffer_pos++];
1060 if( afx->buffer_pos >= afx->buffer_len )
1061 afx->buffer_len = 0;
1065 else if( afx->faked ) {
1066 unsigned int hashes = afx->hashes;
1067 const byte *sesmark;
1070 sesmark = get_session_marker( &sesmarklen );
1071 if ( sesmarklen > 20 )
1074 /* the buffer is at least 15+n*15 bytes long, so it
1075 * is easy to construct the packets */
1077 hashes &= 1|2|8|16|32|64;
1079 hashes |= 2; /* Default to SHA-1. */
1082 /* First a gpg control packet... */
1083 buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1084 n++; /* see below */
1085 memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1086 buf[n++] = CTRLPKT_CLEARSIGN_START;
1087 buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1089 buf[n++] = DIGEST_ALGO_RMD160;
1091 buf[n++] = DIGEST_ALGO_SHA1;
1093 buf[n++] = DIGEST_ALGO_SHA224;
1095 buf[n++] = DIGEST_ALGO_SHA256;
1097 buf[n++] = DIGEST_ALGO_SHA384;
1099 buf[n++] = DIGEST_ALGO_SHA512;
1102 /* ...followed by an invented plaintext packet.
1103 Amusingly enough, this packet is not compliant with
1104 2440 as the initial partial length is less than 512
1105 bytes. Of course, we'll accept it anyway ;) */
1107 buf[n++] = 0xCB; /* new packet format, type 11 */
1108 buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1109 buf[n++] = 't'; /* canonical text mode */
1110 buf[n++] = 0; /* namelength */
1111 buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1112 memset(buf+n, 0, 4); /* timestamp */
1116 rc = radix64_read( afx, a, &n, buf, size );
1119 rc = radix64_read( afx, a, &n, buf, size );
1122 if( fwrite(buf, n, 1, fp ) != 1 )
1127 else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
1128 if( !afx->status ) { /* write the header line */
1130 strlist_t comment=opt.comments;
1132 if( afx->what >= DIM(head_strings) )
1133 log_bug("afx->what=%d", afx->what);
1134 iobuf_writestr(a, "-----");
1135 iobuf_writestr(a, head_strings[afx->what] );
1136 iobuf_writestr(a, "-----" );
1137 iobuf_writestr(a,afx->eol);
1138 if (opt.emit_version)
1140 iobuf_writestr (a, "Version: "GNUPG_NAME" v");
1141 for (s=VERSION; *s && *s != '.'; s++)
1142 iobuf_writebyte (a, *s);
1143 if (opt.emit_version > 1 && *s)
1145 iobuf_writebyte (a, *s++);
1146 for (; *s && *s != '.'; s++)
1147 iobuf_writebyte (a, *s);
1148 if (opt.emit_version > 2)
1150 for (; *s && *s != '-' && !spacep (s); s++)
1151 iobuf_writebyte (a, *s);
1152 if (opt.emit_version > 3)
1153 iobuf_writestr (a, " (" PRINTABLE_OS_NAME ")");
1156 iobuf_writestr(a,afx->eol);
1159 /* write the comment strings */
1160 for(s=comment->d;comment;comment=comment->next,s=comment->d)
1162 iobuf_writestr(a, "Comment: " );
1166 iobuf_writestr(a, "\\n" );
1167 else if( *s == '\r' )
1168 iobuf_writestr(a, "\\r" );
1169 else if( *s == '\v' )
1170 iobuf_writestr(a, "\\v" );
1175 iobuf_writestr(a,afx->eol);
1178 if ( afx->hdrlines ) {
1179 for ( s = afx->hdrlines; *s; s++ ) {
1180 #ifdef HAVE_DOSISH_SYSTEM
1182 iobuf_put( a, '\r');
1188 iobuf_writestr(a,afx->eol);
1198 for(i=0; i < idx; i++ )
1199 radbuf[i] = afx->radbuf[i];
1201 for(i=0; i < size; i++ )
1202 crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
1205 for( ; size; buf++, size-- ) {
1206 radbuf[idx++] = *buf;
1209 c = bintoasc[(*radbuf >> 2) & 077];
1211 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1213 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1215 c = bintoasc[radbuf[2]&077];
1217 if( ++idx2 >= (64/4) )
1218 { /* pgp doesn't like 72 here */
1219 iobuf_writestr(a,afx->eol);
1224 for(i=0; i < idx; i++ )
1225 afx->radbuf[i] = radbuf[i];
1230 else if( control == IOBUFCTRL_INIT )
1232 if( !is_initialized )
1235 /* Figure out what we're using for line endings if the caller
1239 #ifdef HAVE_DOSISH_SYSTEM
1247 else if( control == IOBUFCTRL_CANCEL ) {
1250 else if( control == IOBUFCTRL_FREE ) {
1253 else if( afx->status ) { /* pad, write cecksum, and bottom line */
1258 c = bintoasc[(afx->radbuf[0]>>2)&077];
1261 c = bintoasc[((afx->radbuf[0] << 4) & 060) & 077];
1267 c = bintoasc[(((afx->radbuf[0]<<4)&060)
1268 |((afx->radbuf[1]>>4)&017))&077];
1270 c = bintoasc[((afx->radbuf[1] << 2) & 074) & 077];
1274 if( ++idx2 >= (64/4) )
1275 { /* pgp doesn't like 72 here */
1276 iobuf_writestr(a,afx->eol);
1280 /* may need a linefeed */
1282 iobuf_writestr(a,afx->eol);
1285 radbuf[0] = crc >>16;
1286 radbuf[1] = crc >> 8;
1288 c = bintoasc[(*radbuf >> 2) & 077];
1290 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1292 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1294 c = bintoasc[radbuf[2]&077];
1296 iobuf_writestr(a,afx->eol);
1297 /* and the the trailer */
1298 if( afx->what >= DIM(tail_strings) )
1299 log_bug("afx->what=%d", afx->what);
1300 iobuf_writestr(a, "-----");
1301 iobuf_writestr(a, tail_strings[afx->what] );
1302 iobuf_writestr(a, "-----" );
1303 iobuf_writestr(a,afx->eol);
1305 else if( !afx->any_data && !afx->inp_bypass ) {
1306 log_error(_("no valid OpenPGP data found.\n"));
1307 afx->no_openpgp_data = 1;
1308 write_status_text( STATUS_NODATA, "1" );
1310 if( afx->truncated )
1311 log_info(_("invalid armor: line longer than %d characters\n"),
1313 /* issue an error to enforce dissemination of correct software */
1314 if( afx->qp_detected )
1315 log_error(_("quoted printable character in armor - "
1316 "probably a buggy MTA has been used\n") );
1317 xfree( afx->buffer );
1319 release_armor_context (afx);
1321 else if( control == IOBUFCTRL_DESC )
1322 mem2str (buf, "armor_filter", *ret_len);
1328 * create a radix64 encoded string.
1331 make_radix64_string( const byte *data, size_t len )
1335 buffer = p = xmalloc( (len+2)/3*4 + 1 );
1336 for( ; len >= 3 ; len -= 3, data += 3 ) {
1337 *p++ = bintoasc[(data[0] >> 2) & 077];
1338 *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1339 *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
1340 *p++ = bintoasc[data[2]&077];
1343 *p++ = bintoasc[(data[0] >> 2) & 077];
1344 *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1345 *p++ = bintoasc[((data[1]<<2)&074)];
1347 else if( len == 1 ) {
1348 *p++ = bintoasc[(data[0] >> 2) & 077];
1349 *p++ = bintoasc[(data[0] <<4)&060];
1356 /***********************************************
1357 * For the pipemode command we can't use the armor filter for various
1358 * reasons, so we use this new unarmor_pump stuff to remove the armor
1361 enum unarmor_state_e {
1368 STA_found_header_wait_newline,
1369 STA_skip_header_lines,
1370 STA_skip_header_lines_non_ws,
1377 struct unarmor_pump_s {
1378 enum unarmor_state_e state;
1381 int pos; /* counts from 0..3 */
1383 u32 mycrc; /* the one store in the data */
1389 unarmor_pump_new (void)
1393 if( !is_initialized )
1395 x = xmalloc_clear (sizeof *x);
1400 unarmor_pump_release (UnarmorPump x)
1406 * Get the next character from the ascii armor taken from the IOBUF
1407 * created earlier by unarmor_pump_new().
1408 * Return: c = Character
1409 * 256 = ignore this value
1410 * -1 = End of current armor
1411 * -2 = Premature EOF (not used)
1412 * -3 = Invalid armor
1415 unarmor_pump (UnarmorPump x, int c)
1417 int rval = 256; /* default is to ignore the return value */
1425 if ( is_armored (tmp) )
1426 x->state = c == '-'? STA_first_dash : STA_wait_newline;
1428 x->state = STA_bypass;
1434 return c; /* return here to avoid crc calculation */
1435 case STA_wait_newline:
1437 x->state = STA_wait_dash;
1440 x->state = c == '-'? STA_first_dash : STA_wait_newline;
1442 case STA_first_dash: /* just need for initialization */
1444 x->state = STA_compare_header;
1445 case STA_compare_header:
1446 if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) {
1448 x->state = STA_found_header_wait_newline;
1451 x->state = c == '\n'? STA_wait_dash : STA_wait_newline;
1453 case STA_found_header_wait_newline:
1454 /* to make CR,LF issues easier we simply allow for white space
1455 behind the 5 dashes */
1457 x->state = STA_skip_header_lines;
1458 else if ( c != '\r' && c != ' ' && c != '\t' )
1459 x->state = STA_wait_dash; /* garbage after the header line */
1461 case STA_skip_header_lines:
1462 /* i.e. wait for one empty line */
1464 x->state = STA_read_data;
1469 else if ( c != '\r' && c != ' ' && c != '\t' )
1470 x->state = STA_skip_header_lines_non_ws;
1472 case STA_skip_header_lines_non_ws:
1473 /* like above but we already encountered non white space */
1475 x->state = STA_skip_header_lines;
1478 /* fixme: we don't check for the trailing dash lines but rely
1479 * on the armor stop characters */
1480 if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
1481 break; /* skip all kind of white space */
1483 if( c == '=' ) { /* pad character: stop */
1484 if( x->pos == 1 ) /* in this case val has some value */
1486 x->state = STA_wait_crc;
1492 if( (c = asctobin[(c2=c)]) == 255 ) {
1493 log_error(_("invalid radix64 character %02X skipped\n"), c2);
1505 x->val = (c<<4)&0xf0;
1508 x->val |= (c>>2)&15;
1510 x->val = (c<<6)&0xc0;
1517 x->pos = (x->pos+1) % 4;
1520 if( c == '\n' || c == ' ' || c == '\r' || c == '\t' || c == '=' )
1521 break; /* skip ws and pad characters */
1522 /* assume that we are at the next line */
1523 x->state = STA_read_crc;
1527 if( (c = asctobin[c]) == 255 ) {
1528 rval = -1; /* ready */
1529 if( x->crc != x->mycrc ) {
1530 log_info (_("CRC error; %06lX - %06lX\n"),
1531 (ulong)x->crc, (ulong)x->mycrc);
1532 if ( invalid_crc() )
1535 x->state = STA_ready; /* not sure whether this is correct */
1545 x->mycrc |= x->val << 16;
1546 x->val = (c<<4)&0xf0;
1549 x->val |= (c>>2)&15;
1550 x->mycrc |= x->val << 8;
1551 x->val = (c<<6)&0xc0;
1558 x->pos = (x->pos+1) % 4;
1565 if ( !(rval & ~255) ) { /* compute the CRC */
1566 x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval];
1567 x->crc &= 0x00ffffff;