Coverage Report

Created: 2022-12-08 06:10

/src/gnupg/g10/armor.c
Line
Count
Source (jump to first uncovered line)
1
/* armor.c - Armor filter
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 <https://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 "../common/status.h"
30
#include "../common/iobuf.h"
31
#include "../common/util.h"
32
#include "filter.h"
33
#include "packet.h"
34
#include "options.h"
35
#include "main.h"
36
#include "../common/i18n.h"
37
38
7.04k
#define MAX_LINELEN 20000
39
40
static const byte bintoasc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
41
                               "abcdefghijklmnopqrstuvwxyz"
42
                               "0123456789+/";
43
static u32 asctobin[4][256]; /* runtime initialized */
44
static int is_initialized;
45
46
47
typedef enum {
48
    fhdrHASArmor = 0,
49
    fhdrNOArmor,
50
    fhdrINIT,
51
    fhdrINITCont,
52
    fhdrINITSkip,
53
    fhdrCHECKBegin,
54
    fhdrWAITHeader,
55
    fhdrWAITClearsig,
56
    fhdrSKIPHeader,
57
    fhdrCLEARSIG,
58
    fhdrREADClearsig,
59
    fhdrNullClearsig,
60
    fhdrEMPTYClearsig,
61
    fhdrCHECKClearsig,
62
    fhdrCHECKClearsig2,
63
    fhdrCHECKDashEscaped,
64
    fhdrCHECKDashEscaped2,
65
    fhdrCHECKDashEscaped3,
66
    fhdrREADClearsigNext,
67
    fhdrENDClearsig,
68
    fhdrENDClearsigHelp,
69
    fhdrTESTSpaces,
70
    fhdrCLEARSIGSimple,
71
    fhdrCLEARSIGSimpleNext,
72
    fhdrTEXT,
73
    fhdrTEXTSimple,
74
    fhdrERROR,
75
    fhdrERRORShow,
76
    fhdrEOF
77
} fhdr_state_t;
78
79
80
/* if we encounter this armor string with this index, go
81
 * into a mode which fakes packets and wait for the next armor */
82
0
#define BEGIN_SIGNATURE 2
83
1.49k
#define BEGIN_SIGNED_MSG_IDX 3
84
static char *head_strings[] = {
85
    "BEGIN PGP MESSAGE",
86
    "BEGIN PGP PUBLIC KEY BLOCK",
87
    "BEGIN PGP SIGNATURE",
88
    "BEGIN PGP SIGNED MESSAGE",
89
    "BEGIN PGP ARMORED FILE",       /* gnupg extension */
90
    "BEGIN PGP PRIVATE KEY BLOCK",
91
    "BEGIN PGP SECRET KEY BLOCK",   /* only used by pgp2 */
92
    NULL
93
};
94
static char *tail_strings[] = {
95
    "END PGP MESSAGE",
96
    "END PGP PUBLIC KEY BLOCK",
97
    "END PGP SIGNATURE",
98
    "END dummy",
99
    "END PGP ARMORED FILE",
100
    "END PGP PRIVATE KEY BLOCK",
101
    "END PGP SECRET KEY BLOCK",
102
    NULL
103
};
104
105
106
static int armor_filter ( void *opaque, int control,
107
                          iobuf_t chain, byte *buf, size_t *ret_len);
108
109
110
111

112
/* Create a new context for armor filters.  */
113
armor_filter_context_t *
114
new_armor_context (void)
115
53
{
116
53
  armor_filter_context_t *afx;
117
53
  gpg_error_t err;
118
119
53
  afx = xcalloc (1, sizeof *afx);
120
53
  if (afx)
121
53
    {
122
53
      err = gcry_md_open (&afx->crc_md, GCRY_MD_CRC24_RFC2440, 0);
123
53
      if (err != 0)
124
0
  {
125
0
    log_error ("gcry_md_open failed for GCRY_MD_CRC24_RFC2440: %s",
126
0
        gpg_strerror (err));
127
0
    xfree (afx);
128
0
    return NULL;
129
0
  }
130
131
53
      afx->refcount = 1;
132
53
    }
133
134
53
  return afx;
135
53
}
136
137
/* Release an armor filter context.  Passing NULL is explicitly
138
   allowed and a no-op.  */
139
void
140
release_armor_context (armor_filter_context_t *afx)
141
106
{
142
106
  if (!afx)
143
0
    return;
144
106
  log_assert (afx->refcount);
145
106
  if ( --afx->refcount )
146
53
    return;
147
53
  gcry_md_close (afx->crc_md);
148
53
  xfree (afx);
149
53
}
150
151
/* Push the armor filter onto the iobuf stream IOBUF.  */
152
int
153
push_armor_filter (armor_filter_context_t *afx, iobuf_t iobuf)
154
53
{
155
53
  int rc;
156
157
53
  afx->refcount++;
158
53
  rc = iobuf_push_filter (iobuf, armor_filter, afx);
159
53
  if (rc)
160
0
    afx->refcount--;
161
53
  return rc;
162
53
}
163
164
165
166
167
168
static void
169
initialize(void)
170
1
{
171
1
    u32 i;
172
1
    const byte *s;
173
174
    /* Build the helptable for radix64 to bin conversion.  Value 0xffffffff is
175
       used to detect invalid characters.  */
176
1
    memset (asctobin, 0xff, sizeof(asctobin));
177
65
    for(s=bintoasc,i=0; *s; s++,i++ )
178
64
      {
179
64
  asctobin[0][*s] = i << (0 * 6);
180
64
  asctobin[1][*s] = i << (1 * 6);
181
64
  asctobin[2][*s] = i << (2 * 6);
182
64
  asctobin[3][*s] = i << (3 * 6);
183
64
      }
184
185
1
    is_initialized=1;
186
1
}
187
188
189
static inline u32
190
get_afx_crc (armor_filter_context_t *afx)
191
44
{
192
44
  const byte *crc_buf;
193
44
  u32 crc;
194
195
44
  crc_buf = gcry_md_read (afx->crc_md, GCRY_MD_CRC24_RFC2440);
196
197
44
  crc = crc_buf[0];
198
44
  crc <<= 8;
199
44
  crc |= crc_buf[1];
200
44
  crc <<= 8;
201
44
  crc |= crc_buf[2];
202
203
44
  return crc;
204
44
}
205
206
207
/*
208
 * Check whether this is an armored file.  See also
209
 * parse-packet.c for details on this code.
210
 *
211
 * Note that the buffer BUF needs to be at least 2 bytes long.  If in
212
 * doubt that the second byte to 0.
213
 *
214
 * Returns: True if it seems to be armored
215
 */
216
static int
217
is_armored (const byte *buf)
218
1.36k
{
219
1.36k
  int ctb, pkttype;
220
1.36k
  int indeterminate_length_allowed;
221
222
1.36k
    ctb = *buf;
223
1.36k
    if( !(ctb & 0x80) )
224
      /* The most significant bit of the CTB must be set.  Since it is
225
         cleared, this is not a binary OpenPGP message.  Assume it is
226
         armored.  */
227
1.30k
      return 1;
228
229
60
    pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
230
60
    switch( pkttype ) {
231
0
      case PKT_PUBKEY_ENC:
232
2
      case PKT_SIGNATURE:
233
5
      case PKT_SYMKEY_ENC:
234
5
      case PKT_ONEPASS_SIG:
235
8
      case PKT_SECRET_KEY:
236
16
      case PKT_PUBLIC_KEY:
237
16
      case PKT_SECRET_SUBKEY:
238
16
      case PKT_MARKER:
239
18
      case PKT_RING_TRUST:
240
19
      case PKT_USER_ID:
241
19
      case PKT_PUBLIC_SUBKEY:
242
20
      case PKT_ATTRIBUTE:
243
20
      case PKT_MDC:
244
20
  indeterminate_length_allowed = 0;
245
20
        break;
246
247
0
      case PKT_COMPRESSED:
248
1
      case PKT_ENCRYPTED:
249
1
      case PKT_ENCRYPTED_MDC:
250
1
      case PKT_ENCRYPTED_AEAD:
251
3
      case PKT_PLAINTEXT:
252
3
      case PKT_OLD_COMMENT:
253
4
      case PKT_COMMENT:
254
4
      case PKT_GPG_CONTROL:
255
4
  indeterminate_length_allowed = 1;
256
4
        break;
257
258
36
      default:
259
        /* Invalid packet type.  */
260
36
        return 1;
261
60
    }
262
263
24
    if (! indeterminate_length_allowed)
264
      /* It is only legal to use an indeterminate length with a few
265
         packet types.  If a packet uses an indeterminate length, but
266
         that is not allowed, then the data is not valid binary
267
         OpenPGP data.  */
268
20
      {
269
20
        int new_format;
270
20
        int indeterminate_length;
271
272
20
        new_format = !! (ctb & (1 << 6));
273
20
        if (new_format)
274
10
          indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
275
10
        else
276
10
          indeterminate_length = (ctb & 3) == 3;
277
278
20
        if (indeterminate_length)
279
0
          return 1;
280
20
      }
281
282
    /* The first CTB seems legit.  It is probably not armored
283
       data.  */
284
24
    return 0;
285
24
}
286
287
288
/****************
289
 * Try to check whether the iobuf is armored
290
 * Returns true if this may be the case; the caller should use the
291
 *     filter to do further processing.
292
 */
293
int
294
use_armor_filter( IOBUF a )
295
0
{
296
0
    byte buf[2];
297
0
    int n;
298
299
    /* fixme: there might be a problem with iobuf_peek */
300
0
    n = iobuf_peek (a, buf, 2);
301
0
    if( n == -1 )
302
0
  return 0; /* EOF, doesn't matter whether armored or not */
303
0
    if( !n )
304
0
  return 1; /* can't check it: try armored */
305
0
    if (n != 2)
306
0
  return 0; /* short buffer */
307
0
    return is_armored(buf);
308
0
}
309
310
311
312
313
static void
314
invalid_armor(void)
315
0
{
316
0
    write_status(STATUS_BADARMOR);
317
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
318
    g10_exit(1); /* stop here */
319
#endif
320
0
}
321
322
323
/****************
324
 * check whether the armor header is valid on a signed message.
325
 * this is for security reasons: the header lines are not included in the
326
 * hash and by using some creative formatting rules, Mallory could fake
327
 * any text at the beginning of a document; assuming it is read with
328
 * a simple viewer. We only allow the Hash Header.
329
 */
330
static int
331
parse_hash_header( const char *line )
332
0
{
333
0
    const char *s, *s2;
334
0
    unsigned found = 0;
335
336
0
    if( strlen(line) < 6  || strlen(line) > 60 )
337
0
  return 0; /* too short or too long */
338
0
    if( memcmp( line, "Hash:", 5 ) )
339
0
  return 0; /* invalid header */
340
341
0
    for(s=line+5;;s=s2) {
342
0
  for(; *s && (*s==' ' || *s == '\t'); s++ )
343
0
      ;
344
0
  if( !*s )
345
0
      break;
346
0
  for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
347
0
      ;
348
0
  if( !strncmp( s, "RIPEMD160", s2-s ) )
349
0
      found |= 1;
350
0
  else if( !strncmp( s, "SHA1", s2-s ) )
351
0
      found |= 2;
352
0
  else if( !strncmp( s, "SHA224", s2-s ) )
353
0
      found |= 8;
354
0
  else if( !strncmp( s, "SHA256", s2-s ) )
355
0
      found |= 16;
356
0
  else if( !strncmp( s, "SHA384", s2-s ) )
357
0
      found |= 32;
358
0
  else if( !strncmp( s, "SHA512", s2-s ) )
359
0
      found |= 64;
360
0
  else
361
0
      return 0;
362
0
  for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
363
0
      ;
364
0
  if( *s2 && *s2 != ',' )
365
0
      return 0;
366
0
  if( *s2 )
367
0
      s2++;
368
0
    }
369
0
    return found;
370
0
}
371
372
/* Returns true if this is a valid armor tag as per RFC-2440bis-21. */
373
static int
374
is_armor_tag(const char *line)
375
2
{
376
2
  if(strncmp(line,"Version",7)==0
377
2
     || strncmp(line,"Comment",7)==0
378
2
     || strncmp(line,"MessageID",9)==0
379
2
     || strncmp(line,"Hash",4)==0
380
2
     || strncmp(line,"Charset",7)==0)
381
1
    return 1;
382
383
1
  return 0;
384
2
}
385
386
/****************
387
 * Check whether this is a armor line.  Returns: -1 if it is not a
388
 * armor header, 42 if it is a generic header, or the index number of
389
 * the armor header.
390
 */
391
static int
392
is_armor_header( byte *line, unsigned len )
393
3.00k
{
394
3.00k
    const char *s;
395
3.00k
    byte *save_p, *p;
396
3.00k
    int save_c;
397
3.00k
    int i;
398
399
3.00k
    if( len < 15 )
400
908
  return -1; /* too short */
401
2.09k
    if( memcmp( line, "-----", 5 ) )
402
466
  return -1; /* no */
403
1.63k
    p = strstr( line+5, "-----");
404
1.63k
    if( !p )
405
87
  return -1;
406
1.54k
    save_p = p;
407
1.54k
    p += 5;
408
409
    /* Some Windows environments seem to add whitespace to the end of
410
       the line, so we strip it here.  This becomes strict if
411
       --rfc2440 is set since 2440 reads "The header lines, therefore,
412
       MUST start at the beginning of a line, and MUST NOT have text
413
       following them on the same line."  It is unclear whether "text"
414
       refers to all text or just non-whitespace text.  4880 clarified
415
       this was only non-whitespace text. */
416
417
1.54k
    if(RFC2440)
418
0
      {
419
0
  if( *p == '\r' )
420
0
    p++;
421
0
  if( *p == '\n' )
422
0
    p++;
423
0
      }
424
1.54k
    else
425
3.07k
      while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
426
1.52k
  p++;
427
428
1.54k
    if( *p )
429
18
  return -1; /* garbage after dashes */
430
1.52k
    save_c = *save_p; *save_p = 0;
431
1.52k
    p = line+5;
432
3.34k
    for(i=0; (s=head_strings[i]); i++ )
433
3.31k
  if( !strcmp(s, p) )
434
1.49k
      break;
435
1.52k
    *save_p = save_c;
436
1.52k
    if (!s)
437
36
      {
438
36
        if (!strncmp (p, "BEGIN ", 6))
439
27
          return 42;
440
9
  return -1; /* unknown armor line */
441
36
      }
442
443
1.49k
    if( opt.verbose > 1 )
444
0
  log_info(_("armor: %s\n"), head_strings[i]);
445
1.49k
    return i;
446
1.52k
}
447
448
449
450
/****************
451
 * Parse a header lines
452
 * Return 0: Empty line (end of header lines)
453
 *   -1: invalid header line
454
 *   >0: Good header line
455
 */
456
static int
457
parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len )
458
1.49k
{
459
1.49k
    byte *p;
460
1.49k
    int hashes=0;
461
1.49k
    unsigned int len2;
462
463
1.49k
    len2 = length_sans_trailing_ws ( line, len );
464
1.49k
    if( !len2 ) {
465
666
        afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
466
666
  return 0; /* WS only: same as empty line */
467
666
    }
468
469
    /*
470
      This is fussy.  The spec says that a header line is delimited
471
      with a colon-space pair.  This means that a line such as
472
      "Comment: " (with nothing else) is actually legal as an empty
473
      string comment.  However, email and cut-and-paste being what it
474
      is, that trailing space may go away.  Therefore, we accept empty
475
      headers delimited with only a colon.  --rfc2440, as always,
476
      makes this strict and enforces the colon-space pair. -dms
477
    */
478
479
828
    p = strchr( line, ':');
480
828
    if (!p && afx->dearmor_state)
481
0
      return 0; /* Special treatment in --dearmor mode.  */
482
828
    if( !p || (RFC2440 && p[1]!=' ')
483
828
  || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
484
826
      {
485
826
  log_error (_("invalid armor header: "));
486
826
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
487
826
  log_printf ("\n");
488
826
  return -1;
489
826
      }
490
491
    /* Chop off the whitespace we detected before */
492
2
    len=len2;
493
2
    line[len2]='\0';
494
495
2
    if( opt.verbose ) {
496
0
  log_info(_("armor header: "));
497
0
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
498
0
  log_printf ("\n");
499
0
    }
500
501
2
    if (afx->dearmor_mode)
502
0
      ;
503
2
    else if (afx->in_cleartext)
504
0
      {
505
0
  if( (hashes=parse_hash_header( line )) )
506
0
    afx->hashes |= hashes;
507
0
  else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
508
0
    afx->not_dash_escaped = 1;
509
0
  else
510
0
    {
511
0
      log_error(_("invalid clearsig header\n"));
512
0
      return -1;
513
0
    }
514
0
      }
515
2
    else if(!is_armor_tag(line))
516
1
      {
517
  /* Section 6.2: "Unknown keys should be reported to the user,
518
     but OpenPGP should continue to process the message."  Note
519
     that in a clearsigned message this applies to the signature
520
     part (i.e. "BEGIN PGP SIGNATURE") and not the signed data
521
     ("BEGIN PGP SIGNED MESSAGE").  The only key allowed in the
522
     signed data section is "Hash". */
523
524
1
  log_info(_("unknown armor header: "));
525
1
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
526
1
  log_printf ("\n");
527
1
      }
528
529
2
    return 1;
530
2
}
531
532
533
534
/* figure out whether the data is armored or not */
535
static int
536
check_input( armor_filter_context_t *afx, IOBUF a )
537
1.53k
{
538
1.53k
    int rc = 0;
539
1.53k
    int i;
540
1.53k
    byte *line;
541
1.53k
    unsigned len;
542
1.53k
    unsigned maxlen;
543
1.53k
    int hdr_line = -1;
544
545
    /* read the first line to see whether this is armored data */
546
1.53k
    maxlen = MAX_LINELEN;
547
1.53k
    len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
548
1.53k
               &afx->buffer_size, &maxlen );
549
1.53k
    line = afx->buffer;
550
1.53k
    if( !maxlen ) {
551
  /* line has been truncated: assume not armored */
552
0
  afx->inp_checked = 1;
553
0
  afx->inp_bypass = 1;
554
0
  return 0;
555
0
    }
556
557
1.53k
    if( !len ) {
558
4
  return -1; /* eof */
559
4
    }
560
561
    /* (the line is always a C string but maybe longer) */
562
1.53k
    if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
563
166
  ;
564
1.36k
    else if (len >= 2 && !is_armored (line)) {
565
24
  afx->inp_checked = 1;
566
24
  afx->inp_bypass = 1;
567
24
  return 0;
568
24
    }
569
570
    /* find the armor header */
571
3.02k
    while(len) {
572
3.00k
  i = is_armor_header( line, len );
573
3.00k
        if ( i == 42 ) {
574
27
            if (afx->dearmor_mode) {
575
0
                afx->dearmor_state = 1;
576
0
                break;
577
0
            }
578
27
        }
579
2.98k
        else if (i >= 0
580
2.98k
                 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
581
1.49k
      hdr_line = i;
582
1.49k
      if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
583
0
          if( afx->in_cleartext ) {
584
0
        log_error(_("nested clear text signatures\n"));
585
0
        rc = gpg_error (GPG_ERR_INV_ARMOR);
586
0
                }
587
0
    afx->in_cleartext = 1;
588
0
      }
589
1.49k
      break;
590
1.49k
  }
591
592
  /* read the next line (skip all truncated lines) */
593
1.51k
  do {
594
1.51k
      maxlen = MAX_LINELEN;
595
1.51k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
596
1.51k
                 &afx->buffer_size, &maxlen );
597
1.51k
      line = afx->buffer;
598
1.51k
      len = afx->buffer_len;
599
1.51k
  } while( !maxlen );
600
1.51k
    }
601
602
    /* Parse the header lines.  */
603
1.50k
    while(len) {
604
  /* Read the next line (skip all truncated lines). */
605
1.49k
  do {
606
1.49k
      maxlen = MAX_LINELEN;
607
1.49k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
608
1.49k
                 &afx->buffer_size, &maxlen );
609
1.49k
      line = afx->buffer;
610
1.49k
      len = afx->buffer_len;
611
1.49k
  } while( !maxlen );
612
613
1.49k
  i = parse_header_line( afx, line, len );
614
1.49k
  if( i <= 0 ) {
615
1.49k
      if (i && RFC2440)
616
0
    rc = GPG_ERR_INV_ARMOR;
617
1.49k
      break;
618
1.49k
  }
619
1.49k
    }
620
621
622
1.50k
    if( rc )
623
0
  invalid_armor();
624
1.50k
    else if( afx->in_cleartext )
625
0
  afx->faked = 1;
626
1.50k
    else {
627
1.50k
  afx->inp_checked = 1;
628
1.50k
  gcry_md_reset (afx->crc_md);
629
1.50k
  afx->idx = 0;
630
1.50k
  afx->radbuf[0] = 0;
631
1.50k
    }
632
633
1.50k
    return rc;
634
1.53k
}
635
636
1.53k
#define PARTIAL_CHUNK 512
637
0
#define PARTIAL_POW   9
638
639
/****************
640
 * Fake a literal data packet and wait for the next armor line
641
 * fixme: empty line handling and null length clear text signature are
642
 *    not implemented/checked.
643
 */
644
static int
645
fake_packet( armor_filter_context_t *afx, IOBUF a,
646
       size_t *retn, byte *buf, size_t size  )
647
0
{
648
0
    int rc = 0;
649
0
    size_t len = 0;
650
0
    int lastline = 0;
651
0
    unsigned maxlen, n;
652
0
    byte *p;
653
0
    byte tempbuf[PARTIAL_CHUNK];
654
0
    size_t tempbuf_len=0;
655
0
    int this_truncated;
656
657
0
    while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
658
  /* copy what we have in the line buffer */
659
0
  if( afx->faked == 1 )
660
0
      afx->faked++; /* skip the first (empty) line */
661
0
  else
662
0
    {
663
      /* It's full, so write this partial chunk */
664
0
      if(tempbuf_len==PARTIAL_CHUNK)
665
0
        {
666
0
    buf[len++]=0xE0+PARTIAL_POW;
667
0
    memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
668
0
    len+=PARTIAL_CHUNK;
669
0
    tempbuf_len=0;
670
0
    continue;
671
0
        }
672
673
0
      while( tempbuf_len < PARTIAL_CHUNK
674
0
       && afx->buffer_pos < afx->buffer_len )
675
0
        tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
676
0
      if( tempbuf_len==PARTIAL_CHUNK )
677
0
        continue;
678
0
    }
679
680
  /* read the next line */
681
0
  maxlen = MAX_LINELEN;
682
0
  afx->buffer_pos = 0;
683
0
  afx->buffer_len = iobuf_read_line( a, &afx->buffer,
684
0
             &afx->buffer_size, &maxlen );
685
0
  if( !afx->buffer_len ) {
686
0
      rc = -1; /* eof (should not happen) */
687
0
      continue;
688
0
  }
689
0
  if( !maxlen )
690
0
          {
691
0
      afx->truncated++;
692
0
            this_truncated = 1;
693
0
          }
694
0
        else
695
0
          this_truncated = 0;
696
697
698
0
  p = afx->buffer;
699
0
  n = afx->buffer_len;
700
701
  /* Armor header or dash-escaped line? */
702
0
  if(p[0]=='-')
703
0
    {
704
      /* 2440bis-10: When reversing dash-escaping, an
705
         implementation MUST strip the string "- " if it occurs
706
         at the beginning of a line, and SHOULD warn on "-" and
707
         any character other than a space at the beginning of a
708
         line.  */
709
710
0
      if(p[1]==' ' && !afx->not_dash_escaped)
711
0
        {
712
    /* It's a dash-escaped line, so skip over the
713
       escape. */
714
0
    afx->buffer_pos = 2;
715
0
        }
716
0
      else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
717
0
        {
718
    /* Five dashes in a row mean it's probably armor
719
       header. */
720
0
    int type = is_armor_header( p, n );
721
0
                if (type == 42)
722
0
                  type = -1;  /* Only OpenPGP armors are expected.  */
723
0
    if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
724
0
      ; /* this is okay */
725
0
    else
726
0
      {
727
0
        if( type != BEGIN_SIGNATURE )
728
0
          {
729
0
      log_info(_("unexpected armor: "));
730
0
      es_write_sanitized (log_get_stream (), p, n,
731
0
                                            NULL, NULL);
732
0
      log_printf ("\n");
733
0
          }
734
735
0
        lastline = 1;
736
0
        rc = -1;
737
0
      }
738
0
        }
739
0
      else if(!afx->not_dash_escaped)
740
0
        {
741
    /* Bad dash-escaping. */
742
0
    log_info (_("invalid dash escaped line: "));
743
0
    es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
744
0
    log_printf ("\n");
745
0
        }
746
0
    }
747
748
  /* Now handle the end-of-line canonicalization */
749
0
  if( !afx->not_dash_escaped || this_truncated)
750
0
    {
751
0
      int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
752
753
0
      afx->buffer_len=
754
0
        trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
755
0
           " \t\r\n");
756
0
      afx->buffer_len+=afx->buffer_pos;
757
      /* the buffer is always allocated with enough space to append
758
       * the removed [CR], LF and a Nul
759
       * The reason for this complicated procedure is to keep at least
760
       * the original type of lineending - handling of the removed
761
       * trailing spaces seems to be impossible in our method
762
       * of faking a packet; either we have to use a temporary file
763
       * or calculate the hash here in this module and somehow find
764
       * a way to send the hash down the processing line (well, a special
765
       * faked packet could do the job).
766
             *
767
             * To make sure that a truncated line triggers a bad
768
             * signature error we replace a removed LF by a FF or
769
             * append a FF.  Right, this is a hack but better than a
770
             * global variable and way easier than to introduce a new
771
             * control packet or insert a line like "[truncated]\n"
772
             * into the filter output.
773
       */
774
0
      if( crlf )
775
0
        afx->buffer[afx->buffer_len++] = '\r';
776
0
      afx->buffer[afx->buffer_len++] = this_truncated? '\f':'\n';
777
0
      afx->buffer[afx->buffer_len] = '\0';
778
0
    }
779
0
    }
780
781
0
    if( lastline ) { /* write last (ending) length header */
782
0
        if(tempbuf_len<192)
783
0
    buf[len++]=tempbuf_len;
784
0
  else
785
0
    {
786
0
      buf[len++]=((tempbuf_len-192)/256) + 192;
787
0
      buf[len++]=(tempbuf_len-192) % 256;
788
0
    }
789
0
  memcpy(&buf[len],tempbuf,tempbuf_len);
790
0
  len+=tempbuf_len;
791
792
0
  rc = 0;
793
0
  afx->faked = 0;
794
0
  afx->in_cleartext = 0;
795
  /* and now read the header lines */
796
0
  afx->buffer_pos = 0;
797
0
  for(;;) {
798
0
      int i;
799
800
      /* read the next line (skip all truncated lines) */
801
0
      do {
802
0
    maxlen = MAX_LINELEN;
803
0
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
804
0
             &afx->buffer_size, &maxlen );
805
0
      } while( !maxlen );
806
0
      p = afx->buffer;
807
0
      n = afx->buffer_len;
808
0
      if( !n ) {
809
0
    rc = -1;
810
0
    break; /* eof */
811
0
      }
812
0
      i = parse_header_line( afx, p , n );
813
0
      if( i <= 0 ) {
814
0
    if( i )
815
0
        invalid_armor();
816
0
    break;
817
0
      }
818
0
  }
819
0
  afx->inp_checked = 1;
820
0
  gcry_md_reset (afx->crc_md);
821
0
  afx->idx = 0;
822
0
  afx->radbuf[0] = 0;
823
0
    }
824
825
0
    *retn = len;
826
0
    return rc;
827
0
}
828
829
830
static int
831
invalid_crc(void)
832
1
{
833
1
  if ( opt.ignore_crc_error )
834
0
    return 0;
835
1
  log_inc_errorcount();
836
1
  return gpg_error (GPG_ERR_INV_ARMOR);
837
1
}
838
839
840
static int
841
radix64_read( armor_filter_context_t *afx, IOBUF a, size_t *retn,
842
        byte *buf, size_t size )
843
1.51k
{
844
1.51k
    byte val;
845
1.51k
    int c;
846
1.51k
    u32 binc;
847
1.51k
    int checkcrc=0;
848
1.51k
    int rc = 0;
849
1.51k
    size_t n = 0;
850
1.51k
    int idx, onlypad=0;
851
1.51k
    int skip_fast = 0;
852
853
1.51k
    idx = afx->idx;
854
1.51k
    val = afx->radbuf[0];
855
35.2k
    for( n=0; n < size; ) {
856
857
35.2k
  if( afx->buffer_pos < afx->buffer_len )
858
32.8k
      c = afx->buffer[afx->buffer_pos++];
859
2.39k
  else { /* read the next line */
860
2.39k
      unsigned maxlen = MAX_LINELEN;
861
2.39k
      afx->buffer_pos = 0;
862
2.39k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
863
2.39k
                 &afx->buffer_size, &maxlen );
864
2.39k
      if( !maxlen )
865
0
    afx->truncated++;
866
2.39k
      if( !afx->buffer_len )
867
25
    break; /* eof */
868
2.37k
      continue;
869
2.39k
  }
870
871
32.8k
      again:
872
32.8k
  binc = asctobin[0][c];
873
874
32.8k
  if( binc != 0xffffffffUL )
875
11.8k
    {
876
11.8k
      if( idx == 0 && skip_fast == 0
877
11.8k
    && afx->buffer_pos + (16 - 1) < afx->buffer_len
878
11.8k
    && n + 12 < size)
879
2.89k
        {
880
    /* Fast path for radix64 to binary conversion.  */
881
2.89k
    u32 b0,b1,b2,b3;
882
883
    /* Speculatively load 15 more input bytes.  */
884
2.89k
    b0 = binc << (3 * 6);
885
2.89k
    b0 |= asctobin[2][afx->buffer[afx->buffer_pos + 0]];
886
2.89k
    b0 |= asctobin[1][afx->buffer[afx->buffer_pos + 1]];
887
2.89k
    b0 |= asctobin[0][afx->buffer[afx->buffer_pos + 2]];
888
2.89k
    b1  = asctobin[3][afx->buffer[afx->buffer_pos + 3]];
889
2.89k
    b1 |= asctobin[2][afx->buffer[afx->buffer_pos + 4]];
890
2.89k
    b1 |= asctobin[1][afx->buffer[afx->buffer_pos + 5]];
891
2.89k
    b1 |= asctobin[0][afx->buffer[afx->buffer_pos + 6]];
892
2.89k
    b2  = asctobin[3][afx->buffer[afx->buffer_pos + 7]];
893
2.89k
    b2 |= asctobin[2][afx->buffer[afx->buffer_pos + 8]];
894
2.89k
    b2 |= asctobin[1][afx->buffer[afx->buffer_pos + 9]];
895
2.89k
    b2 |= asctobin[0][afx->buffer[afx->buffer_pos + 10]];
896
2.89k
    b3  = asctobin[3][afx->buffer[afx->buffer_pos + 11]];
897
2.89k
    b3 |= asctobin[2][afx->buffer[afx->buffer_pos + 12]];
898
2.89k
    b3 |= asctobin[1][afx->buffer[afx->buffer_pos + 13]];
899
2.89k
    b3 |= asctobin[0][afx->buffer[afx->buffer_pos + 14]];
900
901
    /* Check if any of the input bytes were invalid. */
902
2.89k
    if( (b0 | b1 | b2 | b3) != 0xffffffffUL )
903
1.84k
      {
904
        /* All 16 bytes are valid. */
905
1.84k
        buf[n + 0] = b0 >> (2 * 8);
906
1.84k
        buf[n + 1] = b0 >> (1 * 8);
907
1.84k
        buf[n + 2] = b0 >> (0 * 8);
908
1.84k
        buf[n + 3] = b1 >> (2 * 8);
909
1.84k
        buf[n + 4] = b1 >> (1 * 8);
910
1.84k
        buf[n + 5] = b1 >> (0 * 8);
911
1.84k
        buf[n + 6] = b2 >> (2 * 8);
912
1.84k
        buf[n + 7] = b2 >> (1 * 8);
913
1.84k
        buf[n + 8] = b2 >> (0 * 8);
914
1.84k
        buf[n + 9] = b3 >> (2 * 8);
915
1.84k
        buf[n + 10] = b3 >> (1 * 8);
916
1.84k
        buf[n + 11] = b3 >> (0 * 8);
917
1.84k
        afx->buffer_pos += 16 - 1;
918
1.84k
        n += 12;
919
1.84k
        continue;
920
1.84k
      }
921
1.05k
    else if( b0 == 0xffffffffUL )
922
381
      {
923
        /* byte[1..3] have invalid character(s).  Switch to slow
924
           path.  */
925
381
        skip_fast = 1;
926
381
      }
927
676
    else if( b1 == 0xffffffffUL )
928
298
      {
929
        /* byte[4..7] have invalid character(s), first 4 bytes are
930
           valid.  */
931
298
        buf[n + 0] = b0 >> (2 * 8);
932
298
        buf[n + 1] = b0 >> (1 * 8);
933
298
        buf[n + 2] = b0 >> (0 * 8);
934
298
        afx->buffer_pos += 4 - 1;
935
298
        n += 3;
936
298
        skip_fast = 1;
937
298
        continue;
938
298
      }
939
378
    else if( b2 == 0xffffffffUL )
940
259
      {
941
        /* byte[8..11] have invalid character(s), first 8 bytes are
942
           valid.  */
943
259
        buf[n + 0] = b0 >> (2 * 8);
944
259
        buf[n + 1] = b0 >> (1 * 8);
945
259
        buf[n + 2] = b0 >> (0 * 8);
946
259
        buf[n + 3] = b1 >> (2 * 8);
947
259
        buf[n + 4] = b1 >> (1 * 8);
948
259
        buf[n + 5] = b1 >> (0 * 8);
949
259
        afx->buffer_pos += 8 - 1;
950
259
        n += 6;
951
259
        skip_fast = 1;
952
259
        continue;
953
259
      }
954
119
    else /*if( b3 == 0xffffffffUL )*/
955
119
      {
956
        /* byte[12..15] have invalid character(s), first 12 bytes
957
           are valid.  */
958
119
        buf[n + 0] = b0 >> (2 * 8);
959
119
        buf[n + 1] = b0 >> (1 * 8);
960
119
        buf[n + 2] = b0 >> (0 * 8);
961
119
        buf[n + 3] = b1 >> (2 * 8);
962
119
        buf[n + 4] = b1 >> (1 * 8);
963
119
        buf[n + 5] = b1 >> (0 * 8);
964
119
        buf[n + 6] = b2 >> (2 * 8);
965
119
        buf[n + 7] = b2 >> (1 * 8);
966
119
        buf[n + 8] = b2 >> (0 * 8);
967
119
        afx->buffer_pos += 12 - 1;
968
119
        n += 9;
969
119
        skip_fast = 1;
970
119
        continue;
971
119
      }
972
2.89k
        }
973
974
9.32k
      switch(idx)
975
9.32k
        {
976
2.78k
    case 0: val =  binc << 2; break;
977
2.31k
    case 1: val |= (binc>>4)&3; buf[n++]=val;val=(binc<<4)&0xf0;break;
978
2.21k
    case 2: val |= (binc>>2)&15; buf[n++]=val;val=(binc<<6)&0xc0;break;
979
2.00k
    case 3: val |= binc&0x3f; buf[n++] = val; break;
980
9.32k
        }
981
9.32k
      idx = (idx+1) % 4;
982
983
9.32k
      continue;
984
9.32k
    }
985
986
21.0k
  skip_fast = 0;
987
988
21.0k
  if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
989
2.59k
      continue;
990
18.4k
  else if( c == '=' ) { /* pad character: stop */
991
      /* some mailers leave quoted-printable encoded characters
992
       * so we try to workaround this */
993
1.48k
      if( afx->buffer_pos+2 < afx->buffer_len ) {
994
1.15k
    int cc1, cc2, cc3;
995
1.15k
    cc1 = afx->buffer[afx->buffer_pos];
996
1.15k
    cc2 = afx->buffer[afx->buffer_pos+1];
997
1.15k
    cc3 = afx->buffer[afx->buffer_pos+2];
998
1.15k
    if( isxdigit(cc1) && isxdigit(cc2)
999
1.15k
          && strchr( "=\n\r\t ", cc3 )) {
1000
        /* well it seems to be the case - adjust */
1001
0
        c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
1002
0
        c <<= 4;
1003
0
        c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
1004
0
        afx->buffer_pos += 2;
1005
0
        afx->qp_detected = 1;
1006
0
        goto again;
1007
0
    }
1008
1.15k
      }
1009
1010
            /* Occasionally a bug MTA will leave the = escaped as
1011
               =3D.  If the 4 characters following that are valid
1012
               Radix64 characters and they are following by a new
1013
               line, assume that this is the case and skip the
1014
               3D.  */
1015
1.48k
            if (afx->buffer_pos + 6 < afx->buffer_len
1016
1.48k
                && afx->buffer[afx->buffer_pos + 0] == '3'
1017
1.48k
                && afx->buffer[afx->buffer_pos + 1] == 'D'
1018
1.48k
                && asctobin[0][afx->buffer[afx->buffer_pos + 2]] != 0xffffffffUL
1019
1.48k
                && asctobin[0][afx->buffer[afx->buffer_pos + 3]] != 0xffffffffUL
1020
1.48k
                && asctobin[0][afx->buffer[afx->buffer_pos + 4]] != 0xffffffffUL
1021
1.48k
                && asctobin[0][afx->buffer[afx->buffer_pos + 5]] != 0xffffffffUL
1022
1.48k
                && afx->buffer[afx->buffer_pos + 6] == '\n')
1023
0
              {
1024
0
                afx->buffer_pos += 2;
1025
0
                afx->qp_detected = 1;
1026
0
              }
1027
1028
1.48k
      if (!n)
1029
779
        onlypad = 1;
1030
1031
1.48k
      if( idx == 1 )
1032
471
    buf[n++] = val;
1033
1.48k
      checkcrc++;
1034
1.48k
      break;
1035
1.48k
  }
1036
16.9k
        else if (afx->dearmor_state && c == '-'
1037
16.9k
                 && afx->buffer_pos + 8 < afx->buffer_len
1038
16.9k
                 && !strncmp (afx->buffer, "-----END ", 8)) {
1039
0
            break; /* End in --dearmor mode.  */
1040
0
        }
1041
16.9k
  else {
1042
16.9k
      log_error(_("invalid radix64 character %02X skipped\n"), c);
1043
16.9k
      continue;
1044
16.9k
  }
1045
21.0k
    }
1046
1047
1.51k
    afx->idx = idx;
1048
1.51k
    afx->radbuf[0] = val;
1049
1050
1.51k
    if( n )
1051
1.00k
      gcry_md_write (afx->crc_md, buf, n);
1052
1053
1.51k
    if( checkcrc ) {
1054
1.48k
  gcry_md_final (afx->crc_md);
1055
1.48k
  afx->any_data = 1;
1056
1.48k
  afx->inp_checked=0;
1057
1.48k
  afx->faked = 0;
1058
2.71k
  for(;;) { /* skip lf and pad characters */
1059
2.71k
      if( afx->buffer_pos < afx->buffer_len )
1060
2.60k
    c = afx->buffer[afx->buffer_pos++];
1061
103
      else { /* read the next line */
1062
103
    unsigned maxlen = MAX_LINELEN;
1063
103
    afx->buffer_pos = 0;
1064
103
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1065
103
               &afx->buffer_size, &maxlen );
1066
103
    if( !maxlen )
1067
0
        afx->truncated++;
1068
103
    if( !afx->buffer_len )
1069
1
        break; /* eof */
1070
102
    continue;
1071
103
      }
1072
2.60k
      if( c == '\n' || c == ' ' || c == '\r'
1073
2.60k
    || c == '\t' || c == '=' )
1074
1.12k
    continue;
1075
1.48k
      break;
1076
2.60k
  }
1077
1.48k
  if( !afx->buffer_len )
1078
1
      log_error(_("premature eof (no CRC)\n"));
1079
1.48k
  else {
1080
1.48k
      u32 mycrc = 0;
1081
1.48k
      idx = 0;
1082
1.61k
      do {
1083
1.61k
    if( (binc = asctobin[0][c]) == 0xffffffffUL )
1084
1.44k
        break;
1085
172
    switch(idx) {
1086
43
      case 0: val =  binc << 2; break;
1087
43
      case 1: val |= (binc>>4)&3; mycrc |= val << 16;val=(binc<<4)&0xf0;break;
1088
43
      case 2: val |= (binc>>2)&15; mycrc |= val << 8;val=(binc<<6)&0xc0;break;
1089
43
      case 3: val |= binc&0x3f; mycrc |= val; break;
1090
172
    }
1091
172
    for(;;) {
1092
172
        if( afx->buffer_pos < afx->buffer_len )
1093
172
      c = afx->buffer[afx->buffer_pos++];
1094
0
        else { /* read the next line */
1095
0
      unsigned maxlen = MAX_LINELEN;
1096
0
      afx->buffer_pos = 0;
1097
0
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1098
0
                 &afx->buffer_size,
1099
0
                &maxlen );
1100
0
      if( !maxlen )
1101
0
          afx->truncated++;
1102
0
      if( !afx->buffer_len )
1103
0
          break; /* eof */
1104
0
      continue;
1105
0
        }
1106
172
        break;
1107
172
    }
1108
172
    if( !afx->buffer_len )
1109
0
        break; /* eof */
1110
172
      } while( ++idx < 4 );
1111
1.48k
      if( !afx->buffer_len ) {
1112
0
    log_info(_("premature eof (in CRC)\n"));
1113
0
    rc = invalid_crc();
1114
0
      }
1115
1.48k
      else if( idx == 0 ) {
1116
          /* No CRC at all is legal ("MAY") */
1117
1.44k
          rc=0;
1118
1.44k
      }
1119
43
      else if( idx != 4 ) {
1120
0
    log_info(_("malformed CRC\n"));
1121
0
    rc = invalid_crc();
1122
0
      }
1123
43
      else if( mycrc != get_afx_crc (afx) ) {
1124
1
    log_info (_("CRC error; %06lX - %06lX\n"),
1125
1
            (ulong)get_afx_crc (afx), (ulong)mycrc);
1126
1
    rc = invalid_crc();
1127
1
      }
1128
42
      else {
1129
42
    rc = 0;
1130
                /* FIXME: Here we should emit another control packet,
1131
                 * so that we know in mainproc that we are processing
1132
                 * a clearsign message */
1133
#if 0
1134
    for(rc=0;!rc;) {
1135
        rc = 0 /*check_trailer( &fhdr, c )*/;
1136
        if( !rc ) {
1137
      if( (c=iobuf_get(a)) == -1 )
1138
          rc = 2;
1139
        }
1140
    }
1141
    if( rc == -1 )
1142
        rc = 0;
1143
    else if( rc == 2 ) {
1144
        log_error(_("premature eof (in trailer)\n"));
1145
        rc = GPG_ERR_INV_ARMOR;
1146
    }
1147
    else {
1148
        log_error(_("error in trailer line\n"));
1149
        rc = GPG_ERR_INV_ARMOR;
1150
    }
1151
#endif
1152
42
      }
1153
1.48k
  }
1154
1.48k
    }
1155
1156
1.51k
    if( !n && !onlypad )
1157
18
  rc = -1;
1158
1159
1.51k
    *retn = n;
1160
1.51k
    return rc;
1161
1.51k
}
1162
1163
static void
1164
armor_output_buf_as_radix64 (armor_filter_context_t *afx, IOBUF a,
1165
           byte *buf, size_t size)
1166
0
{
1167
0
  byte radbuf[sizeof (afx->radbuf)];
1168
0
  byte outbuf[64 + sizeof (afx->eol)];
1169
0
  unsigned int eollen = strlen (afx->eol);
1170
0
  u32 in, in2;
1171
0
  int idx, idx2;
1172
0
  int i;
1173
1174
0
  idx = afx->idx;
1175
0
  idx2 = afx->idx2;
1176
0
  memcpy (radbuf, afx->radbuf, sizeof (afx->radbuf));
1177
1178
0
  if (size && (idx || idx2))
1179
0
    {
1180
      /* preload eol to outbuf buffer */
1181
0
      memcpy (outbuf + 4, afx->eol, sizeof (afx->eol));
1182
1183
0
      for (; size && (idx || idx2); buf++, size--)
1184
0
  {
1185
0
    radbuf[idx++] = *buf;
1186
0
    if (idx > 2)
1187
0
      {
1188
0
        idx = 0;
1189
0
        in = (u32)radbuf[0] << (2 * 8);
1190
0
        in |= (u32)radbuf[1] << (1 * 8);
1191
0
        in |= (u32)radbuf[2] << (0 * 8);
1192
0
        outbuf[0] = bintoasc[(in >> 18) & 077];
1193
0
        outbuf[1] = bintoasc[(in >> 12) & 077];
1194
0
        outbuf[2] = bintoasc[(in >> 6) & 077];
1195
0
        outbuf[3] = bintoasc[(in >> 0) & 077];
1196
0
        if (++idx2 >= (64/4))
1197
0
    { /* pgp doesn't like 72 here */
1198
0
      idx2=0;
1199
0
      iobuf_write (a, outbuf, 4 + eollen);
1200
0
    }
1201
0
        else
1202
0
    {
1203
0
      iobuf_write (a, outbuf, 4);
1204
0
    }
1205
0
      }
1206
0
  }
1207
0
    }
1208
1209
0
  if (size >= (64/4)*3)
1210
0
    {
1211
      /* preload eol to outbuf buffer */
1212
0
      memcpy (outbuf + 64, afx->eol, sizeof(afx->eol));
1213
1214
0
      do
1215
0
  {
1216
    /* idx and idx2 == 0 */
1217
1218
0
    for (i = 0; i < (64/8); i++)
1219
0
      {
1220
0
        in = (u32)buf[0] << (2 * 8);
1221
0
        in |= (u32)buf[1] << (1 * 8);
1222
0
        in |= (u32)buf[2] << (0 * 8);
1223
0
        in2 = (u32)buf[3] << (2 * 8);
1224
0
        in2 |= (u32)buf[4] << (1 * 8);
1225
0
        in2 |= (u32)buf[5] << (0 * 8);
1226
0
        outbuf[i*8+0] = bintoasc[(in >> 18) & 077];
1227
0
        outbuf[i*8+1] = bintoasc[(in >> 12) & 077];
1228
0
        outbuf[i*8+2] = bintoasc[(in >> 6) & 077];
1229
0
        outbuf[i*8+3] = bintoasc[(in >> 0) & 077];
1230
0
        outbuf[i*8+4] = bintoasc[(in2 >> 18) & 077];
1231
0
        outbuf[i*8+5] = bintoasc[(in2 >> 12) & 077];
1232
0
        outbuf[i*8+6] = bintoasc[(in2 >> 6) & 077];
1233
0
        outbuf[i*8+7] = bintoasc[(in2 >> 0) & 077];
1234
0
        buf+=6;
1235
0
        size-=6;
1236
0
      }
1237
1238
    /* pgp doesn't like 72 here */
1239
0
    iobuf_write (a, outbuf, 64 + eollen);
1240
0
  }
1241
0
      while (size >= (64/4)*3);
1242
1243
      /* restore eol for tail handling */
1244
0
      if (size)
1245
0
  memcpy (outbuf + 4, afx->eol, sizeof (afx->eol));
1246
0
    }
1247
1248
0
  for (; size; buf++, size--)
1249
0
    {
1250
0
      radbuf[idx++] = *buf;
1251
0
      if (idx > 2)
1252
0
  {
1253
0
    idx = 0;
1254
0
    in = (u32)radbuf[0] << (2 * 8);
1255
0
    in |= (u32)radbuf[1] << (1 * 8);
1256
0
    in |= (u32)radbuf[2] << (0 * 8);
1257
0
    outbuf[0] = bintoasc[(in >> 18) & 077];
1258
0
    outbuf[1] = bintoasc[(in >> 12) & 077];
1259
0
    outbuf[2] = bintoasc[(in >> 6) & 077];
1260
0
    outbuf[3] = bintoasc[(in >> 0) & 077];
1261
0
    if (++idx2 >= (64/4))
1262
0
      { /* pgp doesn't like 72 here */
1263
0
        idx2=0;
1264
0
        iobuf_write (a, outbuf, 4 + eollen);
1265
0
      }
1266
0
    else
1267
0
      {
1268
0
        iobuf_write (a, outbuf, 4);
1269
0
      }
1270
0
  }
1271
0
    }
1272
1273
0
  memcpy (afx->radbuf, radbuf, sizeof (afx->radbuf));
1274
0
  afx->idx = idx;
1275
0
  afx->idx2 = idx2;
1276
0
}
1277
1278
/****************
1279
 * This filter is used to handle the armor stuff
1280
 */
1281
static int
1282
armor_filter( void *opaque, int control,
1283
       IOBUF a, byte *buf, size_t *ret_len)
1284
1.66k
{
1285
1.66k
    size_t size = *ret_len;
1286
1.66k
    armor_filter_context_t *afx = opaque;
1287
1.66k
    int rc=0, c;
1288
1.66k
    byte radbuf[3];
1289
1.66k
    int  idx, idx2;
1290
1.66k
    size_t n=0;
1291
1.66k
    u32 crc;
1292
#if 0
1293
    static FILE *fp ;
1294
1295
    if( !fp ) {
1296
  fp = fopen("armor.out", "w");
1297
  log_assert(fp);
1298
    }
1299
#endif
1300
1301
1.66k
    if( DBG_FILTER )
1302
0
  log_debug("armor-filter: control: %d\n", control );
1303
1.66k
    if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
1304
23
  n = 0;
1305
23
  if( afx->buffer_len ) {
1306
            /* Copy the data from AFX->BUFFER to BUF.  */
1307
0
      for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
1308
0
    buf[n++] = afx->buffer[afx->buffer_pos++];
1309
0
      if( afx->buffer_pos >= afx->buffer_len )
1310
0
    afx->buffer_len = 0;
1311
0
  }
1312
        /* If there is still space in BUF, read directly into it.  */
1313
77.9k
  for(; n < size; n++ ) {
1314
77.9k
      if( (c=iobuf_get(a)) == -1 )
1315
23
    break;
1316
77.9k
      buf[n] = c & 0xff;
1317
77.9k
  }
1318
23
  if( !n )
1319
            /* We didn't get any data.  EOF.  */
1320
13
      rc = -1;
1321
23
  *ret_len = n;
1322
23
    }
1323
1.64k
    else if( control == IOBUFCTRL_UNDERFLOW ) {
1324
        /* We need some space for the faked packet.  The minmum
1325
         * required size is the PARTIAL_CHUNK size plus a byte for the
1326
         * length itself */
1327
1.53k
  if( size < PARTIAL_CHUNK+1 )
1328
0
      BUG(); /* supplied buffer too short */
1329
1330
1.53k
  if( afx->faked )
1331
0
      rc = fake_packet( afx, a, &n, buf, size );
1332
1.53k
  else if( !afx->inp_checked ) {
1333
1.53k
      rc = check_input( afx, a );
1334
1.53k
      if( afx->inp_bypass ) {
1335
107k
    for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
1336
107k
        buf[n++] = afx->buffer[afx->buffer_pos++];
1337
24
    if( afx->buffer_pos >= afx->buffer_len )
1338
24
        afx->buffer_len = 0;
1339
24
    if( !n )
1340
0
        rc = -1;
1341
24
      }
1342
1.51k
      else if( afx->faked ) {
1343
0
          unsigned int hashes = afx->hashes;
1344
0
                const byte *sesmark;
1345
0
                size_t sesmarklen;
1346
1347
0
                sesmark = get_session_marker( &sesmarklen );
1348
0
                if ( sesmarklen > 20 )
1349
0
                    BUG();
1350
1351
    /* the buffer is at least 15+n*15 bytes long, so it
1352
     * is easy to construct the packets */
1353
1354
0
    hashes &= 1|2|8|16|32|64;
1355
0
    if( !hashes ) {
1356
0
        hashes |= 2;  /* Default to SHA-1. */
1357
0
    }
1358
0
    n=0;
1359
                /* First a gpg control packet... */
1360
0
                buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1361
0
                n++;   /* see below */
1362
0
                memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1363
0
                buf[n++] = CTRLPKT_CLEARSIGN_START;
1364
0
                buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1365
0
                if( hashes & 1 )
1366
0
                    buf[n++] = DIGEST_ALGO_RMD160;
1367
0
                if( hashes & 2 )
1368
0
                    buf[n++] = DIGEST_ALGO_SHA1;
1369
0
                if( hashes & 8 )
1370
0
                    buf[n++] = DIGEST_ALGO_SHA224;
1371
0
                if( hashes & 16 )
1372
0
                    buf[n++] = DIGEST_ALGO_SHA256;
1373
0
                if( hashes & 32 )
1374
0
                    buf[n++] = DIGEST_ALGO_SHA384;
1375
0
                if( hashes & 64 )
1376
0
                    buf[n++] = DIGEST_ALGO_SHA512;
1377
0
                buf[1] = n - 2;
1378
1379
    /* ...followed by an invented plaintext packet.
1380
       Amusingly enough, this packet is not compliant with
1381
       2440 as the initial partial length is less than 512
1382
       bytes.  Of course, we'll accept it anyway ;) */
1383
1384
0
    buf[n++] = 0xCB; /* new packet format, type 11 */
1385
0
    buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1386
0
    buf[n++] = 't';  /* canonical text mode */
1387
0
    buf[n++] = 0;  /* namelength */
1388
0
    buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1389
0
    memset(buf+n, 0, 4); /* timestamp */
1390
0
    n += 4;
1391
0
      }
1392
1.51k
      else if( !rc )
1393
1.50k
    rc = radix64_read( afx, a, &n, buf, size );
1394
1.53k
  }
1395
4
  else
1396
4
      rc = radix64_read( afx, a, &n, buf, size );
1397
#if 0
1398
  if( n )
1399
      if( fwrite(buf, n, 1, fp ) != 1 )
1400
    BUG();
1401
#endif
1402
1.53k
  *ret_len = n;
1403
1.53k
    }
1404
106
    else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
1405
0
  if( !afx->status ) { /* write the header line */
1406
0
      const char *s;
1407
0
      strlist_t comment=opt.comments;
1408
1409
0
      if( afx->what >= DIM(head_strings) )
1410
0
    log_bug("afx->what=%d", afx->what);
1411
0
      iobuf_writestr(a, "-----");
1412
0
      iobuf_writestr(a, head_strings[afx->what] );
1413
0
      iobuf_writestr(a, "-----" );
1414
0
      iobuf_writestr(a,afx->eol);
1415
0
      if (opt.emit_version)
1416
0
        {
1417
0
    iobuf_writestr (a, "Version: "GNUPG_NAME" v");
1418
0
                for (s=VERSION; *s && *s != '.'; s++)
1419
0
                  iobuf_writebyte (a, *s);
1420
0
                if (opt.emit_version > 1 && *s)
1421
0
                  {
1422
0
                    iobuf_writebyte (a, *s++);
1423
0
                    for (; *s && *s != '.'; s++)
1424
0
                      iobuf_writebyte (a, *s);
1425
0
                    if (opt.emit_version > 2)
1426
0
                      {
1427
0
                        for (; *s && *s != '-' && !spacep (s); s++)
1428
0
                          iobuf_writebyte (a, *s);
1429
0
                        if (opt.emit_version > 3)
1430
0
                          iobuf_writestr (a, " (" PRINTABLE_OS_NAME ")");
1431
0
                      }
1432
0
                  }
1433
0
    iobuf_writestr(a,afx->eol);
1434
0
        }
1435
1436
      /* write the comment strings */
1437
0
      for(;comment;comment=comment->next)
1438
0
        {
1439
0
    iobuf_writestr(a, "Comment: " );
1440
0
    for( s=comment->d; *s; s++ )
1441
0
      {
1442
0
        if( *s == '\n' )
1443
0
          iobuf_writestr(a, "\\n" );
1444
0
        else if( *s == '\r' )
1445
0
          iobuf_writestr(a, "\\r" );
1446
0
        else if( *s == '\v' )
1447
0
          iobuf_writestr(a, "\\v" );
1448
0
        else
1449
0
          iobuf_put(a, *s );
1450
0
      }
1451
1452
0
    iobuf_writestr(a,afx->eol);
1453
0
        }
1454
1455
0
      if ( afx->hdrlines ) {
1456
0
                for ( s = afx->hdrlines; *s; s++ ) {
1457
#ifdef HAVE_DOSISH_SYSTEM
1458
                    if ( *s == '\n' )
1459
                        iobuf_put( a, '\r');
1460
#endif
1461
0
                    iobuf_put(a, *s );
1462
0
                }
1463
0
            }
1464
1465
0
      iobuf_writestr(a,afx->eol);
1466
0
      afx->status++;
1467
0
      afx->idx = 0;
1468
0
      afx->idx2 = 0;
1469
0
      gcry_md_reset (afx->crc_md);
1470
0
  }
1471
1472
0
  if( size ) {
1473
0
      gcry_md_write (afx->crc_md, buf, size);
1474
0
      armor_output_buf_as_radix64 (afx, a, buf, size);
1475
0
        }
1476
0
    }
1477
106
    else if( control == IOBUFCTRL_INIT )
1478
53
      {
1479
53
  if( !is_initialized )
1480
1
    initialize();
1481
1482
  /* Figure out what we're using for line endings if the caller
1483
     didn't specify. */
1484
53
  if(afx->eol[0]==0)
1485
53
    {
1486
#ifdef HAVE_DOSISH_SYSTEM
1487
      afx->eol[0]='\r';
1488
      afx->eol[1]='\n';
1489
#else
1490
53
      afx->eol[0]='\n';
1491
53
#endif
1492
53
    }
1493
53
      }
1494
53
    else if( control == IOBUFCTRL_CANCEL ) {
1495
0
  afx->cancel = 1;
1496
0
    }
1497
53
    else if( control == IOBUFCTRL_FREE ) {
1498
53
  if( afx->cancel )
1499
0
      ;
1500
53
  else if( afx->status ) { /* pad, write cecksum, and bottom line */
1501
0
      gcry_md_final (afx->crc_md);
1502
0
      crc = get_afx_crc (afx);
1503
0
      idx = afx->idx;
1504
0
      idx2 = afx->idx2;
1505
0
      if( idx ) {
1506
0
    c = bintoasc[(afx->radbuf[0]>>2)&077];
1507
0
    iobuf_put(a, c);
1508
0
    if( idx == 1 ) {
1509
0
        c = bintoasc[((afx->radbuf[0] << 4) & 060) & 077];
1510
0
        iobuf_put(a, c);
1511
0
        iobuf_put(a, '=');
1512
0
        iobuf_put(a, '=');
1513
0
    }
1514
0
    else { /* 2 */
1515
0
        c = bintoasc[(((afx->radbuf[0]<<4)&060)
1516
0
                                  |((afx->radbuf[1]>>4)&017))&077];
1517
0
        iobuf_put(a, c);
1518
0
        c = bintoasc[((afx->radbuf[1] << 2) & 074) & 077];
1519
0
        iobuf_put(a, c);
1520
0
        iobuf_put(a, '=');
1521
0
    }
1522
0
    if( ++idx2 >= (64/4) )
1523
0
      { /* pgp doesn't like 72 here */
1524
0
        iobuf_writestr(a,afx->eol);
1525
0
        idx2=0;
1526
0
      }
1527
0
      }
1528
      /* may need a linefeed */
1529
0
      if( idx2 )
1530
0
        iobuf_writestr(a,afx->eol);
1531
      /* write the CRC */
1532
0
      iobuf_put(a, '=');
1533
0
      radbuf[0] = crc >>16;
1534
0
      radbuf[1] = crc >> 8;
1535
0
      radbuf[2] = crc;
1536
0
      c = bintoasc[(*radbuf >> 2) & 077];
1537
0
      iobuf_put(a, c);
1538
0
      c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1539
0
      iobuf_put(a, c);
1540
0
      c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1541
0
      iobuf_put(a, c);
1542
0
      c = bintoasc[radbuf[2]&077];
1543
0
      iobuf_put(a, c);
1544
0
      iobuf_writestr(a,afx->eol);
1545
      /* and the trailer */
1546
0
      if( afx->what >= DIM(tail_strings) )
1547
0
    log_bug("afx->what=%d", afx->what);
1548
0
      iobuf_writestr(a, "-----");
1549
0
      iobuf_writestr(a, tail_strings[afx->what] );
1550
0
      iobuf_writestr(a, "-----" );
1551
0
      iobuf_writestr(a,afx->eol);
1552
0
  }
1553
53
  else if( !afx->any_data && !afx->inp_bypass ) {
1554
12
      log_error(_("no valid OpenPGP data found.\n"));
1555
12
      afx->no_openpgp_data = 1;
1556
12
      write_status_text( STATUS_NODATA, "1" );
1557
12
  }
1558
        /* Note that in a cleartext signature truncated lines in the
1559
         * plaintext are detected and propagated to the signature
1560
         * checking code by inserting a \f into the plaintext.  We do
1561
         * not use log_info here because some of the truncated lines
1562
         * are harmless.  */
1563
53
  if( afx->truncated )
1564
0
      log_info(_("invalid armor: line longer than %d characters\n"),
1565
0
          MAX_LINELEN );
1566
  /* issue an error to enforce dissemination of correct software */
1567
53
  if( afx->qp_detected )
1568
0
      log_error(_("quoted printable character in armor - "
1569
0
      "probably a buggy MTA has been used\n") );
1570
53
  xfree( afx->buffer );
1571
53
  afx->buffer = NULL;
1572
53
        release_armor_context (afx);
1573
53
    }
1574
0
    else if( control == IOBUFCTRL_DESC )
1575
0
        mem2str (buf, "armor_filter", *ret_len);
1576
1.66k
    return rc;
1577
1.66k
}
1578
1579
1580
/****************
1581
 * create a radix64 encoded string.
1582
 */
1583
char *
1584
make_radix64_string( const byte *data, size_t len )
1585
0
{
1586
0
    char *buffer, *p;
1587
1588
0
    buffer = p = xmalloc( (len+2)/3*4 + 1 );
1589
0
    for( ; len >= 3 ; len -= 3, data += 3 ) {
1590
0
  *p++ = bintoasc[(data[0] >> 2) & 077];
1591
0
  *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1592
0
  *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
1593
0
  *p++ = bintoasc[data[2]&077];
1594
0
    }
1595
0
    if( len == 2 ) {
1596
0
  *p++ = bintoasc[(data[0] >> 2) & 077];
1597
0
  *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1598
0
  *p++ = bintoasc[((data[1]<<2)&074)];
1599
0
    }
1600
0
    else if( len == 1 ) {
1601
0
  *p++ = bintoasc[(data[0] >> 2) & 077];
1602
0
  *p++ = bintoasc[(data[0] <<4)&060];
1603
0
    }
1604
0
    *p = 0;
1605
0
    return buffer;
1606
0
}