LCOV - code coverage report
Current view: top level - g10 - armor.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 511 767 66.6 %
Date: 2016-09-12 12:29:17 Functions: 15 20 75.0 %

          Line data    Source code
       1             : /* armor.c - Armor flter
       2             :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
       3             :  *               2007 Free Software Foundation, Inc.
       4             :  *
       5             :  * This file is part of GnuPG.
       6             :  *
       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.
      11             :  *
      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.
      16             :  *
      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/>.
      19             :  */
      20             : 
      21             : #include <config.h>
      22             : #include <stdio.h>
      23             : #include <stdlib.h>
      24             : #include <string.h>
      25             : #include <errno.h>
      26             : #include <ctype.h>
      27             : 
      28             : #include "gpg.h"
      29             : #include "status.h"
      30             : #include "iobuf.h"
      31             : #include "util.h"
      32             : #include "filter.h"
      33             : #include "packet.h"
      34             : #include "options.h"
      35             : #include "main.h"
      36             : #include "status.h"
      37             : #include "i18n.h"
      38             : 
      39             : #define MAX_LINELEN 20000
      40             : 
      41             : #define CRCINIT 0xB704CE
      42             : #define CRCPOLY 0X864CFB
      43             : #define CRCUPDATE(a,c) do {                                                 \
      44             :                         a = ((a) << 8) ^ crc_table[((a)&0xff >> 16) ^ (c)]; \
      45             :                         a &= 0x00ffffff;                                \
      46             :                     } while(0)
      47             : static u32 crc_table[256];
      48             : static byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      49             :                          "abcdefghijklmnopqrstuvwxyz"
      50             :                          "0123456789+/";
      51             : static byte asctobin[256]; /* runtime initialized */
      52             : static int is_initialized;
      53             : 
      54             : 
      55             : typedef enum {
      56             :     fhdrHASArmor = 0,
      57             :     fhdrNOArmor,
      58             :     fhdrINIT,
      59             :     fhdrINITCont,
      60             :     fhdrINITSkip,
      61             :     fhdrCHECKBegin,
      62             :     fhdrWAITHeader,
      63             :     fhdrWAITClearsig,
      64             :     fhdrSKIPHeader,
      65             :     fhdrCLEARSIG,
      66             :     fhdrREADClearsig,
      67             :     fhdrNullClearsig,
      68             :     fhdrEMPTYClearsig,
      69             :     fhdrCHECKClearsig,
      70             :     fhdrCHECKClearsig2,
      71             :     fhdrCHECKDashEscaped,
      72             :     fhdrCHECKDashEscaped2,
      73             :     fhdrCHECKDashEscaped3,
      74             :     fhdrREADClearsigNext,
      75             :     fhdrENDClearsig,
      76             :     fhdrENDClearsigHelp,
      77             :     fhdrTESTSpaces,
      78             :     fhdrCLEARSIGSimple,
      79             :     fhdrCLEARSIGSimpleNext,
      80             :     fhdrTEXT,
      81             :     fhdrTEXTSimple,
      82             :     fhdrERROR,
      83             :     fhdrERRORShow,
      84             :     fhdrEOF
      85             : } fhdr_state_t;
      86             : 
      87             : 
      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[] = {
      93             :     "BEGIN PGP MESSAGE",
      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 */
     100             :     NULL
     101             : };
     102             : static char *tail_strings[] = {
     103             :     "END PGP MESSAGE",
     104             :     "END PGP PUBLIC KEY BLOCK",
     105             :     "END PGP SIGNATURE",
     106             :     "END dummy",
     107             :     "END PGP ARMORED FILE",
     108             :     "END PGP PRIVATE KEY BLOCK",
     109             :     "END PGP SECRET KEY BLOCK",
     110             :     NULL
     111             : };
     112             : 
     113             : 
     114             : static int armor_filter ( void *opaque, int control,
     115             :                           iobuf_t chain, byte *buf, size_t *ret_len);
     116             : 
     117             : 
     118             : 
     119             : 
     120             : /* Create a new context for armor filters.  */
     121             : armor_filter_context_t *
     122         301 : new_armor_context (void)
     123             : {
     124             :   armor_filter_context_t *afx;
     125             : 
     126         301 :   afx = xcalloc (1, sizeof *afx);
     127         301 :   afx->refcount = 1;
     128             : 
     129         301 :   return afx;
     130             : }
     131             : 
     132             : /* Release an armor filter context.  Passing NULL is explicitly
     133             :    allowed and a no-op.  */
     134             : void
     135        2598 : release_armor_context (armor_filter_context_t *afx)
     136             : {
     137        2598 :   if (!afx)
     138        2095 :     return;
     139         503 :   log_assert (afx->refcount);
     140         503 :   if ( --afx->refcount )
     141         203 :     return;
     142         300 :   xfree (afx);
     143             : }
     144             : 
     145             : /* Push the armor filter onto the iobuf stream IOBUF.  */
     146             : int
     147         203 : push_armor_filter (armor_filter_context_t *afx, iobuf_t iobuf)
     148             : {
     149             :   int rc;
     150             : 
     151         203 :   afx->refcount++;
     152         203 :   rc = iobuf_push_filter (iobuf, armor_filter, afx);
     153         203 :   if (rc)
     154           0 :     afx->refcount--;
     155         203 :   return rc;
     156             : }
     157             : 
     158             : 
     159             : 
     160             : 
     161             : 
     162             : static void
     163         198 : initialize(void)
     164             : {
     165             :     int i, j;
     166             :     u32 t;
     167             :     byte *s;
     168             : 
     169             :     /* init the crc lookup table */
     170         198 :     crc_table[0] = 0;
     171       25542 :     for(i=j=0; j < 128; j++ ) {
     172       25344 :         t = crc_table[j];
     173       25344 :         if( t & 0x00800000 ) {
     174       12672 :             t <<= 1;
     175       12672 :             crc_table[i++] = t ^ CRCPOLY;
     176       12672 :             crc_table[i++] = t;
     177             :         }
     178             :         else {
     179       12672 :             t <<= 1;
     180       12672 :             crc_table[i++] = t;
     181       12672 :             crc_table[i++] = t ^ CRCPOLY;
     182             :         }
     183             :     }
     184             :     /* build the helptable for radix64 to bin conversion */
     185       50886 :     for(i=0; i < 256; i++ )
     186       50688 :         asctobin[i] = 255; /* used to detect invalid characters */
     187       12870 :     for(s=bintoasc,i=0; *s; s++,i++ )
     188       12672 :         asctobin[*s] = i;
     189             : 
     190         198 :     is_initialized=1;
     191         198 : }
     192             : 
     193             : 
     194             : /*
     195             :  * Check whether this is an armored file.  See also
     196             :  * parse-packet.c for details on this code.
     197             :  *
     198             :  * Note that the buffer BUF needs to be at least 2 bytes long.  If in
     199             :  * doubt that the second byte to 0.
     200             :  *
     201             :  * Returns: True if it seems to be armored
     202             :  */
     203             : static int
     204         899 : is_armored (const byte *buf)
     205             : {
     206             :   int ctb, pkttype;
     207             :   int indeterminate_length_allowed;
     208             : 
     209         899 :     ctb = *buf;
     210         899 :     if( !(ctb & 0x80) )
     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
     213             :          armored.  */
     214         361 :       return 1;
     215             : 
     216         538 :     pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
     217         538 :     switch( pkttype ) {
     218             :       case PKT_PUBKEY_ENC:
     219             :       case PKT_SIGNATURE:
     220             :       case PKT_SYMKEY_ENC:
     221             :       case PKT_ONEPASS_SIG:
     222             :       case PKT_SECRET_KEY:
     223             :       case PKT_PUBLIC_KEY:
     224             :       case PKT_SECRET_SUBKEY:
     225             :       case PKT_MARKER:
     226             :       case PKT_RING_TRUST:
     227             :       case PKT_USER_ID:
     228             :       case PKT_PUBLIC_SUBKEY:
     229             :       case PKT_ATTRIBUTE:
     230             :       case PKT_MDC:
     231         469 :         indeterminate_length_allowed = 0;
     232         469 :         break;
     233             : 
     234             :       case PKT_COMPRESSED:
     235             :       case PKT_ENCRYPTED:
     236             :       case PKT_ENCRYPTED_MDC:
     237             :       case PKT_PLAINTEXT:
     238             :       case PKT_OLD_COMMENT:
     239             :       case PKT_COMMENT:
     240             :       case PKT_GPG_CONTROL:
     241          69 :         indeterminate_length_allowed = 1;
     242          69 :         break;
     243             : 
     244             :       default:
     245             :         /* Invalid packet type.  */
     246           0 :         return 1;
     247             :     }
     248             : 
     249         538 :     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
     253             :          OpenPGP data.  */
     254             :       {
     255             :         int new_format;
     256             :         int indeterminate_length;
     257             : 
     258         469 :         new_format = !! (ctb & (1 << 6));
     259         469 :         if (new_format)
     260           1 :           indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
     261             :         else
     262         468 :           indeterminate_length = (ctb & 3) == 3;
     263             : 
     264         469 :         if (indeterminate_length)
     265           0 :           return 1;
     266             :       }
     267             : 
     268             :     /* The first CTB seems legit.  It is probably not armored
     269             :        data.  */
     270         538 :     return 0;
     271             : }
     272             : 
     273             : 
     274             : /****************
     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.
     278             :  */
     279             : int
     280         621 : use_armor_filter( IOBUF a )
     281             : {
     282             :     byte buf[2];
     283             :     int n;
     284             : 
     285             :     /* fixme: there might be a problem with iobuf_peek */
     286         621 :     n = iobuf_peek (a, buf, 2);
     287         621 :     if( n == -1 )
     288           0 :         return 0; /* EOF, doesn't matter whether armored or not */
     289         621 :     if( !n )
     290           0 :         return 1; /* can't check it: try armored */
     291         621 :     if (n != 2)
     292           1 :         return 0; /* short buffer */
     293         620 :     return is_armored(buf);
     294             : }
     295             : 
     296             : 
     297             : 
     298             : 
     299             : static void
     300           0 : invalid_armor(void)
     301             : {
     302           0 :     write_status(STATUS_BADARMOR);
     303           0 :     g10_exit(1); /* stop here */
     304             : }
     305             : 
     306             : 
     307             : /****************
     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.
     313             :  */
     314             : static int
     315          18 : parse_hash_header( const char *line )
     316             : {
     317             :     const char *s, *s2;
     318          18 :     unsigned found = 0;
     319             : 
     320          18 :     if( strlen(line) < 6  || strlen(line) > 60 )
     321           0 :         return 0; /* too short or too long */
     322          18 :     if( memcmp( line, "Hash:", 5 ) )
     323           1 :         return 0; /* invalid header */
     324             : 
     325          34 :     for(s=line+5;;s=s2) {
     326          34 :         for(; *s && (*s==' ' || *s == '\t'); s++ )
     327             :             ;
     328          34 :         if( !*s )
     329          17 :             break;
     330          17 :         for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
     331             :             ;
     332          17 :         if( !strncmp( s, "RIPEMD160", s2-s ) )
     333           0 :             found |= 1;
     334          17 :         else if( !strncmp( s, "SHA1", s2-s ) )
     335          14 :             found |= 2;
     336           3 :         else if( !strncmp( s, "SHA224", s2-s ) )
     337           0 :             found |= 8;
     338           3 :         else if( !strncmp( s, "SHA256", s2-s ) )
     339           3 :             found |= 16;
     340           0 :         else if( !strncmp( s, "SHA384", s2-s ) )
     341           0 :             found |= 32;
     342           0 :         else if( !strncmp( s, "SHA512", s2-s ) )
     343           0 :             found |= 64;
     344             :         else
     345           0 :             return 0;
     346          17 :         for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
     347             :             ;
     348          17 :         if( *s2 && *s2 != ',' )
     349           0 :             return 0;
     350          17 :         if( *s2 )
     351           0 :             s2++;
     352          17 :     }
     353          17 :     return found;
     354             : }
     355             : 
     356             : /* Returns true if this is a valid armor tag as per RFC-2440bis-21. */
     357             : static int
     358         109 : is_armor_tag(const char *line)
     359             : {
     360         109 :   if(strncmp(line,"Version",7)==0
     361          33 :      || strncmp(line,"Comment",7)==0
     362           0 :      || strncmp(line,"MessageID",9)==0
     363           0 :      || strncmp(line,"Hash",4)==0
     364           0 :      || strncmp(line,"Charset",7)==0)
     365         109 :     return 1;
     366             : 
     367           0 :   return 0;
     368             : }
     369             : 
     370             : /****************
     371             :  * Check whether this is a armor line.
     372             :  * returns: -1 if it is not a armor header or the index number of the
     373             :  * armor header.
     374             :  */
     375             : static int
     376         562 : is_armor_header( byte *line, unsigned len )
     377             : {
     378             :     const char *s;
     379             :     byte *save_p, *p;
     380             :     int save_c;
     381             :     int i;
     382             : 
     383         562 :     if( len < 15 )
     384          66 :         return -1; /* too short */
     385         496 :     if( memcmp( line, "-----", 5 ) )
     386         180 :         return -1; /* no */
     387         316 :     p = strstr( line+5, "-----");
     388         316 :     if( !p )
     389           2 :         return -1;
     390         314 :     save_p = p;
     391         314 :     p += 5;
     392             : 
     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. */
     400             : 
     401         314 :     if(RFC2440)
     402             :       {
     403           0 :         if( *p == '\r' )
     404           0 :           p++;
     405           0 :         if( *p == '\n' )
     406           0 :           p++;
     407             :       }
     408             :     else
     409         934 :       while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
     410         306 :         p++;
     411             : 
     412         314 :     if( *p )
     413           1 :         return -1; /* garbage after dashes */
     414         313 :     save_c = *save_p; *save_p = 0;
     415         313 :     p = line+5;
     416        1650 :     for(i=0; (s=head_strings[i]); i++ )
     417        1503 :         if( !strcmp(s, p) )
     418         166 :             break;
     419         313 :     *save_p = save_c;
     420         313 :     if( !s )
     421         147 :         return -1; /* unknown armor line */
     422             : 
     423         166 :     if( opt.verbose > 1 )
     424           0 :         log_info(_("armor: %s\n"), head_strings[i]);
     425         166 :     return i;
     426             : }
     427             : 
     428             : 
     429             : 
     430             : /****************
     431             :  * Parse a header lines
     432             :  * Return 0: Empty line (end of header lines)
     433             :  *       -1: invalid header line
     434             :  *       >0: Good header line
     435             :  */
     436             : static int
     437         293 : parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
     438             : {
     439             :     byte *p;
     440         293 :     int hashes=0;
     441             :     unsigned int len2;
     442             : 
     443         293 :     len2 = length_sans_trailing_ws ( line, len );
     444         293 :     if( !len2 ) {
     445         166 :         afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
     446         166 :         return 0; /* WS only: same as empty line */
     447             :     }
     448             : 
     449             :     /*
     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
     457             :     */
     458             : 
     459         127 :     p = strchr( line, ':');
     460         127 :     if( !p || (RFC2440 && p[1]!=' ')
     461         127 :         || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
     462             :       {
     463           0 :         log_error (_("invalid armor header: "));
     464           0 :         es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
     465           0 :         log_printf ("\n");
     466           0 :         return -1;
     467             :       }
     468             : 
     469             :     /* Chop off the whitespace we detected before */
     470         127 :     len=len2;
     471         127 :     line[len2]='\0';
     472             : 
     473         127 :     if( opt.verbose ) {
     474           6 :         log_info(_("armor header: "));
     475           6 :         es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
     476           6 :         log_printf ("\n");
     477             :     }
     478             : 
     479         127 :     if( afx->in_cleartext )
     480             :       {
     481          18 :         if( (hashes=parse_hash_header( line )) )
     482          17 :           afx->hashes |= hashes;
     483           1 :         else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
     484           1 :           afx->not_dash_escaped = 1;
     485             :         else
     486             :           {
     487           0 :             log_error(_("invalid clearsig header\n"));
     488           0 :             return -1;
     489             :           }
     490             :       }
     491         109 :     else if(!is_armor_tag(line))
     492             :       {
     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". */
     499             : 
     500           0 :         log_info(_("unknown armor header: "));
     501           0 :         es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
     502           0 :         log_printf ("\n");
     503             :       }
     504             : 
     505         127 :     return 1;
     506             : }
     507             : 
     508             : 
     509             : 
     510             : /* figure out whether the data is armored or not */
     511             : static int
     512         301 : check_input( armor_filter_context_t *afx, IOBUF a )
     513             : {
     514         301 :     int rc = 0;
     515             :     int i;
     516             :     byte *line;
     517             :     unsigned len;
     518             :     unsigned maxlen;
     519         301 :     int hdr_line = -1;
     520             : 
     521             :     /* read the first line to see whether this is armored data */
     522         301 :     maxlen = MAX_LINELEN;
     523         301 :     len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
     524             :                                              &afx->buffer_size, &maxlen );
     525         301 :     line = afx->buffer;
     526         301 :     if( !maxlen ) {
     527             :         /* line has been truncated: assume not armored */
     528           0 :         afx->inp_checked = 1;
     529           0 :         afx->inp_bypass = 1;
     530           0 :         return 0;
     531             :     }
     532             : 
     533         301 :     if( !len ) {
     534           0 :         return -1; /* eof */
     535             :     }
     536             : 
     537             :     /* (the line is always a C string but maybe longer) */
     538         301 :     if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
     539             :         ;
     540         279 :     else if (len >= 2 && !is_armored (line)) {
     541           2 :         afx->inp_checked = 1;
     542           2 :         afx->inp_bypass = 1;
     543           2 :         return 0;
     544             :     }
     545             : 
     546             :     /* find the armor header */
     547         994 :     while(len) {
     548         545 :         i = is_armor_header( line, len );
     549         545 :         if( i >= 0 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
     550         149 :             hdr_line = i;
     551         149 :             if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
     552          17 :                 if( afx->in_cleartext ) {
     553           0 :                     log_error(_("nested clear text signatures\n"));
     554           0 :                     rc = gpg_error (GPG_ERR_INV_ARMOR);
     555             :                 }
     556          17 :                 afx->in_cleartext = 1;
     557             :             }
     558         149 :             break;
     559             :         }
     560             :         /* read the next line (skip all truncated lines) */
     561             :         do {
     562         396 :             maxlen = MAX_LINELEN;
     563         396 :             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
     564             :                                                &afx->buffer_size, &maxlen );
     565         396 :             line = afx->buffer;
     566         396 :             len = afx->buffer_len;
     567         396 :         } while( !maxlen );
     568             :     }
     569             : 
     570             :     /* Parse the header lines.  */
     571         724 :     while(len) {
     572             :         /* Read the next line (skip all truncated lines). */
     573             :         do {
     574         275 :             maxlen = MAX_LINELEN;
     575         275 :             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
     576             :                                                &afx->buffer_size, &maxlen );
     577         275 :             line = afx->buffer;
     578         275 :             len = afx->buffer_len;
     579         275 :         } while( !maxlen );
     580             : 
     581         275 :         i = parse_header_line( afx, line, len );
     582         275 :         if( i <= 0 ) {
     583         149 :             if (i && RFC2440)
     584           0 :                 rc = GPG_ERR_INV_ARMOR;
     585         149 :             break;
     586             :         }
     587             :     }
     588             : 
     589             : 
     590         299 :     if( rc )
     591           0 :         invalid_armor();
     592         299 :     else if( afx->in_cleartext )
     593          17 :         afx->faked = 1;
     594             :     else {
     595         282 :         afx->inp_checked = 1;
     596         282 :         afx->crc = CRCINIT;
     597         282 :         afx->idx = 0;
     598         282 :         afx->radbuf[0] = 0;
     599             :     }
     600             : 
     601         299 :     return rc;
     602             : }
     603             : 
     604             : #define PARTIAL_CHUNK 512
     605             : #define PARTIAL_POW   9
     606             : 
     607             : /****************
     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.
     611             :  */
     612             : static int
     613          43 : fake_packet( armor_filter_context_t *afx, IOBUF a,
     614             :              size_t *retn, byte *buf, size_t size  )
     615             : {
     616          43 :     int rc = 0;
     617          43 :     size_t len = 0;
     618          43 :     int lastline = 0;
     619             :     unsigned maxlen, n;
     620             :     byte *p;
     621             :     byte tempbuf[PARTIAL_CHUNK];
     622          43 :     size_t tempbuf_len=0;
     623             : 
     624        6243 :     while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
     625             :         /* copy what we have in the line buffer */
     626        6157 :         if( afx->faked == 1 )
     627          17 :             afx->faked++; /* skip the first (empty) line */
     628             :         else
     629             :           {
     630             :             /* It's full, so write this partial chunk */
     631        6140 :             if(tempbuf_len==PARTIAL_CHUNK)
     632             :               {
     633         400 :                 buf[len++]=0xE0+PARTIAL_POW;
     634         400 :                 memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
     635         400 :                 len+=PARTIAL_CHUNK;
     636         400 :                 tempbuf_len=0;
     637         400 :                 continue;
     638             :               }
     639             : 
     640      219325 :             while( tempbuf_len < PARTIAL_CHUNK
     641      213185 :                    && afx->buffer_pos < afx->buffer_len )
     642      207845 :               tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
     643        5740 :             if( tempbuf_len==PARTIAL_CHUNK )
     644         400 :               continue;
     645             :           }
     646             : 
     647             :         /* read the next line */
     648        5357 :         maxlen = MAX_LINELEN;
     649        5357 :         afx->buffer_pos = 0;
     650        5357 :         afx->buffer_len = iobuf_read_line( a, &afx->buffer,
     651             :                                            &afx->buffer_size, &maxlen );
     652        5357 :         if( !afx->buffer_len ) {
     653           0 :             rc = -1; /* eof (should not happen) */
     654           0 :             continue;
     655             :         }
     656        5357 :         if( !maxlen )
     657           0 :             afx->truncated++;
     658             : 
     659        5357 :         p = afx->buffer;
     660        5357 :         n = afx->buffer_len;
     661             : 
     662             :         /* Armor header or dash-escaped line? */
     663        5357 :         if(p[0]=='-')
     664             :           {
     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
     669             :                line.  */
     670             : 
     671          29 :             if(p[1]==' ' && !afx->not_dash_escaped)
     672             :               {
     673             :                 /* It's a dash-escaped line, so skip over the
     674             :                    escape. */
     675          10 :                 afx->buffer_pos = 2;
     676             :               }
     677          19 :             else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
     678          17 :               {
     679             :                 /* Five dashes in a row mean it's probably armor
     680             :                    header. */
     681          17 :                 int type = is_armor_header( p, n );
     682          17 :                 if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
     683             :                   ; /* this is okay */
     684             :                 else
     685             :                   {
     686          17 :                     if( type != BEGIN_SIGNATURE )
     687             :                       {
     688           0 :                         log_info(_("unexpected armor: "));
     689           0 :                         es_write_sanitized (log_get_stream (), p, n,
     690             :                                             NULL, NULL);
     691           0 :                         log_printf ("\n");
     692             :                       }
     693             : 
     694          17 :                     lastline = 1;
     695          17 :                     rc = -1;
     696             :                   }
     697             :               }
     698           2 :             else if(!afx->not_dash_escaped)
     699             :               {
     700             :                 /* Bad dash-escaping. */
     701           0 :                 log_info (_("invalid dash escaped line: "));
     702           0 :                 es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
     703           0 :                 log_printf ("\n");
     704             :               }
     705             :           }
     706             : 
     707             :         /* Now handle the end-of-line canonicalization */
     708        5357 :         if( !afx->not_dash_escaped )
     709             :           {
     710        5345 :             int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
     711             : 
     712        5345 :             afx->buffer_len=
     713        5345 :               trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
     714             :                                    " \t\r\n");
     715        5345 :             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).
     725             :              */
     726        5345 :             if( crlf )
     727           0 :               afx->buffer[afx->buffer_len++] = '\r';
     728        5345 :             afx->buffer[afx->buffer_len++] = '\n';
     729        5345 :             afx->buffer[afx->buffer_len] = '\0';
     730             :           }
     731             :     }
     732             : 
     733          43 :     if( lastline ) { /* write last (ending) length header */
     734          17 :         if(tempbuf_len<192)
     735          11 :           buf[len++]=tempbuf_len;
     736             :         else
     737             :           {
     738           6 :             buf[len++]=((tempbuf_len-192)/256) + 192;
     739           6 :             buf[len++]=(tempbuf_len-192) % 256;
     740             :           }
     741          17 :         memcpy(&buf[len],tempbuf,tempbuf_len);
     742          17 :         len+=tempbuf_len;
     743             : 
     744          17 :         rc = 0;
     745          17 :         afx->faked = 0;
     746          17 :         afx->in_cleartext = 0;
     747             :         /* and now read the header lines */
     748          17 :         afx->buffer_pos = 0;
     749             :         for(;;) {
     750             :             int i;
     751             : 
     752             :             /* read the next line (skip all truncated lines) */
     753             :             do {
     754          18 :                 maxlen = MAX_LINELEN;
     755          18 :                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
     756             :                                                  &afx->buffer_size, &maxlen );
     757          18 :             } while( !maxlen );
     758          18 :             p = afx->buffer;
     759          18 :             n = afx->buffer_len;
     760          18 :             if( !n ) {
     761           0 :                 rc = -1;
     762           0 :                 break; /* eof */
     763             :             }
     764          18 :             i = parse_header_line( afx, p , n );
     765          18 :             if( i <= 0 ) {
     766          17 :                 if( i )
     767           0 :                     invalid_armor();
     768          17 :                 break;
     769             :             }
     770           1 :         }
     771          17 :         afx->inp_checked = 1;
     772          17 :         afx->crc = CRCINIT;
     773          17 :         afx->idx = 0;
     774          17 :         afx->radbuf[0] = 0;
     775             :     }
     776             : 
     777          43 :     *retn = len;
     778          43 :     return rc;
     779             : }
     780             : 
     781             : 
     782             : static int
     783           0 : invalid_crc(void)
     784             : {
     785           0 :   if ( opt.ignore_crc_error )
     786           0 :     return 0;
     787           0 :   log_inc_errorcount();
     788           0 :   return gpg_error (GPG_ERR_INV_ARMOR);
     789             : }
     790             : 
     791             : 
     792             : static int
     793         397 : radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
     794             :               byte *buf, size_t size )
     795             : {
     796             :     byte val;
     797         397 :     int c=0, c2; /*init c because gcc is not clever enough for the continue*/
     798         397 :     int checkcrc=0;
     799         397 :     int rc = 0;
     800         397 :     size_t n = 0;
     801         397 :     int  idx, i, onlypad=0;
     802             :     u32 crc;
     803             : 
     804         397 :     crc = afx->crc;
     805         397 :     idx = afx->idx;
     806         397 :     val = afx->radbuf[0];
     807     1340058 :     for( n=0; n < size; ) {
     808             : 
     809     1339563 :         if( afx->buffer_pos < afx->buffer_len )
     810     1319024 :             c = afx->buffer[afx->buffer_pos++];
     811             :         else { /* read the next line */
     812       20539 :             unsigned maxlen = MAX_LINELEN;
     813       20539 :             afx->buffer_pos = 0;
     814       20539 :             afx->buffer_len = iobuf_read_line( a, &afx->buffer,
     815             :                                                &afx->buffer_size, &maxlen );
     816       20539 :             if( !maxlen )
     817           0 :                 afx->truncated++;
     818       20539 :             if( !afx->buffer_len )
     819         150 :                 break; /* eof */
     820       20389 :             continue;
     821             :         }
     822             : 
     823             :       again:
     824     1319024 :         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
     825       20389 :             continue;
     826     1298635 :         else if( c == '=' ) { /* pad character: stop */
     827             :             /* some mailers leave quoted-printable encoded characters
     828             :              * so we try to workaround this */
     829         149 :             if( afx->buffer_pos+2 < afx->buffer_len ) {
     830             :                 int cc1, cc2, cc3;
     831          57 :                 cc1 = afx->buffer[afx->buffer_pos];
     832          57 :                 cc2 = afx->buffer[afx->buffer_pos+1];
     833          57 :                 cc3 = afx->buffer[afx->buffer_pos+2];
     834          57 :                 if( isxdigit(cc1) && isxdigit(cc2)
     835          10 :                                   && strchr( "=\n\r\t ", cc3 )) {
     836             :                     /* well it seems to be the case - adjust */
     837           0 :                     c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
     838           0 :                     c <<= 4;
     839           0 :                     c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
     840           0 :                     afx->buffer_pos += 2;
     841           0 :                     afx->qp_detected = 1;
     842           0 :                     goto again;
     843             :                 }
     844             :             }
     845             : 
     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
     850             :                3D.  */
     851         149 :             if (afx->buffer_pos + 6 < afx->buffer_len
     852           0 :                 && afx->buffer[afx->buffer_pos + 0] == '3'
     853           0 :                 && afx->buffer[afx->buffer_pos + 1] == 'D'
     854           0 :                 && asctobin[afx->buffer[afx->buffer_pos + 2]] != 255
     855           0 :                 && asctobin[afx->buffer[afx->buffer_pos + 3]] != 255
     856           0 :                 && asctobin[afx->buffer[afx->buffer_pos + 4]] != 255
     857           0 :                 && asctobin[afx->buffer[afx->buffer_pos + 5]] != 255
     858           0 :                 && afx->buffer[afx->buffer_pos + 6] == '\n')
     859             :               {
     860           0 :                 afx->buffer_pos += 2;
     861           0 :                 afx->qp_detected = 1;
     862             :               }
     863             : 
     864         149 :             if (!n)
     865           2 :               onlypad = 1;
     866             : 
     867         149 :             if( idx == 1 )
     868           0 :                 buf[n++] = val;
     869         149 :             checkcrc++;
     870         149 :             break;
     871             :         }
     872     1298486 :         else if( (c = asctobin[(c2=c)]) == 255 ) {
     873           0 :             log_error(_("invalid radix64 character %02X skipped\n"), c2);
     874           0 :             continue;
     875             :         }
     876     1298486 :         switch(idx) {
     877      324654 :           case 0: val =  c << 2; break;
     878      324654 :           case 1: val |= (c>>4)&3; buf[n++]=val;val=(c<<4)&0xf0;break;
     879      324616 :           case 2: val |= (c>>2)&15; buf[n++]=val;val=(c<<6)&0xc0;break;
     880      324562 :           case 3: val |= c&0x3f; buf[n++] = val; break;
     881             :         }
     882     1298486 :         idx = (idx+1) % 4;
     883             :     }
     884             : 
     885      974229 :     for(i=0; i < n; i++ )
     886      973832 :         crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
     887         397 :     crc &= 0x00ffffff;
     888         397 :     afx->crc = crc;
     889         397 :     afx->idx = idx;
     890         397 :     afx->radbuf[0] = val;
     891             : 
     892         397 :     if( checkcrc ) {
     893         149 :         afx->any_data = 1;
     894         149 :         afx->inp_checked=0;
     895         149 :         afx->faked = 0;
     896             :         for(;;) { /* skip lf and pad characters */
     897         463 :             if( afx->buffer_pos < afx->buffer_len )
     898         371 :                 c = afx->buffer[afx->buffer_pos++];
     899             :             else { /* read the next line */
     900          92 :                 unsigned maxlen = MAX_LINELEN;
     901          92 :                 afx->buffer_pos = 0;
     902          92 :                 afx->buffer_len = iobuf_read_line( a, &afx->buffer,
     903             :                                                    &afx->buffer_size, &maxlen );
     904          92 :                 if( !maxlen )
     905           0 :                     afx->truncated++;
     906          92 :                 if( !afx->buffer_len )
     907           0 :                     break; /* eof */
     908          92 :                 continue;
     909             :             }
     910         371 :             if( c == '\n' || c == ' ' || c == '\r'
     911         279 :                 || c == '\t' || c == '=' )
     912         222 :                 continue;
     913         149 :             break;
     914         314 :         }
     915         149 :         if( c == -1 )
     916           0 :             log_error(_("premature eof (no CRC)\n"));
     917             :         else {
     918         149 :             u32 mycrc = 0;
     919         149 :             idx = 0;
     920             :             do {
     921         596 :                 if( (c = asctobin[c]) == 255 )
     922           0 :                     break;
     923         596 :                 switch(idx) {
     924         149 :                   case 0: val =  c << 2; break;
     925         149 :                   case 1: val |= (c>>4)&3; mycrc |= val << 16;val=(c<<4)&0xf0;break;
     926         149 :                   case 2: val |= (c>>2)&15; mycrc |= val << 8;val=(c<<6)&0xc0;break;
     927         149 :                   case 3: val |= c&0x3f; mycrc |= val; break;
     928             :                 }
     929             :                 for(;;) {
     930         596 :                     if( afx->buffer_pos < afx->buffer_len )
     931         596 :                         c = afx->buffer[afx->buffer_pos++];
     932             :                     else { /* read the next line */
     933           0 :                         unsigned maxlen = MAX_LINELEN;
     934           0 :                         afx->buffer_pos = 0;
     935           0 :                         afx->buffer_len = iobuf_read_line( a, &afx->buffer,
     936             :                                                            &afx->buffer_size,
     937             :                                                                 &maxlen );
     938           0 :                         if( !maxlen )
     939           0 :                             afx->truncated++;
     940           0 :                         if( !afx->buffer_len )
     941           0 :                             break; /* eof */
     942           0 :                         continue;
     943             :                     }
     944         596 :                     break;
     945           0 :                 }
     946         596 :                 if( !afx->buffer_len )
     947           0 :                     break; /* eof */
     948         596 :             } while( ++idx < 4 );
     949         149 :             if( c == -1 ) {
     950           0 :                 log_info(_("premature eof (in CRC)\n"));
     951           0 :                 rc = invalid_crc();
     952             :             }
     953         149 :             else if( idx == 0 ) {
     954             :                 /* No CRC at all is legal ("MAY") */
     955           0 :                 rc=0;
     956             :             }
     957         149 :             else if( idx != 4 ) {
     958           0 :                 log_info(_("malformed CRC\n"));
     959           0 :                 rc = invalid_crc();
     960             :             }
     961         149 :             else if( mycrc != afx->crc ) {
     962           0 :                 log_info (_("CRC error; %06lX - %06lX\n"),
     963           0 :                                     (ulong)afx->crc, (ulong)mycrc);
     964           0 :                 rc = invalid_crc();
     965             :             }
     966             :             else {
     967         149 :                 rc = 0;
     968             :                 /* FIXME: Here we should emit another control packet,
     969             :                  * so that we know in mainproc that we are processing
     970             :                  * a clearsign message */
     971             : #if 0
     972             :                 for(rc=0;!rc;) {
     973             :                     rc = 0 /*check_trailer( &fhdr, c )*/;
     974             :                     if( !rc ) {
     975             :                         if( (c=iobuf_get(a)) == -1 )
     976             :                             rc = 2;
     977             :                     }
     978             :                 }
     979             :                 if( rc == -1 )
     980             :                     rc = 0;
     981             :                 else if( rc == 2 ) {
     982             :                     log_error(_("premature eof (in trailer)\n"));
     983             :                     rc = GPG_ERR_INVALID_ARMOR;
     984             :                 }
     985             :                 else {
     986             :                     log_error(_("error in trailer line\n"));
     987             :                     rc = GPG_ERR_INVALID_ARMOR;
     988             :                 }
     989             : #endif
     990             :             }
     991             :         }
     992             :     }
     993             : 
     994         397 :     if( !n && !onlypad )
     995         150 :         rc = -1;
     996             : 
     997         397 :     *retn = n;
     998         397 :     return rc;
     999             : }
    1000             : 
    1001             : /****************
    1002             :  * This filter is used to handle the armor stuff
    1003             :  */
    1004             : static int
    1005        1037 : armor_filter( void *opaque, int control,
    1006             :              IOBUF a, byte *buf, size_t *ret_len)
    1007             : {
    1008        1037 :     size_t size = *ret_len;
    1009        1037 :     armor_filter_context_t *afx = opaque;
    1010        1037 :     int rc=0, i, c;
    1011             :     byte radbuf[3];
    1012             :     int  idx, idx2;
    1013        1037 :     size_t n=0;
    1014             :     u32 crc;
    1015             : #if 0
    1016             :     static FILE *fp ;
    1017             : 
    1018             :     if( !fp ) {
    1019             :         fp = fopen("armor.out", "w");
    1020             :         assert(fp);
    1021             :     }
    1022             : #endif
    1023             : 
    1024        1037 :     if( DBG_FILTER )
    1025           0 :         log_debug("armor-filter: control: %d\n", control );
    1026        1037 :     if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
    1027           4 :         n = 0;
    1028           4 :         if( afx->buffer_len ) {
    1029           0 :             for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
    1030           0 :                 buf[n++] = afx->buffer[afx->buffer_pos++];
    1031           0 :             if( afx->buffer_pos >= afx->buffer_len )
    1032           0 :                 afx->buffer_len = 0;
    1033             :         }
    1034        1072 :         for(; n < size; n++ ) {
    1035        1072 :             if( (c=iobuf_get(a)) == -1 )
    1036           4 :                 break;
    1037        1068 :             buf[n] = c & 0xff;
    1038             :         }
    1039           4 :         if( !n )
    1040           2 :             rc = -1;
    1041           4 :         *ret_len = n;
    1042             :     }
    1043        1033 :     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
    1046             :          * length itself */
    1047         459 :         if( size < PARTIAL_CHUNK+1 )
    1048           0 :             BUG(); /* supplied buffer too short */
    1049             : 
    1050         459 :         if( afx->faked )
    1051          43 :             rc = fake_packet( afx, a, &n, buf, size );
    1052         416 :         else if( !afx->inp_checked ) {
    1053         301 :             rc = check_input( afx, a );
    1054         301 :             if( afx->inp_bypass ) {
    1055         783 :                 for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
    1056         779 :                     buf[n++] = afx->buffer[afx->buffer_pos++];
    1057           2 :                 if( afx->buffer_pos >= afx->buffer_len )
    1058           2 :                     afx->buffer_len = 0;
    1059           2 :                 if( !n )
    1060           0 :                     rc = -1;
    1061             :             }
    1062         299 :             else if( afx->faked ) {
    1063          17 :                 unsigned int hashes = afx->hashes;
    1064             :                 const byte *sesmark;
    1065             :                 size_t sesmarklen;
    1066             : 
    1067          17 :                 sesmark = get_session_marker( &sesmarklen );
    1068          17 :                 if ( sesmarklen > 20 )
    1069           0 :                     BUG();
    1070             : 
    1071             :                 /* the buffer is at least 15+n*15 bytes long, so it
    1072             :                  * is easy to construct the packets */
    1073             : 
    1074          17 :                 hashes &= 1|2|8|16|32|64;
    1075          17 :                 if( !hashes ) {
    1076           0 :                     hashes |= 2;  /* Default to SHA-1. */
    1077             :                 }
    1078          17 :                 n=0;
    1079             :                 /* First a gpg control packet... */
    1080          17 :                 buf[n++] = 0xff; /* new format, type 63, 1 length byte */
    1081          17 :                 n++;   /* see below */
    1082          17 :                 memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
    1083          17 :                 buf[n++] = CTRLPKT_CLEARSIGN_START;
    1084          17 :                 buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
    1085          17 :                 if( hashes & 1 )
    1086           0 :                     buf[n++] = DIGEST_ALGO_RMD160;
    1087          17 :                 if( hashes & 2 )
    1088          14 :                     buf[n++] = DIGEST_ALGO_SHA1;
    1089          17 :                 if( hashes & 8 )
    1090           0 :                     buf[n++] = DIGEST_ALGO_SHA224;
    1091          17 :                 if( hashes & 16 )
    1092           3 :                     buf[n++] = DIGEST_ALGO_SHA256;
    1093          17 :                 if( hashes & 32 )
    1094           0 :                     buf[n++] = DIGEST_ALGO_SHA384;
    1095          17 :                 if( hashes & 64 )
    1096           0 :                     buf[n++] = DIGEST_ALGO_SHA512;
    1097          17 :                 buf[1] = n - 2;
    1098             : 
    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 ;) */
    1103             : 
    1104          17 :                 buf[n++] = 0xCB; /* new packet format, type 11 */
    1105          17 :                 buf[n++] = 0xE1; /* 2^1 == 2 bytes */
    1106          17 :                 buf[n++] = 't';  /* canonical text mode */
    1107          17 :                 buf[n++] = 0;    /* namelength */
    1108          17 :                 buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
    1109          17 :                 memset(buf+n, 0, 4); /* timestamp */
    1110          17 :                 n += 4;
    1111             :             }
    1112         282 :             else if( !rc )
    1113         282 :                 rc = radix64_read( afx, a, &n, buf, size );
    1114             :         }
    1115             :         else
    1116         115 :             rc = radix64_read( afx, a, &n, buf, size );
    1117             : #if 0
    1118             :         if( n )
    1119             :             if( fwrite(buf, n, 1, fp ) != 1 )
    1120             :                 BUG();
    1121             : #endif
    1122         459 :         *ret_len = n;
    1123             :     }
    1124         574 :     else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
    1125         168 :         if( !afx->status ) { /* write the header line */
    1126             :             const char *s;
    1127          51 :             strlist_t comment=opt.comments;
    1128             : 
    1129          51 :             if( afx->what >= DIM(head_strings) )
    1130           0 :                 log_bug("afx->what=%d", afx->what);
    1131          51 :             iobuf_writestr(a, "-----");
    1132          51 :             iobuf_writestr(a, head_strings[afx->what] );
    1133          51 :             iobuf_writestr(a, "-----" );
    1134          51 :             iobuf_writestr(a,afx->eol);
    1135          51 :             if (opt.emit_version)
    1136             :               {
    1137           0 :                 iobuf_writestr (a, "Version: "GNUPG_NAME" v");
    1138           0 :                 for (s=VERSION; *s && *s != '.'; s++)
    1139           0 :                   iobuf_writebyte (a, *s);
    1140           0 :                 if (opt.emit_version > 1 && *s)
    1141             :                   {
    1142           0 :                     iobuf_writebyte (a, *s++);
    1143           0 :                     for (; *s && *s != '.'; s++)
    1144           0 :                       iobuf_writebyte (a, *s);
    1145           0 :                     if (opt.emit_version > 2)
    1146             :                       {
    1147           0 :                         for (; *s && *s != '-' && !spacep (s); s++)
    1148           0 :                           iobuf_writebyte (a, *s);
    1149           0 :                         if (opt.emit_version > 3)
    1150           0 :                           iobuf_writestr (a, " (" PRINTABLE_OS_NAME ")");
    1151             :                       }
    1152             :                   }
    1153           0 :                 iobuf_writestr(a,afx->eol);
    1154             :               }
    1155             : 
    1156             :             /* write the comment strings */
    1157          51 :             for(s=comment->d;comment;comment=comment->next,s=comment->d)
    1158             :               {
    1159           0 :                 iobuf_writestr(a, "Comment: " );
    1160           0 :                 for( ; *s; s++ )
    1161             :                   {
    1162           0 :                     if( *s == '\n' )
    1163           0 :                       iobuf_writestr(a, "\\n" );
    1164           0 :                     else if( *s == '\r' )
    1165           0 :                       iobuf_writestr(a, "\\r" );
    1166           0 :                     else if( *s == '\v' )
    1167           0 :                       iobuf_writestr(a, "\\v" );
    1168             :                     else
    1169           0 :                       iobuf_put(a, *s );
    1170             :                   }
    1171             : 
    1172           0 :                 iobuf_writestr(a,afx->eol);
    1173             :               }
    1174             : 
    1175          51 :             if ( afx->hdrlines ) {
    1176          86 :                 for ( s = afx->hdrlines; *s; s++ ) {
    1177             : #ifdef HAVE_DOSISH_SYSTEM
    1178             :                     if ( *s == '\n' )
    1179             :                         iobuf_put( a, '\r');
    1180             : #endif
    1181          84 :                     iobuf_put(a, *s );
    1182             :                 }
    1183             :             }
    1184             : 
    1185          51 :             iobuf_writestr(a,afx->eol);
    1186          51 :             afx->status++;
    1187          51 :             afx->idx = 0;
    1188          51 :             afx->idx2 = 0;
    1189          51 :             afx->crc = CRCINIT;
    1190             : 
    1191             :         }
    1192         168 :         crc = afx->crc;
    1193         168 :         idx = afx->idx;
    1194         168 :         idx2 = afx->idx2;
    1195         242 :         for(i=0; i < idx; i++ )
    1196          74 :             radbuf[i] = afx->radbuf[i];
    1197             : 
    1198      506144 :         for(i=0; i < size; i++ )
    1199      505976 :             crc = (crc << 8) ^ crc_table[((crc >> 16)&0xff) ^ buf[i]];
    1200         168 :         crc &= 0x00ffffff;
    1201             : 
    1202      506144 :         for( ; size; buf++, size-- ) {
    1203      505976 :             radbuf[idx++] = *buf;
    1204      505976 :             if( idx > 2 ) {
    1205      168646 :                 idx = 0;
    1206      168646 :                 c = bintoasc[(*radbuf >> 2) & 077];
    1207      168646 :                 iobuf_put(a, c);
    1208      168646 :                 c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
    1209      168646 :                 iobuf_put(a, c);
    1210      168646 :                 c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
    1211      168646 :                 iobuf_put(a, c);
    1212      168646 :                 c = bintoasc[radbuf[2]&077];
    1213      168646 :                 iobuf_put(a, c);
    1214      168646 :                 if( ++idx2 >= (64/4) )
    1215             :                   { /* pgp doesn't like 72 here */
    1216       10513 :                     iobuf_writestr(a,afx->eol);
    1217       10513 :                     idx2=0;
    1218             :                   }
    1219             :             }
    1220             :         }
    1221         280 :         for(i=0; i < idx; i++ )
    1222         112 :             afx->radbuf[i] = radbuf[i];
    1223         168 :         afx->idx = idx;
    1224         168 :         afx->idx2 = idx2;
    1225         168 :         afx->crc  = crc;
    1226             :     }
    1227         406 :     else if( control == IOBUFCTRL_INIT )
    1228             :       {
    1229         203 :         if( !is_initialized )
    1230         198 :           initialize();
    1231             : 
    1232             :         /* Figure out what we're using for line endings if the caller
    1233             :            didn't specify. */
    1234         203 :         if(afx->eol[0]==0)
    1235             :           {
    1236             : #ifdef HAVE_DOSISH_SYSTEM
    1237             :             afx->eol[0]='\r';
    1238             :             afx->eol[1]='\n';
    1239             : #else
    1240         203 :             afx->eol[0]='\n';
    1241             : #endif
    1242             :           }
    1243             :       }
    1244         203 :     else if( control == IOBUFCTRL_CANCEL ) {
    1245           0 :         afx->cancel = 1;
    1246             :     }
    1247         203 :     else if( control == IOBUFCTRL_FREE ) {
    1248         203 :         if( afx->cancel )
    1249             :             ;
    1250         203 :         else if( afx->status ) { /* pad, write cecksum, and bottom line */
    1251          51 :             crc = afx->crc;
    1252          51 :             idx = afx->idx;
    1253          51 :             idx2 = afx->idx2;
    1254          51 :             if( idx ) {
    1255          24 :                 c = bintoasc[(afx->radbuf[0]>>2)&077];
    1256          24 :                 iobuf_put(a, c);
    1257          24 :                 if( idx == 1 ) {
    1258          10 :                     c = bintoasc[((afx->radbuf[0] << 4) & 060) & 077];
    1259          10 :                     iobuf_put(a, c);
    1260          10 :                     iobuf_put(a, '=');
    1261          10 :                     iobuf_put(a, '=');
    1262             :                 }
    1263             :                 else { /* 2 */
    1264          28 :                     c = bintoasc[(((afx->radbuf[0]<<4)&060)
    1265          14 :                                   |((afx->radbuf[1]>>4)&017))&077];
    1266          14 :                     iobuf_put(a, c);
    1267          14 :                     c = bintoasc[((afx->radbuf[1] << 2) & 074) & 077];
    1268          14 :                     iobuf_put(a, c);
    1269          14 :                     iobuf_put(a, '=');
    1270             :                 }
    1271          24 :                 if( ++idx2 >= (64/4) )
    1272             :                   { /* pgp doesn't like 72 here */
    1273           3 :                     iobuf_writestr(a,afx->eol);
    1274           3 :                     idx2=0;
    1275             :                   }
    1276             :             }
    1277             :             /* may need a linefeed */
    1278          51 :             if( idx2 )
    1279          48 :               iobuf_writestr(a,afx->eol);
    1280             :             /* write the CRC */
    1281          51 :             iobuf_put(a, '=');
    1282          51 :             radbuf[0] = crc >>16;
    1283          51 :             radbuf[1] = crc >> 8;
    1284          51 :             radbuf[2] = crc;
    1285          51 :             c = bintoasc[(*radbuf >> 2) & 077];
    1286          51 :             iobuf_put(a, c);
    1287          51 :             c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
    1288          51 :             iobuf_put(a, c);
    1289          51 :             c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
    1290          51 :             iobuf_put(a, c);
    1291          51 :             c = bintoasc[radbuf[2]&077];
    1292          51 :             iobuf_put(a, c);
    1293          51 :             iobuf_writestr(a,afx->eol);
    1294             :             /* and the the trailer */
    1295          51 :             if( afx->what >= DIM(tail_strings) )
    1296           0 :                 log_bug("afx->what=%d", afx->what);
    1297          51 :             iobuf_writestr(a, "-----");
    1298          51 :             iobuf_writestr(a, tail_strings[afx->what] );
    1299          51 :             iobuf_writestr(a, "-----" );
    1300          51 :             iobuf_writestr(a,afx->eol);
    1301             :         }
    1302         152 :         else if( !afx->any_data && !afx->inp_bypass ) {
    1303           3 :             log_error(_("no valid OpenPGP data found.\n"));
    1304           3 :             afx->no_openpgp_data = 1;
    1305           3 :             write_status_text( STATUS_NODATA, "1" );
    1306             :         }
    1307         203 :         if( afx->truncated )
    1308           0 :             log_info(_("invalid armor: line longer than %d characters\n"),
    1309             :                       MAX_LINELEN );
    1310             :         /* issue an error to enforce dissemination of correct software */
    1311         203 :         if( afx->qp_detected )
    1312           0 :             log_error(_("quoted printable character in armor - "
    1313             :                         "probably a buggy MTA has been used\n") );
    1314         203 :         xfree( afx->buffer );
    1315         203 :         afx->buffer = NULL;
    1316         203 :         release_armor_context (afx);
    1317             :     }
    1318           0 :     else if( control == IOBUFCTRL_DESC )
    1319           0 :         mem2str (buf, "armor_filter", *ret_len);
    1320        1037 :     return rc;
    1321             : }
    1322             : 
    1323             : 
    1324             : /****************
    1325             :  * create a radix64 encoded string.
    1326             :  */
    1327             : char *
    1328          19 : make_radix64_string( const byte *data, size_t len )
    1329             : {
    1330             :     char *buffer, *p;
    1331             : 
    1332          19 :     buffer = p = xmalloc( (len+2)/3*4 + 1 );
    1333         157 :     for( ; len >= 3 ; len -= 3, data += 3 ) {
    1334         138 :         *p++ = bintoasc[(data[0] >> 2) & 077];
    1335         138 :         *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
    1336         138 :         *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
    1337         138 :         *p++ = bintoasc[data[2]&077];
    1338             :     }
    1339          19 :     if( len == 2 ) {
    1340          19 :         *p++ = bintoasc[(data[0] >> 2) & 077];
    1341          19 :         *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
    1342          19 :         *p++ = bintoasc[((data[1]<<2)&074)];
    1343             :     }
    1344           0 :     else if( len == 1 ) {
    1345           0 :         *p++ = bintoasc[(data[0] >> 2) & 077];
    1346           0 :         *p++ = bintoasc[(data[0] <<4)&060];
    1347             :     }
    1348          19 :     *p = 0;
    1349          19 :     return buffer;
    1350             : }
    1351             : 
    1352             : 
    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
    1356             :  */
    1357             : 
    1358             : enum unarmor_state_e {
    1359             :     STA_init = 0,
    1360             :     STA_bypass,
    1361             :     STA_wait_newline,
    1362             :     STA_wait_dash,
    1363             :     STA_first_dash,
    1364             :     STA_compare_header,
    1365             :     STA_found_header_wait_newline,
    1366             :     STA_skip_header_lines,
    1367             :     STA_skip_header_lines_non_ws,
    1368             :     STA_read_data,
    1369             :     STA_wait_crc,
    1370             :     STA_read_crc,
    1371             :     STA_ready
    1372             : };
    1373             : 
    1374             : struct unarmor_pump_s {
    1375             :     enum unarmor_state_e state;
    1376             :     byte val;
    1377             :     int checkcrc;
    1378             :     int pos;   /* counts from 0..3 */
    1379             :     u32 crc;
    1380             :     u32 mycrc; /* the one store in the data */
    1381             : };
    1382             : 
    1383             : 
    1384             : 
    1385             : UnarmorPump
    1386           0 : unarmor_pump_new (void)
    1387             : {
    1388             :     UnarmorPump x;
    1389             : 
    1390           0 :     if( !is_initialized )
    1391           0 :         initialize();
    1392           0 :     x = xmalloc_clear (sizeof *x);
    1393           0 :     return x;
    1394             : }
    1395             : 
    1396             : void
    1397           0 : unarmor_pump_release (UnarmorPump x)
    1398             : {
    1399           0 :     xfree (x);
    1400           0 : }
    1401             : 
    1402             : /*
    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
    1410             :  */
    1411             : int
    1412           0 : unarmor_pump (UnarmorPump x, int c)
    1413             : {
    1414           0 :     int rval = 256; /* default is to ignore the return value */
    1415             : 
    1416           0 :     switch (x->state) {
    1417             :       case STA_init:
    1418             :         {
    1419             :             byte tmp[2];
    1420           0 :             tmp[0] = c;
    1421           0 :             tmp[1] = 0;
    1422           0 :             if ( is_armored (tmp) )
    1423           0 :                 x->state = c == '-'? STA_first_dash : STA_wait_newline;
    1424             :             else {
    1425           0 :                 x->state = STA_bypass;
    1426           0 :                 return c;
    1427             :             }
    1428             :         }
    1429           0 :         break;
    1430             :       case STA_bypass:
    1431           0 :         return c; /* return here to avoid crc calculation */
    1432             :       case STA_wait_newline:
    1433           0 :         if (c == '\n')
    1434           0 :             x->state = STA_wait_dash;
    1435           0 :         break;
    1436             :       case STA_wait_dash:
    1437           0 :         x->state = c == '-'? STA_first_dash : STA_wait_newline;
    1438           0 :         break;
    1439             :       case STA_first_dash: /* just need for initalization */
    1440           0 :         x->pos = 0;
    1441           0 :         x->state = STA_compare_header;
    1442             :       case STA_compare_header:
    1443           0 :         if ( "-----BEGIN PGP SIGNATURE-----"[++x->pos] == c ) {
    1444           0 :             if ( x->pos == 28 )
    1445           0 :                 x->state = STA_found_header_wait_newline;
    1446             :         }
    1447             :         else
    1448           0 :             x->state = c == '\n'? STA_wait_dash : STA_wait_newline;
    1449           0 :         break;
    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 */
    1453           0 :         if ( c == '\n' )
    1454           0 :             x->state = STA_skip_header_lines;
    1455           0 :         else if ( c != '\r' && c != ' ' && c != '\t' )
    1456           0 :             x->state = STA_wait_dash; /* garbage after the header line */
    1457           0 :         break;
    1458             :       case STA_skip_header_lines:
    1459             :         /* i.e. wait for one empty line */
    1460           0 :         if ( c == '\n' ) {
    1461           0 :             x->state = STA_read_data;
    1462           0 :             x->crc = CRCINIT;
    1463           0 :             x->val = 0;
    1464           0 :             x->pos = 0;
    1465             :         }
    1466           0 :         else if ( c != '\r' && c != ' ' && c != '\t' )
    1467           0 :             x->state = STA_skip_header_lines_non_ws;
    1468           0 :         break;
    1469             :       case STA_skip_header_lines_non_ws:
    1470             :         /* like above but we already encountered non white space */
    1471           0 :         if ( c == '\n' )
    1472           0 :             x->state = STA_skip_header_lines;
    1473           0 :         break;
    1474             :       case STA_read_data:
    1475             :         /* fixme: we don't check for the trailing dash lines but rely
    1476             :          * on the armor stop characters */
    1477           0 :         if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
    1478             :             break; /* skip all kind of white space */
    1479             : 
    1480           0 :         if( c == '=' ) { /* pad character: stop */
    1481           0 :             if( x->pos == 1 ) /* in this case val has some value */
    1482           0 :                 rval = x->val;
    1483           0 :             x->state = STA_wait_crc;
    1484           0 :             break;
    1485             :         }
    1486             : 
    1487             :         {
    1488             :             int c2;
    1489           0 :             if( (c = asctobin[(c2=c)]) == 255 ) {
    1490           0 :                 log_error(_("invalid radix64 character %02X skipped\n"), c2);
    1491           0 :                 break;
    1492             :             }
    1493             :         }
    1494             : 
    1495           0 :         switch(x->pos) {
    1496             :           case 0:
    1497           0 :             x->val = c << 2;
    1498           0 :             break;
    1499             :           case 1:
    1500           0 :             x->val |= (c>>4)&3;
    1501           0 :             rval = x->val;
    1502           0 :             x->val = (c<<4)&0xf0;
    1503           0 :             break;
    1504             :           case 2:
    1505           0 :             x->val |= (c>>2)&15;
    1506           0 :             rval = x->val;
    1507           0 :             x->val = (c<<6)&0xc0;
    1508           0 :             break;
    1509             :           case 3:
    1510           0 :             x->val |= c&0x3f;
    1511           0 :             rval = x->val;
    1512           0 :             break;
    1513             :         }
    1514           0 :         x->pos = (x->pos+1) % 4;
    1515           0 :         break;
    1516             :       case STA_wait_crc:
    1517           0 :         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           0 :         x->state = STA_read_crc;
    1521           0 :         x->pos = 0;
    1522           0 :         x->mycrc = 0;
    1523             :       case STA_read_crc:
    1524           0 :         if( (c = asctobin[c]) == 255 ) {
    1525           0 :             rval = -1; /* ready */
    1526           0 :             if( x->crc != x->mycrc ) {
    1527           0 :                 log_info (_("CRC error; %06lX - %06lX\n"),
    1528           0 :                           (ulong)x->crc, (ulong)x->mycrc);
    1529           0 :                 if ( invalid_crc() )
    1530           0 :                     rval = -3;
    1531             :             }
    1532           0 :             x->state = STA_ready; /* not sure whether this is correct */
    1533           0 :             break;
    1534             :         }
    1535             : 
    1536           0 :         switch(x->pos) {
    1537             :           case 0:
    1538           0 :             x->val = c << 2;
    1539           0 :             break;
    1540             :           case 1:
    1541           0 :             x->val |= (c>>4)&3;
    1542           0 :             x->mycrc |= x->val << 16;
    1543           0 :             x->val = (c<<4)&0xf0;
    1544           0 :             break;
    1545             :           case 2:
    1546           0 :             x->val |= (c>>2)&15;
    1547           0 :             x->mycrc |= x->val << 8;
    1548           0 :             x->val = (c<<6)&0xc0;
    1549           0 :             break;
    1550             :           case 3:
    1551           0 :             x->val |= c&0x3f;
    1552           0 :             x->mycrc |= x->val;
    1553           0 :             break;
    1554             :         }
    1555           0 :         x->pos = (x->pos+1) % 4;
    1556           0 :         break;
    1557             :       case STA_ready:
    1558           0 :         rval = -1;
    1559           0 :         break;
    1560             :     }
    1561             : 
    1562           0 :     if ( !(rval & ~255) ) { /* compute the CRC */
    1563           0 :         x->crc = (x->crc << 8) ^ crc_table[((x->crc >> 16)&0xff) ^ rval];
    1564           0 :         x->crc &= 0x00ffffff;
    1565             :     }
    1566             : 
    1567           0 :     return rval;
    1568             : }

Generated by: LCOV version 1.11