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,
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)]; \
50 static u32 crc_table
[256];
51 static byte bintoasc
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
52 "abcdefghijklmnopqrstuvwxyz"
54 static byte asctobin
[256]; /* runtime initialized */
55 static int is_initialized
;
75 fhdrCHECKDashEscaped2
,
76 fhdrCHECKDashEscaped3
,
82 fhdrCLEARSIGSimpleNext
,
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
[] = {
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 */
105 static char *tail_strings
[] = {
107 "END PGP PUBLIC KEY BLOCK",
110 "END PGP ARMORED FILE",
111 "END PGP PRIVATE KEY BLOCK",
112 "END PGP SECRET KEY BLOCK",
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
);
135 /* Release an armor filter context. Passing NULL is explicitly
136 allowed and a no-op. */
138 release_armor_context (armor_filter_context_t
*afx
)
142 assert (afx
->refcount
);
143 if ( --afx
->refcount
)
148 /* Push the armor filter onto the iobuf stream IOBUF. */
150 push_armor_filter (armor_filter_context_t
*afx
, iobuf_t iobuf
)
155 rc
= iobuf_push_filter (iobuf
, armor_filter
, afx
);
172 /* init the crc lookup table */
174 for(i
=j
=0; j
< 128; j
++ ) {
176 if( t
& 0x00800000 ) {
178 crc_table
[i
++] = t
^ CRCPOLY
;
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
++ )
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
203 is_armored( const byte
*buf
)
209 return 1; /* invalid packet: assume it is armored */
210 pkttype
= ctb
& 0x40 ? (ctb
& 0x3f) : ((ctb
>>2)&0xf);
214 case PKT_ONEPASS_SIG
:
220 case PKT_OLD_COMMENT
:
224 return 0; /* seems to be a regular packet: not armored */
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
)
242 /* fixme: there might be a problem with iobuf_peek */
243 n
= iobuf_peek(a
, buf
, 1 );
245 return 0; /* EOF, doesn't matter whether armored or not */
247 return 1; /* can't check it: try armored */
248 return is_armored(buf
);
257 write_status(STATUS_BADARMOR
);
258 g10_exit(1); /* stop here */
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.
270 parse_hash_header( const char *line
)
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 */
280 for(s
=line
+5;;s
=s2
) {
281 for(; *s
&& (*s
==' ' || *s
== '\t'); s
++ )
285 for(s2
=s
+1; *s2
&& *s2
!=' ' && *s2
!= '\t' && *s2
!= ','; s2
++ )
287 if( !strncmp( s
, "RIPEMD160", s2
-s
) )
289 else if( !strncmp( s
, "SHA1", s2
-s
) )
291 else if( !strncmp( s
, "MD5", s2
-s
) )
293 else if( !strncmp( s
, "SHA224", s2
-s
) )
295 else if( !strncmp( s
, "SHA256", s2
-s
) )
297 else if( !strncmp( s
, "SHA384", s2
-s
) )
299 else if( !strncmp( s
, "SHA512", s2
-s
) )
303 for(; *s2
&& (*s2
==' ' || *s2
== '\t'); s2
++ )
305 if( *s2
&& *s2
!= ',' )
316 * Check whether this is a armor line.
317 * returns: -1 if it is not a armor header or the index number of the
321 is_armor_header( byte
*line
, unsigned len
)
329 return -1; /* too short */
330 if( memcmp( line
, "-----", 5 ) )
332 p
= strstr( line
+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. */
353 while(*p
==' ' || *p
=='\r' || *p
=='\n' || *p
=='\t')
357 return -1; /* garbage after dashes */
358 save_c
= *save_p
; *save_p
= 0;
360 for(i
=0; (s
=head_strings
[i
]); i
++ )
365 return -1; /* unknown armor line */
367 if( opt
.verbose
> 1 )
368 log_info(_("armor: %s\n"), head_strings
[i
]);
375 * Parse a header lines
376 * Return 0: Empty line (end of header lines)
377 * -1: invalid header line
378 * >0: Good header line
381 parse_header_line( armor_filter_context_t
*afx
, byte
*line
, unsigned int len
)
387 len2
= length_sans_trailing_ws ( line
, len
);
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 );
413 /* Chop off the whitespace we detected before */
418 log_info(_("armor header: "));
419 print_string( stderr
, line
, len
, 0 );
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;
429 log_error(_("invalid clearsig header\n"));
438 /* figure out whether the data is armored or not */
440 check_input( armor_filter_context_t
*afx
, IOBUF a
)
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
);
455 /* line has been truncated: assume not armored */
456 afx
->inp_checked
= 1;
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;
474 /* find the armor header */
476 i
= is_armor_header( line
, len
);
477 if( i
>= 0 && !(afx
->only_keyblocks
&& i
!= 1 && i
!= 5 && i
!= 6 )) {
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;
488 /* read the next line (skip all truncated lines) */
490 maxlen
= MAX_LINELEN
;
491 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
492 &afx
->buffer_size
, &maxlen
);
494 len
= afx
->buffer_len
;
498 /* Parse the header lines. */
500 /* Read the next line (skip all truncated lines). */
502 maxlen
= MAX_LINELEN
;
503 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
504 &afx
->buffer_size
, &maxlen
);
506 len
= afx
->buffer_len
;
509 i
= parse_header_line( afx
, line
, len
);
512 rc
= G10ERR_INVALID_ARMOR
;
520 else if( afx
->in_cleartext
)
523 afx
->inp_checked
= 1;
532 #define PARTIAL_CHUNK 512
533 #define PARTIAL_POW 9
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.
541 fake_packet( armor_filter_context_t
*afx
, IOBUF a
,
542 size_t *retn
, byte
*buf
, size_t size
)
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 */
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
);
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
)
575 /* read the next line */
576 maxlen
= MAX_LINELEN
;
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) */
590 /* Armor header or dash-escaped line? */
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
599 if(p
[1]==' ' && !afx
->not_dash_escaped
)
601 /* It's a dash-escaped line, so skip over the
605 else if(p
[1]=='-' && p
[2]=='-' && p
[3]=='-' && p
[4]=='-')
607 /* Five dashes in a row mean it's probably armor
609 int type
= is_armor_header( p
, n
);
610 if( afx
->not_dash_escaped
&& type
!= BEGIN_SIGNATURE
)
614 if( type
!= BEGIN_SIGNATURE
)
616 log_info(_("unexpected armor: "));
617 print_string( stderr
, p
, n
, 0 );
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 );
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 */
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).
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 */
663 buf
[len
++]=tempbuf_len
;
666 buf
[len
++]=((tempbuf_len
-192)/256) + 192;
667 buf
[len
++]=(tempbuf_len
-192) % 256;
669 memcpy(&buf
[len
],tempbuf
,tempbuf_len
);
674 afx
->in_cleartext
= 0;
675 /* and now read the header lines */
680 /* read the next line (skip all truncated lines) */
682 maxlen
= MAX_LINELEN
;
683 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
684 &afx
->buffer_size
, &maxlen
);
692 i
= parse_header_line( afx
, p
, n
);
699 afx
->inp_checked
= 1;
713 if ( opt
.ignore_crc_error
)
715 log_inc_errorcount();
716 return gpg_error (GPG_ERR_INV_ARMOR
);
721 radix64_read( armor_filter_context_t
*afx
, IOBUF a
, size_t *retn
,
722 byte
*buf
, size_t size
)
725 int c
=0, c2
; /*init c because gcc is not clever enough for the continue*/
729 int idx
, i
, onlypad
=0;
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
;
742 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
743 &afx
->buffer_size
, &maxlen
);
746 if( !afx
->buffer_len
)
752 if( c
== '\n' || c
== ' ' || c
== '\r' || c
== '\t' )
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
) {
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);
767 c
|= isdigit(cc2
)? (cc2
- '0'): (ascii_toupper(cc2
)-'A'+10);
768 afx
->buffer_pos
+= 2;
769 afx
->qp_detected
= 1;
781 else if( (c
= asctobin
[(c2
=c
)]) == 255 ) {
782 log_error(_("invalid radix64 character %02X skipped\n"), c2
);
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;
794 for(i
=0; i
< n
; i
++ )
795 crc
= (crc
<< 8) ^ crc_table
[((crc
>> 16)&0xff) ^ buf
[i
]];
799 afx
->radbuf
[0] = val
;
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
;
811 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
812 &afx
->buffer_size
, &maxlen
);
815 if( !afx
->buffer_len
)
819 if( c
== '\n' || c
== ' ' || c
== '\r'
820 || c
== '\t' || c
== '=' )
825 log_error(_("premature eof (no CRC)\n"));
830 if( (c
= asctobin
[c
]) == 255 )
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;
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
;
844 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
849 if( !afx
->buffer_len
)
855 if( !afx
->buffer_len
)
857 } while( ++idx
< 4 );
859 log_info(_("premature eof (in CRC)\n"));
862 else if( idx
== 0 ) {
863 /* No CRC at all is legal ("MAY") */
866 else if( idx
!= 4 ) {
867 log_info(_("malformed CRC\n"));
870 else if( mycrc
!= afx
->crc
) {
871 log_info (_("CRC error; %06lX - %06lX\n"),
872 (ulong
)afx
->crc
, (ulong
)mycrc
);
877 /* FIXME: Here we should emit another control packet,
878 * so that we know in mainproc that we are processing
879 * a clearsign message */
882 rc
= 0 /*check_trailer( &fhdr, c )*/;
884 if( (c
=iobuf_get(a
)) == -1 )
891 log_error(_("premature eof (in trailer)\n"));
892 rc
= G10ERR_INVALID_ARMOR
;
895 log_error(_("error in trailer line\n"));
896 rc
= G10ERR_INVALID_ARMOR
;
911 * This filter is used to handle the armor stuff
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
;
928 fp
= fopen("armor.out", "w");
934 log_debug("armor-filter: control: %d\n", control
);
935 if( control
== IOBUFCTRL_UNDERFLOW
&& afx
->inp_bypass
) {
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
)
943 for(; n
< size
; n
++ ) {
944 if( (c
=iobuf_get(a
)) == -1 )
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
956 if( size
< PARTIAL_CHUNK
+1 )
957 BUG(); /* supplied buffer too short */
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
)
971 else if( afx
->faked
) {
972 unsigned int hashes
= afx
->hashes
;
976 sesmark
= get_session_marker( &sesmarklen
);
977 if ( sesmarklen
> 20 )
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;
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
)
993 /* First a gpg control packet... */
994 buf
[n
++] = 0xff; /* new format, type 63, 1 length byte */
996 memcpy(buf
+n
, sesmark
, sesmarklen
); n
+= sesmarklen
;
997 buf
[n
++] = CTRLPKT_CLEARSIGN_START
;
998 buf
[n
++] = afx
->not_dash_escaped
? 0:1; /* sigclass */
1000 buf
[n
++] = DIGEST_ALGO_RMD160
;
1002 buf
[n
++] = DIGEST_ALGO_SHA1
;
1004 buf
[n
++] = DIGEST_ALGO_MD5
;
1006 buf
[n
++] = DIGEST_ALGO_SHA224
;
1008 buf
[n
++] = DIGEST_ALGO_SHA256
;
1010 buf
[n
++] = DIGEST_ALGO_SHA384
;
1012 buf
[n
++] = DIGEST_ALGO_SHA512
;
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 */
1029 rc
= radix64_read( afx
, a
, &n
, buf
, size
);
1032 rc
= radix64_read( afx
, a
, &n
, buf
, size
);
1035 if( fwrite(buf
, n
, 1, fp
) != 1 )
1040 else if( control
== IOBUFCTRL_FLUSH
&& !afx
->cancel
) {
1041 if( !afx
->status
) { /* write the header line */
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: " );
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" );
1074 iobuf_writestr(a
,afx
->eol
);
1077 if ( afx
->hdrlines
) {
1078 for ( s
= afx
->hdrlines
; *s
; s
++ ) {
1079 #ifdef HAVE_DOSISH_SYSTEM
1081 iobuf_put( a
, '\r');
1087 iobuf_writestr(a
,afx
->eol
);
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
]];
1104 for( ; size
; buf
++, size
-- ) {
1105 radbuf
[idx
++] = *buf
;
1108 c
= bintoasc
[(*radbuf
>> 2) & 077];
1110 c
= bintoasc
[(((*radbuf
<<4)&060)|((radbuf
[1] >> 4)&017))&077];
1112 c
= bintoasc
[(((radbuf
[1]<<2)&074)|((radbuf
[2]>>6)&03))&077];
1114 c
= bintoasc
[radbuf
[2]&077];
1116 if( ++idx2
>= (64/4) )
1117 { /* pgp doesn't like 72 here */
1118 iobuf_writestr(a
,afx
->eol
);
1123 for(i
=0; i
< idx
; i
++ )
1124 afx
->radbuf
[i
] = radbuf
[i
];
1129 else if( control
== IOBUFCTRL_INIT
)
1131 if( !is_initialized
)
1134 /* Figure out what we're using for line endings if the caller
1138 #ifdef HAVE_DOSISH_SYSTEM
1146 else if( control
== IOBUFCTRL_CANCEL
) {
1149 else if( control
== IOBUFCTRL_FREE
) {
1152 else if( afx
->status
) { /* pad, write cecksum, and bottom line */
1156 for(i
=0; i
< idx
; i
++ )
1157 radbuf
[i
] = afx
->radbuf
[i
];
1159 c
= bintoasc
[(*radbuf
>>2)&077];
1162 c
= bintoasc
[((*radbuf
<< 4) & 060) & 077];
1168 c
= bintoasc
[(((*radbuf
<<4)&060)|((radbuf
[1]>>4)&017))&077];
1170 c
= bintoasc
[((radbuf
[1] << 2) & 074) & 077];
1174 if( ++idx2
>= (64/4) )
1175 { /* pgp doesn't like 72 here */
1176 iobuf_writestr(a
,afx
->eol
);
1180 /* may need a linefeed */
1182 iobuf_writestr(a
,afx
->eol
);
1185 radbuf
[0] = crc
>>16;
1186 radbuf
[1] = crc
>> 8;
1188 c
= bintoasc
[(*radbuf
>> 2) & 077];
1190 c
= bintoasc
[(((*radbuf
<<4)&060)|((radbuf
[1] >> 4)&017))&077];
1192 c
= bintoasc
[(((radbuf
[1]<<2)&074)|((radbuf
[2]>>6)&03))&077];
1194 c
= bintoasc
[radbuf
[2]&077];
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"),
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
);
1219 release_armor_context (afx
);
1221 else if( control
== IOBUFCTRL_DESC
)
1222 *(char**)buf
= "armor_filter";
1228 * create a radix64 encoded string.
1231 make_radix64_string( const byte
*data
, size_t len
)
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];
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];
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
{
1268 STA_found_header_wait_newline
,
1269 STA_skip_header_lines
,
1270 STA_skip_header_lines_non_ws
,
1277 struct unarmor_pump_s
{
1278 enum unarmor_state_e state
;
1281 int pos
; /* counts from 0..3 */
1283 u32 mycrc
; /* the one store in the data */
1289 unarmor_pump_new (void)
1293 if( !is_initialized
)
1295 x
= xmalloc_clear (sizeof *x
);
1300 unarmor_pump_release (UnarmorPump 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 */
1324 if ( is_armored (tmp
) )
1325 x
->state
= c
== '-'? STA_first_dash
: STA_wait_newline
;
1327 x
->state
= STA_bypass
;
1333 return c
; /* return here to avoid crc calculation */
1334 case STA_wait_newline
:
1336 x
->state
= STA_wait_dash
;
1339 x
->state
= c
== '-'? STA_first_dash
: STA_wait_newline
;
1341 case STA_first_dash
: /* just need for initalization */
1343 x
->state
= STA_compare_header
;
1344 case STA_compare_header
:
1345 if ( "-----BEGIN PGP SIGNATURE-----"[++x
->pos
] == c
) {
1347 x
->state
= STA_found_header_wait_newline
;
1350 x
->state
= c
== '\n'? STA_wait_dash
: STA_wait_newline
;
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 */
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 */
1360 case STA_skip_header_lines
:
1361 /* i.e. wait for one empty line */
1363 x
->state
= STA_read_data
;
1368 else if ( c
!= '\r' && c
!= ' ' && c
!= '\t' )
1369 x
->state
= STA_skip_header_lines_non_ws
;
1371 case STA_skip_header_lines_non_ws
:
1372 /* like above but we already encountered non white space */
1374 x
->state
= STA_skip_header_lines
;
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 */
1385 x
->state
= STA_wait_crc
;
1391 if( (c
= asctobin
[(c2
=c
)]) == 255 ) {
1392 log_error(_("invalid radix64 character %02X skipped\n"), c2
);
1404 x
->val
= (c
<<4)&0xf0;
1407 x
->val
|= (c
>>2)&15;
1409 x
->val
= (c
<<6)&0xc0;
1416 x
->pos
= (x
->pos
+1) % 4;
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
;
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() )
1434 x
->state
= STA_ready
; /* not sure whether this is correct */
1444 x
->mycrc
|= x
->val
<< 16;
1445 x
->val
= (c
<<4)&0xf0;
1448 x
->val
|= (c
>>2)&15;
1449 x
->mycrc
|= x
->val
<< 8;
1450 x
->val
= (c
<<6)&0xc0;
1457 x
->pos
= (x
->pos
+1) % 4;
1464 if ( !(rval
& ~255) ) { /* compute the CRC */
1465 x
->crc
= (x
->crc
<< 8) ^ crc_table
[((x
->crc
>> 16)&0xff) ^ rval
];
1466 x
->crc
&= 0x00ffffff;