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 <http://www.gnu.org/licenses/>.
40 #define MAX_LINELEN 20000
42 #define CRCINIT 0xB704CE
43 #define CRCPOLY 0X864CFB
44 #define CRCUPDATE(a,c) do { \
45 a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \
48 static u32 crc_table
[256];
49 static byte bintoasc
[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
50 "abcdefghijklmnopqrstuvwxyz"
52 static byte asctobin
[256]; /* runtime initialized */
53 static int is_initialized
;
73 fhdrCHECKDashEscaped2
,
74 fhdrCHECKDashEscaped3
,
80 fhdrCLEARSIGSimpleNext
,
89 /* if we encounter this armor string with this index, go
90 * into a mode which fakes packets and wait for the next armor */
91 #define BEGIN_SIGNATURE 2
92 #define BEGIN_SIGNED_MSG_IDX 3
93 static char *head_strings
[] = {
95 "BEGIN PGP PUBLIC KEY BLOCK",
96 "BEGIN PGP SIGNATURE",
97 "BEGIN PGP SIGNED MESSAGE",
98 "BEGIN PGP ARMORED FILE", /* gnupg extension */
99 "BEGIN PGP PRIVATE KEY BLOCK",
100 "BEGIN PGP SECRET KEY BLOCK", /* only used by pgp2 */
103 static char *tail_strings
[] = {
105 "END PGP PUBLIC KEY BLOCK",
108 "END PGP ARMORED FILE",
109 "END PGP PRIVATE KEY BLOCK",
110 "END PGP SECRET KEY BLOCK",
115 static int armor_filter ( void *opaque
, int control
,
116 iobuf_t chain
, byte
*buf
, size_t *ret_len
);
121 /* Create a new context for armor filters. */
122 armor_filter_context_t
*
123 new_armor_context (void)
125 armor_filter_context_t
*afx
;
127 afx
= xcalloc (1, sizeof *afx
);
133 /* Release an armor filter context. Passing NULL is explicitly
134 allowed and a no-op. */
136 release_armor_context (armor_filter_context_t
*afx
)
140 assert (afx
->refcount
);
141 if ( --afx
->refcount
)
146 /* Push the armor filter onto the iobuf stream IOBUF. */
148 push_armor_filter (armor_filter_context_t
*afx
, iobuf_t iobuf
)
153 rc
= iobuf_push_filter (iobuf
, armor_filter
, afx
);
170 /* init the crc lookup table */
172 for(i
=j
=0; j
< 128; j
++ ) {
174 if( t
& 0x00800000 ) {
176 crc_table
[i
++] = t
^ CRCPOLY
;
182 crc_table
[i
++] = t
^ CRCPOLY
;
185 /* build the helptable for radix64 to bin conversion */
186 for(i
=0; i
< 256; i
++ )
187 asctobin
[i
] = 255; /* used to detect invalid characters */
188 for(s
=bintoasc
,i
=0; *s
; s
++,i
++ )
195 * Check whether this is an armored file or not See also
196 * parse-packet.c for details on this code For unknown historic
197 * reasons we use a string here but only the first byte will be used.
198 * Returns: True if it seems to be armored
201 is_armored( const byte
*buf
)
207 return 1; /* invalid packet: assume it is armored */
208 pkttype
= ctb
& 0x40 ? (ctb
& 0x3f) : ((ctb
>>2)&0xf);
212 case PKT_ONEPASS_SIG
:
218 case PKT_OLD_COMMENT
:
222 return 0; /* seems to be a regular packet: not armored */
230 * Try to check whether the iobuf is armored
231 * Returns true if this may be the case; the caller should use the
232 * filter to do further processing.
235 use_armor_filter( IOBUF a
)
240 /* fixme: there might be a problem with iobuf_peek */
241 n
= iobuf_peek(a
, buf
, 1 );
243 return 0; /* EOF, doesn't matter whether armored or not */
245 return 1; /* can't check it: try armored */
246 return is_armored(buf
);
255 write_status(STATUS_BADARMOR
);
256 g10_exit(1); /* stop here */
261 * check whether the armor header is valid on a signed message.
262 * this is for security reasons: the header lines are not included in the
263 * hash and by using some creative formatting rules, Mallory could fake
264 * any text at the beginning of a document; assuming it is read with
265 * a simple viewer. We only allow the Hash Header.
268 parse_hash_header( const char *line
)
273 if( strlen(line
) < 6 || strlen(line
) > 60 )
274 return 0; /* too short or too long */
275 if( memcmp( line
, "Hash:", 5 ) )
276 return 0; /* invalid header */
278 for(s
=line
+5;;s
=s2
) {
279 for(; *s
&& (*s
==' ' || *s
== '\t'); s
++ )
283 for(s2
=s
+1; *s2
&& *s2
!=' ' && *s2
!= '\t' && *s2
!= ','; s2
++ )
285 if( !strncmp( s
, "RIPEMD160", s2
-s
) )
287 else if( !strncmp( s
, "SHA1", s2
-s
) )
289 else if( !strncmp( s
, "MD5", s2
-s
) )
291 else if( !strncmp( s
, "SHA224", s2
-s
) )
293 else if( !strncmp( s
, "SHA256", s2
-s
) )
295 else if( !strncmp( s
, "SHA384", s2
-s
) )
297 else if( !strncmp( s
, "SHA512", s2
-s
) )
301 for(; *s2
&& (*s2
==' ' || *s2
== '\t'); s2
++ )
303 if( *s2
&& *s2
!= ',' )
311 /* Returns true if this is a valid armor tag as per RFC-2440bis-21. */
313 is_armor_tag(const char *line
)
315 if(strncmp(line
,"Version",7)==0
316 || strncmp(line
,"Comment",7)==0
317 || strncmp(line
,"MessageID",9)==0
318 || strncmp(line
,"Hash",4)==0
319 || strncmp(line
,"Charset",7)==0)
326 * Check whether this is a armor line.
327 * returns: -1 if it is not a armor header or the index number of the
331 is_armor_header( byte
*line
, unsigned len
)
339 return -1; /* too short */
340 if( memcmp( line
, "-----", 5 ) )
342 p
= strstr( line
+5, "-----");
348 /* Some Windows environments seem to add whitespace to the end of
349 the line, so we strip it here. This becomes strict if
350 --rfc2440 is set since 2440 reads "The header lines, therefore,
351 MUST start at the beginning of a line, and MUST NOT have text
352 following them on the same line." It is unclear whether "text"
353 refers to all text or just non-whitespace text. 4880 clarified
354 this was only non-whitespace text. */
364 while(*p
==' ' || *p
=='\r' || *p
=='\n' || *p
=='\t')
368 return -1; /* garbage after dashes */
369 save_c
= *save_p
; *save_p
= 0;
371 for(i
=0; (s
=head_strings
[i
]); i
++ )
376 return -1; /* unknown armor line */
378 if( opt
.verbose
> 1 )
379 log_info(_("armor: %s\n"), head_strings
[i
]);
386 * Parse a header lines
387 * Return 0: Empty line (end of header lines)
388 * -1: invalid header line
389 * >0: Good header line
392 parse_header_line( armor_filter_context_t
*afx
, byte
*line
, unsigned int len
)
398 len2
= length_sans_trailing_ws ( line
, len
);
400 afx
->buffer_pos
= len2
; /* (it is not the fine way to do it here) */
401 return 0; /* WS only: same as empty line */
405 This is fussy. The spec says that a header line is delimited
406 with a colon-space pair. This means that a line such as
407 "Comment: " (with nothing else) is actually legal as an empty
408 string comment. However, email and cut-and-paste being what it
409 is, that trailing space may go away. Therefore, we accept empty
410 headers delimited with only a colon. --rfc2440, as always,
411 makes this strict and enforces the colon-space pair. -dms
414 p
= strchr( line
, ':');
415 if( !p
|| (RFC2440
&& p
[1]!=' ')
416 || (!RFC2440
&& p
[1]!=' ' && p
[1]!='\n' && p
[1]!='\r'))
418 log_error(_("invalid armor header: "));
419 print_string( stderr
, line
, len
, 0 );
424 /* Chop off the whitespace we detected before */
429 log_info(_("armor header: "));
430 print_string( stderr
, line
, len
, 0 );
434 if( afx
->in_cleartext
)
436 if( (hashes
=parse_hash_header( line
)) )
437 afx
->hashes
|= hashes
;
438 else if( strlen(line
) > 15 && !memcmp( line
, "NotDashEscaped:", 15 ) )
439 afx
->not_dash_escaped
= 1;
442 log_error(_("invalid clearsig header\n"));
446 else if(!is_armor_tag(line
))
448 /* Section 6.2: "Unknown keys should be reported to the user,
449 but OpenPGP should continue to process the message." Note
450 that in a clearsigned message this applies to the signature
451 part (i.e. "BEGIN PGP SIGNATURE") and not the signed data
452 ("BEGIN PGP SIGNED MESSAGE"). The only key allowed in the
453 signed data section is "Hash". */
455 log_info(_("unknown armor header: "));
456 print_string( stderr
, line
, len
, 0 );
465 /* figure out whether the data is armored or not */
467 check_input( armor_filter_context_t
*afx
, IOBUF a
)
476 /* read the first line to see whether this is armored data */
477 maxlen
= MAX_LINELEN
;
478 len
= afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
479 &afx
->buffer_size
, &maxlen
);
482 /* line has been truncated: assume not armored */
483 afx
->inp_checked
= 1;
492 /* (the line is always a C string but maybe longer) */
493 if( *line
== '\n' || ( len
&& (*line
== '\r' && line
[1]=='\n') ) )
495 else if( !is_armored( line
) ) {
496 afx
->inp_checked
= 1;
501 /* find the armor header */
503 i
= is_armor_header( line
, len
);
504 if( i
>= 0 && !(afx
->only_keyblocks
&& i
!= 1 && i
!= 5 && i
!= 6 )) {
506 if( hdr_line
== BEGIN_SIGNED_MSG_IDX
) {
507 if( afx
->in_cleartext
) {
508 log_error(_("nested clear text signatures\n"));
509 rc
= gpg_error (GPG_ERR_INV_ARMOR
);
511 afx
->in_cleartext
= 1;
515 /* read the next line (skip all truncated lines) */
517 maxlen
= MAX_LINELEN
;
518 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
519 &afx
->buffer_size
, &maxlen
);
521 len
= afx
->buffer_len
;
525 /* Parse the header lines. */
527 /* Read the next line (skip all truncated lines). */
529 maxlen
= MAX_LINELEN
;
530 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
531 &afx
->buffer_size
, &maxlen
);
533 len
= afx
->buffer_len
;
536 i
= parse_header_line( afx
, line
, len
);
539 rc
= G10ERR_INVALID_ARMOR
;
547 else if( afx
->in_cleartext
)
550 afx
->inp_checked
= 1;
559 #define PARTIAL_CHUNK 512
560 #define PARTIAL_POW 9
563 * Fake a literal data packet and wait for the next armor line
564 * fixme: empty line handling and null length clear text signature are
565 * not implemented/checked.
568 fake_packet( armor_filter_context_t
*afx
, IOBUF a
,
569 size_t *retn
, byte
*buf
, size_t size
)
576 byte tempbuf
[PARTIAL_CHUNK
];
577 size_t tempbuf_len
=0;
579 while( !rc
&& size
-len
>=(PARTIAL_CHUNK
+1)) {
580 /* copy what we have in the line buffer */
581 if( afx
->faked
== 1 )
582 afx
->faked
++; /* skip the first (empty) line */
585 /* It's full, so write this partial chunk */
586 if(tempbuf_len
==PARTIAL_CHUNK
)
588 buf
[len
++]=0xE0+PARTIAL_POW
;
589 memcpy(&buf
[len
],tempbuf
,PARTIAL_CHUNK
);
595 while( tempbuf_len
< PARTIAL_CHUNK
596 && afx
->buffer_pos
< afx
->buffer_len
)
597 tempbuf
[tempbuf_len
++] = afx
->buffer
[afx
->buffer_pos
++];
598 if( tempbuf_len
==PARTIAL_CHUNK
)
602 /* read the next line */
603 maxlen
= MAX_LINELEN
;
605 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
606 &afx
->buffer_size
, &maxlen
);
607 if( !afx
->buffer_len
) {
608 rc
= -1; /* eof (should not happen) */
617 /* Armor header or dash-escaped line? */
620 /* 2440bis-10: When reversing dash-escaping, an
621 implementation MUST strip the string "- " if it occurs
622 at the beginning of a line, and SHOULD warn on "-" and
623 any character other than a space at the beginning of a
626 if(p
[1]==' ' && !afx
->not_dash_escaped
)
628 /* It's a dash-escaped line, so skip over the
632 else if(p
[1]=='-' && p
[2]=='-' && p
[3]=='-' && p
[4]=='-')
634 /* Five dashes in a row mean it's probably armor
636 int type
= is_armor_header( p
, n
);
637 if( afx
->not_dash_escaped
&& type
!= BEGIN_SIGNATURE
)
641 if( type
!= BEGIN_SIGNATURE
)
643 log_info(_("unexpected armor: "));
644 print_string( stderr
, p
, n
, 0 );
652 else if(!afx
->not_dash_escaped
)
654 /* Bad dash-escaping. */
655 log_info(_("invalid dash escaped line: "));
656 print_string( stderr
, p
, n
, 0 );
661 /* Now handle the end-of-line canonicalization */
662 if( !afx
->not_dash_escaped
)
664 int crlf
= n
> 1 && p
[n
-2] == '\r' && p
[n
-1]=='\n';
666 /* PGP2 does not treat a tab as white space character */
668 trim_trailing_chars( &p
[afx
->buffer_pos
], n
-afx
->buffer_pos
,
669 afx
->pgp2mode
? " \r\n" : " \t\r\n");
670 afx
->buffer_len
+=afx
->buffer_pos
;
671 /* the buffer is always allocated with enough space to append
672 * the removed [CR], LF and a Nul
673 * The reason for this complicated procedure is to keep at least
674 * the original type of lineending - handling of the removed
675 * trailing spaces seems to be impossible in our method
676 * of faking a packet; either we have to use a temporary file
677 * or calculate the hash here in this module and somehow find
678 * a way to send the hash down the processing line (well, a special
679 * faked packet could do the job).
682 afx
->buffer
[afx
->buffer_len
++] = '\r';
683 afx
->buffer
[afx
->buffer_len
++] = '\n';
684 afx
->buffer
[afx
->buffer_len
] = '\0';
688 if( lastline
) { /* write last (ending) length header */
690 buf
[len
++]=tempbuf_len
;
693 buf
[len
++]=((tempbuf_len
-192)/256) + 192;
694 buf
[len
++]=(tempbuf_len
-192) % 256;
696 memcpy(&buf
[len
],tempbuf
,tempbuf_len
);
701 afx
->in_cleartext
= 0;
702 /* and now read the header lines */
707 /* read the next line (skip all truncated lines) */
709 maxlen
= MAX_LINELEN
;
710 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
711 &afx
->buffer_size
, &maxlen
);
719 i
= parse_header_line( afx
, p
, n
);
726 afx
->inp_checked
= 1;
740 if ( opt
.ignore_crc_error
)
742 log_inc_errorcount();
743 return gpg_error (GPG_ERR_INV_ARMOR
);
748 radix64_read( armor_filter_context_t
*afx
, IOBUF a
, size_t *retn
,
749 byte
*buf
, size_t size
)
752 int c
=0, c2
; /*init c because gcc is not clever enough for the continue*/
756 int idx
, i
, onlypad
=0;
761 val
= afx
->radbuf
[0];
762 for( n
=0; n
< size
; ) {
764 if( afx
->buffer_pos
< afx
->buffer_len
)
765 c
= afx
->buffer
[afx
->buffer_pos
++];
766 else { /* read the next line */
767 unsigned maxlen
= MAX_LINELEN
;
769 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
770 &afx
->buffer_size
, &maxlen
);
773 if( !afx
->buffer_len
)
779 if( c
== '\n' || c
== ' ' || c
== '\r' || c
== '\t' )
781 else if( c
== '=' ) { /* pad character: stop */
782 /* some mailers leave quoted-printable encoded characters
783 * so we try to workaround this */
784 if( afx
->buffer_pos
+2 < afx
->buffer_len
) {
786 cc1
= afx
->buffer
[afx
->buffer_pos
];
787 cc2
= afx
->buffer
[afx
->buffer_pos
+1];
788 cc3
= afx
->buffer
[afx
->buffer_pos
+2];
789 if( isxdigit(cc1
) && isxdigit(cc2
)
790 && strchr( "=\n\r\t ", cc3
)) {
791 /* well it seems to be the case - adjust */
792 c
= isdigit(cc1
)? (cc1
- '0'): (ascii_toupper(cc1
)-'A'+10);
794 c
|= isdigit(cc2
)? (cc2
- '0'): (ascii_toupper(cc2
)-'A'+10);
795 afx
->buffer_pos
+= 2;
796 afx
->qp_detected
= 1;
808 else if( (c
= asctobin
[(c2
=c
)]) == 255 ) {
809 log_error(_("invalid radix64 character %02X skipped\n"), c2
);
813 case 0: val
= c
<< 2; break;
814 case 1: val
|= (c
>>4)&3; buf
[n
++]=val
;val
=(c
<<4)&0xf0;break;
815 case 2: val
|= (c
>>2)&15; buf
[n
++]=val
;val
=(c
<<6)&0xc0;break;
816 case 3: val
|= c
&0x3f; buf
[n
++] = val
; break;
821 for(i
=0; i
< n
; i
++ )
822 crc
= (crc
<< 8) ^ crc_table
[((crc
>> 16)&0xff) ^ buf
[i
]];
826 afx
->radbuf
[0] = val
;
832 for(;;) { /* skip lf and pad characters */
833 if( afx
->buffer_pos
< afx
->buffer_len
)
834 c
= afx
->buffer
[afx
->buffer_pos
++];
835 else { /* read the next line */
836 unsigned maxlen
= MAX_LINELEN
;
838 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
839 &afx
->buffer_size
, &maxlen
);
842 if( !afx
->buffer_len
)
846 if( c
== '\n' || c
== ' ' || c
== '\r'
847 || c
== '\t' || c
== '=' )
852 log_error(_("premature eof (no CRC)\n"));
857 if( (c
= asctobin
[c
]) == 255 )
860 case 0: val
= c
<< 2; break;
861 case 1: val
|= (c
>>4)&3; mycrc
|= val
<< 16;val
=(c
<<4)&0xf0;break;
862 case 2: val
|= (c
>>2)&15; mycrc
|= val
<< 8;val
=(c
<<6)&0xc0;break;
863 case 3: val
|= c
&0x3f; mycrc
|= val
; break;
866 if( afx
->buffer_pos
< afx
->buffer_len
)
867 c
= afx
->buffer
[afx
->buffer_pos
++];
868 else { /* read the next line */
869 unsigned maxlen
= MAX_LINELEN
;
871 afx
->buffer_len
= iobuf_read_line( a
, &afx
->buffer
,
876 if( !afx
->buffer_len
)
882 if( !afx
->buffer_len
)
884 } while( ++idx
< 4 );
886 log_info(_("premature eof (in CRC)\n"));
889 else if( idx
== 0 ) {
890 /* No CRC at all is legal ("MAY") */
893 else if( idx
!= 4 ) {
894 log_info(_("malformed CRC\n"));
897 else if( mycrc
!= afx
->crc
) {
898 log_info (_("CRC error; %06lX - %06lX\n"),
899 (ulong
)afx
->crc
, (ulong
)mycrc
);
904 /* FIXME: Here we should emit another control packet,
905 * so that we know in mainproc that we are processing
906 * a clearsign message */
909 rc
= 0 /*check_trailer( &fhdr, c )*/;
911 if( (c
=iobuf_get(a
)) == -1 )
918 log_error(_("premature eof (in trailer)\n"));
919 rc
= G10ERR_INVALID_ARMOR
;
922 log_error(_("error in trailer line\n"));
923 rc
= G10ERR_INVALID_ARMOR
;
938 * This filter is used to handle the armor stuff
941 armor_filter( void *opaque
, int control
,
942 IOBUF a
, byte
*buf
, size_t *ret_len
)
944 size_t size
= *ret_len
;
945 armor_filter_context_t
*afx
= opaque
;
955 fp
= fopen("armor.out", "w");
961 log_debug("armor-filter: control: %d\n", control
);
962 if( control
== IOBUFCTRL_UNDERFLOW
&& afx
->inp_bypass
) {
964 if( afx
->buffer_len
) {
965 for(; n
< size
&& afx
->buffer_pos
< afx
->buffer_len
; n
++ )
966 buf
[n
++] = afx
->buffer
[afx
->buffer_pos
++];
967 if( afx
->buffer_pos
>= afx
->buffer_len
)
970 for(; n
< size
; n
++ ) {
971 if( (c
=iobuf_get(a
)) == -1 )
979 else if( control
== IOBUFCTRL_UNDERFLOW
) {
980 /* We need some space for the faked packet. The minmum
981 * required size is the PARTIAL_CHUNK size plus a byte for the
983 if( size
< PARTIAL_CHUNK
+1 )
984 BUG(); /* supplied buffer too short */
987 rc
= fake_packet( afx
, a
, &n
, buf
, size
);
988 else if( !afx
->inp_checked
) {
989 rc
= check_input( afx
, a
);
990 if( afx
->inp_bypass
) {
991 for(n
=0; n
< size
&& afx
->buffer_pos
< afx
->buffer_len
; )
992 buf
[n
++] = afx
->buffer
[afx
->buffer_pos
++];
993 if( afx
->buffer_pos
>= afx
->buffer_len
)
998 else if( afx
->faked
) {
999 unsigned int hashes
= afx
->hashes
;
1000 const byte
*sesmark
;
1003 sesmark
= get_session_marker( &sesmarklen
);
1004 if ( sesmarklen
> 20 )
1007 /* the buffer is at least 15+n*15 bytes long, so it
1008 * is easy to construct the packets */
1010 hashes
&= 1|2|4|8|16|32|64;
1012 hashes
|= 4; /* default to MD 5 */
1013 /* This is non-ideal since PGP 5-8 have the same
1014 end-of-line bugs as PGP 2. However, we only
1015 enable pgp2mode if there is no Hash: header. */
1016 if( opt
.pgp2_workarounds
)
1020 /* First a gpg control packet... */
1021 buf
[n
++] = 0xff; /* new format, type 63, 1 length byte */
1022 n
++; /* see below */
1023 memcpy(buf
+n
, sesmark
, sesmarklen
); n
+= sesmarklen
;
1024 buf
[n
++] = CTRLPKT_CLEARSIGN_START
;
1025 buf
[n
++] = afx
->not_dash_escaped
? 0:1; /* sigclass */
1027 buf
[n
++] = DIGEST_ALGO_RMD160
;
1029 buf
[n
++] = DIGEST_ALGO_SHA1
;
1031 buf
[n
++] = DIGEST_ALGO_MD5
;
1033 buf
[n
++] = DIGEST_ALGO_SHA224
;
1035 buf
[n
++] = DIGEST_ALGO_SHA256
;
1037 buf
[n
++] = DIGEST_ALGO_SHA384
;
1039 buf
[n
++] = DIGEST_ALGO_SHA512
;
1042 /* ...followed by an invented plaintext packet.
1043 Amusingly enough, this packet is not compliant with
1044 2440 as the initial partial length is less than 512
1045 bytes. Of course, we'll accept it anyway ;) */
1047 buf
[n
++] = 0xCB; /* new packet format, type 11 */
1048 buf
[n
++] = 0xE1; /* 2^1 == 2 bytes */
1049 buf
[n
++] = 't'; /* canonical text mode */
1050 buf
[n
++] = 0; /* namelength */
1051 buf
[n
++] = 0xE2; /* 2^2 == 4 more bytes */
1052 memset(buf
+n
, 0, 4); /* timestamp */
1056 rc
= radix64_read( afx
, a
, &n
, buf
, size
);
1059 rc
= radix64_read( afx
, a
, &n
, buf
, size
);
1062 if( fwrite(buf
, n
, 1, fp
) != 1 )
1067 else if( control
== IOBUFCTRL_FLUSH
&& !afx
->cancel
) {
1068 if( !afx
->status
) { /* write the header line */
1070 strlist_t comment
=opt
.comments
;
1072 if( afx
->what
>= DIM(head_strings
) )
1073 log_bug("afx->what=%d", afx
->what
);
1074 iobuf_writestr(a
, "-----");
1075 iobuf_writestr(a
, head_strings
[afx
->what
] );
1076 iobuf_writestr(a
, "-----" );
1077 iobuf_writestr(a
,afx
->eol
);
1078 if( !opt
.no_version
)
1080 iobuf_writestr(a
, "Version: GnuPG v" VERSION
" ("
1081 PRINTABLE_OS_NAME
")" );
1082 iobuf_writestr(a
,afx
->eol
);
1085 /* write the comment strings */
1086 for(s
=comment
->d
;comment
;comment
=comment
->next
,s
=comment
->d
)
1088 iobuf_writestr(a
, "Comment: " );
1092 iobuf_writestr(a
, "\\n" );
1093 else if( *s
== '\r' )
1094 iobuf_writestr(a
, "\\r" );
1095 else if( *s
== '\v' )
1096 iobuf_writestr(a
, "\\v" );
1101 iobuf_writestr(a
,afx
->eol
);
1104 if ( afx
->hdrlines
) {
1105 for ( s
= afx
->hdrlines
; *s
; s
++ ) {
1106 #ifdef HAVE_DOSISH_SYSTEM
1108 iobuf_put( a
, '\r');
1114 iobuf_writestr(a
,afx
->eol
);
1124 for(i
=0; i
< idx
; i
++ )
1125 radbuf
[i
] = afx
->radbuf
[i
];
1127 for(i
=0; i
< size
; i
++ )
1128 crc
= (crc
<< 8) ^ crc_table
[((crc
>> 16)&0xff) ^ buf
[i
]];
1131 for( ; size
; buf
++, size
-- ) {
1132 radbuf
[idx
++] = *buf
;
1135 c
= bintoasc
[(*radbuf
>> 2) & 077];
1137 c
= bintoasc
[(((*radbuf
<<4)&060)|((radbuf
[1] >> 4)&017))&077];
1139 c
= bintoasc
[(((radbuf
[1]<<2)&074)|((radbuf
[2]>>6)&03))&077];
1141 c
= bintoasc
[radbuf
[2]&077];
1143 if( ++idx2
>= (64/4) )
1144 { /* pgp doesn't like 72 here */
1145 iobuf_writestr(a
,afx
->eol
);
1150 for(i
=0; i
< idx
; i
++ )
1151 afx
->radbuf
[i
] = radbuf
[i
];
1156 else if( control
== IOBUFCTRL_INIT
)
1158 if( !is_initialized
)
1161 /* Figure out what we're using for line endings if the caller
1165 #ifdef HAVE_DOSISH_SYSTEM
1173 else if( control
== IOBUFCTRL_CANCEL
) {
1176 else if( control
== IOBUFCTRL_FREE
) {
1179 else if( afx
->status
) { /* pad, write cecksum, and bottom line */
1183 for(i
=0; i
< idx
; i
++ )
1184 radbuf
[i
] = afx
->radbuf
[i
];
1186 c
= bintoasc
[(*radbuf
>>2)&077];
1189 c
= bintoasc
[((*radbuf
<< 4) & 060) & 077];
1195 c
= bintoasc
[(((*radbuf
<<4)&060)|((radbuf
[1]>>4)&017))&077];
1197 c
= bintoasc
[((radbuf
[1] << 2) & 074) & 077];
1201 if( ++idx2
>= (64/4) )
1202 { /* pgp doesn't like 72 here */
1203 iobuf_writestr(a
,afx
->eol
);
1207 /* may need a linefeed */
1209 iobuf_writestr(a
,afx
->eol
);
1212 radbuf
[0] = crc
>>16;
1213 radbuf
[1] = crc
>> 8;
1215 c
= bintoasc
[(*radbuf
>> 2) & 077];
1217 c
= bintoasc
[(((*radbuf
<<4)&060)|((radbuf
[1] >> 4)&017))&077];
1219 c
= bintoasc
[(((radbuf
[1]<<2)&074)|((radbuf
[2]>>6)&03))&077];
1221 c
= bintoasc
[radbuf
[2]&077];
1223 iobuf_writestr(a
,afx
->eol
);
1224 /* and the the trailer */
1225 if( afx
->what
>= DIM(tail_strings
) )
1226 log_bug("afx->what=%d", afx
->what
);
1227 iobuf_writestr(a
, "-----");
1228 iobuf_writestr(a
, tail_strings
[afx
->what
] );
1229 iobuf_writestr(a
, "-----" );
1230 iobuf_writestr(a
,afx
->eol
);
1232 else if( !afx
->any_data
&& !afx
->inp_bypass
) {
1233 log_error(_("no valid OpenPGP data found.\n"));
1234 afx
->no_openpgp_data
= 1;
1235 write_status_text( STATUS_NODATA
, "1" );
1237 if( afx
->truncated
)
1238 log_info(_("invalid armor: line longer than %d characters\n"),
1240 /* issue an error to enforce dissemination of correct software */
1241 if( afx
->qp_detected
)
1242 log_error(_("quoted printable character in armor - "
1243 "probably a buggy MTA has been used\n") );
1244 xfree( afx
->buffer
);
1246 release_armor_context (afx
);
1248 else if( control
== IOBUFCTRL_DESC
)
1249 *(char**)buf
= "armor_filter";
1255 * create a radix64 encoded string.
1258 make_radix64_string( const byte
*data
, size_t len
)
1262 buffer
= p
= xmalloc( (len
+2)/3*4 + 1 );
1263 for( ; len
>= 3 ; len
-= 3, data
+= 3 ) {
1264 *p
++ = bintoasc
[(data
[0] >> 2) & 077];
1265 *p
++ = bintoasc
[(((data
[0] <<4)&060)|((data
[1] >> 4)&017))&077];
1266 *p
++ = bintoasc
[(((data
[1]<<2)&074)|((data
[2]>>6)&03))&077];
1267 *p
++ = bintoasc
[data
[2]&077];
1270 *p
++ = bintoasc
[(data
[0] >> 2) & 077];
1271 *p
++ = bintoasc
[(((data
[0] <<4)&060)|((data
[1] >> 4)&017))&077];
1272 *p
++ = bintoasc
[((data
[1]<<2)&074)];
1274 else if( len
== 1 ) {
1275 *p
++ = bintoasc
[(data
[0] >> 2) & 077];
1276 *p
++ = bintoasc
[(data
[0] <<4)&060];
1283 /***********************************************
1284 * For the pipemode command we can't use the armor filter for various
1285 * reasons, so we use this new unarmor_pump stuff to remove the armor
1288 enum unarmor_state_e
{
1295 STA_found_header_wait_newline
,
1296 STA_skip_header_lines
,
1297 STA_skip_header_lines_non_ws
,
1304 struct unarmor_pump_s
{
1305 enum unarmor_state_e state
;
1308 int pos
; /* counts from 0..3 */
1310 u32 mycrc
; /* the one store in the data */
1316 unarmor_pump_new (void)
1320 if( !is_initialized
)
1322 x
= xmalloc_clear (sizeof *x
);
1327 unarmor_pump_release (UnarmorPump x
)
1333 * Get the next character from the ascii armor taken from the IOBUF
1334 * created earlier by unarmor_pump_new().
1335 * Return: c = Character
1336 * 256 = ignore this value
1337 * -1 = End of current armor
1338 * -2 = Premature EOF (not used)
1339 * -3 = Invalid armor
1342 unarmor_pump (UnarmorPump x
, int c
)
1344 int rval
= 256; /* default is to ignore the return value */
1351 if ( is_armored (tmp
) )
1352 x
->state
= c
== '-'? STA_first_dash
: STA_wait_newline
;
1354 x
->state
= STA_bypass
;
1360 return c
; /* return here to avoid crc calculation */
1361 case STA_wait_newline
:
1363 x
->state
= STA_wait_dash
;
1366 x
->state
= c
== '-'? STA_first_dash
: STA_wait_newline
;
1368 case STA_first_dash
: /* just need for initalization */
1370 x
->state
= STA_compare_header
;
1371 case STA_compare_header
:
1372 if ( "-----BEGIN PGP SIGNATURE-----"[++x
->pos
] == c
) {
1374 x
->state
= STA_found_header_wait_newline
;
1377 x
->state
= c
== '\n'? STA_wait_dash
: STA_wait_newline
;
1379 case STA_found_header_wait_newline
:
1380 /* to make CR,LF issues easier we simply allow for white space
1381 behind the 5 dashes */
1383 x
->state
= STA_skip_header_lines
;
1384 else if ( c
!= '\r' && c
!= ' ' && c
!= '\t' )
1385 x
->state
= STA_wait_dash
; /* garbage after the header line */
1387 case STA_skip_header_lines
:
1388 /* i.e. wait for one empty line */
1390 x
->state
= STA_read_data
;
1395 else if ( c
!= '\r' && c
!= ' ' && c
!= '\t' )
1396 x
->state
= STA_skip_header_lines_non_ws
;
1398 case STA_skip_header_lines_non_ws
:
1399 /* like above but we already encountered non white space */
1401 x
->state
= STA_skip_header_lines
;
1404 /* fixme: we don't check for the trailing dash lines but rely
1405 * on the armor stop characters */
1406 if( c
== '\n' || c
== ' ' || c
== '\r' || c
== '\t' )
1407 break; /* skip all kind of white space */
1409 if( c
== '=' ) { /* pad character: stop */
1410 if( x
->pos
== 1 ) /* in this case val has some value */
1412 x
->state
= STA_wait_crc
;
1418 if( (c
= asctobin
[(c2
=c
)]) == 255 ) {
1419 log_error(_("invalid radix64 character %02X skipped\n"), c2
);
1431 x
->val
= (c
<<4)&0xf0;
1434 x
->val
|= (c
>>2)&15;
1436 x
->val
= (c
<<6)&0xc0;
1443 x
->pos
= (x
->pos
+1) % 4;
1446 if( c
== '\n' || c
== ' ' || c
== '\r' || c
== '\t' || c
== '=' )
1447 break; /* skip ws and pad characters */
1448 /* assume that we are at the next line */
1449 x
->state
= STA_read_crc
;
1453 if( (c
= asctobin
[c
]) == 255 ) {
1454 rval
= -1; /* ready */
1455 if( x
->crc
!= x
->mycrc
) {
1456 log_info (_("CRC error; %06lX - %06lX\n"),
1457 (ulong
)x
->crc
, (ulong
)x
->mycrc
);
1458 if ( invalid_crc() )
1461 x
->state
= STA_ready
; /* not sure whether this is correct */
1471 x
->mycrc
|= x
->val
<< 16;
1472 x
->val
= (c
<<4)&0xf0;
1475 x
->val
|= (c
>>2)&15;
1476 x
->mycrc
|= x
->val
<< 8;
1477 x
->val
= (c
<<6)&0xc0;
1484 x
->pos
= (x
->pos
+1) % 4;
1491 if ( !(rval
& ~255) ) { /* compute the CRC */
1492 x
->crc
= (x
->crc
<< 8) ^ crc_table
[((x
->crc
>> 16)&0xff) ^ rval
];
1493 x
->crc
&= 0x00ffffff;